cartobase  4.5.0
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 WeakObject, public 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 );
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 weak_shared_ptr<T> & x ) const
114  { return weak_ptr<T>::operator < (x); }
115  bool operator < ( const rc_ptr<T> & x ) const
116  { return get() < x.get(); }
117  bool operator < ( const weak_ptr<T> & x ) const
118  { return get() < x.get(); }
119  T& operator * () const
120  { return weak_ptr<T>::operator * (); }
121  T* operator -> () const
122  { return weak_ptr<T>::operator -> (); }
123 
127  T* release();
128  void reset( T* r = 0 );
129 
130  private:
131  friend class WeakObject;
132  friend class rc_ptr_trick;
133  void update();
134  };
135 
136 
143  template <typename T>
144  class shared_ptr : public weak_shared_ptr<T>
145  {
146  public:
148  {
152  };
153 
154  explicit shared_ptr( ReferenceType t = Weak, T* x = 0,
155  bool externalowner = false );
156  shared_ptr( const shared_ptr<T> & x );
157  shared_ptr( const weak_shared_ptr<T> & x );
158  shared_ptr( const rc_ptr<T> & x );
159  shared_ptr( const weak_ptr<T> & x );
160  ~shared_ptr();
161 
162  bool operator == ( const shared_ptr<T> & x ) const
163  { return weak_ptr<T>::operator == (x); }
164  bool operator == ( const T* x ) const
165  { return this->weak_ptr<T>::get() == x; }
166  bool operator == ( const rc_ptr<T> & x ) const
167  { return this->weak_ptr<T>::get() == x.get(); }
168  bool operator == ( const weak_ptr<T> & x ) const
169  { return this->weak_ptr<T>::get() == x.get(); }
170  bool operator == ( const weak_shared_ptr<T> & x ) const
171  { return this->weak_ptr<T>::get() == x.get(); }
172  bool operator < ( const shared_ptr<T> & x ) const
173  { return weak_ptr<T>::operator < (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 
181  shared_ptr<T> & operator = ( const shared_ptr<T> & x );
183  shared_ptr<T> & operator = ( const rc_ptr<T> & x );
184  shared_ptr<T> & operator = ( const weak_ptr<T> & x );
185  T* release();
186  void reset( ReferenceType t, T* r = 0 );
187 
189 
190  private:
191  ReferenceType _reftype;
192  };
193 
194 
195  // ----------------------------
196 
197  template <typename T>
198  inline
199  weak_shared_ptr<T>::weak_shared_ptr( T* x, bool externalowner )
200  : rc_ptr<T>( x, externalowner ), weak_ptr<T>( x )
201  {
202  // force re-attaching with the correct type for this
203  if( x )
204  {
205  ++x->weak_count;
206  x->attachWeakPtr( *this );
207  }
208  }
209 
210 
211  template <typename T>
212  inline
214  : rc_ptr<T>( x ), weak_ptr<T>( x )
215  {
216  // force re-attaching with the correct type for this
217  if( x.get() )
218  {
219  ++x->weak_count;
220  x->attachWeakPtr( *this );
221  }
222  }
223 
224 
225  template <typename T>
226  inline
228  : rc_ptr<T>( x ), weak_ptr<T>( x.get() )
229  {
230  // force re-attaching with the correct type for this
231  if( x.get() )
232  {
233  ++x->weak_count;
234  x->attachWeakPtr( *this );
235  }
236  }
237 
238 
239  template <typename T>
240  inline
242  : rc_ptr<T>( x ), weak_ptr<T>( x )
243  {
244  // force re-attaching with the correct type for this
245  if( x.get() )
246  {
247  ++x->weak_count;
248  x->attachWeakPtr( *this );
249  }
250  }
251 
252 
253  template <typename T>
254  inline
256  {
257  if( get() )
258  --get()->weak_count;
259  }
260 
261 
262  template <typename T>
263  inline
265  {
266  // weak_ptr<T>::update(); is done by WeakObject
267  rc_ptr<T>::reset( 0 );
268  }
269 
270 
271  template <typename T>
272  inline
273  weak_shared_ptr<T> & weak_shared_ptr<T>::operator =
274  ( const weak_shared_ptr<T> & x )
275  {
276  if( &x == this )
277  return *this;
278 
279  if( get() )
280  --get()->weak_count;
282  // force re-attaching with the correct type for this
283  if( x.get() )
284  {
285  ++x->weak_count;
286  x->attachWeakPtr( *this );
287  }
289  return *this;
290  }
291 
292 
293  template <typename T>
294  inline
296  ( const rc_ptr<T> & x )
297  {
298  if( this != &x )
299  reset( x.get() );
300  return *this;
301  }
302 
303 
304  template <typename T>
305  inline
307  {
308  if( get() )
309  --get()->weak_count;
311  return rc_ptr<T>::release();
312  }
313 
314 
315  template <typename T>
316  inline
318  {
319  if( get() )
320  --get()->weak_count;
321  weak_ptr<T>::reset( r );
322  // force re-attaching with the correct type for this
323  if( r )
324  {
325  ++r->weak_count;
326  r->attachWeakPtr( *this );
327  }
328  rc_ptr<T>::reset( r );
329  }
330 
331  // ----------------
332 
333 
334  template <typename T>
335  inline
336  shared_ptr<T>::shared_ptr( ReferenceType t, T* x, bool externalowner )
337  : weak_shared_ptr<T>( x, externalowner ), _reftype( t )
338  {
339  switch( t )
340  {
341  case Strong:
342  if( x )
343  --x->weak_count;
344  break;
345  case WeakShared:
346  break;
347  case Weak:
349  weak_ptr<T>::reset( x );
350  break;
351  }
352  }
353 
354 
355  template <typename T>
356  inline
358  : weak_shared_ptr<T>( x ), _reftype( x.referenceType() )
359  {
360  switch( referenceType() )
361  {
362  case Strong:
363  if( x.get() )
364  --x->weak_count;
365  break;
366  case WeakShared:
367  break;
368  case Weak:
370  weak_ptr<T>::reset( x.get() );
371  break;
372  }
373  }
374 
375 
376  template <typename T>
377  inline
379  : weak_shared_ptr<T>( x ), _reftype( WeakShared )
380  {
381  }
382 
383 
384  template <typename T>
385  inline
387  : weak_shared_ptr<T>( x.get() ), _reftype( Strong )
388  {
389  if( x )
390  --x->weak_count;
391  }
392 
393 
394  template <typename T>
395  inline
397  : weak_shared_ptr<T>( x )
398  {
400  weak_ptr<T>::reset( x.get() );
401  }
402 
403 
404  template <typename T>
405  inline
407  {
408  switch( referenceType() )
409  {
410  case Strong:
411  if( this->get() )
412  ++this->get()->weak_count; // as it will be decremented soon
413  // WARNING: this is not thread-safe
414  break;
415  case WeakShared:
416  break;
417  case Weak:
418  release();
419  break;
420  }
421  }
422 
423 
424  template <typename T>
425  inline typename shared_ptr<T>::ReferenceType
427  {
428  return _reftype;
429  }
430 
431 
432  template <typename T>
433  inline
435  ( const shared_ptr<T> & x )
436  {
437  reset( x.referenceType(), x.get() );
438  return *this;
439  }
440 
441 
442  template <typename T>
443  inline
445  ( const weak_shared_ptr<T> & x )
446  {
447  reset( WeakShared, x.get() );
448  return *this;
449  }
450 
451 
452  template <typename T>
453  inline
455  {
456  reset( Strong, x.get() );
457  return *this;
458  }
459 
460 
461  template <typename T>
462  inline
464  {
465  reset( Weak, x.get() );
466  return *this;
467  }
468 
469 
470  template <typename T>
471  inline
473  {
474  T* x = weak_ptr<T>::release();
475  if( this->get() && referenceType() == WeakShared )
476  --this->get()->weak_count;
477  if( referenceType() != Weak )
478  return rc_ptr<T>::release();
479  return x;
480  }
481 
482 
483  template <typename T>
484  inline
486  {
487  if( r == this->get() )
488  {
489  if( t != referenceType() )
490  {
491  switch( t )
492  {
493  case Strong:
494  switch( referenceType() )
495  {
496  case WeakShared:
497  --r->weak_count;
498  break;
499  case Weak:
500  rc_ptr<T>::reset( r );
501  break;
502  default:
503  break;
504  }
505  break;
506  case WeakShared:
507  switch( referenceType() )
508  {
509  case Strong:
510  ++r->weak_count;
511  break;
512  case Weak:
514  break;
515  default:
516  break;
517  }
518  break;
519  case Weak:
520  switch( referenceType() )
521  {
522  case Strong:
523  rc_ptr<T>::reset( 0 );
524  if( this->get() ) // r could have been destroyed by now
525  r->attachWeakPtr( static_cast<weak_ptr<T> &>( *this ) );
526  break;
527  case WeakShared:
528  if( r->_refCounter == 1 )
529  weak_shared_ptr<T>::reset( 0 ); // should destroy r...
530  else
531  {
533  weak_ptr<T>::reset( r );
534  }
535  break;
536  default:
537  break;
538  }
539  }
540  _reftype = t;
541  }
542  return;
543  }
544 
545  if( this->get() )
546  switch( referenceType() )
547  {
548  case Strong:
549  rc_ptr<T>::reset( 0 );
550  break;
551  case WeakShared:
553  break;
554  case Weak:
555  weak_ptr<T>::reset( 0 );
556  }
557 
558  _reftype = t;
559  switch( t )
560  {
561  case Strong:
562  // force re-attaching with the correct type for this
563  if( r )
564  {
565  r->attachWeakPtr( *this );
566  rc_ptr<T>::reset( r );
567  weak_ptr<T>::reset( r );
568  }
569  break;
570  case WeakShared:
571  // force re-attaching with the correct type for this
572  if( r )
574  break;
575  case Weak:
576  weak_ptr<T>::reset( r );
577  break;
578  }
579  }
580 
581 }
582 
583 #endif
584 
Observer pointer, observing a shfj::WeakObject.
Definition: weakptr.h:61
shared_ptr< T > & operator=(const shared_ptr< T > &x)
Definition: sharedptr.h:435
T * operator->() const
Definition: weakptr.h:222
virtual ~SharedObject()
notifies observers
A multi-purpose general smart pointer, which can act as either a rc_ptr, a weak_ptr or a weak_shared_...
Definition: sharedptr.h:144
ref< T > & operator=(const ref< T > &other)
Definition: rcptr.h:470
bool operator<(const weak_ptr< T > &x) const
Definition: weakptr.h:249
T * release()
Definition: rcptr.h:466
bool operator==(const weak_ptr< T > &x) const
Definition: weakptr.h:241
Base class for reference counted objects (intrusive)
Definition: rcptr.h:105
bool operator==(const shared_ptr< T > &x) const
Definition: sharedptr.h:162
int RefCounterType
Definition: rcptr.h:126
weak_shared_ptr: increments a reference count, is told and becomes null whenever the shared object is...
Definition: sharedptr.h:94
T * get() const
Definition: weakptr.h:227
Reference-counting pointer.
Definition: rcptr.h:606
T * get() const
Definition: rcptr.h:625
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
T & operator*() const
Definition: weakptr.h:217
ReferenceType referenceType() const
Definition: sharedptr.h:426
T * operator->() const
Definition: sharedptr.h:121
Base class for weakly referenced objects.
Definition: weakobject.h:48
void disableRefCount()
called by destructors to avoid double deletion.
void reset(T *r=0)
Definition: weakptr.h:103
weak_ptr & operator=(const weak_ptr< Y > &r)
Definition: weakptr.h:144
void reset(T *r=0)
Definition: sharedptr.h:317
T * get() const
Definition: sharedptr.h:103
bool testDeletable()
tests if the shared object can be deleted (no strong pointers to it).
weak_shared_ptr< T > & operator=(const weak_shared_ptr< T > &x)
Definition: sharedptr.h:274
T & operator*() const
Definition: sharedptr.h:119
weak_shared_ptr(T *x=0, bool externalowner=false)
Definition: sharedptr.h:199
bool tryDelete()
tests if the shared object can be deleted.
void reset(T *p=NULL)
Definition: rcptr.h:623
bool operator==(const T *x) const
Definition: sharedptr.h:105
SharedObject allows to work with combined reference counting pointers and weak (Observer) pointers...
Definition: sharedptr.h:47
T * release()
Definition: weakptr.h:232
void reset(ReferenceType t, T *r=0)
Definition: sharedptr.h:485
shared_ptr(ReferenceType t=Weak, T *x=0, bool externalowner=false)
Definition: sharedptr.h:336