Lumiera  0.pre.03
»edit your freedom«
itertools-test.cpp
Go to the documentation of this file.
1 /*
2  IterTools(Test) - building combined and filtering iterators based on the Iterator tools
3 
4  Copyright (C) Lumiera.org
5  2009, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 * *****************************************************/
22 
29 #include "lib/test/run.hpp"
30 #include "lib/test/test-helper.hpp"
31 #include "lib/util-foreach.hpp"
32 #include "lib/format-cout.hpp"
33 #include "lib/util.hpp"
34 
35 #include "lib/itertools.hpp"
36 
37 #include <boost/lexical_cast.hpp>
38 #include <cstdlib>
39 #include <vector>
40 
41 
42 
43 namespace lib {
44 namespace test{
45 
46  using ::Test;
47  using boost::lexical_cast;
48  using util::for_each;
49  using util::isnil;
50  using std::vector;
51  using std::rand;
52 
53  using lumiera::error::LERR_(ITER_EXHAUST);
54 
55 
56 
57  namespace { // Test data
58 
59  uint NUM_ELMS = 10;
60 
61  struct TestSource
62  {
63  vector<int> data_;
64 
65  TestSource(uint num)
66  {
67  while (num)
68  data_.push_back(num--);
69  }
70 
71  typedef vector<int>::iterator sourceIter;
73 
74  iterator begin() { return iterator(data_.begin(),data_.end()); }
75  iterator end() { return iterator(); }
76 
77  };
78 
79  } // (END) Test data
80 
81 
82 
83 
84 
85 
86 
87  /***************************************************************************/
94  class IterTools_test : public Test
95  {
96 
97  typedef TestSource::iterator Iter;
98 
99 
100  virtual void
101  run (Arg arg)
102  {
103  if (0 < arg.size()) NUM_ELMS = lexical_cast<uint> (arg[1]);
104 
105  TestSource source(NUM_ELMS);
106 
107  pullOut (source.begin());
108  verifyComparisons (source.begin());
109 
110 
111  buildFilterIterator (source.begin());
112  Iter ii (source.begin());
113  ++++++ii;
114  buildFilterIterator (ii);
115  verify_filterExtension();
116  verify_filterRepetitions();
117 
118  buildWrappedSingleElement();
119 
120  buildTransformingIterator (source.begin());
121 
122  verifyPullLast(source.begin());
123  }
124 
125 
126 
127  template<class IT>
128  void
129  pullOut (IT const& ii)
130  {
131  for (IT iter(ii) ; iter; ++iter )
132  cout << "::" << *iter;
133  cout << endl;
134  }
135 
136 
137 
138  static bool takeAll (int) { return true; }
139  static bool takeOdd (int i) { return 0 != i % 2; }
140  static bool takeEve (int i) { return 0 == i % 2; }
141  static bool takeTrd (int i) { return 0 == i % 3; }
142 
143  void
144  buildFilterIterator (Iter const& ii)
145  {
146  pullOut (filterIterator (ii, takeAll)); // note: using the convenient builder function
147  pullOut (filterIterator (ii, takeEve));
148  pullOut (filterIterator (ii, takeOdd));
149 
150  FilterIter<Iter> all (ii, takeAll);
151  FilterIter<Iter> odd (ii, takeOdd);
152  verifyComparisons (all);
153  verifyComparisons (odd);
154 
155  while (++all && ++odd)
156  CHECK (all != odd);
157 
158  while (++all) { }
159  CHECK (isnil (odd));
160  CHECK (all == odd);
161  }
162 
163 
175  void
177  {
178  typedef vector<uint64_t> Src;
179  typedef Src::iterator SrcIter;
180  typedef RangeIter<SrcIter> SeqIter;
181  typedef ExtensibleFilterIter<SeqIter> FilteredSeq;
182 
183  Src src;
184  for (uint i=0; i < 3*NUM_ELMS; ++i)
185  src.push_back(i);
186 
187  SeqIter completeSequence (src.begin(), src.end());
188  FilteredSeq filterIter (completeSequence, takeAll);
189 
190  CHECK (!isnil (filterIter));
191  CHECK (0 == *filterIter);
192  ++filterIter;
193  CHECK (1 == *filterIter);
194 
195  filterIter.andFilter(takeEve);
196  CHECK (!isnil (filterIter));
197  CHECK (2 == *filterIter);
198  ++filterIter;
199  CHECK (4 == *filterIter);
200 
201  // sharpen the condition...
202  filterIter.andFilter(takeTrd);
203  CHECK (!isnil (filterIter));
204  CHECK (6 == *filterIter); // divisible by two and by three
205  ++filterIter;
206  CHECK (12 == *filterIter);
207 
208  verifyComparisons (filterIter);
209  pullOut (filterIter);
210 
211  // adding a disjunctive clause actually weakens the filter...
212  filterIter = {completeSequence, takeTrd};
213  CHECK (!isnil (filterIter));
214  CHECK (0 == *filterIter);
215  ++filterIter;
216  CHECK (3 == *filterIter);
217 
218  filterIter.orFilter(takeEve);
219  CHECK (3 == *filterIter);
220  ++filterIter;
221  CHECK (4 == *filterIter);
222  ++filterIter;
223  CHECK (6 == *filterIter);
224  verifyComparisons (filterIter);
225 
226  // flip filter logic
227  filterIter.flipFilter();
228  CHECK (7 == *filterIter); // not even and not divisible by three
229  ++filterIter;
230  CHECK (11 == *filterIter);
231  ++filterIter;
232  CHECK (13 == *filterIter);
233 
234  verifyComparisons (filterIter);
235  pullOut (filterIter);
236  }
237 
238 
243  void
245  {
246  vector<uint> numberz;
247  for (uint i=0; i<NUM_ELMS; ++i)
248  {
249  uint n = 1 + rand() % 100;
250  do numberz.push_back(i);
251  while (--n);
252  }
253  CHECK (NUM_ELMS < numberz.size(), "no repetition in test data??");
254 
255  typedef vector<uint>::iterator SrcIter;
256  typedef RangeIter<SrcIter> SeqIter;
257  typedef FilterIter<SeqIter> FilteredSeq;
258 
259  SeqIter completeSequence (numberz.begin(), numberz.end());
260  FilteredSeq filtered = filterRepetitions (completeSequence);
261 
262  uint num=0;
263  for (; num<NUM_ELMS && !isnil(filtered);
264  ++num,
265  ++filtered
266  )
267  CHECK (num == *filtered);
268 
269  CHECK (num == NUM_ELMS && isnil(filtered));
270  }
271 
272 
273 
275  void
277  {
278  uint i{12};
279 
280  auto i1 = singleValIterator(12);
281  auto i2 = singleValIterator( i);
282  auto i3 = singleValIterator(&i);
283 
284  CHECK (not isnil(i1));
285  CHECK (not isnil(i2));
286  CHECK (not isnil(i3));
287  CHECK (12 == *i1);
288  CHECK (12 == *i2);
289  CHECK (12 == **i3);
290 
291  i = 23;
292  CHECK (12 == *i1);
293  CHECK (23 == *i2);
294  CHECK (23 == **i3);
295 
296  ++i1;
297  ++i2;
298  ++i3;
299  CHECK (isnil(i1));
300  CHECK (isnil(i2));
301  CHECK (isnil(i3));
302  VERIFY_ERROR (ITER_EXHAUST, *i1 );
303  VERIFY_ERROR (ITER_EXHAUST, *i2 );
304  VERIFY_ERROR (ITER_EXHAUST, *i3 );
305 
306  // assignable as any iterator..
307  i1 = singleValIterator(13);
308  CHECK (13 == *i1);
309 
310  i1 = SingleValIter<int>{};
311  CHECK (isnil(i1));
312  }
313 
314 
315 
316  static ulong addTwo (int i) { return i+2; }
317  static int negate (int i) { return -i; }
318  static int idFunc (int i) { return i; }
319 
320  void
321  buildTransformingIterator (Iter const& ii)
322  {
323  pullOut (transformIterator(ii, idFunc));
324  pullOut (transformIterator(ii, negate));
325  pullOut (transformIterator(ii, addTwo)); // note: changing output type to unsigned
326 
327  TransformIter<Iter, int> idi (ii, idFunc);
328  TransformIter<Iter, int> neg (ii, negate);
329  verifyComparisons (idi);
330  verifyComparisons (neg);
331 
332  CHECK (idi);
333  CHECK (neg);
334  for ( ;idi&&neg;
335  ++idi,++neg)
336  CHECK (idi != neg);
337 
338  CHECK (!idi && !neg);
339  CHECK (idi == neg);
340  }
341 
342 
343 
344 
345 
348  template<class IT>
349  void
350  verifyComparisons (IT const& ii)
351  {
352  IT i1(ii);
353  IT i2(ii);
354  IT iN;
355  CHECK ( isnil (iN));
356  CHECK (!isnil (i1));
357  CHECK (!isnil (i2));
358 
359  CHECK (i1 == i2); CHECK (i2 == i1);
360  CHECK (i1 != iN); CHECK (iN != i1);
361  CHECK (i2 != iN); CHECK (iN != i2);
362 
363  ++i1;
364  CHECK (i1 != i2);
365  CHECK (i1 != iN);
366 
367  ++i2;
368  CHECK (i1 == i2);
369  CHECK (i1 != iN);
370  CHECK (i2 != iN);
371 
372  while (++i1) { }
373  CHECK (isnil(i1));
374  CHECK (i1 != i2);
375  CHECK (i1 == iN);
376 
377  while (++i2) { }
378  CHECK (isnil(i2));
379  CHECK (i2 == i1);
380  CHECK (i2 == iN);
381  }
382 
383 
384  void
385  verifyPullLast(Iter const& ii)
386  {
387  Iter::value_type lastElm = pull_last (ii);
388  CHECK (1 == lastElm); // TestSource holds a decreasing sequence of numbers ending with 1
389 
390  Iter emptyIterator;
391  CHECK (isnil (emptyIterator));
392 
393  VERIFY_ERROR (ITER_EXHAUST, pull_last(emptyIterator) );
394  }
395  };
396 
397  LAUNCHER (IterTools_test, "unit common");
398 
399 
400 }} // namespace lib::test
401 
Iterator tool filtering pulled data according to a predicate.
Definition: itertools.hpp:346
Automatically use custom string conversion in C++ stream output.
Definition: run.hpp:49
#define VERIFY_ERROR(ERROR_ID, ERRONEOUS_STATEMENT)
Macro to verify a statement indeed raises an exception.
Additional capabilities for FilterIter, allowing to extend the filter condition underway.
Definition: itertools.hpp:419
Implementation namespace for support and library code.
Simple test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
Iterator tool treating pulled data by a custom transformation (function)
Definition: itertools.hpp:763
void for_each(CON const &elements, FUN function, P1 &&bind1, ARGS &&...args)
Accept binding for arbitrary function arguments.
A collection of frequently used helper functions to support unit testing.
auto singleValIterator(VAL &&something)
Build a SingleValIter: convenience free function shortcut, to pick up just any value and wrap it as L...
Definition: itertools.hpp:664
void verifyComparisons(IT const &ii)
Helpers for working with iterators based on the pipeline model.
Pseudo-Iterator to yield just a single value.
Definition: itertools.hpp:635
Accessing a STL element range through a Lumiera forward iterator, An instance of this iterator adapte...
auto filterIterator(IT const &src, PRED filterPredicate)
Build a FilterIter: convenience free function shortcut, picking up the involved types automatically...
Definition: itertools.hpp:381
auto transformIterator(IT const &src, FUN processingFunc)
Build a TransformIter: convenience free function shortcut, picking up the involved types automaticall...
Definition: itertools.hpp:797
Perform operations "for each element" of a collection.
auto filterRepetitions(IT const &source)
filters away repeated values emitted by source iterator
Definition: itertools.hpp:855