xref: /freebsd-src/contrib/llvm-project/libcxx/include/__algorithm/ranges_reverse.h (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
181ad6265SDimitry Andric //===----------------------------------------------------------------------===//
281ad6265SDimitry Andric //
381ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
481ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
581ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
681ad6265SDimitry Andric //
781ad6265SDimitry Andric //===----------------------------------------------------------------------===//
881ad6265SDimitry Andric 
981ad6265SDimitry Andric #ifndef _LIBCPP___ALGORITHM_RANGES_REVERSE_H
1081ad6265SDimitry Andric #define _LIBCPP___ALGORITHM_RANGES_REVERSE_H
1181ad6265SDimitry Andric 
1281ad6265SDimitry Andric #include <__config>
1381ad6265SDimitry Andric #include <__iterator/concepts.h>
1481ad6265SDimitry Andric #include <__iterator/iter_swap.h>
1581ad6265SDimitry Andric #include <__iterator/next.h>
1681ad6265SDimitry Andric #include <__iterator/permutable.h>
1781ad6265SDimitry Andric #include <__ranges/access.h>
1881ad6265SDimitry Andric #include <__ranges/concepts.h>
1981ad6265SDimitry Andric #include <__ranges/dangling.h>
2081ad6265SDimitry Andric 
2181ad6265SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2281ad6265SDimitry Andric #  pragma GCC system_header
2381ad6265SDimitry Andric #endif
2481ad6265SDimitry Andric 
25*06c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20
2681ad6265SDimitry Andric 
2781ad6265SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
2881ad6265SDimitry Andric 
2981ad6265SDimitry Andric namespace ranges {
3081ad6265SDimitry Andric namespace __reverse {
3181ad6265SDimitry Andric struct __fn {
3281ad6265SDimitry Andric   template <bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent>
3381ad6265SDimitry Andric     requires permutable<_Iter>
operator__fn34*06c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last) const {
3581ad6265SDimitry Andric     if constexpr (random_access_iterator<_Iter>) {
3681ad6265SDimitry Andric       if (__first == __last)
3781ad6265SDimitry Andric         return __first;
3881ad6265SDimitry Andric 
3981ad6265SDimitry Andric       auto __end = ranges::next(__first, __last);
4081ad6265SDimitry Andric       auto __ret = __end;
4181ad6265SDimitry Andric 
4281ad6265SDimitry Andric       while (__first < --__end) {
4381ad6265SDimitry Andric         ranges::iter_swap(__first, __end);
4481ad6265SDimitry Andric         ++__first;
4581ad6265SDimitry Andric       }
4681ad6265SDimitry Andric       return __ret;
4781ad6265SDimitry Andric     } else {
4881ad6265SDimitry Andric       auto __end = ranges::next(__first, __last);
4981ad6265SDimitry Andric       auto __ret = __end;
5081ad6265SDimitry Andric 
5181ad6265SDimitry Andric       while (__first != __end) {
5281ad6265SDimitry Andric         if (__first == --__end)
5381ad6265SDimitry Andric           break;
5481ad6265SDimitry Andric 
5581ad6265SDimitry Andric         ranges::iter_swap(__first, __end);
5681ad6265SDimitry Andric         ++__first;
5781ad6265SDimitry Andric       }
5881ad6265SDimitry Andric       return __ret;
5981ad6265SDimitry Andric     }
6081ad6265SDimitry Andric   }
6181ad6265SDimitry Andric 
6281ad6265SDimitry Andric   template <bidirectional_range _Range>
6381ad6265SDimitry Andric     requires permutable<iterator_t<_Range>>
operator__fn64*06c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> operator()(_Range&& __range) const {
6581ad6265SDimitry Andric     return (*this)(ranges::begin(__range), ranges::end(__range));
6681ad6265SDimitry Andric   }
6781ad6265SDimitry Andric };
6881ad6265SDimitry Andric } // namespace __reverse
6981ad6265SDimitry Andric 
7081ad6265SDimitry Andric inline namespace __cpo {
7181ad6265SDimitry Andric inline constexpr auto reverse = __reverse::__fn{};
7281ad6265SDimitry Andric } // namespace __cpo
7381ad6265SDimitry Andric } // namespace ranges
7481ad6265SDimitry Andric 
7581ad6265SDimitry Andric _LIBCPP_END_NAMESPACE_STD
7681ad6265SDimitry Andric 
77*06c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 20
7881ad6265SDimitry Andric 
7981ad6265SDimitry Andric #endif // _LIBCPP___ALGORITHM_RANGES_REVERSE_H
80