Skip to content

P2281R1 Clarifying range adaptor objects #4681

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
Jun 17, 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
23 changes: 21 additions & 2 deletions source/lib-intro.tex
Original file line number Diff line number Diff line change
Expand Up @@ -771,15 +771,34 @@
\pnum
All instances of a specific customization point object type shall
be equal\iref{concepts.equality}.
The effects of invoking different instances
of a specific customization point object type on the same arguments
are equivalent.

\pnum
The type \tcode{T} of a customization point object shall model
\tcode{\libconcept{invocable}<const T\&, Args...>}\iref{concept.invocable}
The type \tcode{T} of a customization point object,
ignoring \grammarterm{cv-qualifier}s, shall model
\tcode{\libconcept{invocable}<T\&, Args...>},
\tcode{\libconcept{invocable}<const T\&, Args...>},
\tcode{\libconcept{invocable}<T, Args...>}, and
\tcode{\libconcept{invocable}<const T, Args...>}\iref{concept.invocable}
when the types in \tcode{Args...} meet the requirements specified in that
customization point object's definition. When the types of \tcode{Args...} do
not meet the customization point object's requirements, \tcode{T} shall not have
a function call operator that participates in overload resolution.

\pnum
For a given customization point object \tcode{o},
let \tcode{p} be a variable initialized as if by \tcode{auto p = o;}.
Then for any sequence of arguments \tcode{args...},
the following expressions have effects equivalent to \tcode{o(args...)}:
\begin{itemize}
\item \tcode{p(args...)}
\item \tcode{as_const(p)(args...)}
\item \tcode{std::move(p)(args...)}
\item \tcode{std::move(as_const(p))(args...)}
\end{itemize}

\pnum
Each customization point object type constrains its return type to model a
particular concept.
Expand Down
61 changes: 41 additions & 20 deletions source/ranges.tex
Original file line number Diff line number Diff line change
Expand Up @@ -3055,20 +3055,30 @@
a range adaptor closure object \tcode{C} and an expression \tcode{R} such that
\tcode{decltype((R))} models \libconcept{viewable_range}, the following
expressions are equivalent and yield a \libconcept{view}:

\begin{codeblock}
C(R)
R | C
\end{codeblock}

Given an additional range adaptor closure object \tcode{D},
the expression \tcode{C | D} is well-formed and produces another range adaptor
closure object such that the following two expressions are equivalent:

\begin{codeblock}
R | C | D
R | (C | D)
\end{codeblock}
the expression \tcode{C | D} produces another range adaptor
closure object \tcode{E}.
\tcode{E} is a perfect forwarding call wrapper\iref{func.require}
with the following properties:
\begin{itemize}
\item
Its target object is an object \tcode{d} of type \tcode{decay_t<decltype((D))>}
direct-non-list-initialized with \tcode{D}.
\item
It has one bound argument entity,
an object \tcode{c} of type \tcode{decay_t<decltype((C))>}
direct-non-list-initialized with \tcode{C}.
\item
Its call pattern is \tcode{d(c(arg))},
where \tcode{arg} is the argument used in
a function call expression of \tcode{E}.
\end{itemize}
The expression \tcode{C | D} is well-formed if and only if
the initializations of the state entities of \tcode{E} are all well-formed.

\pnum
A \term{range adaptor object} is a
Expand All @@ -3081,17 +3091,28 @@
then it is a range adaptor closure object.

\pnum
If a range adaptor object accepts more than one argument,
then the following expressions are equivalent:

\begin{codeblock}
@\placeholdernc{adaptor}@(range, args...)
@\placeholdernc{adaptor}@(args...)(range)
range | @\placeholdernc{adaptor}@(args...)
\end{codeblock}

In this case, \tcode{\placeholdernc{adaptor}(args...)} is a range adaptor
closure object.
If a range adaptor object \tcode{adaptor} accepts more than one argument,
then let \tcode{range} be an expression
such that \tcode{decltype((range))} models \libconcept{viewable_range},
let \tcode{args...} be arguments
such that \tcode{adaptor(range, args...)} is a well-formed expression
as specified in the rest of subclause\iref{range.adaptors}, and
let \tcode{BoundArgs} be a pack
that denotes \tcode{decay_t<decltype((args))>...}.
The expression \tcode{adaptor(args...)} produces a range adaptor closure object \tcode{f}
that is a perfect forwarding call wrapper with the following properties:
\begin{itemize}
\item
Its target object is a copy of \tcode{adaptor}.
\item
Its bound argument entities \tcode{bound_args} consist of objects of types \tcode{BoundArgs...} direct-non-list-initialized with \tcode{std::forward<decltype((args))>(args)...}, respectively.
\item
Its call pattern is \tcode{adaptor(r, bound_args...)},
where \tcode{r} is the argument used in a function call expression of \tcode{f}.
\end{itemize}
The expression \tcode{adaptor(args...)} is well-formed if and only if
the initialization of the bound argument entities of the result,
as specified above, are all well-formed.

\rSec2[range.semi.wrap]{Semiregular wrapper}

Expand Down