git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@62762 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			858 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			858 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /////////////////////////////////////////////////////////////////////////////
 | |
| // Name:        wx/any.h
 | |
| // Purpose:     wxAny class
 | |
| // Author:      Jaakko Salli
 | |
| // Modified by:
 | |
| // Created:     07/05/2009
 | |
| // RCS-ID:      $Id$
 | |
| // Copyright:   (c) wxWidgets team
 | |
| // Licence:     wxWindows licence
 | |
| /////////////////////////////////////////////////////////////////////////////
 | |
| 
 | |
| #ifndef _WX_ANY_H_
 | |
| #define _WX_ANY_H_
 | |
| 
 | |
| #include "wx/defs.h"
 | |
| 
 | |
| #if wxUSE_ANY
 | |
| 
 | |
| #include "wx/string.h"
 | |
| #include "wx/meta/movable.h"
 | |
| #include "wx/meta/if.h"
 | |
| #include "wx/typeinfo.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 ccompatibility
 | |
|                 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);
 | |
| private:
 | |
| };
 | |
| 
 | |
| //
 | |
| // 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.
 | |
| */
 | |
| #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) == wxTypeId(*otherType); \
 | |
|     } \
 | |
|     virtual bool IsSameType(const wxAnyValueType* otherType) const \
 | |
|     { \
 | |
|         return IsSameClass(otherType); \
 | |
|     } \
 | |
| private: \
 | |
|     static CLS* sm_instance; \
 | |
| public: \
 | |
|     static wxAnyValueType* GetInstance() \
 | |
|     { \
 | |
|         return sm_instance; \
 | |
|     }
 | |
| 
 | |
| 
 | |
| #define WX_IMPLEMENT_ANY_VALUE_TYPE(CLS) \
 | |
|     CLS* 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 wxAnyValueTypeOpsMovable
 | |
| {
 | |
| public:
 | |
|     static void DeleteValue(wxAnyValueBuffer& buf)
 | |
|     {
 | |
|         wxUnusedVar(buf);
 | |
|     }
 | |
| 
 | |
|     static void SetValue(const T& value,
 | |
|                          wxAnyValueBuffer& buf)
 | |
|     {
 | |
|         memcpy(buf.m_buffer, &value, sizeof(T));
 | |
|     }
 | |
| 
 | |
|     static const T& GetValue(const wxAnyValueBuffer& buf)
 | |
|     {
 | |
|         return *(reinterpret_cast<const T*>(&buf.m_buffer[0]));
 | |
|     }
 | |
| };
 | |
| 
 | |
| 
 | |
| 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< wxIsMovable<T>::value &&
 | |
|                                 sizeof(T) <= WX_ANY_VALUE_BUFFER_SIZE,
 | |
|                            wxPrivate::wxAnyValueTypeOpsMovable<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);
 | |
|     }
 | |
| };
 | |
| 
 | |
| 
 | |
| /*
 | |
|     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>
 | |
| wxAnyValueTypeImpl<T>* 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) \
 | |
|     { \
 | |
|         *(reinterpret_cast<UseDataType*>(&buf.m_buffer[0])) = \
 | |
|             static_cast<UseDataType>(value); \
 | |
|     } \
 | |
|     static T GetValue(const wxAnyValueBuffer& buf) \
 | |
|     { \
 | |
|         return static_cast<T>( \
 | |
|             *(reinterpret_cast<const UseDataType*>(&buf.m_buffer[0]))); \
 | |
|     } \
 | |
| };
 | |
| 
 | |
| 
 | |
| //
 | |
| //  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
 | |
| 
 | |
| 
 | |
| //
 | |
| // String value type
 | |
| //
 | |
| class WXDLLIMPEXP_BASE wxAnyValueTypeImplString :
 | |
|     public wxAnyValueTypeImplBase<wxString>
 | |
| {
 | |
|     WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplString)
 | |
| public:
 | |
|     wxAnyValueTypeImplString() :
 | |
|         wxAnyValueTypeImplBase<wxString>() { }
 | |
|     virtual ~wxAnyValueTypeImplString() { }
 | |
| 
 | |
|     /**
 | |
|         Convert value into buffer of different type. Return false if
 | |
|         not possible.
 | |
|     */
 | |
|     virtual bool ConvertValue(const wxAnyValueBuffer& src,
 | |
|                               wxAnyValueType* dstType,
 | |
|                               wxAnyValueBuffer& dst) const;
 | |
| 
 | |
| };
 | |
| 
 | |
| template<>
 | |
| class wxAnyValueTypeImpl<wxString> : public wxAnyValueTypeImplString
 | |
| {
 | |
| public:
 | |
|     wxAnyValueTypeImpl() : wxAnyValueTypeImplString() { }
 | |
|     virtual ~wxAnyValueTypeImpl() { }
 | |
| };
 | |
| 
 | |
| 
 | |
| //
 | |
| // 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 unittests 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)
 | |
| 
 | |
| 
 | |
| 
 | |
| #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; \
 | |
| }
 | |
| 
 | |
| 
 | |
| //
 | |
| // 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.
 | |
|     */
 | |
|     wxAny(const char* value)
 | |
|     {
 | |
|         m_type = wxAnyNullValueType;
 | |
|         Assign(wxString(value));
 | |
|     }
 | |
|     wxAny(const wchar_t* value)
 | |
|     {
 | |
|         m_type = wxAnyNullValueType;
 | |
|         Assign(wxString(value));
 | |
|     }
 | |
| 
 | |
|     wxAny(const wxAny& any)
 | |
|     {
 | |
|         m_type = wxAnyNullValueType;
 | |
|         AssignAny(any);
 | |
|     }
 | |
| 
 | |
|     template<typename T>
 | |
|     wxAny(const T& value)
 | |
|     {
 | |
|         m_type = wxAnyValueTypeImpl<T>::sm_instance;
 | |
|         wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
 | |
|     }
 | |
|     //@}
 | |
| 
 | |
|     /**
 | |
|         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)
 | |
|     {
 | |
|         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
 | |
|                  wxAnyValueType::CheckType<T>() template function.
 | |
|     */
 | |
|     const wxAnyValueType* GetType() const
 | |
|     {
 | |
|         return m_type;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|         Tests if wxAny is null (that is, whether there is 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.
 | |
|     */
 | |
|     wxAny& operator=(const wxAny &any)
 | |
|     {
 | |
|         if (this != &any)
 | |
|             AssignAny(any);
 | |
|         return *this;
 | |
|     }
 | |
| 
 | |
|     template<typename T>
 | |
|     wxAny& operator=(const T &value)
 | |
|     {
 | |
|         m_type->DeleteValue(m_buffer);
 | |
|         m_type = wxAnyValueTypeImpl<T>::sm_instance;
 | |
|         wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
 | |
|         return *this;
 | |
|     }
 | |
| 
 | |
|     wxAny& operator=(const char* value)
 | |
|         { Assign(wxString(value)); return *this; }
 | |
|     wxAny& operator=(const wchar_t* value)
 | |
|         { Assign(wxString(value)); return *this; }
 | |
|     //@}
 | |
| 
 | |
|     //@{
 | |
|     /**
 | |
|         Equality operators.
 | |
|     */
 | |
|     bool operator==(const wxString& value) const
 | |
|     {
 | |
|         if ( !wxAnyValueTypeImpl<wxString>::IsSameClass(m_type) )
 | |
|             return false;
 | |
| 
 | |
|         return value ==
 | |
|             static_cast<wxString>
 | |
|                 (wxAnyValueTypeImpl<wxString>::GetValue(m_buffer));
 | |
|     }
 | |
| 
 | |
|     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
 | |
| 
 | |
|     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));
 | |
|     }
 | |
| 
 | |
|     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. No dynamic
 | |
|         conversion is performed, so if the type is incorrect an assertion
 | |
|         failure will occur in debug builds, and a bogus value is returned
 | |
|         in release ones.
 | |
| 
 | |
|         @remarks This template function does not work on some older compilers
 | |
|                 (such as Visual C++ 6.0). For full compiler ccompatibility
 | |
|                 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));
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|         Template function that etrieves and converts the value of this
 | |
|         variant to the type that T* value is.
 | |
| 
 | |
|         @return Returns @true if conversion was succesfull.
 | |
|     */
 | |
|     template<typename T>
 | |
|     bool GetAs(T* value) const
 | |
|     {
 | |
|         if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )
 | |
|         {
 | |
|             wxAnyValueType* otherType =
 | |
|                 wxAnyValueTypeImpl<T>::sm_instance;
 | |
|             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;
 | |
|     }
 | |
| 
 | |
| 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);
 | |
|     }
 | |
| 
 | |
|     template<typename T>
 | |
|     void Assign(const T &value)
 | |
|     {
 | |
|         m_type->DeleteValue(m_buffer);
 | |
|         m_type = wxAnyValueTypeImpl<T>::sm_instance;
 | |
|         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)
 | |
| {
 | |
|     wxUnusedVar(reserved);
 | |
|     return wxAnyValueTypeImpl<T>::IsSameClass(this);
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| #endif // wxUSE_ANY
 | |
| 
 | |
| #endif // _WX_ANY_H_
 |