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