1bdd1243dSDimitry Andric // -*- C++ -*- 2bdd1243dSDimitry Andric //===----------------------------------------------------------------------===// 3bdd1243dSDimitry Andric // 4bdd1243dSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5bdd1243dSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 6bdd1243dSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7bdd1243dSDimitry Andric // 8bdd1243dSDimitry Andric //===----------------------------------------------------------------------===// 9bdd1243dSDimitry Andric 10bdd1243dSDimitry Andric #ifndef _LIBCPP___RANGES_TAKE_WHILE_VIEW_H 11bdd1243dSDimitry Andric #define _LIBCPP___RANGES_TAKE_WHILE_VIEW_H 12bdd1243dSDimitry Andric 13bdd1243dSDimitry Andric #include <__concepts/constructible.h> 14bdd1243dSDimitry Andric #include <__concepts/convertible_to.h> 15bdd1243dSDimitry Andric #include <__config> 16bdd1243dSDimitry Andric #include <__functional/bind_back.h> 17bdd1243dSDimitry Andric #include <__functional/invoke.h> 18bdd1243dSDimitry Andric #include <__iterator/concepts.h> 19bdd1243dSDimitry Andric #include <__memory/addressof.h> 20bdd1243dSDimitry Andric #include <__ranges/access.h> 21bdd1243dSDimitry Andric #include <__ranges/all.h> 22bdd1243dSDimitry Andric #include <__ranges/concepts.h> 2306c3fb27SDimitry Andric #include <__ranges/movable_box.h> 24bdd1243dSDimitry Andric #include <__ranges/range_adaptor.h> 25bdd1243dSDimitry Andric #include <__ranges/view_interface.h> 26bdd1243dSDimitry Andric #include <__type_traits/decay.h> 27bdd1243dSDimitry Andric #include <__type_traits/is_nothrow_constructible.h> 28bdd1243dSDimitry Andric #include <__type_traits/is_object.h> 29bdd1243dSDimitry Andric #include <__type_traits/maybe_const.h> 30bdd1243dSDimitry Andric #include <__utility/forward.h> 31bdd1243dSDimitry Andric #include <__utility/in_place.h> 32bdd1243dSDimitry Andric #include <__utility/move.h> 33bdd1243dSDimitry Andric 34bdd1243dSDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 35bdd1243dSDimitry Andric # pragma GCC system_header 36bdd1243dSDimitry Andric #endif 37bdd1243dSDimitry Andric 38*b3edf446SDimitry Andric _LIBCPP_PUSH_MACROS 39*b3edf446SDimitry Andric #include <__undef_macros> 40*b3edf446SDimitry Andric 41bdd1243dSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 42bdd1243dSDimitry Andric 43bdd1243dSDimitry Andric #if _LIBCPP_STD_VER >= 20 44bdd1243dSDimitry Andric 45bdd1243dSDimitry Andric namespace ranges { 46bdd1243dSDimitry Andric 47bdd1243dSDimitry Andric template <view _View, class _Pred> 48bdd1243dSDimitry Andric requires input_range<_View> && is_object_v<_Pred> && indirect_unary_predicate<const _Pred, iterator_t<_View>> 497a6dacacSDimitry Andric class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS take_while_view : public view_interface<take_while_view<_View, _Pred>> { 501ac55f4cSDimitry Andric template <bool> 511ac55f4cSDimitry Andric class __sentinel; 52bdd1243dSDimitry Andric 53bdd1243dSDimitry Andric _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); 5406c3fb27SDimitry Andric _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Pred> __pred_; 55bdd1243dSDimitry Andric 56bdd1243dSDimitry Andric public: 57bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI take_while_view() 58bdd1243dSDimitry Andric requires default_initializable<_View> && default_initializable<_Pred> 59bdd1243dSDimitry Andric = default; 60bdd1243dSDimitry Andric take_while_view(_View __base,_Pred __pred)6106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 take_while_view(_View __base, _Pred __pred) 62bdd1243dSDimitry Andric : __base_(std::move(__base)), __pred_(std::in_place, std::move(__pred)) {} 63bdd1243dSDimitry Andric base()64bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr _View base() const& 65bdd1243dSDimitry Andric requires copy_constructible<_View> 66bdd1243dSDimitry Andric { 67bdd1243dSDimitry Andric return __base_; 68bdd1243dSDimitry Andric } 69bdd1243dSDimitry Andric base()70bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); } 71bdd1243dSDimitry Andric pred()72bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr const _Pred& pred() const { return *__pred_; } 73bdd1243dSDimitry Andric begin()74bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto begin() 75bdd1243dSDimitry Andric requires(!__simple_view<_View>) 76bdd1243dSDimitry Andric { 77bdd1243dSDimitry Andric return ranges::begin(__base_); 78bdd1243dSDimitry Andric } 79bdd1243dSDimitry Andric begin()80bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const 815f757f3fSDimitry Andric requires range<const _View> && indirect_unary_predicate<const _Pred, iterator_t<const _View>> 82bdd1243dSDimitry Andric { 83bdd1243dSDimitry Andric return ranges::begin(__base_); 84bdd1243dSDimitry Andric } 85bdd1243dSDimitry Andric end()86bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto end() 87bdd1243dSDimitry Andric requires(!__simple_view<_View>) 88bdd1243dSDimitry Andric { 89bdd1243dSDimitry Andric return __sentinel</*_Const=*/false>(ranges::end(__base_), std::addressof(*__pred_)); 90bdd1243dSDimitry Andric } 91bdd1243dSDimitry Andric end()92bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto end() const 935f757f3fSDimitry Andric requires range<const _View> && indirect_unary_predicate<const _Pred, iterator_t<const _View>> 94bdd1243dSDimitry Andric { 95bdd1243dSDimitry Andric return __sentinel</*_Const=*/true>(ranges::end(__base_), std::addressof(*__pred_)); 96bdd1243dSDimitry Andric } 97bdd1243dSDimitry Andric }; 98bdd1243dSDimitry Andric 99bdd1243dSDimitry Andric template <class _Range, class _Pred> 100bdd1243dSDimitry Andric take_while_view(_Range&&, _Pred) -> take_while_view<views::all_t<_Range>, _Pred>; 101bdd1243dSDimitry Andric 1021ac55f4cSDimitry Andric template <view _View, class _Pred> 1031ac55f4cSDimitry Andric requires input_range<_View> && is_object_v<_Pred> && indirect_unary_predicate<const _Pred, iterator_t<_View>> 1041ac55f4cSDimitry Andric template <bool _Const> 1051ac55f4cSDimitry Andric class take_while_view<_View, _Pred>::__sentinel { 106bdd1243dSDimitry Andric using _Base = __maybe_const<_Const, _View>; 107bdd1243dSDimitry Andric 108bdd1243dSDimitry Andric sentinel_t<_Base> __end_ = sentinel_t<_Base>(); 109bdd1243dSDimitry Andric const _Pred* __pred_ = nullptr; 110bdd1243dSDimitry Andric 1111ac55f4cSDimitry Andric friend class __sentinel<!_Const>; 112bdd1243dSDimitry Andric 113bdd1243dSDimitry Andric public: 1141ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI __sentinel() = default; 115bdd1243dSDimitry Andric __sentinel(sentinel_t<_Base> __end,const _Pred * __pred)1161ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end, const _Pred* __pred) 117bdd1243dSDimitry Andric : __end_(std::move(__end)), __pred_(__pred) {} 118bdd1243dSDimitry Andric __sentinel(__sentinel<!_Const> __s)1191ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel<!_Const> __s) 120bdd1243dSDimitry Andric requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>> 121bdd1243dSDimitry Andric : __end_(std::move(__s.__end_)), __pred_(__s.__pred_) {} 122bdd1243dSDimitry Andric base()123bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Base> base() const { return __end_; } 124bdd1243dSDimitry Andric 1251ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const iterator_t<_Base>& __x, const __sentinel& __y) { 126bdd1243dSDimitry Andric return __x == __y.__end_ || !std::invoke(*__y.__pred_, *__x); 127bdd1243dSDimitry Andric } 128bdd1243dSDimitry Andric 129bdd1243dSDimitry Andric template <bool _OtherConst = !_Const> 130bdd1243dSDimitry Andric requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>> 131bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr bool 1321ac55f4cSDimitry Andric operator==(const iterator_t<__maybe_const<_OtherConst, _View>>& __x, const __sentinel& __y) { 133bdd1243dSDimitry Andric return __x == __y.__end_ || !std::invoke(*__y.__pred_, *__x); 134bdd1243dSDimitry Andric } 135bdd1243dSDimitry Andric }; 136bdd1243dSDimitry Andric 137bdd1243dSDimitry Andric namespace views { 138bdd1243dSDimitry Andric namespace __take_while { 139bdd1243dSDimitry Andric 140bdd1243dSDimitry Andric struct __fn { 141bdd1243dSDimitry Andric template <class _Range, class _Pred> 142bdd1243dSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Pred&& __pred) const 143bdd1243dSDimitry Andric noexcept(noexcept(/**/ take_while_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred)))) 144bdd1243dSDimitry Andric -> decltype(/*--*/ take_while_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred))) { 145bdd1243dSDimitry Andric return /*-------------*/ take_while_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred)); 146bdd1243dSDimitry Andric } 147bdd1243dSDimitry Andric 148bdd1243dSDimitry Andric template <class _Pred> 149bdd1243dSDimitry Andric requires constructible_from<decay_t<_Pred>, _Pred> operator__fn150bdd1243dSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Pred&& __pred) const 151bdd1243dSDimitry Andric noexcept(is_nothrow_constructible_v<decay_t<_Pred>, _Pred>) { 152bdd1243dSDimitry Andric return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Pred>(__pred))); 153bdd1243dSDimitry Andric } 154bdd1243dSDimitry Andric }; 155bdd1243dSDimitry Andric 156bdd1243dSDimitry Andric } // namespace __take_while 157bdd1243dSDimitry Andric 158bdd1243dSDimitry Andric inline namespace __cpo { 159bdd1243dSDimitry Andric inline constexpr auto take_while = __take_while::__fn{}; 160bdd1243dSDimitry Andric } // namespace __cpo 161bdd1243dSDimitry Andric } // namespace views 162bdd1243dSDimitry Andric } // namespace ranges 163bdd1243dSDimitry Andric 164bdd1243dSDimitry Andric #endif // _LIBCPP_STD_VER >= 20 165bdd1243dSDimitry Andric 166bdd1243dSDimitry Andric _LIBCPP_END_NAMESPACE_STD 167bdd1243dSDimitry Andric 168*b3edf446SDimitry Andric _LIBCPP_POP_MACROS 169*b3edf446SDimitry Andric 170bdd1243dSDimitry Andric #endif // _LIBCPP___RANGES_TAKE_WHILE_VIEW_H 171