File failed to load: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/config/TeX-MML-AM_CHTML/MathJax.js
DGtal 2.0.0
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.
const void *const myPtr
 Stores the address of the input parameter for further use.

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:

  • Dupl. Object is duplicated.
  • Lazy. Object is lazily duplicated, meaning only when the user writes on it (which may be never).
  • Acq. Dynamically allocated pointer is acquired. User should take care himself of deletion only if storing the parameter with a pointer.
  • Move. The object is moved into the new object. This is generally much faster than copy. This is true for instance for all classical STL containers. You can also write a specific move constructor for your class.

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 passing by value or by const ref 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 Clone
2xint i7 2.4GHz 48ms 48ms 59ms
2xdouble i7 2.4GHz 48ms 48ms 49ms
2xint Xeon 2.67GHz 54ms 54ms 54ms
2xdouble Xeon 2.67GHz 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 265 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 271 of file Clone.h.

Constructor & Destructor Documentation

◆ ~Clone()

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

Destructor. Does nothing.

Definition at line 319 of file Clone.h.

319{}

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

Aim: This class encapsulates its parameter class to indicate that the given parameter is required to ...
Definition Clone.h:266
const Parameter myParam
Characterizes the type of the input parameter at clone instanciation.
Definition Clone.h:497
const void *const myPtr
Stores the address of the input parameter for further use.
Definition Clone.h:499

References Clone(), myParam, and myPtr.

Referenced by Clone(), and operator=().

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

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

References CONST_LEFT_VALUE_REF, myParam, and myPtr.

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

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

References myParam, myPtr, and PTR.

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

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

References COW_PTR, myParam, and myPtr.

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

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

References COUNTED_PTR, myParam, and myPtr.

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

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

References myParam, myPtr, and RIGHT_VALUE_REF.

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

280 {
282 switch (p) {
283 case CONST_LEFT_VALUE_REF: sp = "CONST_LEFT_VALUE_REF"; break;
284 case LEFT_VALUE_REF: sp = "LEFT_VALUE_REF"; break;
285 case PTR: sp = "PTR"; break;
286 case CONST_PTR: sp = "CONST_PTR"; break;
287 case COW_PTR: sp = "COW_PTR"; break;
288 case COUNTED_PTR: sp = "COUNTED_PTR"; break;
289 case RIGHT_VALUE_REF: sp = "RIGHT_VALUE_REF"; break;
290 case COUNTED_PTR_OR_PTR: sp = "COUNTED_PTR_OR_PTR"; break;
291 case COUNTED_CONST_PTR_OR_CONST_PTR: sp = "COUNTED_CONST_PTR_OR_CONST_PTR"; break;
292 default: sp = "UNKNOWN"; break;
293 }
294 trace.info() << "[Clone<T>::" << method << " param="
295 << sp << "]" << std::endl;
296
297 }

References CONST_LEFT_VALUE_REF, CONST_PTR, COUNTED_CONST_PTR_OR_CONST_PTR, COUNTED_PTR, COUNTED_PTR_OR_PTR, COW_PTR, LEFT_VALUE_REF, PTR, 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.

Definition at line 443 of file Clone.h.

444 {
445 // display( "operator CountedPtr<T>() const", myParam );
446 switch( myParam ) {
448 return CountedPtr<T>( new T( * static_cast< const T* >( myPtr ) ) );
449 case PTR:
450 return CountedPtr<T>( const_cast<T*>( static_cast< const T* >( myPtr ) ) );
451 case COW_PTR:
452 return CountedPtr<T>( new T( * static_cast< const CowPtr<T>* >( myPtr )->get() ) );
453 case COUNTED_PTR:
454 return CountedPtr<T>( * static_cast< const CountedPtr<T>* >( myPtr ) );
455 case RIGHT_VALUE_REF:
456 return CountedPtr<T>( new T( std::move( * const_cast<T*>( static_cast< const T* >( myPtr ) ) ) ) );
457 default: ASSERT( false && "[Clone::operator CountedPtr<T>() const] Invalid cast for given type. " );
458 return CountedPtr<T>( 0 );
459 }
460 }

References CONST_LEFT_VALUE_REF, COUNTED_PTR, COW_PTR, myParam, myPtr, PTR, and 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.

Definition at line 414 of file Clone.h.

415 {
416 // display( "operator CowPtr<T>() const", myParam );
417 switch( myParam ) {
419 return CowPtr<T>( new T( * static_cast< const T* >( myPtr ) ) );
420 case PTR:
421 return CowPtr<T>( const_cast<T*>( static_cast< const T* >( myPtr ) ) );
422 case COW_PTR:
423 return CowPtr<T>( * static_cast< const CowPtr<T>* >( myPtr ) );
424 case COUNTED_PTR:
425 return CowPtr<T>( * static_cast< const CountedPtr<T>* >( myPtr ), true );
426 case RIGHT_VALUE_REF:
427 return CowPtr<T>( new T( std::move( * const_cast<T*>( static_cast< const T* >( myPtr ) ) ) ) );
428 default: ASSERT( false && "[Clone::operator CowPtr<T>() const] Invalid cast for given type. " );
429 return CowPtr<T>( 0 );
430 }
431 }

References CONST_LEFT_VALUE_REF, COUNTED_PTR, COW_PTR, myParam, myPtr, PTR, and 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 383 of file Clone.h.

384 {
385 // display( "operator T() const", myParam );
386 switch( myParam ) {
388 return T( * static_cast< const T* >( myPtr ) );
389 case PTR: {
390 TempPtr tmp( const_cast< T* >( static_cast< const T* >( myPtr ) ) );
391 return T( * static_cast< const T* >( myPtr ) );
392 } // destroy acquired pointer.
393 case COW_PTR:
394 return T( * static_cast< const CowPtr<T>* >( myPtr )->get() );
395 case COUNTED_PTR:
396 return T( * static_cast< const CountedPtr<T>* >( myPtr )->get() );
397 case RIGHT_VALUE_REF:
398 return T( std::move( * const_cast<T*>( static_cast< const T* >( myPtr ) ) ) );
399 default: ASSERT( false && "[Clone::operator T() const] Invalid cast for given type. " );
400 return T( * static_cast< const T* >( myPtr ) );
401 }
402 }
Internal class that is used for a late deletion of an acquired pointer.
Definition Clone.h:299

References CONST_LEFT_VALUE_REF, COUNTED_PTR, COW_PTR, myParam, myPtr, PTR, and 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 475 of file Clone.h.

476 {
477 // display( "T* operator &() const", myParam );
478 switch( myParam ) {
480 return new T( * static_cast< const T* >( myPtr ) );
481 case PTR:
482 return const_cast<T*>( static_cast< const T* >( myPtr ) );
483 case COW_PTR:
484 return new T( *( static_cast< const CowPtr<T>* >( myPtr )->get() ) );
485 case COUNTED_PTR:
486 return new T( *( static_cast< const CountedPtr<T>* >( myPtr )->get() ) );
487 case RIGHT_VALUE_REF:
488 return new T( std::move( * const_cast<T*>( static_cast< const T* >( myPtr ) ) ) );
489 default: ASSERT( false && "[T* Clone::operator&() const] Invalid address for given type. " );
490 return 0;
491 }
492 }

References CONST_LEFT_VALUE_REF, COUNTED_PTR, COW_PTR, myParam, myPtr, PTR, and 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).

References Clone().

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

Referenced by Clone(), Clone(), Clone(), Clone(), Clone(), Clone(), operator CountedPtr< T >(), operator CowPtr< T >(), operator T(), and 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 499 of file Clone.h.

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


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