2 //===----------------------------------------------------------------------===//
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP___RANGES_DROP_WHILE_VIEW_H
11 #define _LIBCPP___RANGES_DROP_WHILE_VIEW_H
13 #include <__algorithm/ranges_find_if_not.h>
15 #include <__concepts/constructible.h>
17 #include <__functional/bind_back.h>
18 #include <__functional/reference_wrapper.h>
19 #include <__iterator/concepts.h>
20 #include <__ranges/access.h>
21 #include <__ranges/all.h>
22 #include <__ranges/concepts.h>
23 #include <__ranges/enable_borrowed_range.h>
24 #include <__ranges/movable_box.h>
25 #include <__ranges/non_propagating_cache.h>
26 #include <__ranges/range_adaptor.h>
27 #include <__ranges/view_interface.h>
28 #include <__type_traits/conditional.h>
29 #include <__type_traits/decay.h>
30 #include <__type_traits/is_nothrow_constructible.h>
31 #include <__type_traits/is_object.h>
32 #include <__utility/forward.h>
33 #include <__utility/in_place.h>
34 #include <__utility/move.h>
36 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
37 # pragma GCC system_header
40 _LIBCPP_BEGIN_NAMESPACE_STD
42 #if _LIBCPP_STD_VER >= 20
46 template <view _View
, class _Pred
>
47 requires input_range
<_View
> && is_object_v
<_Pred
> && indirect_unary_predicate
<const _Pred
, iterator_t
<_View
>>
48 class drop_while_view
: public view_interface
<drop_while_view
<_View
, _Pred
>> {
50 _LIBCPP_HIDE_FROM_ABI
drop_while_view()
51 requires default_initializable
<_View
> && default_initializable
<_Pred
>
54 _LIBCPP_HIDE_FROM_ABI
constexpr _LIBCPP_EXPLICIT_SINCE_CXX23
drop_while_view(_View __base
, _Pred __pred
)
55 : __base_(std::move(__base
)), __pred_(std::in_place
, std::move(__pred
)) {}
57 _LIBCPP_HIDE_FROM_ABI
constexpr _View
base() const&
58 requires copy_constructible
<_View
>
63 _LIBCPP_HIDE_FROM_ABI
constexpr _View
base() && { return std::move(__base_
); }
65 _LIBCPP_HIDE_FROM_ABI
constexpr const _Pred
& pred() const { return *__pred_
; }
67 _LIBCPP_HIDE_FROM_ABI
constexpr auto begin() {
68 _LIBCPP_ASSERT_UNCATEGORIZED(
69 __pred_
.__has_value(),
70 "drop_while_view needs to have a non-empty predicate before calling begin() -- did a previous "
71 "assignment to this drop_while_view fail?");
72 if constexpr (_UseCache
) {
73 if (!__cached_begin_
.__has_value()) {
74 __cached_begin_
.__emplace(ranges::find_if_not(__base_
, std::cref(*__pred_
)));
76 return *__cached_begin_
;
78 return ranges::find_if_not(__base_
, std::cref(*__pred_
));
82 _LIBCPP_HIDE_FROM_ABI
constexpr auto end() { return ranges::end(__base_
); }
85 _LIBCPP_NO_UNIQUE_ADDRESS _View __base_
= _View();
86 _LIBCPP_NO_UNIQUE_ADDRESS __movable_box
<_Pred
> __pred_
;
88 static constexpr bool _UseCache
= forward_range
<_View
>;
89 using _Cache
= _If
<_UseCache
, __non_propagating_cache
<iterator_t
<_View
>>, __empty_cache
>;
90 _LIBCPP_NO_UNIQUE_ADDRESS _Cache __cached_begin_
= _Cache();
93 template <class _View
, class _Pred
>
94 inline constexpr bool enable_borrowed_range
<drop_while_view
<_View
, _Pred
>> = enable_borrowed_range
<_View
>;
96 template <class _Range
, class _Pred
>
97 drop_while_view(_Range
&&, _Pred
) -> drop_while_view
<views::all_t
<_Range
>, _Pred
>;
100 namespace __drop_while
{
103 template <class _Range
, class _Pred
>
104 [[nodiscard
]] _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Range
&& __range
, _Pred
&& __pred
) const
105 noexcept(noexcept(/**/ drop_while_view(std::forward
<_Range
>(__range
), std::forward
<_Pred
>(__pred
))))
106 -> decltype(/*--*/ drop_while_view(std::forward
<_Range
>(__range
), std::forward
<_Pred
>(__pred
))) {
107 return /*-------------*/ drop_while_view(std::forward
<_Range
>(__range
), std::forward
<_Pred
>(__pred
));
110 template <class _Pred
>
111 requires constructible_from
<decay_t
<_Pred
>, _Pred
>
112 [[nodiscard
]] _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Pred
&& __pred
) const
113 noexcept(is_nothrow_constructible_v
<decay_t
<_Pred
>, _Pred
>) {
114 return __range_adaptor_closure_t(std::__bind_back(*this, std::forward
<_Pred
>(__pred
)));
118 } // namespace __drop_while
120 inline namespace __cpo
{
121 inline constexpr auto drop_while
= __drop_while::__fn
{};
124 } // namespace ranges
126 #endif // _LIBCPP_STD_VER >= 20
128 _LIBCPP_END_NAMESPACE_STD
130 #endif // _LIBCPP___RANGES_DROP_WHILE_VIEW_H