]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/multi_index/detail/iter_adaptor.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / multi_index / detail / iter_adaptor.hpp
1 /* Copyright 2003-2013 Joaquin M Lopez Munoz.
2 * Distributed under the Boost Software License, Version 1.0.
3 * (See 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/libs/multi_index for library home page.
7 */
8
9 #ifndef BOOST_MULTI_INDEX_DETAIL_ITER_ADAPTOR_HPP
10 #define BOOST_MULTI_INDEX_DETAIL_ITER_ADAPTOR_HPP
11
12 #if defined(_MSC_VER)
13 #pragma once
14 #endif
15
16 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
17 #include <boost/mpl/apply.hpp>
18 #include <boost/operators.hpp>
19
20 namespace boost{
21
22 namespace multi_index{
23
24 namespace detail{
25
26 /* Poor man's version of boost::iterator_adaptor. Used instead of the
27 * original as compile times for the latter are significantly higher.
28 * The interface is not replicated exactly, only to the extent necessary
29 * for internal consumption.
30 */
31
32 /* NB. The purpose of the (non-inclass) global operators ==, < and - defined
33 * above is to partially alleviate a problem of MSVC++ 6.0 by * which
34 * friend-injected operators on T are not visible if T is instantiated only
35 * in template code where T is a dependent type.
36 */
37
38 class iter_adaptor_access
39 {
40 public:
41 template<class Class>
42 static typename Class::reference dereference(const Class& x)
43 {
44 return x.dereference();
45 }
46
47 template<class Class>
48 static bool equal(const Class& x,const Class& y)
49 {
50 return x.equal(y);
51 }
52
53 template<class Class>
54 static void increment(Class& x)
55 {
56 x.increment();
57 }
58
59 template<class Class>
60 static void decrement(Class& x)
61 {
62 x.decrement();
63 }
64
65 template<class Class>
66 static void advance(Class& x,typename Class::difference_type n)
67 {
68 x.advance(n);
69 }
70
71 template<class Class>
72 static typename Class::difference_type distance_to(
73 const Class& x,const Class& y)
74 {
75 return x.distance_to(y);
76 }
77 };
78
79 template<typename Category>
80 struct iter_adaptor_selector;
81
82 template<class Derived,class Base>
83 class forward_iter_adaptor_base:
84 public forward_iterator_helper<
85 Derived,
86 typename Base::value_type,
87 typename Base::difference_type,
88 typename Base::pointer,
89 typename Base::reference>
90 {
91 public:
92 typedef typename Base::reference reference;
93
94 reference operator*()const
95 {
96 return iter_adaptor_access::dereference(final());
97 }
98
99 friend bool operator==(const Derived& x,const Derived& y)
100 {
101 return iter_adaptor_access::equal(x,y);
102 }
103
104 Derived& operator++()
105 {
106 iter_adaptor_access::increment(final());
107 return final();
108 }
109
110 private:
111 Derived& final(){return *static_cast<Derived*>(this);}
112 const Derived& final()const{return *static_cast<const Derived*>(this);}
113 };
114
115 template<class Derived,class Base>
116 bool operator==(
117 const forward_iter_adaptor_base<Derived,Base>& x,
118 const forward_iter_adaptor_base<Derived,Base>& y)
119 {
120 return iter_adaptor_access::equal(
121 static_cast<const Derived&>(x),static_cast<const Derived&>(y));
122 }
123
124 template<>
125 struct iter_adaptor_selector<std::forward_iterator_tag>
126 {
127 template<class Derived,class Base>
128 struct apply
129 {
130 typedef forward_iter_adaptor_base<Derived,Base> type;
131 };
132 };
133
134 template<class Derived,class Base>
135 class bidirectional_iter_adaptor_base:
136 public bidirectional_iterator_helper<
137 Derived,
138 typename Base::value_type,
139 typename Base::difference_type,
140 typename Base::pointer,
141 typename Base::reference>
142 {
143 public:
144 typedef typename Base::reference reference;
145
146 reference operator*()const
147 {
148 return iter_adaptor_access::dereference(final());
149 }
150
151 friend bool operator==(const Derived& x,const Derived& y)
152 {
153 return iter_adaptor_access::equal(x,y);
154 }
155
156 Derived& operator++()
157 {
158 iter_adaptor_access::increment(final());
159 return final();
160 }
161
162 Derived& operator--()
163 {
164 iter_adaptor_access::decrement(final());
165 return final();
166 }
167
168 private:
169 Derived& final(){return *static_cast<Derived*>(this);}
170 const Derived& final()const{return *static_cast<const Derived*>(this);}
171 };
172
173 template<class Derived,class Base>
174 bool operator==(
175 const bidirectional_iter_adaptor_base<Derived,Base>& x,
176 const bidirectional_iter_adaptor_base<Derived,Base>& y)
177 {
178 return iter_adaptor_access::equal(
179 static_cast<const Derived&>(x),static_cast<const Derived&>(y));
180 }
181
182 template<>
183 struct iter_adaptor_selector<std::bidirectional_iterator_tag>
184 {
185 template<class Derived,class Base>
186 struct apply
187 {
188 typedef bidirectional_iter_adaptor_base<Derived,Base> type;
189 };
190 };
191
192 template<class Derived,class Base>
193 class random_access_iter_adaptor_base:
194 public random_access_iterator_helper<
195 Derived,
196 typename Base::value_type,
197 typename Base::difference_type,
198 typename Base::pointer,
199 typename Base::reference>
200 {
201 public:
202 typedef typename Base::reference reference;
203 typedef typename Base::difference_type difference_type;
204
205 reference operator*()const
206 {
207 return iter_adaptor_access::dereference(final());
208 }
209
210 friend bool operator==(const Derived& x,const Derived& y)
211 {
212 return iter_adaptor_access::equal(x,y);
213 }
214
215 friend bool operator<(const Derived& x,const Derived& y)
216 {
217 return iter_adaptor_access::distance_to(x,y)>0;
218 }
219
220 Derived& operator++()
221 {
222 iter_adaptor_access::increment(final());
223 return final();
224 }
225
226 Derived& operator--()
227 {
228 iter_adaptor_access::decrement(final());
229 return final();
230 }
231
232 Derived& operator+=(difference_type n)
233 {
234 iter_adaptor_access::advance(final(),n);
235 return final();
236 }
237
238 Derived& operator-=(difference_type n)
239 {
240 iter_adaptor_access::advance(final(),-n);
241 return final();
242 }
243
244 friend difference_type operator-(const Derived& x,const Derived& y)
245 {
246 return iter_adaptor_access::distance_to(y,x);
247 }
248
249 private:
250 Derived& final(){return *static_cast<Derived*>(this);}
251 const Derived& final()const{return *static_cast<const Derived*>(this);}
252 };
253
254 template<class Derived,class Base>
255 bool operator==(
256 const random_access_iter_adaptor_base<Derived,Base>& x,
257 const random_access_iter_adaptor_base<Derived,Base>& y)
258 {
259 return iter_adaptor_access::equal(
260 static_cast<const Derived&>(x),static_cast<const Derived&>(y));
261 }
262
263 template<class Derived,class Base>
264 bool operator<(
265 const random_access_iter_adaptor_base<Derived,Base>& x,
266 const random_access_iter_adaptor_base<Derived,Base>& y)
267 {
268 return iter_adaptor_access::distance_to(
269 static_cast<const Derived&>(x),static_cast<const Derived&>(y))>0;
270 }
271
272 template<class Derived,class Base>
273 typename random_access_iter_adaptor_base<Derived,Base>::difference_type
274 operator-(
275 const random_access_iter_adaptor_base<Derived,Base>& x,
276 const random_access_iter_adaptor_base<Derived,Base>& y)
277 {
278 return iter_adaptor_access::distance_to(
279 static_cast<const Derived&>(y),static_cast<const Derived&>(x));
280 }
281
282 template<>
283 struct iter_adaptor_selector<std::random_access_iterator_tag>
284 {
285 template<class Derived,class Base>
286 struct apply
287 {
288 typedef random_access_iter_adaptor_base<Derived,Base> type;
289 };
290 };
291
292 template<class Derived,class Base>
293 struct iter_adaptor_base
294 {
295 typedef iter_adaptor_selector<
296 typename Base::iterator_category> selector;
297 typedef typename mpl::apply2<
298 selector,Derived,Base>::type type;
299 };
300
301 template<class Derived,class Base>
302 class iter_adaptor:public iter_adaptor_base<Derived,Base>::type
303 {
304 protected:
305 iter_adaptor(){}
306 explicit iter_adaptor(const Base& b_):b(b_){}
307
308 const Base& base_reference()const{return b;}
309 Base& base_reference(){return b;}
310
311 private:
312 Base b;
313 };
314
315 } /* namespace multi_index::detail */
316
317 } /* namespace multi_index */
318
319 } /* namespace boost */
320
321 #endif