Use const_cast<> to get 'wxAnyValueType*' from 'const wxAnyValueType*'
[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 #include "wx/hashmap.h"
31
32 using namespace wxPrivate;
33
34 //-------------------------------------------------------------------------
35 // wxAnyValueTypeGlobals
36 //-------------------------------------------------------------------------
37
38 #if wxUSE_VARIANT
39
40 WX_DECLARE_HASH_MAP(wxAnyValueType*,
41 wxVariantDataFactory,
42 wxPointerHash,
43 wxPointerEqual,
44 wxAnyTypeToVariantDataFactoryMap);
45
46 #endif
47
48 //
49 // Helper class to manage wxAnyValueType instances and and other
50 // related global variables (such as wxAny<->wxVariant type association).
51 //
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).
56 //
57 class wxAnyValueTypeGlobals
58 {
59 public:
60 wxAnyValueTypeGlobals()
61 {
62 }
63 ~wxAnyValueTypeGlobals()
64 {
65 #if wxUSE_VARIANT
66 m_anyToVariant.clear();
67 #endif
68 for ( size_t i=0; i<m_valueTypes.size(); i++ )
69 delete m_valueTypes[i];
70 }
71
72 void RegisterValueType(wxAnyValueType* valueType)
73 {
74 m_valueTypes.push_back(valueType);
75 }
76
77 #if wxUSE_VARIANT
78 void PreRegisterAnyToVariant(wxAnyToVariantRegistration* reg)
79 {
80 m_anyToVariantRegs.push_back(reg);
81 }
82
83 // Find wxVariantData factory function for given value type,
84 // (or compatible, if possible)
85 wxVariantDataFactory FindVariantDataFactory(const wxAnyValueType* type_)
86 {
87 // Ideally we'd have the hash map of type 'const wxAnyValueType*',
88 // but WX_DECLARE_HASH_MAP() has some trouble with it.
89 wxAnyValueType* type = const_cast<wxAnyValueType*>(type_);
90
91 wxAnyTypeToVariantDataFactoryMap& anyToVariant = m_anyToVariant;
92 wxAnyTypeToVariantDataFactoryMap::const_iterator it;
93 it = anyToVariant.find(type);
94 if ( it != anyToVariant.end() )
95 return it->second;
96
97 // Not found, handle pre-registrations
98 size_t i = m_anyToVariantRegs.size();
99 while ( i > 0 )
100 {
101 i--;
102 wxAnyToVariantRegistration* reg = m_anyToVariantRegs[i];
103 wxAnyValueType* assocType = reg->GetAssociatedType();
104 if ( assocType )
105 {
106 // Both variant data and wxAnyValueType have been
107 // now been properly initialized, so remove the
108 // pre-registration entry and move data to anyToVarian
109 // map.
110 anyToVariant[assocType] = reg->GetFactory();
111 m_anyToVariantRegs.erase( m_anyToVariantRegs.begin() + i );
112 }
113 }
114
115 // Then try again
116 it = anyToVariant.find(type);
117 if ( it != anyToVariant.end() )
118 return it->second;
119
120 // Finally, attempt to find a compatible type
121 for ( it = anyToVariant.begin(); it != anyToVariant.end(); it++ )
122 {
123 if ( type->IsSameType(it->first) )
124 {
125 wxVariantDataFactory f = it->second;
126 anyToVariant[type] = f;
127 return f;
128 }
129 }
130
131 // Nothing found
132 return NULL;
133 }
134 #endif
135
136 private:
137 wxVector<wxAnyValueType*> m_valueTypes;
138 #if wxUSE_VARIANT
139 wxAnyTypeToVariantDataFactoryMap m_anyToVariant;
140 wxVector<wxAnyToVariantRegistration*> m_anyToVariantRegs;
141 #endif
142 };
143
144 static wxAnyValueTypeGlobals* g_wxAnyValueTypeGlobals = NULL;
145
146 #if wxUSE_VARIANT
147
148 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplVariantData)
149
150 void wxPreRegisterAnyToVariant(wxAnyToVariantRegistration* reg)
151 {
152 if ( !g_wxAnyValueTypeGlobals )
153 g_wxAnyValueTypeGlobals = new wxAnyValueTypeGlobals();
154 g_wxAnyValueTypeGlobals->PreRegisterAnyToVariant(reg);
155 }
156
157 bool wxConvertAnyToVariant(const wxAny& any, wxVariant* variant)
158 {
159 if ( any.IsNull() )
160 {
161 variant->MakeNull();
162 return true;
163 }
164
165 // (signed) integer is a special case, because there is only one type
166 // in wxAny, and two ("long" and "longlong") in wxVariant. For better
167 // backwards compatibility, convert all values that fit in "long",
168 // and others to "longlong".
169 if ( wxANY_CHECK_TYPE(any, signed int) )
170 {
171 #ifdef wxLongLong_t
172 wxLongLong_t ll = 0;
173 if ( any.GetAs(&ll) )
174 {
175 if ( ll > LONG_MAX )
176 *variant = wxLongLong(ll);
177 else
178 *variant = (long) wxLongLong(ll).GetLo();
179 }
180 else
181 {
182 return false;
183 }
184 #else
185 long l;
186 if ( any.GetAs(&l) )
187 *variant = l;
188 else
189 return false;
190 #endif
191 return true;
192 }
193
194 // Find matching factory function
195 wxVariantDataFactory f =
196 g_wxAnyValueTypeGlobals->FindVariantDataFactory(any.GetType());
197
198 wxVariantData* data = NULL;
199
200 if ( f )
201 {
202 data = f(any);
203 }
204 else
205 {
206 // Check if wxAny wrapped wxVariantData*
207 if ( !any.GetAs(&data) )
208 {
209 // Ok, one last chance: while unlikely, it is possible that the
210 // wxAny actually contains wxVariant.
211 if ( wxANY_CHECK_TYPE(any, wxVariant) )
212 *variant = wxANY_AS(any, wxVariant);
213 return false;
214 }
215
216 // Wrapper's GetValue() does not increase reference
217 // count, se have to do it before the data gets passed
218 // to a new variant.
219 data->IncRef();
220 }
221
222 variant->SetData(data);
223 return true;
224 }
225
226 #endif // wxUSE_VARIANT
227
228 //
229 // This class is to make sure that wxAnyValueType instances
230 // etc. get freed correctly. We must use a separate wxAnyValueTypeGlobals
231 // because wxModule itself is instantiated too late.
232 //
233 class wxAnyValueTypeGlobalsManager : public wxModule
234 {
235 DECLARE_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager)
236 public:
237 wxAnyValueTypeGlobalsManager() : wxModule() { }
238 virtual ~wxAnyValueTypeGlobalsManager() { }
239
240 virtual bool OnInit()
241 {
242 return true;
243 }
244 virtual void OnExit()
245 {
246 delete g_wxAnyValueTypeGlobals;
247 g_wxAnyValueTypeGlobals = NULL;
248 }
249 private:
250 };
251
252 IMPLEMENT_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager, wxModule)
253
254
255 //-------------------------------------------------------------------------
256 // wxAnyValueType
257 //-------------------------------------------------------------------------
258
259 wxAnyValueType::wxAnyValueType()
260 {
261 if ( !g_wxAnyValueTypeGlobals )
262 g_wxAnyValueTypeGlobals = new wxAnyValueTypeGlobals();
263
264 g_wxAnyValueTypeGlobals->RegisterValueType(this);
265 }
266
267 //-------------------------------------------------------------------------
268 // Dynamic conversion member functions
269 //-------------------------------------------------------------------------
270
271 //
272 // Define integer minimum and maximum as helpers
273 #ifdef wxLongLong_t
274 #define UseIntMin (wxINT64_MIN)
275 #define UseIntMax (wxINT64_MAX)
276 #define UseUintMax (wxUINT64_MAX)
277 #else
278 #define UseIntMin (LONG_MIN)
279 #define UseIntMax (LONG_MAX)
280 #define UseUintMax (ULONG_MAX)
281 #endif
282
283 namespace
284 {
285
286 const double UseIntMinF = static_cast<double>(UseIntMin);
287 const double UseIntMaxF = static_cast<double>(UseIntMax);
288 const double UseUintMaxF = static_cast<double>(UseUintMax);
289
290 } // anonymous namespace
291
292 bool wxAnyValueTypeImplInt::ConvertValue(const wxAnyValueBuffer& src,
293 wxAnyValueType* dstType,
294 wxAnyValueBuffer& dst) const
295 {
296 wxAnyBaseIntType value = GetValue(src);
297 if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
298 {
299 #ifdef wxLongLong_t
300 wxLongLong ll(value);
301 wxString s = ll.ToString();
302 #else
303 wxString s = wxString::Format(wxS("%ld"), (long)value);
304 #endif
305 wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
306 }
307 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )
308 {
309 if ( value < 0 )
310 return false;
311 wxAnyBaseUintType ul = (wxAnyBaseUintType) value;
312 wxAnyValueTypeImplUint::SetValue(ul, dst);
313 }
314 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) )
315 {
316 double value2 = static_cast<double>(value);
317 wxAnyValueTypeImplDouble::SetValue(value2, dst);
318 }
319 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) )
320 {
321 bool value2 = value ? true : false;
322 wxAnyValueTypeImpl<bool>::SetValue(value2, dst);
323 }
324 else
325 return false;
326
327 return true;
328 }
329
330 bool wxAnyValueTypeImplUint::ConvertValue(const wxAnyValueBuffer& src,
331 wxAnyValueType* dstType,
332 wxAnyValueBuffer& dst) const
333 {
334 wxAnyBaseUintType value = GetValue(src);
335 if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
336 {
337 #ifdef wxLongLong_t
338 wxULongLong ull(value);
339 wxString s = ull.ToString();
340 #else
341 wxString s = wxString::Format(wxS("%lu"), (long)value);
342 #endif
343 wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
344 }
345 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )
346 {
347 if ( value > UseIntMax )
348 return false;
349 wxAnyBaseIntType l = (wxAnyBaseIntType) value;
350 wxAnyValueTypeImplInt::SetValue(l, dst);
351 }
352 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) )
353 {
354 #ifndef __VISUALC6__
355 double value2 = static_cast<double>(value);
356 #else
357 // VC6 doesn't implement conversion from unsigned __int64 to double
358 wxAnyBaseIntType value0 = static_cast<wxAnyBaseIntType>(value);
359 double value2 = static_cast<double>(value0);
360 #endif
361 wxAnyValueTypeImplDouble::SetValue(value2, dst);
362 }
363 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) )
364 {
365 bool value2 = value ? true : false;
366 wxAnyValueTypeImpl<bool>::SetValue(value2, dst);
367 }
368 else
369 return false;
370
371 return true;
372 }
373
374 bool wxAnyValueTypeImplString::ConvertValue(const wxAnyValueBuffer& src,
375 wxAnyValueType* dstType,
376 wxAnyValueBuffer& dst) const
377 {
378 wxString value = GetValue(src);
379 if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )
380 {
381 wxAnyBaseIntType value2;
382 #ifdef wxLongLong_t
383 if ( !value.ToLongLong(&value2) )
384 #else
385 if ( !value.ToLong(&value2) )
386 #endif
387 return false;
388 wxAnyValueTypeImplInt::SetValue(value2, dst);
389 }
390 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )
391 {
392 wxAnyBaseUintType value2;
393 #ifdef wxLongLong_t
394 if ( !value.ToULongLong(&value2) )
395 #else
396 if ( !value.ToULong(&value2) )
397 #endif
398 return false;
399 wxAnyValueTypeImplUint::SetValue(value2, dst);
400 }
401 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) )
402 {
403 double value2;
404 if ( !value.ToDouble(&value2) )
405 return false;
406 wxAnyValueTypeImplDouble::SetValue(value2, dst);
407 }
408 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) )
409 {
410 bool value2;
411 value.MakeLower();
412 if ( value == wxS("true") ||
413 value == wxS("yes") ||
414 value == wxS('1') )
415 value2 = true;
416 else if ( value == wxS("false") ||
417 value == wxS("no") ||
418 value == wxS('0') )
419 value2 = false;
420 else
421 return false;
422
423 wxAnyValueTypeImpl<bool>::SetValue(value2, dst);
424 }
425 else
426 return false;
427
428 return true;
429 }
430
431 bool wxAnyValueTypeImpl<bool>::ConvertValue(const wxAnyValueBuffer& src,
432 wxAnyValueType* dstType,
433 wxAnyValueBuffer& dst) const
434 {
435 bool value = GetValue(src);
436 if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )
437 {
438 wxAnyBaseIntType value2 = static_cast<wxAnyBaseIntType>(value);
439 wxAnyValueTypeImplInt::SetValue(value2, dst);
440 }
441 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )
442 {
443 wxAnyBaseIntType value2 = static_cast<wxAnyBaseUintType>(value);
444 wxAnyValueTypeImplUint::SetValue(value2, dst);
445 }
446 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
447 {
448 wxString s;
449 if ( value )
450 s = wxS("true");
451 else
452 s = wxS("false");
453 wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
454 }
455 else
456 return false;
457
458 return true;
459 }
460
461 bool wxAnyValueTypeImplDouble::ConvertValue(const wxAnyValueBuffer& src,
462 wxAnyValueType* dstType,
463 wxAnyValueBuffer& dst) const
464 {
465 double value = GetValue(src);
466 if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )
467 {
468 if ( value < UseIntMinF || value > UseIntMaxF )
469 return false;
470 wxAnyBaseUintType ul = static_cast<wxAnyBaseUintType>(value);
471 wxAnyValueTypeImplUint::SetValue(ul, dst);
472 }
473 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )
474 {
475 if ( value < 0.0 || value > UseUintMaxF )
476 return false;
477 wxAnyBaseUintType ul = static_cast<wxAnyBaseUintType>(value);
478 wxAnyValueTypeImplUint::SetValue(ul, dst);
479 }
480 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
481 {
482 wxString s = wxString::Format(wxS("%.14g"), value);
483 wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
484 }
485 else
486 return false;
487
488 return true;
489 }
490
491 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplInt)
492 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplUint)
493 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplString)
494 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<bool>)
495 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble)
496
497 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxDateTime>)
498 //WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxObject*>)
499 //WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxArrayString>)
500
501 //-------------------------------------------------------------------------
502 // wxAnyNullValueType implementation
503 //-------------------------------------------------------------------------
504
505 class wxAnyNullValue
506 {
507 private:
508 void* m_dummy;
509 };
510
511 template <>
512 class wxAnyValueTypeImpl<wxAnyNullValue> : public wxAnyValueType
513 {
514 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxAnyNullValue>)
515 public:
516 // Dummy implementations
517 virtual void DeleteValue(wxAnyValueBuffer& buf) const
518 {
519 wxUnusedVar(buf);
520 }
521
522 virtual void CopyBuffer(const wxAnyValueBuffer& src,
523 wxAnyValueBuffer& dst) const
524 {
525 wxUnusedVar(src);
526 wxUnusedVar(dst);
527 }
528
529 virtual bool ConvertValue(const wxAnyValueBuffer& src,
530 wxAnyValueType* dstType,
531 wxAnyValueBuffer& dst) const
532 {
533 wxUnusedVar(src);
534 wxUnusedVar(dstType);
535 wxUnusedVar(dst);
536 return false;
537 }
538
539 private:
540 };
541
542 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxAnyNullValue>)
543
544 wxAnyValueType* wxAnyNullValueType =
545 wxAnyValueTypeImpl<wxAnyNullValue>::GetInstance();
546
547 #endif // wxUSE_ANY