diff --git a/libcxx/include/__iterator/advance.h b/libcxx/include/__iterator/advance.h --- a/libcxx/include/__iterator/advance.h +++ b/libcxx/include/__iterator/advance.h @@ -29,6 +29,41 @@ _LIBCPP_BEGIN_NAMESPACE_STD +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 void +__advance(_InputIter& __i, typename iterator_traits<_InputIter>::difference_type __n, input_iterator_tag) { + for (; __n > 0; --__n) + ++__i; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 void +__advance(_BiDirIter& __i, typename iterator_traits<_BiDirIter>::difference_type __n, bidirectional_iterator_tag) { + if (__n >= 0) + for (; __n > 0; --__n) + ++__i; + else + for (; __n < 0; ++__n) + --__i; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 void +__advance(_RandIter& __i, typename iterator_traits<_RandIter>::difference_type __n, random_access_iterator_tag) { + __i += __n; +} + +template < + class _InputIter, class _Distance, + class = typename enable_if()))>::value>::type> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 void advance(_InputIter& __i, _Distance __orig_n) { + typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize; + _IntegralSize __n = __orig_n; + _LIBCPP_ASSERT(__n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value, + "Attempt to advance(it, n) with negative n on a non-bidirectional iterator"); + _VSTD::__advance(__i, __n, typename iterator_traits<_InputIter>::iterator_category()); +} + #if !defined(_LIBCPP_HAS_NO_RANGES) namespace ranges { diff --git a/libcxx/include/__iterator/next.h b/libcxx/include/__iterator/next.h --- a/libcxx/include/__iterator/next.h +++ b/libcxx/include/__iterator/next.h @@ -25,6 +25,17 @@ _LIBCPP_BEGIN_NAMESPACE_STD +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + typename enable_if<__is_cpp17_input_iterator<_InputIter>::value, _InputIter>::type + next(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) { + _LIBCPP_ASSERT(__n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value, + "Attempt to next(it, n) with negative n on a non-bidirectional iterator"); + + _VSTD::advance(__x, __n); + return __x; +} + #if !defined(_LIBCPP_HAS_NO_RANGES) namespace ranges { diff --git a/libcxx/include/__iterator/prev.h b/libcxx/include/__iterator/prev.h --- a/libcxx/include/__iterator/prev.h +++ b/libcxx/include/__iterator/prev.h @@ -25,6 +25,16 @@ _LIBCPP_BEGIN_NAMESPACE_STD +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + typename enable_if<__is_cpp17_input_iterator<_InputIter>::value, _InputIter>::type + prev(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) { + _LIBCPP_ASSERT(__n <= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value, + "Attempt to prev(it, n) with a positive n on a non-bidirectional iterator"); + _VSTD::advance(__x, -__n); + return __x; +} + #if !defined(_LIBCPP_HAS_NO_RANGES) namespace ranges { diff --git a/libcxx/include/iterator b/libcxx/include/iterator --- a/libcxx/include/iterator +++ b/libcxx/include/iterator @@ -589,48 +589,6 @@ typedef _Category iterator_category; }; -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -void __advance(_InputIter& __i, - typename iterator_traits<_InputIter>::difference_type __n, input_iterator_tag) -{ - for (; __n > 0; --__n) - ++__i; -} - -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -void __advance(_BiDirIter& __i, - typename iterator_traits<_BiDirIter>::difference_type __n, bidirectional_iterator_tag) -{ - if (__n >= 0) - for (; __n > 0; --__n) - ++__i; - else - for (; __n < 0; ++__n) - --__i; -} - -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -void __advance(_RandIter& __i, - typename iterator_traits<_RandIter>::difference_type __n, random_access_iterator_tag) -{ - __i += __n; -} - -template ()))>::value>::type> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -void advance(_InputIter& __i, _Distance __orig_n) -{ - typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize; - _IntegralSize __n = __orig_n; - _LIBCPP_ASSERT(__n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value, - "Attempt to advance(it, n) with negative n on a non-bidirectional iterator"); - _VSTD::__advance(__i, __n, typename iterator_traits<_InputIter>::iterator_category()); -} - template inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 typename iterator_traits<_InputIter>::difference_type @@ -658,40 +616,6 @@ return _VSTD::__distance(__first, __last, typename iterator_traits<_InputIter>::iterator_category()); } -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -typename enable_if -< - __is_cpp17_input_iterator<_InputIter>::value, - _InputIter ->::type -next(_InputIter __x, - typename iterator_traits<_InputIter>::difference_type __n = 1) -{ - _LIBCPP_ASSERT(__n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value, - "Attempt to next(it, n) with negative n on a non-bidirectional iterator"); - - _VSTD::advance(__x, __n); - return __x; -} - -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -typename enable_if -< - __is_cpp17_input_iterator<_InputIter>::value, - _InputIter ->::type -prev(_InputIter __x, - typename iterator_traits<_InputIter>::difference_type __n = 1) -{ - _LIBCPP_ASSERT(__n <= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value, - "Attempt to prev(it, n) with a positive n on a non-bidirectional iterator"); - _VSTD::advance(__x, -__n); - return __x; -} - - template struct __is_stashing_iterator : false_type {};