DGtal  1.5.beta
testClone2.cpp
Go to the documentation of this file.
1 
29 //#define TRACE_BITS
30 
31 #include <cstdio>
32 #include <cmath>
33 #include <iostream>
34 #include "DGtal/base/Common.h"
35 #include "DGtal/base/CountedPtr.h"
36 #include "DGtal/base/CountedPtrOrPtr.h"
37 #include "DGtal/base/CountedConstPtrOrConstPtr.h"
38 #include "DGtal/base/CowPtr.h"
39 #include "DGtal/base/Clone.h"
40 #include "DGtal/base/Alias.h"
41 #include "DGtal/base/ConstAlias.h"
42 #include "DGtal/helpers/StdDefs.h"
43 
44 using namespace DGtal;
45 using namespace std;
46 
47 
48 namespace DGtal {
49 
50 
61  template <typename T>
62  class NClone
63  {
64  // ----------------------- Standard services ------------------------------
65  public:
66 
70  inline ~NClone() {}
71 
75  inline NClone ( const NClone & ) { ASSERT( false ); }
76 
83  inline NClone( const T & t ) : myCowPtr( const_cast<T*>( &t ) ) {}
84 
92  // NClone( const T* ptrT );
93 
94  inline NClone( CountedPtr<T> ptr ) : myCowPtr( ptr ) {}
95  inline NClone( CowPtr<T> ptr ) : myCowPtr( ptr ) {}
96 
102  inline operator T() const
103  { return myCowPtr.unique()
104  ? T( *( const_cast< CowPtr<T>& >( myCowPtr ).drop() ) )
105  : T( *( myCowPtr.get() ) );
106  }
107  // { return T( *( const_cast< CowPtr<T>& >( myCowPtr ).drop() ) ); }
108 
114  inline operator CowPtr<T>() const
115  { return myCowPtr.unique()
116  ? CowPtr<T>( new T( *( const_cast< CowPtr<T>& >( myCowPtr ).drop() ) ) )
117  : myCowPtr;
118  }
119  //{ return myCowPtr; }
120 
121  //inline operator CountedPtr<T>() { return CountedPtr<T>( myCowPtr.get() ); }
122 
123  // ------------------------- Protected Datas ------------------------------
124  private:
125  // ------------------------- Private Datas --------------------------------
126  private:
128  CowPtr<T> myCowPtr;
129 
130 
131  // ------------------------- Hidden services ------------------------------
132  private:
133 
138  NClone();
139 
140 
147  NClone & operator= ( const NClone & other );
148 
149  // ------------------------- Internals ------------------------------------
150  private:
151 
152  }; // end of class NClone
153 
154 } // namespace DGtal
155 
156 
157 // Dummy class to test clones and aliases.
158 struct DummyTbl
159 {
160 public:
161  typedef int Element;
162 private:
163  DummyTbl();
164 public:
165  ~DummyTbl()
166  {
167  std::cout << " ~DummyTbl() this=" << this << " data=" << data << std::endl;
168  if ( data != 0 ) {
169  std::cout << " - freed =" << allocated << std::endl;
170  delete[] data;
171  }
172  else
173  std::cout << " - nothing to do (already moved)" << std::endl;
174  ++nbDeleted;
175  }
176  DummyTbl( int i, int val )
177  : size( 0 ), allocated( i )
178  {
179  std::cout << " DummyTbl( " << i << " ) this=" << this << std::endl;
180  data = new Element[ allocated ];
181  data[ size++ ] = val;
182  std::cout << " - allocated=" << allocated << std::endl;
183  std::cout << " - copied =" << size << std::endl;
184  ++nbCreated;
185  }
186  DummyTbl( const DummyTbl & a ) : size( a.size ), allocated( a.allocated )
187  {
188  std::cout << " DummyTbl( const DummyTbl & a ) this=" << this << " a=" << &a << std::endl;
189  data = new Element[ allocated ];
190  for ( int i = 0; i < size; ++i ) data[ i ] = a.data[ i ];
191  std::cout << " - allocated=" << allocated << std::endl;
192  std::cout << " - copied =" << size << std::endl;
193  ++nbCreated;
194  }
195 
196  DummyTbl( DummyTbl && a ) noexcept
197  : size( std::move( a.size ) ), allocated( std::move( a.allocated ) )
198  {
199  data = a.data; a.data = 0;
200  std::cout << " DummyTbl( DummyTbl && a ) this=" << this << " a=" << &a << std::endl;
201  std::cout << " - check data: a=" << allocated << " s=" << size << std::endl;
202  ++nbCreated;
203  ++nbMoved;
204  }
205 
206  int value() const { return data[ 0 ]; }
207  void setValue( int v ) const { data[ 0 ] = v; }
208 
209 private:
210  DummyTbl& operator=( const DummyTbl & a )
211  {
212  data = a.data;
213  std::cout << " DummyTbl::operator=( const DummyTbl & a ) " << std::endl;
214  return *this;
215  }
216 public:
217  static void reset() {
218  nbCreated = 0;
219  nbDeleted = 0;
220  }
221 
222  Element* data;
223  int size;
224  int allocated;
225 
226  static int nbCreated;
227  static int nbDeleted;
228  static int nbMoved;
229 };
230 
231 int DummyTbl::nbCreated = 0;
232 int DummyTbl::nbDeleted = 0;
233 int DummyTbl::nbMoved = 0;
234 
235 
236 struct CloneToValueMember {
237  inline CloneToValueMember( Clone<DummyTbl> a1 ) : myDummyTbl( a1 ) {}
238  inline int value() const { return myDummyTbl.value(); }
239  DummyTbl myDummyTbl;
240 };
241 
242 struct CloneToCountedMember { // requires explicit duplication
243  inline CloneToCountedMember( Clone<DummyTbl> a1 ) // : myDummyTbl( a1 ) {} does not compile
244  : myDummyTbl( a1 ) {}
245  inline int value() const { return myDummyTbl->value(); }
246  CountedPtr<DummyTbl> myDummyTbl;
247 };
248 
249 struct CloneToCowMember {
250  inline CloneToCowMember( Clone<DummyTbl> a1 ) : myDummyTbl( a1 ) {}
251  inline int value() const { return myDummyTbl->value(); }
252  inline void setValue( int v ) { myDummyTbl->setValue( v ); }
253  CowPtr<DummyTbl> myDummyTbl;
254 };
255 
256 struct CloneToPtrMember {
257  inline CloneToPtrMember() : myDummyTbl( 0 ) {}
258  inline CloneToPtrMember( Clone<DummyTbl> a1 ) : myDummyTbl( &a1 ) {}
259  inline ~CloneToPtrMember() { if ( myDummyTbl != 0 ) delete myDummyTbl; else std::cerr << "[~CloneToPtrMember] error." << std::endl; }
260  inline int value() const { return myDummyTbl->value(); }
261  inline void setValue( int v ) { myDummyTbl->setValue( v ); }
262  DummyTbl* myDummyTbl;
263 };
264 
265 struct AliasToRefMember {
266  inline AliasToRefMember( Alias<DummyTbl> a1 ) : myDummyTbl( a1 ) {}
267  inline int value() const { return myDummyTbl.value(); }
268  DummyTbl& myDummyTbl;
269 };
270 
271 struct AliasToPtrMember {
272  inline AliasToPtrMember( Alias<DummyTbl> a1 ) : myDummyTbl( &a1 ) {}
273  inline int value() const { return myDummyTbl->value(); }
274  DummyTbl* myDummyTbl;
275 };
276 
277 
278 struct AliasToCountedPtrOrPtrMember {
279  inline AliasToCountedPtrOrPtrMember( Alias<DummyTbl> a1 ) : myDummyTbl( a1 ) {}
280  inline int value() const { return myDummyTbl->value(); }
281  CountedPtrOrPtr<DummyTbl> myDummyTbl;
282 };
283 
284 struct AliasToConstRefMember { // restricted but valid.
285  inline AliasToConstRefMember( Alias<DummyTbl> a1 ) : myDummyTbl( a1 ) {}
286  inline int value() const { return myDummyTbl.value(); }
287  const DummyTbl& myDummyTbl;
288 };
289 
290 struct ConstAliasToConstRefMember {
291  inline ConstAliasToConstRefMember( ConstAlias<DummyTbl> a1 ) : myDummyTbl( a1 ) {}
292  inline int value() const { return myDummyTbl.value(); }
293  const DummyTbl& myDummyTbl;
294 };
295 
296 struct ConstAliasToConstPtrMember {
297  inline ConstAliasToConstPtrMember( ConstAlias<DummyTbl> a1 ) : myDummyTbl( &a1 ) {}
298  inline int value() const { return myDummyTbl->value(); }
299  const DummyTbl* myDummyTbl;
300 };
301 
302 struct ConstAliasToCountedConstPtrOrConstPtrMember {
303  inline ConstAliasToCountedConstPtrOrConstPtrMember( ConstAlias<DummyTbl> a1 ) : myDummyTbl( a1 ) {}
304  inline int value() const { return myDummyTbl->value(); }
306 };
307 
308 // struct ConstAliasToRefMember { // invalid
309 // inline ConstAliasToRefMember( ConstAlias<DummyTbl> a1 ) : myDummyTbl( a1 ) {}
310 // inline int value() const { return myDummyTbl.value(); }
311 // DummyTbl& myDummyTbl;
312 // };
313 
314 
315 
316 class MyPoint {
317 public:
318  ~MyPoint()
319  { nbDeleted++; }
320  MyPoint( const MyPoint & other )
321  : _x( other._x ), _y( other._y )
322  { nbCreated++; }
323  MyPoint( int x, int y ) : _x( x ), _y( y )
324  { nbCreated++; }
325  MyPoint operator-( const MyPoint & other ) const
326  {
327  return MyPoint( _x - other._x, _y - other._y );
328  }
329  double norm() const
330  {
331  double dx = (double) _x;
332  double dy = (double) _y;
333  return sqrt( dx * dx + dy * dy );
334  }
335  static void reset()
336  {
337  nbCreated = nbDeleted = 0;
338  }
339  int _x, _y;
340 
341  static int nbCreated;
342  static int nbDeleted;
343 };
344 
345 int MyPoint::nbCreated = 0;
346 int MyPoint::nbDeleted = 0;
347 
348 class MyPointD {
349 public:
350  ~MyPointD()
351  { nbDeleted++; }
352  MyPointD( const MyPointD & other )
353  : _x( other._x ), _y( other._y )
354  { nbCreated++; }
355  MyPointD( int x, int y ) : _x( x ), _y( y )
356  { nbCreated++; }
357  MyPointD( double x, double y ) : _x( x ), _y( y )
358  { nbCreated++; }
359  MyPointD operator-( const MyPointD & other ) const
360  {
361  return MyPointD( _x - other._x, _y - other._y );
362  }
363  double norm() const
364  {
365  double dx = (double) _x;
366  double dy = (double) _y;
367  return sqrt( dx * dx + dy * dy );
368  }
369  static void reset()
370  {
371  nbCreated = nbDeleted = 0;
372  }
373  double _x, _y;
374 
375  static int nbCreated;
376  static int nbDeleted;
377 };
378 
379 int MyPointD::nbCreated = 0;
380 int MyPointD::nbDeleted = 0;
381 
382 //typedef Z2i::Point Point;
383 typedef MyPointD Point;
384 
385 
386 struct TriangleByConstReference {
387  TriangleByConstReference( const Point & a, const Point & b, const Point & c )
388  : _a( a ), _b( b ), _c( c ) {}
389  double perimeter() const
390  {
391  return (_a - _b).norm() + (_b - _c).norm() + (_c - _a).norm();
392  }
393  Point _a, _b, _c;
394 };
395 
396 struct TriangleByValue {
397  TriangleByValue( Point a, Point b, Point c )
398  : _a( a ), _b( b ), _c( c ) {}
399  double perimeter() const
400  {
401  return (_a - _b).norm() + (_b - _c).norm() + (_c - _a).norm();
402  }
403  Point _a, _b, _c;
404 };
405 
406 struct TriangleByClone {
407  TriangleByClone( Clone<Point> a, Clone<Point> b, Clone<Point> c )
408  : _a( a ), _b( b ), _c( c ) {}
409  double perimeter() const
410  {
411  return (_a - _b).norm() + (_b - _c).norm() + (_c - _a).norm();
412  }
413  Point _a, _b, _c;
414 };
415 
416 struct TriangleByCloneAndCow {
417  TriangleByCloneAndCow( Clone<Point> a, Clone<Point> b, Clone<Point> c )
418  : _a( a ), _b( b ), _c( c ) {}
419  double perimeter() const
420  {
421  return (*_a - *_b).norm() + (*_b - *_c).norm() + (*_c - *_a).norm();
422  }
423  CowPtr<Point> _a, _b, _c;
424 };
425 
426 template <typename Triangle>
427 double
428 computeTriangles( int size )
429 {
430  double total = 0.0;
431  Point A( 0, 0 );
432  for ( int yb = 0; yb < size; ++yb )
433  for ( int xb = 0; xb < size; ++xb )
434  {
435  Point B( xb, yb );
436  for ( int yc = 0; yc < size; ++yc )
437  for ( int xc = 0; xc < size; ++xc )
438  {
439  Point C( xc, yc );
440  Triangle T( A, B, C );
441  total += T.perimeter();
442  }
443  }
444  return total;
445 }
446 
447 template <typename Triangle>
448 double
450 {
451  double total = 0.0;
452  CowPtr<Point> A( new Point( 0, 0 ) );
453  for ( int yb = 0; yb < size; ++yb )
454  for ( int xb = 0; xb < size; ++xb )
455  {
456  CowPtr<Point> B( new Point( xb, yb ) );
457  for ( int yc = 0; yc < size; ++yc )
458  for ( int xc = 0; xc < size; ++xc )
459  {
460  CowPtr<Point> C( new Point( xc, yc ) );
461  Triangle T( A, B, C );
462  total += T.perimeter();
463  }
464  }
465  return total;
466 }
467 
478 {
479  unsigned int nb = 0;
480  unsigned int nbok = 0;
481  DummyTbl a1( 100, 10 ); // +1/0
482  DummyTbl* ptr_a2 = new DummyTbl( 100, 18 ); // +1/0
483  CountedPtr<DummyTbl> counted_a1( new DummyTbl( 100, 12 ) ); // +1/0
484  DummyTbl::reset();
485  trace.beginBlock ( "Testing class Alias." );
486 
487  /*
488  - A& -> A& // no duplication
489  - A* -> A& // no duplication, exception if null
490  - A& -> A* // no duplication
491  - A* -> A* // no duplication
492  - CountedPtr<A> -> CountedPtr<A> // shared
493  */
494  trace.beginBlock ( "Alias: #DummyTbl with DummyTbl& to DummyTbl& member. no duplication (0/0)" );
495  AliasToRefMember c00( a1 ); // 0/0
496  trace.info() << "D: d1.value() = " << c00.value() << std::endl;
497  ++nb; nbok += DummyTbl::nbCreated==0 ? 1 : 0;
498  ++nb; nbok += DummyTbl::nbDeleted==0 ? 1 : 0;
499  trace.info() << "(" << nbok << "/" << nb << ")"
500  << " nbCreated=" << DummyTbl::nbCreated
501  << " nbDeleted=" << DummyTbl::nbDeleted << std::endl;
502  trace.endBlock();
503 
504  trace.beginBlock ( "Alias: #DummyTbl with DummyTbl* to DummyTbl& member. no duplication (0/0)" );
505  AliasToRefMember c10( ptr_a2 ); // 0/0
506  trace.info() << "D: d1.value() = " << c10.value() << std::endl;
507  ++nb; nbok += DummyTbl::nbCreated==0 ? 1 : 0;
508  ++nb; nbok += DummyTbl::nbDeleted==0 ? 1 : 0;
509  trace.info() << "(" << nbok << "/" << nb << ")"
510  << " nbCreated=" << DummyTbl::nbCreated
511  << " nbDeleted=" << DummyTbl::nbDeleted << std::endl;
512  trace.endBlock();
513 
514  trace.beginBlock ( "Alias: #DummyTbl with DummyTbl& to DummyTbl* member. no duplication (0/0)" );
515  AliasToPtrMember c01( a1 ); // 0/0
516  trace.info() << "D: d1.value() = " << c01.value() << std::endl;
517  ++nb; nbok += DummyTbl::nbCreated==0 ? 1 : 0;
518  ++nb; nbok += DummyTbl::nbDeleted==0 ? 1 : 0;
519  trace.info() << "(" << nbok << "/" << nb << ")"
520  << " nbCreated=" << DummyTbl::nbCreated
521  << " nbDeleted=" << DummyTbl::nbDeleted << std::endl;
522  trace.endBlock();
523 
524  trace.beginBlock ( "Alias: #DummyTbl with DummyTbl* to DummyTbl* member. no duplication (0/0)" );
525  AliasToPtrMember c11( ptr_a2 ); // 0/0
526  trace.info() << "D: d1.value() = " << c11.value() << std::endl;
527  ++nb; nbok += DummyTbl::nbCreated==0 ? 1 : 0;
528  ++nb; nbok += DummyTbl::nbDeleted==0 ? 1 : 0;
529  trace.info() << "(" << nbok << "/" << nb << ")"
530  << " nbCreated=" << DummyTbl::nbCreated
531  << " nbDeleted=" << DummyTbl::nbDeleted << std::endl;
532  trace.endBlock();
533 
534  trace.beginBlock ( "Alias: #DummyTbl with DummyTbl& to CountedPtrOrPtr<DummyTbl> member. no duplication (0/0)" );
535  AliasToCountedPtrOrPtrMember c06( a1 ); // 0/0
536  trace.info() << "D: d1.value() = " << c06.value() << std::endl;
537  trace.info() << c06.myDummyTbl << std::endl;
538  ++nb; nbok += DummyTbl::nbCreated==0 ? 1 : 0;
539  ++nb; nbok += DummyTbl::nbDeleted==0 ? 1 : 0;
540  trace.info() << "(" << nbok << "/" << nb << ")"
541  << " nbCreated=" << DummyTbl::nbCreated
542  << " nbDeleted=" << DummyTbl::nbDeleted << std::endl;
543  trace.endBlock();
544 
545  trace.beginBlock ( "Alias: #DummyTbl with DummyTbl* to CountedPtrOrPtr<DummyTbl> member. no duplication (0/0)" );
546  AliasToCountedPtrOrPtrMember c16( a1 ); // 0/0
547  trace.info() << "D: d1.value() = " << c16.value() << std::endl;
548  trace.info() << c16.myDummyTbl << std::endl;
549  ++nb; nbok += DummyTbl::nbCreated==0 ? 1 : 0;
550  ++nb; nbok += DummyTbl::nbDeleted==0 ? 1 : 0;
551  trace.info() << "(" << nbok << "/" << nb << ")"
552  << " nbCreated=" << DummyTbl::nbCreated
553  << " nbDeleted=" << DummyTbl::nbDeleted << std::endl;
554  trace.endBlock();
555 
556  // const DummyTbl& const_a1 = a1;
557  // AliasToRefMember c02( const_a1 ); // does not execute.
558  // const DummyTbl* const_ptr_a1 = &a1;
559  // AliasToRefMember c05( const_ptr_a1 ); // does not execute.
560 
561  trace.endBlock();
562 
563  delete ptr_a2;
564  return nbok == nb;
565 }
566 
577 {
578  unsigned int nb = 0;
579  unsigned int nbok = 0;
580  DummyTbl a1( 100, 10 ); // +1/0
581  DummyTbl* ptr_a2 = new DummyTbl( 100, 18 ); // +1/0
582  CountedPtr<DummyTbl> counted_a1( new DummyTbl( 100, 12 ) ); // +1/0
583  CowPtr<DummyTbl> cow_a1( new DummyTbl( 100, 16 ) ); // +1/0
584  DummyTbl::reset();
585  trace.beginBlock ( "Testing class ConstAlias." );
586 
587  /*
588  - const A & -> const A & // no duplication
589  - const A* -> const A & // no duplication, exception if null
590  - const A & -> const A* // no duplication
591  - const A* -> const A* // no duplication
592  - CountedPtr<A> -> CowPtr<A> // potential lazy duplication
593  - CowPtr<A> -> CowPtr<A> // potential lazy duplication
594  */
595  trace.beginBlock ( "ConstAlias: #DummyTbl with const DummyTbl& to const DummyTbl& member. no duplication (0/0)" );
596  ConstAliasToConstRefMember c00( a1 ); // 0/0
597  trace.info() << "D: d1.value() = " << c00.value() << std::endl;
598  ++nb; nbok += DummyTbl::nbCreated==0 ? 1 : 0;
599  ++nb; nbok += DummyTbl::nbDeleted==0 ? 1 : 0;
600  trace.info() << "(" << nbok << "/" << nb << ")"
601  << " nbCreated=" << DummyTbl::nbCreated
602  << " nbDeleted=" << DummyTbl::nbDeleted << std::endl;
603  trace.endBlock();
604 
605  trace.beginBlock ( "ConstAlias: #DummyTbl with const DummyTbl* to const DummyTbl& member. no duplication (0/0)" );
606  ConstAliasToConstRefMember c10( ptr_a2 ); // 0/0
607  trace.info() << "D: d1.value() = " << c10.value() << std::endl;
608  ++nb; nbok += DummyTbl::nbCreated==0 ? 1 : 0;
609  ++nb; nbok += DummyTbl::nbDeleted==0 ? 1 : 0;
610  trace.info() << "(" << nbok << "/" << nb << ")"
611  << " nbCreated=" << DummyTbl::nbCreated
612  << " nbDeleted=" << DummyTbl::nbDeleted << std::endl;
613  trace.endBlock();
614 
615  trace.beginBlock ( "ConstAlias: #DummyTbl with const DummyTbl& to const DummyTbl* member. no duplication (0/0)" );
616  ConstAliasToConstPtrMember c01( a1 ); // 0/0
617  trace.info() << "D: d1.value() = " << c01.value() << std::endl;
618  ++nb; nbok += DummyTbl::nbCreated==0 ? 1 : 0;
619  ++nb; nbok += DummyTbl::nbDeleted==0 ? 1 : 0;
620  trace.info() << "(" << nbok << "/" << nb << ")"
621  << " nbCreated=" << DummyTbl::nbCreated
622  << " nbDeleted=" << DummyTbl::nbDeleted << std::endl;
623  trace.endBlock();
624 
625  trace.beginBlock ( "ConstAlias: #DummyTbl with const DummyTbl* to const DummyTbl* member. no duplication (0/0)" );
626  ConstAliasToConstPtrMember c11( ptr_a2 ); // 0/0
627  trace.info() << "D: d1.value() = " << c11.value() << std::endl;
628  ++nb; nbok += DummyTbl::nbCreated==0 ? 1 : 0;
629  ++nb; nbok += DummyTbl::nbDeleted==0 ? 1 : 0;
630  trace.info() << "(" << nbok << "/" << nb << ")"
631  << " nbCreated=" << DummyTbl::nbCreated
632  << " nbDeleted=" << DummyTbl::nbDeleted << std::endl;
633  trace.endBlock();
634 
635  trace.beginBlock ( "ConstAlias: #DummyTbl with const DummyTbl* to CountedConstPtrOrConstPtr<DummyTbl> member. No duplication (0/0)" );
636  ConstAliasToCountedConstPtrOrConstPtrMember c17( ptr_a2 ); // 0/0
637  trace.info() << "D: d1.value() = " << c17.value() << std::endl;
638  ++nb; nbok += DummyTbl::nbCreated==0 ? 1 : 0;
639  ++nb; nbok += DummyTbl::nbDeleted==0 ? 1 : 0;
640  trace.info() << "(" << nbok << "/" << nb << ")"
641  << " nbCreated=" << DummyTbl::nbCreated
642  << " nbDeleted=" << DummyTbl::nbDeleted << std::endl;
643  trace.endBlock();
644 
645  trace.beginBlock ( "ConstAlias: #DummyTbl with const DummyTbl& to CountedConstPtrOrConstPtr<DummyTbl> member. No duplication (0/0)" );
646  ConstAliasToCountedConstPtrOrConstPtrMember c07( a1 ); // 0/0
647  trace.info() << "D: d1.value() = " << c07.value() << std::endl;
648  ++nb; nbok += DummyTbl::nbCreated==0 ? 1 : 0;
649  ++nb; nbok += DummyTbl::nbDeleted==0 ? 1 : 0;
650  trace.info() << "(" << nbok << "/" << nb << ")"
651  << " nbCreated=" << DummyTbl::nbCreated
652  << " nbDeleted=" << DummyTbl::nbDeleted << std::endl;
653  trace.endBlock();
654 
655  trace.beginBlock ( "ConstAlias: #DummyTbl with CountedPtr<DummyTbl> to CountedConstPtrOrConstPtr<DummyTbl> member. No duplication (0/0)" );
656  ConstAliasToCountedConstPtrOrConstPtrMember c37( counted_a1 ); // 0/0
657  trace.info() << "D: d1.value() = " << c37.value() << std::endl;
658  ++nb; nbok += DummyTbl::nbCreated==0 ? 1 : 0;
659  ++nb; nbok += DummyTbl::nbDeleted==0 ? 1 : 0;
660  trace.info() << "(" << nbok << "/" << nb << ")"
661  << " nbCreated=" << DummyTbl::nbCreated
662  << " nbDeleted=" << DummyTbl::nbDeleted << std::endl;
663  trace.endBlock();
664 
665  // These lines do not compile.
666  // DummyTbl& ref_a1 = ConstAlias<DummyTbl>( a1 );
667  // DummyTbl* ptr_a1( & ConstAlias<DummyTbl>( a1 ) );
668 
669  trace.endBlock();
670 
671  delete ptr_a2;
672  return nbok == nb;
673 }
674 
694 {
695  unsigned int nb = 0;
696  unsigned int nbok = 0;
697  DummyTbl a1( 50, 10 ); // +1/0
698  CowPtr<DummyTbl> cow_a1( new DummyTbl( 50, 5 ) ); // +1/0
699  CountedPtr<DummyTbl> counted_a1( new DummyTbl( 50, 12 ) ); // +1/0
700  DummyTbl::reset();
701  trace.beginBlock ( "Testing class Clone." );
702 
703 
704  trace.beginBlock ( "Clone: #DummyTbl with (const DummyTbl &) to DummyTbl member. Duplication (+1/0)" );
705  CloneToValueMember c00( a1 ); // +1/0
706  trace.info() << "D: d1.value() = " << c00.value() << std::endl;
707  ++nb; nbok += DummyTbl::nbCreated==1 ? 1 : 0;
708  ++nb; nbok += DummyTbl::nbDeleted==0 ? 1 : 0;
709  trace.info() << "(" << nbok << "/" << nb << ")"
710  << " nbCreated=" << DummyTbl::nbCreated
711  << " nbDeleted=" << DummyTbl::nbDeleted << std::endl;
712  trace.endBlock();
713 
714  trace.beginBlock ( "Clone: #DummyTbl with (CountedPtr<DummyTbl>) to DummyTbl member. Duplication (+1/0)" );
715  CloneToValueMember c30( a1 ); // +1/0
716  trace.info() << "D: d1.value() = " << c30.value() << std::endl;
717  ++nb; nbok += DummyTbl::nbCreated==2 ? 1 : 0;
718  ++nb; nbok += DummyTbl::nbDeleted==0 ? 1 : 0;
719  trace.info() << "(" << nbok << "/" << nb << ")"
720  << " nbCreated=" << DummyTbl::nbCreated
721  << " nbDeleted=" << DummyTbl::nbDeleted << std::endl;
722  trace.endBlock();
723 
724  trace.beginBlock ( "Clone: #DummyTbl with (const DummyTbl &) to CountedPtr<DummyTbl> member. Duplication (+1/0)" );
725  CloneToCountedMember c03( a1 ); // +1/0
726  trace.info() << "D: d1.value() = " << c03.value() << std::endl;
727  ++nb; nbok += DummyTbl::nbCreated==3 ? 1 : 0;
728  ++nb; nbok += DummyTbl::nbDeleted==0 ? 1 : 0;
729  trace.info() << "(" << nbok << "/" << nb << ")"
730  << " nbCreated=" << DummyTbl::nbCreated
731  << " nbDeleted=" << DummyTbl::nbDeleted << std::endl;
732  trace.endBlock();
733 
734  trace.beginBlock ( "Clone: #DummyTbl with (const DummyTbl &) to CowPtr<DummyTbl> member. Duplication (+1/0)" );
735  CloneToCowMember c02( a1 ); // +1/0
736  trace.info() << "D: d1.value() = " << c02.value() << std::endl;
737  ++nb; nbok += DummyTbl::nbCreated==4 ? 1 : 0;
738  ++nb; nbok += DummyTbl::nbDeleted==0 ? 1 : 0;
739  trace.info() << "(" << nbok << "/" << nb << ")"
740  << " nbCreated=" << DummyTbl::nbCreated
741  << " nbDeleted=" << DummyTbl::nbDeleted << std::endl;
742  trace.endBlock();
743 
744  trace.beginBlock ( "Clone: #DummyTbl with (CowPtr<DummyTbl> &) to CowPtr<DummyTbl> member. Lazy duplication (0/0)" );
745  CloneToCowMember c22( cow_a1 ); // +0/0
746  trace.info() << "D: d1.value() = " << c22.value() << std::endl;
747  ++nb; nbok += DummyTbl::nbCreated==4 ? 1 : 0;
748  ++nb; nbok += DummyTbl::nbDeleted==0 ? 1 : 0;
749  trace.info() << "(" << nbok << "/" << nb << ")"
750  << " nbCreated=" << DummyTbl::nbCreated
751  << " nbDeleted=" << DummyTbl::nbDeleted << std::endl;
752  c22.setValue( 17 );
753  trace.info() << "D: d1.setValue( 17 ) -> now duplicating " << std::endl;
754  trace.info() << "D: d1.value() = " << c22.value() << std::endl;
755  ++nb; nbok += DummyTbl::nbCreated==5 ? 1 : 0;
756  ++nb; nbok += DummyTbl::nbDeleted==0 ? 1 : 0;
757  trace.info() << "(" << nbok << "/" << nb << ")"
758  << " nbCreated=" << DummyTbl::nbCreated
759  << " nbDeleted=" << DummyTbl::nbDeleted << std::endl;
760  trace.endBlock();
761 
762  trace.beginBlock ( "Clone: #DummyTbl with (CountedPtr<DummyTbl> &) to CowPtr<DummyTbl> member. Lazy duplication (0/0)" );
763  CloneToCowMember c32( counted_a1 ); // +0/0
764  trace.info() << "D: d1.value() = " << c32.value() << std::endl;
765  ++nb; nbok += DummyTbl::nbCreated==5 ? 1 : 0;
766  ++nb; nbok += DummyTbl::nbDeleted==0 ? 1 : 0;
767  trace.info() << "(" << nbok << "/" << nb << ")"
768  << " nbCreated=" << DummyTbl::nbCreated
769  << " nbDeleted=" << DummyTbl::nbDeleted << std::endl;
770  c32.setValue( 21 );
771  trace.info() << "D: d1.setValue( 21 ) -> now duplicating " << std::endl;
772  trace.info() << "D: d1.value() = " << c32.value() << std::endl;
773  ++nb; nbok += DummyTbl::nbCreated==6 ? 1 : 0;
774  ++nb; nbok += DummyTbl::nbDeleted==0 ? 1 : 0;
775  trace.info() << "(" << nbok << "/" << nb << ")"
776  << " nbCreated=" << DummyTbl::nbCreated
777  << " nbDeleted=" << DummyTbl::nbDeleted << std::endl;
778  trace.endBlock();
779 
780  trace.beginBlock ( "Clone: #DummyTbl with (DummyTbl*) to DummyTbl member. Acquisition, duplication, delete (+2/+1)" );
781  CloneToValueMember c10( new DummyTbl( 50, 2 ) ); // +2/+1
782  trace.info() << "D: d1.value() = " << c10.value() << std::endl;
783  ++nb; nbok += DummyTbl::nbCreated==8 ? 1 : 0;
784  ++nb; nbok += DummyTbl::nbDeleted==1 ? 1 : 0;
785  trace.info() << "(" << nbok << "/" << nb << ")"
786  << " nbCreated=" << DummyTbl::nbCreated
787  << " nbDeleted=" << DummyTbl::nbDeleted << std::endl;
788  trace.endBlock();
789 
790  trace.beginBlock ( "Clone: #DummyTbl with (DummyTbl*) to CowPtr<DummyTbl> member. Acquisition, no duplication (+1/0)" );
791  CloneToCowMember c12( new DummyTbl( 50, 15 ) ); // +1/0
792  trace.info() << "D: d1.value() = " << c12.value() << std::endl;
793  ++nb; nbok += DummyTbl::nbCreated==9 ? 1 : 0;
794  ++nb; nbok += DummyTbl::nbDeleted==1 ? 1 : 0;
795  trace.info() << "(" << nbok << "/" << nb << ")"
796  << " nbCreated=" << DummyTbl::nbCreated
797  << " nbDeleted=" << DummyTbl::nbDeleted << std::endl;
798  trace.endBlock();
799 
800  trace.beginBlock ( "Clone: #DummyTbl with (const DummyTbl&) to DummyTbl* member. Duplication (+1/0)" );
801  CloneToPtrMember c01( a1 ); // +1/0
802  trace.info() << "D: d1.value() = " << c01.value() << std::endl;
803  ++nb; nbok += DummyTbl::nbCreated==10 ? 1 : 0;
804  ++nb; nbok += DummyTbl::nbDeleted==1 ? 1 : 0;
805  trace.info() << "(" << nbok << "/" << nb << ")"
806  << " nbCreated=" << DummyTbl::nbCreated
807  << " nbDeleted=" << DummyTbl::nbDeleted << std::endl;
808  trace.endBlock();
809 
810  trace.beginBlock ( "Clone: #DummyTbl with (DummyTbl*) to DummyTbl* member. Acquisition (+1/0)" );
811  CloneToPtrMember c11( new DummyTbl( 50, 42 ) ); // +1/0
812  trace.info() << "D: d1.value() = " << c11.value() << std::endl;
813  ++nb; nbok += DummyTbl::nbCreated==11 ? 1 : 0;
814  ++nb; nbok += DummyTbl::nbDeleted==1 ? 1 : 0;
815  trace.info() << "(" << nbok << "/" << nb << ")"
816  << " nbCreated=" << DummyTbl::nbCreated
817  << " nbDeleted=" << DummyTbl::nbDeleted << std::endl;
818  trace.endBlock();
819 
820  trace.beginBlock ( "Clone: #DummyTbl with (CowPtr<DummyTbl>) to DummyTbl* member. Duplication (+1/0)" );
821  CloneToPtrMember c21( cow_a1 ); // +1/0
822  trace.info() << "D: d1.value() = " << c21.value() << std::endl;
823  ++nb; nbok += DummyTbl::nbCreated==12 ? 1 : 0;
824  ++nb; nbok += DummyTbl::nbDeleted==1 ? 1 : 0;
825  trace.info() << "(" << nbok << "/" << nb << ")"
826  << " nbCreated=" << DummyTbl::nbCreated
827  << " nbDeleted=" << DummyTbl::nbDeleted << std::endl;
828  trace.endBlock();
829 
830  trace.beginBlock ( "Clone: #DummyTbl with (CountedPtr<DummyTbl>) to DummyTbl* member. Duplication (+1/0)" );
831  CloneToPtrMember c31( counted_a1 ); // +1/0
832  trace.info() << "D: d1.value() = " << c31.value() << std::endl;
833  ++nb; nbok += DummyTbl::nbCreated==13 ? 1 : 0;
834  ++nb; nbok += DummyTbl::nbDeleted==1 ? 1 : 0;
835  trace.info() << "(" << nbok << "/" << nb << ")"
836  << " nbCreated=" << DummyTbl::nbCreated
837  << " nbDeleted=" << DummyTbl::nbDeleted << std::endl;
838  trace.endBlock();
839 
840  trace.beginBlock ( "Clone: #DummyTbl with (DummyTbl &&) to DummyTbl member. Duplication by move (+2/+1/+1)" );
841  CloneToValueMember c40( DummyTbl( 50, -4 ) ); // +2/+1/+1
842  trace.info() << "D: d1.value() = " << c40.value() << std::endl;
843  ++nb; nbok += DummyTbl::nbCreated==15 ? 1 : 0;
844  ++nb; nbok += DummyTbl::nbDeleted==2 ? 1 : 0;
845  ++nb; nbok += DummyTbl::nbMoved==1 ? 1 : 0;
846  trace.info() << "(" << nbok << "/" << nb << ")"
847  << " nbCreated=" << DummyTbl::nbCreated
848  << " nbDeleted=" << DummyTbl::nbDeleted
849  << " nbMoved=" << DummyTbl::nbMoved
850  << std::endl;
851  trace.endBlock();
852 
853  trace.beginBlock ( "Clone: #DummyTbl with (DummyTbl &&) to CowPtr<DummyTbl> member. Duplication by move (+2/+1/+1)" );
854  CloneToCowMember c42( DummyTbl( 50, -9 ) ); // +2/+1/+1
855  trace.info() << "D: d1.value() = " << c42.value() << std::endl;
856  ++nb; nbok += DummyTbl::nbCreated==17 ? 1 : 0;
857  ++nb; nbok += DummyTbl::nbDeleted==3 ? 1 : 0;
858  ++nb; nbok += DummyTbl::nbMoved==2 ? 1 : 0;
859  trace.info() << "(" << nbok << "/" << nb << ")"
860  << " nbCreated=" << DummyTbl::nbCreated
861  << " nbDeleted=" << DummyTbl::nbDeleted
862  << " nbMoved=" << DummyTbl::nbMoved
863  << std::endl;
864  trace.endBlock();
865 
866  trace.beginBlock ( "Clone: #DummyTbl with (DummyTbl &&) to DummyTbl* member. Duplication by move (+2/+1/+1)" );
867  CloneToCowMember c41( DummyTbl( 50, -12 ) ); // +2/+1/+1
868  trace.info() << "D: d1.value() = " << c41.value() << std::endl;
869  ++nb; nbok += DummyTbl::nbCreated==19 ? 1 : 0;
870  ++nb; nbok += DummyTbl::nbDeleted==4 ? 1 : 0;
871  ++nb; nbok += DummyTbl::nbMoved==3 ? 1 : 0;
872  trace.info() << "(" << nbok << "/" << nb << ")"
873  << " nbCreated=" << DummyTbl::nbCreated
874  << " nbDeleted=" << DummyTbl::nbDeleted
875  << " nbMoved=" << DummyTbl::nbMoved
876  << std::endl;
877  trace.endBlock();
878 
879  trace.endBlock();
880 
881  return nbok == nb;
882 }
883 
885 {
886  unsigned int nb = 0;
887  unsigned int nbok = 0;
888  int size = 10;
889  trace.beginBlock ( "Testing Clone timings." );
890 
891  trace.beginBlock ( "Total perimeter of triangles with by-value parameter passing." );
892  double t1 = computeTriangles<TriangleByValue>( size );
893  trace.info() << "Perimeter is " << t1 << std::endl;
894  ++nb; nbok += Point::nbCreated == Point::nbDeleted ? 1 : 0;
895  trace.info() << "(" << nbok << "/" << nb << ")"
896  << " Point nbCreated=" << Point::nbCreated
897  << " nbDeleted=" << Point::nbDeleted << std::endl;
898  int nbC = Point::nbCreated;
899  Point::reset();
900  trace.endBlock();
901  trace.beginBlock ( "Total perimeter of triangles with by-const reference parameter passing." );
902  double t2 = computeTriangles<TriangleByConstReference>( size );
903  trace.info() << "Perimeter is " << t2 << std::endl;
904  ++nb; nbok += Point::nbCreated == Point::nbDeleted ? 1 : 0;
905  ++nb; nbok += Point::nbCreated < nbC ? 1 : 0;
906  trace.info() << "(" << nbok << "/" << nb << ")"
907  << " Point nbCreated=" << Point::nbCreated
908  << " nbDeleted=" << Point::nbDeleted << std::endl;
909  Point::reset();
910  trace.endBlock();
911  trace.beginBlock ( "Total perimeter of triangles with by Clone parameter passing." );
912  double t4 = computeTriangles<TriangleByClone>( size );
913  trace.info() << "Perimeter is " << t4 << std::endl;
914  ++nb; nbok += Point::nbCreated == Point::nbDeleted ? 1 : 0;
915  ++nb; nbok += Point::nbCreated <= nbC ? 1 : 0;
916  trace.info() << "(" << nbok << "/" << nb << ")"
917  << " Point nbCreated=" << Point::nbCreated
918  << " nbDeleted=" << Point::nbDeleted << std::endl;
919  Point::reset();
920  trace.endBlock();
921  trace.beginBlock ( "Total perimeter of triangles with by CloneAndCow parameter passing." );
922  double t5 = computeTriangles<TriangleByCloneAndCow>( size );
923  trace.info() << "Perimeter is " << t5 << std::endl;
924  ++nb; nbok += Point::nbCreated == Point::nbDeleted ? 1 : 0;
925  ++nb; nbok += Point::nbCreated < nbC ? 1 : 0;
926  trace.info() << "(" << nbok << "/" << nb << ")"
927  << " Point nbCreated=" << Point::nbCreated
928  << " nbDeleted=" << Point::nbDeleted << std::endl;
929  Point::reset();
930  trace.endBlock();
931  trace.beginBlock ( "Total perimeter of triangles with CowPtr by CloneAndCow parameter passing." );
932  double t6 = computeTrianglesByCowPtr<TriangleByCloneAndCow>( size );
933  trace.info() << "Perimeter is " << t6 << std::endl;
934  ++nb; nbok += Point::nbCreated == Point::nbDeleted ? 1 : 0;
935  ++nb; nbok += Point::nbCreated < nbC ? 1 : 0;
936  trace.info() << "(" << nbok << "/" << nb << ")"
937  << " Point nbCreated=" << Point::nbCreated
938  << " nbDeleted=" << Point::nbDeleted << std::endl;
939  Point::reset();
940  trace.endBlock();
941 
942  trace.endBlock();
943 
944  return nb == nbok;
945 }
946 
947 int main()
948 {
949  bool ok = true
950  && testCloneCases()
951  && testCloneTimings()
952  && testAliasCases()
953  && testConstAliasCases();
954 
955  return ok ? 0 : 1;
956 }
Aim: This class encapsulates its parameter class so that to indicate to the user that the object/poin...
Definition: Alias.h:183
Aim: This class encapsulates its parameter class to indicate that the given parameter is required to ...
Definition: Clone.h:267
Aim: This class encapsulates its parameter class so that to indicate to the user that the object/poin...
Definition: ConstAlias.h:187
Aim: Smart pointer based on reference counts.
Definition: CountedPtr.h:80
Aim: Copy on write shared pointer.
Definition: CowPtr.h:68
bool unique() const noexcept
Definition: CowPtr.h:175
void beginBlock(const std::string &keyword="")
std::ostream & info()
double endBlock()
DGtal is the top-level namespace which contains all DGtal functions and types.
Trace trace
Definition: Common.h:153
KForm< Calculus, order, duality > operator-(const KForm< Calculus, order, duality > &form_a, const KForm< Calculus, order, duality > &form_b)
Represents an unoriented triangle as three vertices.
MyPointD Point
Definition: testClone2.cpp:383
bool testAliasCases()
Definition: testClone2.cpp:477
bool testCloneTimings()
Definition: testClone2.cpp:884
bool testCloneCases()
Definition: testClone2.cpp:693
double computeTriangles(int size)
Definition: testClone2.cpp:428
bool testConstAliasCases()
Definition: testClone2.cpp:576
double computeTrianglesByCowPtr(int size)
Definition: testClone2.cpp:449
int main()
Definition: testClone2.cpp:947