mirror of
https://github.com/boostorg/intrusive.git
synced 2025-08-02 14:04:36 +02:00
Avoid instantiating iterator tags in iterator_advance and iterator_distance, to allow iterators that forward declare tags and avoid including <iterator>
This commit is contained in:
@@ -20,12 +20,16 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <boost/intrusive/detail/std_fwd.hpp>
|
#include <boost/intrusive/detail/std_fwd.hpp>
|
||||||
#include <boost/move/detail/iterator_traits.hpp>
|
#include <boost/move/detail/iterator_traits.hpp>
|
||||||
|
#include <boost/move/detail/meta_utils_core.hpp>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace intrusive {
|
namespace intrusive {
|
||||||
|
|
||||||
using boost::movelib::iterator_traits;
|
using boost::movelib::iterator_traits;
|
||||||
|
|
||||||
|
////////////////////
|
||||||
|
// iterator
|
||||||
|
////////////////////
|
||||||
template<class Category, class T, class Distance, class Pointer = T*, class Reference = T&>
|
template<class Category, class T, class Distance, class Pointer = T*, class Reference = T&>
|
||||||
struct iterator
|
struct iterator
|
||||||
{
|
{
|
||||||
@@ -36,24 +40,64 @@ struct iterator
|
|||||||
typedef Reference reference;
|
typedef Reference reference;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace detail {
|
////////////////////////////////////////
|
||||||
|
// iterator_[dis|en]able_if_tag
|
||||||
|
////////////////////////////////////////
|
||||||
|
template<class I, class Tag, class R = void>
|
||||||
|
struct iterator_enable_if_tag
|
||||||
|
: ::boost::move_detail::enable_if_c
|
||||||
|
< ::boost::move_detail::is_same
|
||||||
|
< typename boost::intrusive::iterator_traits<I>::iterator_category
|
||||||
|
, Tag
|
||||||
|
>::value
|
||||||
|
, R>
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<class I, class Tag, class R = void>
|
||||||
|
struct iterator_disable_if_tag
|
||||||
|
: ::boost::move_detail::enable_if_c
|
||||||
|
< !::boost::move_detail::is_same
|
||||||
|
< typename boost::intrusive::iterator_traits<I>::iterator_category
|
||||||
|
, Tag
|
||||||
|
>::value
|
||||||
|
, R>
|
||||||
|
{};
|
||||||
|
|
||||||
|
////////////////////////////////////////
|
||||||
|
// iterator_[dis|en]able_if_tag_difference_type
|
||||||
|
////////////////////////////////////////
|
||||||
|
template<class I, class Tag>
|
||||||
|
struct iterator_enable_if_tag_difference_type
|
||||||
|
: iterator_enable_if_tag<I, Tag, typename boost::intrusive::iterator_traits<I>::difference_type>
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<class I, class Tag>
|
||||||
|
struct iterator_disable_if_tag_difference_type
|
||||||
|
: iterator_disable_if_tag<I, Tag, typename boost::intrusive::iterator_traits<I>::difference_type>
|
||||||
|
{};
|
||||||
|
|
||||||
|
////////////////////
|
||||||
|
// advance
|
||||||
|
////////////////////
|
||||||
template<class InputIt, class Distance> inline
|
template<class InputIt, class Distance> inline
|
||||||
void advance_impl(InputIt& it, Distance n, const std::input_iterator_tag&)
|
typename iterator_enable_if_tag<InputIt, std::input_iterator_tag>::type
|
||||||
|
iterator_advance(InputIt& it, Distance n)
|
||||||
{
|
{
|
||||||
while(n--)
|
while(n--)
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class InputIt, class Distance> inline
|
template<class InputIt, class Distance> inline
|
||||||
void advance_impl(InputIt& it, Distance n, std::forward_iterator_tag &)
|
typename iterator_enable_if_tag<InputIt, std::forward_iterator_tag>::type
|
||||||
|
iterator_advance(InputIt& it, Distance n)
|
||||||
{
|
{
|
||||||
while(n--)
|
while(n--)
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class InputIt, class Distance> inline
|
template<class InputIt, class Distance> inline
|
||||||
void advance_impl(InputIt& it, Distance n, std::bidirectional_iterator_tag &)
|
typename iterator_enable_if_tag<InputIt, std::bidirectional_iterator_tag>::type
|
||||||
|
iterator_advance(InputIt& it, Distance n)
|
||||||
{
|
{
|
||||||
for (; 0 < n; --n)
|
for (; 0 < n; --n)
|
||||||
++it;
|
++it;
|
||||||
@@ -61,42 +105,35 @@ void advance_impl(InputIt& it, Distance n, std::bidirectional_iterator_tag &)
|
|||||||
--it;
|
--it;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class InputIt, class Distance>
|
template<class InputIt, class Distance> inline
|
||||||
inline void advance_impl(InputIt& it, Distance n, const std::random_access_iterator_tag &)
|
typename iterator_enable_if_tag<InputIt, std::random_access_iterator_tag>::type
|
||||||
|
iterator_advance(InputIt& it, Distance n)
|
||||||
{
|
{
|
||||||
it += n;
|
it += n;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class InputIt, class Distance, class Category>
|
////////////////////
|
||||||
inline void distance_impl(InputIt first, InputIt last, Distance& off, const Category &)
|
// distance
|
||||||
|
////////////////////
|
||||||
|
template<class InputIt> inline
|
||||||
|
typename iterator_disable_if_tag_difference_type
|
||||||
|
<InputIt, std::random_access_iterator_tag>::type
|
||||||
|
iterator_distance(InputIt first, InputIt last)
|
||||||
{
|
{
|
||||||
|
typename iterator_traits<InputIt>::difference_type off = 0;
|
||||||
while(first != last){
|
while(first != last){
|
||||||
++off;
|
++off;
|
||||||
++first;
|
++first;
|
||||||
}
|
}
|
||||||
}
|
return off;
|
||||||
|
|
||||||
template<class InputIt, class Distance> inline
|
|
||||||
void distance_impl(InputIt first, InputIt last, Distance& off, const std::random_access_iterator_tag&)
|
|
||||||
{
|
|
||||||
off += last - first;
|
|
||||||
}
|
|
||||||
|
|
||||||
} //namespace detail
|
|
||||||
|
|
||||||
template<class InputIt, class Distance>
|
|
||||||
inline void iterator_advance(InputIt& it, Distance n)
|
|
||||||
{ // increment iterator by offset, arbitrary iterators
|
|
||||||
typedef typename boost::intrusive::iterator_traits<InputIt>::iterator_category category_t;
|
|
||||||
boost::intrusive::detail::advance_impl(it, n, category_t());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class InputIt> inline
|
template<class InputIt> inline
|
||||||
typename iterator_traits<InputIt>::difference_type iterator_distance(InputIt first, InputIt last)
|
typename iterator_enable_if_tag_difference_type
|
||||||
|
<InputIt, std::random_access_iterator_tag>::type
|
||||||
|
iterator_distance(InputIt first, InputIt last)
|
||||||
{
|
{
|
||||||
typename iterator_traits<InputIt>::difference_type off = 0;
|
typename iterator_traits<InputIt>::difference_type off = last - first;
|
||||||
typedef typename boost::intrusive::iterator_traits<InputIt>::iterator_category category_t;
|
|
||||||
boost::intrusive::detail::distance_impl(first, last, off, category_t());
|
|
||||||
return off;
|
return off;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user