]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/any.cpp
fixing osx_cocoa
[wxWidgets.git] / src / common / any.cpp
index 62f6b45d080fda6885a5ca80d2c938f3703f2aab..c8681efec7a01811ab9da4d791563450d39839aa 100644 (file)
-/////////////////////////////////////////////////////////////////////////////\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