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