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