1349cc55cSDimitry Andric // -*- C++ -*- 2349cc55cSDimitry Andric //===----------------------------------------------------------------------===// 3349cc55cSDimitry Andric // 4349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 6349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7349cc55cSDimitry Andric // 8349cc55cSDimitry Andric //===----------------------------------------------------------------------===// 9bdd1243dSDimitry Andric 10349cc55cSDimitry Andric #ifndef _LIBCPP___RANGES_TAKE_VIEW_H 11349cc55cSDimitry Andric #define _LIBCPP___RANGES_TAKE_VIEW_H 12349cc55cSDimitry Andric 13349cc55cSDimitry Andric #include <__algorithm/min.h> 1481ad6265SDimitry Andric #include <__algorithm/ranges_min.h> 15bdd1243dSDimitry Andric #include <__assert> 16bdd1243dSDimitry Andric #include <__concepts/constructible.h> 17bdd1243dSDimitry Andric #include <__concepts/convertible_to.h> 18349cc55cSDimitry Andric #include <__config> 1981ad6265SDimitry Andric #include <__functional/bind_back.h> 2081ad6265SDimitry Andric #include <__fwd/span.h> 2181ad6265SDimitry Andric #include <__fwd/string_view.h> 22349cc55cSDimitry Andric #include <__iterator/concepts.h> 23349cc55cSDimitry Andric #include <__iterator/counted_iterator.h> 24349cc55cSDimitry Andric #include <__iterator/default_sentinel.h> 2581ad6265SDimitry Andric #include <__iterator/distance.h> 26349cc55cSDimitry Andric #include <__iterator/iterator_traits.h> 27349cc55cSDimitry Andric #include <__ranges/access.h> 28349cc55cSDimitry Andric #include <__ranges/all.h> 29349cc55cSDimitry Andric #include <__ranges/concepts.h> 3081ad6265SDimitry Andric #include <__ranges/empty_view.h> 31349cc55cSDimitry Andric #include <__ranges/enable_borrowed_range.h> 3281ad6265SDimitry Andric #include <__ranges/iota_view.h> 3381ad6265SDimitry Andric #include <__ranges/range_adaptor.h> 3406c3fb27SDimitry Andric #include <__ranges/repeat_view.h> 35349cc55cSDimitry Andric #include <__ranges/size.h> 3681ad6265SDimitry Andric #include <__ranges/subrange.h> 37349cc55cSDimitry Andric #include <__ranges/view_interface.h> 3806c3fb27SDimitry Andric #include <__type_traits/decay.h> 3906c3fb27SDimitry Andric #include <__type_traits/is_nothrow_constructible.h> 40bdd1243dSDimitry Andric #include <__type_traits/maybe_const.h> 4106c3fb27SDimitry Andric #include <__type_traits/remove_cvref.h> 4281ad6265SDimitry Andric #include <__utility/auto_cast.h> 4381ad6265SDimitry Andric #include <__utility/forward.h> 44349cc55cSDimitry Andric #include <__utility/move.h> 4506c3fb27SDimitry Andric #include <cstddef> 46349cc55cSDimitry Andric 47349cc55cSDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 48349cc55cSDimitry Andric # pragma GCC system_header 49349cc55cSDimitry Andric #endif 50349cc55cSDimitry Andric 51349cc55cSDimitry Andric _LIBCPP_PUSH_MACROS 52349cc55cSDimitry Andric #include <__undef_macros> 53349cc55cSDimitry Andric 54349cc55cSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 55349cc55cSDimitry Andric 5606c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20 57349cc55cSDimitry Andric 58349cc55cSDimitry Andric namespace ranges { 5981ad6265SDimitry Andric 60349cc55cSDimitry Andric template <view _View> 61349cc55cSDimitry Andric class take_view : public view_interface<take_view<_View>> { 6281ad6265SDimitry Andric _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); 63349cc55cSDimitry Andric range_difference_t<_View> __count_ = 0; 64349cc55cSDimitry Andric 65cb14a3feSDimitry Andric template <bool> 66cb14a3feSDimitry Andric class __sentinel; 67349cc55cSDimitry Andric 68349cc55cSDimitry Andric public: 69cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI take_view() 70cb14a3feSDimitry Andric requires default_initializable<_View> 71cb14a3feSDimitry Andric = default; 72349cc55cSDimitry Andric 73cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 74cb14a3feSDimitry Andric take_view(_View __base, range_difference_t<_View> __count) 75bdd1243dSDimitry Andric : __base_(std::move(__base)), __count_(__count) { 7606c3fb27SDimitry Andric _LIBCPP_ASSERT_UNCATEGORIZED(__count >= 0, "count has to be greater than or equal to zero"); 77bdd1243dSDimitry Andric } 78349cc55cSDimitry Andric 79cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr _View base() const& 80cb14a3feSDimitry Andric requires copy_constructible<_View> 81cb14a3feSDimitry Andric { 82cb14a3feSDimitry Andric return __base_; 83cb14a3feSDimitry Andric } 84349cc55cSDimitry Andric 85cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); } 86349cc55cSDimitry Andric 87cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto begin() 88cb14a3feSDimitry Andric requires(!__simple_view<_View>) 89cb14a3feSDimitry Andric { 90349cc55cSDimitry Andric if constexpr (sized_range<_View>) { 91349cc55cSDimitry Andric if constexpr (random_access_range<_View>) { 92349cc55cSDimitry Andric return ranges::begin(__base_); 93349cc55cSDimitry Andric } else { 94349cc55cSDimitry Andric using _DifferenceT = range_difference_t<_View>; 95349cc55cSDimitry Andric auto __size = size(); 96349cc55cSDimitry Andric return counted_iterator(ranges::begin(__base_), static_cast<_DifferenceT>(__size)); 97349cc55cSDimitry Andric } 98349cc55cSDimitry Andric } else { 99349cc55cSDimitry Andric return counted_iterator(ranges::begin(__base_), __count_); 100349cc55cSDimitry Andric } 101349cc55cSDimitry Andric } 102349cc55cSDimitry Andric 103cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const 104cb14a3feSDimitry Andric requires range<const _View> 105cb14a3feSDimitry Andric { 106349cc55cSDimitry Andric if constexpr (sized_range<const _View>) { 107349cc55cSDimitry Andric if constexpr (random_access_range<const _View>) { 108349cc55cSDimitry Andric return ranges::begin(__base_); 109349cc55cSDimitry Andric } else { 110349cc55cSDimitry Andric using _DifferenceT = range_difference_t<const _View>; 111349cc55cSDimitry Andric auto __size = size(); 112349cc55cSDimitry Andric return counted_iterator(ranges::begin(__base_), static_cast<_DifferenceT>(__size)); 113349cc55cSDimitry Andric } 114349cc55cSDimitry Andric } else { 115349cc55cSDimitry Andric return counted_iterator(ranges::begin(__base_), __count_); 116349cc55cSDimitry Andric } 117349cc55cSDimitry Andric } 118349cc55cSDimitry Andric 119cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto end() 120cb14a3feSDimitry Andric requires(!__simple_view<_View>) 121cb14a3feSDimitry Andric { 122349cc55cSDimitry Andric if constexpr (sized_range<_View>) { 123349cc55cSDimitry Andric if constexpr (random_access_range<_View>) { 124349cc55cSDimitry Andric return ranges::begin(__base_) + size(); 125349cc55cSDimitry Andric } else { 126349cc55cSDimitry Andric return default_sentinel; 127349cc55cSDimitry Andric } 128349cc55cSDimitry Andric } else { 129349cc55cSDimitry Andric return __sentinel<false>{ranges::end(__base_)}; 130349cc55cSDimitry Andric } 131349cc55cSDimitry Andric } 132349cc55cSDimitry Andric 133cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto end() const 134cb14a3feSDimitry Andric requires range<const _View> 135cb14a3feSDimitry Andric { 136349cc55cSDimitry Andric if constexpr (sized_range<const _View>) { 137349cc55cSDimitry Andric if constexpr (random_access_range<const _View>) { 138349cc55cSDimitry Andric return ranges::begin(__base_) + size(); 139349cc55cSDimitry Andric } else { 140349cc55cSDimitry Andric return default_sentinel; 141349cc55cSDimitry Andric } 142349cc55cSDimitry Andric } else { 143349cc55cSDimitry Andric return __sentinel<true>{ranges::end(__base_)}; 144349cc55cSDimitry Andric } 145349cc55cSDimitry Andric } 146349cc55cSDimitry Andric 147cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto size() 148cb14a3feSDimitry Andric requires sized_range<_View> 149cb14a3feSDimitry Andric { 150349cc55cSDimitry Andric auto __n = ranges::size(__base_); 15181ad6265SDimitry Andric return ranges::min(__n, static_cast<decltype(__n)>(__count_)); 152349cc55cSDimitry Andric } 153349cc55cSDimitry Andric 154cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto size() const 155cb14a3feSDimitry Andric requires sized_range<const _View> 156cb14a3feSDimitry Andric { 157349cc55cSDimitry Andric auto __n = ranges::size(__base_); 15881ad6265SDimitry Andric return ranges::min(__n, static_cast<decltype(__n)>(__count_)); 159349cc55cSDimitry Andric } 160349cc55cSDimitry Andric }; 161349cc55cSDimitry Andric 162349cc55cSDimitry Andric template <view _View> 163349cc55cSDimitry Andric template <bool _Const> 164349cc55cSDimitry Andric class take_view<_View>::__sentinel { 165349cc55cSDimitry Andric using _Base = __maybe_const<_Const, _View>; 166349cc55cSDimitry Andric template <bool _OtherConst> 167349cc55cSDimitry Andric using _Iter = counted_iterator<iterator_t<__maybe_const<_OtherConst, _View>>>; 16881ad6265SDimitry Andric _LIBCPP_NO_UNIQUE_ADDRESS sentinel_t<_Base> __end_ = sentinel_t<_Base>(); 169349cc55cSDimitry Andric 170349cc55cSDimitry Andric template <bool> 171349cc55cSDimitry Andric friend class take_view<_View>::__sentinel; 172349cc55cSDimitry Andric 173349cc55cSDimitry Andric public: 174cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __sentinel() = default; 175349cc55cSDimitry Andric 176cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(std::move(__end)) {} 177349cc55cSDimitry Andric 178cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel<!_Const> __s) 179349cc55cSDimitry Andric requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>> 18081ad6265SDimitry Andric : __end_(std::move(__s.__end_)) {} 181349cc55cSDimitry Andric 182cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Base> base() const { return __end_; } 183349cc55cSDimitry Andric 184cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const _Iter<_Const>& __lhs, const __sentinel& __rhs) { 185349cc55cSDimitry Andric return __lhs.count() == 0 || __lhs.base() == __rhs.__end_; 186349cc55cSDimitry Andric } 187349cc55cSDimitry Andric 188349cc55cSDimitry Andric template <bool _OtherConst = !_Const> 189349cc55cSDimitry Andric requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>> 1905f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const _Iter<_OtherConst>& __lhs, const __sentinel& __rhs) { 191349cc55cSDimitry Andric return __lhs.count() == 0 || __lhs.base() == __rhs.__end_; 192349cc55cSDimitry Andric } 193349cc55cSDimitry Andric }; 194349cc55cSDimitry Andric 195349cc55cSDimitry Andric template <class _Range> 196349cc55cSDimitry Andric take_view(_Range&&, range_difference_t<_Range>) -> take_view<views::all_t<_Range>>; 197349cc55cSDimitry Andric 198349cc55cSDimitry Andric template <class _Tp> 199349cc55cSDimitry Andric inline constexpr bool enable_borrowed_range<take_view<_Tp>> = enable_borrowed_range<_Tp>; 20081ad6265SDimitry Andric 20181ad6265SDimitry Andric namespace views { 20281ad6265SDimitry Andric namespace __take { 20381ad6265SDimitry Andric 20481ad6265SDimitry Andric template <class _Tp> 20581ad6265SDimitry Andric inline constexpr bool __is_empty_view = false; 20681ad6265SDimitry Andric 20781ad6265SDimitry Andric template <class _Tp> 20881ad6265SDimitry Andric inline constexpr bool __is_empty_view<empty_view<_Tp>> = true; 20981ad6265SDimitry Andric 21081ad6265SDimitry Andric template <class _Tp> 21181ad6265SDimitry Andric inline constexpr bool __is_passthrough_specialization = false; 21281ad6265SDimitry Andric 21381ad6265SDimitry Andric template <class _Tp, size_t _Extent> 21481ad6265SDimitry Andric inline constexpr bool __is_passthrough_specialization<span<_Tp, _Extent>> = true; 21581ad6265SDimitry Andric 21681ad6265SDimitry Andric template <class _CharT, class _Traits> 21781ad6265SDimitry Andric inline constexpr bool __is_passthrough_specialization<basic_string_view<_CharT, _Traits>> = true; 21881ad6265SDimitry Andric 21981ad6265SDimitry Andric template <class _Iter, class _Sent, subrange_kind _Kind> 22081ad6265SDimitry Andric inline constexpr bool __is_passthrough_specialization<subrange<_Iter, _Sent, _Kind>> = true; 22181ad6265SDimitry Andric 22281ad6265SDimitry Andric template <class _Tp> 22381ad6265SDimitry Andric inline constexpr bool __is_iota_specialization = false; 22481ad6265SDimitry Andric 22581ad6265SDimitry Andric template <class _Np, class _Bound> 22681ad6265SDimitry Andric inline constexpr bool __is_iota_specialization<iota_view<_Np, _Bound>> = true; 22781ad6265SDimitry Andric 22881ad6265SDimitry Andric template <class _Tp> 22981ad6265SDimitry Andric struct __passthrough_type; 23081ad6265SDimitry Andric 23181ad6265SDimitry Andric template <class _Tp, size_t _Extent> 23281ad6265SDimitry Andric struct __passthrough_type<span<_Tp, _Extent>> { 23381ad6265SDimitry Andric using type = span<_Tp>; 23481ad6265SDimitry Andric }; 23581ad6265SDimitry Andric 23681ad6265SDimitry Andric template <class _CharT, class _Traits> 23781ad6265SDimitry Andric struct __passthrough_type<basic_string_view<_CharT, _Traits>> { 23881ad6265SDimitry Andric using type = basic_string_view<_CharT, _Traits>; 23981ad6265SDimitry Andric }; 24081ad6265SDimitry Andric 24181ad6265SDimitry Andric template <class _Iter, class _Sent, subrange_kind _Kind> 242bdd1243dSDimitry Andric requires requires { typename subrange<_Iter>; } 24381ad6265SDimitry Andric struct __passthrough_type<subrange<_Iter, _Sent, _Kind>> { 24481ad6265SDimitry Andric using type = subrange<_Iter>; 24581ad6265SDimitry Andric }; 24681ad6265SDimitry Andric 24781ad6265SDimitry Andric template <class _Tp> 24881ad6265SDimitry Andric using __passthrough_type_t = typename __passthrough_type<_Tp>::type; 24981ad6265SDimitry Andric 25081ad6265SDimitry Andric struct __fn { 25181ad6265SDimitry Andric // [range.take.overview]: the `empty_view` case. 25281ad6265SDimitry Andric template <class _Range, convertible_to<range_difference_t<_Range>> _Np> 25381ad6265SDimitry Andric requires __is_empty_view<remove_cvref_t<_Range>> 254cb14a3feSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&&) const 25581ad6265SDimitry Andric noexcept(noexcept(_LIBCPP_AUTO_CAST(std::forward<_Range>(__range)))) 256cb14a3feSDimitry Andric -> decltype(_LIBCPP_AUTO_CAST(std::forward<_Range>(__range))) { 257cb14a3feSDimitry Andric return _LIBCPP_AUTO_CAST(std::forward<_Range>(__range)); 258cb14a3feSDimitry Andric } 25981ad6265SDimitry Andric 26081ad6265SDimitry Andric // [range.take.overview]: the `span | basic_string_view | subrange` case. 26181ad6265SDimitry Andric template <class _Range, 26281ad6265SDimitry Andric convertible_to<range_difference_t<_Range>> _Np, 26381ad6265SDimitry Andric class _RawRange = remove_cvref_t<_Range>, 26481ad6265SDimitry Andric class _Dist = range_difference_t<_Range>> 265cb14a3feSDimitry Andric requires(!__is_empty_view<_RawRange> && random_access_range<_RawRange> && sized_range<_RawRange> && 26681ad6265SDimitry Andric __is_passthrough_specialization<_RawRange>) 267cb14a3feSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto 268cb14a3feSDimitry Andric operator()(_Range&& __rng, _Np&& __n) const noexcept(noexcept(__passthrough_type_t<_RawRange>( 269cb14a3feSDimitry Andric ranges::begin(__rng), ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n))))) 27081ad6265SDimitry Andric -> decltype(__passthrough_type_t<_RawRange>( 27181ad6265SDimitry Andric // Note: deliberately not forwarding `__rng` to guard against double moves. 27281ad6265SDimitry Andric ranges::begin(__rng), 273cb14a3feSDimitry Andric ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)))) { 274cb14a3feSDimitry Andric return __passthrough_type_t<_RawRange>( 275cb14a3feSDimitry Andric ranges::begin(__rng), ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n))); 276cb14a3feSDimitry Andric } 27781ad6265SDimitry Andric 27881ad6265SDimitry Andric // [range.take.overview]: the `iota_view` case. 279cb14a3feSDimitry Andric // clang-format off 28081ad6265SDimitry Andric template <class _Range, 28181ad6265SDimitry Andric convertible_to<range_difference_t<_Range>> _Np, 28281ad6265SDimitry Andric class _RawRange = remove_cvref_t<_Range>, 28381ad6265SDimitry Andric class _Dist = range_difference_t<_Range>> 28481ad6265SDimitry Andric requires (!__is_empty_view<_RawRange> && 28581ad6265SDimitry Andric random_access_range<_RawRange> && 28681ad6265SDimitry Andric sized_range<_RawRange> && 28781ad6265SDimitry Andric __is_iota_specialization<_RawRange>) 28881ad6265SDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI 28981ad6265SDimitry Andric constexpr auto operator()(_Range&& __rng, _Np&& __n) const 29081ad6265SDimitry Andric noexcept(noexcept(ranges::iota_view( 29181ad6265SDimitry Andric *ranges::begin(__rng), 292cb14a3feSDimitry Andric *(ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n))) 29381ad6265SDimitry Andric ))) 29481ad6265SDimitry Andric -> decltype( ranges::iota_view( 29581ad6265SDimitry Andric // Note: deliberately not forwarding `__rng` to guard against double moves. 29681ad6265SDimitry Andric *ranges::begin(__rng), 297cb14a3feSDimitry Andric *(ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n))) 29881ad6265SDimitry Andric )) 29981ad6265SDimitry Andric { return ranges::iota_view( 30081ad6265SDimitry Andric *ranges::begin(__rng), 301cb14a3feSDimitry Andric *(ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n))) 30281ad6265SDimitry Andric ); } 303cb14a3feSDimitry Andric 30406c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23 30506c3fb27SDimitry Andric // [range.take.overview]: the `repeat_view` "_RawRange models sized_range" case. 30606c3fb27SDimitry Andric template <class _Range, 30706c3fb27SDimitry Andric convertible_to<range_difference_t<_Range>> _Np, 30806c3fb27SDimitry Andric class _RawRange = remove_cvref_t<_Range>, 30906c3fb27SDimitry Andric class _Dist = range_difference_t<_Range>> 31006c3fb27SDimitry Andric requires(__is_repeat_specialization<_RawRange> && sized_range<_RawRange>) 311*0fca6ea1SDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const 31206c3fb27SDimitry Andric noexcept(noexcept(views::repeat(*__range.__value_, std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))))) 31306c3fb27SDimitry Andric -> decltype( views::repeat(*__range.__value_, std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n)))) 31406c3fb27SDimitry Andric { return views::repeat(*__range.__value_, std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))); } 31506c3fb27SDimitry Andric 31606c3fb27SDimitry Andric // [range.take.overview]: the `repeat_view` "otherwise" case. 31706c3fb27SDimitry Andric template <class _Range, 31806c3fb27SDimitry Andric convertible_to<range_difference_t<_Range>> _Np, 31906c3fb27SDimitry Andric class _RawRange = remove_cvref_t<_Range>, 32006c3fb27SDimitry Andric class _Dist = range_difference_t<_Range>> 32106c3fb27SDimitry Andric requires(__is_repeat_specialization<_RawRange> && !sized_range<_RawRange>) 322*0fca6ea1SDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const 32306c3fb27SDimitry Andric noexcept(noexcept(views::repeat(*__range.__value_, static_cast<_Dist>(__n)))) 32406c3fb27SDimitry Andric -> decltype( views::repeat(*__range.__value_, static_cast<_Dist>(__n))) 32506c3fb27SDimitry Andric { return views::repeat(*__range.__value_, static_cast<_Dist>(__n)); } 32606c3fb27SDimitry Andric #endif 32706c3fb27SDimitry Andric // clang-format on 32881ad6265SDimitry Andric 32981ad6265SDimitry Andric // [range.take.overview]: the "otherwise" case. 330cb14a3feSDimitry Andric template <class _Range, convertible_to<range_difference_t<_Range>> _Np, class _RawRange = remove_cvref_t<_Range>> 33181ad6265SDimitry Andric // Note: without specifically excluding the other cases, GCC sees this overload as ambiguous with the other 33281ad6265SDimitry Andric // overloads. 33381ad6265SDimitry Andric requires(!(__is_empty_view<_RawRange> || 33406c3fb27SDimitry Andric # if _LIBCPP_STD_VER >= 23 33506c3fb27SDimitry Andric __is_repeat_specialization<_RawRange> || 33606c3fb27SDimitry Andric # endif 337cb14a3feSDimitry Andric (__is_iota_specialization<_RawRange> && sized_range<_RawRange> && random_access_range<_RawRange>) || 338cb14a3feSDimitry Andric (__is_passthrough_specialization<_RawRange> && sized_range<_RawRange> && 339cb14a3feSDimitry Andric random_access_range<_RawRange>))) 340cb14a3feSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const 34181ad6265SDimitry Andric noexcept(noexcept(take_view(std::forward<_Range>(__range), std::forward<_Np>(__n)))) 342cb14a3feSDimitry Andric -> decltype(take_view(std::forward<_Range>(__range), std::forward<_Np>(__n))) { 343cb14a3feSDimitry Andric return take_view(std::forward<_Range>(__range), std::forward<_Np>(__n)); 344cb14a3feSDimitry Andric } 34581ad6265SDimitry Andric 34681ad6265SDimitry Andric template <class _Np> 34781ad6265SDimitry Andric requires constructible_from<decay_t<_Np>, _Np> 348cb14a3feSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Np&& __n) const 349cb14a3feSDimitry Andric noexcept(is_nothrow_constructible_v<decay_t<_Np>, _Np>) { 350cb14a3feSDimitry Andric return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Np>(__n))); 351cb14a3feSDimitry Andric } 35281ad6265SDimitry Andric }; 35381ad6265SDimitry Andric 35481ad6265SDimitry Andric } // namespace __take 35581ad6265SDimitry Andric 35681ad6265SDimitry Andric inline namespace __cpo { 35781ad6265SDimitry Andric inline constexpr auto take = __take::__fn{}; 35881ad6265SDimitry Andric } // namespace __cpo 35981ad6265SDimitry Andric } // namespace views 36081ad6265SDimitry Andric 361349cc55cSDimitry Andric } // namespace ranges 362349cc55cSDimitry Andric 36306c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 20 364349cc55cSDimitry Andric 365349cc55cSDimitry Andric _LIBCPP_END_NAMESPACE_STD 366349cc55cSDimitry Andric 367349cc55cSDimitry Andric _LIBCPP_POP_MACROS 368349cc55cSDimitry Andric 369349cc55cSDimitry Andric #endif // _LIBCPP___RANGES_TAKE_VIEW_H 370