fix doc example typo
[boost.git] / boost / pending / iterator_tests.hpp
blobdd5fe2ddd6a52f6cc2a50a8c26648ca85b487c90
1 // Copyright David Abrahams and Jeremy Siek 2003.
2 // Distributed under the Boost Software License, Version 1.0. (See
3 // accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
5 #ifndef BOOST_ITERATOR_TESTS_HPP
6 # define BOOST_ITERATOR_TESTS_HPP
8 // This is meant to be the beginnings of a comprehensive, generic
9 // test suite for STL concepts such as iterators and containers.
11 // Revision History:
12 // 28 Apr 2002 Fixed input iterator requirements.
13 // For a == b a++ == b++ is no longer required.
14 // See 24.1.1/3 for details.
15 // (Thomas Witt)
16 // 08 Feb 2001 Fixed bidirectional iterator test so that
17 // --i is no longer a precondition.
18 // (Jeremy Siek)
19 // 04 Feb 2001 Added lvalue test, corrected preconditions
20 // (David Abrahams)
22 # include <iterator>
23 # include <assert.h>
24 # include <boost/type_traits.hpp>
25 # include <boost/static_assert.hpp>
26 # include <boost/concept_archetype.hpp> // for detail::dummy_constructor
27 # include <boost/implicit_cast.hpp>
28 # include <boost/type_traits/broken_compiler_spec.hpp>
30 namespace boost {
32 // use this for the value type
33 struct dummyT {
34 dummyT() { }
35 dummyT(detail::dummy_constructor) { }
36 dummyT(int x) : m_x(x) { }
37 int foo() const { return m_x; }
38 bool operator==(const dummyT& d) const { return m_x == d.m_x; }
39 int m_x;
44 BOOST_TT_BROKEN_COMPILER_SPEC(boost::dummyT)
46 namespace boost {
48 // Tests whether type Iterator satisfies the requirements for a
49 // TrivialIterator.
50 // Preconditions: i != j, *i == val
51 template <class Iterator, class T>
52 void trivial_iterator_test(const Iterator i, const Iterator j, T val)
54 Iterator k;
55 assert(i == i);
56 assert(j == j);
57 assert(i != j);
58 #ifdef BOOST_NO_STD_ITERATOR_TRAITS
59 T v = *i;
60 #else
61 typename std::iterator_traits<Iterator>::value_type v = *i;
62 #endif
63 assert(v == val);
64 #if 0
65 // hmm, this will give a warning for transform_iterator... perhaps
66 // this should be separated out into a stand-alone test since there
67 // are several situations where it can't be used, like for
68 // integer_range::iterator.
69 assert(v == i->foo());
70 #endif
71 k = i;
72 assert(k == k);
73 assert(k == i);
74 assert(k != j);
75 assert(*k == val);
79 // Preconditions: i != j
80 template <class Iterator, class T>
81 void mutable_trivial_iterator_test(const Iterator i, const Iterator j, T val)
83 *i = val;
84 trivial_iterator_test(i, j, val);
88 // Preconditions: *i == v1, *++i == v2
89 template <class Iterator, class T>
90 void input_iterator_test(Iterator i, T v1, T v2)
92 Iterator i1(i);
94 assert(i == i1);
95 assert(!(i != i1));
97 // I can see no generic way to create an input iterator
98 // that is in the domain of== of i and != i.
99 // The following works for istream_iterator but is not
100 // guaranteed to work for arbitrary input iterators.
102 // Iterator i2;
104 // assert(i != i2);
105 // assert(!(i == i2));
107 assert(*i1 == v1);
108 assert(*i == v1);
110 // we cannot test for equivalence of (void)++i & (void)i++
111 // as i is only guaranteed to be single pass.
112 assert(*i++ == v1);
114 i1 = i;
116 assert(i == i1);
117 assert(!(i != i1));
119 assert(*i1 == v2);
120 assert(*i == v2);
122 // i is dereferencable, so it must be incrementable.
123 ++i;
125 // how to test for operator-> ?
128 // how to test output iterator?
131 template <bool is_pointer> struct lvalue_test
133 template <class Iterator> static void check(Iterator)
135 # ifndef BOOST_NO_STD_ITERATOR_TRAITS
136 typedef typename std::iterator_traits<Iterator>::reference reference;
137 typedef typename std::iterator_traits<Iterator>::value_type value_type;
138 # else
139 typedef typename Iterator::reference reference;
140 typedef typename Iterator::value_type value_type;
141 # endif
142 BOOST_STATIC_ASSERT(boost::is_reference<reference>::value);
143 BOOST_STATIC_ASSERT((boost::is_same<reference,value_type&>::value
144 || boost::is_same<reference,const value_type&>::value
149 # ifdef BOOST_NO_STD_ITERATOR_TRAITS
150 template <> struct lvalue_test<true> {
151 template <class T> static void check(T) {}
153 #endif
155 template <class Iterator, class T>
156 void forward_iterator_test(Iterator i, T v1, T v2)
158 input_iterator_test(i, v1, v2);
160 Iterator i1 = i, i2 = i;
162 assert(i == i1++);
163 assert(i != ++i2);
165 trivial_iterator_test(i, i1, v1);
166 trivial_iterator_test(i, i2, v1);
168 ++i;
169 assert(i == i1);
170 assert(i == i2);
171 ++i1;
172 ++i2;
174 trivial_iterator_test(i, i1, v2);
175 trivial_iterator_test(i, i2, v2);
177 // borland doesn't allow non-type template parameters
178 # if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551)
179 lvalue_test<(boost::is_pointer<Iterator>::value)>::check(i);
180 #endif
183 // Preconditions: *i == v1, *++i == v2
184 template <class Iterator, class T>
185 void bidirectional_iterator_test(Iterator i, T v1, T v2)
187 forward_iterator_test(i, v1, v2);
188 ++i;
190 Iterator i1 = i, i2 = i;
192 assert(i == i1--);
193 assert(i != --i2);
195 trivial_iterator_test(i, i1, v2);
196 trivial_iterator_test(i, i2, v2);
198 --i;
199 assert(i == i1);
200 assert(i == i2);
201 ++i1;
202 ++i2;
204 trivial_iterator_test(i, i1, v1);
205 trivial_iterator_test(i, i2, v1);
208 // mutable_bidirectional_iterator_test
210 template <class U> struct undefined;
212 // Preconditions: [i,i+N) is a valid range
213 template <class Iterator, class TrueVals>
214 void random_access_iterator_test(Iterator i, int N, TrueVals vals)
216 bidirectional_iterator_test(i, vals[0], vals[1]);
217 const Iterator j = i;
218 int c;
220 typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
222 for (c = 0; c < N-1; ++c) {
223 assert(i == j + c);
224 assert(*i == vals[c]);
225 assert(*i == boost::implicit_cast<value_type>(j[c]));
226 assert(*i == *(j + c));
227 assert(*i == *(c + j));
228 ++i;
229 assert(i > j);
230 assert(i >= j);
231 assert(j <= i);
232 assert(j < i);
235 Iterator k = j + N - 1;
236 for (c = 0; c < N-1; ++c) {
237 assert(i == k - c);
238 assert(*i == vals[N - 1 - c]);
239 assert(*i == boost::implicit_cast<value_type>(j[N - 1 - c]));
240 Iterator q = k - c;
241 assert(*i == *q);
242 assert(i > j);
243 assert(i >= j);
244 assert(j <= i);
245 assert(j < i);
246 --i;
250 // Precondition: i != j
251 template <class Iterator, class ConstIterator>
252 void const_nonconst_iterator_test(Iterator i, ConstIterator j)
254 assert(i != j);
255 assert(j != i);
257 ConstIterator k(i);
258 assert(k == i);
259 assert(i == k);
261 k = i;
262 assert(k == i);
263 assert(i == k);
266 } // namespace boost
268 #endif // BOOST_ITERATOR_TESTS_HPP