Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:42:07

0001 /* Copyright 2003-2013 Joaquin M Lopez Munoz.
0002  * Distributed under the Boost Software License, Version 1.0.
0003  * (See accompanying file LICENSE_1_0.txt or copy at
0004  * http://www.boost.org/LICENSE_1_0.txt)
0005  *
0006  * See http://www.boost.org/libs/multi_index for library home page.
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 /* Poor man's version of boost::iterator_adaptor. Used instead of the
0027  * original as compile times for the latter are significantly higher.
0028  * The interface is not replicated exactly, only to the extent necessary
0029  * for internal consumption.
0030  */
0031 
0032 /* NB. The purpose of the (non-inclass) global operators ==, < and - defined
0033  * above is to partially alleviate a problem of MSVC++ 6.0 by * which
0034  * friend-injected operators on T are not visible if T is instantiated only
0035  * in template code where T is a dependent type.
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 } /* namespace multi_index::detail */
0316 
0317 } /* namespace multi_index */
0318 
0319 } /* namespace boost */
0320 
0321 #endif