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 wxAny::HasSameType().
794 const wxAnyValueType
* GetType() const
800 Returns @true if this and another wxAny have the same
803 bool HasSameType(const wxAny
& other
) const
805 return GetType()->IsSameType(other
.GetType());
809 Tests if wxAny is null (that is, whether there is no data).
813 return (m_type
== wxAnyNullValueType
);
817 Makes wxAny null (that is, clears it).
821 m_type
->DeleteValue(m_buffer
);
822 m_type
= wxAnyNullValueType
;
827 Assignment operators.
830 wxAny
& operator=(const T
&value
)
832 m_type
->DeleteValue(m_buffer
);
833 m_type
= wxAnyValueTypeImpl
<T
>::sm_instance
.get();
834 wxAnyValueTypeImpl
<T
>::SetValue(value
, m_buffer
);
838 wxAny
& operator=(const wxAny
&any
)
846 wxAny
& operator=(const wxVariant
&variant
)
848 AssignVariant(variant
);
853 // These two operators are needed to deal with string literals
854 wxAny
& operator=(const char* value
)
859 wxAny
& operator=(const wchar_t* value
)
869 bool operator==(const wxString
& value
) const
872 if ( !GetAs(&value2
) )
874 return value
== value2
;
877 bool operator==(const char* value
) const
878 { return (*this) == wxString(value
); }
879 bool operator==(const wchar_t* value
) const
880 { return (*this) == wxString(value
); }
883 // We need to implement custom signed/unsigned int equals operators
884 // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
885 WXANY_IMPLEMENT_INT_EQ_OP(signed char, unsigned char)
886 WXANY_IMPLEMENT_INT_EQ_OP(signed short, unsigned short)
887 WXANY_IMPLEMENT_INT_EQ_OP(signed int, unsigned int)
888 WXANY_IMPLEMENT_INT_EQ_OP(signed long, unsigned long)
890 WXANY_IMPLEMENT_INT_EQ_OP(wxLongLong_t
, wxULongLong_t
)
893 bool operator==(float value
) const
895 if ( !wxAnyValueTypeImpl
<float>::IsSameClass(m_type
) )
900 (wxAnyValueTypeImpl
<float>::GetValue(m_buffer
));
903 bool operator==(double value
) const
905 if ( !wxAnyValueTypeImpl
<double>::IsSameClass(m_type
) )
910 (wxAnyValueTypeImpl
<double>::GetValue(m_buffer
));
913 bool operator==(bool value
) const
915 if ( !wxAnyValueTypeImpl
<bool>::IsSameClass(m_type
) )
918 return value
== (wxAnyValueTypeImpl
<bool>::GetValue(m_buffer
));
925 Inequality operators (implement as template).
928 bool operator!=(const T
& value
) const
929 { return !((*this) == value
); }
933 This template function converts wxAny into given type. In most cases
934 no type conversion is performed, so if the type is incorrect an
935 assertion failure will occur.
937 @remarks For conveniency, conversion is done when T is wxString. This
938 is useful when a string literal (which are treated as
939 const char* and const wchar_t*) has been assigned to wxAny.
941 This template function may not work properly with Visual C++
942 6. For full compiler compatibility, please use
943 wxANY_AS(any, T) macro instead.
945 // FIXME-VC6: remove this hack when VC6 is no longer supported
947 T
As(T
* = NULL
) const
949 if ( !wxAnyValueTypeImpl
<T
>::IsSameClass(m_type
) )
951 wxFAIL_MSG("Incorrect or non-convertible data type");
954 return static_cast<T
>(wxAnyValueTypeImpl
<T
>::GetValue(m_buffer
));
957 // Allow easy conversion from 'const char *' etc. to wxString
958 // FIXME-VC6: remove this hack when VC6 is no longer supported
960 wxString
As(wxString
*) const
963 if ( !GetAs(&value
) )
965 wxFAIL_MSG("Incorrect or non-convertible data type");
971 Template function that etrieves and converts the value of this
972 variant to the type that T* value is.
974 @return Returns @true if conversion was succesfull.
977 bool GetAs(T
* value
) const
979 if ( !wxAnyValueTypeImpl
<T
>::IsSameClass(m_type
) )
981 wxAnyValueType
* otherType
=
982 wxAnyValueTypeImpl
<T
>::sm_instance
.get();
983 wxAnyValueBuffer temp_buf
;
985 if ( !m_type
->ConvertValue(m_buffer
, otherType
, temp_buf
) )
989 static_cast<T
>(wxAnyValueTypeImpl
<T
>::GetValue(temp_buf
));
990 otherType
->DeleteValue(temp_buf
);
994 *value
= static_cast<T
>(wxAnyValueTypeImpl
<T
>::GetValue(m_buffer
));
999 // GetAs() wxVariant specialization
1000 bool GetAs(wxVariant
* value
) const
1002 return wxConvertAnyToVariant(*this, value
);
1007 // Assignment functions
1008 void AssignAny(const wxAny
& any
)
1010 // Must delete value - CopyBuffer() never does that
1011 m_type
->DeleteValue(m_buffer
);
1013 wxAnyValueType
* newType
= any
.m_type
;
1015 if ( !newType
->IsSameType(m_type
) )
1018 newType
->CopyBuffer(any
.m_buffer
, m_buffer
);
1022 void AssignVariant(const wxVariant
& variant
)
1024 wxVariantData
* data
= variant
.GetData();
1026 if ( data
&& data
->GetAsAny(this) )
1029 m_type
->DeleteValue(m_buffer
);
1031 if ( variant
.IsNull() )
1034 m_type
= wxAnyNullValueType
;
1038 // If everything else fails, wrap the whole wxVariantData
1039 m_type
= wxAnyValueTypeImpl
<wxVariantData
*>::sm_instance
.get();
1040 wxAnyValueTypeImpl
<wxVariantData
*>::SetValue(data
, m_buffer
);
1045 template<typename T
>
1046 void Assign(const T
&value
)
1048 m_type
->DeleteValue(m_buffer
);
1049 m_type
= wxAnyValueTypeImpl
<T
>::sm_instance
.get();
1050 wxAnyValueTypeImpl
<T
>::SetValue(value
, m_buffer
);
1054 wxAnyValueBuffer m_buffer
;
1055 wxAnyValueType
* m_type
;
1060 // This method of checking the type is compatible with VC6
1061 #define wxANY_CHECK_TYPE(any, T) \
1062 wxANY_VALUE_TYPE_CHECK_TYPE((any).GetType(), T)
1066 // This method of getting the value is compatible with VC6
1067 #define wxANY_AS(any, T) \
1068 (any).As(static_cast<T*>(NULL))
1071 template<typename T
>
1072 inline bool wxAnyValueType::CheckType(T
* reserved
) const
1074 wxUnusedVar(reserved
);
1075 return wxAnyValueTypeImpl
<T
>::IsSameClass(this);
1082 #endif // _WX_ANY_H_