source: trunk/test/iterator_test.cc @ 1538

Last change on this file since 1538 was 1538, checked in by Peter, 13 years ago

refs #368 - added several tests. Left now is to add specializations for trait classes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 14.4 KB
Line 
1// $Id: iterator_test.cc 1538 2008-09-27 04:27:55Z peter $
2
3/*
4  Copyright (C) 2007, 2008 Jari Häkkinen, Peter Johansson, Markus Ringnér
5
6  This file is part of the yat library, http://dev.thep.lu.se/yat
7
8  The yat library is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 3 of the
11  License, or (at your option) any later version.
12
13  The yat library is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17
18  You should have received a copy of the GNU General Public License
19  along with yat. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22#include "Suite.h"
23
24#include "yat/classifier/DataLookup1D.h"
25
26#include "yat/classifier/DataLookupWeighted1D.h"
27#include "yat/classifier/MatrixLookupWeighted.h"
28#include "yat/utility/Container2DIterator.h"
29#include "yat/utility/DataWeight.h"
30#include "yat/utility/DataIterator.h"
31#include "yat/utility/Matrix.h"
32#include "yat/utility/MatrixWeighted.h"
33#include "yat/utility/stl_utility.h"
34#include "yat/utility/Vector.h"
35#include "yat/utility/VectorView.h"
36#include "yat/utility/VectorConstView.h"
37#include "yat/utility/WeightedIterator.h"
38#include "yat/utility/WeightIterator.h"
39
40#include <boost/iterator/transform_iterator.hpp>
41
42#include <algorithm>
43#include <fstream>
44#include <iterator>
45#include <string>
46#include <vector>
47
48using namespace theplu::yat;
49
50void old_main(test::Suite&);
51
52template<typename Iterator>
53void is_weighted(Iterator, test::Suite&);
54
55bool is_weighted(utility::unweighted_iterator_tag x) { return false; } 
56bool is_weighted(utility::weighted_iterator_tag x) { return true; }
57
58void test_boost_util(test::Suite&);
59
60template<typename TrivialIterator>
61void test_trivial_iterator(const TrivialIterator&, test::Suite&);
62
63template<typename InputIterator>
64void test_input_iterator(InputIterator&, test::Suite&);
65
66template<typename OutputIterator>
67void test_output_iterator(OutputIterator&, test::Suite&);
68
69template<typename ForwardIterator>
70void test_forward_iterator(ForwardIterator, test::Suite&);
71
72template<typename BidirectionalIterator>
73void test_bidirectional_iterator(BidirectionalIterator, test::Suite&);
74
75template<typename RandomAccessIterator>
76void test_random_access_iterator(RandomAccessIterator, test::Suite&);
77
78void test_stride_iterator(test::Suite& suite);
79void test_weighted_iterator(test::Suite& suite);
80
81int main(int argc, char* argv[])
82{ 
83  test::Suite suite(argc, argv);
84  suite.err() << "testing iterator" << std::endl;
85
86  test_stride_iterator(suite);
87  old_main(suite);
88  test_boost_util(suite);
89  test_weighted_iterator(suite);
90  return suite.return_value();
91}
92 
93template<typename Iterator>
94void is_weighted(Iterator i, test::Suite& suite)
95{
96  suite.err() << "testing that iterator is unweighted... ";
97  typename utility::weighted_iterator_traits<Iterator>::type tag;
98  if (is_weighted(tag))
99    suite.err() << "ok.\n";
100  else {
101    suite.err() << "failed.\n";
102    suite.add(false);
103  }
104   
105}
106
107
108void old_main(test::Suite& suite)
109{
110  suite.err() << "testing utility::Vector::iterator" << std::endl;
111  utility::Vector vec(12);
112  classifier::DataLookup1D lookup(vec);
113  utility::Vector::iterator begin=vec.begin();
114  test_random_access_iterator(begin, suite);
115  // test iterator to const_iterator conversion
116  utility::Vector::const_iterator ci = vec.begin();
117  test_random_access_iterator(ci, suite);
118  ci = begin;
119  if (begin!=ci)
120    suite.add(false);
121
122  suite.err() << "sorting...";
123  utility::Vector::iterator end=vec.end();
124  std::sort(begin, end);
125  suite.err() << " sorting done\n";
126
127  suite.err() << "testing classifier::DataLookup1D::const_iterator" << std::endl;
128  classifier::DataLookup1D::const_iterator lbegin=lookup.begin();
129  classifier::DataLookup1D::const_iterator lend=lookup.end();
130  test_random_access_iterator(lbegin, suite);
131 
132  suite.err() << "copy from DataLookup1D to Vector" << std::endl;
133  std::copy(lbegin, lend, begin);
134  suite.err() << "copy from Vector to Vector" << std::endl;
135  std::copy(begin, end, begin);
136  suite.err() << "sort Vector" << std::endl;
137  std::sort(begin, end);
138
139  // test std algorithm on IteratorWeighted
140  utility::Matrix m(1,3,1);
141  m(0,1)=2.0;
142  utility::Matrix w(1,3,1);
143  classifier::MatrixLookupWeighted mw(m,w);
144  classifier::DataLookupWeighted1D aw(mw,0,true);
145  size_t nof1=std::count(aw.begin(),aw.end(),
146                         std::pair<double, double>(1.0, 1.0));
147  if(nof1!=2) {
148    suite.err() << "std algoritm with IteratorWeighted failed" << std::endl;
149    suite.add(false);
150  }
151  if (aw.begin()!=mw.begin_row(0))
152    suite.add(false);
153  if (aw.end()!=mw.end_row(0))
154    suite.add(false);
155  classifier::DataLookupWeighted1D aw2(mw,0,false);
156  if (aw2.begin()!=mw.begin_column(0))
157    suite.add(false);
158  if (aw2.end()!=mw.end_column(0))
159    suite.add(false);
160
161  utility::DataIterator<classifier::DataLookupWeighted1D::const_iterator> 
162    data_iter(aw2.begin());
163  suite.add(*data_iter == 1.0);
164  suite.add(*data_iterator(aw2.begin()) == 1.0);
165  std::vector<double> stl_vec(1,0);
166  utility::DataIterator<std::vector<double>::iterator> 
167    data_iter2(stl_vec.begin());
168  suite.add(*data_iter2 == 0.0);
169  *data_iter2 = 3.14;
170  suite.add(*data_iter2 == 3.14);
171  utility::WeightIterator<std::vector<double>::iterator> 
172    data_iter3(stl_vec.begin());
173  suite.add(*data_iter3 == 1.0);
174
175  // testing constness conversion
176  std::vector<double>::const_iterator c_iter(stl_vec.begin());
177  std::vector<double>::iterator iter(stl_vec.begin());
178  suite.add(iter==c_iter);
179  utility::DataIterator<std::vector<double>::const_iterator> 
180    data_iter4(c_iter);
181  utility::DataIterator<std::vector<double>::iterator> 
182    data_iter5(iter);
183  suite.add(data_iter2 == data_iter5);
184  suite.add(data_iter4 == data_iter5);
185  utility::StrideIterator<std::vector<double>::const_iterator> stride_ci(c_iter);
186  utility::StrideIterator<std::vector<double>::iterator> stride_i(iter);
187  suite.add(stride_ci==stride_i);
188  suite.add(stride_i==stride_ci);
189
190  utility::MatrixWeighted x_weighted(3,4);
191  x_weighted.begin();
192  *x_weighted.begin();
193  utility::DataWeight element = *x_weighted.begin();
194  *(x_weighted.begin()+1) = element;
195  double element_data = *data_iterator(x_weighted.begin());
196  suite.add(element_data==x_weighted.begin()->data());
197
198  classifier::MatrixLookup ml(m);
199  classifier::DataLookup1D dl1(ml,0,true);
200  if (dl1.begin()!=ml.begin_row(0))
201    suite.add(false);
202  if (dl1.end()!=ml.end_row(0))
203    suite.add(false);
204  classifier::DataLookup1D dl2(ml,0,false);
205  if (dl2.begin()!=ml.begin_column(0))
206    suite.add(false);
207  if (dl2.end()!=ml.end_column(0))
208    suite.add(false);
209
210}
211
212void test_boost_util(test::Suite& suite)
213{
214  bool ok_cached=suite.ok();
215  utility::PairFirst<std::pair<std::string, int> > pf;
216  std::pair<std::string, int> p("July", 31);
217  std::string str=pf(p);
218  suite.add(str=="July");
219  pf(p)="juli";
220  suite.add(pf(p)=="juli");
221
222  typedef utility::PairFirst<std::pair<const std::string, int> > PF2;
223  PF2 pf2;
224  std::pair<const std::string, int> p2("July", 31);
225  suite.add(pf2(p2)=="July");
226
227  utility::PairFirst<const std::pair<std::string, int> > pf3;
228  std::pair<std::string, int> p3("July", 31);
229  suite.add(pf3(p3)=="July");
230
231  utility::PairFirst<std::pair<std::string, const int> > pf4;
232  std::pair<std::string, const int> p4("July", 31);
233  suite.add(pf4(p4)=="July");
234  pf4(p4)="juli";
235  suite.add(pf4(p4)=="juli");
236
237  utility::PairFirst<std::pair<const std::string, const int> > pf5;
238  std::pair<const std::string, const int> p5("July", 31);
239  suite.add(pf5(p5)=="July");
240
241  typedef std::map<std::string, int> Map;
242  Map m;
243  m["July"]=31;
244  m["September"]=30;
245  m["June"]=30;
246  m["April"]=30;
247
248  boost::transform_iterator<PF2, Map::iterator> first_iterator(m.begin(), pf2);
249  boost::transform_iterator<PF2, Map::iterator> first_iterator_end(m.end(), pf2);
250  std::vector<std::string> vec(m.size());
251  std::copy(first_iterator, first_iterator_end, vec.begin());
252  std::vector<std::string> correct;
253  correct.push_back("April");
254  correct.push_back("July");
255  correct.push_back("June");
256  correct.push_back("September");
257  for (size_t i=0; i<vec.size(); ++i)
258    if (!suite.add(vec[i]==correct[i]))
259      suite.err() << "Error: vec[" << i << "] = " << vec[i] 
260                  << " expected " << correct[i] << "\n";
261
262  std::vector<std::string> vec2(m.size());
263  std::copy(utility::pair_first_iterator(m.begin()), 
264            utility::pair_first_iterator(m.end()),
265            vec2.begin());
266  suite.add(vec2==vec);
267 
268  std::vector<int> days;
269  days.resize(m.size());
270  std::copy(utility::pair_second_iterator(m.begin()), 
271            utility::pair_second_iterator(m.end()),
272            days.begin());
273  std::vector<int> days_correct;
274  days_correct.push_back(30);
275  days_correct.push_back(31);
276  days_correct.push_back(30);
277  days_correct.push_back(30);
278  for (size_t i=0; i<days.size(); ++i)
279    if (!suite.add(days[i]==days_correct[i]))
280      suite.err() << "Error: days[" << i << "] = " << days[i] 
281                  << " expected " << days_correct[i] << "\n";
282  days = std::vector<int>(days.size(), 0);
283  std::copy(days.begin(), days.end(), utility::pair_second_iterator(m.begin()));
284  for (std::map<std::string, int>::const_iterator i=m.begin(); i!=m.end(); ++i)
285    if (!suite.add(i->second==0) )
286      suite.err() << "Error: m[" << i->first << "] = " << i->second
287                  << " expected 0\n";
288
289  if (ok_cached && !suite.ok())
290    suite.err() << "test_bool_util failed" << std::endl;
291}
292
293template<typename TrivialIterator>
294void test_trivial_iterator(const TrivialIterator& iter, test::Suite& suite)
295{
296  suite.err() << "  testing Trivial features" << std::endl;
297  typename std::iterator_traits<TrivialIterator>::value_type tmp = *iter;
298  suite.add(tmp==*iter);
299}
300
301template<typename InputIterator>
302void test_input_iterator(InputIterator& iter, test::Suite& suite)
303{
304  test_trivial_iterator(iter, suite);
305  suite.err() << "  testing Input features" << std::endl;
306  // just to check compilation
307  if (false) {
308    ++iter;
309    iter++;
310  }
311}
312
313template<typename OutputIterator>
314void test_output_iterator(OutputIterator& iter, test::Suite& suite)
315{
316  test_trivial_iterator(iter, suite);
317  suite.err() << "  testing Output features" << std::endl;
318}
319
320template<typename ForwardIterator>
321void test_forward_iterator(ForwardIterator iter, test::Suite& suite)
322{
323  test_output_iterator(iter, suite);
324  test_input_iterator(iter, suite);
325  suite.err() << "  testing Forward features" << std::endl;
326
327  typename std::iterator_traits<ForwardIterator>::value_type tmp = *iter;
328  // testing multiple traversing is possible and does not change the data
329  ForwardIterator iter1 = iter;
330  ++iter1;
331  suite.add(iter!=iter1);
332  ForwardIterator iter2 = iter;
333  ++iter2;
334  suite.add(tmp==*iter);
335
336}
337
338template<typename BidirectionalIterator>
339void test_bidirectional_iterator(BidirectionalIterator iter, test::Suite& suite)
340{
341  test_forward_iterator(iter, suite);
342  bool ok_cached = suite.ok();
343  suite.err() << "  testing Bidirectional features" << std::endl;
344  const BidirectionalIterator i = iter;
345  BidirectionalIterator tmp = iter--;
346  suite.add(tmp==i);
347  ++iter;
348  tmp = --iter;
349  if (!suite.add(tmp==iter))
350    suite.err() << "operator-- failed" << std::endl;
351  suite.add(++tmp==i);
352  if (ok_cached && !suite.ok())
353    suite.err() << "failed" << std::endl;
354}
355
356template<typename RandomAccessIterator>
357void test_random_access_iterator(RandomAccessIterator iter, test::Suite& suite)
358{
359  test_bidirectional_iterator(iter, suite);
360  suite.err() << "  testing RandomAccess features" << std::endl;
361  bool ok_cached = suite.ok();
362  RandomAccessIterator iter2 = iter;
363  iter2 += 1;
364  iter2 -= 1;
365  RandomAccessIterator& iter3 = (iter2 += 1);
366  RandomAccessIterator& iter4 = (iter3 -= 1);
367  if (!suite.add(iter2 == iter4))
368    suite.err() << "operator-(int) failed" << std::endl;
369  suite.add(++iter2 == iter3);
370 
371  RandomAccessIterator iter5 = iter + 0;
372  RandomAccessIterator iter6 = 0 + iter;
373  suite.add(iter6 == iter5);
374
375  RandomAccessIterator iter7 = iter - 0;
376  suite.add(iter7 == iter);
377  suite.add(iter7 - iter == 0);
378  suite.add(! (iter7<iter));
379
380  typename RandomAccessIterator::value_type tmp = iter[0];
381  typename RandomAccessIterator::value_type tmp2 = *iter;
382  tmp = tmp; // avoid compiler warning
383  if (!suite.add(tmp == tmp2))
384    suite.err() << "operator[] failed" << std::endl;
385  if (!suite.add(iter[0] == *iter))
386    suite.err() << "operator[] failed" << std::endl;
387  if (ok_cached && !suite.ok())
388    suite.err() << "failed" << std::endl;
389}
390
391void test_stride_iterator(test::Suite& suite)
392{
393  suite.err() << "testing StrideIterator" << std::endl;
394  using utility::Vector;
395  Vector a(10);
396  // stride 2
397  utility::VectorConstView b(a, 0, 5, 2);
398  if (!suite.add(b.end()-b.begin()==5))
399    suite.err() << "ERROR: StrideIterator::operator- returned: " 
400                << b.end()-b.begin() 
401                << " expected 5\n";
402  utility::VectorView c(a, 0, 3, 2);
403  Vector::iterator begin = c.begin();
404  Vector::iterator end = c.end();
405  Vector::const_iterator cbegin = begin;
406  Vector::const_iterator cend = end;
407
408  if (!suite.add(c.size()==3))
409    suite.err() << "c.size() incorrect" << std::endl;
410  if (!suite.add(cend-cbegin == 3))
411    suite.err() << "cend-cbegin failed\n"; 
412}
413
414void test_weighted_iterator(test::Suite& suite)
415{
416  std::vector<double> vec(3,1);
417  typedef std::vector<double>::iterator Iter;
418  typedef utility::WeightedIterator<Iter, Iter> WIter;
419  WIter iter(vec.begin(), vec.begin());
420
421  utility::DataWeight tmp = *iter;
422
423  test_bidirectional_iterator(iter, suite);
424  test_random_access_iterator(iter, suite);
425  std::vector<double> data(vec.size());
426  std::vector<double> weight(vec.size());
427  WIter iter2(data.begin(), weight.begin());
428  utility::DataWeight tmp2(6.89, 0.79);
429  *iter2 = tmp2;
430  if (!suite.add(tmp2==*iter2))
431    suite.err() << "error: tmp2==*iter2" << std::endl;
432  utility::DataWeight tmp3(*iter2);
433  suite.add(suite.equal(tmp3.data(), tmp2.data()));
434  suite.add(suite.equal(tmp3.weight(), tmp2.weight()));
435  *iter2 = *iter;
436  if (!suite.add(*iter2 == *iter))
437    suite.err() << "error: *iter2 == *iter\n";
438  tmp = *iter2;
439  suite.add(suite.equal(tmp.data(), 1));
440  std::copy(iter, iter+3, iter2);
441  suite.add(suite.equal(vec.front(), 1));
442  suite.add(suite.equal(data.front(), 1));
443
444  suite.err() << "  testing const conversion\n";
445  typedef std::vector<double>::const_iterator const_Iter;
446  typedef utility::WeightedIterator<const_Iter, const_Iter> const_WIter;
447  const_WIter const_iter(vec.begin(), vec.begin());
448  const_iter = iter;
449 
450  suite.err() << "  testing assignment between different iterators\n";
451  const std::vector<double> const_vec(10, 10.7);
452  const_WIter const_iter2(const_vec.begin(), const_vec.begin());
453  utility::DataWeight tmp4;
454  tmp4 = *const_iter2;
455  *iter = *const_iter2;
456  suite.add(*iter==*const_iter2);
457  *iter = *const_iter;
458  suite.add(*iter==*const_iter);
459
460  double x=101;
461  utility::WeightedIterator<double*, double*> iter_p(&x, &x);
462  *iter_p = *iter;
463  suite.add(*iter_p==*iter); 
464}
Note: See TracBrowser for help on using the repository browser.