Pol  Revision:3cfda13
refptr.h
Go to the documentation of this file.
1 
10 //
12 // Copyright (c) 1997 Software Masters
13 // All rights reserved
14 //
16 
17 #ifndef __REFPTR_H
18 #define __REFPTR_H
19 
20 #include "compilerspecifics.h"
21 
22 #include <atomic>
23 
24 // **** base class for ref counted classes
25 
26 #define REFPTR_DEBUG 0
27 
28 #define REFERER_PARAM( x )
29 
31 {
32  // Construction
33 protected:
34  ref_counted();
35 
36 public:
37  // Operations
38  unsigned int add_ref();
39  unsigned int release();
40  unsigned int count() const;
41 #if REFPTR_DEBUG
42  unsigned int instance() const;
43 #endif
44  // Representation
45 protected:
46  std::atomic<unsigned int> _count;
47 #if REFPTR_DEBUG
48  unsigned int _cumulative_references;
49  unsigned int _instance;
50  static unsigned int _ctor_calls;
51 #endif
52 
53 private: // not implemented
55  ref_counted( const ref_counted& );
56 };
57 
58 // **** ref_ptr class, assuming T implements ref_counted interface
59 #if REFPTR_DEBUG
60 extern unsigned int refptr_count;
61 #endif
62 
63 template <class T>
64 class ref_ptr
65 {
66  // Construction
67 public:
68  explicit ref_ptr( T* ptr = 0 );
69  ref_ptr( const ref_ptr& rptr );
70  ref_ptr( ref_ptr&& rptr ) POL_NOEXCEPT;
71  ~ref_ptr();
72 
73  // Operations
74  T* get() const;
75  T* operator->() const;
76  T& operator*() const;
77 
78  bool operator!() const;
79  bool operator==( const ref_ptr& rptr ) const;
80  bool operator!=( const ref_ptr& rptr ) const;
81  bool operator<( const ref_ptr& rptr ) const;
82  bool operator<=( const ref_ptr& rptr ) const;
83  bool operator>( const ref_ptr& rptr ) const;
84  bool operator>=( const ref_ptr& rptr ) const;
85 
86  bool operator==( T* ptr ) const;
87  bool operator!=( T* ptr ) const;
88  bool operator<( T* ptr ) const;
89  bool operator<=( T* ptr ) const;
90  bool operator>( T* ptr ) const;
91  bool operator>=( T* ptr ) const;
92 
93  ref_ptr& operator=( const ref_ptr& rptr );
94  ref_ptr& operator=( ref_ptr&& rptr );
95 
96  void set( T* ptr );
97  void clear();
98 
99 protected:
100  void add_ref();
101  void release();
102 
103  // Representation
104 private:
105  std::atomic<T*> _ptr;
106 };
107 
109  : _count( 0 )
110 #if REFPTR_DEBUG
111  ,
112  _cumulative_references( 0 ),
113  _instance( ++_ctor_calls )
114 #endif
115 {
116 }
117 
118 inline unsigned int ref_counted::add_ref()
119 {
120 #if REFPTR_DEBUG
121  ++_cumulative_references;
122 #endif
123  return ++_count;
124 }
125 inline unsigned int ref_counted::release()
126 {
127  return --_count;
128 }
129 inline unsigned int ref_counted::count() const
130 {
131  return _count;
132 }
133 #if REFPTR_DEBUG
134 inline unsigned int ref_counted::instance() const
135 {
136  return _instance;
137 }
138 #endif
139 
140 template <class T>
141 ref_ptr<T>::ref_ptr( T* ptr ) : _ptr( ptr )
142 {
143  add_ref();
144 #if REFPTR_DEBUG
145  ++refptr_count;
146 #endif
147 }
148 template <class T>
149 ref_ptr<T>::ref_ptr( const ref_ptr& rptr ) : _ptr( rptr.get() )
150 {
151  add_ref();
152 #if REFPTR_DEBUG
153  ++refptr_count;
154 #endif
155 }
156 
157 template <class T>
158 ref_ptr<T>::ref_ptr( ref_ptr&& rptr ) POL_NOEXCEPT : _ptr( rptr._ptr.exchange( nullptr ) )
159 {
160 #if REFPTR_DEBUG
161  --refptr_count;
162 #endif
163 }
164 
165 template <class T>
167 {
168 #if REFPTR_DEBUG
169  --refptr_count;
170 #endif
171  release();
172 }
173 
174 template <class T>
175 T* ref_ptr<T>::get() const
176 {
177  return _ptr;
178 }
179 template <class T>
181 {
182  return _ptr;
183 }
184 template <class T>
186 {
187  return *_ptr;
188 }
189 
190 template <class T>
192 {
193  return get() == 0;
194 }
195 template <class T>
196 bool ref_ptr<T>::operator==( const ref_ptr<T>& rptr ) const
197 {
198  return get() == rptr.get();
199 }
200 template <class T>
201 bool ref_ptr<T>::operator!=( const ref_ptr<T>& rptr ) const
202 {
203  return get() != rptr.get();
204 }
205 template <class T>
206 bool ref_ptr<T>::operator<( const ref_ptr<T>& rptr ) const
207 {
208  return get() < rptr.get();
209 }
210 template <class T>
211 bool ref_ptr<T>::operator<=( const ref_ptr<T>& rptr ) const
212 {
213  return get() <= rptr.get();
214 }
215 template <class T>
216 bool ref_ptr<T>::operator>( const ref_ptr<T>& rptr ) const
217 {
218  return get() > rptr.get();
219 }
220 template <class T>
221 bool ref_ptr<T>::operator>=( const ref_ptr<T>& rptr ) const
222 {
223  return get() >= rptr.get();
224 }
225 
226 template <class T>
227 bool ref_ptr<T>::operator==( T* ptr ) const
228 {
229  return get() == ptr;
230 }
231 template <class T>
232 bool ref_ptr<T>::operator!=( T* ptr ) const
233 {
234  return get() != ptr;
235 }
236 template <class T>
237 bool ref_ptr<T>::operator<( T* ptr ) const
238 {
239  return get() < ptr;
240 }
241 template <class T>
242 bool ref_ptr<T>::operator<=( T* ptr ) const
243 {
244  return get() <= ptr;
245 }
246 template <class T>
247 bool ref_ptr<T>::operator>( T* ptr ) const
248 {
249  return get() > ptr;
250 }
251 template <class T>
252 bool ref_ptr<T>::operator>=( T* ptr ) const
253 {
254  return get() >= ptr;
255 }
256 template <class T>
258 {
259  release();
260  _ptr = rptr.get();
261  add_ref();
262 
263  return *this;
264 }
265 
266 template <class T>
268 {
269  release();
270  _ptr = rptr._ptr.exchange( nullptr );
271  return *this;
272 }
273 
274 template <class T>
275 void ref_ptr<T>::set( T* ptr )
276 {
277  release();
278  _ptr = ptr;
279  add_ref();
280 }
281 template <class T>
283 {
284  release();
285 }
286 
287 template <class T>
289 {
290  T* Pointee = _ptr.load();
291  if ( Pointee )
292  {
293  Pointee->add_ref( REFERER_PARAM( this ) );
294  }
295 }
296 template <class T>
298 {
299  T* Pointee = _ptr.exchange( nullptr );
300  if ( Pointee )
301  {
302  if ( 0 == Pointee->release( REFERER_PARAM( this ) ) )
303  {
304  delete Pointee;
305  }
306  }
307 }
308 
309 template <class T>
310 bool operator==( T* ptr, const ref_ptr<T>& rptr )
311 {
312  return ptr == rptr.get();
313 }
314 
315 template <class T>
316 bool operator!=( T* ptr, const ref_ptr<T>& rptr )
317 {
318  return ptr != rptr.get();
319 }
320 
321 template <class T>
322 bool operator<( T* ptr, const ref_ptr<T>& rptr )
323 {
324  return ptr < rptr.get();
325 }
326 
327 template <class T>
328 bool operator<=( T* ptr, const ref_ptr<T>& rptr )
329 {
330  return ptr <= rptr.get();
331 }
332 
333 template <class T>
334 bool operator>( T* ptr, const ref_ptr<T>& rptr )
335 {
336  return ptr > rptr.get();
337 }
338 
339 template <class T>
340 bool operator>=( T* ptr, const ref_ptr<T>& rptr )
341 {
342  return ptr >= rptr.get();
343 }
344 
345 #endif // __REFPTR_H
void add_ref()
Definition: refptr.h:288
bool operator>(T *ptr, const ref_ptr< T > &rptr)
Definition: refptr.h:334
#define POL_NOEXCEPT
std::atomic< unsigned int > _count
Definition: refptr.h:46
bool operator<(T *ptr, const ref_ptr< T > &rptr)
Definition: refptr.h:322
std::atomic< T * > _ptr
Definition: refptr.h:105
unsigned int release()
Definition: refptr.h:125
T * get() const
Definition: refptr.h:175
bool operator==(T *ptr, const ref_ptr< T > &rptr)
Definition: refptr.h:310
ref_counted & operator=(const ref_counted &)
ref_ptr & operator=(const ref_ptr &rptr)
Definition: refptr.h:257
#define REFERER_PARAM(x)
Definition: refptr.h:28
T & operator*() const
Definition: refptr.h:185
bool operator<(const ref_ptr &rptr) const
Definition: refptr.h:206
unsigned int add_ref()
Definition: refptr.h:118
void clear()
Definition: refptr.h:282
ref_ptr(T *ptr=0)
Definition: refptr.h:141
bool operator>(const ref_ptr &rptr) const
Definition: refptr.h:216
Definition: refptr.h:64
bool operator>=(T *ptr, const ref_ptr< T > &rptr)
Definition: refptr.h:340
bool operator!() const
Definition: refptr.h:191
unsigned int count() const
Definition: refptr.h:129
bool operator<=(const ref_ptr &rptr) const
Definition: refptr.h:211
bool operator>=(const ref_ptr &rptr) const
Definition: refptr.h:221
bool operator!=(const ref_ptr &rptr) const
Definition: refptr.h:201
bool operator!=(T *ptr, const ref_ptr< T > &rptr)
Definition: refptr.h:316
void set(T *ptr)
Definition: refptr.h:275
bool operator<=(T *ptr, const ref_ptr< T > &rptr)
Definition: refptr.h:328
bool operator==(const ref_ptr &rptr) const
Definition: refptr.h:196
void release()
Definition: refptr.h:297
ref_counted()
Definition: refptr.h:108
T * operator->() const
Definition: refptr.h:180
#define REFPTR_DEBUG
Definition: refptr.h:26
~ref_ptr()
Definition: refptr.h:166