#pragma once #include "Frames/Value.h" #include "Wrapping/Symbol.h" #include "Wrapping/WrappedAutoPtr.h" namespace Bblids { namespace Wrapping { // ----------------------------------------------------------------------------- // ***************************************************************************** // ----------------------------------------------------------------------------- ref class CValue; // ----------------------------------------------------------------------------- // ***************************************************************************** // ----------------------------------------------------------------------------- public ref class CValueType sealed : System::IComparable , System::IEquatable { private: CValueType(const Bblids::Frames::TValueType& parNativeValueType); public: property Bblids::Frames::EValueType Id { Bblids::Frames::EValueType get() { return (FWrappedValueType->Id()); } } property Bblids::Wrapping::CSymbol^ Name { Bblids::Wrapping::CSymbol^ get() { return (gcnew Bblids::Wrapping::CSymbol(FWrappedValueType->Name())); } } public: virtual int CompareTo(CValueType^ parOther); virtual bool Equals(CValueType^ parOther); bool operator ==(CValueType% parOther) { return (*FWrappedValueType == *parOther.FWrappedValueType); } bool operator !=(CValueType% parOther) { return (*FWrappedValueType != *parOther.FWrappedValueType); } bool operator <(CValueType% parOther) { return (*FWrappedValueType < *parOther.FWrappedValueType); } bool operator >=(CValueType% parOther) { return (*FWrappedValueType >= *parOther.FWrappedValueType); } private: const Bblids::Frames::TValueType* FWrappedValueType; public: static CValueType^ Integer; static CValueType^ Real; static CValueType^ Boolean; static CValueType^ String; static CValueType^ Symbol; static CValueType^ DateTime; static CValueType^ List; static CValueType^ Guid; static CValueType^ Frame; static CValueType() { Integer = gcnew CValueType(Bblids::Frames::TValueType::Integer); Real = gcnew CValueType(Bblids::Frames::TValueType::Real); Boolean = gcnew CValueType(Bblids::Frames::TValueType::Boolean); String = gcnew CValueType(Bblids::Frames::TValueType::String); Symbol = gcnew CValueType(Bblids::Frames::TValueType::Symbol); DateTime = gcnew CValueType(Bblids::Frames::TValueType::DateTime); List = gcnew CValueType(Bblids::Frames::TValueType::List); Guid = gcnew CValueType(Bblids::Frames::TValueType::Guid); Frame = gcnew CValueType(Bblids::Frames::TValueType::Frame); } static CValueType^ FromTypeId(const Bblids::Frames::EValueType parTypeId); static CValueType^ FromTypeName(CSymbol^ parTypeName); static CValueType^ FromTypeName(System::String^ parTypeName); static CValueType^ FromTypeId_Clr(const Bblids::Frames::EValueType parTypeId); }; // ----------------------------------------------------------------------------- // ***************************************************************************** // ----------------------------------------------------------------------------- ref class CFrame; // ----------------------------------------------------------------------------- public ref class CValue sealed : System::IEquatable , System::IComparable , System::IComparable , System::IConvertible , System::ICloneable , System::IDisposable { public: typedef System::Int32 CInteger; typedef System::Double CReal; typedef System::Boolean CBoolean; typedef System::String^ CString; typedef Bblids::Wrapping::CSymbol^ CSymbol; typedef System::DateTime^ CDateTime; typedef System::Collections::Generic::List^ CList; typedef System::Guid^ CGuid; typedef Bblids::Wrapping::CFrame^ CFrame; public: CValue(CInteger parValue); CValue(CReal parValue); CValue(CBoolean parValue); CValue(CString parValue); CValue(CSymbol parValue); CValue(CDateTime parValue); CValue(CList parValue); CValue(CGuid parValue); CValue(CFrame parValue); CValue(const Bblids::Frames::TValue& parWrappedValue); CValue(CValue% parOther); public: System::Object^ Get(); void Set(System::Object^ parValue); property System::Object^ Value { System::Object^ get() { return (Get()); } void set(System::Object^ parValue) { Set(parValue); } } Bblids::Frames::TValue& GetWrappedValue() { return (FWrappedValue.Get()); } public: property CValueType^ Type { CValueType^ get() { BBLIDS_ASSERT(FWrappedValue.IsNotNull); return (CValueType::FromTypeId_Clr(FWrappedValue->Type().Id())); } } property bool Initialized { bool get() { BBLIDS_ASSERT(FWrappedValue.IsNotNull); return (FWrappedValue->Initialized()); } } void Swap(CValue% parOther) { BBLIDS_ASSERT(FWrappedValue.IsNotNull); FWrappedValue->Swap(parOther.FWrappedValue.Get()); } void Swap_Ptr(CValue% parOther) { FWrappedValue.Swap(parOther.FWrappedValue); } void Clear() { BBLIDS_ASSERT(FWrappedValue.IsNotNull); FWrappedValue->Clear(); } public: void AssignFromNativeValue(const Bblids::Frames::TValue& parValue) { BBLIDS_ASSERT(FWrappedValue.IsNotNull); FWrappedValue.Get() = parValue; } void AssignFromInteger(CInteger parValue) { CValue::NativeFromInteger(FWrappedValue.Get(), parValue); } void AssignFromReal(CReal parValue) { CValue::NativeFromReal(FWrappedValue.Get(), parValue); } void AssignFromBoolean(CBoolean parValue) { CValue::NativeFromBoolean(FWrappedValue.Get(), parValue); } void AssignFromString(CString parValue) { CValue::NativeFromString(FWrappedValue.Get(), parValue); } void AssignFromSymbol(CSymbol parValue) { CValue::NativeFromSymbol(FWrappedValue.Get(), parValue); } void AssignFromDateTime(CDateTime parValue) { CValue::NativeFromDateTime(FWrappedValue.Get(), parValue); } void AssignFromList(CList parValue) { CValue::NativeFromList(FWrappedValue.Get(), parValue); } void AssignFromGuid(CGuid parValue) { CValue::NativeFromGuid(FWrappedValue.Get(), parValue); } void AssignFromFrame(CFrame parValue) { CValue::NativeFromFrame(FWrappedValue.Get(), parValue); } CValue% operator =(CInteger parValue) { AssignFromInteger(parValue); return (*this); } CValue% operator =(CReal parValue) { AssignFromReal(parValue); return (*this); } CValue% operator =(CBoolean parValue) { AssignFromBoolean(parValue); return (*this); } CValue% operator =(CString parValue) { AssignFromString(parValue); return (*this); } CValue% operator =(CSymbol parValue) { AssignFromSymbol(parValue); return (*this); } CValue% operator =(CDateTime parValue) { AssignFromDateTime(parValue); return (*this); } CValue% operator =(CList parValue) { AssignFromList(parValue); return (*this); } CValue% operator =(CGuid parValue) { AssignFromGuid(parValue); return (*this); } CValue% operator =(CFrame parValue) { AssignFromFrame(parValue); return (*this); } public: generic T As() { return (safe_cast(Get())); } CInteger ConvertToInteger() { return (CValue::NativeToInteger(FWrappedValue.Get())); } CReal ConvertToReal() { return (CValue::NativeToReal(FWrappedValue.Get())); } CBoolean ConvertToBoolean() { return (CValue::NativeToBoolean(FWrappedValue.Get())); } CString ConvertToString() { return (CValue::NativeToString(FWrappedValue.Get())); } CSymbol ConvertToSymbol() { return (CValue::NativeToSymbol(FWrappedValue.Get())); } CDateTime ConvertToDateTime() { return (CValue::NativeToDateTime(FWrappedValue.Get())); } CList ConvertToList() { return (CValue::NativeToList(FWrappedValue.Get())); } CGuid ConvertToGuid() { return (CValue::NativeToGuid(FWrappedValue.Get())); } CFrame ConvertToFrame() { return (CValue::NativeToFrame(FWrappedValue.Get())); } public: static explicit operator CInteger(CValue^ parValue) { BBLIDS_ASSERT(parValue != nullptr); return (parValue->ConvertToInteger()); } static explicit operator CReal(CValue^ parValue) { BBLIDS_ASSERT(parValue != nullptr); return (parValue->ConvertToReal()); } static explicit operator CBoolean(CValue^ parValue) { BBLIDS_ASSERT(parValue != nullptr); return (parValue->ConvertToBoolean()); } static explicit operator CString(CValue^ parValue) { BBLIDS_ASSERT(parValue != nullptr); return (parValue->ConvertToString()); } static explicit operator CSymbol(CValue^ parValue) { BBLIDS_ASSERT(parValue != nullptr); return (parValue->ConvertToSymbol()); } static explicit operator CDateTime(CValue^ parValue) { BBLIDS_ASSERT(parValue != nullptr); return (parValue->ConvertToDateTime()); } static explicit operator CList(CValue^ parValue) { BBLIDS_ASSERT(parValue != nullptr); return (parValue->ConvertToList()); } static explicit operator CGuid(CValue^ parValue) { BBLIDS_ASSERT(parValue != nullptr); return (parValue->ConvertToGuid()); } static explicit operator CFrame(CValue^ parValue) { BBLIDS_ASSERT(parValue != nullptr); return (parValue->ConvertToFrame()); } public: virtual System::String^ ToString() override { return (Get()->ToString()); } virtual System::TypeCode GetTypeCode() { return (System::Type::GetTypeCode(Get()->GetType())); } virtual System::Boolean ToBoolean(System::IFormatProvider^) = System::IConvertible::ToBoolean { return (ConvertToBoolean()); } virtual System::Byte ToByte(System::IFormatProvider^) = System::IConvertible::ToByte { ASSERT_UNREACHED; return (0); } virtual System::Char ToChar(System::IFormatProvider^) = System::IConvertible::ToChar { ASSERT_UNREACHED; return (0); } virtual System::DateTime ToDateTime(System::IFormatProvider^) = System::IConvertible::ToDateTime { return (*ConvertToDateTime()); } virtual System::Decimal ToDecimal(System::IFormatProvider^) = System::IConvertible::ToDecimal { ASSERT_UNREACHED; return (0); } virtual System::Double ToDouble(System::IFormatProvider^) = System::IConvertible::ToDouble { return (ConvertToReal()); } virtual System::Int16 ToInt16(System::IFormatProvider^) = System::IConvertible::ToInt16 { return (System::Convert::ToInt16(ConvertToInteger())); } virtual System::Int32 ToInt32(System::IFormatProvider^) = System::IConvertible::ToInt32 { return (System::Convert::ToInt32(ConvertToInteger())); } virtual System::Int64 ToInt64(System::IFormatProvider^) = System::IConvertible::ToInt64 { return (System::Convert::ToInt64(ConvertToInteger())); } virtual System::SByte ToSByte(System::IFormatProvider^) = System::IConvertible::ToSByte { ASSERT_UNREACHED; return (0); } virtual System::Single ToSingle(System::IFormatProvider^) = System::IConvertible::ToSingle { return (System::Convert::ToSingle(ConvertToReal())); } virtual System::String^ ToString(System::IFormatProvider^) = System::IConvertible::ToString { return (ConvertToString()); } virtual System::Object^ ToType(System::Type^ parConversionType, System::IFormatProvider^) = System::IConvertible::ToType { BBLIDS_ASSERT(parConversionType != nullptr); return (System::Convert::ChangeType(Get(), parConversionType)); } virtual System::UInt16 ToUInt16(System::IFormatProvider^) = System::IConvertible::ToUInt16 { return (System::Convert::ToUInt16(ConvertToInteger())); } virtual System::UInt32 ToUInt32(System::IFormatProvider^) = System::IConvertible::ToUInt32 { return (System::Convert::ToUInt32(ConvertToInteger())); } virtual System::UInt64 ToUInt64(System::IFormatProvider^) = System::IConvertible::ToUInt64 { return (System::Convert::ToUInt64(ConvertToInteger())); } public: virtual int CompareTo(System::Object^ parOther) { BBLIDS_ASSERT(parOther != nullptr); return (safe_cast(parOther)->CompareTo(Get())); } virtual int CompareTo(CValue^ parOther) { BBLIDS_ASSERT(parOther != nullptr); return ((FWrappedValue.Get() < parOther->FWrappedValue.Get()) ? -1 : ((FWrappedValue.Get() == parOther->FWrappedValue.Get()) ? 0 : 1)); } virtual bool Equals(CValue^ parOther) { BBLIDS_ASSERT(parOther != nullptr); return (parOther->FWrappedValue.Get() == FWrappedValue.Get()); } virtual System::Object^ Clone() { return (gcnew CValue(*this)); } bool operator ==(CValue% parOther) { return (FWrappedValue.Get() == parOther.FWrappedValue.Get()); } bool operator !=(CValue% parOther) { return (FWrappedValue.Get() != parOther.FWrappedValue.Get()); } bool operator <(CValue% parOther) { return (FWrappedValue.Get() < parOther.FWrappedValue.Get()); } bool operator >=(CValue% parOther) { return (FWrappedValue.Get() >= parOther.FWrappedValue.Get()); } private: /** * TODO: the fucking interop does not allow to mix native and managed types * by other mean that a pointer, which enforce to allocate a new * Bblids::Frames::TValue for each affectation. * It will be a good optimisation to batch those allocations by using memory * buckets instead of one shot calls to new(). */ CWrappedAutoPtr FWrappedValue; public: static void NativeFromInteger(Bblids::Frames::TValue& outValue, CInteger parValue); static void NativeFromReal(Bblids::Frames::TValue& outValue, CReal parValue); static void NativeFromBoolean(Bblids::Frames::TValue& outValue, CBoolean parValue); static void NativeFromString(Bblids::Frames::TValue& outValue, CString parValue); static void NativeFromSymbol(Bblids::Frames::TValue& outValue, CSymbol parValue); static void NativeFromDateTime(Bblids::Frames::TValue& outValue, CDateTime parValue); static void NativeFromList(Bblids::Frames::TValue& outValue, CList parValue); static void NativeFromGuid(Bblids::Frames::TValue& outValue, CGuid parValue); static void NativeFromFrame(Bblids::Frames::TValue& outValue, CFrame parValue); static CInteger NativeToInteger(const Bblids::Frames::TValue& parValue); static CReal NativeToReal(const Bblids::Frames::TValue& parValue); static CBoolean NativeToBoolean(const Bblids::Frames::TValue& parValue); static CString NativeToString(const Bblids::Frames::TValue& parValue); static CSymbol NativeToSymbol(const Bblids::Frames::TValue& parValue); static CDateTime NativeToDateTime(const Bblids::Frames::TValue& parValue); static CList NativeToList(const Bblids::Frames::TValue& parValue); static CGuid NativeToGuid(const Bblids::Frames::TValue& parValue); static CFrame NativeToFrame(const Bblids::Frames::TValue& parValue); }; // ----------------------------------------------------------------------------- // ***************************************************************************** // ----------------------------------------------------------------------------- }}