25 Iterators library [iterators]

25.5 Iterator adaptors [predef.iterators]

25.5.3 Constant iterators and sentinels [const.iterators]

25.5.3.1 General [const.iterators.general]

Class template basic_­const_­iterator is an iterator adaptor with the same behavior as the underlying iterator except that its indirection operator implicitly converts the value returned by the underlying iterator's indirection operator to a type such that the adapted iterator is a constant iterator ([iterator.requirements]).
Some generic algorithms can be called with constant iterators to avoid mutation.
Specializations of basic_­const_­iterator are constant iterators.

25.5.3.2 Alias templates [const.iterators.alias]

template<indirectly_­readable It> using iter_const_reference_t = common_reference_t<const iter_value_t<It>&&, iter_reference_t<It>>; template<class It> concept constant-iterator = // exposition only input_­iterator<It> && same_­as<iter_const_reference_t<It>, iter_reference_t<It>>; template<input_­iterator I> using const_iterator = see below;
Result: If I models constant-iterator, I.
Otherwise, basic_­const_­iterator<I>.
template<semiregular S> using const_sentinel = see below;
Result: If S models input_­iterator, const_­iterator<S>.
Otherwise, S.

25.5.3.3 Class template basic_­const_­iterator [const.iterators.iterator]

namespace std { template<class I> concept not-a-const-iterator = see below; template<input_­iterator Iterator> class basic_const_iterator { Iterator current_ = Iterator(); // exposition only using reference = iter_const_reference_t<Iterator>; // exposition only public: using iterator_concept = see below; using iterator_category = see below; // not always present using value_type = iter_value_t<Iterator>; using difference_type = iter_difference_t<Iterator>; basic_const_iterator() requires default_­initializable<Iterator> = default; constexpr basic_const_iterator(Iterator current); template<convertible_­to<Iterator> U> constexpr basic_const_iterator(basic_const_iterator<U> current); template<different-from<basic_const_iterator> T> requires convertible_­to<T, Iterator> constexpr basic_const_iterator(T&& current); constexpr const Iterator& base() const & noexcept; constexpr Iterator base() &&; constexpr reference operator*() const; constexpr const value_type* operator->() const requires is_lvalue_reference_v<iter_reference_t<Iterator>> && same_­as<remove_cvref_t<iter_reference_t<Iterator>>, value_type>; constexpr basic_const_iterator& operator++(); constexpr void operator++(int); constexpr basic_const_iterator operator++(int) requires forward_­iterator<Iterator>; constexpr basic_const_iterator& operator--() requires bidirectional_­iterator<Iterator>; constexpr basic_const_iterator operator--(int) requires bidirectional_­iterator<Iterator>; constexpr basic_const_iterator& operator+=(difference_type n) requires random_­access_­iterator<Iterator>; constexpr basic_const_iterator& operator-=(difference_type n) requires random_­access_­iterator<Iterator>; constexpr reference operator[](difference_type n) const requires random_­access_­iterator<Iterator>; template<sentinel_­for<Iterator> S> friend constexpr bool operator==(const basic_const_iterator& x, const S& s); friend constexpr bool operator<(const basic_const_iterator& x, const basic_const_iterator& y) requires random_­access_­iterator<Iterator>; friend constexpr bool operator>(const basic_const_iterator& x, const basic_const_iterator& y) requires random_­access_­iterator<Iterator>; friend constexpr bool operator<=(const basic_const_iterator& x, const basic_const_iterator& y) requires random_­access_­iterator<Iterator>; friend constexpr bool operator>=(const basic_const_iterator& x, const basic_const_iterator& y) requires random_­access_­iterator<Iterator>; friend constexpr auto operator<=>(const basic_const_iterator& x, const basic_const_iterator& y) requires random_­access_­iterator<Iterator> && three_­way_­comparable<Iterator>; template<different-from<basic_const_iterator> I> friend constexpr bool operator<(const basic_const_iterator& x, const I& y) requires random_­access_­iterator<Iterator> && totally_­ordered_­with<Iterator, I>; template<different-from<basic_const_iterator> I> friend constexpr bool operator>(const basic_const_iterator& x, const I& y) requires random_­access_­iterator<Iterator> && totally_­ordered_­with<Iterator, I>; template<different-from<basic_const_iterator> I> friend constexpr bool operator<=(const basic_const_iterator& x, const I& y) requires random_­access_­iterator<Iterator> && totally_­ordered_­with<Iterator, I>; template<different-from<basic_const_iterator> I> friend constexpr bool operator>=(const basic_const_iterator& x, const I& y) requires random_­access_­iterator<Iterator> && totally_­ordered_­with<Iterator, I>; template<not-a-const-iterator I> friend constexpr bool operator<(const I& x, const basic_const_iterator& y) requires random_­access_­iterator<Iterator> && totally_­ordered_­with<Iterator, I>; template<not-a-const-iterator I> friend constexpr bool operator>(const I& x, const basic_const_iterator& y) requires random_­access_­iterator<Iterator> && totally_­ordered_­with<Iterator, I>; template<not-a-const-iterator I> friend constexpr bool operator<=(const I& x, const basic_const_iterator& y) requires random_­access_­iterator<Iterator> && totally_­ordered_­with<Iterator, I>; template<not-a-const-iterator I> friend constexpr bool operator>=(const I& x, const basic_const_iterator& y) requires random_­access_­iterator<Iterator> && totally_­ordered_­with<Iterator, I>; template<different-from<basic_const_iterator> I> friend constexpr auto operator<=>(const basic_const_iterator& x, const I& y) requires random_­access_­iterator<Iterator> && totally_­ordered_­with<Iterator, I> && three_­way_­comparable_­with<Iterator, I>; friend constexpr basic_const_iterator operator+(const basic_const_iterator& i, difference_type n) requires random_­access_­iterator<Iterator>; friend constexpr basic_const_iterator operator+(difference_type n, const basic_const_iterator& i) requires random_­access_­iterator<Iterator>; friend constexpr basic_const_iterator operator-(const basic_const_iterator& i, difference_type n) requires random_­access_­iterator<Iterator>; template<sized_­sentinel_­for<Iterator> S> friend constexpr difference_type operator-(const basic_const_iterator& x, const S& y); template<sized_­sentinel_­for<Iterator> S> requires different-from<S, basic_const_iterator> friend constexpr difference_type operator-(const S& x, const basic_const_iterator& y); }; }
Given some type I, the concept not-a-const-iterator is defined as false if I is a specialization of basic_­const_­iterator and true otherwise.

25.5.3.4 Member types [const.iterators.types]

basic_­const_­iterator<Iterator>​::​iterator_­concept is defined as follows:
The member typedef-name iterator_­category is defined if and only if Iterator models forward_­iterator.
In that case, basic_­const_­iterator<Iterator>​::​iterator_­category denotes the type iterator_­traits<​Iterator>​::​iterator_­category.

25.5.3.5 Operations [const.iterators.ops]

constexpr basic_const_iterator(Iterator current);
Effects: Initializes current_­ with std​::​move(current).
template<convertible_­to<Iterator> U> constexpr basic_const_iterator(basic_const_iterator<U> current);
Effects: Initializes current_­ with std​::​move(current.current_­).
template<different-from<basic_const_iterator> T> requires convertible_­to<T, Iterator> constexpr basic_const_iterator(T&& current);
Effects: Initializes current_­ with std​::​forward<T>(current).
constexpr const Iterator& base() const & noexcept;
Effects: Equivalent to: return current_­;
constexpr Iterator base() &&;
Effects: Equivalent to: return std​::​move(current_­);
constexpr reference operator*() const;
Effects: Equivalent to: return static_­cast<reference>(*current_­);
constexpr const value_type* operator->() const requires is_lvalue_reference_v<iter_reference_t<Iterator>> && same_­as<remove_cvref_t<iter_reference_t<Iterator>>, value_type>;
Returns: If Iterator models contiguous_­iterator, to_­address(current_­); otherwise, addressof(*current_­).
constexpr basic_const_iterator& operator++();
Effects: Equivalent to: ++current_; return *this;
constexpr void operator++(int);
Effects: Equivalent to: ++current_­;
constexpr basic_const_iterator operator++(int) requires forward_­iterator<Iterator>;
Effects: Equivalent to: auto tmp = *this; ++*this; return tmp;
constexpr basic_const_iterator& operator--() requires bidirectional_­iterator<Iterator>;
Effects: Equivalent to: --current_; return *this;
constexpr basic_const_iterator operator--(int) requires bidirectional_­iterator<Iterator>;
Effects: Equivalent to: auto tmp = *this; --*this; return tmp;
constexpr basic_const_iterator& operator+=(difference_type n) requires random_­access_­iterator<Iterator>; constexpr basic_const_iterator& operator-=(difference_type n) requires random_­access_­iterator<Iterator>;
Let op be the operator.
Effects: Equivalent to: current_ op n; return *this;
constexpr reference operator[](difference_type n) const requires random_­access_­iterator<Iterator>
Effects: Equivalent to: return static_­cast<reference>(current_­[n]);
template<sentinel_­for<Iterator> S> friend constexpr bool operator==(const basic_const_iterator& x, const S& s);
Effects: Equivalent to: return x.current_­ == s;
friend constexpr bool operator<(const basic_const_iterator& x, const basic_const_iterator& y) requires random_­access_­iterator<Iterator>; friend constexpr bool operator>(const basic_const_iterator& x, const basic_const_iterator& y) requires random_­access_­iterator<Iterator>; friend constexpr bool operator<=(const basic_const_iterator& x, const basic_const_iterator& y) requires random_­access_­iterator<Iterator>; friend constexpr bool operator>=(const basic_const_iterator& x, const basic_const_iterator& y) requires random_­access_­iterator<Iterator>; friend constexpr auto operator<=>(const basic_const_iterator& x, const basic_const_iterator& y) requires random_­access_­iterator<Iterator> && three_­way_­comparable<Iterator>;
Let op be the operator.
Effects: Equivalent to: return x.current_­ op y.current_­;
template<different-from<basic_const_iterator> I> friend constexpr bool operator<(const basic_const_iterator& x, const I& y) requires random_­access_­iterator<Iterator> && totally_­ordered_­with<Iterator, I>; template<different-from<basic_const_iterator> I> friend constexpr bool operator>(const basic_const_iterator& x, const I& y) requires random_­access_­iterator<Iterator> && totally_­ordered_­with<Iterator, I>; template<different-from<basic_const_iterator> I> friend constexpr bool operator<=(const basic_const_iterator& x, const I& y) requires random_­access_­iterator<Iterator> && totally_­ordered_­with<Iterator, I>; template<different-from<basic_const_iterator> I> friend constexpr bool operator>=(const basic_const_iterator& x, const I& y) requires random_­access_­iterator<Iterator> && totally_­ordered_­with<Iterator, I>; template<different-from<basic_const_iterator> I> friend constexpr auto operator<=>(const basic_const_iterator& x, const I& y) requires random_­access_­iterator<Iterator> && totally_­ordered_­with<Iterator, I> && three_­way_­comparable_­with<Iterator, I>;
Let op be the operator.
Returns: Equivalent to: return x.current_­ op y;
template<not-a-const-iterator I> friend constexpr bool operator<(const I& x, const basic_const_iterator& y) requires random_­access_­iterator<Iterator> && totally_­ordered_­with<Iterator, I>; template<not-a-const-iterator I> friend constexpr bool operator>(const I& x, const basic_const_iterator& y) requires random_­access_­iterator<Iterator> && totally_­ordered_­with<Iterator, I>; template<not-a-const-iterator I> friend constexpr bool operator<=(const I& x, const basic_const_iterator& y) requires random_­access_­iterator<Iterator> && totally_­ordered_­with<Iterator, I>; template<not-a-const-iterator I> friend constexpr bool operator>=(const I& x, const basic_const_iterator& y) requires random_­access_­iterator<Iterator> && totally_­ordered_­with<Iterator, I>;
Let op be the operator.
Returns: Equivalent to: return x op y.current_­;
friend constexpr basic_const_iterator operator+(const basic_const_iterator& i, difference_type n) requires random_­access_­iterator<Iterator>; friend constexpr basic_const_iterator operator+(difference_type n, const basic_const_iterator& i) requires random_­access_­iterator<Iterator>;
Effects: Equivalent to: return basic_­const_­iterator(i.current_­ + n);
friend constexpr basic_const_iterator operator-(const basic_const_iterator& i, difference_type n) requires random_­access_­iterator<Iterator>;
Effects: Equivalent to: return basic_­const_­iterator(i.current_­ - n);
template<sized_­sentinel_­for<Iterator> S> friend constexpr difference_type operator-(const basic_const_iterator& x, const S& y);
Effects: Equivalent to: return x.current_­ - y;
template<sized_­sentinel_­for<Iterator> S> requires different-from<S, basic_const_iterator> friend constexpr difference_type operator-(const S& x, const basic_const_iterator& y);
Effects: Equivalent to: return x - y.current_­;