24 Ranges library [ranges]

24.7 Range adaptors [range.adaptors]

24.7.7 Take while view [range.take.while]

24.7.7.1 Overview [range.take.while.overview]

Given a unary predicate pred and a view r, take_­while_­view produces a view of the range [begin(r), ranges​::​find_­if_­not(r, pred)).
The name views​::​take_­while denotes a range adaptor object ([range.adaptor.object]).
Given subexpressions E and F, the expression views​::​take_­while(E, F) is expression-equivalent to take_­while_­view{E, F}.
Example
:
auto input = istringstream{"0 1 2 3 4 5 6 7 8 9"};
auto small = [](const auto x) noexcept { return x < 5; };
auto small_ints = istream_view<int>(input) | views::take_while(small);
for (const auto i : small_ints) {
  cout << i << ' ';                             // prints 0 1 2 3 4
}
auto i = 0;
input >> i;
cout << i;                                      // prints 6
— end example
 ]

24.7.7.2 Class template take_­while_­view [range.take.while.view]

namespace std::ranges {
  template<view V, class Pred>
    requires input_range<V> && is_object_v<Pred> &&
             indirect_unary_predicate<const Pred, iterator_t<V>>
  class take_while_view : public view_interface<take_while_view<V, Pred>> {
    // [range.take.while.sentinel], class template take_­while_­view​::​sentinel
    template<bool> class sentinel;                      // exposition only

    V base_ = V();                                      // exposition only
    semiregular-box<Pred> pred_;                        // exposition only

  public:
    take_while_view() = default;
    constexpr take_while_view(V base, Pred pred);

    constexpr V base() const& requires copy_constructible<V> { return base_; }
    constexpr V base() && { return std::move(base_); }

    constexpr const Pred& pred() const;

    constexpr auto begin() requires (!simple-view<V>)
    { return ranges::begin(base_); }

    constexpr auto begin() const requires range<const V>
    { return ranges::begin(base_); }

    constexpr auto end() requires (!simple-view<V>)
    { return sentinel<false>(ranges::end(base_), addressof(*pred_)); }

    constexpr auto end() const requires range<const V>
    { return sentinel<true>(ranges::end(base_), addressof(*pred_)); }
  };

  template<class R, class Pred>
    take_while_view(R&&, Pred) -> take_while_view<views::all_t<R>, Pred>;
}
constexpr take_while_view(V base, Pred pred);
Effects: Initializes base_­ with std​::​move(base) and pred_­ with std​::​move(pred).
constexpr const Pred& pred() const;
Effects: Equivalent to: return *pred_­;

24.7.7.3 Class template take_­while_­view​::​sentinel [range.take.while.sentinel]

namespace std::ranges {
  template<view V, class Pred>
    requires input_range<V> && is_object_v<Pred> &&
             indirect_unary_predicate<const Pred, iterator_t<V>>
  template<bool Const>
  class take_while_view<V, Pred>::sentinel {            // exposition only
    using Base = conditional_t<Const, const V, V>;      // exposition only

    sentinel_t<Base> end_ = sentinel_t<Base>();         // exposition only
    const Pred* pred_ = nullptr;                        // exposition only
  public:
    sentinel() = default;
    constexpr explicit sentinel(sentinel_t<Base> end, const Pred* pred);
    constexpr sentinel(sentinel<!Const> s)
      requires Const && convertible_to<sentinel_t<V>, sentinel_t<Base>>;

    constexpr sentinel_t<Base> base() const { return end_; }

    friend constexpr bool operator==(const iterator_t<Base>& x, const sentinel& y);
  };
}
constexpr explicit sentinel(sentinel_t<Base> end, const Pred* pred);
Effects: Initializes end_­ with end and pred_­ with pred.
constexpr sentinel(sentinel<!Const> s) requires Const && convertible_­to<sentinel_t<V>, sentinel_t<Base>>;
Effects: Initializes end_­ with s.end_­ and pred_­ with s.pred_­.
friend constexpr bool operator==(const iterator_t<Base>& x, const sentinel& y);
Effects: Equivalent to: return y.end_­ == x || !invoke(*y.pred_­, *x);