-/////////////////////////////////////////////////////////////////////////////\r
-// Name: src/common/any.cpp\r
-// Purpose: wxAny class, container for any type\r
-// Author: Jaakko Salli\r
-// Modified by:\r
-// Created: 07/05/2009\r
-// RCS-ID: $Id$\r
-// Copyright: (c) wxWidgets team\r
-// Licence: wxWindows licence\r
-/////////////////////////////////////////////////////////////////////////////\r
-\r
-// For compilers that support precompilation, includes "wx/wx.h".\r
-#include "wx/wxprec.h"\r
-\r
-#ifdef __BORLANDC__\r
- #pragma hdrstop\r
-#endif\r
-\r
-#include "wx/any.h"\r
-\r
-#if wxUSE_ANY\r
-\r
-#ifndef WX_PRECOMP\r
- #include "wx/math.h"\r
- #include "wx/crt.h"\r
-#endif\r
-\r
-#include "wx/vector.h"\r
-#include "wx/module.h"\r
-\r
-using namespace wxPrivate;\r
-\r
-//-------------------------------------------------------------------------\r
-// wxAnyValueTypeGlobals\r
-//-------------------------------------------------------------------------\r
-\r
-//\r
-// Helper class to manage wxAnyValueType instances and other\r
-// related global variables.\r
-//\r
-// NB: We really need to have wxAnyValueType instances allocated\r
-// in heap. They are stored as static template member variables,\r
-// and with them we just can't be too careful (eg. not allocating\r
-// them in heap broke the type identification in GCC).\r
-//\r
-class wxAnyValueTypeGlobals\r
-{\r
-public:\r
- wxAnyValueTypeGlobals()\r
- {\r
- }\r
- ~wxAnyValueTypeGlobals()\r
- {\r
- for ( size_t i=0; i<m_valueTypes.size(); i++ )\r
- delete m_valueTypes[i];\r
- }\r
-\r
- void RegisterValueType(wxAnyValueType* valueType)\r
- {\r
- m_valueTypes.push_back(valueType);\r
- }\r
-\r
-private:\r
- wxVector<wxAnyValueType*> m_valueTypes;\r
-};\r
-\r
-static wxAnyValueTypeGlobals* g_wxAnyValueTypeGlobals = NULL;\r
-\r
-//\r
-// This class is to make sure that wxAnyValueType instances\r
-// etc. get freed correctly. We must use a separate wxAnyValueTypeGlobals\r
-// because wxModule itself is instantiated too late.\r
-//\r
-class wxAnyValueTypeGlobalsManager : public wxModule\r
-{\r
- DECLARE_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager)\r
-public:\r
- wxAnyValueTypeGlobalsManager() : wxModule() { }\r
- virtual ~wxAnyValueTypeGlobalsManager() { }\r
-\r
- virtual bool OnInit()\r
- {\r
- return true;\r
- }\r
- virtual void OnExit()\r
- {\r
- delete g_wxAnyValueTypeGlobals;\r
- g_wxAnyValueTypeGlobals = NULL;\r
- }\r
-private:\r
-};\r
-\r
-IMPLEMENT_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager, wxModule)\r
-\r
-\r
-//-------------------------------------------------------------------------\r
-// wxAnyValueType\r
-//-------------------------------------------------------------------------\r
-\r
-wxAnyValueType::wxAnyValueType()\r
-{\r
- if ( !g_wxAnyValueTypeGlobals )\r
- g_wxAnyValueTypeGlobals = new wxAnyValueTypeGlobals();\r
-\r
- g_wxAnyValueTypeGlobals->RegisterValueType(this);\r
-}\r
-\r
-//-------------------------------------------------------------------------\r
-// wxAny\r
-//-------------------------------------------------------------------------\r
-\r
-void wxAny::AssignAny(const wxAny &any)\r
-{\r
- if ( !any.m_type->IsSameType(m_type) )\r
- {\r
- m_type->DeleteValue(m_buffer);\r
- m_type = any.m_type;\r
- }\r
- m_type->CopyBuffer(any.m_buffer, m_buffer);\r
-}\r
-\r
-//-------------------------------------------------------------------------\r
-// Dynamic conversion member functions\r
-//-------------------------------------------------------------------------\r
-\r
-//\r
-// Define integer minimum and maximum as helpers\r
-#ifdef wxLongLong_t\r
-const wxAnyBaseIntType UseIntMin = wxINT64_MIN;\r
-const wxAnyBaseUintType UseIntMax = wxINT64_MAX;\r
-const wxAnyBaseUintType UseUintMax = wxUINT64_MAX;\r
-#else\r
-const wxAnyBaseIntType UseIntMin = LONG_MIN;\r
-const wxAnyBaseUintType UseUintMax = ULONG_MAX;\r
-const wxAnyBaseUintType UseIntMax = LONG_MAX;\r
-#endif\r
-\r
-const double UseIntMinF = static_cast<double>(UseIntMin);\r
-#ifndef __VISUALC6__\r
-const double UseIntMaxF = static_cast<double>(UseIntMax);\r
-const double UseUintMaxF = static_cast<double>(UseUintMax);\r
-#else\r
-// VC6 doesn't implement conversion from unsigned __int64 to double\r
-const wxAnyBaseIntType UseIntMax0 = static_cast<wxAnyBaseIntType>(UseIntMax);\r
-const wxAnyBaseIntType UseUintMax0 = static_cast<wxAnyBaseIntType>(UseUintMax);\r
-const double UseIntMaxF = static_cast<double>(UseIntMax0);\r
-const double UseUintMaxF = static_cast<double>(UseUintMax0);\r
-#endif\r
-\r
-\r
-bool wxAnyValueTypeImplInt::ConvertValue(const wxAnyValueBuffer& src,\r
- wxAnyValueType* dstType,\r
- wxAnyValueBuffer& dst) const\r
-{\r
- wxAnyBaseIntType value = GetValue(src);\r
- if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )\r
- {\r
-#ifdef wxLongLong_t\r
- wxLongLong ll(value);\r
- wxString s = ll.ToString();\r
-#else\r
- wxString s = wxString::Format(wxS("%ld"), (long)value);\r
-#endif\r
- wxAnyValueTypeImpl<wxString>::SetValue(s, dst);\r
- }\r
- else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )\r
- {\r
- if ( value < 0 )\r
- return false;\r
- wxAnyBaseUintType ul = (wxAnyBaseUintType) value;\r
- wxAnyValueTypeImplUint::SetValue(ul, dst);\r
- }\r
- else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) )\r
- {\r
- double value2 = static_cast<double>(value);\r
- wxAnyValueTypeImplDouble::SetValue(value2, dst);\r
- }\r
- else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) )\r
- {\r
- bool value2 = value ? true : false;\r
- wxAnyValueTypeImpl<bool>::SetValue(value2, dst);\r
- }\r
- else\r
- return false;\r
-\r
- return true;\r
-}\r
-\r
-bool wxAnyValueTypeImplUint::ConvertValue(const wxAnyValueBuffer& src,\r
- wxAnyValueType* dstType,\r
- wxAnyValueBuffer& dst) const\r
-{\r
- wxAnyBaseUintType value = GetValue(src);\r
- if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )\r
- {\r
-#ifdef wxLongLong_t\r
- wxULongLong ull(value);\r
- wxString s = ull.ToString();\r
-#else\r
- wxString s = wxString::Format(wxS("%lu"), (long)value);\r
-#endif\r
- wxAnyValueTypeImpl<wxString>::SetValue(s, dst);\r
- }\r
- else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )\r
- {\r
- if ( value > UseIntMax )\r
- return false;\r
- wxAnyBaseIntType l = (wxAnyBaseIntType) value;\r
- wxAnyValueTypeImplInt::SetValue(l, dst);\r
- }\r
- else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) )\r
- {\r
-#ifndef __VISUALC6__\r
- double value2 = static_cast<double>(value);\r
-#else\r
- // VC6 doesn't implement conversion from unsigned __int64 to double\r
- wxAnyBaseIntType value0 = static_cast<wxAnyBaseIntType>(value);\r
- double value2 = static_cast<double>(value0);\r
-#endif\r
- wxAnyValueTypeImplDouble::SetValue(value2, dst);\r
- }\r
- else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) )\r
- {\r
- bool value2 = value ? true : false;\r
- wxAnyValueTypeImpl<bool>::SetValue(value2, dst);\r
- }\r
- else\r
- return false;\r
-\r
- return true;\r
-}\r
-\r
-bool wxAnyValueTypeImplString::ConvertValue(const wxAnyValueBuffer& src,\r
- wxAnyValueType* dstType,\r
- wxAnyValueBuffer& dst) const\r
-{\r
- wxString value = GetValue(src);\r
- if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )\r
- {\r
- wxAnyBaseIntType value2;\r
-#ifdef wxLongLong_t\r
- if ( !value.ToLongLong(&value2) )\r
-#else\r
- if ( !value.ToLong(&value2) )\r
-#endif\r
- return false;\r
- wxAnyValueTypeImplInt::SetValue(value2, dst);\r
- }\r
- else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )\r
- {\r
- wxAnyBaseUintType value2;\r
-#ifdef wxLongLong_t\r
- if ( !value.ToULongLong(&value2) )\r
-#else\r
- if ( !value.ToULong(&value2) )\r
-#endif\r
- return false;\r
- wxAnyValueTypeImplUint::SetValue(value2, dst);\r
- }\r
- else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) )\r
- {\r
- double value2;\r
- if ( !value.ToDouble(&value2) )\r
- return false;\r
- wxAnyValueTypeImplDouble::SetValue(value2, dst);\r
- }\r
- else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) )\r
- {\r
- bool value2;\r
- value.MakeLower();\r
- if ( value == wxS("true") ||\r
- value == wxS("yes") ||\r
- value == wxS('1') )\r
- value2 = true;\r
- else if ( value == wxS("false") ||\r
- value == wxS("no") ||\r
- value == wxS('0') )\r
- value2 = false;\r
- else\r
- return false;\r
-\r
- wxAnyValueTypeImpl<bool>::SetValue(value2, dst);\r
- }\r
- else\r
- return false;\r
-\r
- return true;\r
-}\r
-\r
-bool wxAnyValueTypeImpl<bool>::ConvertValue(const wxAnyValueBuffer& src,\r
- wxAnyValueType* dstType,\r
- wxAnyValueBuffer& dst) const\r
-{\r
- bool value = GetValue(src);\r
- if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )\r
- {\r
- wxAnyBaseIntType value2 = static_cast<wxAnyBaseIntType>(value);\r
- wxAnyValueTypeImplInt::SetValue(value2, dst);\r
- }\r
- else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )\r
- {\r
- wxAnyBaseIntType value2 = static_cast<wxAnyBaseUintType>(value);\r
- wxAnyValueTypeImplUint::SetValue(value2, dst);\r
- }\r
- else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )\r
- {\r
- wxString s;\r
- if ( value )\r
- s = wxS("true");\r
- else\r
- s = wxS("false");\r
- wxAnyValueTypeImpl<wxString>::SetValue(s, dst);\r
- }\r
- else\r
- return false;\r
-\r
- return true;\r
-}\r
-\r
-bool wxAnyValueTypeImplDouble::ConvertValue(const wxAnyValueBuffer& src,\r
- wxAnyValueType* dstType,\r
- wxAnyValueBuffer& dst) const\r
-{\r
- double value = GetValue(src);\r
- if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )\r
- {\r
- if ( value < UseIntMinF || value > UseIntMaxF )\r
- return false;\r
- wxAnyBaseUintType ul = static_cast<wxAnyBaseUintType>(value);\r
- wxAnyValueTypeImplUint::SetValue(ul, dst);\r
- }\r
- else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )\r
- {\r
- if ( value < 0.0 || value > UseUintMaxF )\r
- return false;\r
- wxAnyBaseUintType ul = static_cast<wxAnyBaseUintType>(value);\r
- wxAnyValueTypeImplUint::SetValue(ul, dst);\r
- }\r
- else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )\r
- {\r
- wxString s = wxString::Format(wxS("%.14g"), value);\r
- wxAnyValueTypeImpl<wxString>::SetValue(s, dst);\r
- }\r
- else\r
- return false;\r
-\r
- return true;\r
-}\r
-\r
-WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplInt)\r
-WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplUint)\r
-WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplString)\r
-WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<bool>)\r
-WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble)\r
-\r
-//-------------------------------------------------------------------------\r
-// wxAnyNullValueType implementation\r
-//-------------------------------------------------------------------------\r
-\r
-class wxAnyNullValue\r
-{\r
-private:\r
- void* m_dummy;\r
-};\r
-\r
-template <>\r
-class wxAnyValueTypeImpl<wxAnyNullValue> : public wxAnyValueType\r
-{\r
- WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxAnyNullValue>)\r
-public:\r
- virtual void DeleteValue(wxAnyValueBuffer& buf) const\r
- {\r
- buf.m_ptr = NULL; // This is important\r
- }\r
-\r
- // Dummy implementations\r
- virtual void CopyBuffer(const wxAnyValueBuffer& src,\r
- wxAnyValueBuffer& dst) const\r
- {\r
- wxUnusedVar(src);\r
- wxUnusedVar(dst);\r
- }\r
-\r
- virtual bool ConvertValue(const wxAnyValueBuffer& src,\r
- wxAnyValueType* dstType,\r
- wxAnyValueBuffer& dst) const\r
- {\r
- wxUnusedVar(src);\r
- wxUnusedVar(dstType);\r
- wxUnusedVar(dst);\r
- return false;\r
- }\r
-\r
-private:\r
-};\r
-\r
-WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxAnyNullValue>)\r
-\r
-wxAnyValueType* wxAnyNullValueType =\r
- wxAnyValueTypeImpl<wxAnyNullValue>::GetInstance();\r
-\r
-#endif // wxUSE_ANY\r
+/////////////////////////////////////////////////////////////////////////////
+// Name: src/common/any.cpp
+// Purpose: wxAny class, container for any type
+// Author: Jaakko Salli
+// Modified by:
+// Created: 07/05/2009
+// RCS-ID: $Id$
+// Copyright: (c) wxWidgets team
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+// For compilers that support precompilation, includes "wx/wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#include "wx/any.h"
+
+#if wxUSE_ANY
+
+#ifndef WX_PRECOMP
+ #include "wx/math.h"
+ #include "wx/crt.h"
+#endif
+
+#include "wx/vector.h"
+#include "wx/module.h"
+#include "wx/hashmap.h"
+#include "wx/hashset.h"
+
+using namespace wxPrivate;
+
+#if wxUSE_VARIANT
+
+//-------------------------------------------------------------------------
+// wxAnyValueTypeGlobals
+//-------------------------------------------------------------------------
+
+WX_DECLARE_HASH_MAP(wxAnyValueType*,
+ wxVariantDataFactory,
+ wxPointerHash,
+ wxPointerEqual,
+ wxAnyTypeToVariantDataFactoryMap);
+
+//
+// Helper class to manage global variables related to type conversion
+// between wxAny and wxVariant.
+//
+class wxAnyValueTypeGlobals
+{
+public:
+ wxAnyValueTypeGlobals()
+ {
+ }
+ ~wxAnyValueTypeGlobals()
+ {
+ m_anyToVariant.clear();
+ }
+
+ void PreRegisterAnyToVariant(wxAnyToVariantRegistration* reg)
+ {
+ m_anyToVariantRegs.push_back(reg);
+ }
+
+ // Find wxVariantData factory function for given value type,
+ // (or compatible, if possible)
+ wxVariantDataFactory FindVariantDataFactory(const wxAnyValueType* type_)
+ {
+ // Ideally we'd have the hash map of type 'const wxAnyValueType*',
+ // but WX_DECLARE_HASH_MAP() has some trouble with it.
+ wxAnyValueType* type = const_cast<wxAnyValueType*>(type_);
+
+ wxAnyTypeToVariantDataFactoryMap& anyToVariant = m_anyToVariant;
+ wxAnyTypeToVariantDataFactoryMap::const_iterator it;
+ it = anyToVariant.find(type);
+ if ( it != anyToVariant.end() )
+ return it->second;
+
+ // Not found, handle pre-registrations
+ size_t i = m_anyToVariantRegs.size();
+ while ( i > 0 )
+ {
+ i--;
+ wxAnyToVariantRegistration* reg = m_anyToVariantRegs[i];
+ wxAnyValueType* assocType = reg->GetAssociatedType();
+ if ( assocType )
+ {
+ // Both variant data and wxAnyValueType have been
+ // now been properly initialized, so remove the
+ // pre-registration entry and move data to anyToVarian
+ // map.
+ anyToVariant[assocType] = reg->GetFactory();
+ m_anyToVariantRegs.erase( m_anyToVariantRegs.begin() + i );
+ }
+ }
+
+ // Then try again
+ it = anyToVariant.find(type);
+ if ( it != anyToVariant.end() )
+ return it->second;
+
+ // Finally, attempt to find a compatible type
+ for ( it = anyToVariant.begin(); it != anyToVariant.end(); it++ )
+ {
+ if ( type->IsSameType(it->first) )
+ {
+ wxVariantDataFactory f = it->second;
+ anyToVariant[type] = f;
+ return f;
+ }
+ }
+
+ // Nothing found
+ return NULL;
+ }
+
+private:
+ wxAnyTypeToVariantDataFactoryMap m_anyToVariant;
+ wxVector<wxAnyToVariantRegistration*> m_anyToVariantRegs;
+};
+
+static wxAnyValueTypeGlobals* g_wxAnyValueTypeGlobals = NULL;
+
+
+WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplVariantData)
+
+void wxPreRegisterAnyToVariant(wxAnyToVariantRegistration* reg)
+{
+ if ( !g_wxAnyValueTypeGlobals )
+ g_wxAnyValueTypeGlobals = new wxAnyValueTypeGlobals();
+ g_wxAnyValueTypeGlobals->PreRegisterAnyToVariant(reg);
+}
+
+bool wxConvertAnyToVariant(const wxAny& any, wxVariant* variant)
+{
+ if ( any.IsNull() )
+ {
+ variant->MakeNull();
+ return true;
+ }
+
+ // (signed) integer is a special case, because there is only one type
+ // in wxAny, and two ("long" and "longlong") in wxVariant. For better
+ // backwards compatibility, convert all values that fit in "long",
+ // and others to "longlong".
+ if ( wxANY_CHECK_TYPE(any, signed int) )
+ {
+#ifdef wxLongLong_t
+ wxLongLong_t ll = 0;
+ if ( any.GetAs(&ll) )
+ {
+ // NB: Do not use LONG_MAX here. Explicitly using 32-bit
+ // integer constraint yields more consistent behaviour across
+ // builds.
+ if ( ll > wxINT32_MAX || ll < wxINT32_MIN )
+ *variant = wxLongLong(ll);
+ else
+ *variant = (long) wxLongLong(ll).GetLo();
+ }
+ else
+ {
+ return false;
+ }
+#else
+ long l;
+ if ( any.GetAs(&l) )
+ *variant = l;
+ else
+ return false;
+#endif
+ return true;
+ }
+
+ // Find matching factory function
+ wxVariantDataFactory f =
+ g_wxAnyValueTypeGlobals->FindVariantDataFactory(any.GetType());
+
+ wxVariantData* data = NULL;
+
+ if ( f )
+ {
+ data = f(any);
+ }
+ else
+ {
+ // Check if wxAny wrapped wxVariantData*
+ if ( !any.GetAs(&data) )
+ {
+ // Ok, one last chance: while unlikely, it is possible that the
+ // wxAny actually contains wxVariant.
+ if ( wxANY_CHECK_TYPE(any, wxVariant) )
+ *variant = wxANY_AS(any, wxVariant);
+ return false;
+ }
+
+ // Wrapper's GetValue() does not increase reference
+ // count, se have to do it before the data gets passed
+ // to a new variant.
+ data->IncRef();
+ }
+
+ variant->SetData(data);
+ return true;
+}
+
+//
+// This class is to make sure that wxAnyValueType instances
+// etc. get freed correctly. We must use a separate wxAnyValueTypeGlobals
+// because wxModule itself is instantiated too late.
+//
+class wxAnyValueTypeGlobalsManager : public wxModule
+{
+ DECLARE_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager)
+public:
+ wxAnyValueTypeGlobalsManager() : wxModule() { }
+ virtual ~wxAnyValueTypeGlobalsManager() { }
+
+ virtual bool OnInit()
+ {
+ return true;
+ }
+ virtual void OnExit()
+ {
+ wxDELETE(g_wxAnyValueTypeGlobals);
+ }
+private:
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager, wxModule)
+
+#endif // wxUSE_VARIANT
+
+
+//-------------------------------------------------------------------------
+// Dynamic conversion member functions
+//-------------------------------------------------------------------------
+
+//
+// Define integer minimum and maximum as helpers
+#ifdef wxLongLong_t
+ #define UseIntMin (wxINT64_MIN)
+ #define UseIntMax (wxINT64_MAX)
+ #define UseUintMax (wxUINT64_MAX)
+#else
+ #define UseIntMin (LONG_MIN)
+ #define UseIntMax (LONG_MAX)
+ #define UseUintMax (ULONG_MAX)
+#endif
+
+namespace
+{
+
+const double UseIntMinF = static_cast<double>(UseIntMin);
+const double UseIntMaxF = static_cast<double>(UseIntMax);
+const double UseUintMaxF = static_cast<double>(UseUintMax);
+
+} // anonymous namespace
+
+bool wxAnyValueTypeImplInt::ConvertValue(const wxAnyValueBuffer& src,
+ wxAnyValueType* dstType,
+ wxAnyValueBuffer& dst) const
+{
+ wxAnyBaseIntType value = GetValue(src);
+ if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
+ {
+#ifdef wxLongLong_t
+ wxLongLong ll(value);
+ wxString s = ll.ToString();
+#else
+ wxString s = wxString::Format(wxS("%ld"), (long)value);
+#endif
+ wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
+ }
+ else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )
+ {
+ if ( value < 0 )
+ return false;
+ wxAnyBaseUintType ul = (wxAnyBaseUintType) value;
+ wxAnyValueTypeImplUint::SetValue(ul, dst);
+ }
+ else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) )
+ {
+ double value2 = static_cast<double>(value);
+ wxAnyValueTypeImplDouble::SetValue(value2, dst);
+ }
+ else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) )
+ {
+ bool value2 = value ? true : false;
+ wxAnyValueTypeImpl<bool>::SetValue(value2, dst);
+ }
+ else
+ return false;
+
+ return true;
+}
+
+bool wxAnyValueTypeImplUint::ConvertValue(const wxAnyValueBuffer& src,
+ wxAnyValueType* dstType,
+ wxAnyValueBuffer& dst) const
+{
+ wxAnyBaseUintType value = GetValue(src);
+ if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
+ {
+#ifdef wxLongLong_t
+ wxULongLong ull(value);
+ wxString s = ull.ToString();
+#else
+ wxString s = wxString::Format(wxS("%lu"), (long)value);
+#endif
+ wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
+ }
+ else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )
+ {
+ if ( value > UseIntMax )
+ return false;
+ wxAnyBaseIntType l = (wxAnyBaseIntType) value;
+ wxAnyValueTypeImplInt::SetValue(l, dst);
+ }
+ else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) )
+ {
+#ifndef __VISUALC6__
+ double value2 = static_cast<double>(value);
+#else
+ // VC6 doesn't implement conversion from unsigned __int64 to double
+ wxAnyBaseIntType value0 = static_cast<wxAnyBaseIntType>(value);
+ double value2 = static_cast<double>(value0);
+#endif
+ wxAnyValueTypeImplDouble::SetValue(value2, dst);
+ }
+ else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) )
+ {
+ bool value2 = value ? true : false;
+ wxAnyValueTypeImpl<bool>::SetValue(value2, dst);
+ }
+ else
+ return false;
+
+ return true;
+}
+
+// Convert wxString to destination wxAny value type
+bool wxAnyConvertString(const wxString& value,
+ wxAnyValueType* dstType,
+ wxAnyValueBuffer& dst)
+{
+ if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
+ {
+ wxAnyValueTypeImpl<wxString>::SetValue(value, dst);
+ }
+ else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )
+ {
+ wxAnyBaseIntType value2;
+#ifdef wxLongLong_t
+ if ( !value.ToLongLong(&value2) )
+#else
+ if ( !value.ToLong(&value2) )
+#endif
+ return false;
+ wxAnyValueTypeImplInt::SetValue(value2, dst);
+ }
+ else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )
+ {
+ wxAnyBaseUintType value2;
+#ifdef wxLongLong_t
+ if ( !value.ToULongLong(&value2) )
+#else
+ if ( !value.ToULong(&value2) )
+#endif
+ return false;
+ wxAnyValueTypeImplUint::SetValue(value2, dst);
+ }
+ else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) )
+ {
+ double value2;
+ if ( !value.ToDouble(&value2) )
+ return false;
+ wxAnyValueTypeImplDouble::SetValue(value2, dst);
+ }
+ else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) )
+ {
+ bool value2;
+ wxString s(value);
+ s.MakeLower();
+ if ( s == wxS("true") ||
+ s == wxS("yes") ||
+ s == wxS('1') )
+ value2 = true;
+ else if ( s == wxS("false") ||
+ s == wxS("no") ||
+ s == wxS('0') )
+ value2 = false;
+ else
+ return false;
+
+ wxAnyValueTypeImpl<bool>::SetValue(value2, dst);
+ }
+ else
+ return false;
+
+ return true;
+}
+
+bool wxAnyValueTypeImpl<bool>::ConvertValue(const wxAnyValueBuffer& src,
+ wxAnyValueType* dstType,
+ wxAnyValueBuffer& dst) const
+{
+ bool value = GetValue(src);
+ if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )
+ {
+ wxAnyBaseIntType value2 = static_cast<wxAnyBaseIntType>(value);
+ wxAnyValueTypeImplInt::SetValue(value2, dst);
+ }
+ else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )
+ {
+ wxAnyBaseIntType value2 = static_cast<wxAnyBaseUintType>(value);
+ wxAnyValueTypeImplUint::SetValue(value2, dst);
+ }
+ else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
+ {
+ wxString s;
+ if ( value )
+ s = wxS("true");
+ else
+ s = wxS("false");
+ wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
+ }
+ else
+ return false;
+
+ return true;
+}
+
+bool wxAnyValueTypeImplDouble::ConvertValue(const wxAnyValueBuffer& src,
+ wxAnyValueType* dstType,
+ wxAnyValueBuffer& dst) const
+{
+ double value = GetValue(src);
+ if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )
+ {
+ if ( value < UseIntMinF || value > UseIntMaxF )
+ return false;
+ wxAnyBaseUintType ul = static_cast<wxAnyBaseUintType>(value);
+ wxAnyValueTypeImplUint::SetValue(ul, dst);
+ }
+ else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )
+ {
+ if ( value < 0.0 || value > UseUintMaxF )
+ return false;
+ wxAnyBaseUintType ul = static_cast<wxAnyBaseUintType>(value);
+ wxAnyValueTypeImplUint::SetValue(ul, dst);
+ }
+ else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
+ {
+ wxString s = wxString::Format(wxS("%.14g"), value);
+ wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
+ }
+ else
+ return false;
+
+ return true;
+}
+
+WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplInt)
+WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplUint)
+WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<bool>)
+WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble)
+
+WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplwxString)
+WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplConstCharPtr)
+WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplConstWchar_tPtr)
+
+#if wxUSE_DATETIME
+WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxDateTime>)
+#endif // wxUSE_DATETIME
+
+//WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxObject*>)
+//WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxArrayString>)
+
+//-------------------------------------------------------------------------
+// wxAnyNullValueType implementation
+//-------------------------------------------------------------------------
+
+class wxAnyNullValue
+{
+private:
+ void* m_dummy;
+};
+
+template <>
+class wxAnyValueTypeImpl<wxAnyNullValue> : public wxAnyValueType
+{
+ WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxAnyNullValue>)
+public:
+ // Dummy implementations
+ virtual void DeleteValue(wxAnyValueBuffer& buf) const
+ {
+ wxUnusedVar(buf);
+ }
+
+ virtual void CopyBuffer(const wxAnyValueBuffer& src,
+ wxAnyValueBuffer& dst) const
+ {
+ wxUnusedVar(src);
+ wxUnusedVar(dst);
+ }
+
+ virtual bool ConvertValue(const wxAnyValueBuffer& src,
+ wxAnyValueType* dstType,
+ wxAnyValueBuffer& dst) const
+ {
+ wxUnusedVar(src);
+ wxUnusedVar(dstType);
+ wxUnusedVar(dst);
+ return false;
+ }
+
+#if wxUSE_EXTENDED_RTTI
+ virtual const wxTypeInfo* GetTypeInfo() const
+ {
+ wxFAIL_MSG("Null Type Info not available");
+ return NULL;
+ }
+#endif
+
+private:
+};
+
+WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxAnyNullValue>)
+
+wxAnyValueType* wxAnyNullValueType =
+ wxAnyValueTypeImpl<wxAnyNullValue>::GetInstance();
+
+#include "wx/listimpl.cpp"
+WX_DEFINE_LIST(wxAnyList)
+
+#endif // wxUSE_ANY