DGtal  0.9.2
CountedPtrOrPtr.h
1 
17 #pragma once
18 
33 #if defined(CountedPtrOrPtr_RECURSES)
34 #error Recursive header files inclusion detected in CountedPtrOrPtr.h
35 #else // defined(CountedPtrOrPtr_RECURSES)
36 
37 #define CountedPtrOrPtr_RECURSES
38 
39 #if !defined CountedPtrOrPtr_h
40 
41 #define CountedPtrOrPtr_h
42 
44 // Inclusions
45 #include <iostream>
46 #include "DGtal/base/Common.h"
47 #include "DGtal/base/CountedPtr.h"
49 
50 namespace DGtal
51 {
52  template <typename T> class CountedConstPtrOrConstPtr;
53 
55  // template class CountedPtrOrPtr
94  template <typename T>
95  class CountedPtrOrPtr
96  {
97  public:
98  friend class CountedConstPtrOrConstPtr<T>;
99 
100  // ----------------------- Standard services ------------------------------
101  public:
102 
104  typedef typename CountedPtr<T>::Counter Counter;
105 
121  inline explicit CountedPtrOrPtr( T* p = 0, bool isCountedPtr = true )
122  : myAny(0), myIsCountedPtr( isCountedPtr )
123  {
124  if ( isCountedPtr ) {
125  if (p) myAny = static_cast<void*>( new Counter( p ) );
126  }
127  else
128  myAny = static_cast<void*>( p );
129  }
130 
138  {
139  if ( myIsCountedPtr ) release();
140  }
141 
149  CountedPtrOrPtr( const CountedPtr<T> & r ) throw()
150  : myIsCountedPtr( true )
151  {
152  acquire( r.myCounter );
153  }
154 
165  : myIsCountedPtr( r.myIsCountedPtr )
166  {
167  if ( myIsCountedPtr )
168  acquire( r.counterPtr() );
169  else
170  myAny = r.myAny;
171  }
172 
186  {
187  if ( this != & r ) {
188  if ( myIsCountedPtr ) release();
189  myIsCountedPtr = r.myIsCountedPtr;
190  if ( r.myIsCountedPtr ) acquire( r.counterPtr() );
191  else myAny = r.myAny;
192  }
193  return *this;
194  }
195 
207  {
208  if ( myIsCountedPtr ) release();
209  myIsCountedPtr = true;
210  acquire( r.myCounter );
211  return *this;
212  }
213 
217  bool isSmart() const
218  {
219  return myIsCountedPtr;
220  }
221 
225  bool isSimple() const
226  {
227  return ! myIsCountedPtr;
228  }
229 
236  bool operator==( const T* other ) const
237  {
238  return myIsCountedPtr ? ( myAny ? counterPtr()->ptr : 0 ) == other : ptr() == other;
239  }
240 
247  bool operator!=( const T* other ) const
248  {
249  return myIsCountedPtr ? ( myAny ? counterPtr()->ptr : 0 ) != other : ptr() != other;
250  }
251 
260  T& operator*() const throw()
261  {
262  // Travis is too slow in Debug mode with this ASSERT.
263  ASSERT( isValid() );
264  return myIsCountedPtr ? ( * counterPtr()->ptr ) : ( * ptr() );
265  }
266 
276  T* operator->() const throw()
277  {
278  // Travis is too slow in Debug mode with this ASSERT.
279  ASSERT( isValid() );
280  return myIsCountedPtr ? counterPtr()->ptr : ptr();
281  }
282 
290  T* get() const throw()
291  {
292  return myIsCountedPtr ? ( myAny ? counterPtr()->ptr : 0 ) : ptr();
293  }
294 
300  bool unique() const throw()
301  {
302  return myIsCountedPtr
303  ? ( myAny ? counterPtr()->count == 1 : true )
304  : true;
305  }
306 
314  unsigned int count() const
315  {
316  return myIsCountedPtr ? counterPtr()->count : 0;
317  }
318 
329  inline T* drop()
330  { // Gives back the pointer without deleting him. Delete only the counter.
331  ASSERT( isValid() );
332  if ( myIsCountedPtr ) {
333  ASSERT( unique() );
334  T* tmp = counterPtr()->ptr;
335  delete counterPtr();
336  myAny = 0;
337  return tmp;
338  } else {
339  return ptr();
340  }
341  }
342 
343 private:
344 
347  void* myAny;
350 
356  inline Counter* counterPtr() const
357  {
358  // Travis is too slow in Debug mode with this ASSERT.
359  ASSERT( myIsCountedPtr );
360  return static_cast<Counter*>( myAny );
361  }
362 
368  inline T* ptr() const
369  {
370  // Travis is too slow in Debug mode with this ASSERT.
371  ASSERT( ! myIsCountedPtr );
372  return static_cast<T*>( myAny );
373  }
374 
382  inline void acquire(Counter* c) throw()
383  { // increment the count
384  // Travis is too slow in Debug mode with this ASSERT.
385  ASSERT( myIsCountedPtr );
386  myAny = static_cast<void*>( c );
387  if (c) ++c->count;
388  }
389 
398  void release()
399  { // decrement the count, delete if it is 0
400  // Travis is too slow in Debug mode with this ASSERT.
401  ASSERT( myIsCountedPtr );
402  if (myAny) {
403  Counter * counter = counterPtr();
404  if (--counter->count == 0) {
405  delete counter->ptr;
406  delete counter;
407  }
408  myAny = 0;
409  }
410  }
411 
412 
413  // ----------------------- Interface --------------------------------------
414  public:
415 
420  void selfDisplay ( std::ostream & out ) const;
421 
426  bool isValid() const;
427 
428  // ------------------------- Protected Datas ------------------------------
429  private:
430  // ------------------------- Private Datas --------------------------------
431  private:
432 
433  // ------------------------- Hidden services ------------------------------
434  protected:
435 
436 
437  // ------------------------- Internals ------------------------------------
438  private:
439 
440  }; // end of class CountedPtrOrPtr
441 
442 
449  template <typename T>
450  std::ostream&
451  operator<< ( std::ostream & out, const CountedPtrOrPtr<T> & object );
452 
453 } // namespace DGtal
454 
455 
457 // Includes inline functions.
458 #include "DGtal/base/CountedPtrOrPtr.ih"
459 
460 // //
462 
463 #endif // !defined CountedPtrOrPtr_h
464 
465 #undef CountedPtrOrPtr_RECURSES
466 #endif // else defined(CountedPtrOrPtr_RECURSES)
Aim: Smart pointer based on reference counts.
Definition: CountedPtr.h:79
Aim: Smart or simple const pointer on T. It can be a smart pointer based on reference counts or a sim...
CountedPtrOrPtr(const CountedPtr< T > &r)
T * ptr
A pointer to a (shared) dynamically allocated object of type T.
Definition: CountedPtr.h:105
Aim: Smart or simple pointer on T. It can be a smart pointer based on reference counts or a simple po...
Definition: CountedPtr.h:51
void acquire(Counter *c)
Counter * counterPtr() const
CountedPtrOrPtr(T *p=0, bool isCountedPtr=true)
void selfDisplay(std::ostream &out) const
DGtal is the top-level namespace which contains all DGtal functions and types.
bool operator==(const T *other) const
CountedPtrOrPtr(const CountedPtrOrPtr &r)
bool isValid() const
CountedPtrOrPtr & operator=(const CountedPtrOrPtr &r)
CountedPtr< T >::Counter Counter
The counter is the same as CountedPtr.
unsigned int count() const
CountedPtrOrPtr & operator=(const CountedPtr< T > &r)
unsigned count
The number of CountedPtr pointing to this counter.
Definition: CountedPtr.h:107
bool myIsCountedPtr
If true, 'this' pointer object is smart, otherwise it is simple.
bool operator!=(const T *other) const
Counter * myCounter
The counter object pointed by this smart pointer.
Definition: CountedPtr.h:308