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" 
  31 using namespace wxPrivate
; 
  33 //------------------------------------------------------------------------- 
  34 // wxAnyValueTypeGlobals 
  35 //------------------------------------------------------------------------- 
  38 // Helper class to manage wxAnyValueType instances and other 
  39 // related global variables. 
  41 // NB: We really need to have wxAnyValueType instances allocated 
  42 //     in heap. They are stored as static template member variables, 
  43 //     and with them we just can't be too careful (eg. not allocating 
  44 //     them in heap broke the type identification in GCC). 
  46 class wxAnyValueTypeGlobals
 
  49     wxAnyValueTypeGlobals() 
  52     ~wxAnyValueTypeGlobals() 
  54         for ( size_t i
=0; i
<m_valueTypes
.size(); i
++ ) 
  55             delete m_valueTypes
[i
]; 
  58     void RegisterValueType(wxAnyValueType
* valueType
) 
  60         m_valueTypes
.push_back(valueType
); 
  64     wxVector
<wxAnyValueType
*>   m_valueTypes
; 
  67 static wxAnyValueTypeGlobals
* g_wxAnyValueTypeGlobals 
= NULL
; 
  70 // This class is to make sure that wxAnyValueType instances 
  71 // etc. get freed correctly. We must use a separate wxAnyValueTypeGlobals 
  72 // because wxModule itself is instantiated too late. 
  74 class wxAnyValueTypeGlobalsManager 
: public wxModule
 
  76     DECLARE_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager
) 
  78     wxAnyValueTypeGlobalsManager() : wxModule() { } 
  79     virtual ~wxAnyValueTypeGlobalsManager() { } 
  87         delete g_wxAnyValueTypeGlobals
; 
  88         g_wxAnyValueTypeGlobals 
= NULL
; 
  93 IMPLEMENT_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager
, wxModule
) 
  96 //------------------------------------------------------------------------- 
  98 //------------------------------------------------------------------------- 
 100 wxAnyValueType::wxAnyValueType() 
 102     if ( !g_wxAnyValueTypeGlobals 
) 
 103         g_wxAnyValueTypeGlobals 
= new wxAnyValueTypeGlobals(); 
 105     g_wxAnyValueTypeGlobals
->RegisterValueType(this); 
 108 //------------------------------------------------------------------------- 
 110 //------------------------------------------------------------------------- 
 112 void wxAny::AssignAny(const wxAny 
&any
) 
 114     if ( !any
.m_type
->IsSameType(m_type
) ) 
 116         m_type
->DeleteValue(m_buffer
); 
 119     m_type
->CopyBuffer(any
.m_buffer
, m_buffer
); 
 122 //------------------------------------------------------------------------- 
 123 // Dynamic conversion member functions 
 124 //------------------------------------------------------------------------- 
 127 // Define integer minimum and maximum as helpers 
 129 const wxAnyBaseIntType UseIntMin 
= wxINT64_MIN
; 
 130 const wxAnyBaseUintType UseIntMax 
= wxINT64_MAX
; 
 131 const wxAnyBaseUintType UseUintMax 
= wxUINT64_MAX
; 
 133 const wxAnyBaseIntType UseIntMin 
= LONG_MIN
; 
 134 const wxAnyBaseUintType UseUintMax 
= ULONG_MAX
; 
 135 const wxAnyBaseUintType UseIntMax 
= LONG_MAX
; 
 138 const double UseIntMinF 
= static_cast<double>(UseIntMin
); 
 140 const double UseIntMaxF 
= static_cast<double>(UseIntMax
); 
 141 const double UseUintMaxF 
= static_cast<double>(UseUintMax
); 
 143 // VC6 doesn't implement conversion from unsigned __int64 to double 
 144 const wxAnyBaseIntType UseIntMax0 
= static_cast<wxAnyBaseIntType
>(UseIntMax
); 
 145 const wxAnyBaseIntType UseUintMax0 
= static_cast<wxAnyBaseIntType
>(UseUintMax
); 
 146 const double UseIntMaxF 
= static_cast<double>(UseIntMax0
); 
 147 const double UseUintMaxF 
= static_cast<double>(UseUintMax0
); 
 151 bool wxAnyValueTypeImplInt::ConvertValue(const wxAnyValueBuffer
& src
, 
 152                                          wxAnyValueType
* dstType
, 
 153                                          wxAnyValueBuffer
& dst
) const 
 155     wxAnyBaseIntType value 
= GetValue(src
); 
 156     if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxString
) ) 
 159         wxLongLong 
ll(value
); 
 160         wxString s 
= ll
.ToString(); 
 162         wxString s 
= wxString::Format(wxS("%ld"), (long)value
); 
 164         wxAnyValueTypeImpl
<wxString
>::SetValue(s
, dst
); 
 166     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseUintType
) ) 
 170         wxAnyBaseUintType ul 
= (wxAnyBaseUintType
) value
; 
 171         wxAnyValueTypeImplUint::SetValue(ul
, dst
); 
 173     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, double) ) 
 175         double value2 
= static_cast<double>(value
); 
 176         wxAnyValueTypeImplDouble::SetValue(value2
, dst
); 
 178     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, bool) ) 
 180         bool value2 
= value 
? true : false; 
 181         wxAnyValueTypeImpl
<bool>::SetValue(value2
, dst
); 
 189 bool wxAnyValueTypeImplUint::ConvertValue(const wxAnyValueBuffer
& src
, 
 190                                           wxAnyValueType
* dstType
, 
 191                                           wxAnyValueBuffer
& dst
) const 
 193     wxAnyBaseUintType value 
= GetValue(src
); 
 194     if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxString
) ) 
 197         wxULongLong 
ull(value
); 
 198         wxString s 
= ull
.ToString(); 
 200         wxString s 
= wxString::Format(wxS("%lu"), (long)value
); 
 202         wxAnyValueTypeImpl
<wxString
>::SetValue(s
, dst
); 
 204     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseIntType
) ) 
 206         if ( value 
> UseIntMax 
) 
 208         wxAnyBaseIntType l 
= (wxAnyBaseIntType
) value
; 
 209         wxAnyValueTypeImplInt::SetValue(l
, dst
); 
 211     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, double) ) 
 214         double value2 
= static_cast<double>(value
); 
 216         // VC6 doesn't implement conversion from unsigned __int64 to double 
 217         wxAnyBaseIntType value0 
= static_cast<wxAnyBaseIntType
>(value
); 
 218         double value2 
= static_cast<double>(value0
); 
 220         wxAnyValueTypeImplDouble::SetValue(value2
, dst
); 
 222     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, bool) ) 
 224         bool value2 
= value 
? true : false; 
 225         wxAnyValueTypeImpl
<bool>::SetValue(value2
, dst
); 
 233 bool wxAnyValueTypeImplString::ConvertValue(const wxAnyValueBuffer
& src
, 
 234                                             wxAnyValueType
* dstType
, 
 235                                             wxAnyValueBuffer
& dst
) const 
 237     wxString value 
= GetValue(src
); 
 238     if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseIntType
) ) 
 240         wxAnyBaseIntType value2
; 
 242         if ( !value
.ToLongLong(&value2
) ) 
 244         if ( !value
.ToLong(&value2
) ) 
 247         wxAnyValueTypeImplInt::SetValue(value2
, dst
); 
 249     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseUintType
) ) 
 251         wxAnyBaseUintType value2
; 
 253         if ( !value
.ToULongLong(&value2
) ) 
 255         if ( !value
.ToULong(&value2
) ) 
 258         wxAnyValueTypeImplUint::SetValue(value2
, dst
); 
 260     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, double) ) 
 263         if ( !value
.ToDouble(&value2
) ) 
 265         wxAnyValueTypeImplDouble::SetValue(value2
, dst
); 
 267     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, bool) ) 
 271         if ( value 
== wxS("true") || 
 272              value 
== wxS("yes") || 
 275         else if ( value 
== wxS("false") || 
 276                   value 
== wxS("no") || 
 282         wxAnyValueTypeImpl
<bool>::SetValue(value2
, dst
); 
 290 bool wxAnyValueTypeImpl
<bool>::ConvertValue(const wxAnyValueBuffer
& src
, 
 291                                             wxAnyValueType
* dstType
, 
 292                                             wxAnyValueBuffer
& dst
) const 
 294     bool value 
= GetValue(src
); 
 295     if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseIntType
) ) 
 297         wxAnyBaseIntType value2 
= static_cast<wxAnyBaseIntType
>(value
); 
 298         wxAnyValueTypeImplInt::SetValue(value2
, dst
); 
 300     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseUintType
) ) 
 302         wxAnyBaseIntType value2 
= static_cast<wxAnyBaseUintType
>(value
); 
 303         wxAnyValueTypeImplUint::SetValue(value2
, dst
); 
 305     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxString
) ) 
 312         wxAnyValueTypeImpl
<wxString
>::SetValue(s
, dst
); 
 320 bool wxAnyValueTypeImplDouble::ConvertValue(const wxAnyValueBuffer
& src
, 
 321                                             wxAnyValueType
* dstType
, 
 322                                             wxAnyValueBuffer
& dst
) const 
 324     double value 
= GetValue(src
); 
 325     if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseIntType
) ) 
 327         if ( value 
< UseIntMinF 
|| value 
> UseIntMaxF 
) 
 329         wxAnyBaseUintType ul 
= static_cast<wxAnyBaseUintType
>(value
); 
 330         wxAnyValueTypeImplUint::SetValue(ul
, dst
); 
 332     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseUintType
) ) 
 334         if ( value 
< 0.0 || value 
> UseUintMaxF 
) 
 336         wxAnyBaseUintType ul 
= static_cast<wxAnyBaseUintType
>(value
); 
 337         wxAnyValueTypeImplUint::SetValue(ul
, dst
); 
 339     else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxString
) ) 
 341         wxString s 
= wxString::Format(wxS("%.14g"), value
); 
 342         wxAnyValueTypeImpl
<wxString
>::SetValue(s
, dst
); 
 350 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplInt
) 
 351 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplUint
) 
 352 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplString
) 
 353 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl
<bool>) 
 354 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble
) 
 356 //------------------------------------------------------------------------- 
 357 // wxAnyNullValueType implementation 
 358 //------------------------------------------------------------------------- 
 367 class wxAnyValueTypeImpl
<wxAnyNullValue
> : public wxAnyValueType
 
 369     WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl
<wxAnyNullValue
>) 
 371     virtual void DeleteValue(wxAnyValueBuffer
& buf
) const 
 373         buf
.m_ptr 
= NULL
;  // This is important 
 376     // Dummy implementations 
 377     virtual void CopyBuffer(const wxAnyValueBuffer
& src
, 
 378                             wxAnyValueBuffer
& dst
) const 
 384     virtual bool ConvertValue(const wxAnyValueBuffer
& src
, 
 385                               wxAnyValueType
* dstType
, 
 386                               wxAnyValueBuffer
& dst
) const 
 389         wxUnusedVar(dstType
); 
 397 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl
<wxAnyNullValue
>) 
 399 wxAnyValueType
* wxAnyNullValueType 
= 
 400     wxAnyValueTypeImpl
<wxAnyNullValue
>::GetInstance();