X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/178c77606f3186250b42685ca752d0bc34cd02e9..b404a8f3b072129c107c6d9a5e0f6f53cd34807b:/src/common/any.cpp diff --git a/src/common/any.cpp b/src/common/any.cpp index 62f6b45d08..c8681efec7 100644 --- a/src/common/any.cpp +++ b/src/common/any.cpp @@ -1,402 +1,538 @@ -///////////////////////////////////////////////////////////////////////////// -// 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" - -using namespace wxPrivate; - -//------------------------------------------------------------------------- -// wxAnyValueTypeGlobals -//------------------------------------------------------------------------- - -// -// Helper class to manage wxAnyValueType instances and other -// related global variables. -// -// NB: We really need to have wxAnyValueType instances allocated -// in heap. They are stored as static template member variables, -// and with them we just can't be too careful (eg. not allocating -// them in heap broke the type identification in GCC). -// -class wxAnyValueTypeGlobals -{ -public: - wxAnyValueTypeGlobals() - { - } - ~wxAnyValueTypeGlobals() - { - for ( size_t i=0; i m_valueTypes; -}; - -static wxAnyValueTypeGlobals* g_wxAnyValueTypeGlobals = NULL; - -// -// 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() - { - delete g_wxAnyValueTypeGlobals; - g_wxAnyValueTypeGlobals = NULL; - } -private: -}; - -IMPLEMENT_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager, wxModule) - - -//------------------------------------------------------------------------- -// wxAnyValueType -//------------------------------------------------------------------------- - -wxAnyValueType::wxAnyValueType() -{ - if ( !g_wxAnyValueTypeGlobals ) - g_wxAnyValueTypeGlobals = new wxAnyValueTypeGlobals(); - - g_wxAnyValueTypeGlobals->RegisterValueType(this); -} - -//------------------------------------------------------------------------- -// wxAny -//------------------------------------------------------------------------- - -void wxAny::AssignAny(const wxAny &any) -{ - if ( !any.m_type->IsSameType(m_type) ) - { - m_type->DeleteValue(m_buffer); - m_type = any.m_type; - } - m_type->CopyBuffer(any.m_buffer, m_buffer); -} - -//------------------------------------------------------------------------- -// Dynamic conversion member functions -//------------------------------------------------------------------------- - -// -// Define integer minimum and maximum as helpers -#ifdef wxLongLong_t -const wxAnyBaseIntType UseIntMin = wxINT64_MIN; -const wxAnyBaseUintType UseIntMax = wxINT64_MAX; -const wxAnyBaseUintType UseUintMax = wxUINT64_MAX; -#else -const wxAnyBaseIntType UseIntMin = LONG_MIN; -const wxAnyBaseUintType UseUintMax = ULONG_MAX; -const wxAnyBaseUintType UseIntMax = LONG_MAX; -#endif - -const double UseIntMinF = static_cast(UseIntMin); -#ifndef __VISUALC6__ -const double UseIntMaxF = static_cast(UseIntMax); -const double UseUintMaxF = static_cast(UseUintMax); -#else -// VC6 doesn't implement conversion from unsigned __int64 to double -const wxAnyBaseIntType UseIntMax0 = static_cast(UseIntMax); -const wxAnyBaseIntType UseUintMax0 = static_cast(UseUintMax); -const double UseIntMaxF = static_cast(UseIntMax0); -const double UseUintMaxF = static_cast(UseUintMax0); -#endif - - -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::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(value); - wxAnyValueTypeImplDouble::SetValue(value2, dst); - } - else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) ) - { - bool value2 = value ? true : false; - wxAnyValueTypeImpl::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::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(value); -#else - // VC6 doesn't implement conversion from unsigned __int64 to double - wxAnyBaseIntType value0 = static_cast(value); - double value2 = static_cast(value0); -#endif - wxAnyValueTypeImplDouble::SetValue(value2, dst); - } - else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) ) - { - bool value2 = value ? true : false; - wxAnyValueTypeImpl::SetValue(value2, dst); - } - else - return false; - - return true; -} - -bool wxAnyValueTypeImplString::ConvertValue(const wxAnyValueBuffer& src, - wxAnyValueType* dstType, - wxAnyValueBuffer& dst) const -{ - wxString value = GetValue(src); - 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; - value.MakeLower(); - if ( value == wxS("true") || - value == wxS("yes") || - value == wxS('1') ) - value2 = true; - else if ( value == wxS("false") || - value == wxS("no") || - value == wxS('0') ) - value2 = false; - else - return false; - - wxAnyValueTypeImpl::SetValue(value2, dst); - } - else - return false; - - return true; -} - -bool wxAnyValueTypeImpl::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(value); - wxAnyValueTypeImplInt::SetValue(value2, dst); - } - else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) ) - { - wxAnyBaseIntType value2 = static_cast(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::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(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(value); - wxAnyValueTypeImplUint::SetValue(ul, dst); - } - else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) ) - { - wxString s = wxString::Format(wxS("%.14g"), value); - wxAnyValueTypeImpl::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(wxAnyValueTypeImplString) -WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl) -WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble) - -//------------------------------------------------------------------------- -// wxAnyNullValueType implementation -//------------------------------------------------------------------------- - -class wxAnyNullValue -{ -private: - void* m_dummy; -}; - -template <> -class wxAnyValueTypeImpl : public wxAnyValueType -{ - WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl) -public: - virtual void DeleteValue(wxAnyValueBuffer& buf) const - { - buf.m_ptr = NULL; // This is important - } - - // Dummy implementations - 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; - } - -private: -}; - -WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl) - -wxAnyValueType* wxAnyNullValueType = - wxAnyValueTypeImpl::GetInstance(); - -#endif // wxUSE_ANY +///////////////////////////////////////////////////////////////////////////// +// 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(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 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(UseIntMin); +const double UseIntMaxF = static_cast(UseIntMax); +const double UseUintMaxF = static_cast(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::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(value); + wxAnyValueTypeImplDouble::SetValue(value2, dst); + } + else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) ) + { + bool value2 = value ? true : false; + wxAnyValueTypeImpl::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::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(value); +#else + // VC6 doesn't implement conversion from unsigned __int64 to double + wxAnyBaseIntType value0 = static_cast(value); + double value2 = static_cast(value0); +#endif + wxAnyValueTypeImplDouble::SetValue(value2, dst); + } + else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) ) + { + bool value2 = value ? true : false; + wxAnyValueTypeImpl::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::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::SetValue(value2, dst); + } + else + return false; + + return true; +} + +bool wxAnyValueTypeImpl::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(value); + wxAnyValueTypeImplInt::SetValue(value2, dst); + } + else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) ) + { + wxAnyBaseIntType value2 = static_cast(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::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(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(value); + wxAnyValueTypeImplUint::SetValue(ul, dst); + } + else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) ) + { + wxString s = wxString::Format(wxS("%.14g"), value); + wxAnyValueTypeImpl::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) +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) +#endif // wxUSE_DATETIME + +//WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl) +//WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl) + +//------------------------------------------------------------------------- +// wxAnyNullValueType implementation +//------------------------------------------------------------------------- + +class wxAnyNullValue +{ +private: + void* m_dummy; +}; + +template <> +class wxAnyValueTypeImpl : public wxAnyValueType +{ + WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl) +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) + +wxAnyValueType* wxAnyNullValueType = + wxAnyValueTypeImpl::GetInstance(); + +#include "wx/listimpl.cpp" +WX_DEFINE_LIST(wxAnyList) + +#endif // wxUSE_ANY