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