File indexing completed on 2025-01-18 09:42:07
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_MULTI_INDEX_DETAIL_ITER_ADAPTOR_HPP
0010 #define BOOST_MULTI_INDEX_DETAIL_ITER_ADAPTOR_HPP
0011
0012 #if defined(_MSC_VER)
0013 #pragma once
0014 #endif
0015
0016 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
0017 #include <boost/mpl/apply.hpp>
0018 #include <boost/operators.hpp>
0019
0020 namespace boost{
0021
0022 namespace multi_index{
0023
0024 namespace detail{
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 class iter_adaptor_access
0039 {
0040 public:
0041 template<class Class>
0042 static typename Class::reference dereference(const Class& x)
0043 {
0044 return x.dereference();
0045 }
0046
0047 template<class Class>
0048 static bool equal(const Class& x,const Class& y)
0049 {
0050 return x.equal(y);
0051 }
0052
0053 template<class Class>
0054 static void increment(Class& x)
0055 {
0056 x.increment();
0057 }
0058
0059 template<class Class>
0060 static void decrement(Class& x)
0061 {
0062 x.decrement();
0063 }
0064
0065 template<class Class>
0066 static void advance(Class& x,typename Class::difference_type n)
0067 {
0068 x.advance(n);
0069 }
0070
0071 template<class Class>
0072 static typename Class::difference_type distance_to(
0073 const Class& x,const Class& y)
0074 {
0075 return x.distance_to(y);
0076 }
0077 };
0078
0079 template<typename Category>
0080 struct iter_adaptor_selector;
0081
0082 template<class Derived,class Base>
0083 class forward_iter_adaptor_base:
0084 public forward_iterator_helper<
0085 Derived,
0086 typename Base::value_type,
0087 typename Base::difference_type,
0088 typename Base::pointer,
0089 typename Base::reference>
0090 {
0091 public:
0092 typedef typename Base::reference reference;
0093
0094 reference operator*()const
0095 {
0096 return iter_adaptor_access::dereference(final());
0097 }
0098
0099 friend bool operator==(const Derived& x,const Derived& y)
0100 {
0101 return iter_adaptor_access::equal(x,y);
0102 }
0103
0104 Derived& operator++()
0105 {
0106 iter_adaptor_access::increment(final());
0107 return final();
0108 }
0109
0110 private:
0111 Derived& final(){return *static_cast<Derived*>(this);}
0112 const Derived& final()const{return *static_cast<const Derived*>(this);}
0113 };
0114
0115 template<class Derived,class Base>
0116 bool operator==(
0117 const forward_iter_adaptor_base<Derived,Base>& x,
0118 const forward_iter_adaptor_base<Derived,Base>& y)
0119 {
0120 return iter_adaptor_access::equal(
0121 static_cast<const Derived&>(x),static_cast<const Derived&>(y));
0122 }
0123
0124 template<>
0125 struct iter_adaptor_selector<std::forward_iterator_tag>
0126 {
0127 template<class Derived,class Base>
0128 struct apply
0129 {
0130 typedef forward_iter_adaptor_base<Derived,Base> type;
0131 };
0132 };
0133
0134 template<class Derived,class Base>
0135 class bidirectional_iter_adaptor_base:
0136 public bidirectional_iterator_helper<
0137 Derived,
0138 typename Base::value_type,
0139 typename Base::difference_type,
0140 typename Base::pointer,
0141 typename Base::reference>
0142 {
0143 public:
0144 typedef typename Base::reference reference;
0145
0146 reference operator*()const
0147 {
0148 return iter_adaptor_access::dereference(final());
0149 }
0150
0151 friend bool operator==(const Derived& x,const Derived& y)
0152 {
0153 return iter_adaptor_access::equal(x,y);
0154 }
0155
0156 Derived& operator++()
0157 {
0158 iter_adaptor_access::increment(final());
0159 return final();
0160 }
0161
0162 Derived& operator--()
0163 {
0164 iter_adaptor_access::decrement(final());
0165 return final();
0166 }
0167
0168 private:
0169 Derived& final(){return *static_cast<Derived*>(this);}
0170 const Derived& final()const{return *static_cast<const Derived*>(this);}
0171 };
0172
0173 template<class Derived,class Base>
0174 bool operator==(
0175 const bidirectional_iter_adaptor_base<Derived,Base>& x,
0176 const bidirectional_iter_adaptor_base<Derived,Base>& y)
0177 {
0178 return iter_adaptor_access::equal(
0179 static_cast<const Derived&>(x),static_cast<const Derived&>(y));
0180 }
0181
0182 template<>
0183 struct iter_adaptor_selector<std::bidirectional_iterator_tag>
0184 {
0185 template<class Derived,class Base>
0186 struct apply
0187 {
0188 typedef bidirectional_iter_adaptor_base<Derived,Base> type;
0189 };
0190 };
0191
0192 template<class Derived,class Base>
0193 class random_access_iter_adaptor_base:
0194 public random_access_iterator_helper<
0195 Derived,
0196 typename Base::value_type,
0197 typename Base::difference_type,
0198 typename Base::pointer,
0199 typename Base::reference>
0200 {
0201 public:
0202 typedef typename Base::reference reference;
0203 typedef typename Base::difference_type difference_type;
0204
0205 reference operator*()const
0206 {
0207 return iter_adaptor_access::dereference(final());
0208 }
0209
0210 friend bool operator==(const Derived& x,const Derived& y)
0211 {
0212 return iter_adaptor_access::equal(x,y);
0213 }
0214
0215 friend bool operator<(const Derived& x,const Derived& y)
0216 {
0217 return iter_adaptor_access::distance_to(x,y)>0;
0218 }
0219
0220 Derived& operator++()
0221 {
0222 iter_adaptor_access::increment(final());
0223 return final();
0224 }
0225
0226 Derived& operator--()
0227 {
0228 iter_adaptor_access::decrement(final());
0229 return final();
0230 }
0231
0232 Derived& operator+=(difference_type n)
0233 {
0234 iter_adaptor_access::advance(final(),n);
0235 return final();
0236 }
0237
0238 Derived& operator-=(difference_type n)
0239 {
0240 iter_adaptor_access::advance(final(),-n);
0241 return final();
0242 }
0243
0244 friend difference_type operator-(const Derived& x,const Derived& y)
0245 {
0246 return iter_adaptor_access::distance_to(y,x);
0247 }
0248
0249 private:
0250 Derived& final(){return *static_cast<Derived*>(this);}
0251 const Derived& final()const{return *static_cast<const Derived*>(this);}
0252 };
0253
0254 template<class Derived,class Base>
0255 bool operator==(
0256 const random_access_iter_adaptor_base<Derived,Base>& x,
0257 const random_access_iter_adaptor_base<Derived,Base>& y)
0258 {
0259 return iter_adaptor_access::equal(
0260 static_cast<const Derived&>(x),static_cast<const Derived&>(y));
0261 }
0262
0263 template<class Derived,class Base>
0264 bool operator<(
0265 const random_access_iter_adaptor_base<Derived,Base>& x,
0266 const random_access_iter_adaptor_base<Derived,Base>& y)
0267 {
0268 return iter_adaptor_access::distance_to(
0269 static_cast<const Derived&>(x),static_cast<const Derived&>(y))>0;
0270 }
0271
0272 template<class Derived,class Base>
0273 typename random_access_iter_adaptor_base<Derived,Base>::difference_type
0274 operator-(
0275 const random_access_iter_adaptor_base<Derived,Base>& x,
0276 const random_access_iter_adaptor_base<Derived,Base>& y)
0277 {
0278 return iter_adaptor_access::distance_to(
0279 static_cast<const Derived&>(y),static_cast<const Derived&>(x));
0280 }
0281
0282 template<>
0283 struct iter_adaptor_selector<std::random_access_iterator_tag>
0284 {
0285 template<class Derived,class Base>
0286 struct apply
0287 {
0288 typedef random_access_iter_adaptor_base<Derived,Base> type;
0289 };
0290 };
0291
0292 template<class Derived,class Base>
0293 struct iter_adaptor_base
0294 {
0295 typedef iter_adaptor_selector<
0296 typename Base::iterator_category> selector;
0297 typedef typename mpl::apply2<
0298 selector,Derived,Base>::type type;
0299 };
0300
0301 template<class Derived,class Base>
0302 class iter_adaptor:public iter_adaptor_base<Derived,Base>::type
0303 {
0304 protected:
0305 iter_adaptor(){}
0306 explicit iter_adaptor(const Base& b_):b(b_){}
0307
0308 const Base& base_reference()const{return b;}
0309 Base& base_reference(){return b;}
0310
0311 private:
0312 Base b;
0313 };
0314
0315 }
0316
0317 }
0318
0319 }
0320
0321 #endif