1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/common/any.cpp 
   3 // Purpose:     wxAny class, container for any type 
   4 // Author:      Jaakko Salli 
   8 // Copyright:   (c) wxWidgets team 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // For compilers that support precompilation, includes "wx/wx.h". 
  13 #include "wx/wxprec.h" 
  28 #include "wx/vector.h" 
  29 #include "wx/module.h" 
  30 #include "wx/hashmap.h" 
  31 #include "wx/hashset.h" 
  33 using namespace wxPrivate
; 
  37 //------------------------------------------------------------------------- 
  38 // wxAnyValueTypeGlobals 
  39 //------------------------------------------------------------------------- 
  41 WX_DECLARE_HASH_MAP(wxAnyValueType
*, 
  45                     wxAnyTypeToVariantDataFactoryMap
); 
  48 // Helper class to manage global variables related to type conversion 
  49 // between wxAny and wxVariant. 
  51 class wxAnyValueTypeGlobals
 
  54     wxAnyValueTypeGlobals() 
  57     ~wxAnyValueTypeGlobals() 
  59         m_anyToVariant
.clear(); 
  62     void PreRegisterAnyToVariant(wxAnyToVariantRegistration
* reg
) 
  64         m_anyToVariantRegs
.push_back(reg
); 
  67     // Find wxVariantData factory function for given value type, 
  68     // (or compatible, if possible) 
  69     wxVariantDataFactory 
FindVariantDataFactory(const wxAnyValueType
* type_
) 
  71         // Ideally we'd have the hash map of type 'const wxAnyValueType*', 
  72         // but WX_DECLARE_HASH_MAP() has some trouble with it. 
  73         wxAnyValueType
* type 
= const_cast<wxAnyValueType
*>(type_
); 
  75         wxAnyTypeToVariantDataFactoryMap
& anyToVariant 
= m_anyToVariant
; 
  76         wxAnyTypeToVariantDataFactoryMap::const_iterator it
; 
  77         it 
= anyToVariant
.find(type
); 
  78         if ( it 
!= anyToVariant
.end() ) 
  81         // Not found, handle pre-registrations 
  82         size_t i 
= m_anyToVariantRegs
.size(); 
  86             wxAnyToVariantRegistration
* reg 
= m_anyToVariantRegs
[i
]; 
  87             wxAnyValueType
* assocType 
= reg
->GetAssociatedType(); 
  90                 // Both variant data and wxAnyValueType have been 
  91                 // now been properly initialized, so remove the 
  92                 // pre-registration entry and move data to anyToVarian 
  94                 anyToVariant
[assocType
] = reg
->GetFactory(); 
  95                 m_anyToVariantRegs
.erase( m_anyToVariantRegs
.begin() + i 
); 
 100         it 
= anyToVariant
.find(type
); 
 101         if ( it 
!= anyToVariant
.end() ) 
 104         // Finally, attempt to find a compatible type 
 105         for ( it 
= anyToVariant
.begin(); it 
!= anyToVariant
.end(); it
++ ) 
 107             if ( type
->IsSameType(it
->first
) ) 
 109                 wxVariantDataFactory f 
= it
->second
; 
 110                 anyToVariant
[type
] = f
; 
 120     wxAnyTypeToVariantDataFactoryMap        m_anyToVariant
; 
 121     wxVector
<wxAnyToVariantRegistration
*>   m_anyToVariantRegs
; 
 124 static wxAnyValueTypeGlobals
* g_wxAnyValueTypeGlobals 
= NULL
; 
 127 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplVariantData
) 
 129 void wxPreRegisterAnyToVariant(wxAnyToVariantRegistration
* reg
) 
 131     if ( !g_wxAnyValueTypeGlobals 
) 
 132         g_wxAnyValueTypeGlobals 
= new wxAnyValueTypeGlobals(); 
 133     g_wxAnyValueTypeGlobals
->PreRegisterAnyToVariant(reg
); 
 136 bool wxConvertAnyToVariant(const wxAny
& any
, wxVariant
* variant
) 
 144     // (signed) integer is a special case, because there is only one type 
 145     // in wxAny, and two ("long" and "longlong") in wxVariant. For better 
 146     // backwards compatibility, convert all values that fit in "long", 
 147     // and others to "longlong". 
 148     if ( wxANY_CHECK_TYPE(any
, signed int) ) 
 152         if ( any
.GetAs(&ll
) ) 
 154             // NB: Do not use LONG_MAX here. Explicitly using 32-bit 
 155             //     integer constraint yields more consistent behaviour across 
 157             if ( ll 
> wxINT32_MAX 
|| ll 
< wxINT32_MIN 
) 
 158                 *variant 
= wxLongLong(ll
); 
 160                 *variant 
= (long) wxLongLong(ll
).GetLo(); 
 176     // Find matching factory function 
 177     wxVariantDataFactory f 
= 
 178         g_wxAnyValueTypeGlobals
->FindVariantDataFactory(any
.GetType()); 
 180     wxVariantData
* data 
= NULL
; 
 188         // Check if wxAny wrapped wxVariantData* 
 189         if ( !any
.GetAs(&data
) ) 
 191             // Ok, one last chance: while unlikely, it is possible that the 
 192             // wxAny actually contains wxVariant. 
 193             if ( wxANY_CHECK_TYPE(any
, wxVariant
) ) 
 194                 *variant 
= wxANY_AS(any
, wxVariant
); 
 198         // Wrapper's GetValue() does not increase reference 
 199         // count, se have to do it before the data gets passed 
 204     variant
->SetData(data
); 
 209 // This class is to make sure that wxAnyValueType instances 
 210 // etc. get freed correctly. We must use a separate wxAnyValueTypeGlobals 
 211 // because wxModule itself is instantiated too late. 
 213 class wxAnyValueTypeGlobalsManager 
: public wxModule
 
 215     DECLARE_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager
) 
 217     wxAnyValueTypeGlobalsManager() : wxModule() { } 
 218     virtual ~wxAnyValueTypeGlobalsManager() { } 
 220     virtual bool OnInit() 
 224     virtual void OnExit() 
 226         wxDELETE(g_wxAnyValueTypeGlobals
); 
 231 IMPLEMENT_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager
, wxModule
) 
 233 #endif // wxUSE_VARIANT 
 236 //------------------------------------------------------------------------- 
 237 // Dynamic conversion member functions 
 238 //------------------------------------------------------------------------- 
 241 // Define integer minimum and maximum as helpers 
 243     #define UseIntMin  (wxINT64_MIN) 
 244     #define UseIntMax  (wxINT64_MAX) 
 245     #define UseUintMax (wxUINT64_MAX) 
 247     #define UseIntMin  (LONG_MIN) 
 248     #define UseIntMax  (LONG_MAX) 
 249     #define UseUintMax (ULONG_MAX) 
 255 const double UseIntMinF 
= static_cast<double>(UseIntMin
); 
 256 const double UseIntMaxF 
= static_cast<double>(UseIntMax
); 
 257 const double UseUintMaxF 
= static_cast<double>(UseUintMax
); 
 259 } // anonymous namespace 
 261 bool wxAnyValueTypeImplInt::ConvertValue(const wxAnyValueBuffer
& src
, 
 262                                          wxAnyValueType
* dstType
, 
 263                                          wxAnyValueBuffer
& dst
) const 
 265     wxAnyBaseIntType value 
= GetValue(src
); 
 266     if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxString
) ) 
 269         wxLongLong 
ll(value
); 
 270         wxString s 
= ll
.ToString(); 
 272         wxString s 
= wxString::Format(wxS("%ld"), (long)value
); 
 274         wxAnyValueTypeImpl
<wxString
>::SetValue(s
, dst
); 
 276     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseUintType
) ) 
 280         wxAnyBaseUintType ul 
= (wxAnyBaseUintType
) value
; 
 281         wxAnyValueTypeImplUint::SetValue(ul
, dst
); 
 283     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, double) ) 
 285         double value2 
= static_cast<double>(value
); 
 286         wxAnyValueTypeImplDouble::SetValue(value2
, dst
); 
 288     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, bool) ) 
 290         bool value2 
= value 
? true : false; 
 291         wxAnyValueTypeImpl
<bool>::SetValue(value2
, dst
); 
 299 bool wxAnyValueTypeImplUint::ConvertValue(const wxAnyValueBuffer
& src
, 
 300                                           wxAnyValueType
* dstType
, 
 301                                           wxAnyValueBuffer
& dst
) const 
 303     wxAnyBaseUintType value 
= GetValue(src
); 
 304     if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxString
) ) 
 307         wxULongLong 
ull(value
); 
 308         wxString s 
= ull
.ToString(); 
 310         wxString s 
= wxString::Format(wxS("%lu"), (long)value
); 
 312         wxAnyValueTypeImpl
<wxString
>::SetValue(s
, dst
); 
 314     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseIntType
) ) 
 316         if ( value 
> UseIntMax 
) 
 318         wxAnyBaseIntType l 
= (wxAnyBaseIntType
) value
; 
 319         wxAnyValueTypeImplInt::SetValue(l
, dst
); 
 321     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, double) ) 
 324         double value2 
= static_cast<double>(value
); 
 326         // VC6 doesn't implement conversion from unsigned __int64 to double 
 327         wxAnyBaseIntType value0 
= static_cast<wxAnyBaseIntType
>(value
); 
 328         double value2 
= static_cast<double>(value0
); 
 330         wxAnyValueTypeImplDouble::SetValue(value2
, dst
); 
 332     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, bool) ) 
 334         bool value2 
= value 
? true : false; 
 335         wxAnyValueTypeImpl
<bool>::SetValue(value2
, dst
); 
 343 // Convert wxString to destination wxAny value type 
 344 bool wxAnyConvertString(const wxString
& value
, 
 345                         wxAnyValueType
* dstType
, 
 346                         wxAnyValueBuffer
& dst
) 
 348     if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxString
) ) 
 350         wxAnyValueTypeImpl
<wxString
>::SetValue(value
, dst
); 
 352     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseIntType
) ) 
 354         wxAnyBaseIntType value2
; 
 356         if ( !value
.ToLongLong(&value2
) ) 
 358         if ( !value
.ToLong(&value2
) ) 
 361         wxAnyValueTypeImplInt::SetValue(value2
, dst
); 
 363     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseUintType
) ) 
 365         wxAnyBaseUintType value2
; 
 367         if ( !value
.ToULongLong(&value2
) ) 
 369         if ( !value
.ToULong(&value2
) ) 
 372         wxAnyValueTypeImplUint::SetValue(value2
, dst
); 
 374     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, double) ) 
 377         if ( !value
.ToDouble(&value2
) ) 
 379         wxAnyValueTypeImplDouble::SetValue(value2
, dst
); 
 381     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, bool) ) 
 386         if ( s 
== wxS("true") || 
 390         else if ( s 
== wxS("false") || 
 397         wxAnyValueTypeImpl
<bool>::SetValue(value2
, dst
); 
 405 bool wxAnyValueTypeImpl
<bool>::ConvertValue(const wxAnyValueBuffer
& src
, 
 406                                             wxAnyValueType
* dstType
, 
 407                                             wxAnyValueBuffer
& dst
) const 
 409     bool value 
= GetValue(src
); 
 410     if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseIntType
) ) 
 412         wxAnyBaseIntType value2 
= static_cast<wxAnyBaseIntType
>(value
); 
 413         wxAnyValueTypeImplInt::SetValue(value2
, dst
); 
 415     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseUintType
) ) 
 417         wxAnyBaseIntType value2 
= static_cast<wxAnyBaseUintType
>(value
); 
 418         wxAnyValueTypeImplUint::SetValue(value2
, dst
); 
 420     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxString
) ) 
 427         wxAnyValueTypeImpl
<wxString
>::SetValue(s
, dst
); 
 435 bool wxAnyValueTypeImplDouble::ConvertValue(const wxAnyValueBuffer
& src
, 
 436                                             wxAnyValueType
* dstType
, 
 437                                             wxAnyValueBuffer
& dst
) const 
 439     double value 
= GetValue(src
); 
 440     if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseIntType
) ) 
 442         if ( value 
< UseIntMinF 
|| value 
> UseIntMaxF 
) 
 444         wxAnyBaseUintType ul 
= static_cast<wxAnyBaseUintType
>(value
); 
 445         wxAnyValueTypeImplUint::SetValue(ul
, dst
); 
 447     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseUintType
) ) 
 449         if ( value 
< 0.0 || value 
> UseUintMaxF 
) 
 451         wxAnyBaseUintType ul 
= static_cast<wxAnyBaseUintType
>(value
); 
 452         wxAnyValueTypeImplUint::SetValue(ul
, dst
); 
 454     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxString
) ) 
 456         wxString s 
= wxString::Format(wxS("%.14g"), value
); 
 457         wxAnyValueTypeImpl
<wxString
>::SetValue(s
, dst
); 
 465 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplInt
) 
 466 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplUint
) 
 467 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl
<bool>) 
 468 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble
) 
 470 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplwxString
) 
 471 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplConstCharPtr
) 
 472 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplConstWchar_tPtr
) 
 475 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl
<wxDateTime
>) 
 476 #endif // wxUSE_DATETIME 
 478 //WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxObject*>) 
 479 //WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxArrayString>) 
 481 //------------------------------------------------------------------------- 
 482 // wxAnyNullValueType implementation 
 483 //------------------------------------------------------------------------- 
 492 class wxAnyValueTypeImpl
<wxAnyNullValue
> : public wxAnyValueType
 
 494     WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl
<wxAnyNullValue
>) 
 496     // Dummy implementations 
 497     virtual void DeleteValue(wxAnyValueBuffer
& buf
) const 
 502     virtual void CopyBuffer(const wxAnyValueBuffer
& src
, 
 503                             wxAnyValueBuffer
& dst
) const 
 509     virtual bool ConvertValue(const wxAnyValueBuffer
& src
, 
 510                               wxAnyValueType
* dstType
, 
 511                               wxAnyValueBuffer
& dst
) const 
 514         wxUnusedVar(dstType
); 
 519 #if wxUSE_EXTENDED_RTTI 
 520     virtual const wxTypeInfo
* GetTypeInfo() const 
 522         wxFAIL_MSG("Null Type Info not available"); 
 530 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl
<wxAnyNullValue
>) 
 532 wxAnyValueType
* wxAnyNullValueType 
= 
 533     wxAnyValueTypeImpl
<wxAnyNullValue
>::GetInstance(); 
 535 #include "wx/listimpl.cpp" 
 536 WX_DEFINE_LIST(wxAnyList
)