Added wxDECLARE_ANY_TYPE(CLS, DECL) and documented for what kind of situation it...
[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 "wx/string.h"
20 #include "wx/meta/movable.h"
21 #include "wx/meta/if.h"
22
23
24 // Size of the wxAny value buffer.
25 enum
26 {
27 WX_ANY_VALUE_BUFFER_SIZE = 16
28 };
29
30 union wxAnyValueBuffer
31 {
32 union Alignment
33 {
34 #if wxHAS_INT64
35 wxInt64 m_int64;
36 #endif
37 long double m_longDouble;
38 void ( *m_funcPtr )(void);
39 void ( wxAnyValueBuffer::*m_mFuncPtr )(void);
40 } m_alignment;
41
42 void* m_ptr;
43 wxByte m_buffer[WX_ANY_VALUE_BUFFER_SIZE];
44 };
45
46 typedef void (*wxAnyClassInfo)();
47
48
49 //
50 // wxAnyValueType is base class for value type functionality for C++ data
51 // types used with wxAny. Usually the default template (wxAnyValueTypeImpl<>)
52 // will create a satisfactory wxAnyValueType implementation for a data type.
53 //
54 class WXDLLIMPEXP_BASE wxAnyValueType
55 {
56 public:
57 /**
58 Default constructor.
59 */
60 wxAnyValueType();
61
62 /**
63 Destructor.
64 */
65 virtual ~wxAnyValueType()
66 {
67 }
68
69 /**
70 This function is used for internal type matching.
71 */
72 virtual wxAnyClassInfo GetClassInfo() const = 0;
73
74 /**
75 This function is used for internal type matching.
76 */
77 virtual bool IsSameType(const wxAnyValueType* otherType) const = 0;
78
79 /**
80 This function is called every time the data in wxAny
81 buffer needs to be freed.
82 */
83 virtual void DeleteValue(wxAnyValueBuffer& buf) const = 0;
84
85 /**
86 Implement this for buffer-to-buffer copy.
87
88 @param src
89 This is the source data buffer.
90
91 @param dst
92 This is the destination data buffer that is in either
93 uninitialized or freed state.
94 */
95 virtual void CopyBuffer(const wxAnyValueBuffer& src,
96 wxAnyValueBuffer& dst) const = 0;
97
98 /**
99 Convert value into buffer of different type. Return false if
100 not possible.
101 */
102 virtual bool ConvertValue(const wxAnyValueBuffer& src,
103 wxAnyValueType* dstType,
104 wxAnyValueBuffer& dst) const = 0;
105
106 /**
107 Use this template function for checking if wxAnyValueType represents
108 a specific C++ data type.
109
110 @remarks This template function does not work on some older compilers
111 (such as Visual C++ 6.0). For full compiler ccompatibility
112 please use wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) macro
113 instead.
114
115 @see wxAny::CheckType()
116 */
117 // FIXME-VC6: remove this hack when VC6 is no longer supported
118 template <typename T>
119 bool CheckType(T* reserved = NULL);
120 private:
121 };
122
123 //
124 // This method of checking the type is compatible with VC6
125 #define wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) \
126 wxAnyValueTypeImpl<T>::IsSameClass(valueTypePtr)
127
128 //valueTypePtr->CheckType(static_cast<T*>(NULL))
129
130
131 /**
132 Helper macro for defining user value types.
133
134 NB: We really cannot compare sm_classInfo directly in IsSameClass(),
135 but instead call sm_instance->GetClassInfo(). The former technique
136 broke at least on GCC 4.2 (but worked on VC8 shared build).
137 */
138 #define WX_DECLARE_ANY_VALUE_TYPE(CLS) \
139 friend class wxAny; \
140 public: \
141 static void sm_classInfo() {} \
142 \
143 virtual wxAnyClassInfo GetClassInfo() const \
144 { \
145 return sm_classInfo; \
146 } \
147 static bool IsSameClass(const wxAnyValueType* otherType) \
148 { \
149 return sm_instance->GetClassInfo() == otherType->GetClassInfo(); \
150 } \
151 virtual bool IsSameType(const wxAnyValueType* otherType) const \
152 { \
153 return IsSameClass(otherType); \
154 } \
155 private: \
156 static CLS* sm_instance; \
157 public: \
158 static wxAnyValueType* GetInstance() \
159 { \
160 return sm_instance; \
161 }
162
163
164 #define WX_IMPLEMENT_ANY_VALUE_TYPE(CLS) \
165 CLS* CLS::sm_instance = new CLS();
166
167
168 #ifdef __VISUALC6__
169 // "non dll-interface class 'xxx' used as base interface
170 #pragma warning (push)
171 #pragma warning (disable:4275)
172 #endif
173
174 /**
175 Following are helper classes for the wxAnyValueTypeImplBase.
176 */
177 namespace wxPrivate
178 {
179
180 template<typename T>
181 class wxAnyValueTypeOpsMovable
182 {
183 public:
184 static void DeleteValue(wxAnyValueBuffer& buf)
185 {
186 wxUnusedVar(buf);
187 }
188
189 static void SetValue(const T& value,
190 wxAnyValueBuffer& buf)
191 {
192 memcpy(buf.m_buffer, &value, sizeof(T));
193 }
194
195 static const T& GetValue(const wxAnyValueBuffer& buf)
196 {
197 return *(reinterpret_cast<const T*>(&buf.m_buffer[0]));
198 }
199 };
200
201
202 template<typename T>
203 class wxAnyValueTypeOpsGeneric
204 {
205 public:
206 template<typename T2>
207 class DataHolder
208 {
209 public:
210 DataHolder(const T2& value)
211 {
212 m_value = value;
213 }
214 virtual ~DataHolder() { }
215
216 T2 m_value;
217 private:
218 wxDECLARE_NO_COPY_CLASS(DataHolder);
219 };
220
221 static void DeleteValue(wxAnyValueBuffer& buf)
222 {
223 DataHolder<T>* holder = static_cast<DataHolder<T>*>(buf.m_ptr);
224 delete holder;
225 }
226
227 static void SetValue(const T& value,
228 wxAnyValueBuffer& buf)
229 {
230 DataHolder<T>* holder = new DataHolder<T>(value);
231 buf.m_ptr = holder;
232 }
233
234 static const T& GetValue(const wxAnyValueBuffer& buf)
235 {
236 DataHolder<T>* holder = static_cast<DataHolder<T>*>(buf.m_ptr);
237 return holder->m_value;
238 }
239 };
240
241 } // namespace wxPrivate
242
243
244 /**
245 Intermediate template for the generic value type implementation.
246 We can derive from this same value type for multiple actual types
247 (for instance, we can have wxAnyValueTypeImplInt for all signed
248 integer types), and also easily implement specialized templates
249 with specific dynamic type conversion.
250 */
251 template<typename T>
252 class wxAnyValueTypeImplBase : public wxAnyValueType
253 {
254 typedef typename wxIf< wxIsMovable<T>::value &&
255 sizeof(T) <= WX_ANY_VALUE_BUFFER_SIZE,
256 wxPrivate::wxAnyValueTypeOpsMovable<T>,
257 wxPrivate::wxAnyValueTypeOpsGeneric<T> >::value
258 Ops;
259
260 public:
261 wxAnyValueTypeImplBase() : wxAnyValueType() { }
262 virtual ~wxAnyValueTypeImplBase() { }
263
264 virtual void DeleteValue(wxAnyValueBuffer& buf) const
265 {
266 Ops::DeleteValue(buf);
267 }
268
269 virtual void CopyBuffer(const wxAnyValueBuffer& src,
270 wxAnyValueBuffer& dst) const
271 {
272 Ops::SetValue(Ops::GetValue(src), dst);
273 }
274
275 /**
276 It is important to reimplement this in any specialized template
277 classes that inherit from wxAnyValueTypeImplBase.
278 */
279 static void SetValue(const T& value,
280 wxAnyValueBuffer& buf)
281 {
282 Ops::SetValue(value, buf);
283 }
284
285 /**
286 It is important to reimplement this in any specialized template
287 classes that inherit from wxAnyValueTypeImplBase.
288 */
289 static const T& GetValue(const wxAnyValueBuffer& buf)
290 {
291 return Ops::GetValue(buf);
292 }
293 };
294
295
296 /*
297 Generic value type template. Note that bulk of the implementation
298 resides in wxAnyValueTypeImplBase.
299 */
300 template<typename T>
301 class wxAnyValueTypeImpl : public wxAnyValueTypeImplBase<T>
302 {
303 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<T>)
304 public:
305 wxAnyValueTypeImpl() : wxAnyValueTypeImplBase<T>() { }
306 virtual ~wxAnyValueTypeImpl() { }
307
308 virtual bool ConvertValue(const wxAnyValueBuffer& src,
309 wxAnyValueType* dstType,
310 wxAnyValueBuffer& dst) const
311 {
312 wxUnusedVar(src);
313 wxUnusedVar(dstType);
314 wxUnusedVar(dst);
315 return false;
316 }
317 };
318
319 template<typename T>
320 wxAnyValueTypeImpl<T>* wxAnyValueTypeImpl<T>::sm_instance =
321 new wxAnyValueTypeImpl<T>();
322
323
324 //
325 // Helper macro for using same base value type implementation for multiple
326 // actual C++ data types.
327 //
328 #define WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
329 template<> \
330 class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##CLSTYPE \
331 { \
332 typedef wxAnyBase##CLSTYPE##Type UseDataType; \
333 public: \
334 wxAnyValueTypeImpl() : wxAnyValueTypeImpl##CLSTYPE() { } \
335 virtual ~wxAnyValueTypeImpl() { } \
336 static void SetValue(const T& value, wxAnyValueBuffer& buf) \
337 { \
338 *(reinterpret_cast<UseDataType*>(&buf.m_buffer[0])) = \
339 static_cast<UseDataType>(value); \
340 } \
341 static T GetValue(const wxAnyValueBuffer& buf) \
342 { \
343 return static_cast<T>( \
344 *(reinterpret_cast<const UseDataType*>(&buf.m_buffer[0]))); \
345 } \
346 };
347
348
349 //
350 // Integer value types
351 //
352
353 #ifdef wxLongLong_t
354 typedef wxLongLong_t wxAnyBaseIntType;
355 typedef wxULongLong_t wxAnyBaseUintType;
356 #else
357 typedef long wxAnyBaseIntType;
358 typedef unsigned long wxAnyBaseUintType;
359 #endif
360
361
362 class WXDLLIMPEXP_BASE wxAnyValueTypeImplInt :
363 public wxAnyValueTypeImplBase<wxAnyBaseIntType>
364 {
365 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplInt)
366 public:
367 wxAnyValueTypeImplInt() :
368 wxAnyValueTypeImplBase<wxAnyBaseIntType>() { }
369 virtual ~wxAnyValueTypeImplInt() { }
370
371 virtual bool ConvertValue(const wxAnyValueBuffer& src,
372 wxAnyValueType* dstType,
373 wxAnyValueBuffer& dst) const;
374 };
375
376
377 class WXDLLIMPEXP_BASE wxAnyValueTypeImplUint :
378 public wxAnyValueTypeImplBase<wxAnyBaseUintType>
379 {
380 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplUint)
381 public:
382 wxAnyValueTypeImplUint() :
383 wxAnyValueTypeImplBase<wxAnyBaseUintType>() { }
384 virtual ~wxAnyValueTypeImplUint() { }
385
386 virtual bool ConvertValue(const wxAnyValueBuffer& src,
387 wxAnyValueType* dstType,
388 wxAnyValueBuffer& dst) const;
389 };
390
391
392 WX_ANY_DEFINE_SUB_TYPE(signed long, Int)
393 WX_ANY_DEFINE_SUB_TYPE(signed int, Int)
394 WX_ANY_DEFINE_SUB_TYPE(signed short, Int)
395 WX_ANY_DEFINE_SUB_TYPE(signed char, Int)
396 #ifdef wxLongLong_t
397 WX_ANY_DEFINE_SUB_TYPE(wxLongLong_t, Int)
398 #endif
399
400 WX_ANY_DEFINE_SUB_TYPE(unsigned long, Uint)
401 WX_ANY_DEFINE_SUB_TYPE(unsigned int, Uint)
402 WX_ANY_DEFINE_SUB_TYPE(unsigned short, Uint)
403 WX_ANY_DEFINE_SUB_TYPE(unsigned char, Uint)
404 #ifdef wxLongLong_t
405 WX_ANY_DEFINE_SUB_TYPE(wxULongLong_t, Uint)
406 #endif
407
408
409 //
410 // String value type
411 //
412 class WXDLLIMPEXP_BASE wxAnyValueTypeImplString :
413 public wxAnyValueTypeImplBase<wxString>
414 {
415 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplString)
416 public:
417 wxAnyValueTypeImplString() :
418 wxAnyValueTypeImplBase<wxString>() { }
419 virtual ~wxAnyValueTypeImplString() { }
420
421 /**
422 Convert value into buffer of different type. Return false if
423 not possible.
424 */
425 virtual bool ConvertValue(const wxAnyValueBuffer& src,
426 wxAnyValueType* dstType,
427 wxAnyValueBuffer& dst) const;
428
429 };
430
431 template<>
432 class wxAnyValueTypeImpl<wxString> : public wxAnyValueTypeImplString
433 {
434 public:
435 wxAnyValueTypeImpl() : wxAnyValueTypeImplString() { }
436 virtual ~wxAnyValueTypeImpl() { }
437 };
438
439
440 //
441 // Bool value type
442 //
443 template<>
444 class WXDLLIMPEXP_BASE wxAnyValueTypeImpl<bool> :
445 public wxAnyValueTypeImplBase<bool>
446 {
447 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<bool>)
448 public:
449 wxAnyValueTypeImpl() :
450 wxAnyValueTypeImplBase<bool>() { }
451 virtual ~wxAnyValueTypeImpl() { }
452
453 virtual bool ConvertValue(const wxAnyValueBuffer& src,
454 wxAnyValueType* dstType,
455 wxAnyValueBuffer& dst) const;
456 };
457
458 //
459 // Floating point value type
460 //
461 class WXDLLIMPEXP_BASE wxAnyValueTypeImplDouble :
462 public wxAnyValueTypeImplBase<double>
463 {
464 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble)
465 public:
466 wxAnyValueTypeImplDouble() :
467 wxAnyValueTypeImplBase<double>() { }
468 virtual ~wxAnyValueTypeImplDouble() { }
469
470 virtual bool ConvertValue(const wxAnyValueBuffer& src,
471 wxAnyValueType* dstType,
472 wxAnyValueBuffer& dst) const;
473 };
474
475 // WX_ANY_DEFINE_SUB_TYPE requires this
476 typedef double wxAnyBaseDoubleType;
477
478 WX_ANY_DEFINE_SUB_TYPE(float, Double)
479 WX_ANY_DEFINE_SUB_TYPE(double, Double)
480
481
482 //
483 // Defines a dummy wxAnyValueTypeImpl<> with given export
484 // declaration. This is needed if a class is used with
485 // wxAny in both user shared library and application.
486 //
487 #define wxDECLARE_ANY_TYPE(CLS, DECL) \
488 template<> \
489 class DECL wxAnyValueTypeImpl<CLS> : \
490 public wxAnyValueTypeImplBase<CLS> \
491 { \
492 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<CLS>) \
493 public: \
494 wxAnyValueTypeImpl() : \
495 wxAnyValueTypeImplBase<CLS>() { } \
496 virtual ~wxAnyValueTypeImpl() { } \
497 \
498 virtual bool ConvertValue(const wxAnyValueBuffer& src, \
499 wxAnyValueType* dstType, \
500 wxAnyValueBuffer& dst) const \
501 { \
502 wxUnusedVar(src); \
503 wxUnusedVar(dstType); \
504 wxUnusedVar(dst); \
505 return false; \
506 } \
507 };
508
509
510 // Make sure some of wx's own types get the right wxAnyValueType export
511 // (this is needed only for types that are referred to from wxBase.
512 // currently we may not use any of these types from there, but let's
513 // use the macro on at least one to make sure it compiles since we can't
514 // really test it properly in unittests since a separate DLL would
515 // be needed).
516 #if wxUSE_DATETIME
517 #include "wx/datetime.h"
518 wxDECLARE_ANY_TYPE(wxDateTime, WXDLLIMPEXP_BASE)
519 #endif
520
521 //#include "wx/object.h"
522 //wxDECLARE_ANY_TYPE(wxObject*, WXDLLIMPEXP_BASE)
523
524 //#include "wx/arrstr.h"
525 //wxDECLARE_ANY_TYPE(wxArrayString, WXDLLIMPEXP_BASE)
526
527
528
529 #ifdef __VISUALC6__
530 // Re-enable useless VC6 warnings
531 #pragma warning (pop)
532 #endif
533
534
535 /*
536 Let's define a discrete Null value so we don't have to really
537 ever check if wxAny.m_type pointer is NULL or not. This is an
538 optimization, mostly. Implementation of this value type is
539 "hidden" in the source file.
540 */
541 extern WXDLLIMPEXP_DATA_BASE(wxAnyValueType*) wxAnyNullValueType;
542
543
544 //
545 // We need to implement custom signed/unsigned int equals operators
546 // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
547 #define WXANY_IMPLEMENT_INT_EQ_OP(TS, TUS) \
548 bool operator==(TS value) const \
549 { \
550 if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
551 return (value == static_cast<TS> \
552 (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
553 if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
554 return (value == static_cast<TS> \
555 (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
556 return false; \
557 } \
558 bool operator==(TUS value) const \
559 { \
560 if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
561 return (value == static_cast<TUS> \
562 (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
563 if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
564 return (value == static_cast<TUS> \
565 (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
566 return false; \
567 }
568
569
570 //
571 // The wxAny class represents a container for any type. A variant's value
572 // can be changed at run time, possibly to a different type of value.
573 //
574 // As standard, wxAny can store value of almost any type, in a fairly
575 // optimal manner even.
576 //
577 class wxAny
578 {
579 public:
580 /**
581 Default constructor.
582 */
583 wxAny()
584 {
585 m_type = wxAnyNullValueType;
586 }
587
588 /**
589 Destructor.
590 */
591 ~wxAny()
592 {
593 m_type->DeleteValue(m_buffer);
594 }
595
596 //@{
597 /**
598 Various constructors.
599 */
600 wxAny(const char* value)
601 {
602 m_type = wxAnyNullValueType;
603 Assign(wxString(value));
604 }
605 wxAny(const wchar_t* value)
606 {
607 m_type = wxAnyNullValueType;
608 Assign(wxString(value));
609 }
610
611 wxAny(const wxAny& any)
612 {
613 m_type = wxAnyNullValueType;
614 AssignAny(any);
615 }
616
617 template<typename T>
618 wxAny(const T& value)
619 {
620 m_type = wxAnyValueTypeImpl<T>::sm_instance;
621 wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
622 }
623 //@}
624
625 /**
626 Use this template function for checking if this wxAny holds
627 a specific C++ data type.
628
629 @remarks This template function does not work on some older compilers
630 (such as Visual C++ 6.0). For full compiler ccompatibility
631 please use wxANY_CHECK_TYPE(any, T) macro instead.
632
633 @see wxAnyValueType::CheckType()
634 */
635 // FIXME-VC6: remove this hack when VC6 is no longer supported
636 template <typename T>
637 bool CheckType(T* = NULL)
638 {
639 return m_type->CheckType<T>();
640 }
641
642 /**
643 Returns the value type as wxAnyValueType instance.
644
645 @remarks You cannot reliably test whether two wxAnys are of
646 same value type by simply comparing return values
647 of wxAny::GetType(). Instead use
648 wxAnyValueType::CheckType<T>() template function.
649 */
650 const wxAnyValueType* GetType() const
651 {
652 return m_type;
653 }
654
655 /**
656 Tests if wxAny is null (that is, whether there is data).
657 */
658 bool IsNull() const
659 {
660 return (m_type == wxAnyNullValueType);
661 }
662
663 /**
664 Makes wxAny null (that is, clears it).
665 */
666 void MakeNull()
667 {
668 m_type->DeleteValue(m_buffer);
669 m_type = wxAnyNullValueType;
670 }
671
672 //@{
673 /**
674 Assignment operators.
675 */
676 wxAny& operator=(const wxAny &any)
677 {
678 AssignAny(any);
679 return *this;
680 }
681
682 template<typename T>
683 wxAny& operator=(const T &value)
684 {
685 m_type->DeleteValue(m_buffer);
686 m_type = wxAnyValueTypeImpl<T>::sm_instance;
687 wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
688 return *this;
689 }
690
691 wxAny& operator=(const char* value)
692 { Assign(wxString(value)); return *this; }
693 wxAny& operator=(const wchar_t* value)
694 { Assign(wxString(value)); return *this; }
695 //@}
696
697 //@{
698 /**
699 Equality operators.
700 */
701 bool operator==(const wxString& value) const
702 {
703 if ( !wxAnyValueTypeImpl<wxString>::IsSameClass(m_type) )
704 return false;
705
706 return value ==
707 static_cast<wxString>
708 (wxAnyValueTypeImpl<wxString>::GetValue(m_buffer));
709 }
710
711 bool operator==(const char* value) const
712 { return (*this) == wxString(value); }
713 bool operator==(const wchar_t* value) const
714 { return (*this) == wxString(value); }
715
716 //
717 // We need to implement custom signed/unsigned int equals operators
718 // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
719 WXANY_IMPLEMENT_INT_EQ_OP(signed char, unsigned char)
720 WXANY_IMPLEMENT_INT_EQ_OP(signed short, unsigned short)
721 WXANY_IMPLEMENT_INT_EQ_OP(signed int, unsigned int)
722 WXANY_IMPLEMENT_INT_EQ_OP(signed long, unsigned long)
723 #ifdef wxLongLong_t
724 WXANY_IMPLEMENT_INT_EQ_OP(wxLongLong_t, wxULongLong_t)
725 #endif
726
727 bool operator==(float value) const
728 {
729 if ( !wxAnyValueTypeImpl<float>::IsSameClass(m_type) )
730 return false;
731
732 return value ==
733 static_cast<float>
734 (wxAnyValueTypeImpl<float>::GetValue(m_buffer));
735 }
736
737 bool operator==(double value) const
738 {
739 if ( !wxAnyValueTypeImpl<double>::IsSameClass(m_type) )
740 return false;
741
742 return value ==
743 static_cast<double>
744 (wxAnyValueTypeImpl<double>::GetValue(m_buffer));
745 }
746
747 bool operator==(bool value) const
748 {
749 if ( !wxAnyValueTypeImpl<bool>::IsSameClass(m_type) )
750 return false;
751
752 return value == (wxAnyValueTypeImpl<bool>::GetValue(m_buffer));
753 }
754
755 //@}
756
757 //@{
758 /**
759 Inequality operators (implement as template).
760 */
761 template<typename T>
762 bool operator!=(const T& value) const
763 { return !((*this) == value); }
764 //@}
765
766 /**
767 This template function converts wxAny into given type. No dynamic
768 conversion is performed, so if the type is incorrect an assertion
769 failure will occur in debug builds, and a bogus value is returned
770 in release ones.
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_AS(any, T) macro instead.
775 */
776 // FIXME-VC6: remove this hack when VC6 is no longer supported
777 template<typename T>
778 T As(T* = NULL) const
779 {
780 if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )
781 {
782 wxFAIL_MSG("Incorrect or non-convertible data type");
783 }
784
785 return static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(m_buffer));
786 }
787
788 /**
789 Template function that etrieves and converts the value of this
790 variant to the type that T* value is.
791
792 @return Returns @true if conversion was succesfull.
793 */
794 template<typename T>
795 bool GetAs(T* value) const
796 {
797 if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )
798 {
799 wxAnyValueType* otherType =
800 wxAnyValueTypeImpl<T>::sm_instance;
801 wxAnyValueBuffer temp_buf;
802
803 if ( !m_type->ConvertValue(m_buffer, otherType, temp_buf) )
804 return false;
805
806 *value =
807 static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(temp_buf));
808 otherType->DeleteValue(temp_buf);
809
810 return true;
811 }
812 *value = static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(m_buffer));
813 return true;
814 }
815
816 private:
817 // Assignment functions
818 void AssignAny(const wxAny& any)
819 {
820 // Must delete value - CopyBuffer() never does that
821 m_type->DeleteValue(m_buffer);
822
823 wxAnyValueType* newType = any.m_type;
824
825 if ( !newType->IsSameType(m_type) )
826 m_type = newType;
827
828 newType->CopyBuffer(any.m_buffer, m_buffer);
829 }
830
831 template<typename T>
832 void Assign(const T &value)
833 {
834 m_type->DeleteValue(m_buffer);
835 m_type = wxAnyValueTypeImpl<T>::sm_instance;
836 wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
837 }
838
839 // Data
840 wxAnyValueBuffer m_buffer;
841 wxAnyValueType* m_type;
842 };
843
844
845 //
846 // This method of checking the type is compatible with VC6
847 #define wxANY_CHECK_TYPE(any, T) \
848 wxANY_VALUE_TYPE_CHECK_TYPE(any.GetType(), T)
849
850
851 //
852 // This method of getting the value is compatible with VC6
853 #define wxANY_AS(any, T) \
854 any.As(static_cast<T*>(NULL))
855
856
857 template<typename T>
858 inline bool wxAnyValueType::CheckType(T* reserved)
859 {
860 wxUnusedVar(reserved);
861 return wxAnyValueTypeImpl<T>::IsSameClass(this);
862 }
863
864
865
866 #endif // wxUSE_ANY
867
868 #endif // _WX_ANY_H_