diff --git a/source/ranges.tex b/source/ranges.tex index 7e0ebb1bd0..faafdeb2f8 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -193,6 +193,11 @@ namespace views { template inline constexpr @\unspec@ istream = @\unspec@; } + // \ref{range.adaptor.object}, range adaptor objects + template + requires is_class_v && @\libconcept{same_as}@> + class range_adaptor_closure { }; + // \ref{range.all}, all view namespace views { inline constexpr @\unspec@ all = @\unspec@; @@ -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 @@ -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}>}, +\item +\tcode{T} has no other base classes of type \tcode{range_adaptor_closure} for any other type \tcode{U}, and +\item +\tcode{T} does not model \libconcept{range} +\end{itemize} +then the implementation ensures +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}>}. +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} +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} diff --git a/source/support.tex b/source/support.tex index 9eb63bc7b7..35cbe37ccc 100644 --- a/source/support.tex +++ b/source/support.tex @@ -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} @@ -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} diff --git a/source/utilities.tex b/source/utilities.tex index 216efc596c..c9a0f03518 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -16256,8 +16256,9 @@ // \ref{func.not.fn}, function template \tcode{not_fn} template 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 constexpr @\unspec@ bind_front(F&&, Args&&...); + template constexpr @\unspec@ bind_back(F&&, Args&&...); // \ref{func.bind}, bind template struct is_bind_expression; @@ -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 constexpr @\unspec@ bind_front(F&& f, Args&&... args); +template + 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}, \item \tcode{fd} is the target object of \tcode{g}\iref{func.def} of type \tcode{FD}, @@ -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 diff --git a/source/xrefdelta.tex b/source/xrefdelta.tex index fbd137a397..a58c53dce7 100644 --- a/source/xrefdelta.tex +++ b/source/xrefdelta.tex @@ -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)