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
							 |