]> git.saurik.com Git - wxWidgets.git/commitdiff
Add basic deleter support to wxSharedPtr<T>.
authorVáclav Slavík <vslavik@fastmail.fm>
Fri, 6 Sep 2013 17:09:11 +0000 (17:09 +0000)
committerVáclav Slavík <vslavik@fastmail.fm>
Fri, 6 Sep 2013 17:09:11 +0000 (17:09 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74773 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/sharedptr.h
interface/wx/sharedptr.h

index c6b28f81a6e584185b829ca104891d1a2ee1e82f..a9b6442c09b52a8cc22dda34759aac8a153eb3d2 100644 (file)
@@ -30,6 +30,14 @@ public:
             m_ref = new reftype(ptr);
     }
 
+    template<typename Deleter>
+    wxEXPLICIT wxSharedPtr(T* ptr, Deleter d)
+        : m_ref(NULL)
+    {
+        if (ptr)
+            m_ref = new reftype_with_deleter<Deleter>(ptr, d);
+    }
+
     ~wxSharedPtr()                           { Release(); }
     wxSharedPtr(const wxSharedPtr& tocopy)   { Acquire(tocopy.m_ref); }
 
@@ -91,6 +99,14 @@ public:
             m_ref = new reftype(ptr);
     }
 
+    template<typename Deleter>
+    void reset(T* ptr, Deleter d)
+    {
+        Release();
+        if (ptr)
+            m_ref = new reftype_with_deleter<Deleter>(ptr, d);
+    }
+
     bool unique()   const    { return (m_ref ? m_ref->m_count == 1 : true); }
     long use_count() const   { return (m_ref ? (long)m_ref->m_count : 0); }
 
@@ -98,10 +114,24 @@ private:
 
     struct reftype
     {
-        reftype( T* ptr = NULL, unsigned count = 1 ) : m_ptr(ptr), m_count(count) {}
+        reftype(T* ptr) : m_ptr(ptr), m_count(1) {}
+        virtual ~reftype() {}
+        virtual void delete_ptr() { delete m_ptr; }
+
         T*          m_ptr;
         wxAtomicInt m_count;
-    }* m_ref;
+    };
+
+    template<typename Deleter>
+    struct reftype_with_deleter : public reftype
+    {
+        reftype_with_deleter(T* ptr, Deleter d) : reftype(ptr), m_deleter(d) {}
+        virtual void delete_ptr() { m_deleter(this->m_ptr); }
+
+        Deleter m_deleter;
+    };
+
+    reftype* m_ref;
 
     void Acquire(reftype* ref)
     {
@@ -116,7 +146,7 @@ private:
         {
             if (!wxAtomicDec( m_ref->m_count ))
             {
-                delete m_ref->m_ptr;
+                m_ref->delete_ptr();
                 delete m_ref;
             }
             m_ref = NULL;
index f3c2131c3504490f1a53b841c54e4228c49b1080..8b7087baed8e85c0245919d63f66642cc05d2127 100644 (file)
@@ -28,6 +28,22 @@ public:
     */
     wxEXPLICIT wxSharedPtr(T* ptr = NULL);
 
+    /**
+        Constructor.
+
+        Creates shared pointer from the raw pointer @a ptr and deleter @a d
+        and takes ownership of it.
+
+        @param ptr  The raw pointer.
+        @param d    Deleter - a functor that is called instead of delete to
+                    free the @a ptr raw pointer when its reference count drops to
+                    zero.
+
+        @since 3.0
+    */
+    template<typename Deleter>
+    wxEXPLICIT wxSharedPtr(T* ptr, Deleter d);
+
     /**
         Copy constructor.
     */
@@ -88,6 +104,21 @@ public:
     */
     void reset(T* ptr = NULL);
 
+    /**
+        Reset pointer to @a ptr.
+
+        If the reference count of the previously owned pointer was 1 it will be deleted.
+
+        @param ptr  The new raw pointer.
+        @param d    Deleter - a functor that is called instead of delete to
+                    free the @a ptr raw pointer when its reference count drops to
+                    zero.
+
+        @since 3.0
+    */
+    template<typename Deleter>
+    void reset(T* ptr, Deleter d);
+
     /**
         Returns @true if this is the only pointer pointing to its object.
     */