1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxAny class
4 // Author: Jaakko Salli
8 // Copyright: (c) wxWidgets team
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
19 #include "wx/string.h"
20 #include "wx/meta/movable.h"
21 #include "wx/meta/if.h"
22 #include "wx/typeinfo.h"
25 // Size of the wxAny value buffer.
28 WX_ANY_VALUE_BUFFER_SIZE
= 16
31 union wxAnyValueBuffer
38 long double m_longDouble
;
39 void ( *m_funcPtr
)(void);
40 void ( wxAnyValueBuffer::*m_mFuncPtr
)(void);
44 wxByte m_buffer
[WX_ANY_VALUE_BUFFER_SIZE
];
48 // wxAnyValueType is base class for value type functionality for C++ data
49 // types used with wxAny. Usually the default template (wxAnyValueTypeImpl<>)
50 // will create a satisfactory wxAnyValueType implementation for a data type.
52 class WXDLLIMPEXP_BASE wxAnyValueType
54 WX_DECLARE_ABSTRACT_TYPEINFO(wxAnyValueType
)
64 virtual ~wxAnyValueType()
69 This function is used for internal type matching.
71 virtual bool IsSameType(const wxAnyValueType
* otherType
) const = 0;
74 This function is called every time the data in wxAny
75 buffer needs to be freed.
77 virtual void DeleteValue(wxAnyValueBuffer
& buf
) const = 0;
80 Implement this for buffer-to-buffer copy.
83 This is the source data buffer.
86 This is the destination data buffer that is in either
87 uninitialized or freed state.
89 virtual void CopyBuffer(const wxAnyValueBuffer
& src
,
90 wxAnyValueBuffer
& dst
) const = 0;
93 Convert value into buffer of different type. Return false if
96 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
97 wxAnyValueType
* dstType
,
98 wxAnyValueBuffer
& dst
) const = 0;
101 Use this template function for checking if wxAnyValueType represents
102 a specific C++ data type.
104 @remarks This template function does not work on some older compilers
105 (such as Visual C++ 6.0). For full compiler ccompatibility
106 please use wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) macro
109 @see wxAny::CheckType()
111 // FIXME-VC6: remove this hack when VC6 is no longer supported
112 template <typename T
>
113 bool CheckType(T
* reserved
= NULL
);
118 // This method of checking the type is compatible with VC6
119 #define wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) \
120 wxAnyValueTypeImpl<T>::IsSameClass(valueTypePtr)
124 Helper macro for defining user value types.
126 Even though C++ RTTI would be fully available to use, we'd have to to
127 facilitate sub-type system which allows, for instance, wxAny with
128 signed short '15' to be treated equal to wxAny with signed long long '15'.
129 Having sm_instance is important here.
131 #define WX_DECLARE_ANY_VALUE_TYPE(CLS) \
132 friend class wxAny; \
133 WX_DECLARE_TYPEINFO_INLINE(CLS) \
135 static bool IsSameClass(const wxAnyValueType* otherType) \
137 return wxTypeId(*sm_instance) == wxTypeId(*otherType); \
139 virtual bool IsSameType(const wxAnyValueType* otherType) const \
141 return IsSameClass(otherType); \
144 static CLS* sm_instance; \
146 static wxAnyValueType* GetInstance() \
148 return sm_instance; \
152 #define WX_IMPLEMENT_ANY_VALUE_TYPE(CLS) \
153 CLS* CLS::sm_instance = new CLS();
157 // "non dll-interface class 'xxx' used as base interface
158 #pragma warning (push)
159 #pragma warning (disable:4275)
163 Following are helper classes for the wxAnyValueTypeImplBase.
169 class wxAnyValueTypeOpsMovable
172 static void DeleteValue(wxAnyValueBuffer
& buf
)
177 static void SetValue(const T
& value
,
178 wxAnyValueBuffer
& buf
)
180 memcpy(buf
.m_buffer
, &value
, sizeof(T
));
183 static const T
& GetValue(const wxAnyValueBuffer
& buf
)
185 // Breaking this code into two lines should supress
186 // GCC's 'type-punned pointer will break strict-aliasing rules'
188 const T
* value
= reinterpret_cast<const T
*>(&buf
.m_buffer
[0]);
195 class wxAnyValueTypeOpsGeneric
198 template<typename T2
>
202 DataHolder(const T2
& value
)
206 virtual ~DataHolder() { }
210 wxDECLARE_NO_COPY_CLASS(DataHolder
);
213 static void DeleteValue(wxAnyValueBuffer
& buf
)
215 DataHolder
<T
>* holder
= static_cast<DataHolder
<T
>*>(buf
.m_ptr
);
219 static void SetValue(const T
& value
,
220 wxAnyValueBuffer
& buf
)
222 DataHolder
<T
>* holder
= new DataHolder
<T
>(value
);
226 static const T
& GetValue(const wxAnyValueBuffer
& buf
)
228 DataHolder
<T
>* holder
= static_cast<DataHolder
<T
>*>(buf
.m_ptr
);
229 return holder
->m_value
;
233 } // namespace wxPrivate
237 Intermediate template for the generic value type implementation.
238 We can derive from this same value type for multiple actual types
239 (for instance, we can have wxAnyValueTypeImplInt for all signed
240 integer types), and also easily implement specialized templates
241 with specific dynamic type conversion.
244 class wxAnyValueTypeImplBase
: public wxAnyValueType
246 typedef typename wxIf
< wxIsMovable
<T
>::value
&&
247 sizeof(T
) <= WX_ANY_VALUE_BUFFER_SIZE
,
248 wxPrivate::wxAnyValueTypeOpsMovable
<T
>,
249 wxPrivate::wxAnyValueTypeOpsGeneric
<T
> >::value
253 wxAnyValueTypeImplBase() : wxAnyValueType() { }
254 virtual ~wxAnyValueTypeImplBase() { }
256 virtual void DeleteValue(wxAnyValueBuffer
& buf
) const
258 Ops::DeleteValue(buf
);
261 virtual void CopyBuffer(const wxAnyValueBuffer
& src
,
262 wxAnyValueBuffer
& dst
) const
264 Ops::SetValue(Ops::GetValue(src
), dst
);
268 It is important to reimplement this in any specialized template
269 classes that inherit from wxAnyValueTypeImplBase.
271 static void SetValue(const T
& value
,
272 wxAnyValueBuffer
& buf
)
274 Ops::SetValue(value
, buf
);
278 It is important to reimplement this in any specialized template
279 classes that inherit from wxAnyValueTypeImplBase.
281 static const T
& GetValue(const wxAnyValueBuffer
& buf
)
283 return Ops::GetValue(buf
);
289 Generic value type template. Note that bulk of the implementation
290 resides in wxAnyValueTypeImplBase.
293 class wxAnyValueTypeImpl
: public wxAnyValueTypeImplBase
<T
>
295 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl
<T
>)
297 wxAnyValueTypeImpl() : wxAnyValueTypeImplBase
<T
>() { }
298 virtual ~wxAnyValueTypeImpl() { }
300 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
301 wxAnyValueType
* dstType
,
302 wxAnyValueBuffer
& dst
) const
305 wxUnusedVar(dstType
);
312 wxAnyValueTypeImpl
<T
>* wxAnyValueTypeImpl
<T
>::sm_instance
=
313 new wxAnyValueTypeImpl
<T
>();
317 // Helper macro for using same base value type implementation for multiple
318 // actual C++ data types.
320 #define WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
322 class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##CLSTYPE \
324 typedef wxAnyBase##CLSTYPE##Type UseDataType; \
326 wxAnyValueTypeImpl() : wxAnyValueTypeImpl##CLSTYPE() { } \
327 virtual ~wxAnyValueTypeImpl() { } \
328 static void SetValue(const T& value, wxAnyValueBuffer& buf) \
330 void* voidPtr = reinterpret_cast<void*>(&buf.m_buffer[0]); \
331 UseDataType* dptr = reinterpret_cast<UseDataType*>(voidPtr); \
332 *dptr = static_cast<UseDataType>(value); \
334 static T GetValue(const wxAnyValueBuffer& buf) \
336 const void* voidPtr = \
337 reinterpret_cast<const void*>(&buf.m_buffer[0]); \
338 const UseDataType* sptr = \
339 reinterpret_cast<const UseDataType*>(voidPtr); \
340 return static_cast<T>(*sptr); \
346 // Integer value types
350 typedef wxLongLong_t wxAnyBaseIntType
;
351 typedef wxULongLong_t wxAnyBaseUintType
;
353 typedef long wxAnyBaseIntType
;
354 typedef unsigned long wxAnyBaseUintType
;
358 class WXDLLIMPEXP_BASE wxAnyValueTypeImplInt
:
359 public wxAnyValueTypeImplBase
<wxAnyBaseIntType
>
361 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplInt
)
363 wxAnyValueTypeImplInt() :
364 wxAnyValueTypeImplBase
<wxAnyBaseIntType
>() { }
365 virtual ~wxAnyValueTypeImplInt() { }
367 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
368 wxAnyValueType
* dstType
,
369 wxAnyValueBuffer
& dst
) const;
373 class WXDLLIMPEXP_BASE wxAnyValueTypeImplUint
:
374 public wxAnyValueTypeImplBase
<wxAnyBaseUintType
>
376 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplUint
)
378 wxAnyValueTypeImplUint() :
379 wxAnyValueTypeImplBase
<wxAnyBaseUintType
>() { }
380 virtual ~wxAnyValueTypeImplUint() { }
382 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
383 wxAnyValueType
* dstType
,
384 wxAnyValueBuffer
& dst
) const;
388 WX_ANY_DEFINE_SUB_TYPE(signed long, Int
)
389 WX_ANY_DEFINE_SUB_TYPE(signed int, Int
)
390 WX_ANY_DEFINE_SUB_TYPE(signed short, Int
)
391 WX_ANY_DEFINE_SUB_TYPE(signed char, Int
)
393 WX_ANY_DEFINE_SUB_TYPE(wxLongLong_t
, Int
)
396 WX_ANY_DEFINE_SUB_TYPE(unsigned long, Uint
)
397 WX_ANY_DEFINE_SUB_TYPE(unsigned int, Uint
)
398 WX_ANY_DEFINE_SUB_TYPE(unsigned short, Uint
)
399 WX_ANY_DEFINE_SUB_TYPE(unsigned char, Uint
)
401 WX_ANY_DEFINE_SUB_TYPE(wxULongLong_t
, Uint
)
408 class WXDLLIMPEXP_BASE wxAnyValueTypeImplString
:
409 public wxAnyValueTypeImplBase
<wxString
>
411 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplString
)
413 wxAnyValueTypeImplString() :
414 wxAnyValueTypeImplBase
<wxString
>() { }
415 virtual ~wxAnyValueTypeImplString() { }
418 Convert value into buffer of different type. Return false if
421 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
422 wxAnyValueType
* dstType
,
423 wxAnyValueBuffer
& dst
) const;
428 class wxAnyValueTypeImpl
<wxString
> : public wxAnyValueTypeImplString
431 wxAnyValueTypeImpl() : wxAnyValueTypeImplString() { }
432 virtual ~wxAnyValueTypeImpl() { }
440 class WXDLLIMPEXP_BASE wxAnyValueTypeImpl
<bool> :
441 public wxAnyValueTypeImplBase
<bool>
443 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl
<bool>)
445 wxAnyValueTypeImpl() :
446 wxAnyValueTypeImplBase
<bool>() { }
447 virtual ~wxAnyValueTypeImpl() { }
449 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
450 wxAnyValueType
* dstType
,
451 wxAnyValueBuffer
& dst
) const;
455 // Floating point value type
457 class WXDLLIMPEXP_BASE wxAnyValueTypeImplDouble
:
458 public wxAnyValueTypeImplBase
<double>
460 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble
)
462 wxAnyValueTypeImplDouble() :
463 wxAnyValueTypeImplBase
<double>() { }
464 virtual ~wxAnyValueTypeImplDouble() { }
466 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
467 wxAnyValueType
* dstType
,
468 wxAnyValueBuffer
& dst
) const;
471 // WX_ANY_DEFINE_SUB_TYPE requires this
472 typedef double wxAnyBaseDoubleType
;
474 WX_ANY_DEFINE_SUB_TYPE(float, Double
)
475 WX_ANY_DEFINE_SUB_TYPE(double, Double
)
479 // Defines a dummy wxAnyValueTypeImpl<> with given export
480 // declaration. This is needed if a class is used with
481 // wxAny in both user shared library and application.
483 #define wxDECLARE_ANY_TYPE(CLS, DECL) \
485 class DECL wxAnyValueTypeImpl<CLS> : \
486 public wxAnyValueTypeImplBase<CLS> \
488 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<CLS>) \
490 wxAnyValueTypeImpl() : \
491 wxAnyValueTypeImplBase<CLS>() { } \
492 virtual ~wxAnyValueTypeImpl() { } \
494 virtual bool ConvertValue(const wxAnyValueBuffer& src, \
495 wxAnyValueType* dstType, \
496 wxAnyValueBuffer& dst) const \
499 wxUnusedVar(dstType); \
506 // Make sure some of wx's own types get the right wxAnyValueType export
507 // (this is needed only for types that are referred to from wxBase.
508 // currently we may not use any of these types from there, but let's
509 // use the macro on at least one to make sure it compiles since we can't
510 // really test it properly in unittests since a separate DLL would
513 #include "wx/datetime.h"
514 wxDECLARE_ANY_TYPE(wxDateTime
, WXDLLIMPEXP_BASE
)
517 //#include "wx/object.h"
518 //wxDECLARE_ANY_TYPE(wxObject*, WXDLLIMPEXP_BASE)
520 //#include "wx/arrstr.h"
521 //wxDECLARE_ANY_TYPE(wxArrayString, WXDLLIMPEXP_BASE)
526 class WXDLLIMPEXP_FWD_BASE wxAnyToVariantRegistration
;
528 // Because of header inter-dependencies, cannot include this earlier
529 #include "wx/variant.h"
532 // wxVariantData* data type implementation. For cases when appropriate
533 // wxAny<->wxVariant conversion code is missing.
536 class WXDLLIMPEXP_BASE wxAnyValueTypeImplVariantData
:
537 public wxAnyValueTypeImplBase
<wxVariantData
*>
539 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplVariantData
)
541 wxAnyValueTypeImplVariantData() :
542 wxAnyValueTypeImplBase
<wxVariantData
*>() { }
543 virtual ~wxAnyValueTypeImplVariantData() { }
545 virtual void DeleteValue(wxAnyValueBuffer
& buf
) const
547 wxVariantData
* data
= static_cast<wxVariantData
*>(buf
.m_ptr
);
552 virtual void CopyBuffer(const wxAnyValueBuffer
& src
,
553 wxAnyValueBuffer
& dst
) const
555 wxVariantData
* data
= static_cast<wxVariantData
*>(src
.m_ptr
);
561 static void SetValue(wxVariantData
* value
,
562 wxAnyValueBuffer
& buf
)
568 static wxVariantData
* GetValue(const wxAnyValueBuffer
& buf
)
570 return static_cast<wxVariantData
*>(buf
.m_ptr
);
573 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
574 wxAnyValueType
* dstType
,
575 wxAnyValueBuffer
& dst
) const
578 wxUnusedVar(dstType
);
585 class wxAnyValueTypeImpl
<wxVariantData
*> :
586 public wxAnyValueTypeImplVariantData
589 wxAnyValueTypeImpl() : wxAnyValueTypeImplVariantData() { }
590 virtual ~wxAnyValueTypeImpl() { }
593 #endif // wxUSE_VARIANT
596 // Re-enable useless VC6 warnings
597 #pragma warning (pop)
602 Let's define a discrete Null value so we don't have to really
603 ever check if wxAny.m_type pointer is NULL or not. This is an
604 optimization, mostly. Implementation of this value type is
605 "hidden" in the source file.
607 extern WXDLLIMPEXP_DATA_BASE(wxAnyValueType
*) wxAnyNullValueType
;
611 // We need to implement custom signed/unsigned int equals operators
612 // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
613 #define WXANY_IMPLEMENT_INT_EQ_OP(TS, TUS) \
614 bool operator==(TS value) const \
616 if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
617 return (value == static_cast<TS> \
618 (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
619 if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
620 return (value == static_cast<TS> \
621 (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
624 bool operator==(TUS value) const \
626 if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
627 return (value == static_cast<TUS> \
628 (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
629 if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
630 return (value == static_cast<TUS> \
631 (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
638 // Note that the following functions are implemented outside wxAny class
639 // so that it can reside entirely in header and lack the export declaration.
641 // Helper function used to associate wxAnyValueType with a wxVariantData.
642 extern WXDLLIMPEXP_BASE
void
643 wxPreRegisterAnyToVariant(wxAnyToVariantRegistration
* reg
);
645 // This function performs main wxAny to wxVariant conversion duties.
646 extern WXDLLIMPEXP_BASE
bool
647 wxConvertAnyToVariant(const wxAny
& any
, wxVariant
* variant
);
649 #endif // wxUSE_VARIANT
653 // The wxAny class represents a container for any type. A variant's value
654 // can be changed at run time, possibly to a different type of value.
656 // As standard, wxAny can store value of almost any type, in a fairly
657 // optimal manner even.
667 m_type
= wxAnyNullValueType
;
675 m_type
->DeleteValue(m_buffer
);
680 Various constructors.
683 wxAny(const T
& value
)
685 m_type
= wxAnyValueTypeImpl
<T
>::sm_instance
;
686 wxAnyValueTypeImpl
<T
>::SetValue(value
, m_buffer
);
689 wxAny(const char* value
)
691 m_type
= wxAnyNullValueType
;
692 Assign(wxString(value
));
695 wxAny(const wchar_t* value
)
697 m_type
= wxAnyNullValueType
;
698 Assign(wxString(value
));
701 wxAny(const wxAny
& any
)
703 m_type
= wxAnyNullValueType
;
708 wxAny(const wxVariant
& variant
)
710 m_type
= wxAnyNullValueType
;
711 AssignVariant(variant
);
718 Use this template function for checking if this wxAny holds
719 a specific C++ data type.
721 @remarks This template function does not work on some older compilers
722 (such as Visual C++ 6.0). For full compiler ccompatibility
723 please use wxANY_CHECK_TYPE(any, T) macro instead.
725 @see wxAnyValueType::CheckType()
727 // FIXME-VC6: remove this hack when VC6 is no longer supported
728 template <typename T
>
729 bool CheckType(T
* = NULL
)
731 return m_type
->CheckType
<T
>();
735 Returns the value type as wxAnyValueType instance.
737 @remarks You cannot reliably test whether two wxAnys are of
738 same value type by simply comparing return values
739 of wxAny::GetType(). Instead use
740 wxAnyValueType::CheckType<T>() template function.
742 const wxAnyValueType
* GetType() const
748 Tests if wxAny is null (that is, whether there is data).
752 return (m_type
== wxAnyNullValueType
);
756 Makes wxAny null (that is, clears it).
760 m_type
->DeleteValue(m_buffer
);
761 m_type
= wxAnyNullValueType
;
766 Assignment operators.
768 wxAny
& operator=(const wxAny
&any
)
775 #if wxUSE_VARIANT && (!defined(__VISUALC__) || __VISUALC__ >= 1300)
777 // Adding this operator for VC6 breaks wxAny, and also
778 // some cases of implicit conversion from wxVariant to wxAny.
780 // e.g. wxAny any = variant; // should work
784 // any = variant; // probably doesn't work - uses template
785 // // assignment, most likely
787 wxAny
& operator=(const wxVariant
&variant
)
789 AssignVariant(variant
);
795 wxAny
& operator=(const T
&value
)
797 m_type
->DeleteValue(m_buffer
);
798 m_type
= wxAnyValueTypeImpl
<T
>::sm_instance
;
799 wxAnyValueTypeImpl
<T
>::SetValue(value
, m_buffer
);
803 wxAny
& operator=(const char* value
)
804 { Assign(wxString(value
)); return *this; }
805 wxAny
& operator=(const wchar_t* value
)
806 { Assign(wxString(value
)); return *this; }
813 bool operator==(const wxString
& value
) const
815 if ( !wxAnyValueTypeImpl
<wxString
>::IsSameClass(m_type
) )
819 static_cast<wxString
>
820 (wxAnyValueTypeImpl
<wxString
>::GetValue(m_buffer
));
823 bool operator==(const char* value
) const
824 { return (*this) == wxString(value
); }
825 bool operator==(const wchar_t* value
) const
826 { return (*this) == wxString(value
); }
829 // We need to implement custom signed/unsigned int equals operators
830 // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
831 WXANY_IMPLEMENT_INT_EQ_OP(signed char, unsigned char)
832 WXANY_IMPLEMENT_INT_EQ_OP(signed short, unsigned short)
833 WXANY_IMPLEMENT_INT_EQ_OP(signed int, unsigned int)
834 WXANY_IMPLEMENT_INT_EQ_OP(signed long, unsigned long)
836 WXANY_IMPLEMENT_INT_EQ_OP(wxLongLong_t
, wxULongLong_t
)
839 bool operator==(float value
) const
841 if ( !wxAnyValueTypeImpl
<float>::IsSameClass(m_type
) )
846 (wxAnyValueTypeImpl
<float>::GetValue(m_buffer
));
849 bool operator==(double value
) const
851 if ( !wxAnyValueTypeImpl
<double>::IsSameClass(m_type
) )
856 (wxAnyValueTypeImpl
<double>::GetValue(m_buffer
));
859 bool operator==(bool value
) const
861 if ( !wxAnyValueTypeImpl
<bool>::IsSameClass(m_type
) )
864 return value
== (wxAnyValueTypeImpl
<bool>::GetValue(m_buffer
));
871 Inequality operators (implement as template).
874 bool operator!=(const T
& value
) const
875 { return !((*this) == value
); }
879 This template function converts wxAny into given type. No dynamic
880 conversion is performed, so if the type is incorrect an assertion
881 failure will occur in debug builds, and a bogus value is returned
884 @remarks This template function does not work on some older compilers
885 (such as Visual C++ 6.0). For full compiler compatibility
886 please use wxANY_AS(any, T) macro instead.
888 // FIXME-VC6: remove this hack when VC6 is no longer supported
890 T
As(T
* = NULL
) const
892 if ( !wxAnyValueTypeImpl
<T
>::IsSameClass(m_type
) )
894 wxFAIL_MSG("Incorrect or non-convertible data type");
897 return static_cast<T
>(wxAnyValueTypeImpl
<T
>::GetValue(m_buffer
));
901 Template function that etrieves and converts the value of this
902 variant to the type that T* value is.
904 @return Returns @true if conversion was succesfull.
907 bool GetAs(T
* value
) const
909 if ( !wxAnyValueTypeImpl
<T
>::IsSameClass(m_type
) )
911 wxAnyValueType
* otherType
=
912 wxAnyValueTypeImpl
<T
>::sm_instance
;
913 wxAnyValueBuffer temp_buf
;
915 if ( !m_type
->ConvertValue(m_buffer
, otherType
, temp_buf
) )
919 static_cast<T
>(wxAnyValueTypeImpl
<T
>::GetValue(temp_buf
));
920 otherType
->DeleteValue(temp_buf
);
924 *value
= static_cast<T
>(wxAnyValueTypeImpl
<T
>::GetValue(m_buffer
));
929 // GetAs() wxVariant specialization
930 bool GetAs(wxVariant
* value
) const
932 return wxConvertAnyToVariant(*this, value
);
937 // Assignment functions
938 void AssignAny(const wxAny
& any
)
940 // Must delete value - CopyBuffer() never does that
941 m_type
->DeleteValue(m_buffer
);
943 wxAnyValueType
* newType
= any
.m_type
;
945 if ( !newType
->IsSameType(m_type
) )
948 newType
->CopyBuffer(any
.m_buffer
, m_buffer
);
952 void AssignVariant(const wxVariant
& variant
)
954 wxVariantData
* data
= variant
.GetData();
956 if ( data
&& data
->GetAsAny(this) )
959 m_type
->DeleteValue(m_buffer
);
961 if ( variant
.IsNull() )
964 m_type
= wxAnyNullValueType
;
968 // If everything else fails, wrap the whole wxVariantData
969 m_type
= wxAnyValueTypeImpl
<wxVariantData
*>::sm_instance
;
970 wxAnyValueTypeImpl
<wxVariantData
*>::SetValue(data
, m_buffer
);
976 void Assign(const T
&value
)
978 m_type
->DeleteValue(m_buffer
);
979 m_type
= wxAnyValueTypeImpl
<T
>::sm_instance
;
980 wxAnyValueTypeImpl
<T
>::SetValue(value
, m_buffer
);
984 wxAnyValueBuffer m_buffer
;
985 wxAnyValueType
* m_type
;
990 // This method of checking the type is compatible with VC6
991 #define wxANY_CHECK_TYPE(any, T) \
992 wxANY_VALUE_TYPE_CHECK_TYPE(any.GetType(), T)
996 // This method of getting the value is compatible with VC6
997 #define wxANY_AS(any, T) \
998 any.As(static_cast<T*>(NULL))
1001 template<typename T
>
1002 inline bool wxAnyValueType::CheckType(T
* reserved
)
1004 wxUnusedVar(reserved
);
1005 return wxAnyValueTypeImpl
<T
>::IsSameClass(this);
1012 #endif // _WX_ANY_H_