]> git.saurik.com Git - wxWidgets.git/blame - include/wx/sharedptr.h
simpler implementation that also works over remote connections by Kevin O.
[wxWidgets.git] / include / wx / sharedptr.h
CommitLineData
5200ca36 1/////////////////////////////////////////////////////////////////////////////
664e1314 2// Name: wx/sharedptr.h
5200ca36
RR
3// Purpose: Shared pointer based on the counted_ptr<> template, which
4// is in the public domain
5// Author: Robert Roebling, Yonat Sharon
a9a4f229 6// RCS-ID: $Id$
5200ca36
RR
7// Copyright: Robert Roebling
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
664e1314
VZ
11#ifndef _WX_SHAREDPTR_H_
12#define _WX_SHAREDPTR_H_
5200ca36
RR
13
14#include "wx/defs.h"
15#include "wx/atomic.h"
16
17// ----------------------------------------------------------------------------
18// wxSharedPtr: A smart pointer with non-intrusive reference counting.
19// ----------------------------------------------------------------------------
20
664e1314 21template <class T>
5200ca36
RR
22class wxSharedPtr
23{
24public:
25 typedef T element_type;
26
27 wxEXPLICIT wxSharedPtr( T* ptr = NULL )
664e1314
VZ
28 : m_ref(NULL)
29 {
30 if (ptr)
31 m_ref = new reftype(ptr);
5200ca36 32 }
664e1314 33
5200ca36
RR
34 ~wxSharedPtr() { Release(); }
35 wxSharedPtr(const wxSharedPtr& tocopy) { Acquire(tocopy.m_ref); }
664e1314 36
5200ca36
RR
37 wxSharedPtr& operator=( const wxSharedPtr& tocopy )
38 {
664e1314 39 if (this != &tocopy)
5200ca36
RR
40 {
41 Release();
42 Acquire(tocopy.m_ref);
43 }
44 return *this;
45 }
46
47 wxSharedPtr& operator=( T* ptr )
48 {
664e1314 49 if (get() != ptr)
5200ca36
RR
50 {
51 Release();
664e1314
VZ
52 if (ptr)
53 m_ref = new reftype(ptr);
5200ca36
RR
54 }
55 return *this;
56 }
57
a60b0ddc
RR
58 // test for pointer validity: defining conversion to unspecified_bool_type
59 // and not more obvious bool to avoid implicit conversions to integer types
60 typedef T *(wxSharedPtr<T>::*unspecified_bool_type)() const;
61 operator unspecified_bool_type() const
62 {
63 if (m_ref && m_ref->m_ptr)
64 return &wxSharedPtr<T>::get;
65 else
66 return NULL;
67 }
68
5200ca36 69 T& operator*() const
664e1314
VZ
70 {
71 wxASSERT(m_ref != NULL);
72 wxASSERT(m_ref->m_ptr != NULL);
5200ca36
RR
73 return *(m_ref->m_ptr);
74 }
664e1314 75
5200ca36 76 T* operator->() const
664e1314
VZ
77 {
78 wxASSERT(m_ref != NULL);
79 wxASSERT(m_ref->m_ptr != NULL);
5200ca36
RR
80 return m_ref->m_ptr;
81 }
664e1314
VZ
82
83 T* get() const
84 {
85 return m_ref ? m_ref->m_ptr : NULL;
5200ca36 86 }
664e1314 87
5200ca36
RR
88 void reset( T* ptr = NULL )
89 {
90 Release();
664e1314
VZ
91 if (ptr)
92 m_ref = new reftype(ptr);
5200ca36 93 }
664e1314 94
5200ca36
RR
95 bool unique() const { return (m_ref ? m_ref->m_count == 1 : true); }
96 long use_count() const { return (m_ref ? (long)m_ref->m_count : 0); }
5200ca36
RR
97
98private:
99
664e1314 100 struct reftype
5200ca36
RR
101 {
102 reftype( T* ptr = NULL, unsigned count = 1 ) : m_ptr(ptr), m_count(count) {}
103 T* m_ptr;
104 wxAtomicInt m_count;
105 }* m_ref;
106
664e1314 107 void Acquire(reftype* ref)
5200ca36
RR
108 {
109 m_ref = ref;
664e1314 110 if (ref)
5200ca36
RR
111 wxAtomicInc( ref->m_count );
112 }
113
114 void Release()
115 {
664e1314 116 if (m_ref)
5200ca36
RR
117 {
118 wxAtomicDec( m_ref->m_count );
664e1314 119 if (m_ref->m_count == 0)
5200ca36
RR
120 {
121 delete m_ref->m_ptr;
122 delete m_ref;
123 }
124 m_ref = NULL;
125 }
126 }
127};
128
129template <class T, class U>
130bool operator == (wxSharedPtr<T> const &a, wxSharedPtr<U> const &b )
131{
132 return a.get() == b.get();
133}
134
135template <class T, class U>
136bool operator != (wxSharedPtr<T> const &a, wxSharedPtr<U> const &b )
137{
138 return a.get() != b.get();
139}
140
664e1314 141#endif // _WX_SHAREDPTR_H_