Removed dst buffer delete responsibility from wxAnyValueType::CopyBuffer(), clarified...
[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 #ifdef __VISUALC6__
483 // Re-enable useless VC6 warnings
484 #pragma warning (pop)
485 #endif
486
487
488 /*
489 Let's define a discrete Null value so we don't have to really
490 ever check if wxAny.m_type pointer is NULL or not. This is an
491 optimization, mostly. Implementation of this value type is
492 "hidden" in the source file.
493 */
494 extern WXDLLIMPEXP_DATA_BASE(wxAnyValueType*) wxAnyNullValueType;
495
496
497 //
498 // We need to implement custom signed/unsigned int equals operators
499 // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
500 #define WXANY_IMPLEMENT_INT_EQ_OP(TS, TUS) \
501 bool operator==(TS value) const \
502 { \
503 if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
504 return (value == static_cast<TS> \
505 (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
506 if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
507 return (value == static_cast<TS> \
508 (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
509 return false; \
510 } \
511 bool operator==(TUS value) const \
512 { \
513 if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
514 return (value == static_cast<TUS> \
515 (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
516 if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
517 return (value == static_cast<TUS> \
518 (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
519 return false; \
520 }
521
522
523 //
524 // The wxAny class represents a container for any type. A variant's value
525 // can be changed at run time, possibly to a different type of value.
526 //
527 // As standard, wxAny can store value of almost any type, in a fairly
528 // optimal manner even.
529 //
530 class wxAny
531 {
532 public:
533 /**
534 Default constructor.
535 */
536 wxAny()
537 {
538 m_type = wxAnyNullValueType;
539 }
540
541 /**
542 Destructor.
543 */
544 ~wxAny()
545 {
546 m_type->DeleteValue(m_buffer);
547 }
548
549 //@{
550 /**
551 Various constructors.
552 */
553 wxAny(const char* value)
554 {
555 m_type = wxAnyNullValueType;
556 Assign(wxString(value));
557 }
558 wxAny(const wchar_t* value)
559 {
560 m_type = wxAnyNullValueType;
561 Assign(wxString(value));
562 }
563
564 wxAny(const wxAny& any)
565 {
566 m_type = wxAnyNullValueType;
567 AssignAny(any);
568 }
569
570 template<typename T>
571 wxAny(const T& value)
572 {
573 m_type = wxAnyValueTypeImpl<T>::sm_instance;
574 wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
575 }
576 //@}
577
578 /**
579 Use this template function for checking if this wxAny holds
580 a specific C++ data type.
581
582 @remarks This template function does not work on some older compilers
583 (such as Visual C++ 6.0). For full compiler ccompatibility
584 please use wxANY_CHECK_TYPE(any, T) macro instead.
585
586 @see wxAnyValueType::CheckType()
587 */
588 // FIXME-VC6: remove this hack when VC6 is no longer supported
589 template <typename T>
590 bool CheckType(T* = NULL)
591 {
592 return m_type->CheckType<T>();
593 }
594
595 /**
596 Returns the value type as wxAnyValueType instance.
597
598 @remarks You cannot reliably test whether two wxAnys are of
599 same value type by simply comparing return values
600 of wxAny::GetType(). Instead use
601 wxAnyValueType::CheckType<T>() template function.
602 */
603 const wxAnyValueType* GetType() const
604 {
605 return m_type;
606 }
607
608 /**
609 Tests if wxAny is null (that is, whether there is data).
610 */
611 bool IsNull() const
612 {
613 return (m_type == wxAnyNullValueType);
614 }
615
616 /**
617 Makes wxAny null (that is, clears it).
618 */
619 void MakeNull()
620 {
621 m_type->DeleteValue(m_buffer);
622 m_type = wxAnyNullValueType;
623 }
624
625 //@{
626 /**
627 Assignment operators.
628 */
629 wxAny& operator=(const wxAny &any)
630 {
631 AssignAny(any);
632 return *this;
633 }
634
635 template<typename T>
636 wxAny& operator=(const T &value)
637 {
638 m_type->DeleteValue(m_buffer);
639 m_type = wxAnyValueTypeImpl<T>::sm_instance;
640 wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
641 return *this;
642 }
643
644 wxAny& operator=(const char* value)
645 { Assign(wxString(value)); return *this; }
646 wxAny& operator=(const wchar_t* value)
647 { Assign(wxString(value)); return *this; }
648 //@}
649
650 //@{
651 /**
652 Equality operators.
653 */
654 bool operator==(const wxString& value) const
655 {
656 if ( !wxAnyValueTypeImpl<wxString>::IsSameClass(m_type) )
657 return false;
658
659 return value ==
660 static_cast<wxString>
661 (wxAnyValueTypeImpl<wxString>::GetValue(m_buffer));
662 }
663
664 bool operator==(const char* value) const
665 { return (*this) == wxString(value); }
666 bool operator==(const wchar_t* value) const
667 { return (*this) == wxString(value); }
668
669 //
670 // We need to implement custom signed/unsigned int equals operators
671 // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
672 WXANY_IMPLEMENT_INT_EQ_OP(signed char, unsigned char)
673 WXANY_IMPLEMENT_INT_EQ_OP(signed short, unsigned short)
674 WXANY_IMPLEMENT_INT_EQ_OP(signed int, unsigned int)
675 WXANY_IMPLEMENT_INT_EQ_OP(signed long, unsigned long)
676 #ifdef wxLongLong_t
677 WXANY_IMPLEMENT_INT_EQ_OP(wxLongLong_t, wxULongLong_t)
678 #endif
679
680 bool operator==(float value) const
681 {
682 if ( !wxAnyValueTypeImpl<float>::IsSameClass(m_type) )
683 return false;
684
685 return value ==
686 static_cast<float>
687 (wxAnyValueTypeImpl<float>::GetValue(m_buffer));
688 }
689
690 bool operator==(double value) const
691 {
692 if ( !wxAnyValueTypeImpl<double>::IsSameClass(m_type) )
693 return false;
694
695 return value ==
696 static_cast<double>
697 (wxAnyValueTypeImpl<double>::GetValue(m_buffer));
698 }
699
700 bool operator==(bool value) const
701 {
702 if ( !wxAnyValueTypeImpl<bool>::IsSameClass(m_type) )
703 return false;
704
705 return value == (wxAnyValueTypeImpl<bool>::GetValue(m_buffer));
706 }
707
708 //@}
709
710 //@{
711 /**
712 Inequality operators (implement as template).
713 */
714 template<typename T>
715 bool operator!=(const T& value) const
716 { return !((*this) == value); }
717 //@}
718
719 /**
720 This template function converts wxAny into given type. No dynamic
721 conversion is performed, so if the type is incorrect an assertion
722 failure will occur in debug builds, and a bogus value is returned
723 in release ones.
724
725 @remarks This template function does not work on some older compilers
726 (such as Visual C++ 6.0). For full compiler ccompatibility
727 please use wxANY_AS(any, T) macro instead.
728 */
729 // FIXME-VC6: remove this hack when VC6 is no longer supported
730 template<typename T>
731 T As(T* = NULL) const
732 {
733 if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )
734 {
735 wxFAIL_MSG("Incorrect or non-convertible data type");
736 }
737
738 return static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(m_buffer));
739 }
740
741 /**
742 Template function that etrieves and converts the value of this
743 variant to the type that T* value is.
744
745 @return Returns @true if conversion was succesfull.
746 */
747 template<typename T>
748 bool GetAs(T* value) const
749 {
750 if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )
751 {
752 wxAnyValueType* otherType =
753 wxAnyValueTypeImpl<T>::sm_instance;
754 wxAnyValueBuffer temp_buf;
755
756 if ( !m_type->ConvertValue(m_buffer, otherType, temp_buf) )
757 return false;
758
759 *value =
760 static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(temp_buf));
761 otherType->DeleteValue(temp_buf);
762
763 return true;
764 }
765 *value = static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(m_buffer));
766 return true;
767 }
768
769 private:
770 // Assignment functions
771 void AssignAny(const wxAny& any)
772 {
773 // Must delete value - CopyBuffer() never does that
774 m_type->DeleteValue(m_buffer);
775
776 wxAnyValueType* newType = any.m_type;
777
778 if ( !newType->IsSameType(m_type) )
779 m_type = newType;
780
781 newType->CopyBuffer(any.m_buffer, m_buffer);
782 }
783
784 template<typename T>
785 void Assign(const T &value)
786 {
787 m_type->DeleteValue(m_buffer);
788 m_type = wxAnyValueTypeImpl<T>::sm_instance;
789 wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
790 }
791
792 // Data
793 wxAnyValueBuffer m_buffer;
794 wxAnyValueType* m_type;
795 };
796
797
798 //
799 // This method of checking the type is compatible with VC6
800 #define wxANY_CHECK_TYPE(any, T) \
801 wxANY_VALUE_TYPE_CHECK_TYPE(any.GetType(), T)
802
803
804 //
805 // This method of getting the value is compatible with VC6
806 #define wxANY_AS(any, T) \
807 any.As(static_cast<T*>(NULL))
808
809
810 template<typename T>
811 inline bool wxAnyValueType::CheckType(T* reserved)
812 {
813 wxUnusedVar(reserved);
814 return wxAnyValueTypeImpl<T>::IsSameClass(this);
815 }
816
817
818
819 #endif // wxUSE_ANY
820
821 #endif // _WX_ANY_H_