std::ranges::views::filter, std::ranges::filter_view

From cppreference.com
< cpp‎ | ranges
 
 
 
template< ranges::input_range V,

          std::indirect_unary_predicate<ranges::iterator_t<V>> Pred >
    requires ranges::view<V> && std::is_object_v<Pred>

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

    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 views::filter(E, P) is expression-equivalent to filter_view{E, P} for any suitable subexpressions E and P.

filter_view models the concepts bidirectional_range, forward_range, input_range, and common_range when the underlying view V models respective concepts.

Expression-equivalent

Expression e is expression-equivalent to expression f, if e and f have the same effects, either are both potentially-throwing or are both not potentially-throwing (i.e. noexcept(e) == noexcept(f)), and either are both constant subexpressions or are both not constant subexpressions.

Data members

std::ranges::filter_view::base_

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

the underlying view

std::ranges::filter_view::pred_

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

the predicate used to filter out elements of base_

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

Member functions

(constructor)
constructs a filter_view
(public member function)
base
returns the underlying view V
(public member function)
beginend
returns an iterator or sentinel to element of the range
(public member function)

std::ranges::filter_view::filter_view

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

    requires
        ranges::viewable_range<R> && std::constructible_from<V, ranges::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 views::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 (ranges::common_range<V>)
    return iterator{*this, ranges::end(base_)};
  else
    return sentinel{*this};

}

Deduction guides

template<class R, class Pred>
filter_view(R&&, Pred) -> filter_view<ranges::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 bidirectional_iterator if V models bidirectional_range, a forward_iterator if V models forward_range, and input_iterator 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.

Member types

Member type Definition
iterator_concept as required by the respective concept
iterator_category as required by the respective concept
value_type std::range_value_t<V>
difference_type std::range_difference_t<V>

Member functions

(constructor)
constructs an iterator
(public member function)
base
returns the underlying iterator
(public member function)
operator*operator->
forwards to the underlying iterator
(public member function)
operator++operator++(int)operator--operator--(int)
advances or decrements the iterator
(public member function)

Non-member functions

operator==iter_moveiter_swap
forwards to the underlying iterator
(public member function)

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

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

Initializes exposition-only data member current_ with current and exposition-only data members parent_ with std::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 ranges::bidirectional_range<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.

Member functions

(constructor)
constructs a sentinel
(public member function)
base
returns the underlying sentinel
(public member function)

Non-member functions

operator==
compares the underlying iterator and the underlying sentinel
(public member function)

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

ranges::sentinel_t<V> end_ = ranges::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 ranges::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);

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

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::views::filter(even) | std::views::transform(square)) {
       std::cout << i << ' ';
    }
}

Output:

0 4 16