cartobase  5.0.5
sharedptr.h
Go to the documentation of this file.
1 /* This software and supporting documentation are distributed by
2  * Institut Federatif de Recherche 49
3  * CEA/NeuroSpin, Batiment 145,
4  * 91191 Gif-sur-Yvette cedex
5  * France
6  *
7  * This software is governed by the CeCILL-B license under
8  * French law and abiding by the rules of distribution of free software.
9  * You can use, modify and/or redistribute the software under the
10  * terms of the CeCILL-B license as circulated by CEA, CNRS
11  * and INRIA at the following URL "http://www.cecill.info".
12  *
13  * As a counterpart to the access to the source code and rights to copy,
14  * modify and redistribute granted by the license, users are provided only
15  * with a limited warranty and the software's author, the holder of the
16  * economic rights, and the successive licensors have only limited
17  * liability.
18  *
19  * In this respect, the user's attention is drawn to the risks associated
20  * with loading, using, modifying and/or developing or reproducing the
21  * software by the user in light of its specific status of free software,
22  * that may mean that it is complicated to manipulate, and that also
23  * therefore means that it is reserved for developers and experienced
24  * professionals having in-depth computer knowledge. Users are therefore
25  * encouraged to load and test the software's suitability as regards their
26  * requirements in conditions enabling the security of their systems and/or
27  * data to be ensured and, more generally, to use and operate it in the
28  * same conditions as regards security.
29  *
30  * The fact that you are presently reading this means that you have had
31  * knowledge of the CeCILL-B license and that you accept its terms.
32  */
33 
34 #ifndef CARTOBASE_SMART_SHAREDPTR_H
35 #define CARTOBASE_SMART_SHAREDPTR_H
36 
38 #include <cartobase/smart/rcptr.h>
39 
40 namespace carto
41 {
42 
47  class SharedObject : public virtual WeakObject, public virtual RCObject
48  {
49  public:
50  SharedObject();
51  SharedObject( const SharedObject & x );
53  virtual ~SharedObject();
54 
55  SharedObject & operator = ( const SharedObject & ) { return *this; }
56 
63  bool testDeletable();
68  bool tryDelete();
69 
70  protected:
75  void disableRefCount();
76 
77  private:
78  template <typename T> friend class weak_shared_ptr;
79  template <typename T> friend class shared_ptr;
80  friend class rc_ptr_trick;
81 
82  mutable RCObject::RefCounterType weak_count;
83  };
84 
85 
93  template <typename T>
94  class weak_shared_ptr : public rc_ptr<T>, public weak_ptr<T>
95  {
96  public:
97  explicit weak_shared_ptr( T* x = 0, bool externalowner = false );
99  weak_shared_ptr( const rc_ptr<T> & x );
100  weak_shared_ptr( const weak_ptr<T> & x );
101  ~weak_shared_ptr();
102 
103  T* get() const { return weak_ptr<T>::get(); }
104 
105  bool operator == ( const T* x ) const
106  { return get() == x; }
107  bool operator == ( const weak_shared_ptr<T> & x ) const
108  { return weak_ptr<T>::operator == (x); }
109  bool operator == ( const rc_ptr<T> & x ) const
110  { return get() == x.get(); }
111  bool operator == ( const weak_ptr<T> & x ) const
112  { return get() == x.get(); }
113  bool operator != ( const T* x ) const
114  { return get() != x; }
115  bool operator != ( const weak_shared_ptr<T> & x ) const
116  { return weak_ptr<T>::operator != (x); }
117  bool operator != ( const rc_ptr<T> & x ) const
118  { return get() != x.get(); }
119  bool operator != ( const weak_ptr<T> & x ) const
120  { return get() != x.get(); }
121  bool operator < ( const weak_shared_ptr<T> & x ) const
122  { return weak_ptr<T>::operator < (x); }
123  bool operator < ( const rc_ptr<T> & x ) const
124  { return get() < x.get(); }
125  bool operator < ( const weak_ptr<T> & x ) const
126  { return get() < x.get(); }
127  T& operator * () const
128  { return weak_ptr<T>::operator * (); }
129  T* operator -> () const
130  { return weak_ptr<T>::operator -> (); }
131 
135  T* release();
136  void reset( T* r = 0 );
137 
138  private:
139  friend class WeakObject;
140  friend class rc_ptr_trick;
141  void update();
142  };
143 
144 
151  template <typename T>
152  class shared_ptr : public weak_shared_ptr<T>
153  {
154  public:
156  {
160  };
161 
162  explicit shared_ptr( ReferenceType t = Weak, T* x = 0,
163  bool externalowner = false );
164  shared_ptr( const shared_ptr<T> & x );
165  shared_ptr( const weak_shared_ptr<T> & x );
166  shared_ptr( const rc_ptr<T> & x );
167  shared_ptr( const weak_ptr<T> & x );
168  ~shared_ptr();
169 
170  bool operator == ( const shared_ptr<T> & x ) const
171  { return weak_ptr<T>::operator == (x); }
172  bool operator == ( const T* x ) const
173  { return this->weak_ptr<T>::get() == x; }
174  bool operator == ( const rc_ptr<T> & x ) const
175  { return this->weak_ptr<T>::get() == x.get(); }
176  bool operator == ( const weak_ptr<T> & x ) const
177  { return this->weak_ptr<T>::get() == x.get(); }
178  bool operator == ( const weak_shared_ptr<T> & x ) const
179  { return this->weak_ptr<T>::get() == x.get(); }
180  bool operator != ( const shared_ptr<T> & x ) const
181  { return weak_ptr<T>::operator != (x); }
182  bool operator != ( const T* x ) const
183  { return this->weak_ptr<T>::get() != x; }
184  bool operator != ( const rc_ptr<T> & x ) const
185  { return this->weak_ptr<T>::get() != x.get(); }
186  bool operator != ( const weak_ptr<T> & x ) const
187  { return this->weak_ptr<T>::get() != x.get(); }
188  bool operator != ( const weak_shared_ptr<T> & x ) const
189  { return this->weak_ptr<T>::get() != x.get(); }
190  bool operator < ( const shared_ptr<T> & x ) const
191  { return weak_ptr<T>::operator < (x); }
192  bool operator < ( const rc_ptr<T> & x ) const
193  { return this->weak_ptr<T>::get() < x.get(); }
194  bool operator < ( const weak_ptr<T> & x ) const
195  { return this->weak_ptr<T>::get() < x.get(); }
196  bool operator < ( const weak_shared_ptr<T> & x ) const
197  { return this->weak_ptr<T>::get() < x.get(); }
198 
199  shared_ptr<T> & operator = ( const shared_ptr<T> & x );
201  shared_ptr<T> & operator = ( const rc_ptr<T> & x );
202  shared_ptr<T> & operator = ( const weak_ptr<T> & x );
203  T* release();
204  void reset( ReferenceType t, T* r = 0 );
205 
206  ReferenceType referenceType() const;
207 
208  private:
209  ReferenceType _reftype;
210  };
211 
212 
213  // ----------------------------
214 
215  template <typename T>
216  inline
217  weak_shared_ptr<T>::weak_shared_ptr( T* x, bool externalowner )
218  : rc_ptr<T>( x, externalowner ), weak_ptr<T>( x )
219  {
220  // force re-attaching with the correct type for this
221  if( x )
222  {
223  ++x->weak_count;
224  x->attachWeakPtr( *this );
225  }
226  }
227 
228 
229  template <typename T>
230  inline
232  : rc_ptr<T>( x ), weak_ptr<T>( x )
233  {
234  // force re-attaching with the correct type for this
235  if( x.get() )
236  {
237  ++x->weak_count;
238  x->attachWeakPtr( *this );
239  }
240  }
241 
242 
243  template <typename T>
244  inline
246  : rc_ptr<T>( x ), weak_ptr<T>( x.get() )
247  {
248  // force re-attaching with the correct type for this
249  if( x.get() )
250  {
251  ++x->weak_count;
252  x->attachWeakPtr( *this );
253  }
254  }
255 
256 
257  template <typename T>
258  inline
260  : rc_ptr<T>( x ), weak_ptr<T>( x )
261  {
262  // force re-attaching with the correct type for this
263  if( x.get() )
264  {
265  ++x->weak_count;
266  x->attachWeakPtr( *this );
267  }
268  }
269 
270 
271  template <typename T>
272  inline
274  {
275  if( get() )
276  --get()->weak_count;
277  }
278 
279 
280  template <typename T>
281  inline
283  {
284  // weak_ptr<T>::update(); is done by WeakObject
285  rc_ptr<T>::reset( 0 );
286  }
287 
288 
289  template <typename T>
290  inline
292  ( const weak_shared_ptr<T> & x )
293  {
294  if( &x == this )
295  return *this;
296 
297  if( get() )
298  --get()->weak_count;
300  // force re-attaching with the correct type for this
301  if( x.get() )
302  {
303  ++x->weak_count;
304  x->attachWeakPtr( *this );
305  }
307  return *this;
308  }
309 
310 
311  template <typename T>
312  inline
313  weak_shared_ptr<T> & weak_shared_ptr<T>::operator =
314  ( const rc_ptr<T> & x )
315  {
316  if( this != &x )
317  reset( x.get() );
318  return *this;
319  }
320 
321 
322  template <typename T>
323  inline
325  {
326  if( get() )
327  --get()->weak_count;
329  return rc_ptr<T>::release();
330  }
331 
332 
333  template <typename T>
334  inline
336  {
337  if( get() )
338  --get()->weak_count;
339  weak_ptr<T>::reset( r );
340  // force re-attaching with the correct type for this
341  if( r )
342  {
343  ++r->weak_count;
344  r->attachWeakPtr( *this );
345  }
346  rc_ptr<T>::reset( r );
347  }
348 
349  // ----------------
350 
351 
352  template <typename T>
353  inline
354  shared_ptr<T>::shared_ptr( ReferenceType t, T* x, bool externalowner )
355  : weak_shared_ptr<T>( x, externalowner ), _reftype( t )
356  {
357  switch( t )
358  {
359  case Strong:
360  if( x )
361  --x->weak_count;
362  break;
363  case WeakShared:
364  break;
365  case Weak:
367  weak_ptr<T>::reset( x );
368  break;
369  }
370  }
371 
372 
373  template <typename T>
374  inline
376  : weak_shared_ptr<T>( x ), _reftype( x.referenceType() )
377  {
378  switch( referenceType() )
379  {
380  case Strong:
381  if( x.get() )
382  --x->weak_count;
383  break;
384  case WeakShared:
385  break;
386  case Weak:
388  weak_ptr<T>::reset( x.get() );
389  break;
390  }
391  }
392 
393 
394  template <typename T>
395  inline
397  : weak_shared_ptr<T>( x ), _reftype( WeakShared )
398  {
399  }
400 
401 
402  template <typename T>
403  inline
405  : weak_shared_ptr<T>( x.get() ), _reftype( Strong )
406  {
407  if( x )
408  --x->weak_count;
409  }
410 
411 
412  template <typename T>
413  inline
415  : weak_shared_ptr<T>( x )
416  {
418  weak_ptr<T>::reset( x.get() );
419  }
420 
421 
422  template <typename T>
423  inline
425  {
426  switch( referenceType() )
427  {
428  case Strong:
429  if( this->get() )
430  ++this->get()->weak_count; // as it will be decremented soon
431  // WARNING: this is not thread-safe
432  break;
433  case WeakShared:
434  break;
435  case Weak:
436  release();
437  break;
438  }
439  }
440 
441 
442  template <typename T>
443  inline typename shared_ptr<T>::ReferenceType
445  {
446  return _reftype;
447  }
448 
449 
450  template <typename T>
451  inline
453  ( const shared_ptr<T> & x )
454  {
455  reset( x.referenceType(), x.get() );
456  return *this;
457  }
458 
459 
460  template <typename T>
461  inline
462  shared_ptr<T> & shared_ptr<T>::operator =
463  ( const weak_shared_ptr<T> & x )
464  {
465  reset( WeakShared, x.get() );
466  return *this;
467  }
468 
469 
470  template <typename T>
471  inline
473  {
474  reset( Strong, x.get() );
475  return *this;
476  }
477 
478 
479  template <typename T>
480  inline
482  {
483  reset( Weak, x.get() );
484  return *this;
485  }
486 
487 
488  template <typename T>
489  inline
491  {
492  T* x = weak_ptr<T>::release();
493  if( this->get() && referenceType() == WeakShared )
494  --this->get()->weak_count;
495  if( referenceType() != Weak )
496  return rc_ptr<T>::release();
497  return x;
498  }
499 
500 
501  template <typename T>
502  inline
504  {
505  if( r == this->get() )
506  {
507  if( t != referenceType() )
508  {
509  switch( t )
510  {
511  case Strong:
512  switch( referenceType() )
513  {
514  case WeakShared:
515  --r->weak_count;
516  break;
517  case Weak:
518  rc_ptr<T>::reset( r );
519  break;
520  default:
521  break;
522  }
523  break;
524  case WeakShared:
525  switch( referenceType() )
526  {
527  case Strong:
528  ++r->weak_count;
529  break;
530  case Weak:
532  break;
533  default:
534  break;
535  }
536  break;
537  case Weak:
538  switch( referenceType() )
539  {
540  case Strong:
541  rc_ptr<T>::reset( 0 );
542  if( this->get() ) // r could have been destroyed by now
543  r->attachWeakPtr( static_cast<weak_ptr<T> &>( *this ) );
544  break;
545  case WeakShared:
546  if( r->_refCounter == 1 )
547  weak_shared_ptr<T>::reset( 0 ); // should destroy r...
548  else
549  {
551  weak_ptr<T>::reset( r );
552  }
553  break;
554  default:
555  break;
556  }
557  }
558  _reftype = t;
559  }
560  return;
561  }
562 
563  if( this->get() )
564  switch( referenceType() )
565  {
566  case Strong:
567  rc_ptr<T>::reset( 0 );
568  break;
569  case WeakShared:
571  break;
572  case Weak:
573  weak_ptr<T>::reset( 0 );
574  }
575 
576  _reftype = t;
577  switch( t )
578  {
579  case Strong:
580  // force re-attaching with the correct type for this
581  if( r )
582  {
583  r->attachWeakPtr( *this );
584  rc_ptr<T>::reset( r );
585  weak_ptr<T>::reset( r );
586  }
587  break;
588  case WeakShared:
589  // force re-attaching with the correct type for this
590  if( r )
592  break;
593  case Weak:
594  weak_ptr<T>::reset( r );
595  break;
596  }
597  }
598 
599 }
600 
601 #endif
602 
Observer pointer, observing a shfj::WeakObject.
Definition: weakptr.h:61
shared_ptr< T > & operator=(const shared_ptr< T > &x)
Definition: sharedptr.h:453
T * operator->() const
Definition: weakptr.h:222
virtual ~SharedObject()
notifies observers
friend class weak_shared_ptr
Definition: sharedptr.h:78
A multi-purpose general smart pointer, which can act as either a rc_ptr, a weak_ptr or a weak_shared_...
Definition: sharedptr.h:152
ref< T > & operator=(const ref< T > &other)
Definition: rcptr.h:503
T * release()
Definition: rcptr.h:499
T * get() const
Definition: weakptr.h:227
Base class for reference counted objects (intrusive)
Definition: rcptr.h:106
bool operator!=(const weak_ptr< T > &x) const
Definition: weakptr.h:249
int RefCounterType
Definition: rcptr.h:127
weak_shared_ptr: increments a reference count, is told and becomes null whenever the shared object is...
Definition: sharedptr.h:94
bool operator==(const carto::block< T, N > &b1, const carto::block< T, N > &b2)
Definition: block.h:252
VoxelRGB operator*(const VoxelRGB &aa, const uint8_t &bb)
Definition: voxelrgb_def.h:637
Reference-counting pointer.
Definition: rcptr.h:639
friend class shared_ptr
Definition: sharedptr.h:79
SharedObject & operator=(const SharedObject &)
Definition: sharedptr.h:55
rc_ptr_trick merely makes a public access to the reference counter inside a rc_ptr.
Definition: rcptrtrick.h:49
Base class for weakly referenced objects.
Definition: weakobject.h:48
T & operator*() const
Definition: weakptr.h:217
void disableRefCount()
called by destructors to avoid double deletion.
void reset(T *r=0)
Definition: weakptr.h:103
bool operator<(const weak_ptr< T > &x) const
Definition: weakptr.h:257
weak_ptr & operator=(const weak_ptr< Y > &r)
Definition: weakptr.h:144
void reset(T *r=0)
Definition: sharedptr.h:335
T * get() const
Definition: rcptr.h:666
bool testDeletable()
tests if the shared object can be deleted (no strong pointers to it).
weak_shared_ptr(T *x=0, bool externalowner=false)
Definition: sharedptr.h:217
ReferenceType referenceType() const
Definition: sharedptr.h:444
bool tryDelete()
tests if the shared object can be deleted.
void reset(T *p=NULL)
Definition: rcptr.h:664
SharedObject allows to work with combined reference counting pointers and weak (Observer) pointers...
Definition: sharedptr.h:47
bool operator==(const weak_ptr< T > &x) const
Definition: weakptr.h:241
T * release()
Definition: weakptr.h:232
void reset(ReferenceType t, T *r=0)
Definition: sharedptr.h:503
shared_ptr(ReferenceType t=Weak, T *x=0, bool externalowner=false)
Definition: sharedptr.h:354