]> git.saurik.com Git - wxWidgets.git/commitdiff
Set svn properties correctly for the newly added files.
authorVadim Zeitlin <vadim@wxwidgets.org>
Sat, 19 Sep 2009 15:41:08 +0000 (15:41 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sat, 19 Sep 2009 15:41:08 +0000 (15:41 +0000)
Set svn:keyword and, most importantly, svn:eol-style, to avoid having files
with DOS line endings in svn, for the new files added by r61971.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@61973 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/any.h
interface/wx/any.h
src/common/any.cpp
tests/any/anytest.cpp

index 9acda4ef5501fcbd9f8cfe5e1701f774cbae39ef..0a5b075c56cad07bf0958690dae7cdf33e8651d0 100644 (file)
-/////////////////////////////////////////////////////////////////////////////\r
-// Name:        wx/any.h\r
-// Purpose:     wxAny class\r
-// Author:      Jaakko Salli\r
-// Modified by:\r
-// Created:     07/05/2009\r
-// RCS-ID:      $Id$\r
-// Copyright:   (c) wxWidgets team\r
-// Licence:     wxWindows licence\r
-/////////////////////////////////////////////////////////////////////////////\r
-\r
-#ifndef _WX_ANY_H_\r
-#define _WX_ANY_H_\r
-\r
-#include "wx/defs.h"\r
-\r
-#if wxUSE_ANY\r
-\r
-#include "wx/string.h"\r
-#include "wx/meta/movable.h"\r
-#include "wx/meta/if.h"\r
-\r
-\r
-// Size of the wxAny value buffer.\r
-enum\r
-{\r
-    WX_ANY_VALUE_BUFFER_SIZE = 16\r
-};\r
-\r
-union wxAnyValueBuffer\r
-{\r
-    void*   m_ptr;\r
-    wxByte  m_buffer[WX_ANY_VALUE_BUFFER_SIZE];\r
-};\r
-\r
-typedef void (*wxAnyClassInfo)();\r
-\r
-\r
-//\r
-// wxAnyValueType is base class for value type functionality for C++ data\r
-// types used with wxAny. Usually the default template (wxAnyValueTypeImpl<>)\r
-// will create a satisfactory wxAnyValueType implementation for a data type.\r
-//\r
-class WXDLLIMPEXP_BASE wxAnyValueType\r
-{\r
-public:\r
-    /**\r
-        Default constructor.\r
-    */\r
-    wxAnyValueType();\r
-\r
-    /**\r
-        Destructor.\r
-    */\r
-    virtual ~wxAnyValueType()\r
-    {\r
-    }\r
-\r
-    /**\r
-        This function is used for internal type matching.\r
-    */\r
-    virtual wxAnyClassInfo GetClassInfo() const = 0;\r
-\r
-    /**\r
-        This function is used for internal type matching.\r
-    */\r
-    virtual bool IsSameType(const wxAnyValueType* otherType) const = 0;\r
-\r
-    /**\r
-        This function is called every time the data in wxAny\r
-        buffer needs to be freed.\r
-    */\r
-    virtual void DeleteValue(wxAnyValueBuffer& buf) const = 0;\r
-\r
-    /**\r
-        Implement this for buffer-to-buffer copy. src.m_ptr can\r
-        be expected to be NULL if value type of previously stored\r
-        data was different.\r
-    */\r
-    virtual void CopyBuffer(const wxAnyValueBuffer& src,\r
-                            wxAnyValueBuffer& dst) const = 0;\r
-\r
-    /**\r
-        Convert value into buffer of different type. Return false if\r
-        not possible.\r
-    */\r
-    virtual bool ConvertValue(const wxAnyValueBuffer& src,\r
-                              wxAnyValueType* dstType,\r
-                              wxAnyValueBuffer& dst) const = 0;\r
-\r
-    /**\r
-        Use this template function for checking if wxAnyValueType represents\r
-        a specific C++ data type.\r
-\r
-        @remarks This template function does not work on some older compilers\r
-                (such as Visual C++ 6.0). For full compiler ccompatibility\r
-                please use wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) macro\r
-                instead.\r
-\r
-        @see wxAny::CheckType()\r
-    */\r
-    // FIXME-VC6: remove this hack when VC6 is no longer supported\r
-    template <typename T>\r
-    bool CheckType(T* reserved = NULL);\r
-private:\r
-};\r
-\r
-//\r
-// This method of checking the type is compatible with VC6\r
-#define wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) \\r
-    wxAnyValueTypeImpl<T>::IsSameClass(valueTypePtr)\r
-\r
-    //valueTypePtr->CheckType(static_cast<T*>(NULL))\r
-\r
-\r
-/**\r
-    Helper macro for defining user value types.\r
-\r
-    NB: We really cannot compare sm_classInfo directly in IsSameClass(),\r
-        but instead call sm_instance->GetClassInfo(). The former technique\r
-        broke at least on GCC 4.2 (but worked on VC8 shared build).\r
-*/\r
-#define WX_DECLARE_ANY_VALUE_TYPE(CLS) \\r
-    friend class wxAny; \\r
-public: \\r
-    static void sm_classInfo() {} \\r
- \\r
-    virtual wxAnyClassInfo GetClassInfo() const \\r
-    { \\r
-        return sm_classInfo; \\r
-    } \\r
-    static bool IsSameClass(const wxAnyValueType* otherType) \\r
-    { \\r
-        return sm_instance->GetClassInfo() == otherType->GetClassInfo(); \\r
-    } \\r
-    virtual bool IsSameType(const wxAnyValueType* otherType) const \\r
-    { \\r
-        return IsSameClass(otherType); \\r
-    } \\r
-private: \\r
-    static CLS* sm_instance; \\r
-public: \\r
-    static wxAnyValueType* GetInstance() \\r
-    { \\r
-        return sm_instance; \\r
-    }\r
-\r
-\r
-#define WX_IMPLEMENT_ANY_VALUE_TYPE(CLS) \\r
-    CLS* CLS::sm_instance = new CLS();\r
-\r
-\r
-#ifdef __VISUALC6__\r
-    // "non dll-interface class 'xxx' used as base interface\r
-    #pragma warning (push)\r
-    #pragma warning (disable:4275)\r
-#endif\r
-\r
-/**\r
-    Following are helper classes for the wxAnyValueTypeImplBase.\r
-*/\r
-namespace wxPrivate\r
-{\r
-\r
-template<typename T>\r
-class wxAnyValueTypeOpsMovable\r
-{\r
-public:\r
-    static void DeleteValue(wxAnyValueBuffer& buf)\r
-    {\r
-        wxUnusedVar(buf);\r
-    }\r
-\r
-    static void SetValue(const T& value,\r
-                         wxAnyValueBuffer& buf)\r
-    {\r
-        memcpy(buf.m_buffer, &value, sizeof(T));\r
-    }\r
-\r
-    static const T& GetValue(const wxAnyValueBuffer& buf)\r
-    {\r
-        return *(reinterpret_cast<const T*>(&buf.m_buffer[0]));\r
-    }\r
-};\r
-\r
-\r
-template<typename T>\r
-class wxAnyValueTypeOpsGeneric\r
-{\r
-public:\r
-    template<typename T2>\r
-    class DataHolder\r
-    {\r
-    public:\r
-        DataHolder(const T2& value)\r
-        {\r
-            m_value = value;\r
-        }\r
-        virtual ~DataHolder() { }\r
-\r
-        T2   m_value;\r
-    private:\r
-        wxDECLARE_NO_COPY_CLASS(DataHolder);\r
-    };\r
-\r
-    static void DeleteValue(wxAnyValueBuffer& buf)\r
-    {\r
-        DataHolder<T>* holder = static_cast<DataHolder<T>*>(buf.m_ptr);\r
-        delete holder;\r
-    }\r
-\r
-    static void SetValue(const T& value,\r
-                         wxAnyValueBuffer& buf)\r
-    {\r
-        DataHolder<T>* holder = new DataHolder<T>(value);\r
-        buf.m_ptr = holder;\r
-    }\r
-\r
-    static const T& GetValue(const wxAnyValueBuffer& buf)\r
-    {\r
-        DataHolder<T>* holder = static_cast<DataHolder<T>*>(buf.m_ptr);\r
-        return holder->m_value;\r
-    }\r
-};\r
-\r
-} // namespace wxPrivate\r
-\r
-\r
-/**\r
-    Intermediate template for the generic value type implementation.\r
-    We can derive from this same value type for multiple actual types\r
-    (for instance, we can have wxAnyValueTypeImplInt for all signed\r
-    integer types), and also easily implement specialized templates\r
-    with specific dynamic type conversion.\r
-*/\r
-template<typename T>\r
-class wxAnyValueTypeImplBase : public wxAnyValueType\r
-{\r
-    typedef typename wxIf< wxIsMovable<T>::value &&\r
-                                sizeof(T) <= WX_ANY_VALUE_BUFFER_SIZE,\r
-                           wxPrivate::wxAnyValueTypeOpsMovable<T>,\r
-                           wxPrivate::wxAnyValueTypeOpsGeneric<T> >::value\r
-            Ops;\r
-\r
-public:\r
-    wxAnyValueTypeImplBase() : wxAnyValueType() { }\r
-    virtual ~wxAnyValueTypeImplBase() { }\r
-\r
-    virtual void DeleteValue(wxAnyValueBuffer& buf) const\r
-    {\r
-        Ops::DeleteValue(buf);\r
-        buf.m_ptr = NULL;  // This is important\r
-    }\r
-\r
-    virtual void CopyBuffer(const wxAnyValueBuffer& src,\r
-                            wxAnyValueBuffer& dst) const\r
-    {\r
-        Ops::DeleteValue(dst);\r
-        Ops::SetValue(Ops::GetValue(src), dst);\r
-    }\r
-\r
-    /**\r
-        It is important to reimplement this in any specialized template\r
-        classes that inherit from wxAnyValueTypeImplBase.\r
-    */\r
-    static void SetValue(const T& value,\r
-                         wxAnyValueBuffer& buf)\r
-    {\r
-        Ops::SetValue(value, buf);\r
-    }\r
-\r
-    /**\r
-        It is important to reimplement this in any specialized template\r
-        classes that inherit from wxAnyValueTypeImplBase.\r
-    */\r
-    static const T& GetValue(const wxAnyValueBuffer& buf)\r
-    {\r
-        return Ops::GetValue(buf);\r
-    }\r
-};\r
-\r
-\r
-/*\r
-    Generic value type template. Note that bulk of the implementation\r
-    resides in wxAnyValueTypeImplBase.\r
-*/\r
-template<typename T>\r
-class wxAnyValueTypeImpl : public wxAnyValueTypeImplBase<T>\r
-{\r
-    WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<T>)\r
-public:\r
-    wxAnyValueTypeImpl() : wxAnyValueTypeImplBase<T>() { }\r
-    virtual ~wxAnyValueTypeImpl() { }\r
-\r
-    virtual bool ConvertValue(const wxAnyValueBuffer& src,\r
-                              wxAnyValueType* dstType,\r
-                              wxAnyValueBuffer& dst) const\r
-    {\r
-        wxUnusedVar(src);\r
-        wxUnusedVar(dstType);\r
-        wxUnusedVar(dst);\r
-        return false;\r
-    }\r
-};\r
-\r
-template<typename T>\r
-wxAnyValueTypeImpl<T>* wxAnyValueTypeImpl<T>::sm_instance =\r
-    new wxAnyValueTypeImpl<T>();\r
-\r
-\r
-//\r
-// Helper macro for using same base value type implementation for multiple\r
-// actual C++ data types.\r
-//\r
-#define WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \\r
-template<> \\r
-class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##CLSTYPE \\r
-{ \\r
-    typedef wxAnyBase##CLSTYPE##Type UseDataType; \\r
-public: \\r
-    wxAnyValueTypeImpl() : wxAnyValueTypeImpl##CLSTYPE() { } \\r
-    virtual ~wxAnyValueTypeImpl() { } \\r
-    static void SetValue(const T& value, wxAnyValueBuffer& buf) \\r
-    { \\r
-        *(reinterpret_cast<UseDataType*>(&buf.m_buffer[0])) = \\r
-            static_cast<UseDataType>(value); \\r
-    } \\r
-    static T GetValue(const wxAnyValueBuffer& buf) \\r
-    { \\r
-        return static_cast<T>( \\r
-            *(reinterpret_cast<const UseDataType*>(&buf.m_buffer[0]))); \\r
-    } \\r
-};\r
-\r
-\r
-//\r
-//  Integer value types\r
-//\r
-\r
-#ifdef wxLongLong_t\r
-    typedef wxLongLong_t wxAnyBaseIntType;\r
-    typedef wxULongLong_t wxAnyBaseUintType;\r
-#else\r
-    typedef long wxAnyBaseIntType;\r
-    typedef unsigned long wxAnyBaseUintType;\r
-#endif\r
-\r
-\r
-class WXDLLIMPEXP_BASE wxAnyValueTypeImplInt :\r
-    public wxAnyValueTypeImplBase<wxAnyBaseIntType>\r
-{\r
-    WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplInt)\r
-public:\r
-    wxAnyValueTypeImplInt() :\r
-        wxAnyValueTypeImplBase<wxAnyBaseIntType>() { }\r
-    virtual ~wxAnyValueTypeImplInt() { }\r
-\r
-    virtual bool ConvertValue(const wxAnyValueBuffer& src,\r
-                              wxAnyValueType* dstType,\r
-                              wxAnyValueBuffer& dst) const;\r
-};\r
-\r
-\r
-class WXDLLIMPEXP_BASE wxAnyValueTypeImplUint :\r
-    public wxAnyValueTypeImplBase<wxAnyBaseUintType>\r
-{\r
-    WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplUint)\r
-public:\r
-    wxAnyValueTypeImplUint() :\r
-        wxAnyValueTypeImplBase<wxAnyBaseUintType>() { }\r
-    virtual ~wxAnyValueTypeImplUint() { }\r
-\r
-    virtual bool ConvertValue(const wxAnyValueBuffer& src,\r
-                              wxAnyValueType* dstType,\r
-                              wxAnyValueBuffer& dst) const;\r
-};\r
-\r
-\r
-WX_ANY_DEFINE_SUB_TYPE(signed long, Int)\r
-WX_ANY_DEFINE_SUB_TYPE(signed int, Int)\r
-WX_ANY_DEFINE_SUB_TYPE(signed short, Int)\r
-WX_ANY_DEFINE_SUB_TYPE(signed char, Int)\r
-#ifdef wxLongLong_t\r
-WX_ANY_DEFINE_SUB_TYPE(wxLongLong_t, Int)\r
-#endif\r
-\r
-WX_ANY_DEFINE_SUB_TYPE(unsigned long, Uint)\r
-WX_ANY_DEFINE_SUB_TYPE(unsigned int, Uint)\r
-WX_ANY_DEFINE_SUB_TYPE(unsigned short, Uint)\r
-WX_ANY_DEFINE_SUB_TYPE(unsigned char, Uint)\r
-#ifdef wxLongLong_t\r
-WX_ANY_DEFINE_SUB_TYPE(wxULongLong_t, Uint)\r
-#endif\r
-\r
-\r
-//\r
-// String value type\r
-//\r
-class WXDLLIMPEXP_BASE wxAnyValueTypeImplString :\r
-    public wxAnyValueTypeImplBase<wxString>\r
-{\r
-    WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplString)\r
-public:\r
-    wxAnyValueTypeImplString() :\r
-        wxAnyValueTypeImplBase<wxString>() { }\r
-    virtual ~wxAnyValueTypeImplString() { }\r
-\r
-    /**\r
-        Convert value into buffer of different type. Return false if\r
-        not possible.\r
-    */\r
-    virtual bool ConvertValue(const wxAnyValueBuffer& src,\r
-                              wxAnyValueType* dstType,\r
-                              wxAnyValueBuffer& dst) const;\r
-\r
-};\r
-\r
-template<>\r
-class wxAnyValueTypeImpl<wxString> : public wxAnyValueTypeImplString\r
-{\r
-public:\r
-    wxAnyValueTypeImpl() : wxAnyValueTypeImplString() { }\r
-    virtual ~wxAnyValueTypeImpl() { }\r
-};\r
-\r
-\r
-//\r
-// Bool value type\r
-//\r
-template<>\r
-class WXDLLIMPEXP_BASE wxAnyValueTypeImpl<bool> :\r
-    public wxAnyValueTypeImplBase<bool>\r
-{\r
-    WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<bool>)\r
-public:\r
-    wxAnyValueTypeImpl() :\r
-        wxAnyValueTypeImplBase<bool>() { }\r
-    virtual ~wxAnyValueTypeImpl() { }\r
-\r
-    virtual bool ConvertValue(const wxAnyValueBuffer& src,\r
-                              wxAnyValueType* dstType,\r
-                              wxAnyValueBuffer& dst) const;\r
-};\r
-\r
-//\r
-// Floating point value type\r
-//\r
-class WXDLLIMPEXP_BASE wxAnyValueTypeImplDouble :\r
-    public wxAnyValueTypeImplBase<double>\r
-{\r
-    WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble)\r
-public:\r
-    wxAnyValueTypeImplDouble() :\r
-        wxAnyValueTypeImplBase<double>() { }\r
-    virtual ~wxAnyValueTypeImplDouble() { }\r
-\r
-    virtual bool ConvertValue(const wxAnyValueBuffer& src,\r
-                              wxAnyValueType* dstType,\r
-                              wxAnyValueBuffer& dst) const;\r
-};\r
-\r
-// WX_ANY_DEFINE_SUB_TYPE requires this\r
-typedef double wxAnyBaseDoubleType;\r
-\r
-WX_ANY_DEFINE_SUB_TYPE(float, Double)\r
-WX_ANY_DEFINE_SUB_TYPE(double, Double)\r
-\r
-\r
-#ifdef __VISUALC6__\r
-    // Re-enable useless VC6 warnings\r
-    #pragma warning (pop)\r
-#endif\r
-\r
-\r
-/*\r
-    Let's define a discrete Null value so we don't have to really\r
-    ever check if wxAny.m_type pointer is NULL or not. This is an\r
-    optimization, mostly. Implementation of this value type is\r
-    "hidden" in the source file.\r
-*/\r
-extern WXDLLIMPEXP_DATA_BASE(wxAnyValueType*) wxAnyNullValueType;\r
-\r
-\r
-//\r
-// We need to implement custom signed/unsigned int equals operators\r
-// for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.\r
-#define WXANY_IMPLEMENT_INT_EQ_OP(TS, TUS) \\r
-bool operator==(TS value) const \\r
-{ \\r
-    if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \\r
-        return (value == static_cast<TS> \\r
-                (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \\r
-    if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \\r
-        return (value == static_cast<TS> \\r
-                (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \\r
-    return false; \\r
-} \\r
-bool operator==(TUS value) const \\r
-{ \\r
-    if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \\r
-        return (value == static_cast<TUS> \\r
-                (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \\r
-    if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \\r
-        return (value == static_cast<TUS> \\r
-                (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \\r
-    return false; \\r
-}\r
-\r
-\r
-//\r
-// The wxAny class represents a container for any type. A variant's value\r
-// can be changed at run time, possibly to a different type of value.\r
-//\r
-// As standard, wxAny can store value of almost any type, in a fairly\r
-// optimal manner even.\r
-//\r
-class WXDLLIMPEXP_BASE wxAny\r
-{\r
-public:\r
-    /**\r
-        Default constructor.\r
-    */\r
-    wxAny()\r
-    {\r
-        m_type = wxAnyNullValueType;\r
-    }\r
-\r
-    /**\r
-        Destructor.\r
-    */\r
-    ~wxAny()\r
-    {\r
-        m_type->DeleteValue(m_buffer);\r
-    }\r
-\r
-    //@{\r
-    /**\r
-        Various constructors.\r
-    */\r
-    wxAny(const char* value)\r
-    {\r
-        m_type = wxAnyNullValueType;\r
-        Assign(wxString(value));\r
-    }\r
-    wxAny(const wchar_t* value)\r
-    {\r
-        m_type = wxAnyNullValueType;\r
-        Assign(wxString(value));\r
-    }\r
-\r
-    wxAny(const wxAny& any)\r
-    {\r
-        m_type = wxAnyNullValueType;\r
-        AssignAny(any);\r
-    }\r
-\r
-    template<typename T>\r
-    wxAny(const T& value)\r
-    {\r
-        m_type = wxAnyValueTypeImpl<T>::sm_instance;\r
-        wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);\r
-    }\r
-    //@}\r
-\r
-    /**\r
-        Use this template function for checking if this wxAny holds\r
-        a specific C++ data type.\r
-\r
-        @remarks This template function does not work on some older compilers\r
-                (such as Visual C++ 6.0). For full compiler ccompatibility\r
-                please use wxANY_CHECK_TYPE(any, T) macro instead.\r
-\r
-        @see wxAnyValueType::CheckType()\r
-    */\r
-    // FIXME-VC6: remove this hack when VC6 is no longer supported\r
-    template <typename T>\r
-    bool CheckType(T* = NULL)\r
-    {\r
-        return m_type->CheckType<T>();\r
-    }\r
-\r
-    /**\r
-        Returns the value type as wxAnyValueType instance.\r
-\r
-        @remarks You cannot reliably test whether two wxAnys are of\r
-                 same value type by simply comparing return values\r
-                 of wxAny::GetType(). Instead use\r
-                 wxAnyValueType::CheckType<T>() template function.\r
-    */\r
-    const wxAnyValueType* GetType() const\r
-    {\r
-        return m_type;\r
-    }\r
-\r
-    /**\r
-        Tests if wxAny is null (that is, whether there is data).\r
-    */\r
-    bool IsNull() const\r
-    {\r
-        return (m_type == wxAnyNullValueType);\r
-    }\r
-\r
-    /**\r
-        Makes wxAny null (that is, clears it).\r
-    */\r
-    void MakeNull()\r
-    {\r
-        m_type->DeleteValue(m_buffer);\r
-        m_type = wxAnyNullValueType;\r
-    }\r
-\r
-    //@{\r
-    /**\r
-        Assignment operators.\r
-    */\r
-    wxAny& operator=(const wxAny &any)\r
-    {\r
-        AssignAny(any);\r
-        return *this;\r
-    }\r
-\r
-    template<typename T>\r
-    wxAny& operator=(const T &value)\r
-    {\r
-        m_type->DeleteValue(m_buffer);\r
-        m_type = wxAnyValueTypeImpl<T>::sm_instance;\r
-        wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);\r
-        return *this;\r
-    }\r
-\r
-    wxAny& operator=(const char* value)\r
-        { Assign(wxString(value)); return *this; }\r
-    wxAny& operator=(const wchar_t* value)\r
-        { Assign(wxString(value)); return *this; }\r
-    //@}\r
-\r
-    //@{\r
-    /**\r
-        Equality operators.\r
-    */\r
-    bool operator==(const wxString& value) const\r
-    {\r
-        if ( !wxAnyValueTypeImpl<wxString>::IsSameClass(m_type) )\r
-            return false;\r
-\r
-        return value ==\r
-            static_cast<wxString>\r
-                (wxAnyValueTypeImpl<wxString>::GetValue(m_buffer));\r
-    }\r
-\r
-    bool operator==(const char* value) const\r
-        { return (*this) == wxString(value); }\r
-    bool operator==(const wchar_t* value) const\r
-        { return (*this) == wxString(value); }\r
-\r
-    //\r
-    // We need to implement custom signed/unsigned int equals operators\r
-    // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.\r
-    WXANY_IMPLEMENT_INT_EQ_OP(signed char, unsigned char)\r
-    WXANY_IMPLEMENT_INT_EQ_OP(signed short, unsigned short)\r
-    WXANY_IMPLEMENT_INT_EQ_OP(signed int, unsigned int)\r
-    WXANY_IMPLEMENT_INT_EQ_OP(signed long, unsigned long)\r
-#ifdef wxLongLong_t\r
-    WXANY_IMPLEMENT_INT_EQ_OP(wxLongLong_t, wxULongLong_t)\r
-#endif\r
-\r
-    bool operator==(float value) const\r
-    {\r
-        if ( !wxAnyValueTypeImpl<float>::IsSameClass(m_type) )\r
-            return false;\r
-\r
-        return value ==\r
-            static_cast<float>\r
-                (wxAnyValueTypeImpl<float>::GetValue(m_buffer));\r
-    }\r
-\r
-    bool operator==(double value) const\r
-    {\r
-        if ( !wxAnyValueTypeImpl<double>::IsSameClass(m_type) )\r
-            return false;\r
-\r
-        return value ==\r
-            static_cast<double>\r
-                (wxAnyValueTypeImpl<double>::GetValue(m_buffer));\r
-    }\r
-\r
-    bool operator==(bool value) const\r
-    {\r
-        if ( !wxAnyValueTypeImpl<bool>::IsSameClass(m_type) )\r
-            return false;\r
-\r
-        return value == (wxAnyValueTypeImpl<bool>::GetValue(m_buffer));\r
-    }\r
-\r
-    //@}\r
-\r
-    //@{\r
-    /**\r
-        Inequality operators (implement as template).\r
-    */\r
-    template<typename T>\r
-    bool operator!=(const T& value) const\r
-        { return !((*this) == value); }\r
-    //@}\r
-\r
-    /**\r
-        This template function converts wxAny into given type. No dynamic\r
-        conversion is performed, so if the type is incorrect an assertion\r
-        failure will occur in debug builds, and a bogus value is returned\r
-        in release ones.\r
-\r
-        @remarks This template function does not work on some older compilers\r
-                (such as Visual C++ 6.0). For full compiler ccompatibility\r
-                please use wxANY_AS(any, T) macro instead.\r
-    */\r
-    // FIXME-VC6: remove this hack when VC6 is no longer supported\r
-    template<typename T>\r
-    T As(T* = NULL) const\r
-    {\r
-        if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )\r
-            wxFAIL_MSG("Incorrect or non-convertible data type");\r
-        return static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(m_buffer));\r
-    }\r
-\r
-    /**\r
-        Template function that etrieves and converts the value of this\r
-        variant to the type that T* value is.\r
-\r
-        @return Returns @true if conversion was succesfull.\r
-    */\r
-    template<typename T>\r
-    bool GetAs(T* value) const\r
-    {\r
-        if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )\r
-        {\r
-            wxAnyValueType* otherType =\r
-                wxAnyValueTypeImpl<T>::sm_instance;\r
-            wxAnyValueBuffer temp_buf;\r
-\r
-            if ( !m_type->ConvertValue(m_buffer, otherType, temp_buf) )\r
-                return false;\r
-\r
-            *value =\r
-                static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(temp_buf));\r
-            otherType->DeleteValue(temp_buf);\r
-\r
-            return true;\r
-        }\r
-        *value = static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(m_buffer));\r
-        return true;\r
-    }\r
-\r
-private:\r
-    // Assignment functions\r
-    void AssignAny(const wxAny &any);\r
-\r
-    template<typename T>\r
-    void Assign(const T &value)\r
-    {\r
-        m_type->DeleteValue(m_buffer);\r
-        m_type = wxAnyValueTypeImpl<T>::sm_instance;\r
-        wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);\r
-    }\r
-\r
-    // Data\r
-    wxAnyValueType*     m_type;\r
-    wxAnyValueBuffer    m_buffer;\r
-};\r
-\r
-\r
-//\r
-// This method of checking the type is compatible with VC6\r
-#define wxANY_CHECK_TYPE(any, T) \\r
-    wxANY_VALUE_TYPE_CHECK_TYPE(any.GetType(), T)\r
-\r
-\r
-//\r
-// This method of getting the value is compatible with VC6\r
-#define wxANY_AS(any, T) \\r
-    any.As(static_cast<T*>(NULL))\r
-\r
-\r
-template<typename T>\r
-inline bool wxAnyValueType::CheckType(T* reserved)\r
-{\r
-    wxUnusedVar(reserved);\r
-    return wxAnyValueTypeImpl<T>::IsSameClass(this);\r
-}\r
-\r
-\r
-\r
-#endif // wxUSE_ANY\r
-\r
-#endif // _WX_ANY_H_\r
+/////////////////////////////////////////////////////////////////////////////
+// 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"
+
+
+// Size of the wxAny value buffer.
+enum
+{
+    WX_ANY_VALUE_BUFFER_SIZE = 16
+};
+
+union wxAnyValueBuffer
+{
+    void*   m_ptr;
+    wxByte  m_buffer[WX_ANY_VALUE_BUFFER_SIZE];
+};
+
+typedef void (*wxAnyClassInfo)();
+
+
+//
+// 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
+{
+public:
+    /**
+        Default constructor.
+    */
+    wxAnyValueType();
+
+    /**
+        Destructor.
+    */
+    virtual ~wxAnyValueType()
+    {
+    }
+
+    /**
+        This function is used for internal type matching.
+    */
+    virtual wxAnyClassInfo GetClassInfo() const = 0;
+
+    /**
+        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. src.m_ptr can
+        be expected to be NULL if value type of previously stored
+        data was different.
+    */
+    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)
+
+    //valueTypePtr->CheckType(static_cast<T*>(NULL))
+
+
+/**
+    Helper macro for defining user value types.
+
+    NB: We really cannot compare sm_classInfo directly in IsSameClass(),
+        but instead call sm_instance->GetClassInfo(). The former technique
+        broke at least on GCC 4.2 (but worked on VC8 shared build).
+*/
+#define WX_DECLARE_ANY_VALUE_TYPE(CLS) \
+    friend class wxAny; \
+public: \
+    static void sm_classInfo() {} \
+ \
+    virtual wxAnyClassInfo GetClassInfo() const \
+    { \
+        return sm_classInfo; \
+    } \
+    static bool IsSameClass(const wxAnyValueType* otherType) \
+    { \
+        return sm_instance->GetClassInfo() == otherType->GetClassInfo(); \
+    } \
+    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);
+        buf.m_ptr = NULL;  // This is important
+    }
+
+    virtual void CopyBuffer(const wxAnyValueBuffer& src,
+                            wxAnyValueBuffer& dst) const
+    {
+        Ops::DeleteValue(dst);
+        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)
+
+
+#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 WXDLLIMPEXP_BASE 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)
+    {
+        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);
+
+    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
+    wxAnyValueType*     m_type;
+    wxAnyValueBuffer    m_buffer;
+};
+
+
+//
+// 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_
index 9dc3442018d7f59e35c1b53f7849758baaa607e8..acbd9157a2adf983923f171ef0b036b3d8944762 100644 (file)
-/////////////////////////////////////////////////////////////////////////////\r
-// Name:        any.h\r
-// Purpose:     interface of wxAny\r
-// Author:      wxWidgets team\r
-// RCS-ID:      $Id$\r
-// Licence:     wxWindows license\r
-/////////////////////////////////////////////////////////////////////////////\r
-\r
-\r
-/**\r
-    @class wxAny\r
-\r
-    The wxAny class represents a container for any type. Its value\r
-    can be changed at run time, possibly to a different type of value.\r
-\r
-    wxAny is successor class for wxVariant, essentially doing the same thing\r
-    in a more modern, template-based manner and with transparent support\r
-    for any user data type.\r
-\r
-    Some pseudo-code'ish example of use with arbitrary user data:\r
-\r
-    @code\r
-    void SomeFunction()\r
-    {\r
-        MyClass myObject;\r
-        wxAny any = myObject;\r
-\r
-        // Do something\r
-        // ...\r
-\r
-        // Let's do a sanity check to make sure that any still holds\r
-        // data of correct type.\r
-        if ( any.CheckType<MyClass>() )\r
-        {\r
-            // Thank goodness, still a correct type.\r
-            MyClass myObject2 = any.As<MyClass>();\r
-        }\r
-        else\r
-        {\r
-            // Something has gone horribly wrong!\r
-            wxFAIL();\r
-        }\r
-    }\r
-    @endcode\r
-\r
-    When compared to wxVariant, there are various internal implementation\r
-    differences as well. For instance, wxAny only allocates separate data\r
-    object in heap for large (ie. size in bytes more than\r
-    WX_ANY_VALUE_BUFFER_SIZE) or 'non-movable' data types. Pointers, integers,\r
-    bools etc. are fitted in the wxAny's own buffer without need for any extra\r
-    allocation. Use following code to declare your own data type as 'movable':\r
-\r
-    @code\r
-    #include "wx/meta/movable.h"\r
-    WX_DECLARE_TYPE_MOVABLE(MyClass)\r
-    @endcode\r
-\r
-    However, you must be aware that 'movable' means such data that can be\r
-    copied with memcpy() without corrupting program integrity. For instance,\r
-    movable objects usually cannot contain pointers or references to other\r
-    data. wxRect, wxPoint, and wxSize are good examples of movable classes.\r
-\r
-    Note that pointers to any and all classes are already automatically\r
-    declared as movable data.\r
-\r
-    @library{wxbase}\r
-    @category{data}\r
-\r
-    @see wxAnyValueType, wxVariant\r
-*/\r
-class wxAny\r
-{\r
-public:\r
-    /**\r
-        Default constructor. It seeds the object with a null value.\r
-    */\r
-    wxAny();\r
-\r
-    /**\r
-        Constructs wxAny from data.\r
-    */\r
-    template<typename T>\r
-    wxAny(const T& value);\r
-\r
-    /**\r
-        Constructs wxAny from another wxAny.\r
-    */\r
-    wxAny(const wxAny& any);\r
-\r
-    /**\r
-        Destructor.\r
-    */\r
-    ~wxAny();\r
-\r
-    /**\r
-        This template function converts wxAny into given type. No dynamic\r
-        conversion is performed, so if the type is incorrect an assertion\r
-        failure will occur in debug builds, and a bogus value is returned\r
-        in release ones.\r
-\r
-        @remarks This template function may not work properly with Visual C++\r
-                6. For full compiler compatibility, please use\r
-                wxANY_AS(any, T) macro instead.\r
-    */\r
-    template<typename T>\r
-    T As() const;\r
-\r
-    /**\r
-        Use this template function for checking if this wxAny holds\r
-        a specific C++ data type.\r
-\r
-        @remarks This template function may not work properly with Visual C++\r
-                6. For full compiler compatibility, please use\r
-                wxANY_CHECK_TYPE(any, T) macro instead.\r
-\r
-        @see wxAnyValueType::CheckType()\r
-    */\r
-    template<typename T>\r
-    bool CheckType();\r
-\r
-    /**\r
-        Template function that retrieves and converts the value of this\r
-        wxAny to the type that T* value is.\r
-\r
-        @return Returns @true if conversion was succesfull.\r
-    */\r
-    template<typename T>\r
-    bool GetAs(T* value) const;\r
-\r
-    /**\r
-        Returns the value type as wxAnyValueType instance.\r
-\r
-        @remarks You cannot reliably test whether two wxAnys are of\r
-                same value type by simply comparing return values\r
-                of wxAny::GetType(). Instead use\r
-                wxAnyValueType::CheckType<T>() template function.\r
-    */\r
-    const wxAnyValueType* GetType() const;\r
-\r
-    /**\r
-        Tests if wxAny is null (that is, whether there is data).\r
-    */\r
-    bool IsNull() const;\r
-\r
-    /**\r
-        Makes wxAny null (that is, clears it).\r
-    */\r
-    void MakeNull();\r
-\r
-    //@{\r
-    /**\r
-        @name Assignment operators\r
-    */\r
-    template<typename T>\r
-    wxAny& operator=(const T &value);\r
-    wxAny& operator=(const wxAny &any);\r
-    //@}\r
-\r
-    //@{\r
-    /**\r
-        @name Equality operators\r
-\r
-        @remarks Generic template-based comparison operators have not been\r
-                provided for various code consistency reasons, so for custom\r
-                data types you have do something like this:\r
-\r
-                @code\r
-                if ( any.CheckType<MyClass*>() &&\r
-                     any.As<MyClass*>() == myObjectPtr )\r
-                {\r
-                    // Do something if any stores myObjectPtr\r
-                }\r
-                @endcode\r
-    */\r
-    bool operator==(signed char value) const;\r
-    bool operator==(signed short value) const;\r
-    bool operator==(signed int value) const;\r
-    bool operator==(signed long value) const;\r
-    bool operator==(wxLongLong_t value) const;\r
-    bool operator==(unsigned char value) const;\r
-    bool operator==(unsigned short value) const;\r
-    bool operator==(unsigned int value) const;\r
-    bool operator==(unsigned long value) const;\r
-    bool operator==(wxULongLong_t value) const;\r
-    bool operator==(float value) const;\r
-    bool operator==(double value) const;\r
-    bool operator==(bool value) const;\r
-    bool operator==(const char* value) const;\r
-    bool operator==(const wchar_t* value) const;\r
-    bool operator==(const wxString& value) const;\r
-    //@}\r
-\r
-    //@{\r
-    /**\r
-        @name Inequality operators\r
-    */\r
-    bool operator!=(signed char value) const;\r
-    bool operator!=(signed short value) const;\r
-    bool operator!=(signed int value) const;\r
-    bool operator!=(signed long value) const;\r
-    bool operator!=(wxLongLong_t value) const;\r
-    bool operator!=(unsigned char value) const;\r
-    bool operator!=(unsigned short value) const;\r
-    bool operator!=(unsigned int value) const;\r
-    bool operator!=(unsigned long value) const;\r
-    bool operator!=(wxULongLong_t value) const;\r
-    bool operator!=(float value) const;\r
-    bool operator!=(double value) const;\r
-    bool operator!=(bool value) const;\r
-    bool operator!=(const char* value) const;\r
-    bool operator!=(const wchar_t* value) const;\r
-    bool operator!=(const wxString& value) const;\r
-    //@}\r
-};\r
-\r
-/**\r
-    This is value getter macro that is more compatible with older\r
-    compilers, such as Visual C++ 6.0.\r
-*/\r
-#define wxANY_AS(any, T)\r
-\r
-\r
-/**\r
-    This is type checking macro that is more compatible with older\r
-    compilers, such as Visual C++ 6.0.\r
-*/\r
-#define wxANY_CHECK_TYPE(any, T)\r
-\r
-\r
-/**\r
-    Size of the wxAny value buffer.\r
-*/\r
-enum\r
-{\r
-    WX_ANY_VALUE_BUFFER_SIZE = 16\r
-};\r
-\r
-/**\r
-    Type for buffer within wxAny for holding data.\r
-*/\r
-union wxAnyValueBuffer\r
-{\r
-    void*   m_ptr;\r
-    wxByte  m_buffer[WX_ANY_VALUE_BUFFER_SIZE];\r
-};\r
-\r
-\r
-/**\r
-    @class wxAnyValueType\r
-\r
-    wxAnyValueType is base class for value type functionality for C++ data\r
-    types used with wxAny. Usually the default template will create a\r
-    satisfactory wxAnyValueType implementation for a data type, but\r
-    sometimes you may need to add some customization. To do this you will need\r
-    to add specialized template of wxAnyValueTypeImpl<>. Often your only\r
-    need may be to add dynamic type conversion which would be done like\r
-    this:\r
-\r
-    @code\r
-        template<>\r
-        class wxAnyValueTypeImpl<MyClass> :\r
-            public wxAnyValueTypeImplBase<MyClass>\r
-        {\r
-            WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)\r
-        public:\r
-            wxAnyValueTypeImpl() :\r
-                wxAnyValueTypeImplBase<MyClass>() { }\r
-            virtual ~wxAnyValueTypeImpl() { }\r
-\r
-            virtual bool ConvertValue(const wxAnyValueBuffer& src,\r
-                                      wxAnyValueType* dstType,\r
-                                      wxAnyValueBuffer& dst) const\r
-            {\r
-                // GetValue() is a static member function implemented\r
-                // in wxAnyValueTypeImplBase<>.\r
-                MyClass value = GetValue(src);\r
-\r
-                // TODO: Convert value from src buffer to destination\r
-                //       type and buffer. If cannot be done, return\r
-                //       false. This is a simple sample.\r
-                if ( dstType->CheckType<wxString>() )\r
-                {\r
-                    wxString s = value.ToString();\r
-                    wxAnyValueTypeImpl<wxString>::SetValue(s, dst);\r
-                }\r
-                else\r
-                {\r
-                    return false;\r
-                }\r
-            }\r
-        };\r
-\r
-        //\r
-        // Following must be placed somewhere in your source code\r
-        WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)\r
-    @endcode\r
-\r
-    wxAnyValueTypeImplBase<> template, from which we inherit in the above\r
-    example, contains the bulk of the default wxAnyValueTypeImpl<> template\r
-    implementation, and as such allows you to easily add some minor\r
-    customization.\r
-\r
-    If you need a have complete control over the type interpretation, you\r
-    will need to derive a class directly from wxAnyValueType, like this:\r
-\r
-    @code\r
-        template <>\r
-        class wxAnyValueTypeImpl<MyClass> : public wxAnyValueType\r
-        {\r
-            WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)\r
-        public:\r
-            virtual void DeleteValue(wxAnyValueBuffer& buf) const\r
-            {\r
-                // TODO: Free the data in buffer\r
-                // It is important to clear the buffer like this\r
-                // at the end of DeleteValue().\r
-                buf.m_ptr = NULL;\r
-            }\r
-\r
-            virtual void CopyBuffer(const wxAnyValueBuffer& src,\r
-                                    wxAnyValueBuffer& dst) const\r
-            {\r
-                // TODO: Copy value from one buffer to another.\r
-            }\r
-\r
-            virtual bool ConvertValue(const wxAnyValueBuffer& src,\r
-                                      wxAnyValueType* dstType,\r
-                                      wxAnyValueBuffer& dst) const\r
-            {\r
-                // TODO: Convert value from src buffer to destination\r
-                //       type and buffer.\r
-            }\r
-\r
-            //\r
-            // Following static functions must be implemented\r
-            //\r
-\r
-            static void SetValue(const T& value,\r
-                                 wxAnyValueBuffer& buf)\r
-            {\r
-                // TODO: Store value into buf.\r
-            }\r
-\r
-            static const T& GetValue(const wxAnyValueBuffer& buf)\r
-            {\r
-                // TODO: Return reference to value stored in buffer.\r
-            }\r
-        };\r
-\r
-        //\r
-        // Following must be placed somewhere in your source code\r
-        WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)\r
-\r
-    @endcode\r
-\r
-    @library{wxbase}\r
-    @category{data}\r
-\r
-    @see wxAny\r
-*/\r
-class wxAnyValueType\r
-{\r
-public:\r
-    /**\r
-        Default constructor.\r
-    */\r
-    wxAnyValueType();\r
-\r
-    /**\r
-        Destructor.\r
-    */\r
-    virtual ~wxAnyValueType();\r
-\r
-    /**\r
-        Use this template function for checking if wxAnyValueType represents\r
-        a specific C++ data type.\r
-\r
-        @remarks This template function does not work on some older compilers\r
-                (such as Visual C++ 6.0). For full compiler ccompatibility\r
-                please use wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) macro\r
-                instead.\r
-\r
-        @see wxAny::CheckType()\r
-    */\r
-    template <typename T>\r
-    bool CheckType();\r
-\r
-    /**\r
-        Convert value into buffer of different type. Return false if\r
-        not possible.\r
-    */\r
-    virtual bool ConvertValue(const wxAnyValueBuffer& src,\r
-                              wxAnyValueType* dstType,\r
-                              wxAnyValueBuffer& dst) const = 0;\r
-\r
-    /**\r
-        Implement this for buffer-to-buffer copy. src.m_ptr can\r
-        be expected to be NULL if value type of previously stored\r
-        data was different.\r
-    */\r
-    virtual void CopyBuffer(const wxAnyValueBuffer& src,\r
-                            wxAnyValueBuffer& dst) const = 0;\r
-\r
-    /**\r
-        This function is called every time the data in wxAny\r
-        buffer needs to be freed.\r
-    */\r
-    virtual void DeleteValue(wxAnyValueBuffer& buf) const = 0;\r
-\r
-    /**\r
-        This function is used for internal type matching.\r
-    */\r
-    virtual wxAnyClassInfo GetClassInfo() const = 0;\r
-\r
-    /**\r
-        This function is used for internal type matching.\r
-    */\r
-    virtual bool IsSameType(const wxAnyValueType* otherType) const = 0;\r
-};\r
-\r
-/**\r
-    This is type checking macro that is more compatible with older\r
-    compilers, such as Visual C++ 6.0.\r
-*/\r
-#define wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T)\r
+/////////////////////////////////////////////////////////////////////////////
+// Name:        any.h
+// Purpose:     interface of wxAny
+// Author:      wxWidgets team
+// RCS-ID:      $Id$
+// Licence:     wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+
+/**
+    @class wxAny
+
+    The wxAny class represents a container for any type. Its value
+    can be changed at run time, possibly to a different type of value.
+
+    wxAny is successor class for wxVariant, essentially doing the same thing
+    in a more modern, template-based manner and with transparent support
+    for any user data type.
+
+    Some pseudo-code'ish example of use with arbitrary user data:
+
+    @code
+    void SomeFunction()
+    {
+        MyClass myObject;
+        wxAny any = myObject;
+
+        // Do something
+        // ...
+
+        // Let's do a sanity check to make sure that any still holds
+        // data of correct type.
+        if ( any.CheckType<MyClass>() )
+        {
+            // Thank goodness, still a correct type.
+            MyClass myObject2 = any.As<MyClass>();
+        }
+        else
+        {
+            // Something has gone horribly wrong!
+            wxFAIL();
+        }
+    }
+    @endcode
+
+    When compared to wxVariant, there are various internal implementation
+    differences as well. For instance, wxAny only allocates separate data
+    object in heap for large (ie. size in bytes more than
+    WX_ANY_VALUE_BUFFER_SIZE) or 'non-movable' data types. Pointers, integers,
+    bools etc. are fitted in the wxAny's own buffer without need for any extra
+    allocation. Use following code to declare your own data type as 'movable':
+
+    @code
+    #include "wx/meta/movable.h"
+    WX_DECLARE_TYPE_MOVABLE(MyClass)
+    @endcode
+
+    However, you must be aware that 'movable' means such data that can be
+    copied with memcpy() without corrupting program integrity. For instance,
+    movable objects usually cannot contain pointers or references to other
+    data. wxRect, wxPoint, and wxSize are good examples of movable classes.
+
+    Note that pointers to any and all classes are already automatically
+    declared as movable data.
+
+    @library{wxbase}
+    @category{data}
+
+    @see wxAnyValueType, wxVariant
+*/
+class wxAny
+{
+public:
+    /**
+        Default constructor. It seeds the object with a null value.
+    */
+    wxAny();
+
+    /**
+        Constructs wxAny from data.
+    */
+    template<typename T>
+    wxAny(const T& value);
+
+    /**
+        Constructs wxAny from another wxAny.
+    */
+    wxAny(const wxAny& any);
+
+    /**
+        Destructor.
+    */
+    ~wxAny();
+
+    /**
+        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 may not work properly with Visual C++
+                6. For full compiler compatibility, please use
+                wxANY_AS(any, T) macro instead.
+    */
+    template<typename T>
+    T As() const;
+
+    /**
+        Use this template function for checking if this wxAny holds
+        a specific C++ data type.
+
+        @remarks This template function may not work properly with Visual C++
+                6. For full compiler compatibility, please use
+                wxANY_CHECK_TYPE(any, T) macro instead.
+
+        @see wxAnyValueType::CheckType()
+    */
+    template<typename T>
+    bool CheckType();
+
+    /**
+        Template function that retrieves and converts the value of this
+        wxAny to the type that T* value is.
+
+        @return Returns @true if conversion was succesfull.
+    */
+    template<typename T>
+    bool GetAs(T* value) const;
+
+    /**
+        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;
+
+    /**
+        Tests if wxAny is null (that is, whether there is data).
+    */
+    bool IsNull() const;
+
+    /**
+        Makes wxAny null (that is, clears it).
+    */
+    void MakeNull();
+
+    //@{
+    /**
+        @name Assignment operators
+    */
+    template<typename T>
+    wxAny& operator=(const T &value);
+    wxAny& operator=(const wxAny &any);
+    //@}
+
+    //@{
+    /**
+        @name Equality operators
+
+        @remarks Generic template-based comparison operators have not been
+                provided for various code consistency reasons, so for custom
+                data types you have do something like this:
+
+                @code
+                if ( any.CheckType<MyClass*>() &&
+                     any.As<MyClass*>() == myObjectPtr )
+                {
+                    // Do something if any stores myObjectPtr
+                }
+                @endcode
+    */
+    bool operator==(signed char value) const;
+    bool operator==(signed short value) const;
+    bool operator==(signed int value) const;
+    bool operator==(signed long value) const;
+    bool operator==(wxLongLong_t value) const;
+    bool operator==(unsigned char value) const;
+    bool operator==(unsigned short value) const;
+    bool operator==(unsigned int value) const;
+    bool operator==(unsigned long value) const;
+    bool operator==(wxULongLong_t value) const;
+    bool operator==(float value) const;
+    bool operator==(double value) const;
+    bool operator==(bool value) const;
+    bool operator==(const char* value) const;
+    bool operator==(const wchar_t* value) const;
+    bool operator==(const wxString& value) const;
+    //@}
+
+    //@{
+    /**
+        @name Inequality operators
+    */
+    bool operator!=(signed char value) const;
+    bool operator!=(signed short value) const;
+    bool operator!=(signed int value) const;
+    bool operator!=(signed long value) const;
+    bool operator!=(wxLongLong_t value) const;
+    bool operator!=(unsigned char value) const;
+    bool operator!=(unsigned short value) const;
+    bool operator!=(unsigned int value) const;
+    bool operator!=(unsigned long value) const;
+    bool operator!=(wxULongLong_t value) const;
+    bool operator!=(float value) const;
+    bool operator!=(double value) const;
+    bool operator!=(bool value) const;
+    bool operator!=(const char* value) const;
+    bool operator!=(const wchar_t* value) const;
+    bool operator!=(const wxString& value) const;
+    //@}
+};
+
+/**
+    This is value getter macro that is more compatible with older
+    compilers, such as Visual C++ 6.0.
+*/
+#define wxANY_AS(any, T)
+
+
+/**
+    This is type checking macro that is more compatible with older
+    compilers, such as Visual C++ 6.0.
+*/
+#define wxANY_CHECK_TYPE(any, T)
+
+
+/**
+    Size of the wxAny value buffer.
+*/
+enum
+{
+    WX_ANY_VALUE_BUFFER_SIZE = 16
+};
+
+/**
+    Type for buffer within wxAny for holding data.
+*/
+union wxAnyValueBuffer
+{
+    void*   m_ptr;
+    wxByte  m_buffer[WX_ANY_VALUE_BUFFER_SIZE];
+};
+
+
+/**
+    @class wxAnyValueType
+
+    wxAnyValueType is base class for value type functionality for C++ data
+    types used with wxAny. Usually the default template will create a
+    satisfactory wxAnyValueType implementation for a data type, but
+    sometimes you may need to add some customization. To do this you will need
+    to add specialized template of wxAnyValueTypeImpl<>. Often your only
+    need may be to add dynamic type conversion which would be done like
+    this:
+
+    @code
+        template<>
+        class wxAnyValueTypeImpl<MyClass> :
+            public wxAnyValueTypeImplBase<MyClass>
+        {
+            WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)
+        public:
+            wxAnyValueTypeImpl() :
+                wxAnyValueTypeImplBase<MyClass>() { }
+            virtual ~wxAnyValueTypeImpl() { }
+
+            virtual bool ConvertValue(const wxAnyValueBuffer& src,
+                                      wxAnyValueType* dstType,
+                                      wxAnyValueBuffer& dst) const
+            {
+                // GetValue() is a static member function implemented
+                // in wxAnyValueTypeImplBase<>.
+                MyClass value = GetValue(src);
+
+                // TODO: Convert value from src buffer to destination
+                //       type and buffer. If cannot be done, return
+                //       false. This is a simple sample.
+                if ( dstType->CheckType<wxString>() )
+                {
+                    wxString s = value.ToString();
+                    wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
+                }
+                else
+                {
+                    return false;
+                }
+            }
+        };
+
+        //
+        // Following must be placed somewhere in your source code
+        WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)
+    @endcode
+
+    wxAnyValueTypeImplBase<> template, from which we inherit in the above
+    example, contains the bulk of the default wxAnyValueTypeImpl<> template
+    implementation, and as such allows you to easily add some minor
+    customization.
+
+    If you need a have complete control over the type interpretation, you
+    will need to derive a class directly from wxAnyValueType, like this:
+
+    @code
+        template <>
+        class wxAnyValueTypeImpl<MyClass> : public wxAnyValueType
+        {
+            WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)
+        public:
+            virtual void DeleteValue(wxAnyValueBuffer& buf) const
+            {
+                // TODO: Free the data in buffer
+                // It is important to clear the buffer like this
+                // at the end of DeleteValue().
+                buf.m_ptr = NULL;
+            }
+
+            virtual void CopyBuffer(const wxAnyValueBuffer& src,
+                                    wxAnyValueBuffer& dst) const
+            {
+                // TODO: Copy value from one buffer to another.
+            }
+
+            virtual bool ConvertValue(const wxAnyValueBuffer& src,
+                                      wxAnyValueType* dstType,
+                                      wxAnyValueBuffer& dst) const
+            {
+                // TODO: Convert value from src buffer to destination
+                //       type and buffer.
+            }
+
+            //
+            // Following static functions must be implemented
+            //
+
+            static void SetValue(const T& value,
+                                 wxAnyValueBuffer& buf)
+            {
+                // TODO: Store value into buf.
+            }
+
+            static const T& GetValue(const wxAnyValueBuffer& buf)
+            {
+                // TODO: Return reference to value stored in buffer.
+            }
+        };
+
+        //
+        // Following must be placed somewhere in your source code
+        WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)
+
+    @endcode
+
+    @library{wxbase}
+    @category{data}
+
+    @see wxAny
+*/
+class wxAnyValueType
+{
+public:
+    /**
+        Default constructor.
+    */
+    wxAnyValueType();
+
+    /**
+        Destructor.
+    */
+    virtual ~wxAnyValueType();
+
+    /**
+        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()
+    */
+    template <typename T>
+    bool CheckType();
+
+    /**
+        Convert value into buffer of different type. Return false if
+        not possible.
+    */
+    virtual bool ConvertValue(const wxAnyValueBuffer& src,
+                              wxAnyValueType* dstType,
+                              wxAnyValueBuffer& dst) const = 0;
+
+    /**
+        Implement this for buffer-to-buffer copy. src.m_ptr can
+        be expected to be NULL if value type of previously stored
+        data was different.
+    */
+    virtual void CopyBuffer(const wxAnyValueBuffer& src,
+                            wxAnyValueBuffer& dst) const = 0;
+
+    /**
+        This function is called every time the data in wxAny
+        buffer needs to be freed.
+    */
+    virtual void DeleteValue(wxAnyValueBuffer& buf) const = 0;
+
+    /**
+        This function is used for internal type matching.
+    */
+    virtual wxAnyClassInfo GetClassInfo() const = 0;
+
+    /**
+        This function is used for internal type matching.
+    */
+    virtual bool IsSameType(const wxAnyValueType* otherType) const = 0;
+};
+
+/**
+    This is type checking macro that is more compatible with older
+    compilers, such as Visual C++ 6.0.
+*/
+#define wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T)
index 62f6b45d080fda6885a5ca80d2c938f3703f2aab..9923d3ef07cac0bde6e81588448828b78bff6fed 100644 (file)
-/////////////////////////////////////////////////////////////////////////////\r
-// Name:        src/common/any.cpp\r
-// Purpose:     wxAny class, container for any type\r
-// Author:      Jaakko Salli\r
-// Modified by:\r
-// Created:     07/05/2009\r
-// RCS-ID:      $Id$\r
-// Copyright:   (c) wxWidgets team\r
-// Licence:     wxWindows licence\r
-/////////////////////////////////////////////////////////////////////////////\r
-\r
-// For compilers that support precompilation, includes "wx/wx.h".\r
-#include "wx/wxprec.h"\r
-\r
-#ifdef __BORLANDC__\r
-    #pragma hdrstop\r
-#endif\r
-\r
-#include "wx/any.h"\r
-\r
-#if wxUSE_ANY\r
-\r
-#ifndef WX_PRECOMP\r
-    #include "wx/math.h"\r
-    #include "wx/crt.h"\r
-#endif\r
-\r
-#include "wx/vector.h"\r
-#include "wx/module.h"\r
-\r
-using namespace wxPrivate;\r
-\r
-//-------------------------------------------------------------------------\r
-// wxAnyValueTypeGlobals\r
-//-------------------------------------------------------------------------\r
-\r
-//\r
-// Helper class to manage wxAnyValueType instances and other\r
-// related global variables.\r
-//\r
-// NB: We really need to have wxAnyValueType instances allocated\r
-//     in heap. They are stored as static template member variables,\r
-//     and with them we just can't be too careful (eg. not allocating\r
-//     them in heap broke the type identification in GCC).\r
-//\r
-class wxAnyValueTypeGlobals\r
-{\r
-public:\r
-    wxAnyValueTypeGlobals()\r
-    {\r
-    }\r
-    ~wxAnyValueTypeGlobals()\r
-    {\r
-        for ( size_t i=0; i<m_valueTypes.size(); i++ )\r
-            delete m_valueTypes[i];\r
-    }\r
-\r
-    void RegisterValueType(wxAnyValueType* valueType)\r
-    {\r
-        m_valueTypes.push_back(valueType);\r
-    }\r
-\r
-private:\r
-    wxVector<wxAnyValueType*>   m_valueTypes;\r
-};\r
-\r
-static wxAnyValueTypeGlobals* g_wxAnyValueTypeGlobals = NULL;\r
-\r
-//\r
-// This class is to make sure that wxAnyValueType instances\r
-// etc. get freed correctly. We must use a separate wxAnyValueTypeGlobals\r
-// because wxModule itself is instantiated too late.\r
-//\r
-class wxAnyValueTypeGlobalsManager : public wxModule\r
-{\r
-    DECLARE_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager)\r
-public:\r
-    wxAnyValueTypeGlobalsManager() : wxModule() { }\r
-    virtual ~wxAnyValueTypeGlobalsManager() { }\r
-\r
-    virtual bool OnInit()\r
-    {\r
-        return true;\r
-    }\r
-    virtual void OnExit()\r
-    {\r
-        delete g_wxAnyValueTypeGlobals;\r
-        g_wxAnyValueTypeGlobals = NULL;\r
-    }\r
-private:\r
-};\r
-\r
-IMPLEMENT_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager, wxModule)\r
-\r
-\r
-//-------------------------------------------------------------------------\r
-// wxAnyValueType\r
-//-------------------------------------------------------------------------\r
-\r
-wxAnyValueType::wxAnyValueType()\r
-{\r
-    if ( !g_wxAnyValueTypeGlobals )\r
-        g_wxAnyValueTypeGlobals = new wxAnyValueTypeGlobals();\r
-\r
-    g_wxAnyValueTypeGlobals->RegisterValueType(this);\r
-}\r
-\r
-//-------------------------------------------------------------------------\r
-// wxAny\r
-//-------------------------------------------------------------------------\r
-\r
-void wxAny::AssignAny(const wxAny &any)\r
-{\r
-    if ( !any.m_type->IsSameType(m_type) )\r
-    {\r
-        m_type->DeleteValue(m_buffer);\r
-        m_type = any.m_type;\r
-    }\r
-    m_type->CopyBuffer(any.m_buffer, m_buffer);\r
-}\r
-\r
-//-------------------------------------------------------------------------\r
-// Dynamic conversion member functions\r
-//-------------------------------------------------------------------------\r
-\r
-//\r
-// Define integer minimum and maximum as helpers\r
-#ifdef wxLongLong_t\r
-const wxAnyBaseIntType UseIntMin = wxINT64_MIN;\r
-const wxAnyBaseUintType UseIntMax = wxINT64_MAX;\r
-const wxAnyBaseUintType UseUintMax = wxUINT64_MAX;\r
-#else\r
-const wxAnyBaseIntType UseIntMin = LONG_MIN;\r
-const wxAnyBaseUintType UseUintMax = ULONG_MAX;\r
-const wxAnyBaseUintType UseIntMax = LONG_MAX;\r
-#endif\r
-\r
-const double UseIntMinF = static_cast<double>(UseIntMin);\r
-#ifndef __VISUALC6__\r
-const double UseIntMaxF = static_cast<double>(UseIntMax);\r
-const double UseUintMaxF = static_cast<double>(UseUintMax);\r
-#else\r
-// VC6 doesn't implement conversion from unsigned __int64 to double\r
-const wxAnyBaseIntType UseIntMax0 = static_cast<wxAnyBaseIntType>(UseIntMax);\r
-const wxAnyBaseIntType UseUintMax0 = static_cast<wxAnyBaseIntType>(UseUintMax);\r
-const double UseIntMaxF = static_cast<double>(UseIntMax0);\r
-const double UseUintMaxF = static_cast<double>(UseUintMax0);\r
-#endif\r
-\r
-\r
-bool wxAnyValueTypeImplInt::ConvertValue(const wxAnyValueBuffer& src,\r
-                                         wxAnyValueType* dstType,\r
-                                         wxAnyValueBuffer& dst) const\r
-{\r
-    wxAnyBaseIntType value = GetValue(src);\r
-    if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )\r
-    {\r
-#ifdef wxLongLong_t\r
-        wxLongLong ll(value);\r
-        wxString s = ll.ToString();\r
-#else\r
-        wxString s = wxString::Format(wxS("%ld"), (long)value);\r
-#endif\r
-        wxAnyValueTypeImpl<wxString>::SetValue(s, dst);\r
-    }\r
-    else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )\r
-    {\r
-        if ( value < 0 )\r
-            return false;\r
-        wxAnyBaseUintType ul = (wxAnyBaseUintType) value;\r
-        wxAnyValueTypeImplUint::SetValue(ul, dst);\r
-    }\r
-    else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) )\r
-    {\r
-        double value2 = static_cast<double>(value);\r
-        wxAnyValueTypeImplDouble::SetValue(value2, dst);\r
-    }\r
-    else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) )\r
-    {\r
-        bool value2 = value ? true : false;\r
-        wxAnyValueTypeImpl<bool>::SetValue(value2, dst);\r
-    }\r
-    else\r
-        return false;\r
-\r
-    return true;\r
-}\r
-\r
-bool wxAnyValueTypeImplUint::ConvertValue(const wxAnyValueBuffer& src,\r
-                                          wxAnyValueType* dstType,\r
-                                          wxAnyValueBuffer& dst) const\r
-{\r
-    wxAnyBaseUintType value = GetValue(src);\r
-    if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )\r
-    {\r
-#ifdef wxLongLong_t\r
-        wxULongLong ull(value);\r
-        wxString s = ull.ToString();\r
-#else\r
-        wxString s = wxString::Format(wxS("%lu"), (long)value);\r
-#endif\r
-        wxAnyValueTypeImpl<wxString>::SetValue(s, dst);\r
-    }\r
-    else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )\r
-    {\r
-        if ( value > UseIntMax )\r
-            return false;\r
-        wxAnyBaseIntType l = (wxAnyBaseIntType) value;\r
-        wxAnyValueTypeImplInt::SetValue(l, dst);\r
-    }\r
-    else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) )\r
-    {\r
-#ifndef __VISUALC6__\r
-        double value2 = static_cast<double>(value);\r
-#else\r
-        // VC6 doesn't implement conversion from unsigned __int64 to double\r
-        wxAnyBaseIntType value0 = static_cast<wxAnyBaseIntType>(value);\r
-        double value2 = static_cast<double>(value0);\r
-#endif\r
-        wxAnyValueTypeImplDouble::SetValue(value2, dst);\r
-    }\r
-    else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) )\r
-    {\r
-        bool value2 = value ? true : false;\r
-        wxAnyValueTypeImpl<bool>::SetValue(value2, dst);\r
-    }\r
-    else\r
-        return false;\r
-\r
-    return true;\r
-}\r
-\r
-bool wxAnyValueTypeImplString::ConvertValue(const wxAnyValueBuffer& src,\r
-                                            wxAnyValueType* dstType,\r
-                                            wxAnyValueBuffer& dst) const\r
-{\r
-    wxString value = GetValue(src);\r
-    if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )\r
-    {\r
-        wxAnyBaseIntType value2;\r
-#ifdef wxLongLong_t\r
-        if ( !value.ToLongLong(&value2) )\r
-#else\r
-        if ( !value.ToLong(&value2) )\r
-#endif\r
-            return false;\r
-        wxAnyValueTypeImplInt::SetValue(value2, dst);\r
-    }\r
-    else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )\r
-    {\r
-        wxAnyBaseUintType value2;\r
-#ifdef wxLongLong_t\r
-        if ( !value.ToULongLong(&value2) )\r
-#else\r
-        if ( !value.ToULong(&value2) )\r
-#endif\r
-            return false;\r
-        wxAnyValueTypeImplUint::SetValue(value2, dst);\r
-    }\r
-    else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) )\r
-    {\r
-        double value2;\r
-        if ( !value.ToDouble(&value2) )\r
-            return false;\r
-        wxAnyValueTypeImplDouble::SetValue(value2, dst);\r
-    }\r
-    else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) )\r
-    {\r
-        bool value2;\r
-        value.MakeLower();\r
-        if ( value == wxS("true") ||\r
-             value == wxS("yes") ||\r
-             value == wxS('1') )\r
-            value2 = true;\r
-        else if ( value == wxS("false") ||\r
-                  value == wxS("no") ||\r
-                  value == wxS('0') )\r
-            value2 = false;\r
-        else\r
-            return false;\r
-\r
-        wxAnyValueTypeImpl<bool>::SetValue(value2, dst);\r
-    }\r
-    else\r
-        return false;\r
-\r
-    return true;\r
-}\r
-\r
-bool wxAnyValueTypeImpl<bool>::ConvertValue(const wxAnyValueBuffer& src,\r
-                                            wxAnyValueType* dstType,\r
-                                            wxAnyValueBuffer& dst) const\r
-{\r
-    bool value = GetValue(src);\r
-    if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )\r
-    {\r
-        wxAnyBaseIntType value2 = static_cast<wxAnyBaseIntType>(value);\r
-        wxAnyValueTypeImplInt::SetValue(value2, dst);\r
-    }\r
-    else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )\r
-    {\r
-        wxAnyBaseIntType value2 = static_cast<wxAnyBaseUintType>(value);\r
-        wxAnyValueTypeImplUint::SetValue(value2, dst);\r
-    }\r
-    else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )\r
-    {\r
-        wxString s;\r
-        if ( value )\r
-            s = wxS("true");\r
-        else\r
-            s = wxS("false");\r
-        wxAnyValueTypeImpl<wxString>::SetValue(s, dst);\r
-    }\r
-    else\r
-        return false;\r
-\r
-    return true;\r
-}\r
-\r
-bool wxAnyValueTypeImplDouble::ConvertValue(const wxAnyValueBuffer& src,\r
-                                            wxAnyValueType* dstType,\r
-                                            wxAnyValueBuffer& dst) const\r
-{\r
-    double value = GetValue(src);\r
-    if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )\r
-    {\r
-        if ( value < UseIntMinF || value > UseIntMaxF )\r
-            return false;\r
-        wxAnyBaseUintType ul = static_cast<wxAnyBaseUintType>(value);\r
-        wxAnyValueTypeImplUint::SetValue(ul, dst);\r
-    }\r
-    else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )\r
-    {\r
-        if ( value < 0.0 || value > UseUintMaxF )\r
-            return false;\r
-        wxAnyBaseUintType ul = static_cast<wxAnyBaseUintType>(value);\r
-        wxAnyValueTypeImplUint::SetValue(ul, dst);\r
-    }\r
-    else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )\r
-    {\r
-        wxString s = wxString::Format(wxS("%.14g"), value);\r
-        wxAnyValueTypeImpl<wxString>::SetValue(s, dst);\r
-    }\r
-    else\r
-        return false;\r
-\r
-    return true;\r
-}\r
-\r
-WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplInt)\r
-WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplUint)\r
-WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplString)\r
-WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<bool>)\r
-WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble)\r
-\r
-//-------------------------------------------------------------------------\r
-// wxAnyNullValueType implementation\r
-//-------------------------------------------------------------------------\r
-\r
-class wxAnyNullValue\r
-{\r
-private:\r
-    void*   m_dummy;\r
-};\r
-\r
-template <>\r
-class wxAnyValueTypeImpl<wxAnyNullValue> : public wxAnyValueType\r
-{\r
-    WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxAnyNullValue>)\r
-public:\r
-    virtual void DeleteValue(wxAnyValueBuffer& buf) const\r
-    {\r
-        buf.m_ptr = NULL;  // This is important\r
-    }\r
-\r
-    // Dummy implementations\r
-    virtual void CopyBuffer(const wxAnyValueBuffer& src,\r
-                            wxAnyValueBuffer& dst) const\r
-    {\r
-        wxUnusedVar(src);\r
-        wxUnusedVar(dst);\r
-    }\r
-\r
-    virtual bool ConvertValue(const wxAnyValueBuffer& src,\r
-                              wxAnyValueType* dstType,\r
-                              wxAnyValueBuffer& dst) const\r
-    {\r
-        wxUnusedVar(src);\r
-        wxUnusedVar(dstType);\r
-        wxUnusedVar(dst);\r
-        return false;\r
-    }\r
-\r
-private:\r
-};\r
-\r
-WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxAnyNullValue>)\r
-\r
-wxAnyValueType* wxAnyNullValueType =\r
-    wxAnyValueTypeImpl<wxAnyNullValue>::GetInstance();\r
-\r
-#endif // wxUSE_ANY\r
+/////////////////////////////////////////////////////////////////////////////
+// Name:        src/common/any.cpp
+// Purpose:     wxAny class, container for any type
+// Author:      Jaakko Salli
+// Modified by:
+// Created:     07/05/2009
+// RCS-ID:      $Id$
+// Copyright:   (c) wxWidgets team
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+// For compilers that support precompilation, includes "wx/wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/any.h"
+
+#if wxUSE_ANY
+
+#ifndef WX_PRECOMP
+    #include "wx/math.h"
+    #include "wx/crt.h"
+#endif
+
+#include "wx/vector.h"
+#include "wx/module.h"
+
+using namespace wxPrivate;
+
+//-------------------------------------------------------------------------
+// wxAnyValueTypeGlobals
+//-------------------------------------------------------------------------
+
+//
+// Helper class to manage wxAnyValueType instances and other
+// related global variables.
+//
+// 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).
+//
+class wxAnyValueTypeGlobals
+{
+public:
+    wxAnyValueTypeGlobals()
+    {
+    }
+    ~wxAnyValueTypeGlobals()
+    {
+        for ( size_t i=0; i<m_valueTypes.size(); i++ )
+            delete m_valueTypes[i];
+    }
+
+    void RegisterValueType(wxAnyValueType* valueType)
+    {
+        m_valueTypes.push_back(valueType);
+    }
+
+private:
+    wxVector<wxAnyValueType*>   m_valueTypes;
+};
+
+static wxAnyValueTypeGlobals* g_wxAnyValueTypeGlobals = NULL;
+
+//
+// This class is to make sure that wxAnyValueType instances
+// etc. get freed correctly. We must use a separate wxAnyValueTypeGlobals
+// because wxModule itself is instantiated too late.
+//
+class wxAnyValueTypeGlobalsManager : public wxModule
+{
+    DECLARE_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager)
+public:
+    wxAnyValueTypeGlobalsManager() : wxModule() { }
+    virtual ~wxAnyValueTypeGlobalsManager() { }
+
+    virtual bool OnInit()
+    {
+        return true;
+    }
+    virtual void OnExit()
+    {
+        delete g_wxAnyValueTypeGlobals;
+        g_wxAnyValueTypeGlobals = NULL;
+    }
+private:
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager, wxModule)
+
+
+//-------------------------------------------------------------------------
+// wxAnyValueType
+//-------------------------------------------------------------------------
+
+wxAnyValueType::wxAnyValueType()
+{
+    if ( !g_wxAnyValueTypeGlobals )
+        g_wxAnyValueTypeGlobals = new wxAnyValueTypeGlobals();
+
+    g_wxAnyValueTypeGlobals->RegisterValueType(this);
+}
+
+//-------------------------------------------------------------------------
+// wxAny
+//-------------------------------------------------------------------------
+
+void wxAny::AssignAny(const wxAny &any)
+{
+    if ( !any.m_type->IsSameType(m_type) )
+    {
+        m_type->DeleteValue(m_buffer);
+        m_type = any.m_type;
+    }
+    m_type->CopyBuffer(any.m_buffer, m_buffer);
+}
+
+//-------------------------------------------------------------------------
+// Dynamic conversion member functions
+//-------------------------------------------------------------------------
+
+//
+// Define integer minimum and maximum as helpers
+#ifdef wxLongLong_t
+const wxAnyBaseIntType UseIntMin = wxINT64_MIN;
+const wxAnyBaseUintType UseIntMax = wxINT64_MAX;
+const wxAnyBaseUintType UseUintMax = wxUINT64_MAX;
+#else
+const wxAnyBaseIntType UseIntMin = LONG_MIN;
+const wxAnyBaseUintType UseUintMax = ULONG_MAX;
+const wxAnyBaseUintType UseIntMax = LONG_MAX;
+#endif
+
+const double UseIntMinF = static_cast<double>(UseIntMin);
+#ifndef __VISUALC6__
+const double UseIntMaxF = static_cast<double>(UseIntMax);
+const double UseUintMaxF = static_cast<double>(UseUintMax);
+#else
+// VC6 doesn't implement conversion from unsigned __int64 to double
+const wxAnyBaseIntType UseIntMax0 = static_cast<wxAnyBaseIntType>(UseIntMax);
+const wxAnyBaseIntType UseUintMax0 = static_cast<wxAnyBaseIntType>(UseUintMax);
+const double UseIntMaxF = static_cast<double>(UseIntMax0);
+const double UseUintMaxF = static_cast<double>(UseUintMax0);
+#endif
+
+
+bool wxAnyValueTypeImplInt::ConvertValue(const wxAnyValueBuffer& src,
+                                         wxAnyValueType* dstType,
+                                         wxAnyValueBuffer& dst) const
+{
+    wxAnyBaseIntType value = GetValue(src);
+    if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
+    {
+#ifdef wxLongLong_t
+        wxLongLong ll(value);
+        wxString s = ll.ToString();
+#else
+        wxString s = wxString::Format(wxS("%ld"), (long)value);
+#endif
+        wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
+    }
+    else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )
+    {
+        if ( value < 0 )
+            return false;
+        wxAnyBaseUintType ul = (wxAnyBaseUintType) value;
+        wxAnyValueTypeImplUint::SetValue(ul, dst);
+    }
+    else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) )
+    {
+        double value2 = static_cast<double>(value);
+        wxAnyValueTypeImplDouble::SetValue(value2, dst);
+    }
+    else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) )
+    {
+        bool value2 = value ? true : false;
+        wxAnyValueTypeImpl<bool>::SetValue(value2, dst);
+    }
+    else
+        return false;
+
+    return true;
+}
+
+bool wxAnyValueTypeImplUint::ConvertValue(const wxAnyValueBuffer& src,
+                                          wxAnyValueType* dstType,
+                                          wxAnyValueBuffer& dst) const
+{
+    wxAnyBaseUintType value = GetValue(src);
+    if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
+    {
+#ifdef wxLongLong_t
+        wxULongLong ull(value);
+        wxString s = ull.ToString();
+#else
+        wxString s = wxString::Format(wxS("%lu"), (long)value);
+#endif
+        wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
+    }
+    else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )
+    {
+        if ( value > UseIntMax )
+            return false;
+        wxAnyBaseIntType l = (wxAnyBaseIntType) value;
+        wxAnyValueTypeImplInt::SetValue(l, dst);
+    }
+    else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) )
+    {
+#ifndef __VISUALC6__
+        double value2 = static_cast<double>(value);
+#else
+        // VC6 doesn't implement conversion from unsigned __int64 to double
+        wxAnyBaseIntType value0 = static_cast<wxAnyBaseIntType>(value);
+        double value2 = static_cast<double>(value0);
+#endif
+        wxAnyValueTypeImplDouble::SetValue(value2, dst);
+    }
+    else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) )
+    {
+        bool value2 = value ? true : false;
+        wxAnyValueTypeImpl<bool>::SetValue(value2, dst);
+    }
+    else
+        return false;
+
+    return true;
+}
+
+bool wxAnyValueTypeImplString::ConvertValue(const wxAnyValueBuffer& src,
+                                            wxAnyValueType* dstType,
+                                            wxAnyValueBuffer& dst) const
+{
+    wxString value = GetValue(src);
+    if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )
+    {
+        wxAnyBaseIntType value2;
+#ifdef wxLongLong_t
+        if ( !value.ToLongLong(&value2) )
+#else
+        if ( !value.ToLong(&value2) )
+#endif
+            return false;
+        wxAnyValueTypeImplInt::SetValue(value2, dst);
+    }
+    else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )
+    {
+        wxAnyBaseUintType value2;
+#ifdef wxLongLong_t
+        if ( !value.ToULongLong(&value2) )
+#else
+        if ( !value.ToULong(&value2) )
+#endif
+            return false;
+        wxAnyValueTypeImplUint::SetValue(value2, dst);
+    }
+    else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) )
+    {
+        double value2;
+        if ( !value.ToDouble(&value2) )
+            return false;
+        wxAnyValueTypeImplDouble::SetValue(value2, dst);
+    }
+    else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) )
+    {
+        bool value2;
+        value.MakeLower();
+        if ( value == wxS("true") ||
+             value == wxS("yes") ||
+             value == wxS('1') )
+            value2 = true;
+        else if ( value == wxS("false") ||
+                  value == wxS("no") ||
+                  value == wxS('0') )
+            value2 = false;
+        else
+            return false;
+
+        wxAnyValueTypeImpl<bool>::SetValue(value2, dst);
+    }
+    else
+        return false;
+
+    return true;
+}
+
+bool wxAnyValueTypeImpl<bool>::ConvertValue(const wxAnyValueBuffer& src,
+                                            wxAnyValueType* dstType,
+                                            wxAnyValueBuffer& dst) const
+{
+    bool value = GetValue(src);
+    if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )
+    {
+        wxAnyBaseIntType value2 = static_cast<wxAnyBaseIntType>(value);
+        wxAnyValueTypeImplInt::SetValue(value2, dst);
+    }
+    else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )
+    {
+        wxAnyBaseIntType value2 = static_cast<wxAnyBaseUintType>(value);
+        wxAnyValueTypeImplUint::SetValue(value2, dst);
+    }
+    else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
+    {
+        wxString s;
+        if ( value )
+            s = wxS("true");
+        else
+            s = wxS("false");
+        wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
+    }
+    else
+        return false;
+
+    return true;
+}
+
+bool wxAnyValueTypeImplDouble::ConvertValue(const wxAnyValueBuffer& src,
+                                            wxAnyValueType* dstType,
+                                            wxAnyValueBuffer& dst) const
+{
+    double value = GetValue(src);
+    if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )
+    {
+        if ( value < UseIntMinF || value > UseIntMaxF )
+            return false;
+        wxAnyBaseUintType ul = static_cast<wxAnyBaseUintType>(value);
+        wxAnyValueTypeImplUint::SetValue(ul, dst);
+    }
+    else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )
+    {
+        if ( value < 0.0 || value > UseUintMaxF )
+            return false;
+        wxAnyBaseUintType ul = static_cast<wxAnyBaseUintType>(value);
+        wxAnyValueTypeImplUint::SetValue(ul, dst);
+    }
+    else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
+    {
+        wxString s = wxString::Format(wxS("%.14g"), value);
+        wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
+    }
+    else
+        return false;
+
+    return true;
+}
+
+WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplInt)
+WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplUint)
+WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplString)
+WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<bool>)
+WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble)
+
+//-------------------------------------------------------------------------
+// wxAnyNullValueType implementation
+//-------------------------------------------------------------------------
+
+class wxAnyNullValue
+{
+private:
+    void*   m_dummy;
+};
+
+template <>
+class wxAnyValueTypeImpl<wxAnyNullValue> : public wxAnyValueType
+{
+    WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxAnyNullValue>)
+public:
+    virtual void DeleteValue(wxAnyValueBuffer& buf) const
+    {
+        buf.m_ptr = NULL;  // This is important
+    }
+
+    // Dummy implementations
+    virtual void CopyBuffer(const wxAnyValueBuffer& src,
+                            wxAnyValueBuffer& dst) const
+    {
+        wxUnusedVar(src);
+        wxUnusedVar(dst);
+    }
+
+    virtual bool ConvertValue(const wxAnyValueBuffer& src,
+                              wxAnyValueType* dstType,
+                              wxAnyValueBuffer& dst) const
+    {
+        wxUnusedVar(src);
+        wxUnusedVar(dstType);
+        wxUnusedVar(dst);
+        return false;
+    }
+
+private:
+};
+
+WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxAnyNullValue>)
+
+wxAnyValueType* wxAnyNullValueType =
+    wxAnyValueTypeImpl<wxAnyNullValue>::GetInstance();
+
+#endif // wxUSE_ANY
index 5e6252b49ed86e1e0ecfc1bdc2978aaf27c87108..74a9d9cd05624fe71f2bfc970d313ddc972600d1 100644 (file)
-///////////////////////////////////////////////////////////////////////////////\r
-// Name:        tests/any/anytest.cpp\r
-// Purpose:     Test the wxAny classes\r
-// Author:      Jaakko Salli\r
-// RCS-ID:      $Id$\r
-// Copyright:   (c) the wxWidgets team\r
-// Licence:     wxWindows licence\r
-///////////////////////////////////////////////////////////////////////////////\r
-\r
-#include "testprec.h"\r
-\r
-#ifdef __BORLANDC__\r
-#   pragma hdrstop\r
-#endif\r
-\r
-#if wxUSE_ANY\r
-\r
-#include "wx/any.h"\r
-#include "wx/datetime.h"\r
-\r
-#include <math.h>\r
-\r
-// ----------------------------------------------------------------------------\r
-// test class\r
-// ----------------------------------------------------------------------------\r
-\r
-class wxAnyTestCase : public CppUnit::TestCase\r
-{\r
-public:\r
-    wxAnyTestCase();\r
-\r
-private:\r
-    CPPUNIT_TEST_SUITE( wxAnyTestCase );\r
-        CPPUNIT_TEST( Equality );\r
-        CPPUNIT_TEST( As );\r
-        CPPUNIT_TEST( GetAs );\r
-        CPPUNIT_TEST( Null );\r
-        CPPUNIT_TEST( CustomTemplateSpecialization );\r
-    CPPUNIT_TEST_SUITE_END();\r
-\r
-    void Equality();\r
-    void As();\r
-    void GetAs();\r
-    void Null();\r
-    void CustomTemplateSpecialization();\r
-\r
-    wxDateTime m_testDateTime;\r
-\r
-    wxAny   m_anySignedChar1;\r
-    wxAny   m_anySignedShort1;\r
-    wxAny   m_anySignedInt1;\r
-    wxAny   m_anySignedLong1;\r
-    wxAny   m_anySignedLongLong1;\r
-    wxAny   m_anyUnsignedChar1;\r
-    wxAny   m_anyUnsignedShort1;\r
-    wxAny   m_anyUnsignedInt1;\r
-    wxAny   m_anyUnsignedLong1;\r
-    wxAny   m_anyUnsignedLongLong1;\r
-    wxAny   m_anyStringString1;\r
-    wxAny   m_anyCharString1;\r
-    wxAny   m_anyWcharString1;\r
-    wxAny   m_anyBool1;\r
-    wxAny   m_anyFloatDouble1;\r
-    wxAny   m_anyDoubleDouble1;\r
-    wxAny   m_anyWxObjectPtr1;\r
-    wxAny   m_anyVoidPtr1;\r
-    wxAny   m_anyDateTime1;\r
-\r
-    wxAny   m_anySignedChar2;\r
-    wxAny   m_anySignedShort2;\r
-    wxAny   m_anySignedInt2;\r
-    wxAny   m_anySignedLong2;\r
-    wxAny   m_anySignedLongLong2;\r
-    wxAny   m_anyUnsignedChar2;\r
-    wxAny   m_anyUnsignedShort2;\r
-    wxAny   m_anyUnsignedInt2;\r
-    wxAny   m_anyUnsignedLong2;\r
-    wxAny   m_anyUnsignedLongLong2;\r
-    wxAny   m_anyStringString2;\r
-    wxAny   m_anyCharString2;\r
-    wxAny   m_anyWcharString2;\r
-    wxAny   m_anyBool2;\r
-    wxAny   m_anyFloatDouble2;\r
-    wxAny   m_anyDoubleDouble2;\r
-    wxAny   m_anyWxObjectPtr2;\r
-    wxAny   m_anyVoidPtr2;\r
-    wxAny   m_anyDateTime2;\r
-\r
-    DECLARE_NO_COPY_CLASS(wxAnyTestCase)\r
-};\r
-\r
-// register in the unnamed registry so that these tests are run by default\r
-CPPUNIT_TEST_SUITE_REGISTRATION( wxAnyTestCase );\r
-\r
-// also include in it's own registry so that these tests can be run alone\r
-CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( wxAnyTestCase, "wxAnyTestCase" );\r
-\r
-// Let's use a number with first digit after decimal dot less than 5,\r
-// so that we don't have to worry about whether conversion from float\r
-// to int truncates or rounds.\r
-const double TEST_FLOAT_CONST = 123.456;\r
-\r
-const double FEQ_DELTA = 0.001;\r
-\r
-wxObject* dummyWxObjectPointer = reinterpret_cast<wxObject*>(1234);\r
-void* dummyVoidPointer = reinterpret_cast<void*>(1234);\r
-\r
-\r
-//\r
-// Test both 'creation' methods\r
-wxAnyTestCase::wxAnyTestCase()\r
-    : m_anySignedChar1((signed char)15),\r
-      m_anySignedShort1((signed short)15),\r
-      m_anySignedInt1((signed int)15),\r
-      m_anySignedLong1((signed long)15),\r
-#ifdef wxLongLong_t\r
-      m_anySignedLongLong1((wxLongLong_t)15),\r
-#endif\r
-      m_anyUnsignedChar1((unsigned char)15),\r
-      m_anyUnsignedShort1((unsigned short)15),\r
-      m_anyUnsignedInt1((unsigned int)15),\r
-      m_anyUnsignedLong1((unsigned long)15),\r
-#ifdef wxLongLong_t\r
-      m_anyUnsignedLongLong1((wxULongLong_t)15),\r
-#endif\r
-      m_anyStringString1(wxString("abc")),\r
-      m_anyCharString1("abc"),\r
-      m_anyWcharString1(L"abc"),\r
-      m_anyBool1(true),\r
-      m_anyFloatDouble1((float)TEST_FLOAT_CONST),\r
-      m_anyDoubleDouble1((double)TEST_FLOAT_CONST),\r
-      m_anyWxObjectPtr1(dummyWxObjectPointer),\r
-      m_anyVoidPtr1(dummyVoidPointer),\r
-      m_anyDateTime1(wxDateTime::Now())\r
-{\r
-    m_testDateTime = wxDateTime::Now();\r
-    m_anySignedChar2 = (signed char)15;\r
-    m_anySignedShort2 = (signed short)15;\r
-    m_anySignedInt2 = (signed int)15;\r
-    m_anySignedLong2 = (signed long)15;\r
-#ifdef wxLongLong_t\r
-    m_anySignedLongLong2 = (wxLongLong_t)15;\r
-#endif\r
-    m_anyUnsignedChar2 = (unsigned char)15;\r
-    m_anyUnsignedShort2 = (unsigned short)15;\r
-    m_anyUnsignedInt2 = (unsigned int)15;\r
-    m_anyUnsignedLong2 = (unsigned long)15;\r
-#ifdef wxLongLong_t\r
-    m_anyUnsignedLongLong2 = (wxULongLong_t)15;\r
-#endif\r
-    m_anyStringString2 = wxString("abc");\r
-    m_anyCharString2 = "abc";\r
-    m_anyWcharString2 = L"abc";\r
-    m_anyBool2 = true;\r
-    m_anyFloatDouble2 = (float)TEST_FLOAT_CONST;\r
-    m_anyDoubleDouble2 = (double)TEST_FLOAT_CONST;\r
-    m_anyDateTime2 = m_testDateTime;\r
-    m_anyWxObjectPtr2 = dummyWxObjectPointer;\r
-    m_anyVoidPtr2 = dummyVoidPointer;\r
-}\r
-\r
-void wxAnyTestCase::Equality()\r
-{\r
-    //\r
-    // Currently this should work\r
-    CPPUNIT_ASSERT(m_anyUnsignedLong1 == 15L);\r
-    CPPUNIT_ASSERT(m_anyUnsignedLong1 != 30L);\r
-    CPPUNIT_ASSERT(m_anyUnsignedLong1 == 15UL);\r
-    CPPUNIT_ASSERT(m_anyUnsignedLong1 != 30UL);\r
-    CPPUNIT_ASSERT(m_anyStringString1 == wxString("abc"));\r
-    CPPUNIT_ASSERT(m_anyStringString1 != wxString("ABC"));\r
-    CPPUNIT_ASSERT(m_anyStringString1 == "abc");\r
-    CPPUNIT_ASSERT(m_anyStringString1 != "ABC");\r
-    CPPUNIT_ASSERT(m_anyStringString1 == L"abc");\r
-    CPPUNIT_ASSERT(m_anyStringString1 != L"ABC");\r
-    CPPUNIT_ASSERT(m_anyBool1 == true);\r
-    CPPUNIT_ASSERT(m_anyBool1 != false);\r
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble1, double),\r
-                                 wxANY_AS(m_anyDoubleDouble1, double),\r
-                                 FEQ_DELTA);\r
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble1, double),\r
-                                 TEST_FLOAT_CONST,\r
-                                 FEQ_DELTA);\r
-    CPPUNIT_ASSERT(wxANY_AS(m_anyWxObjectPtr1, wxObject*)\r
-                        == dummyWxObjectPointer);\r
-    CPPUNIT_ASSERT(wxANY_AS(m_anyVoidPtr1, void*) == dummyVoidPointer);\r
-\r
-    CPPUNIT_ASSERT(m_anySignedLong2 == 15);\r
-    CPPUNIT_ASSERT(m_anyStringString2 == wxString("abc"));\r
-    CPPUNIT_ASSERT(m_anyStringString2 == "abc");\r
-    CPPUNIT_ASSERT(m_anyStringString2 == L"abc");\r
-    CPPUNIT_ASSERT(m_anyBool2 == true);\r
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble2, double),\r
-                                 wxANY_AS(m_anyDoubleDouble2, double),\r
-                                 FEQ_DELTA);\r
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble2, double),\r
-                                 TEST_FLOAT_CONST,\r
-                                 FEQ_DELTA);\r
-    CPPUNIT_ASSERT(wxANY_AS(m_anyWxObjectPtr2, wxObject*)\r
-                        == dummyWxObjectPointer);\r
-    CPPUNIT_ASSERT(wxANY_AS(m_anyVoidPtr2, void*) == dummyVoidPointer);\r
-}\r
-\r
-void wxAnyTestCase::As()\r
-{\r
-    //\r
-    // Test getting C++ data from wxAny without dynamic conversion\r
-    signed char a = wxANY_AS(m_anySignedChar1, signed char);\r
-    CPPUNIT_ASSERT(a == (signed int)15);\r
-    signed short b = wxANY_AS(m_anySignedShort1, signed short);\r
-    CPPUNIT_ASSERT(b == (signed int)15);\r
-    signed int c = wxANY_AS(m_anySignedInt1, signed int);\r
-    CPPUNIT_ASSERT(c == (signed int)15);\r
-    signed long d = wxANY_AS(m_anySignedLong1, signed long);\r
-    CPPUNIT_ASSERT(d == (signed int)15);\r
-#ifdef wxLongLong_t\r
-    wxLongLong_t e = wxANY_AS(m_anySignedLongLong1, wxLongLong_t);\r
-    CPPUNIT_ASSERT(e == (signed int)15);\r
-#endif\r
-    unsigned char f = wxANY_AS(m_anyUnsignedChar1, unsigned char);\r
-    CPPUNIT_ASSERT(f == (unsigned int)15);\r
-    unsigned short g = wxANY_AS(m_anyUnsignedShort1, unsigned short);\r
-    CPPUNIT_ASSERT(g == (unsigned int)15);\r
-    unsigned int h = wxANY_AS(m_anyUnsignedInt1, unsigned int);\r
-    CPPUNIT_ASSERT(h == (unsigned int)15);\r
-    unsigned long i = wxANY_AS(m_anyUnsignedLong1, unsigned long);\r
-    CPPUNIT_ASSERT(i == (unsigned int)15);\r
-#ifdef wxLongLong_t\r
-    wxULongLong_t j = wxANY_AS(m_anyUnsignedLongLong1, wxULongLong_t);\r
-    CPPUNIT_ASSERT(j == (unsigned int)15);\r
-#endif\r
-    wxString k = wxANY_AS(m_anyStringString1, wxString);\r
-    CPPUNIT_ASSERT(k == "abc");\r
-    wxString l = wxANY_AS(m_anyCharString1, wxString);\r
-    CPPUNIT_ASSERT(l == "abc");\r
-    wxString m = wxANY_AS(m_anyWcharString1, wxString);\r
-    CPPUNIT_ASSERT(m == "abc");\r
-    bool n = wxANY_AS(m_anyBool1, bool);\r
-    CPPUNIT_ASSERT(n);\r
-    float o = wxANY_AS(m_anyFloatDouble1, float);\r
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(o, TEST_FLOAT_CONST, FEQ_DELTA);\r
-    double p = wxANY_AS(m_anyDoubleDouble1, double);\r
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(p, TEST_FLOAT_CONST, FEQ_DELTA);\r
-    wxDateTime q = wxANY_AS(m_anyDateTime1, wxDateTime);\r
-    CPPUNIT_ASSERT(q == m_testDateTime);\r
-    wxObject* r = wxANY_AS(m_anyWxObjectPtr1, wxObject*);\r
-    CPPUNIT_ASSERT(r == dummyWxObjectPointer);\r
-    void* s = wxANY_AS(m_anyVoidPtr1, void*);\r
-    CPPUNIT_ASSERT(s == dummyVoidPointer);\r
-}\r
-\r
-void wxAnyTestCase::Null()\r
-{\r
-    wxAny a;\r
-    CPPUNIT_ASSERT(a.IsNull());\r
-    a = -127;\r
-    CPPUNIT_ASSERT(a == -127);\r
-    a.MakeNull();\r
-    CPPUNIT_ASSERT(a.IsNull());\r
-}\r
-\r
-void wxAnyTestCase::GetAs()\r
-{\r
-    //\r
-    // Test dynamic conversion\r
-    bool res;\r
-    long l = 0;\r
-    unsigned long ul = 0;\r
-    wxString s;\r
-    // Let's test against float instead of double, since the former\r
-    // is not the native underlying type the code converts to, but\r
-    // should still work, all the same.\r
-    float f = 0.0;\r
-    bool b = false;\r
-\r
-    // Conversions from signed long type\r
-    res = m_anySignedLong1.GetAs(&ul);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT_EQUAL(ul, static_cast<unsigned long>(15));\r
-    res = m_anySignedLong1.GetAs(&s);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT(s == "15");\r
-    res = m_anySignedLong1.GetAs(&f);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(f, 15.0, FEQ_DELTA);\r
-    res = m_anySignedLong1.GetAs(&b);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT(b == true);\r
-\r
-    // Conversions from unsigned long type\r
-    res = m_anyUnsignedLong1.GetAs(&l);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT(l == static_cast<signed long>(15));\r
-    res = m_anyUnsignedLong1.GetAs(&s);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT(s == "15");\r
-    res = m_anyUnsignedLong1.GetAs(&f);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(f, 15.0, FEQ_DELTA);\r
-    res = m_anyUnsignedLong1.GetAs(&b);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT(b == true);\r
-\r
-    // Conversions from default "abc" string to other types\r
-    // should not work.\r
-    CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&l));\r
-    CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&ul));\r
-    CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&f));\r
-    CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&b));\r
-\r
-    // Let's test some other conversions from string that should work.\r
-    wxAny anyString;\r
-\r
-    anyString = "15";\r
-    res = anyString.GetAs(&l);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT(l == static_cast<signed long>(15));\r
-    res = anyString.GetAs(&ul);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT_EQUAL(ul, static_cast<unsigned long>(15));\r
-    res = anyString.GetAs(&f);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(f, 15.0, FEQ_DELTA);\r
-    anyString = "TRUE";\r
-    res = anyString.GetAs(&b);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT(b == true);\r
-    anyString = "0";\r
-    res = anyString.GetAs(&b);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT(b == false);\r
-\r
-    // Conversions from bool type\r
-    res = m_anyBool1.GetAs(&l);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT(l == static_cast<signed long>(1));\r
-    res = m_anyBool1.GetAs(&ul);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT_EQUAL(ul, static_cast<unsigned long>(1));\r
-    res = m_anyBool1.GetAs(&s);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT(s == "true");\r
-    CPPUNIT_ASSERT(!m_anyBool1.GetAs(&f));\r
-\r
-    // Conversions from floating point type\r
-    res = m_anyDoubleDouble1.GetAs(&l);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT(l == static_cast<signed long>(123));\r
-    res = m_anyDoubleDouble1.GetAs(&ul);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT_EQUAL(ul, static_cast<unsigned long>(123));\r
-    res = m_anyDoubleDouble1.GetAs(&s);\r
-    CPPUNIT_ASSERT(res);\r
-    double d2;\r
-    res = s.ToDouble(&d2);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(d2, TEST_FLOAT_CONST, FEQ_DELTA);\r
-}\r
-\r
-//\r
-// Test user data type specialization of wxAnyValueTypeImpl\r
-//\r
-\r
-class MyClass\r
-{\r
-public:\r
-    MyClass( int someValue = 32768 )\r
-    {\r
-        m_someValue = someValue;\r
-    }\r
-\r
-    wxString ToString()\r
-    {\r
-        return wxString::Format("%i", m_someValue);\r
-    }\r
-\r
-private:\r
-    int     m_someValue;\r
-};\r
-\r
-\r
-template<>\r
-class wxAnyValueTypeImpl<MyClass> :\r
-    public wxAnyValueTypeImplBase<MyClass>\r
-{\r
-    WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)\r
-public:\r
-    wxAnyValueTypeImpl() :\r
-        wxAnyValueTypeImplBase<MyClass>() { }\r
-    virtual ~wxAnyValueTypeImpl() { }\r
-\r
-    virtual bool ConvertValue(const wxAnyValueBuffer& src,\r
-                              wxAnyValueType* dstType,\r
-                              wxAnyValueBuffer& dst) const\r
-    {\r
-        MyClass value = GetValue(src);\r
-\r
-        if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )\r
-        {\r
-            wxString s = value.ToString();\r
-            wxAnyValueTypeImpl<wxString>::SetValue(s, dst);\r
-        }\r
-        else\r
-            return false;\r
-\r
-        return true;\r
-    }\r
-};\r
-\r
-//\r
-// Following must be placed somewhere in your source code\r
-WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)\r
-\r
-void wxAnyTestCase::CustomTemplateSpecialization()\r
-{\r
-    // Do only a minimal CheckType() test, as dynamic type conversion already\r
-    // uses it a lot.\r
-    bool res;\r
-    MyClass myObject;\r
-    wxAny any = myObject;\r
-\r
-    CPPUNIT_ASSERT( wxANY_CHECK_TYPE(any, MyClass) );\r
-    MyClass myObject2 = wxANY_AS(any, MyClass);\r
-    wxUnusedVar(myObject2);\r
-\r
-    wxString str;\r
-    res = any.GetAs(&str);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT_EQUAL(str, myObject.ToString());\r
-}\r
-\r
-#endif // wxUSE_ANY\r
-\r
+///////////////////////////////////////////////////////////////////////////////
+// Name:        tests/any/anytest.cpp
+// Purpose:     Test the wxAny classes
+// Author:      Jaakko Salli
+// RCS-ID:      $Id$
+// Copyright:   (c) the wxWidgets team
+// Licence:     wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#include "testprec.h"
+
+#ifdef __BORLANDC__
+#   pragma hdrstop
+#endif
+
+#if wxUSE_ANY
+
+#include "wx/any.h"
+#include "wx/datetime.h"
+
+#include <math.h>
+
+// ----------------------------------------------------------------------------
+// test class
+// ----------------------------------------------------------------------------
+
+class wxAnyTestCase : public CppUnit::TestCase
+{
+public:
+    wxAnyTestCase();
+
+private:
+    CPPUNIT_TEST_SUITE( wxAnyTestCase );
+        CPPUNIT_TEST( Equality );
+        CPPUNIT_TEST( As );
+        CPPUNIT_TEST( GetAs );
+        CPPUNIT_TEST( Null );
+        CPPUNIT_TEST( CustomTemplateSpecialization );
+    CPPUNIT_TEST_SUITE_END();
+
+    void Equality();
+    void As();
+    void GetAs();
+    void Null();
+    void CustomTemplateSpecialization();
+
+    wxDateTime m_testDateTime;
+
+    wxAny   m_anySignedChar1;
+    wxAny   m_anySignedShort1;
+    wxAny   m_anySignedInt1;
+    wxAny   m_anySignedLong1;
+    wxAny   m_anySignedLongLong1;
+    wxAny   m_anyUnsignedChar1;
+    wxAny   m_anyUnsignedShort1;
+    wxAny   m_anyUnsignedInt1;
+    wxAny   m_anyUnsignedLong1;
+    wxAny   m_anyUnsignedLongLong1;
+    wxAny   m_anyStringString1;
+    wxAny   m_anyCharString1;
+    wxAny   m_anyWcharString1;
+    wxAny   m_anyBool1;
+    wxAny   m_anyFloatDouble1;
+    wxAny   m_anyDoubleDouble1;
+    wxAny   m_anyWxObjectPtr1;
+    wxAny   m_anyVoidPtr1;
+    wxAny   m_anyDateTime1;
+
+    wxAny   m_anySignedChar2;
+    wxAny   m_anySignedShort2;
+    wxAny   m_anySignedInt2;
+    wxAny   m_anySignedLong2;
+    wxAny   m_anySignedLongLong2;
+    wxAny   m_anyUnsignedChar2;
+    wxAny   m_anyUnsignedShort2;
+    wxAny   m_anyUnsignedInt2;
+    wxAny   m_anyUnsignedLong2;
+    wxAny   m_anyUnsignedLongLong2;
+    wxAny   m_anyStringString2;
+    wxAny   m_anyCharString2;
+    wxAny   m_anyWcharString2;
+    wxAny   m_anyBool2;
+    wxAny   m_anyFloatDouble2;
+    wxAny   m_anyDoubleDouble2;
+    wxAny   m_anyWxObjectPtr2;
+    wxAny   m_anyVoidPtr2;
+    wxAny   m_anyDateTime2;
+
+    DECLARE_NO_COPY_CLASS(wxAnyTestCase)
+};
+
+// register in the unnamed registry so that these tests are run by default
+CPPUNIT_TEST_SUITE_REGISTRATION( wxAnyTestCase );
+
+// also include in it's own registry so that these tests can be run alone
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( wxAnyTestCase, "wxAnyTestCase" );
+
+// Let's use a number with first digit after decimal dot less than 5,
+// so that we don't have to worry about whether conversion from float
+// to int truncates or rounds.
+const double TEST_FLOAT_CONST = 123.456;
+
+const double FEQ_DELTA = 0.001;
+
+wxObject* dummyWxObjectPointer = reinterpret_cast<wxObject*>(1234);
+void* dummyVoidPointer = reinterpret_cast<void*>(1234);
+
+
+//
+// Test both 'creation' methods
+wxAnyTestCase::wxAnyTestCase()
+    : m_anySignedChar1((signed char)15),
+      m_anySignedShort1((signed short)15),
+      m_anySignedInt1((signed int)15),
+      m_anySignedLong1((signed long)15),
+#ifdef wxLongLong_t
+      m_anySignedLongLong1((wxLongLong_t)15),
+#endif
+      m_anyUnsignedChar1((unsigned char)15),
+      m_anyUnsignedShort1((unsigned short)15),
+      m_anyUnsignedInt1((unsigned int)15),
+      m_anyUnsignedLong1((unsigned long)15),
+#ifdef wxLongLong_t
+      m_anyUnsignedLongLong1((wxULongLong_t)15),
+#endif
+      m_anyStringString1(wxString("abc")),
+      m_anyCharString1("abc"),
+      m_anyWcharString1(L"abc"),
+      m_anyBool1(true),
+      m_anyFloatDouble1((float)TEST_FLOAT_CONST),
+      m_anyDoubleDouble1((double)TEST_FLOAT_CONST),
+      m_anyWxObjectPtr1(dummyWxObjectPointer),
+      m_anyVoidPtr1(dummyVoidPointer),
+      m_anyDateTime1(wxDateTime::Now())
+{
+    m_testDateTime = wxDateTime::Now();
+    m_anySignedChar2 = (signed char)15;
+    m_anySignedShort2 = (signed short)15;
+    m_anySignedInt2 = (signed int)15;
+    m_anySignedLong2 = (signed long)15;
+#ifdef wxLongLong_t
+    m_anySignedLongLong2 = (wxLongLong_t)15;
+#endif
+    m_anyUnsignedChar2 = (unsigned char)15;
+    m_anyUnsignedShort2 = (unsigned short)15;
+    m_anyUnsignedInt2 = (unsigned int)15;
+    m_anyUnsignedLong2 = (unsigned long)15;
+#ifdef wxLongLong_t
+    m_anyUnsignedLongLong2 = (wxULongLong_t)15;
+#endif
+    m_anyStringString2 = wxString("abc");
+    m_anyCharString2 = "abc";
+    m_anyWcharString2 = L"abc";
+    m_anyBool2 = true;
+    m_anyFloatDouble2 = (float)TEST_FLOAT_CONST;
+    m_anyDoubleDouble2 = (double)TEST_FLOAT_CONST;
+    m_anyDateTime2 = m_testDateTime;
+    m_anyWxObjectPtr2 = dummyWxObjectPointer;
+    m_anyVoidPtr2 = dummyVoidPointer;
+}
+
+void wxAnyTestCase::Equality()
+{
+    //
+    // Currently this should work
+    CPPUNIT_ASSERT(m_anyUnsignedLong1 == 15L);
+    CPPUNIT_ASSERT(m_anyUnsignedLong1 != 30L);
+    CPPUNIT_ASSERT(m_anyUnsignedLong1 == 15UL);
+    CPPUNIT_ASSERT(m_anyUnsignedLong1 != 30UL);
+    CPPUNIT_ASSERT(m_anyStringString1 == wxString("abc"));
+    CPPUNIT_ASSERT(m_anyStringString1 != wxString("ABC"));
+    CPPUNIT_ASSERT(m_anyStringString1 == "abc");
+    CPPUNIT_ASSERT(m_anyStringString1 != "ABC");
+    CPPUNIT_ASSERT(m_anyStringString1 == L"abc");
+    CPPUNIT_ASSERT(m_anyStringString1 != L"ABC");
+    CPPUNIT_ASSERT(m_anyBool1 == true);
+    CPPUNIT_ASSERT(m_anyBool1 != false);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble1, double),
+                                 wxANY_AS(m_anyDoubleDouble1, double),
+                                 FEQ_DELTA);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble1, double),
+                                 TEST_FLOAT_CONST,
+                                 FEQ_DELTA);
+    CPPUNIT_ASSERT(wxANY_AS(m_anyWxObjectPtr1, wxObject*)
+                        == dummyWxObjectPointer);
+    CPPUNIT_ASSERT(wxANY_AS(m_anyVoidPtr1, void*) == dummyVoidPointer);
+
+    CPPUNIT_ASSERT(m_anySignedLong2 == 15);
+    CPPUNIT_ASSERT(m_anyStringString2 == wxString("abc"));
+    CPPUNIT_ASSERT(m_anyStringString2 == "abc");
+    CPPUNIT_ASSERT(m_anyStringString2 == L"abc");
+    CPPUNIT_ASSERT(m_anyBool2 == true);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble2, double),
+                                 wxANY_AS(m_anyDoubleDouble2, double),
+                                 FEQ_DELTA);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble2, double),
+                                 TEST_FLOAT_CONST,
+                                 FEQ_DELTA);
+    CPPUNIT_ASSERT(wxANY_AS(m_anyWxObjectPtr2, wxObject*)
+                        == dummyWxObjectPointer);
+    CPPUNIT_ASSERT(wxANY_AS(m_anyVoidPtr2, void*) == dummyVoidPointer);
+}
+
+void wxAnyTestCase::As()
+{
+    //
+    // Test getting C++ data from wxAny without dynamic conversion
+    signed char a = wxANY_AS(m_anySignedChar1, signed char);
+    CPPUNIT_ASSERT(a == (signed int)15);
+    signed short b = wxANY_AS(m_anySignedShort1, signed short);
+    CPPUNIT_ASSERT(b == (signed int)15);
+    signed int c = wxANY_AS(m_anySignedInt1, signed int);
+    CPPUNIT_ASSERT(c == (signed int)15);
+    signed long d = wxANY_AS(m_anySignedLong1, signed long);
+    CPPUNIT_ASSERT(d == (signed int)15);
+#ifdef wxLongLong_t
+    wxLongLong_t e = wxANY_AS(m_anySignedLongLong1, wxLongLong_t);
+    CPPUNIT_ASSERT(e == (signed int)15);
+#endif
+    unsigned char f = wxANY_AS(m_anyUnsignedChar1, unsigned char);
+    CPPUNIT_ASSERT(f == (unsigned int)15);
+    unsigned short g = wxANY_AS(m_anyUnsignedShort1, unsigned short);
+    CPPUNIT_ASSERT(g == (unsigned int)15);
+    unsigned int h = wxANY_AS(m_anyUnsignedInt1, unsigned int);
+    CPPUNIT_ASSERT(h == (unsigned int)15);
+    unsigned long i = wxANY_AS(m_anyUnsignedLong1, unsigned long);
+    CPPUNIT_ASSERT(i == (unsigned int)15);
+#ifdef wxLongLong_t
+    wxULongLong_t j = wxANY_AS(m_anyUnsignedLongLong1, wxULongLong_t);
+    CPPUNIT_ASSERT(j == (unsigned int)15);
+#endif
+    wxString k = wxANY_AS(m_anyStringString1, wxString);
+    CPPUNIT_ASSERT(k == "abc");
+    wxString l = wxANY_AS(m_anyCharString1, wxString);
+    CPPUNIT_ASSERT(l == "abc");
+    wxString m = wxANY_AS(m_anyWcharString1, wxString);
+    CPPUNIT_ASSERT(m == "abc");
+    bool n = wxANY_AS(m_anyBool1, bool);
+    CPPUNIT_ASSERT(n);
+    float o = wxANY_AS(m_anyFloatDouble1, float);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(o, TEST_FLOAT_CONST, FEQ_DELTA);
+    double p = wxANY_AS(m_anyDoubleDouble1, double);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(p, TEST_FLOAT_CONST, FEQ_DELTA);
+    wxDateTime q = wxANY_AS(m_anyDateTime1, wxDateTime);
+    CPPUNIT_ASSERT(q == m_testDateTime);
+    wxObject* r = wxANY_AS(m_anyWxObjectPtr1, wxObject*);
+    CPPUNIT_ASSERT(r == dummyWxObjectPointer);
+    void* s = wxANY_AS(m_anyVoidPtr1, void*);
+    CPPUNIT_ASSERT(s == dummyVoidPointer);
+}
+
+void wxAnyTestCase::Null()
+{
+    wxAny a;
+    CPPUNIT_ASSERT(a.IsNull());
+    a = -127;
+    CPPUNIT_ASSERT(a == -127);
+    a.MakeNull();
+    CPPUNIT_ASSERT(a.IsNull());
+}
+
+void wxAnyTestCase::GetAs()
+{
+    //
+    // Test dynamic conversion
+    bool res;
+    long l = 0;
+    unsigned long ul = 0;
+    wxString s;
+    // Let's test against float instead of double, since the former
+    // is not the native underlying type the code converts to, but
+    // should still work, all the same.
+    float f = 0.0;
+    bool b = false;
+
+    // Conversions from signed long type
+    res = m_anySignedLong1.GetAs(&ul);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT_EQUAL(ul, static_cast<unsigned long>(15));
+    res = m_anySignedLong1.GetAs(&s);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT(s == "15");
+    res = m_anySignedLong1.GetAs(&f);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(f, 15.0, FEQ_DELTA);
+    res = m_anySignedLong1.GetAs(&b);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT(b == true);
+
+    // Conversions from unsigned long type
+    res = m_anyUnsignedLong1.GetAs(&l);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT(l == static_cast<signed long>(15));
+    res = m_anyUnsignedLong1.GetAs(&s);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT(s == "15");
+    res = m_anyUnsignedLong1.GetAs(&f);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(f, 15.0, FEQ_DELTA);
+    res = m_anyUnsignedLong1.GetAs(&b);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT(b == true);
+
+    // Conversions from default "abc" string to other types
+    // should not work.
+    CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&l));
+    CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&ul));
+    CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&f));
+    CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&b));
+
+    // Let's test some other conversions from string that should work.
+    wxAny anyString;
+
+    anyString = "15";
+    res = anyString.GetAs(&l);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT(l == static_cast<signed long>(15));
+    res = anyString.GetAs(&ul);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT_EQUAL(ul, static_cast<unsigned long>(15));
+    res = anyString.GetAs(&f);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(f, 15.0, FEQ_DELTA);
+    anyString = "TRUE";
+    res = anyString.GetAs(&b);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT(b == true);
+    anyString = "0";
+    res = anyString.GetAs(&b);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT(b == false);
+
+    // Conversions from bool type
+    res = m_anyBool1.GetAs(&l);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT(l == static_cast<signed long>(1));
+    res = m_anyBool1.GetAs(&ul);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT_EQUAL(ul, static_cast<unsigned long>(1));
+    res = m_anyBool1.GetAs(&s);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT(s == "true");
+    CPPUNIT_ASSERT(!m_anyBool1.GetAs(&f));
+
+    // Conversions from floating point type
+    res = m_anyDoubleDouble1.GetAs(&l);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT(l == static_cast<signed long>(123));
+    res = m_anyDoubleDouble1.GetAs(&ul);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT_EQUAL(ul, static_cast<unsigned long>(123));
+    res = m_anyDoubleDouble1.GetAs(&s);
+    CPPUNIT_ASSERT(res);
+    double d2;
+    res = s.ToDouble(&d2);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(d2, TEST_FLOAT_CONST, FEQ_DELTA);
+}
+
+//
+// Test user data type specialization of wxAnyValueTypeImpl
+//
+
+class MyClass
+{
+public:
+    MyClass( int someValue = 32768 )
+    {
+        m_someValue = someValue;
+    }
+
+    wxString ToString()
+    {
+        return wxString::Format("%i", m_someValue);
+    }
+
+private:
+    int     m_someValue;
+};
+
+
+template<>
+class wxAnyValueTypeImpl<MyClass> :
+    public wxAnyValueTypeImplBase<MyClass>
+{
+    WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)
+public:
+    wxAnyValueTypeImpl() :
+        wxAnyValueTypeImplBase<MyClass>() { }
+    virtual ~wxAnyValueTypeImpl() { }
+
+    virtual bool ConvertValue(const wxAnyValueBuffer& src,
+                              wxAnyValueType* dstType,
+                              wxAnyValueBuffer& dst) const
+    {
+        MyClass value = GetValue(src);
+
+        if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
+        {
+            wxString s = value.ToString();
+            wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
+        }
+        else
+            return false;
+
+        return true;
+    }
+};
+
+//
+// Following must be placed somewhere in your source code
+WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)
+
+void wxAnyTestCase::CustomTemplateSpecialization()
+{
+    // Do only a minimal CheckType() test, as dynamic type conversion already
+    // uses it a lot.
+    bool res;
+    MyClass myObject;
+    wxAny any = myObject;
+
+    CPPUNIT_ASSERT( wxANY_CHECK_TYPE(any, MyClass) );
+    MyClass myObject2 = wxANY_AS(any, MyClass);
+    wxUnusedVar(myObject2);
+
+    wxString str;
+    res = any.GetAs(&str);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT_EQUAL(str, myObject.ToString());
+}
+
+#endif // wxUSE_ANY
+