File indexing completed on 2025-01-18 10:09:59
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef RANGES_V3_VIEW_TAKE_WHILE_HPP
0015 #define RANGES_V3_VIEW_TAKE_WHILE_HPP
0016
0017 #include <type_traits>
0018 #include <utility>
0019
0020 #include <meta/meta.hpp>
0021
0022 #include <range/v3/range_fwd.hpp>
0023
0024 #include <range/v3/functional/bind_back.hpp>
0025 #include <range/v3/functional/compose.hpp>
0026 #include <range/v3/functional/indirect.hpp>
0027 #include <range/v3/functional/invoke.hpp>
0028 #include <range/v3/iterator/concepts.hpp>
0029 #include <range/v3/range/concepts.hpp>
0030 #include <range/v3/utility/semiregular_box.hpp>
0031 #include <range/v3/utility/static_const.hpp>
0032 #include <range/v3/view/adaptor.hpp>
0033 #include <range/v3/view/view.hpp>
0034
0035 #include <range/v3/detail/prologue.hpp>
0036
0037 namespace ranges
0038 {
0039
0040
0041 template<typename Rng, typename Pred>
0042 struct iter_take_while_view
0043 : view_adaptor<iter_take_while_view<Rng, Pred>, Rng,
0044 is_finite<Rng>::value ? finite : unknown>
0045 {
0046 private:
0047 friend range_access;
0048 RANGES_NO_UNIQUE_ADDRESS semiregular_box_t<Pred> pred_;
0049
0050 template<bool IsConst>
0051 struct sentinel_adaptor : adaptor_base
0052 {
0053 private:
0054 friend struct sentinel_adaptor<!IsConst>;
0055 using CRng = meta::const_if_c<IsConst, Rng>;
0056 RANGES_NO_UNIQUE_ADDRESS semiregular_box_ref_or_val_t<Pred, IsConst> pred_;
0057
0058 public:
0059 sentinel_adaptor() = default;
0060 sentinel_adaptor(semiregular_box_ref_or_val_t<Pred, IsConst> pred)
0061 : pred_(std::move(pred))
0062 {}
0063 template(bool Other)(
0064 requires IsConst AND CPP_NOT(Other))
0065 sentinel_adaptor(sentinel_adaptor<Other> that)
0066 : pred_(std::move(that.pred_))
0067 {}
0068 bool empty(iterator_t<CRng> const & it, sentinel_t<CRng> const & last) const
0069 {
0070 return it == last || !invoke(pred_, it);
0071 }
0072 };
0073 sentinel_adaptor<false> end_adaptor()
0074 {
0075 return {pred_};
0076 }
0077 template(bool Const = true)(
0078 requires Const AND range<meta::const_if_c<Const, Rng>> AND
0079 invocable<Pred const &, iterator_t<meta::const_if_c<Const, Rng>>>)
0080 sentinel_adaptor<Const> end_adaptor() const
0081 {
0082 return {pred_};
0083 }
0084
0085 public:
0086 iter_take_while_view() = default;
0087 constexpr iter_take_while_view(Rng rng, Pred pred)
0088 : iter_take_while_view::view_adaptor{std::move(rng)}
0089 , pred_(std::move(pred))
0090 {}
0091 };
0092
0093 template<typename Rng, typename Pred>
0094 struct take_while_view : iter_take_while_view<Rng, indirected<Pred>>
0095 {
0096 take_while_view() = default;
0097 constexpr take_while_view(Rng rng, Pred pred)
0098 : iter_take_while_view<Rng, indirected<Pred>>{std::move(rng),
0099 indirect(std::move(pred))}
0100 {}
0101 };
0102
0103 #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
0104 template(typename Rng, typename Fun)(
0105 requires copy_constructible<Fun>)
0106 take_while_view(Rng &&, Fun)
0107 -> take_while_view<views::all_t<Rng>, Fun>;
0108 #endif
0109
0110 namespace views
0111 {
0112 struct iter_take_while_base_fn
0113 {
0114 template(typename Rng, typename Pred)(
0115 requires viewable_range<Rng> AND input_range<Rng> AND
0116 predicate<Pred &, iterator_t<Rng>> AND copy_constructible<Pred>)
0117 constexpr iter_take_while_view<all_t<Rng>, Pred>
0118 operator()(Rng && rng, Pred pred) const
0119 {
0120 return {all(static_cast<Rng &&>(rng)), std::move(pred)};
0121 }
0122 };
0123
0124 struct iter_take_while_fn : iter_take_while_base_fn
0125 {
0126 using iter_take_while_base_fn::operator();
0127
0128 template<typename Pred>
0129 constexpr auto operator()(Pred pred) const
0130 {
0131 return make_view_closure(
0132 bind_back(iter_take_while_base_fn{}, std::move(pred)));
0133 }
0134 };
0135
0136 struct take_while_base_fn
0137 {
0138 template(typename Rng, typename Pred)(
0139 requires viewable_range<Rng> AND input_range<Rng> AND
0140 indirect_unary_predicate<Pred &, iterator_t<Rng>>)
0141 constexpr take_while_view<all_t<Rng>, Pred>
0142 operator()(Rng && rng, Pred pred) const
0143 {
0144 return {all(static_cast<Rng &&>(rng)), std::move(pred)};
0145 }
0146 template(typename Rng, typename Pred, typename Proj)(
0147 requires viewable_range<Rng> AND input_range<Rng> AND
0148 indirect_unary_predicate<composed<Pred, Proj> &, iterator_t<Rng>>)
0149 constexpr take_while_view<all_t<Rng>, composed<Pred, Proj>>
0150 operator()(Rng && rng, Pred pred, Proj proj) const
0151 {
0152 return {all(static_cast<Rng &&>(rng)),
0153 compose(std::move(pred), std::move(proj))};
0154 }
0155 };
0156
0157 struct take_while_bind_fn
0158 {
0159 template<typename Pred>
0160 constexpr auto operator()(Pred pred) const
0161 {
0162 return make_view_closure(
0163 bind_back(take_while_base_fn{}, std::move(pred)));
0164 }
0165 template(typename Pred, typename Proj)(
0166 requires (!range<Pred>))
0167 constexpr auto operator()(Pred && pred, Proj proj) const
0168
0169 {
0170 return make_view_closure(bind_back(
0171 take_while_base_fn{}, static_cast<Pred &&>(pred), std::move(proj)));
0172 }
0173 };
0174
0175 struct RANGES_EMPTY_BASES take_while_fn
0176 : take_while_base_fn, take_while_bind_fn
0177 {
0178 using take_while_base_fn::operator();
0179 using take_while_bind_fn::operator();
0180 };
0181
0182
0183
0184 RANGES_INLINE_VARIABLE(iter_take_while_fn, iter_take_while)
0185
0186
0187
0188 RANGES_INLINE_VARIABLE(take_while_fn, take_while)
0189 }
0190
0191 namespace cpp20
0192 {
0193 namespace views
0194 {
0195 using ranges::views::take_while;
0196 }
0197 template(typename Rng, typename Pred)(
0198 requires viewable_range<Rng> AND input_range<Rng> AND
0199 predicate<Pred &, iterator_t<Rng>> AND copy_constructible<Pred>)
0200 using take_while_view = ranges::take_while_view<Rng, Pred>;
0201 }
0202
0203 }
0204
0205 #include <range/v3/detail/epilogue.hpp>
0206 #include <range/v3/detail/satisfy_boost_range.hpp>
0207 RANGES_SATISFY_BOOST_RANGE(::ranges::iter_take_while_view)
0208 RANGES_SATISFY_BOOST_RANGE(::ranges::take_while_view)
0209
0210 #endif