class Id; class Value; class ValueArray; class ValueMap; class XmlIO; class JsonIO; class Ref; struct ValueTypeRef; template void Jsonize(JsonIO& io, T& var); template void Xmlize(XmlIO& xml, T& var); const dword VOID_V = 0; const dword INT_V = 1; const dword DOUBLE_V = 2; const dword STRING_V = 3; const dword DATE_V = 4; const dword TIME_V = 5; const dword ERROR_V = 6; const dword VALUE_V = 7; const dword WSTRING_V = 8; const dword VALUEARRAY_V = 9; const dword INT64_V = 10; const dword BOOL_V = 11; const dword VALUEMAP_V = 12; const dword FLOAT_V = 13; const dword UNKNOWN_V = (dword)0xffffffff; template inline dword ValueTypeNo(const T *) { return StaticTypeNo() + 0x8000000; } template<> inline dword ValueTypeNo(const int*) { return INT_V; } template<> inline dword ValueTypeNo(const int64*) { return INT64_V; } template<> inline dword ValueTypeNo(const double*) { return DOUBLE_V; } template<> inline dword ValueTypeNo(const float*) { return FLOAT_V; } template<> inline dword ValueTypeNo(const bool*) { return BOOL_V; } template<> inline dword ValueTypeNo(const String*) { return STRING_V; } template<> inline dword ValueTypeNo(const WString*) { return WSTRING_V; } template<> inline dword ValueTypeNo(const Date*) { return DATE_V; } template<> inline dword ValueTypeNo(const Time*) { return TIME_V; } template<> inline dword ValueTypeNo(const Value*) { return VALUE_V; } template class ValueType : public B { public: static dword ValueTypeNo() { return type == UNKNOWN_V ? StaticTypeNo() + 0x8000000 : type; } friend dword ValueTypeNo(const T*) { return T::ValueTypeNo(); } bool IsNullInstance() const { return false; } void Serialize(Stream& s) { NEVER(); } void Xmlize(XmlIO& xio) { NEVER(); } void Jsonize(JsonIO& jio) { NEVER(); } hash_t GetHashValue() const { return 0; } bool operator==(const T&) const { NEVER(); return false; } String ToString() const { return typeid(T).name(); } int Compare(const T&) const { NEVER(); return 0; } int PolyCompare(const Value&) const { NEVER(); return 0; } operator ValueTypeRef(); }; template // Backward compatiblity class AssignValueTypeNo : public ValueType {}; template dword GetValueTypeNo() { return ValueTypeNo((T*)NULL); } class Value : Moveable { public: class Void { protected: Atomic refcount; public: void Retain() { AtomicInc(refcount); } void Release() { if(AtomicDec(refcount) == 0) delete this; } int GetRefCount() const { return refcount; } virtual bool IsNull() const { return true; } virtual void Serialize(Stream& s) {} virtual void Xmlize(XmlIO& xio) {} virtual void Jsonize(JsonIO& jio) {} virtual hash_t GetHashValue() const { return 0; } virtual bool IsEqual(const Void *p) { return false; } virtual bool IsPolyEqual(const Value& v) { return false; } virtual String AsString() const { return ""; } virtual int Compare(const Void *p) { return 0; } virtual int PolyCompare(const Value& p) { return 0; } Void() { refcount = 1; } virtual ~Void() {} friend class Value; }; struct Sval { bool (*IsNull)(const void *p); void (*Serialize)(void *p, Stream& s); void (*Xmlize)(void *p, XmlIO& xio); void (*Jsonize)(void *p, JsonIO& jio); hash_t (*GetHashValue)(const void *p); bool (*IsEqual)(const void *p1, const void *p2); bool (*IsPolyEqual)(const void *p, const Value& v); String (*AsString)(const void *p); int (*Compare)(const void *p1, const void *p2); int (*PolyCompare)(const void *p1, const Value& p2); }; protected: enum { STRING = 0, REF = 255, VOIDV = 3 }; static VectorMap& Typemap(); static Sval *svo[256]; static Index& NameNdx(); static Index& TypeNdx(); static void AddName(dword type, const char *name); static int GetType(const char *name); static String GetName(dword type); static void RegisterStd(); friend void ValueRegisterHelper(); String data; Void *&ptr() { ASSERT(IsRef()); return *(Void **)&data; } Void *ptr() const { ASSERT(IsRef()); return *(Void **)&data; } void SetRefType(dword type) { ASSERT(IsRef()); ((int *)&data)[2] = type; } dword GetRefType() const { ASSERT(IsRef()); return ((int *)&data)[2]; } bool IsString() const { return !data.IsSpecial(); } bool Is(byte v) const { return data.IsSpecial(v); } bool IsRef() const { return Is(REF); } void InitRef(Void *p, dword t) { data.SetSpecial(REF); ptr() = p; SetRefType(t); } void RefRelease(); void RefRetain(); void FreeRef() { if(IsRef()) RefRelease(); } void Free() { FreeRef(); data.Clear(); } void SetLarge(const Value& v); template void InitSmall(const T& init); template T& GetSmallRaw() const; template T& GetSmall() const; int GetOtherInt() const; int64 GetOtherInt64() const; double GetOtherDouble() const; float GetOtherFloat() const; bool GetOtherBool() const; Date GetOtherDate() const; Time GetOtherTime() const; String GetOtherString() const; hash_t GetOtherHashValue() const; bool IsPolyEqual(const Value& v) const; enum VSMALL { SMALL }; template Value(const T& value, VSMALL); template friend Value SvoToValue(const T& x); String GetName() const; int PolyCompare(const Value& v) const; int Compare2(const Value& v) const; Vector& UnShareArray(); const Vector& GetVA() const; #if defined(_DEBUG) && defined(COMPILER_GCC) uint32 magic[4]; void Magic() { magic[0] = 0xc436d851; magic[1] = 0x72f67c76; magic[2] = 0x3e5e10fd; magic[3] = 0xc90d370b; } void ClearMagic() { magic[0] = magic[1] = magic[2] = magic[3] = 0; } #else void Magic() {} void ClearMagic() {} #endif #ifndef DEPRECATED static void Register(dword w, Void* (*c)(), const char *name = NULL); #endif Value(Void *p) = delete; public: template static void Register(const char *name = NULL); template static void SvoRegister(const char *name = NULL); dword GetType() const; bool IsError() const { return GetType() == ERROR_V; } bool IsVoid() const { return Is(VOIDV) || IsError(); } bool IsNull() const; template bool Is() const; template const T& To() const; template const T& Get() const; operator String() const { return IsString() ? data : GetOtherString(); } operator WString() const; operator Date() const { return Is(DATE_V) ? GetSmallRaw() : GetOtherDate(); } operator Time() const { return Is(TIME_V) ? GetSmallRaw