]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/any.h
Make storing non-trivial data in wxThreadSpecificInfo possible.
[wxWidgets.git] / include / wx / any.h
index c021ce65c7fcc3688d7ecdfdf7c9377d4030fa96..c2cd7a79f437ff9d32bbcda832dc1153c0178814 100644 (file)
@@ -4,7 +4,6 @@
 // Author:      Jaakko Salli
 // Modified by:
 // Created:     07/05/2009
-// RCS-ID:      $Id$
 // Copyright:   (c) wxWidgets team
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 #if wxUSE_ANY
 
+#include <new> // for placement new
 #include "wx/string.h"
-#include "wx/meta/movable.h"
 #include "wx/meta/if.h"
-
+#include "wx/typeinfo.h"
+#include "wx/list.h"
 
 // Size of the wxAny value buffer.
 enum
@@ -29,17 +29,20 @@ enum
 
 union wxAnyValueBuffer
 {
+    union Alignment
+    {
+    #if wxHAS_INT64
+        wxInt64 m_int64;
+    #endif
+        long double m_longDouble;
+        void ( *m_funcPtr )(void);
+        void ( wxAnyValueBuffer::*m_mFuncPtr )(void);
+    } m_alignment;
+
     void*   m_ptr;
-#if wxHAS_INT64
-    wxInt64 m_int64;
-#endif
-    double  m_double;
     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<>)
@@ -47,11 +50,14 @@ typedef void (*wxAnyClassInfo)();
 //
 class WXDLLIMPEXP_BASE wxAnyValueType
 {
+    WX_DECLARE_ABSTRACT_TYPEINFO(wxAnyValueType)
 public:
     /**
         Default constructor.
     */
-    wxAnyValueType();
+    wxAnyValueType()
+    {
+    }
 
     /**
         Destructor.
@@ -60,11 +66,6 @@ public:
     {
     }
 
-    /**
-        This function is used for internal type matching.
-    */
-    virtual wxAnyClassInfo GetClassInfo() const = 0;
-
     /**
         This function is used for internal type matching.
     */
@@ -77,9 +78,14 @@ public:
     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.
+        Implement this for buffer-to-buffer copy.
+
+        @param src
+            This is the source data buffer.
+
+        @param dst
+            This is the destination data buffer that is in either
+            uninitialized or freed state.
     */
     virtual void CopyBuffer(const wxAnyValueBuffer& src,
                             wxAnyValueBuffer& dst) const = 0;
@@ -97,7 +103,7 @@ public:
         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
+                (such as Visual C++ 6.0). For full compiler compatibility
                 please use wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) macro
                 instead.
 
@@ -105,53 +111,76 @@ public:
     */
     // FIXME-VC6: remove this hack when VC6 is no longer supported
     template <typename T>
-    bool CheckType(T* reserved = NULL);
+    bool CheckType(T* reserved = NULL) const;
+
+#if wxUSE_EXTENDED_RTTI
+    virtual const wxTypeInfo* GetTypeInfo() const = 0;
+#endif
 private:
 };
 
+
+//
+// We need to allocate wxAnyValueType instances in heap, and need to use
+// scoped ptr to properly deallocate them in dynamic library use cases.
+// Here we have a minimal specialized scoped ptr implementation to deal
+// with various compiler-specific problems with template class' static
+// member variable of template type with explicit constructor which
+// is initialized in global scope.
+//
+class wxAnyValueTypeScopedPtr
+{
+public:
+    wxAnyValueTypeScopedPtr(wxAnyValueType* ptr) : m_ptr(ptr) { }
+    ~wxAnyValueTypeScopedPtr() { delete m_ptr; }
+    wxAnyValueType* get() const { return m_ptr; }
+private:
+    wxAnyValueType* m_ptr;
+};
+
+
 //
 // This method of checking the type is compatible with VC6
 #define wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) \
     wxAnyValueTypeImpl<T>::IsSameClass(valueTypePtr)
 
-    //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).
+    Even though C++ RTTI would be fully available to use, we'd have to to
+    facilitate sub-type system which allows, for instance, wxAny with
+    signed short '15' to be treated equal to wxAny with signed long long '15'.
+    Having sm_instance is important here.
+
+    NB: We really need to have wxAnyValueType instances allocated
+        in heap. They are stored as static template member variables,
+        and with them we just can't be too careful (eg. not allocating
+        them in heap broke the type identification in GCC).
 */
 #define WX_DECLARE_ANY_VALUE_TYPE(CLS) \
     friend class wxAny; \
+    WX_DECLARE_TYPEINFO_INLINE(CLS) \
 public: \
-    static void sm_classInfo() {} \
- \
-    virtual wxAnyClassInfo GetClassInfo() const \
-    { \
-        return sm_classInfo; \
-    } \
     static bool IsSameClass(const wxAnyValueType* otherType) \
     { \
-        return sm_instance->GetClassInfo() == otherType->GetClassInfo(); \
+        return wxTypeId(*sm_instance.get()) == wxTypeId(*otherType); \
     } \
     virtual bool IsSameType(const wxAnyValueType* otherType) const \
     { \
         return IsSameClass(otherType); \
     } \
 private: \
-    static CLS* sm_instance; \
+    static wxAnyValueTypeScopedPtr sm_instance; \
 public: \
     static wxAnyValueType* GetInstance() \
     { \
-        return sm_instance; \
+        return sm_instance.get(); \
     }
 
 
 #define WX_IMPLEMENT_ANY_VALUE_TYPE(CLS) \
-    CLS* CLS::sm_instance = new CLS();
+wxAnyValueTypeScopedPtr CLS::sm_instance(new CLS());
 
 
 #ifdef __VISUALC6__
@@ -167,23 +196,33 @@ namespace wxPrivate
 {
 
 template<typename T>
-class wxAnyValueTypeOpsMovable
+class wxAnyValueTypeOpsInplace
 {
 public:
     static void DeleteValue(wxAnyValueBuffer& buf)
     {
-        wxUnusedVar(buf);
+        T* value = reinterpret_cast<T*>(&buf.m_buffer[0]);
+        value->~T();
+
+        // Some compiler may given 'unused variable' warnings without this
+        wxUnusedVar(value);
     }
 
     static void SetValue(const T& value,
                          wxAnyValueBuffer& buf)
     {
-        memcpy(buf.m_buffer, &value, sizeof(T));
+        // Use placement new
+        void* const place = buf.m_buffer;
+        ::new(place) T(value);
     }
 
     static const T& GetValue(const wxAnyValueBuffer& buf)
     {
-        return *(reinterpret_cast<const T*>(&buf.m_buffer[0]));
+        // Breaking this code into two lines should suppress
+        // GCC's 'type-punned pointer will break strict-aliasing rules'
+        // warning.
+        const T* value = reinterpret_cast<const T*>(&buf.m_buffer[0]);
+        return *value;
     }
 };
 
@@ -240,9 +279,8 @@ public:
 template<typename T>
 class wxAnyValueTypeImplBase : public wxAnyValueType
 {
-    typedef typename wxIf< wxIsMovable<T>::value &&
-                                sizeof(T) <= WX_ANY_VALUE_BUFFER_SIZE,
-                           wxPrivate::wxAnyValueTypeOpsMovable<T>,
+    typedef typename wxIf< sizeof(T) <= WX_ANY_VALUE_BUFFER_SIZE,
+                           wxPrivate::wxAnyValueTypeOpsInplace<T>,
                            wxPrivate::wxAnyValueTypeOpsGeneric<T> >::value
             Ops;
 
@@ -253,13 +291,11 @@ public:
     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);
     }
 
@@ -281,6 +317,12 @@ public:
     {
         return Ops::GetValue(buf);
     }
+#if wxUSE_EXTENDED_RTTI
+    virtual const wxTypeInfo* GetTypeInfo() const 
+    {
+        return wxGetTypeInfo((T*)NULL);
+    }
+#endif
 };
 
 
@@ -308,15 +350,14 @@ public:
 };
 
 template<typename T>
-wxAnyValueTypeImpl<T>* wxAnyValueTypeImpl<T>::sm_instance =
-    new wxAnyValueTypeImpl<T>();
+wxAnyValueTypeScopedPtr wxAnyValueTypeImpl<T>::sm_instance = new wxAnyValueTypeImpl<T>();
 
 
 //
 // Helper macro for using same base value type implementation for multiple
 // actual C++ data types.
 //
-#define WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
+#define _WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
 template<> \
 class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##CLSTYPE \
 { \
@@ -326,16 +367,32 @@ public: \
     virtual ~wxAnyValueTypeImpl() { } \
     static void SetValue(const T& value, wxAnyValueBuffer& buf) \
     { \
-        *(reinterpret_cast<UseDataType*>(&buf.m_buffer[0])) = \
-            static_cast<UseDataType>(value); \
+        void* voidPtr = reinterpret_cast<void*>(&buf.m_buffer[0]); \
+        UseDataType* dptr = reinterpret_cast<UseDataType*>(voidPtr); \
+        *dptr = static_cast<UseDataType>(value); \
     } \
     static T GetValue(const wxAnyValueBuffer& buf) \
     { \
-        return static_cast<T>( \
-            *(reinterpret_cast<const UseDataType*>(&buf.m_buffer[0]))); \
+        const void* voidPtr = \
+            reinterpret_cast<const void*>(&buf.m_buffer[0]); \
+        const UseDataType* sptr = \
+            reinterpret_cast<const UseDataType*>(voidPtr); \
+        return static_cast<T>(*sptr); \
+    } 
+
+#if wxUSE_EXTENDED_RTTI
+#define WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
+_WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE)\
+    virtual const wxTypeInfo* GetTypeInfo() const  \
+    { \
+        return wxGetTypeInfo((T*)NULL); \
     } \
 };
-
+#else
+#define WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
+_WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE)\
+};
+#endif
 
 //
 //  Integer value types
@@ -398,35 +455,55 @@ WX_ANY_DEFINE_SUB_TYPE(wxULongLong_t, Uint)
 
 
 //
-// String value type
+// This macro is used in header, but then in source file we must have:
+// WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl##TYPENAME)
 //
-class WXDLLIMPEXP_BASE wxAnyValueTypeImplString :
-    public wxAnyValueTypeImplBase<wxString>
-{
-    WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplString)
-public:
-    wxAnyValueTypeImplString() :
-        wxAnyValueTypeImplBase<wxString>() { }
-    virtual ~wxAnyValueTypeImplString() { }
+#define _WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, GV) \
+class WXDLLIMPEXP_BASE wxAnyValueTypeImpl##TYPENAME : \
+    public wxAnyValueTypeImplBase<T> \
+{ \
+    WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl##TYPENAME) \
+public: \
+    wxAnyValueTypeImpl##TYPENAME() : \
+        wxAnyValueTypeImplBase<T>() { } \
+    virtual ~wxAnyValueTypeImpl##TYPENAME() { } \
+    virtual bool ConvertValue(const wxAnyValueBuffer& src, \
+                              wxAnyValueType* dstType, \
+                              wxAnyValueBuffer& dst) const \
+    { \
+        GV value = GetValue(src); \
+        return CONVFUNC(value, dstType, dst); \
+    } \
+}; \
+template<> \
+class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##TYPENAME \
+{ \
+public: \
+    wxAnyValueTypeImpl() : wxAnyValueTypeImpl##TYPENAME() { } \
+    virtual ~wxAnyValueTypeImpl() { } \
+};
 
-    /**
-        Convert value into buffer of different type. Return false if
-        not possible.
-    */
-    virtual bool ConvertValue(const wxAnyValueBuffer& src,
-                              wxAnyValueType* dstType,
-                              wxAnyValueBuffer& dst) const;
+#define WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, BT) \
+_WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, BT) \
 
-};
+#define WX_ANY_DEFINE_CONVERTIBLE_TYPE_BASE(T, TYPENAME, CONVFUNC) \
+_WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, \
+                                CONVFUNC, const T&) \
 
-template<>
-class wxAnyValueTypeImpl<wxString> : public wxAnyValueTypeImplString
-{
-public:
-    wxAnyValueTypeImpl() : wxAnyValueTypeImplString() { }
-    virtual ~wxAnyValueTypeImpl() { }
-};
+//
+// String value type
+//
+
+// Convert wxString to destination wxAny value type
+extern WXDLLIMPEXP_BASE bool wxAnyConvertString(const wxString& value,
+                                                wxAnyValueType* dstType,
+                                                wxAnyValueBuffer& dst);
 
+WX_ANY_DEFINE_CONVERTIBLE_TYPE_BASE(wxString, wxString, wxAnyConvertString)
+WX_ANY_DEFINE_CONVERTIBLE_TYPE(const char*, ConstCharPtr,
+                               wxAnyConvertString, wxString)
+WX_ANY_DEFINE_CONVERTIBLE_TYPE(const wchar_t*, ConstWchar_tPtr,
+                               wxAnyConvertString, wxString)
 
 //
 // Bool value type
@@ -470,6 +547,123 @@ WX_ANY_DEFINE_SUB_TYPE(float, Double)
 WX_ANY_DEFINE_SUB_TYPE(double, Double)
 
 
+//
+// Defines a dummy wxAnyValueTypeImpl<> with given export
+// declaration. This is needed if a class is used with
+// wxAny in both user shared library and application.
+//
+#define wxDECLARE_ANY_TYPE(CLS, DECL) \
+template<> \
+class DECL wxAnyValueTypeImpl<CLS> : \
+    public wxAnyValueTypeImplBase<CLS> \
+{ \
+    WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<CLS>) \
+public: \
+    wxAnyValueTypeImpl() : \
+        wxAnyValueTypeImplBase<CLS>() { } \
+    virtual ~wxAnyValueTypeImpl() { } \
+ \
+    virtual bool ConvertValue(const wxAnyValueBuffer& src, \
+                              wxAnyValueType* dstType, \
+                              wxAnyValueBuffer& dst) const \
+    { \
+        wxUnusedVar(src); \
+        wxUnusedVar(dstType); \
+        wxUnusedVar(dst); \
+        return false; \
+    } \
+};
+
+
+// Make sure some of wx's own types get the right wxAnyValueType export
+// (this is needed only for types that are referred to from wxBase.
+// currently we may not use any of these types from there, but let's
+// use the macro on at least one to make sure it compiles since we can't
+// really test it properly in unit tests since a separate DLL would
+// be needed).
+#if wxUSE_DATETIME
+    #include "wx/datetime.h"
+    wxDECLARE_ANY_TYPE(wxDateTime, WXDLLIMPEXP_BASE)
+#endif
+
+//#include "wx/object.h"
+//wxDECLARE_ANY_TYPE(wxObject*, WXDLLIMPEXP_BASE)
+
+//#include "wx/arrstr.h"
+//wxDECLARE_ANY_TYPE(wxArrayString, WXDLLIMPEXP_BASE)
+
+
+#if wxUSE_VARIANT
+
+class WXDLLIMPEXP_FWD_BASE wxAnyToVariantRegistration;
+
+// Because of header inter-dependencies, cannot include this earlier
+#include "wx/variant.h"
+
+//
+// wxVariantData* data type implementation. For cases when appropriate
+// wxAny<->wxVariant conversion code is missing.
+//
+
+class WXDLLIMPEXP_BASE wxAnyValueTypeImplVariantData :
+    public wxAnyValueTypeImplBase<wxVariantData*>
+{
+    WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplVariantData)
+public:
+    wxAnyValueTypeImplVariantData() :
+        wxAnyValueTypeImplBase<wxVariantData*>() { }
+    virtual ~wxAnyValueTypeImplVariantData() { }
+
+    virtual void DeleteValue(wxAnyValueBuffer& buf) const
+    {
+        wxVariantData* data = static_cast<wxVariantData*>(buf.m_ptr);
+        if ( data )
+            data->DecRef();
+    }
+
+    virtual void CopyBuffer(const wxAnyValueBuffer& src,
+                            wxAnyValueBuffer& dst) const
+    {
+        wxVariantData* data = static_cast<wxVariantData*>(src.m_ptr);
+        if ( data )
+            data->IncRef();
+        dst.m_ptr = data;
+    }
+
+    static void SetValue(wxVariantData* value,
+                         wxAnyValueBuffer& buf)
+    {
+        value->IncRef();
+        buf.m_ptr = value;
+    }
+
+    static wxVariantData* GetValue(const wxAnyValueBuffer& buf)
+    {
+        return static_cast<wxVariantData*>(buf.m_ptr);
+    }
+
+    virtual bool ConvertValue(const wxAnyValueBuffer& src,
+                              wxAnyValueType* dstType,
+                              wxAnyValueBuffer& dst) const
+    {
+        wxUnusedVar(src);
+        wxUnusedVar(dstType);
+        wxUnusedVar(dst);
+        return false;
+    }
+};
+
+template<>
+class wxAnyValueTypeImpl<wxVariantData*> :
+    public wxAnyValueTypeImplVariantData
+{
+public:
+    wxAnyValueTypeImpl() : wxAnyValueTypeImplVariantData() { }
+    virtual ~wxAnyValueTypeImpl() { }
+};
+
+#endif // wxUSE_VARIANT
+
 #ifdef __VISUALC6__
     // Re-enable useless VC6 warnings
     #pragma warning (pop)
@@ -511,6 +705,22 @@ bool operator==(TUS value) const \
 }
 
 
+#if wxUSE_VARIANT
+
+// Note that the following functions are implemented outside wxAny class
+// so that it can reside entirely in header and lack the export declaration.
+
+// Helper function used to associate wxAnyValueType with a wxVariantData.
+extern WXDLLIMPEXP_BASE void
+wxPreRegisterAnyToVariant(wxAnyToVariantRegistration* reg);
+
+// This function performs main wxAny to wxVariant conversion duties.
+extern WXDLLIMPEXP_BASE bool
+wxConvertAnyToVariant(const wxAny& any, wxVariant* variant);
+
+#endif // wxUSE_VARIANT
+
+
 //
 // The wxAny class represents a container for any type. A variant's value
 // can be changed at run time, possibly to a different type of value.
@@ -541,15 +751,23 @@ public:
     /**
         Various constructors.
     */
+    template<typename T>
+    wxAny(const T& value)
+    {
+        m_type = wxAnyValueTypeImpl<T>::sm_instance.get();
+        wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
+    }
+
+    // These two constructors are needed to deal with string literals
     wxAny(const char* value)
     {
-        m_type = wxAnyNullValueType;
-        Assign(wxString(value));
+        m_type = wxAnyValueTypeImpl<const char*>::sm_instance.get();
+        wxAnyValueTypeImpl<const char*>::SetValue(value, m_buffer);
     }
     wxAny(const wchar_t* value)
     {
-        m_type = wxAnyNullValueType;
-        Assign(wxString(value));
+        m_type = wxAnyValueTypeImpl<const wchar_t*>::sm_instance.get();
+        wxAnyValueTypeImpl<const wchar_t*>::SetValue(value, m_buffer);
     }
 
     wxAny(const wxAny& any)
@@ -558,12 +776,14 @@ public:
         AssignAny(any);
     }
 
-    template<typename T>
-    wxAny(const T& value)
+#if wxUSE_VARIANT
+    wxAny(const wxVariant& variant)
     {
-        m_type = wxAnyValueTypeImpl<T>::sm_instance;
-        wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
+        m_type = wxAnyNullValueType;
+        AssignVariant(variant);
     }
+#endif
+
     //@}
 
     /**
@@ -578,7 +798,7 @@ public:
     */
     // FIXME-VC6: remove this hack when VC6 is no longer supported
     template <typename T>
-    bool CheckType(T* = NULL)
+    bool CheckType(T* = NULL) const
     {
         return m_type->CheckType<T>();
     }
@@ -588,8 +808,9 @@ public:
 
         @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.
+                 of wxAny::GetType(). Instead, use wxAny::HasSameType().
+
+        @see HasSameType()
     */
     const wxAnyValueType* GetType() const
     {
@@ -597,7 +818,16 @@ public:
     }
 
     /**
-        Tests if wxAny is null (that is, whether there is data).
+        Returns @true if this and another wxAny have the same
+        value type.
+    */
+    bool HasSameType(const wxAny& other) const
+    {
+        return GetType()->IsSameType(other.GetType());
+    }
+
+    /**
+        Tests if wxAny is null (that is, whether there is no data).
     */
     bool IsNull() const
     {
@@ -617,26 +847,41 @@ public:
     /**
         Assignment operators.
     */
+    template<typename T>
+    wxAny& operator=(const T &value)
+    {
+        m_type->DeleteValue(m_buffer);
+        m_type = wxAnyValueTypeImpl<T>::sm_instance.get();
+        wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
+        return *this;
+    }
+
     wxAny& operator=(const wxAny &any)
     {
-        AssignAny(any);
+        if (this != &any)
+            AssignAny(any);
         return *this;
     }
 
-    template<typename T>
-    wxAny& operator=(const T &value)
+#if wxUSE_VARIANT
+    wxAny& operator=(const wxVariant &variant)
     {
-        m_type->DeleteValue(m_buffer);
-        m_type = wxAnyValueTypeImpl<T>::sm_instance;
-        wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
+        AssignVariant(variant);
         return *this;
     }
+#endif
 
+    // These two operators are needed to deal with string literals
     wxAny& operator=(const char* value)
-        { Assign(wxString(value)); return *this; }
+    {
+        Assign(value);
+        return *this;
+    }
     wxAny& operator=(const wchar_t* value)
-        { Assign(wxString(value)); return *this; }
-    //@}
+    {
+        Assign(value);
+        return *this;
+    }
 
     //@{
     /**
@@ -644,12 +889,10 @@ public:
     */
     bool operator==(const wxString& value) const
     {
-        if ( !wxAnyValueTypeImpl<wxString>::IsSameClass(m_type) )
+        wxString value2;
+        if ( !GetAs(&value2) )
             return false;
-
-        return value ==
-            static_cast<wxString>
-                (wxAnyValueTypeImpl<wxString>::GetValue(m_buffer));
+        return value == value2;
     }
 
     bool operator==(const char* value) const
@@ -668,6 +911,8 @@ public:
     WXANY_IMPLEMENT_INT_EQ_OP(wxLongLong_t, wxULongLong_t)
 #endif
 
+    wxGCC_WARNING_SUPPRESS(float-equal)
+
     bool operator==(float value) const
     {
         if ( !wxAnyValueTypeImpl<float>::IsSameClass(m_type) )
@@ -688,6 +933,8 @@ public:
                 (wxAnyValueTypeImpl<double>::GetValue(m_buffer));
     }
 
+    wxGCC_WARNING_RESTORE(float-equal)
+
     bool operator==(bool value) const
     {
         if ( !wxAnyValueTypeImpl<bool>::IsSameClass(m_type) )
@@ -708,14 +955,17 @@ public:
     //@}
 
     /**
-        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.
+        This template function converts wxAny into given type. In most cases
+        no type conversion is performed, so if the type is incorrect an
+        assertion failure will occur.
 
-        @remarks 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.
+        @remarks For convenience, conversion is done when T is wxString. This
+                 is useful when a string literal (which are treated as
+                 const char* and const wchar_t*) has been assigned to wxAny.
+
+                 This template function may not work properly with Visual C++
+                 6. For full compiler compatibility, please use
+                 wxANY_AS(any, T) macro instead.
     */
     // FIXME-VC6: remove this hack when VC6 is no longer supported
     template<typename T>
@@ -729,11 +979,30 @@ public:
         return static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(m_buffer));
     }
 
+    // Allow easy conversion from 'const char *' etc. to wxString
+    // FIXME-VC6: remove this hack when VC6 is no longer supported
+    //template<>
+    wxString As(wxString*) const
+    {
+        wxString value;
+        if ( !GetAs(&value) )
+        {
+            wxFAIL_MSG("Incorrect or non-convertible data type");
+        }
+        return value;
+    }
+
+#if wxUSE_EXTENDED_RTTI
+    const wxTypeInfo* GetTypeInfo() const
+    {
+        return m_type->GetTypeInfo();
+    }
+#endif
     /**
-        Template function that etrieves and converts the value of this
+        Template function that retrieves and converts the value of this
         variant to the type that T* value is.
 
-        @return Returns @true if conversion was succesfull.
+        @return Returns @true if conversion was successful.
     */
     template<typename T>
     bool GetAs(T* value) const
@@ -741,7 +1010,7 @@ public:
         if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )
         {
             wxAnyValueType* otherType =
-                wxAnyValueTypeImpl<T>::sm_instance;
+                wxAnyValueTypeImpl<T>::sm_instance.get();
             wxAnyValueBuffer temp_buf;
 
             if ( !m_type->ConvertValue(m_buffer, otherType, temp_buf) )
@@ -757,23 +1026,58 @@ public:
         return true;
     }
 
+#if wxUSE_VARIANT
+    // GetAs() wxVariant specialization
+    bool GetAs(wxVariant* value) const
+    {
+        return wxConvertAnyToVariant(*this, value);
+    }
+#endif
+
 private:
     // Assignment functions
     void AssignAny(const wxAny& any)
     {
-        if ( !any.m_type->IsSameType(m_type) )
+        // Must delete value - CopyBuffer() never does that
+        m_type->DeleteValue(m_buffer);
+
+        wxAnyValueType* newType = any.m_type;
+
+        if ( !newType->IsSameType(m_type) )
+            m_type = newType;
+
+        newType->CopyBuffer(any.m_buffer, m_buffer);
+    }
+
+#if wxUSE_VARIANT
+    void AssignVariant(const wxVariant& variant)
+    {
+        wxVariantData* data = variant.GetData();
+
+        if ( data && data->GetAsAny(this) )
+            return;
+
+        m_type->DeleteValue(m_buffer);
+
+        if ( variant.IsNull() )
+        {
+            // Init as Null
+            m_type = wxAnyNullValueType;
+        }
+        else
         {
-            m_type->DeleteValue(m_buffer);
-            m_type = any.m_type;
+            // If everything else fails, wrap the whole wxVariantData
+            m_type = wxAnyValueTypeImpl<wxVariantData*>::sm_instance.get();
+            wxAnyValueTypeImpl<wxVariantData*>::SetValue(data, m_buffer);
         }
-        m_type->CopyBuffer(any.m_buffer, m_buffer);
     }
+#endif
 
     template<typename T>
     void Assign(const T &value)
     {
         m_type->DeleteValue(m_buffer);
-        m_type = wxAnyValueTypeImpl<T>::sm_instance;
+        m_type = wxAnyValueTypeImpl<T>::sm_instance.get();
         wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
     }
 
@@ -786,23 +1090,23 @@ private:
 //
 // This method of checking the type is compatible with VC6
 #define wxANY_CHECK_TYPE(any, T) \
-    wxANY_VALUE_TYPE_CHECK_TYPE(any.GetType(), 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))
+    (any).As(static_cast<T*>(NULL))
 
 
 template<typename T>
-inline bool wxAnyValueType::CheckType(T* reserved)
+inline bool wxAnyValueType::CheckType(T* reserved) const
 {
     wxUnusedVar(reserved);
     return wxAnyValueTypeImpl<T>::IsSameClass(this);
 }
 
-
+WX_DECLARE_LIST_WITH_DECL(wxAny, wxAnyList, class WXDLLIMPEXP_BASE);
 
 #endif // wxUSE_ANY