11d1a191eSNikolas Klauser //===----------------------------------------------------------------------===// 21d1a191eSNikolas Klauser // 31d1a191eSNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 41d1a191eSNikolas Klauser // See https://llvm.org/LICENSE.txt for license information. 51d1a191eSNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 61d1a191eSNikolas Klauser // 71d1a191eSNikolas Klauser //===----------------------------------------------------------------------===// 81d1a191eSNikolas Klauser 91d1a191eSNikolas Klauser #ifndef _LIBCPP___ALGORITHM_RANGES_REVERSE_H 101d1a191eSNikolas Klauser #define _LIBCPP___ALGORITHM_RANGES_REVERSE_H 111d1a191eSNikolas Klauser 121d1a191eSNikolas Klauser #include <__config> 131d1a191eSNikolas Klauser #include <__iterator/concepts.h> 141d1a191eSNikolas Klauser #include <__iterator/iter_swap.h> 151d1a191eSNikolas Klauser #include <__iterator/next.h> 161d1a191eSNikolas Klauser #include <__iterator/permutable.h> 171d1a191eSNikolas Klauser #include <__ranges/access.h> 181d1a191eSNikolas Klauser #include <__ranges/concepts.h> 191d1a191eSNikolas Klauser #include <__ranges/dangling.h> 201d1a191eSNikolas Klauser 211d1a191eSNikolas Klauser #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 221d1a191eSNikolas Klauser # pragma GCC system_header 231d1a191eSNikolas Klauser #endif 241d1a191eSNikolas Klauser 254f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 20 261d1a191eSNikolas Klauser 271d1a191eSNikolas Klauser _LIBCPP_BEGIN_NAMESPACE_STD 281d1a191eSNikolas Klauser 291d1a191eSNikolas Klauser namespace ranges { 30*d10dc5a0SChristopher Di Bella struct __reverse { 311d1a191eSNikolas Klauser template <bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent> 321d1a191eSNikolas Klauser requires permutable<_Iter> 335aa03b64SLouis Dionne _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last) const { 341d1a191eSNikolas Klauser if constexpr (random_access_iterator<_Iter>) { 351d1a191eSNikolas Klauser if (__first == __last) 361d1a191eSNikolas Klauser return __first; 371d1a191eSNikolas Klauser 381d1a191eSNikolas Klauser auto __end = ranges::next(__first, __last); 391d1a191eSNikolas Klauser auto __ret = __end; 401d1a191eSNikolas Klauser 411d1a191eSNikolas Klauser while (__first < --__end) { 421d1a191eSNikolas Klauser ranges::iter_swap(__first, __end); 431d1a191eSNikolas Klauser ++__first; 441d1a191eSNikolas Klauser } 451d1a191eSNikolas Klauser return __ret; 461d1a191eSNikolas Klauser } else { 471d1a191eSNikolas Klauser auto __end = ranges::next(__first, __last); 481d1a191eSNikolas Klauser auto __ret = __end; 491d1a191eSNikolas Klauser 501d1a191eSNikolas Klauser while (__first != __end) { 511d1a191eSNikolas Klauser if (__first == --__end) 521d1a191eSNikolas Klauser break; 531d1a191eSNikolas Klauser 541d1a191eSNikolas Klauser ranges::iter_swap(__first, __end); 551d1a191eSNikolas Klauser ++__first; 561d1a191eSNikolas Klauser } 571d1a191eSNikolas Klauser return __ret; 581d1a191eSNikolas Klauser } 591d1a191eSNikolas Klauser } 601d1a191eSNikolas Klauser 611d1a191eSNikolas Klauser template <bidirectional_range _Range> 621d1a191eSNikolas Klauser requires permutable<iterator_t<_Range>> 635aa03b64SLouis Dionne _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> operator()(_Range&& __range) const { 641d1a191eSNikolas Klauser return (*this)(ranges::begin(__range), ranges::end(__range)); 651d1a191eSNikolas Klauser } 661d1a191eSNikolas Klauser }; 671d1a191eSNikolas Klauser 681d1a191eSNikolas Klauser inline namespace __cpo { 69*d10dc5a0SChristopher Di Bella inline constexpr auto reverse = __reverse{}; 701d1a191eSNikolas Klauser } // namespace __cpo 711d1a191eSNikolas Klauser } // namespace ranges 721d1a191eSNikolas Klauser 731d1a191eSNikolas Klauser _LIBCPP_END_NAMESPACE_STD 741d1a191eSNikolas Klauser 754f15267dSNikolas Klauser #endif // _LIBCPP_STD_VER >= 20 761d1a191eSNikolas Klauser 771d1a191eSNikolas Klauser #endif // _LIBCPP___ALGORITHM_RANGES_REVERSE_H 78