Pointer to a map

Just starting out? Need help? Post your questions and find answers here.
User avatar
mariosk8s
Enthusiast
Enthusiast
Posts: 103
Joined: Wed Apr 06, 2011 11:37 am
Location: Hüfingen, Germany
Contact:

Pointer to a map

Post by mariosk8s »

Hello everyone.
I'm having a problem trying to figure out how to create a pointer to a map.
Documentation and forum search hasn't yielded how to go about that.

Here's what i'm trying to do:

Code: Select all

Structure test
  Map a.s()
  Map b.s()
  Map *current.s()
EndStructure

Define t.test
Define *pt.test = @t.test

*pt.test\current.s() = *pt.test\a.s()
It fails with
The map doesn't have a current element
Even something simpler like

Code: Select all

NewMap a.s()
Map *pa.s() = @a.s()
I'm not sure what the syntax would be.
Is this even possible?
It would be nice, as i am trying to set a current map for subsequent access based on a bunch of if … elseif statements.
I really don't want to have to repeat the if block for every access.

Clue sticks would be appreciated

Thanks

Mario
User avatar
PureLeo
Enthusiast
Enthusiast
Posts: 221
Joined: Fri Jan 29, 2010 1:05 pm
Location: Brazil

Re: Pointer to a map

Post by PureLeo »

Try this :)

Code: Select all

Structure test
  Map a.s()
  Map b.s()
  Map current.s() ; no * needed
EndStructure

;initialize a structure with dynamic objects (map, list, etc)
*t.test = AllocateMemory(SizeOf(test)) 
InitializeStructure(*t,test)

*pt.test = AllocateMemory(SizeOf(test)) 
InitializeStructure(*pt,test)

;you can copy a structure this way
CopyStructure(*t,*pt,test)

;copy every element from a map to another map
CopyMap(*pt\a(),*pt\current())
 
Also, you only need to use .s , .test, etc, once, when you declare the object
User avatar
Demivec
Addict
Addict
Posts: 4086
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Pointer to a map

Post by Demivec »

mariosk8s wrote:Hello everyone.
I'm having a problem trying to figure out how to create a pointer to a map.
Documentation and forum search hasn't yielded how to go about that.

Here's what i'm trying to do:

Code: Select all

Structure test
  Map a.s()
  Map b.s()
  Map *current.s()
EndStructure

Define t.test
Define *pt.test = @t.test

*pt.test\current.s() = *pt.test\a.s()
It fails with
The map doesn't have a current element
Even something simpler like

Code: Select all

NewMap a.s()
Map *pa.s() = @a.s()
I'm not sure what the syntax would be.
Is this even possible?
It would be nice, as i am trying to set a current map for subsequent access based on a bunch of if … elseif statements.
I really don't want to have to repeat the if block for every access.

Clue sticks would be appreciated
First, if a pointer doesn't have a structure type then it has no type. This means you can't have *pa.s() or *current.s(). It would either be *pa.String() or *pa().

Second, a map needs a string to be used as the key.

Third, I can't make any sense of any of the example code you suggested nor of your explanation. Let me attempt to reword your question. Are you trying to have a single pointer that points to a element in a map? If that is the case then here is an example:

Code: Select all

NewMap a.s()
a("Test 1") = "result 1"
a("Test 2") = "result 2"

Define *pa.String


;this fails if there is no elements in map, or no current element
*pa = @a()
Debug *pa
Debug *pa\s

*pa = FindMapElement(a(),"Test 1") ;points to element if it exists
Debug *pa
Debug *pa\s

ResetMap(a()) ;now there is no current element
;the next line will generate a debugger warning if there is no current element, ignore it and continue running
If MapKey(a()) <> "" ;check for current element's key
  Debug "There is a current element."
Else
  Debug "There isn't a current element."
EndIf 
User avatar
mariosk8s
Enthusiast
Enthusiast
Posts: 103
Joined: Wed Apr 06, 2011 11:37 am
Location: Hüfingen, Germany
Contact:

Re: Pointer to a map

Post by mariosk8s »

@PureLeo and @Demivec thanks for your replies.

I think i really messed up on communicating this.
I'm not trying to get a pointer to an element inside a map.
Neither do i want to copy a map.

What i'm looking for is to setup an alias to a map.
I want to point that alias at one map or another based on some logic, and then subsequently work with that map using the alias

Assuming the notation below were correct, which it is not i'd want to do the following

Code: Select all

; one real map
NewMap a.s()
; another real map
NewMap b.s()
; a pointer to a map
NewMap *pt.s()

; decide which real map to work with by pointing to pointer at it
*pt.s() = @a.s()

; now work with whatever map was chosen
*pt.s("key") = "valueA"

Debug *pt.s("key") ; should be "valueA"

; if i point my pointer at the other map
*pt.s() = @b.s()

; work with the map
*pt.s("key") = "valueB"

Debug *pt.s("key") ; should be "valueB"

; now point it back
*pt.s() = @a.s()

Debug *pt.s("key") ; should be "valueA"

I did manage to work around this by wrapping the map inside a structure, which is a rather ugly hack. That would look like this and works:

Code: Select all

; map struct
Structure ms
  Map m.s()
EndStructure

; one real map struct
Define a.ms
; another real map struct
Define b.ms
; a pointer to a map struct
Define *pt.ms

; decide which real map to work with by pointing to pointer at it
*pt = @a

; now work with whatever map was chosen
*pt\m("key") = "valueA"

Debug *pt\m("key") ; should be "valueA"

; if i point my pointer at the other map
*pt = @b

; work with the map
*pt\m("key") = "valueB"

Debug *pt\m("key") ; should be "valueB"

; now point it back
*pt = @a

Debug *pt\m("key") ; should be "valueA"
So the question is, is there a way to do this with maps themselves, ideally without resorting to manual memory management.

Thanks

Mario
User avatar
PureLeo
Enthusiast
Enthusiast
Posts: 221
Joined: Fri Jan 29, 2010 1:05 pm
Location: Brazil

Re: Pointer to a map

Post by PureLeo »

Hi!
What i'm looking for is to setup an alias to a map.
Yes, I know...

But since I can't think of a better way of doing that, and using a pointer like *p = map() just wouldn't work, I thought of copying the map to a dummy map as a workaround...
I did manage To work around This by wrapping the Map inside a Structure, which is a rather ugly hack.
Pointers in purebasic don't work just like in C/C++ , so using a structure gives you the same result, your "hack" is a good example :)
Last edited by PureLeo on Wed Apr 06, 2011 5:51 pm, edited 3 times in total.
User avatar
Demivec
Addict
Addict
Posts: 4086
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Pointer to a map

Post by Demivec »

@mariosk8s: After your additional explanation I can understand your first message. :)
mariosk8s wrote:I did manage to work around this by wrapping the map inside a structure, which is a rather ugly hack.
That method works with a pointer, you can also do something similar using procedure's and parameters. Here's a sample:

Code: Select all

Procedure assignToMap(Map pt.s(), key.s, Value.s)
  pt(key) = Value   
EndProcedure

Procedure.s valueFromMap(Map pt.s(), key.s)
  ProcedureReturn pt(key)
EndProcedure


NewMap a.s()
NewMap b.s()

assignToMap(a(), "key", "valueA")

Debug valueFromMap(a(), "key") ; should be "valueA"

assignToMap(b(), "key", "valueB")

Debug valueFromMap(b(), "key") ; should be "valueB"

Debug valueFromMap(a(), "key") ; should be "valueA"
The example was meant to be a proof of concept. I know that you would want to avoid the overhead of a procedure call for each of these simple actions, but you might find it worthwhile if you are going to be doing something more involved.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: Pointer to a map

Post by Trond »

So the question is, is there a way to do this with maps themselves, ideally without resorting to manual memory management.
In your example code you don't use manual memory management. With manual memory management your pointers point to memory allocated with AllocateMemory(), not another declared variable.

That said, if you mean without using structures, then no.
Rinzwind
Enthusiast
Enthusiast
Posts: 636
Joined: Wed Mar 11, 2009 4:06 pm
Location: NL

Re: Pointer to a map

Post by Rinzwind »

IMHO it should be possible to point to any data structure, including maps and lists. PB doesn't allow it, and so you can't use maps in OS callbacks (enum) to collect the info for example.
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Pointer to a map

Post by mk-soft »

Map are PB internally managed.
What do you mean by OS callbacks. Enum API's are something completely different.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Rinzwind
Enthusiast
Enthusiast
Posts: 636
Joined: Wed Mar 11, 2009 4:06 pm
Location: NL

Re: Pointer to a map

Post by Rinzwind »

Yup enum apis just an example. Handy to collect the result of the enumeration. Most support a custom variable. Normally one can pass a pointer through. Bit silly we need a structure pointer to handle a map in this case.
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Pointer to a map

Post by mk-soft »

Callbacks works fine with Prototypes ...

Code: Select all

;-TOP

Prototype.s MapCallback(Map sVal.s())

Procedure.s MyGetMapL(Map sVal.s())
  Protected r1.s
  ForEach sVal()
    r1 + LCase(sVal()) + ";"
  Next
  ProcedureReturn r1
EndProcedure

Procedure.s MyGetMapU(Map sVal.s())
  Protected r1.s
  ForEach sVal()
    r1 + UCase(sVal()) + ";"
  Next
  ProcedureReturn r1
EndProcedure

Global NewMap Text.s()

Procedure foo(Map sVal.s(), *Callback.MapCallback)
  Protected r1.s
  
  r1 = *Callback(sVal())
  Debug r1
  
EndProcedure

Text("1") = "One"
Text("2") = "Two"
Text("3") = "Three"

foo(Text(), @MyGetMapL())
foo(Text(), @MyGetMapU())

My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Post Reply