| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113 |
- /////////////////////////////////////////////////////////////////////////////
- // Name: wx/any.h
- // Purpose: wxAny class
- // Author: Jaakko Salli
- // Modified by:
- // Created: 07/05/2009
- // Copyright: (c) wxWidgets team
- // Licence: wxWindows licence
- /////////////////////////////////////////////////////////////////////////////
- #ifndef _WX_ANY_H_
- #define _WX_ANY_H_
- #include "wx/defs.h"
- #if wxUSE_ANY
- #include <new> // for placement new
- #include "wx/string.h"
- #include "wx/meta/if.h"
- #include "wx/typeinfo.h"
- #include "wx/list.h"
- // Size of the wxAny value buffer.
- enum
- {
- WX_ANY_VALUE_BUFFER_SIZE = 16
- };
- union wxAnyValueBuffer
- {
- union Alignment
- {
- #if wxHAS_INT64
- wxInt64 m_int64;
- #endif
- long double m_longDouble;
- void ( *m_funcPtr )(void);
- void ( wxAnyValueBuffer::*m_mFuncPtr )(void);
- } m_alignment;
- void* m_ptr;
- wxByte m_buffer[WX_ANY_VALUE_BUFFER_SIZE];
- };
- //
- // wxAnyValueType is base class for value type functionality for C++ data
- // types used with wxAny. Usually the default template (wxAnyValueTypeImpl<>)
- // will create a satisfactory wxAnyValueType implementation for a data type.
- //
- class WXDLLIMPEXP_BASE wxAnyValueType
- {
- WX_DECLARE_ABSTRACT_TYPEINFO(wxAnyValueType)
- public:
- /**
- Default constructor.
- */
- wxAnyValueType()
- {
- }
- /**
- Destructor.
- */
- virtual ~wxAnyValueType()
- {
- }
- /**
- This function is used for internal type matching.
- */
- virtual bool IsSameType(const wxAnyValueType* otherType) const = 0;
- /**
- This function is called every time the data in wxAny
- buffer needs to be freed.
- */
- virtual void DeleteValue(wxAnyValueBuffer& buf) const = 0;
- /**
- Implement this for buffer-to-buffer copy.
- @param src
- This is the source data buffer.
- @param dst
- This is the destination data buffer that is in either
- uninitialized or freed state.
- */
- virtual void CopyBuffer(const wxAnyValueBuffer& src,
- wxAnyValueBuffer& dst) const = 0;
- /**
- Convert value into buffer of different type. Return false if
- not possible.
- */
- virtual bool ConvertValue(const wxAnyValueBuffer& src,
- wxAnyValueType* dstType,
- wxAnyValueBuffer& dst) const = 0;
- /**
- Use this template function for checking if wxAnyValueType represents
- a specific C++ data type.
- @remarks This template function does not work on some older compilers
- (such as Visual C++ 6.0). For full compiler compatibility
- please use wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) macro
- instead.
- @see wxAny::CheckType()
- */
- // FIXME-VC6: remove this hack when VC6 is no longer supported
- template <typename T>
- bool CheckType(T* reserved = NULL) const;
- #if wxUSE_EXTENDED_RTTI
- virtual const wxTypeInfo* GetTypeInfo() const = 0;
- #endif
- private:
- };
- //
- // We need to allocate wxAnyValueType instances in heap, and need to use
- // scoped ptr to properly deallocate them in dynamic library use cases.
- // Here we have a minimal specialized scoped ptr implementation to deal
- // with various compiler-specific problems with template class' static
- // member variable of template type with explicit constructor which
- // is initialized in global scope.
- //
- class wxAnyValueTypeScopedPtr
- {
- public:
- wxAnyValueTypeScopedPtr(wxAnyValueType* ptr) : m_ptr(ptr) { }
- ~wxAnyValueTypeScopedPtr() { delete m_ptr; }
- wxAnyValueType* get() const { return m_ptr; }
- private:
- wxAnyValueType* m_ptr;
- };
- //
- // This method of checking the type is compatible with VC6
- #define wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) \
- wxAnyValueTypeImpl<T>::IsSameClass(valueTypePtr)
- /**
- Helper macro for defining user value types.
- Even though C++ RTTI would be fully available to use, we'd have to to
- facilitate sub-type system which allows, for instance, wxAny with
- signed short '15' to be treated equal to wxAny with signed long long '15'.
- Having sm_instance is important here.
- NB: We really need to have wxAnyValueType instances allocated
- in heap. They are stored as static template member variables,
- and with them we just can't be too careful (eg. not allocating
- them in heap broke the type identification in GCC).
- */
- #define WX_DECLARE_ANY_VALUE_TYPE(CLS) \
- friend class wxAny; \
- WX_DECLARE_TYPEINFO_INLINE(CLS) \
- public: \
- static bool IsSameClass(const wxAnyValueType* otherType) \
- { \
- return wxTypeId(*sm_instance.get()) == wxTypeId(*otherType); \
- } \
- virtual bool IsSameType(const wxAnyValueType* otherType) const \
- { \
- return IsSameClass(otherType); \
- } \
- private: \
- static wxAnyValueTypeScopedPtr sm_instance; \
- public: \
- static wxAnyValueType* GetInstance() \
- { \
- return sm_instance.get(); \
- }
- #define WX_IMPLEMENT_ANY_VALUE_TYPE(CLS) \
- wxAnyValueTypeScopedPtr CLS::sm_instance(new CLS());
- #ifdef __VISUALC6__
- // "non dll-interface class 'xxx' used as base interface
- #pragma warning (push)
- #pragma warning (disable:4275)
- #endif
- /**
- Following are helper classes for the wxAnyValueTypeImplBase.
- */
- namespace wxPrivate
- {
- template<typename T>
- class wxAnyValueTypeOpsInplace
- {
- public:
- static void DeleteValue(wxAnyValueBuffer& buf)
- {
- T* value = reinterpret_cast<T*>(&buf.m_buffer[0]);
- value->~T();
- // Some compiler may given 'unused variable' warnings without this
- wxUnusedVar(value);
- }
- static void SetValue(const T& value,
- wxAnyValueBuffer& buf)
- {
- // Use placement new
- void* const place = buf.m_buffer;
- ::new(place) T(value);
- }
- static const T& GetValue(const wxAnyValueBuffer& buf)
- {
- // Breaking this code into two lines should suppress
- // GCC's 'type-punned pointer will break strict-aliasing rules'
- // warning.
- const T* value = reinterpret_cast<const T*>(&buf.m_buffer[0]);
- return *value;
- }
- };
- template<typename T>
- class wxAnyValueTypeOpsGeneric
- {
- public:
- template<typename T2>
- class DataHolder
- {
- public:
- DataHolder(const T2& value)
- {
- m_value = value;
- }
- virtual ~DataHolder() { }
- T2 m_value;
- private:
- wxDECLARE_NO_COPY_CLASS(DataHolder);
- };
- static void DeleteValue(wxAnyValueBuffer& buf)
- {
- DataHolder<T>* holder = static_cast<DataHolder<T>*>(buf.m_ptr);
- delete holder;
- }
- static void SetValue(const T& value,
- wxAnyValueBuffer& buf)
- {
- DataHolder<T>* holder = new DataHolder<T>(value);
- buf.m_ptr = holder;
- }
- static const T& GetValue(const wxAnyValueBuffer& buf)
- {
- DataHolder<T>* holder = static_cast<DataHolder<T>*>(buf.m_ptr);
- return holder->m_value;
- }
- };
- } // namespace wxPrivate
- /**
- Intermediate template for the generic value type implementation.
- We can derive from this same value type for multiple actual types
- (for instance, we can have wxAnyValueTypeImplInt for all signed
- integer types), and also easily implement specialized templates
- with specific dynamic type conversion.
- */
- template<typename T>
- class wxAnyValueTypeImplBase : public wxAnyValueType
- {
- typedef typename wxIf< sizeof(T) <= WX_ANY_VALUE_BUFFER_SIZE,
- wxPrivate::wxAnyValueTypeOpsInplace<T>,
- wxPrivate::wxAnyValueTypeOpsGeneric<T> >::value
- Ops;
- public:
- wxAnyValueTypeImplBase() : wxAnyValueType() { }
- virtual ~wxAnyValueTypeImplBase() { }
- virtual void DeleteValue(wxAnyValueBuffer& buf) const
- {
- Ops::DeleteValue(buf);
- }
- virtual void CopyBuffer(const wxAnyValueBuffer& src,
- wxAnyValueBuffer& dst) const
- {
- Ops::SetValue(Ops::GetValue(src), dst);
- }
- /**
- It is important to reimplement this in any specialized template
- classes that inherit from wxAnyValueTypeImplBase.
- */
- static void SetValue(const T& value,
- wxAnyValueBuffer& buf)
- {
- Ops::SetValue(value, buf);
- }
- /**
- It is important to reimplement this in any specialized template
- classes that inherit from wxAnyValueTypeImplBase.
- */
- static const T& GetValue(const wxAnyValueBuffer& buf)
- {
- return Ops::GetValue(buf);
- }
- #if wxUSE_EXTENDED_RTTI
- virtual const wxTypeInfo* GetTypeInfo() const
- {
- return wxGetTypeInfo((T*)NULL);
- }
- #endif
- };
- /*
- Generic value type template. Note that bulk of the implementation
- resides in wxAnyValueTypeImplBase.
- */
- template<typename T>
- class wxAnyValueTypeImpl : public wxAnyValueTypeImplBase<T>
- {
- WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<T>)
- public:
- wxAnyValueTypeImpl() : wxAnyValueTypeImplBase<T>() { }
- virtual ~wxAnyValueTypeImpl() { }
- virtual bool ConvertValue(const wxAnyValueBuffer& src,
- wxAnyValueType* dstType,
- wxAnyValueBuffer& dst) const
- {
- wxUnusedVar(src);
- wxUnusedVar(dstType);
- wxUnusedVar(dst);
- return false;
- }
- };
- template<typename T>
- wxAnyValueTypeScopedPtr wxAnyValueTypeImpl<T>::sm_instance = new wxAnyValueTypeImpl<T>();
- //
- // Helper macro for using same base value type implementation for multiple
- // actual C++ data types.
- //
- #define _WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
- template<> \
- class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##CLSTYPE \
- { \
- typedef wxAnyBase##CLSTYPE##Type UseDataType; \
- public: \
- wxAnyValueTypeImpl() : wxAnyValueTypeImpl##CLSTYPE() { } \
- virtual ~wxAnyValueTypeImpl() { } \
- static void SetValue(const T& value, wxAnyValueBuffer& buf) \
- { \
- void* voidPtr = reinterpret_cast<void*>(&buf.m_buffer[0]); \
- UseDataType* dptr = reinterpret_cast<UseDataType*>(voidPtr); \
- *dptr = static_cast<UseDataType>(value); \
- } \
- static T GetValue(const wxAnyValueBuffer& buf) \
- { \
- const void* voidPtr = \
- reinterpret_cast<const void*>(&buf.m_buffer[0]); \
- const UseDataType* sptr = \
- reinterpret_cast<const UseDataType*>(voidPtr); \
- return static_cast<T>(*sptr); \
- }
- #if wxUSE_EXTENDED_RTTI
- #define WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
- _WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE)\
- virtual const wxTypeInfo* GetTypeInfo() const \
- { \
- return wxGetTypeInfo((T*)NULL); \
- } \
- };
- #else
- #define WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
- _WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE)\
- };
- #endif
- //
- // Integer value types
- //
- #ifdef wxLongLong_t
- typedef wxLongLong_t wxAnyBaseIntType;
- typedef wxULongLong_t wxAnyBaseUintType;
- #else
- typedef long wxAnyBaseIntType;
- typedef unsigned long wxAnyBaseUintType;
- #endif
- class WXDLLIMPEXP_BASE wxAnyValueTypeImplInt :
- public wxAnyValueTypeImplBase<wxAnyBaseIntType>
- {
- WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplInt)
- public:
- wxAnyValueTypeImplInt() :
- wxAnyValueTypeImplBase<wxAnyBaseIntType>() { }
- virtual ~wxAnyValueTypeImplInt() { }
- virtual bool ConvertValue(const wxAnyValueBuffer& src,
- wxAnyValueType* dstType,
- wxAnyValueBuffer& dst) const;
- };
- class WXDLLIMPEXP_BASE wxAnyValueTypeImplUint :
- public wxAnyValueTypeImplBase<wxAnyBaseUintType>
- {
- WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplUint)
- public:
- wxAnyValueTypeImplUint() :
- wxAnyValueTypeImplBase<wxAnyBaseUintType>() { }
- virtual ~wxAnyValueTypeImplUint() { }
- virtual bool ConvertValue(const wxAnyValueBuffer& src,
- wxAnyValueType* dstType,
- wxAnyValueBuffer& dst) const;
- };
- WX_ANY_DEFINE_SUB_TYPE(signed long, Int)
- WX_ANY_DEFINE_SUB_TYPE(signed int, Int)
- WX_ANY_DEFINE_SUB_TYPE(signed short, Int)
- WX_ANY_DEFINE_SUB_TYPE(signed char, Int)
- #ifdef wxLongLong_t
- WX_ANY_DEFINE_SUB_TYPE(wxLongLong_t, Int)
- #endif
- WX_ANY_DEFINE_SUB_TYPE(unsigned long, Uint)
- WX_ANY_DEFINE_SUB_TYPE(unsigned int, Uint)
- WX_ANY_DEFINE_SUB_TYPE(unsigned short, Uint)
- WX_ANY_DEFINE_SUB_TYPE(unsigned char, Uint)
- #ifdef wxLongLong_t
- WX_ANY_DEFINE_SUB_TYPE(wxULongLong_t, Uint)
- #endif
- //
- // This macro is used in header, but then in source file we must have:
- // WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl##TYPENAME)
- //
- #define _WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, GV) \
- class WXDLLIMPEXP_BASE wxAnyValueTypeImpl##TYPENAME : \
- public wxAnyValueTypeImplBase<T> \
- { \
- WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl##TYPENAME) \
- public: \
- wxAnyValueTypeImpl##TYPENAME() : \
- wxAnyValueTypeImplBase<T>() { } \
- virtual ~wxAnyValueTypeImpl##TYPENAME() { } \
- virtual bool ConvertValue(const wxAnyValueBuffer& src, \
- wxAnyValueType* dstType, \
- wxAnyValueBuffer& dst) const \
- { \
- GV value = GetValue(src); \
- return CONVFUNC(value, dstType, dst); \
- } \
- }; \
- template<> \
- class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##TYPENAME \
- { \
- public: \
- wxAnyValueTypeImpl() : wxAnyValueTypeImpl##TYPENAME() { } \
- virtual ~wxAnyValueTypeImpl() { } \
- };
- #define WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, BT) \
- _WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, BT) \
- #define WX_ANY_DEFINE_CONVERTIBLE_TYPE_BASE(T, TYPENAME, CONVFUNC) \
- _WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, \
- CONVFUNC, const T&) \
- //
- // String value type
- //
- // Convert wxString to destination wxAny value type
- extern WXDLLIMPEXP_BASE bool wxAnyConvertString(const wxString& value,
- wxAnyValueType* dstType,
- wxAnyValueBuffer& dst);
- WX_ANY_DEFINE_CONVERTIBLE_TYPE_BASE(wxString, wxString, wxAnyConvertString)
- WX_ANY_DEFINE_CONVERTIBLE_TYPE(const char*, ConstCharPtr,
- wxAnyConvertString, wxString)
- WX_ANY_DEFINE_CONVERTIBLE_TYPE(const wchar_t*, ConstWchar_tPtr,
- wxAnyConvertString, wxString)
- //
- // Bool value type
- //
- template<>
- class WXDLLIMPEXP_BASE wxAnyValueTypeImpl<bool> :
- public wxAnyValueTypeImplBase<bool>
- {
- WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<bool>)
- public:
- wxAnyValueTypeImpl() :
- wxAnyValueTypeImplBase<bool>() { }
- virtual ~wxAnyValueTypeImpl() { }
- virtual bool ConvertValue(const wxAnyValueBuffer& src,
- wxAnyValueType* dstType,
- wxAnyValueBuffer& dst) const;
- };
- //
- // Floating point value type
- //
- class WXDLLIMPEXP_BASE wxAnyValueTypeImplDouble :
- public wxAnyValueTypeImplBase<double>
- {
- WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble)
- public:
- wxAnyValueTypeImplDouble() :
- wxAnyValueTypeImplBase<double>() { }
- virtual ~wxAnyValueTypeImplDouble() { }
- virtual bool ConvertValue(const wxAnyValueBuffer& src,
- wxAnyValueType* dstType,
- wxAnyValueBuffer& dst) const;
- };
- // WX_ANY_DEFINE_SUB_TYPE requires this
- typedef double wxAnyBaseDoubleType;
- WX_ANY_DEFINE_SUB_TYPE(float, Double)
- WX_ANY_DEFINE_SUB_TYPE(double, Double)
- //
- // Defines a dummy wxAnyValueTypeImpl<> with given export
- // declaration. This is needed if a class is used with
- // wxAny in both user shared library and application.
- //
- #define wxDECLARE_ANY_TYPE(CLS, DECL) \
- template<> \
- class DECL wxAnyValueTypeImpl<CLS> : \
- public wxAnyValueTypeImplBase<CLS> \
- { \
- WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<CLS>) \
- public: \
- wxAnyValueTypeImpl() : \
- wxAnyValueTypeImplBase<CLS>() { } \
- virtual ~wxAnyValueTypeImpl() { } \
- \
- virtual bool ConvertValue(const wxAnyValueBuffer& src, \
- wxAnyValueType* dstType, \
- wxAnyValueBuffer& dst) const \
- { \
- wxUnusedVar(src); \
- wxUnusedVar(dstType); \
- wxUnusedVar(dst); \
- return false; \
- } \
- };
- // Make sure some of wx's own types get the right wxAnyValueType export
- // (this is needed only for types that are referred to from wxBase.
- // currently we may not use any of these types from there, but let's
- // use the macro on at least one to make sure it compiles since we can't
- // really test it properly in unit tests since a separate DLL would
- // be needed).
- #if wxUSE_DATETIME
- #include "wx/datetime.h"
- wxDECLARE_ANY_TYPE(wxDateTime, WXDLLIMPEXP_BASE)
- #endif
- //#include "wx/object.h"
- //wxDECLARE_ANY_TYPE(wxObject*, WXDLLIMPEXP_BASE)
- //#include "wx/arrstr.h"
- //wxDECLARE_ANY_TYPE(wxArrayString, WXDLLIMPEXP_BASE)
- #if wxUSE_VARIANT
- class WXDLLIMPEXP_FWD_BASE wxAnyToVariantRegistration;
- // Because of header inter-dependencies, cannot include this earlier
- #include "wx/variant.h"
- //
- // wxVariantData* data type implementation. For cases when appropriate
- // wxAny<->wxVariant conversion code is missing.
- //
- class WXDLLIMPEXP_BASE wxAnyValueTypeImplVariantData :
- public wxAnyValueTypeImplBase<wxVariantData*>
- {
- WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplVariantData)
- public:
- wxAnyValueTypeImplVariantData() :
- wxAnyValueTypeImplBase<wxVariantData*>() { }
- virtual ~wxAnyValueTypeImplVariantData() { }
- virtual void DeleteValue(wxAnyValueBuffer& buf) const
- {
- wxVariantData* data = static_cast<wxVariantData*>(buf.m_ptr);
- if ( data )
- data->DecRef();
- }
- virtual void CopyBuffer(const wxAnyValueBuffer& src,
- wxAnyValueBuffer& dst) const
- {
- wxVariantData* data = static_cast<wxVariantData*>(src.m_ptr);
- if ( data )
- data->IncRef();
- dst.m_ptr = data;
- }
- static void SetValue(wxVariantData* value,
- wxAnyValueBuffer& buf)
- {
- value->IncRef();
- buf.m_ptr = value;
- }
- static wxVariantData* GetValue(const wxAnyValueBuffer& buf)
- {
- return static_cast<wxVariantData*>(buf.m_ptr);
- }
- virtual bool ConvertValue(const wxAnyValueBuffer& src,
- wxAnyValueType* dstType,
- wxAnyValueBuffer& dst) const
- {
- wxUnusedVar(src);
- wxUnusedVar(dstType);
- wxUnusedVar(dst);
- return false;
- }
- };
- template<>
- class wxAnyValueTypeImpl<wxVariantData*> :
- public wxAnyValueTypeImplVariantData
- {
- public:
- wxAnyValueTypeImpl() : wxAnyValueTypeImplVariantData() { }
- virtual ~wxAnyValueTypeImpl() { }
- };
- #endif // wxUSE_VARIANT
- #ifdef __VISUALC6__
- // Re-enable useless VC6 warnings
- #pragma warning (pop)
- #endif
- /*
- Let's define a discrete Null value so we don't have to really
- ever check if wxAny.m_type pointer is NULL or not. This is an
- optimization, mostly. Implementation of this value type is
- "hidden" in the source file.
- */
- extern WXDLLIMPEXP_DATA_BASE(wxAnyValueType*) wxAnyNullValueType;
- //
- // We need to implement custom signed/unsigned int equals operators
- // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
- #define WXANY_IMPLEMENT_INT_EQ_OP(TS, TUS) \
- bool operator==(TS value) const \
- { \
- if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
- return (value == static_cast<TS> \
- (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
- if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
- return (value == static_cast<TS> \
- (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
- return false; \
- } \
- bool operator==(TUS value) const \
- { \
- if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
- return (value == static_cast<TUS> \
- (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
- if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
- return (value == static_cast<TUS> \
- (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
- return false; \
- }
- #if wxUSE_VARIANT
- // Note that the following functions are implemented outside wxAny class
- // so that it can reside entirely in header and lack the export declaration.
- // Helper function used to associate wxAnyValueType with a wxVariantData.
- extern WXDLLIMPEXP_BASE void
- wxPreRegisterAnyToVariant(wxAnyToVariantRegistration* reg);
- // This function performs main wxAny to wxVariant conversion duties.
- extern WXDLLIMPEXP_BASE bool
- wxConvertAnyToVariant(const wxAny& any, wxVariant* variant);
- #endif // wxUSE_VARIANT
- //
- // The wxAny class represents a container for any type. A variant's value
- // can be changed at run time, possibly to a different type of value.
- //
- // As standard, wxAny can store value of almost any type, in a fairly
- // optimal manner even.
- //
- class wxAny
- {
- public:
- /**
- Default constructor.
- */
- wxAny()
- {
- m_type = wxAnyNullValueType;
- }
- /**
- Destructor.
- */
- ~wxAny()
- {
- m_type->DeleteValue(m_buffer);
- }
- //@{
- /**
- Various constructors.
- */
- template<typename T>
- wxAny(const T& value)
- {
- m_type = wxAnyValueTypeImpl<T>::sm_instance.get();
- wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
- }
- // These two constructors are needed to deal with string literals
- wxAny(const char* value)
- {
- m_type = wxAnyValueTypeImpl<const char*>::sm_instance.get();
- wxAnyValueTypeImpl<const char*>::SetValue(value, m_buffer);
- }
- wxAny(const wchar_t* value)
- {
- m_type = wxAnyValueTypeImpl<const wchar_t*>::sm_instance.get();
- wxAnyValueTypeImpl<const wchar_t*>::SetValue(value, m_buffer);
- }
- wxAny(const wxAny& any)
- {
- m_type = wxAnyNullValueType;
- AssignAny(any);
- }
- #if wxUSE_VARIANT
- wxAny(const wxVariant& variant)
- {
- m_type = wxAnyNullValueType;
- AssignVariant(variant);
- }
- #endif
- //@}
- /**
- Use this template function for checking if this wxAny holds
- a specific C++ data type.
- @remarks This template function does not work on some older compilers
- (such as Visual C++ 6.0). For full compiler ccompatibility
- please use wxANY_CHECK_TYPE(any, T) macro instead.
- @see wxAnyValueType::CheckType()
- */
- // FIXME-VC6: remove this hack when VC6 is no longer supported
- template <typename T>
- bool CheckType(T* = NULL) const
- {
- return m_type->CheckType<T>();
- }
- /**
- Returns the value type as wxAnyValueType instance.
- @remarks You cannot reliably test whether two wxAnys are of
- same value type by simply comparing return values
- of wxAny::GetType(). Instead, use wxAny::HasSameType().
- @see HasSameType()
- */
- const wxAnyValueType* GetType() const
- {
- return m_type;
- }
- /**
- Returns @true if this and another wxAny have the same
- value type.
- */
- bool HasSameType(const wxAny& other) const
- {
- return GetType()->IsSameType(other.GetType());
- }
- /**
- Tests if wxAny is null (that is, whether there is no data).
- */
- bool IsNull() const
- {
- return (m_type == wxAnyNullValueType);
- }
- /**
- Makes wxAny null (that is, clears it).
- */
- void MakeNull()
- {
- m_type->DeleteValue(m_buffer);
- m_type = wxAnyNullValueType;
- }
- //@{
- /**
- Assignment operators.
- */
- template<typename T>
- wxAny& operator=(const T &value)
- {
- m_type->DeleteValue(m_buffer);
- m_type = wxAnyValueTypeImpl<T>::sm_instance.get();
- wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
- return *this;
- }
- wxAny& operator=(const wxAny &any)
- {
- if (this != &any)
- AssignAny(any);
- return *this;
- }
- #if wxUSE_VARIANT
- wxAny& operator=(const wxVariant &variant)
- {
- AssignVariant(variant);
- return *this;
- }
- #endif
- // These two operators are needed to deal with string literals
- wxAny& operator=(const char* value)
- {
- Assign(value);
- return *this;
- }
- wxAny& operator=(const wchar_t* value)
- {
- Assign(value);
- return *this;
- }
- //@{
- /**
- Equality operators.
- */
- bool operator==(const wxString& value) const
- {
- wxString value2;
- if ( !GetAs(&value2) )
- return false;
- return value == value2;
- }
- bool operator==(const char* value) const
- { return (*this) == wxString(value); }
- bool operator==(const wchar_t* value) const
- { return (*this) == wxString(value); }
- //
- // We need to implement custom signed/unsigned int equals operators
- // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
- WXANY_IMPLEMENT_INT_EQ_OP(signed char, unsigned char)
- WXANY_IMPLEMENT_INT_EQ_OP(signed short, unsigned short)
- WXANY_IMPLEMENT_INT_EQ_OP(signed int, unsigned int)
- WXANY_IMPLEMENT_INT_EQ_OP(signed long, unsigned long)
- #ifdef wxLongLong_t
- WXANY_IMPLEMENT_INT_EQ_OP(wxLongLong_t, wxULongLong_t)
- #endif
- wxGCC_WARNING_SUPPRESS(float-equal)
- bool operator==(float value) const
- {
- if ( !wxAnyValueTypeImpl<float>::IsSameClass(m_type) )
- return false;
- return value ==
- static_cast<float>
- (wxAnyValueTypeImpl<float>::GetValue(m_buffer));
- }
- bool operator==(double value) const
- {
- if ( !wxAnyValueTypeImpl<double>::IsSameClass(m_type) )
- return false;
- return value ==
- static_cast<double>
- (wxAnyValueTypeImpl<double>::GetValue(m_buffer));
- }
- wxGCC_WARNING_RESTORE(float-equal)
- bool operator==(bool value) const
- {
- if ( !wxAnyValueTypeImpl<bool>::IsSameClass(m_type) )
- return false;
- return value == (wxAnyValueTypeImpl<bool>::GetValue(m_buffer));
- }
- //@}
- //@{
- /**
- Inequality operators (implement as template).
- */
- template<typename T>
- bool operator!=(const T& value) const
- { return !((*this) == value); }
- //@}
- /**
- This template function converts wxAny into given type. In most cases
- no type conversion is performed, so if the type is incorrect an
- assertion failure will occur.
- @remarks For convenience, conversion is done when T is wxString. This
- is useful when a string literal (which are treated as
- const char* and const wchar_t*) has been assigned to wxAny.
- This template function may not work properly with Visual C++
- 6. For full compiler compatibility, please use
- wxANY_AS(any, T) macro instead.
- */
- // FIXME-VC6: remove this hack when VC6 is no longer supported
- template<typename T>
- T As(T* = NULL) const
- {
- if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )
- {
- wxFAIL_MSG("Incorrect or non-convertible data type");
- }
- return static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(m_buffer));
- }
- // Allow easy conversion from 'const char *' etc. to wxString
- // FIXME-VC6: remove this hack when VC6 is no longer supported
- //template<>
- wxString As(wxString*) const
- {
- wxString value;
- if ( !GetAs(&value) )
- {
- wxFAIL_MSG("Incorrect or non-convertible data type");
- }
- return value;
- }
- #if wxUSE_EXTENDED_RTTI
- const wxTypeInfo* GetTypeInfo() const
- {
- return m_type->GetTypeInfo();
- }
- #endif
- /**
- Template function that retrieves and converts the value of this
- variant to the type that T* value is.
- @return Returns @true if conversion was successful.
- */
- template<typename T>
- bool GetAs(T* value) const
- {
- if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )
- {
- wxAnyValueType* otherType =
- wxAnyValueTypeImpl<T>::sm_instance.get();
- wxAnyValueBuffer temp_buf;
- if ( !m_type->ConvertValue(m_buffer, otherType, temp_buf) )
- return false;
- *value =
- static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(temp_buf));
- otherType->DeleteValue(temp_buf);
- return true;
- }
- *value = static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(m_buffer));
- return true;
- }
- #if wxUSE_VARIANT
- // GetAs() wxVariant specialization
- bool GetAs(wxVariant* value) const
- {
- return wxConvertAnyToVariant(*this, value);
- }
- #endif
- private:
- // Assignment functions
- void AssignAny(const wxAny& any)
- {
- // Must delete value - CopyBuffer() never does that
- m_type->DeleteValue(m_buffer);
- wxAnyValueType* newType = any.m_type;
- if ( !newType->IsSameType(m_type) )
- m_type = newType;
- newType->CopyBuffer(any.m_buffer, m_buffer);
- }
- #if wxUSE_VARIANT
- void AssignVariant(const wxVariant& variant)
- {
- wxVariantData* data = variant.GetData();
- if ( data && data->GetAsAny(this) )
- return;
- m_type->DeleteValue(m_buffer);
- if ( variant.IsNull() )
- {
- // Init as Null
- m_type = wxAnyNullValueType;
- }
- else
- {
- // If everything else fails, wrap the whole wxVariantData
- m_type = wxAnyValueTypeImpl<wxVariantData*>::sm_instance.get();
- wxAnyValueTypeImpl<wxVariantData*>::SetValue(data, m_buffer);
- }
- }
- #endif
- template<typename T>
- void Assign(const T &value)
- {
- m_type->DeleteValue(m_buffer);
- m_type = wxAnyValueTypeImpl<T>::sm_instance.get();
- wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
- }
- // Data
- wxAnyValueBuffer m_buffer;
- wxAnyValueType* m_type;
- };
- //
- // This method of checking the type is compatible with VC6
- #define wxANY_CHECK_TYPE(any, T) \
- wxANY_VALUE_TYPE_CHECK_TYPE((any).GetType(), T)
- //
- // This method of getting the value is compatible with VC6
- #define wxANY_AS(any, T) \
- (any).As(static_cast<T*>(NULL))
- template<typename T>
- inline bool wxAnyValueType::CheckType(T* reserved) const
- {
- wxUnusedVar(reserved);
- return wxAnyValueTypeImpl<T>::IsSameClass(this);
- }
- WX_DECLARE_LIST_WITH_DECL(wxAny, wxAnyList, class WXDLLIMPEXP_BASE);
- #endif // wxUSE_ANY
- #endif // _WX_ANY_H_
|