24 Ranges library [ranges]

24.7 Range adaptors [range.adaptors]

24.7.4 Filter view [range.filter]

24.7.4.3 Class filter_­view​::​iterator [range.filter.iterator]

namespace std::ranges {
  template<class V, class Pred>
  class filter_view<V, Pred>::iterator {
  private:
    iterator_t<V> current_ = iterator_t<V>();   // exposition only
    filter_view* parent_ = nullptr;             // exposition only
  public:
    using iterator_concept  = see below;
    using iterator_category = see below;
    using value_type        = iter_value_t<iterator_t<V>>;
    using difference_type   = iter_difference_t<iterator_t<V>>;

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

    constexpr iterator_t<V> base() const;
    constexpr iter_reference_t<iterator_t<V>> operator*() const;
    constexpr iterator_t<V> operator->() const
      requires has-arrow<iterator_t<V>>;

    constexpr iterator& operator++();
    constexpr void operator++(int);
    constexpr iterator operator++(int) requires ForwardRange<V>;

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

    friend constexpr bool operator==(const iterator& x, const iterator& y)
      requires EqualityComparable<iterator_t<V>>;
    friend constexpr bool operator!=(const iterator& x, const iterator& y)
      requires EqualityComparable<iterator_t<V>>;

    friend constexpr iter_rvalue_reference_t<iterator_t<V>> iter_move(const iterator& i)
      noexcept(noexcept(ranges::iter_move(i.current_)));
    friend constexpr void iter_swap(const iterator& x, const iterator& y)
      noexcept(noexcept(ranges::iter_swap(x.current_, y.current_)))
      requires IndirectlySwappable<iterator_t<V>>;
  };
}
Modification of the element a filter_­view::iterator denotes is permitted, but results in undefined behavior if the resulting value does not satisfy the filter predicate.
iterator::iterator_­concept is defined as follows:
  • If V models BidirectionalRange, then iterator_­concept denotes bidirectional_­iterator_­tag.
  • Otherwise, if V models ForwardRange, then iterator_­concept denotes forward_­iterator_­tag.
  • Otherwise, iterator_­concept denotes input_­iterator_­tag.
iterator::iterator_­category is defined as follows:
  • Let C denote the type iterator_­traits<iterator_­t<V>>::iterator_­category.
  • If C models DerivedFrom<bidirectional_­iterator_­tag>, then iterator_­category denotes bidirectional_­iterator_­tag.
  • Otherwise, if C models DerivedFrom<forward_­iterator_­tag>, then iterator_­category denotes forward_­iterator_­tag.
  • Otherwise, iterator_­category denotes input_­iterator_­tag.
constexpr iterator(filter_view& parent, iterator_t<V> current);
Effects: Initializes current_­ with current and parent_­ with addressof(parent).
constexpr iterator_t<V> base() const;
Effects: Equivalent to: return current_­;
constexpr iter_reference_t<iterator_t<V>> operator*() const;
Effects: Equivalent to: return *current_­;
constexpr iterator_t<V> operator->() const requires has-arrow<iterator_t<V>>;
Effects: Equivalent to: return current_­;
constexpr iterator& operator++();
Effects: Equivalent to:
current_ = ranges::find_if(++current_, ranges::end(parent_->base_), ref(*parent_->pred_));
return *this;
constexpr void operator++(int);
Effects: Equivalent to ++*this.
constexpr iterator operator++(int) requires ForwardRange<V>;
Effects: Equivalent to:
auto tmp = *this;
++*this;
return tmp;
constexpr iterator& operator--() requires BidirectionalRange<V>;
Effects: Equivalent to:
do
  --current_;
while (!invoke(*parent_->pred_, *current_));
return *this;
constexpr iterator operator--(int) requires BidirectionalRange<V>;
Effects: Equivalent to:
auto tmp = *this;
--*this;
return tmp;
friend constexpr bool operator==(const iterator& x, const iterator& y) requires EqualityComparable<iterator_t<V>>;
Effects: Equivalent to: return x.current_­ == y.current_­;
friend constexpr bool operator!=(const iterator& x, const iterator& y) requires EqualityComparable<iterator_t<V>>;
Effects: Equivalent to: return !(x == y);
friend constexpr iter_rvalue_reference_t<iterator_t<V>> iter_move(const iterator& i) noexcept(noexcept(ranges::iter_move(i.current_)));
Effects: Equivalent to: return ranges::iter_­move(i.current_­);
friend constexpr void iter_swap(const iterator& x, const iterator& y) noexcept(noexcept(ranges::iter_swap(x.current_, y.current_))) requires IndirectlySwappable<iterator_t<V>>;
Effects: Equivalent to ranges::iter_­swap(x.current_­, y.current_­).