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" 
  32 using namespace wxPrivate
; 
  34 //------------------------------------------------------------------------- 
  35 // wxAnyValueTypeGlobals 
  36 //------------------------------------------------------------------------- 
  40 WX_DECLARE_HASH_MAP(wxAnyValueType
*, 
  44                     wxAnyTypeToVariantDataFactoryMap
); 
  49 // Helper class to manage wxAnyValueType instances and and other 
  50 // related global variables (such as wxAny<->wxVariant type association). 
  52 // NB: We really need to have wxAnyValueType instances allocated 
  53 //     in heap. They are stored as static template member variables, 
  54 //     and with them we just can't be too careful (eg. not allocating 
  55 //     them in heap broke the type identification in GCC). 
  57 class wxAnyValueTypeGlobals
 
  60     wxAnyValueTypeGlobals() 
  63     ~wxAnyValueTypeGlobals() 
  66         m_anyToVariant
.clear(); 
  68         for ( size_t i
=0; i
<m_valueTypes
.size(); i
++ ) 
  69             delete m_valueTypes
[i
]; 
  72     void RegisterValueType(wxAnyValueType
* valueType
) 
  74         m_valueTypes
.push_back(valueType
); 
  78     void PreRegisterAnyToVariant(wxAnyToVariantRegistration
* reg
) 
  80         m_anyToVariantRegs
.push_back(reg
); 
  83     // Find wxVariantData factory function for given value type, 
  84     // (or compatible, if possible) 
  85     wxVariantDataFactory 
FindVariantDataFactory(const wxAnyValueType
* type
) 
  87         wxAnyTypeToVariantDataFactoryMap
& anyToVariant 
= m_anyToVariant
; 
  88         wxAnyTypeToVariantDataFactoryMap::const_iterator it
; 
  89         it 
= anyToVariant
.find(type
); 
  90         if ( it 
!= anyToVariant
.end() ) 
  93         // Not found, handle pre-registrations 
  94         size_t i 
= m_anyToVariantRegs
.size(); 
  98             wxAnyToVariantRegistration
* reg 
= m_anyToVariantRegs
[i
]; 
  99             wxAnyValueType
* assocType 
= reg
->GetAssociatedType(); 
 102                 // Both variant data and wxAnyValueType have been 
 103                 // now been properly initialized, so remove the 
 104                 // pre-registration entry and move data to anyToVarian 
 106                 anyToVariant
[assocType
] = reg
->GetFactory(); 
 107                 m_anyToVariantRegs
.erase( m_anyToVariantRegs
.begin() + i 
); 
 112         it 
= anyToVariant
.find(type
); 
 113         if ( it 
!= anyToVariant
.end() ) 
 116         // Finally, attempt to find a compatible type 
 117         for ( it 
= anyToVariant
.begin(); it 
!= anyToVariant
.end(); it
++ ) 
 119             if ( type
->IsSameType(it
->first
) ) 
 121                 wxVariantDataFactory f 
= it
->second
; 
 122                 anyToVariant
[type
] = f
; 
 133     wxVector
<wxAnyValueType
*>               m_valueTypes
; 
 135     wxAnyTypeToVariantDataFactoryMap        m_anyToVariant
; 
 136     wxVector
<wxAnyToVariantRegistration
*>   m_anyToVariantRegs
; 
 140 static wxAnyValueTypeGlobals
* g_wxAnyValueTypeGlobals 
= NULL
; 
 144 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplVariantData
) 
 146 void wxPreRegisterAnyToVariant(wxAnyToVariantRegistration
* reg
) 
 148     if ( !g_wxAnyValueTypeGlobals 
) 
 149         g_wxAnyValueTypeGlobals 
= new wxAnyValueTypeGlobals(); 
 150     g_wxAnyValueTypeGlobals
->PreRegisterAnyToVariant(reg
); 
 153 bool wxConvertAnyToVariant(const wxAny
& any
, wxVariant
* variant
) 
 161     // (signed) integer is a special case, because there is only one type 
 162     // in wxAny, and two ("long" and "longlong") in wxVariant. For better 
 163     // backwards compatibility, convert all values that fit in "long", 
 164     // and others to "longlong". 
 165     if ( wxANY_CHECK_TYPE(any
, signed int) ) 
 169         if ( any
.GetAs(&ll
) ) 
 172                 *variant 
= wxLongLong(ll
); 
 174                 *variant 
= (long) wxLongLong(ll
).GetLo(); 
 190     // Find matching factory function 
 191     wxVariantDataFactory f 
= 
 192         g_wxAnyValueTypeGlobals
->FindVariantDataFactory(any
.GetType()); 
 194     wxVariantData
* data 
= NULL
; 
 202         // Check if wxAny wrapped wxVariantData* 
 203         if ( !any
.GetAs(&data
) ) 
 206         // Wrapper's GetValue() does not increase reference 
 207         // count, se have to do it before the data gets passed 
 212     variant
->SetData(data
); 
 216 #endif // wxUSE_VARIANT 
 219 // This class is to make sure that wxAnyValueType instances 
 220 // etc. get freed correctly. We must use a separate wxAnyValueTypeGlobals 
 221 // because wxModule itself is instantiated too late. 
 223 class wxAnyValueTypeGlobalsManager 
: public wxModule
 
 225     DECLARE_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager
) 
 227     wxAnyValueTypeGlobalsManager() : wxModule() { } 
 228     virtual ~wxAnyValueTypeGlobalsManager() { } 
 230     virtual bool OnInit() 
 234     virtual void OnExit() 
 236         delete g_wxAnyValueTypeGlobals
; 
 237         g_wxAnyValueTypeGlobals 
= NULL
; 
 242 IMPLEMENT_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager
, wxModule
) 
 245 //------------------------------------------------------------------------- 
 247 //------------------------------------------------------------------------- 
 249 wxAnyValueType::wxAnyValueType() 
 251     if ( !g_wxAnyValueTypeGlobals 
) 
 252         g_wxAnyValueTypeGlobals 
= new wxAnyValueTypeGlobals(); 
 254     g_wxAnyValueTypeGlobals
->RegisterValueType(this); 
 257 //------------------------------------------------------------------------- 
 258 // Dynamic conversion member functions 
 259 //------------------------------------------------------------------------- 
 262 // Define integer minimum and maximum as helpers 
 264     #define UseIntMin  (wxINT64_MIN) 
 265     #define UseIntMax  (wxINT64_MAX) 
 266     #define UseUintMax (wxUINT64_MAX) 
 268     #define UseIntMin  (LONG_MIN) 
 269     #define UseIntMax  (LONG_MAX) 
 270     #define UseUintMax (ULONG_MAX) 
 276 const double UseIntMinF 
= static_cast<double>(UseIntMin
); 
 277 const double UseIntMaxF 
= static_cast<double>(UseIntMax
); 
 278 const double UseUintMaxF 
= static_cast<double>(UseUintMax
); 
 280 } // anonymous namespace 
 282 bool wxAnyValueTypeImplInt::ConvertValue(const wxAnyValueBuffer
& src
, 
 283                                          wxAnyValueType
* dstType
, 
 284                                          wxAnyValueBuffer
& dst
) const 
 286     wxAnyBaseIntType value 
= GetValue(src
); 
 287     if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxString
) ) 
 290         wxLongLong 
ll(value
); 
 291         wxString s 
= ll
.ToString(); 
 293         wxString s 
= wxString::Format(wxS("%ld"), (long)value
); 
 295         wxAnyValueTypeImpl
<wxString
>::SetValue(s
, dst
); 
 297     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseUintType
) ) 
 301         wxAnyBaseUintType ul 
= (wxAnyBaseUintType
) value
; 
 302         wxAnyValueTypeImplUint::SetValue(ul
, dst
); 
 304     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, double) ) 
 306         double value2 
= static_cast<double>(value
); 
 307         wxAnyValueTypeImplDouble::SetValue(value2
, dst
); 
 309     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, bool) ) 
 311         bool value2 
= value 
? true : false; 
 312         wxAnyValueTypeImpl
<bool>::SetValue(value2
, dst
); 
 320 bool wxAnyValueTypeImplUint::ConvertValue(const wxAnyValueBuffer
& src
, 
 321                                           wxAnyValueType
* dstType
, 
 322                                           wxAnyValueBuffer
& dst
) const 
 324     wxAnyBaseUintType value 
= GetValue(src
); 
 325     if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxString
) ) 
 328         wxULongLong 
ull(value
); 
 329         wxString s 
= ull
.ToString(); 
 331         wxString s 
= wxString::Format(wxS("%lu"), (long)value
); 
 333         wxAnyValueTypeImpl
<wxString
>::SetValue(s
, dst
); 
 335     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseIntType
) ) 
 337         if ( value 
> UseIntMax 
) 
 339         wxAnyBaseIntType l 
= (wxAnyBaseIntType
) value
; 
 340         wxAnyValueTypeImplInt::SetValue(l
, dst
); 
 342     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, double) ) 
 345         double value2 
= static_cast<double>(value
); 
 347         // VC6 doesn't implement conversion from unsigned __int64 to double 
 348         wxAnyBaseIntType value0 
= static_cast<wxAnyBaseIntType
>(value
); 
 349         double value2 
= static_cast<double>(value0
); 
 351         wxAnyValueTypeImplDouble::SetValue(value2
, dst
); 
 353     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, bool) ) 
 355         bool value2 
= value 
? true : false; 
 356         wxAnyValueTypeImpl
<bool>::SetValue(value2
, dst
); 
 364 bool wxAnyValueTypeImplString::ConvertValue(const wxAnyValueBuffer
& src
, 
 365                                             wxAnyValueType
* dstType
, 
 366                                             wxAnyValueBuffer
& dst
) const 
 368     wxString value 
= GetValue(src
); 
 369     if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseIntType
) ) 
 371         wxAnyBaseIntType value2
; 
 373         if ( !value
.ToLongLong(&value2
) ) 
 375         if ( !value
.ToLong(&value2
) ) 
 378         wxAnyValueTypeImplInt::SetValue(value2
, dst
); 
 380     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseUintType
) ) 
 382         wxAnyBaseUintType value2
; 
 384         if ( !value
.ToULongLong(&value2
) ) 
 386         if ( !value
.ToULong(&value2
) ) 
 389         wxAnyValueTypeImplUint::SetValue(value2
, dst
); 
 391     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, double) ) 
 394         if ( !value
.ToDouble(&value2
) ) 
 396         wxAnyValueTypeImplDouble::SetValue(value2
, dst
); 
 398     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, bool) ) 
 402         if ( value 
== wxS("true") || 
 403              value 
== wxS("yes") || 
 406         else if ( value 
== wxS("false") || 
 407                   value 
== wxS("no") || 
 413         wxAnyValueTypeImpl
<bool>::SetValue(value2
, dst
); 
 421 bool wxAnyValueTypeImpl
<bool>::ConvertValue(const wxAnyValueBuffer
& src
, 
 422                                             wxAnyValueType
* dstType
, 
 423                                             wxAnyValueBuffer
& dst
) const 
 425     bool value 
= GetValue(src
); 
 426     if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseIntType
) ) 
 428         wxAnyBaseIntType value2 
= static_cast<wxAnyBaseIntType
>(value
); 
 429         wxAnyValueTypeImplInt::SetValue(value2
, dst
); 
 431     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseUintType
) ) 
 433         wxAnyBaseIntType value2 
= static_cast<wxAnyBaseUintType
>(value
); 
 434         wxAnyValueTypeImplUint::SetValue(value2
, dst
); 
 436     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxString
) ) 
 443         wxAnyValueTypeImpl
<wxString
>::SetValue(s
, dst
); 
 451 bool wxAnyValueTypeImplDouble::ConvertValue(const wxAnyValueBuffer
& src
, 
 452                                             wxAnyValueType
* dstType
, 
 453                                             wxAnyValueBuffer
& dst
) const 
 455     double value 
= GetValue(src
); 
 456     if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseIntType
) ) 
 458         if ( value 
< UseIntMinF 
|| value 
> UseIntMaxF 
) 
 460         wxAnyBaseUintType ul 
= static_cast<wxAnyBaseUintType
>(value
); 
 461         wxAnyValueTypeImplUint::SetValue(ul
, dst
); 
 463     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseUintType
) ) 
 465         if ( value 
< 0.0 || value 
> UseUintMaxF 
) 
 467         wxAnyBaseUintType ul 
= static_cast<wxAnyBaseUintType
>(value
); 
 468         wxAnyValueTypeImplUint::SetValue(ul
, dst
); 
 470     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxString
) ) 
 472         wxString s 
= wxString::Format(wxS("%.14g"), value
); 
 473         wxAnyValueTypeImpl
<wxString
>::SetValue(s
, dst
); 
 481 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplInt
) 
 482 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplUint
) 
 483 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplString
) 
 484 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl
<bool>) 
 485 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble
) 
 487 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl
<wxDateTime
>) 
 488 //WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxObject*>) 
 489 //WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxArrayString>) 
 491 //------------------------------------------------------------------------- 
 492 // wxAnyNullValueType implementation 
 493 //------------------------------------------------------------------------- 
 502 class wxAnyValueTypeImpl
<wxAnyNullValue
> : public wxAnyValueType
 
 504     WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl
<wxAnyNullValue
>) 
 506     // Dummy implementations 
 507     virtual void DeleteValue(wxAnyValueBuffer
& buf
) const 
 512     virtual void CopyBuffer(const wxAnyValueBuffer
& src
, 
 513                             wxAnyValueBuffer
& dst
) const 
 519     virtual bool ConvertValue(const wxAnyValueBuffer
& src
, 
 520                               wxAnyValueType
* dstType
, 
 521                               wxAnyValueBuffer
& dst
) const 
 524         wxUnusedVar(dstType
); 
 532 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl
<wxAnyNullValue
>) 
 534 wxAnyValueType
* wxAnyNullValueType 
= 
 535     wxAnyValueTypeImpl
<wxAnyNullValue
>::GetInstance();