]> git.lyx.org Git - lyx.git/blob - boost/boost/iterator/new_iterator_tests.hpp
update to boost 1.39: add new files
[lyx.git] / boost / boost / iterator / new_iterator_tests.hpp
1 #ifndef BOOST_NEW_ITERATOR_TESTS_HPP\r
2 # define BOOST_NEW_ITERATOR_TESTS_HPP\r
3 \r
4 //\r
5 // Copyright (c) David Abrahams 2001.\r
6 // Copyright (c) Jeremy Siek 2001-2003.\r
7 // Copyright (c) Thomas Witt 2002.\r
8 //\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
13 //\r
14 \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
17 //\r
18 // Revision History:\r
19 // 28 Oct 2002  Started update for new iterator categories\r
20 //              (Jeremy Siek)\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
24 //              (Thomas Witt)\r
25 // 08 Feb 2001  Fixed bidirectional iterator test so that\r
26 //              --i is no longer a precondition.\r
27 //              (Jeremy Siek)\r
28 // 04 Feb 2001  Added lvalue test, corrected preconditions\r
29 //              (David Abrahams)\r
30 \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
39 \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
43 \r
44 namespace boost {\r
45 \r
46 \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
51 {\r
52     T v2(*i1++);\r
53     BOOST_TEST(v == v2);\r
54 }\r
55 \r
56 template <class Iterator, class T>\r
57 void readable_iterator_traversal_test(const Iterator i1, T v, mpl::false_)\r
58 {}\r
59 \r
60 template <class Iterator, class T>\r
61 void writable_iterator_traversal_test(Iterator i1, T v, mpl::true_)\r
62 {\r
63     ++i1;  // we just wrote into that position\r
64     *i1++ = v;\r
65     Iterator x(i1++);\r
66     (void)x;\r
67 }\r
68 \r
69 template <class Iterator, class T>\r
70 void writable_iterator_traversal_test(const Iterator i1, T v, mpl::false_)\r
71 {}\r
72 \r
73 \r
74 // Preconditions: *i == v\r
75 template <class Iterator, class T>\r
76 void readable_iterator_test(const Iterator i1, T v)\r
77 {\r
78   Iterator i2(i1); // Copy Constructible\r
79   typedef typename detail::iterator_traits<Iterator>::reference ref_t;\r
80   ref_t r1 = *i1;\r
81   ref_t r2 = *i2;\r
82   T v1 = r1;\r
83   T v2 = r2;\r
84   BOOST_TEST(v1 == v);\r
85   BOOST_TEST(v2 == v);\r
86 \r
87 # if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)\r
88   readable_iterator_traversal_test(i1, v, detail::is_postfix_incrementable<Iterator>());\r
89       \r
90   // I think we don't really need this as it checks the same things as\r
91   // the above code.\r
92   BOOST_STATIC_ASSERT(is_readable_iterator<Iterator>::value);\r
93 # endif \r
94 }\r
95 \r
96 template <class Iterator, class T>\r
97 void writable_iterator_test(Iterator i, T v, T v2)\r
98 {\r
99   Iterator i2(i); // Copy Constructible\r
100   *i2 = v;\r
101 \r
102 # if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)\r
103   writable_iterator_traversal_test(\r
104       i, v2, mpl::and_<\r
105           detail::is_incrementable<Iterator>\r
106         , detail::is_postfix_incrementable<Iterator>\r
107       >());\r
108 # endif \r
109 }\r
110 \r
111 template <class Iterator>\r
112 void swappable_iterator_test(Iterator i, Iterator j)\r
113 {\r
114   Iterator i2(i), j2(j);\r
115   typename detail::iterator_traits<Iterator>::value_type bi = *i, bj = *j;\r
116   iter_swap(i2, j2);\r
117   typename detail::iterator_traits<Iterator>::value_type ai = *i, aj = *j;\r
118   BOOST_TEST(bi == aj && bj == ai);\r
119 }\r
120 \r
121 template <class Iterator, class T>\r
122 void constant_lvalue_iterator_test(Iterator i, T v1)\r
123 {\r
124   Iterator i2(i);\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
128   const T& v2 = *i2;\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
133 # endif \r
134 }\r
135 \r
136 template <class Iterator, class T>\r
137 void non_const_lvalue_iterator_test(Iterator i, T v1, T v2)\r
138 {\r
139   Iterator i2(i);\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
143   T& v3 = *i2;\r
144   BOOST_TEST(v1 == v3);\r
145   \r
146   // A non-const lvalue iterator is not neccessarily writable, but we\r
147   // are assuming the value_type is assignable here\r
148   *i = v2;\r
149   \r
150   T& v4 = *i2;\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
155 # endif \r
156 }\r
157 \r
158 template <class Iterator, class T>\r
159 void forward_readable_iterator_test(Iterator i, Iterator j, T val1, T val2)\r
160 {\r
161   Iterator i2;\r
162   Iterator i3(i);\r
163   i2 = i;\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
170 \r
171   BOOST_TEST(i == i2++);\r
172   BOOST_TEST(i != ++i3);\r
173 \r
174   readable_iterator_test(i2, val2);\r
175   readable_iterator_test(i3, val2);\r
176 \r
177   readable_iterator_test(i, val1);\r
178 }\r
179 \r
180 template <class Iterator, class T>\r
181 void forward_swappable_iterator_test(Iterator i, Iterator j, T val1, T val2)\r
182 {\r
183   forward_readable_iterator_test(i, j, val1, val2);\r
184   Iterator i2 = i;\r
185   ++i2;\r
186   swappable_iterator_test(i, i2);\r
187 }\r
188 \r
189 // bidirectional\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
193 {\r
194   Iterator j(i);\r
195   ++j;\r
196   forward_readable_iterator_test(i, j, v1, v2);\r
197   ++i;\r
198 \r
199   Iterator i1 = i, i2 = i;\r
200 \r
201   BOOST_TEST(i == i1--);\r
202   BOOST_TEST(i != --i2);\r
203 \r
204   readable_iterator_test(i, v2);\r
205   readable_iterator_test(i1, v1);\r
206   readable_iterator_test(i2, v1);\r
207 \r
208   --i;\r
209   BOOST_TEST(i == i1);\r
210   BOOST_TEST(i == i2);\r
211   ++i1;\r
212   ++i2;\r
213 \r
214   readable_iterator_test(i, v1);\r
215   readable_iterator_test(i1, v2);\r
216   readable_iterator_test(i2, v2);\r
217 }\r
218 \r
219 // random access\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
223 {\r
224   bidirectional_readable_iterator_test(i, vals[0], vals[1]);\r
225   const Iterator j = i;\r
226   int c;\r
227 \r
228   for (c = 0; c < N-1; ++c)\r
229   {\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
236     ++i;\r
237     BOOST_TEST(i > j);\r
238     BOOST_TEST(i >= j);\r
239     BOOST_TEST(j <= i);\r
240     BOOST_TEST(j < i);\r
241   }\r
242 \r
243   Iterator k = j + N - 1;\r
244   for (c = 0; c < N-1; ++c)\r
245   {\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
252     BOOST_TEST(i > j);\r
253     BOOST_TEST(i >= j);\r
254     BOOST_TEST(j <= i);\r
255     BOOST_TEST(j < i);\r
256     --i;\r
257   }\r
258 }\r
259 \r
260 } // namespace boost\r
261 \r
262 # include <boost/iterator/detail/config_undef.hpp>\r
263 \r
264 #endif // BOOST_NEW_ITERATOR_TESTS_HPP\r