1126 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1126 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /////////////////////////////////////////////////////////////////////////////
 | |
| // 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];
 | |
| 
 | |
|     wxAnyValueBuffer()
 | |
|     {
 | |
|         m_ptr = NULL;
 | |
|     }
 | |
| };
 | |
| 
 | |
| //
 | |
| // 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.
 | |
| 
 | |
|         @see wxAny::CheckType()
 | |
|     */
 | |
|     template <typename T>
 | |
|     bool CheckType() 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;
 | |
| };
 | |
| 
 | |
| 
 | |
| // Deprecated macro for checking the type which was originally introduced for
 | |
| // MSVC6 compatibility and is not needed any longer now that this compiler is
 | |
| // not supported any more.
 | |
| #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 AreSameClasses(*sm_instance.get(), *otherType); \
 | |
|     } \
 | |
|     virtual bool IsSameType(const wxAnyValueType* otherType) const wxOVERRIDE \
 | |
|     { \
 | |
|         return IsSameClass(otherType); \
 | |
|     } \
 | |
| private: \
 | |
|     static bool AreSameClasses(const wxAnyValueType& a, const wxAnyValueType& b) \
 | |
|     { \
 | |
|         return wxTypeId(a) == wxTypeId(b); \
 | |
|     } \
 | |
|     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());
 | |
| 
 | |
| 
 | |
| /**
 | |
|     Following are helper classes for the wxAnyValueTypeImplBase.
 | |
| */
 | |
| namespace wxPrivate
 | |
| {
 | |
| 
 | |
| template<typename T>
 | |
| class wxAnyValueTypeOpsInplace
 | |
| {
 | |
| public:
 | |
|     static void DeleteValue(wxAnyValueBuffer& buf)
 | |
|     {
 | |
|         GetValue(buf).~T();
 | |
|     }
 | |
| 
 | |
|     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)
 | |
|     {
 | |
|         // Use a union to avoid undefined behaviour (and gcc -Wstrict-alias
 | |
|         // warnings about it) which would occur if we just casted a wxByte
 | |
|         // pointer to a T one.
 | |
|         union
 | |
|         {
 | |
|             const T* ptr;
 | |
|             const wxByte *buf;
 | |
|         } u;
 | |
|         u.buf = buf.m_buffer;
 | |
| 
 | |
|         return *u.ptr;
 | |
|     }
 | |
| };
 | |
| 
 | |
| 
 | |
| 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;
 | |
|     }
 | |
| };
 | |
| 
 | |
| 
 | |
| template <typename T>
 | |
| struct wxAnyAsImpl;
 | |
| 
 | |
| } // 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 wxOVERRIDE
 | |
|     {
 | |
|         Ops::DeleteValue(buf);
 | |
|     }
 | |
| 
 | |
|     virtual void CopyBuffer(const wxAnyValueBuffer& src,
 | |
|                             wxAnyValueBuffer& dst) const wxOVERRIDE
 | |
|     {
 | |
|         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 wxOVERRIDE
 | |
|     {
 | |
|         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 wxOVERRIDE;
 | |
| };
 | |
| 
 | |
| 
 | |
| 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 wxOVERRIDE;
 | |
| };
 | |
| 
 | |
| 
 | |
| 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 wxOVERRIDE \
 | |
|     { \
 | |
|         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 wxOVERRIDE;
 | |
| };
 | |
| 
 | |
| //
 | |
| // 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 wxOVERRIDE;
 | |
| };
 | |
| 
 | |
| // 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 wxOVERRIDE \
 | |
|     { \
 | |
|         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 wxOVERRIDE
 | |
|     {
 | |
|         wxVariantData* data = static_cast<wxVariantData*>(buf.m_ptr);
 | |
|         if ( data )
 | |
|             data->DecRef();
 | |
|     }
 | |
| 
 | |
|     virtual void CopyBuffer(const wxAnyValueBuffer& src,
 | |
|                             wxAnyValueBuffer& dst) const wxOVERRIDE
 | |
|     {
 | |
|         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 wxOVERRIDE
 | |
|     {
 | |
|         wxUnusedVar(src);
 | |
|         wxUnusedVar(dstType);
 | |
|         wxUnusedVar(dst);
 | |
|         return false;
 | |
|     }
 | |
| };
 | |
| 
 | |
| template<>
 | |
| class wxAnyValueTypeImpl<wxVariantData*> :
 | |
|     public wxAnyValueTypeImplVariantData
 | |
| {
 | |
| public:
 | |
|     wxAnyValueTypeImpl() : wxAnyValueTypeImplVariantData() { }
 | |
|     virtual ~wxAnyValueTypeImpl() { }
 | |
| };
 | |
| 
 | |
| #endif // wxUSE_VARIANT
 | |
| 
 | |
| 
 | |
| /*
 | |
|     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.
 | |
| 
 | |
|         @see wxAnyValueType::CheckType()
 | |
|     */
 | |
|     template <typename T>
 | |
|     bool CheckType() 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.
 | |
|     */
 | |
|     template <typename T>
 | |
|     T As(T* = NULL) const
 | |
|     {
 | |
|         return wxPrivate::wxAnyAsImpl<T>::DoAs(*this);
 | |
|     }
 | |
| 
 | |
|     // Semi private helper: get the value without coercion, for all types.
 | |
|     template <typename T>
 | |
|     T RawAs() const
 | |
|     {
 | |
|         if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )
 | |
|         {
 | |
|             wxFAIL_MSG("Incorrect or non-convertible data type");
 | |
|         }
 | |
| 
 | |
|         return static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(m_buffer));
 | |
|     }
 | |
| 
 | |
| #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;
 | |
| };
 | |
| 
 | |
| 
 | |
| namespace wxPrivate
 | |
| {
 | |
| 
 | |
| // Dispatcher for template wxAny::As() implementation which is different for
 | |
| // wxString and all the other types: the generic implementation check if the
 | |
| // value is of the right type and returns it.
 | |
| template <typename T>
 | |
| struct wxAnyAsImpl
 | |
| {
 | |
|     static T DoAs(const wxAny& any)
 | |
|     {
 | |
|         return any.RawAs<T>();
 | |
|     }
 | |
| };
 | |
| 
 | |
| // Specialization for wxString does coercion.
 | |
| template <>
 | |
| struct wxAnyAsImpl<wxString>
 | |
| {
 | |
|     static wxString DoAs(const wxAny& any)
 | |
|     {
 | |
|         wxString value;
 | |
|         if ( !any.GetAs(&value) )
 | |
|         {
 | |
|             wxFAIL_MSG("Incorrect or non-convertible data type");
 | |
|         }
 | |
|         return value;
 | |
|     }
 | |
| };
 | |
| 
 | |
| }
 | |
| 
 | |
| // See comment for wxANY_VALUE_TYPE_CHECK_TYPE.
 | |
| #define wxANY_CHECK_TYPE(any, T) \
 | |
|     wxANY_VALUE_TYPE_CHECK_TYPE((any).GetType(), T)
 | |
| 
 | |
| 
 | |
| // This macro shouldn't be used any longer for the same reasons as
 | |
| // wxANY_VALUE_TYPE_CHECK_TYPE(), just call As() directly.
 | |
| #define wxANY_AS(any, T) \
 | |
|     (any).As(static_cast<T*>(NULL))
 | |
| 
 | |
| 
 | |
| template<typename T>
 | |
| inline bool wxAnyValueType::CheckType() const
 | |
| {
 | |
|     return wxAnyValueTypeImpl<T>::IsSameClass(this);
 | |
| }
 | |
| 
 | |
| WX_DECLARE_LIST_WITH_DECL(wxAny, wxAnyList, class WXDLLIMPEXP_BASE);
 | |
| 
 | |
| #endif // wxUSE_ANY
 | |
| 
 | |
| #endif // _WX_ANY_H_
 |