]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/iterator/test/iterator_facade.cpp
bump version to 19.2.0-pve1
[ceph.git] / ceph / src / boost / libs / iterator / test / iterator_facade.cpp
CommitLineData
7c673cae
FG
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)
4
5// This is really an incomplete test; should be fleshed out.
6
7#include <boost/iterator/iterator_facade.hpp>
8#include <boost/iterator/new_iterator_tests.hpp>
9
10#include <boost/call_traits.hpp>
11#include <boost/polymorphic_cast.hpp>
12#include <boost/type_traits/is_convertible.hpp>
f51cf556 13#include <boost/core/enable_if.hpp>
7c673cae
FG
14
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.
18template <class Ref>
19class counter_iterator
20 : public boost::iterator_facade<
21 counter_iterator<Ref>
22 , int const
23 , boost::single_pass_traversal_tag
24 , Ref
25 >
26{
27 public:
28 counter_iterator() {}
29 counter_iterator(int* state) : state(state) {}
30
31 void increment()
32 {
33 ++*state;
34 }
35
36 Ref
37 dereference() const
38 {
39 return *state;
40 }
41
42 bool equal(counter_iterator const& y) const
43 {
44 return *this->state == *y.state;
45 }
46
47 int* state;
48};
49
50struct proxy
51{
52 proxy(int& x) : state(x) {}
53
54 operator int const&() const
55 {
56 return state;
57 }
58
59 int& operator=(int x) { state = x; return state; }
60
61 int& state;
62};
63
64struct value
65{
f51cf556
TL
66 int increment_count;
67 int private_mutator_count;
68 int& shared_mutator_count;
69
70 explicit value(int& shared_mutator_count) :
71 increment_count(0),
72 private_mutator_count(0),
73 shared_mutator_count(shared_mutator_count)
74 {
75 }
76
77 // non-const member function
78 void mutator()
79 {
80 ++private_mutator_count;
81 ++shared_mutator_count;
82 }
7c673cae
FG
83};
84
85struct input_iter
86 : boost::iterator_facade<
87 input_iter
88 , value
89 , boost::single_pass_traversal_tag
90 , value
91 >
92{
93 public:
f51cf556 94 explicit input_iter(value& val) : state(&val) {}
7c673cae
FG
95
96 void increment()
97 {
f51cf556 98 ++(state->increment_count);
7c673cae
FG
99 }
100 value
101 dereference() const
102 {
f51cf556 103 return *state;
7c673cae
FG
104 }
105
b32b8144 106 bool equal(input_iter const&) const
7c673cae
FG
107 {
108 return false;
109 }
f51cf556
TL
110
111 private:
112 value* state;
7c673cae
FG
113};
114
115template <class T>
116struct wrapper
117{
118 T m_x;
119 explicit wrapper(typename boost::call_traits<T>::param_type x)
120 : m_x(x)
121 { }
122 template <class U>
123 wrapper(const wrapper<U>& other,
124 typename boost::enable_if< boost::is_convertible<U,T> >::type* = 0)
125 : m_x(other.m_x)
126 { }
127};
128
129struct iterator_with_proxy_reference
130 : boost::iterator_facade<
131 iterator_with_proxy_reference
132 , wrapper<int>
133 , boost::incrementable_traversal_tag
134 , wrapper<int&>
135 >
136{
137 int& m_x;
138 explicit iterator_with_proxy_reference(int& x)
139 : m_x(x)
140 { }
141
142 void increment()
143 { }
144 wrapper<int&> dereference() const
145 { return wrapper<int&>(m_x); }
146};
147
148template <class T, class U>
149void same_type(U const&)
150{ BOOST_MPL_ASSERT((boost::is_same<T,U>)); }
151
152template <class I, class A>
153struct abstract_iterator
154 : boost::iterator_facade<
155 abstract_iterator<I, A>
156 , A &
157 // In order to be value type as a reference, traversal category has
158 // to satisfy least forward traversal.
159 , boost::forward_traversal_tag
160 , A &
161 >
162{
163 abstract_iterator(I iter) : iter(iter) {}
164
165 void increment()
166 { ++iter; }
167
168 A & dereference() const
169 { return *iter; }
170
171 bool equal(abstract_iterator const& y) const
172 { return iter == y.iter; }
173
174 I iter;
175};
176
177struct base
178{
179 virtual void assign(const base &) = 0;
180 virtual bool equal(const base &) const = 0;
181};
182
183struct derived : base
184{
185 derived(int state) : state(state) { }
186 derived(const derived &d) : state(d.state) { }
187 derived(const base &b) { derived::assign(b); }
188
189 virtual void assign(const base &b)
190 {
191 state = boost::polymorphic_cast<const derived *>(&b)->state;
192 }
193
194 virtual bool equal(const base &b) const
195 {
196 return state == boost::polymorphic_cast<const derived *>(&b)->state;
197 }
198
199 int state;
200};
201
202inline bool operator==(const base &lhs, const base &rhs)
203{
204 return lhs.equal(rhs);
205}
206
207int main()
208{
209 {
210 int state = 0;
211 boost::readable_iterator_test(counter_iterator<int const&>(&state), 0);
212 state = 3;
213 boost::readable_iterator_test(counter_iterator<proxy>(&state), 3);
214 boost::writable_iterator_test(counter_iterator<proxy>(&state), 9, 7);
215 BOOST_TEST(state == 8);
216 }
217
218 {
219 // test for a fix to http://tinyurl.com/zuohe
220 // These two lines should be equivalent (and both compile)
f51cf556
TL
221 int shared_mutator_count = 0;
222 value val(shared_mutator_count);
223 input_iter p(val);
7c673cae
FG
224 (*p).mutator();
225 p->mutator();
f51cf556
TL
226 BOOST_TEST_EQ(val.increment_count, 0);
227 BOOST_TEST_EQ(val.private_mutator_count, 0); // mutator() should be invoked on an object returned by value
228 BOOST_TEST_EQ(shared_mutator_count, 2);
7c673cae
FG
229
230 same_type<input_iter::pointer>(p.operator->());
231 }
232
f51cf556
TL
233 {
234 // Test that accessing dereferenced value of a post-incremented iterator works
235 int shared_mutator_count = 0;
236 value val(shared_mutator_count);
237 input_iter p(val);
238 (*p++).mutator();
239 (p++)->mutator();
240 BOOST_TEST_EQ(val.increment_count, 2);
241 BOOST_TEST_EQ(val.private_mutator_count, 0); // mutator() should be invoked on an object returned by value
242 BOOST_TEST_EQ(shared_mutator_count, 2);
243 }
244
7c673cae
FG
245 {
246 int x = 0;
247 iterator_with_proxy_reference i(x);
248 BOOST_TEST(x == 0);
249 BOOST_TEST(i.m_x == 0);
250 ++(*i).m_x;
251 BOOST_TEST(x == 1);
252 BOOST_TEST(i.m_x == 1);
253 ++i->m_x;
254 BOOST_TEST(x == 2);
255 BOOST_TEST(i.m_x == 2);
256 }
257
258 {
259 derived d(1);
260 boost::readable_iterator_test(abstract_iterator<derived *, base>(&d), derived(1));
261 }
262
263 return boost::report_errors();
264}