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