1 /* Copyright 2003-2007 Joaquín M López Muñoz.
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)
6 * See http://www.boost.org/libs/multi_index for library home page.
9 #ifndef BOOST_MULTI_INDEX_DETAIL_ITER_ADAPTOR_HPP
10 #define BOOST_MULTI_INDEX_DETAIL_ITER_ADAPTOR_HPP
12 #if defined(_MSC_VER)&&(_MSC_VER>=1200)
16 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
17 #include <boost/mpl/apply.hpp>
18 #include <boost/multi_index/detail/prevent_eti.hpp>
19 #include <boost/operators.hpp>
23 namespace multi_index{
27 /* Poor man's version of boost::iterator_adaptor. Used instead of the
28 * original as compile times for the latter are significantly higher.
29 * The interface is not replicated exactly, only to the extent necessary
30 * for internal consumption.
33 /* NB. The purpose of the (non-inclass) global operators ==, < and - defined
34 * above is to partially alleviate a problem of MSVC++ 6.0 by * which
35 * friend-injected operators on T are not visible if T is instantiated only
36 * in template code where T is a dependent type.
39 class iter_adaptor_access
43 static typename Class::reference dereference(const Class& x)
45 return x.dereference();
49 static bool equal(const Class& x,const Class& y)
55 static void increment(Class& x)
61 static void decrement(Class& x)
67 static void advance(Class& x,typename Class::difference_type n)
73 static typename Class::difference_type distance_to(
74 const Class& x,const Class& y)
76 return x.distance_to(y);
80 template<typename Category>
81 struct iter_adaptor_selector;
83 template<class Derived,class Base>
84 class forward_iter_adaptor_base:
85 public forward_iterator_helper<
87 typename Base::value_type,
88 typename Base::difference_type,
89 typename Base::pointer,
90 typename Base::reference>
93 typedef typename Base::reference reference;
95 reference operator*()const
97 return iter_adaptor_access::dereference(final());
100 friend bool operator==(const Derived& x,const Derived& y)
102 return iter_adaptor_access::equal(x,y);
105 Derived& operator++()
107 iter_adaptor_access::increment(final());
112 Derived& final(){return *static_cast<Derived*>(this);}
113 const Derived& final()const{return *static_cast<const Derived*>(this);}
116 template<class Derived,class Base>
118 const forward_iter_adaptor_base<Derived,Base>& x,
119 const forward_iter_adaptor_base<Derived,Base>& y)
121 return iter_adaptor_access::equal(
122 static_cast<const Derived&>(x),static_cast<const Derived&>(y));
126 struct iter_adaptor_selector<std::forward_iterator_tag>
128 template<class Derived,class Base>
131 typedef forward_iter_adaptor_base<Derived,Base> type;
135 template<class Derived,class Base>
136 class bidirectional_iter_adaptor_base:
137 public bidirectional_iterator_helper<
139 typename Base::value_type,
140 typename Base::difference_type,
141 typename Base::pointer,
142 typename Base::reference>
145 typedef typename Base::reference reference;
147 reference operator*()const
149 return iter_adaptor_access::dereference(final());
152 friend bool operator==(const Derived& x,const Derived& y)
154 return iter_adaptor_access::equal(x,y);
157 Derived& operator++()
159 iter_adaptor_access::increment(final());
163 Derived& operator--()
165 iter_adaptor_access::decrement(final());
170 Derived& final(){return *static_cast<Derived*>(this);}
171 const Derived& final()const{return *static_cast<const Derived*>(this);}
174 template<class Derived,class Base>
176 const bidirectional_iter_adaptor_base<Derived,Base>& x,
177 const bidirectional_iter_adaptor_base<Derived,Base>& y)
179 return iter_adaptor_access::equal(
180 static_cast<const Derived&>(x),static_cast<const Derived&>(y));
184 struct iter_adaptor_selector<std::bidirectional_iterator_tag>
186 template<class Derived,class Base>
189 typedef bidirectional_iter_adaptor_base<Derived,Base> type;
193 template<class Derived,class Base>
194 class random_access_iter_adaptor_base:
195 public random_access_iterator_helper<
197 typename Base::value_type,
198 typename Base::difference_type,
199 typename Base::pointer,
200 typename Base::reference>
203 typedef typename Base::reference reference;
204 typedef typename Base::difference_type difference_type;
206 reference operator*()const
208 return iter_adaptor_access::dereference(final());
211 friend bool operator==(const Derived& x,const Derived& y)
213 return iter_adaptor_access::equal(x,y);
216 friend bool operator<(const Derived& x,const Derived& y)
218 return iter_adaptor_access::distance_to(x,y)>0;
221 Derived& operator++()
223 iter_adaptor_access::increment(final());
227 Derived& operator--()
229 iter_adaptor_access::decrement(final());
233 Derived& operator+=(difference_type n)
235 iter_adaptor_access::advance(final(),n);
239 Derived& operator-=(difference_type n)
241 iter_adaptor_access::advance(final(),-n);
245 friend difference_type operator-(const Derived& x,const Derived& y)
247 return iter_adaptor_access::distance_to(y,x);
251 Derived& final(){return *static_cast<Derived*>(this);}
252 const Derived& final()const{return *static_cast<const Derived*>(this);}
255 template<class Derived,class Base>
257 const random_access_iter_adaptor_base<Derived,Base>& x,
258 const random_access_iter_adaptor_base<Derived,Base>& y)
260 return iter_adaptor_access::equal(
261 static_cast<const Derived&>(x),static_cast<const Derived&>(y));
264 template<class Derived,class Base>
266 const random_access_iter_adaptor_base<Derived,Base>& x,
267 const random_access_iter_adaptor_base<Derived,Base>& y)
269 return iter_adaptor_access::distance_to(
270 static_cast<const Derived&>(x),static_cast<const Derived&>(y))>0;
273 template<class Derived,class Base>
274 typename random_access_iter_adaptor_base<Derived,Base>::difference_type
276 const random_access_iter_adaptor_base<Derived,Base>& x,
277 const random_access_iter_adaptor_base<Derived,Base>& y)
279 return iter_adaptor_access::distance_to(
280 static_cast<const Derived&>(y),static_cast<const Derived&>(x));
284 struct iter_adaptor_selector<std::random_access_iterator_tag>
286 template<class Derived,class Base>
289 typedef random_access_iter_adaptor_base<Derived,Base> type;
293 template<class Derived,class Base>
294 struct iter_adaptor_base
296 typedef iter_adaptor_selector<
297 typename Base::iterator_category> selector;
298 typedef typename prevent_eti<
300 typename mpl::apply2<
301 selector,Derived,Base>::type
305 template<class Derived,class Base>
306 class iter_adaptor:public iter_adaptor_base<Derived,Base>::type
310 explicit iter_adaptor(const Base& b_):b(b_){}
312 const Base& base_reference()const{return b;}
313 Base& base_reference(){return b;}
319 } /* namespace multi_index::detail */
321 } /* namespace multi_index */
323 } /* namespace boost */