]> git.saurik.com Git - wxWidgets.git/commitdiff
Use scoped ptrs to managed wxAnyValueType instances. This fixes deallocation issues...
authorJaakko Salli <jaakko.salli@dnainternet.net>
Fri, 30 Apr 2010 13:32:41 +0000 (13:32 +0000)
committerJaakko Salli <jaakko.salli@dnainternet.net>
Fri, 30 Apr 2010 13:32:41 +0000 (13:32 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@64179 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/any.h
src/common/any.cpp

index b5dac8fb7caf8f2391a92a9a4bb7ced19158c2b2..2a1bf7142a6ea675a0300f2ef0a3fd03043ec0be 100644 (file)
@@ -56,7 +56,9 @@ public:
     /**
         Default constructor.
     */
     /**
         Default constructor.
     */
-    wxAnyValueType();
+    wxAnyValueType()
+    {
+    }
 
     /**
         Destructor.
 
     /**
         Destructor.
@@ -114,6 +116,26 @@ public:
 private:
 };
 
 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) \
 //
 // This method of checking the type is compatible with VC6
 #define wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) \
@@ -127,6 +149,11 @@ private:
     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.
     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; \
 */
 #define WX_DECLARE_ANY_VALUE_TYPE(CLS) \
     friend class wxAny; \
@@ -134,23 +161,23 @@ private:
 public: \
     static bool IsSameClass(const wxAnyValueType* otherType) \
     { \
 public: \
     static bool IsSameClass(const wxAnyValueType* otherType) \
     { \
-        return wxTypeId(*sm_instance) == wxTypeId(*otherType); \
+        return wxTypeId(*sm_instance.get()) == wxTypeId(*otherType); \
     } \
     virtual bool IsSameType(const wxAnyValueType* otherType) const \
     { \
         return IsSameClass(otherType); \
     } \
 private: \
     } \
     virtual bool IsSameType(const wxAnyValueType* otherType) const \
     { \
         return IsSameClass(otherType); \
     } \
 private: \
-    static CLS* sm_instance; \
+    static wxAnyValueTypeScopedPtr sm_instance; \
 public: \
     static wxAnyValueType* GetInstance() \
     { \
 public: \
     static wxAnyValueType* GetInstance() \
     { \
-        return sm_instance; \
+        return sm_instance.get(); \
     }
 
 
 #define WX_IMPLEMENT_ANY_VALUE_TYPE(CLS) \
     }
 
 
 #define WX_IMPLEMENT_ANY_VALUE_TYPE(CLS) \
-    CLS* CLS::sm_instance = new CLS();
+wxAnyValueTypeScopedPtr CLS::sm_instance(new CLS());
 
 
 #ifdef __VISUALC6__
 
 
 #ifdef __VISUALC6__
@@ -309,8 +336,7 @@ public:
 };
 
 template<typename T>
 };
 
 template<typename T>
-wxAnyValueTypeImpl<T>* wxAnyValueTypeImpl<T>::sm_instance =
-    new wxAnyValueTypeImpl<T>();
+wxAnyValueTypeScopedPtr wxAnyValueTypeImpl<T>::sm_instance = new wxAnyValueTypeImpl<T>();
 
 
 //
 
 
 //
@@ -702,19 +728,19 @@ public:
     template<typename T>
     wxAny(const T& value)
     {
     template<typename T>
     wxAny(const T& value)
     {
-        m_type = wxAnyValueTypeImpl<T>::sm_instance;
+        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)
     {
         wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
     }
 
     // These two constructors are needed to deal with string literals
     wxAny(const char* value)
     {
-        m_type = wxAnyValueTypeImpl<const char*>::sm_instance;
+        m_type = wxAnyValueTypeImpl<const char*>::sm_instance.get();
         wxAnyValueTypeImpl<const char*>::SetValue(value, m_buffer);
     }
     wxAny(const wchar_t* value)
     {
         wxAnyValueTypeImpl<const char*>::SetValue(value, m_buffer);
     }
     wxAny(const wchar_t* value)
     {
-        m_type = wxAnyValueTypeImpl<const wchar_t*>::sm_instance;
+        m_type = wxAnyValueTypeImpl<const wchar_t*>::sm_instance.get();
         wxAnyValueTypeImpl<const wchar_t*>::SetValue(value, m_buffer);
     }
 
         wxAnyValueTypeImpl<const wchar_t*>::SetValue(value, m_buffer);
     }
 
@@ -789,7 +815,7 @@ public:
     wxAny& operator=(const T &value)
     {
         m_type->DeleteValue(m_buffer);
     wxAny& operator=(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);
         return *this;
     }
         wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
         return *this;
     }
@@ -938,7 +964,7 @@ public:
         if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )
         {
             wxAnyValueType* otherType =
         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) )
             wxAnyValueBuffer temp_buf;
 
             if ( !m_type->ConvertValue(m_buffer, otherType, temp_buf) )
@@ -995,7 +1021,7 @@ private:
         else
         {
             // If everything else fails, wrap the whole wxVariantData
         else
         {
             // If everything else fails, wrap the whole wxVariantData
-            m_type = wxAnyValueTypeImpl<wxVariantData*>::sm_instance;
+            m_type = wxAnyValueTypeImpl<wxVariantData*>::sm_instance.get();
             wxAnyValueTypeImpl<wxVariantData*>::SetValue(data, m_buffer);
         }
     }
             wxAnyValueTypeImpl<wxVariantData*>::SetValue(data, m_buffer);
         }
     }
@@ -1005,7 +1031,7 @@ private:
     void Assign(const T &value)
     {
         m_type->DeleteValue(m_buffer);
     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);
     }
 
         wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
     }
 
index 79aed46067160defff177be8fb808a11682606d6..5136577dc59afec2e85e94c757ad2fe1155167a5 100644 (file)
 
 using namespace wxPrivate;
 
 
 using namespace wxPrivate;
 
+#if wxUSE_VARIANT
+
 //-------------------------------------------------------------------------
 // wxAnyValueTypeGlobals
 //-------------------------------------------------------------------------
 
 //-------------------------------------------------------------------------
 // wxAnyValueTypeGlobals
 //-------------------------------------------------------------------------
 
-#if wxUSE_VARIANT
-
 WX_DECLARE_HASH_MAP(wxAnyValueType*,
                     wxVariantDataFactory,
                     wxPointerHash,
                     wxPointerEqual,
                     wxAnyTypeToVariantDataFactoryMap);
 
 WX_DECLARE_HASH_MAP(wxAnyValueType*,
                     wxVariantDataFactory,
                     wxPointerHash,
                     wxPointerEqual,
                     wxAnyTypeToVariantDataFactoryMap);
 
-#endif
-
-WX_DECLARE_HASH_SET(wxAnyValueType*,
-                    wxPointerHash,
-                    wxPointerEqual,
-                    wxAnyValueTypePtrSet);
-
-//
-// Helper class to manage wxAnyValueType instances and and other
-// related global variables (such as wxAny<->wxVariant type association).
 //
 //
-// 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).
+// Helper class to manage global variables related to type conversion
+// between wxAny and wxVariant.
 //
 class wxAnyValueTypeGlobals
 {
 //
 class wxAnyValueTypeGlobals
 {
@@ -68,26 +56,9 @@ public:
     }
     ~wxAnyValueTypeGlobals()
     {
     }
     ~wxAnyValueTypeGlobals()
     {
-    #if wxUSE_VARIANT
         m_anyToVariant.clear();
         m_anyToVariant.clear();
-    #endif
-
-        wxAnyValueTypePtrSet::iterator it;
-        for ( it = m_valueTypes.begin(); it != m_valueTypes.end(); ++it )
-        {
-            delete *it;
-        }
-    }
-
-    void RegisterValueType(wxAnyValueType* valueType)
-    {
-        // Let's store value types in set to prevent deleting the same object
-        // several times (it may be possible, under certain conditions, that
-        // the same wxAnyValueType instance gets registered twice)
-        m_valueTypes.insert(valueType);
     }
 
     }
 
-#if wxUSE_VARIANT
     void PreRegisterAnyToVariant(wxAnyToVariantRegistration* reg)
     {
         m_anyToVariantRegs.push_back(reg);
     void PreRegisterAnyToVariant(wxAnyToVariantRegistration* reg)
     {
         m_anyToVariantRegs.push_back(reg);
@@ -144,19 +115,14 @@ public:
         // Nothing found
         return NULL;
     }
         // Nothing found
         return NULL;
     }
-#endif
 
 private:
 
 private:
-    wxAnyValueTypePtrSet                    m_valueTypes;
-#if wxUSE_VARIANT
     wxAnyTypeToVariantDataFactoryMap        m_anyToVariant;
     wxVector<wxAnyToVariantRegistration*>   m_anyToVariantRegs;
     wxAnyTypeToVariantDataFactoryMap        m_anyToVariant;
     wxVector<wxAnyToVariantRegistration*>   m_anyToVariantRegs;
-#endif
 };
 
 static wxAnyValueTypeGlobals* g_wxAnyValueTypeGlobals = NULL;
 
 };
 
 static wxAnyValueTypeGlobals* g_wxAnyValueTypeGlobals = NULL;
 
-#if wxUSE_VARIANT
 
 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplVariantData)
 
 
 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplVariantData)
 
@@ -239,8 +205,6 @@ bool wxConvertAnyToVariant(const wxAny& any, wxVariant* variant)
     return true;
 }
 
     return true;
 }
 
-#endif // wxUSE_VARIANT
-
 //
 // This class is to make sure that wxAnyValueType instances
 // etc. get freed correctly. We must use a separate wxAnyValueTypeGlobals
 //
 // This class is to make sure that wxAnyValueType instances
 // etc. get freed correctly. We must use a separate wxAnyValueTypeGlobals
@@ -267,18 +231,8 @@ private:
 
 IMPLEMENT_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager, wxModule)
 
 
 IMPLEMENT_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager, wxModule)
 
+#endif // wxUSE_VARIANT
 
 
-//-------------------------------------------------------------------------
-// wxAnyValueType
-//-------------------------------------------------------------------------
-
-wxAnyValueType::wxAnyValueType()
-{
-    if ( !g_wxAnyValueTypeGlobals )
-        g_wxAnyValueTypeGlobals = new wxAnyValueTypeGlobals();
-
-    g_wxAnyValueTypeGlobals->RegisterValueType(this);
-}
 
 //-------------------------------------------------------------------------
 // Dynamic conversion member functions
 
 //-------------------------------------------------------------------------
 // Dynamic conversion member functions