From a60b0ddc20fd5ffeb7f49a02f329a1fa291bba11 Mon Sep 17 00:00:00 2001
From: Robert Roebling <robert@roebling.de>
Date: Tue, 8 Jan 2008 22:02:12 +0000
Subject: [PATCH] Added the conversion to unspecfied_bool to all smart
 pointers, added T& operator* to wxObjectDataPtr

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@51118 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/latex/wx/objectdataptr.tex | 125 ++++++++++++++++----------------
 docs/latex/wx/scopedptr.tex     |   9 +++
 docs/latex/wx/sharedptr.tex     |   9 +++
 docs/latex/wx/weakref.tex       |  14 +++-
 include/wx/object.h             |  14 ++++
 include/wx/ptr_scpd.h           |   8 ++
 include/wx/ptr_shrd.h           |  12 ++-
 7 files changed, 128 insertions(+), 63 deletions(-)

diff --git a/docs/latex/wx/objectdataptr.tex b/docs/latex/wx/objectdataptr.tex
index f6777ff59c..cd2bbf81d9 100644
--- a/docs/latex/wx/objectdataptr.tex
+++ b/docs/latex/wx/objectdataptr.tex
@@ -1,11 +1,16 @@
 \section{\class{wxObjectDataPtr<T>}}\label{wxobjectdataptr}
 
-This is helper template class to avoid memleaks because of missing calls
-to \helpref{wxObjectRefData::DecRef}{wxobjectrefdatadecref}.
+This is helper template class primarily written to avoid memory 
+leaks because of missing calls to \helpref{wxObjectRefData::DecRef}{wxobjectrefdatadecref}.
 
-Despite the name this template can actually be used for any
-class implementing the reference counting interface and it
-does not use or depend on wxObject.
+Despite the name this template can actually be used as a
+smart pointer for any class implementing the reference
+counting interface and it does not use or depend on wxObject.
+
+The difference to \helpref{wxSharedPtr}{wxsharedptr} is that
+wxObjectDataPtr relies on the reference counting to be in
+the class pointed to where as wxSharedPtr implements the
+reference counting itself.
 
 \wxheading{See also}
 
@@ -13,6 +18,11 @@ does not use or depend on wxObject.
 \helpref{wxObjectRefData}{wxobjectrefdata},
 \helpref{Reference counting}{trefcount}
 
+\helpref{wxSharedPtr}{wxsharedptr}, 
+\helpref{wxScopedPtr}{wxscopedptrtemplate},
+\helpref{wxWeakRef}{wxweakref}
+
+
 \wxheading{Derived from}
 
 No base class
@@ -33,8 +43,6 @@ typedef T element_type
 
 \begin{verbatim}
 
-// include file
-
 class MyCarRefData: public wxObjectRefData
 {
 public:
@@ -46,11 +54,6 @@ public:
         m_price = data.m_price;
     }
 
-    bool operator == (const MyCarRefData& data) const
-    {
-        return m_price == data.m_price;
-    }
-    
     void SetPrice( int price )  { m_price = price; }
     int GetPrice()              { return m_price; }
     
@@ -61,61 +64,45 @@ protected:
 class MyCar
 {
 public:
-    MyCar( int price );
-    MyCar( const MyCar& data );
+    MyCar( int price ) : m_data( new MyCarRefData )
+    {
+        m_data->SetPrice( price );
+    }
+    
+    MyCar& operator =( const MyCar& tocopy )
+    {
+        m_data = tocopy.m_data;
+        return *this;
+    }
     
-    bool operator == ( const MyCar& car ) const;
-    bool operator != (const MyCar& car) const { return !(*this == car); }
+    bool operator == ( const MyCar& other ) const
+    {
+        if (m_data.get() == other.m_data.get()) return true;
+        return (m_data->GetPrice() == other.m_data->GetPrice());
+    }
 
-    void SetPrice( int price );
-    int GetPrice() const;
+    void SetPrice( int price )
+    {
+       UnShare();
+       m_data->SetPrice( price );
+    }
+    
+    int GetPrice() const
+    {
+       return m_data->GetPrice();
+    }
 
-    wxObjectRefPtr<MyCarRefData> m_data;
+    wxObjectDataPtr<MyCarRefData> m_data;
     
 protected:
-    void UnShare();
-};
-
-
-// implementation
-
-MyCar::MyCar( int price )
-{
-    m_data = new MyCarRefData;
-    m_data.get()->SetPrice( price );
-}
-
-MyCar::MyCar( const MyCar& car )
-{
-    m_data.reset( car.m_data.get() );
-}
-
-bool MyCar::operator == ( const MyCar& car ) const
-{
-    if (m_data.get() == car.m_data.get()) return true;
-
-    return (*m_data.get() == *car.m_data.get());
-}
-
-void MyCar::SetPrice( int price )
-{
-    UnShare();
-        
-    m_data.get()->SetPrice( price );
-}
-
-int MyCar::GetPrice() const
-{
-    return m_data.get()->GetPrice();
-}
-
-void MyCar::UnShare()
-{
-    if (m_data.get()->GetCount() == 1)
-        return;
+    void UnShare()
+    {
+        if (m_data->GetRefCount() == 1)
+            return;
     
-    m_data.reset( new MyCarRefData( *m_data.get() ) );
-}
+        m_data.reset( new MyCarRefData( *m_data ) );
+    }
+};
 
 \end{verbatim}
 
@@ -142,6 +129,22 @@ class will point to, as well.
 Calls \helpref{DecRef}{wxobjectrefdatadecref} on the reference
 counted object to which this class points.
 
+\membersection{wxObjectDataPtr<T>::operator unspecified\_bool\_type}\label{wxobjectdataptroperatorbool}
+
+\constfunc{}{operator unspecified\_bool\_type}{\void}
+
+Conversion to a boolean expression (in a variant which is not 
+convertable to anything but a boolean expression). If this class
+contains a valid pointer it will return {\it true}, if it contains
+a NULL pointer it will return {\it false}.
+
+\membersection{wxObjectDataPtr<T>::operator*}\label{wxobjectdataptroperatorreft}
+
+\constfunc{T \&}{operator*}{\void}
+
+Returns a reference to the object. If the internal pointer is NULL
+this method will cause an assert in debug mode.
+
 \membersection{wxObjectDataPtr<T>::operator->}\label{wxobjectdataptroperatorpointer}
 
 \constfunc{T*}{operator->}{\void}
diff --git a/docs/latex/wx/scopedptr.tex b/docs/latex/wx/scopedptr.tex
index 0e2e980518..2ceddcf6ef 100644
--- a/docs/latex/wx/scopedptr.tex
+++ b/docs/latex/wx/scopedptr.tex
@@ -44,6 +44,15 @@ Destructor.
 
 Returns pointer to object or NULL.
 
+\membersection{wxScopedPtr<T>::operator unspecified\_bool\_type}\label{wxscopedptrtemplateoperatorbool}
+
+\constfunc{}{operator unspecified\_bool\_type}{\void}
+
+Conversion to a boolean expression (in a variant which is not 
+convertable to anything but a boolean expression). If this class
+contains a valid pointer it will return {\it true}, if it contains
+a NULL pointer it will return {\it false}.
+
 \membersection{wxScopedPtr<T>::operator*}\label{wxscopedptrtemplateoperatorreft}
 
 \constfunc{T \&}{operator*}{\void}
diff --git a/docs/latex/wx/sharedptr.tex b/docs/latex/wx/sharedptr.tex
index 840b54cba2..6edf72a5c9 100644
--- a/docs/latex/wx/sharedptr.tex
+++ b/docs/latex/wx/sharedptr.tex
@@ -49,6 +49,15 @@ Destructor.
 
 Returns pointer to its object or NULL.
 
+\membersection{wxSharedPtr<T>::operator unspecified\_bool\_type}\label{wxsharedptroperatorbool}
+
+\constfunc{}{operator unspecified\_bool\_type}{\void}
+
+Conversion to a boolean expression (in a variant which is not 
+convertable to anything but a boolean expression). If this class
+contains a valid pointer it will return {\it true}, if it contains
+a NULL pointer it will return {\it false}.
+
 \membersection{wxSharedPtr<T>::operator*}\label{wxsharedptroperatorreft}
 
 \constfunc{T\&}{operator*}{\void}
diff --git a/docs/latex/wx/weakref.tex b/docs/latex/wx/weakref.tex
index 1276850cca..de989942c5 100644
--- a/docs/latex/wx/weakref.tex
+++ b/docs/latex/wx/weakref.tex
@@ -50,7 +50,6 @@ difference between the two base classes is that wxTrackableBase
 has no virtual member functions (no VTable), and thus cannot be detected
 through \texttt{dynamic\_cast<>}.
 
-
 \wxheading{Predefined types}
 
 The following types of weak references are predefined: 
@@ -70,6 +69,10 @@ wxTrackerNode
 
 <weakref.h>
 
+\wxheading{See also}
+
+\helpref{wxSharedPtr}{wxsharedptr}, \helpref{wxScopedPtr}{wxscopedptrtemplate}
+
 \wxheading{Data structures}
 
 {\small% 
@@ -102,6 +105,15 @@ Destructor.
 
 Returns pointer to the tracked object or NULL.
 
+\membersection{wxWeakRef<T>::operator unspecified\_bool\_type}\label{wxweakrefoperatorbool}
+
+\constfunc{}{operator unspecified\_bool\_type}{\void}
+
+Conversion to a boolean expression (in a variant which is not 
+convertable to anything but a boolean expression). If this class
+contains a valid pointer it will return {\it true}, if it contains
+a NULL pointer it will return {\it false}.
+
 
 \membersection{wxWeakRef<T>::operator*}\label{wxweakrefoperatorreft}
 
diff --git a/include/wx/object.h b/include/wx/object.h
index df40c11d43..88297d21b8 100644
--- a/include/wx/object.h
+++ b/include/wx/object.h
@@ -457,6 +457,20 @@ public:
 
     T *get() const { return m_ptr; }
     
+    // test for pointer validity: defining conversion to unspecified_bool_type
+    // and not more obvious bool to avoid implicit conversions to integer types
+    typedef T *(wxObjectDataPtr<T>::*unspecified_bool_type)() const;
+    operator unspecified_bool_type() const
+    {
+        return m_ptr ? &wxObjectDataPtr<T>::get : NULL;
+    }
+
+    T& operator*() const
+    { 
+        wxASSERT(m_ptr != NULL);    
+        return *(m_ptr);
+    }
+    
     T *operator->() const
     { 
         wxASSERT(m_ptr != NULL);    
diff --git a/include/wx/ptr_scpd.h b/include/wx/ptr_scpd.h
index 100e6bdd0a..2ae40220c9 100644
--- a/include/wx/ptr_scpd.h
+++ b/include/wx/ptr_scpd.h
@@ -55,6 +55,14 @@ public:
            delete m_ptr;
     }
                                     
+    // test for pointer validity: defining conversion to unspecified_bool_type
+    // and not more obvious bool to avoid implicit conversions to integer types
+    typedef T *(wxScopedPtr<T>::*unspecified_bool_type)() const;
+    operator unspecified_bool_type() const
+    {
+        return m_ptr ? &wxScopedPtr<T>::get : NULL;
+    }
+
     void reset(T * ptr = NULL)      
     {                               
         if (m_ptr != ptr)           
diff --git a/include/wx/ptr_shrd.h b/include/wx/ptr_shrd.h
index f90f4ec8b1..71492d9754 100644
--- a/include/wx/ptr_shrd.h
+++ b/include/wx/ptr_shrd.h
@@ -55,6 +55,17 @@ public:
         return *this;
     }
 
+    // test for pointer validity: defining conversion to unspecified_bool_type
+    // and not more obvious bool to avoid implicit conversions to integer types
+    typedef T *(wxSharedPtr<T>::*unspecified_bool_type)() const;
+    operator unspecified_bool_type() const
+    {
+        if (m_ref && m_ref->m_ptr)
+           return  &wxSharedPtr<T>::get;
+        else
+           return NULL;
+    }
+
     T& operator*() const
     { 
         wxASSERT(m_ref != NULL);    
@@ -83,7 +94,6 @@ public:
     
     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:
 
-- 
2.45.2

