23 Ranges library [ranges]

23.8 Range adaptors [range.adaptors]

23.8.5 Transform view [range.transform]

23.8.5.3 Class template transform_­view​::​iterator [range.transform.iterator]

namespace std::ranges {
  template<class V, class F>
  template<bool Const>
  class transform_view<V, F>::iterator {
  private:
    using Parent =                              // exposition only
      conditional_t<Const, const transform_view, transform_view>;
    using Base   =                              // exposition only
      conditional_t<Const, const V, V>;
    iterator_t<Base> current_ =                 // exposition only
      iterator_t<Base>();
    Parent* parent_ = nullptr;                  // exposition only
  public:
    using iterator_concept  = see below;
    using iterator_category = see below;
    using value_type        =
      remove_cvref_t<invoke_result_t<F&, iter_reference_t<iterator_t<Base>>>>;
    using difference_type   = iter_difference_t<iterator_t<Base>>;

    iterator() = default;
    constexpr iterator(Parent& parent, iterator_t<Base> current);
    constexpr iterator(iterator<!Const> i)
      requires Const && ConvertibleTo<iterator_t<V>, iterator_t<Base>>;

    constexpr iterator_t<Base> base() const;
    constexpr decltype(auto) operator*() const
    { return invoke(*parent_->fun_, *current_); }

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

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

    constexpr iterator& operator+=(difference_type n)
      requires RandomAccessRange<Base>;
    constexpr iterator& operator-=(difference_type n)
      requires RandomAccessRange<Base>;
    constexpr decltype(auto) operator[](difference_type n) const
      requires RandomAccessRange<Base>
    { return invoke(*parent_->fun_, current_[n]); }

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

    friend constexpr bool operator<(const iterator& x, const iterator& y)
      requires RandomAccessRange<Base>;
    friend constexpr bool operator>(const iterator& x, const iterator& y)
      requires RandomAccessRange<Base>;
    friend constexpr bool operator<=(const iterator& x, const iterator& y)
      requires RandomAccessRange<Base>;
    friend constexpr bool operator>=(const iterator& x, const iterator& y)
      requires RandomAccessRange<Base>;

    friend constexpr iterator operator+(iterator i, difference_type n)
      requires RandomAccessRange<Base>;
    friend constexpr iterator operator+(difference_type n, iterator i)
      requires RandomAccessRange<Base>;

    friend constexpr iterator operator-(iterator i, difference_type n)
      requires RandomAccessRange<Base>;
    friend constexpr difference_type operator-(const iterator& x, const iterator& y)
      requires RandomAccessRange<Base>;

    friend constexpr decltype(auto) iter_move(const iterator& i)
      noexcept(noexcept(invoke(*i.parent_->fun_, *i.current_)))
    {
      if constexpr (is_lvalue_reference_v<decltype(*i)>)
        return std::move(*i);
      else
        return *i;
    }

    friend constexpr void iter_swap(const iterator& x, const iterator& y)
      noexcept(noexcept(ranges::iter_swap(x.current_, y.current_)))
      requires IndirectlySwappable<iterator_t<Base>>;
  };
}
iterator::iterator_­concept is defined as follows:
  • If V models RandomAccessRange, then iterator_­concept denotes random_­access_­iterator_­tag.
  • Otherwise, 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.
Let C denote the type iterator_­traits<iterator_­t<Base>>::iterator_­category.
If C models DerivedFrom<contiguous_­iterator_­tag>, then iterator_­category denotes random_­access_­iterator_­tag; otherwise, iterator_­category denotes C.
constexpr iterator(Parent& parent, iterator_t<Base> current);
Effects: Initializes current_­ with current and parent_­ with addressof(parent).
constexpr iterator(iterator<!Const> i) requires Const && ConvertibleTo<iterator_t<V>, iterator_t<Base>>;
Effects: Initializes current_­ with std::move(i.current_­) and parent_­ with i.parent_­.
constexpr iterator_t<Base> base() const;
Effects: Equivalent to: return current_­;
constexpr iterator& operator++();
Effects: Equivalent to:
++current_;
return *this;
constexpr void operator++(int);
Effects: Equivalent to ++current_­.
constexpr iterator operator++(int) requires ForwardRange<Base>;
Effects: Equivalent to:
auto tmp = *this;
++*this;
return tmp;
constexpr iterator& operator--() requires BidirectionalRange<Base>;
Effects: Equivalent to:
--current_;
return *this;
constexpr iterator operator--(int) requires BidirectionalRange<Base>;
Effects: Equivalent to:
auto tmp = *this;
--*this;
return tmp;
constexpr iterator& operator+=(difference_type n) requires RandomAccessRange<Base>;
Effects: Equivalent to:
current_ += n;
return *this;
constexpr iterator& operator-=(difference_type n) requires RandomAccessRange<Base>;
Effects: Equivalent to:
current_ -= n;
return *this;
friend constexpr bool operator==(const iterator& x, const iterator& y) requires EqualityComparable<iterator_t<Base>>;
Effects: Equivalent to: return x.current_­ == y.current_­;
friend constexpr bool operator!=(const iterator& x, const iterator& y) requires EqualityComparable<iterator_t<Base>>;
Effects: Equivalent to: return !(x == y);
friend constexpr bool operator<(const iterator& x, const iterator& y) requires RandomAccessRange<Base>;
Effects: Equivalent to: return x.current_­ < y.current_­;
friend constexpr bool operator>(const iterator& x, const iterator& y) requires RandomAccessRange<Base>;
Effects: Equivalent to: return y < x;
friend constexpr bool operator<=(const iterator& x, const iterator& y) requires RandomAccessRange<Base>;
Effects: Equivalent to: return !(y < x);
friend constexpr bool operator>=(const iterator& x, const iterator& y) requires RandomAccessRange<Base>;
Effects: Equivalent to: return !(x < y);
friend constexpr iterator operator+(iterator i, difference_type n) requires RandomAccessRange<Base>; friend constexpr iterator operator+(difference_type n, iterator i) requires RandomAccessRange<Base>;
Effects: Equivalent to: return iterator{*i.parent_­, i.current_­ + n};
friend constexpr iterator operator-(iterator i, difference_type n) requires RandomAccessRange<Base>;
Effects: Equivalent to: return iterator{*i.parent_­, i.current_­ - n};
friend constexpr difference_type operator-(const iterator& x, const iterator& y) requires RandomAccessRange<Base>;
Effects: Equivalent to: return x.current_­ - y.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<Base>>;
Effects: Equivalent to ranges::iter_­swap(x.current_­, y.current_­).