DGtal 1.3.0
Loading...
Searching...
No Matches
Data Structures | Public Member Functions | Protected Types | Protected Member Functions | Private Member Functions | Private Attributes
DGtal::Clone< T > Class Template Reference

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. More...

#include <DGtal/base/Clone.h>

Data Structures

struct  TempPtr
 Internal class that is used for a late deletion of an acquired pointer. More...
 

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
 
 operator CountedPtr< 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
}
 Internal class that allows to distinguish the different types of parameters. More...
 

Protected Member Functions

void display (const std::string &method, Parameter p) const
 

Private Member Functions

 Clone ()
 
Cloneoperator= (const Clone &other)
 

Private Attributes

const Parameter myParam
 Characterizes the type of the input parameter at clone instanciation. More...
 
const void *const myPtr
 Stores the address of the input parameter for further use. More...
 

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*
parameter T 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
2xdouble i7 2.4GHz 48ms 48ms 48ms 49ms
2xint Xeon 2.67GHz 54ms 54ms 54ms 54ms
2xdouble Xeon 2.67GHz 54ms 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
Aim: This class encapsulates its parameter class so that to indicate to the user that the object/poin...
Definition: ConstAlias.h:187

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

◆ Parameter

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

◆ ~Clone()

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

Destructor. Does nothing.

Definition at line 320 of file Clone.h.

320{}

◆ Clone() [1/7]

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 326 of file Clone.h.

327 : myParam( other.myParam ), myPtr( other.myPtr ) {}
const Parameter myParam
Characterizes the type of the input parameter at clone instanciation.
Definition: Clone.h:498
const void *const myPtr
Stores the address of the input parameter for further use.
Definition: Clone.h:500

◆ Clone() [2/7]

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 334 of file Clone.h.

335 : myParam( CONST_LEFT_VALUE_REF ), myPtr( static_cast<const void*>( &t ) ) {}

◆ Clone() [3/7]

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 343 of file Clone.h.

344 : myParam( PTR ), myPtr( static_cast<const void*>( ptrT ) ) {}

◆ Clone() [4/7]

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 352 of file Clone.h.

353 : myParam( COW_PTR ), myPtr( static_cast<const void*>( &ptrT ) ) {}

◆ Clone() [5/7]

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 361 of file Clone.h.

362 : myParam( COUNTED_PTR ), myPtr( static_cast<const void*>( &ptrT ) ) {}

◆ Clone() [6/7]

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 370 of file Clone.h.

371 : myParam( RIGHT_VALUE_REF ), myPtr( static_cast<const void*>( &t ) ) {}

◆ Clone() [7/7]

template<typename T >
DGtal::Clone< T >::Clone ( )
private

Constructor. Forbidden.

Member Function Documentation

◆ display()

template<typename T >
void DGtal::Clone< T >::display ( const std::string &  method,
Parameter  p 
) const
inlineprotected

Debug method for displaying what's happening when using Clone mechanism

Parameters
methodthe name of the conversion method
pthe type of parameter

Definition at line 280 of file Clone.h.

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 }
std::ostream & info()
Trace trace
Definition: Common.h:154

References DGtal::Clone< T >::CONST_LEFT_VALUE_REF, DGtal::Clone< T >::CONST_PTR, DGtal::Clone< T >::COUNTED_CONST_PTR_OR_CONST_PTR, DGtal::Clone< T >::COUNTED_PTR, DGtal::Clone< T >::COUNTED_PTR_OR_PTR, DGtal::Clone< T >::COW_PTR, DGtal::Trace::info(), DGtal::Clone< T >::LEFT_VALUE_REF, DGtal::Clone< T >::PTR, DGtal::Clone< T >::RIGHT_VALUE_REF, and DGtal::trace.

◆ operator CountedPtr< T >()

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

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

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

Definition at line 444 of file Clone.h.

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 }

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.

◆ operator CowPtr< T >()

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 415 of file Clone.h.

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 }

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.

◆ operator T()

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 384 of file Clone.h.

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 }

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.

◆ operator&()

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 476 of file Clone.h.

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 }

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.

◆ operator=()

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

◆ myParam

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

Characterizes the type of the input parameter at clone instanciation.

Definition at line 498 of file Clone.h.

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

◆ myPtr

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

Stores the address of the input parameter for further use.

Definition at line 500 of file Clone.h.

Referenced by DGtal::Clone< T >::operator CountedPtr< T >(), 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: