100 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef _LIBCPP___ALGORITHM_UNWRAP_RANGE_H10#define _LIBCPP___ALGORITHM_UNWRAP_RANGE_H11 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_header23#endif24 25_LIBCPP_PUSH_MACROS26#include <__undef_macros>27 28_LIBCPP_BEGIN_NAMESPACE_STD29 30// __unwrap_range and __rewrap_range are used to unwrap ranges which may have different iterator and sentinel types.31// __unwrap_iter and __rewrap_iter don't work for this, because they assume that the iterator and sentinel have32// the same type. __unwrap_range tries to get two iterators and then forward to __unwrap_iter.33 34#if _LIBCPP_STD_VER >= 2035template <class _Iter, class _Sent>36struct __unwrap_range_impl {37 _LIBCPP_HIDE_FROM_ABI static constexpr auto __unwrap(_Iter __first, _Sent __sent)38 requires random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>39 {40 auto __last = ranges::next(__first, __sent);41 return pair{std::__unwrap_iter(std::move(__first)), std::__unwrap_iter(std::move(__last))};42 }43 44 _LIBCPP_HIDE_FROM_ABI static constexpr auto __unwrap(_Iter __first, _Sent __last) {45 return pair{std::move(__first), std::move(__last)};46 }47 48 _LIBCPP_HIDE_FROM_ABI static constexpr auto49 __rewrap(_Iter __orig_iter, decltype(std::__unwrap_iter(std::move(__orig_iter))) __iter)50 requires random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>51 {52 return std::__rewrap_iter(std::move(__orig_iter), std::move(__iter));53 }54 55 _LIBCPP_HIDE_FROM_ABI static constexpr auto __rewrap(const _Iter&, _Iter __iter)56 requires(!(random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>))57 {58 return __iter;59 }60};61 62template <class _Iter>63struct __unwrap_range_impl<_Iter, _Iter> {64 _LIBCPP_HIDE_FROM_ABI static constexpr auto __unwrap(_Iter __first, _Iter __last) {65 return pair{std::__unwrap_iter(std::move(__first)), std::__unwrap_iter(std::move(__last))};66 }67 68 _LIBCPP_HIDE_FROM_ABI static constexpr auto69 __rewrap(_Iter __orig_iter, decltype(std::__unwrap_iter(__orig_iter)) __iter) {70 return std::__rewrap_iter(std::move(__orig_iter), std::move(__iter));71 }72};73 74template <class _Iter, class _Sent>75_LIBCPP_HIDE_FROM_ABI constexpr auto __unwrap_range(_Iter __first, _Sent __last) {76 return __unwrap_range_impl<_Iter, _Sent>::__unwrap(std::move(__first), std::move(__last));77}78 79template < class _Sent, class _Iter, class _Unwrapped>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 >= 2084template <class _Iter, class _Unwrapped = decltype(std::__unwrap_iter(std::declval<_Iter>()))>85_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR pair<_Unwrapped, _Unwrapped> __unwrap_range(_Iter __first, _Iter __last) {86 return std::make_pair(std::__unwrap_iter(std::move(__first)), std::__unwrap_iter(std::move(__last)));87}88 89template <class _Iter, class _Unwrapped>90_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iter __rewrap_range(_Iter __orig_iter, _Unwrapped __iter) {91 return std::__rewrap_iter(std::move(__orig_iter), std::move(__iter));92}93#endif // _LIBCPP_STD_VER >= 2094 95_LIBCPP_END_NAMESPACE_STD96 97_LIBCPP_POP_MACROS98 99#endif // _LIBCPP___ALGORITHM_UNWRAP_RANGE_H100