xref: /llvm-project/libcxx/include/__algorithm/unwrap_range.h (revision 7b4622514d232ce5f7110dd8b20d90e81127c467)
1e01b4fe9SNikolas Klauser //===----------------------------------------------------------------------===//
2e01b4fe9SNikolas Klauser //
3e01b4fe9SNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e01b4fe9SNikolas Klauser // See https://llvm.org/LICENSE.txt for license information.
5e01b4fe9SNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e01b4fe9SNikolas Klauser //
7e01b4fe9SNikolas Klauser //===----------------------------------------------------------------------===//
8e01b4fe9SNikolas Klauser 
9e01b4fe9SNikolas Klauser #ifndef _LIBCPP___ALGORITHM_UNWRAP_RANGE_H
10e01b4fe9SNikolas Klauser #define _LIBCPP___ALGORITHM_UNWRAP_RANGE_H
11e01b4fe9SNikolas Klauser 
12e01b4fe9SNikolas Klauser #include <__algorithm/unwrap_iter.h>
13e01b4fe9SNikolas Klauser #include <__concepts/constructible.h>
14e01b4fe9SNikolas Klauser #include <__config>
15e01b4fe9SNikolas Klauser #include <__iterator/concepts.h>
16e01b4fe9SNikolas Klauser #include <__iterator/next.h>
17e01b4fe9SNikolas Klauser #include <__utility/declval.h>
18e01b4fe9SNikolas Klauser #include <__utility/move.h>
19e01b4fe9SNikolas Klauser #include <__utility/pair.h>
20e01b4fe9SNikolas Klauser 
21e01b4fe9SNikolas Klauser #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22e01b4fe9SNikolas Klauser #  pragma GCC system_header
23e01b4fe9SNikolas Klauser #endif
24e01b4fe9SNikolas Klauser 
25*7b462251SLouis Dionne _LIBCPP_PUSH_MACROS
26*7b462251SLouis Dionne #include <__undef_macros>
27*7b462251SLouis Dionne 
28e01b4fe9SNikolas Klauser _LIBCPP_BEGIN_NAMESPACE_STD
29e01b4fe9SNikolas Klauser 
30e01b4fe9SNikolas Klauser // __unwrap_range and __rewrap_range are used to unwrap ranges which may have different iterator and sentinel types.
31e01b4fe9SNikolas Klauser // __unwrap_iter and __rewrap_iter don't work for this, because they assume that the iterator and sentinel have
32e01b4fe9SNikolas Klauser // the same type. __unwrap_range tries to get two iterators and then forward to __unwrap_iter.
33e01b4fe9SNikolas Klauser 
344f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 20
35e01b4fe9SNikolas Klauser template <class _Iter, class _Sent>
36e01b4fe9SNikolas Klauser struct __unwrap_range_impl {
__unwrap__unwrap_range_impl37e01b4fe9SNikolas Klauser   _LIBCPP_HIDE_FROM_ABI static constexpr auto __unwrap(_Iter __first, _Sent __sent)
38e01b4fe9SNikolas Klauser     requires random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>
39e01b4fe9SNikolas Klauser   {
40e01b4fe9SNikolas Klauser     auto __last = ranges::next(__first, __sent);
41e01b4fe9SNikolas Klauser     return pair{std::__unwrap_iter(std::move(__first)), std::__unwrap_iter(std::move(__last))};
42e01b4fe9SNikolas Klauser   }
43e01b4fe9SNikolas Klauser 
__unwrap__unwrap_range_impl44e01b4fe9SNikolas Klauser   _LIBCPP_HIDE_FROM_ABI static constexpr auto __unwrap(_Iter __first, _Sent __last) {
45e01b4fe9SNikolas Klauser     return pair{std::move(__first), std::move(__last)};
46e01b4fe9SNikolas Klauser   }
47e01b4fe9SNikolas Klauser 
48e01b4fe9SNikolas Klauser   _LIBCPP_HIDE_FROM_ABI static constexpr auto
__rewrap__unwrap_range_impl49b4ecfd3cSNikolas Klauser   __rewrap(_Iter __orig_iter, decltype(std::__unwrap_iter(std::move(__orig_iter))) __iter)
50e01b4fe9SNikolas Klauser     requires random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>
51e01b4fe9SNikolas Klauser   {
52e01b4fe9SNikolas Klauser     return std::__rewrap_iter(std::move(__orig_iter), std::move(__iter));
53e01b4fe9SNikolas Klauser   }
54e01b4fe9SNikolas Klauser 
__rewrap__unwrap_range_impl55e01b4fe9SNikolas Klauser   _LIBCPP_HIDE_FROM_ABI static constexpr auto __rewrap(const _Iter&, _Iter __iter)
56e01b4fe9SNikolas Klauser     requires(!(random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>))
57e01b4fe9SNikolas Klauser   {
58e01b4fe9SNikolas Klauser     return __iter;
59e01b4fe9SNikolas Klauser   }
60e01b4fe9SNikolas Klauser };
61e01b4fe9SNikolas Klauser 
62e01b4fe9SNikolas Klauser template <class _Iter>
63e01b4fe9SNikolas Klauser struct __unwrap_range_impl<_Iter, _Iter> {
64e01b4fe9SNikolas Klauser   _LIBCPP_HIDE_FROM_ABI static constexpr auto __unwrap(_Iter __first, _Iter __last) {
65e01b4fe9SNikolas Klauser     return pair{std::__unwrap_iter(std::move(__first)), std::__unwrap_iter(std::move(__last))};
66e01b4fe9SNikolas Klauser   }
67e01b4fe9SNikolas Klauser 
68e01b4fe9SNikolas Klauser   _LIBCPP_HIDE_FROM_ABI static constexpr auto
69e01b4fe9SNikolas Klauser   __rewrap(_Iter __orig_iter, decltype(std::__unwrap_iter(__orig_iter)) __iter) {
70e01b4fe9SNikolas Klauser     return std::__rewrap_iter(std::move(__orig_iter), std::move(__iter));
71e01b4fe9SNikolas Klauser   }
72e01b4fe9SNikolas Klauser };
73e01b4fe9SNikolas Klauser 
74e01b4fe9SNikolas Klauser template <class _Iter, class _Sent>
75e01b4fe9SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr auto __unwrap_range(_Iter __first, _Sent __last) {
76e01b4fe9SNikolas Klauser   return __unwrap_range_impl<_Iter, _Sent>::__unwrap(std::move(__first), std::move(__last));
77e01b4fe9SNikolas Klauser }
78e01b4fe9SNikolas Klauser 
79b6f6fe98SAmirreza Ashouri template < class _Sent, class _Iter, class _Unwrapped>
80e01b4fe9SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr _Iter __rewrap_range(_Iter __orig_iter, _Unwrapped __iter) {
81e01b4fe9SNikolas Klauser   return __unwrap_range_impl<_Iter, _Sent>::__rewrap(std::move(__orig_iter), std::move(__iter));
82e01b4fe9SNikolas Klauser }
834f15267dSNikolas Klauser #else  // _LIBCPP_STD_VER >= 20
84e01b4fe9SNikolas Klauser template <class _Iter, class _Unwrapped = decltype(std::__unwrap_iter(std::declval<_Iter>()))>
85e01b4fe9SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR pair<_Unwrapped, _Unwrapped> __unwrap_range(_Iter __first, _Iter __last) {
86e01b4fe9SNikolas Klauser   return std::make_pair(std::__unwrap_iter(std::move(__first)), std::__unwrap_iter(std::move(__last)));
87e01b4fe9SNikolas Klauser }
88e01b4fe9SNikolas Klauser 
89b6f6fe98SAmirreza Ashouri template <class _Iter, class _Unwrapped>
90e01b4fe9SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iter __rewrap_range(_Iter __orig_iter, _Unwrapped __iter) {
91e01b4fe9SNikolas Klauser   return std::__rewrap_iter(std::move(__orig_iter), std::move(__iter));
92e01b4fe9SNikolas Klauser }
934f15267dSNikolas Klauser #endif // _LIBCPP_STD_VER >= 20
94e01b4fe9SNikolas Klauser 
95e01b4fe9SNikolas Klauser _LIBCPP_END_NAMESPACE_STD
96e01b4fe9SNikolas Klauser 
97*7b462251SLouis Dionne _LIBCPP_POP_MACROS
98*7b462251SLouis Dionne 
99e01b4fe9SNikolas Klauser #endif // _LIBCPP___ALGORITHM_UNWRAP_RANGE_H
100