Please add the command SwapStructure(*Source, *Destination, Structure) to swap the contents of the structures located at *Source and *Destination.
Alternatively this could also be accomplished by adding a command such as the previously requested SwapMemory(*Source, *Destination, length) discussed here.
Add SwapStructure(*Source, *Destination, Structure)
Re: Add SwapStructure(*Source, *Destination, Structure)
or: Swap Source, Destination [, Structure]
but i think CopyStructure sufficient:
but i think CopyStructure sufficient:
Code: Select all
Global *SwapStructureBuffer
Macro SwapStructure(Source, Destination, StructureName)
*SwapStructureBuffer = AllocateMemory(SizeOf(StructureName))
CopyStructure(Source, *SwapStructureBuffer, StructureName)
CopyStructure(Destination, Source, StructureName)
CopyStructure(*SwapStructureBuffer, Destination, StructureName)
ClearStructure(*SwapStructureBuffer, StructureName)
FreeMemory(*SwapStructureBuffer)
EndMacro
Structure Test
List MyList.i()
Map MyMap.s()
Float.f
EndStructure
Dim Test.Test(10)
AddElement(Test(1)\MyList())
Test(2)\MyMap("Test") = "Test"
SwapStructure(Test(1), Test(2), Test)
Debug ListSize(Test(1)\MyList())
Debug ListSize(Test(2)\MyList())
Debug Test(1)\MyMap("Test")
Debug Test(2)\MyMap("Test")
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and more ― Typeface - Sprite-based font include/module
Lizard - Script language for symbolic calculations and more ― Typeface - Sprite-based font include/module
Re: Add SwapStructure(*Source, *Destination, Structure)
I would favor this too but it may cause some confusion.STARGÅTE wrote:or: Swap Source, Destination [, Structure]
Thanks for your example code. I am not in need of a solution though. I just think a native implementation would be better. It would avoid allocating additional memory by instead exchanging a register's worth of data at a time. If that isn't ideal than I guess I'll continue with the usual 'tmp = a: a = b: b = tmp' solution.

Re: Add SwapStructure(*Source, *Destination, Structure)
Code: Select all
Procedure SwapStr( str.i, str2.i )
define pa.i = PeekI(str)
define pb.i = PeekI(str2)
PokeI( str, pb)
PokeI( str2, pa)
EndProcedure
Code: Select all
Procedure SwapStr( str.i, str2.i )
define pa.i = PeekI(str)
define pb.i = PeekI(str2)
PokeI( str, pb)
PokeI( str2, pa)
EndProcedure
str.string
str2.string
str\s = "HELLO"
str2\s = "WORLD"
debug "str ("+hex( str )+") = "+str\s
debug "str2 ("+hex( str2 )+") = "+str2\s
debug "=========="
SwapStr( str, str2 )
debug "str ("+hex( str )+") = "+str\s
debug "str2 ("+hex( str2 )+") = "+str2\s
debug "=========="
Structure TEST_STR
a.f
b.i
c.d
EndStructure
test1.TEST_STR
test2.TEST_STR
with test1
\a = 4.55
\b = 984
\c = 8.45648
EndWith
with test2
\a = 1.545
\b = 324
\c = 77.124
EndWith
SwapStr( test1, test2 )
debug "test1:"
debug test1\a
debug test1\b
debug test1\c
debug ""
debug "test2:"
debug test2\a
debug test2\b
debug test2\c
Re: Add SwapStructure(*Source, *Destination, Structure)
Really nice code xorc1zt,
but what will it do is the structure is in a linked list or map.
+1 on Demivec's request.
but what will it do is the structure is in a linked list or map.
+1 on Demivec's request.
The best preparation for tomorrow is doing your best today.
Re: Add SwapStructure(*Source, *Destination, Structure)
I understand you want this natively. But I still made this, which avoids using a temp variable:
Code: Select all
; Swap two memory areas
Procedure SwapMemory(*Source.Ascii, *Destination.Ascii, Size)
For I = 1 To SIZE
Swap *Source\a, *Destination\a
*Source + 1
*Destination + 1
Next
EndProcedure
; Swap two structured memory areas (obviously of the same structure)
Macro SwapStructure(Source, Destination, Structure_)
SwapMemory(Source, Destination, SizeOf(Structure_))
EndMacro
; Test code
Structure Test
List MyList.i()
Map MyMap.s()
Float.f
EndStructure
Dim Test.Test(10)
AddElement(Test(1)\MyList())
Test(2)\MyMap("Test") = "Test"
SwapStructure(Test(1), Test(2), Test)
Debug ListSize(Test(1)\MyList())
Debug ListSize(Test(2)\MyList())
Debug Test(1)\MyMap("Test")
Debug Test(2)\MyMap("Test")
Re: Add SwapStructure(*Source, *Destination, Structure)
you can swap structure inside a list if you grab the pointer.KJ67 wrote:Really nice code xorc1zt,
but what will it do is the structure is in a linked list or map.
+1 on Demivec's request.
example:
Code: Select all
SelectElement( testlist(), 0 )
struct1 = testlist() ; save the pointer of element 0
SelectElement( testlist(), 1 )
struct2 = testlist() ; save the pointer of element 1
SwapStr( struct1, struct2 ) ; swap the pointers
http://www.purebasic.com/documentation/ ... ments.html
Re: Add SwapStructure(*Source, *Destination, Structure)
It is interesting to see the many approaches.
I've timed this small optimization to your code sample. Your original code is faster for structures of 8 bytes or less. The optimizations are faster for all larger structure (i.e. 30% faster for the 16 - 20 byte structure you gave an example of) with the greatest increases for the largest structures:
Though I am still interested in a native solution, I thought to improve a little on your suggested code.Trond wrote:I understand you want this natively. But I still made this, which avoids using a temp variable:

I've timed this small optimization to your code sample. Your original code is faster for structures of 8 bytes or less. The optimizations are faster for all larger structure (i.e. 30% faster for the 16 - 20 byte structure you gave an example of) with the greatest increases for the largest structures:
Code: Select all
Structure bi_array
StructureUnion
b.b
i.i
EndStructureUnion
EndStructure
; Swap two memory areas
Procedure SwapMemory(*Source.bi_array, *Destination.bi_array, size)
Protected i, bytes = size % SizeOf(Integer)
For i = 1 To bytes
Swap *Source\b, *Destination\b
*Source + SizeOf(Byte)
*Destination + SizeOf(Byte)
Next
size = (size - bytes) / SizeOf(Integer)
For i = 1 To size
Swap *Source\i, *Destination\i
*Source + SizeOf(Integer)
*Destination + SizeOf(Integer)
Next
EndProcedure
; Swap two structured memory areas (obviously of the same structure)
Macro SwapStructure(source, Destination, Structure_)
SwapMemory(source, Destination, SizeOf(Structure_))
EndMacro