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
)
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 wxAnyValueTypeOpsMovable
199 static void DeleteValue(wxAnyValueBuffer
& buf
)
204 static void SetValue(const T
& value
,
205 wxAnyValueBuffer
& buf
)
207 memcpy(buf
.m_buffer
, &value
, sizeof(T
));
210 static const T
& GetValue(const wxAnyValueBuffer
& buf
)
212 // Breaking this code into two lines should supress
213 // GCC's 'type-punned pointer will break strict-aliasing rules'
215 const T
* value
= reinterpret_cast<const T
*>(&buf
.m_buffer
[0]);
222 class wxAnyValueTypeOpsGeneric
225 template<typename T2
>
229 DataHolder(const T2
& value
)
233 virtual ~DataHolder() { }
237 wxDECLARE_NO_COPY_CLASS(DataHolder
);
240 static void DeleteValue(wxAnyValueBuffer
& buf
)
242 DataHolder
<T
>* holder
= static_cast<DataHolder
<T
>*>(buf
.m_ptr
);
246 static void SetValue(const T
& value
,
247 wxAnyValueBuffer
& buf
)
249 DataHolder
<T
>* holder
= new DataHolder
<T
>(value
);
253 static const T
& GetValue(const wxAnyValueBuffer
& buf
)
255 DataHolder
<T
>* holder
= static_cast<DataHolder
<T
>*>(buf
.m_ptr
);
256 return holder
->m_value
;
260 } // namespace wxPrivate
264 Intermediate template for the generic value type implementation.
265 We can derive from this same value type for multiple actual types
266 (for instance, we can have wxAnyValueTypeImplInt for all signed
267 integer types), and also easily implement specialized templates
268 with specific dynamic type conversion.
271 class wxAnyValueTypeImplBase
: public wxAnyValueType
273 typedef typename wxIf
< wxIsMovable
<T
>::value
&&
274 sizeof(T
) <= WX_ANY_VALUE_BUFFER_SIZE
,
275 wxPrivate::wxAnyValueTypeOpsMovable
<T
>,
276 wxPrivate::wxAnyValueTypeOpsGeneric
<T
> >::value
280 wxAnyValueTypeImplBase() : wxAnyValueType() { }
281 virtual ~wxAnyValueTypeImplBase() { }
283 virtual void DeleteValue(wxAnyValueBuffer
& buf
) const
285 Ops::DeleteValue(buf
);
288 virtual void CopyBuffer(const wxAnyValueBuffer
& src
,
289 wxAnyValueBuffer
& dst
) const
291 Ops::SetValue(Ops::GetValue(src
), dst
);
295 It is important to reimplement this in any specialized template
296 classes that inherit from wxAnyValueTypeImplBase.
298 static void SetValue(const T
& value
,
299 wxAnyValueBuffer
& buf
)
301 Ops::SetValue(value
, buf
);
305 It is important to reimplement this in any specialized template
306 classes that inherit from wxAnyValueTypeImplBase.
308 static const T
& GetValue(const wxAnyValueBuffer
& buf
)
310 return Ops::GetValue(buf
);
316 Generic value type template. Note that bulk of the implementation
317 resides in wxAnyValueTypeImplBase.
320 class wxAnyValueTypeImpl
: public wxAnyValueTypeImplBase
<T
>
322 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl
<T
>)
324 wxAnyValueTypeImpl() : wxAnyValueTypeImplBase
<T
>() { }
325 virtual ~wxAnyValueTypeImpl() { }
327 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
328 wxAnyValueType
* dstType
,
329 wxAnyValueBuffer
& dst
) const
332 wxUnusedVar(dstType
);
339 wxAnyValueTypeScopedPtr wxAnyValueTypeImpl
<T
>::sm_instance
= new wxAnyValueTypeImpl
<T
>();
343 // Helper macro for using same base value type implementation for multiple
344 // actual C++ data types.
346 #define WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
348 class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##CLSTYPE \
350 typedef wxAnyBase##CLSTYPE##Type UseDataType; \
352 wxAnyValueTypeImpl() : wxAnyValueTypeImpl##CLSTYPE() { } \
353 virtual ~wxAnyValueTypeImpl() { } \
354 static void SetValue(const T& value, wxAnyValueBuffer& buf) \
356 void* voidPtr = reinterpret_cast<void*>(&buf.m_buffer[0]); \
357 UseDataType* dptr = reinterpret_cast<UseDataType*>(voidPtr); \
358 *dptr = static_cast<UseDataType>(value); \
360 static T GetValue(const wxAnyValueBuffer& buf) \
362 const void* voidPtr = \
363 reinterpret_cast<const void*>(&buf.m_buffer[0]); \
364 const UseDataType* sptr = \
365 reinterpret_cast<const UseDataType*>(voidPtr); \
366 return static_cast<T>(*sptr); \
372 // Integer value types
376 typedef wxLongLong_t wxAnyBaseIntType
;
377 typedef wxULongLong_t wxAnyBaseUintType
;
379 typedef long wxAnyBaseIntType
;
380 typedef unsigned long wxAnyBaseUintType
;
384 class WXDLLIMPEXP_BASE wxAnyValueTypeImplInt
:
385 public wxAnyValueTypeImplBase
<wxAnyBaseIntType
>
387 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplInt
)
389 wxAnyValueTypeImplInt() :
390 wxAnyValueTypeImplBase
<wxAnyBaseIntType
>() { }
391 virtual ~wxAnyValueTypeImplInt() { }
393 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
394 wxAnyValueType
* dstType
,
395 wxAnyValueBuffer
& dst
) const;
399 class WXDLLIMPEXP_BASE wxAnyValueTypeImplUint
:
400 public wxAnyValueTypeImplBase
<wxAnyBaseUintType
>
402 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplUint
)
404 wxAnyValueTypeImplUint() :
405 wxAnyValueTypeImplBase
<wxAnyBaseUintType
>() { }
406 virtual ~wxAnyValueTypeImplUint() { }
408 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
409 wxAnyValueType
* dstType
,
410 wxAnyValueBuffer
& dst
) const;
414 WX_ANY_DEFINE_SUB_TYPE(signed long, Int
)
415 WX_ANY_DEFINE_SUB_TYPE(signed int, Int
)
416 WX_ANY_DEFINE_SUB_TYPE(signed short, Int
)
417 WX_ANY_DEFINE_SUB_TYPE(signed char, Int
)
419 WX_ANY_DEFINE_SUB_TYPE(wxLongLong_t
, Int
)
422 WX_ANY_DEFINE_SUB_TYPE(unsigned long, Uint
)
423 WX_ANY_DEFINE_SUB_TYPE(unsigned int, Uint
)
424 WX_ANY_DEFINE_SUB_TYPE(unsigned short, Uint
)
425 WX_ANY_DEFINE_SUB_TYPE(unsigned char, Uint
)
427 WX_ANY_DEFINE_SUB_TYPE(wxULongLong_t
, Uint
)
432 // This macro is used in header, but then in source file we must have:
433 // WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl##TYPENAME)
435 #define _WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, GV) \
436 class WXDLLIMPEXP_BASE wxAnyValueTypeImpl##TYPENAME : \
437 public wxAnyValueTypeImplBase<T> \
439 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl##TYPENAME) \
441 wxAnyValueTypeImpl##TYPENAME() : \
442 wxAnyValueTypeImplBase<T>() { } \
443 virtual ~wxAnyValueTypeImpl##TYPENAME() { } \
444 virtual bool ConvertValue(const wxAnyValueBuffer& src, \
445 wxAnyValueType* dstType, \
446 wxAnyValueBuffer& dst) const \
448 GV value = GetValue(src); \
449 return CONVFUNC(value, dstType, dst); \
453 class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##TYPENAME \
456 wxAnyValueTypeImpl() : wxAnyValueTypeImpl##TYPENAME() { } \
457 virtual ~wxAnyValueTypeImpl() { } \
460 #define WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, BT) \
461 _WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, BT) \
463 #define WX_ANY_DEFINE_CONVERTIBLE_TYPE_BASE(T, TYPENAME, CONVFUNC) \
464 _WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, \
465 CONVFUNC, const T&) \
471 // Convert wxString to destination wxAny value type
472 extern WXDLLIMPEXP_BASE
bool wxAnyConvertString(const wxString
& value
,
473 wxAnyValueType
* dstType
,
474 wxAnyValueBuffer
& dst
);
476 WX_ANY_DEFINE_CONVERTIBLE_TYPE_BASE(wxString
, wxString
, wxAnyConvertString
)
477 WX_ANY_DEFINE_CONVERTIBLE_TYPE(const char*, ConstCharPtr
,
478 wxAnyConvertString
, wxString
)
479 WX_ANY_DEFINE_CONVERTIBLE_TYPE(const wchar_t*, ConstWchar_tPtr
,
480 wxAnyConvertString
, wxString
)
486 class WXDLLIMPEXP_BASE wxAnyValueTypeImpl
<bool> :
487 public wxAnyValueTypeImplBase
<bool>
489 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl
<bool>)
491 wxAnyValueTypeImpl() :
492 wxAnyValueTypeImplBase
<bool>() { }
493 virtual ~wxAnyValueTypeImpl() { }
495 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
496 wxAnyValueType
* dstType
,
497 wxAnyValueBuffer
& dst
) const;
501 // Floating point value type
503 class WXDLLIMPEXP_BASE wxAnyValueTypeImplDouble
:
504 public wxAnyValueTypeImplBase
<double>
506 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble
)
508 wxAnyValueTypeImplDouble() :
509 wxAnyValueTypeImplBase
<double>() { }
510 virtual ~wxAnyValueTypeImplDouble() { }
512 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
513 wxAnyValueType
* dstType
,
514 wxAnyValueBuffer
& dst
) const;
517 // WX_ANY_DEFINE_SUB_TYPE requires this
518 typedef double wxAnyBaseDoubleType
;
520 WX_ANY_DEFINE_SUB_TYPE(float, Double
)
521 WX_ANY_DEFINE_SUB_TYPE(double, Double
)
525 // Defines a dummy wxAnyValueTypeImpl<> with given export
526 // declaration. This is needed if a class is used with
527 // wxAny in both user shared library and application.
529 #define wxDECLARE_ANY_TYPE(CLS, DECL) \
531 class DECL wxAnyValueTypeImpl<CLS> : \
532 public wxAnyValueTypeImplBase<CLS> \
534 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<CLS>) \
536 wxAnyValueTypeImpl() : \
537 wxAnyValueTypeImplBase<CLS>() { } \
538 virtual ~wxAnyValueTypeImpl() { } \
540 virtual bool ConvertValue(const wxAnyValueBuffer& src, \
541 wxAnyValueType* dstType, \
542 wxAnyValueBuffer& dst) const \
545 wxUnusedVar(dstType); \
552 // Make sure some of wx's own types get the right wxAnyValueType export
553 // (this is needed only for types that are referred to from wxBase.
554 // currently we may not use any of these types from there, but let's
555 // use the macro on at least one to make sure it compiles since we can't
556 // really test it properly in unittests since a separate DLL would
559 #include "wx/datetime.h"
560 wxDECLARE_ANY_TYPE(wxDateTime
, WXDLLIMPEXP_BASE
)
563 //#include "wx/object.h"
564 //wxDECLARE_ANY_TYPE(wxObject*, WXDLLIMPEXP_BASE)
566 //#include "wx/arrstr.h"
567 //wxDECLARE_ANY_TYPE(wxArrayString, WXDLLIMPEXP_BASE)
572 class WXDLLIMPEXP_FWD_BASE wxAnyToVariantRegistration
;
574 // Because of header inter-dependencies, cannot include this earlier
575 #include "wx/variant.h"
578 // wxVariantData* data type implementation. For cases when appropriate
579 // wxAny<->wxVariant conversion code is missing.
582 class WXDLLIMPEXP_BASE wxAnyValueTypeImplVariantData
:
583 public wxAnyValueTypeImplBase
<wxVariantData
*>
585 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplVariantData
)
587 wxAnyValueTypeImplVariantData() :
588 wxAnyValueTypeImplBase
<wxVariantData
*>() { }
589 virtual ~wxAnyValueTypeImplVariantData() { }
591 virtual void DeleteValue(wxAnyValueBuffer
& buf
) const
593 wxVariantData
* data
= static_cast<wxVariantData
*>(buf
.m_ptr
);
598 virtual void CopyBuffer(const wxAnyValueBuffer
& src
,
599 wxAnyValueBuffer
& dst
) const
601 wxVariantData
* data
= static_cast<wxVariantData
*>(src
.m_ptr
);
607 static void SetValue(wxVariantData
* value
,
608 wxAnyValueBuffer
& buf
)
614 static wxVariantData
* GetValue(const wxAnyValueBuffer
& buf
)
616 return static_cast<wxVariantData
*>(buf
.m_ptr
);
619 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
620 wxAnyValueType
* dstType
,
621 wxAnyValueBuffer
& dst
) const
624 wxUnusedVar(dstType
);
631 class wxAnyValueTypeImpl
<wxVariantData
*> :
632 public wxAnyValueTypeImplVariantData
635 wxAnyValueTypeImpl() : wxAnyValueTypeImplVariantData() { }
636 virtual ~wxAnyValueTypeImpl() { }
639 #endif // wxUSE_VARIANT
642 // Re-enable useless VC6 warnings
643 #pragma warning (pop)
648 Let's define a discrete Null value so we don't have to really
649 ever check if wxAny.m_type pointer is NULL or not. This is an
650 optimization, mostly. Implementation of this value type is
651 "hidden" in the source file.
653 extern WXDLLIMPEXP_DATA_BASE(wxAnyValueType
*) wxAnyNullValueType
;
657 // We need to implement custom signed/unsigned int equals operators
658 // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
659 #define WXANY_IMPLEMENT_INT_EQ_OP(TS, TUS) \
660 bool operator==(TS value) const \
662 if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
663 return (value == static_cast<TS> \
664 (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
665 if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
666 return (value == static_cast<TS> \
667 (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
670 bool operator==(TUS value) const \
672 if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
673 return (value == static_cast<TUS> \
674 (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
675 if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
676 return (value == static_cast<TUS> \
677 (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
684 // Note that the following functions are implemented outside wxAny class
685 // so that it can reside entirely in header and lack the export declaration.
687 // Helper function used to associate wxAnyValueType with a wxVariantData.
688 extern WXDLLIMPEXP_BASE
void
689 wxPreRegisterAnyToVariant(wxAnyToVariantRegistration
* reg
);
691 // This function performs main wxAny to wxVariant conversion duties.
692 extern WXDLLIMPEXP_BASE
bool
693 wxConvertAnyToVariant(const wxAny
& any
, wxVariant
* variant
);
695 #endif // wxUSE_VARIANT
699 // The wxAny class represents a container for any type. A variant's value
700 // can be changed at run time, possibly to a different type of value.
702 // As standard, wxAny can store value of almost any type, in a fairly
703 // optimal manner even.
713 m_type
= wxAnyNullValueType
;
721 m_type
->DeleteValue(m_buffer
);
726 Various constructors.
729 wxAny(const T
& value
)
731 m_type
= wxAnyValueTypeImpl
<T
>::sm_instance
.get();
732 wxAnyValueTypeImpl
<T
>::SetValue(value
, m_buffer
);
735 // These two constructors are needed to deal with string literals
736 wxAny(const char* value
)
738 m_type
= wxAnyValueTypeImpl
<const char*>::sm_instance
.get();
739 wxAnyValueTypeImpl
<const char*>::SetValue(value
, m_buffer
);
741 wxAny(const wchar_t* value
)
743 m_type
= wxAnyValueTypeImpl
<const wchar_t*>::sm_instance
.get();
744 wxAnyValueTypeImpl
<const wchar_t*>::SetValue(value
, m_buffer
);
747 wxAny(const wxAny
& any
)
749 m_type
= wxAnyNullValueType
;
754 wxAny(const wxVariant
& variant
)
756 m_type
= wxAnyNullValueType
;
757 AssignVariant(variant
);
764 Use this template function for checking if this wxAny holds
765 a specific C++ data type.
767 @remarks This template function does not work on some older compilers
768 (such as Visual C++ 6.0). For full compiler ccompatibility
769 please use wxANY_CHECK_TYPE(any, T) macro instead.
771 @see wxAnyValueType::CheckType()
773 // FIXME-VC6: remove this hack when VC6 is no longer supported
774 template <typename T
>
775 bool CheckType(T
* = NULL
) const
777 return m_type
->CheckType
<T
>();
781 Returns the value type as wxAnyValueType instance.
783 @remarks You cannot reliably test whether two wxAnys are of
784 same value type by simply comparing return values
785 of wxAny::GetType(). Instead use
786 wxAnyValueType::CheckType<T>() template function.
788 const wxAnyValueType
* GetType() const
794 Tests if wxAny is null (that is, whether there is data).
798 return (m_type
== wxAnyNullValueType
);
802 Makes wxAny null (that is, clears it).
806 m_type
->DeleteValue(m_buffer
);
807 m_type
= wxAnyNullValueType
;
812 Assignment operators.
815 wxAny
& operator=(const T
&value
)
817 m_type
->DeleteValue(m_buffer
);
818 m_type
= wxAnyValueTypeImpl
<T
>::sm_instance
.get();
819 wxAnyValueTypeImpl
<T
>::SetValue(value
, m_buffer
);
823 wxAny
& operator=(const wxAny
&any
)
831 wxAny
& operator=(const wxVariant
&variant
)
833 AssignVariant(variant
);
838 // These two operators are needed to deal with string literals
839 wxAny
& operator=(const char* value
)
844 wxAny
& operator=(const wchar_t* value
)
854 bool operator==(const wxString
& value
) const
857 if ( !GetAs(&value2
) )
859 return value
== value2
;
862 bool operator==(const char* value
) const
863 { return (*this) == wxString(value
); }
864 bool operator==(const wchar_t* value
) const
865 { return (*this) == wxString(value
); }
868 // We need to implement custom signed/unsigned int equals operators
869 // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
870 WXANY_IMPLEMENT_INT_EQ_OP(signed char, unsigned char)
871 WXANY_IMPLEMENT_INT_EQ_OP(signed short, unsigned short)
872 WXANY_IMPLEMENT_INT_EQ_OP(signed int, unsigned int)
873 WXANY_IMPLEMENT_INT_EQ_OP(signed long, unsigned long)
875 WXANY_IMPLEMENT_INT_EQ_OP(wxLongLong_t
, wxULongLong_t
)
878 bool operator==(float value
) const
880 if ( !wxAnyValueTypeImpl
<float>::IsSameClass(m_type
) )
885 (wxAnyValueTypeImpl
<float>::GetValue(m_buffer
));
888 bool operator==(double value
) const
890 if ( !wxAnyValueTypeImpl
<double>::IsSameClass(m_type
) )
895 (wxAnyValueTypeImpl
<double>::GetValue(m_buffer
));
898 bool operator==(bool value
) const
900 if ( !wxAnyValueTypeImpl
<bool>::IsSameClass(m_type
) )
903 return value
== (wxAnyValueTypeImpl
<bool>::GetValue(m_buffer
));
910 Inequality operators (implement as template).
913 bool operator!=(const T
& value
) const
914 { return !((*this) == value
); }
918 This template function converts wxAny into given type. In most cases
919 no type conversion is performed, so if the type is incorrect an
920 assertion failure will occur.
922 @remarks For conveniency, conversion is done when T is wxString. This
923 is useful when a string literal (which are treated as
924 const char* and const wchar_t*) has been assigned to wxAny.
926 This template function may not work properly with Visual C++
927 6. For full compiler compatibility, please use
928 wxANY_AS(any, T) macro instead.
930 // FIXME-VC6: remove this hack when VC6 is no longer supported
932 T
As(T
* = NULL
) const
934 if ( !wxAnyValueTypeImpl
<T
>::IsSameClass(m_type
) )
936 wxFAIL_MSG("Incorrect or non-convertible data type");
939 return static_cast<T
>(wxAnyValueTypeImpl
<T
>::GetValue(m_buffer
));
942 // Allow easy conversion from 'const char *' etc. to wxString
943 // FIXME-VC6: remove this hack when VC6 is no longer supported
945 wxString
As(wxString
*) const
948 if ( !GetAs(&value
) )
950 wxFAIL_MSG("Incorrect or non-convertible data type");
956 Template function that etrieves and converts the value of this
957 variant to the type that T* value is.
959 @return Returns @true if conversion was succesfull.
962 bool GetAs(T
* value
) const
964 if ( !wxAnyValueTypeImpl
<T
>::IsSameClass(m_type
) )
966 wxAnyValueType
* otherType
=
967 wxAnyValueTypeImpl
<T
>::sm_instance
.get();
968 wxAnyValueBuffer temp_buf
;
970 if ( !m_type
->ConvertValue(m_buffer
, otherType
, temp_buf
) )
974 static_cast<T
>(wxAnyValueTypeImpl
<T
>::GetValue(temp_buf
));
975 otherType
->DeleteValue(temp_buf
);
979 *value
= static_cast<T
>(wxAnyValueTypeImpl
<T
>::GetValue(m_buffer
));
984 // GetAs() wxVariant specialization
985 bool GetAs(wxVariant
* value
) const
987 return wxConvertAnyToVariant(*this, value
);
992 // Assignment functions
993 void AssignAny(const wxAny
& any
)
995 // Must delete value - CopyBuffer() never does that
996 m_type
->DeleteValue(m_buffer
);
998 wxAnyValueType
* newType
= any
.m_type
;
1000 if ( !newType
->IsSameType(m_type
) )
1003 newType
->CopyBuffer(any
.m_buffer
, m_buffer
);
1007 void AssignVariant(const wxVariant
& variant
)
1009 wxVariantData
* data
= variant
.GetData();
1011 if ( data
&& data
->GetAsAny(this) )
1014 m_type
->DeleteValue(m_buffer
);
1016 if ( variant
.IsNull() )
1019 m_type
= wxAnyNullValueType
;
1023 // If everything else fails, wrap the whole wxVariantData
1024 m_type
= wxAnyValueTypeImpl
<wxVariantData
*>::sm_instance
.get();
1025 wxAnyValueTypeImpl
<wxVariantData
*>::SetValue(data
, m_buffer
);
1030 template<typename T
>
1031 void Assign(const T
&value
)
1033 m_type
->DeleteValue(m_buffer
);
1034 m_type
= wxAnyValueTypeImpl
<T
>::sm_instance
.get();
1035 wxAnyValueTypeImpl
<T
>::SetValue(value
, m_buffer
);
1039 wxAnyValueBuffer m_buffer
;
1040 wxAnyValueType
* m_type
;
1045 // This method of checking the type is compatible with VC6
1046 #define wxANY_CHECK_TYPE(any, T) \
1047 wxANY_VALUE_TYPE_CHECK_TYPE((any).GetType(), T)
1051 // This method of getting the value is compatible with VC6
1052 #define wxANY_AS(any, T) \
1053 (any).As(static_cast<T*>(NULL))
1056 template<typename T
>
1057 inline bool wxAnyValueType::CheckType(T
* reserved
) const
1059 wxUnusedVar(reserved
);
1060 return wxAnyValueTypeImpl
<T
>::IsSameClass(this);
1067 #endif // _WX_ANY_H_