source: trunk/test/iterator_test.cc @ 1788

Last change on this file since 1788 was 1788, checked in by Peter, 12 years ago

Changed MatrixLookup::operator() to return const double& rather than double. Fixes #488

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