]> 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 0e3e4a9bea56feeb6f6b03320a01101f98a73370..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
@@ -104,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.
 
@@ -113,6 +112,10 @@ public:
     // FIXME-VC6: remove this hack when VC6 is no longer supported
     template <typename T>
     bool CheckType(T* reserved = NULL) const;
+
+#if wxUSE_EXTENDED_RTTI
+    virtual const wxTypeInfo* GetTypeInfo() const = 0;
+#endif
 private:
 };
 
@@ -193,23 +196,29 @@ 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)
     {
-        // Breaking this code into two lines should supress
+        // 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]);
@@ -270,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;
 
@@ -309,6 +317,12 @@ public:
     {
         return Ops::GetValue(buf);
     }
+#if wxUSE_EXTENDED_RTTI
+    virtual const wxTypeInfo* GetTypeInfo() const 
+    {
+        return wxGetTypeInfo((T*)NULL);
+    }
+#endif
 };
 
 
@@ -343,7 +357,7 @@ wxAnyValueTypeScopedPtr wxAnyValueTypeImpl<T>::sm_instance = new wxAnyValueTypeI
 // 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 \
 { \
@@ -364,9 +378,21 @@ public: \
         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
@@ -553,7 +579,7 @@ public: \
 // (this is needed only for types that are referred to from wxBase.
 // currently we may not use any of these types from there, but let's
 // use the macro on at least one to make sure it compiles since we can't
-// really test it properly in unittests since a separate DLL would
+// really test it properly in unit tests since a separate DLL would
 // be needed).
 #if wxUSE_DATETIME
     #include "wx/datetime.h"
@@ -782,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
     {
@@ -791,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
     {
@@ -875,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) )
@@ -895,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) )
@@ -919,7 +959,7 @@ public:
         no type conversion is performed, so if the type is incorrect an
         assertion failure will occur.
 
-        @remarks For conveniency, conversion is done when T is wxString. This
+        @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.
 
@@ -952,11 +992,17 @@ public:
         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
@@ -1060,7 +1106,7 @@ inline bool wxAnyValueType::CheckType(T* reserved) const
     return wxAnyValueTypeImpl<T>::IsSameClass(this);
 }
 
-
+WX_DECLARE_LIST_WITH_DECL(wxAny, wxAnyList, class WXDLLIMPEXP_BASE);
 
 #endif // wxUSE_ANY