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