source: trunk/test/iterator_test.cc @ 1797

Last change on this file since 1797 was 1797, checked in by Peter, 14 years ago

updating copyright statements

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