62f6b45d080fda6885a5ca80d2c938f3703f2aab
[wxWidgets.git] / src / common / any.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/any.cpp
3 // Purpose: wxAny class, container for any type
4 // Author: Jaakko Salli
5 // Modified by:
6 // Created: 07/05/2009
7 // RCS-ID: $Id$
8 // Copyright: (c) wxWidgets team
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx/wx.h".
13 #include "wx/wxprec.h"
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 #include "wx/any.h"
20
21 #if wxUSE_ANY
22
23 #ifndef WX_PRECOMP
24 #include "wx/math.h"
25 #include "wx/crt.h"
26 #endif
27
28 #include "wx/vector.h"
29 #include "wx/module.h"
30
31 using namespace wxPrivate;
32
33 //-------------------------------------------------------------------------
34 // wxAnyValueTypeGlobals
35 //-------------------------------------------------------------------------
36
37 //
38 // Helper class to manage wxAnyValueType instances and other
39 // related global variables.
40 //
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).
45 //
46 class wxAnyValueTypeGlobals
47 {
48 public:
49 wxAnyValueTypeGlobals()
50 {
51 }
52 ~wxAnyValueTypeGlobals()
53 {
54 for ( size_t i=0; i<m_valueTypes.size(); i++ )
55 delete m_valueTypes[i];
56 }
57
58 void RegisterValueType(wxAnyValueType* valueType)
59 {
60 m_valueTypes.push_back(valueType);
61 }
62
63 private:
64 wxVector<wxAnyValueType*> m_valueTypes;
65 };
66
67 static wxAnyValueTypeGlobals* g_wxAnyValueTypeGlobals = NULL;
68
69 //
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.
73 //
74 class wxAnyValueTypeGlobalsManager : public wxModule
75 {
76 DECLARE_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager)
77 public:
78 wxAnyValueTypeGlobalsManager() : wxModule() { }
79 virtual ~wxAnyValueTypeGlobalsManager() { }
80
81 virtual bool OnInit()
82 {
83 return true;
84 }
85 virtual void OnExit()
86 {
87 delete g_wxAnyValueTypeGlobals;
88 g_wxAnyValueTypeGlobals = NULL;
89 }
90 private:
91 };
92
93 IMPLEMENT_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager, wxModule)
94
95
96 //-------------------------------------------------------------------------
97 // wxAnyValueType
98 //-------------------------------------------------------------------------
99
100 wxAnyValueType::wxAnyValueType()
101 {
102 if ( !g_wxAnyValueTypeGlobals )
103 g_wxAnyValueTypeGlobals = new wxAnyValueTypeGlobals();
104
105 g_wxAnyValueTypeGlobals->RegisterValueType(this);
106 }
107
108 //-------------------------------------------------------------------------
109 // wxAny
110 //-------------------------------------------------------------------------
111
112 void wxAny::AssignAny(const wxAny &any)
113 {
114 if ( !any.m_type->IsSameType(m_type) )
115 {
116 m_type->DeleteValue(m_buffer);
117 m_type = any.m_type;
118 }
119 m_type->CopyBuffer(any.m_buffer, m_buffer);
120 }
121
122 //-------------------------------------------------------------------------
123 // Dynamic conversion member functions
124 //-------------------------------------------------------------------------
125
126 //
127 // Define integer minimum and maximum as helpers
128 #ifdef wxLongLong_t
129 const wxAnyBaseIntType UseIntMin = wxINT64_MIN;
130 const wxAnyBaseUintType UseIntMax = wxINT64_MAX;
131 const wxAnyBaseUintType UseUintMax = wxUINT64_MAX;
132 #else
133 const wxAnyBaseIntType UseIntMin = LONG_MIN;
134 const wxAnyBaseUintType UseUintMax = ULONG_MAX;
135 const wxAnyBaseUintType UseIntMax = LONG_MAX;
136 #endif
137
138 const double UseIntMinF = static_cast<double>(UseIntMin);
139 #ifndef __VISUALC6__
140 const double UseIntMaxF = static_cast<double>(UseIntMax);
141 const double UseUintMaxF = static_cast<double>(UseUintMax);
142 #else
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);
148 #endif
149
150
151 bool wxAnyValueTypeImplInt::ConvertValue(const wxAnyValueBuffer& src,
152 wxAnyValueType* dstType,
153 wxAnyValueBuffer& dst) const
154 {
155 wxAnyBaseIntType value = GetValue(src);
156 if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
157 {
158 #ifdef wxLongLong_t
159 wxLongLong ll(value);
160 wxString s = ll.ToString();
161 #else
162 wxString s = wxString::Format(wxS("%ld"), (long)value);
163 #endif
164 wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
165 }
166 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )
167 {
168 if ( value < 0 )
169 return false;
170 wxAnyBaseUintType ul = (wxAnyBaseUintType) value;
171 wxAnyValueTypeImplUint::SetValue(ul, dst);
172 }
173 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) )
174 {
175 double value2 = static_cast<double>(value);
176 wxAnyValueTypeImplDouble::SetValue(value2, dst);
177 }
178 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) )
179 {
180 bool value2 = value ? true : false;
181 wxAnyValueTypeImpl<bool>::SetValue(value2, dst);
182 }
183 else
184 return false;
185
186 return true;
187 }
188
189 bool wxAnyValueTypeImplUint::ConvertValue(const wxAnyValueBuffer& src,
190 wxAnyValueType* dstType,
191 wxAnyValueBuffer& dst) const
192 {
193 wxAnyBaseUintType value = GetValue(src);
194 if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
195 {
196 #ifdef wxLongLong_t
197 wxULongLong ull(value);
198 wxString s = ull.ToString();
199 #else
200 wxString s = wxString::Format(wxS("%lu"), (long)value);
201 #endif
202 wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
203 }
204 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )
205 {
206 if ( value > UseIntMax )
207 return false;
208 wxAnyBaseIntType l = (wxAnyBaseIntType) value;
209 wxAnyValueTypeImplInt::SetValue(l, dst);
210 }
211 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) )
212 {
213 #ifndef __VISUALC6__
214 double value2 = static_cast<double>(value);
215 #else
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);
219 #endif
220 wxAnyValueTypeImplDouble::SetValue(value2, dst);
221 }
222 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) )
223 {
224 bool value2 = value ? true : false;
225 wxAnyValueTypeImpl<bool>::SetValue(value2, dst);
226 }
227 else
228 return false;
229
230 return true;
231 }
232
233 bool wxAnyValueTypeImplString::ConvertValue(const wxAnyValueBuffer& src,
234 wxAnyValueType* dstType,
235 wxAnyValueBuffer& dst) const
236 {
237 wxString value = GetValue(src);
238 if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )
239 {
240 wxAnyBaseIntType value2;
241 #ifdef wxLongLong_t
242 if ( !value.ToLongLong(&value2) )
243 #else
244 if ( !value.ToLong(&value2) )
245 #endif
246 return false;
247 wxAnyValueTypeImplInt::SetValue(value2, dst);
248 }
249 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )
250 {
251 wxAnyBaseUintType value2;
252 #ifdef wxLongLong_t
253 if ( !value.ToULongLong(&value2) )
254 #else
255 if ( !value.ToULong(&value2) )
256 #endif
257 return false;
258 wxAnyValueTypeImplUint::SetValue(value2, dst);
259 }
260 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) )
261 {
262 double value2;
263 if ( !value.ToDouble(&value2) )
264 return false;
265 wxAnyValueTypeImplDouble::SetValue(value2, dst);
266 }
267 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) )
268 {
269 bool value2;
270 value.MakeLower();
271 if ( value == wxS("true") ||
272 value == wxS("yes") ||
273 value == wxS('1') )
274 value2 = true;
275 else if ( value == wxS("false") ||
276 value == wxS("no") ||
277 value == wxS('0') )
278 value2 = false;
279 else
280 return false;
281
282 wxAnyValueTypeImpl<bool>::SetValue(value2, dst);
283 }
284 else
285 return false;
286
287 return true;
288 }
289
290 bool wxAnyValueTypeImpl<bool>::ConvertValue(const wxAnyValueBuffer& src,
291 wxAnyValueType* dstType,
292 wxAnyValueBuffer& dst) const
293 {
294 bool value = GetValue(src);
295 if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )
296 {
297 wxAnyBaseIntType value2 = static_cast<wxAnyBaseIntType>(value);
298 wxAnyValueTypeImplInt::SetValue(value2, dst);
299 }
300 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )
301 {
302 wxAnyBaseIntType value2 = static_cast<wxAnyBaseUintType>(value);
303 wxAnyValueTypeImplUint::SetValue(value2, dst);
304 }
305 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
306 {
307 wxString s;
308 if ( value )
309 s = wxS("true");
310 else
311 s = wxS("false");
312 wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
313 }
314 else
315 return false;
316
317 return true;
318 }
319
320 bool wxAnyValueTypeImplDouble::ConvertValue(const wxAnyValueBuffer& src,
321 wxAnyValueType* dstType,
322 wxAnyValueBuffer& dst) const
323 {
324 double value = GetValue(src);
325 if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )
326 {
327 if ( value < UseIntMinF || value > UseIntMaxF )
328 return false;
329 wxAnyBaseUintType ul = static_cast<wxAnyBaseUintType>(value);
330 wxAnyValueTypeImplUint::SetValue(ul, dst);
331 }
332 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )
333 {
334 if ( value < 0.0 || value > UseUintMaxF )
335 return false;
336 wxAnyBaseUintType ul = static_cast<wxAnyBaseUintType>(value);
337 wxAnyValueTypeImplUint::SetValue(ul, dst);
338 }
339 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
340 {
341 wxString s = wxString::Format(wxS("%.14g"), value);
342 wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
343 }
344 else
345 return false;
346
347 return true;
348 }
349
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)
355
356 //-------------------------------------------------------------------------
357 // wxAnyNullValueType implementation
358 //-------------------------------------------------------------------------
359
360 class wxAnyNullValue
361 {
362 private:
363 void* m_dummy;
364 };
365
366 template <>
367 class wxAnyValueTypeImpl<wxAnyNullValue> : public wxAnyValueType
368 {
369 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxAnyNullValue>)
370 public:
371 virtual void DeleteValue(wxAnyValueBuffer& buf) const
372 {
373 buf.m_ptr = NULL; // This is important
374 }
375
376 // Dummy implementations
377 virtual void CopyBuffer(const wxAnyValueBuffer& src,
378 wxAnyValueBuffer& dst) const
379 {
380 wxUnusedVar(src);
381 wxUnusedVar(dst);
382 }
383
384 virtual bool ConvertValue(const wxAnyValueBuffer& src,
385 wxAnyValueType* dstType,
386 wxAnyValueBuffer& dst) const
387 {
388 wxUnusedVar(src);
389 wxUnusedVar(dstType);
390 wxUnusedVar(dst);
391 return false;
392 }
393
394 private:
395 };
396
397 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxAnyNullValue>)
398
399 wxAnyValueType* wxAnyNullValueType =
400 wxAnyValueTypeImpl<wxAnyNullValue>::GetInstance();
401
402 #endif // wxUSE_ANY