1 #ifndef BOOST_NEW_ITERATOR_TESTS_HPP
\r
2 # define BOOST_NEW_ITERATOR_TESTS_HPP
\r
5 // Copyright (c) David Abrahams 2001.
\r
6 // Copyright (c) Jeremy Siek 2001-2003.
\r
7 // Copyright (c) Thomas Witt 2002.
\r
9 // Use, modification and distribution is subject to the
\r
10 // Boost Software License, Version 1.0.
\r
11 // (See accompanying file LICENSE_1_0.txt or copy at
\r
12 // http://www.boost.org/LICENSE_1_0.txt)
\r
15 // This is meant to be the beginnings of a comprehensive, generic
\r
16 // test suite for STL concepts such as iterators and containers.
\r
18 // Revision History:
\r
19 // 28 Oct 2002 Started update for new iterator categories
\r
21 // 28 Apr 2002 Fixed input iterator requirements.
\r
22 // For a == b a++ == b++ is no longer required.
\r
23 // See 24.1.1/3 for details.
\r
25 // 08 Feb 2001 Fixed bidirectional iterator test so that
\r
26 // --i is no longer a precondition.
\r
28 // 04 Feb 2001 Added lvalue test, corrected preconditions
\r
31 # include <iterator>
\r
32 # include <boost/type_traits.hpp>
\r
33 # include <boost/static_assert.hpp>
\r
34 # include <boost/concept_archetype.hpp> // for detail::dummy_constructor
\r
35 # include <boost/detail/iterator.hpp>
\r
36 # include <boost/pending/iterator_tests.hpp>
\r
37 # include <boost/iterator/is_readable_iterator.hpp>
\r
38 # include <boost/iterator/is_lvalue_iterator.hpp>
\r
40 # include <boost/iterator/detail/config_def.hpp>
\r
41 # include <boost/detail/is_incrementable.hpp>
\r
42 # include <boost/detail/lightweight_test.hpp>
\r
47 // Do separate tests for *i++ so we can treat, e.g., smart pointers,
\r
48 // as readable and/or writable iterators.
\r
49 template <class Iterator, class T>
\r
50 void readable_iterator_traversal_test(Iterator i1, T v, mpl::true_)
\r
53 BOOST_TEST(v == v2);
\r
56 template <class Iterator, class T>
\r
57 void readable_iterator_traversal_test(const Iterator i1, T v, mpl::false_)
\r
60 template <class Iterator, class T>
\r
61 void writable_iterator_traversal_test(Iterator i1, T v, mpl::true_)
\r
63 ++i1; // we just wrote into that position
\r
69 template <class Iterator, class T>
\r
70 void writable_iterator_traversal_test(const Iterator i1, T v, mpl::false_)
\r
74 // Preconditions: *i == v
\r
75 template <class Iterator, class T>
\r
76 void readable_iterator_test(const Iterator i1, T v)
\r
78 Iterator i2(i1); // Copy Constructible
\r
79 typedef typename detail::iterator_traits<Iterator>::reference ref_t;
\r
84 BOOST_TEST(v1 == v);
\r
85 BOOST_TEST(v2 == v);
\r
87 # if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
\r
88 readable_iterator_traversal_test(i1, v, detail::is_postfix_incrementable<Iterator>());
\r
90 // I think we don't really need this as it checks the same things as
\r
92 BOOST_STATIC_ASSERT(is_readable_iterator<Iterator>::value);
\r
96 template <class Iterator, class T>
\r
97 void writable_iterator_test(Iterator i, T v, T v2)
\r
99 Iterator i2(i); // Copy Constructible
\r
102 # if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
\r
103 writable_iterator_traversal_test(
\r
105 detail::is_incrementable<Iterator>
\r
106 , detail::is_postfix_incrementable<Iterator>
\r
111 template <class Iterator>
\r
112 void swappable_iterator_test(Iterator i, Iterator j)
\r
114 Iterator i2(i), j2(j);
\r
115 typename detail::iterator_traits<Iterator>::value_type bi = *i, bj = *j;
\r
117 typename detail::iterator_traits<Iterator>::value_type ai = *i, aj = *j;
\r
118 BOOST_TEST(bi == aj && bj == ai);
\r
121 template <class Iterator, class T>
\r
122 void constant_lvalue_iterator_test(Iterator i, T v1)
\r
125 typedef typename detail::iterator_traits<Iterator>::value_type value_type;
\r
126 typedef typename detail::iterator_traits<Iterator>::reference reference;
\r
127 BOOST_STATIC_ASSERT((is_same<const value_type&, reference>::value));
\r
129 BOOST_TEST(v1 == v2);
\r
130 # ifndef BOOST_NO_LVALUE_RETURN_DETECTION
\r
131 BOOST_STATIC_ASSERT(is_lvalue_iterator<Iterator>::value);
\r
132 BOOST_STATIC_ASSERT(!is_non_const_lvalue_iterator<Iterator>::value);
\r
136 template <class Iterator, class T>
\r
137 void non_const_lvalue_iterator_test(Iterator i, T v1, T v2)
\r
140 typedef typename detail::iterator_traits<Iterator>::value_type value_type;
\r
141 typedef typename detail::iterator_traits<Iterator>::reference reference;
\r
142 BOOST_STATIC_ASSERT((is_same<value_type&, reference>::value));
\r
144 BOOST_TEST(v1 == v3);
\r
146 // A non-const lvalue iterator is not neccessarily writable, but we
\r
147 // are assuming the value_type is assignable here
\r
151 BOOST_TEST(v2 == v4);
\r
152 # ifndef BOOST_NO_LVALUE_RETURN_DETECTION
\r
153 BOOST_STATIC_ASSERT(is_lvalue_iterator<Iterator>::value);
\r
154 BOOST_STATIC_ASSERT(is_non_const_lvalue_iterator<Iterator>::value);
\r
158 template <class Iterator, class T>
\r
159 void forward_readable_iterator_test(Iterator i, Iterator j, T val1, T val2)
\r
164 BOOST_TEST(i2 == i3);
\r
165 BOOST_TEST(i != j);
\r
166 BOOST_TEST(i2 != j);
\r
167 readable_iterator_test(i, val1);
\r
168 readable_iterator_test(i2, val1);
\r
169 readable_iterator_test(i3, val1);
\r
171 BOOST_TEST(i == i2++);
\r
172 BOOST_TEST(i != ++i3);
\r
174 readable_iterator_test(i2, val2);
\r
175 readable_iterator_test(i3, val2);
\r
177 readable_iterator_test(i, val1);
\r
180 template <class Iterator, class T>
\r
181 void forward_swappable_iterator_test(Iterator i, Iterator j, T val1, T val2)
\r
183 forward_readable_iterator_test(i, j, val1, val2);
\r
186 swappable_iterator_test(i, i2);
\r
190 // Preconditions: *i == v1, *++i == v2
\r
191 template <class Iterator, class T>
\r
192 void bidirectional_readable_iterator_test(Iterator i, T v1, T v2)
\r
196 forward_readable_iterator_test(i, j, v1, v2);
\r
199 Iterator i1 = i, i2 = i;
\r
201 BOOST_TEST(i == i1--);
\r
202 BOOST_TEST(i != --i2);
\r
204 readable_iterator_test(i, v2);
\r
205 readable_iterator_test(i1, v1);
\r
206 readable_iterator_test(i2, v1);
\r
209 BOOST_TEST(i == i1);
\r
210 BOOST_TEST(i == i2);
\r
214 readable_iterator_test(i, v1);
\r
215 readable_iterator_test(i1, v2);
\r
216 readable_iterator_test(i2, v2);
\r
220 // Preconditions: [i,i+N) is a valid range
\r
221 template <class Iterator, class TrueVals>
\r
222 void random_access_readable_iterator_test(Iterator i, int N, TrueVals vals)
\r
224 bidirectional_readable_iterator_test(i, vals[0], vals[1]);
\r
225 const Iterator j = i;
\r
228 for (c = 0; c < N-1; ++c)
\r
230 BOOST_TEST(i == j + c);
\r
231 BOOST_TEST(*i == vals[c]);
\r
232 typename detail::iterator_traits<Iterator>::value_type x = j[c];
\r
233 BOOST_TEST(*i == x);
\r
234 BOOST_TEST(*i == *(j + c));
\r
235 BOOST_TEST(*i == *(c + j));
\r
238 BOOST_TEST(i >= j);
\r
239 BOOST_TEST(j <= i);
\r
243 Iterator k = j + N - 1;
\r
244 for (c = 0; c < N-1; ++c)
\r
246 BOOST_TEST(i == k - c);
\r
247 BOOST_TEST(*i == vals[N - 1 - c]);
\r
248 typename detail::iterator_traits<Iterator>::value_type x = j[N - 1 - c];
\r
249 BOOST_TEST(*i == x);
\r
250 Iterator q = k - c;
\r
251 BOOST_TEST(*i == *q);
\r
253 BOOST_TEST(i >= j);
\r
254 BOOST_TEST(j <= i);
\r
260 } // namespace boost
\r
262 # include <boost/iterator/detail/config_undef.hpp>
\r
264 #endif // BOOST_NEW_ITERATOR_TESTS_HPP
\r