source: trunk/test/iterator_test.cc @ 1487

Last change on this file since 1487 was 1487, checked in by Jari Häkkinen, 15 years ago

Addresses #436. GPL license copy reference should also be updated.

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