Line data Source code
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_UNWRAP_RANGE_H
10 : #define _LIBCPP___ALGORITHM_UNWRAP_RANGE_H
11 :
12 : #include <__algorithm/unwrap_iter.h>
13 : #include <__concepts/constructible.h>
14 : #include <__config>
15 : #include <__iterator/concepts.h>
16 : #include <__iterator/next.h>
17 : #include <__utility/declval.h>
18 : #include <__utility/move.h>
19 : #include <__utility/pair.h>
20 :
21 : #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22 : # pragma GCC system_header
23 : #endif
24 :
25 : _LIBCPP_BEGIN_NAMESPACE_STD
26 :
27 : // __unwrap_range and __rewrap_range are used to unwrap ranges which may have different iterator and sentinel types.
28 : // __unwrap_iter and __rewrap_iter don't work for this, because they assume that the iterator and sentinel have
29 : // the same type. __unwrap_range tries to get two iterators and then forward to __unwrap_iter.
30 :
31 : #if _LIBCPP_STD_VER > 17
32 : template <class _Iter, class _Sent>
33 : struct __unwrap_range_impl {
34 : _LIBCPP_HIDE_FROM_ABI static constexpr auto __unwrap(_Iter __first, _Sent __sent)
35 : requires random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>
36 : {
37 : auto __last = ranges::next(__first, __sent);
38 : return pair{std::__unwrap_iter(std::move(__first)), std::__unwrap_iter(std::move(__last))};
39 : }
40 :
41 : _LIBCPP_HIDE_FROM_ABI static constexpr auto __unwrap(_Iter __first, _Sent __last) {
42 : return pair{std::move(__first), std::move(__last)};
43 : }
44 :
45 : _LIBCPP_HIDE_FROM_ABI static constexpr auto
46 : __rewrap(_Iter __orig_iter, decltype(std::__unwrap_iter(__orig_iter)) __iter)
47 : requires random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>
48 : {
49 : return std::__rewrap_iter(std::move(__orig_iter), std::move(__iter));
50 : }
51 :
52 : _LIBCPP_HIDE_FROM_ABI static constexpr auto __rewrap(const _Iter&, _Iter __iter)
53 : requires (!(random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>))
54 : {
55 : return __iter;
56 : }
57 : };
58 :
59 : template <class _Iter>
60 : struct __unwrap_range_impl<_Iter, _Iter> {
61 : _LIBCPP_HIDE_FROM_ABI static constexpr auto __unwrap(_Iter __first, _Iter __last) {
62 : return pair{std::__unwrap_iter(std::move(__first)), std::__unwrap_iter(std::move(__last))};
63 : }
64 :
65 : _LIBCPP_HIDE_FROM_ABI static constexpr auto
66 : __rewrap(_Iter __orig_iter, decltype(std::__unwrap_iter(__orig_iter)) __iter) {
67 : return std::__rewrap_iter(std::move(__orig_iter), std::move(__iter));
68 : }
69 : };
70 :
71 : template <class _Iter, class _Sent>
72 : _LIBCPP_HIDE_FROM_ABI constexpr auto __unwrap_range(_Iter __first, _Sent __last) {
73 : return __unwrap_range_impl<_Iter, _Sent>::__unwrap(std::move(__first), std::move(__last));
74 : }
75 :
76 : template <
77 : class _Sent,
78 : class _Iter,
79 : class _Unwrapped = decltype(std::__unwrap_range(std::declval<_Iter>(), std::declval<_Sent>()))>
80 : _LIBCPP_HIDE_FROM_ABI constexpr _Iter __rewrap_range(_Iter __orig_iter, _Unwrapped __iter) {
81 : return __unwrap_range_impl<_Iter, _Sent>::__rewrap(std::move(__orig_iter), std::move(__iter));
82 : }
83 : #else // _LIBCPP_STD_VER > 17
84 : template <class _Iter, class _Unwrapped = decltype(std::__unwrap_iter(std::declval<_Iter>()))>
85 2462 : _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR pair<_Unwrapped, _Unwrapped> __unwrap_range(_Iter __first, _Iter __last) {
86 2462 : return std::make_pair(std::__unwrap_iter(std::move(__first)), std::__unwrap_iter(std::move(__last)));
87 : }
88 :
89 : template <class _Iter, class _Unwrapped = decltype(std::__unwrap_iter(std::declval<_Iter>()))>
90 2462 : _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iter __rewrap_range(_Iter __orig_iter, _Unwrapped __iter) {
91 2462 : return std::__rewrap_iter(std::move(__orig_iter), std::move(__iter));
92 : }
93 : #endif // _LIBCPP_STD_VER > 17
94 :
95 : _LIBCPP_END_NAMESPACE_STD
96 :
97 : #endif // _LIBCPP___ALGORITHM_UNWRAP_RANGE_H
|