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
)
406 // This macro is used in header, but then in source file we must have:
407 // WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl##TYPENAME)
409 #define _WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, GV) \
410 class WXDLLIMPEXP_BASE wxAnyValueTypeImpl##TYPENAME : \
411 public wxAnyValueTypeImplBase<T> \
413 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl##TYPENAME) \
415 wxAnyValueTypeImpl##TYPENAME() : \
416 wxAnyValueTypeImplBase<T>() { } \
417 virtual ~wxAnyValueTypeImpl##TYPENAME() { } \
418 virtual bool ConvertValue(const wxAnyValueBuffer& src, \
419 wxAnyValueType* dstType, \
420 wxAnyValueBuffer& dst) const \
422 GV value = GetValue(src); \
423 return CONVFUNC(value, dstType, dst); \
427 class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##TYPENAME \
430 wxAnyValueTypeImpl() : wxAnyValueTypeImpl##TYPENAME() { } \
431 virtual ~wxAnyValueTypeImpl() { } \
434 #define WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, BT) \
435 _WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, BT) \
437 #define WX_ANY_DEFINE_CONVERTIBLE_TYPE_BASE(T, TYPENAME, CONVFUNC) \
438 _WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, \
439 CONVFUNC, const T&) \
445 // Convert wxString to destination wxAny value type
446 extern WXDLLIMPEXP_BASE
bool wxAnyConvertString(const wxString
& value
,
447 wxAnyValueType
* dstType
,
448 wxAnyValueBuffer
& dst
);
450 WX_ANY_DEFINE_CONVERTIBLE_TYPE_BASE(wxString
, wxString
, wxAnyConvertString
)
451 WX_ANY_DEFINE_CONVERTIBLE_TYPE(const char*, ConstCharPtr
,
452 wxAnyConvertString
, wxString
)
453 WX_ANY_DEFINE_CONVERTIBLE_TYPE(const wchar_t*, ConstWchar_tPtr
,
454 wxAnyConvertString
, wxString
)
460 class WXDLLIMPEXP_BASE wxAnyValueTypeImpl
<bool> :
461 public wxAnyValueTypeImplBase
<bool>
463 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl
<bool>)
465 wxAnyValueTypeImpl() :
466 wxAnyValueTypeImplBase
<bool>() { }
467 virtual ~wxAnyValueTypeImpl() { }
469 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
470 wxAnyValueType
* dstType
,
471 wxAnyValueBuffer
& dst
) const;
475 // Floating point value type
477 class WXDLLIMPEXP_BASE wxAnyValueTypeImplDouble
:
478 public wxAnyValueTypeImplBase
<double>
480 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble
)
482 wxAnyValueTypeImplDouble() :
483 wxAnyValueTypeImplBase
<double>() { }
484 virtual ~wxAnyValueTypeImplDouble() { }
486 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
487 wxAnyValueType
* dstType
,
488 wxAnyValueBuffer
& dst
) const;
491 // WX_ANY_DEFINE_SUB_TYPE requires this
492 typedef double wxAnyBaseDoubleType
;
494 WX_ANY_DEFINE_SUB_TYPE(float, Double
)
495 WX_ANY_DEFINE_SUB_TYPE(double, Double
)
499 // Defines a dummy wxAnyValueTypeImpl<> with given export
500 // declaration. This is needed if a class is used with
501 // wxAny in both user shared library and application.
503 #define wxDECLARE_ANY_TYPE(CLS, DECL) \
505 class DECL wxAnyValueTypeImpl<CLS> : \
506 public wxAnyValueTypeImplBase<CLS> \
508 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<CLS>) \
510 wxAnyValueTypeImpl() : \
511 wxAnyValueTypeImplBase<CLS>() { } \
512 virtual ~wxAnyValueTypeImpl() { } \
514 virtual bool ConvertValue(const wxAnyValueBuffer& src, \
515 wxAnyValueType* dstType, \
516 wxAnyValueBuffer& dst) const \
519 wxUnusedVar(dstType); \
526 // Make sure some of wx's own types get the right wxAnyValueType export
527 // (this is needed only for types that are referred to from wxBase.
528 // currently we may not use any of these types from there, but let's
529 // use the macro on at least one to make sure it compiles since we can't
530 // really test it properly in unittests since a separate DLL would
533 #include "wx/datetime.h"
534 wxDECLARE_ANY_TYPE(wxDateTime
, WXDLLIMPEXP_BASE
)
537 //#include "wx/object.h"
538 //wxDECLARE_ANY_TYPE(wxObject*, WXDLLIMPEXP_BASE)
540 //#include "wx/arrstr.h"
541 //wxDECLARE_ANY_TYPE(wxArrayString, WXDLLIMPEXP_BASE)
546 class WXDLLIMPEXP_FWD_BASE wxAnyToVariantRegistration
;
548 // Because of header inter-dependencies, cannot include this earlier
549 #include "wx/variant.h"
552 // wxVariantData* data type implementation. For cases when appropriate
553 // wxAny<->wxVariant conversion code is missing.
556 class WXDLLIMPEXP_BASE wxAnyValueTypeImplVariantData
:
557 public wxAnyValueTypeImplBase
<wxVariantData
*>
559 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplVariantData
)
561 wxAnyValueTypeImplVariantData() :
562 wxAnyValueTypeImplBase
<wxVariantData
*>() { }
563 virtual ~wxAnyValueTypeImplVariantData() { }
565 virtual void DeleteValue(wxAnyValueBuffer
& buf
) const
567 wxVariantData
* data
= static_cast<wxVariantData
*>(buf
.m_ptr
);
572 virtual void CopyBuffer(const wxAnyValueBuffer
& src
,
573 wxAnyValueBuffer
& dst
) const
575 wxVariantData
* data
= static_cast<wxVariantData
*>(src
.m_ptr
);
581 static void SetValue(wxVariantData
* value
,
582 wxAnyValueBuffer
& buf
)
588 static wxVariantData
* GetValue(const wxAnyValueBuffer
& buf
)
590 return static_cast<wxVariantData
*>(buf
.m_ptr
);
593 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
594 wxAnyValueType
* dstType
,
595 wxAnyValueBuffer
& dst
) const
598 wxUnusedVar(dstType
);
605 class wxAnyValueTypeImpl
<wxVariantData
*> :
606 public wxAnyValueTypeImplVariantData
609 wxAnyValueTypeImpl() : wxAnyValueTypeImplVariantData() { }
610 virtual ~wxAnyValueTypeImpl() { }
613 #endif // wxUSE_VARIANT
616 // Re-enable useless VC6 warnings
617 #pragma warning (pop)
622 Let's define a discrete Null value so we don't have to really
623 ever check if wxAny.m_type pointer is NULL or not. This is an
624 optimization, mostly. Implementation of this value type is
625 "hidden" in the source file.
627 extern WXDLLIMPEXP_DATA_BASE(wxAnyValueType
*) wxAnyNullValueType
;
631 // We need to implement custom signed/unsigned int equals operators
632 // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
633 #define WXANY_IMPLEMENT_INT_EQ_OP(TS, TUS) \
634 bool operator==(TS value) const \
636 if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
637 return (value == static_cast<TS> \
638 (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
639 if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
640 return (value == static_cast<TS> \
641 (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
644 bool operator==(TUS value) const \
646 if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
647 return (value == static_cast<TUS> \
648 (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
649 if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
650 return (value == static_cast<TUS> \
651 (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
658 // Note that the following functions are implemented outside wxAny class
659 // so that it can reside entirely in header and lack the export declaration.
661 // Helper function used to associate wxAnyValueType with a wxVariantData.
662 extern WXDLLIMPEXP_BASE
void
663 wxPreRegisterAnyToVariant(wxAnyToVariantRegistration
* reg
);
665 // This function performs main wxAny to wxVariant conversion duties.
666 extern WXDLLIMPEXP_BASE
bool
667 wxConvertAnyToVariant(const wxAny
& any
, wxVariant
* variant
);
669 #endif // wxUSE_VARIANT
673 // The wxAny class represents a container for any type. A variant's value
674 // can be changed at run time, possibly to a different type of value.
676 // As standard, wxAny can store value of almost any type, in a fairly
677 // optimal manner even.
687 m_type
= wxAnyNullValueType
;
695 m_type
->DeleteValue(m_buffer
);
700 Various constructors.
703 wxAny(const T
& value
)
705 m_type
= wxAnyValueTypeImpl
<T
>::sm_instance
;
706 wxAnyValueTypeImpl
<T
>::SetValue(value
, m_buffer
);
709 // These two constructors are needed to deal with string literals
710 wxAny(const char* value
)
712 m_type
= wxAnyValueTypeImpl
<const char*>::sm_instance
;
713 wxAnyValueTypeImpl
<const char*>::SetValue(value
, m_buffer
);
715 wxAny(const wchar_t* value
)
717 m_type
= wxAnyValueTypeImpl
<const wchar_t*>::sm_instance
;
718 wxAnyValueTypeImpl
<const wchar_t*>::SetValue(value
, m_buffer
);
721 wxAny(const wxAny
& any
)
723 m_type
= wxAnyNullValueType
;
728 wxAny(const wxVariant
& variant
)
730 m_type
= wxAnyNullValueType
;
731 AssignVariant(variant
);
738 Use this template function for checking if this wxAny holds
739 a specific C++ data type.
741 @remarks This template function does not work on some older compilers
742 (such as Visual C++ 6.0). For full compiler ccompatibility
743 please use wxANY_CHECK_TYPE(any, T) macro instead.
745 @see wxAnyValueType::CheckType()
747 // FIXME-VC6: remove this hack when VC6 is no longer supported
748 template <typename T
>
749 bool CheckType(T
* = NULL
)
751 return m_type
->CheckType
<T
>();
755 Returns the value type as wxAnyValueType instance.
757 @remarks You cannot reliably test whether two wxAnys are of
758 same value type by simply comparing return values
759 of wxAny::GetType(). Instead use
760 wxAnyValueType::CheckType<T>() template function.
762 const wxAnyValueType
* GetType() const
768 Tests if wxAny is null (that is, whether there is data).
772 return (m_type
== wxAnyNullValueType
);
776 Makes wxAny null (that is, clears it).
780 m_type
->DeleteValue(m_buffer
);
781 m_type
= wxAnyNullValueType
;
786 Assignment operators.
789 wxAny
& operator=(const T
&value
)
791 m_type
->DeleteValue(m_buffer
);
792 m_type
= wxAnyValueTypeImpl
<T
>::sm_instance
;
793 wxAnyValueTypeImpl
<T
>::SetValue(value
, m_buffer
);
797 wxAny
& operator=(const wxAny
&any
)
805 wxAny
& operator=(const wxVariant
&variant
)
807 AssignVariant(variant
);
812 // These two operators are needed to deal with string literals
813 wxAny
& operator=(const char* value
)
818 wxAny
& operator=(const wchar_t* value
)
828 bool operator==(const wxString
& value
) const
831 if ( !GetAs(&value2
) )
833 return value
== value2
;
836 bool operator==(const char* value
) const
837 { return (*this) == wxString(value
); }
838 bool operator==(const wchar_t* value
) const
839 { return (*this) == wxString(value
); }
842 // We need to implement custom signed/unsigned int equals operators
843 // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
844 WXANY_IMPLEMENT_INT_EQ_OP(signed char, unsigned char)
845 WXANY_IMPLEMENT_INT_EQ_OP(signed short, unsigned short)
846 WXANY_IMPLEMENT_INT_EQ_OP(signed int, unsigned int)
847 WXANY_IMPLEMENT_INT_EQ_OP(signed long, unsigned long)
849 WXANY_IMPLEMENT_INT_EQ_OP(wxLongLong_t
, wxULongLong_t
)
852 bool operator==(float value
) const
854 if ( !wxAnyValueTypeImpl
<float>::IsSameClass(m_type
) )
859 (wxAnyValueTypeImpl
<float>::GetValue(m_buffer
));
862 bool operator==(double value
) const
864 if ( !wxAnyValueTypeImpl
<double>::IsSameClass(m_type
) )
869 (wxAnyValueTypeImpl
<double>::GetValue(m_buffer
));
872 bool operator==(bool value
) const
874 if ( !wxAnyValueTypeImpl
<bool>::IsSameClass(m_type
) )
877 return value
== (wxAnyValueTypeImpl
<bool>::GetValue(m_buffer
));
884 Inequality operators (implement as template).
887 bool operator!=(const T
& value
) const
888 { return !((*this) == value
); }
892 This template function converts wxAny into given type. In most cases
893 no type conversion is performed, so if the type is incorrect an
894 assertion failure will occur.
896 @remarks For conveniency, conversion is done when T is wxString. This
897 is useful when a string literal (which are treated as
898 const char* and const wchar_t*) has been assigned to wxAny.
900 This template function may not work properly with Visual C++
901 6. For full compiler compatibility, please use
902 wxANY_AS(any, T) macro instead.
904 // FIXME-VC6: remove this hack when VC6 is no longer supported
906 T
As(T
* = NULL
) const
908 if ( !wxAnyValueTypeImpl
<T
>::IsSameClass(m_type
) )
910 wxFAIL_MSG("Incorrect or non-convertible data type");
913 return static_cast<T
>(wxAnyValueTypeImpl
<T
>::GetValue(m_buffer
));
916 // Allow easy conversion from 'const char *' etc. to wxString
917 // FIXME-VC6: remove this hack when VC6 is no longer supported
919 wxString
As(wxString
*) const
922 if ( !GetAs(&value
) )
924 wxFAIL_MSG("Incorrect or non-convertible data type");
930 Template function that etrieves and converts the value of this
931 variant to the type that T* value is.
933 @return Returns @true if conversion was succesfull.
936 bool GetAs(T
* value
) const
938 if ( !wxAnyValueTypeImpl
<T
>::IsSameClass(m_type
) )
940 wxAnyValueType
* otherType
=
941 wxAnyValueTypeImpl
<T
>::sm_instance
;
942 wxAnyValueBuffer temp_buf
;
944 if ( !m_type
->ConvertValue(m_buffer
, otherType
, temp_buf
) )
948 static_cast<T
>(wxAnyValueTypeImpl
<T
>::GetValue(temp_buf
));
949 otherType
->DeleteValue(temp_buf
);
953 *value
= static_cast<T
>(wxAnyValueTypeImpl
<T
>::GetValue(m_buffer
));
958 // GetAs() wxVariant specialization
959 bool GetAs(wxVariant
* value
) const
961 return wxConvertAnyToVariant(*this, value
);
966 // Assignment functions
967 void AssignAny(const wxAny
& any
)
969 // Must delete value - CopyBuffer() never does that
970 m_type
->DeleteValue(m_buffer
);
972 wxAnyValueType
* newType
= any
.m_type
;
974 if ( !newType
->IsSameType(m_type
) )
977 newType
->CopyBuffer(any
.m_buffer
, m_buffer
);
981 void AssignVariant(const wxVariant
& variant
)
983 wxVariantData
* data
= variant
.GetData();
985 if ( data
&& data
->GetAsAny(this) )
988 m_type
->DeleteValue(m_buffer
);
990 if ( variant
.IsNull() )
993 m_type
= wxAnyNullValueType
;
997 // If everything else fails, wrap the whole wxVariantData
998 m_type
= wxAnyValueTypeImpl
<wxVariantData
*>::sm_instance
;
999 wxAnyValueTypeImpl
<wxVariantData
*>::SetValue(data
, m_buffer
);
1004 template<typename T
>
1005 void Assign(const T
&value
)
1007 m_type
->DeleteValue(m_buffer
);
1008 m_type
= wxAnyValueTypeImpl
<T
>::sm_instance
;
1009 wxAnyValueTypeImpl
<T
>::SetValue(value
, m_buffer
);
1013 wxAnyValueBuffer m_buffer
;
1014 wxAnyValueType
* m_type
;
1019 // This method of checking the type is compatible with VC6
1020 #define wxANY_CHECK_TYPE(any, T) \
1021 wxANY_VALUE_TYPE_CHECK_TYPE((any).GetType(), T)
1025 // This method of getting the value is compatible with VC6
1026 #define wxANY_AS(any, T) \
1027 (any).As(static_cast<T*>(NULL))
1030 template<typename T
>
1031 inline bool wxAnyValueType::CheckType(T
* reserved
)
1033 wxUnusedVar(reserved
);
1034 return wxAnyValueTypeImpl
<T
>::IsSameClass(this);
1041 #endif // _WX_ANY_H_