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