source: trunk/test/iterator_test.cc @ 1490

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

fixes #440

The bug was introduced in trunk after 0.4 release, so it has never
seen daylight.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 12.3 KB
Line 
1// $Id: iterator_test.cc 1490 2008-09-11 22:10:26Z 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/DataIterator.h"
30#include "yat/utility/Matrix.h"
31#include "yat/utility/MatrixWeighted.h"
32#include "yat/utility/stl_utility.h"
33#include "yat/utility/Vector.h"
34#include "yat/utility/VectorView.h"
35#include "yat/utility/VectorConstView.h"
36#include "yat/utility/WeightIterator.h"
37
38#include <boost/iterator/transform_iterator.hpp>
39
40#include <algorithm>
41#include <fstream>
42#include <iterator>
43#include <string>
44#include <vector>
45
46using namespace theplu::yat;
47
48void old_main(test::Suite&);
49
50template<typename Iterator>
51void is_weighted(Iterator, test::Suite&);
52
53bool is_weighted(utility::unweighted_iterator_tag x) { return false; } 
54bool is_weighted(utility::weighted_iterator_tag x) { return true; }
55
56void test_boost_util(test::Suite&);
57
58template<typename TrivialIterator>
59void test_trivial_iterator(const TrivialIterator&, test::Suite&);
60
61template<typename InputIterator>
62void test_input_iterator(InputIterator&, test::Suite&);
63
64template<typename OutputIterator>
65void test_output_iterator(OutputIterator&, test::Suite&);
66
67template<typename ForwardIterator>
68void test_forward_iterator(ForwardIterator, test::Suite&);
69
70template<typename BidirectionalIterator>
71void test_bidirectional_iterator(BidirectionalIterator, test::Suite&);
72
73template<typename RandomAccessIterator>
74void test_random_access_iterator(RandomAccessIterator, test::Suite&);
75
76void test_stride_iterator(test::Suite& suite);
77
78int main(int argc, char* argv[])
79{ 
80  test::Suite suite(argc, argv);
81  suite.err() << "testing iterator" << std::endl;
82
83  test_stride_iterator(suite);
84  old_main(suite);
85  test_boost_util(suite);
86  return suite.return_value();
87}
88 
89template<typename Iterator>
90void is_weighted(Iterator i, test::Suite& suite)
91{
92  suite.err() << "testing that iterator is unweighted... ";
93  typename utility::weighted_iterator_traits<Iterator>::type tag;
94  if (is_weighted(tag))
95    suite.err() << "ok.\n";
96  else {
97    suite.err() << "failed.\n";
98    suite.add(false);
99  }
100   
101}
102
103
104void old_main(test::Suite& suite)
105{
106  suite.err() << "testing utility::Vector::iterator" << std::endl;
107  utility::Vector vec(12);
108  classifier::DataLookup1D lookup(vec);
109  utility::Vector::iterator begin=vec.begin();
110  test_random_access_iterator(begin, suite);
111  // test iterator to const_iterator conversion
112  utility::Vector::const_iterator ci = vec.begin();
113  test_random_access_iterator(ci, suite);
114  ci = begin;
115  if (begin!=ci)
116    suite.add(false);
117
118  suite.err() << "sorting...";
119  utility::Vector::iterator end=vec.end();
120  std::sort(begin, end);
121  suite.err() << " sorting done\n";
122
123  suite.err() << "testing classifier::DataLookup1D::const_iterator" << std::endl;
124  classifier::DataLookup1D::const_iterator lbegin=lookup.begin();
125  classifier::DataLookup1D::const_iterator lend=lookup.end();
126  test_random_access_iterator(lbegin, suite);
127 
128  suite.err() << "copy from DataLookup1D to Vector" << std::endl;
129  std::copy(lbegin, lend, begin);
130  suite.err() << "copy from Vector to Vector" << std::endl;
131  std::copy(begin, end, begin);
132  suite.err() << "sort Vector" << std::endl;
133  std::sort(begin, end);
134
135  // test std algorithm on IteratorWeighted
136  utility::Matrix m(1,3,1);
137  m(0,1)=2.0;
138  utility::Matrix w(1,3,1);
139  classifier::MatrixLookupWeighted mw(m,w);
140  classifier::DataLookupWeighted1D aw(mw,0,true);
141  size_t nof1=std::count(aw.begin(),aw.end(),
142                         std::pair<double, double>(1.0, 1.0));
143  if(nof1!=2) {
144    suite.err() << "std algoritm with IteratorWeighted failed" << std::endl;
145    suite.add(false);
146  }
147  if (aw.begin()!=mw.begin_row(0))
148    suite.add(false);
149  if (aw.end()!=mw.end_row(0))
150    suite.add(false);
151  classifier::DataLookupWeighted1D aw2(mw,0,false);
152  if (aw2.begin()!=mw.begin_column(0))
153    suite.add(false);
154  if (aw2.end()!=mw.end_column(0))
155    suite.add(false);
156
157  utility::DataIterator<classifier::DataLookupWeighted1D::const_iterator> 
158    data_iter(aw2.begin());
159  suite.add(*data_iter == 1.0);
160  suite.add(*data_iterator(aw2.begin()) == 1.0);
161  std::vector<double> stl_vec(1,0);
162  utility::DataIterator<std::vector<double>::iterator> 
163    data_iter2(stl_vec.begin());
164  suite.add(*data_iter2 == 0.0);
165  *data_iter2 = 3.14;
166  suite.add(*data_iter2 == 3.14);
167  utility::WeightIterator<std::vector<double>::iterator> 
168    data_iter3(stl_vec.begin());
169  suite.add(*data_iter3 == 1.0);
170
171  // testing constness conversion
172  std::vector<double>::const_iterator c_iter(stl_vec.begin());
173  std::vector<double>::iterator iter(stl_vec.begin());
174  suite.add(iter==c_iter);
175  utility::DataIterator<std::vector<double>::const_iterator> 
176    data_iter4(c_iter);
177  utility::DataIterator<std::vector<double>::iterator> 
178    data_iter5(iter);
179  suite.add(data_iter2 == data_iter5);
180  suite.add(data_iter4 == data_iter5);
181  utility::StrideIterator<std::vector<double>::const_iterator> stride_ci(c_iter);
182  utility::StrideIterator<std::vector<double>::iterator> stride_i(iter);
183  suite.add(stride_ci==stride_i);
184  suite.add(stride_i==stride_ci);
185
186  utility::MatrixWeighted x_weighted(3,4);
187  x_weighted.begin();
188  *x_weighted.begin();
189  utility::DataWeight element = *x_weighted.begin();
190  *(x_weighted.begin()+1) = element;
191  double element_data = *data_iterator(x_weighted.begin());
192  suite.add(element_data==x_weighted.begin()->data());
193
194  classifier::MatrixLookup ml(m);
195  classifier::DataLookup1D dl1(ml,0,true);
196  if (dl1.begin()!=ml.begin_row(0))
197    suite.add(false);
198  if (dl1.end()!=ml.end_row(0))
199    suite.add(false);
200  classifier::DataLookup1D dl2(ml,0,false);
201  if (dl2.begin()!=ml.begin_column(0))
202    suite.add(false);
203  if (dl2.end()!=ml.end_column(0))
204    suite.add(false);
205
206}
207
208void test_boost_util(test::Suite& suite)
209{
210  bool ok_cached=suite.ok();
211  utility::PairFirst<std::pair<std::string, int> > pf;
212  std::pair<std::string, int> p("July", 31);
213  std::string str=pf(p);
214  suite.add(str=="July");
215  pf(p)="juli";
216  suite.add(pf(p)=="juli");
217
218  typedef utility::PairFirst<std::pair<const std::string, int> > PF2;
219  PF2 pf2;
220  std::pair<const std::string, int> p2("July", 31);
221  suite.add(pf2(p2)=="July");
222
223  utility::PairFirst<const std::pair<std::string, int> > pf3;
224  std::pair<std::string, int> p3("July", 31);
225  suite.add(pf3(p3)=="July");
226
227  utility::PairFirst<std::pair<std::string, const int> > pf4;
228  std::pair<std::string, const int> p4("July", 31);
229  suite.add(pf4(p4)=="July");
230  pf4(p4)="juli";
231  suite.add(pf4(p4)=="juli");
232
233  utility::PairFirst<std::pair<const std::string, const int> > pf5;
234  std::pair<const std::string, const int> p5("July", 31);
235  suite.add(pf5(p5)=="July");
236
237  typedef std::map<std::string, int> Map;
238  Map m;
239  m["July"]=31;
240  m["September"]=30;
241  m["June"]=30;
242  m["April"]=30;
243
244  boost::transform_iterator<PF2, Map::iterator> first_iterator(m.begin(), pf2);
245  boost::transform_iterator<PF2, Map::iterator> first_iterator_end(m.end(), pf2);
246  std::vector<std::string> vec(m.size());
247  std::copy(first_iterator, first_iterator_end, vec.begin());
248  std::vector<std::string> correct;
249  correct.push_back("April");
250  correct.push_back("July");
251  correct.push_back("June");
252  correct.push_back("September");
253  for (size_t i=0; i<vec.size(); ++i)
254    if (!suite.add(vec[i]==correct[i]))
255      suite.err() << "Error: vec[" << i << "] = " << vec[i] 
256                  << " expected " << correct[i] << "\n";
257
258  std::vector<std::string> vec2(m.size());
259  std::copy(utility::pair_first_iterator(m.begin()), 
260            utility::pair_first_iterator(m.end()),
261            vec2.begin());
262  suite.add(vec2==vec);
263 
264  std::vector<int> days;
265  days.resize(m.size());
266  std::copy(utility::pair_second_iterator(m.begin()), 
267            utility::pair_second_iterator(m.end()),
268            days.begin());
269  std::vector<int> days_correct;
270  days_correct.push_back(30);
271  days_correct.push_back(31);
272  days_correct.push_back(30);
273  days_correct.push_back(30);
274  for (size_t i=0; i<days.size(); ++i)
275    if (!suite.add(days[i]==days_correct[i]))
276      suite.err() << "Error: days[" << i << "] = " << days[i] 
277                  << " expected " << days_correct[i] << "\n";
278  days = std::vector<int>(days.size(), 0);
279  std::copy(days.begin(), days.end(), utility::pair_second_iterator(m.begin()));
280  for (std::map<std::string, int>::const_iterator i=m.begin(); i!=m.end(); ++i)
281    if (!suite.add(i->second==0) )
282      suite.err() << "Error: m[" << i->first << "] = " << i->second
283                  << " expected 0\n";
284
285  if (ok_cached && !suite.ok())
286    suite.err() << "test_bool_util failed" << std::endl;
287}
288
289template<typename TrivialIterator>
290void test_trivial_iterator(const TrivialIterator& iter, test::Suite& suite)
291{
292  suite.err() << "  testing Trivial features" << std::endl;
293  typename std::iterator_traits<TrivialIterator>::value_type tmp = *iter;
294  suite.add(tmp==*iter);
295}
296
297template<typename InputIterator>
298void test_input_iterator(InputIterator& iter, test::Suite& suite)
299{
300  test_trivial_iterator(iter, suite);
301  suite.err() << "  testing Input features" << std::endl;
302  // just to check compilation
303  if (false) {
304    ++iter;
305    iter++;
306  }
307}
308
309template<typename OutputIterator>
310void test_output_iterator(OutputIterator& iter, test::Suite& suite)
311{
312  test_trivial_iterator(iter, suite);
313  suite.err() << "  testing Output features" << std::endl;
314}
315
316template<typename ForwardIterator>
317void test_forward_iterator(ForwardIterator iter, test::Suite& suite)
318{
319  test_output_iterator(iter, suite);
320  test_input_iterator(iter, suite);
321  suite.err() << "  testing Forward features" << std::endl;
322
323  typename std::iterator_traits<ForwardIterator>::value_type tmp = *iter;
324  // testing multiple traversing is possible and does not change the data
325  ForwardIterator iter1 = iter;
326  ++iter1;
327  suite.add(iter!=iter1);
328  ForwardIterator iter2 = iter;
329  ++iter2;
330  suite.add(tmp==*iter);
331
332}
333
334template<typename BidirectionalIterator>
335void test_bidirectional_iterator(BidirectionalIterator iter, test::Suite& suite)
336{
337  test_forward_iterator(iter, suite);
338  bool ok_cached = suite.ok();
339  suite.err() << "  testing Bidirectional features" << std::endl;
340  const BidirectionalIterator i = iter;
341  BidirectionalIterator tmp = iter--;
342  suite.add(tmp==i);
343  ++iter;
344  tmp = --iter;
345  if (!suite.add(tmp==iter))
346    suite.err() << "operator-- failed" << std::endl;
347  suite.add(++tmp==i);
348  if (ok_cached && !suite.ok())
349    suite.err() << "failed" << std::endl;
350}
351
352template<typename RandomAccessIterator>
353void test_random_access_iterator(RandomAccessIterator iter, test::Suite& suite)
354{
355  test_bidirectional_iterator(iter, suite);
356  suite.err() << "  testing RandomAccess features" << std::endl;
357  bool ok_cached = suite.ok();
358  RandomAccessIterator iter2 = iter;
359  iter2 += 1;
360  iter2 -= 1;
361  RandomAccessIterator& iter3 = (iter2 += 1);
362  RandomAccessIterator& iter4 = (iter3 -= 1);
363  if (!suite.add(iter2 == iter4))
364    suite.err() << "operator-(int) failed" << std::endl;
365  suite.add(++iter2 == iter3);
366 
367  RandomAccessIterator iter5 = iter + 0;
368  RandomAccessIterator iter6 = 0 + iter;
369  suite.add(iter6 == iter5);
370
371  RandomAccessIterator iter7 = iter - 0;
372  suite.add(iter7 == iter);
373  suite.add(iter7 - iter == 0);
374  suite.add(! (iter7<iter));
375
376  if (!suite.add(iter[0] == *iter))
377    suite.err() << "operator[] failed" << std::endl;
378  if (ok_cached && !suite.ok())
379    suite.err() << "failed" << std::endl;
380}
381
382void test_stride_iterator(test::Suite& suite)
383{
384  suite.err() << "testing StrideIterator" << std::endl;
385  using utility::Vector;
386  Vector a(10);
387  // stride 2
388  utility::VectorConstView b(a, 0, 5, 2);
389  if (!suite.add(b.end()-b.begin()==5))
390    suite.err() << "ERROR: StrideIterator::operator- returned: " 
391                << b.end()-b.begin() 
392                << " expected 5\n";
393  utility::VectorView c(a, 0, 3, 2);
394  Vector::iterator begin = c.begin();
395  Vector::iterator end = c.end();
396  Vector::const_iterator cbegin = begin;
397  Vector::const_iterator cend = end;
398
399  if (!suite.add(c.size()==3))
400    suite.err() << "c.size() incorrect" << std::endl;
401  if (!suite.add(cend-cbegin == 3))
402    suite.err() << "cend-cbegin failed\n"; 
403}
Note: See TracBrowser for help on using the repository browser.