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