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