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