DGtal  1.5.beta
CountedConstPtrOrConstPtr.h
1 
17 #pragma once
18 
33 #if defined(CountedConstPtrOrConstPtr_RECURSES)
34 #error Recursive header files inclusion detected in CountedConstPtrOrConstPtr.h
35 #else // defined(CountedConstPtrOrConstPtr_RECURSES)
37 #define CountedConstPtrOrConstPtr_RECURSES
38 
39 #if !defined CountedConstPtrOrConstPtr_h
41 #define CountedConstPtrOrConstPtr_h
42 
44 // Inclusions
45 #include <iostream>
46 #include "DGtal/base/Common.h"
47 #include "DGtal/base/CountedPtr.h"
48 #include "DGtal/base/CountedPtrOrPtr.h"
50 
51 namespace DGtal
52 {
53 
55  // template class CountedConstPtrOrConstPtr
93  template <typename T>
95  {
96  public:
97 
98  // ----------------------- Standard services ------------------------------
99  public:
100 
102  typedef typename CountedPtr<T>::Counter Counter;
103 
119  inline explicit CountedConstPtrOrConstPtr( const T* p = 0, bool isCountedPtr = true )
120  : myAny(0), myIsCountedPtr( isCountedPtr )
121  {
122  if ( isCountedPtr ) {
123  if (p) myAny = static_cast<void*>( new Counter( const_cast<T*>( p ) ) );
124  }
125  else
126  myAny = const_cast<void*>( static_cast<const void*>( p ) );
127  }
128 
136  {
137  if ( myIsCountedPtr ) release();
138  }
139 
148  : myIsCountedPtr( true )
149  {
150  acquire( r.myCounter );
151  }
152 
163  : myIsCountedPtr( r.myIsCountedPtr )
164  {
165  if ( myIsCountedPtr )
166  acquire( r.counterPtr() );
167  else
168  myAny = r.myAny;
169  }
170 
181  : myIsCountedPtr( r.myIsCountedPtr )
182  {
183  if ( myIsCountedPtr )
184  acquire( r.counterPtr() );
185  else
186  myAny = r.myAny;
187  }
188 
202  {
203  if ( this != & r ) {
204  if ( myIsCountedPtr ) release();
205  myIsCountedPtr = r.myIsCountedPtr;
206  if ( r.myIsCountedPtr ) acquire( r.counterPtr() );
207  else myAny = r.myAny;
208  }
209  return *this;
210  }
211 
225  {
226  if ( myIsCountedPtr ) release();
227  myIsCountedPtr = r.myIsCountedPtr;
228  if ( r.myIsCountedPtr ) acquire( r.counterPtr() );
229  else myAny = r.myAny;
230  return *this;
231  }
232 
244  {
245  if ( myIsCountedPtr ) release();
246  myIsCountedPtr = true;
247  acquire( r.myCounter );
248  return *this;
249  }
250 
254  bool isSmart() const
255  {
256  return myIsCountedPtr;
257  }
258 
262  bool isSimple() const
263  {
264  return ! myIsCountedPtr;
265  }
266 
273  bool operator==( const T* other ) const
274  {
275  return myIsCountedPtr ? ( myAny ? counterPtr()->ptr : 0 ) == other : ptr() == other;
276  }
277 
284  bool operator!=( const T* other ) const
285  {
286  return myIsCountedPtr ? ( myAny ? counterPtr()->ptr : 0 ) != other : ptr() != other;
287  }
288 
297  const T& operator*() const noexcept
298  {
299  // Travis is too slow in Debug mode with this ASSERT.
300  ASSERT( isValid() );
301  return myIsCountedPtr ? ( * counterPtr()->ptr ) : ( * ptr() );
302  }
303 
313  const T* operator->() const noexcept
314  {
315  // Travis is too slow in Debug mode with this ASSERT.
316  ASSERT( isValid() );
317  return myIsCountedPtr ? counterPtr()->ptr : ptr();
318  }
319 
327  const T* get() const noexcept
328  {
329  return myIsCountedPtr ? ( myAny ? counterPtr()->ptr : 0 ) : ptr();
330  }
331 
337  bool unique() const noexcept
338  {
339  return myIsCountedPtr
340  ? ( myAny ? counterPtr()->count == 1 : true )
341  : true;
342  }
343 
351  unsigned int count() const
352  {
353  return myIsCountedPtr ? counterPtr()->count : 0;
354  }
355 
366  inline const T* drop()
367  { // Gives back the pointer without deleting him. Delete only the counter.
368  ASSERT( isValid() );
369  if ( myIsCountedPtr ) {
370  ASSERT( unique() );
371  T* tmp = counterPtr()->ptr;
372  delete counterPtr();
373  myAny = 0;
374  return tmp;
375  } else {
376  return ptr();
377  }
378  }
379 
380 private:
381 
384  void* myAny;
387 
388 
394  inline Counter* counterPtr() const
395  {
396  // Travis is too slow in Debug mode with this ASSERT.
397  ASSERT( myIsCountedPtr );
398  return static_cast<Counter*>( myAny );
399  }
400 
406  inline T* ptr() const
407  {
408  // Travis is too slow in Debug mode with this ASSERT.
409  ASSERT( ! myIsCountedPtr );
410  return static_cast<T*>( myAny );
411  }
412 
420  inline void acquire(Counter* c) noexcept
421  { // increment the count
422  // Travis is too slow in Debug mode with this ASSERT.
423  ASSERT( myIsCountedPtr );
424  myAny = static_cast<void*>( c );
425  if (c) ++c->count;
426  }
427 
436  void release()
437  { // decrement the count, delete if it is 0
438  // Travis is too slow in Debug mode with this ASSERT.
439  ASSERT( myIsCountedPtr );
440  if (myAny) {
441  Counter * counter = counterPtr();
442  if (--counter->count == 0) {
443  delete counter->ptr;
444  delete counter;
445  }
446  myAny = 0;
447  }
448  }
449 
450 
451  // ----------------------- Interface --------------------------------------
452  public:
453 
458  void selfDisplay ( std::ostream & out ) const;
459 
464  bool isValid() const;
465 
466  // ------------------------- Protected Datas ------------------------------
467  private:
468  // ------------------------- Private Datas --------------------------------
469  private:
470 
471  // ------------------------- Hidden services ------------------------------
472  protected:
473 
474 
475  // ------------------------- Internals ------------------------------------
476  private:
477 
478  }; // end of class CountedConstPtrOrConstPtr
479 
480 
487  template <typename T>
488  std::ostream&
489  operator<< ( std::ostream & out, const CountedConstPtrOrConstPtr<T> & object );
490 
491 } // namespace DGtal
492 
493 
495 // Includes inline functions.
496 #include "DGtal/base/CountedConstPtrOrConstPtr.ih"
497 
498 // //
500 
501 #endif // !defined CountedConstPtrOrConstPtr_h
502 
503 #undef CountedConstPtrOrConstPtr_RECURSES
504 #endif // else defined(CountedConstPtrOrConstPtr_RECURSES)
Aim: Smart or simple const pointer on T. It can be a smart pointer based on reference counts or a sim...
CountedConstPtrOrConstPtr(const T *p=0, bool isCountedPtr=true)
CountedConstPtrOrConstPtr & operator=(const CountedConstPtrOrConstPtr &r)
CountedConstPtrOrConstPtr(const CountedPtrOrPtr< T > &r) noexcept
CountedConstPtrOrConstPtr & operator=(const CountedPtrOrPtr< T > &r)
CountedConstPtrOrConstPtr(const CountedPtr< T > &r) noexcept
bool myIsCountedPtr
If true, 'this' pointer object is smart, otherwise it is simple.
CountedConstPtrOrConstPtr & operator=(const CountedPtr< T > &r)
void selfDisplay(std::ostream &out) const
CountedConstPtrOrConstPtr(const CountedConstPtrOrConstPtr &r) noexcept
CountedPtr< T >::Counter Counter
The counter is the same as CountedPtr.
Aim: Smart or simple pointer on T. It can be a smart pointer based on reference counts or a simple po...
Aim: Smart pointer based on reference counts.
Definition: CountedPtr.h:80
DGtal is the top-level namespace which contains all DGtal functions and types.
std::ostream & operator<<(std::ostream &out, const ATu0v1< TKSpace, TLinearAlgebra > &object)
T * ptr
A pointer to a (shared) dynamically allocated object of type T.
Definition: CountedPtr.h:105
unsigned count
The number of CountedPtr pointing to this counter.
Definition: CountedPtr.h:107