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 //-------------------------------------------------------------------------
109 // Dynamic conversion member functions
110 //-------------------------------------------------------------------------
113 // Define integer minimum and maximum as helpers
115 const wxAnyBaseIntType UseIntMin
= wxINT64_MIN
;
116 const wxAnyBaseUintType UseIntMax
= wxINT64_MAX
;
117 const wxAnyBaseUintType UseUintMax
= wxUINT64_MAX
;
119 const wxAnyBaseIntType UseIntMin
= LONG_MIN
;
120 const wxAnyBaseUintType UseUintMax
= ULONG_MAX
;
121 const wxAnyBaseUintType UseIntMax
= LONG_MAX
;
124 const double UseIntMinF
= static_cast<double>(UseIntMin
);
126 const double UseIntMaxF
= static_cast<double>(UseIntMax
);
127 const double UseUintMaxF
= static_cast<double>(UseUintMax
);
129 // VC6 doesn't implement conversion from unsigned __int64 to double
130 const wxAnyBaseIntType UseIntMax0
= static_cast<wxAnyBaseIntType
>(UseIntMax
);
131 const wxAnyBaseIntType UseUintMax0
= static_cast<wxAnyBaseIntType
>(UseUintMax
);
132 const double UseIntMaxF
= static_cast<double>(UseIntMax0
);
133 const double UseUintMaxF
= static_cast<double>(UseUintMax0
);
137 bool wxAnyValueTypeImplInt::ConvertValue(const wxAnyValueBuffer
& src
,
138 wxAnyValueType
* dstType
,
139 wxAnyValueBuffer
& dst
) const
141 wxAnyBaseIntType value
= GetValue(src
);
142 if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxString
) )
145 wxLongLong
ll(value
);
146 wxString s
= ll
.ToString();
148 wxString s
= wxString::Format(wxS("%ld"), (long)value
);
150 wxAnyValueTypeImpl
<wxString
>::SetValue(s
, dst
);
152 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseUintType
) )
156 wxAnyBaseUintType ul
= (wxAnyBaseUintType
) value
;
157 wxAnyValueTypeImplUint::SetValue(ul
, dst
);
159 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, double) )
161 double value2
= static_cast<double>(value
);
162 wxAnyValueTypeImplDouble::SetValue(value2
, dst
);
164 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, bool) )
166 bool value2
= value
? true : false;
167 wxAnyValueTypeImpl
<bool>::SetValue(value2
, dst
);
175 bool wxAnyValueTypeImplUint::ConvertValue(const wxAnyValueBuffer
& src
,
176 wxAnyValueType
* dstType
,
177 wxAnyValueBuffer
& dst
) const
179 wxAnyBaseUintType value
= GetValue(src
);
180 if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxString
) )
183 wxULongLong
ull(value
);
184 wxString s
= ull
.ToString();
186 wxString s
= wxString::Format(wxS("%lu"), (long)value
);
188 wxAnyValueTypeImpl
<wxString
>::SetValue(s
, dst
);
190 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseIntType
) )
192 if ( value
> UseIntMax
)
194 wxAnyBaseIntType l
= (wxAnyBaseIntType
) value
;
195 wxAnyValueTypeImplInt::SetValue(l
, dst
);
197 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, double) )
200 double value2
= static_cast<double>(value
);
202 // VC6 doesn't implement conversion from unsigned __int64 to double
203 wxAnyBaseIntType value0
= static_cast<wxAnyBaseIntType
>(value
);
204 double value2
= static_cast<double>(value0
);
206 wxAnyValueTypeImplDouble::SetValue(value2
, dst
);
208 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, bool) )
210 bool value2
= value
? true : false;
211 wxAnyValueTypeImpl
<bool>::SetValue(value2
, dst
);
219 bool wxAnyValueTypeImplString::ConvertValue(const wxAnyValueBuffer
& src
,
220 wxAnyValueType
* dstType
,
221 wxAnyValueBuffer
& dst
) const
223 wxString value
= GetValue(src
);
224 if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseIntType
) )
226 wxAnyBaseIntType value2
;
228 if ( !value
.ToLongLong(&value2
) )
230 if ( !value
.ToLong(&value2
) )
233 wxAnyValueTypeImplInt::SetValue(value2
, dst
);
235 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseUintType
) )
237 wxAnyBaseUintType value2
;
239 if ( !value
.ToULongLong(&value2
) )
241 if ( !value
.ToULong(&value2
) )
244 wxAnyValueTypeImplUint::SetValue(value2
, dst
);
246 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, double) )
249 if ( !value
.ToDouble(&value2
) )
251 wxAnyValueTypeImplDouble::SetValue(value2
, dst
);
253 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, bool) )
257 if ( value
== wxS("true") ||
258 value
== wxS("yes") ||
261 else if ( value
== wxS("false") ||
262 value
== wxS("no") ||
268 wxAnyValueTypeImpl
<bool>::SetValue(value2
, dst
);
276 bool wxAnyValueTypeImpl
<bool>::ConvertValue(const wxAnyValueBuffer
& src
,
277 wxAnyValueType
* dstType
,
278 wxAnyValueBuffer
& dst
) const
280 bool value
= GetValue(src
);
281 if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseIntType
) )
283 wxAnyBaseIntType value2
= static_cast<wxAnyBaseIntType
>(value
);
284 wxAnyValueTypeImplInt::SetValue(value2
, dst
);
286 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseUintType
) )
288 wxAnyBaseIntType value2
= static_cast<wxAnyBaseUintType
>(value
);
289 wxAnyValueTypeImplUint::SetValue(value2
, dst
);
291 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxString
) )
298 wxAnyValueTypeImpl
<wxString
>::SetValue(s
, dst
);
306 bool wxAnyValueTypeImplDouble::ConvertValue(const wxAnyValueBuffer
& src
,
307 wxAnyValueType
* dstType
,
308 wxAnyValueBuffer
& dst
) const
310 double value
= GetValue(src
);
311 if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseIntType
) )
313 if ( value
< UseIntMinF
|| value
> UseIntMaxF
)
315 wxAnyBaseUintType ul
= static_cast<wxAnyBaseUintType
>(value
);
316 wxAnyValueTypeImplUint::SetValue(ul
, dst
);
318 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxAnyBaseUintType
) )
320 if ( value
< 0.0 || value
> UseUintMaxF
)
322 wxAnyBaseUintType ul
= static_cast<wxAnyBaseUintType
>(value
);
323 wxAnyValueTypeImplUint::SetValue(ul
, dst
);
325 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxString
) )
327 wxString s
= wxString::Format(wxS("%.14g"), value
);
328 wxAnyValueTypeImpl
<wxString
>::SetValue(s
, dst
);
336 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplInt
)
337 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplUint
)
338 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplString
)
339 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl
<bool>)
340 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble
)
342 //-------------------------------------------------------------------------
343 // wxAnyNullValueType implementation
344 //-------------------------------------------------------------------------
353 class wxAnyValueTypeImpl
<wxAnyNullValue
> : public wxAnyValueType
355 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl
<wxAnyNullValue
>)
357 virtual void DeleteValue(wxAnyValueBuffer
& buf
) const
359 buf
.m_ptr
= NULL
; // This is important
362 // Dummy implementations
363 virtual void CopyBuffer(const wxAnyValueBuffer
& src
,
364 wxAnyValueBuffer
& dst
) const
370 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
371 wxAnyValueType
* dstType
,
372 wxAnyValueBuffer
& dst
) const
375 wxUnusedVar(dstType
);
383 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl
<wxAnyNullValue
>)
385 wxAnyValueType
* wxAnyNullValueType
=
386 wxAnyValueTypeImpl
<wxAnyNullValue
>::GetInstance();