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();