DGtal  0.9.2
testCirculator.cpp
1 
30 #include <iostream>
32 #include <vector>
33 #include <list>
34 #include <forward_list>
35 
36 #include "DGtal/base/Common.h"
37 #include "DGtal/base/Circulator.h"
39 
40 
41 using namespace std;
42 using namespace DGtal;
43 
44 
46 // Functions for testing class Circulator.
48 
52 template<typename Iterator>
53 bool testOffset(const Iterator& itb, const Iterator& ite, const vector<int>& groundTruth)
54 {
55 
56  BOOST_CONCEPT_ASSERT(( boost::BidirectionalIterator<Iterator> ));
57  BOOST_CONCEPT_ASSERT(( boost::BidirectionalIterator< Circulator<Iterator> > ));
58 
59  //list
60  copy(itb,ite,ostream_iterator<int>(trace.info(), " "));
61  trace.info() << " => ";
62 
63  //use of Circulators
64  vector<int> v;
65  Circulator<Iterator> cb( itb, itb, ite );
66  Circulator<Iterator> c( ++cb );
67  do {
68  v.push_back(*c);
69  c++;
70  } while (c != cb);
71 
72  //offset list
73  copy(v.begin(),v.end(),ostream_iterator<int>(trace.info(), " "));
74 
75  //ground truth
76  trace.info() << " ( == ";
77  copy(groundTruth.begin(),groundTruth.end(),ostream_iterator<int>(trace.info(), " "));
78  trace.info() << ")" << std::endl;
79 
80  return equal( v.begin(),v.end(),groundTruth.begin() );
81 }
82 
88 template<typename Container>
89 bool basicForwardTest(const Container& cont)
90 {
91  unsigned int nbok = 0;
92  unsigned int nb = 0;
93 
94  trace.beginBlock ( "Operators of forward circulator" );
95  typedef typename Container::const_iterator I;
96 
97  //default construction
98  Circulator<I> circ0;
99  if ( !(circ0.isValid()) )
100  nbok++;
101  nb++;
102  trace.info() << "(" << nbok << "/" << nb << ") " << std::endl;
103  //construction
104  Circulator<I> circ1(cont.begin(), cont.begin(), cont.end());
105  if ( circ1.isValid() )
106  nbok++;
107  nb++;
108  trace.info() << "(" << nbok << "/" << nb << ") " << std::endl;
109  //copy
110  Circulator<I> circ2 = circ1;
111  //assignement
112  circ0 = circ1;
113  //pre/post-incrementation
114  circ1++;
115  ++circ2;
116  //equality
117  if ( (circ0 != circ1) && (circ0 != circ2) && (circ1 == circ2) )
118  nbok++;
119  nb++;
120  trace.info() << "(" << nbok << "/" << nb << ") " << std::endl;
121  //base, begin, end
122  if ( (circ0.base() != circ1.base())
123  && (circ0.base() != circ2.base())
124  && (circ1.base() == circ2.base()) )
125  nbok++;
126  nb++;
127  trace.info() << "(" << nbok << "/" << nb << ") " << std::endl;
128  if ( (circ0.begin() == circ1.begin())
129  && (circ0.end() == circ1.end())
130  && (circ1.begin() == circ2.begin()) )
131  nbok++;
132  nb++;
133  trace.info() << "(" << nbok << "/" << nb << ") " << std::endl;
134  //operator *, ->
135  if ( (*circ1 == *circ2) && (circ1.operator->() == &(*circ1)) )
136  nbok++;
137  nb++;
138  trace.info() << "(" << nbok << "/" << nb << ") " << std::endl;
139 
140  trace.endBlock();
141 
142  return (nbok == nb);
143 }
144 
150 template<typename Container>
151 bool basicBidirectionalTest(const Container& cont)
152 {
153  ASSERT( cont.size() >= 1 );
154  unsigned int nbok = 0;
155  unsigned int nb = 0;
156 
157  trace.beginBlock ( "Operators of bidirectional circulator" );
158  typedef typename Container::const_iterator I;
159 
160  //construction/copy
161  Circulator<I> res(cont.begin(), cont.begin(), cont.end());
162  Circulator<I> circ1(cont.begin(), cont.begin(), cont.end());
163  Circulator<I> circ2 = circ1;
164  //pre/post-incrementation
165  circ1++;
166  ++circ2;
167  if (circ1 == circ2)
168  nbok++;
169  nb++;
170  trace.info() << "(" << nbok << "/" << nb << ") " << std::endl;
171  //pre/post-decrementation
172  circ1--;
173  --circ2;
174  if ( (circ1 == circ2) && (circ1 == res) && (circ2 == res) )
175  nbok++;
176  nb++;
177  trace.info() << "(" << nbok << "/" << nb << ") " << std::endl;
178 
179  trace.endBlock();
180 
181  return (nbok == nb);
182 }
183 
189 template<typename Container>
190 bool basicRandomAccessTest(const Container& cont)
191 {
192  ASSERT( cont.size() == 5 );
193 
194  unsigned int nbok = 0;
195  unsigned int nb = 0;
196 
197  trace.beginBlock ( "Operators of random access circulator" );
198  typedef typename Container::const_iterator I;
199 
200  //construction/copy
201  Circulator<I> circ1(cont.begin(), cont.begin(), cont.end());
202  Circulator<I> circ2 = circ1;
203 
204  trace.info() << "arithmetic operators" << std::endl;
205  circ2 += 4;
206  if ( (circ2) == (circ1+4) )
207  nbok++;
208  nb++;
209  trace.info() << "(" << nbok << "/" << nb << ") " << std::endl;
210 
211  circ2 -= 5;
212  circ2++;
213  if ( circ1 == circ2 )
214  nbok++;
215  nb++;
216  trace.info() << "(" << nbok << "/" << nb << ") " << std::endl;
217 
218  if ( (circ1+3) == (3+circ1) )
219  nbok++;
220  nb++;
221  trace.info() << "(" << nbok << "/" << nb << ") " << std::endl;
222 
223  circ2 += 7;
224  if ( (circ1+2) == circ2 )
225  nbok++;
226  nb++;
227  trace.info() << "(" << nbok << "/" << nb << ") " << std::endl;
228 
229  if ( ((circ1-circ2) + (circ2-circ1)) == (cont.end()-cont.begin()) )
230  nbok++;
231  nb++;
232  trace.info() << "(" << nbok << "/" << nb << ") " << std::endl;
233 
234  trace.info() << "comparison operators" << std::endl;
235  if ( (circ1 < circ2) && (circ1 <= circ2)
236  && (circ2 < circ1) && (circ2 <= circ1) )
237  nbok++;
238  nb++;
239  trace.info() << "(" << nbok << "/" << nb << ") " << std::endl;
240 
241  if ( !( (circ1 > circ2) && (circ1 >= circ2)
242  && (circ2 > circ1) && (circ2 >= circ1) ) )
243  nbok++;
244  nb++;
245  trace.info() << "(" << nbok << "/" << nb << ") " << std::endl;
246 
247  trace.endBlock();
248 
249  return (nbok == nb);
250 }
251 
253 // Standard services - public :
254 
255 int main( int argc, char** argv )
256 {
257  trace.beginBlock ( "Testing class Circulator" );
258  trace.info() << "Args:";
259  for ( int i = 0; i < argc; ++i )
260  trace.info() << " " << argv[ i ];
261  trace.info() << endl;
262 
263  vector<int> v;
264  v.push_back(1);
265  v.push_back(2);
266  v.push_back(3);
267  v.push_back(4);
268  v.push_back(5);
269 
270  vector<int> v2;
271  v2.push_back(2);
272  v2.push_back(3);
273  v2.push_back(4);
274  v2.push_back(5);
275  v2.push_back(1);
276 
277  vector<int> v3;
278  v3.push_back(4);
279  v3.push_back(3);
280  v3.push_back(2);
281  v3.push_back(1);
282  v3.push_back(5);
283 
284  //incrementation
285  trace.beginBlock ( "Iteration" );
286  bool res = testOffset(v.begin(),v.end(), v2)
287  && testOffset(v.rbegin(),v.rend(), v3)
288  && testOffset(v.begin(),v.end(), v2)
289  && testOffset(v.rbegin(),v.rend(), v3);
290  trace.endBlock();
291 
292  //comparisons
293  trace.beginBlock ( "Comparison" );
294  trace.info() << "(const / not const)" << endl;
295  Circulator<vector<int>::iterator> c1( v.begin(), v.begin(), v.end() );
298  res = res && (c1 == c2) && (c1 == c3);
299 
300  trace.info() << "(reverse_iterator<Circulator> / Circulator<reverse_iterator>)" << endl;
301  std::reverse_iterator<Circulator<vector<int>::iterator> > rc1( c1 );
302  Circulator <vector<int>::reverse_iterator> c4( v.rend(), v.rbegin(), v.rend() );
303  res = res && (rc1.base().base() == c4.base().base());
304  trace.info() << "first element: (" << *--rc1 << " == " << *--c4 << ")" << endl;
305  res = res && ((*rc1) == (*c4));
306  trace.endBlock();
307 
308  std::forward_list<int> fl;
309  fl.push_front(1);
310  fl.push_front(2);
311  fl.push_front(3);
312  fl.push_front(4);
313  fl.push_front(5);
314 
315  std::list<int> bl;
316  bl.push_back(1);
317  bl.push_back(2);
318  bl.push_back(3);
319  bl.push_back(4);
320  bl.push_back(5);
321 
322  res = res &&
323  basicForwardTest(fl) &&
324  basicForwardTest(bl) &&
325  basicForwardTest(v) &&
326  basicBidirectionalTest(bl) &&
327  basicBidirectionalTest(v) &&
328  basicRandomAccessTest(v);
329 
330  trace.emphase() << ( res ? "Passed." : "Error." ) << endl;
331  trace.endBlock();
332  return res ? 0 : 1;
333 }
334 // //
void beginBlock(const std::string &keyword="")
Trace trace
Definition: Common.h:130
Iterator end() const
Definition: Circulator.h:228
STL namespace.
double endBlock()
bool isValid() const
Definition: Circulator.h:206
std::ostream & emphase()
Aim: Provides an adapter for classical iterators that can iterate through the underlying data structu...
Definition: Circulator.h:85
Iterator base() const
Definition: Circulator.h:216
DGtal is the top-level namespace which contains all DGtal functions and types.
std::ostream & info()
Go to http://www.sgi.com/tech/stl/BidirectionalIterator.html.
Definition: Boost.dox:42
Iterator begin() const
Definition: Circulator.h:222