DGtal  1.0.0
Clone.h
1 
17 #pragma once
18 
31 #if defined(Clone_RECURSES)
32 #error Recursive header files inclusion detected in Clone.h
33 #else // defined(Clone_RECURSES)
34 
35 #define Clone_RECURSES
36 
37 #if !defined Clone_h
38 
39 #define Clone_h
40 
42 // Inclusions
43 #include <iostream>
44 #include "DGtal/base/Common.h"
45 #include "DGtal/base/CountedPtr.h"
46 #include "DGtal/base/CowPtr.h"
48 
49 namespace DGtal
50 {
51 
53  // template class Clone
265  template <typename T>
266  class Clone
267  {
268  // ----------------------- Internal classes ------------------------------
269  protected:
270 
280  void display( const std::string& method, Parameter p ) const
281  {
282  std::string sp;
283  switch (p) {
284  case CONST_LEFT_VALUE_REF: sp = "CONST_LEFT_VALUE_REF"; break;
285  case LEFT_VALUE_REF: sp = "LEFT_VALUE_REF"; break;
286  case PTR: sp = "PTR"; break;
287  case CONST_PTR: sp = "CONST_PTR"; break;
288  case COW_PTR: sp = "COW_PTR"; break;
289  case COUNTED_PTR: sp = "COUNTED_PTR"; break;
290  case RIGHT_VALUE_REF: sp = "RIGHT_VALUE_REF"; break;
291  case COUNTED_PTR_OR_PTR: sp = "COUNTED_PTR_OR_PTR"; break;
292  case COUNTED_CONST_PTR_OR_CONST_PTR: sp = "COUNTED_CONST_PTR_OR_CONST_PTR"; break;
293  default: sp = "UNKNOWN"; break;
294  }
295  trace.info() << "[Clone<T>::" << method << " param="
296  << sp << "]" << std::endl;
297 
298  }
300  struct TempPtr {
305  inline TempPtr( T* ptr ) : _ptr( ptr ) {}
309  inline ~TempPtr() { ASSERT( _ptr != 0 ); delete _ptr; }
311  T* _ptr;
312  };
313 
314  // ----------------------- Standard services ------------------------------
315  public:
316 
320  inline ~Clone() {}
321 
326  inline Clone( const Clone & other )
327  : myParam( other.myParam ), myPtr( other.myPtr ) {}
328 
334  inline Clone( const T & t )
335  : myParam( CONST_LEFT_VALUE_REF ), myPtr( static_cast<const void*>( &t ) ) {}
336 
343  inline Clone( T* ptrT )
344  : myParam( PTR ), myPtr( static_cast<const void*>( ptrT ) ) {}
345 
352  inline Clone( const CowPtr<T> & ptrT )
353  : myParam( COW_PTR ), myPtr( static_cast<const void*>( &ptrT ) ) {}
354 
361  inline Clone( const CountedPtr<T> & ptrT )
362  : myParam( COUNTED_PTR ), myPtr( static_cast<const void*>( &ptrT ) ) {}
363 
370  inline Clone( T && t )
371  : myParam( RIGHT_VALUE_REF ), myPtr( static_cast<const void*>( &t ) ) {}
372 
373 
384  inline operator T() const
385  {
386  // display( "operator T() const", myParam );
387  switch( myParam ) {
389  return T( * static_cast< const T* >( myPtr ) );
390  case PTR: {
391  TempPtr tmp( const_cast< T* >( static_cast< const T* >( myPtr ) ) );
392  return T( * static_cast< const T* >( myPtr ) );
393  } // destroy acquired pointer.
394  case COW_PTR:
395  return T( * static_cast< const CowPtr<T>* >( myPtr )->get() );
396  case COUNTED_PTR:
397  return T( * static_cast< const CountedPtr<T>* >( myPtr )->get() );
398  case RIGHT_VALUE_REF:
399  return T( std::move( * const_cast<T*>( static_cast< const T* >( myPtr ) ) ) );
400  default: ASSERT( false && "[Clone::operator T() const] Invalid cast for given type. " );
401  return T( * static_cast< const T* >( myPtr ) );
402  }
403  }
404 
415  inline operator CowPtr<T>() const
416  {
417  // display( "operator CowPtr<T>() const", myParam );
418  switch( myParam ) {
420  return CowPtr<T>( new T( * static_cast< const T* >( myPtr ) ) );
421  case PTR:
422  return CowPtr<T>( const_cast<T*>( static_cast< const T* >( myPtr ) ) );
423  case COW_PTR:
424  return CowPtr<T>( * static_cast< const CowPtr<T>* >( myPtr ) );
425  case COUNTED_PTR:
426  return CowPtr<T>( * static_cast< const CountedPtr<T>* >( myPtr ), true );
427  case RIGHT_VALUE_REF:
428  return CowPtr<T>( new T( std::move( * const_cast<T*>( static_cast< const T* >( myPtr ) ) ) ) );
429  default: ASSERT( false && "[Clone::operator CowPtr<T>() const] Invalid cast for given type. " );
430  return CowPtr<T>( 0 );
431  }
432  }
433 
444  inline operator CountedPtr<T>() const
445  {
446  // display( "operator CountedPtr<T>() const", myParam );
447  switch( myParam ) {
449  return CountedPtr<T>( new T( * static_cast< const T* >( myPtr ) ) );
450  case PTR:
451  return CountedPtr<T>( const_cast<T*>( static_cast< const T* >( myPtr ) ) );
452  case COW_PTR:
453  return CountedPtr<T>( new T( * static_cast< const CowPtr<T>* >( myPtr )->get() ) );
454  case COUNTED_PTR:
455  return CountedPtr<T>( * static_cast< const CountedPtr<T>* >( myPtr ) );
456  case RIGHT_VALUE_REF:
457  return CountedPtr<T>( new T( std::move( * const_cast<T*>( static_cast< const T* >( myPtr ) ) ) ) );
458  default: ASSERT( false && "[Clone::operator CountedPtr<T>() const] Invalid cast for given type. " );
459  return CountedPtr<T>( 0 );
460  }
461  }
462 
476  inline T* operator&() const
477  {
478  // display( "T* operator &() const", myParam );
479  switch( myParam ) {
481  return new T( * static_cast< const T* >( myPtr ) );
482  case PTR:
483  return const_cast<T*>( static_cast< const T* >( myPtr ) );
484  case COW_PTR:
485  return new T( *( static_cast< const CowPtr<T>* >( myPtr )->get() ) );
486  case COUNTED_PTR:
487  return new T( *( static_cast< const CountedPtr<T>* >( myPtr )->get() ) );
488  case RIGHT_VALUE_REF:
489  return new T( std::move( * const_cast<T*>( static_cast< const T* >( myPtr ) ) ) );
490  default: ASSERT( false && "[T* Clone::operator&() const] Invalid address for given type. " );
491  return 0;
492  }
493  }
494 
495  // ------------------------- Private Datas --------------------------------
496  private:
500  const void* const myPtr;
501 
502 
503  // ------------------------- Hidden services ------------------------------
504  private:
505 
510  Clone();
511 
512 
519  Clone & operator= ( const Clone & other );
520 
521  // ------------------------- Internals ------------------------------------
522  private:
523 
524  }; // end of class Clone
525 
526 } // namespace DGtal
527 
528 
530 // Includes inline functions.
531 
532 // //
534 
535 #endif // !defined Clone_h
536 
537 #undef Clone_RECURSES
538 #endif // else defined(Clone_RECURSES)
Clone(T *ptrT)
Definition: Clone.h:343
Aim: Smart pointer based on reference counts.
Definition: CountedPtr.h:79
Trace trace
Definition: Common.h:144
T * operator &() const
Definition: Clone.h:476
Clone(T &&t)
Definition: Clone.h:370
Clone(const T &t)
Definition: Clone.h:334
Parameter
Internal class that allows to distinguish the different types of parameters.
Definition: Clone.h:272
Clone & operator=(const Clone &other)
Clone(const CountedPtr< T > &ptrT)
Definition: Clone.h:361
Clone(const Clone &other)
Definition: Clone.h:326
Aim: This class encapsulates its parameter class to indicate that the given parameter is required to ...
Definition: Clone.h:266
T * _ptr
Acquired pointer.
Definition: Clone.h:311
Internal class that is used for a late deletion of an acquired pointer.
Definition: Clone.h:300
const Parameter myParam
Characterizes the type of the input parameter at clone instanciation.
Definition: Clone.h:498
DGtal is the top-level namespace which contains all DGtal functions and types.
std::ostream & info()
const void *const myPtr
Stores the address of the input parameter for further use.
Definition: Clone.h:500
void display(const std::string &method, Parameter p) const
Definition: Clone.h:280
Aim: Copy on write shared pointer.
Definition: CowPtr.h:67
Clone(const CowPtr< T > &ptrT)
Definition: Clone.h:352