1 // -*- C++ -*- 2 //===----------------------------------------------------------------------===// 3 // 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 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef _LIBCPP___RANGES_TAKE_WHILE_VIEW_H 11 #define _LIBCPP___RANGES_TAKE_WHILE_VIEW_H 12 13 #include <__concepts/constructible.h> 14 #include <__concepts/convertible_to.h> 15 #include <__config> 16 #include <__functional/bind_back.h> 17 #include <__functional/invoke.h> 18 #include <__iterator/concepts.h> 19 #include <__memory/addressof.h> 20 #include <__ranges/access.h> 21 #include <__ranges/all.h> 22 #include <__ranges/concepts.h> 23 #include <__ranges/movable_box.h> 24 #include <__ranges/range_adaptor.h> 25 #include <__ranges/view_interface.h> 26 #include <__type_traits/decay.h> 27 #include <__type_traits/is_nothrow_constructible.h> 28 #include <__type_traits/is_object.h> 29 #include <__type_traits/maybe_const.h> 30 #include <__utility/forward.h> 31 #include <__utility/in_place.h> 32 #include <__utility/move.h> 33 34 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 35 # pragma GCC system_header 36 #endif 37 38 _LIBCPP_PUSH_MACROS 39 #include <__undef_macros> 40 41 _LIBCPP_BEGIN_NAMESPACE_STD 42 43 #if _LIBCPP_STD_VER >= 20 44 45 namespace ranges { 46 47 template <view _View, class _Pred> 48 requires input_range<_View> && is_object_v<_Pred> && indirect_unary_predicate<const _Pred, iterator_t<_View>> 49 class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS take_while_view : public view_interface<take_while_view<_View, _Pred>> { 50 template <bool> 51 class __sentinel; 52 53 _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); 54 _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Pred> __pred_; 55 56 public: 57 _LIBCPP_HIDE_FROM_ABI take_while_view() 58 requires default_initializable<_View> && default_initializable<_Pred> 59 = default; 60 61 _LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 take_while_view(_View __base, _Pred __pred) 62 : __base_(std::move(__base)), __pred_(std::in_place, std::move(__pred)) {} 63 64 _LIBCPP_HIDE_FROM_ABI constexpr _View base() const& 65 requires copy_constructible<_View> 66 { 67 return __base_; 68 } 69 70 _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); } 71 72 _LIBCPP_HIDE_FROM_ABI constexpr const _Pred& pred() const { return *__pred_; } 73 74 _LIBCPP_HIDE_FROM_ABI constexpr auto begin() 75 requires(!__simple_view<_View>) 76 { 77 return ranges::begin(__base_); 78 } 79 80 _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const 81 requires range<const _View> && indirect_unary_predicate<const _Pred, iterator_t<const _View>> 82 { 83 return ranges::begin(__base_); 84 } 85 86 _LIBCPP_HIDE_FROM_ABI constexpr auto end() 87 requires(!__simple_view<_View>) 88 { 89 return __sentinel</*_Const=*/false>(ranges::end(__base_), std::addressof(*__pred_)); 90 } 91 92 _LIBCPP_HIDE_FROM_ABI constexpr auto end() const 93 requires range<const _View> && indirect_unary_predicate<const _Pred, iterator_t<const _View>> 94 { 95 return __sentinel</*_Const=*/true>(ranges::end(__base_), std::addressof(*__pred_)); 96 } 97 }; 98 99 template <class _Range, class _Pred> 100 take_while_view(_Range&&, _Pred) -> take_while_view<views::all_t<_Range>, _Pred>; 101 102 template <view _View, class _Pred> 103 requires input_range<_View> && is_object_v<_Pred> && indirect_unary_predicate<const _Pred, iterator_t<_View>> 104 template <bool _Const> 105 class take_while_view<_View, _Pred>::__sentinel { 106 using _Base = __maybe_const<_Const, _View>; 107 108 sentinel_t<_Base> __end_ = sentinel_t<_Base>(); 109 const _Pred* __pred_ = nullptr; 110 111 friend class __sentinel<!_Const>; 112 113 public: 114 _LIBCPP_HIDE_FROM_ABI __sentinel() = default; 115 116 _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end, const _Pred* __pred) 117 : __end_(std::move(__end)), __pred_(__pred) {} 118 119 _LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel<!_Const> __s) 120 requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>> 121 : __end_(std::move(__s.__end_)), __pred_(__s.__pred_) {} 122 123 _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Base> base() const { return __end_; } 124 125 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const iterator_t<_Base>& __x, const __sentinel& __y) { 126 return __x == __y.__end_ || !std::invoke(*__y.__pred_, *__x); 127 } 128 129 template <bool _OtherConst = !_Const> 130 requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>> 131 _LIBCPP_HIDE_FROM_ABI friend constexpr bool 132 operator==(const iterator_t<__maybe_const<_OtherConst, _View>>& __x, const __sentinel& __y) { 133 return __x == __y.__end_ || !std::invoke(*__y.__pred_, *__x); 134 } 135 }; 136 137 namespace views { 138 namespace __take_while { 139 140 struct __fn { 141 template <class _Range, class _Pred> 142 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Pred&& __pred) const 143 noexcept(noexcept(/**/ take_while_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred)))) 144 -> decltype(/*--*/ take_while_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred))) { 145 return /*-------------*/ take_while_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred)); 146 } 147 148 template <class _Pred> 149 requires constructible_from<decay_t<_Pred>, _Pred> 150 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Pred&& __pred) const 151 noexcept(is_nothrow_constructible_v<decay_t<_Pred>, _Pred>) { 152 return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Pred>(__pred))); 153 } 154 }; 155 156 } // namespace __take_while 157 158 inline namespace __cpo { 159 inline constexpr auto take_while = __take_while::__fn{}; 160 } // namespace __cpo 161 } // namespace views 162 } // namespace ranges 163 164 #endif // _LIBCPP_STD_VER >= 20 165 166 _LIBCPP_END_NAMESPACE_STD 167 168 _LIBCPP_POP_MACROS 169 170 #endif // _LIBCPP___RANGES_TAKE_WHILE_VIEW_H 171