[ Aleksandar Ružičić @ 14.03.2008. 01:35 ] @
FreeBASIC nema Variant tip i tesko je implementirati tip koji ce odgovarati Variant tip-u VB-a sve dok se u FreeBASIC ne uvedu klase i oop, ali pomocu operator overloadinga moguce je postici slicne rezultate. Zato ovaj tip nisam nazvao Variant nego Mixed, evo implementacije: mixed.bi: Code: '' '' 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 evo primera kako se koristi: Code: #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 sto ce kao rezultat dati: Code: m = 123 m = 24.6 m = bla bla m = 5 u svakom trenutku mozete porveriti koji tip podatka se nalazi u Mixed tipu pomocu TypeId propertija Code: if m.TypeId = fbString Then ' neki kod ako je u pitanju string... |