From 974bb7b14d1591a7dc1434c9e64a6b8e27c50487 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sun, 4 Jan 2015 02:15:44 +0100 Subject: [PATCH] Avoid instantiating iterator tags in iterator_advance and iterator_distance, to allow iterators that forward declare tags and avoid including --- include/boost/intrusive/detail/iterator.hpp | 91 +++++++++++++++------ 1 file changed, 64 insertions(+), 27 deletions(-) diff --git a/include/boost/intrusive/detail/iterator.hpp b/include/boost/intrusive/detail/iterator.hpp index 7eea1db..6a4ac09 100644 --- a/include/boost/intrusive/detail/iterator.hpp +++ b/include/boost/intrusive/detail/iterator.hpp @@ -20,12 +20,16 @@ #include #include #include +#include namespace boost { namespace intrusive { using boost::movelib::iterator_traits; +//////////////////// +// iterator +//////////////////// template struct iterator { @@ -36,24 +40,64 @@ struct iterator typedef Reference reference; }; -namespace detail { +//////////////////////////////////////// +// iterator_[dis|en]able_if_tag +//////////////////////////////////////// +template +struct iterator_enable_if_tag + : ::boost::move_detail::enable_if_c + < ::boost::move_detail::is_same + < typename boost::intrusive::iterator_traits::iterator_category + , Tag + >::value + , R> +{}; +template +struct iterator_disable_if_tag + : ::boost::move_detail::enable_if_c + < !::boost::move_detail::is_same + < typename boost::intrusive::iterator_traits::iterator_category + , Tag + >::value + , R> +{}; + +//////////////////////////////////////// +// iterator_[dis|en]able_if_tag_difference_type +//////////////////////////////////////// +template +struct iterator_enable_if_tag_difference_type + : iterator_enable_if_tag::difference_type> +{}; + +template +struct iterator_disable_if_tag_difference_type + : iterator_disable_if_tag::difference_type> +{}; + +//////////////////// +// advance +//////////////////// template inline -void advance_impl(InputIt& it, Distance n, const std::input_iterator_tag&) +typename iterator_enable_if_tag::type + iterator_advance(InputIt& it, Distance n) { while(n--) ++it; } template inline -void advance_impl(InputIt& it, Distance n, std::forward_iterator_tag &) +typename iterator_enable_if_tag::type + iterator_advance(InputIt& it, Distance n) { while(n--) ++it; } template inline -void advance_impl(InputIt& it, Distance n, std::bidirectional_iterator_tag &) +typename iterator_enable_if_tag::type + iterator_advance(InputIt& it, Distance n) { for (; 0 < n; --n) ++it; @@ -61,42 +105,35 @@ void advance_impl(InputIt& it, Distance n, std::bidirectional_iterator_tag &) --it; } -template -inline void advance_impl(InputIt& it, Distance n, const std::random_access_iterator_tag &) +template inline +typename iterator_enable_if_tag::type + iterator_advance(InputIt& it, Distance n) { it += n; } -template -inline void distance_impl(InputIt first, InputIt last, Distance& off, const Category &) +//////////////////// +// distance +//////////////////// +template inline +typename iterator_disable_if_tag_difference_type + ::type + iterator_distance(InputIt first, InputIt last) { + typename iterator_traits::difference_type off = 0; while(first != last){ ++off; ++first; } -} - -template inline -void distance_impl(InputIt first, InputIt last, Distance& off, const std::random_access_iterator_tag&) -{ - off += last - first; -} - -} //namespace detail - -template -inline void iterator_advance(InputIt& it, Distance n) -{ // increment iterator by offset, arbitrary iterators - typedef typename boost::intrusive::iterator_traits::iterator_category category_t; - boost::intrusive::detail::advance_impl(it, n, category_t()); + return off; } template inline -typename iterator_traits::difference_type iterator_distance(InputIt first, InputIt last) +typename iterator_enable_if_tag_difference_type + ::type + iterator_distance(InputIt first, InputIt last) { - typename iterator_traits::difference_type off = 0; - typedef typename boost::intrusive::iterator_traits::iterator_category category_t; - boost::intrusive::detail::distance_impl(first, last, off, category_t()); + typename iterator_traits::difference_type off = last - first; return off; }