| ///////////////////////////////////////////////////////////////////////////// |
| // |
| // (C) Copyright Ion Gaztanaga 2014-2014 |
| // |
| // 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/intrusive for documentation. |
| // |
| ///////////////////////////////////////////////////////////////////////////// |
| |
| #ifndef BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP |
| #define BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP |
| |
| #ifndef BOOST_CONFIG_HPP |
| # include <boost/config.hpp> |
| #endif |
| |
| #if defined(BOOST_HAS_PRAGMA_ONCE) |
| # pragma once |
| #endif |
| |
| #include <cstddef> |
| #include <boost/intrusive/detail/std_fwd.hpp> |
| #include <boost/move/detail/iterator_traits.hpp> |
| #include <boost/move/detail/meta_utils_core.hpp> |
| |
| namespace boost { |
| namespace intrusive { |
| |
| using boost::movelib::iterator_traits; |
| |
| //////////////////// |
| // iterator |
| //////////////////// |
| template<class Category, class T, class Distance, class Pointer = T*, class Reference = T&> |
| struct iterator |
| { |
| typedef Category iterator_category; |
| typedef T value_type; |
| typedef Distance difference_type; |
| typedef Pointer pointer; |
| typedef Reference reference; |
| }; |
| |
| //////////////////////////////////////// |
| // 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 |
| typename iterator_enable_if_tag<InputIt, std::input_iterator_tag>::type |
| iterator_advance(InputIt& it, Distance n) |
| { |
| while(n--) |
| ++it; |
| } |
| |
| template<class InputIt, class Distance> inline |
| typename iterator_enable_if_tag<InputIt, std::forward_iterator_tag>::type |
| iterator_advance(InputIt& it, Distance n) |
| { |
| while(n--) |
| ++it; |
| } |
| |
| template<class InputIt, class Distance> inline |
| typename iterator_enable_if_tag<InputIt, std::bidirectional_iterator_tag>::type |
| iterator_advance(InputIt& it, Distance n) |
| { |
| for (; 0 < n; --n) |
| ++it; |
| for (; n < 0; ++n) |
| --it; |
| } |
| |
| template<class InputIt, class Distance> inline |
| typename iterator_enable_if_tag<InputIt, std::random_access_iterator_tag>::type |
| iterator_advance(InputIt& it, Distance n) |
| { |
| it += n; |
| } |
| |
| //////////////////// |
| // 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){ |
| ++off; |
| ++first; |
| } |
| return off; |
| } |
| |
| template<class InputIt> inline |
| 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 = last - first; |
| return off; |
| } |
| |
| } //namespace intrusive |
| } //namespace boost |
| |
| #endif //BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP |