Chris@101: /* Copyright 2003-2013 Joaquin M Lopez Munoz. Chris@16: * Distributed under the Boost Software License, Version 1.0. Chris@16: * (See accompanying file LICENSE_1_0.txt or copy at Chris@16: * http://www.boost.org/LICENSE_1_0.txt) Chris@16: * Chris@16: * See http://www.boost.org/libs/multi_index for library home page. Chris@16: */ Chris@16: Chris@16: #ifndef BOOST_MULTI_INDEX_DETAIL_ITER_ADAPTOR_HPP Chris@16: #define BOOST_MULTI_INDEX_DETAIL_ITER_ADAPTOR_HPP Chris@16: Chris@101: #if defined(_MSC_VER) Chris@16: #pragma once Chris@16: #endif Chris@16: Chris@16: #include /* keep it first to prevent nasty warns in MSVC */ Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost{ Chris@16: Chris@16: namespace multi_index{ Chris@16: Chris@16: namespace detail{ Chris@16: Chris@16: /* Poor man's version of boost::iterator_adaptor. Used instead of the Chris@16: * original as compile times for the latter are significantly higher. Chris@16: * The interface is not replicated exactly, only to the extent necessary Chris@16: * for internal consumption. Chris@16: */ Chris@16: Chris@16: /* NB. The purpose of the (non-inclass) global operators ==, < and - defined Chris@16: * above is to partially alleviate a problem of MSVC++ 6.0 by * which Chris@16: * friend-injected operators on T are not visible if T is instantiated only Chris@16: * in template code where T is a dependent type. Chris@16: */ Chris@16: Chris@16: class iter_adaptor_access Chris@16: { Chris@16: public: Chris@16: template Chris@16: static typename Class::reference dereference(const Class& x) Chris@16: { Chris@16: return x.dereference(); Chris@16: } Chris@16: Chris@16: template Chris@16: static bool equal(const Class& x,const Class& y) Chris@16: { Chris@16: return x.equal(y); Chris@16: } Chris@16: Chris@16: template Chris@16: static void increment(Class& x) Chris@16: { Chris@16: x.increment(); Chris@16: } Chris@16: Chris@16: template Chris@16: static void decrement(Class& x) Chris@16: { Chris@16: x.decrement(); Chris@16: } Chris@16: Chris@16: template Chris@16: static void advance(Class& x,typename Class::difference_type n) Chris@16: { Chris@16: x.advance(n); Chris@16: } Chris@16: Chris@16: template Chris@16: static typename Class::difference_type distance_to( Chris@16: const Class& x,const Class& y) Chris@16: { Chris@16: return x.distance_to(y); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct iter_adaptor_selector; Chris@16: Chris@16: template Chris@16: class forward_iter_adaptor_base: Chris@16: public forward_iterator_helper< Chris@16: Derived, Chris@16: typename Base::value_type, Chris@16: typename Base::difference_type, Chris@16: typename Base::pointer, Chris@16: typename Base::reference> Chris@16: { Chris@16: public: Chris@16: typedef typename Base::reference reference; Chris@16: Chris@16: reference operator*()const Chris@16: { Chris@16: return iter_adaptor_access::dereference(final()); Chris@16: } Chris@16: Chris@16: friend bool operator==(const Derived& x,const Derived& y) Chris@16: { Chris@16: return iter_adaptor_access::equal(x,y); Chris@16: } Chris@16: Chris@16: Derived& operator++() Chris@16: { Chris@16: iter_adaptor_access::increment(final()); Chris@16: return final(); Chris@16: } Chris@16: Chris@16: private: Chris@16: Derived& final(){return *static_cast(this);} Chris@16: const Derived& final()const{return *static_cast(this);} Chris@16: }; Chris@16: Chris@16: template Chris@16: bool operator==( Chris@16: const forward_iter_adaptor_base& x, Chris@16: const forward_iter_adaptor_base& y) Chris@16: { Chris@16: return iter_adaptor_access::equal( Chris@16: static_cast(x),static_cast(y)); Chris@16: } Chris@16: Chris@16: template<> Chris@16: struct iter_adaptor_selector Chris@16: { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef forward_iter_adaptor_base type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template Chris@16: class bidirectional_iter_adaptor_base: Chris@16: public bidirectional_iterator_helper< Chris@16: Derived, Chris@16: typename Base::value_type, Chris@16: typename Base::difference_type, Chris@16: typename Base::pointer, Chris@16: typename Base::reference> Chris@16: { Chris@16: public: Chris@16: typedef typename Base::reference reference; Chris@16: Chris@16: reference operator*()const Chris@16: { Chris@16: return iter_adaptor_access::dereference(final()); Chris@16: } Chris@16: Chris@16: friend bool operator==(const Derived& x,const Derived& y) Chris@16: { Chris@16: return iter_adaptor_access::equal(x,y); Chris@16: } Chris@16: Chris@16: Derived& operator++() Chris@16: { Chris@16: iter_adaptor_access::increment(final()); Chris@16: return final(); Chris@16: } Chris@16: Chris@16: Derived& operator--() Chris@16: { Chris@16: iter_adaptor_access::decrement(final()); Chris@16: return final(); Chris@16: } Chris@16: Chris@16: private: Chris@16: Derived& final(){return *static_cast(this);} Chris@16: const Derived& final()const{return *static_cast(this);} Chris@16: }; Chris@16: Chris@16: template Chris@16: bool operator==( Chris@16: const bidirectional_iter_adaptor_base& x, Chris@16: const bidirectional_iter_adaptor_base& y) Chris@16: { Chris@16: return iter_adaptor_access::equal( Chris@16: static_cast(x),static_cast(y)); Chris@16: } Chris@16: Chris@16: template<> Chris@16: struct iter_adaptor_selector Chris@16: { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef bidirectional_iter_adaptor_base type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template Chris@16: class random_access_iter_adaptor_base: Chris@16: public random_access_iterator_helper< Chris@16: Derived, Chris@16: typename Base::value_type, Chris@16: typename Base::difference_type, Chris@16: typename Base::pointer, Chris@16: typename Base::reference> Chris@16: { Chris@16: public: Chris@16: typedef typename Base::reference reference; Chris@16: typedef typename Base::difference_type difference_type; Chris@16: Chris@16: reference operator*()const Chris@16: { Chris@16: return iter_adaptor_access::dereference(final()); Chris@16: } Chris@16: Chris@16: friend bool operator==(const Derived& x,const Derived& y) Chris@16: { Chris@16: return iter_adaptor_access::equal(x,y); Chris@16: } Chris@16: Chris@16: friend bool operator<(const Derived& x,const Derived& y) Chris@16: { Chris@16: return iter_adaptor_access::distance_to(x,y)>0; Chris@16: } Chris@16: Chris@16: Derived& operator++() Chris@16: { Chris@16: iter_adaptor_access::increment(final()); Chris@16: return final(); Chris@16: } Chris@16: Chris@16: Derived& operator--() Chris@16: { Chris@16: iter_adaptor_access::decrement(final()); Chris@16: return final(); Chris@16: } Chris@16: Chris@16: Derived& operator+=(difference_type n) Chris@16: { Chris@16: iter_adaptor_access::advance(final(),n); Chris@16: return final(); Chris@16: } Chris@16: Chris@16: Derived& operator-=(difference_type n) Chris@16: { Chris@16: iter_adaptor_access::advance(final(),-n); Chris@16: return final(); Chris@16: } Chris@16: Chris@16: friend difference_type operator-(const Derived& x,const Derived& y) Chris@16: { Chris@16: return iter_adaptor_access::distance_to(y,x); Chris@16: } Chris@16: Chris@16: private: Chris@16: Derived& final(){return *static_cast(this);} Chris@16: const Derived& final()const{return *static_cast(this);} Chris@16: }; Chris@16: Chris@16: template Chris@16: bool operator==( Chris@16: const random_access_iter_adaptor_base& x, Chris@16: const random_access_iter_adaptor_base& y) Chris@16: { Chris@16: return iter_adaptor_access::equal( Chris@16: static_cast(x),static_cast(y)); Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator<( Chris@16: const random_access_iter_adaptor_base& x, Chris@16: const random_access_iter_adaptor_base& y) Chris@16: { Chris@16: return iter_adaptor_access::distance_to( Chris@16: static_cast(x),static_cast(y))>0; Chris@16: } Chris@16: Chris@16: template Chris@16: typename random_access_iter_adaptor_base::difference_type Chris@16: operator-( Chris@16: const random_access_iter_adaptor_base& x, Chris@16: const random_access_iter_adaptor_base& y) Chris@16: { Chris@16: return iter_adaptor_access::distance_to( Chris@16: static_cast(y),static_cast(x)); Chris@16: } Chris@16: Chris@16: template<> Chris@16: struct iter_adaptor_selector Chris@16: { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef random_access_iter_adaptor_base type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct iter_adaptor_base Chris@16: { Chris@16: typedef iter_adaptor_selector< Chris@101: typename Base::iterator_category> selector; Chris@101: typedef typename mpl::apply2< Chris@101: selector,Derived,Base>::type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: class iter_adaptor:public iter_adaptor_base::type Chris@16: { Chris@16: protected: Chris@16: iter_adaptor(){} Chris@16: explicit iter_adaptor(const Base& b_):b(b_){} Chris@16: Chris@16: const Base& base_reference()const{return b;} Chris@16: Base& base_reference(){return b;} Chris@16: Chris@16: private: Chris@16: Base b; Chris@16: }; Chris@16: Chris@16: } /* namespace multi_index::detail */ Chris@16: Chris@16: } /* namespace multi_index */ Chris@16: Chris@16: } /* namespace boost */ Chris@16: Chris@16: #endif