DGtal  0.9.3beta
Data Structures | Public Member Functions | Protected Types | Private Member Functions | Private Attributes
DGtal::Clone< T > Class Template Reference

#include <DGtal/base/Clone.h>

Data Structures

struct  TempPtr
 

Public Member Functions

 ~Clone ()
 
 Clone (const Clone &other)
 
 Clone (const T &t)
 
 Clone (T *ptrT)
 
 Clone (const CowPtr< T > &ptrT)
 
 Clone (const CountedPtr< T > &ptrT)
 
 Clone (T &&t)
 
 operator T () const
 
 operator CowPtr< T > () const
 
T * operator& () const
 

Protected Types

enum  Parameter {
  CONST_LEFT_VALUE_REF, LEFT_VALUE_REF, PTR, CONST_PTR,
  COW_PTR, COUNTED_PTR, RIGHT_VALUE_REF, COUNTED_PTR_OR_PTR,
  COUNTED_CONST_PTR_OR_CONST_PTR
}
 

Private Member Functions

 Clone ()
 
Cloneoperator= (const Clone &other)
 

Private Attributes

const Parameter myParam
 
const void *const myPtr
 

Detailed Description

template<typename T>
class DGtal::Clone< T >

Aim: This class encapsulates its parameter class to indicate that the given parameter is required to be duplicated (generally, this is done to have a longer lifetime than the function itself). On one hand, the user is reminded of the possible cost of duplicating the argument parameter, while he is also aware that the lifetime of the parameter is not a problem for the function. On the other hand, the Clone class is smart enough to enforce duplication only if needed. Substantial speed-up can be achieve through this mechanism.

Description of template class 'Clone'

(For a complete description, see Parameter passing, cloning and referencing).

The class Clone is used in methods or functions to encapsulate the parameter types. The following conversion from input parameter to data member or variable are sumed up in the following table:

Argument type: const T& T* CountedPtr<T> CowPtr<T> T&& (c++11)
To:T Dupl. O(N) Acq. Dupl. O(N)Dupl. O(N) Dupl. O(N) Move. O(1)
To:T* Dupl. O(N) Acq. O(1) Dupl. O(N) Dupl. O(N) Move. O(1)
To:CowPtr<T> Dupl. O(N) Acq. O(1) Lazy. O(1)/O(N)Lazy. O(1)/O(N)Move. O(1)

with abbreviations:

It is clear that worst case is duplication while sometimes Clone is constant time (while guaranteeing object invariance and life-time).

Note
The usage of Clone<T> instead of const T & or const T * in parameters is always recommended when the user duplicates the parameter and stores a clone of it as a data member for later use. The usage Clone<T> instead of T is recommended whenever T is big (the object is sometimes duplicated twice). When the object is small, writing either Clone<T> or T is acceptable. If your member is a CowPtr<T>, then you should use a Clone<T> as parameter. Depending on your data member, we advise the following parameter definition when duplication is asked for.
member type:T big T CowPtr<T> T*
parameterT or Clone<T> Clone<T> Clone<T> Clone<T>
Note
A conversion to T* means pointer acquisition. Hence the programmer should take care of deletion of the object. Otherwise, deletion is automatic for T or CowPtr<T> member. Furthermore, a conversion to a T* requires the use of the address operator (operator&) by the developer. If argument is Clone<T> a, and member name is b:
member type:T T* CowPtr<T>
member deletion:automatic manual automatic
conversion:automatic: b(a) address: b(&a)automatic: b(a)
Note
When choosing a Clone<T> parameter, the programmer should really consider using a CowPtr<T> member to store it, since it is the most versatile and optimizable variant. The only advantage of the two others storing methods (T and T*) is that there is one less indirection.
Note that an instance of Clone<T> is itself a light object (it holds only a const enum and const pointer), the duplication (if necessary) takes place when the user instantiates its member of type T (or CowPtr<T> or T* member).
Template Parameters
Tis any type.
See also
Alias
ConstAlias
Note
(Speed) Even on a small type (here a pair<int,int>), it is much faster than NClone and has the advantage (wrt Clone<T>) to handle nicely both const T& and CowPtr<T> as input. It may be slightly slower than deprecated::Clone (and by value or by const ref parameter passing) for small objects like a pair<int,int>. This is certainly due to the fact that it uses one more integer register for myParam data member.
Type Context value const ref deprecated::Clone Clone
2xint i7 2.4GHz 48ms 48ms 48ms 59ms
2xdoublei7 2.4GHz 48ms 48ms 48ms 49ms
2xint Xeon 2.67GHz54ms 54ms 54ms 54ms
2xdoubleXeon 2.67GHz54ms 54ms 54ms 53.5ms
Note
It prevents direct assignment to CountedPtr<T> since their meaning is "shared_ptr".

It can be used as follows. Consider this simple example where class A is a big object. Then we define three classes B1, B2 and B3, that uses some instance of A.

const int N = 10000;
struct A { ...
int table[N];
};
// Each B1, B2 or B3 uses A, but we do not know if A will be copied
// or just referenced by only looking at the declaration of
// the method. Generally the ambiguity is removed by adding
// comments or, for the experienced developper, by looking at
// other parts of the code.
// Only aliasing, but for a long lifetime.
struct B1 {
B1( const A & a ) // ambiguous, cost is O(1) here and lifetime of a should exceed constructor.
: myA( a ) {}
...
const A & myA;
};
// Copying as data member (stack or heap depending on B2 instance)
struct B2 {
B2( const A & a ) // ambiguous, cost is O(N) here
: myA( a ) {}
...
A myA;
};
// Copying on heap and data member pointing on it.
struct B3 {
B3( const A & a ) // ambiguous, cost is O(N) here
{ myA = new A( a ); }
~B3()
{ if ( myA != 0 ) delete myA; }
...
A* myA;
};

Sometimes it is also very important that the developper that uses the library is conscious that an object, say b, may require that an instance a given as parameter should have a lifetime longer than b itself (case for an instance of B1 above). Classes Clone, Alias, ConstAlias exist for these reasons. The classes above may be rewritten as follows.

// Aliasing for a long lifetime is visible.
struct B1 {
B1( ConstAlias<A> a ) // not ambiguous, cost is O(1) here and lifetime of a should be long enough
: myA( a ) {}
...
const A & myA;
// or Const A* myA;
};
// Cloning as data member is visible.
struct B2 {
B2( Clone<A> a ) // not ambiguous, cost is O(N) here and lifetime of a is whatever.
: myA( a ) {}
...
A myA;
};
// Cloning on the heap requires address operator, so that the user remembers calling \c delete.
struct B3_v1 {
B3_v1( Clone<A> a ) // not ambiguous, cost is O(N) here and lifetime of a is whatever.
: myA( &a ) {}
~B3_v1() { if ( myA != 0 ) delete myA; }
...
A* myA;
};
// Cloning on the heap with CountedPtr mechanism is straightforward.
struct B3_v2 {
B3_v2( Clone<A> a ) // not ambiguous, cost is O(N) here and lifetime of a is whatever.
: myA( a ) {}
~B3_v2() {} // CountedPtr takes care of delete.
...
CountedPtr<A> myA;
};
// Cloning on the heap with CowPtr mechanism is straightforward.
struct B3_v3 {
B3_v3( Clone<A> a ) // not ambiguous, cost is O(N) here and lifetime of a is whatever.
: myA( a ) {}
~B3_v3() {} // CountedPtr takes care of delete.
...
CowPtr<A> myA;
};
...
A a1;
B1 b( a1 ); // do not duplicate a1
B2 bb( a1 ); // duplicate a1
B2 bbb( &a1 ); // also duplicate a1 !
B3_v1 c1( a1 ); // duplicate a1 on the heap
B3_v2 c1( a1 ); // duplicate a1 on the heap
B3_v3 c1( a1 ); // duplicate a1 on the heap

A last question could be why are we not just passing the instance of A by value. This, for sure, would tell the developper that the instance is duplicated somehow. The problem is that it induces generally two duplications, and not only one ! It may be possible that the compiler optimizes things nicely but it is unclear if the compiler will always do it. Furthermore, sometimes, no duplication is needed (when duplicating a CowPtr for instance).

struct B4 {
B4( A a ) // not ambiguous, but cost is O(2N) here.
: myA( a ) {}
...
A myA;
};
A a1;
B4 b4( a1 ) // The object \a a1 is copied once on the heap as the parameter \a a, and once as the member \a b3.myA.
Note
The user should not used Clone<T> for data members, only as a type for parameters.

Definition at line 266 of file Clone.h.

Member Enumeration Documentation

template<typename T>
enum DGtal::Clone::Parameter
protected

Internal class that allows to distinguish the different types of parameters.

Enumerator
CONST_LEFT_VALUE_REF 
LEFT_VALUE_REF 
PTR 
CONST_PTR 
COW_PTR 
COUNTED_PTR 
RIGHT_VALUE_REF 
COUNTED_PTR_OR_PTR 
COUNTED_CONST_PTR_OR_CONST_PTR 

Definition at line 272 of file Clone.h.

Constructor & Destructor Documentation

template<typename T>
DGtal::Clone< T >::~Clone ( )
inline

Destructor. Does nothing.

Definition at line 297 of file Clone.h.

297 {}
template<typename T>
DGtal::Clone< T >::Clone ( const Clone< T > &  other)
inline

Copy constructor. The cloning is just forwarded.

Parameters
otherthe clone object to clone

Definition at line 303 of file Clone.h.

304  : myParam( other.myParam ), myPtr( other.myPtr ) {}
const Parameter myParam
Characterizes the type of the input parameter at clone instanciation.
Definition: Clone.h:443
const void *const myPtr
Stores the address of the input parameter for further use.
Definition: Clone.h:445
template<typename T>
DGtal::Clone< T >::Clone ( const T &  t)
inline

Constructor from an instance of T. The object is pointed in 'this'. It is duplicated (or not) when the user claims it.

Parameters
tany object of type T.

Definition at line 311 of file Clone.h.

312  : myParam( CONST_LEFT_VALUE_REF ), myPtr( static_cast<const void*>( &t ) ) {}
const Parameter myParam
Characterizes the type of the input parameter at clone instanciation.
Definition: Clone.h:443
const void *const myPtr
Stores the address of the input parameter for further use.
Definition: Clone.h:445
template<typename T>
DGtal::Clone< T >::Clone ( T *  ptrT)
inline

Constructor from a pointer to a valid instance of T. The object is pointed in 'this'. It is duplicated (or not) when the user claims it.

Parameters
ptrTany valid pointer to a object of type T.
Precondition
ptrT != 0

Definition at line 320 of file Clone.h.

321  : myParam( PTR ), myPtr( static_cast<const void*>( ptrT ) ) {}
const Parameter myParam
Characterizes the type of the input parameter at clone instanciation.
Definition: Clone.h:443
const void *const myPtr
Stores the address of the input parameter for further use.
Definition: Clone.h:445
template<typename T>
DGtal::Clone< T >::Clone ( const CowPtr< T > &  ptrT)
inline

Constructor from CowPtr<T>. The object is pointed in 'this'. It is duplicated (or not) when the user claims it.

Parameters
ptrTany copy-on-write pointer to a object of type T.

Definition at line 329 of file Clone.h.

330  : myParam( COW_PTR ), myPtr( static_cast<const void*>( &ptrT ) ) {}
const Parameter myParam
Characterizes the type of the input parameter at clone instanciation.
Definition: Clone.h:443
const void *const myPtr
Stores the address of the input parameter for further use.
Definition: Clone.h:445
template<typename T>
DGtal::Clone< T >::Clone ( const CountedPtr< T > &  ptrT)
inline

Constructor from CountedPtr<T>. The object is pointed in 'this'. It is duplicated (or not) when the user claims it.

Parameters
ptrTany shared pointer to a object of type T.

Definition at line 338 of file Clone.h.

339  : myParam( COUNTED_PTR ), myPtr( static_cast<const void*>( &ptrT ) ) {}
const Parameter myParam
Characterizes the type of the input parameter at clone instanciation.
Definition: Clone.h:443
const void *const myPtr
Stores the address of the input parameter for further use.
Definition: Clone.h:445
template<typename T>
DGtal::Clone< T >::Clone ( T &&  t)
inline

Constructor from right-reference value. The object is pointed in 'this'. It is duplicated (or not) when the user claims it.

Parameters
tany shared pointer to a object of type T.

Definition at line 347 of file Clone.h.

348  : myParam( RIGHT_VALUE_REF ), myPtr( static_cast<const void*>( &t ) ) {}
const Parameter myParam
Characterizes the type of the input parameter at clone instanciation.
Definition: Clone.h:443
const void *const myPtr
Stores the address of the input parameter for further use.
Definition: Clone.h:445
template<typename T>
DGtal::Clone< T >::Clone ( )
private

Constructor. Forbidden.

Member Function Documentation

template<typename T>
DGtal::Clone< T >::operator CowPtr< T > ( ) const
inline

Cast operator to a copy-on-write pointer on T instance. The object is duplicated or not depending on the type of input parameter.

  • const T & -> CowPtr<T> // immediate duplication (checked)
  • T* -> CowPtr<T> // acquired (checked)
  • CountedPtr<T> -> CowPtr<T> // lazy duplication (checked)
  • CowPtr<T> -> CowPtr<T> // lazy duplication (checked)
  • T&& -> CowPtr<T> // move into member (checked)

Definition at line 391 of file Clone.h.

References DGtal::Clone< T >::CONST_LEFT_VALUE_REF, DGtal::Clone< T >::COUNTED_PTR, DGtal::Clone< T >::COW_PTR, DGtal::Clone< T >::myParam, DGtal::Clone< T >::myPtr, DGtal::Clone< T >::PTR, and DGtal::Clone< T >::RIGHT_VALUE_REF.

392  {
393  switch( myParam ) {
395  return CowPtr<T>( new T( * static_cast< const T* >( myPtr ) ) );
396  case PTR:
397  return CowPtr<T>( const_cast<T*>( static_cast< const T* >( myPtr ) ) );
398  case COW_PTR:
399  return CowPtr<T>( * static_cast< const CowPtr<T>* >( myPtr ) );
400  case COUNTED_PTR:
401  return CowPtr<T>( * static_cast< const CountedPtr<T>* >( myPtr ) );
402  case RIGHT_VALUE_REF:
403  return CowPtr<T>( new T( std::move( * const_cast<T*>( static_cast< const T* >( myPtr ) ) ) ) );
404  default: ASSERT( false && "[Clone::operator CowPtr<T>() const] Invalid cast for given type. " );
405  return CowPtr<T>( 0 );
406  }
407  }
const Parameter myParam
Characterizes the type of the input parameter at clone instanciation.
Definition: Clone.h:443
const void *const myPtr
Stores the address of the input parameter for further use.
Definition: Clone.h:445
template<typename T>
DGtal::Clone< T >::operator T ( ) const
inline

Cast operator to a T instance. The object is duplicated or not depending on the type of input parameter.

  • const T & -> T // immediate duplication (checked)
  • T* -> T // immediate duplication, acquired and deleted. (checked)
  • CountedPtr<T> -> T // immediate duplication (checked)
  • CowPtr<T> -> T // immediate duplication (checked)
  • T&& -> T // move into member (checked)

Definition at line 361 of file Clone.h.

References DGtal::Clone< T >::CONST_LEFT_VALUE_REF, DGtal::Clone< T >::COUNTED_PTR, DGtal::Clone< T >::COW_PTR, DGtal::Clone< T >::myParam, DGtal::Clone< T >::myPtr, DGtal::Clone< T >::PTR, and DGtal::Clone< T >::RIGHT_VALUE_REF.

362  {
363  switch( myParam ) {
365  return T( * static_cast< const T* >( myPtr ) );
366  case PTR: {
367  TempPtr tmp( const_cast< T* >( static_cast< const T* >( myPtr ) ) );
368  return T( * static_cast< const T* >( myPtr ) );
369  } // destroy acquired pointer.
370  case COW_PTR:
371  return T( * static_cast< const CowPtr<T>* >( myPtr )->get() );
372  case COUNTED_PTR:
373  return T( * static_cast< const CountedPtr<T>* >( myPtr )->get() );
374  case RIGHT_VALUE_REF:
375  return T( std::move( * const_cast<T*>( static_cast< const T* >( myPtr ) ) ) );
376  default: ASSERT( false && "[Clone::operator T() const] Invalid cast for given type. " );
377  return T( * static_cast< const T* >( myPtr ) );
378  }
379  }
const Parameter myParam
Characterizes the type of the input parameter at clone instanciation.
Definition: Clone.h:443
const void *const myPtr
Stores the address of the input parameter for further use.
Definition: Clone.h:445
template<typename T>
T* DGtal::Clone< T >::operator& ( ) const
inline

Address operator that returns the address of the given T instance. The object is duplicated or not depending on the type of input parameter.

Returns
a pointer on an instance of T.
  • const T & -> T* // immediate duplication, should be deleted at the end. (checked)
  • CowPtr<T> -> T* // immediate duplication, should be deleted at the end. (checked)
  • CountedPtr<T> -> T* // immediate duplication, should be deleted at the end. (checked)
  • T* -> T* // acquired, should be deleted at the end. (checked)
  • T&& -> T* // move into member, should be deleted at the end. (checked)

Definition at line 422 of file Clone.h.

References DGtal::Clone< T >::CONST_LEFT_VALUE_REF, DGtal::Clone< T >::COUNTED_PTR, DGtal::Clone< T >::COW_PTR, DGtal::Clone< T >::myParam, DGtal::Clone< T >::myPtr, DGtal::Clone< T >::PTR, and DGtal::Clone< T >::RIGHT_VALUE_REF.

423  {
424  switch( myParam ) {
426  return new T( * static_cast< const T* >( myPtr ) );
427  case PTR:
428  return const_cast<T*>( static_cast< const T* >( myPtr ) );
429  case COW_PTR:
430  return new T( *( static_cast< const CowPtr<T>* >( myPtr )->get() ) );
431  case COUNTED_PTR:
432  return new T( *( static_cast< const CountedPtr<T>* >( myPtr )->get() ) );
433  case RIGHT_VALUE_REF:
434  return new T( std::move( * const_cast<T*>( static_cast< const T* >( myPtr ) ) ) );
435  default: ASSERT( false && "[T* Clone::operator&() const] Invalid address for given type. " );
436  return 0;
437  }
438  }
const Parameter myParam
Characterizes the type of the input parameter at clone instanciation.
Definition: Clone.h:443
const void *const myPtr
Stores the address of the input parameter for further use.
Definition: Clone.h:445
template<typename T>
Clone& DGtal::Clone< T >::operator= ( const Clone< T > &  other)
private

Assignment.

Parameters
otherthe object to copy.
Returns
a reference on 'this'. Forbidden (otherwise the user might be tempted to use it as a member).

Field Documentation

template<typename T>
const Parameter DGtal::Clone< T >::myParam
private

Characterizes the type of the input parameter at clone instanciation.

Definition at line 443 of file Clone.h.

Referenced by DGtal::Clone< T >::operator CowPtr< T >(), DGtal::Clone< T >::operator T(), and DGtal::Clone< T >::operator&().

template<typename T>
const void* const DGtal::Clone< T >::myPtr
private

Stores the address of the input parameter for further use.

Definition at line 445 of file Clone.h.

Referenced by DGtal::Clone< T >::operator CowPtr< T >(), DGtal::Clone< T >::operator T(), and DGtal::Clone< T >::operator&().


The documentation for this class was generated from the following file: