source: NonGTP/Boost/boost/iterator/new_iterator_tests.hpp @ 857

Revision 857, 7.3 KB checked in by igarcia, 19 years ago (diff)
Line 
1#ifndef BOOST_NEW_ITERATOR_TESTS_HPP
2# define BOOST_NEW_ITERATOR_TESTS_HPP
3
4//
5// Copyright (c) David Abrahams 2001.
6// Copyright (c) Jeremy Siek 2001-2003.
7// Copyright (c) Thomas Witt 2002.
8//
9// Use, modification and distribution is subject to the
10// Boost Software License, Version 1.0.
11// (See accompanying file LICENSE_1_0.txt or copy at
12// http://www.boost.org/LICENSE_1_0.txt)
13//
14
15// This is meant to be the beginnings of a comprehensive, generic
16// test suite for STL concepts such as iterators and containers.
17//
18// Revision History:
19// 28 Oct 2002  Started update for new iterator categories
20//              (Jeremy Siek)
21// 28 Apr 2002  Fixed input iterator requirements.
22//              For a == b a++ == b++ is no longer required.
23//              See 24.1.1/3 for details.
24//              (Thomas Witt)
25// 08 Feb 2001  Fixed bidirectional iterator test so that
26//              --i is no longer a precondition.
27//              (Jeremy Siek)
28// 04 Feb 2001  Added lvalue test, corrected preconditions
29//              (David Abrahams)
30
31# include <iterator>
32# include <assert.h>
33# include <boost/type_traits.hpp>
34# include <boost/static_assert.hpp>
35# include <boost/concept_archetype.hpp> // for detail::dummy_constructor
36# include <boost/detail/iterator.hpp>
37# include <boost/pending/iterator_tests.hpp>
38# include <boost/iterator/is_readable_iterator.hpp>
39# include <boost/iterator/is_lvalue_iterator.hpp>
40
41# include <boost/iterator/detail/config_def.hpp>
42# include <boost/detail/is_incrementable.hpp>
43
44namespace boost {
45
46
47// Do separate tests for *i++ so we can treat, e.g., smart pointers,
48// as readable and/or writable iterators.
49template <class Iterator, class T>
50void readable_iterator_traversal_test(Iterator i1, T v, mpl::true_)
51{
52    T v2(*i1++);
53    assert(v == v2);
54}
55
56template <class Iterator, class T>
57void readable_iterator_traversal_test(const Iterator i1, T v, mpl::false_)
58{}
59
60template <class Iterator, class T>
61void writable_iterator_traversal_test(Iterator i1, T v, mpl::true_)
62{
63    ++i1;  // we just wrote into that position
64    *i1++ = v;
65    Iterator x(i1++);
66    (void)x;
67}
68
69template <class Iterator, class T>
70void writable_iterator_traversal_test(const Iterator i1, T v, mpl::false_)
71{}
72
73
74// Preconditions: *i == v
75template <class Iterator, class T>
76void readable_iterator_test(const Iterator i1, T v)
77{
78  Iterator i2(i1); // Copy Constructible
79  typedef typename detail::iterator_traits<Iterator>::reference ref_t;
80  ref_t r1 = *i1;
81  ref_t r2 = *i2;
82  T v1 = r1;
83  T v2 = r2;
84  assert(v1 == v);
85  assert(v2 == v);
86
87# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
88  readable_iterator_traversal_test(i1, v, detail::is_postfix_incrementable<Iterator>());
89     
90  // I think we don't really need this as it checks the same things as
91  // the above code.
92  BOOST_STATIC_ASSERT(is_readable_iterator<Iterator>::value);
93# endif
94}
95
96template <class Iterator, class T>
97void writable_iterator_test(Iterator i, T v, T v2)
98{
99  Iterator i2(i); // Copy Constructible
100  *i2 = v;
101
102# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
103  writable_iterator_traversal_test(
104      i, v2, mpl::and_<
105          detail::is_incrementable<Iterator>
106        , detail::is_postfix_incrementable<Iterator>
107      >());
108# endif
109}
110
111template <class Iterator>
112void swappable_iterator_test(Iterator i, Iterator j)
113{
114  Iterator i2(i), j2(j);
115  typename detail::iterator_traits<Iterator>::value_type bi = *i, bj = *j;
116  iter_swap(i2, j2);
117  typename detail::iterator_traits<Iterator>::value_type ai = *i, aj = *j;
118  assert(bi == aj && bj == ai);
119}
120
121template <class Iterator, class T>
122void constant_lvalue_iterator_test(Iterator i, T v1)
123{
124  Iterator i2(i);
125  typedef typename detail::iterator_traits<Iterator>::value_type value_type;
126  typedef typename detail::iterator_traits<Iterator>::reference reference;
127  BOOST_STATIC_ASSERT((is_same<const value_type&, reference>::value));
128  const T& v2 = *i2;
129  assert(v1 == v2);
130# ifndef BOOST_NO_LVALUE_RETURN_DETECTION
131  BOOST_STATIC_ASSERT(is_lvalue_iterator<Iterator>::value);
132  BOOST_STATIC_ASSERT(!is_non_const_lvalue_iterator<Iterator>::value);
133# endif
134}
135
136template <class Iterator, class T>
137void non_const_lvalue_iterator_test(Iterator i, T v1, T v2)
138{
139  Iterator i2(i);
140  typedef typename detail::iterator_traits<Iterator>::value_type value_type;
141  typedef typename detail::iterator_traits<Iterator>::reference reference;
142  BOOST_STATIC_ASSERT((is_same<value_type&, reference>::value));
143  T& v3 = *i2;
144  assert(v1 == v3);
145 
146  // A non-const lvalue iterator is not neccessarily writable, but we
147  // are assuming the value_type is assignable here
148  *i = v2;
149 
150  T& v4 = *i2;
151  assert(v2 == v4);
152# ifndef BOOST_NO_LVALUE_RETURN_DETECTION
153  BOOST_STATIC_ASSERT(is_lvalue_iterator<Iterator>::value);
154  BOOST_STATIC_ASSERT(is_non_const_lvalue_iterator<Iterator>::value);
155# endif
156}
157
158template <class Iterator, class T>
159void forward_readable_iterator_test(Iterator i, Iterator j, T val1, T val2)
160{
161  Iterator i2;
162  Iterator i3(i);
163  i2 = i;
164  assert(i2 == i3);
165  assert(i != j);
166  assert(i2 != j);
167  readable_iterator_test(i, val1);
168  readable_iterator_test(i2, val1);
169  readable_iterator_test(i3, val1);
170
171  assert(i == i2++);
172  assert(i != ++i3);
173
174  readable_iterator_test(i2, val2);
175  readable_iterator_test(i3, val2);
176
177  readable_iterator_test(i, val1);
178}
179
180template <class Iterator, class T>
181void forward_swappable_iterator_test(Iterator i, Iterator j, T val1, T val2)
182{
183  forward_readable_iterator_test(i, j, val1, val2);
184  Iterator i2 = i;
185  ++i2;
186  swappable_iterator_test(i, i2);
187}
188
189// bidirectional
190// Preconditions: *i == v1, *++i == v2
191template <class Iterator, class T>
192void bidirectional_readable_iterator_test(Iterator i, T v1, T v2)
193{
194  Iterator j(i);
195  ++j;
196  forward_readable_iterator_test(i, j, v1, v2);
197  ++i;
198
199  Iterator i1 = i, i2 = i;
200
201  assert(i == i1--);
202  assert(i != --i2);
203
204  readable_iterator_test(i, v2);
205  readable_iterator_test(i1, v1);
206  readable_iterator_test(i2, v1);
207
208  --i;
209  assert(i == i1);
210  assert(i == i2);
211  ++i1;
212  ++i2;
213
214  readable_iterator_test(i, v1);
215  readable_iterator_test(i1, v2);
216  readable_iterator_test(i2, v2);
217}
218
219// random access
220// Preconditions: [i,i+N) is a valid range
221template <class Iterator, class TrueVals>
222void random_access_readable_iterator_test(Iterator i, int N, TrueVals vals)
223{
224  bidirectional_readable_iterator_test(i, vals[0], vals[1]);
225  const Iterator j = i;
226  int c;
227
228  for (c = 0; c < N-1; ++c)
229  {
230    assert(i == j + c);
231    assert(*i == vals[c]);
232    typename detail::iterator_traits<Iterator>::value_type x = j[c];
233    assert(*i == x);
234    assert(*i == *(j + c));
235    assert(*i == *(c + j));
236    ++i;
237    assert(i > j);
238    assert(i >= j);
239    assert(j <= i);
240    assert(j < i);
241  }
242
243  Iterator k = j + N - 1;
244  for (c = 0; c < N-1; ++c)
245  {
246    assert(i == k - c);
247    assert(*i == vals[N - 1 - c]);
248    typename detail::iterator_traits<Iterator>::value_type x = j[N - 1 - c];
249    assert(*i == x);
250    Iterator q = k - c;
251    assert(*i == *q);
252    assert(i > j);
253    assert(i >= j);
254    assert(j <= i);
255    assert(j < i);
256    --i;
257  }
258}
259
260} // namespace boost
261
262# include <boost/iterator/detail/config_undef.hpp>
263
264#endif // BOOST_NEW_ITERATOR_TESTS_HPP
Note: See TracBrowser for help on using the repository browser.