1*1d1a191eSNikolas Klauser //===----------------------------------------------------------------------===// 2*1d1a191eSNikolas Klauser // 3*1d1a191eSNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*1d1a191eSNikolas Klauser // See https://llvm.org/LICENSE.txt for license information. 5*1d1a191eSNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*1d1a191eSNikolas Klauser // 7*1d1a191eSNikolas Klauser //===----------------------------------------------------------------------===// 8*1d1a191eSNikolas Klauser 9*1d1a191eSNikolas Klauser #ifndef _LIBCPP___ALGORITHM_RANGES_REVERSE_H 10*1d1a191eSNikolas Klauser #define _LIBCPP___ALGORITHM_RANGES_REVERSE_H 11*1d1a191eSNikolas Klauser 12*1d1a191eSNikolas Klauser #include <__config> 13*1d1a191eSNikolas Klauser #include <__iterator/concepts.h> 14*1d1a191eSNikolas Klauser #include <__iterator/iter_swap.h> 15*1d1a191eSNikolas Klauser #include <__iterator/next.h> 16*1d1a191eSNikolas Klauser #include <__iterator/permutable.h> 17*1d1a191eSNikolas Klauser #include <__ranges/access.h> 18*1d1a191eSNikolas Klauser #include <__ranges/concepts.h> 19*1d1a191eSNikolas Klauser #include <__ranges/dangling.h> 20*1d1a191eSNikolas Klauser 21*1d1a191eSNikolas Klauser #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 22*1d1a191eSNikolas Klauser # pragma GCC system_header 23*1d1a191eSNikolas Klauser #endif 24*1d1a191eSNikolas Klauser 25*1d1a191eSNikolas Klauser #if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) 26*1d1a191eSNikolas Klauser 27*1d1a191eSNikolas Klauser _LIBCPP_BEGIN_NAMESPACE_STD 28*1d1a191eSNikolas Klauser 29*1d1a191eSNikolas Klauser namespace ranges { 30*1d1a191eSNikolas Klauser namespace __reverse { 31*1d1a191eSNikolas Klauser struct __fn { 32*1d1a191eSNikolas Klauser 33*1d1a191eSNikolas Klauser template <bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent> 34*1d1a191eSNikolas Klauser requires permutable<_Iter> 35*1d1a191eSNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr operator__fn36*1d1a191eSNikolas Klauser _Iter operator()(_Iter __first, _Sent __last) const { 37*1d1a191eSNikolas Klauser if constexpr (random_access_iterator<_Iter>) { 38*1d1a191eSNikolas Klauser if (__first == __last) 39*1d1a191eSNikolas Klauser return __first; 40*1d1a191eSNikolas Klauser 41*1d1a191eSNikolas Klauser auto __end = ranges::next(__first, __last); 42*1d1a191eSNikolas Klauser auto __ret = __end; 43*1d1a191eSNikolas Klauser 44*1d1a191eSNikolas Klauser while (__first < --__end) { 45*1d1a191eSNikolas Klauser ranges::iter_swap(__first, __end); 46*1d1a191eSNikolas Klauser ++__first; 47*1d1a191eSNikolas Klauser } 48*1d1a191eSNikolas Klauser return __ret; 49*1d1a191eSNikolas Klauser } else { 50*1d1a191eSNikolas Klauser auto __end = ranges::next(__first, __last); 51*1d1a191eSNikolas Klauser auto __ret = __end; 52*1d1a191eSNikolas Klauser 53*1d1a191eSNikolas Klauser while (__first != __end) { 54*1d1a191eSNikolas Klauser if (__first == --__end) 55*1d1a191eSNikolas Klauser break; 56*1d1a191eSNikolas Klauser 57*1d1a191eSNikolas Klauser ranges::iter_swap(__first, __end); 58*1d1a191eSNikolas Klauser ++__first; 59*1d1a191eSNikolas Klauser } 60*1d1a191eSNikolas Klauser return __ret; 61*1d1a191eSNikolas Klauser } 62*1d1a191eSNikolas Klauser } 63*1d1a191eSNikolas Klauser 64*1d1a191eSNikolas Klauser template <bidirectional_range _Range> 65*1d1a191eSNikolas Klauser requires permutable<iterator_t<_Range>> 66*1d1a191eSNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr operator__fn67*1d1a191eSNikolas Klauser borrowed_iterator_t<_Range> operator()(_Range&& __range) const { 68*1d1a191eSNikolas Klauser return (*this)(ranges::begin(__range), ranges::end(__range)); 69*1d1a191eSNikolas Klauser } 70*1d1a191eSNikolas Klauser 71*1d1a191eSNikolas Klauser }; 72*1d1a191eSNikolas Klauser } // namespace __reverse 73*1d1a191eSNikolas Klauser 74*1d1a191eSNikolas Klauser inline namespace __cpo { 75*1d1a191eSNikolas Klauser inline constexpr auto reverse = __reverse::__fn{}; 76*1d1a191eSNikolas Klauser } // namespace __cpo 77*1d1a191eSNikolas Klauser } // namespace ranges 78*1d1a191eSNikolas Klauser 79*1d1a191eSNikolas Klauser _LIBCPP_END_NAMESPACE_STD 80*1d1a191eSNikolas Klauser 81*1d1a191eSNikolas Klauser #endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) 82*1d1a191eSNikolas Klauser 83*1d1a191eSNikolas Klauser #endif // _LIBCPP___ALGORITHM_RANGES_REVERSE_H 84