You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
325 lines
7.6 KiB
325 lines
7.6 KiB
/* Copyright 2003-2008 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)&&(_MSC_VER>=1200) |
|
#pragma once |
|
#endif |
|
|
|
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ |
|
#include <boost/mpl/apply.hpp> |
|
#include <boost/multi_index/detail/prevent_eti.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 prevent_eti< |
|
selector, |
|
typename mpl::apply2< |
|
selector,Derived,Base>::type |
|
>::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
|
|
|