williamr@2: /* Copyright 2003-2005 Joaquín M López Muñoz. williamr@2: * Distributed under the Boost Software License, Version 1.0. williamr@2: * (See accompanying file LICENSE_1_0.txt or copy at williamr@2: * http://www.boost.org/LICENSE_1_0.txt) williamr@2: * williamr@2: * See http://www.boost.org/libs/multi_index for library home page. williamr@2: */ williamr@2: williamr@2: #ifndef BOOST_MULTI_INDEX_DETAIL_ITER_ADAPTOR_HPP williamr@2: #define BOOST_MULTI_INDEX_DETAIL_ITER_ADAPTOR_HPP williamr@2: williamr@2: #if defined(_MSC_VER)&&(_MSC_VER>=1200) williamr@2: #pragma once williamr@2: #endif williamr@2: williamr@2: #include /* keep it first to prevent nasty warns in MSVC */ williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: williamr@2: namespace boost{ williamr@2: williamr@2: namespace multi_index{ williamr@2: williamr@2: namespace detail{ williamr@2: williamr@2: /* Poor man's version of boost::iterator_adaptor. Used instead of the williamr@2: * original as compile times for the latter are significantly higher. williamr@2: * The interface is not replicated exactly, only to the extent necessary williamr@2: * for internal consumption. williamr@2: */ williamr@2: williamr@2: class iter_adaptor_access williamr@2: { williamr@2: public: williamr@2: template williamr@2: static typename Class::reference dereference(const Class& x) williamr@2: { williamr@2: return x.dereference(); williamr@2: } williamr@2: williamr@2: template williamr@2: static bool equal(const Class& x,const Class& y) williamr@2: { williamr@2: return x.equal(y); williamr@2: } williamr@2: williamr@2: template williamr@2: static void increment(Class& x) williamr@2: { williamr@2: x.increment(); williamr@2: } williamr@2: williamr@2: template williamr@2: static void decrement(Class& x) williamr@2: { williamr@2: x.decrement(); williamr@2: } williamr@2: williamr@2: template williamr@2: static void advance(Class& x,typename Class::difference_type n) williamr@2: { williamr@2: x.advance(n); williamr@2: } williamr@2: williamr@2: template williamr@2: static typename Class::difference_type distance_to( williamr@2: const Class& x,const Class& y) williamr@2: { williamr@2: return x.distance_to(y); williamr@2: } williamr@2: }; williamr@2: williamr@2: template williamr@2: struct iter_adaptor_selector; williamr@2: williamr@2: template williamr@2: class forward_iter_adaptor_base: williamr@2: public forward_iterator_helper< williamr@2: Derived, williamr@2: typename Base::value_type, williamr@2: typename Base::difference_type, williamr@2: typename Base::pointer, williamr@2: typename Base::reference> williamr@2: { williamr@2: public: williamr@2: typedef typename Base::reference reference; williamr@2: williamr@2: reference operator*()const williamr@2: { williamr@2: return iter_adaptor_access::dereference(final()); williamr@2: } williamr@2: williamr@2: friend bool operator==(const Derived& x,const Derived& y) williamr@2: { williamr@2: return iter_adaptor_access::equal(x,y); williamr@2: } williamr@2: williamr@2: Derived& operator++() williamr@2: { williamr@2: iter_adaptor_access::increment(final()); williamr@2: return final(); williamr@2: } williamr@2: williamr@2: private: williamr@2: Derived& final(){return *static_cast(this);} williamr@2: const Derived& final()const{return *static_cast(this);} williamr@2: }; williamr@2: williamr@2: template<> williamr@2: struct iter_adaptor_selector williamr@2: { williamr@2: template williamr@2: struct apply williamr@2: { williamr@2: typedef forward_iter_adaptor_base type; williamr@2: }; williamr@2: }; williamr@2: williamr@2: template williamr@2: class bidirectional_iter_adaptor_base: williamr@2: public bidirectional_iterator_helper< williamr@2: Derived, williamr@2: typename Base::value_type, williamr@2: typename Base::difference_type, williamr@2: typename Base::pointer, williamr@2: typename Base::reference> williamr@2: { williamr@2: public: williamr@2: typedef typename Base::reference reference; williamr@2: williamr@2: reference operator*()const williamr@2: { williamr@2: return iter_adaptor_access::dereference(final()); williamr@2: } williamr@2: williamr@2: friend bool operator==(const Derived& x,const Derived& y) williamr@2: { williamr@2: return iter_adaptor_access::equal(x,y); williamr@2: } williamr@2: williamr@2: Derived& operator++() williamr@2: { williamr@2: iter_adaptor_access::increment(final()); williamr@2: return final(); williamr@2: } williamr@2: williamr@2: Derived& operator--() williamr@2: { williamr@2: iter_adaptor_access::decrement(final()); williamr@2: return final(); williamr@2: } williamr@2: williamr@2: private: williamr@2: Derived& final(){return *static_cast(this);} williamr@2: const Derived& final()const{return *static_cast(this);} williamr@2: }; williamr@2: williamr@2: template<> williamr@2: struct iter_adaptor_selector williamr@2: { williamr@2: template williamr@2: struct apply williamr@2: { williamr@2: typedef bidirectional_iter_adaptor_base type; williamr@2: }; williamr@2: }; williamr@2: williamr@2: template williamr@2: class random_access_iter_adaptor_base: williamr@2: public random_access_iterator_helper< williamr@2: Derived, williamr@2: typename Base::value_type, williamr@2: typename Base::difference_type, williamr@2: typename Base::pointer, williamr@2: typename Base::reference> williamr@2: { williamr@2: public: williamr@2: typedef typename Base::reference reference; williamr@2: typedef typename Base::difference_type difference_type; williamr@2: williamr@2: reference operator*()const williamr@2: { williamr@2: return iter_adaptor_access::dereference(final()); williamr@2: } williamr@2: williamr@2: friend bool operator==(const Derived& x,const Derived& y) williamr@2: { williamr@2: return iter_adaptor_access::equal(x,y); williamr@2: } williamr@2: williamr@2: friend bool operator<(const Derived& x,const Derived& y) williamr@2: { williamr@2: return iter_adaptor_access::distance_to(x,y)>0; williamr@2: } williamr@2: williamr@2: Derived& operator++() williamr@2: { williamr@2: iter_adaptor_access::increment(final()); williamr@2: return final(); williamr@2: } williamr@2: williamr@2: Derived& operator--() williamr@2: { williamr@2: iter_adaptor_access::decrement(final()); williamr@2: return final(); williamr@2: } williamr@2: williamr@2: Derived& operator+=(difference_type n) williamr@2: { williamr@2: iter_adaptor_access::advance(final(),n); williamr@2: return final(); williamr@2: } williamr@2: williamr@2: Derived& operator-=(difference_type n) williamr@2: { williamr@2: iter_adaptor_access::advance(final(),-n); williamr@2: return final(); williamr@2: } williamr@2: williamr@2: friend difference_type operator-(const Derived& x,const Derived& y) williamr@2: { williamr@2: return iter_adaptor_access::distance_to(y,x); williamr@2: } williamr@2: williamr@2: private: williamr@2: Derived& final(){return *static_cast(this);} williamr@2: const Derived& final()const{return *static_cast(this);} williamr@2: }; williamr@2: williamr@2: template<> williamr@2: struct iter_adaptor_selector williamr@2: { williamr@2: template williamr@2: struct apply williamr@2: { williamr@2: typedef random_access_iter_adaptor_base type; williamr@2: }; williamr@2: }; williamr@2: williamr@2: template williamr@2: struct iter_adaptor_base williamr@2: { williamr@2: typedef iter_adaptor_selector< williamr@2: typename Base::iterator_category> selector; williamr@2: typedef typename prevent_eti< williamr@2: selector, williamr@2: typename mpl::apply2< williamr@2: selector,Derived,Base>::type williamr@2: >::type type; williamr@2: }; williamr@2: williamr@2: template williamr@2: class iter_adaptor:public iter_adaptor_base::type williamr@2: { williamr@2: protected: williamr@2: iter_adaptor(){} williamr@2: explicit iter_adaptor(const Base& b_):b(b_){} williamr@2: williamr@2: const Base& base_reference()const{return b;} williamr@2: Base& base_reference(){return b;} williamr@2: williamr@2: private: williamr@2: Base b; williamr@2: }; williamr@2: williamr@2: } /* namespace multi_index::detail */ williamr@2: williamr@2: } /* namespace multi_index */ williamr@2: williamr@2: } /* namespace boost */ williamr@2: williamr@2: #endif