1 // Copyright (C) 2017 Michel Morin. 2 // 3 // Distributed under the Boost Software License, Version 1.0. 4 // (See accompanying file LICENSE_1_0.txt or copy at 5 // http://www.boost.org/LICENSE_1_0.txt) 6 7 #ifndef BOOST_ITERATOR_ADVANCE_HPP 8 #define BOOST_ITERATOR_ADVANCE_HPP 9 10 #include <boost/config.hpp> 11 #include <boost/iterator/iterator_categories.hpp> 12 13 namespace boost { 14 namespace iterators { 15 16 namespace detail { 17 template <typename InputIterator, typename Distance> 18 inline BOOST_CXX14_CONSTEXPR void advance_impl(InputIterator & it,Distance n,incrementable_traversal_tag)19 advance_impl( 20 InputIterator& it 21 , Distance n 22 , incrementable_traversal_tag 23 ) 24 { 25 while (n > 0) { 26 ++it; 27 --n; 28 } 29 } 30 31 template <typename BidirectionalIterator, typename Distance> 32 inline BOOST_CXX14_CONSTEXPR void advance_impl(BidirectionalIterator & it,Distance n,bidirectional_traversal_tag)33 advance_impl( 34 BidirectionalIterator& it 35 , Distance n 36 , bidirectional_traversal_tag 37 ) 38 { 39 if (n >= 0) { 40 while (n > 0) { 41 ++it; 42 --n; 43 } 44 } 45 else { 46 while (n < 0) { 47 --it; 48 ++n; 49 } 50 } 51 } 52 53 template <typename RandomAccessIterator, typename Distance> 54 inline BOOST_CXX14_CONSTEXPR void advance_impl(RandomAccessIterator & it,Distance n,random_access_traversal_tag)55 advance_impl( 56 RandomAccessIterator& it 57 , Distance n 58 , random_access_traversal_tag 59 ) 60 { 61 it += n; 62 } 63 } 64 65 namespace advance_adl_barrier { 66 template <typename InputIterator, typename Distance> 67 inline BOOST_CXX14_CONSTEXPR void advance(InputIterator & it,Distance n)68 advance(InputIterator& it, Distance n) 69 { 70 detail::advance_impl( 71 it, n, typename iterator_traversal<InputIterator>::type() 72 ); 73 } 74 } 75 76 using namespace advance_adl_barrier; 77 78 } // namespace iterators 79 80 using namespace iterators::advance_adl_barrier; 81 82 } // namespace boost 83 84 #endif 85