xref: /llvm-project/libcxx/include/__algorithm/ranges_reverse.h (revision d10dc5a06fac4dcabf2264c64c8672c6f6ae36fb)
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