1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxAny class
4 // Author: Jaakko Salli
7 // Copyright: (c) wxWidgets team
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
18 #include <new> // for placement new
19 #include "wx/string.h"
20 #include "wx/meta/if.h"
21 #include "wx/typeinfo.h"
24 // Size of the wxAny value buffer.
27 WX_ANY_VALUE_BUFFER_SIZE
= 16
30 union wxAnyValueBuffer
37 long double m_longDouble
;
38 void ( *m_funcPtr
)(void);
39 void ( wxAnyValueBuffer::*m_mFuncPtr
)(void);
43 wxByte m_buffer
[WX_ANY_VALUE_BUFFER_SIZE
];
47 // wxAnyValueType is base class for value type functionality for C++ data
48 // types used with wxAny. Usually the default template (wxAnyValueTypeImpl<>)
49 // will create a satisfactory wxAnyValueType implementation for a data type.
51 class WXDLLIMPEXP_BASE wxAnyValueType
53 WX_DECLARE_ABSTRACT_TYPEINFO(wxAnyValueType
)
65 virtual ~wxAnyValueType()
70 This function is used for internal type matching.
72 virtual bool IsSameType(const wxAnyValueType
* otherType
) const = 0;
75 This function is called every time the data in wxAny
76 buffer needs to be freed.
78 virtual void DeleteValue(wxAnyValueBuffer
& buf
) const = 0;
81 Implement this for buffer-to-buffer copy.
84 This is the source data buffer.
87 This is the destination data buffer that is in either
88 uninitialized or freed state.
90 virtual void CopyBuffer(const wxAnyValueBuffer
& src
,
91 wxAnyValueBuffer
& dst
) const = 0;
94 Convert value into buffer of different type. Return false if
97 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
98 wxAnyValueType
* dstType
,
99 wxAnyValueBuffer
& dst
) const = 0;
102 Use this template function for checking if wxAnyValueType represents
103 a specific C++ data type.
105 @remarks This template function does not work on some older compilers
106 (such as Visual C++ 6.0). For full compiler compatibility
107 please use wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) macro
110 @see wxAny::CheckType()
112 // FIXME-VC6: remove this hack when VC6 is no longer supported
113 template <typename T
>
114 bool CheckType(T
* reserved
= NULL
) const;
116 #if wxUSE_EXTENDED_RTTI
117 virtual const wxTypeInfo
* GetTypeInfo() const = 0;
124 // We need to allocate wxAnyValueType instances in heap, and need to use
125 // scoped ptr to properly deallocate them in dynamic library use cases.
126 // Here we have a minimal specialized scoped ptr implementation to deal
127 // with various compiler-specific problems with template class' static
128 // member variable of template type with explicit constructor which
129 // is initialized in global scope.
131 class wxAnyValueTypeScopedPtr
134 wxAnyValueTypeScopedPtr(wxAnyValueType
* ptr
) : m_ptr(ptr
) { }
135 ~wxAnyValueTypeScopedPtr() { delete m_ptr
; }
136 wxAnyValueType
* get() const { return m_ptr
; }
138 wxAnyValueType
* m_ptr
;
143 // This method of checking the type is compatible with VC6
144 #define wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) \
145 wxAnyValueTypeImpl<T>::IsSameClass(valueTypePtr)
149 Helper macro for defining user value types.
151 Even though C++ RTTI would be fully available to use, we'd have to to
152 facilitate sub-type system which allows, for instance, wxAny with
153 signed short '15' to be treated equal to wxAny with signed long long '15'.
154 Having sm_instance is important here.
156 NB: We really need to have wxAnyValueType instances allocated
157 in heap. They are stored as static template member variables,
158 and with them we just can't be too careful (eg. not allocating
159 them in heap broke the type identification in GCC).
161 #define WX_DECLARE_ANY_VALUE_TYPE(CLS) \
162 friend class wxAny; \
163 WX_DECLARE_TYPEINFO_INLINE(CLS) \
165 static bool IsSameClass(const wxAnyValueType* otherType) \
167 return wxTypeId(*sm_instance.get()) == wxTypeId(*otherType); \
169 virtual bool IsSameType(const wxAnyValueType* otherType) const \
171 return IsSameClass(otherType); \
174 static wxAnyValueTypeScopedPtr sm_instance; \
176 static wxAnyValueType* GetInstance() \
178 return sm_instance.get(); \
182 #define WX_IMPLEMENT_ANY_VALUE_TYPE(CLS) \
183 wxAnyValueTypeScopedPtr CLS::sm_instance(new CLS());
187 // "non dll-interface class 'xxx' used as base interface
188 #pragma warning (push)
189 #pragma warning (disable:4275)
193 Following are helper classes for the wxAnyValueTypeImplBase.
199 class wxAnyValueTypeOpsInplace
202 static void DeleteValue(wxAnyValueBuffer
& buf
)
204 T
* value
= reinterpret_cast<T
*>(&buf
.m_buffer
[0]);
207 // Some compiler may given 'unused variable' warnings without this
211 static void SetValue(const T
& value
,
212 wxAnyValueBuffer
& buf
)
215 void* const place
= buf
.m_buffer
;
216 ::new(place
) T(value
);
219 static const T
& GetValue(const wxAnyValueBuffer
& buf
)
221 // Breaking this code into two lines should suppress
222 // GCC's 'type-punned pointer will break strict-aliasing rules'
224 const T
* value
= reinterpret_cast<const T
*>(&buf
.m_buffer
[0]);
231 class wxAnyValueTypeOpsGeneric
234 template<typename T2
>
238 DataHolder(const T2
& value
)
242 virtual ~DataHolder() { }
246 wxDECLARE_NO_COPY_CLASS(DataHolder
);
249 static void DeleteValue(wxAnyValueBuffer
& buf
)
251 DataHolder
<T
>* holder
= static_cast<DataHolder
<T
>*>(buf
.m_ptr
);
255 static void SetValue(const T
& value
,
256 wxAnyValueBuffer
& buf
)
258 DataHolder
<T
>* holder
= new DataHolder
<T
>(value
);
262 static const T
& GetValue(const wxAnyValueBuffer
& buf
)
264 DataHolder
<T
>* holder
= static_cast<DataHolder
<T
>*>(buf
.m_ptr
);
265 return holder
->m_value
;
269 } // namespace wxPrivate
273 Intermediate template for the generic value type implementation.
274 We can derive from this same value type for multiple actual types
275 (for instance, we can have wxAnyValueTypeImplInt for all signed
276 integer types), and also easily implement specialized templates
277 with specific dynamic type conversion.
280 class wxAnyValueTypeImplBase
: public wxAnyValueType
282 typedef typename wxIf
< sizeof(T
) <= WX_ANY_VALUE_BUFFER_SIZE
,
283 wxPrivate::wxAnyValueTypeOpsInplace
<T
>,
284 wxPrivate::wxAnyValueTypeOpsGeneric
<T
> >::value
288 wxAnyValueTypeImplBase() : wxAnyValueType() { }
289 virtual ~wxAnyValueTypeImplBase() { }
291 virtual void DeleteValue(wxAnyValueBuffer
& buf
) const
293 Ops::DeleteValue(buf
);
296 virtual void CopyBuffer(const wxAnyValueBuffer
& src
,
297 wxAnyValueBuffer
& dst
) const
299 Ops::SetValue(Ops::GetValue(src
), dst
);
303 It is important to reimplement this in any specialized template
304 classes that inherit from wxAnyValueTypeImplBase.
306 static void SetValue(const T
& value
,
307 wxAnyValueBuffer
& buf
)
309 Ops::SetValue(value
, buf
);
313 It is important to reimplement this in any specialized template
314 classes that inherit from wxAnyValueTypeImplBase.
316 static const T
& GetValue(const wxAnyValueBuffer
& buf
)
318 return Ops::GetValue(buf
);
320 #if wxUSE_EXTENDED_RTTI
321 virtual const wxTypeInfo
* GetTypeInfo() const
323 return wxGetTypeInfo((T
*)NULL
);
330 Generic value type template. Note that bulk of the implementation
331 resides in wxAnyValueTypeImplBase.
334 class wxAnyValueTypeImpl
: public wxAnyValueTypeImplBase
<T
>
336 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl
<T
>)
338 wxAnyValueTypeImpl() : wxAnyValueTypeImplBase
<T
>() { }
339 virtual ~wxAnyValueTypeImpl() { }
341 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
342 wxAnyValueType
* dstType
,
343 wxAnyValueBuffer
& dst
) const
346 wxUnusedVar(dstType
);
353 wxAnyValueTypeScopedPtr wxAnyValueTypeImpl
<T
>::sm_instance
= new wxAnyValueTypeImpl
<T
>();
357 // Helper macro for using same base value type implementation for multiple
358 // actual C++ data types.
360 #define _WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
362 class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##CLSTYPE \
364 typedef wxAnyBase##CLSTYPE##Type UseDataType; \
366 wxAnyValueTypeImpl() : wxAnyValueTypeImpl##CLSTYPE() { } \
367 virtual ~wxAnyValueTypeImpl() { } \
368 static void SetValue(const T& value, wxAnyValueBuffer& buf) \
370 void* voidPtr = reinterpret_cast<void*>(&buf.m_buffer[0]); \
371 UseDataType* dptr = reinterpret_cast<UseDataType*>(voidPtr); \
372 *dptr = static_cast<UseDataType>(value); \
374 static T GetValue(const wxAnyValueBuffer& buf) \
376 const void* voidPtr = \
377 reinterpret_cast<const void*>(&buf.m_buffer[0]); \
378 const UseDataType* sptr = \
379 reinterpret_cast<const UseDataType*>(voidPtr); \
380 return static_cast<T>(*sptr); \
383 #if wxUSE_EXTENDED_RTTI
384 #define WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
385 _WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE)\
386 virtual const wxTypeInfo* GetTypeInfo() const \
388 return wxGetTypeInfo((T*)NULL); \
392 #define WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
393 _WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE)\
398 // Integer value types
402 typedef wxLongLong_t wxAnyBaseIntType
;
403 typedef wxULongLong_t wxAnyBaseUintType
;
405 typedef long wxAnyBaseIntType
;
406 typedef unsigned long wxAnyBaseUintType
;
410 class WXDLLIMPEXP_BASE wxAnyValueTypeImplInt
:
411 public wxAnyValueTypeImplBase
<wxAnyBaseIntType
>
413 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplInt
)
415 wxAnyValueTypeImplInt() :
416 wxAnyValueTypeImplBase
<wxAnyBaseIntType
>() { }
417 virtual ~wxAnyValueTypeImplInt() { }
419 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
420 wxAnyValueType
* dstType
,
421 wxAnyValueBuffer
& dst
) const;
425 class WXDLLIMPEXP_BASE wxAnyValueTypeImplUint
:
426 public wxAnyValueTypeImplBase
<wxAnyBaseUintType
>
428 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplUint
)
430 wxAnyValueTypeImplUint() :
431 wxAnyValueTypeImplBase
<wxAnyBaseUintType
>() { }
432 virtual ~wxAnyValueTypeImplUint() { }
434 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
435 wxAnyValueType
* dstType
,
436 wxAnyValueBuffer
& dst
) const;
440 WX_ANY_DEFINE_SUB_TYPE(signed long, Int
)
441 WX_ANY_DEFINE_SUB_TYPE(signed int, Int
)
442 WX_ANY_DEFINE_SUB_TYPE(signed short, Int
)
443 WX_ANY_DEFINE_SUB_TYPE(signed char, Int
)
445 WX_ANY_DEFINE_SUB_TYPE(wxLongLong_t
, Int
)
448 WX_ANY_DEFINE_SUB_TYPE(unsigned long, Uint
)
449 WX_ANY_DEFINE_SUB_TYPE(unsigned int, Uint
)
450 WX_ANY_DEFINE_SUB_TYPE(unsigned short, Uint
)
451 WX_ANY_DEFINE_SUB_TYPE(unsigned char, Uint
)
453 WX_ANY_DEFINE_SUB_TYPE(wxULongLong_t
, Uint
)
458 // This macro is used in header, but then in source file we must have:
459 // WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl##TYPENAME)
461 #define _WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, GV) \
462 class WXDLLIMPEXP_BASE wxAnyValueTypeImpl##TYPENAME : \
463 public wxAnyValueTypeImplBase<T> \
465 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl##TYPENAME) \
467 wxAnyValueTypeImpl##TYPENAME() : \
468 wxAnyValueTypeImplBase<T>() { } \
469 virtual ~wxAnyValueTypeImpl##TYPENAME() { } \
470 virtual bool ConvertValue(const wxAnyValueBuffer& src, \
471 wxAnyValueType* dstType, \
472 wxAnyValueBuffer& dst) const \
474 GV value = GetValue(src); \
475 return CONVFUNC(value, dstType, dst); \
479 class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##TYPENAME \
482 wxAnyValueTypeImpl() : wxAnyValueTypeImpl##TYPENAME() { } \
483 virtual ~wxAnyValueTypeImpl() { } \
486 #define WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, BT) \
487 _WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, BT) \
489 #define WX_ANY_DEFINE_CONVERTIBLE_TYPE_BASE(T, TYPENAME, CONVFUNC) \
490 _WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, \
491 CONVFUNC, const T&) \
497 // Convert wxString to destination wxAny value type
498 extern WXDLLIMPEXP_BASE
bool wxAnyConvertString(const wxString
& value
,
499 wxAnyValueType
* dstType
,
500 wxAnyValueBuffer
& dst
);
502 WX_ANY_DEFINE_CONVERTIBLE_TYPE_BASE(wxString
, wxString
, wxAnyConvertString
)
503 WX_ANY_DEFINE_CONVERTIBLE_TYPE(const char*, ConstCharPtr
,
504 wxAnyConvertString
, wxString
)
505 WX_ANY_DEFINE_CONVERTIBLE_TYPE(const wchar_t*, ConstWchar_tPtr
,
506 wxAnyConvertString
, wxString
)
512 class WXDLLIMPEXP_BASE wxAnyValueTypeImpl
<bool> :
513 public wxAnyValueTypeImplBase
<bool>
515 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl
<bool>)
517 wxAnyValueTypeImpl() :
518 wxAnyValueTypeImplBase
<bool>() { }
519 virtual ~wxAnyValueTypeImpl() { }
521 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
522 wxAnyValueType
* dstType
,
523 wxAnyValueBuffer
& dst
) const;
527 // Floating point value type
529 class WXDLLIMPEXP_BASE wxAnyValueTypeImplDouble
:
530 public wxAnyValueTypeImplBase
<double>
532 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble
)
534 wxAnyValueTypeImplDouble() :
535 wxAnyValueTypeImplBase
<double>() { }
536 virtual ~wxAnyValueTypeImplDouble() { }
538 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
539 wxAnyValueType
* dstType
,
540 wxAnyValueBuffer
& dst
) const;
543 // WX_ANY_DEFINE_SUB_TYPE requires this
544 typedef double wxAnyBaseDoubleType
;
546 WX_ANY_DEFINE_SUB_TYPE(float, Double
)
547 WX_ANY_DEFINE_SUB_TYPE(double, Double
)
551 // Defines a dummy wxAnyValueTypeImpl<> with given export
552 // declaration. This is needed if a class is used with
553 // wxAny in both user shared library and application.
555 #define wxDECLARE_ANY_TYPE(CLS, DECL) \
557 class DECL wxAnyValueTypeImpl<CLS> : \
558 public wxAnyValueTypeImplBase<CLS> \
560 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<CLS>) \
562 wxAnyValueTypeImpl() : \
563 wxAnyValueTypeImplBase<CLS>() { } \
564 virtual ~wxAnyValueTypeImpl() { } \
566 virtual bool ConvertValue(const wxAnyValueBuffer& src, \
567 wxAnyValueType* dstType, \
568 wxAnyValueBuffer& dst) const \
571 wxUnusedVar(dstType); \
578 // Make sure some of wx's own types get the right wxAnyValueType export
579 // (this is needed only for types that are referred to from wxBase.
580 // currently we may not use any of these types from there, but let's
581 // use the macro on at least one to make sure it compiles since we can't
582 // really test it properly in unit tests since a separate DLL would
585 #include "wx/datetime.h"
586 wxDECLARE_ANY_TYPE(wxDateTime
, WXDLLIMPEXP_BASE
)
589 //#include "wx/object.h"
590 //wxDECLARE_ANY_TYPE(wxObject*, WXDLLIMPEXP_BASE)
592 //#include "wx/arrstr.h"
593 //wxDECLARE_ANY_TYPE(wxArrayString, WXDLLIMPEXP_BASE)
598 class WXDLLIMPEXP_FWD_BASE wxAnyToVariantRegistration
;
600 // Because of header inter-dependencies, cannot include this earlier
601 #include "wx/variant.h"
604 // wxVariantData* data type implementation. For cases when appropriate
605 // wxAny<->wxVariant conversion code is missing.
608 class WXDLLIMPEXP_BASE wxAnyValueTypeImplVariantData
:
609 public wxAnyValueTypeImplBase
<wxVariantData
*>
611 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplVariantData
)
613 wxAnyValueTypeImplVariantData() :
614 wxAnyValueTypeImplBase
<wxVariantData
*>() { }
615 virtual ~wxAnyValueTypeImplVariantData() { }
617 virtual void DeleteValue(wxAnyValueBuffer
& buf
) const
619 wxVariantData
* data
= static_cast<wxVariantData
*>(buf
.m_ptr
);
624 virtual void CopyBuffer(const wxAnyValueBuffer
& src
,
625 wxAnyValueBuffer
& dst
) const
627 wxVariantData
* data
= static_cast<wxVariantData
*>(src
.m_ptr
);
633 static void SetValue(wxVariantData
* value
,
634 wxAnyValueBuffer
& buf
)
640 static wxVariantData
* GetValue(const wxAnyValueBuffer
& buf
)
642 return static_cast<wxVariantData
*>(buf
.m_ptr
);
645 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
646 wxAnyValueType
* dstType
,
647 wxAnyValueBuffer
& dst
) const
650 wxUnusedVar(dstType
);
657 class wxAnyValueTypeImpl
<wxVariantData
*> :
658 public wxAnyValueTypeImplVariantData
661 wxAnyValueTypeImpl() : wxAnyValueTypeImplVariantData() { }
662 virtual ~wxAnyValueTypeImpl() { }
665 #endif // wxUSE_VARIANT
668 // Re-enable useless VC6 warnings
669 #pragma warning (pop)
674 Let's define a discrete Null value so we don't have to really
675 ever check if wxAny.m_type pointer is NULL or not. This is an
676 optimization, mostly. Implementation of this value type is
677 "hidden" in the source file.
679 extern WXDLLIMPEXP_DATA_BASE(wxAnyValueType
*) wxAnyNullValueType
;
683 // We need to implement custom signed/unsigned int equals operators
684 // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
685 #define WXANY_IMPLEMENT_INT_EQ_OP(TS, TUS) \
686 bool operator==(TS value) const \
688 if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
689 return (value == static_cast<TS> \
690 (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
691 if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
692 return (value == static_cast<TS> \
693 (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
696 bool operator==(TUS value) const \
698 if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
699 return (value == static_cast<TUS> \
700 (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
701 if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
702 return (value == static_cast<TUS> \
703 (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
710 // Note that the following functions are implemented outside wxAny class
711 // so that it can reside entirely in header and lack the export declaration.
713 // Helper function used to associate wxAnyValueType with a wxVariantData.
714 extern WXDLLIMPEXP_BASE
void
715 wxPreRegisterAnyToVariant(wxAnyToVariantRegistration
* reg
);
717 // This function performs main wxAny to wxVariant conversion duties.
718 extern WXDLLIMPEXP_BASE
bool
719 wxConvertAnyToVariant(const wxAny
& any
, wxVariant
* variant
);
721 #endif // wxUSE_VARIANT
725 // The wxAny class represents a container for any type. A variant's value
726 // can be changed at run time, possibly to a different type of value.
728 // As standard, wxAny can store value of almost any type, in a fairly
729 // optimal manner even.
739 m_type
= wxAnyNullValueType
;
747 m_type
->DeleteValue(m_buffer
);
752 Various constructors.
755 wxAny(const T
& value
)
757 m_type
= wxAnyValueTypeImpl
<T
>::sm_instance
.get();
758 wxAnyValueTypeImpl
<T
>::SetValue(value
, m_buffer
);
761 // These two constructors are needed to deal with string literals
762 wxAny(const char* value
)
764 m_type
= wxAnyValueTypeImpl
<const char*>::sm_instance
.get();
765 wxAnyValueTypeImpl
<const char*>::SetValue(value
, m_buffer
);
767 wxAny(const wchar_t* value
)
769 m_type
= wxAnyValueTypeImpl
<const wchar_t*>::sm_instance
.get();
770 wxAnyValueTypeImpl
<const wchar_t*>::SetValue(value
, m_buffer
);
773 wxAny(const wxAny
& any
)
775 m_type
= wxAnyNullValueType
;
780 wxAny(const wxVariant
& variant
)
782 m_type
= wxAnyNullValueType
;
783 AssignVariant(variant
);
790 Use this template function for checking if this wxAny holds
791 a specific C++ data type.
793 @remarks This template function does not work on some older compilers
794 (such as Visual C++ 6.0). For full compiler ccompatibility
795 please use wxANY_CHECK_TYPE(any, T) macro instead.
797 @see wxAnyValueType::CheckType()
799 // FIXME-VC6: remove this hack when VC6 is no longer supported
800 template <typename T
>
801 bool CheckType(T
* = NULL
) const
803 return m_type
->CheckType
<T
>();
807 Returns the value type as wxAnyValueType instance.
809 @remarks You cannot reliably test whether two wxAnys are of
810 same value type by simply comparing return values
811 of wxAny::GetType(). Instead, use wxAny::HasSameType().
815 const wxAnyValueType
* GetType() const
821 Returns @true if this and another wxAny have the same
824 bool HasSameType(const wxAny
& other
) const
826 return GetType()->IsSameType(other
.GetType());
830 Tests if wxAny is null (that is, whether there is no data).
834 return (m_type
== wxAnyNullValueType
);
838 Makes wxAny null (that is, clears it).
842 m_type
->DeleteValue(m_buffer
);
843 m_type
= wxAnyNullValueType
;
848 Assignment operators.
851 wxAny
& operator=(const T
&value
)
853 m_type
->DeleteValue(m_buffer
);
854 m_type
= wxAnyValueTypeImpl
<T
>::sm_instance
.get();
855 wxAnyValueTypeImpl
<T
>::SetValue(value
, m_buffer
);
859 wxAny
& operator=(const wxAny
&any
)
867 wxAny
& operator=(const wxVariant
&variant
)
869 AssignVariant(variant
);
874 // These two operators are needed to deal with string literals
875 wxAny
& operator=(const char* value
)
880 wxAny
& operator=(const wchar_t* value
)
890 bool operator==(const wxString
& value
) const
893 if ( !GetAs(&value2
) )
895 return value
== value2
;
898 bool operator==(const char* value
) const
899 { return (*this) == wxString(value
); }
900 bool operator==(const wchar_t* value
) const
901 { return (*this) == wxString(value
); }
904 // We need to implement custom signed/unsigned int equals operators
905 // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
906 WXANY_IMPLEMENT_INT_EQ_OP(signed char, unsigned char)
907 WXANY_IMPLEMENT_INT_EQ_OP(signed short, unsigned short)
908 WXANY_IMPLEMENT_INT_EQ_OP(signed int, unsigned int)
909 WXANY_IMPLEMENT_INT_EQ_OP(signed long, unsigned long)
911 WXANY_IMPLEMENT_INT_EQ_OP(wxLongLong_t
, wxULongLong_t
)
914 wxGCC_WARNING_SUPPRESS(float-equal
)
916 bool operator==(float value
) const
918 if ( !wxAnyValueTypeImpl
<float>::IsSameClass(m_type
) )
923 (wxAnyValueTypeImpl
<float>::GetValue(m_buffer
));
926 bool operator==(double value
) const
928 if ( !wxAnyValueTypeImpl
<double>::IsSameClass(m_type
) )
933 (wxAnyValueTypeImpl
<double>::GetValue(m_buffer
));
936 wxGCC_WARNING_RESTORE(float-equal
)
938 bool operator==(bool value
) const
940 if ( !wxAnyValueTypeImpl
<bool>::IsSameClass(m_type
) )
943 return value
== (wxAnyValueTypeImpl
<bool>::GetValue(m_buffer
));
950 Inequality operators (implement as template).
953 bool operator!=(const T
& value
) const
954 { return !((*this) == value
); }
958 This template function converts wxAny into given type. In most cases
959 no type conversion is performed, so if the type is incorrect an
960 assertion failure will occur.
962 @remarks For convenience, conversion is done when T is wxString. This
963 is useful when a string literal (which are treated as
964 const char* and const wchar_t*) has been assigned to wxAny.
966 This template function may not work properly with Visual C++
967 6. For full compiler compatibility, please use
968 wxANY_AS(any, T) macro instead.
970 // FIXME-VC6: remove this hack when VC6 is no longer supported
972 T
As(T
* = NULL
) const
974 if ( !wxAnyValueTypeImpl
<T
>::IsSameClass(m_type
) )
976 wxFAIL_MSG("Incorrect or non-convertible data type");
979 return static_cast<T
>(wxAnyValueTypeImpl
<T
>::GetValue(m_buffer
));
982 // Allow easy conversion from 'const char *' etc. to wxString
983 // FIXME-VC6: remove this hack when VC6 is no longer supported
985 wxString
As(wxString
*) const
988 if ( !GetAs(&value
) )
990 wxFAIL_MSG("Incorrect or non-convertible data type");
995 #if wxUSE_EXTENDED_RTTI
996 const wxTypeInfo
* GetTypeInfo() const
998 return m_type
->GetTypeInfo();
1002 Template function that retrieves and converts the value of this
1003 variant to the type that T* value is.
1005 @return Returns @true if conversion was successful.
1007 template<typename T
>
1008 bool GetAs(T
* value
) const
1010 if ( !wxAnyValueTypeImpl
<T
>::IsSameClass(m_type
) )
1012 wxAnyValueType
* otherType
=
1013 wxAnyValueTypeImpl
<T
>::sm_instance
.get();
1014 wxAnyValueBuffer temp_buf
;
1016 if ( !m_type
->ConvertValue(m_buffer
, otherType
, temp_buf
) )
1020 static_cast<T
>(wxAnyValueTypeImpl
<T
>::GetValue(temp_buf
));
1021 otherType
->DeleteValue(temp_buf
);
1025 *value
= static_cast<T
>(wxAnyValueTypeImpl
<T
>::GetValue(m_buffer
));
1030 // GetAs() wxVariant specialization
1031 bool GetAs(wxVariant
* value
) const
1033 return wxConvertAnyToVariant(*this, value
);
1038 // Assignment functions
1039 void AssignAny(const wxAny
& any
)
1041 // Must delete value - CopyBuffer() never does that
1042 m_type
->DeleteValue(m_buffer
);
1044 wxAnyValueType
* newType
= any
.m_type
;
1046 if ( !newType
->IsSameType(m_type
) )
1049 newType
->CopyBuffer(any
.m_buffer
, m_buffer
);
1053 void AssignVariant(const wxVariant
& variant
)
1055 wxVariantData
* data
= variant
.GetData();
1057 if ( data
&& data
->GetAsAny(this) )
1060 m_type
->DeleteValue(m_buffer
);
1062 if ( variant
.IsNull() )
1065 m_type
= wxAnyNullValueType
;
1069 // If everything else fails, wrap the whole wxVariantData
1070 m_type
= wxAnyValueTypeImpl
<wxVariantData
*>::sm_instance
.get();
1071 wxAnyValueTypeImpl
<wxVariantData
*>::SetValue(data
, m_buffer
);
1076 template<typename T
>
1077 void Assign(const T
&value
)
1079 m_type
->DeleteValue(m_buffer
);
1080 m_type
= wxAnyValueTypeImpl
<T
>::sm_instance
.get();
1081 wxAnyValueTypeImpl
<T
>::SetValue(value
, m_buffer
);
1085 wxAnyValueBuffer m_buffer
;
1086 wxAnyValueType
* m_type
;
1091 // This method of checking the type is compatible with VC6
1092 #define wxANY_CHECK_TYPE(any, T) \
1093 wxANY_VALUE_TYPE_CHECK_TYPE((any).GetType(), T)
1097 // This method of getting the value is compatible with VC6
1098 #define wxANY_AS(any, T) \
1099 (any).As(static_cast<T*>(NULL))
1102 template<typename T
>
1103 inline bool wxAnyValueType::CheckType(T
* reserved
) const
1105 wxUnusedVar(reserved
);
1106 return wxAnyValueTypeImpl
<T
>::IsSameClass(this);
1109 WX_DECLARE_LIST_WITH_DECL(wxAny
, wxAnyList
, class WXDLLIMPEXP_BASE
);
1113 #endif // _WX_ANY_H_