Lumiera  0.pre.03
»edit your freedom«
iter-adapter-stl-test.cpp
Go to the documentation of this file.
1 /*
2  IterAdapterSTL(Test) - building various custom iterators for a given container
3 
4  Copyright (C) Lumiera.org
5  2010, 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-coll.hpp"
31 #include "lib/format-cout.hpp"
32 #include "lib/util.hpp"
33 
34 #include "lib/iter-adapter-stl.hpp"
35 
36 #include <boost/lexical_cast.hpp>
37 #include <vector>
38 
39 
40 
41 namespace lib {
42 namespace test{
43 
44  using ::Test;
45  using boost::lexical_cast;
46  using util::isnil;
47 
48  namespace iter = lib::iter_stl;
49 
50 
53 #define TEST_ITER(_CTOR_, _ARG_) \
54  cout << STRINGIFY(_CTOR_) ;\
55  pullOut (_CTOR_ _ARG_) ;\
56  cout << endl;
57 
59 #define PRINT_FUNC(_F_NAME_, _F_TYPE_) \
60  cout << "-----"<<STRINGIFY(_F_NAME_)<<"---" << util::typeStr<_F_TYPE_>() << endl;
61 
62 
63  namespace {
64  uint NUM_ELMS = 10;
65  }
66 
67 
68 
69 
70 
71 
72 
73 
74  /********************************************************************/
91  class IterAdapterSTL_test : public Test
92  {
93 
94  virtual void
95  run (Arg arg)
96  {
97  if (0 < arg.size()) NUM_ELMS = lexical_cast<uint> (arg[1]);
98 
99  checkDistinctValIter();
100 
101  iterateMapKeyVal (getTestMap_int<MapII> (NUM_ELMS));
102  iterateMapKeyVal (getTestMap_int<HMapII> (NUM_ELMS));
103 
104  iterateMapKeyVal (getTestMultiMap_int<MMapII> (NUM_ELMS));
105  iterateMapKeyVal (getTestMultiMap_int<HMMapII> (NUM_ELMS));
106 
107  iterateValues4Key (getTestMultiMap_int<MMapII> (NUM_ELMS));
108  iterateValues4Key (getTestMultiMap_int<HMMapII> (NUM_ELMS));
109 
110  checkIteratorSnapshot();
111  }
112 
113 
114  template<class MAP>
115  void
116  iterateMapKeyVal (MAP const& map)
117  {
118  PRINT_FUNC (iterateMapKeyVal, MAP);
119 
120  TEST_ITER (iter::eachKey, (map));
121  TEST_ITER (iter::eachKey, (map.begin(), map.end()));
122  TEST_ITER (iter::eachVal, (map));
123  TEST_ITER (iter::eachVal, (map.begin(), map.end()));
124  TEST_ITER (iter::eachDistinctKey, (map));
125  }
126 
127 
128  template<class MMAP>
129  void
130  iterateValues4Key (MMAP const& mumap)
131  {
132  PRINT_FUNC (iterateValues4Key, MMAP);
133 
134  TEST_ITER (iter::eachValForKey, (mumap, 0));
135 
136  // non-existing key should yield empty iterator
137  CHECK (! iter::eachValForKey (mumap, NUM_ELMS));
138  }
139 
140 
141  void
142  checkDistinctValIter()
143  {
144  PRINT_FUNC (filter-distinct-values, VecI);
145 
146  VecI vec;
147  TEST_ITER(iter::eachDistinct, (vec));
148 
149  vec.push_back (1);
150  vec.push_back (1);
151  vec.push_back (1);
152  TEST_ITER(iter::eachDistinct, (vec));
153 
154  vec.push_back (2);
155  vec.push_back (3);
156  vec.push_back (3);
157  vec.push_back (1);
158  TEST_ITER(iter::eachDistinct, (vec));
159 
160  vec.push_back (1);
161  vec.push_back (1);
162  vec.push_back (1);
163  vec.push_back (1);
164  vec.push_back (1);
165  TEST_ITER(iter::eachDistinct, (vec));
166  }
167 
168 
169  void
170  checkIteratorSnapshot()
171  {
172  typedef VecI::iterator Iter;
173  typedef RangeIter<Iter> Range;
174  typedef iter::IterSnapshot<int> Snapshot;
175 
176  VecI vec = getTestSeq_int<VecI> (NUM_ELMS);
177  Snapshot capture1 (vec.begin(), vec.end());
178 
179  Range range_of_all (vec.begin(), vec.end());
180  Snapshot capture2 = iter::snapshot(range_of_all); // NOTE: when specifically taken this way,
181  CHECK (range_of_all); // snapshot doesn't affect given source iterator pos
182  CHECK (capture2); // (but WARNING, the IterSnapshot ctor itself is destructive)
183 
184  CHECK (vec.begin() == range_of_all.getPos());
185  CHECK (vec.end() == range_of_all.getEnd());
186  CHECK (!isnil (vec));
187 
188  // concurrent or intermittent modification
189  vec.clear();
190  CHECK (isnil (vec));
191  CHECK (vec.end() != range_of_all.getEnd()); // range_of_all is now corrupted
192 
193  CHECK (capture1); // ...but the snapshots remain unaffected
194  CHECK (capture2);
195  CHECK (capture1 == capture2); // can compare snapshots, based on actual contents
196 
197  vec.push_back(22);
198  vec.push_back(44);
199  Snapshot capture3 (vec.begin(), vec.end()); // take another snapshot from current contents
200  CHECK (capture3);
201  CHECK (capture3 != capture1);
202  CHECK (capture3 != capture2);
203 
204 
205  uint sum_should_be = (NUM_ELMS-1)*NUM_ELMS/2;
206 
207  CHECK (sum_should_be == sumAll (capture1));
208  CHECK (!capture1); // this one is exhausted now
209  CHECK ( capture2); // ...but the others are really independent
210  CHECK ( capture3);
211  CHECK (capture1 != capture2); // comparison includes the current position
212 
213  CHECK (sum_should_be == sumAll (capture2));
214  CHECK (!capture1);
215  CHECK (!capture2);
216  CHECK ( capture3);
217  CHECK (capture1 == capture2); // now again equal (both exhausted and equal contents)
218 
219  CHECK (22+44 == sumAll (capture3));
220  CHECK (!capture1);
221  CHECK (!capture2);
222  CHECK (!capture3);
223  CHECK (capture1 == capture2); // all exhausted iterators count as "equal"
224  CHECK (capture3 == capture1); // this ensures the idiom while(pos != end) works
225  CHECK (capture3 == capture2);
226  }
227 
228  template<class IT>
229  uint
230  sumAll (IT& it)
231  {
232  uint sum(0);
233  cout << "snapshot";
234  while (it)
235  {
236  cout << "-" << *it;
237  sum += *it;
238  ++it;
239  }
240  cout << endl;
241  return sum;
242  }
243  };
244 
245  LAUNCHER (IterAdapterSTL_test, "unit common");
246 
247 
248 }} // namespace lib::test
Automatically use custom string conversion in C++ stream output.
bool filter(Placement< DummyMO > const &candidate)
a filter predicate to pick some objects from a resultset.
Definition: run.hpp:49
#define PRINT_FUNC(_F_NAME_, _F_TYPE_)
print descriptive separator to STDOUT
Implementation namespace for support and library code.
Simple test class runner.
some bits of unit test helper code to fabricate collections with test data
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
#define TEST_ITER(_CTOR_, _ARG_)
test an iterator: create it by calling a constructor function and then pull out all contents and prin...
Accessing a STL element range through a Lumiera forward iterator, An instance of this iterator adapte...
materialised iterator contents.
Preconfigured adapters for some STL container standard usage situations.