Merge c:/dyninst/pc_bluegene/dyninst into dyn_pc_integration
[dyninst.git] / external / boost / iterator / new_iterator_tests.hpp
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/type_traits.hpp>
33 # include <boost/static_assert.hpp>
34 # include <boost/concept_archetype.hpp> // for detail::dummy_constructor
35 # include <boost/detail/iterator.hpp>
36 # include <boost/pending/iterator_tests.hpp>
37 # include <boost/iterator/is_readable_iterator.hpp>
38 # include <boost/iterator/is_lvalue_iterator.hpp>
39
40 # include <boost/iterator/detail/config_def.hpp>
41 # include <boost/detail/is_incrementable.hpp>
42 # include <boost/detail/lightweight_test.hpp>
43
44 namespace boost {
45
46
47 // Do separate tests for *i++ so we can treat, e.g., smart pointers,
48 // as readable and/or writable iterators.
49 template <class Iterator, class T>
50 void readable_iterator_traversal_test(Iterator i1, T v, mpl::true_)
51 {
52     T v2(*i1++);
53     BOOST_TEST(v == v2);
54 }
55
56 template <class Iterator, class T>
57 void readable_iterator_traversal_test(const Iterator i1, T v, mpl::false_)
58 {}
59
60 template <class Iterator, class T>
61 void writable_iterator_traversal_test(Iterator i1, T v, mpl::true_)
62 {
63     ++i1;  // we just wrote into that position
64     *i1++ = v;
65     Iterator x(i1++);
66     (void)x;
67 }
68
69 template <class Iterator, class T>
70 void writable_iterator_traversal_test(const Iterator i1, T v, mpl::false_)
71 {}
72
73
74 // Preconditions: *i == v
75 template <class Iterator, class T>
76 void readable_iterator_test(const Iterator i1, T v)
77 {
78   Iterator i2(i1); // Copy Constructible
79   typedef typename detail::iterator_traits<Iterator>::reference ref_t;
80   ref_t r1 = *i1;
81   ref_t r2 = *i2;
82   T v1 = r1;
83   T v2 = r2;
84   BOOST_TEST(v1 == v);
85   BOOST_TEST(v2 == v);
86
87 # if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
88   readable_iterator_traversal_test(i1, v, detail::is_postfix_incrementable<Iterator>());
89       
90   // I think we don't really need this as it checks the same things as
91   // the above code.
92   BOOST_STATIC_ASSERT(is_readable_iterator<Iterator>::value);
93 # endif 
94 }
95
96 template <class Iterator, class T>
97 void writable_iterator_test(Iterator i, T v, T v2)
98 {
99   Iterator i2(i); // Copy Constructible
100   *i2 = v;
101
102 # if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
103   writable_iterator_traversal_test(
104       i, v2, mpl::and_<
105           detail::is_incrementable<Iterator>
106         , detail::is_postfix_incrementable<Iterator>
107       >());
108 # endif 
109 }
110
111 template <class Iterator>
112 void swappable_iterator_test(Iterator i, Iterator j)
113 {
114   Iterator i2(i), j2(j);
115   typename detail::iterator_traits<Iterator>::value_type bi = *i, bj = *j;
116   iter_swap(i2, j2);
117   typename detail::iterator_traits<Iterator>::value_type ai = *i, aj = *j;
118   BOOST_TEST(bi == aj && bj == ai);
119 }
120
121 template <class Iterator, class T>
122 void constant_lvalue_iterator_test(Iterator i, T v1)
123 {
124   Iterator i2(i);
125   typedef typename detail::iterator_traits<Iterator>::value_type value_type;
126   typedef typename detail::iterator_traits<Iterator>::reference reference;
127   BOOST_STATIC_ASSERT((is_same<const value_type&, reference>::value));
128   const T& v2 = *i2;
129   BOOST_TEST(v1 == v2);
130 # ifndef BOOST_NO_LVALUE_RETURN_DETECTION
131   BOOST_STATIC_ASSERT(is_lvalue_iterator<Iterator>::value);
132   BOOST_STATIC_ASSERT(!is_non_const_lvalue_iterator<Iterator>::value);
133 # endif 
134 }
135
136 template <class Iterator, class T>
137 void non_const_lvalue_iterator_test(Iterator i, T v1, T v2)
138 {
139   Iterator i2(i);
140   typedef typename detail::iterator_traits<Iterator>::value_type value_type;
141   typedef typename detail::iterator_traits<Iterator>::reference reference;
142   BOOST_STATIC_ASSERT((is_same<value_type&, reference>::value));
143   T& v3 = *i2;
144   BOOST_TEST(v1 == v3);
145   
146   // A non-const lvalue iterator is not neccessarily writable, but we
147   // are assuming the value_type is assignable here
148   *i = v2;
149   
150   T& v4 = *i2;
151   BOOST_TEST(v2 == v4);
152 # ifndef BOOST_NO_LVALUE_RETURN_DETECTION
153   BOOST_STATIC_ASSERT(is_lvalue_iterator<Iterator>::value);
154   BOOST_STATIC_ASSERT(is_non_const_lvalue_iterator<Iterator>::value);
155 # endif 
156 }
157
158 template <class Iterator, class T>
159 void forward_readable_iterator_test(Iterator i, Iterator j, T val1, T val2)
160 {
161   Iterator i2;
162   Iterator i3(i);
163   i2 = i;
164   BOOST_TEST(i2 == i3);
165   BOOST_TEST(i != j);
166   BOOST_TEST(i2 != j);
167   readable_iterator_test(i, val1);
168   readable_iterator_test(i2, val1);
169   readable_iterator_test(i3, val1);
170
171   BOOST_TEST(i == i2++);
172   BOOST_TEST(i != ++i3);
173
174   readable_iterator_test(i2, val2);
175   readable_iterator_test(i3, val2);
176
177   readable_iterator_test(i, val1);
178 }
179
180 template <class Iterator, class T>
181 void forward_swappable_iterator_test(Iterator i, Iterator j, T val1, T val2)
182 {
183   forward_readable_iterator_test(i, j, val1, val2);
184   Iterator i2 = i;
185   ++i2;
186   swappable_iterator_test(i, i2);
187 }
188
189 // bidirectional
190 // Preconditions: *i == v1, *++i == v2
191 template <class Iterator, class T>
192 void bidirectional_readable_iterator_test(Iterator i, T v1, T v2)
193 {
194   Iterator j(i);
195   ++j;
196   forward_readable_iterator_test(i, j, v1, v2);
197   ++i;
198
199   Iterator i1 = i, i2 = i;
200
201   BOOST_TEST(i == i1--);
202   BOOST_TEST(i != --i2);
203
204   readable_iterator_test(i, v2);
205   readable_iterator_test(i1, v1);
206   readable_iterator_test(i2, v1);
207
208   --i;
209   BOOST_TEST(i == i1);
210   BOOST_TEST(i == i2);
211   ++i1;
212   ++i2;
213
214   readable_iterator_test(i, v1);
215   readable_iterator_test(i1, v2);
216   readable_iterator_test(i2, v2);
217 }
218
219 // random access
220 // Preconditions: [i,i+N) is a valid range
221 template <class Iterator, class TrueVals>
222 void random_access_readable_iterator_test(Iterator i, int N, TrueVals vals)
223 {
224   bidirectional_readable_iterator_test(i, vals[0], vals[1]);
225   const Iterator j = i;
226   int c;
227
228   for (c = 0; c < N-1; ++c)
229   {
230     BOOST_TEST(i == j + c);
231     BOOST_TEST(*i == vals[c]);
232     typename detail::iterator_traits<Iterator>::value_type x = j[c];
233     BOOST_TEST(*i == x);
234     BOOST_TEST(*i == *(j + c));
235     BOOST_TEST(*i == *(c + j));
236     ++i;
237     BOOST_TEST(i > j);
238     BOOST_TEST(i >= j);
239     BOOST_TEST(j <= i);
240     BOOST_TEST(j < i);
241   }
242
243   Iterator k = j + N - 1;
244   for (c = 0; c < N-1; ++c)
245   {
246     BOOST_TEST(i == k - c);
247     BOOST_TEST(*i == vals[N - 1 - c]);
248     typename detail::iterator_traits<Iterator>::value_type x = j[N - 1 - c];
249     BOOST_TEST(*i == x);
250     Iterator q = k - c; 
251     BOOST_TEST(*i == *q);
252     BOOST_TEST(i > j);
253     BOOST_TEST(i >= j);
254     BOOST_TEST(j <= i);
255     BOOST_TEST(j < i);
256     --i;
257   }
258 }
259
260 } // namespace boost
261
262 # include <boost/iterator/detail/config_undef.hpp>
263
264 #endif // BOOST_NEW_ITERATOR_TESTS_HPP