DGtal 1.3.0
Loading...
Searching...
No Matches
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
40using namespace DGtal;
41using namespace std;
42
43// Dummy class to test clones and aliases.
44struct A1
45{
46private:
47 A1();
48public:
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
81int A1::nbCreated = 0;
82int A1::nbDeleted = 0;
83
84// This class uses standard by-value parameter passing
85// The data member is an instance of A1.
86struct 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.
103struct 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.
120struct 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.
137struct 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
152class MyPoint {
153public:
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
181int MyPoint::nbCreated = 0;
182int MyPoint::nbDeleted = 0;
183
184//typedef Z2i::Point Point;
185typedef MyPoint Point;
186
187struct 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
197struct 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
207struct 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
217template <typename Triangle>
218double
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
238struct 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
255struct 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
272int 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}
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: Copy on write shared pointer.
Definition: CowPtr.h:68
void beginBlock(const std::string &keyword="")
std::ostream & info()
double endBlock()
Container operator-(const Container &S1, const Container &S2)
DGtal is the top-level namespace which contains all DGtal functions and types.
Trace trace
Definition: Common.h:154
STL namespace.
Represents an unoriented triangle as three vertices.
MyPointD Point
Definition: testClone2.cpp:383
double computeTriangles(int size)
int main()
MyPoint Point