[iterator.traits] (original) (raw)

23 Iterators library [iterators]

23.3 Iterator requirements [iterator.requirements]

23.3.2 Associated types [iterator.assoc.types]

23.3.2.3 Iterator traits [iterator.traits]

To implement algorithms only in terms of iterators, it is sometimes necessary to determine the iterator category that corresponds to a particular iterator type.

Accordingly, it is required that ifIis the type of an iterator, the type

iterator_traits::iterator_category

be defined as the iterator's iterator category.

In addition, the types

iterator_traits::pointer iterator_traits::reference

shall be defined as the iterator's pointer and reference types; that is, for an iterator object a of class type, the same type asdecltype(a.operator->()) anddecltype(*a), respectively.

The typeiterator_­traits<I>​::​pointershall be voidfor an iterator of class type Ithat does not support operator->.

Additionally, in the case of an output iterator, the types

iterator_traits::value_type iterator_traits::difference_type iterator_traits::reference

may be defined as void.

The definitions in this subclause make use of the following exposition-only concepts:

template concept cpp17-iterator = copyable && requires(I i) { { *i } -> can-reference; { ++i } -> same_as<I&>; { *i++ } -> can-reference; };

template concept cpp17-input-iterator = cpp17-iterator && equality_comparable && requires(I i) { typename incrementable_traits::difference_type; typename indirectly_readable_traits::value_type; typename common_reference_t<iter_reference_t&&, typename indirectly_readable_traits::value_type&>; typename common_reference_t<decltype(*i++)&&, typename indirectly_readable_traits::value_type&>; requires signed_integral<typename incrementable_traits::difference_type>; };

template concept cpp17-forward-iterator = cpp17-input-iterator && constructible_from && is_lvalue_reference_v<iter_reference_t> && same_as<remove_cvref_t<iter_reference_t>, typename indirectly_readable_traits::value_type> && requires(I i) { { i++ } -> convertible_to<const I&>; { *i++ } -> same_as<iter_reference_t>; };

template concept cpp17-bidirectional-iterator = cpp17-forward-iterator && requires(I i) { { --i } -> same_as<I&>; { i-- } -> convertible_to<const I&>; { *i-- } -> same_as<iter_reference_t>; };

template concept cpp17-random-access-iterator = cpp17-bidirectional-iterator && totally_ordered && requires(I i, typename incrementable_traits::difference_type n) { { i += n } -> same_as<I&>; { i -= n } -> same_as<I&>; { i + n } -> same_as; { n + i } -> same_as; { i - n } -> same_as; { i - i } -> same_as<decltype(n)>; { i[n] } -> convertible_to<iter_reference_t>; };

The members of a specialization iterator_­traits<I> generated from theiterator_­traits primary template are computed as follows:

Explicit or partial specializations of iterator_­traits may have a member type iterator_­concept that is used to indicate conformance to the iterator concepts ([iterator.concepts]).

iterator_­traits is specialized for pointers as

namespace std { template requires is_object_v struct iterator_traits<T*> { using iterator_concept = contiguous_iterator_tag; using iterator_category = random_access_iterator_tag; using value_type = remove_cv_t; using difference_type = ptrdiff_t; using pointer = T*; using reference = T&; }; }

[ Example

:

To implement a genericreversefunction, a C++ program can do the following:

template void reverse(BI first, BI last) { typename iterator_traits::difference_type n = distance(first, last); --n; while(n > 0) { typename iterator_traits::value_type tmp = *first; *first++ = *--last; *last = tmp; n -= 2; } }

end example

]