summaryrefslogtreecommitdiff
path: root/boost/intrusive/detail/iterator.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/intrusive/detail/iterator.hpp')
-rw-r--r--boost/intrusive/detail/iterator.hpp110
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
////////////////////