xref: /freebsd/contrib/llvm-project/libcxx/include/__algorithm/unwrap_range.h (revision b3edf4467982447620505a28fc82e38a414c07dc)
161cfbce3SDimitry Andric //===----------------------------------------------------------------------===//
261cfbce3SDimitry Andric //
361cfbce3SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
461cfbce3SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
561cfbce3SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
661cfbce3SDimitry Andric //
761cfbce3SDimitry Andric //===----------------------------------------------------------------------===//
861cfbce3SDimitry Andric 
961cfbce3SDimitry Andric #ifndef _LIBCPP___ALGORITHM_UNWRAP_RANGE_H
1061cfbce3SDimitry Andric #define _LIBCPP___ALGORITHM_UNWRAP_RANGE_H
1161cfbce3SDimitry Andric 
1261cfbce3SDimitry Andric #include <__algorithm/unwrap_iter.h>
1361cfbce3SDimitry Andric #include <__concepts/constructible.h>
1461cfbce3SDimitry Andric #include <__config>
1561cfbce3SDimitry Andric #include <__iterator/concepts.h>
1661cfbce3SDimitry Andric #include <__iterator/next.h>
1761cfbce3SDimitry Andric #include <__utility/declval.h>
1861cfbce3SDimitry Andric #include <__utility/move.h>
1961cfbce3SDimitry Andric #include <__utility/pair.h>
2061cfbce3SDimitry Andric 
2161cfbce3SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2261cfbce3SDimitry Andric #  pragma GCC system_header
2361cfbce3SDimitry Andric #endif
2461cfbce3SDimitry Andric 
25*b3edf446SDimitry Andric _LIBCPP_PUSH_MACROS
26*b3edf446SDimitry Andric #include <__undef_macros>
27*b3edf446SDimitry Andric 
2861cfbce3SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
2961cfbce3SDimitry Andric 
3061cfbce3SDimitry Andric // __unwrap_range and __rewrap_range are used to unwrap ranges which may have different iterator and sentinel types.
3161cfbce3SDimitry Andric // __unwrap_iter and __rewrap_iter don't work for this, because they assume that the iterator and sentinel have
3261cfbce3SDimitry Andric // the same type. __unwrap_range tries to get two iterators and then forward to __unwrap_iter.
3361cfbce3SDimitry Andric 
3406c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20
3561cfbce3SDimitry Andric template <class _Iter, class _Sent>
3661cfbce3SDimitry Andric struct __unwrap_range_impl {
3761cfbce3SDimitry Andric   _LIBCPP_HIDE_FROM_ABI static constexpr auto __unwrap(_Iter __first, _Sent __sent)
3861cfbce3SDimitry Andric     requires random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>
3961cfbce3SDimitry Andric   {
4061cfbce3SDimitry Andric     auto __last = ranges::next(__first, __sent);
4161cfbce3SDimitry Andric     return pair{std::__unwrap_iter(std::move(__first)), std::__unwrap_iter(std::move(__last))};
4261cfbce3SDimitry Andric   }
4361cfbce3SDimitry Andric 
4461cfbce3SDimitry Andric   _LIBCPP_HIDE_FROM_ABI static constexpr auto __unwrap(_Iter __first, _Sent __last) {
4561cfbce3SDimitry Andric     return pair{std::move(__first), std::move(__last)};
4661cfbce3SDimitry Andric   }
4761cfbce3SDimitry Andric 
4861cfbce3SDimitry Andric   _LIBCPP_HIDE_FROM_ABI static constexpr auto
4906c3fb27SDimitry Andric   __rewrap(_Iter __orig_iter, decltype(std::__unwrap_iter(std::move(__orig_iter))) __iter)
5061cfbce3SDimitry Andric     requires random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>
5161cfbce3SDimitry Andric   {
5261cfbce3SDimitry Andric     return std::__rewrap_iter(std::move(__orig_iter), std::move(__iter));
5361cfbce3SDimitry Andric   }
5461cfbce3SDimitry Andric 
5561cfbce3SDimitry Andric   _LIBCPP_HIDE_FROM_ABI static constexpr auto __rewrap(const _Iter&, _Iter __iter)
5661cfbce3SDimitry Andric     requires(!(random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>))
5761cfbce3SDimitry Andric   {
5861cfbce3SDimitry Andric     return __iter;
5961cfbce3SDimitry Andric   }
6061cfbce3SDimitry Andric };
6161cfbce3SDimitry Andric 
6261cfbce3SDimitry Andric template <class _Iter>
6361cfbce3SDimitry Andric struct __unwrap_range_impl<_Iter, _Iter> {
6461cfbce3SDimitry Andric   _LIBCPP_HIDE_FROM_ABI static constexpr auto __unwrap(_Iter __first, _Iter __last) {
6561cfbce3SDimitry Andric     return pair{std::__unwrap_iter(std::move(__first)), std::__unwrap_iter(std::move(__last))};
6661cfbce3SDimitry Andric   }
6761cfbce3SDimitry Andric 
6861cfbce3SDimitry Andric   _LIBCPP_HIDE_FROM_ABI static constexpr auto
6961cfbce3SDimitry Andric   __rewrap(_Iter __orig_iter, decltype(std::__unwrap_iter(__orig_iter)) __iter) {
7061cfbce3SDimitry Andric     return std::__rewrap_iter(std::move(__orig_iter), std::move(__iter));
7161cfbce3SDimitry Andric   }
7261cfbce3SDimitry Andric };
7361cfbce3SDimitry Andric 
7461cfbce3SDimitry Andric template <class _Iter, class _Sent>
7561cfbce3SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto __unwrap_range(_Iter __first, _Sent __last) {
7661cfbce3SDimitry Andric   return __unwrap_range_impl<_Iter, _Sent>::__unwrap(std::move(__first), std::move(__last));
7761cfbce3SDimitry Andric }
7861cfbce3SDimitry Andric 
795f757f3fSDimitry Andric template < class _Sent, class _Iter, class _Unwrapped>
8061cfbce3SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr _Iter __rewrap_range(_Iter __orig_iter, _Unwrapped __iter) {
8161cfbce3SDimitry Andric   return __unwrap_range_impl<_Iter, _Sent>::__rewrap(std::move(__orig_iter), std::move(__iter));
8261cfbce3SDimitry Andric }
8306c3fb27SDimitry Andric #else  // _LIBCPP_STD_VER >= 20
8461cfbce3SDimitry Andric template <class _Iter, class _Unwrapped = decltype(std::__unwrap_iter(std::declval<_Iter>()))>
8561cfbce3SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR pair<_Unwrapped, _Unwrapped> __unwrap_range(_Iter __first, _Iter __last) {
8661cfbce3SDimitry Andric   return std::make_pair(std::__unwrap_iter(std::move(__first)), std::__unwrap_iter(std::move(__last)));
8761cfbce3SDimitry Andric }
8861cfbce3SDimitry Andric 
895f757f3fSDimitry Andric template <class _Iter, class _Unwrapped>
9061cfbce3SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iter __rewrap_range(_Iter __orig_iter, _Unwrapped __iter) {
9161cfbce3SDimitry Andric   return std::__rewrap_iter(std::move(__orig_iter), std::move(__iter));
9261cfbce3SDimitry Andric }
9306c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 20
9461cfbce3SDimitry Andric 
9561cfbce3SDimitry Andric _LIBCPP_END_NAMESPACE_STD
9661cfbce3SDimitry Andric 
97*b3edf446SDimitry Andric _LIBCPP_POP_MACROS
98*b3edf446SDimitry Andric 
9961cfbce3SDimitry Andric #endif // _LIBCPP___ALGORITHM_UNWRAP_RANGE_H
100