]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/iterator/test/iterator_adaptor_test.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / iterator / test / iterator_adaptor_test.cpp
1 // (C) Copyright Thomas Witt 2003.
2 // Distributed under the Boost Software License, Version 1.0. (See
3 // accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
5
6 // See http://www.boost.org for most recent version including documentation.
7
8 #include <boost/config.hpp>
9 #include <iostream>
10
11 #include <algorithm>
12 #include <functional>
13 #include <numeric>
14
15 #include <boost/iterator/iterator_adaptor.hpp>
16 #if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
17 # include <boost/iterator/is_readable_iterator.hpp>
18 # include <boost/iterator/is_lvalue_iterator.hpp>
19 #endif
20 #include <boost/pending/iterator_tests.hpp>
21
22 # include <boost/detail/lightweight_test.hpp>
23
24 #include <stdlib.h>
25 #include <vector>
26 #include <deque>
27 #include <set>
28 #include <list>
29
30 #include "static_assert_same.hpp"
31
32 #include <boost/iterator/detail/config_def.hpp>
33
34 using boost::dummyT;
35
36 struct mult_functor {
37 typedef int result_type;
38 typedef int argument_type;
39 // Functors used with transform_iterator must be
40 // DefaultConstructible, as the transform_iterator must be
41 // DefaultConstructible to satisfy the requirements for
42 // TrivialIterator.
43 mult_functor() { }
44 mult_functor(int aa) : a(aa) { }
45 int operator()(int b) const { return a * b; }
46 int a;
47 };
48
49 template <class Pair>
50 struct select1st_
51 : public std::unary_function<Pair, typename Pair::first_type>
52 {
53 const typename Pair::first_type& operator()(const Pair& x) const {
54 return x.first;
55 }
56 typename Pair::first_type& operator()(Pair& x) const {
57 return x.first;
58 }
59 };
60
61 struct one_or_four {
62 bool operator()(dummyT x) const {
63 return x.foo() == 1 || x.foo() == 4;
64 }
65 };
66
67 typedef std::deque<int> storage;
68 typedef std::deque<int*> pointer_deque;
69 typedef std::set<storage::iterator> iterator_set;
70
71 template <class T> struct foo;
72
73 void blah(int) { }
74
75 struct my_gen
76 {
77 typedef int result_type;
78 my_gen() : n(0) { }
79 int operator()() { return ++n; }
80 int n;
81 };
82
83 template <class V>
84 struct ptr_iterator
85 : boost::iterator_adaptor<
86 ptr_iterator<V>
87 , V*
88 , V
89 , boost::random_access_traversal_tag
90 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
91 , V&
92 #endif
93 >
94 {
95 private:
96 typedef boost::iterator_adaptor<
97 ptr_iterator<V>
98 , V*
99 , V
100 , boost::random_access_traversal_tag
101 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
102 , V&
103 #endif
104 > super_t;
105
106 public:
107 ptr_iterator() { }
108 ptr_iterator(V* d) : super_t(d) { }
109
110 template <class V2>
111 ptr_iterator(
112 const ptr_iterator<V2>& x
113 , typename boost::enable_if_convertible<V2*, V*>::type* = 0
114 )
115 : super_t(x.base())
116 {}
117 };
118
119 // Non-functional iterator for category modification checking
120 template <class Iter, class Traversal>
121 struct modify_traversal
122 : boost::iterator_adaptor<
123 modify_traversal<Iter, Traversal>
124 , Iter
125 , boost::use_default
126 , Traversal
127 >
128 {};
129
130 template <class T>
131 struct fwd_iterator
132 : boost::iterator_adaptor<
133 fwd_iterator<T>
134 , boost::forward_iterator_archetype<T>
135 >
136 {
137 private:
138 typedef boost::iterator_adaptor<
139 fwd_iterator<T>
140 , boost::forward_iterator_archetype<T>
141 > super_t;
142
143 public:
144 fwd_iterator() { }
145 fwd_iterator(boost::forward_iterator_archetype<T> d) : super_t(d) { }
146 };
147
148 template <class T>
149 struct in_iterator
150 : boost::iterator_adaptor<
151 in_iterator<T>
152 , boost::input_iterator_archetype_no_proxy<T>
153 >
154 {
155 private:
156 typedef boost::iterator_adaptor<
157 in_iterator<T>
158 , boost::input_iterator_archetype_no_proxy<T>
159 > super_t;
160
161 public:
162 in_iterator() { }
163 in_iterator(boost::input_iterator_archetype_no_proxy<T> d) : super_t(d) { }
164 };
165
166 template <class Iter>
167 struct constant_iterator
168 : boost::iterator_adaptor<
169 constant_iterator<Iter>
170 , Iter
171 , typename std::iterator_traits<Iter>::value_type const
172 >
173 {
174 typedef boost::iterator_adaptor<
175 constant_iterator<Iter>
176 , Iter
177 , typename std::iterator_traits<Iter>::value_type const
178 > base_t;
179
180 constant_iterator() {}
181 constant_iterator(Iter it)
182 : base_t(it) {}
183 };
184
185 char (& traversal2(boost::incrementable_traversal_tag) )[1];
186 char (& traversal2(boost::single_pass_traversal_tag ) )[2];
187 char (& traversal2(boost::forward_traversal_tag ) )[3];
188 char (& traversal2(boost::bidirectional_traversal_tag) )[4];
189 char (& traversal2(boost::random_access_traversal_tag) )[5];
190
191 template <class Cat>
192 struct traversal3
193 {
194 static typename boost::iterator_category_to_traversal<Cat>::type x;
195 BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(traversal2(x)));
196 typedef char (&type)[value];
197 };
198
199 template <class Cat>
200 typename traversal3<Cat>::type traversal(Cat);
201
202 template <class Iter, class Trav>
203 int static_assert_traversal(Iter* = 0, Trav* = 0)
204 {
205 typedef typename boost::iterator_category_to_traversal<
206 BOOST_DEDUCED_TYPENAME Iter::iterator_category
207 >::type t2;
208
209 return static_assert_same<Trav,t2>::value;
210 }
211
212 int
213 main()
214 {
215 dummyT array[] = { dummyT(0), dummyT(1), dummyT(2),
216 dummyT(3), dummyT(4), dummyT(5) };
217 const int N = sizeof(array)/sizeof(dummyT);
218
219 // sanity check, if this doesn't pass the test is buggy
220 boost::random_access_iterator_test(array, N, array);
221
222 // Test the iterator_adaptor
223 {
224 ptr_iterator<dummyT> i(array);
225 boost::random_access_iterator_test(i, N, array);
226
227 ptr_iterator<const dummyT> j(array);
228 boost::random_access_iterator_test(j, N, array);
229 boost::const_nonconst_iterator_test(i, ++j);
230 }
231
232 int test;
233 // Test the iterator_traits
234 {
235 // Test computation of defaults
236 typedef ptr_iterator<int> Iter1;
237 // don't use std::iterator_traits here to avoid VC++ problems
238 test = static_assert_same<Iter1::value_type, int>::value;
239 test = static_assert_same<Iter1::reference, int&>::value;
240 test = static_assert_same<Iter1::pointer, int*>::value;
241 test = static_assert_same<Iter1::difference_type, std::ptrdiff_t>::value;
242 #if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
243 BOOST_STATIC_ASSERT((boost::is_convertible<Iter1::iterator_category, std::random_access_iterator_tag>::value));
244 #endif
245 }
246
247 {
248 // Test computation of default when the Value is const
249 typedef ptr_iterator<int const> Iter1;
250 test = static_assert_same<Iter1::value_type, int>::value;
251 test = static_assert_same<Iter1::reference, const int&>::value;
252
253 #if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
254 BOOST_STATIC_ASSERT(boost::is_readable_iterator<Iter1>::value);
255 # ifndef BOOST_NO_LVALUE_RETURN_DETECTION
256 BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<Iter1>::value);
257 # endif
258 #endif
259
260 #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) // borland drops constness
261 test = static_assert_same<Iter1::pointer, int const*>::value;
262 #endif
263 }
264
265 {
266 // Test constant iterator idiom
267 typedef ptr_iterator<int> BaseIter;
268 typedef constant_iterator<BaseIter> Iter;
269
270 test = static_assert_same<Iter::value_type, int>::value;
271 test = static_assert_same<Iter::reference, int const&>::value;
272 #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) // borland drops constness
273 test = static_assert_same<Iter::pointer, int const*>::value;
274 #endif
275
276 #ifndef BOOST_NO_LVALUE_RETURN_DETECTION
277 BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<BaseIter>::value);
278 BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<Iter>::value);
279 #endif
280
281 typedef modify_traversal<BaseIter, boost::incrementable_traversal_tag> IncrementableIter;
282
283 static_assert_traversal<BaseIter,boost::random_access_traversal_tag>();
284 static_assert_traversal<IncrementableIter,boost::incrementable_traversal_tag>();
285 }
286
287 // Test the iterator_adaptor
288 {
289 ptr_iterator<dummyT> i(array);
290 boost::random_access_iterator_test(i, N, array);
291
292 ptr_iterator<const dummyT> j(array);
293 boost::random_access_iterator_test(j, N, array);
294 boost::const_nonconst_iterator_test(i, ++j);
295 }
296
297 // check operator-> with a forward iterator
298 {
299 boost::forward_iterator_archetype<dummyT> forward_iter;
300
301 typedef fwd_iterator<dummyT> adaptor_type;
302
303 adaptor_type i(forward_iter);
304 int zero = 0;
305 if (zero) // don't do this, just make sure it compiles
306 BOOST_TEST((*i).m_x == i->foo());
307 }
308
309 // check operator-> with an input iterator
310 {
311 boost::input_iterator_archetype_no_proxy<dummyT> input_iter;
312 typedef in_iterator<dummyT> adaptor_type;
313 adaptor_type i(input_iter);
314 int zero = 0;
315 if (zero) // don't do this, just make sure it compiles
316 BOOST_TEST((*i).m_x == i->foo());
317 }
318
319 // check that base_type is correct
320 {
321 // Test constant iterator idiom
322 typedef ptr_iterator<int> BaseIter;
323
324 test = static_assert_same<BaseIter::base_type,int*>::value;
325 test = static_assert_same<constant_iterator<BaseIter>::base_type,BaseIter>::value;
326
327 typedef modify_traversal<BaseIter, boost::incrementable_traversal_tag> IncrementableIter;
328
329 test = static_assert_same<IncrementableIter::base_type,BaseIter>::value;
330 }
331
332 std::cout << "test successful " << std::endl;
333 (void)test;
334 return boost::report_errors();
335 }