1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxAny class
4 // Author: Jaakko Salli
8 // Copyright: (c) wxWidgets team
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
19 #include <new> // for placement new
20 #include "wx/string.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
)
66 virtual ~wxAnyValueType()
71 This function is used for internal type matching.
73 virtual bool IsSameType(const wxAnyValueType
* otherType
) const = 0;
76 This function is called every time the data in wxAny
77 buffer needs to be freed.
79 virtual void DeleteValue(wxAnyValueBuffer
& buf
) const = 0;
82 Implement this for buffer-to-buffer copy.
85 This is the source data buffer.
88 This is the destination data buffer that is in either
89 uninitialized or freed state.
91 virtual void CopyBuffer(const wxAnyValueBuffer
& src
,
92 wxAnyValueBuffer
& dst
) const = 0;
95 Convert value into buffer of different type. Return false if
98 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
99 wxAnyValueType
* dstType
,
100 wxAnyValueBuffer
& dst
) const = 0;
103 Use this template function for checking if wxAnyValueType represents
104 a specific C++ data type.
106 @remarks This template function does not work on some older compilers
107 (such as Visual C++ 6.0). For full compiler ccompatibility
108 please use wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) macro
111 @see wxAny::CheckType()
113 // FIXME-VC6: remove this hack when VC6 is no longer supported
114 template <typename T
>
115 bool CheckType(T
* reserved
= NULL
) const;
121 // We need to allocate wxAnyValueType instances in heap, and need to use
122 // scoped ptr to properly deallocate them in dynamic library use cases.
123 // Here we have a minimal specialized scoped ptr implementation to deal
124 // with various compiler-specific problems with template class' static
125 // member variable of template type with explicit constructor which
126 // is initialized in global scope.
128 class wxAnyValueTypeScopedPtr
131 wxAnyValueTypeScopedPtr(wxAnyValueType
* ptr
) : m_ptr(ptr
) { }
132 ~wxAnyValueTypeScopedPtr() { delete m_ptr
; }
133 wxAnyValueType
* get() const { return m_ptr
; }
135 wxAnyValueType
* m_ptr
;
140 // This method of checking the type is compatible with VC6
141 #define wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) \
142 wxAnyValueTypeImpl<T>::IsSameClass(valueTypePtr)
146 Helper macro for defining user value types.
148 Even though C++ RTTI would be fully available to use, we'd have to to
149 facilitate sub-type system which allows, for instance, wxAny with
150 signed short '15' to be treated equal to wxAny with signed long long '15'.
151 Having sm_instance is important here.
153 NB: We really need to have wxAnyValueType instances allocated
154 in heap. They are stored as static template member variables,
155 and with them we just can't be too careful (eg. not allocating
156 them in heap broke the type identification in GCC).
158 #define WX_DECLARE_ANY_VALUE_TYPE(CLS) \
159 friend class wxAny; \
160 WX_DECLARE_TYPEINFO_INLINE(CLS) \
162 static bool IsSameClass(const wxAnyValueType* otherType) \
164 return wxTypeId(*sm_instance.get()) == wxTypeId(*otherType); \
166 virtual bool IsSameType(const wxAnyValueType* otherType) const \
168 return IsSameClass(otherType); \
171 static wxAnyValueTypeScopedPtr sm_instance; \
173 static wxAnyValueType* GetInstance() \
175 return sm_instance.get(); \
179 #define WX_IMPLEMENT_ANY_VALUE_TYPE(CLS) \
180 wxAnyValueTypeScopedPtr CLS::sm_instance(new CLS());
184 // "non dll-interface class 'xxx' used as base interface
185 #pragma warning (push)
186 #pragma warning (disable:4275)
190 Following are helper classes for the wxAnyValueTypeImplBase.
196 class wxAnyValueTypeOpsInplace
199 static void DeleteValue(wxAnyValueBuffer
& buf
)
201 T
* value
= reinterpret_cast<T
*>(&buf
.m_buffer
[0]);
204 // Some compiler may given 'unused variable' warnings without this
208 static void SetValue(const T
& value
,
209 wxAnyValueBuffer
& buf
)
212 void* const place
= buf
.m_buffer
;
213 ::new(place
) T(value
);
216 static const T
& GetValue(const wxAnyValueBuffer
& buf
)
218 // Breaking this code into two lines should supress
219 // GCC's 'type-punned pointer will break strict-aliasing rules'
221 const T
* value
= reinterpret_cast<const T
*>(&buf
.m_buffer
[0]);
228 class wxAnyValueTypeOpsGeneric
231 template<typename T2
>
235 DataHolder(const T2
& value
)
239 virtual ~DataHolder() { }
243 wxDECLARE_NO_COPY_CLASS(DataHolder
);
246 static void DeleteValue(wxAnyValueBuffer
& buf
)
248 DataHolder
<T
>* holder
= static_cast<DataHolder
<T
>*>(buf
.m_ptr
);
252 static void SetValue(const T
& value
,
253 wxAnyValueBuffer
& buf
)
255 DataHolder
<T
>* holder
= new DataHolder
<T
>(value
);
259 static const T
& GetValue(const wxAnyValueBuffer
& buf
)
261 DataHolder
<T
>* holder
= static_cast<DataHolder
<T
>*>(buf
.m_ptr
);
262 return holder
->m_value
;
266 } // namespace wxPrivate
270 Intermediate template for the generic value type implementation.
271 We can derive from this same value type for multiple actual types
272 (for instance, we can have wxAnyValueTypeImplInt for all signed
273 integer types), and also easily implement specialized templates
274 with specific dynamic type conversion.
277 class wxAnyValueTypeImplBase
: public wxAnyValueType
279 typedef typename wxIf
< sizeof(T
) <= WX_ANY_VALUE_BUFFER_SIZE
,
280 wxPrivate
::wxAnyValueTypeOpsInplace
<T
>,
281 wxPrivate
::wxAnyValueTypeOpsGeneric
<T
> >::value
285 wxAnyValueTypeImplBase() : wxAnyValueType() { }
286 virtual ~wxAnyValueTypeImplBase() { }
288 virtual void DeleteValue(wxAnyValueBuffer
& buf
) const
290 Ops
::DeleteValue(buf
);
293 virtual void CopyBuffer(const wxAnyValueBuffer
& src
,
294 wxAnyValueBuffer
& dst
) const
296 Ops
::SetValue(Ops
::GetValue(src
), dst
);
300 It is important to reimplement this in any specialized template
301 classes that inherit from wxAnyValueTypeImplBase.
303 static void SetValue(const T
& value
,
304 wxAnyValueBuffer
& buf
)
306 Ops
::SetValue(value
, buf
);
310 It is important to reimplement this in any specialized template
311 classes that inherit from wxAnyValueTypeImplBase.
313 static const T
& GetValue(const wxAnyValueBuffer
& buf
)
315 return Ops
::GetValue(buf
);
321 Generic value type template. Note that bulk of the implementation
322 resides in wxAnyValueTypeImplBase.
325 class wxAnyValueTypeImpl
: public wxAnyValueTypeImplBase
<T
>
327 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl
<T
>)
329 wxAnyValueTypeImpl() : wxAnyValueTypeImplBase
<T
>() { }
330 virtual ~wxAnyValueTypeImpl() { }
332 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
333 wxAnyValueType
* dstType
,
334 wxAnyValueBuffer
& dst
) const
337 wxUnusedVar(dstType
);
344 wxAnyValueTypeScopedPtr wxAnyValueTypeImpl
<T
>::sm_instance
= new wxAnyValueTypeImpl
<T
>();
348 // Helper macro for using same base value type implementation for multiple
349 // actual C++ data types.
351 #define WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
353 class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##CLSTYPE \
355 typedef wxAnyBase##CLSTYPE##Type UseDataType; \
357 wxAnyValueTypeImpl() : wxAnyValueTypeImpl##CLSTYPE() { } \
358 virtual ~wxAnyValueTypeImpl() { } \
359 static void SetValue(const T& value, wxAnyValueBuffer& buf) \
361 void* voidPtr = reinterpret_cast<void*>(&buf.m_buffer[0]); \
362 UseDataType* dptr = reinterpret_cast<UseDataType*>(voidPtr); \
363 *dptr = static_cast<UseDataType>(value); \
365 static T GetValue(const wxAnyValueBuffer& buf) \
367 const void* voidPtr = \
368 reinterpret_cast<const void*>(&buf.m_buffer[0]); \
369 const UseDataType* sptr = \
370 reinterpret_cast<const UseDataType*>(voidPtr); \
371 return static_cast<T>(*sptr); \
377 // Integer value types
381 typedef wxLongLong_t wxAnyBaseIntType
;
382 typedef wxULongLong_t wxAnyBaseUintType
;
384 typedef long wxAnyBaseIntType
;
385 typedef unsigned long wxAnyBaseUintType
;
389 class WXDLLIMPEXP_BASE wxAnyValueTypeImplInt
:
390 public wxAnyValueTypeImplBase
<wxAnyBaseIntType
>
392 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplInt
)
394 wxAnyValueTypeImplInt() :
395 wxAnyValueTypeImplBase
<wxAnyBaseIntType
>() { }
396 virtual ~wxAnyValueTypeImplInt() { }
398 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
399 wxAnyValueType
* dstType
,
400 wxAnyValueBuffer
& dst
) const;
404 class WXDLLIMPEXP_BASE wxAnyValueTypeImplUint
:
405 public wxAnyValueTypeImplBase
<wxAnyBaseUintType
>
407 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplUint
)
409 wxAnyValueTypeImplUint() :
410 wxAnyValueTypeImplBase
<wxAnyBaseUintType
>() { }
411 virtual ~wxAnyValueTypeImplUint() { }
413 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
414 wxAnyValueType
* dstType
,
415 wxAnyValueBuffer
& dst
) const;
419 WX_ANY_DEFINE_SUB_TYPE(signed long, Int
)
420 WX_ANY_DEFINE_SUB_TYPE(signed int, Int
)
421 WX_ANY_DEFINE_SUB_TYPE(signed short, Int
)
422 WX_ANY_DEFINE_SUB_TYPE(signed char, Int
)
424 WX_ANY_DEFINE_SUB_TYPE(wxLongLong_t
, Int
)
427 WX_ANY_DEFINE_SUB_TYPE(unsigned long, Uint
)
428 WX_ANY_DEFINE_SUB_TYPE(unsigned int, Uint
)
429 WX_ANY_DEFINE_SUB_TYPE(unsigned short, Uint
)
430 WX_ANY_DEFINE_SUB_TYPE(unsigned char, Uint
)
432 WX_ANY_DEFINE_SUB_TYPE(wxULongLong_t
, Uint
)
437 // This macro is used in header, but then in source file we must have:
438 // WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl##TYPENAME)
440 #define _WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, GV) \
441 class WXDLLIMPEXP_BASE wxAnyValueTypeImpl##TYPENAME : \
442 public wxAnyValueTypeImplBase<T> \
444 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl##TYPENAME) \
446 wxAnyValueTypeImpl##TYPENAME() : \
447 wxAnyValueTypeImplBase<T>() { } \
448 virtual ~wxAnyValueTypeImpl##TYPENAME() { } \
449 virtual bool ConvertValue(const wxAnyValueBuffer& src, \
450 wxAnyValueType* dstType, \
451 wxAnyValueBuffer& dst) const \
453 GV value = GetValue(src); \
454 return CONVFUNC(value, dstType, dst); \
458 class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##TYPENAME \
461 wxAnyValueTypeImpl() : wxAnyValueTypeImpl##TYPENAME() { } \
462 virtual ~wxAnyValueTypeImpl() { } \
465 #define WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, BT) \
466 _WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, BT) \
468 #define WX_ANY_DEFINE_CONVERTIBLE_TYPE_BASE(T, TYPENAME, CONVFUNC) \
469 _WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, \
470 CONVFUNC, const T&) \
476 // Convert wxString to destination wxAny value type
477 extern WXDLLIMPEXP_BASE
bool wxAnyConvertString(const wxString
& value
,
478 wxAnyValueType
* dstType
,
479 wxAnyValueBuffer
& dst
);
481 WX_ANY_DEFINE_CONVERTIBLE_TYPE_BASE(wxString
, wxString
, wxAnyConvertString
)
482 WX_ANY_DEFINE_CONVERTIBLE_TYPE(const char*, ConstCharPtr
,
483 wxAnyConvertString
, wxString
)
484 WX_ANY_DEFINE_CONVERTIBLE_TYPE(const wchar_t*, ConstWchar_tPtr
,
485 wxAnyConvertString
, wxString
)
491 class WXDLLIMPEXP_BASE wxAnyValueTypeImpl
<bool> :
492 public wxAnyValueTypeImplBase
<bool>
494 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl
<bool>)
496 wxAnyValueTypeImpl() :
497 wxAnyValueTypeImplBase
<bool>() { }
498 virtual ~wxAnyValueTypeImpl() { }
500 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
501 wxAnyValueType
* dstType
,
502 wxAnyValueBuffer
& dst
) const;
506 // Floating point value type
508 class WXDLLIMPEXP_BASE wxAnyValueTypeImplDouble
:
509 public wxAnyValueTypeImplBase
<double>
511 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble
)
513 wxAnyValueTypeImplDouble() :
514 wxAnyValueTypeImplBase
<double>() { }
515 virtual ~wxAnyValueTypeImplDouble() { }
517 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
518 wxAnyValueType
* dstType
,
519 wxAnyValueBuffer
& dst
) const;
522 // WX_ANY_DEFINE_SUB_TYPE requires this
523 typedef double wxAnyBaseDoubleType
;
525 WX_ANY_DEFINE_SUB_TYPE(float, Double
)
526 WX_ANY_DEFINE_SUB_TYPE(double, Double
)
530 // Defines a dummy wxAnyValueTypeImpl<> with given export
531 // declaration. This is needed if a class is used with
532 // wxAny in both user shared library and application.
534 #define wxDECLARE_ANY_TYPE(CLS, DECL) \
536 class DECL wxAnyValueTypeImpl<CLS> : \
537 public wxAnyValueTypeImplBase<CLS> \
539 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<CLS>) \
541 wxAnyValueTypeImpl() : \
542 wxAnyValueTypeImplBase<CLS>() { } \
543 virtual ~wxAnyValueTypeImpl() { } \
545 virtual bool ConvertValue(const wxAnyValueBuffer& src, \
546 wxAnyValueType* dstType, \
547 wxAnyValueBuffer& dst) const \
550 wxUnusedVar(dstType); \
557 // Make sure some of wx's own types get the right wxAnyValueType export
558 // (this is needed only for types that are referred to from wxBase.
559 // currently we may not use any of these types from there, but let's
560 // use the macro on at least one to make sure it compiles since we can't
561 // really test it properly in unittests since a separate DLL would
564 #include "wx/datetime.h"
565 wxDECLARE_ANY_TYPE(wxDateTime
, WXDLLIMPEXP_BASE
)
568 //#include "wx/object.h"
569 //wxDECLARE_ANY_TYPE(wxObject*, WXDLLIMPEXP_BASE)
571 //#include "wx/arrstr.h"
572 //wxDECLARE_ANY_TYPE(wxArrayString, WXDLLIMPEXP_BASE)
577 class WXDLLIMPEXP_FWD_BASE wxAnyToVariantRegistration
;
579 // Because of header inter-dependencies, cannot include this earlier
580 #include "wx/variant.h"
583 // wxVariantData* data type implementation. For cases when appropriate
584 // wxAny<->wxVariant conversion code is missing.
587 class WXDLLIMPEXP_BASE wxAnyValueTypeImplVariantData
:
588 public wxAnyValueTypeImplBase
<wxVariantData
*>
590 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplVariantData
)
592 wxAnyValueTypeImplVariantData() :
593 wxAnyValueTypeImplBase
<wxVariantData
*>() { }
594 virtual ~wxAnyValueTypeImplVariantData() { }
596 virtual void DeleteValue(wxAnyValueBuffer
& buf
) const
598 wxVariantData
* data
= static_cast<wxVariantData
*>(buf
.m_ptr
);
603 virtual void CopyBuffer(const wxAnyValueBuffer
& src
,
604 wxAnyValueBuffer
& dst
) const
606 wxVariantData
* data
= static_cast<wxVariantData
*>(src
.m_ptr
);
612 static void SetValue(wxVariantData
* value
,
613 wxAnyValueBuffer
& buf
)
619 static wxVariantData
* GetValue(const wxAnyValueBuffer
& buf
)
621 return static_cast<wxVariantData
*>(buf
.m_ptr
);
624 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
625 wxAnyValueType
* dstType
,
626 wxAnyValueBuffer
& dst
) const
629 wxUnusedVar(dstType
);
636 class wxAnyValueTypeImpl
<wxVariantData
*> :
637 public wxAnyValueTypeImplVariantData
640 wxAnyValueTypeImpl() : wxAnyValueTypeImplVariantData() { }
641 virtual ~wxAnyValueTypeImpl() { }
644 #endif // wxUSE_VARIANT
647 // Re-enable useless VC6 warnings
648 #pragma warning (pop)
653 Let's define a discrete Null value so we don't have to really
654 ever check if wxAny.m_type pointer is NULL or not. This is an
655 optimization, mostly. Implementation of this value type is
656 "hidden" in the source file.
658 extern WXDLLIMPEXP_DATA_BASE(wxAnyValueType
*) wxAnyNullValueType
;
662 // We need to implement custom signed/unsigned int equals operators
663 // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
664 #define WXANY_IMPLEMENT_INT_EQ_OP(TS, TUS) \
665 bool operator==(TS value) const \
667 if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
668 return (value == static_cast<TS> \
669 (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
670 if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
671 return (value == static_cast<TS> \
672 (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
675 bool operator==(TUS value) const \
677 if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
678 return (value == static_cast<TUS> \
679 (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
680 if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
681 return (value == static_cast<TUS> \
682 (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
689 // Note that the following functions are implemented outside wxAny class
690 // so that it can reside entirely in header and lack the export declaration.
692 // Helper function used to associate wxAnyValueType with a wxVariantData.
693 extern WXDLLIMPEXP_BASE
void
694 wxPreRegisterAnyToVariant(wxAnyToVariantRegistration
* reg
);
696 // This function performs main wxAny to wxVariant conversion duties.
697 extern WXDLLIMPEXP_BASE
bool
698 wxConvertAnyToVariant(const wxAny
& any
, wxVariant
* variant
);
700 #endif // wxUSE_VARIANT
704 // The wxAny class represents a container for any type. A variant's value
705 // can be changed at run time, possibly to a different type of value.
707 // As standard, wxAny can store value of almost any type, in a fairly
708 // optimal manner even.
718 m_type
= wxAnyNullValueType
;
726 m_type
->DeleteValue(m_buffer
);
731 Various constructors.
734 wxAny(const T
& value
)
736 m_type
= wxAnyValueTypeImpl
<T
>::sm_instance
.get();
737 wxAnyValueTypeImpl
<T
>::SetValue(value
, m_buffer
);
740 // These two constructors are needed to deal with string literals
741 wxAny(const char* value
)
743 m_type
= wxAnyValueTypeImpl
<const char*>::sm_instance
.get();
744 wxAnyValueTypeImpl
<const char*>::SetValue(value
, m_buffer
);
746 wxAny(const wchar_t* value
)
748 m_type
= wxAnyValueTypeImpl
<const wchar_t*>::sm_instance
.get();
749 wxAnyValueTypeImpl
<const wchar_t*>::SetValue(value
, m_buffer
);
752 wxAny(const wxAny
& any
)
754 m_type
= wxAnyNullValueType
;
759 wxAny(const wxVariant
& variant
)
761 m_type
= wxAnyNullValueType
;
762 AssignVariant(variant
);
769 Use this template function for checking if this wxAny holds
770 a specific C++ data type.
772 @remarks This template function does not work on some older compilers
773 (such as Visual C++ 6.0). For full compiler ccompatibility
774 please use wxANY_CHECK_TYPE(any, T) macro instead.
776 @see wxAnyValueType::CheckType()
778 // FIXME-VC6: remove this hack when VC6 is no longer supported
779 template <typename T
>
780 bool CheckType(T
* = NULL
) const
782 return m_type
->CheckType
<T
>();
786 Returns the value type as wxAnyValueType instance.
788 @remarks You cannot reliably test whether two wxAnys are of
789 same value type by simply comparing return values
790 of wxAny::GetType(). Instead use
791 wxAnyValueType::CheckType<T>() template function.
793 const wxAnyValueType
* GetType() const
799 Tests if wxAny is null (that is, whether there is data).
803 return (m_type
== wxAnyNullValueType
);
807 Makes wxAny null (that is, clears it).
811 m_type
->DeleteValue(m_buffer
);
812 m_type
= wxAnyNullValueType
;
817 Assignment operators.
820 wxAny
& operator=(const T
&value
)
822 m_type
->DeleteValue(m_buffer
);
823 m_type
= wxAnyValueTypeImpl
<T
>::sm_instance
.get();
824 wxAnyValueTypeImpl
<T
>::SetValue(value
, m_buffer
);
828 wxAny
& operator=(const wxAny
&any
)
836 wxAny
& operator=(const wxVariant
&variant
)
838 AssignVariant(variant
);
843 // These two operators are needed to deal with string literals
844 wxAny
& operator=(const char* value
)
849 wxAny
& operator=(const wchar_t* value
)
859 bool operator==(const wxString
& value
) const
862 if ( !GetAs(&value2
) )
864 return value
== value2
;
867 bool operator==(const char* value
) const
868 { return (*this) == wxString(value
); }
869 bool operator==(const wchar_t* value
) const
870 { return (*this) == wxString(value
); }
873 // We need to implement custom signed/unsigned int equals operators
874 // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
875 WXANY_IMPLEMENT_INT_EQ_OP(signed char, unsigned char)
876 WXANY_IMPLEMENT_INT_EQ_OP(signed short, unsigned short)
877 WXANY_IMPLEMENT_INT_EQ_OP(signed int, unsigned int)
878 WXANY_IMPLEMENT_INT_EQ_OP(signed long, unsigned long)
880 WXANY_IMPLEMENT_INT_EQ_OP(wxLongLong_t
, wxULongLong_t
)
883 bool operator==(float value
) const
885 if ( !wxAnyValueTypeImpl
<float>::IsSameClass(m_type
) )
890 (wxAnyValueTypeImpl
<float>::GetValue(m_buffer
));
893 bool operator==(double value
) const
895 if ( !wxAnyValueTypeImpl
<double>::IsSameClass(m_type
) )
900 (wxAnyValueTypeImpl
<double>::GetValue(m_buffer
));
903 bool operator==(bool value
) const
905 if ( !wxAnyValueTypeImpl
<bool>::IsSameClass(m_type
) )
908 return value
== (wxAnyValueTypeImpl
<bool>::GetValue(m_buffer
));
915 Inequality operators (implement as template).
918 bool operator!=(const T
& value
) const
919 { return !((*this) == value
); }
923 This template function converts wxAny into given type. In most cases
924 no type conversion is performed, so if the type is incorrect an
925 assertion failure will occur.
927 @remarks For conveniency, conversion is done when T is wxString. This
928 is useful when a string literal (which are treated as
929 const char* and const wchar_t*) has been assigned to wxAny.
931 This template function may not work properly with Visual C++
932 6. For full compiler compatibility, please use
933 wxANY_AS(any, T) macro instead.
935 // FIXME-VC6: remove this hack when VC6 is no longer supported
937 T
As(T
* = NULL
) const
939 if ( !wxAnyValueTypeImpl
<T
>::IsSameClass(m_type
) )
941 wxFAIL_MSG("Incorrect or non-convertible data type");
944 return static_cast<T
>(wxAnyValueTypeImpl
<T
>::GetValue(m_buffer
));
947 // Allow easy conversion from 'const char *' etc. to wxString
948 // FIXME-VC6: remove this hack when VC6 is no longer supported
950 wxString
As(wxString
*) const
953 if ( !GetAs(&value
) )
955 wxFAIL_MSG("Incorrect or non-convertible data type");
961 Template function that etrieves and converts the value of this
962 variant to the type that T* value is.
964 @return Returns @true if conversion was succesfull.
967 bool GetAs(T
* value
) const
969 if ( !wxAnyValueTypeImpl
<T
>::IsSameClass(m_type
) )
971 wxAnyValueType
* otherType
=
972 wxAnyValueTypeImpl
<T
>::sm_instance
.get();
973 wxAnyValueBuffer temp_buf
;
975 if ( !m_type
->ConvertValue(m_buffer
, otherType
, temp_buf
) )
979 static_cast<T
>(wxAnyValueTypeImpl
<T
>::GetValue(temp_buf
));
980 otherType
->DeleteValue(temp_buf
);
984 *value
= static_cast<T
>(wxAnyValueTypeImpl
<T
>::GetValue(m_buffer
));
989 // GetAs() wxVariant specialization
990 bool GetAs(wxVariant
* value
) const
992 return wxConvertAnyToVariant(*this, value
);
997 // Assignment functions
998 void AssignAny(const wxAny
& any
)
1000 // Must delete value - CopyBuffer() never does that
1001 m_type
->DeleteValue(m_buffer
);
1003 wxAnyValueType
* newType
= any
.m_type
;
1005 if ( !newType
->IsSameType(m_type
) )
1008 newType
->CopyBuffer(any
.m_buffer
, m_buffer
);
1012 void AssignVariant(const wxVariant
& variant
)
1014 wxVariantData
* data
= variant
.GetData();
1016 if ( data
&& data
->GetAsAny(this) )
1019 m_type
->DeleteValue(m_buffer
);
1021 if ( variant
.IsNull() )
1024 m_type
= wxAnyNullValueType
;
1028 // If everything else fails, wrap the whole wxVariantData
1029 m_type
= wxAnyValueTypeImpl
<wxVariantData
*>::sm_instance
.get();
1030 wxAnyValueTypeImpl
<wxVariantData
*>::SetValue(data
, m_buffer
);
1035 template<typename T
>
1036 void Assign(const T
&value
)
1038 m_type
->DeleteValue(m_buffer
);
1039 m_type
= wxAnyValueTypeImpl
<T
>::sm_instance
.get();
1040 wxAnyValueTypeImpl
<T
>::SetValue(value
, m_buffer
);
1044 wxAnyValueBuffer m_buffer
;
1045 wxAnyValueType
* m_type
;
1050 // This method of checking the type is compatible with VC6
1051 #define wxANY_CHECK_TYPE(any, T) \
1052 wxANY_VALUE_TYPE_CHECK_TYPE((any).GetType(), T)
1056 // This method of getting the value is compatible with VC6
1057 #define wxANY_AS(any, T) \
1058 (any).As(static_cast<T*>(NULL))
1061 template<typename T
>
1062 inline bool wxAnyValueType
::CheckType(T
* reserved
) const
1064 wxUnusedVar(reserved
);
1065 return wxAnyValueTypeImpl
<T
>::IsSameClass(this);
1072 #endif // _WX_ANY_H_