diff --git a/source/iterators.tex b/source/iterators.tex index f38f819f83..cb60f0a9be 100644 --- a/source/iterators.tex +++ b/source/iterators.tex @@ -384,10 +384,8 @@ // \ref{iterators.counted}, counted iterators template<@\libconcept{input_or_output_iterator}@ I> class counted_iterator; - template - struct incrementable_traits>; - template<@\libconcept{input_iterator}@ I> + requires @\seebelow@ struct iterator_traits>; // \ref{unreachable.sentinel}, unreachable sentinel @@ -1011,6 +1009,14 @@ Explicit or partial specializations of \tcode{iterator_traits} may have a member type \tcode{iterator_concept} that is used to indicate conformance to the iterator concepts\iref{iterator.concepts}. +\begin{example} +To indicate conformance to the \libconcept{input_iterator} concept +but a lack of conformance to +the \oldconcept{InputIter\-ator} requirements\iref{input.iterators}, +an \tcode{iterator_traits} specialization might have +\tcode{iterator_concept} denote \tcode{input_iterator_tag} +but not define \tcode{iterator_category}. +\end{example} \pnum \tcode{iterator_traits} is specialized for pointers as @@ -4085,7 +4091,7 @@ public: using iterator_type = Iterator; using iterator_concept = input_iterator_tag; - using iterator_category = @\seebelow@; + using iterator_category = @\seebelow@; // not always present using value_type = iter_value_t; using difference_type = iter_difference_t; using pointer = Iterator; @@ -4135,7 +4141,11 @@ \end{codeblock} \pnum -The member \grammarterm{typedef-name} \tcode{iterator_category} denotes +The member \grammarterm{typedef-name} \tcode{iterator_category} is defined +if and only if the \grammarterm{qualified-id} +\tcode{iterator_traits::iterator_category} +is valid and denotes a type. +In that case, \tcode{iterator_category} denotes \begin{itemize} \item \tcode{random_access_iterator_tag} if @@ -4795,7 +4805,8 @@ \item \tcode{iterator_category} denotes \tcode{forward_iterator_tag} -if \tcode{iterator_traits::iterator_category} +if the \grammarterm{qualified-id} \tcode{iterator_traits::iter\-ator_category} +is valid and denotes a type that models \tcode{\libconcept{derived_from}}; otherwise it denotes \tcode{input_iterator_tag}. @@ -4990,7 +5001,33 @@ ++*this; return tmp; \end{codeblock} -Otherwise, equivalent to: \tcode{return get(v_)++;} +Otherwise, if +\tcode{requires (I\& i) \{ \{ *i++ \} -> \exposconceptnc{can-reference}; \}} +is \tcode{true} or +\tcode{\libconcept{constructible_\newline{}from}, iter_reference_t>} +is \tcode{false}, +equivalent to: +\begin{codeblock} +return get(v_)++; +\end{codeblock} +Otherwise, equivalent to: +\begin{codeblock} +@\exposid{postfix-proxy}@ p(**this); +++*this; +return p; +\end{codeblock} +where \exposid{postfix-proxy} is the exposition-only class: +\begin{codeblock} +class @\exposid{postfix-proxy}@ { + iter_value_t keep_; + @\exposid{postfix-proxy}@(iter_reference_t&& x) + : keep_(std::move(x)) {} +public: + const iter_value_t& operator*() const { + return keep_; + } +}; +\end{codeblock} \end{itemdescr} \rSec3[common.iter.cmp]{Comparisons} @@ -5151,7 +5188,13 @@ class counted_iterator { public: using iterator_type = I; - + using value_type = iter_value_t; // present only + // if \tcode{I} models \libconcept{indirectly_readable} + using difference_type = iter_difference_t; + using iterator_concept = typename I::iterator_concept; // present only + // if the \grammarterm{qualified-id} \tcode{I::iterator_concept} is valid and denotes a type + using iterator_category = typename I::iterator_category; // present only + // if the \grammarterm{qualified-id} \tcode{I::iterator_category} is valid and denotes a type constexpr counted_iterator() = default; constexpr counted_iterator(I x, iter_difference_t n); template @@ -5169,6 +5212,9 @@ constexpr decltype(auto) operator*() const requires @\exposconcept{dereferenceable}@; + constexpr auto operator->() const noexcept + requires @\libconcept{contiguous_iterator}@; + constexpr counted_iterator& operator++(); decltype(auto) operator++(int); constexpr counted_iterator operator++(int) @@ -5223,14 +5269,11 @@ iter_difference_t length = 0; // \expos }; - template - struct incrementable_traits> { - using difference_type = iter_difference_t; - }; - template<@\libconcept{input_iterator}@ I> + requires @\libconcept{same_as}@<@\exposid{ITER_TRAITS}@(I), iterator_traits> // see \ref{iterator.concepts.general} struct iterator_traits> : iterator_traits { - using pointer = void; + using pointer = conditional_t<@\libconcept{contiguous_iterator}@, + add_pointer_t>, void>; }; } \end{codeblock} @@ -5339,6 +5382,18 @@ Equivalent to: \tcode{return *current;} \end{itemdescr} +\indexlibrarymember{operator->}{counted_iterator}% +\begin{itemdecl} +constexpr auto operator->() const noexcept + requires @\libconcept{contiguous_iterator}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return to_address(current);} +\end{itemdescr} + \indexlibrarymember{operator[]}{counted_iterator}% \begin{itemdecl} constexpr decltype(auto) operator[](iter_difference_t n) const diff --git a/source/ranges.tex b/source/ranges.tex index 4477268a95..00fa442bea 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -2309,7 +2309,7 @@ W @\exposid{value_}@ = W(); // \expos public: using iterator_concept = @\seebelow@; - using iterator_category = input_iterator_tag; + using iterator_category = input_iterator_tag; // present only if \tcode{W} models \libconcept{incrementable} using value_type = W; using difference_type = @\placeholdernc{IOTA-DIFF-T}@(W); @@ -3269,7 +3269,7 @@ filter_view* @\exposid{parent_}@ = nullptr; // \expos public: using iterator_concept = @\seebelow@; - using iterator_category = @\seebelow@; + using iterator_category = @\seebelow@; // not always present using value_type = range_value_t; using difference_type = range_difference_t; @@ -3320,6 +3320,9 @@ \end{itemize} \pnum +The member \grammarterm{typedef-name} \tcode{iterator_category} is defined +if and only if \tcode{V} models \libconcept{forward_range}. +In that case, \tcode{\exposid{iterator}::iterator_category} is defined as follows: \begin{itemize} \item Let \tcode{C} denote the type @@ -3759,7 +3762,7 @@ @\exposid{Parent}@* @\exposid{parent_}@ = nullptr; // \expos public: using iterator_concept = @\seebelow@; - using iterator_category = @\seebelow@; + using iterator_category = @\seebelow@; // not always present using value_type = remove_cvref_t>>; using difference_type = range_difference_t<@\exposid{Base}@>; @@ -3846,6 +3849,9 @@ \end{itemize} \pnum +The member \grammarterm{typedef-name} \tcode{iterator_category} is defined +if and only if \exposid{Base} models \libconcept{forward_range}. +In that case, \tcode{iterator::iterator_category} is defined as follows: Let \tcode{C} denote the type \tcode{iterator_traits>::iterator_category}. @@ -5071,7 +5077,7 @@ constexpr void @\exposid{satisfy}@(); // \expos public: using iterator_concept = @\seebelow@; - using iterator_category = @\seebelow@; + using iterator_category = @\seebelow@; // not always present using value_type = range_value_t>; using difference_type = @\seebelow@; @@ -5133,24 +5139,27 @@ \end{itemize} \pnum -\tcode{iterator::iterator_category} is defined as follows: +The member \grammarterm{typedef-name} \tcode{iterator_category} is defined +if and only if \exposid{ref-is-glvalue} is \tcode{true}, +\exposid{Base} models \libconcept{forward_range}, and +\tcode{range_reference_t<\exposid{Base}>} models \libconcept{forward_range}. +In that case, +\tcode{iterator::iter\-ator_category} is defined as follows: \begin{itemize} \item Let \placeholder{OUTERC} denote \tcode{iterator_traits>::iterator_category}, and let \placeholder{INNERC} denote \tcode{iterator_traits>>::iterator_category}. -\item If \exposid{ref-is-glvalue} is \tcode{true} and +\item If \placeholder{OUTERC} and \placeholder{INNERC} each model \tcode{\libconcept{derived_from}}, \tcode{iterator_category} denotes \tcode{bidirectional_iterator_tag}. -\item Otherwise, if \exposid{ref-is-glvalue} is \tcode{true} and +\item Otherwise, if \placeholder{OUTERC} and \placeholder{INNERC} each model - \tcode{\libconcept{derived_from}}, \tcode{iterator_category} + \tcode{\libconcept{derived_from}}, \tcode{iter\-ator_category} denotes \tcode{forward_iterator_tag}. -\item Otherwise, if \placeholder{OUTERC} and \placeholder{INNERC} each model - \tcode{\libconcept{derived_from}}, +\item Otherwise, \tcode{iterator_category} denotes \tcode{input_iterator_tag}. -\item Otherwise, \tcode{iterator_category} denotes \tcode{output_iterator_tag}. \end{itemize} \pnum @@ -5572,7 +5581,7 @@ public: using iterator_concept = conditional_t<@\libconcept{forward_range}@<@\exposid{Base}@>, forward_iterator_tag, input_iterator_tag>; - using iterator_category = input_iterator_tag; + using iterator_category = input_iterator_tag; // present only if \exposid{Base} models \libconcept{forward_range} // \ref{range.split.outer.value}, class \tcode{split_view::\exposid{outer-iterator}::value_type} struct value_type; using difference_type = range_difference_t<@\exposid{Base}@>; @@ -5801,7 +5810,7 @@ bool @\exposid{incremented_}@ = false; // \expos public: using iterator_concept = typename @\exposid{outer-iterator}@::iterator_concept; - using iterator_category = @\seebelow@; + using iterator_category = @\seebelow@; // present only if \exposid{Base} models \libconcept{forward_range} using value_type = range_value_t<@\exposid{Base}@>; using difference_type = range_difference_t<@\exposid{Base}@>; @@ -6395,7 +6404,8 @@ static constexpr decltype(auto) @\exposid{get-element}@(const iterator_t<@\exposid{Base}@>& i); // \expos public: - using iterator_category = typename iterator_traits>::iterator_category; + using iterator_concept = @\seebelow@; + using iterator_category = @\seebelow@; // not always present using value_type = remove_cvref_t>>; using difference_type = range_difference_t<@\exposid{Base}@>; @@ -6453,6 +6463,40 @@ } \end{codeblock} +\pnum +The member \grammarterm{typedef-name} \tcode{iterator_concept} +is defined as follows: +\begin{itemize} +\item +If \tcode{V} models \libconcept{random_access_range}, +then \tcode{iterator_concept} denotes \tcode{random_access_iterator_tag}. +\item +Otherwise, if \tcode{V} models \libconcept{bidirectional_range}, +then \tcode{iterator_concept} denotes \tcode{bidirectional_iterator_tag}. +\item +Otherwise, if \tcode{V} models \libconcept{forward_range}, +then \tcode{iterator_concept} denotes \tcode{forward_iterator_tag}. +\item +Otherwise, \tcode{iterator_concept} denotes \tcode{input_iterator_tag}. +\end{itemize} + +\pnum +The member \grammarterm{typedef-name} \tcode{iterator_category} is defined +if and only if \exposid{Base} models \libconcept{forward_range}. +In that case, \tcode{iterator_category} is defined as follows: +Let \tcode{C} denote the type +\tcode{iterator_traits>::iterator_category}. +\begin{itemize} +\item +If \tcode{get(*\exposid{current_})} is an rvalue, +\tcode{iterator_category} denotes \tcode{input_iterator_tag}. +\item +Otherwise, if \tcode{C} models \tcode{\libconcept{derived_from}}, +\tcode{iterator_category} denotes \tcode{random_access_iterator_tag}. +\item +Otherwise, \tcode{iterator_category} denotes \tcode{C}. +\end{itemize} + \indexlibrarymember{\exposid{get-element}}{elements_view::iterator}% \begin{itemdecl} static constexpr decltype(auto) @\exposid{get-element}@(const iterator_t<@\exposid{Base}@>& i); // \expos