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> 34*06c3fb27SDimitry 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> 38*06c3fb27SDimitry Andric #include <__type_traits/decay.h> 39*06c3fb27SDimitry Andric #include <__type_traits/is_nothrow_constructible.h> 40bdd1243dSDimitry Andric #include <__type_traits/maybe_const.h> 41*06c3fb27SDimitry 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> 45*06c3fb27SDimitry 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 56*06c3fb27SDimitry 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 65349cc55cSDimitry Andric template<bool> class __sentinel; 66349cc55cSDimitry Andric 67349cc55cSDimitry Andric public: 68349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 69349cc55cSDimitry Andric take_view() requires default_initializable<_View> = default; 70349cc55cSDimitry Andric 71*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 72*06c3fb27SDimitry Andric constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 take_view(_View __base, range_difference_t<_View> __count) 73bdd1243dSDimitry Andric : __base_(std::move(__base)), __count_(__count) { 74*06c3fb27SDimitry Andric _LIBCPP_ASSERT_UNCATEGORIZED(__count >= 0, "count has to be greater than or equal to zero"); 75bdd1243dSDimitry Andric } 76349cc55cSDimitry Andric 77349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 78349cc55cSDimitry Andric constexpr _View base() const& requires copy_constructible<_View> { return __base_; } 79349cc55cSDimitry Andric 80349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 8181ad6265SDimitry Andric constexpr _View base() && { return std::move(__base_); } 82349cc55cSDimitry Andric 83349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 84349cc55cSDimitry Andric constexpr auto begin() requires (!__simple_view<_View>) { 85349cc55cSDimitry Andric if constexpr (sized_range<_View>) { 86349cc55cSDimitry Andric if constexpr (random_access_range<_View>) { 87349cc55cSDimitry Andric return ranges::begin(__base_); 88349cc55cSDimitry Andric } else { 89349cc55cSDimitry Andric using _DifferenceT = range_difference_t<_View>; 90349cc55cSDimitry Andric auto __size = size(); 91349cc55cSDimitry Andric return counted_iterator(ranges::begin(__base_), static_cast<_DifferenceT>(__size)); 92349cc55cSDimitry Andric } 93349cc55cSDimitry Andric } else { 94349cc55cSDimitry Andric return counted_iterator(ranges::begin(__base_), __count_); 95349cc55cSDimitry Andric } 96349cc55cSDimitry Andric } 97349cc55cSDimitry Andric 98349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 99349cc55cSDimitry Andric constexpr auto begin() const requires range<const _View> { 100349cc55cSDimitry Andric if constexpr (sized_range<const _View>) { 101349cc55cSDimitry Andric if constexpr (random_access_range<const _View>) { 102349cc55cSDimitry Andric return ranges::begin(__base_); 103349cc55cSDimitry Andric } else { 104349cc55cSDimitry Andric using _DifferenceT = range_difference_t<const _View>; 105349cc55cSDimitry Andric auto __size = size(); 106349cc55cSDimitry Andric return counted_iterator(ranges::begin(__base_), static_cast<_DifferenceT>(__size)); 107349cc55cSDimitry Andric } 108349cc55cSDimitry Andric } else { 109349cc55cSDimitry Andric return counted_iterator(ranges::begin(__base_), __count_); 110349cc55cSDimitry Andric } 111349cc55cSDimitry Andric } 112349cc55cSDimitry Andric 113349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 114349cc55cSDimitry Andric constexpr auto end() requires (!__simple_view<_View>) { 115349cc55cSDimitry Andric if constexpr (sized_range<_View>) { 116349cc55cSDimitry Andric if constexpr (random_access_range<_View>) { 117349cc55cSDimitry Andric return ranges::begin(__base_) + size(); 118349cc55cSDimitry Andric } else { 119349cc55cSDimitry Andric return default_sentinel; 120349cc55cSDimitry Andric } 121349cc55cSDimitry Andric } else { 122349cc55cSDimitry Andric return __sentinel<false>{ranges::end(__base_)}; 123349cc55cSDimitry Andric } 124349cc55cSDimitry Andric } 125349cc55cSDimitry Andric 126349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 127349cc55cSDimitry Andric constexpr auto end() const requires range<const _View> { 128349cc55cSDimitry Andric if constexpr (sized_range<const _View>) { 129349cc55cSDimitry Andric if constexpr (random_access_range<const _View>) { 130349cc55cSDimitry Andric return ranges::begin(__base_) + size(); 131349cc55cSDimitry Andric } else { 132349cc55cSDimitry Andric return default_sentinel; 133349cc55cSDimitry Andric } 134349cc55cSDimitry Andric } else { 135349cc55cSDimitry Andric return __sentinel<true>{ranges::end(__base_)}; 136349cc55cSDimitry Andric } 137349cc55cSDimitry Andric } 138349cc55cSDimitry Andric 139349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 140349cc55cSDimitry Andric constexpr auto size() requires sized_range<_View> { 141349cc55cSDimitry Andric auto __n = ranges::size(__base_); 14281ad6265SDimitry Andric return ranges::min(__n, static_cast<decltype(__n)>(__count_)); 143349cc55cSDimitry Andric } 144349cc55cSDimitry Andric 145349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 146349cc55cSDimitry Andric constexpr auto size() const requires sized_range<const _View> { 147349cc55cSDimitry Andric auto __n = ranges::size(__base_); 14881ad6265SDimitry Andric return ranges::min(__n, static_cast<decltype(__n)>(__count_)); 149349cc55cSDimitry Andric } 150349cc55cSDimitry Andric }; 151349cc55cSDimitry Andric 152349cc55cSDimitry Andric template<view _View> 153349cc55cSDimitry Andric template<bool _Const> 154349cc55cSDimitry Andric class take_view<_View>::__sentinel { 155349cc55cSDimitry Andric using _Base = __maybe_const<_Const, _View>; 156349cc55cSDimitry Andric template<bool _OtherConst> 157349cc55cSDimitry Andric using _Iter = counted_iterator<iterator_t<__maybe_const<_OtherConst, _View>>>; 15881ad6265SDimitry Andric _LIBCPP_NO_UNIQUE_ADDRESS sentinel_t<_Base> __end_ = sentinel_t<_Base>(); 159349cc55cSDimitry Andric 160349cc55cSDimitry Andric template<bool> 161349cc55cSDimitry Andric friend class take_view<_View>::__sentinel; 162349cc55cSDimitry Andric 163349cc55cSDimitry Andric public: 164349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 165349cc55cSDimitry Andric __sentinel() = default; 166349cc55cSDimitry Andric 167349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 16881ad6265SDimitry Andric constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(std::move(__end)) {} 169349cc55cSDimitry Andric 170349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 171349cc55cSDimitry Andric constexpr __sentinel(__sentinel<!_Const> __s) 172349cc55cSDimitry Andric requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>> 17381ad6265SDimitry Andric : __end_(std::move(__s.__end_)) {} 174349cc55cSDimitry Andric 175349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 176349cc55cSDimitry Andric constexpr sentinel_t<_Base> base() const { return __end_; } 177349cc55cSDimitry Andric 178349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 179349cc55cSDimitry Andric friend constexpr bool operator==(const _Iter<_Const>& __lhs, const __sentinel& __rhs) { 180349cc55cSDimitry Andric return __lhs.count() == 0 || __lhs.base() == __rhs.__end_; 181349cc55cSDimitry Andric } 182349cc55cSDimitry Andric 183349cc55cSDimitry Andric template<bool _OtherConst = !_Const> 184349cc55cSDimitry Andric requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>> 185349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 186349cc55cSDimitry Andric friend constexpr bool operator==(const _Iter<_Const>& __lhs, const __sentinel& __rhs) { 187349cc55cSDimitry Andric return __lhs.count() == 0 || __lhs.base() == __rhs.__end_; 188349cc55cSDimitry Andric } 189349cc55cSDimitry Andric }; 190349cc55cSDimitry Andric 191349cc55cSDimitry Andric template<class _Range> 192349cc55cSDimitry Andric take_view(_Range&&, range_difference_t<_Range>) -> take_view<views::all_t<_Range>>; 193349cc55cSDimitry Andric 194349cc55cSDimitry Andric template<class _Tp> 195349cc55cSDimitry Andric inline constexpr bool enable_borrowed_range<take_view<_Tp>> = enable_borrowed_range<_Tp>; 19681ad6265SDimitry Andric 19781ad6265SDimitry Andric namespace views { 19881ad6265SDimitry Andric namespace __take { 19981ad6265SDimitry Andric 20081ad6265SDimitry Andric template <class _Tp> 20181ad6265SDimitry Andric inline constexpr bool __is_empty_view = false; 20281ad6265SDimitry Andric 20381ad6265SDimitry Andric template <class _Tp> 20481ad6265SDimitry Andric inline constexpr bool __is_empty_view<empty_view<_Tp>> = true; 20581ad6265SDimitry Andric 20681ad6265SDimitry Andric template <class _Tp> 20781ad6265SDimitry Andric inline constexpr bool __is_passthrough_specialization = false; 20881ad6265SDimitry Andric 20981ad6265SDimitry Andric template <class _Tp, size_t _Extent> 21081ad6265SDimitry Andric inline constexpr bool __is_passthrough_specialization<span<_Tp, _Extent>> = true; 21181ad6265SDimitry Andric 21281ad6265SDimitry Andric template <class _CharT, class _Traits> 21381ad6265SDimitry Andric inline constexpr bool __is_passthrough_specialization<basic_string_view<_CharT, _Traits>> = true; 21481ad6265SDimitry Andric 21581ad6265SDimitry Andric template <class _Iter, class _Sent, subrange_kind _Kind> 21681ad6265SDimitry Andric inline constexpr bool __is_passthrough_specialization<subrange<_Iter, _Sent, _Kind>> = true; 21781ad6265SDimitry Andric 21881ad6265SDimitry Andric template <class _Tp> 21981ad6265SDimitry Andric inline constexpr bool __is_iota_specialization = false; 22081ad6265SDimitry Andric 22181ad6265SDimitry Andric template <class _Np, class _Bound> 22281ad6265SDimitry Andric inline constexpr bool __is_iota_specialization<iota_view<_Np, _Bound>> = true; 22381ad6265SDimitry Andric 22481ad6265SDimitry Andric template <class _Tp> 22581ad6265SDimitry Andric struct __passthrough_type; 22681ad6265SDimitry Andric 22781ad6265SDimitry Andric template <class _Tp, size_t _Extent> 22881ad6265SDimitry Andric struct __passthrough_type<span<_Tp, _Extent>> { 22981ad6265SDimitry Andric using type = span<_Tp>; 23081ad6265SDimitry Andric }; 23181ad6265SDimitry Andric 23281ad6265SDimitry Andric template <class _CharT, class _Traits> 23381ad6265SDimitry Andric struct __passthrough_type<basic_string_view<_CharT, _Traits>> { 23481ad6265SDimitry Andric using type = basic_string_view<_CharT, _Traits>; 23581ad6265SDimitry Andric }; 23681ad6265SDimitry Andric 23781ad6265SDimitry Andric template <class _Iter, class _Sent, subrange_kind _Kind> 238bdd1243dSDimitry Andric requires requires{typename subrange<_Iter>;} 23981ad6265SDimitry Andric struct __passthrough_type<subrange<_Iter, _Sent, _Kind>> { 24081ad6265SDimitry Andric using type = subrange<_Iter>; 24181ad6265SDimitry Andric }; 24281ad6265SDimitry Andric 24381ad6265SDimitry Andric template <class _Tp> 24481ad6265SDimitry Andric using __passthrough_type_t = typename __passthrough_type<_Tp>::type; 24581ad6265SDimitry Andric 24681ad6265SDimitry Andric struct __fn { 24781ad6265SDimitry Andric // [range.take.overview]: the `empty_view` case. 24881ad6265SDimitry Andric template <class _Range, convertible_to<range_difference_t<_Range>> _Np> 24981ad6265SDimitry Andric requires __is_empty_view<remove_cvref_t<_Range>> 25081ad6265SDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI 25181ad6265SDimitry Andric constexpr auto operator()(_Range&& __range, _Np&&) const 25281ad6265SDimitry Andric noexcept(noexcept(_LIBCPP_AUTO_CAST(std::forward<_Range>(__range)))) 25381ad6265SDimitry Andric -> decltype( _LIBCPP_AUTO_CAST(std::forward<_Range>(__range))) 25481ad6265SDimitry Andric { return _LIBCPP_AUTO_CAST(std::forward<_Range>(__range)); } 25581ad6265SDimitry Andric 25681ad6265SDimitry Andric // [range.take.overview]: the `span | basic_string_view | subrange` case. 25781ad6265SDimitry Andric template <class _Range, 25881ad6265SDimitry Andric convertible_to<range_difference_t<_Range>> _Np, 25981ad6265SDimitry Andric class _RawRange = remove_cvref_t<_Range>, 26081ad6265SDimitry Andric class _Dist = range_difference_t<_Range>> 26181ad6265SDimitry Andric requires (!__is_empty_view<_RawRange> && 26281ad6265SDimitry Andric random_access_range<_RawRange> && 26381ad6265SDimitry Andric sized_range<_RawRange> && 26481ad6265SDimitry Andric __is_passthrough_specialization<_RawRange>) 26581ad6265SDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI 26681ad6265SDimitry Andric constexpr auto operator()(_Range&& __rng, _Np&& __n) const 26781ad6265SDimitry Andric noexcept(noexcept(__passthrough_type_t<_RawRange>( 26881ad6265SDimitry Andric ranges::begin(__rng), 26981ad6265SDimitry Andric ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)) 27081ad6265SDimitry Andric ))) 27181ad6265SDimitry Andric -> decltype( __passthrough_type_t<_RawRange>( 27281ad6265SDimitry Andric // Note: deliberately not forwarding `__rng` to guard against double moves. 27381ad6265SDimitry Andric ranges::begin(__rng), 27481ad6265SDimitry Andric ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)) 27581ad6265SDimitry Andric )) 27681ad6265SDimitry Andric { return __passthrough_type_t<_RawRange>( 27781ad6265SDimitry Andric ranges::begin(__rng), 27881ad6265SDimitry Andric ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)) 27981ad6265SDimitry Andric ); } 28081ad6265SDimitry Andric 28181ad6265SDimitry Andric // [range.take.overview]: the `iota_view` case. 28281ad6265SDimitry Andric template <class _Range, 28381ad6265SDimitry Andric convertible_to<range_difference_t<_Range>> _Np, 28481ad6265SDimitry Andric class _RawRange = remove_cvref_t<_Range>, 28581ad6265SDimitry Andric class _Dist = range_difference_t<_Range>> 28681ad6265SDimitry Andric requires (!__is_empty_view<_RawRange> && 28781ad6265SDimitry Andric random_access_range<_RawRange> && 28881ad6265SDimitry Andric sized_range<_RawRange> && 28981ad6265SDimitry Andric __is_iota_specialization<_RawRange>) 29081ad6265SDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI 29181ad6265SDimitry Andric constexpr auto operator()(_Range&& __rng, _Np&& __n) const 29281ad6265SDimitry Andric noexcept(noexcept(ranges::iota_view( 29381ad6265SDimitry Andric *ranges::begin(__rng), 29481ad6265SDimitry Andric *ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)) 29581ad6265SDimitry Andric ))) 29681ad6265SDimitry Andric -> decltype( ranges::iota_view( 29781ad6265SDimitry Andric // Note: deliberately not forwarding `__rng` to guard against double moves. 29881ad6265SDimitry Andric *ranges::begin(__rng), 29981ad6265SDimitry Andric *ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)) 30081ad6265SDimitry Andric )) 30181ad6265SDimitry Andric { return ranges::iota_view( 30281ad6265SDimitry Andric *ranges::begin(__rng), 30381ad6265SDimitry Andric *ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)) 30481ad6265SDimitry Andric ); } 305*06c3fb27SDimitry Andric // clang-format off 306*06c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23 307*06c3fb27SDimitry Andric // [range.take.overview]: the `repeat_view` "_RawRange models sized_range" case. 308*06c3fb27SDimitry Andric template <class _Range, 309*06c3fb27SDimitry Andric convertible_to<range_difference_t<_Range>> _Np, 310*06c3fb27SDimitry Andric class _RawRange = remove_cvref_t<_Range>, 311*06c3fb27SDimitry Andric class _Dist = range_difference_t<_Range>> 312*06c3fb27SDimitry Andric requires(__is_repeat_specialization<_RawRange> && sized_range<_RawRange>) 313*06c3fb27SDimitry Andric _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const 314*06c3fb27SDimitry Andric noexcept(noexcept(views::repeat(*__range.__value_, std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))))) 315*06c3fb27SDimitry Andric -> decltype( views::repeat(*__range.__value_, std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n)))) 316*06c3fb27SDimitry Andric { return views::repeat(*__range.__value_, std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))); } 317*06c3fb27SDimitry Andric 318*06c3fb27SDimitry Andric // [range.take.overview]: the `repeat_view` "otherwise" case. 319*06c3fb27SDimitry Andric template <class _Range, 320*06c3fb27SDimitry Andric convertible_to<range_difference_t<_Range>> _Np, 321*06c3fb27SDimitry Andric class _RawRange = remove_cvref_t<_Range>, 322*06c3fb27SDimitry Andric class _Dist = range_difference_t<_Range>> 323*06c3fb27SDimitry Andric requires(__is_repeat_specialization<_RawRange> && !sized_range<_RawRange>) 324*06c3fb27SDimitry Andric _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const 325*06c3fb27SDimitry Andric noexcept(noexcept(views::repeat(*__range.__value_, static_cast<_Dist>(__n)))) 326*06c3fb27SDimitry Andric -> decltype( views::repeat(*__range.__value_, static_cast<_Dist>(__n))) 327*06c3fb27SDimitry Andric { return views::repeat(*__range.__value_, static_cast<_Dist>(__n)); } 328*06c3fb27SDimitry Andric #endif 329*06c3fb27SDimitry Andric // clang-format on 33081ad6265SDimitry Andric 33181ad6265SDimitry Andric // [range.take.overview]: the "otherwise" case. 33281ad6265SDimitry Andric template <class _Range, convertible_to<range_difference_t<_Range>> _Np, 33381ad6265SDimitry Andric class _RawRange = remove_cvref_t<_Range>> 33481ad6265SDimitry Andric // Note: without specifically excluding the other cases, GCC sees this overload as ambiguous with the other 33581ad6265SDimitry Andric // overloads. 33681ad6265SDimitry Andric requires (!(__is_empty_view<_RawRange> || 337*06c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23 338*06c3fb27SDimitry Andric __is_repeat_specialization<_RawRange> || 339*06c3fb27SDimitry Andric #endif 34081ad6265SDimitry Andric (__is_iota_specialization<_RawRange> && 34181ad6265SDimitry Andric sized_range<_RawRange> && 34281ad6265SDimitry Andric random_access_range<_RawRange>) || 34381ad6265SDimitry Andric (__is_passthrough_specialization<_RawRange> && 34481ad6265SDimitry Andric sized_range<_RawRange> && 34581ad6265SDimitry Andric random_access_range<_RawRange>) 34681ad6265SDimitry Andric )) 34781ad6265SDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI 34881ad6265SDimitry Andric constexpr auto operator()(_Range&& __range, _Np&& __n) const 34981ad6265SDimitry Andric noexcept(noexcept(take_view(std::forward<_Range>(__range), std::forward<_Np>(__n)))) 35081ad6265SDimitry Andric -> decltype( take_view(std::forward<_Range>(__range), std::forward<_Np>(__n))) 35181ad6265SDimitry Andric { return take_view(std::forward<_Range>(__range), std::forward<_Np>(__n)); } 35281ad6265SDimitry Andric 35381ad6265SDimitry Andric template <class _Np> 35481ad6265SDimitry Andric requires constructible_from<decay_t<_Np>, _Np> 35581ad6265SDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI 35681ad6265SDimitry Andric constexpr auto operator()(_Np&& __n) const 35781ad6265SDimitry Andric noexcept(is_nothrow_constructible_v<decay_t<_Np>, _Np>) 35881ad6265SDimitry Andric { return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Np>(__n))); } 35981ad6265SDimitry Andric }; 36081ad6265SDimitry Andric 36181ad6265SDimitry Andric } // namespace __take 36281ad6265SDimitry Andric 36381ad6265SDimitry Andric inline namespace __cpo { 36481ad6265SDimitry Andric inline constexpr auto take = __take::__fn{}; 36581ad6265SDimitry Andric } // namespace __cpo 36681ad6265SDimitry Andric } // namespace views 36781ad6265SDimitry Andric 368349cc55cSDimitry Andric } // namespace ranges 369349cc55cSDimitry Andric 370*06c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 20 371349cc55cSDimitry Andric 372349cc55cSDimitry Andric _LIBCPP_END_NAMESPACE_STD 373349cc55cSDimitry Andric 374349cc55cSDimitry Andric _LIBCPP_POP_MACROS 375349cc55cSDimitry Andric 376349cc55cSDimitry Andric #endif // _LIBCPP___RANGES_TAKE_VIEW_H 377