DGtal  1.3.beta
testCloneAndAliases.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/Clone.h"
36 #include "DGtal/base/Alias.h"
37 #include "DGtal/base/ConstAlias.h"
38 #include "DGtal/helpers/StdDefs.h"
39 
40 using namespace DGtal;
41 using namespace std;
42 
43 // Dummy class to test clones and aliases.
44 struct A1
45 {
46 private:
47  A1();
48 public:
49  ~A1()
50  {
51  std::cout << " ~A1() " << std::endl;
52  ++nbDeleted;
53  }
54  A1( int i ) : data( i )
55  {
56  std::cout << " A1( int i ) " << std::endl;
57  ++nbCreated;
58  }
59  A1( const A1 & a ) : data( a.data )
60  {
61  std::cout << " A1( const A1 & a ) " << std::endl;
62  ++nbCreated;
63  }
64  A1& operator=( const A1 & a )
65  {
66  data = a.data;
67  std::cout << " A1::operator=( const A1 & a ) " << std::endl;
68  return *this;
69  }
70  static void reset() {
71  nbCreated = 0;
72  nbDeleted = 0;
73  }
74 
75  int data;
76 
77  static int nbCreated;
78  static int nbDeleted;
79 };
80 
81 int A1::nbCreated = 0;
82 int A1::nbDeleted = 0;
83 
84 // This class uses standard by-value parameter passing
85 // The data member is an instance of A1.
86 struct DByValue {
87  DByValue( A1 a )
88  : myA1( a )
89  {
90  std::cout << " DByValue( A1 a) " << std::endl;
91  }
92 
93  int value() const
94  {
95  return myA1.data;
96  }
97 
98  A1 myA1;
99 };
100 
101 // This class uses the provided explicit by-value parameter passing (with Clone).
102 // The data member is an instance of A1.
103 struct DByClone {
104  DByClone( Clone<A1> a )
105  : myA1( a )
106  {
107  std::cout << " DByClone( Clone<A1> a) " << std::endl;
108  }
109 
110  int value() const
111  {
112  return myA1.data;
113  }
114 
115  A1 myA1;
116 };
117 
118 // This class uses the provided explicit by-reference parameter passing (with Alias).
119 // The data member is a pointer to the given instance.
120 struct EByAlias {
121  EByAlias( Alias<A1> a )
122  : myA1( &a )
123  {
124  std::cout << " EByAlias( Alias<A1> a ) " << myA1 << std::endl;
125  }
126 
127  int value() const
128  {
129  return myA1->data;
130  }
131 
132  A1* myA1;
133 };
134 
135 // This class uses the provided explicit by-reference parameter passing (with Alias).
136 // The data member is a const pointer to the given instance.
137 struct EByConstAlias {
138  EByConstAlias( ConstAlias<A1> a )
139  : myA1( &a )
140  {
141  std::cout << " EByConstAlias( Alias<A1> a ) " << myA1 << std::endl;
142  }
143 
144  int value() const
145  {
146  return myA1->data;
147  }
148 
149  const A1* myA1;
150 };
151 
152 class MyPoint {
153 public:
154  ~MyPoint()
155  { nbDeleted++; }
156  MyPoint( const MyPoint & other )
157  : _x( other._x ), _y( other._y )
158  { nbCreated++; }
159  MyPoint( int x, int y ) : _x( x ), _y( y )
160  { nbCreated++; }
161  MyPoint operator-( const MyPoint & other ) const
162  {
163  return MyPoint( _x - other._x, _y - other._y );
164  }
165  double norm() const
166  {
167  double dx = (double) _x;
168  double dy = (double) _y;
169  return sqrt( dx * dx + dy * dy );
170  }
171  static void reset()
172  {
173  nbCreated = nbDeleted = 0;
174  }
175  int _x, _y;
176 
177  static int nbCreated;
178  static int nbDeleted;
179 };
180 
181 int MyPoint::nbCreated = 0;
182 int MyPoint::nbDeleted = 0;
183 
184 //typedef Z2i::Point Point;
185 typedef MyPoint Point;
186 
187 struct TriangleByConstReference {
188  TriangleByConstReference( const Point & a, const Point & b, const Point & c )
189  : _a( a ), _b( b ), _c( c ) {}
190  double perimeter() const
191  {
192  return (_a - _b).norm() + (_b - _c).norm() + (_c - _a).norm();
193  }
194  Point _a, _b, _c;
195 };
196 
197 struct TriangleByValue {
198  TriangleByValue( Point a, Point b, Point c )
199  : _a( a ), _b( b ), _c( c ) {}
200  double perimeter() const
201  {
202  return (_a - _b).norm() + (_b - _c).norm() + (_c - _a).norm();
203  }
204  Point _a, _b, _c;
205 };
206 
207 struct TriangleByClone {
208  TriangleByClone( Clone<Point> a, Clone<Point> b, Clone<Point> c )
209  : _a( a ), _b( b ), _c( c ) {}
210  double perimeter() const
211  {
212  return (_a - _b).norm() + (_b - _c).norm() + (_c - _a).norm();
213  }
214  Point _a, _b, _c;
215 };
216 
217 template <typename Triangle>
218 double
219 computeTriangles( int size )
220 {
221  double total = 0.0;
222  Point A( 0, 0 );
223  for ( int yb = 0; yb < size; ++yb )
224  for ( int xb = 0; xb < size; ++xb )
225  {
226  Point B( xb, yb );
227  for ( int yc = 0; yc < size; ++yc )
228  for ( int xc = 0; xc < size; ++xc )
229  {
230  Point C( xc, yc );
231  Triangle T( A, B, C );
232  total += T.perimeter();
233  }
234  }
235  return total;
236 }
237 
238 struct FByCloneHeap {
239  FByCloneHeap( Clone<A1> a ) // not ambiguous, cost is O(N) here and lifetime of a is whatever.
240  : myA1( &a )
241  {
242  std::cout << " FByCloneHeap( Clone<A1> a ) " << myA1 << std::endl;
243  }
244 
245  ~FByCloneHeap() { if ( myA1 != 0 ) delete myA1; }
246 
247  int value() const
248  {
249  return myA1->data;
250  }
251 
252  A1* myA1;
253 };
254 
255 struct FByCloneCowPtr {
256  FByCloneCowPtr( Clone<A1> a ) // not ambiguous, cost is O(N) here and lifetime of a is whatever.
257  : myA1( a )
258  {
259  std::cout << " FByCloneCowPtr( Clone<A1> a ) " << myA1 << std::endl;
260  }
261 
262  ~FByCloneCowPtr() {}
263 
264  int value() const
265  {
266  return myA1->data;
267  }
268 
269  CowPtr<A1> myA1;
270 };
271 
272 int main()
273 {
274  unsigned int nb = 0;
275  unsigned int nbok = 0;
276  trace.beginBlock ( "Number of A1 instances with standard by-value parameter passing." );
277  A1 a1( 10 ); // +1/ 0
278  DByValue d1( a1 ); // +2/+1
279  trace.info() << "D: d1.value() = " << d1.value() << std::endl;
280  ++nb; nbok += A1::nbCreated==3 ? 1 : 0;
281  ++nb; nbok += A1::nbDeleted==1 ? 1 : 0;
282  trace.info() << "(" << nbok << "/" << nb << ")"
283  << " nbCreated=" << A1::nbCreated
284  << " nbDeleted=" << A1::nbDeleted << std::endl;
285  trace.endBlock();
286  trace.beginBlock ( "Number of A1 instances with explicit by-value parameter passing (Clone)." );
287  DByClone dd1( a1 ); // +1/0
288  ++nb; nbok += A1::nbCreated==4 ? 1 : 0;
289  ++nb; nbok += A1::nbDeleted==1 ? 1 : 0;
290  trace.info() << "(" << nbok << "/" << nb << ")"
291  << " nbCreated=" << A1::nbCreated
292  << " nbDeleted=" << A1::nbDeleted << std::endl;
293  trace.endBlock();
294  trace.beginBlock ( "Number of A1 instances with explicit by-reference parameter passing (Alias)." );
295  EByAlias e1( a1 ); // +0/0
296  ++nb; nbok += A1::nbCreated==4 ? 1 : 0;
297  ++nb; nbok += A1::nbDeleted==1 ? 1 : 0;
298  trace.info() << "(" << nbok << "/" << nb << ")"
299  << " nbCreated=" << A1::nbCreated
300  << " nbDeleted=" << A1::nbDeleted << std::endl;
301  trace.endBlock();
302  trace.beginBlock ( "Number of A1 instances with explicit by-const reference parameter passing (Alias)." );
303  EByConstAlias ee1( a1 ); // +0/0
304  ++nb; nbok += A1::nbCreated==4 ? 1 : 0;
305  ++nb; nbok += A1::nbDeleted==1 ? 1 : 0;
306  trace.info() << "(" << nbok << "/" << nb << ")"
307  << " nbCreated=" << A1::nbCreated
308  << " nbDeleted=" << A1::nbDeleted << std::endl;
309  trace.endBlock();
310  trace.beginBlock ( "Number of A1 instances with explicit by-value parameter passing into heap (Clone)." );
311  FByCloneHeap fe1( a1 ); // +1/0
312  ++nb; nbok += A1::nbCreated==5 ? 1 : 0;
313  ++nb; nbok += A1::nbDeleted==1 ? 1 : 0;
314  trace.info() << "(" << nbok << "/" << nb << ")"
315  << " nbCreated=" << A1::nbCreated
316  << " nbDeleted=" << A1::nbDeleted << std::endl;
317  trace.endBlock();
318  trace.beginBlock ( "Number of A1 instances with explicit by-value parameter passing into CowPtr (Clone)." );
319  FByCloneCowPtr fe3( a1 ); // +1/0
320  ++nb; nbok += A1::nbCreated==6 ? 1 : 0;
321  ++nb; nbok += A1::nbDeleted==1 ? 1 : 0;
322  trace.info() << "(" << nbok << "/" << nb << ")"
323  << " nbCreated=" << A1::nbCreated
324  << " nbDeleted=" << A1::nbDeleted << std::endl;
325  trace.endBlock();
326 
327  int size = 20;
328  trace.beginBlock ( "Total perimeter of triangles with by-value parameter passing." );
329  double t1 = computeTriangles<TriangleByValue>( size );
330  trace.info() << "Perimeter is " << t1 << std::endl;
331  ++nb; nbok += Point::nbCreated == Point::nbDeleted ? 1 : 0;
332  trace.info() << "(" << nbok << "/" << nb << ")"
333  << " Point nbCreated=" << Point::nbCreated
334  << " nbDeleted=" << Point::nbDeleted << std::endl;
335  int nbC = Point::nbCreated;
336  Point::reset();
337  trace.endBlock();
338  trace.beginBlock ( "Total perimeter of triangles with by-const reference parameter passing." );
339  double t2 = computeTriangles<TriangleByConstReference>( size );
340  trace.info() << "Perimeter is " << t2 << std::endl;
341  ++nb; nbok += Point::nbCreated == Point::nbDeleted ? 1 : 0;
342  ++nb; nbok += Point::nbCreated < nbC ? 1 : 0;
343  trace.info() << "(" << nbok << "/" << nb << ")"
344  << " Point nbCreated=" << Point::nbCreated
345  << " nbDeleted=" << Point::nbDeleted << std::endl;
346  Point::reset();
347  trace.endBlock();
348  trace.beginBlock ( "Total perimeter of triangles with by Clone parameter passing." );
349  double t3 = computeTriangles<TriangleByClone>( size );
350  trace.info() << "Perimeter is " << t3 << std::endl;
351  ++nb; nbok += Point::nbCreated == Point::nbDeleted ? 1 : 0;
352  ++nb; nbok += Point::nbCreated < nbC ? 1 : 0;
353  trace.info() << "(" << nbok << "/" << nb << ")"
354  << " Point nbCreated=" << Point::nbCreated
355  << " nbDeleted=" << Point::nbDeleted << std::endl;
356  Point::reset();
357  trace.endBlock();
358 
359  // These two lines should not compile.
360  // Clone<A1> clone1( a1 );
361  // Clone<A1> clone2( clone2 );
362 
363  return ( nb == nbok ) ? 0 : 1;
364 }
DGtal::Clone
Aim: This class encapsulates its parameter class to indicate that the given parameter is required to ...
Definition: Clone.h:266
DGtal::operator-
KForm< Calculus, order, duality > operator-(const KForm< Calculus, order, duality > &form_a, const KForm< Calculus, order, duality > &form_b)
DGtal::ConstAlias
Aim: This class encapsulates its parameter class so that to indicate to the user that the object/poin...
Definition: ConstAlias.h:186
DGtal::Trace::endBlock
double endBlock()
DGtal::trace
Trace trace
Definition: Common.h:154
DGtal::Trace::beginBlock
void beginBlock(const std::string &keyword="")
computeTriangles
double computeTriangles(int size)
Definition: testCloneAndAliases.cpp:219
Point
MyPoint Point
Definition: testCloneAndAliases.cpp:185
DGtal::HalfEdgeDataStructure::Triangle
Represents an unoriented triangle as three vertices.
Definition: HalfEdgeDataStructure.h:154
DGtal::Trace::info
std::ostream & info()
DGtal
DGtal is the top-level namespace which contains all DGtal functions and types.
DGtal::Alias
Aim: This class encapsulates its parameter class so that to indicate to the user that the object/poin...
Definition: Alias.h:182
Point
MyPointD Point
Definition: testClone2.cpp:383
main
int main()
Definition: testCloneAndAliases.cpp:272
DGtal::CowPtr< A1 >