]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/ptr_shrd.h
Added wxSharedPtr<T>
[wxWidgets.git] / include / wx / ptr_shrd.h
diff --git a/include/wx/ptr_shrd.h b/include/wx/ptr_shrd.h
new file mode 100644 (file)
index 0000000..f90f4ec
--- /dev/null
@@ -0,0 +1,133 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        wx/ptr_shrd.h
+// Purpose:     Shared pointer based on the counted_ptr<> template, which
+//              is in the public domain
+// Author:      Robert Roebling, Yonat Sharon
+// RCS-ID:      $Id: object.h 47254 2007-07-09 10:09:52Z VS $
+// Copyright:   Robert Roebling
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_SHARED_PTRH__
+#define _WX_SHARED_PTRH__
+
+#include "wx/defs.h"
+#include "wx/atomic.h"
+
+// ----------------------------------------------------------------------------
+// wxSharedPtr: A smart pointer with non-intrusive reference counting.
+// ----------------------------------------------------------------------------
+
+template <class T> 
+class wxSharedPtr
+{
+public:
+    typedef T element_type;
+
+    wxEXPLICIT wxSharedPtr( T* ptr = NULL )
+        : m_ref(NULL) 
+    { 
+        if (ptr) 
+            m_ref = new reftype(ptr); 
+    }
+        
+    ~wxSharedPtr()                           { Release(); }
+    wxSharedPtr(const wxSharedPtr& tocopy)   { Acquire(tocopy.m_ref); }
+    
+    wxSharedPtr& operator=( const wxSharedPtr& tocopy )
+    {
+        if (this != &tocopy) 
+        {
+            Release();
+            Acquire(tocopy.m_ref);
+        }
+        return *this;
+    }
+
+    wxSharedPtr& operator=( T* ptr )
+    {
+        if (get() != ptr) 
+        {
+            Release();
+            if (ptr) 
+                m_ref = new reftype(ptr); 
+        }
+        return *this;
+    }
+
+    T& operator*() const
+    { 
+        wxASSERT(m_ref != NULL);    
+        wxASSERT(m_ref->m_ptr != NULL);    
+        return *(m_ref->m_ptr);
+    }
+    
+    T* operator->() const
+    { 
+        wxASSERT(m_ref != NULL);    
+        wxASSERT(m_ref->m_ptr != NULL);    
+        return m_ref->m_ptr;
+    }
+    
+    T* get() const    
+    { 
+        return m_ref ? m_ref->m_ptr : NULL; 
+    }
+    
+    void reset( T* ptr = NULL )
+    {
+        Release();
+        if (ptr) 
+            m_ref = new reftype(ptr); 
+    }
+    
+    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); }
+    operator bool() const    { return (get() != NULL); }
+
+private:
+
+    struct reftype 
+    {
+        reftype( T* ptr = NULL, unsigned count = 1 ) : m_ptr(ptr), m_count(count) {}
+        T*          m_ptr;
+        wxAtomicInt m_count;
+    }* m_ref;
+
+    void Acquire(reftype* ref) 
+    {
+        m_ref = ref;
+        if (ref) 
+            wxAtomicInc( ref->m_count );
+    }
+
+    void Release()
+    {
+        if (m_ref) 
+        {
+            wxAtomicDec( m_ref->m_count );
+            if (m_ref->m_count == 0) 
+            {
+                delete m_ref->m_ptr;
+                delete m_ref;
+            }
+            m_ref = NULL;
+        }
+    }
+};
+
+template <class T, class U>
+bool operator == (wxSharedPtr<T> const &a, wxSharedPtr<U> const &b )
+{
+    return a.get() == b.get();
+}
+
+template <class T, class U>
+bool operator != (wxSharedPtr<T> const &a, wxSharedPtr<U> const &b )
+{
+    return a.get() != b.get();
+}
+
+
+
+#endif // _WX_SHARED_PTRH__