Choreonoid  1.5
Referenced.h
Go to the documentation of this file.
1 
5 #ifndef CNOID_UTIL_REFERENCED_H
6 #define CNOID_UTIL_REFERENCED_H
7 
8 #include <boost/version.hpp>
9 
10 #ifdef WIN32
11 #include <memory>
12 #endif
13 
14 #if (BOOST_VERSION >= 105300) && !defined(NOT_USE_BOOST_ATOMIC)
15 #include <boost/atomic.hpp>
16 #define CNOID_REFERENCED_USE_ATOMIC_COUNTER
17 #endif
18 
19 #include <cassert>
20 #include <iosfwd>
21 
22 namespace cnoid {
23 
24 class Referenced;
25 
30 {
31 public:
33  isObjectAlive_ = true;
34  weakCount = 0;
35  }
36 
37  void add() { ++weakCount; }
38 
39  void release() {
40  if(--weakCount == 0){
41  if(!isObjectAlive_){
42  delete this;
43  }
44  }
45  }
46 
47  void setDestructed() {
48  isObjectAlive_ = false;
49  if(weakCount == 0){
50  delete this;
51  }
52  }
53 
54  bool isObjectAlive(){
55  return isObjectAlive_;
56  }
57 
58 private:
59  bool isObjectAlive_;
60  int weakCount;
61 };
62 
63 
68 {
69  friend class WeakCounter;
70  template<class Y> friend class weak_ref_ptr;
71  template<class Y> friend class ref_ptr;
72 
73 protected:
74  Referenced() : refCount_(0), weakCounter_(0) { }
75  Referenced(const Referenced& org) : refCount_(0), weakCounter_(0) { }
76 
77 public:
78  virtual ~Referenced() {
79  if(weakCounter_){
80  weakCounter_->setDestructed();
81  }
82  }
83 
84 #ifdef CNOID_REFERENCED_USE_ATOMIC_COUNTER
85  void addRef() const {
86  refCount_.fetch_add(1, boost::memory_order_relaxed);
87  }
88  void releaseRef() const {
89  if(refCount_.fetch_sub(1, boost::memory_order_release) == 1) {
90  boost::atomic_thread_fence(boost::memory_order_acquire);
91  delete this;
92  }
93  }
94 private:
95  mutable boost::atomic<int> refCount_;
96 
97 protected:
98  int refCount() const { return refCount_.load(boost::memory_order_relaxed); }
99 #else
100  void addRef() {
101  ++refCount_;
102  }
103  void releaseRef() {
104  if(--refCount_ == 0){
105  delete this;
106  }
107  }
108 
109 private:
110  int refCount_;
111 
112 protected:
113  int refCount() const { return refCount_; }
114 #endif
115 
116 private:
117  WeakCounter* weakCounter_;
118 
119  WeakCounter* weakCounter(){
120  if(!weakCounter_){
121  weakCounter_ = new WeakCounter();
122  }
123  return weakCounter_;
124  }
125 };
126 
127 
128 template<class T> class ref_ptr
129 {
130 public:
131  typedef T element_type;
132 
133  ref_ptr() : px(0) { }
134 
135  ref_ptr(T* p) : px(p){
136  if(px != 0){
137  px->addRef();
138  }
139  }
140 
141  template<class U>
142  ref_ptr(ref_ptr<U> const & rhs) : px(rhs.get()){
143  if(px != 0){
144  px->addRef();
145  }
146  }
147 
148  ref_ptr(ref_ptr const & rhs) : px(rhs.px){
149  if(px != 0){
150  px->addRef();
151  }
152  }
153 
155  if(px != 0){
156  px->releaseRef();
157  }
158  }
159 
160  template<class U> ref_ptr& operator=(ref_ptr<U> const & rhs){
161  ref_ptr(rhs).swap(*this);
162  return *this;
163  }
164 
165 #if defined( BOOST_HAS_RVALUE_REFS )
166 
167  ref_ptr(ref_ptr&& rhs) : px(rhs.px){
168  rhs.px = 0;
169  }
170 
171  ref_ptr & operator=(ref_ptr&& rhs){
172  ref_ptr(static_cast<ref_ptr &&>(rhs)).swap(*this);
173  return *this;
174  }
175 
176 #endif
177 
178  ref_ptr& operator=(ref_ptr const & rhs){
179  ref_ptr(rhs).swap(*this);
180  return *this;
181  }
182 
183  ref_ptr& operator=(T* rhs){
184  ref_ptr(rhs).swap(*this);
185  return *this;
186  }
187 
188  void reset(){
189  ref_ptr().swap(*this);
190  }
191 
192  void reset(T* rhs){
193  ref_ptr(rhs).swap(*this);
194  }
195 
196  // explicit conversion to the raw pointer
197  T* get() const{
198  return px;
199  }
200 
201  // implict conversion to the raw pointer
202  operator T*() const {
203  return px;
204  }
205 
206  T& operator*() const {
207  assert(px != 0);
208  return *px;
209  }
210 
211  T* operator->() const {
212  assert(px != 0);
213  return px;
214  }
215 
216  void swap(ref_ptr& rhs){
217  T* tmp = px;
218  px = rhs.px;
219  rhs.px = tmp;
220  }
221 
222 private:
223  template<class Y> friend class weak_ref_ptr;
224  template<class Y> friend class ref_ptr;
225 
226  T* px;
227 };
228 
229 
230 template<class T, class U> inline bool operator==(ref_ptr<T> const & a, ref_ptr<U> const & b)
231 {
232  return a.get() == b.get();
233 }
234 
235 template<class T, class U> inline bool operator!=(ref_ptr<T> const & a, ref_ptr<U> const & b)
236 {
237  return a.get() != b.get();
238 }
239 
240 template<class T, class U> inline bool operator==(ref_ptr<T> const & a, U * b)
241 {
242  return a.get() == b;
243 }
244 
245 template<class T, class U> inline bool operator!=(ref_ptr<T> const & a, U * b)
246 {
247  return a.get() != b;
248 }
249 
250 template<class T, class U> inline bool operator==(T * a, ref_ptr<U> const & b)
251 {
252  return a == b.get();
253 }
254 
255 template<class T, class U> inline bool operator!=(T * a, ref_ptr<U> const & b)
256 {
257  return a != b.get();
258 }
259 
260 template<class T> inline bool operator<(ref_ptr<T> const & a, ref_ptr<T> const & b)
261 {
262  return a.get() < b.get();
263 }
264 
265 template<class T> void swap(ref_ptr<T> & lhs, ref_ptr<T> & rhs)
266 {
267  lhs.swap(rhs);
268 }
269 
270 template<class T, class U> ref_ptr<T> static_pointer_cast(ref_ptr<U> const & p)
271 {
272  return static_cast<T*>(p.get());
273 }
274 
275 template<class T, class U> ref_ptr<T> const_pointer_cast(ref_ptr<U> const & p)
276 {
277  return const_cast<T*>(p.get());
278 }
279 
280 template<class T, class U> ref_ptr<T> dynamic_pointer_cast(ref_ptr<U> const & p)
281 {
282  return dynamic_cast<T*>(p.get());
283 }
284 
285 template<class Y> std::ostream & operator<< (std::ostream & os, ref_ptr<Y> const & p)
286 {
287  os << p.get();
288  return os;
289 }
290 
291 
293 
294 
295 template<class T> class weak_ref_ptr
296 {
297  typedef void (weak_ref_ptr<T>::*bool_type)() const;
298 
299  void bool_type_func() const { }
300 
301  void setCounter(){
302  if(px){
303  counter = px->weakCounter();
304  counter->add();
305  } else {
306  counter = 0;
307  }
308  }
309 
310 public:
311  typedef T element_type;
312 
313  weak_ref_ptr() : px(0), counter(0) { }
314 
315  template<class Y>
316  weak_ref_ptr(weak_ref_ptr<Y> const & rhs) : px(rhs.lock().get()){
317  setCounter();
318  }
319 
320  template<class Y>
322  px = rhs.lock().get();
323  setCounter();
324  return *this;
325  }
326 
327 #if defined( BOOST_HAS_RVALUE_REFS )
328 
329  template<class Y>
330  weak_ref_ptr(weak_ref_ptr<Y>&& rhs) : px(rhs.lock().get()), counter(rhs.counter){
331  rhs.px = 0;
332  rhs.counter = 0;
333  }
334 
335  weak_ref_ptr(weak_ref_ptr&& rhs) : px(rhs.px), counter(rhs.counter){
336  rhs.px = 0;
337  rhs.counter = 0;
338  }
339 
340  weak_ref_ptr& operator=(weak_ref_ptr&& rhs){
341  weak_ref_ptr(static_cast<weak_ref_ptr&&>(rhs)).swap(*this);
342  rhs.px = 0;
343  rhs.counter = 0;
344  return rhs;
345  }
346 
347 #endif
348  template<class Y>
349  weak_ref_ptr(ref_ptr<Y> const & rhs) : px(rhs.px){
350  setCounter();
351  }
352 
353  template<class Y>
354  weak_ref_ptr(Y* const & rhs) : px(rhs){
355  setCounter();
356  }
357 
358  template<class Y>
360  px = rhs.px;
361  setCounter();
362  return *this;
363  }
364 
365  operator bool_type() const { return px ? &weak_ref_ptr<T>::bool_type_func : 0; }
366 
367  ref_ptr<T> lock() const {
368  if(counter && counter->isObjectAlive()){
369  return ref_ptr<T>(px);
370  } else {
371  return ref_ptr<T>();
372  }
373  }
374 
375  bool expired() const {
376  return !counter || !counter->isObjectAlive();
377  }
378 
379  void reset(){
380  weak_ref_ptr().swap(*this);
381  }
382 
383  void swap(weak_ref_ptr& other){
384  T* px_ = px;
385  px = other.px;
386  other.px = px_;
387  WeakCounter* counter_ = counter;
388  counter = other.counter;
389  other.counter = counter_;
390  }
391 
392  template<class Y> bool _internal_less(weak_ref_ptr<Y> const & rhs) const {
393  return counter < rhs.counter;
394  }
395 
396 private:
397  template<class Y> friend class weak_ref_ptr;
398  template<class Y> friend class ref_ptr;
399 
400  T* px;
401  WeakCounter* counter;
402 };
403 
404 template<class T, class U> inline bool operator<(weak_ref_ptr<T> const & a, weak_ref_ptr<U> const & b)
405 {
406  return a._internal_less(b);
407 }
408 
409 template<class T> void swap(weak_ref_ptr<T> & a, weak_ref_ptr<T> & b)
410 {
411  a.swap(b);
412 }
413 
414 }
415 
416 #endif
Definition: Referenced.h:29
bool isObjectAlive()
Definition: Referenced.h:54
void swap(weak_ref_ptr &other)
Definition: Referenced.h:383
weak_ref_ptr(weak_ref_ptr< Y > const &rhs)
Definition: Referenced.h:316
ref_ptr< T > dynamic_pointer_cast(ref_ptr< U > const &p)
Definition: Referenced.h:280
void reset(T *rhs)
Definition: Referenced.h:192
bool operator!=(ref_ptr< T > const &a, ref_ptr< U > const &b)
Definition: Referenced.h:235
ref_ptr & operator=(ref_ptr const &rhs)
Definition: Referenced.h:178
ref_ptr< T > lock() const
Definition: Referenced.h:367
ref_ptr(T *p)
Definition: Referenced.h:135
ref_ptr(ref_ptr const &rhs)
Definition: Referenced.h:148
Referenced()
Definition: Referenced.h:74
void addRef()
Definition: Referenced.h:100
Definition: Referenced.h:67
weak_ref_ptr & operator=(weak_ref_ptr< Y > const &rhs)
Definition: Referenced.h:321
Definition: Referenced.h:128
ref_ptr< T > const_pointer_cast(ref_ptr< U > const &p)
Definition: Referenced.h:275
void reset()
Definition: Referenced.h:379
T element_type
Definition: Referenced.h:131
Referenced(const Referenced &org)
Definition: Referenced.h:75
T & operator*() const
Definition: Referenced.h:206
ref_ptr< Referenced > ReferencedPtr
Definition: Referenced.h:292
void swap(ref_ptr< T > &lhs, ref_ptr< T > &rhs)
Definition: Referenced.h:265
T element_type
Definition: Referenced.h:311
Definition: Referenced.h:295
void releaseRef()
Definition: Referenced.h:103
weak_ref_ptr & operator=(ref_ptr< Y > const &rhs)
Definition: Referenced.h:359
Defines the minimum processing for performing pasing file for STL.
Definition: AbstractSceneLoader.h:9
ref_ptr & operator=(T *rhs)
Definition: Referenced.h:183
weak_ref_ptr(ref_ptr< Y > const &rhs)
Definition: Referenced.h:349
ref_ptr()
Definition: Referenced.h:133
void swap(ref_ptr &rhs)
Definition: Referenced.h:216
~ref_ptr()
Definition: Referenced.h:154
WeakCounter()
Definition: Referenced.h:32
bool operator==(ref_ptr< T > const &a, ref_ptr< U > const &b)
Definition: Referenced.h:230
weak_ref_ptr(Y *const &rhs)
Definition: Referenced.h:354
T * operator->() const
Definition: Referenced.h:211
ref_ptr< T > static_pointer_cast(ref_ptr< U > const &p)
Definition: Referenced.h:270
ref_ptr & operator=(ref_ptr< U > const &rhs)
Definition: Referenced.h:160
void reset()
Definition: Referenced.h:188
T * get() const
Definition: Referenced.h:197
weak_ref_ptr()
Definition: Referenced.h:313
ref_ptr(ref_ptr< U > const &rhs)
Definition: Referenced.h:142
void add()
Definition: Referenced.h:37
int refCount() const
Definition: Referenced.h:113
bool expired() const
Definition: Referenced.h:375
void release()
Definition: Referenced.h:39
void setDestructed()
Definition: Referenced.h:47
bool _internal_less(weak_ref_ptr< Y > const &rhs) const
Definition: Referenced.h:392
virtual ~Referenced()
Definition: Referenced.h:78