Skip to content

Commit ad2ddb8

Browse files
authored
Merge 2018-11 LWG Motion 26
P0356R5 Simplified partial function application Fixes #2432
2 parents 5afa60a + e6b8936 commit ad2ddb8

File tree

2 files changed

+136
-82
lines changed

2 files changed

+136
-82
lines changed

source/support.tex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,8 @@
555555
\tcode{<atomic>} \\ \rowsep
556556
\defnlibxname{cpp_lib_bit_cast} & \tcode{201806L} &
557557
\tcode{<bit>} \\ \rowsep
558+
\defnlibxname{cpp_lib_bind_front} & \tcode{201811L} &
559+
\tcode{<functional>} \\ \rowsep
558560
\defnlibxname{cpp_lib_bool_constant} & \tcode{201505L} &
559561
\tcode{<type_traits>} \\ \rowsep
560562
\defnlibxname{cpp_lib_boyer_moore_searcher} & \tcode{201603L} &

source/utilities.tex

Lines changed: 134 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -13721,6 +13721,9 @@
1372113721
// \ref{func.not_fn}, function template \tcode{not_fn}
1372213722
template<class F> @\unspec@ not_fn(F&& f);
1372313723

13724+
// \ref{func.bind_front}, function template \tcode{bind_front}
13725+
template <class F, class... Args> @\unspec@ bind_front(F&&, Args&&...);
13726+
1372413727
// \ref{func.bind}, bind
1372513728
template<class T> struct is_bind_expression;
1372613729
template<class T> struct is_placeholder;
@@ -13868,6 +13871,17 @@
1386813871
\pnum
1386913872
A \defn{target object} is the callable object held by a call wrapper.
1387013873

13874+
\pnum
13875+
A call wrapper type may additionally hold
13876+
a sequence of objects and references
13877+
that may be passed as arguments to the target object.
13878+
These entities are collectively referred to
13879+
as \defnx{bound argument entities}{bound argument entity}.
13880+
13881+
\pnum
13882+
The target object and bound argument entities of the call wrapper are
13883+
collectively referred to as \defnx{state entities}{state entity}.
13884+
1387113885
\rSec2[func.require]{Requirements}
1387213886

1387313887
\pnum
@@ -13914,28 +13928,64 @@
1391413928
\indextext{call wrapper}%
1391513929
\indextext{call wrapper!simple}%
1391613930
\indextext{call wrapper!forwarding}%
13917-
Every call wrapper\iref{func.def} shall be
13918-
\oldconcept{MoveConstructible}.
13919-
A \defn{forwarding call wrapper} is a
13931+
Every call wrapper\iref{func.def} is \oldconcept{MoveConstructible}.
13932+
A \defn{argument forwarding call wrapper} is a
1392013933
call wrapper that can be called with an arbitrary argument list
1392113934
and delivers the arguments to the wrapped callable object as references.
13922-
This forwarding step shall ensure that rvalue arguments are delivered as rvalue references
13923-
and lvalue arguments are delivered as lvalue references.
13924-
A \defn{simple call wrapper} is a forwarding call wrapper that is
13935+
This forwarding step delivers rvalue arguments as rvalue references
13936+
and lvalue arguments as lvalue references.
13937+
A \defn{simple call wrapper} is an argument forwarding call wrapper that is
1392513938
\oldconcept{CopyConstructible} and \oldconcept{CopyAssignable} and
1392613939
whose copy constructor, move constructor, copy assignment operator,
1392713940
and move assignment operator do not throw exceptions.
1392813941
\begin{note}
13929-
In a typical implementation
13930-
forwarding call wrappers have an overloaded function call
13931-
operator of
13932-
the form
13942+
In a typical implementation, argument forwarding call wrappers have
13943+
an overloaded function call operator of the form
1393313944
\begin{codeblock}
1393413945
template<class... UnBoundArgs>
1393513946
R operator()(UnBoundArgs&&... unbound_args) @\textit{cv-qual}@;
1393613947
\end{codeblock}
1393713948
\end{note}
1393813949

13950+
\pnum
13951+
\indextext{call wrapper!perfect forwarding}%
13952+
A \defn{perfect forwarding call wrapper} is
13953+
an argument forwarding call wrapper
13954+
that forwards its state entities to the underlying call expression.
13955+
This forwarding step delivers a state entity of type \tcode{T}
13956+
as \cv{} \tcode{T\&}
13957+
when the call is performed on an lvalue of the call wrapper type and
13958+
as \cv{} \tcode{T\&\&} otherwise,
13959+
where \cv{} represents the cv-qualifiers of the call wrapper and
13960+
where \cv{} shall be neither \tcode{volatile} nor \tcode{const volatile}.
13961+
13962+
\pnum
13963+
A \defn{call pattern} defines the semantics of invoking
13964+
a perfect forwarding call wrapper.
13965+
A postfix call performed on a perfect forwarding call wrapper is
13966+
expression-equivalent\iref{defns.expression-equivalent} to
13967+
an expression \tcode{e} determined from its call pattern \tcode{cp}
13968+
by replacing all occurrences
13969+
of the arguments of the call wrapper and its state entities
13970+
with references as described in the corresponding forwarding steps.
13971+
13972+
\pnum
13973+
The copy/move constructor of a perfect forwarding call wrapper has
13974+
the same apparent semantics
13975+
as if memberwise copy/move of its state entities
13976+
were performed\iref{class.copy.ctor}.
13977+
\begin{note}
13978+
This implies that each of the copy/move constructors has
13979+
the same exception-specification as
13980+
the corresponding implicit definition and is declared as \tcode{constexpr}
13981+
if the corresponding implicit definition would be considered to be constexpr.
13982+
\end{note}
13983+
13984+
\pnum
13985+
Perfect forwarding call wrappers returned by
13986+
a given standard library function template have the same type
13987+
if the types of their corresponding state entities are the same.
13988+
1393913989
\rSec2[func.invoke]{Function template \tcode{invoke}}
1394013990
\indexlibrary{\idxcode{invoke}}%
1394113991
\indexlibrary{invoke@\tcode{\placeholder{INVOKE}}}%
@@ -15193,93 +15243,95 @@
1519315243

1519415244
\begin{itemdescr}
1519515245
\pnum
15196-
\effects
15197-
Equivalent to: \tcode{return \placeholder{call-wrapper}(std::forward<F>(f));}
15198-
where \tcode{\placeholder{call-wrapper}} is an exposition only class defined as follows:
15199-
\begin{codeblock}
15200-
class @\placeholder{call-wrapper}@ {
15201-
using FD = decay_t<F>;
15202-
FD fd;
15203-
15204-
explicit @\placeholder{call-wrapper}@(F&& f);
15205-
15206-
public:
15207-
@\placeholder{call-wrapper}@(@\placeholder{call-wrapper}@&&) = default;
15208-
@\placeholder{call-wrapper}@(const @\placeholder{call-wrapper}@&) = default;
15209-
15210-
template<class... Args>
15211-
auto operator()(Args&&...) &
15212-
-> decltype(!declval<invoke_result_t<FD&, Args...>>());
15213-
15214-
template<class... Args>
15215-
auto operator()(Args&&...) const&
15216-
-> decltype(!declval<invoke_result_t<const FD&, Args...>>());
15217-
15218-
template<class... Args>
15219-
auto operator()(Args&&...) &&
15220-
-> decltype(!declval<invoke_result_t<FD, Args...>>());
15221-
15222-
template<class... Args>
15223-
auto operator()(Args&&...) const&&
15224-
-> decltype(!declval<invoke_result_t<const FD, Args...>>());
15225-
};
15226-
\end{codeblock}
15227-
\end{itemdescr}
15246+
In the text that follows:
15247+
\begin{itemize}
15248+
\item \tcode{g} is a value of the result of a \tcode{not_fn} invocation,
15249+
\item \tcode{FD} is the type \tcode{decay_t<F>},
15250+
\item \tcode{fd} is the target object of \tcode{g}\iref{func.def}
15251+
of type \tcode{FD},
15252+
initialized with
15253+
the \grammarterm{initializer} \tcode{(std::forward<F>(f\brk{}))}\iref{dcl.init},
15254+
\item \tcode{call_args} is an argument pack
15255+
used in a function call expression\iref{expr.call} of \tcode{g}.
15256+
\end{itemize}
1522815257

15229-
\begin{itemdecl}
15230-
explicit @\placeholdernc{call-wrapper}@(F&& f);
15231-
\end{itemdecl}
15258+
\pnum
15259+
\mandates
15260+
\tcode{is_constructible_v<FD, F> \&\& is_move_constructible_v<FD>}
15261+
shall be true.
1523215262

15233-
\begin{itemdescr}
1523415263
\pnum
15235-
\requires
15236-
\tcode{FD} shall satisfy the \oldconcept{MoveConstructible} requirements.
15237-
\tcode{is_constructible_v<FD, F>} shall be \tcode{true}.
15238-
\tcode{fd} shall be a callable object\iref{func.def}.
15264+
\expects
15265+
\tcode{FD} shall meet the requirements of \oldconcept{MoveConstructible}.
1523915266

1524015267
\pnum
15241-
\effects
15242-
Initializes \tcode{fd} from \tcode{std::forward<F>(f)}.
15268+
\returns
15269+
A perfect forwarding call wrapper \tcode{g}
15270+
with call pattern \tcode{!invoke(fd, call_args...)}.
1524315271

1524415272
\pnum
1524515273
\throws
15246-
Any exception thrown by construction of \tcode{fd}.
15274+
Any exception thrown by the initialization of \tcode{fd}.
1524715275
\end{itemdescr}
1524815276

15277+
\rSec2[func.bind_front]{Function template \tcode{bind_front}}
15278+
15279+
\indexlibrary{\idxcode{bind_front}}%
1524915280
\begin{itemdecl}
15250-
template<class... Args>
15251-
auto operator()(Args&&... args) &
15252-
-> decltype(!declval<invoke_result_t<FD&, Args...>>());
15253-
template<class... Args>
15254-
auto operator()(Args&&... args) const&
15255-
-> decltype(!declval<invoke_result_t<const FD&, Args...>>());
15281+
template <class F, class... Args>
15282+
@\unspec@ bind_front(F&& f, Args&&... args);
1525615283
\end{itemdecl}
1525715284

1525815285
\begin{itemdescr}
1525915286
\pnum
15260-
\effects
15261-
Equivalent to:
15287+
In the text that follows:
15288+
\begin{itemize}
15289+
\item \tcode{g} is a value of the result of a \tcode{bind_front} invocation,
15290+
\item \tcode{FD} is the type \tcode{decay_t<F>},
15291+
\item \tcode{fd} is the target object of \tcode{g}\iref{func.def}
15292+
of type \tcode{FD} initialized with
15293+
the \grammarterm{initializer} \tcode{(std::forward<F>(\brk{}f))}\iref{dcl.init},
15294+
\item \tcode{BoundArgs} is a pack of types
15295+
equivalent to \tcode{\placeholdernc{DECAY_UNWRAP}(Args)...},
15296+
\item \tcode{bound_args} is
15297+
a pack of bound argument entities of \tcode{g}\iref{func.def}
15298+
of types \tcode{BoundArgs...},
15299+
initialized with
15300+
\grammarterm{initializer}{s} \tcode{(std::forward<Args>(args))...},
15301+
respectively,
15302+
\item \tcode{call_args} is an argument pack used in
15303+
a function call expression\iref{expr.call} of \tcode{g},
15304+
\end{itemize}
15305+
where \tcode{\placeholdernc{DECAY_UNWRAP}(T)} is determined as follows:
15306+
Let \tcode{U} be \tcode{decay_t<T>}.
15307+
Then \tcode{\placeholdernc{DECAY_UNWRAP}(T)} is \tcode{X\&}
15308+
if \tcode{U} is a specialization \tcode{reference_wrapper<X>},
15309+
otherwise \tcode{\placeholdernc{DECAY_UNWRAP}(T)} is \tcode{U}.
15310+
15311+
\pnum
15312+
\mandates
1526215313
\begin{codeblock}
15263-
return !@\placeholdernc{INVOKE}@(fd, std::forward<Args>(args)...); // see \ref{func.require}
15314+
conjunction_v<is_constructible<FD, F>, is_move_constructible<FD>,
15315+
is_constructible<BoundArgs, Args>..., is_move_constructible<BoundArgs>...>
1526415316
\end{codeblock}
15265-
\end{itemdescr}
15317+
shall be true.
1526615318

15267-
\begin{itemdecl}
15268-
template<class... Args>
15269-
auto operator()(Args&&... args) &&
15270-
-> decltype(!declval<invoke_result_t<FD, Args...>>());
15271-
template<class... Args>
15272-
auto operator()(Args&&... args) const&&
15273-
-> decltype(!declval<invoke_result_t<const FD, Args...>>());
15274-
\end{itemdecl}
15319+
\pnum
15320+
\expects
15321+
\tcode{FD} shall meet the requirements of \oldconcept{MoveConstructible}.
15322+
For each $\tcode{T}_i$ in \tcode{BoundArgs},
15323+
if $\tcode{T}_i$ is an object type,
15324+
$\tcode{T}_i$ shall meet the requirements of \oldconcept{MoveConstructible}.
1527515325

15276-
\begin{itemdescr}
1527715326
\pnum
15278-
\effects
15279-
Equivalent to:
15280-
\begin{codeblock}
15281-
return !@\placeholdernc{INVOKE}@(std::move(fd), std::forward<Args>(args)...); // see \ref{func.require}
15282-
\end{codeblock}
15327+
\returns
15328+
A perfect forwarding call wrapper \tcode{g}
15329+
with call pattern \tcode{invoke(fd, bound_args..., call_args...)}.
15330+
15331+
\pnum
15332+
\throws
15333+
Any exception thrown by
15334+
the initialization of the state entities of \tcode{g}\iref{func.def}.
1528315335
\end{itemdescr}
1528415336

1528515337
\rSec2[func.bind]{Function object binders}%
@@ -15353,7 +15405,7 @@
1535315405
\item $\tcode{t}_i$ is the $i^\text{th}$ argument in the function parameter pack \tcode{bound_args},
1535415406
\item $\tcode{td}_i$ is an lvalue of type $\tcode{TD}_i$ constructed from \tcode{std::forward<$\tcode{T}_i$>($\tcode{t}_i$)},
1535515407
\item $\tcode{U}_j$ is the $j^\text{th}$ deduced type of the \tcode{UnBoundArgs\&\&...} parameter
15356-
of the forwarding call wrapper, and
15408+
of the argument forwarding call wrapper, and
1535715409
\item $\tcode{u}_j$ is the $j^\text{th}$ argument associated with $\tcode{U}_j$.
1535815410
\end{itemize}
1535915411

@@ -15376,15 +15428,15 @@
1537615428
as specified below, shall be neither \tcode{volatile} nor \tcode{const volatile}.
1537715429

1537815430
\pnum\returns
15379-
A forwarding call wrapper \tcode{g}\iref{func.require}.
15431+
An argument forwarding call wrapper \tcode{g}\iref{func.require}.
1538015432
The effect of \tcode{g($\tcode{u}_1$, $\tcode{u}_2$, $\dotsc$, $\tcode{u}_M$)} shall
1538115433
be
1538215434
\begin{codeblock}
1538315435
@\placeholdernc{INVOKE}@(fd, std::forward<@$\tcode{V}_1$@>(@$\tcode{v}_1$@), std::forward<@$\tcode{V}_2$@>(@$\tcode{v}_2$@), @$\dotsc$@, std::forward<@$\tcode{V}_N$@>(@$\tcode{v}_N$@))
1538415436
\end{codeblock}
1538515437
where the values and types of the bound
1538615438
arguments $\tcode{v}_1$, $\tcode{v}_2$, $\dotsc$, $\tcode{v}_N$ are determined as specified below.
15387-
The copy constructor and move constructor of the forwarding call wrapper shall throw an
15439+
The copy constructor and move constructor of the argument forwarding call wrapper shall throw an
1538815440
exception if and only if the corresponding constructor of \tcode{FD} or of any of the types
1538915441
$\tcode{TD}_i$ throws an exception.
1539015442

@@ -15419,15 +15471,15 @@
1541915471

1542015472
\pnum
1542115473
\returns
15422-
A forwarding call wrapper \tcode{g}\iref{func.require}.
15474+
An argument forwarding call wrapper \tcode{g}\iref{func.require}.
1542315475
The effect of
1542415476
\tcode{g($\tcode{u}_1$, $\tcode{u}_2$, $\dotsc$, $\tcode{u}_M$)} shall be
1542515477
\begin{codeblock}
1542615478
@\placeholdernc{INVOKE}@<R>(fd, std::forward<@$\tcode{V}_1$@>(@$\tcode{v}_1$@), std::forward<@$\tcode{V}_2$@>(@$\tcode{v}_2$@), @$\dotsc$@, std::forward<@$\tcode{V}_N$@>(@$\tcode{v}_N$@))
1542715479
\end{codeblock}
1542815480
where the values and types of the bound
1542915481
arguments $\tcode{v}_1$, $\tcode{v}_2$, $\dotsc$, $\tcode{v}_N$ are determined as specified below.
15430-
The copy constructor and move constructor of the forwarding call wrapper shall throw an
15482+
The copy constructor and move constructor of the argument forwarding call wrapper shall throw an
1543115483
exception if and only if the corresponding constructor of \tcode{FD} or of any of the types
1543215484
$\tcode{TD}_i$ throws an exception.
1543315485

0 commit comments

Comments
 (0)