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 compatibility
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;
117 #if wxUSE_EXTENDED_RTTI
118 virtual const wxTypeInfo
* GetTypeInfo() const = 0;
125 // We need to allocate wxAnyValueType instances in heap, and need to use
126 // scoped ptr to properly deallocate them in dynamic library use cases.
127 // Here we have a minimal specialized scoped ptr implementation to deal
128 // with various compiler-specific problems with template class' static
129 // member variable of template type with explicit constructor which
130 // is initialized in global scope.
132 class wxAnyValueTypeScopedPtr
135 wxAnyValueTypeScopedPtr(wxAnyValueType
* ptr
) : m_ptr(ptr
) { }
136 ~wxAnyValueTypeScopedPtr() { delete m_ptr
; }
137 wxAnyValueType
* get() const { return m_ptr
; }
139 wxAnyValueType
* m_ptr
;
144 // This method of checking the type is compatible with VC6
145 #define wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) \
146 wxAnyValueTypeImpl<T>::IsSameClass(valueTypePtr)
150 Helper macro for defining user value types.
152 Even though C++ RTTI would be fully available to use, we'd have to to
153 facilitate sub-type system which allows, for instance, wxAny with
154 signed short '15' to be treated equal to wxAny with signed long long '15'.
155 Having sm_instance is important here.
157 NB: We really need to have wxAnyValueType instances allocated
158 in heap. They are stored as static template member variables,
159 and with them we just can't be too careful (eg. not allocating
160 them in heap broke the type identification in GCC).
162 #define WX_DECLARE_ANY_VALUE_TYPE(CLS) \
163 friend class wxAny; \
164 WX_DECLARE_TYPEINFO_INLINE(CLS) \
166 static bool IsSameClass(const wxAnyValueType* otherType) \
168 return wxTypeId(*sm_instance.get()) == wxTypeId(*otherType); \
170 virtual bool IsSameType(const wxAnyValueType* otherType) const \
172 return IsSameClass(otherType); \
175 static wxAnyValueTypeScopedPtr sm_instance; \
177 static wxAnyValueType* GetInstance() \
179 return sm_instance.get(); \
183 #define WX_IMPLEMENT_ANY_VALUE_TYPE(CLS) \
184 wxAnyValueTypeScopedPtr CLS::sm_instance(new CLS());
188 // "non dll-interface class 'xxx' used as base interface
189 #pragma warning (push)
190 #pragma warning (disable:4275)
194 Following are helper classes for the wxAnyValueTypeImplBase.
200 class wxAnyValueTypeOpsInplace
203 static void DeleteValue(wxAnyValueBuffer
& buf
)
205 T
* value
= reinterpret_cast<T
*>(&buf
.m_buffer
[0]);
208 // Some compiler may given 'unused variable' warnings without this
212 static void SetValue(const T
& value
,
213 wxAnyValueBuffer
& buf
)
216 void* const place
= buf
.m_buffer
;
217 ::new(place
) T(value
);
220 static const T
& GetValue(const wxAnyValueBuffer
& buf
)
222 // Breaking this code into two lines should suppress
223 // GCC's 'type-punned pointer will break strict-aliasing rules'
225 const T
* value
= reinterpret_cast<const T
*>(&buf
.m_buffer
[0]);
232 class wxAnyValueTypeOpsGeneric
235 template<typename T2
>
239 DataHolder(const T2
& value
)
243 virtual ~DataHolder() { }
247 wxDECLARE_NO_COPY_CLASS(DataHolder
);
250 static void DeleteValue(wxAnyValueBuffer
& buf
)
252 DataHolder
<T
>* holder
= static_cast<DataHolder
<T
>*>(buf
.m_ptr
);
256 static void SetValue(const T
& value
,
257 wxAnyValueBuffer
& buf
)
259 DataHolder
<T
>* holder
= new DataHolder
<T
>(value
);
263 static const T
& GetValue(const wxAnyValueBuffer
& buf
)
265 DataHolder
<T
>* holder
= static_cast<DataHolder
<T
>*>(buf
.m_ptr
);
266 return holder
->m_value
;
270 } // namespace wxPrivate
274 Intermediate template for the generic value type implementation.
275 We can derive from this same value type for multiple actual types
276 (for instance, we can have wxAnyValueTypeImplInt for all signed
277 integer types), and also easily implement specialized templates
278 with specific dynamic type conversion.
281 class wxAnyValueTypeImplBase
: public wxAnyValueType
283 typedef typename wxIf
< sizeof(T
) <= WX_ANY_VALUE_BUFFER_SIZE
,
284 wxPrivate::wxAnyValueTypeOpsInplace
<T
>,
285 wxPrivate::wxAnyValueTypeOpsGeneric
<T
> >::value
289 wxAnyValueTypeImplBase() : wxAnyValueType() { }
290 virtual ~wxAnyValueTypeImplBase() { }
292 virtual void DeleteValue(wxAnyValueBuffer
& buf
) const
294 Ops::DeleteValue(buf
);
297 virtual void CopyBuffer(const wxAnyValueBuffer
& src
,
298 wxAnyValueBuffer
& dst
) const
300 Ops::SetValue(Ops::GetValue(src
), dst
);
304 It is important to reimplement this in any specialized template
305 classes that inherit from wxAnyValueTypeImplBase.
307 static void SetValue(const T
& value
,
308 wxAnyValueBuffer
& buf
)
310 Ops::SetValue(value
, buf
);
314 It is important to reimplement this in any specialized template
315 classes that inherit from wxAnyValueTypeImplBase.
317 static const T
& GetValue(const wxAnyValueBuffer
& buf
)
319 return Ops::GetValue(buf
);
321 #if wxUSE_EXTENDED_RTTI
322 virtual const wxTypeInfo
* GetTypeInfo() const
324 return wxGetTypeInfo((T
*)NULL
);
331 Generic value type template. Note that bulk of the implementation
332 resides in wxAnyValueTypeImplBase.
335 class wxAnyValueTypeImpl
: public wxAnyValueTypeImplBase
<T
>
337 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl
<T
>)
339 wxAnyValueTypeImpl() : wxAnyValueTypeImplBase
<T
>() { }
340 virtual ~wxAnyValueTypeImpl() { }
342 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
343 wxAnyValueType
* dstType
,
344 wxAnyValueBuffer
& dst
) const
347 wxUnusedVar(dstType
);
354 wxAnyValueTypeScopedPtr wxAnyValueTypeImpl
<T
>::sm_instance
= new wxAnyValueTypeImpl
<T
>();
358 // Helper macro for using same base value type implementation for multiple
359 // actual C++ data types.
361 #define _WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
363 class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##CLSTYPE \
365 typedef wxAnyBase##CLSTYPE##Type UseDataType; \
367 wxAnyValueTypeImpl() : wxAnyValueTypeImpl##CLSTYPE() { } \
368 virtual ~wxAnyValueTypeImpl() { } \
369 static void SetValue(const T& value, wxAnyValueBuffer& buf) \
371 void* voidPtr = reinterpret_cast<void*>(&buf.m_buffer[0]); \
372 UseDataType* dptr = reinterpret_cast<UseDataType*>(voidPtr); \
373 *dptr = static_cast<UseDataType>(value); \
375 static T GetValue(const wxAnyValueBuffer& buf) \
377 const void* voidPtr = \
378 reinterpret_cast<const void*>(&buf.m_buffer[0]); \
379 const UseDataType* sptr = \
380 reinterpret_cast<const UseDataType*>(voidPtr); \
381 return static_cast<T>(*sptr); \
384 #if wxUSE_EXTENDED_RTTI
385 #define WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
386 _WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE)\
387 virtual const wxTypeInfo* GetTypeInfo() const \
389 return wxGetTypeInfo((T*)NULL); \
393 #define WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
394 _WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE)\
399 // Integer value types
403 typedef wxLongLong_t wxAnyBaseIntType
;
404 typedef wxULongLong_t wxAnyBaseUintType
;
406 typedef long wxAnyBaseIntType
;
407 typedef unsigned long wxAnyBaseUintType
;
411 class WXDLLIMPEXP_BASE wxAnyValueTypeImplInt
:
412 public wxAnyValueTypeImplBase
<wxAnyBaseIntType
>
414 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplInt
)
416 wxAnyValueTypeImplInt() :
417 wxAnyValueTypeImplBase
<wxAnyBaseIntType
>() { }
418 virtual ~wxAnyValueTypeImplInt() { }
420 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
421 wxAnyValueType
* dstType
,
422 wxAnyValueBuffer
& dst
) const;
426 class WXDLLIMPEXP_BASE wxAnyValueTypeImplUint
:
427 public wxAnyValueTypeImplBase
<wxAnyBaseUintType
>
429 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplUint
)
431 wxAnyValueTypeImplUint() :
432 wxAnyValueTypeImplBase
<wxAnyBaseUintType
>() { }
433 virtual ~wxAnyValueTypeImplUint() { }
435 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
436 wxAnyValueType
* dstType
,
437 wxAnyValueBuffer
& dst
) const;
441 WX_ANY_DEFINE_SUB_TYPE(signed long, Int
)
442 WX_ANY_DEFINE_SUB_TYPE(signed int, Int
)
443 WX_ANY_DEFINE_SUB_TYPE(signed short, Int
)
444 WX_ANY_DEFINE_SUB_TYPE(signed char, Int
)
446 WX_ANY_DEFINE_SUB_TYPE(wxLongLong_t
, Int
)
449 WX_ANY_DEFINE_SUB_TYPE(unsigned long, Uint
)
450 WX_ANY_DEFINE_SUB_TYPE(unsigned int, Uint
)
451 WX_ANY_DEFINE_SUB_TYPE(unsigned short, Uint
)
452 WX_ANY_DEFINE_SUB_TYPE(unsigned char, Uint
)
454 WX_ANY_DEFINE_SUB_TYPE(wxULongLong_t
, Uint
)
459 // This macro is used in header, but then in source file we must have:
460 // WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl##TYPENAME)
462 #define _WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, GV) \
463 class WXDLLIMPEXP_BASE wxAnyValueTypeImpl##TYPENAME : \
464 public wxAnyValueTypeImplBase<T> \
466 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl##TYPENAME) \
468 wxAnyValueTypeImpl##TYPENAME() : \
469 wxAnyValueTypeImplBase<T>() { } \
470 virtual ~wxAnyValueTypeImpl##TYPENAME() { } \
471 virtual bool ConvertValue(const wxAnyValueBuffer& src, \
472 wxAnyValueType* dstType, \
473 wxAnyValueBuffer& dst) const \
475 GV value = GetValue(src); \
476 return CONVFUNC(value, dstType, dst); \
480 class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##TYPENAME \
483 wxAnyValueTypeImpl() : wxAnyValueTypeImpl##TYPENAME() { } \
484 virtual ~wxAnyValueTypeImpl() { } \
487 #define WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, BT) \
488 _WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, BT) \
490 #define WX_ANY_DEFINE_CONVERTIBLE_TYPE_BASE(T, TYPENAME, CONVFUNC) \
491 _WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, \
492 CONVFUNC, const T&) \
498 // Convert wxString to destination wxAny value type
499 extern WXDLLIMPEXP_BASE
bool wxAnyConvertString(const wxString
& value
,
500 wxAnyValueType
* dstType
,
501 wxAnyValueBuffer
& dst
);
503 WX_ANY_DEFINE_CONVERTIBLE_TYPE_BASE(wxString
, wxString
, wxAnyConvertString
)
504 WX_ANY_DEFINE_CONVERTIBLE_TYPE(const char*, ConstCharPtr
,
505 wxAnyConvertString
, wxString
)
506 WX_ANY_DEFINE_CONVERTIBLE_TYPE(const wchar_t*, ConstWchar_tPtr
,
507 wxAnyConvertString
, wxString
)
513 class WXDLLIMPEXP_BASE wxAnyValueTypeImpl
<bool> :
514 public wxAnyValueTypeImplBase
<bool>
516 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl
<bool>)
518 wxAnyValueTypeImpl() :
519 wxAnyValueTypeImplBase
<bool>() { }
520 virtual ~wxAnyValueTypeImpl() { }
522 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
523 wxAnyValueType
* dstType
,
524 wxAnyValueBuffer
& dst
) const;
528 // Floating point value type
530 class WXDLLIMPEXP_BASE wxAnyValueTypeImplDouble
:
531 public wxAnyValueTypeImplBase
<double>
533 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble
)
535 wxAnyValueTypeImplDouble() :
536 wxAnyValueTypeImplBase
<double>() { }
537 virtual ~wxAnyValueTypeImplDouble() { }
539 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
540 wxAnyValueType
* dstType
,
541 wxAnyValueBuffer
& dst
) const;
544 // WX_ANY_DEFINE_SUB_TYPE requires this
545 typedef double wxAnyBaseDoubleType
;
547 WX_ANY_DEFINE_SUB_TYPE(float, Double
)
548 WX_ANY_DEFINE_SUB_TYPE(double, Double
)
552 // Defines a dummy wxAnyValueTypeImpl<> with given export
553 // declaration. This is needed if a class is used with
554 // wxAny in both user shared library and application.
556 #define wxDECLARE_ANY_TYPE(CLS, DECL) \
558 class DECL wxAnyValueTypeImpl<CLS> : \
559 public wxAnyValueTypeImplBase<CLS> \
561 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<CLS>) \
563 wxAnyValueTypeImpl() : \
564 wxAnyValueTypeImplBase<CLS>() { } \
565 virtual ~wxAnyValueTypeImpl() { } \
567 virtual bool ConvertValue(const wxAnyValueBuffer& src, \
568 wxAnyValueType* dstType, \
569 wxAnyValueBuffer& dst) const \
572 wxUnusedVar(dstType); \
579 // Make sure some of wx's own types get the right wxAnyValueType export
580 // (this is needed only for types that are referred to from wxBase.
581 // currently we may not use any of these types from there, but let's
582 // use the macro on at least one to make sure it compiles since we can't
583 // really test it properly in unit tests since a separate DLL would
586 #include "wx/datetime.h"
587 wxDECLARE_ANY_TYPE(wxDateTime
, WXDLLIMPEXP_BASE
)
590 //#include "wx/object.h"
591 //wxDECLARE_ANY_TYPE(wxObject*, WXDLLIMPEXP_BASE)
593 //#include "wx/arrstr.h"
594 //wxDECLARE_ANY_TYPE(wxArrayString, WXDLLIMPEXP_BASE)
599 class WXDLLIMPEXP_FWD_BASE wxAnyToVariantRegistration
;
601 // Because of header inter-dependencies, cannot include this earlier
602 #include "wx/variant.h"
605 // wxVariantData* data type implementation. For cases when appropriate
606 // wxAny<->wxVariant conversion code is missing.
609 class WXDLLIMPEXP_BASE wxAnyValueTypeImplVariantData
:
610 public wxAnyValueTypeImplBase
<wxVariantData
*>
612 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplVariantData
)
614 wxAnyValueTypeImplVariantData() :
615 wxAnyValueTypeImplBase
<wxVariantData
*>() { }
616 virtual ~wxAnyValueTypeImplVariantData() { }
618 virtual void DeleteValue(wxAnyValueBuffer
& buf
) const
620 wxVariantData
* data
= static_cast<wxVariantData
*>(buf
.m_ptr
);
625 virtual void CopyBuffer(const wxAnyValueBuffer
& src
,
626 wxAnyValueBuffer
& dst
) const
628 wxVariantData
* data
= static_cast<wxVariantData
*>(src
.m_ptr
);
634 static void SetValue(wxVariantData
* value
,
635 wxAnyValueBuffer
& buf
)
641 static wxVariantData
* GetValue(const wxAnyValueBuffer
& buf
)
643 return static_cast<wxVariantData
*>(buf
.m_ptr
);
646 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
647 wxAnyValueType
* dstType
,
648 wxAnyValueBuffer
& dst
) const
651 wxUnusedVar(dstType
);
658 class wxAnyValueTypeImpl
<wxVariantData
*> :
659 public wxAnyValueTypeImplVariantData
662 wxAnyValueTypeImpl() : wxAnyValueTypeImplVariantData() { }
663 virtual ~wxAnyValueTypeImpl() { }
666 #endif // wxUSE_VARIANT
669 // Re-enable useless VC6 warnings
670 #pragma warning (pop)
675 Let's define a discrete Null value so we don't have to really
676 ever check if wxAny.m_type pointer is NULL or not. This is an
677 optimization, mostly. Implementation of this value type is
678 "hidden" in the source file.
680 extern WXDLLIMPEXP_DATA_BASE(wxAnyValueType
*) wxAnyNullValueType
;
684 // We need to implement custom signed/unsigned int equals operators
685 // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
686 #define WXANY_IMPLEMENT_INT_EQ_OP(TS, TUS) \
687 bool operator==(TS value) const \
689 if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
690 return (value == static_cast<TS> \
691 (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
692 if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
693 return (value == static_cast<TS> \
694 (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
697 bool operator==(TUS value) const \
699 if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
700 return (value == static_cast<TUS> \
701 (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
702 if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
703 return (value == static_cast<TUS> \
704 (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
711 // Note that the following functions are implemented outside wxAny class
712 // so that it can reside entirely in header and lack the export declaration.
714 // Helper function used to associate wxAnyValueType with a wxVariantData.
715 extern WXDLLIMPEXP_BASE
void
716 wxPreRegisterAnyToVariant(wxAnyToVariantRegistration
* reg
);
718 // This function performs main wxAny to wxVariant conversion duties.
719 extern WXDLLIMPEXP_BASE
bool
720 wxConvertAnyToVariant(const wxAny
& any
, wxVariant
* variant
);
722 #endif // wxUSE_VARIANT
726 // The wxAny class represents a container for any type. A variant's value
727 // can be changed at run time, possibly to a different type of value.
729 // As standard, wxAny can store value of almost any type, in a fairly
730 // optimal manner even.
740 m_type
= wxAnyNullValueType
;
748 m_type
->DeleteValue(m_buffer
);
753 Various constructors.
756 wxAny(const T
& value
)
758 m_type
= wxAnyValueTypeImpl
<T
>::sm_instance
.get();
759 wxAnyValueTypeImpl
<T
>::SetValue(value
, m_buffer
);
762 // These two constructors are needed to deal with string literals
763 wxAny(const char* value
)
765 m_type
= wxAnyValueTypeImpl
<const char*>::sm_instance
.get();
766 wxAnyValueTypeImpl
<const char*>::SetValue(value
, m_buffer
);
768 wxAny(const wchar_t* value
)
770 m_type
= wxAnyValueTypeImpl
<const wchar_t*>::sm_instance
.get();
771 wxAnyValueTypeImpl
<const wchar_t*>::SetValue(value
, m_buffer
);
774 wxAny(const wxAny
& any
)
776 m_type
= wxAnyNullValueType
;
781 wxAny(const wxVariant
& variant
)
783 m_type
= wxAnyNullValueType
;
784 AssignVariant(variant
);
791 Use this template function for checking if this wxAny holds
792 a specific C++ data type.
794 @remarks This template function does not work on some older compilers
795 (such as Visual C++ 6.0). For full compiler ccompatibility
796 please use wxANY_CHECK_TYPE(any, T) macro instead.
798 @see wxAnyValueType::CheckType()
800 // FIXME-VC6: remove this hack when VC6 is no longer supported
801 template <typename T
>
802 bool CheckType(T
* = NULL
) const
804 return m_type
->CheckType
<T
>();
808 Returns the value type as wxAnyValueType instance.
810 @remarks You cannot reliably test whether two wxAnys are of
811 same value type by simply comparing return values
812 of wxAny::GetType(). Instead, use wxAny::HasSameType().
816 const wxAnyValueType
* GetType() const
822 Returns @true if this and another wxAny have the same
825 bool HasSameType(const wxAny
& other
) const
827 return GetType()->IsSameType(other
.GetType());
831 Tests if wxAny is null (that is, whether there is no data).
835 return (m_type
== wxAnyNullValueType
);
839 Makes wxAny null (that is, clears it).
843 m_type
->DeleteValue(m_buffer
);
844 m_type
= wxAnyNullValueType
;
849 Assignment operators.
852 wxAny
& operator=(const T
&value
)
854 m_type
->DeleteValue(m_buffer
);
855 m_type
= wxAnyValueTypeImpl
<T
>::sm_instance
.get();
856 wxAnyValueTypeImpl
<T
>::SetValue(value
, m_buffer
);
860 wxAny
& operator=(const wxAny
&any
)
868 wxAny
& operator=(const wxVariant
&variant
)
870 AssignVariant(variant
);
875 // These two operators are needed to deal with string literals
876 wxAny
& operator=(const char* value
)
881 wxAny
& operator=(const wchar_t* value
)
891 bool operator==(const wxString
& value
) const
894 if ( !GetAs(&value2
) )
896 return value
== value2
;
899 bool operator==(const char* value
) const
900 { return (*this) == wxString(value
); }
901 bool operator==(const wchar_t* value
) const
902 { return (*this) == wxString(value
); }
905 // We need to implement custom signed/unsigned int equals operators
906 // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
907 WXANY_IMPLEMENT_INT_EQ_OP(signed char, unsigned char)
908 WXANY_IMPLEMENT_INT_EQ_OP(signed short, unsigned short)
909 WXANY_IMPLEMENT_INT_EQ_OP(signed int, unsigned int)
910 WXANY_IMPLEMENT_INT_EQ_OP(signed long, unsigned long)
912 WXANY_IMPLEMENT_INT_EQ_OP(wxLongLong_t
, wxULongLong_t
)
915 wxGCC_WARNING_SUPPRESS(float-equal
)
917 bool operator==(float value
) const
919 if ( !wxAnyValueTypeImpl
<float>::IsSameClass(m_type
) )
924 (wxAnyValueTypeImpl
<float>::GetValue(m_buffer
));
927 bool operator==(double value
) const
929 if ( !wxAnyValueTypeImpl
<double>::IsSameClass(m_type
) )
934 (wxAnyValueTypeImpl
<double>::GetValue(m_buffer
));
937 wxGCC_WARNING_RESTORE(float-equal
)
939 bool operator==(bool value
) const
941 if ( !wxAnyValueTypeImpl
<bool>::IsSameClass(m_type
) )
944 return value
== (wxAnyValueTypeImpl
<bool>::GetValue(m_buffer
));
951 Inequality operators (implement as template).
954 bool operator!=(const T
& value
) const
955 { return !((*this) == value
); }
959 This template function converts wxAny into given type. In most cases
960 no type conversion is performed, so if the type is incorrect an
961 assertion failure will occur.
963 @remarks For convenience, conversion is done when T is wxString. This
964 is useful when a string literal (which are treated as
965 const char* and const wchar_t*) has been assigned to wxAny.
967 This template function may not work properly with Visual C++
968 6. For full compiler compatibility, please use
969 wxANY_AS(any, T) macro instead.
971 // FIXME-VC6: remove this hack when VC6 is no longer supported
973 T
As(T
* = NULL
) const
975 if ( !wxAnyValueTypeImpl
<T
>::IsSameClass(m_type
) )
977 wxFAIL_MSG("Incorrect or non-convertible data type");
980 return static_cast<T
>(wxAnyValueTypeImpl
<T
>::GetValue(m_buffer
));
983 // Allow easy conversion from 'const char *' etc. to wxString
984 // FIXME-VC6: remove this hack when VC6 is no longer supported
986 wxString
As(wxString
*) const
989 if ( !GetAs(&value
) )
991 wxFAIL_MSG("Incorrect or non-convertible data type");
996 #if wxUSE_EXTENDED_RTTI
997 const wxTypeInfo
* GetTypeInfo() const
999 return m_type
->GetTypeInfo();
1003 Template function that retrieves and converts the value of this
1004 variant to the type that T* value is.
1006 @return Returns @true if conversion was successful.
1008 template<typename T
>
1009 bool GetAs(T
* value
) const
1011 if ( !wxAnyValueTypeImpl
<T
>::IsSameClass(m_type
) )
1013 wxAnyValueType
* otherType
=
1014 wxAnyValueTypeImpl
<T
>::sm_instance
.get();
1015 wxAnyValueBuffer temp_buf
;
1017 if ( !m_type
->ConvertValue(m_buffer
, otherType
, temp_buf
) )
1021 static_cast<T
>(wxAnyValueTypeImpl
<T
>::GetValue(temp_buf
));
1022 otherType
->DeleteValue(temp_buf
);
1026 *value
= static_cast<T
>(wxAnyValueTypeImpl
<T
>::GetValue(m_buffer
));
1031 // GetAs() wxVariant specialization
1032 bool GetAs(wxVariant
* value
) const
1034 return wxConvertAnyToVariant(*this, value
);
1039 // Assignment functions
1040 void AssignAny(const wxAny
& any
)
1042 // Must delete value - CopyBuffer() never does that
1043 m_type
->DeleteValue(m_buffer
);
1045 wxAnyValueType
* newType
= any
.m_type
;
1047 if ( !newType
->IsSameType(m_type
) )
1050 newType
->CopyBuffer(any
.m_buffer
, m_buffer
);
1054 void AssignVariant(const wxVariant
& variant
)
1056 wxVariantData
* data
= variant
.GetData();
1058 if ( data
&& data
->GetAsAny(this) )
1061 m_type
->DeleteValue(m_buffer
);
1063 if ( variant
.IsNull() )
1066 m_type
= wxAnyNullValueType
;
1070 // If everything else fails, wrap the whole wxVariantData
1071 m_type
= wxAnyValueTypeImpl
<wxVariantData
*>::sm_instance
.get();
1072 wxAnyValueTypeImpl
<wxVariantData
*>::SetValue(data
, m_buffer
);
1077 template<typename T
>
1078 void Assign(const T
&value
)
1080 m_type
->DeleteValue(m_buffer
);
1081 m_type
= wxAnyValueTypeImpl
<T
>::sm_instance
.get();
1082 wxAnyValueTypeImpl
<T
>::SetValue(value
, m_buffer
);
1086 wxAnyValueBuffer m_buffer
;
1087 wxAnyValueType
* m_type
;
1092 // This method of checking the type is compatible with VC6
1093 #define wxANY_CHECK_TYPE(any, T) \
1094 wxANY_VALUE_TYPE_CHECK_TYPE((any).GetType(), T)
1098 // This method of getting the value is compatible with VC6
1099 #define wxANY_AS(any, T) \
1100 (any).As(static_cast<T*>(NULL))
1103 template<typename T
>
1104 inline bool wxAnyValueType::CheckType(T
* reserved
) const
1106 wxUnusedVar(reserved
);
1107 return wxAnyValueTypeImpl
<T
>::IsSameClass(this);
1110 WX_DECLARE_LIST_WITH_DECL(wxAny
, wxAnyList
, class WXDLLIMPEXP_BASE
);
1114 #endif // _WX_ANY_H_