From 5200ca361e9edef8b7c075f8989b2dbe9c4c7ad8 Mon Sep 17 00:00:00 2001
From: Robert Roebling <robert@roebling.de>
Date: Tue, 8 Jan 2008 10:51:28 +0000
Subject: [PATCH] Added wxSharedPtr<T>

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@51102 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 build/bakefiles/files.bkl  |   2 +
 docs/latex/wx/category.tex |   3 +-
 docs/latex/wx/classes.tex  |   1 +
 include/wx/ptr_shrd.h      | 133 +++++++++++++++++++++++++++++++++++++
 4 files changed, 138 insertions(+), 1 deletion(-)
 create mode 100644 include/wx/ptr_shrd.h

diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl
index 01b133293c..6d3decf75f 100644
--- a/build/bakefiles/files.bkl
+++ b/build/bakefiles/files.bkl
@@ -507,6 +507,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
     wx/power.h
     wx/process.h
     wx/ptr_scpd.h
+    wx/ptr_shrd.h
     wx/recguard.h
     wx/regex.h
     wx/scopeguard.h
@@ -935,6 +936,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
     wx/prntbase.h
     wx/progdlg.h
     wx/ptr_scpd.h
+    wx/ptr_shrd.h
     wx/quantize.h
     wx/rawbmp.h
     wx/region.h
diff --git a/docs/latex/wx/category.tex b/docs/latex/wx/category.tex
index 1af5871f2a..a6d91d76af 100644
--- a/docs/latex/wx/category.tex
+++ b/docs/latex/wx/category.tex
@@ -382,8 +382,9 @@ wxWidgets provides a few smart pointer class templates.
 
 \twocolwidtha{6cm}
 \begin{twocollist}\itemsep=0pt
-\twocolitem{\helpref{wxObjectDataPtr<T>}{wxobjectdataptr}}{A shared pointer using intrusive reference counting}
+\twocolitem{\helpref{wxObjectDataPtr<T>}{wxobjectdataptr}}{A shared pointer (using intrusive reference counting)}
 \twocolitem{\helpref{wxScopedPtr<T>}{wxscopedptrtemplate}}{A scoped pointer}
+\twocolitem{\helpref{wxSharedPtr<T>}{wxsharedptr}}{A shared pointer (using non-intrusive reference counting)}
 \twocolitem{\helpref{wxWeakRef<T>}{wxweakref}}{A weak reference}
 \end{twocollist}
 
diff --git a/docs/latex/wx/classes.tex b/docs/latex/wx/classes.tex
index 055a5b3309..e270a4397b 100644
--- a/docs/latex/wx/classes.tex
+++ b/docs/latex/wx/classes.tex
@@ -371,6 +371,7 @@
 \input srchctrl.tex
 \input sngchdlg.tex
 \input snglinst.tex
+\input sharedptr.tex
 \input size.tex
 \input sizeevt.tex
 \input sizer.tex
diff --git a/include/wx/ptr_shrd.h b/include/wx/ptr_shrd.h
new file mode 100644
index 0000000000..f90f4ec8b1
--- /dev/null
+++ b/include/wx/ptr_shrd.h
@@ -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__
-- 
2.50.0

