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)
6 // See http://www.boost.org for most recent version including documentation.
8 #include <boost/config.hpp>
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>
20 #include <boost/pending/iterator_tests.hpp>
22 # include <boost/detail/lightweight_test.hpp>
30 #include "static_assert_same.hpp"
32 #include <boost/iterator/detail/config_def.hpp>
36 typedef std::deque
<int> storage
;
37 typedef std::deque
<int*> pointer_deque
;
38 typedef std::set
<storage::iterator
> iterator_set
;
40 template <class T
> struct foo
;
46 typedef int result_type
;
48 int operator()() { return ++n
; }
54 : boost::iterator_adaptor
<
58 , boost::random_access_traversal_tag
59 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
65 typedef boost::iterator_adaptor
<
69 , boost::random_access_traversal_tag
70 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
77 ptr_iterator(V
* d
) : super_t(d
) { }
81 const ptr_iterator
<V2
>& x
82 , typename
boost::enable_if_convertible
<V2
*, V
*>::type
* = 0
88 // Non-functional iterator for category modification checking
89 template <class Iter
, class Traversal
>
90 struct modify_traversal
91 : boost::iterator_adaptor
<
92 modify_traversal
<Iter
, Traversal
>
101 : boost::iterator_adaptor
<
103 , boost::forward_iterator_archetype
<T
>
107 typedef boost::iterator_adaptor
<
109 , boost::forward_iterator_archetype
<T
>
114 fwd_iterator(boost::forward_iterator_archetype
<T
> d
) : super_t(d
) { }
119 : boost::iterator_adaptor
<
121 , boost::input_iterator_archetype_no_proxy
<T
>
125 typedef boost::iterator_adaptor
<
127 , boost::input_iterator_archetype_no_proxy
<T
>
132 in_iterator(boost::input_iterator_archetype_no_proxy
<T
> d
) : super_t(d
) { }
135 template <class Iter
>
136 struct constant_iterator
137 : boost::iterator_adaptor
<
138 constant_iterator
<Iter
>
140 , typename
std::iterator_traits
<Iter
>::value_type
const
143 typedef boost::iterator_adaptor
<
144 constant_iterator
<Iter
>
146 , typename
std::iterator_traits
<Iter
>::value_type
const
149 constant_iterator() {}
150 constant_iterator(Iter it
)
154 char (& traversal2(boost::incrementable_traversal_tag
) )[1];
155 char (& traversal2(boost::single_pass_traversal_tag
) )[2];
156 char (& traversal2(boost::forward_traversal_tag
) )[3];
157 char (& traversal2(boost::bidirectional_traversal_tag
) )[4];
158 char (& traversal2(boost::random_access_traversal_tag
) )[5];
163 static typename
boost::iterator_category_to_traversal
<Cat
>::type x
;
164 BOOST_STATIC_CONSTANT(std::size_t, value
= sizeof(traversal2(x
)));
165 typedef char (&type
)[value
];
169 typename traversal3
<Cat
>::type
traversal(Cat
);
171 template <class Iter
, class Trav
>
172 int static_assert_traversal(Iter
* = 0, Trav
* = 0)
174 typedef typename
boost::iterator_category_to_traversal
<
175 BOOST_DEDUCED_TYPENAME
Iter::iterator_category
178 return static_assert_same
<Trav
,t2
>::value
;
184 dummyT array
[] = { dummyT(0), dummyT(1), dummyT(2),
185 dummyT(3), dummyT(4), dummyT(5) };
186 const int N
= sizeof(array
)/sizeof(dummyT
);
188 // sanity check, if this doesn't pass the test is buggy
189 boost::random_access_iterator_test(array
, N
, array
);
191 // Test the iterator_adaptor
193 ptr_iterator
<dummyT
> i(array
);
194 boost::random_access_iterator_test(i
, N
, array
);
196 ptr_iterator
<const dummyT
> j(array
);
197 boost::random_access_iterator_test(j
, N
, array
);
198 boost::const_nonconst_iterator_test(i
, ++j
);
202 // Test the iterator_traits
204 // Test computation of defaults
205 typedef ptr_iterator
<int> Iter1
;
206 // don't use std::iterator_traits here to avoid VC++ problems
207 test
= static_assert_same
<Iter1::value_type
, int>::value
;
208 test
= static_assert_same
<Iter1::reference
, int&>::value
;
209 test
= static_assert_same
<Iter1::pointer
, int*>::value
;
210 test
= static_assert_same
<Iter1::difference_type
, std::ptrdiff_t>::value
;
211 #if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
212 BOOST_STATIC_ASSERT((boost::is_convertible
<Iter1::iterator_category
, std::random_access_iterator_tag
>::value
));
217 // Test computation of default when the Value is const
218 typedef ptr_iterator
<int const> Iter1
;
219 test
= static_assert_same
<Iter1::value_type
, int>::value
;
220 test
= static_assert_same
<Iter1::reference
, const int&>::value
;
222 #if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
223 BOOST_STATIC_ASSERT(boost::is_readable_iterator
<Iter1
>::value
);
224 # ifndef BOOST_NO_LVALUE_RETURN_DETECTION
225 BOOST_STATIC_ASSERT(boost::is_lvalue_iterator
<Iter1
>::value
);
229 #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) // borland drops constness
230 test
= static_assert_same
<Iter1::pointer
, int const*>::value
;
235 // Test constant iterator idiom
236 typedef ptr_iterator
<int> BaseIter
;
237 typedef constant_iterator
<BaseIter
> Iter
;
239 test
= static_assert_same
<Iter::value_type
, int>::value
;
240 test
= static_assert_same
<Iter::reference
, int const&>::value
;
241 #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) // borland drops constness
242 test
= static_assert_same
<Iter::pointer
, int const*>::value
;
245 #ifndef BOOST_NO_LVALUE_RETURN_DETECTION
246 BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator
<BaseIter
>::value
);
247 BOOST_STATIC_ASSERT(boost::is_lvalue_iterator
<Iter
>::value
);
250 typedef modify_traversal
<BaseIter
, boost::incrementable_traversal_tag
> IncrementableIter
;
252 static_assert_traversal
<BaseIter
,boost::random_access_traversal_tag
>();
253 static_assert_traversal
<IncrementableIter
,boost::incrementable_traversal_tag
>();
256 // Test the iterator_adaptor
258 ptr_iterator
<dummyT
> i(array
);
259 boost::random_access_iterator_test(i
, N
, array
);
261 ptr_iterator
<const dummyT
> j(array
);
262 boost::random_access_iterator_test(j
, N
, array
);
263 boost::const_nonconst_iterator_test(i
, ++j
);
266 // check operator-> with a forward iterator
268 boost::forward_iterator_archetype
<dummyT
> forward_iter
;
270 typedef fwd_iterator
<dummyT
> adaptor_type
;
272 adaptor_type
i(forward_iter
);
274 if (zero
) // don't do this, just make sure it compiles
275 BOOST_TEST((*i
).m_x
== i
->foo());
278 // check operator-> with an input iterator
280 boost::input_iterator_archetype_no_proxy
<dummyT
> input_iter
;
281 typedef in_iterator
<dummyT
> adaptor_type
;
282 adaptor_type
i(input_iter
);
284 if (zero
) // don't do this, just make sure it compiles
285 BOOST_TEST((*i
).m_x
== i
->foo());
288 // check that base_type is correct
290 // Test constant iterator idiom
291 typedef ptr_iterator
<int> BaseIter
;
293 test
= static_assert_same
<BaseIter::base_type
,int*>::value
;
294 test
= static_assert_same
<constant_iterator
<BaseIter
>::base_type
,BaseIter
>::value
;
296 typedef modify_traversal
<BaseIter
, boost::incrementable_traversal_tag
> IncrementableIter
;
298 test
= static_assert_same
<IncrementableIter::base_type
,BaseIter
>::value
;
301 std::cout
<< "test successful " << std::endl
;
303 return boost::report_errors();