diff options
Diffstat (limited to 'boost/intrusive/detail/iterator.hpp')
-rw-r--r-- | boost/intrusive/detail/iterator.hpp | 110 |
1 files changed, 108 insertions, 2 deletions
diff --git a/boost/intrusive/detail/iterator.hpp b/boost/intrusive/detail/iterator.hpp index 2ae6abb7d0..c25be430a2 100644 --- a/boost/intrusive/detail/iterator.hpp +++ b/boost/intrusive/detail/iterator.hpp @@ -27,6 +27,24 @@ #include <boost/move/detail/iterator_traits.hpp> #include <boost/move/detail/meta_utils_core.hpp> +namespace boost{ +namespace iterators{ + +struct incrementable_traversal_tag; +struct single_pass_traversal_tag; +struct forward_traversal_tag; +struct bidirectional_traversal_tag; +struct random_access_traversal_tag; + +namespace detail{ + +template <class Category, class Traversal> +struct iterator_category_with_traversal; + +} //namespace boost{ +} //namespace iterators{ +} //namespace detail{ + namespace boost { namespace intrusive { @@ -46,6 +64,28 @@ struct iterator }; //////////////////////////////////////// +// iterator_[dis|en]able_if_boost_iterator +//////////////////////////////////////// +template<class I> +struct is_boost_iterator +{ + static const bool value = false; +}; + +template<class Category, class Traversal> +struct is_boost_iterator< boost::iterators::detail::iterator_category_with_traversal<Category, Traversal> > +{ + static const bool value = true; +}; + +template<class I, class R = void> +struct iterator_enable_if_boost_iterator + : ::boost::move_detail::enable_if_c + < is_boost_iterator<typename boost::intrusive::iterator_traits<I>::iterator_category >::value + , R> +{}; + +//////////////////////////////////////// // iterator_[dis|en]able_if_tag //////////////////////////////////////// template<class I, class Tag, class R = void> @@ -69,6 +109,23 @@ struct iterator_disable_if_tag {}; //////////////////////////////////////// +// iterator_[dis|en]able_if_tag +//////////////////////////////////////// +template<class I, class Tag, class Tag2, class R = void> +struct iterator_enable_if_convertible_tag + : ::boost::move_detail::enable_if_c + < ::boost::move_detail::is_same_or_convertible + < typename boost::intrusive::iterator_traits<I>::iterator_category + , Tag + >::value && + !::boost::move_detail::is_same_or_convertible + < typename boost::intrusive::iterator_traits<I>::iterator_category + , Tag2 + >::value + , R> +{}; + +//////////////////////////////////////// // iterator_[dis|en]able_if_tag_difference_type //////////////////////////////////////// template<class I, class Tag> @@ -84,8 +141,9 @@ struct iterator_disable_if_tag_difference_type //////////////////// // advance //////////////////// + template<class InputIt, class Distance> -typename iterator_enable_if_tag<InputIt, std::input_iterator_tag>::type +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag<InputIt, std::input_iterator_tag>::type iterator_advance(InputIt& it, Distance n) { while(n--) @@ -101,7 +159,7 @@ typename iterator_enable_if_tag<InputIt, std::forward_iterator_tag>::type } template<class InputIt, class Distance> -typename iterator_enable_if_tag<InputIt, std::bidirectional_iterator_tag>::type +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag<InputIt, std::bidirectional_iterator_tag>::type iterator_advance(InputIt& it, Distance n) { for (; 0 < n; --n) @@ -117,6 +175,54 @@ BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag<InputIt, std::random it += n; } +template<class InputIt, class Distance> +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_convertible_tag + <InputIt, const boost::iterators::incrementable_traversal_tag&, const boost::iterators::single_pass_traversal_tag&>::type + iterator_advance(InputIt& it, Distance n) +{ + while(n--) + ++it; +} + +template<class InputIt, class Distance> +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_convertible_tag + <InputIt, const boost::iterators::single_pass_traversal_tag &, const boost::iterators::forward_traversal_tag&>::type + iterator_advance(InputIt& it, Distance n) +{ + while(n--) + ++it; +} + +template<class InputIt, class Distance> +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_convertible_tag + <InputIt, const boost::iterators::forward_traversal_tag&, const boost::iterators::bidirectional_traversal_tag&>::type + iterator_advance(InputIt& it, Distance n) +{ + while(n--) + ++it; +} + +template<class InputIt, class Distance> +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_convertible_tag + <InputIt, const boost::iterators::bidirectional_traversal_tag&, const boost::iterators::random_access_traversal_tag&>::type + iterator_advance(InputIt& it, Distance n) +{ + for (; 0 < n; --n) + ++it; + for (; n < 0; ++n) + --it; +} + +class fake{}; + +template<class InputIt, class Distance> +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_convertible_tag + <InputIt, const boost::iterators::random_access_traversal_tag&, const fake&>::type + iterator_advance(InputIt& it, Distance n) +{ + it += n; +} + //////////////////// // distance //////////////////// |