]> git.saurik.com Git - wxWidgets.git/blame - include/wx/sharedptr.h
Make storing non-trivial data in wxThreadSpecificInfo possible.
[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
5200ca36
RR
6// Copyright: Robert Roebling
7// Licence: wxWindows licence
8/////////////////////////////////////////////////////////////////////////////
9
664e1314
VZ
10#ifndef _WX_SHAREDPTR_H_
11#define _WX_SHAREDPTR_H_
5200ca36
RR
12
13#include "wx/defs.h"
14#include "wx/atomic.h"
15
16// ----------------------------------------------------------------------------
17// wxSharedPtr: A smart pointer with non-intrusive reference counting.
18// ----------------------------------------------------------------------------
19
664e1314 20template <class T>
5200ca36
RR
21class wxSharedPtr
22{
23public:
24 typedef T element_type;
25
26 wxEXPLICIT wxSharedPtr( T* ptr = NULL )
664e1314
VZ
27 : m_ref(NULL)
28 {
29 if (ptr)
30 m_ref = new reftype(ptr);
5200ca36 31 }
664e1314 32
4852df90
VS
33 template<typename Deleter>
34 wxEXPLICIT wxSharedPtr(T* ptr, Deleter d)
35 : m_ref(NULL)
36 {
37 if (ptr)
38 m_ref = new reftype_with_deleter<Deleter>(ptr, d);
39 }
40
5200ca36
RR
41 ~wxSharedPtr() { Release(); }
42 wxSharedPtr(const wxSharedPtr& tocopy) { Acquire(tocopy.m_ref); }
664e1314 43
5200ca36
RR
44 wxSharedPtr& operator=( const wxSharedPtr& tocopy )
45 {
664e1314 46 if (this != &tocopy)
5200ca36
RR
47 {
48 Release();
49 Acquire(tocopy.m_ref);
50 }
51 return *this;
52 }
53
54 wxSharedPtr& operator=( T* ptr )
55 {
664e1314 56 if (get() != ptr)
5200ca36
RR
57 {
58 Release();
664e1314
VZ
59 if (ptr)
60 m_ref = new reftype(ptr);
5200ca36
RR
61 }
62 return *this;
63 }
64
a60b0ddc
RR
65 // test for pointer validity: defining conversion to unspecified_bool_type
66 // and not more obvious bool to avoid implicit conversions to integer types
67 typedef T *(wxSharedPtr<T>::*unspecified_bool_type)() const;
68 operator unspecified_bool_type() const
69 {
70 if (m_ref && m_ref->m_ptr)
71 return &wxSharedPtr<T>::get;
72 else
73 return NULL;
74 }
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 82
5200ca36 83 T* operator->() const
664e1314
VZ
84 {
85 wxASSERT(m_ref != NULL);
86 wxASSERT(m_ref->m_ptr != NULL);
5200ca36
RR
87 return m_ref->m_ptr;
88 }
664e1314
VZ
89
90 T* get() const
91 {
92 return m_ref ? m_ref->m_ptr : NULL;
5200ca36 93 }
664e1314 94
5200ca36
RR
95 void reset( T* ptr = NULL )
96 {
97 Release();
664e1314
VZ
98 if (ptr)
99 m_ref = new reftype(ptr);
5200ca36 100 }
664e1314 101
4852df90
VS
102 template<typename Deleter>
103 void reset(T* ptr, Deleter d)
104 {
105 Release();
106 if (ptr)
107 m_ref = new reftype_with_deleter<Deleter>(ptr, d);
108 }
109
5200ca36
RR
110 bool unique() const { return (m_ref ? m_ref->m_count == 1 : true); }
111 long use_count() const { return (m_ref ? (long)m_ref->m_count : 0); }
5200ca36
RR
112
113private:
114
664e1314 115 struct reftype
5200ca36 116 {
4852df90
VS
117 reftype(T* ptr) : m_ptr(ptr), m_count(1) {}
118 virtual ~reftype() {}
119 virtual void delete_ptr() { delete m_ptr; }
120
5200ca36
RR
121 T* m_ptr;
122 wxAtomicInt m_count;
4852df90
VS
123 };
124
125 template<typename Deleter>
126 struct reftype_with_deleter : public reftype
127 {
128 reftype_with_deleter(T* ptr, Deleter d) : reftype(ptr), m_deleter(d) {}
129 virtual void delete_ptr() { m_deleter(this->m_ptr); }
130
131 Deleter m_deleter;
132 };
133
134 reftype* m_ref;
5200ca36 135
664e1314 136 void Acquire(reftype* ref)
5200ca36
RR
137 {
138 m_ref = ref;
664e1314 139 if (ref)
5200ca36
RR
140 wxAtomicInc( ref->m_count );
141 }
142
143 void Release()
144 {
664e1314 145 if (m_ref)
5200ca36 146 {
43003176 147 if (!wxAtomicDec( m_ref->m_count ))
5200ca36 148 {
4852df90 149 m_ref->delete_ptr();
5200ca36
RR
150 delete m_ref;
151 }
152 m_ref = NULL;
153 }
154 }
155};
156
157template <class T, class U>
158bool operator == (wxSharedPtr<T> const &a, wxSharedPtr<U> const &b )
159{
160 return a.get() == b.get();
161}
162
163template <class T, class U>
164bool operator != (wxSharedPtr<T> const &a, wxSharedPtr<U> const &b )
165{
166 return a.get() != b.get();
167}
168
664e1314 169#endif // _WX_SHAREDPTR_H_