1857fa7b7SChristopher Di Bella // -*- C++ -*- 2857fa7b7SChristopher Di Bella //===----------------------------------------------------------------------===// 3857fa7b7SChristopher Di Bella // 4857fa7b7SChristopher Di Bella // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5857fa7b7SChristopher Di Bella // See https://llvm.org/LICENSE.txt for license information. 6857fa7b7SChristopher Di Bella // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7857fa7b7SChristopher Di Bella // 8857fa7b7SChristopher Di Bella //===----------------------------------------------------------------------===// 9857fa7b7SChristopher Di Bella 10857fa7b7SChristopher Di Bella #ifndef _LIBCPP___ITERATOR_NEXT_H 11857fa7b7SChristopher Di Bella #define _LIBCPP___ITERATOR_NEXT_H 12857fa7b7SChristopher Di Bella 13f87aa19bSLouis Dionne #include <__assert> 14857fa7b7SChristopher Di Bella #include <__config> 15857fa7b7SChristopher Di Bella #include <__iterator/advance.h> 16857fa7b7SChristopher Di Bella #include <__iterator/concepts.h> 17857fa7b7SChristopher Di Bella #include <__iterator/incrementable_traits.h> 18332da1c2SChristopher Di Bella #include <__iterator/iterator_traits.h> 19e0a66116SNikolas Klauser #include <__type_traits/enable_if.h> 20857fa7b7SChristopher Di Bella 21857fa7b7SChristopher Di Bella #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 22857fa7b7SChristopher Di Bella # pragma GCC system_header 23857fa7b7SChristopher Di Bella #endif 24857fa7b7SChristopher Di Bella 25857fa7b7SChristopher Di Bella _LIBCPP_BEGIN_NAMESPACE_STD 26857fa7b7SChristopher Di Bella 27475bd19eSNikolas Klauser template <class _InputIter, __enable_if_t<__has_input_iterator_category<_InputIter>::value, int> = 0> 28*e9c0c660SMarc Auberer [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _InputIter 29bf92bdadSChristopher Di Bella next(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) { 304f215fddSKonstantin Varlamov // Calling `advance` with a negative value on a non-bidirectional iterator is a no-op in the current implementation. 314f215fddSKonstantin Varlamov // Note that this check duplicates the similar check in `std::advance`. 324f215fddSKonstantin Varlamov _LIBCPP_ASSERT_PEDANTIC(__n >= 0 || __has_bidirectional_iterator_category<_InputIter>::value, 33bf92bdadSChristopher Di Bella "Attempt to next(it, n) with negative n on a non-bidirectional iterator"); 34bf92bdadSChristopher Di Bella 3577a00c0dSLouis Dionne std::advance(__x, __n); 36bf92bdadSChristopher Di Bella return __x; 37bf92bdadSChristopher Di Bella } 38bf92bdadSChristopher Di Bella 394f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 20 40857fa7b7SChristopher Di Bella 416ce732cbSArthur O'Dwyer // [range.iter.op.next] 426ce732cbSArthur O'Dwyer 43857fa7b7SChristopher Di Bella namespace ranges { 44d10dc5a0SChristopher Di Bella struct __next { 45857fa7b7SChristopher Di Bella template <input_or_output_iterator _Ip> 46*e9c0c660SMarc Auberer [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x) const { 47857fa7b7SChristopher Di Bella ++__x; 48857fa7b7SChristopher Di Bella return __x; 49857fa7b7SChristopher Di Bella } 50857fa7b7SChristopher Di Bella 51857fa7b7SChristopher Di Bella template <input_or_output_iterator _Ip> 52*e9c0c660SMarc Auberer [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n) const { 53857fa7b7SChristopher Di Bella ranges::advance(__x, __n); 54857fa7b7SChristopher Di Bella return __x; 55857fa7b7SChristopher Di Bella } 56857fa7b7SChristopher Di Bella 57857fa7b7SChristopher Di Bella template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp> 58*e9c0c660SMarc Auberer [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x, _Sp __bound_sentinel) const { 595a4f177cSPeter Kasting ranges::advance(__x, __bound_sentinel); 60857fa7b7SChristopher Di Bella return __x; 61857fa7b7SChristopher Di Bella } 62857fa7b7SChristopher Di Bella 63857fa7b7SChristopher Di Bella template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp> 64*e9c0c660SMarc Auberer [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Ip 65*e9c0c660SMarc Auberer operator()(_Ip __x, iter_difference_t<_Ip> __n, _Sp __bound_sentinel) const { 665a4f177cSPeter Kasting ranges::advance(__x, __n, __bound_sentinel); 67857fa7b7SChristopher Di Bella return __x; 68857fa7b7SChristopher Di Bella } 69857fa7b7SChristopher Di Bella }; 70857fa7b7SChristopher Di Bella 716ce732cbSArthur O'Dwyer inline namespace __cpo { 72d10dc5a0SChristopher Di Bella inline constexpr auto next = __next{}; 736ce732cbSArthur O'Dwyer } // namespace __cpo 74857fa7b7SChristopher Di Bella } // namespace ranges 75857fa7b7SChristopher Di Bella 764f15267dSNikolas Klauser #endif // _LIBCPP_STD_VER >= 20 77857fa7b7SChristopher Di Bella 78857fa7b7SChristopher Di Bella _LIBCPP_END_NAMESPACE_STD 79857fa7b7SChristopher Di Bella 800b609efdSArthur O'Dwyer #endif // _LIBCPP___ITERATOR_NEXT_H 81