1 // Copyright David Abrahams 2004. Distributed under the Boost
2 // Software License, Version 1.0. (See accompanying
3 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 // This is really an incomplete test; should be fleshed out.
7 #include <boost/iterator/iterator_facade.hpp>
8 #include <boost/iterator/new_iterator_tests.hpp>
10 #include <boost/call_traits.hpp>
11 #include <boost/polymorphic_cast.hpp>
12 #include <boost/type_traits/is_convertible.hpp>
13 #include <boost/utility/enable_if.hpp>
15 // This is a really, really limited test so far. All we're doing
16 // right now is checking that the postfix++ proxy for single-pass
17 // iterators works properly.
19 class counter_iterator
20 : public boost::iterator_facade
<
23 , boost::single_pass_traversal_tag
29 counter_iterator(int* state
) : state(state
) {}
42 bool equal(counter_iterator
const& y
) const
44 return *this->state
== *y
.state
;
52 proxy(int& x
) : state(x
) {}
54 operator int const&() const
59 int& operator=(int x
) { state
= x
; return state
; }
66 void mutator() {} // non-const member function
70 : boost::iterator_facade
<
73 , boost::single_pass_traversal_tag
89 bool equal(input_iter
const&) const
99 explicit wrapper(typename
boost::call_traits
<T
>::param_type x
)
103 wrapper(const wrapper
<U
>& other
,
104 typename
boost::enable_if
< boost::is_convertible
<U
,T
> >::type
* = 0)
109 struct iterator_with_proxy_reference
110 : boost::iterator_facade
<
111 iterator_with_proxy_reference
113 , boost::incrementable_traversal_tag
118 explicit iterator_with_proxy_reference(int& x
)
124 wrapper
<int&> dereference() const
125 { return wrapper
<int&>(m_x
); }
128 template <class T
, class U
>
129 void same_type(U
const&)
130 { BOOST_MPL_ASSERT((boost::is_same
<T
,U
>)); }
132 template <class I
, class A
>
133 struct abstract_iterator
134 : boost::iterator_facade
<
135 abstract_iterator
<I
, A
>
137 // In order to be value type as a reference, traversal category has
138 // to satisfy least forward traversal.
139 , boost::forward_traversal_tag
143 abstract_iterator(I iter
) : iter(iter
) {}
148 A
& dereference() const
151 bool equal(abstract_iterator
const& y
) const
152 { return iter
== y
.iter
; }
159 virtual void assign(const base
&) = 0;
160 virtual bool equal(const base
&) const = 0;
163 struct derived
: base
165 derived(int state
) : state(state
) { }
166 derived(const derived
&d
) : state(d
.state
) { }
167 derived(const base
&b
) { derived::assign(b
); }
169 virtual void assign(const base
&b
)
171 state
= boost::polymorphic_cast
<const derived
*>(&b
)->state
;
174 virtual bool equal(const base
&b
) const
176 return state
== boost::polymorphic_cast
<const derived
*>(&b
)->state
;
182 inline bool operator==(const base
&lhs
, const base
&rhs
)
184 return lhs
.equal(rhs
);
191 boost::readable_iterator_test(counter_iterator
<int const&>(&state
), 0);
193 boost::readable_iterator_test(counter_iterator
<proxy
>(&state
), 3);
194 boost::writable_iterator_test(counter_iterator
<proxy
>(&state
), 9, 7);
195 BOOST_TEST(state
== 8);
199 // test for a fix to http://tinyurl.com/zuohe
200 // These two lines should be equivalent (and both compile)
205 same_type
<input_iter::pointer
>(p
.operator->());
210 iterator_with_proxy_reference
i(x
);
212 BOOST_TEST(i
.m_x
== 0);
215 BOOST_TEST(i
.m_x
== 1);
218 BOOST_TEST(i
.m_x
== 2);
223 boost::readable_iterator_test(abstract_iterator
<derived
*, base
>(&d
), derived(1));
226 return boost::report_errors();