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