Skip to content

Commit 24afe25

Browse files
jensmaurertkoeppe
authored andcommitted
P2387R3 Pipe support for user-defined range adaptors
1 parent caf7f66 commit 24afe25

File tree

4 files changed

+66
-8
lines changed

4 files changed

+66
-8
lines changed

source/ranges.tex

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,11 @@
193193

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

196+
// \ref{range.adaptor.object}, range adaptor objects
197+
template<class D>
198+
requires is_class_v<D> && @\libconcept{same_as}@<D, remove_cv_t<D>>
199+
class range_adaptor_closure { };
200+
196201
// \ref{range.all}, all view
197202
namespace views {
198203
inline constexpr @\unspec@ all = @\unspec@;
@@ -3365,10 +3370,10 @@
33653370

33663371
\pnum
33673372
A \term{range adaptor closure object} is a unary function object that accepts
3368-
a \libconcept{viewable_range} argument and returns a \libconcept{view}. For
3373+
a \libconcept{range} argument. For
33693374
a range adaptor closure object \tcode{C} and an expression \tcode{R} such that
3370-
\tcode{decltype((R))} models \libconcept{viewable_range}, the following
3371-
expressions are equivalent and yield a \libconcept{view}:
3375+
\tcode{decltype((R))} models \libconcept{range}, the following
3376+
expressions are equivalent:
33723377
\begin{codeblock}
33733378
C(R)
33743379
R | C
@@ -3394,6 +3399,42 @@
33943399
The expression \tcode{C | D} is well-formed if and only if
33953400
the initializations of the state entities of \tcode{E} are all well-formed.
33963401

3402+
\pnum
3403+
Given an object \tcode{t} of type \tcode{T}, where
3404+
\begin{itemize}
3405+
\item
3406+
\tcode{t} is a unary function object that accepts a \libconcept{range} argument,
3407+
\item
3408+
\tcode{T} models \tcode{\libconcept{derived_from}<range_adaptor_closure<T>>},
3409+
\item
3410+
\tcode{T} has no other base classes of type \tcode{range_adaptor_closure<U>} for any other type \tcode{U}, and
3411+
\item
3412+
\tcode{T} does not model \libconcept{range}
3413+
\end{itemize}
3414+
then the implementation ensures
3415+
that \tcode{t} is a range adaptor closure object.
3416+
3417+
\pnum
3418+
The template parameter \tcode{D} for \tcode{range_adaptor_closure}
3419+
may be an incomplete type.
3420+
If an expression of type \cv{} \tcode{D}
3421+
is used as an operand to the \tcode{|} operator,
3422+
\tcode{D} shall be complete and
3423+
model \tcode{\libconcept{derived_from}<range_adaptor_closure<D>>}.
3424+
The behavior of an expression involving an object of type \cv{} \tcode{D}
3425+
as an operand to the \tcode{|} operator is undefined
3426+
if overload resolution selects a program-defined \tcode{operator|} function.
3427+
3428+
\pnum
3429+
If an expression of type \cv{} \tcode{U}
3430+
is used as an operand to the \tcode{|} operator,
3431+
where \tcode{U} has a base class of type \tcode{range_adaptor_closure<T>}
3432+
for some type \tcode{T} other than \tcode{U}, the behavior is undefined.
3433+
3434+
\pnum
3435+
The behavior of a program
3436+
that adds a specialization for \tcode{range_adaptor_closure} is undefined.
3437+
33973438
\pnum
33983439
A \term{range adaptor object} is a
33993440
customization point object\iref{customization.point.object}

source/support.tex

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,7 @@
573573
#define @\defnlibxname{cpp_lib_atomic_value_initialization}@ 201911L // also in \libheader{atomic}, \libheader{memory}
574574
#define @\defnlibxname{cpp_lib_atomic_wait}@ 201907L // also in \libheader{atomic}
575575
#define @\defnlibxname{cpp_lib_barrier}@ 201907L // also in \libheader{barrier}
576+
#define @\defnlibxname{cpp_lib_bind_back}@ 202202L // also in \libheader{functional}
576577
#define @\defnlibxname{cpp_lib_bind_front}@ 201907L // also in \libheader{functional}
577578
#define @\defnlibxname{cpp_lib_bit_cast}@ 201806L // also in \libheader{bit}
578579
#define @\defnlibxname{cpp_lib_bitops}@ 201907L // also in \libheader{bit}
@@ -668,7 +669,7 @@
668669
#define @\defnlibxname{cpp_lib_parallel_algorithm}@ 201603L // also in \libheader{algorithm}, \libheader{numeric}
669670
#define @\defnlibxname{cpp_lib_polymorphic_allocator}@ 201902L // also in \libheader{memory_resource}
670671
#define @\defnlibxname{cpp_lib_quoted_string_io}@ 201304L // also in \libheader{iomanip}
671-
#define @\defnlibxname{cpp_lib_ranges}@ 202110L
672+
#define @\defnlibxname{cpp_lib_ranges}@ 202202L
672673
// also in \libheader{algorithm}, \libheader{functional}, \libheader{iterator}, \libheader{memory}, \libheader{ranges}
673674
#define @\defnlibxname{cpp_lib_ranges_starts_ends_with}@ 202106L // also in \libheader{algorithm}
674675
#define @\defnlibxname{cpp_lib_ranges_to_container}@ 202202L // also in \libheader{ranges}

source/utilities.tex

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16256,8 +16256,9 @@
1625616256
// \ref{func.not.fn}, function template \tcode{not_fn}
1625716257
template<class F> constexpr @\unspec@ not_fn(F&& f);
1625816258

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

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

17910-
\rSec2[func.bind.front]{Function template \tcode{bind_front}}
17911+
\rSec2[func.bind.partial]{Function templates \tcode{bind_front} and \tcode{bind_back}}
1791117912

1791217913
\indexlibraryglobal{bind_front}%
17914+
\indexlibraryglobal{bind_back}%
1791317915
\begin{itemdecl}
1791417916
template<class F, class... Args>
1791517917
constexpr @\unspec@ bind_front(F&& f, Args&&... args);
17918+
template<class F, class... Args>
17919+
constexpr @\unspec@ bind_back(F&& f, Args&&... args);
1791617920
\end{itemdecl}
1791717921

1791817922
\begin{itemdescr}
1791917923
\pnum
1792017924
Within this subclause:
1792117925
\begin{itemize}
17922-
\item \tcode{g} is a value of the result of a \tcode{bind_front} invocation,
17926+
\item \tcode{g} is a value of
17927+
the result of a \tcode{bind_front} or \tcode{bind_back} invocation,
1792317928
\item \tcode{FD} is the type \tcode{decay_t<F>},
1792417929
\item \tcode{fd} is the target object of \tcode{g}\iref{func.def}
1792517930
of type \tcode{FD},
@@ -17955,7 +17960,15 @@
1795517960
\pnum
1795617961
\returns
1795717962
A perfect forwarding call wrapper \tcode{g}
17958-
with call pattern \tcode{invoke(fd, bound_args..., call_args...)}.
17963+
with call pattern:
17964+
\begin{itemize}
17965+
\item
17966+
\tcode{invoke(fd, bound_args..., call_args...)}
17967+
for a \tcode{bind_front} invocation, or
17968+
\item
17969+
\tcode{invoke(fd, call_args..., bound_args...)}
17970+
for a \tcode{bind_back} invocation.
17971+
\end{itemize}
1795917972

1796017973
\pnum
1796117974
\throws

source/xrefdelta.tex

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,5 +89,8 @@
8989
\movedxref{ofstream.assign}{ofstream.swap}
9090
\movedxref{fstream.assign}{fstream.swap}
9191

92+
% P2387R3 Pipe support for user-defined range adaptors
93+
\movedxref{func.bind.front}{func.bind.partial}
94+
9295
% Deprecated features.
9396
%\deprxref{old.label} (if moved to depr.old.label, otherwise use \movedxref)

0 commit comments

Comments
 (0)