std::ranges::view::filter, std::ranges::filter_view

< cpp‎ | ranges
template< InputRange V, IndirectUnaryPredicate<iterator_t<V>> Pred >

    requires View<V> && std::is_object_v<Pred>

class filter_view : public ranges::view_interface<filter_view<V, Pred>>
(1) (since C++20)
namespace view {

    inline constexpr /*unspecified*/ filter = /*unspecified*/;

}
(2) (since C++20)
1) A range adaptor that represents View of an underlying sequence without the elements that fail to satisfy a predicate.
2) The expression view::filter(E, P) is expression-equivalent to (has the same effect as) filter_view{E, P} for any suitable subexpressions E and P.

filter_view models the concepts BidirectionalRange, ForwardRange, InputRange, and CommonRange when the underlying view V models respective concepts.

Data members

std::ranges::filter_view::base_

V base_ = V(); /* exposition-only */

the underlying view

std::ranges::filter_view::pred_

semiregular<Pred> pred_; /* exposition-only */

the predicate used to filter out elements of base_

semiregular is a wrapper class template which behaves exactly like std::optional except for some small differences. The name semiregular is for exposition purposes only and not normative.

Member functions

std::ranges::filter_view::filter_view

filter_view() = default;
(1)
constexpr filter_view(V base, Pred pred);
(2)
template<InputRange R>

requires ViewableRange<R> && Constructible<V, all_view<R>>

constexpr filter_view(R&& r, Pred pred);
(3)
1) Default-initializes base_ and pred_
2) Initializes base_ with std::move(base) and initializes pred_ with std::move(pred).
3) Initializes base_ with view::all(std::forward<R>(r)) and initializes pred_ with std::​move(pred).

Parameters

r - range to filter
pred - predicate to filter out elements

std::ranges::filter_view::base

constexpr V base() const;

Equivalent to return base_;

std::ranges::filter_view::begin

constexpr iterator begin();

Returns the iterator initialized with {*this, ranges::find_if(base_, std::ref(*pred_))}. In order to provide the amortized constant time complexity required by the Range concept, this function caches the result within the filter_view object for use on subsequent calls.

The behavior is undefined unless pred_.has_value()

std::ranges::filter_view::end

constexpr auto end() {

  if constexpr (CommonRange<V>)
    return iterator{*this, ranges::end(base_)};
  else
    return sentinel{*this};

}

Deduction guides

template<class R, class Pred>
filter_view(R&&, Pred) -> filter_view<all_view<R>, Pred>;

Nested classes

std::ranges::filter_view::iterator

template<class V, class Pred>
class filter_view<V, Pred>::iterator /* exposition-only */

The return type of filter_view::begin.

This is a InputIterator otherwise.

Modification of the element denoted by this iterator is permitted, but results in undefined behavior if the resulting value does not satisfy the filter's predicate.

std::ranges::filter_view::iterator::iterator

iterator() = default;
constexpr iterator(filter_view& parent, iterator_t<V> current);

Initializes exposition-only data member current_ with current and exposition-only data members parent_ with addressof(parent).

std::ranges::filter_view::iterator::operator++

constexpr iterator& operator++()

Equivalent to

current_ = ranges::find_if(++current_, ranges::end(parent_->base_), ref(*parent_->pred_));
return *this;

std::ranges::filter_view::iterator::operator--

constexpr iterator& operator--() requires BidirectionalRange<V>;

Equivalent to

do
  --current_;
while (!invoke(*parent_->pred_, *current_));
return *this;

Other members as expected of an iterator.

std::ranges::filter_view::sentinel

template<class V, class Pred>
class filter_view<V, Pred>::sentinel /* exposition-only */

The return type of filter_view::end.

std::ranges::filter_view::sentinel::end_

sentinel_t<V> end_ = sentinel_t<V>(); /* exposition only */

Exposition-only data member holding the sentinel of the underlying View.

std::ranges::filter_view::sentinel::sentinel

sentinel() = default;
constexpr explicit sentinel(filter_view& parent);

Initializes exposition-only data member end_ with parent.

std::ranges::filter_view::sentinel::base

constexpr sentinel_t<V> base() const;

Equivalent to: return end_;

std::ranges::filter_view::sentinel::operator==

friend constexpr bool operator==(const iterator& x, const sentinel& y);
friend constexpr bool operator==(const sentinel& x, const iterator& y);

Equivalent to: return x.current_ == y.end_; and return y == x; respectively.

std::ranges::filter_view::sentinel::operator!=

friend constexpr bool operator!=(const iterator& x, const sentinel& y);
friend constexpr bool operator!=(const sentinel& x, const iterator& y);

Equivalent to return !(x == y); and return !(y == x); respectively


Example

#include <vector>
#include <ranges>
#include <iostream>
 
int main()
{
  std::vector<int> ints{0,1,2,3,4,5};
  auto even = [](int i){ return 0 == i % 2; };
  auto square = [](int i) { return i * i; };
 
  for (int i : ints | std::view::filter(even) | std::view::transform(square)) {
    std::cout << i << ' ';
  }
}

Output:

0 4 16