source: trunk/test/iterator_test.cc @ 1532

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

refs #368 - const version is now working

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