Files
cppdraft_translate/cppdraft/iterator/traits.md
2025-10-25 03:02:53 +03:00

156 lines
12 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[iterator.traits]
# 24 Iterators library [[iterators]](./#iterators)
## 24.3 Iterator requirements [[iterator.requirements]](iterator.requirements#iterator.traits)
### 24.3.2 Associated types [[iterator.assoc.types]](iterator.assoc.types#iterator.traits)
#### 24.3.2.3 Iterator traits [iterator.traits]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L908)
To implement algorithms only in terms of iterators, it is sometimes necessary to
determine the iterator category that corresponds to a particular iterator type[.](#1.sentence-1)
Accordingly, it is required that ifI is the type of an iterator,
the type
[🔗](#lib:iterator_category,iterator_traits)
iterator_traits<I>::iterator_category be defined as the iterator's iterator category[.](#1.sentence-2)
In addition, the types
[🔗](#lib:pointer,iterator_traits)
iterator_traits<I>::pointer
iterator_traits<I>::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[.](#1.sentence-3)
The typeiterator_traits<I>::pointer shall be void for an iterator of class type I that does not support operator->[.](#1.sentence-4)
Additionally, in the case of an output iterator, the typesiterator_traits<I>::value_type
iterator_traits<I>::difference_type
iterator_traits<I>::reference may be defined as void[.](#1.sentence-5)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L948)
The definitions in this subclause make use of the following
exposition-only concepts:template<class I>concept [*cpp17-iterator*](#concept:cpp17-iterator "24.3.2.3Iterator traits[iterator.traits]") =requires(I i) {{ *i } -> [*can-reference*](iterator.synopsis#concept:can-reference "24.2Header <iterator>&nbsp;synopsis[iterator.synopsis]"); { ++i } -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<I&>; { *i++ } -> [*can-reference*](iterator.synopsis#concept:can-reference "24.2Header <iterator>&nbsp;synopsis[iterator.synopsis]"); } && [copyable](concepts.object#concept:copyable "18.6Object concepts[concepts.object]")<I>;
template<class I>concept [*cpp17-input-iterator*](#concept:cpp17-input-iterator "24.3.2.3Iterator traits[iterator.traits]") =[*cpp17-iterator*](#concept:cpp17-iterator "24.3.2.3Iterator traits[iterator.traits]")<I> && [equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4Concept equality_­comparable[concept.equalitycomparable]")<I> && requires(I i) {typename incrementable_traits<I>::difference_type; typename indirectly_readable_traits<I>::value_type; typename common_reference_t<iter_reference_t<I>&&, typename indirectly_readable_traits<I>::value_type&>; typename common_reference_t<decltype(*i++)&&, typename indirectly_readable_traits<I>::value_type&>; requires [signed_integral](concepts.arithmetic#concept:signed_integral "18.4.7Arithmetic concepts[concepts.arithmetic]")<typename incrementable_traits<I>::difference_type>; };
template<class I>concept [*cpp17-forward-iterator*](#concept:cpp17-forward-iterator "24.3.2.3Iterator traits[iterator.traits]") =[*cpp17-input-iterator*](#concept:cpp17-input-iterator "24.3.2.3Iterator traits[iterator.traits]")<I> && [constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept constructible_­from[concept.constructible]")<I> && is_reference_v<iter_reference_t<I>> &&[same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<remove_cvref_t<iter_reference_t<I>>, typename indirectly_readable_traits<I>::value_type> &&requires(I i) {{ i++ } -> [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<const I&>; { *i++ } -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<iter_reference_t<I>>; };
template<class I>concept [*cpp17-bidirectional-iterator*](#concept:cpp17-bidirectional-iterator "24.3.2.3Iterator traits[iterator.traits]") =[*cpp17-forward-iterator*](#concept:cpp17-forward-iterator "24.3.2.3Iterator traits[iterator.traits]")<I> && requires(I i) {{ --i } -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<I&>; { i-- } -> [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<const I&>; { *i-- } -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<iter_reference_t<I>>; };
template<class I>concept [*cpp17-random-access-iterator*](#concept:cpp17-random-access-iterator "24.3.2.3Iterator traits[iterator.traits]") =[*cpp17-bidirectional-iterator*](#concept:cpp17-bidirectional-iterator "24.3.2.3Iterator traits[iterator.traits]")<I> && [totally_ordered](concept.totallyordered#concept:totally_ordered "18.5.5Concept totally_­ordered[concept.totallyordered]")<I> &&requires(I i, typename incrementable_traits<I>::difference_type n) {{ i += n } -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<I&>; { i -= n } -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<I&>; { i + n } -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<I>; { n + i } -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<I>; { i - n } -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<I>; { i - i } -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<decltype(n)>; { i[n] } -> [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<iter_reference_t<I>>; };
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1005)
The members of a specialization iterator_traits<I> generated from theiterator_traits primary template are computed as follows:
- [(3.1)](#3.1)
If I has valid ([[temp.deduct]](temp.deduct "13.10.3Template argument deduction")) member
types difference_type, value_type,reference, and iterator_category,
theniterator_traits<I> has the following publicly accessible members:using iterator_category = typename I::iterator_category;using value_type = typename I::value_type;using difference_type = typename I::difference_type;using pointer = *see below*;using reference = typename I::reference;
If the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]") I::pointer is valid and
denotes a type, then iterator_traits<I>::pointer names that type;
otherwise, it names void[.](#3.1.sentence-2)
- [(3.2)](#3.2)
Otherwise, if I satisfies the exposition-only concept[*cpp17-input-iterator*](#concept:cpp17-input-iterator "24.3.2.3Iterator traits[iterator.traits]"),iterator_traits<I> has the following
publicly accessible members:using iterator_category = *see below*;using value_type = typename indirectly_readable_traits<I>::value_type;using difference_type = typename incrementable_traits<I>::difference_type;using pointer = *see below*;using reference = *see below*;
* [(3.2.1)](#3.2.1)
If the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]") I::pointer is valid and denotes a type,pointer names that type[.](#3.2.1.sentence-1)
Otherwise, ifdecltype(declval<I&>().operator->()) is well-formed, thenpointer names that type[.](#3.2.1.sentence-2)
Otherwise, pointer names void[.](#3.2.1.sentence-3)
* [(3.2.2)](#3.2.2)
If the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]") I::reference is valid and denotes a
type, reference names that type[.](#3.2.2.sentence-1)
Otherwise, reference names iter_reference_t<I>[.](#3.2.2.sentence-2)
* [(3.2.3)](#3.2.3)
If the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]") I::iterator_category is valid and
denotes a type, iterator_category names that type[.](#3.2.3.sentence-1)
Otherwise, iterator_category names:
+
[(3.2.3.1)](#3.2.3.1)
random_access_iterator_tag ifI satisfies [*cpp17-random-access-iterator*](#concept:cpp17-random-access-iterator "24.3.2.3Iterator traits[iterator.traits]"),
or otherwise
+
[(3.2.3.2)](#3.2.3.2)
bidirectional_iterator_tag ifI satisfies [*cpp17-bidirectional-iterator*](#concept:cpp17-bidirectional-iterator "24.3.2.3Iterator traits[iterator.traits]"),
or otherwise
+
[(3.2.3.3)](#3.2.3.3)
forward_iterator_tag ifI satisfies [*cpp17-forward-iterator*](#concept:cpp17-forward-iterator "24.3.2.3Iterator traits[iterator.traits]"),
or otherwise
+
[(3.2.3.4)](#3.2.3.4)
input_iterator_tag[.](#3.2.3.sentence-2)
- [(3.3)](#3.3)
Otherwise, if I satisfies the exposition-only concept[*cpp17-iterator*](#concept:cpp17-iterator "24.3.2.3Iterator traits[iterator.traits]"), then iterator_traits<I> has the following publicly accessible
members:using iterator_category = output_iterator_tag;using value_type = void;using difference_type = *see below*;using pointer = void;using reference = void;
If the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]")incrementable_traits<I>::difference_type is valid and denotes a type,
then difference_type names that type; otherwise, it names void[.](#3.3.sentence-2)
- [(3.4)](#3.4)
Otherwise, iterator_traits<I> has no members by any of the above names[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1094)
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.concepts "24.3.4Iterator concepts"))[.](#4.sentence-1)
[*Example [1](#example-1)*:
To indicate conformance to the [input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9Concept input_­iterator[iterator.concept.input]") concept
but a lack of conformance to
the *Cpp17InputIterator* requirements ([[input.iterators]](input.iterators "24.3.5.3Input iterators")),
an iterator_traits specialization might haveiterator_concept denote input_iterator_tag but not define iterator_category[.](#4.sentence-2)
— *end example*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1107)
iterator_traits is specialized for pointers asnamespace std {template<class T>requires is_object_v<T>struct iterator_traits<T*> {using iterator_concept = contiguous_iterator_tag; using iterator_category = random_access_iterator_tag; using value_type = remove_cv_t<T>; using difference_type = ptrdiff_t; using pointer = T*; using reference = T&; };}
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L1124)
[*Example [2](#example-2)*:
To implement a genericreverse function, a C++ program can do the following:template<class BI>void reverse(BI first, BI last) {typename iterator_traits<BI>::difference_type n = distance(first, last); --n; while (n > 0) {typename iterator_traits<BI>::value_type tmp = *first; *first++ = *--last; *last = tmp;
n -= 2; }}
— *end example*]