1
#ifndef BOOST_ITERATOR_TESTS_HPP
2
# define BOOST_ITERATOR_TESTS_HPP
4
// This is meant to be the beginnings of a comprehensive, generic
5
// test suite for STL concepts such as iterators and containers.
8
// 28 Apr 2002 Fixed input iterator requirements.
9
// For a == b a++ == b++ is no longer required.
10
// See 24.1.1/3 for details.
12
// 08 Feb 2001 Fixed bidirectional iterator test so that
13
// --i is no longer a precondition.
15
// 04 Feb 2001 Added lvalue test, corrected preconditions
20
# include <boost/type_traits.hpp>
21
# include <boost/static_assert.hpp>
22
# include <boost/concept_archetype.hpp> // for detail::dummy_constructor
26
// use this for the value type
29
dummyT(detail::dummy_constructor) { }
30
dummyT(int x) : m_x(x) { }
31
int foo() const { return m_x; }
32
bool operator==(const dummyT& d) const { return m_x == d.m_x; }
37
// Tests whether type Iterator satisfies the requirements for a
39
// Preconditions: i != j, *i == val
40
template <class Iterator, class T>
41
void trivial_iterator_test(const Iterator i, const Iterator j, T val)
47
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
50
typename std::iterator_traits<Iterator>::value_type v = *i;
54
// hmm, this will give a warning for transform_iterator... perhaps
55
// this should be separated out into a stand-alone test since there
56
// are several situations where it can't be used, like for
57
// integer_range::iterator.
58
assert(v == i->foo());
68
// Preconditions: i != j
69
template <class Iterator, class T>
70
void mutable_trivial_iterator_test(const Iterator i, const Iterator j, T val)
73
trivial_iterator_test(i, j, val);
77
// Preconditions: *i == v1, *++i == v2
78
template <class Iterator, class T>
79
void input_iterator_test(Iterator i, T v1, T v2)
86
// I can see no generic way to create an input iterator
87
// that is in the domain of== of i and != i.
88
// The following works for istream_iterator but is not
89
// guaranteed to work for arbitrary input iterators.
94
// assert(!(i == i2));
99
// we cannot test for equivalence of (void)++i & (void)i++
100
// as i is only guaranteed to be single pass.
111
// i is dereferencable, so it must be incrementable.
114
// how to test for operator-> ?
117
// how to test output iterator?
120
template <bool is_pointer> struct lvalue_test
122
template <class Iterator> static void check(Iterator)
124
# ifndef BOOST_NO_STD_ITERATOR_TRAITS
125
typedef typename std::iterator_traits<Iterator>::reference reference;
126
typedef typename std::iterator_traits<Iterator>::value_type value_type;
128
typedef typename Iterator::reference reference;
129
typedef typename Iterator::value_type value_type;
131
BOOST_STATIC_ASSERT(boost::is_reference<reference>::value);
132
BOOST_STATIC_ASSERT((boost::is_same<reference,value_type&>::value
133
|| boost::is_same<reference,const value_type&>::value
138
# ifdef BOOST_NO_STD_ITERATOR_TRAITS
139
template <> struct lvalue_test<true> {
140
template <class T> static void check(T) {}
144
template <class Iterator, class T>
145
void forward_iterator_test(Iterator i, T v1, T v2)
147
input_iterator_test(i, v1, v2);
149
Iterator i1 = i, i2 = i;
154
trivial_iterator_test(i, i1, v1);
155
trivial_iterator_test(i, i2, v1);
163
trivial_iterator_test(i, i1, v2);
164
trivial_iterator_test(i, i2, v2);
166
// borland doesn't allow non-type template parameters
167
# if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551)
168
lvalue_test<(boost::is_pointer<Iterator>::value)>::check(i);
172
// Preconditions: *i == v1, *++i == v2
173
template <class Iterator, class T>
174
void bidirectional_iterator_test(Iterator i, T v1, T v2)
176
forward_iterator_test(i, v1, v2);
179
Iterator i1 = i, i2 = i;
184
trivial_iterator_test(i, i1, v2);
185
trivial_iterator_test(i, i2, v2);
193
trivial_iterator_test(i, i1, v1);
194
trivial_iterator_test(i, i2, v1);
197
// mutable_bidirectional_iterator_test
199
// Preconditions: [i,i+N) is a valid range
200
template <class Iterator, class TrueVals>
201
void random_access_iterator_test(Iterator i, int N, TrueVals vals)
203
bidirectional_iterator_test(i, vals[0], vals[1]);
204
const Iterator j = i;
207
for (c = 0; c < N-1; ++c) {
209
assert(*i == vals[c]);
211
assert(*i == *(j + c));
212
assert(*i == *(c + j));
220
Iterator k = j + N - 1;
221
for (c = 0; c < N-1; ++c) {
223
assert(*i == vals[N - 1 - c]);
224
assert(*i == j[N - 1 - c]);
235
// Precondition: i != j
236
template <class Iterator, class ConstIterator>
237
void const_nonconst_iterator_test(Iterator i, ConstIterator j)
253
#endif // BOOST_ITERATOR_TESTS_HPP