Skip to content

P2259R1 Repairing input range adaptors and counted_iterator #4518

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 69 additions & 14 deletions source/iterators.tex
Original file line number Diff line number Diff line change
Expand Up @@ -384,10 +384,8 @@
// \ref{iterators.counted}, counted iterators
template<@\libconcept{input_or_output_iterator}@ I> class counted_iterator;

template<class I>
struct incrementable_traits<counted_iterator<I>>;

template<@\libconcept{input_iterator}@ I>
requires @\seebelow@
struct iterator_traits<counted_iterator<I>>;

// \ref{unreachable.sentinel}, unreachable sentinel
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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<Iterator>;
using difference_type = iter_difference_t<Iterator>;
using pointer = Iterator;
Expand Down Expand Up @@ -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<It\-erator>::iterator_category}
is valid and denotes a type.
In that case, \tcode{iterator_category} denotes
\begin{itemize}
\item
\tcode{random_access_iterator_tag} if
Expand Down Expand Up @@ -4795,7 +4805,8 @@
\item
\tcode{iterator_category} denotes
\tcode{forward_iterator_tag}
if \tcode{iterator_traits<I>::iterator_category}
if the \grammarterm{qualified-id} \tcode{iterator_traits<I>::iter\-ator_category}
is valid and denotes a type that
models \tcode{\libconcept{derived_from}<forward_iterator_tag>};
otherwise it denotes \tcode{input_iterator_tag}.

Expand Down Expand Up @@ -4990,7 +5001,33 @@
++*this;
return tmp;
\end{codeblock}
Otherwise, equivalent to: \tcode{return get<I>(v_)++;}
Otherwise, if
\tcode{requires (I\& i) \{ \{ *i++ \} -> \exposconceptnc{can-reference}; \}}
is \tcode{true} or
\tcode{\libconcept{constructible_\newline{}from}<iter_value_t<I>, iter_reference_t<I>>}
is \tcode{false},
equivalent to:
\begin{codeblock}
return get<I>(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<I> keep_;
@\exposid{postfix-proxy}@(iter_reference_t<I>&& x)
: keep_(std::move(x)) {}
public:
const iter_value_t<I>& operator*() const {
return keep_;
}
};
\end{codeblock}
\end{itemdescr}

\rSec3[common.iter.cmp]{Comparisons}
Expand Down Expand Up @@ -5151,7 +5188,13 @@
class counted_iterator {
public:
using iterator_type = I;

using value_type = iter_value_t<I>; // present only
// if \tcode{I} models \libconcept{indirectly_readable}
using difference_type = iter_difference_t<I>;
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<I> n);
template<class I2>
Expand All @@ -5169,6 +5212,9 @@
constexpr decltype(auto) operator*() const
requires @\exposconcept{dereferenceable}@<const I>;

constexpr auto operator->() const noexcept
requires @\libconcept{contiguous_iterator}@<I>;

constexpr counted_iterator& operator++();
decltype(auto) operator++(int);
constexpr counted_iterator operator++(int)
Expand Down Expand Up @@ -5223,14 +5269,11 @@
iter_difference_t<I> length = 0; // \expos
};

template<class I>
struct incrementable_traits<counted_iterator<I>> {
using difference_type = iter_difference_t<I>;
};

template<@\libconcept{input_iterator}@ I>
requires @\libconcept{same_as}@<@\exposid{ITER_TRAITS}@(I), iterator_traits<I>> // see \ref{iterator.concepts.general}
struct iterator_traits<counted_iterator<I>> : iterator_traits<I> {
using pointer = void;
using pointer = conditional_t<@\libconcept{contiguous_iterator}@<I>,
add_pointer_t<iter_reference_t<I>>, void>;
};
}
\end{codeblock}
Expand Down Expand Up @@ -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}@<I>;
\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<I> n) const
Expand Down
72 changes: 58 additions & 14 deletions source/ranges.tex
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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<V>;
using difference_type = range_difference_t<V>;

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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<invoke_result_t<F&, range_reference_t<@\exposid{Base}@>>>;
using difference_type = range_difference_t<@\exposid{Base}@>;
Expand Down Expand Up @@ -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_t<\exposid{Base}>>::iterator_category}.
Expand Down Expand Up @@ -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<range_reference_t<@\exposid{Base}@>>;
using difference_type = @\seebelow@;

Expand Down Expand Up @@ -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_t<\exposid{Base}>>::iterator_category}, and
let \placeholder{INNERC} denote
\tcode{iterator_traits<iterator_t<range_reference_t<\exposid{Base}>>>::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}<bidirectional_iterator_tag>}, \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}<for\-ward_iterator_tag>}, \tcode{iterator_category}
\tcode{\libconcept{derived_from}<forward_iterator_tag>}, \tcode{iter\-ator_category}
denotes \tcode{forward_iterator_tag}.
\item Otherwise, if \placeholder{OUTERC} and \placeholder{INNERC} each model
\tcode{\libconcept{derived_from}<input_iterator_tag>},
\item Otherwise,
\tcode{iterator_category} denotes \tcode{input_iterator_tag}.
\item Otherwise, \tcode{iterator_category} denotes \tcode{output_iterator_tag}.
\end{itemize}

\pnum
Expand Down Expand Up @@ -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}@>;
Expand Down Expand Up @@ -5801,7 +5810,7 @@
bool @\exposid{incremented_}@ = false; // \expos
public:
using iterator_concept = typename @\exposid{outer-iterator}@<Const>::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}@>;

Expand Down Expand Up @@ -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_t<@\exposid{Base}@>>::iterator_category;
using iterator_concept = @\seebelow@;
using iterator_category = @\seebelow@; // not always present
using value_type = remove_cvref_t<tuple_element_t<N, range_value_t<@\exposid{Base}@>>>;
using difference_type = range_difference_t<@\exposid{Base}@>;

Expand Down Expand Up @@ -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_t<\exposid{Base}>>::iterator_category}.
\begin{itemize}
\item
If \tcode{get<N>(*\exposid{current_})} is an rvalue,
\tcode{iterator_category} denotes \tcode{input_iterator_tag}.
\item
Otherwise, if \tcode{C} models \tcode{\libconcept{derived_from}<random_access_iterator_tag>},
\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
Expand Down