xref: /freebsd-src/contrib/llvm-project/libcxx/include/__ranges/take_view.h (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
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