Mixed datatype

Post your FreeBASIC tips and tricks here. Please don’t post your code without including an explanation.
krcko
Posts: 163
Joined: Jul 30, 2006 0:34
Location: Serbia
Contact:

Mixed datatype

Postby krcko » Mar 14, 2008 2:45

i know that this has already been done many times in many ways, but i'm promoting (can't find better word, my enginsh is very bad) FreeBASIC to people visiting VB & ASP board in EliteSecurity Forum (board is on serbian/croatian/bosnian language) and i've just wrote my implementation of Mixed datatype (i.e. Variant in VB)

so here it is:

mixed.bi

Code: Select all

''
''    Mixed datatype definition
''
''    by Aleksandar Ruzicic
''

#Ifndef __MIXED_TYPE__
#Define __MIXED_TYPE__

   #Macro MixedDeclareOperators(_TYPE_)
      Declare Operator Cast As _TYPE_
      Declare Operator Let(value As _TYPE_)
      Declare Operator +=(value As _TYPE_)
      Declare Operator -=(value As _TYPE_)
      Declare Operator *=(value As _TYPE_)
      Declare Operator /=(value As _TYPE_)
      Declare Operator \=(value As _TYPE_)
      Declare Operator ^=(value As _TYPE_)
      Declare Operator Mod=(value As _TYPE_)
      Declare Operator Shl=(value As _TYPE_)
      Declare Operator Shr=(value As _TYPE_)
      Declare Operator And=(value As _TYPE_)
      Declare Operator Or=(value As _TYPE_)
      Declare Operator Xor=(value As _TYPE_)
      Declare Operator Imp=(value As _TYPE_)
      Declare Operator Eqv=(value As _TYPE_)
   #EndMacro

   #Macro MixedImplementAssignmentOperators(_TYPE_)
      Operator Mixed.+=(value As _TYPE_)
         This = Cast(_TYPE_, This) + value
      End Operator
      Operator Mixed.-=(value As _TYPE_)
         This = Cast(_TYPE_, This) - value
      End Operator
      Operator Mixed.*=(value As _TYPE_)
         This = Cast(_TYPE_, This) * value
      End Operator
      Operator Mixed./=(value As _TYPE_)
         This = Cast(_TYPE_, This) / value
      End Operator
      Operator Mixed.\=(value As _TYPE_)
         This = Cast(_TYPE_, This) \ value
      End Operator
      Operator Mixed.^=(value As _TYPE_)
         This = Cast(_TYPE_, This) ^ value
      End Operator
      Operator Mixed.Mod=(value As _TYPE_)
         This = Cast(_TYPE_, This) Mod value
      End Operator
      Operator Mixed.Shl=(value As _TYPE_)
         This = Cast(_TYPE_, This) Shl value
      End Operator
      Operator Mixed.Shr=(value As _TYPE_)
         This = Cast(_TYPE_, This) Shr value
      End Operator
      Operator Mixed.And=(value As _TYPE_)
         This = Cast(_TYPE_, This) And value
      End Operator
      Operator Mixed.Or=(value As _TYPE_)
         This = Cast(_TYPE_, This) Or value
      End Operator
      Operator Mixed.Xor=(value As _TYPE_)
         This = Cast(_TYPE_, This) Xor value
      End Operator
      Operator Mixed.Imp=(value As _TYPE_)
         This = Cast(_TYPE_, This) Imp value
      End Operator
      Operator Mixed.Eqv=(value As _TYPE_)
         This = Cast(_TYPE_, This) Eqv value
      End Operator
   #EndMacro

   #Macro MixedImplementBinaryOperator(_OP_)
   Operator _OP_(ByRef lhs As Mixed, ByRef rhs As Mixed) As Mixed
      If lhs.TypeId < fbInteger Or rhs.TypeId < fbInteger Then
         Return CDbl(lhs) _OP_ CDbl(rhs)
      Else
         Return CInt(lhs) _OP_ CInt(rhs)
      EndIf
   End Operator
   #EndMacro


   Enum MixedType
      fbEmpty
      fbString
      fbDouble
      fbSingle
      fbLongInt
      fbLong
      fbInteger
      fbShort
      fbByte
      fbAnyPointer
   End Enum

   Type Mixed

      Public:

         Declare Destructor

         Declare Property TypeId As MixedType

         Declare Operator Cast As String
         Declare Operator Let(value As String)
         Declare Operator +=(value As String)
         Declare Operator &=(value As String)

         MixedDeclareOperators(Double)
         MixedDeclareOperators(Single)
         MixedDeclareOperators(LongInt)
         MixedDeclareOperators(Long)
         MixedDeclareOperators(Integer)
         MixedDeclareOperators(Short)
         MixedDeclareOperators(Byte)

         Declare Operator Cast As Any Pointer
         Declare Operator Let(value As Any Pointer)

      Private:

         StoredType   As MixedType   = fbEmpty
         StoredData   As Any Pointer   = 0

   End Type

   Destructor Mixed
      If This.StoredType <> fbEmpty And this.StoredType <> fbAnyPointer Then
         DeAllocate This.StoredData
      EndIf
   End Destructor

   Property Mixed.TypeId As MixedType
      Return This.StoredType
   End Property

   Operator Mixed.Cast As String
      Select Case This.StoredType
         Case fbEmpty: Return ""
         Case fbString: Return *Cast(String Pointer, This.StoredData)
         Case fbDouble: Return Str(*Cast(Double Pointer, This.StoredData))
         Case fbSingle: Return Str(*Cast(Single Pointer, This.StoredData))
         Case fbLongInt: Return Str(*Cast(LongInt Pointer, This.StoredData))
         Case fbLong: Return Str(*Cast(Long Pointer, This.StoredData))
         Case fbInteger: Return Str(*Cast(Integer Pointer, This.StoredData))
         Case fbShort: Return Str(*Cast(Short Pointer, This.StoredData))
         Case fbByte: Return Str(*Cast(Byte Pointer, This.StoredData))
         Case fbAnyPointer: Return *Cast(String Pointer, This.StoredData)
      End Select
   End Operator
   Operator Mixed.Let(Value As String)
      If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
         DeAllocate This.StoredData
      EndIf
      This.StoredType = fbString
      This.StoredData = Allocate(SizeOf(String))
      *Cast(String Pointer, This.StoredData) = value
   End Operator
   Operator Mixed.+=(value As String)
      This = Cast(String, This) & value
   End Operator
   Operator Mixed.&=(value As String)
      This = Cast(String, This) & value
   End Operator

   Operator Mixed.Cast As Double
      Select Case This.StoredType
         Case fbEmpty: Return 0
         Case fbString: Return CDbl(*Cast(String Pointer, This.StoredData))
         Case fbDouble: Return *Cast(Double Pointer, This.StoredData)
         Case fbSingle: Return CDbl(*Cast(Single Pointer, This.StoredData))
         Case fbLongInt: Return CDbl(*Cast(LongInt Pointer, This.StoredData))
         Case fbLong: Return CDbl(*Cast(Long Pointer, This.StoredData))
         Case fbInteger: Return CDbl(*Cast(Integer Pointer, This.StoredData))
         Case fbShort: Return CDbl(*Cast(Short Pointer, This.StoredData))
         Case fbByte: Return CDbl(*Cast(Byte Pointer, This.StoredData))
         Case fbAnyPointer: Return *Cast(Double Pointer, This.StoredData)
      End Select
   End Operator
   Operator Mixed.Let(Value As Double)
      If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
         DeAllocate This.StoredData
      EndIf
      This.StoredType = fbDouble
      This.StoredData = Allocate(SizeOf(Double))
      *Cast(Double Pointer, This.StoredData) = value
   End Operator
   MixedImplementAssignmentOperators(Double)

   Operator Mixed.Cast As Single
      Select Case This.StoredType
         Case fbEmpty: Return 0
         Case fbString: Return CSng(*Cast(String Pointer, This.StoredData))
         Case fbDouble: Return CSng(*Cast(Double Pointer, This.StoredData))
         Case fbSingle: Return *Cast(Single Pointer, This.StoredData)
         Case fbLongInt: Return CSng(*Cast(LongInt Pointer, This.StoredData))
         Case fbLong: Return CSng(*Cast(Long Pointer, This.StoredData))
         Case fbInteger: Return CSng(*Cast(Integer Pointer, This.StoredData))
         Case fbShort: Return CSng(*Cast(Short Pointer, This.StoredData))
         Case fbByte: Return CSng(*Cast(Byte Pointer, This.StoredData))
         Case fbAnyPointer: Return *Cast(Single Pointer, This.StoredData)
      End Select
   End Operator
   Operator Mixed.Let(Value As Single)
      If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
         DeAllocate This.StoredData
      EndIf
      This.StoredType = fbSingle
      This.StoredData = Allocate(SizeOf(Single))
      *Cast(Single Pointer, This.StoredData) = value
   End Operator
   MixedImplementAssignmentOperators(Single)

   Operator Mixed.Cast As LongInt
      Select Case This.StoredType
         Case fbEmpty: Return 0
         Case fbString: Return CLngInt(*Cast(String Pointer, This.StoredData))
         Case fbDouble: Return CLngInt(*Cast(Double Pointer, This.StoredData))
         Case fbSingle: Return CLngInt(*Cast(Single Pointer, This.StoredData))
         Case fbLongInt: Return *Cast(LongInt Pointer, This.StoredData)
         Case fbLong: Return CLngInt(*Cast(Long Pointer, This.StoredData))
         Case fbInteger: Return CLngInt(*Cast(Integer Pointer, This.StoredData))
         Case fbShort: Return CLngInt(*Cast(Short Pointer, This.StoredData))
         Case fbByte: Return CLngInt(*Cast(Byte Pointer, This.StoredData))
         Case fbAnyPointer: Return *Cast(LongInt Pointer, This.StoredData)
      End Select
   End Operator
   Operator Mixed.Let(Value As LongInt)
      If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
         DeAllocate This.StoredData
      EndIf
      This.StoredType = fbLongInt
      This.StoredData = Allocate(SizeOf(LongInt))
      *Cast(LongInt Pointer, This.StoredData) = value
   End Operator
   MixedImplementAssignmentOperators(LongInt)

   Operator Mixed.Cast As Long
      Select Case This.StoredType
         Case fbEmpty: Return 0
         Case fbString: Return CLng(*Cast(String Pointer, This.StoredData))
         Case fbDouble: Return CLng(*Cast(Double Pointer, This.StoredData))
         Case fbSingle: Return CLng(*Cast(Single Pointer, This.StoredData))
         Case fbLongInt: Return CLng(*Cast(LongInt Pointer, This.StoredData))
         Case fbLong: Return *Cast(Long Pointer, This.StoredData)
         Case fbInteger: Return CLng(*Cast(Integer Pointer, This.StoredData))
         Case fbShort: Return CLng(*Cast(Short Pointer, This.StoredData))
         Case fbByte: Return CLng(*Cast(Byte Pointer, This.StoredData))
         Case fbAnyPointer: Return *Cast(Long Pointer, This.StoredData)
      End Select
   End Operator
   Operator Mixed.Let(Value As Long)
      If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
         DeAllocate This.StoredData
      EndIf
      This.StoredType = fbLong
      This.StoredData = Allocate(SizeOf(Long))
      *Cast(Long Pointer, This.StoredData) = value
   End Operator
   MixedImplementAssignmentOperators(Long)

   Operator Mixed.Cast As Integer
      Select Case This.StoredType
         Case fbEmpty: Return 0
         Case fbString: Return CInt(*Cast(String Pointer, This.StoredData))
         Case fbDouble: Return CInt(*Cast(Double Pointer, This.StoredData))
         Case fbSingle: Return CInt(*Cast(Single Pointer, This.StoredData))
         Case fbLongInt: Return CInt(*Cast(LongInt Pointer, This.StoredData))
         Case fbLong: Return CInt(*Cast(Long Pointer, This.StoredData))
         Case fbInteger: Return *Cast(Integer Pointer, This.StoredData)
         Case fbShort: Return CInt(*Cast(Short Pointer, This.StoredData))
         Case fbByte: Return CInt(*Cast(Byte Pointer, This.StoredData))
         Case fbAnyPointer: Return *Cast(Integer Pointer, This.StoredData)
      End Select
   End Operator
   Operator Mixed.Let(Value As Integer)
      If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
         DeAllocate This.StoredData
      EndIf
      This.StoredType = fbInteger
      This.StoredData = Allocate(SizeOf(Integer))
      *Cast(Integer Pointer, This.StoredData) = value
   End Operator
   MixedImplementAssignmentOperators(Integer)

   Operator Mixed.Cast As Short
      Select Case This.StoredType
         Case fbEmpty: Return 0
         Case fbString: Return CShort(*Cast(String Pointer, This.StoredData))
         Case fbDouble: Return CShort(*Cast(Double Pointer, This.StoredData))
         Case fbSingle: Return CShort(*Cast(Single Pointer, This.StoredData))
         Case fbLongInt: Return CShort(*Cast(LongInt Pointer, This.StoredData))
         Case fbLong: Return CShort(*Cast(Long Pointer, This.StoredData))
         Case fbInteger: Return CShort(*Cast(Integer Pointer, This.StoredData))
         Case fbShort: Return *Cast(Short Pointer, This.StoredData)
         Case fbByte: Return CShort(*Cast(Byte Pointer, This.StoredData))
         Case fbAnyPointer: Return *Cast(Short Pointer, This.StoredData)
      End Select
   End Operator
   Operator Mixed.Let(Value As Short)
      If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
         DeAllocate This.StoredData
      EndIf
      This.StoredType = fbShort
      This.StoredData = Allocate(SizeOf(Short))
      *Cast(Short Pointer, This.StoredData) = value
   End Operator
   MixedImplementAssignmentOperators(Short)

   Operator Mixed.Cast As Byte
      Select Case This.StoredType
         Case fbEmpty: Return 0
         Case fbString: Return CByte(*Cast(String Pointer, This.StoredData))
         Case fbDouble: Return CByte(*Cast(Double Pointer, This.StoredData))
         Case fbSingle: Return CByte(*Cast(Single Pointer, This.StoredData))
         Case fbLongInt: Return CByte(*Cast(LongInt Pointer, This.StoredData))
         Case fbLong: Return CByte(*Cast(Long Pointer, This.StoredData))
         Case fbInteger: Return CByte(*Cast(Integer Pointer, This.StoredData))
         Case fbShort: Return CByte(*Cast(Short Pointer, This.StoredData))
         Case fbByte: Return *Cast(Byte Pointer, This.StoredData)
         Case fbAnyPointer: Return *Cast(Byte Pointer, This.StoredData)
      End Select
   End Operator
   Operator Mixed.Let(Value As Byte)
      If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
         DeAllocate This.StoredData
      EndIf
      This.StoredType = fbByte
      This.StoredData = Allocate(SizeOf(Byte))
      *Cast(Byte Pointer, This.StoredData) = value
   End Operator
   MixedImplementAssignmentOperators(Byte)

   Operator Mixed.Cast As Any Pointer
      Select Case This.StoredType
         Case fbEmpty: Return 0
         Case fbString: Return Cast(String Pointer, This.StoredData)
         Case fbDouble: Return Cast(Double Pointer, This.StoredData)
         Case fbSingle: Return Cast(Single Pointer, This.StoredData)
         Case fbLongInt: Return Cast(LongInt Pointer, This.StoredData)
         Case fbLong: Return Cast(Long Pointer, This.StoredData)
         Case fbInteger: Return Cast(Integer Pointer, This.StoredData)
         Case fbShort: Return Cast(Short Pointer, This.StoredData)
         Case fbByte: Return Cast(Byte Pointer, This.StoredData)
         Case fbAnyPointer: Return This.StoredData
      End Select
   End Operator
   Operator Mixed.Let(Value As Any Pointer)
      If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
         DeAllocate This.StoredData
      EndIf
      This.StoredType = fbAnyPointer
      This.StoredData = Allocate(SizeOf(Any Pointer))
      This.StoredData = value
   End Operator

   Operator -(ByRef rhs As Mixed) As Mixed
      Select Case rhs.TypeId
         Case fbEmpty:    Return 0
         Case Else:       Return -Cast(Double, rhs)
      End Select
   End Operator

   Operator &(ByRef lhs As Mixed, ByRef rhs As Mixed) As Mixed
      Return Str(lhs) & Str(rhs)
   End Operator

   MixedImplementBinaryOperator(+)
   MixedImplementBinaryOperator(-)
   MixedImplementBinaryOperator(*)
   MixedImplementBinaryOperator(/)
   MixedImplementBinaryOperator(\)
   MixedImplementBinaryOperator(Mod)
   MixedImplementBinaryOperator(Shl)
   MixedImplementBinaryOperator(Shr)
   MixedImplementBinaryOperator(And)
   MixedImplementBinaryOperator(Or)
   MixedImplementBinaryOperator(Xor)
   MixedImplementBinaryOperator(Imp)
   MixedImplementBinaryOperator(Eqv)
   MixedImplementBinaryOperator(^)
   MixedImplementBinaryOperator(=)
   MixedImplementBinaryOperator(<>)
   MixedImplementBinaryOperator(<)
   MixedImplementBinaryOperator(>)
   MixedImplementBinaryOperator(<=)
   MixedImplementBinaryOperator(>=)

#EndIf

and sample of using it:

Code: Select all

#include "mixed.bi"

Dim m As Mixed

m = 123   ' Integer

Print "m = "; m

m /= 5    ' Single

Print "m = "; m

m = "bla bla"  ' String

Print "m = "; m

m = m + 5 ' Integer

Print "m = "; m

Sleep

and it will result in following output:

Code: Select all

m = 123
m = 24.6
m = bla bla
m = 5

and there is also TypeId property to determine which type is stored inside variable:

Code: Select all

If m.TypeId = fbString Then
   ' it has String data stored in it, do something with strings here...
End If
cha0s
Site Admin
Posts: 5317
Joined: May 27, 2005 6:42
Location: Illinois
Contact:

Postby cha0s » Mar 14, 2008 8:40

Check out FreeBASIC/examples/Windows/variants
krcko
Posts: 163
Joined: Jul 30, 2006 0:34
Location: Serbia
Contact:

Postby krcko » Mar 14, 2008 15:03

nice! i haven't seen this before :)

but does it supports storing Any Pointer? i needed type to be able to store strings, integers and any ptrs (dynamic arrays actualy) so thats why i've made this Mixed type...

thanks for this variantlib, i'll check it out better, maybe i can add any ptr to it...
duke4e
Posts: 717
Joined: Dec 04, 2005 0:16
Location: Varazdin, Croatia, Europe
Contact:

Postby duke4e » Mar 14, 2008 15:07

[croatian]
Jos jedan balkanac na FB forumu.
Pozdrav!
[/croatian]
krcko
Posts: 163
Joined: Jul 30, 2006 0:34
Location: Serbia
Contact:

Postby krcko » Mar 14, 2008 16:42

[serbian]
Pozdrav duke!
drago mi je sto vidim da ima nas balkanaca ovde, mada nisam ja od skora ovde, davno sam se registrovao, ali dugo nisam radio nista u freebasic-u pa me nije bilo ni na forumu...
ne znam da li si cuo za EliteSecurity forume, ali ako hoces dobrodosao si da se prikljucis radu foruma, ja sam moderator na VB & ASP i sa par ljudi sa foruma sam pokrenuo inicijativu da napisemo sto vise freebasic-related postova u tom forumu kako bi admini otvorili FreeBASIC podforum

poz jos jednom!
[/serbian]
Lachie Dazdarian
Posts: 2338
Joined: May 31, 2005 9:59
Location: Croatia
Contact:

Postby Lachie Dazdarian » Mar 14, 2008 23:06

Od Vardara pa do Triglava

Od Đerdapa pa do Jadrana

Kao niska sjajnog đerdana

Svijetlim suncem obasjana

Ponosita, sred Balkana,

Jugoslavijo

Jugoslavijo
krcko
Posts: 163
Joined: Jul 30, 2006 0:34
Location: Serbia
Contact:

Postby krcko » Mar 15, 2008 0:06

jos jedan balkanac! pa ovo je super! :)

drago mi ja da vidim da nas ima ovoliko ovde, jebiga, da ne bi politike jos bi bili u istoj drzavi, al dobro bar nam je jezik zajednicki.

jos jednom veliki pozdrav svima!
Lachie Dazdarian
Posts: 2338
Joined: May 31, 2005 9:59
Location: Croatia
Contact:

Postby Lachie Dazdarian » Mar 15, 2008 0:20

Hej! Ja nisam balkanac! Ja sam jebeni laponac! Barem tako kaže Primorac. :P


Ma zajebavam se.

Ak' imaš vremena (a moraš imat) provjeri neke od mojih igričica na mom situ (website link pod mojim postom).
Merick
Posts: 1038
Joined: May 28, 2007 1:52

Postby Merick » Mar 15, 2008 1:05

Iway avehay onay ideaway atwhay ouyay uysgay areway ayingsay
krcko
Posts: 163
Joined: Jul 30, 2006 0:34
Location: Serbia
Contact:

Postby krcko » Mar 15, 2008 4:41

Lachie igre su ti odlicne i mnooogo zarazne :)

mnogo mi se svidja screen transition efekat u StarCage-u, nadam se da se neces ljututi ako "pozajmim" to od tebe za igru na kojoj trenutno radim? :D
duke4e
Posts: 717
Joined: Dec 04, 2005 0:16
Location: Varazdin, Croatia, Europe
Contact:

Postby duke4e » Mar 15, 2008 11:35

Wow, Balkan 0wnz FB forums!

Rijetko se dogadja da se ovak raspistoljimo na domacem jeziku.
Jos bude pala neka kolaboracija za super-ultra-mega-cool-odlicnu igru.

Btw. pretpostavljam da te bude u jednom od iducih postova Lachie pozval na svoj forum ;)
krcko
Posts: 163
Joined: Jul 30, 2006 0:34
Location: Serbia
Contact:

Postby krcko » Mar 15, 2008 23:48

necu da cekam da me pozove, vec sam se registrovao :D
Lachie Dazdarian
Posts: 2338
Joined: May 31, 2005 9:59
Location: Croatia
Contact:

Postby Lachie Dazdarian » Mar 16, 2008 0:26

Ma nemoj pričat gluposti. Ja nikad ne pozivam ljude u svoj forum. :P

krcko, hvala na komplimentima. Slobodno posudi bilo koju ideju iz mojih igara i ako se radi o nečem konkretnijem, spomeni me u creditsu.

Nadam se da ću uskoro naći vremena i volje dovršiti Barren (bivši LONG). Trenutno sam u određenoj....hmm, mentalnoj blokadi. Stara priča...stvarni život uzima svoj danak. Hmm...da bar idem negdje.

Da.

Bolje da prestanem pisat. :P
cha0s
Site Admin
Posts: 5317
Joined: May 27, 2005 6:42
Location: Illinois
Contact:

Postby cha0s » Mar 16, 2008 1:46

You guys should speak in english on this forum. It's just the easiest language for all to participate in. If you want to chat using your native languages, there are plenty of other mediums to do that...
Lachie Dazdarian
Posts: 2338
Joined: May 31, 2005 9:59
Location: Croatia
Contact:

Postby Lachie Dazdarian » Mar 16, 2008 1:58

Rascist!

Return to “Tips and Tricks”

Who is online

Users browsing this forum: No registered users and 5 guests