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<input_range V, indirect_unary_predicate<iterator_t<V>> Pred>
    requires view<V> && is_object_v<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        = range_value_t<V>;
    using difference_type   = range_difference_t<V>;

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

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

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

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

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

    friend constexpr range_rvalue_reference_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 indirectly_swappable<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 bidirectional_­range, then iterator_­concept denotes bidirectional_­iterator_­tag.
  • Otherwise, if V models forward_­range, 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 derived_­from<bidirectional_­iterator_­tag>, then iterator_­category denotes bidirectional_­iterator_­tag.
  • Otherwise, if C models derived_­from<forward_­iterator_­tag>, then iterator_­category denotes forward_­iterator_­tag.
  • Otherwise, iterator_­category denotes C.
constexpr iterator(filter_view& parent, iterator_t<V> current);
Effects: Initializes current_­ with std​::​move(current) and parent_­ with addressof(parent).
constexpr iterator_t<V> base() const & requires copyable<iterator_t<V>>;
Effects: Equivalent to: return current_­;
constexpr iterator_t<V> base() &&;
Effects: Equivalent to: return std​::​move(current_­);
constexpr range_reference_t<V> operator*() const;
Effects: Equivalent to: return *current_­;
constexpr iterator_t<V> operator->() const requires has-arrow<iterator_t<V>> && copyable<iterator_t<V>>;
Effects: Equivalent to: return current_­;
constexpr iterator& operator++();
Effects: Equivalent to:
current_ = ranges::find_if(std::move(++current_), ranges::end(parent_->base_),
                           ref(*parent_->pred_));
return *this;
constexpr void operator++(int);
Effects: Equivalent to ++*this.
constexpr iterator operator++(int) requires forward_­range<V>;
Effects: Equivalent to:
auto tmp = *this;
++*this;
return tmp;
constexpr iterator& operator--() requires bidirectional_­range<V>;
Effects: Equivalent to:
do
  --current_;
while (!invoke(*parent_->pred_, *current_));
return *this;
constexpr iterator operator--(int) requires bidirectional_­range<V>;
Effects: Equivalent to:
auto tmp = *this;
--*this;
return tmp;
friend constexpr bool operator==(const iterator& x, const iterator& y) requires equality_comparable<iterator_t<V>>;
Effects: Equivalent to: return x.current_­ == y.current_­;
friend constexpr range_rvalue_reference_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 indirectly_­swappable<iterator_t<V>>;
Effects: Equivalent to ranges​::​iter_­swap(x.current_­, y.current_­).