Chombo + EB  3.0
RefCountedPtr.H
Go to the documentation of this file.
1 #ifdef CH_LANG_CC
2 /*
3  * _______ __
4  * / ___/ / ___ __ _ / / ___
5  * / /__/ _ \/ _ \/ V \/ _ \/ _ \
6  * \___/_//_/\___/_/_/_/_.__/\___/
7  * Please refer to Copyright.txt, in Chombo's root directory.
8  */
9 #endif
10 
11 #ifndef _REFCOUNTEDPTR_H_
12 #define _REFCOUNTEDPTR_H_
13 
14 #include <string>
15 #include <typeinfo>
16 #include "MayDay.H"
17 #include "Arena.H"
18 #include "CH_assert.H"
19 #include "BaseNamespaceHeader.H"
20 
21 /// A reference-counting handle class.
22 /**
23  This is to be used as a pointer to class T.
24  This will feel and smell just like a built-in pointer except:
25  -# There is no need to call delete on the pointer.
26  -# The default copy constructor and assignment implement ref-counting.
27  -# The user may call isNonUnique to determine if this pointer is
28  the only pointer to the data. This can be used to hide the
29  ref-counting behavior of a class.
30  -# Checks for dereference of a null pointer.
31 
32 This class is completely inlined.
33 
34 typical usage:
35 
36 \code
37 
38 {
39  Box b;
40  IntVect a;
41  //refCount() == 1
42  RefCountedPtr<IntVectSet> set(new IntVectSet());
43 
44  // still just one IntVectSet, but refCount()==2
45  RefCountedPtr<IntVectSet> otherSet(set);
46 
47  // Like a pointer, modifying one modifies the other
48  otherSet->define(b);
49  (*set)|=a;
50  {
51  RefCountedPtr<IntVectSet> anotherSet; // null
52  anotherSet = otherSet ; //now all three have refCount()==3
53  }//anotherSet out of scope, so deleted. IntVectSet NOT deleted.
54 
55  // set.refCount() == 2
56  // otherSet.refCount() == 2;
57  // otherset == set;
58 
59 }
60 // when all RefCountedPtr's for a given object are deleted, the last
61 // one calls 'delete' on the member pointer.
62 \endcode
63 
64 */
65 template <class T>
67 {
68 public:
69  //
70  explicit inline RefCountedPtr(T* ptr = 0);
71  //
72  inline RefCountedPtr(const RefCountedPtr<T>& other);
73  //
74  inline ~RefCountedPtr();
75  /// assignement operator. copies pointer member
76  /** copies pointer member and integer pointer, decreases refcount of rhs member
77  before assignment. this refcount increased my one. */
78  inline const RefCountedPtr<T>& operator =(const RefCountedPtr<T>& rhs);
79  /// dereference access operator. use like a pointer derefence access function.
80  inline T* operator ->();
81  inline const T* operator ->() const;
82  //
83  inline bool isNull() const;
84  //
85  /// pointer dereference.
86  inline T& operator *();
87 #ifdef CH_TEMPEST
88  inline T& operator *() const; // As in Boost::shared_ptr.
89 #else
90  inline const T& operator *() const;
91 #endif
92  //
93  /// auto conversion to regular const pointer where required.
94  inline operator const T* () const;
95 
96  /// true when refcount is one.
97  inline bool isNonUnique() const;
98 
99  inline int refCount() const;
100 
101  inline void swap(RefCountedPtr<T>& b);
102 
103  /// Template Conversion
104  /**
105  provides a mechanism for the compiler to generate a conversion to a base class, like
106  a real pointer would have
107  */
108  template<class T2> inline operator RefCountedPtr<T2>();
109 
110  // Will never delete ptr_. Useful in functions that need to return a
111  // pointer which, under some circumstances, we want to own, and under others
112  // we don't.
113  inline void neverDelete();
114 
115  template<class T2> friend class RefCountedPtr;
116 
117  static const std::string& name()
118  {
119  return name_;
120  }
121 
122  inline void increment();
123  inline void decrement();
124 protected:
125  T* ptr_;
126  int* refCount_;
127  static std::string name_;
128  static BArena s_Arena;
129  static int size_;
130 private:
131 
132 };
133 
134 template<class T>
135 std::string RefCountedPtr<T>::name_(std::string("RefCountedPtr ")+std::string(typeid(T).name()));
136 
137 //template<class T>
138 //BArena RefCountedPtr<T>::s_Arena(name_.c_str());
139 template<class T>
141 
142 template<class T>
143 int RefCountedPtr<T>::size_ = sizeof(T)+2*sizeof(int);
144 
145 template <class T> inline
147 {
148 #ifdef CH_USE_MEMORY_TRACKING
149  s_Arena.bytes += size_;
150  refCount_[1] = size_;
151  if (s_Arena.bytes > s_Arena.peak)
152  {
153  s_Arena.peak = s_Arena.bytes;
154  }
155 #endif
156 }
157 template <class T> inline
159 {
160 #ifdef CH_USE_MEMORY_TRACKING
161  s_Arena.bytes -= refCount_[1];
162 #endif
163 }
164 
165 template <class T> inline
167  : ptr_(ptr),
168  refCount_(0)
169 {
170  if (ptr_)
171  {
172  refCount_ = new int[2];
173  if (refCount_ == 0)
174  MayDay::Error("RefCountedPtr::RefCountedPtr(T* ptr) out of memory");
175  *refCount_ = 1;
176  increment();
177  }
178 }
179 
180 template <class T> inline
182  : ptr_(other.ptr_),
183  refCount_(other.refCount_)
184 {
185  if (refCount_ != 0)
186  ++(*refCount_);
187 }
188 
189 template <class T> inline
191 {
192  if (refCount_ != 0 && --(*refCount_) == 0)
193  {
194  decrement();
195  delete ptr_;
196  ptr_ = 0;
197  delete [] refCount_;
198  refCount_ = 0;
199 
200  }
201 }
202 
203 template <class T> inline
205 {
206  if (ptr_ != rhs.ptr_)
207  {
208  if (refCount_ != 0 && --(*refCount_) == 0)
209  {
210  decrement();
211  delete ptr_;
212  delete [] refCount_;
213  }
214  ptr_ = rhs.ptr_;
215  refCount_ = rhs.refCount_;
216  if (refCount_ != 0)
217  ++(*refCount_);
218  }
219  return *this;
220 }
221 
222 template <class T> inline
224 {
225  return (ptr_ == 0);
226 }
227 
228 template <class T> inline
230 {
231  if (ptr_ == 0)
232  MayDay::Error("RefCountedPtr<T>::operator ->() on null pointer");
233  return ptr_;
234 }
235 
236 template <class T> inline
238 {
239  if (ptr_ == 0)
240  MayDay::Error("RefCountedPtr<T>::operator ->() on null pointer");
241  return ptr_;
242 }
243 
244 template <class T> inline
246 {
247  if (ptr_ == 0)
248  MayDay::Error("RefCountedPtr<T>::operator *() on null pointer");
249  return *ptr_;
250 }
251 
252 template <class T> inline
253 #ifndef CH_TEMPEST
254 const
255 #endif
257 {
258  if (ptr_ == 0)
259  MayDay::Error("RefCountedPtr<T>::operator *() on null pointer");
260  return *ptr_;
261 }
262 
263 template <class T> inline
264 RefCountedPtr<T>::operator const T* () const
265 {
266  return ptr_;
267 }
268 
269 template <class T> inline
271 {
272  return refCount_ == 0 ? false : *refCount_ != 1;
273 }
274 
275 template <class T> inline
277 {
278  return refCount_ == 0 ? 0 : *refCount_;
279 }
280 
281 
282 
283 
284 template <class T>
285 template <class T2>
287 {
288  T2* t2 = dynamic_cast<T2*>(ptr_); // Handles upward and downward casts... -JNJ
289  CH_assert(t2 != NULL); // ... unless the cast fails, of course. :-)
290  RefCountedPtr<T2> rtn; // if you have a compiler error that points here, then T2 is probably not a T
291  rtn.ptr_= t2;
292 #ifdef CH_USE_MEMORY_TRACKING
293  // by fiat the derived classes memory is transfered to the base class Arena
294  s_Arena.bytes -=refCount_[1];
295  rtn.s_Arena.bytes +=refCount_[1];
296 #endif
297 
298  ++ *refCount_;
299  rtn.refCount_ = refCount_;
300  return rtn;
301 }
302 
303 
304 template <class T> inline
306 {
307  T* s = ptr_;
308  ptr_ = b.ptr_;
309  b.ptr_ = s;
310 
311  int* r = refCount_;
312  refCount_ = b.refCount_;
313  b.refCount_ = r;
314 
315 }
316 
317 template <class T> inline
319 {
320  ++ *refCount_;
321 }
322 
323 #include "BaseNamespaceFooter.H"
324 #endif
const RefCountedPtr< T > & operator=(const RefCountedPtr< T > &rhs)
assignement operator. copies pointer member
Definition: RefCountedPtr.H:204
int * refCount_
Definition: RefCountedPtr.H:126
bool isNonUnique() const
true when refcount is one.
Definition: RefCountedPtr.H:270
static std::string name_
Definition: RefCountedPtr.H:127
A reference-counting handle class.
Definition: RefCountedPtr.H:66
#define CH_assert(cond)
Definition: CHArray.H:37
bool isNull() const
Definition: RefCountedPtr.H:223
T * operator->()
dereference access operator. use like a pointer derefence access function.
Definition: RefCountedPtr.H:229
void swap(RefCountedPtr< T > &b)
Definition: RefCountedPtr.H:305
void increment()
Definition: RefCountedPtr.H:146
void neverDelete()
Definition: RefCountedPtr.H:318
~RefCountedPtr()
Definition: RefCountedPtr.H:190
A Concrete Class for Dynamic Memory Management.
Definition: Arena.H:124
static int size_
Definition: RefCountedPtr.H:129
static void Error(const char *const a_msg=m_nullString, int m_exitCode=CH_DEFAULT_ERROR_CODE)
Print out message to cerr and exit with the specified exit code.
static BArena s_Arena
Definition: RefCountedPtr.H:128
T * ptr_
Definition: RefCountedPtr.H:125
T & operator*()
pointer dereference.
Definition: RefCountedPtr.H:245
static const std::string & name()
Definition: RefCountedPtr.H:117
void decrement()
Definition: RefCountedPtr.H:158
int refCount() const
Definition: RefCountedPtr.H:276
friend class RefCountedPtr
Definition: RefCountedPtr.H:115