xref: /freebsd-src/contrib/llvm-project/libcxx/include/__ranges/drop_view.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1fe6060f1SDimitry Andric // -*- C++ -*-
2fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
3fe6060f1SDimitry Andric //
4fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
6fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7fe6060f1SDimitry Andric //
8fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
9bdd1243dSDimitry Andric 
10fe6060f1SDimitry Andric #ifndef _LIBCPP___RANGES_DROP_VIEW_H
11fe6060f1SDimitry Andric #define _LIBCPP___RANGES_DROP_VIEW_H
12fe6060f1SDimitry Andric 
1381ad6265SDimitry Andric #include <__algorithm/min.h>
1481ad6265SDimitry Andric #include <__assert>
15bdd1243dSDimitry Andric #include <__concepts/constructible.h>
16bdd1243dSDimitry Andric #include <__concepts/convertible_to.h>
17fe6060f1SDimitry Andric #include <__config>
1881ad6265SDimitry Andric #include <__functional/bind_back.h>
1981ad6265SDimitry Andric #include <__fwd/span.h>
2081ad6265SDimitry Andric #include <__fwd/string_view.h>
21fe6060f1SDimitry Andric #include <__iterator/concepts.h>
2281ad6265SDimitry Andric #include <__iterator/distance.h>
23fe6060f1SDimitry Andric #include <__iterator/iterator_traits.h>
24fe6060f1SDimitry Andric #include <__iterator/next.h>
25fe6060f1SDimitry Andric #include <__ranges/access.h>
26fe6060f1SDimitry Andric #include <__ranges/all.h>
27fe6060f1SDimitry Andric #include <__ranges/concepts.h>
2881ad6265SDimitry Andric #include <__ranges/empty_view.h>
29fe6060f1SDimitry Andric #include <__ranges/enable_borrowed_range.h>
3081ad6265SDimitry Andric #include <__ranges/iota_view.h>
31fe6060f1SDimitry Andric #include <__ranges/non_propagating_cache.h>
3281ad6265SDimitry Andric #include <__ranges/range_adaptor.h>
3306c3fb27SDimitry Andric #include <__ranges/repeat_view.h>
34fe6060f1SDimitry Andric #include <__ranges/size.h>
3581ad6265SDimitry Andric #include <__ranges/subrange.h>
36fe6060f1SDimitry Andric #include <__ranges/view_interface.h>
3706c3fb27SDimitry Andric #include <__type_traits/conditional.h>
3806c3fb27SDimitry Andric #include <__type_traits/decay.h>
3906c3fb27SDimitry Andric #include <__type_traits/is_nothrow_constructible.h>
4006c3fb27SDimitry Andric #include <__type_traits/make_unsigned.h>
4106c3fb27SDimitry Andric #include <__type_traits/remove_cvref.h>
4281ad6265SDimitry Andric #include <__utility/auto_cast.h>
4381ad6265SDimitry Andric #include <__utility/forward.h>
44fe6060f1SDimitry Andric #include <__utility/move.h>
4506c3fb27SDimitry Andric #include <cstddef>
46fe6060f1SDimitry Andric 
47fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
48fe6060f1SDimitry Andric #  pragma GCC system_header
49fe6060f1SDimitry Andric #endif
50fe6060f1SDimitry Andric 
5181ad6265SDimitry Andric _LIBCPP_PUSH_MACROS
5281ad6265SDimitry Andric #include <__undef_macros>
5381ad6265SDimitry Andric 
54fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
55fe6060f1SDimitry Andric 
5606c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20
57fe6060f1SDimitry Andric 
58fe6060f1SDimitry Andric namespace ranges {
59fe6060f1SDimitry Andric template <view _View>
60cb14a3feSDimitry Andric class drop_view : public view_interface<drop_view<_View>> {
61fe6060f1SDimitry Andric   // We cache begin() whenever ranges::next is not guaranteed O(1) to provide an
62fe6060f1SDimitry Andric   // amortized O(1) begin() method. If this is an input_range, then we cannot cache
63fe6060f1SDimitry Andric   // begin because begin is not equality preserving.
64fe6060f1SDimitry Andric   // Note: drop_view<input-range>::begin() is still trivially amortized O(1) because
65fe6060f1SDimitry Andric   // one can't call begin() on it more than once.
66fe6060f1SDimitry Andric   static constexpr bool _UseCache = forward_range<_View> && !(random_access_range<_View> && sized_range<_View>);
67fe6060f1SDimitry Andric   using _Cache                    = _If<_UseCache, __non_propagating_cache<iterator_t<_View>>, __empty_cache>;
6881ad6265SDimitry Andric   _LIBCPP_NO_UNIQUE_ADDRESS _Cache __cached_begin_ = _Cache();
69fe6060f1SDimitry Andric   range_difference_t<_View> __count_               = 0;
70fe6060f1SDimitry Andric   _View __base_                                    = _View();
71fe6060f1SDimitry Andric 
72fe6060f1SDimitry Andric public:
73cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI drop_view()
74cb14a3feSDimitry Andric     requires default_initializable<_View>
75cb14a3feSDimitry Andric   = default;
76fe6060f1SDimitry Andric 
77cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23
78cb14a3feSDimitry Andric   drop_view(_View __base, range_difference_t<_View> __count)
79cb14a3feSDimitry Andric       : __count_(__count), __base_(std::move(__base)) {
8006c3fb27SDimitry Andric     _LIBCPP_ASSERT_UNCATEGORIZED(__count_ >= 0, "count must be greater than or equal to zero.");
81fe6060f1SDimitry Andric   }
82fe6060f1SDimitry Andric 
83cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
84cb14a3feSDimitry Andric     requires copy_constructible<_View>
85cb14a3feSDimitry Andric   {
86cb14a3feSDimitry Andric     return __base_;
87cb14a3feSDimitry Andric   }
8881ad6265SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
89fe6060f1SDimitry Andric 
90cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto begin()
91cb14a3feSDimitry Andric     requires(!(__simple_view<_View> && random_access_range<const _View> && sized_range<const _View>))
92fe6060f1SDimitry Andric   {
93647cbc5dSDimitry Andric     if constexpr (random_access_range<_View> && sized_range<_View>) {
94647cbc5dSDimitry Andric       const auto __dist = std::min(ranges::distance(__base_), __count_);
95647cbc5dSDimitry Andric       return ranges::begin(__base_) + __dist;
96647cbc5dSDimitry Andric     }
97fe6060f1SDimitry Andric     if constexpr (_UseCache)
98fe6060f1SDimitry Andric       if (__cached_begin_.__has_value())
99fe6060f1SDimitry Andric         return *__cached_begin_;
100fe6060f1SDimitry Andric 
101fe6060f1SDimitry Andric     auto __tmp = ranges::next(ranges::begin(__base_), __count_, ranges::end(__base_));
102fe6060f1SDimitry Andric     if constexpr (_UseCache)
103349cc55cSDimitry Andric       __cached_begin_.__emplace(__tmp);
104fe6060f1SDimitry Andric     return __tmp;
105fe6060f1SDimitry Andric   }
106fe6060f1SDimitry Andric 
107cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
108fe6060f1SDimitry Andric     requires random_access_range<const _View> && sized_range<const _View>
109fe6060f1SDimitry Andric   {
110647cbc5dSDimitry Andric     const auto __dist = std::min(ranges::distance(__base_), __count_);
111647cbc5dSDimitry Andric     return ranges::begin(__base_) + __dist;
112fe6060f1SDimitry Andric   }
113fe6060f1SDimitry Andric 
114cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto end()
115fe6060f1SDimitry Andric     requires(!__simple_view<_View>)
116cb14a3feSDimitry Andric   {
117cb14a3feSDimitry Andric     return ranges::end(__base_);
118cb14a3feSDimitry Andric   }
119fe6060f1SDimitry Andric 
120cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
121fe6060f1SDimitry Andric     requires range<const _View>
122cb14a3feSDimitry Andric   {
123cb14a3feSDimitry Andric     return ranges::end(__base_);
124cb14a3feSDimitry Andric   }
125fe6060f1SDimitry Andric 
126cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI static constexpr auto __size(auto& __self) {
127fe6060f1SDimitry Andric     const auto __s = ranges::size(__self.__base_);
128fe6060f1SDimitry Andric     const auto __c = static_cast<decltype(__s)>(__self.__count_);
129fe6060f1SDimitry Andric     return __s < __c ? 0 : __s - __c;
130fe6060f1SDimitry Andric   }
131fe6060f1SDimitry Andric 
132cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto size()
133fe6060f1SDimitry Andric     requires sized_range<_View>
134cb14a3feSDimitry Andric   {
135cb14a3feSDimitry Andric     return __size(*this);
136cb14a3feSDimitry Andric   }
137fe6060f1SDimitry Andric 
138cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
139fe6060f1SDimitry Andric     requires sized_range<const _View>
140cb14a3feSDimitry Andric   {
141cb14a3feSDimitry Andric     return __size(*this);
142cb14a3feSDimitry Andric   }
143fe6060f1SDimitry Andric };
144fe6060f1SDimitry Andric 
145fe6060f1SDimitry Andric template <class _Range>
146fe6060f1SDimitry Andric drop_view(_Range&&, range_difference_t<_Range>) -> drop_view<views::all_t<_Range>>;
147fe6060f1SDimitry Andric 
148fe6060f1SDimitry Andric template <class _Tp>
149fe6060f1SDimitry Andric inline constexpr bool enable_borrowed_range<drop_view<_Tp>> = enable_borrowed_range<_Tp>;
15081ad6265SDimitry Andric 
15181ad6265SDimitry Andric namespace views {
15281ad6265SDimitry Andric namespace __drop {
15381ad6265SDimitry Andric 
15481ad6265SDimitry Andric template <class _Tp>
15581ad6265SDimitry Andric inline constexpr bool __is_empty_view = false;
15681ad6265SDimitry Andric 
15781ad6265SDimitry Andric template <class _Tp>
15881ad6265SDimitry Andric inline constexpr bool __is_empty_view<empty_view<_Tp>> = true;
15981ad6265SDimitry Andric 
16081ad6265SDimitry Andric template <class _Tp>
16181ad6265SDimitry Andric inline constexpr bool __is_passthrough_specialization = false;
16281ad6265SDimitry Andric 
16381ad6265SDimitry Andric template <class _Tp, size_t _Extent>
16481ad6265SDimitry Andric inline constexpr bool __is_passthrough_specialization<span<_Tp, _Extent>> = true;
16581ad6265SDimitry Andric 
16681ad6265SDimitry Andric template <class _CharT, class _Traits>
16781ad6265SDimitry Andric inline constexpr bool __is_passthrough_specialization<basic_string_view<_CharT, _Traits>> = true;
16881ad6265SDimitry Andric 
16981ad6265SDimitry Andric template <class _Np, class _Bound>
17081ad6265SDimitry Andric inline constexpr bool __is_passthrough_specialization<iota_view<_Np, _Bound>> = true;
17181ad6265SDimitry Andric 
17281ad6265SDimitry Andric template <class _Iter, class _Sent, subrange_kind _Kind>
17381ad6265SDimitry Andric inline constexpr bool __is_passthrough_specialization<subrange<_Iter, _Sent, _Kind>> =
17481ad6265SDimitry Andric     !subrange<_Iter, _Sent, _Kind>::_StoreSize;
17581ad6265SDimitry Andric 
17681ad6265SDimitry Andric template <class _Tp>
17781ad6265SDimitry Andric inline constexpr bool __is_subrange_specialization_with_store_size = false;
17881ad6265SDimitry Andric 
17981ad6265SDimitry Andric template <class _Iter, class _Sent, subrange_kind _Kind>
18081ad6265SDimitry Andric inline constexpr bool __is_subrange_specialization_with_store_size<subrange<_Iter, _Sent, _Kind>> =
18181ad6265SDimitry Andric     subrange<_Iter, _Sent, _Kind>::_StoreSize;
18281ad6265SDimitry Andric 
18381ad6265SDimitry Andric template <class _Tp>
18481ad6265SDimitry Andric struct __passthrough_type;
18581ad6265SDimitry Andric 
18681ad6265SDimitry Andric template <class _Tp, size_t _Extent>
18781ad6265SDimitry Andric struct __passthrough_type<span<_Tp, _Extent>> {
18881ad6265SDimitry Andric   using type = span<_Tp>;
18981ad6265SDimitry Andric };
19081ad6265SDimitry Andric 
19181ad6265SDimitry Andric template <class _CharT, class _Traits>
19281ad6265SDimitry Andric struct __passthrough_type<basic_string_view<_CharT, _Traits>> {
19381ad6265SDimitry Andric   using type = basic_string_view<_CharT, _Traits>;
19481ad6265SDimitry Andric };
19581ad6265SDimitry Andric 
19681ad6265SDimitry Andric template <class _Np, class _Bound>
19781ad6265SDimitry Andric struct __passthrough_type<iota_view<_Np, _Bound>> {
19881ad6265SDimitry Andric   using type = iota_view<_Np, _Bound>;
19981ad6265SDimitry Andric };
20081ad6265SDimitry Andric 
20181ad6265SDimitry Andric template <class _Iter, class _Sent, subrange_kind _Kind>
20281ad6265SDimitry Andric struct __passthrough_type<subrange<_Iter, _Sent, _Kind>> {
20381ad6265SDimitry Andric   using type = subrange<_Iter, _Sent, _Kind>;
20481ad6265SDimitry Andric };
20581ad6265SDimitry Andric 
20681ad6265SDimitry Andric template <class _Tp>
20781ad6265SDimitry Andric using __passthrough_type_t = typename __passthrough_type<_Tp>::type;
20881ad6265SDimitry Andric 
20981ad6265SDimitry Andric struct __fn {
21081ad6265SDimitry Andric   // [range.drop.overview]: the `empty_view` case.
21181ad6265SDimitry Andric   template <class _Range, convertible_to<range_difference_t<_Range>> _Np>
21281ad6265SDimitry Andric     requires __is_empty_view<remove_cvref_t<_Range>>
213cb14a3feSDimitry Andric   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&&) const
21481ad6265SDimitry Andric       noexcept(noexcept(_LIBCPP_AUTO_CAST(std::forward<_Range>(__range))))
215cb14a3feSDimitry Andric           -> decltype(_LIBCPP_AUTO_CAST(std::forward<_Range>(__range))) {
216cb14a3feSDimitry Andric     return _LIBCPP_AUTO_CAST(std::forward<_Range>(__range));
217cb14a3feSDimitry Andric   }
21881ad6265SDimitry Andric 
21981ad6265SDimitry Andric   // [range.drop.overview]: the `span | basic_string_view | iota_view | subrange (StoreSize == false)` case.
22081ad6265SDimitry Andric   template <class _Range,
22181ad6265SDimitry Andric             convertible_to<range_difference_t<_Range>> _Np,
22281ad6265SDimitry Andric             class _RawRange = remove_cvref_t<_Range>,
22381ad6265SDimitry Andric             class _Dist     = range_difference_t<_Range>>
224cb14a3feSDimitry Andric     requires(!__is_empty_view<_RawRange> && random_access_range<_RawRange> && sized_range<_RawRange> &&
22581ad6265SDimitry Andric              __is_passthrough_specialization<_RawRange>)
226cb14a3feSDimitry Andric   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __rng, _Np&& __n) const
22781ad6265SDimitry Andric       noexcept(noexcept(__passthrough_type_t<_RawRange>(
228cb14a3feSDimitry Andric           ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)), ranges::end(__rng))))
22981ad6265SDimitry Andric           -> decltype(__passthrough_type_t<_RawRange>(
23081ad6265SDimitry Andric               // Note: deliberately not forwarding `__rng` to guard against double moves.
23181ad6265SDimitry Andric               ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)),
232cb14a3feSDimitry Andric               ranges::end(__rng))) {
233cb14a3feSDimitry Andric     return __passthrough_type_t<_RawRange>(
234cb14a3feSDimitry Andric         ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)), ranges::end(__rng));
235cb14a3feSDimitry Andric   }
23681ad6265SDimitry Andric 
23781ad6265SDimitry Andric   // [range.drop.overview]: the `subrange (StoreSize == true)` case.
23881ad6265SDimitry Andric   template <class _Range,
23981ad6265SDimitry Andric             convertible_to<range_difference_t<_Range>> _Np,
24081ad6265SDimitry Andric             class _RawRange = remove_cvref_t<_Range>,
24181ad6265SDimitry Andric             class _Dist     = range_difference_t<_Range>>
242cb14a3feSDimitry Andric     requires(!__is_empty_view<_RawRange> && random_access_range<_RawRange> && sized_range<_RawRange> &&
24381ad6265SDimitry Andric              __is_subrange_specialization_with_store_size<_RawRange>)
244cb14a3feSDimitry Andric   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __rng, _Np&& __n) const noexcept(noexcept(
245cb14a3feSDimitry Andric       _RawRange(ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)),
24681ad6265SDimitry Andric                 ranges::end(__rng),
24781ad6265SDimitry Andric                 std::__to_unsigned_like(ranges::distance(__rng) -
248cb14a3feSDimitry Andric                                         std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n))))))
24981ad6265SDimitry Andric       -> decltype(_RawRange(
25081ad6265SDimitry Andric           // Note: deliberately not forwarding `__rng` to guard against double moves.
25181ad6265SDimitry Andric           ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)),
25281ad6265SDimitry Andric           ranges::end(__rng),
25381ad6265SDimitry Andric           std::__to_unsigned_like(ranges::distance(__rng) -
254cb14a3feSDimitry Andric                                   std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n))))) {
25581ad6265SDimitry Andric     // Introducing local variables avoids calculating `min` and `distance` twice (at the cost of diverging from the
25681ad6265SDimitry Andric     // expression used in the `noexcept` clause and the return statement).
25706c3fb27SDimitry Andric     auto __dist    = ranges::distance(__rng);
25806c3fb27SDimitry Andric     auto __clamped = std::min<_Dist>(__dist, std::forward<_Np>(__n));
259cb14a3feSDimitry Andric     return _RawRange(ranges::begin(__rng) + __clamped, ranges::end(__rng), std::__to_unsigned_like(__dist - __clamped));
260cb14a3feSDimitry Andric   }
26106c3fb27SDimitry Andric   // clang-format off
26206c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23
26306c3fb27SDimitry Andric   // [range.drop.overview]: the `repeat_view` "_RawRange models sized_range" case.
26406c3fb27SDimitry Andric   template <class _Range,
26506c3fb27SDimitry Andric             convertible_to<range_difference_t<_Range>> _Np,
26606c3fb27SDimitry Andric             class _RawRange = remove_cvref_t<_Range>,
26706c3fb27SDimitry Andric             class _Dist     = range_difference_t<_Range>>
26806c3fb27SDimitry Andric     requires (__is_repeat_specialization<_RawRange> && sized_range<_RawRange>)
269*0fca6ea1SDimitry Andric   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const
27006c3fb27SDimitry Andric     noexcept(noexcept(views::repeat(*__range.__value_, ranges::distance(__range) - std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n)))))
27106c3fb27SDimitry Andric     -> decltype(      views::repeat(*__range.__value_, ranges::distance(__range) - std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))))
27206c3fb27SDimitry Andric     { return          views::repeat(*__range.__value_, ranges::distance(__range) - std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))); }
27306c3fb27SDimitry Andric 
27406c3fb27SDimitry Andric   // [range.drop.overview]: the `repeat_view` "otherwise" case.
27506c3fb27SDimitry Andric   template <class _Range,
27606c3fb27SDimitry Andric             convertible_to<range_difference_t<_Range>> _Np,
27706c3fb27SDimitry Andric             class _RawRange = remove_cvref_t<_Range>,
27806c3fb27SDimitry Andric             class _Dist     = range_difference_t<_Range>>
27906c3fb27SDimitry Andric     requires (__is_repeat_specialization<_RawRange> && !sized_range<_RawRange>)
280*0fca6ea1SDimitry Andric   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
28106c3fb27SDimitry Andric   constexpr auto operator()(_Range&& __range, _Np&&) const
28206c3fb27SDimitry Andric     noexcept(noexcept(_LIBCPP_AUTO_CAST(std::forward<_Range>(__range))))
28306c3fb27SDimitry Andric     -> decltype(      _LIBCPP_AUTO_CAST(std::forward<_Range>(__range)))
28406c3fb27SDimitry Andric     { return          _LIBCPP_AUTO_CAST(std::forward<_Range>(__range)); }
28506c3fb27SDimitry Andric #endif
28606c3fb27SDimitry Andric   // clang-format on
28781ad6265SDimitry Andric 
28881ad6265SDimitry Andric   // [range.drop.overview]: the "otherwise" case.
289cb14a3feSDimitry Andric   template <class _Range, convertible_to<range_difference_t<_Range>> _Np, class _RawRange = remove_cvref_t<_Range>>
29081ad6265SDimitry Andric   // Note: without specifically excluding the other cases, GCC sees this overload as ambiguous with the other
29181ad6265SDimitry Andric   // overloads.
292*0fca6ea1SDimitry Andric     requires(!(__is_empty_view<_RawRange> ||
29306c3fb27SDimitry Andric #  if _LIBCPP_STD_VER >= 23
29406c3fb27SDimitry Andric                __is_repeat_specialization<_RawRange> ||
29506c3fb27SDimitry Andric #  endif
296cb14a3feSDimitry Andric                (__is_subrange_specialization_with_store_size<_RawRange> && sized_range<_RawRange> &&
29781ad6265SDimitry Andric                 random_access_range<_RawRange>) ||
298*0fca6ea1SDimitry Andric                (__is_passthrough_specialization<_RawRange> && sized_range<_RawRange> &&
299*0fca6ea1SDimitry Andric                 random_access_range<_RawRange>)))
300cb14a3feSDimitry Andric   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const
30181ad6265SDimitry Andric       noexcept(noexcept(drop_view(std::forward<_Range>(__range), std::forward<_Np>(__n))))
302cb14a3feSDimitry Andric           -> decltype(drop_view(std::forward<_Range>(__range), std::forward<_Np>(__n))) {
303cb14a3feSDimitry Andric     return drop_view(std::forward<_Range>(__range), std::forward<_Np>(__n));
304cb14a3feSDimitry Andric   }
30581ad6265SDimitry Andric 
30681ad6265SDimitry Andric   template <class _Np>
30781ad6265SDimitry Andric     requires constructible_from<decay_t<_Np>, _Np>
308cb14a3feSDimitry Andric   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Np&& __n) const
309cb14a3feSDimitry Andric       noexcept(is_nothrow_constructible_v<decay_t<_Np>, _Np>) {
310cb14a3feSDimitry Andric     return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Np>(__n)));
311cb14a3feSDimitry Andric   }
31281ad6265SDimitry Andric };
31381ad6265SDimitry Andric 
31481ad6265SDimitry Andric } // namespace __drop
31581ad6265SDimitry Andric 
31681ad6265SDimitry Andric inline namespace __cpo {
31781ad6265SDimitry Andric inline constexpr auto drop = __drop::__fn{};
31881ad6265SDimitry Andric } // namespace __cpo
31981ad6265SDimitry Andric } // namespace views
32081ad6265SDimitry Andric 
321fe6060f1SDimitry Andric } // namespace ranges
322fe6060f1SDimitry Andric 
32306c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 20
324fe6060f1SDimitry Andric 
325fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD
326fe6060f1SDimitry Andric 
32781ad6265SDimitry Andric _LIBCPP_POP_MACROS
32881ad6265SDimitry Andric 
329fe6060f1SDimitry Andric #endif // _LIBCPP___RANGES_DROP_VIEW_H
330