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.
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.
16 // 08 Feb 2001 Fixed bidirectional iterator test so that
17 // --i is no longer a precondition.
19 // 04 Feb 2001 Added lvalue test, corrected preconditions
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>
32 // use this for the value type
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
; }
44 BOOST_TT_BROKEN_COMPILER_SPEC(boost::dummyT
)
48 // Tests whether type Iterator satisfies the requirements for a
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
)
58 #ifdef BOOST_NO_STD_ITERATOR_TRAITS
61 typename
std::iterator_traits
<Iterator
>::value_type v
= *i
;
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());
79 // Preconditions: i != j
80 template <class Iterator
, class T
>
81 void mutable_trivial_iterator_test(const Iterator i
, const Iterator j
, T 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
)
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.
105 // assert(!(i == i2));
110 // we cannot test for equivalence of (void)++i & (void)i++
111 // as i is only guaranteed to be single pass.
122 // i is dereferencable, so it must be incrementable.
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
;
139 typedef typename
Iterator::reference reference
;
140 typedef typename
Iterator::value_type value_type
;
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
) {}
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
;
165 trivial_iterator_test(i
, i1
, v1
);
166 trivial_iterator_test(i
, i2
, v1
);
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
);
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
);
190 Iterator i1
= i
, i2
= i
;
195 trivial_iterator_test(i
, i1
, v2
);
196 trivial_iterator_test(i
, i2
, v2
);
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
;
220 typedef typename
boost::detail::iterator_traits
<Iterator
>::value_type value_type
;
222 for (c
= 0; c
< N
-1; ++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
));
235 Iterator k
= j
+ N
- 1;
236 for (c
= 0; c
< N
-1; ++c
) {
238 assert(*i
== vals
[N
- 1 - c
]);
239 assert(*i
== boost::implicit_cast
<value_type
>(j
[N
- 1 - c
]));
250 // Precondition: i != j
251 template <class Iterator
, class ConstIterator
>
252 void const_nonconst_iterator_test(Iterator i
, ConstIterator j
)
268 #endif // BOOST_ITERATOR_TESTS_HPP