Use placement new when storing value in wxAnyValueBuffer. This should allow using...
[wxWidgets.git] / include / wx / any.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/any.h
3 // Purpose: wxAny class
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 #ifndef _WX_ANY_H_
13 #define _WX_ANY_H_
14
15 #include "wx/defs.h"
16
17 #if wxUSE_ANY
18
19 #include <new> // for placement new
20 #include "wx/string.h"
21 #include "wx/meta/if.h"
22 #include "wx/typeinfo.h"
23
24
25 // Size of the wxAny value buffer.
26 enum
27 {
28 WX_ANY_VALUE_BUFFER_SIZE = 16
29 };
30
31 union wxAnyValueBuffer
32 {
33 union Alignment
34 {
35 #if wxHAS_INT64
36 wxInt64 m_int64;
37 #endif
38 long double m_longDouble;
39 void ( *m_funcPtr )(void);
40 void ( wxAnyValueBuffer::*m_mFuncPtr )(void);
41 } m_alignment;
42
43 void* m_ptr;
44 wxByte m_buffer[WX_ANY_VALUE_BUFFER_SIZE];
45 };
46
47 //
48 // wxAnyValueType is base class for value type functionality for C++ data
49 // types used with wxAny. Usually the default template (wxAnyValueTypeImpl<>)
50 // will create a satisfactory wxAnyValueType implementation for a data type.
51 //
52 class WXDLLIMPEXP_BASE wxAnyValueType
53 {
54 WX_DECLARE_ABSTRACT_TYPEINFO(wxAnyValueType)
55 public:
56 /**
57 Default constructor.
58 */
59 wxAnyValueType()
60 {
61 }
62
63 /**
64 Destructor.
65 */
66 virtual ~wxAnyValueType()
67 {
68 }
69
70 /**
71 This function is used for internal type matching.
72 */
73 virtual bool IsSameType(const wxAnyValueType* otherType) const = 0;
74
75 /**
76 This function is called every time the data in wxAny
77 buffer needs to be freed.
78 */
79 virtual void DeleteValue(wxAnyValueBuffer& buf) const = 0;
80
81 /**
82 Implement this for buffer-to-buffer copy.
83
84 @param src
85 This is the source data buffer.
86
87 @param dst
88 This is the destination data buffer that is in either
89 uninitialized or freed state.
90 */
91 virtual void CopyBuffer(const wxAnyValueBuffer& src,
92 wxAnyValueBuffer& dst) const = 0;
93
94 /**
95 Convert value into buffer of different type. Return false if
96 not possible.
97 */
98 virtual bool ConvertValue(const wxAnyValueBuffer& src,
99 wxAnyValueType* dstType,
100 wxAnyValueBuffer& dst) const = 0;
101
102 /**
103 Use this template function for checking if wxAnyValueType represents
104 a specific C++ data type.
105
106 @remarks This template function does not work on some older compilers
107 (such as Visual C++ 6.0). For full compiler ccompatibility
108 please use wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) macro
109 instead.
110
111 @see wxAny::CheckType()
112 */
113 // FIXME-VC6: remove this hack when VC6 is no longer supported
114 template <typename T>
115 bool CheckType(T* reserved = NULL) const;
116 private:
117 };
118
119
120 //
121 // We need to allocate wxAnyValueType instances in heap, and need to use
122 // scoped ptr to properly deallocate them in dynamic library use cases.
123 // Here we have a minimal specialized scoped ptr implementation to deal
124 // with various compiler-specific problems with template class' static
125 // member variable of template type with explicit constructor which
126 // is initialized in global scope.
127 //
128 class wxAnyValueTypeScopedPtr
129 {
130 public:
131 wxAnyValueTypeScopedPtr(wxAnyValueType* ptr) : m_ptr(ptr) { }
132 ~wxAnyValueTypeScopedPtr() { delete m_ptr; }
133 wxAnyValueType* get() const { return m_ptr; }
134 private:
135 wxAnyValueType* m_ptr;
136 };
137
138
139 //
140 // This method of checking the type is compatible with VC6
141 #define wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) \
142 wxAnyValueTypeImpl<T>::IsSameClass(valueTypePtr)
143
144
145 /**
146 Helper macro for defining user value types.
147
148 Even though C++ RTTI would be fully available to use, we'd have to to
149 facilitate sub-type system which allows, for instance, wxAny with
150 signed short '15' to be treated equal to wxAny with signed long long '15'.
151 Having sm_instance is important here.
152
153 NB: We really need to have wxAnyValueType instances allocated
154 in heap. They are stored as static template member variables,
155 and with them we just can't be too careful (eg. not allocating
156 them in heap broke the type identification in GCC).
157 */
158 #define WX_DECLARE_ANY_VALUE_TYPE(CLS) \
159 friend class wxAny; \
160 WX_DECLARE_TYPEINFO_INLINE(CLS) \
161 public: \
162 static bool IsSameClass(const wxAnyValueType* otherType) \
163 { \
164 return wxTypeId(*sm_instance.get()) == wxTypeId(*otherType); \
165 } \
166 virtual bool IsSameType(const wxAnyValueType* otherType) const \
167 { \
168 return IsSameClass(otherType); \
169 } \
170 private: \
171 static wxAnyValueTypeScopedPtr sm_instance; \
172 public: \
173 static wxAnyValueType* GetInstance() \
174 { \
175 return sm_instance.get(); \
176 }
177
178
179 #define WX_IMPLEMENT_ANY_VALUE_TYPE(CLS) \
180 wxAnyValueTypeScopedPtr CLS::sm_instance(new CLS());
181
182
183 #ifdef __VISUALC6__
184 // "non dll-interface class 'xxx' used as base interface
185 #pragma warning (push)
186 #pragma warning (disable:4275)
187 #endif
188
189 /**
190 Following are helper classes for the wxAnyValueTypeImplBase.
191 */
192 namespace wxPrivate
193 {
194
195 template<typename T>
196 class wxAnyValueTypeOpsInplace
197 {
198 public:
199 static void DeleteValue(wxAnyValueBuffer& buf)
200 {
201 T* value = reinterpret_cast<T*>(&buf.m_buffer[0]);
202 value->~T();
203
204 // Some compiler may given 'unused variable' warnings without this
205 wxUnusedVar(value);
206 }
207
208 static void SetValue(const T& value,
209 wxAnyValueBuffer& buf)
210 {
211 // Use placement new
212 void* const place = buf.m_buffer;
213 ::new(place) T(value);
214 }
215
216 static const T& GetValue(const wxAnyValueBuffer& buf)
217 {
218 // Breaking this code into two lines should supress
219 // GCC's 'type-punned pointer will break strict-aliasing rules'
220 // warning.
221 const T* value = reinterpret_cast<const T*>(&buf.m_buffer[0]);
222 return *value;
223 }
224 };
225
226
227 template<typename T>
228 class wxAnyValueTypeOpsGeneric
229 {
230 public:
231 template<typename T2>
232 class DataHolder
233 {
234 public:
235 DataHolder(const T2& value)
236 {
237 m_value = value;
238 }
239 virtual ~DataHolder() { }
240
241 T2 m_value;
242 private:
243 wxDECLARE_NO_COPY_CLASS(DataHolder);
244 };
245
246 static void DeleteValue(wxAnyValueBuffer& buf)
247 {
248 DataHolder<T>* holder = static_cast<DataHolder<T>*>(buf.m_ptr);
249 delete holder;
250 }
251
252 static void SetValue(const T& value,
253 wxAnyValueBuffer& buf)
254 {
255 DataHolder<T>* holder = new DataHolder<T>(value);
256 buf.m_ptr = holder;
257 }
258
259 static const T& GetValue(const wxAnyValueBuffer& buf)
260 {
261 DataHolder<T>* holder = static_cast<DataHolder<T>*>(buf.m_ptr);
262 return holder->m_value;
263 }
264 };
265
266 } // namespace wxPrivate
267
268
269 /**
270 Intermediate template for the generic value type implementation.
271 We can derive from this same value type for multiple actual types
272 (for instance, we can have wxAnyValueTypeImplInt for all signed
273 integer types), and also easily implement specialized templates
274 with specific dynamic type conversion.
275 */
276 template<typename T>
277 class wxAnyValueTypeImplBase : public wxAnyValueType
278 {
279 typedef typename wxIf< sizeof(T) <= WX_ANY_VALUE_BUFFER_SIZE,
280 wxPrivate::wxAnyValueTypeOpsInplace<T>,
281 wxPrivate::wxAnyValueTypeOpsGeneric<T> >::value
282 Ops;
283
284 public:
285 wxAnyValueTypeImplBase() : wxAnyValueType() { }
286 virtual ~wxAnyValueTypeImplBase() { }
287
288 virtual void DeleteValue(wxAnyValueBuffer& buf) const
289 {
290 Ops::DeleteValue(buf);
291 }
292
293 virtual void CopyBuffer(const wxAnyValueBuffer& src,
294 wxAnyValueBuffer& dst) const
295 {
296 Ops::SetValue(Ops::GetValue(src), dst);
297 }
298
299 /**
300 It is important to reimplement this in any specialized template
301 classes that inherit from wxAnyValueTypeImplBase.
302 */
303 static void SetValue(const T& value,
304 wxAnyValueBuffer& buf)
305 {
306 Ops::SetValue(value, buf);
307 }
308
309 /**
310 It is important to reimplement this in any specialized template
311 classes that inherit from wxAnyValueTypeImplBase.
312 */
313 static const T& GetValue(const wxAnyValueBuffer& buf)
314 {
315 return Ops::GetValue(buf);
316 }
317 };
318
319
320 /*
321 Generic value type template. Note that bulk of the implementation
322 resides in wxAnyValueTypeImplBase.
323 */
324 template<typename T>
325 class wxAnyValueTypeImpl : public wxAnyValueTypeImplBase<T>
326 {
327 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<T>)
328 public:
329 wxAnyValueTypeImpl() : wxAnyValueTypeImplBase<T>() { }
330 virtual ~wxAnyValueTypeImpl() { }
331
332 virtual bool ConvertValue(const wxAnyValueBuffer& src,
333 wxAnyValueType* dstType,
334 wxAnyValueBuffer& dst) const
335 {
336 wxUnusedVar(src);
337 wxUnusedVar(dstType);
338 wxUnusedVar(dst);
339 return false;
340 }
341 };
342
343 template<typename T>
344 wxAnyValueTypeScopedPtr wxAnyValueTypeImpl<T>::sm_instance = new wxAnyValueTypeImpl<T>();
345
346
347 //
348 // Helper macro for using same base value type implementation for multiple
349 // actual C++ data types.
350 //
351 #define WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
352 template<> \
353 class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##CLSTYPE \
354 { \
355 typedef wxAnyBase##CLSTYPE##Type UseDataType; \
356 public: \
357 wxAnyValueTypeImpl() : wxAnyValueTypeImpl##CLSTYPE() { } \
358 virtual ~wxAnyValueTypeImpl() { } \
359 static void SetValue(const T& value, wxAnyValueBuffer& buf) \
360 { \
361 void* voidPtr = reinterpret_cast<void*>(&buf.m_buffer[0]); \
362 UseDataType* dptr = reinterpret_cast<UseDataType*>(voidPtr); \
363 *dptr = static_cast<UseDataType>(value); \
364 } \
365 static T GetValue(const wxAnyValueBuffer& buf) \
366 { \
367 const void* voidPtr = \
368 reinterpret_cast<const void*>(&buf.m_buffer[0]); \
369 const UseDataType* sptr = \
370 reinterpret_cast<const UseDataType*>(voidPtr); \
371 return static_cast<T>(*sptr); \
372 } \
373 };
374
375
376 //
377 // Integer value types
378 //
379
380 #ifdef wxLongLong_t
381 typedef wxLongLong_t wxAnyBaseIntType;
382 typedef wxULongLong_t wxAnyBaseUintType;
383 #else
384 typedef long wxAnyBaseIntType;
385 typedef unsigned long wxAnyBaseUintType;
386 #endif
387
388
389 class WXDLLIMPEXP_BASE wxAnyValueTypeImplInt :
390 public wxAnyValueTypeImplBase<wxAnyBaseIntType>
391 {
392 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplInt)
393 public:
394 wxAnyValueTypeImplInt() :
395 wxAnyValueTypeImplBase<wxAnyBaseIntType>() { }
396 virtual ~wxAnyValueTypeImplInt() { }
397
398 virtual bool ConvertValue(const wxAnyValueBuffer& src,
399 wxAnyValueType* dstType,
400 wxAnyValueBuffer& dst) const;
401 };
402
403
404 class WXDLLIMPEXP_BASE wxAnyValueTypeImplUint :
405 public wxAnyValueTypeImplBase<wxAnyBaseUintType>
406 {
407 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplUint)
408 public:
409 wxAnyValueTypeImplUint() :
410 wxAnyValueTypeImplBase<wxAnyBaseUintType>() { }
411 virtual ~wxAnyValueTypeImplUint() { }
412
413 virtual bool ConvertValue(const wxAnyValueBuffer& src,
414 wxAnyValueType* dstType,
415 wxAnyValueBuffer& dst) const;
416 };
417
418
419 WX_ANY_DEFINE_SUB_TYPE(signed long, Int)
420 WX_ANY_DEFINE_SUB_TYPE(signed int, Int)
421 WX_ANY_DEFINE_SUB_TYPE(signed short, Int)
422 WX_ANY_DEFINE_SUB_TYPE(signed char, Int)
423 #ifdef wxLongLong_t
424 WX_ANY_DEFINE_SUB_TYPE(wxLongLong_t, Int)
425 #endif
426
427 WX_ANY_DEFINE_SUB_TYPE(unsigned long, Uint)
428 WX_ANY_DEFINE_SUB_TYPE(unsigned int, Uint)
429 WX_ANY_DEFINE_SUB_TYPE(unsigned short, Uint)
430 WX_ANY_DEFINE_SUB_TYPE(unsigned char, Uint)
431 #ifdef wxLongLong_t
432 WX_ANY_DEFINE_SUB_TYPE(wxULongLong_t, Uint)
433 #endif
434
435
436 //
437 // This macro is used in header, but then in source file we must have:
438 // WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl##TYPENAME)
439 //
440 #define _WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, GV) \
441 class WXDLLIMPEXP_BASE wxAnyValueTypeImpl##TYPENAME : \
442 public wxAnyValueTypeImplBase<T> \
443 { \
444 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl##TYPENAME) \
445 public: \
446 wxAnyValueTypeImpl##TYPENAME() : \
447 wxAnyValueTypeImplBase<T>() { } \
448 virtual ~wxAnyValueTypeImpl##TYPENAME() { } \
449 virtual bool ConvertValue(const wxAnyValueBuffer& src, \
450 wxAnyValueType* dstType, \
451 wxAnyValueBuffer& dst) const \
452 { \
453 GV value = GetValue(src); \
454 return CONVFUNC(value, dstType, dst); \
455 } \
456 }; \
457 template<> \
458 class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##TYPENAME \
459 { \
460 public: \
461 wxAnyValueTypeImpl() : wxAnyValueTypeImpl##TYPENAME() { } \
462 virtual ~wxAnyValueTypeImpl() { } \
463 };
464
465 #define WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, BT) \
466 _WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, BT) \
467
468 #define WX_ANY_DEFINE_CONVERTIBLE_TYPE_BASE(T, TYPENAME, CONVFUNC) \
469 _WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, \
470 CONVFUNC, const T&) \
471
472 //
473 // String value type
474 //
475
476 // Convert wxString to destination wxAny value type
477 extern WXDLLIMPEXP_BASE bool wxAnyConvertString(const wxString& value,
478 wxAnyValueType* dstType,
479 wxAnyValueBuffer& dst);
480
481 WX_ANY_DEFINE_CONVERTIBLE_TYPE_BASE(wxString, wxString, wxAnyConvertString)
482 WX_ANY_DEFINE_CONVERTIBLE_TYPE(const char*, ConstCharPtr,
483 wxAnyConvertString, wxString)
484 WX_ANY_DEFINE_CONVERTIBLE_TYPE(const wchar_t*, ConstWchar_tPtr,
485 wxAnyConvertString, wxString)
486
487 //
488 // Bool value type
489 //
490 template<>
491 class WXDLLIMPEXP_BASE wxAnyValueTypeImpl<bool> :
492 public wxAnyValueTypeImplBase<bool>
493 {
494 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<bool>)
495 public:
496 wxAnyValueTypeImpl() :
497 wxAnyValueTypeImplBase<bool>() { }
498 virtual ~wxAnyValueTypeImpl() { }
499
500 virtual bool ConvertValue(const wxAnyValueBuffer& src,
501 wxAnyValueType* dstType,
502 wxAnyValueBuffer& dst) const;
503 };
504
505 //
506 // Floating point value type
507 //
508 class WXDLLIMPEXP_BASE wxAnyValueTypeImplDouble :
509 public wxAnyValueTypeImplBase<double>
510 {
511 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble)
512 public:
513 wxAnyValueTypeImplDouble() :
514 wxAnyValueTypeImplBase<double>() { }
515 virtual ~wxAnyValueTypeImplDouble() { }
516
517 virtual bool ConvertValue(const wxAnyValueBuffer& src,
518 wxAnyValueType* dstType,
519 wxAnyValueBuffer& dst) const;
520 };
521
522 // WX_ANY_DEFINE_SUB_TYPE requires this
523 typedef double wxAnyBaseDoubleType;
524
525 WX_ANY_DEFINE_SUB_TYPE(float, Double)
526 WX_ANY_DEFINE_SUB_TYPE(double, Double)
527
528
529 //
530 // Defines a dummy wxAnyValueTypeImpl<> with given export
531 // declaration. This is needed if a class is used with
532 // wxAny in both user shared library and application.
533 //
534 #define wxDECLARE_ANY_TYPE(CLS, DECL) \
535 template<> \
536 class DECL wxAnyValueTypeImpl<CLS> : \
537 public wxAnyValueTypeImplBase<CLS> \
538 { \
539 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<CLS>) \
540 public: \
541 wxAnyValueTypeImpl() : \
542 wxAnyValueTypeImplBase<CLS>() { } \
543 virtual ~wxAnyValueTypeImpl() { } \
544 \
545 virtual bool ConvertValue(const wxAnyValueBuffer& src, \
546 wxAnyValueType* dstType, \
547 wxAnyValueBuffer& dst) const \
548 { \
549 wxUnusedVar(src); \
550 wxUnusedVar(dstType); \
551 wxUnusedVar(dst); \
552 return false; \
553 } \
554 };
555
556
557 // Make sure some of wx's own types get the right wxAnyValueType export
558 // (this is needed only for types that are referred to from wxBase.
559 // currently we may not use any of these types from there, but let's
560 // use the macro on at least one to make sure it compiles since we can't
561 // really test it properly in unittests since a separate DLL would
562 // be needed).
563 #if wxUSE_DATETIME
564 #include "wx/datetime.h"
565 wxDECLARE_ANY_TYPE(wxDateTime, WXDLLIMPEXP_BASE)
566 #endif
567
568 //#include "wx/object.h"
569 //wxDECLARE_ANY_TYPE(wxObject*, WXDLLIMPEXP_BASE)
570
571 //#include "wx/arrstr.h"
572 //wxDECLARE_ANY_TYPE(wxArrayString, WXDLLIMPEXP_BASE)
573
574
575 #if wxUSE_VARIANT
576
577 class WXDLLIMPEXP_FWD_BASE wxAnyToVariantRegistration;
578
579 // Because of header inter-dependencies, cannot include this earlier
580 #include "wx/variant.h"
581
582 //
583 // wxVariantData* data type implementation. For cases when appropriate
584 // wxAny<->wxVariant conversion code is missing.
585 //
586
587 class WXDLLIMPEXP_BASE wxAnyValueTypeImplVariantData :
588 public wxAnyValueTypeImplBase<wxVariantData*>
589 {
590 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplVariantData)
591 public:
592 wxAnyValueTypeImplVariantData() :
593 wxAnyValueTypeImplBase<wxVariantData*>() { }
594 virtual ~wxAnyValueTypeImplVariantData() { }
595
596 virtual void DeleteValue(wxAnyValueBuffer& buf) const
597 {
598 wxVariantData* data = static_cast<wxVariantData*>(buf.m_ptr);
599 if ( data )
600 data->DecRef();
601 }
602
603 virtual void CopyBuffer(const wxAnyValueBuffer& src,
604 wxAnyValueBuffer& dst) const
605 {
606 wxVariantData* data = static_cast<wxVariantData*>(src.m_ptr);
607 if ( data )
608 data->IncRef();
609 dst.m_ptr = data;
610 }
611
612 static void SetValue(wxVariantData* value,
613 wxAnyValueBuffer& buf)
614 {
615 value->IncRef();
616 buf.m_ptr = value;
617 }
618
619 static wxVariantData* GetValue(const wxAnyValueBuffer& buf)
620 {
621 return static_cast<wxVariantData*>(buf.m_ptr);
622 }
623
624 virtual bool ConvertValue(const wxAnyValueBuffer& src,
625 wxAnyValueType* dstType,
626 wxAnyValueBuffer& dst) const
627 {
628 wxUnusedVar(src);
629 wxUnusedVar(dstType);
630 wxUnusedVar(dst);
631 return false;
632 }
633 };
634
635 template<>
636 class wxAnyValueTypeImpl<wxVariantData*> :
637 public wxAnyValueTypeImplVariantData
638 {
639 public:
640 wxAnyValueTypeImpl() : wxAnyValueTypeImplVariantData() { }
641 virtual ~wxAnyValueTypeImpl() { }
642 };
643
644 #endif // wxUSE_VARIANT
645
646 #ifdef __VISUALC6__
647 // Re-enable useless VC6 warnings
648 #pragma warning (pop)
649 #endif
650
651
652 /*
653 Let's define a discrete Null value so we don't have to really
654 ever check if wxAny.m_type pointer is NULL or not. This is an
655 optimization, mostly. Implementation of this value type is
656 "hidden" in the source file.
657 */
658 extern WXDLLIMPEXP_DATA_BASE(wxAnyValueType*) wxAnyNullValueType;
659
660
661 //
662 // We need to implement custom signed/unsigned int equals operators
663 // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
664 #define WXANY_IMPLEMENT_INT_EQ_OP(TS, TUS) \
665 bool operator==(TS value) const \
666 { \
667 if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
668 return (value == static_cast<TS> \
669 (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
670 if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
671 return (value == static_cast<TS> \
672 (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
673 return false; \
674 } \
675 bool operator==(TUS value) const \
676 { \
677 if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
678 return (value == static_cast<TUS> \
679 (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
680 if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
681 return (value == static_cast<TUS> \
682 (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
683 return false; \
684 }
685
686
687 #if wxUSE_VARIANT
688
689 // Note that the following functions are implemented outside wxAny class
690 // so that it can reside entirely in header and lack the export declaration.
691
692 // Helper function used to associate wxAnyValueType with a wxVariantData.
693 extern WXDLLIMPEXP_BASE void
694 wxPreRegisterAnyToVariant(wxAnyToVariantRegistration* reg);
695
696 // This function performs main wxAny to wxVariant conversion duties.
697 extern WXDLLIMPEXP_BASE bool
698 wxConvertAnyToVariant(const wxAny& any, wxVariant* variant);
699
700 #endif // wxUSE_VARIANT
701
702
703 //
704 // The wxAny class represents a container for any type. A variant's value
705 // can be changed at run time, possibly to a different type of value.
706 //
707 // As standard, wxAny can store value of almost any type, in a fairly
708 // optimal manner even.
709 //
710 class wxAny
711 {
712 public:
713 /**
714 Default constructor.
715 */
716 wxAny()
717 {
718 m_type = wxAnyNullValueType;
719 }
720
721 /**
722 Destructor.
723 */
724 ~wxAny()
725 {
726 m_type->DeleteValue(m_buffer);
727 }
728
729 //@{
730 /**
731 Various constructors.
732 */
733 template<typename T>
734 wxAny(const T& value)
735 {
736 m_type = wxAnyValueTypeImpl<T>::sm_instance.get();
737 wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
738 }
739
740 // These two constructors are needed to deal with string literals
741 wxAny(const char* value)
742 {
743 m_type = wxAnyValueTypeImpl<const char*>::sm_instance.get();
744 wxAnyValueTypeImpl<const char*>::SetValue(value, m_buffer);
745 }
746 wxAny(const wchar_t* value)
747 {
748 m_type = wxAnyValueTypeImpl<const wchar_t*>::sm_instance.get();
749 wxAnyValueTypeImpl<const wchar_t*>::SetValue(value, m_buffer);
750 }
751
752 wxAny(const wxAny& any)
753 {
754 m_type = wxAnyNullValueType;
755 AssignAny(any);
756 }
757
758 #if wxUSE_VARIANT
759 wxAny(const wxVariant& variant)
760 {
761 m_type = wxAnyNullValueType;
762 AssignVariant(variant);
763 }
764 #endif
765
766 //@}
767
768 /**
769 Use this template function for checking if this wxAny holds
770 a specific C++ data type.
771
772 @remarks This template function does not work on some older compilers
773 (such as Visual C++ 6.0). For full compiler ccompatibility
774 please use wxANY_CHECK_TYPE(any, T) macro instead.
775
776 @see wxAnyValueType::CheckType()
777 */
778 // FIXME-VC6: remove this hack when VC6 is no longer supported
779 template <typename T>
780 bool CheckType(T* = NULL) const
781 {
782 return m_type->CheckType<T>();
783 }
784
785 /**
786 Returns the value type as wxAnyValueType instance.
787
788 @remarks You cannot reliably test whether two wxAnys are of
789 same value type by simply comparing return values
790 of wxAny::GetType(). Instead use
791 wxAnyValueType::CheckType<T>() template function.
792 */
793 const wxAnyValueType* GetType() const
794 {
795 return m_type;
796 }
797
798 /**
799 Tests if wxAny is null (that is, whether there is data).
800 */
801 bool IsNull() const
802 {
803 return (m_type == wxAnyNullValueType);
804 }
805
806 /**
807 Makes wxAny null (that is, clears it).
808 */
809 void MakeNull()
810 {
811 m_type->DeleteValue(m_buffer);
812 m_type = wxAnyNullValueType;
813 }
814
815 //@{
816 /**
817 Assignment operators.
818 */
819 template<typename T>
820 wxAny& operator=(const T &value)
821 {
822 m_type->DeleteValue(m_buffer);
823 m_type = wxAnyValueTypeImpl<T>::sm_instance.get();
824 wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
825 return *this;
826 }
827
828 wxAny& operator=(const wxAny &any)
829 {
830 if (this != &any)
831 AssignAny(any);
832 return *this;
833 }
834
835 #if wxUSE_VARIANT
836 wxAny& operator=(const wxVariant &variant)
837 {
838 AssignVariant(variant);
839 return *this;
840 }
841 #endif
842
843 // These two operators are needed to deal with string literals
844 wxAny& operator=(const char* value)
845 {
846 Assign(value);
847 return *this;
848 }
849 wxAny& operator=(const wchar_t* value)
850 {
851 Assign(value);
852 return *this;
853 }
854
855 //@{
856 /**
857 Equality operators.
858 */
859 bool operator==(const wxString& value) const
860 {
861 wxString value2;
862 if ( !GetAs(&value2) )
863 return false;
864 return value == value2;
865 }
866
867 bool operator==(const char* value) const
868 { return (*this) == wxString(value); }
869 bool operator==(const wchar_t* value) const
870 { return (*this) == wxString(value); }
871
872 //
873 // We need to implement custom signed/unsigned int equals operators
874 // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
875 WXANY_IMPLEMENT_INT_EQ_OP(signed char, unsigned char)
876 WXANY_IMPLEMENT_INT_EQ_OP(signed short, unsigned short)
877 WXANY_IMPLEMENT_INT_EQ_OP(signed int, unsigned int)
878 WXANY_IMPLEMENT_INT_EQ_OP(signed long, unsigned long)
879 #ifdef wxLongLong_t
880 WXANY_IMPLEMENT_INT_EQ_OP(wxLongLong_t, wxULongLong_t)
881 #endif
882
883 bool operator==(float value) const
884 {
885 if ( !wxAnyValueTypeImpl<float>::IsSameClass(m_type) )
886 return false;
887
888 return value ==
889 static_cast<float>
890 (wxAnyValueTypeImpl<float>::GetValue(m_buffer));
891 }
892
893 bool operator==(double value) const
894 {
895 if ( !wxAnyValueTypeImpl<double>::IsSameClass(m_type) )
896 return false;
897
898 return value ==
899 static_cast<double>
900 (wxAnyValueTypeImpl<double>::GetValue(m_buffer));
901 }
902
903 bool operator==(bool value) const
904 {
905 if ( !wxAnyValueTypeImpl<bool>::IsSameClass(m_type) )
906 return false;
907
908 return value == (wxAnyValueTypeImpl<bool>::GetValue(m_buffer));
909 }
910
911 //@}
912
913 //@{
914 /**
915 Inequality operators (implement as template).
916 */
917 template<typename T>
918 bool operator!=(const T& value) const
919 { return !((*this) == value); }
920 //@}
921
922 /**
923 This template function converts wxAny into given type. In most cases
924 no type conversion is performed, so if the type is incorrect an
925 assertion failure will occur.
926
927 @remarks For conveniency, conversion is done when T is wxString. This
928 is useful when a string literal (which are treated as
929 const char* and const wchar_t*) has been assigned to wxAny.
930
931 This template function may not work properly with Visual C++
932 6. For full compiler compatibility, please use
933 wxANY_AS(any, T) macro instead.
934 */
935 // FIXME-VC6: remove this hack when VC6 is no longer supported
936 template<typename T>
937 T As(T* = NULL) const
938 {
939 if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )
940 {
941 wxFAIL_MSG("Incorrect or non-convertible data type");
942 }
943
944 return static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(m_buffer));
945 }
946
947 // Allow easy conversion from 'const char *' etc. to wxString
948 // FIXME-VC6: remove this hack when VC6 is no longer supported
949 //template<>
950 wxString As(wxString*) const
951 {
952 wxString value;
953 if ( !GetAs(&value) )
954 {
955 wxFAIL_MSG("Incorrect or non-convertible data type");
956 }
957 return value;
958 }
959
960 /**
961 Template function that etrieves and converts the value of this
962 variant to the type that T* value is.
963
964 @return Returns @true if conversion was succesfull.
965 */
966 template<typename T>
967 bool GetAs(T* value) const
968 {
969 if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )
970 {
971 wxAnyValueType* otherType =
972 wxAnyValueTypeImpl<T>::sm_instance.get();
973 wxAnyValueBuffer temp_buf;
974
975 if ( !m_type->ConvertValue(m_buffer, otherType, temp_buf) )
976 return false;
977
978 *value =
979 static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(temp_buf));
980 otherType->DeleteValue(temp_buf);
981
982 return true;
983 }
984 *value = static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(m_buffer));
985 return true;
986 }
987
988 #if wxUSE_VARIANT
989 // GetAs() wxVariant specialization
990 bool GetAs(wxVariant* value) const
991 {
992 return wxConvertAnyToVariant(*this, value);
993 }
994 #endif
995
996 private:
997 // Assignment functions
998 void AssignAny(const wxAny& any)
999 {
1000 // Must delete value - CopyBuffer() never does that
1001 m_type->DeleteValue(m_buffer);
1002
1003 wxAnyValueType* newType = any.m_type;
1004
1005 if ( !newType->IsSameType(m_type) )
1006 m_type = newType;
1007
1008 newType->CopyBuffer(any.m_buffer, m_buffer);
1009 }
1010
1011 #if wxUSE_VARIANT
1012 void AssignVariant(const wxVariant& variant)
1013 {
1014 wxVariantData* data = variant.GetData();
1015
1016 if ( data && data->GetAsAny(this) )
1017 return;
1018
1019 m_type->DeleteValue(m_buffer);
1020
1021 if ( variant.IsNull() )
1022 {
1023 // Init as Null
1024 m_type = wxAnyNullValueType;
1025 }
1026 else
1027 {
1028 // If everything else fails, wrap the whole wxVariantData
1029 m_type = wxAnyValueTypeImpl<wxVariantData*>::sm_instance.get();
1030 wxAnyValueTypeImpl<wxVariantData*>::SetValue(data, m_buffer);
1031 }
1032 }
1033 #endif
1034
1035 template<typename T>
1036 void Assign(const T &value)
1037 {
1038 m_type->DeleteValue(m_buffer);
1039 m_type = wxAnyValueTypeImpl<T>::sm_instance.get();
1040 wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
1041 }
1042
1043 // Data
1044 wxAnyValueBuffer m_buffer;
1045 wxAnyValueType* m_type;
1046 };
1047
1048
1049 //
1050 // This method of checking the type is compatible with VC6
1051 #define wxANY_CHECK_TYPE(any, T) \
1052 wxANY_VALUE_TYPE_CHECK_TYPE((any).GetType(), T)
1053
1054
1055 //
1056 // This method of getting the value is compatible with VC6
1057 #define wxANY_AS(any, T) \
1058 (any).As(static_cast<T*>(NULL))
1059
1060
1061 template<typename T>
1062 inline bool wxAnyValueType::CheckType(T* reserved) const
1063 {
1064 wxUnusedVar(reserved);
1065 return wxAnyValueTypeImpl<T>::IsSameClass(this);
1066 }
1067
1068
1069
1070 #endif // wxUSE_ANY
1071
1072 #endif // _WX_ANY_H_