sttcl  v0.9c
STTCL C++ template state machine framework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
RefCountPtr.h
Go to the documentation of this file.
1 
25 #ifndef REFCOUNTPTR_H_
26 #define REFCOUNTPTR_H_
27 
28 #include "SttclMutex.h"
29 #include <stdlib.h>
30 
31 namespace sttcl
32 {
33 
34 namespace internal
35 {
36 template<class MutexType>
38 {
39 public:
44  typedef void (*ReleaseFunc)(void* ptr);
45 
51  {
53  }
54 
55 
56 protected:
57 
58  struct PtrRef
59  {
60  void* pointee;
61  int refcount;
62  MutexType refcountMutex;
64 
65  PtrRef(void* argPointee, ReleaseFunc argReleaseFunc)
66  : pointee(argPointee)
67  , refcount(0)
68  , refcountMutex()
69  , releaseFunc(argReleaseFunc)
70  {
71  }
72 
74  {
75  }
76  };
77 
82  : ptrRef(0)
83  {
84  }
85 
89  RefCountPtrBase(void* argPointee, ReleaseFunc argReleaseFunc)
90  : ptrRef(0)
91  {
92  if(argPointee)
93  {
94  ptrRef = new PtrRef(argPointee,argReleaseFunc);
96  }
97  }
98 
104  : ptrRef(rhs.ptrRef)
105  {
107  }
108 
110  {
111  if(ptrRef && ptrRef != rhs.ptrRef)
112  {
114  }
115  ptrRef = rhs.ptrRef;
117  return *this;
118  }
119 
120  void incrementRefCount();
121  void decrementRefCount();
122 
123  mutable PtrRef* ptrRef;
124 };
125 
126 template
127 < class MutexType
128 >
130 {
131  if(ptrRef)
132  {
133  sttcl::internal::AutoLocker<MutexType> lock(ptrRef->refcountMutex);
134  ++(ptrRef->refcount);
135  }
136 }
137 
138 template
139 < class MutexType
140 >
142 {
143  if(ptrRef)
144  {
145  bool destroy = false;
146  { sttcl::internal::AutoLocker<MutexType> lock(ptrRef->refcountMutex);
147  --(ptrRef->refcount);
148  if(ptrRef->refcount <= 0)
149  {
150  if(ptrRef->releaseFunc)
151  {
152  (*ptrRef->releaseFunc)(ptrRef->pointee);
153  ptrRef->pointee = 0;
154  }
155  destroy = true;
156  }
157  }
158  if(destroy)
159  {
160  delete ptrRef;
161  ptrRef = 0;
162  }
163  }
164 }
165 }
166 
176 template
177 < typename T
179 >
181 : public sttcl::internal::RefCountPtrBase<MutexType>
182 {
183 public:
184 
189  : sttcl::internal::RefCountPtrBase<MutexType>()
190  {
191  }
192 
199  : sttcl::internal::RefCountPtrBase<MutexType>(argPointee,argReleaseFunc)
200  {
201  }
202 
208  template<typename U>
210  : sttcl::internal::RefCountPtrBase<MutexType>(static_cast<T*>(argPointee),argReleaseFunc)
211  {
212  }
213 
220  : sttcl::internal::RefCountPtrBase<MutexType>(rhs)
221  {
222  }
223 
229  template<typename U>
231  : sttcl::internal::RefCountPtrBase<MutexType>(rhs)
232  {
233  T* dummy = static_cast<T*>(rhs.get());
234  (void)dummy;
235  }
236 
242  {
243  }
244 
252  {
254  return *this;
255  }
256 
263  template<typename U>
265  {
266  T* dummy = static_cast<T*>(rhs.get());
267  (void)dummy;
269  return *this;
270  }
271 
276  T* get() const
277  {
279  {
281  }
282  return 0;
283  }
284 
288  operator T*() const
289  {
290  return get();
291  }
292 
298  {
300  {
301  return reinterpret_cast<T*>(sttcl::internal::RefCountPtrBase<MutexType>::ptrRef->pointee);
302  }
303  return 0;
304  }
305 
311  {
312  static T dummy;
314  {
315  return *(reinterpret_cast<T*>(sttcl::internal::RefCountPtrBase<MutexType>::ptrRef->pointee));
316  }
317  return dummy;
318  }
319 
320 private:
321  static void release(void* ptr);
322 };
323 
324 template
325 < typename T
326 , class MutexType
327 >
328 void RefCountPtr<T,MutexType>::release(void* ptr)
329 {
330  delete reinterpret_cast<T*>(ptr);
331 }
332 
336 template<class MutexType>
337 class RefCountPtr<void,MutexType>
338 {
339  static void release(void* ptr)
340  {
341 // free(ptr);
342  }
343 };
344 
345 } /* namespace sttcl */
346 #endif /* REFCOUNTPTR_H_ */