Skip to content

Commit ae6d4ac

Browse files
committed
P2387R3 Pipe support for user-defined range adaptors
1 parent 4b1a735 commit ae6d4ac

File tree

4 files changed

+66
-9
lines changed

4 files changed

+66
-9
lines changed

source/ranges.tex

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

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

186+
// \ref{range.adaptor.object}, range adaptor objects
187+
template<class D>
188+
requires is_class_v<D> && @\libconcept{same_as}@<D, remove_cv_t<D>>
189+
class range_adaptor_closure { };
190+
186191
// \ref{range.all}, all view
187192
namespace views {
188193
inline constexpr @\unspec@ all = @\unspec@;
@@ -3137,10 +3142,10 @@
31373142

31383143
\pnum
31393144
A \term{range adaptor closure object} is a unary function object that accepts
3140-
a \libconcept{viewable_range} argument and returns a \libconcept{view}. For
3145+
a \libconcept{range} argument. For
31413146
a range adaptor closure object \tcode{C} and an expression \tcode{R} such that
3142-
\tcode{decltype((R))} models \libconcept{viewable_range}, the following
3143-
expressions are equivalent and yield a \libconcept{view}:
3147+
\tcode{decltype((R))} models \libconcept{range}, the following
3148+
expressions are equivalent:
31443149
\begin{codeblock}
31453150
C(R)
31463151
R | C
@@ -3166,6 +3171,42 @@
31663171
The expression \tcode{C | D} is well-formed if and only if
31673172
the initializations of the state entities of \tcode{E} are all well-formed.
31683173

3174+
\pnum
3175+
Given an object \tcode{t} of type \tcode{T}, where
3176+
\begin{itemize}
3177+
\item
3178+
\tcode{t} is a unary function object that accepts a \tcode{range} argument,
3179+
\item
3180+
\tcode{T} models \tcode{\libconcept{derived_from}<range_adaptor_closure<T>>},
3181+
\item
3182+
\tcode{T} has no other base classes of type \tcode{range_adaptor_closure<U>} for any other type \tcode{U}, and
3183+
\item
3184+
\tcode{T} does not model \tcode{range}
3185+
\end{itemize}
3186+
then the implementation ensures
3187+
that \tcode{t} is a range adaptor closure object.
3188+
3189+
\pnum
3190+
The template parameter \tcode{D} for \tcode{range_adaptor_closure}
3191+
may be an incomplete type.
3192+
If an expression of type \cv{} \tcode{D}
3193+
is used as an operand to the \tcode{|} operator,
3194+
\tcode{D} shall be complete and
3195+
model \tcode{\libconcept{derived_from}<range_adaptor_closure<D>>}.
3196+
The behavior of an expression involving an object of type \cv{} \tcode{D}
3197+
as an operand to the \tcode{|} operator is undefined
3198+
if overload resolution selects a program-defined \tcode{operator|} function.
3199+
3200+
\pnum
3201+
If an expression of type \cv{} \tcode{U}
3202+
is used as an operand to the \tcode{|} operator,
3203+
where \tcode{U} has a base class of type \tcode{range_adaptor_closure<T>}
3204+
for some type \tcode{T} other than \tcode{U}, the behavior is undefined.
3205+
3206+
\pnum
3207+
The behavior of a program
3208+
that adds a specialization for \tcode{range_adaptor_closure} is undefined.
3209+
31693210
\pnum
31703211
A \term{range adaptor object} is a
31713212
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}
@@ -664,7 +665,7 @@
664665
#define @\defnlibxname{cpp_lib_parallel_algorithm}@ 201603L // also in \libheader{algorithm}, \libheader{numeric}
665666
#define @\defnlibxname{cpp_lib_polymorphic_allocator}@ 201902L // also in \libheader{memory_resource}
666667
#define @\defnlibxname{cpp_lib_quoted_string_io}@ 201304L // also in \libheader{iomanip}
667-
#define @\defnlibxname{cpp_lib_ranges}@ 202110L
668+
#define @\defnlibxname{cpp_lib_ranges}@ 202202L
668669
// also in \libheader{algorithm}, \libheader{functional}, \libheader{iterator}, \libheader{memory}, \libheader{ranges}
669670
#define @\defnlibxname{cpp_lib_ranges_starts_ends_with}@ 202106L // also in \libheader{algorithm}
670671
#define @\defnlibxname{cpp_lib_ranges_zip}@ 202110L // also in \libheader{ranges}, \libheader{tuple}, \libheader{utility}

source/utilities.tex

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14090,9 +14090,9 @@
1409014090
// \ref{func.not.fn}, function template \tcode{not_fn}
1409114091
template<class F> constexpr @\unspec@ not_fn(F&& f);
1409214092

14093-
// \ref{func.bind.front}, function template \tcode{bind_front}
14093+
// \ref{func.bind.partial}, function templates \tcode{bind_front} and \tcode{bind_back}
1409414094
template<class F, class... Args> constexpr @\unspec@ bind_front(F&&, Args&&...);
14095-
14095+
template<class F, class... Args> constexpr @\unspec@ bind_back(F&&, Args&&...);
1409614096
// \ref{func.bind}, bind
1409714097
template<class T> struct is_bind_expression;
1409814098
template<class T>
@@ -15736,19 +15736,23 @@
1573615736
Any exception thrown by the initialization of \tcode{fd}.
1573715737
\end{itemdescr}
1573815738

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

1574115741
\indexlibraryglobal{bind_front}%
15742+
\indexlibraryglobal{bind_back}%
1574215743
\begin{itemdecl}
1574315744
template<class F, class... Args>
1574415745
constexpr @\unspec@ bind_front(F&& f, Args&&... args);
15746+
template<class F, class... Args>
15747+
constexpr @\unspec@ bind_back(F&& f, Args&&... args);
1574515748
\end{itemdecl}
1574615749

1574715750
\begin{itemdescr}
1574815751
\pnum
1574915752
Within this subclause:
1575015753
\begin{itemize}
15751-
\item \tcode{g} is a value of the result of a \tcode{bind_front} invocation,
15754+
\item \tcode{g} is a value of
15755+
the result of a \tcode{bind_front} or \tcode{bind_back} invocation,
1575215756
\item \tcode{FD} is the type \tcode{decay_t<F>},
1575315757
\item \tcode{fd} is the target object of \tcode{g}\iref{func.def}
1575415758
of type \tcode{FD},
@@ -15784,7 +15788,15 @@
1578415788
\pnum
1578515789
\returns
1578615790
A perfect forwarding call wrapper \tcode{g}
15787-
with call pattern \tcode{invoke(fd, bound_args..., call_args...)}.
15791+
with call pattern:
15792+
\begin{itemize}
15793+
\item
15794+
\tcode{invoke(fd, bound_args..., call_args...)}
15795+
for a \tcode{bind_front} invocation, or
15796+
\item
15797+
\tcode{invoke(fd, call_args..., bound_args...)}
15798+
for a \tcode{bind_back} invocation.
15799+
\end{itemize}
1578815800

1578915801
\pnum
1579015802
\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)