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