Skip to content

P2387R3 Pipe support for user-defined range adaptors #5285

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
Feb 20, 2022
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
47 changes: 44 additions & 3 deletions source/ranges.tex
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,11 @@

namespace views { template<class T> inline constexpr @\unspec@ istream = @\unspec@; }

// \ref{range.adaptor.object}, range adaptor objects
template<class D>
requires is_class_v<D> && @\libconcept{same_as}@<D, remove_cv_t<D>>
class range_adaptor_closure { };

// \ref{range.all}, all view
namespace views {
inline constexpr @\unspec@ all = @\unspec@;
Expand Down Expand Up @@ -3365,10 +3370,10 @@

\pnum
A \term{range adaptor closure object} is a unary function object that accepts
a \libconcept{viewable_range} argument and returns a \libconcept{view}. For
a \libconcept{range} argument. For
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}:
\tcode{decltype((R))} models \libconcept{range}, the following
expressions are equivalent:
\begin{codeblock}
C(R)
R | C
Expand All @@ -3394,6 +3399,42 @@
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
Given an object \tcode{t} of type \tcode{T}, where
\begin{itemize}
\item
\tcode{t} is a unary function object that accepts a \libconcept{range} argument,
\item
\tcode{T} models \tcode{\libconcept{derived_from}<range_adaptor_closure<T>>},
\item
\tcode{T} has no other base classes of type \tcode{range_adaptor_closure<U>} for any other type \tcode{U}, and
\item
\tcode{T} does not model \libconcept{range}
\end{itemize}
then the implementation ensures
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I'm not wild about the use of "then" here, which is trying to make it sound as if the sentence had started with "If t is an object of type T...". Really we should drop the "then" and have a comma after the preceding item. But that's how it was given to us.)

that \tcode{t} is a range adaptor closure object.

\pnum
The template parameter \tcode{D} for \tcode{range_adaptor_closure}
may be an incomplete type.
If an expression of type \cv{} \tcode{D}
is used as an operand to the \tcode{|} operator,
\tcode{D} shall be complete and
model \tcode{\libconcept{derived_from}<range_adaptor_closure<D>>}.
The behavior of an expression involving an object of type \cv{} \tcode{D}
as an operand to the \tcode{|} operator is undefined
if overload resolution selects a program-defined \tcode{operator|} function.

\pnum
If an expression of type \cv{} \tcode{U}
is used as an operand to the \tcode{|} operator,
where \tcode{U} has a base class of type \tcode{range_adaptor_closure<T>}
for some type \tcode{T} other than \tcode{U}, the behavior is undefined.

\pnum
The behavior of a program
that adds a specialization for \tcode{range_adaptor_closure} is undefined.

\pnum
A \term{range adaptor object} is a
customization point object\iref{customization.point.object}
Expand Down
3 changes: 2 additions & 1 deletion source/support.tex
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,7 @@
#define @\defnlibxname{cpp_lib_atomic_value_initialization}@ 201911L // also in \libheader{atomic}, \libheader{memory}
#define @\defnlibxname{cpp_lib_atomic_wait}@ 201907L // also in \libheader{atomic}
#define @\defnlibxname{cpp_lib_barrier}@ 201907L // also in \libheader{barrier}
#define @\defnlibxname{cpp_lib_bind_back}@ 202202L // also in \libheader{functional}
#define @\defnlibxname{cpp_lib_bind_front}@ 201907L // also in \libheader{functional}
#define @\defnlibxname{cpp_lib_bit_cast}@ 201806L // also in \libheader{bit}
#define @\defnlibxname{cpp_lib_bitops}@ 201907L // also in \libheader{bit}
Expand Down Expand Up @@ -668,7 +669,7 @@
#define @\defnlibxname{cpp_lib_parallel_algorithm}@ 201603L // also in \libheader{algorithm}, \libheader{numeric}
#define @\defnlibxname{cpp_lib_polymorphic_allocator}@ 201902L // also in \libheader{memory_resource}
#define @\defnlibxname{cpp_lib_quoted_string_io}@ 201304L // also in \libheader{iomanip}
#define @\defnlibxname{cpp_lib_ranges}@ 202110L
#define @\defnlibxname{cpp_lib_ranges}@ 202202L
// also in \libheader{algorithm}, \libheader{functional}, \libheader{iterator}, \libheader{memory}, \libheader{ranges}
#define @\defnlibxname{cpp_lib_ranges_starts_ends_with}@ 202106L // also in \libheader{algorithm}
#define @\defnlibxname{cpp_lib_ranges_to_container}@ 202202L // also in \libheader{ranges}
Expand Down
21 changes: 17 additions & 4 deletions source/utilities.tex
Original file line number Diff line number Diff line change
Expand Up @@ -16256,8 +16256,9 @@
// \ref{func.not.fn}, function template \tcode{not_fn}
template<class F> constexpr @\unspec@ not_fn(F&& f);

// \ref{func.bind.front}, function template \tcode{bind_front}
// \ref{func.bind.partial}, function templates \tcode{bind_front} and \tcode{bind_back}
template<class F, class... Args> constexpr @\unspec@ bind_front(F&&, Args&&...);
template<class F, class... Args> constexpr @\unspec@ bind_back(F&&, Args&&...);

// \ref{func.bind}, bind
template<class T> struct is_bind_expression;
Expand Down Expand Up @@ -17907,19 +17908,23 @@
Any exception thrown by the initialization of \tcode{fd}.
\end{itemdescr}

\rSec2[func.bind.front]{Function template \tcode{bind_front}}
\rSec2[func.bind.partial]{Function templates \tcode{bind_front} and \tcode{bind_back}}

\indexlibraryglobal{bind_front}%
\indexlibraryglobal{bind_back}%
\begin{itemdecl}
template<class F, class... Args>
constexpr @\unspec@ bind_front(F&& f, Args&&... args);
template<class F, class... Args>
constexpr @\unspec@ bind_back(F&& f, Args&&... args);
\end{itemdecl}

\begin{itemdescr}
\pnum
Within this subclause:
\begin{itemize}
\item \tcode{g} is a value of the result of a \tcode{bind_front} invocation,
\item \tcode{g} is a value of
the result of a \tcode{bind_front} or \tcode{bind_back} invocation,
\item \tcode{FD} is the type \tcode{decay_t<F>},
\item \tcode{fd} is the target object of \tcode{g}\iref{func.def}
of type \tcode{FD},
Expand Down Expand Up @@ -17955,7 +17960,15 @@
\pnum
\returns
A perfect forwarding call wrapper \tcode{g}
with call pattern \tcode{invoke(fd, bound_args..., call_args...)}.
with call pattern:
\begin{itemize}
\item
\tcode{invoke(fd, bound_args..., call_args...)}
for a \tcode{bind_front} invocation, or
\item
\tcode{invoke(fd, call_args..., bound_args...)}
for a \tcode{bind_back} invocation.
\end{itemize}

\pnum
\throws
Expand Down
3 changes: 3 additions & 0 deletions source/xrefdelta.tex
Original file line number Diff line number Diff line change
Expand Up @@ -89,5 +89,8 @@
\movedxref{ofstream.assign}{ofstream.swap}
\movedxref{fstream.assign}{fstream.swap}

% P2387R3 Pipe support for user-defined range adaptors
\movedxref{func.bind.front}{func.bind.partial}

% Deprecated features.
%\deprxref{old.label} (if moved to depr.old.label, otherwise use \movedxref)