From 2df85f0bd5f74e7916bd5e6d15a3d91605ae7b34 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sat, 17 Nov 2018 00:28:54 +0100 Subject: [PATCH 1/3] P0356R5 Simplified partial function application [support.limits.general] Introduce feature-test macro even though it was not presented as a wording diff in the paper. [functional.syn] Use proper subclause name in cross-reference. [func.bind_front] Do not use 'equals' when discussing types identity. --- source/support.tex | 2 + source/utilities.tex | 213 ++++++++++++++++++++++++++----------------- 2 files changed, 133 insertions(+), 82 deletions(-) diff --git a/source/support.tex b/source/support.tex index 0ff1f18ee2..1ef122b00d 100644 --- a/source/support.tex +++ b/source/support.tex @@ -555,6 +555,8 @@ \tcode{} \\ \rowsep \defnlibxname{cpp_lib_bit_cast} & \tcode{201806L} & \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_bind_front} & \tcode{201811L} & + \tcode{} \\ \rowsep \defnlibxname{cpp_lib_bool_constant} & \tcode{201505L} & \tcode{} \\ \rowsep \defnlibxname{cpp_lib_boyer_moore_searcher} & \tcode{201603L} & diff --git a/source/utilities.tex b/source/utilities.tex index 38214181ef..b90bb4b1a7 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -13721,6 +13721,9 @@ // \ref{func.not_fn}, function template \tcode{not_fn} template @\unspec@ not_fn(F&& f); + // \ref{func.bind_front}, function template \tcode{bind_front} + template @\unspec@ bind_front(F&&, Args&&...); + // \ref{func.bind}, bind template struct is_bind_expression; template struct is_placeholder; @@ -13868,6 +13871,17 @@ \pnum A \defn{target object} is the callable object held by a call wrapper. +\pnum +A call wrapper type may additionally hold +a sequence of objects, references to functions, and references to objects, +that may be passed as arguments to the target object. +These entities are collectively referred to +as \defnx{bound argument entities}{bound argument entity}. + +\pnum +The target object and bound argument entities of the call wrapper are +collectively referred to as \defnx{state entities}{state entity}. + \rSec2[func.require]{Requirements} \pnum @@ -13914,28 +13928,64 @@ \indextext{call wrapper}% \indextext{call wrapper!simple}% \indextext{call wrapper!forwarding}% -Every call wrapper\iref{func.def} shall be -\oldconcept{MoveConstructible}. -A \defn{forwarding call wrapper} is a +Every call wrapper\iref{func.def} is \oldconcept{MoveConstructible}. +A \defn{argument forwarding call wrapper} is a call wrapper that can be called with an arbitrary argument list and delivers the arguments to the wrapped callable object as references. -This forwarding step shall ensure that rvalue arguments are delivered as rvalue references -and lvalue arguments are delivered as lvalue references. -A \defn{simple call wrapper} is a forwarding call wrapper that is +This forwarding step delivers rvalue arguments as rvalue references +and lvalue arguments as lvalue references. +A \defn{simple call wrapper} is an argument forwarding call wrapper that is \oldconcept{CopyConstructible} and \oldconcept{CopyAssignable} and whose copy constructor, move constructor, copy assignment operator, and move assignment operator do not throw exceptions. \begin{note} -In a typical implementation -forwarding call wrappers have an overloaded function call -operator of -the form +In a typical implementation, argument forwarding call wrappers have +an overloaded function call operator of the form \begin{codeblock} template R operator()(UnBoundArgs&&... unbound_args) @\textit{cv-qual}@; \end{codeblock} \end{note} +\pnum +\indextext{call wrapper!perfect forwarding}% +A \defn{perfect forwarding call wrapper} is +an argument forwarding call wrapper +that forwards its state entities to the underlying call expression. +This forwarding step delivers a state entity of type \tcode{T} +as \cv{} \tcode{T\&} +when the call is performed on an lvalue of the call wrapper type and +as \cv{} \tcode{T\&\&} otherwise, +where \cv{} represents the cv-qualifiers of the call wrapper and +where \cv{} shall be neither \tcode{volatile} nor \tcode{const volatile}. + +\pnum +A \defn{call pattern} defines the semantics of invoking +a perfect forwarding call wrapper. +A postfix call performed on a perfect forwarding call wrapper is +expression-equivalent\iref{defns.expression-equivalent} to +an expression \tcode{e} determined from its call pattern \tcode{cp} +by replacing all occurrences +of the arguments of the call wrapper and its state entities +with references as described in the corresponding forwarding steps. + +\pnum +The copy/move constructor of a perfect forwarding call wrapper has +the same apparent semantics +as if memberwise copy/move of its state entities +were performed\iref{class.copy.ctor}. +\begin{note} +This implies that each of the copy/move constructors has +the same exception-specification as +the corresponding implicit definition and is declared as \tcode{constexpr} +if the corresponding implicit definition would be considered to be constexpr. +\end{note} + +\pnum +Perfect forwarding call wrappers returned by +a given standard library function template have the same type +if the types of their corresponding state entities are the same. + \rSec2[func.invoke]{Function template \tcode{invoke}} \indexlibrary{\idxcode{invoke}}% \indexlibrary{invoke@\tcode{\placeholder{INVOKE}}}% @@ -15193,93 +15243,92 @@ \begin{itemdescr} \pnum -\effects -Equivalent to: \tcode{return \placeholder{call-wrapper}(std::forward(f));} -where \tcode{\placeholder{call-wrapper}} is an exposition only class defined as follows: -\begin{codeblock} -class @\placeholder{call-wrapper}@ { - using FD = decay_t; - FD fd; - - explicit @\placeholder{call-wrapper}@(F&& f); - -public: - @\placeholder{call-wrapper}@(@\placeholder{call-wrapper}@&&) = default; - @\placeholder{call-wrapper}@(const @\placeholder{call-wrapper}@&) = default; - - template - auto operator()(Args&&...) & - -> decltype(!declval>()); - - template - auto operator()(Args&&...) const& - -> decltype(!declval>()); - - template - auto operator()(Args&&...) && - -> decltype(!declval>()); - - template - auto operator()(Args&&...) const&& - -> decltype(!declval>()); -}; -\end{codeblock} -\end{itemdescr} +In the text that follows: +\begin{itemize} +\item \tcode{g} is a value of the result of a \tcode{not_fn} invocation, +\item \tcode{FD} is the type \tcode{decay_t}, +\item \tcode{fd} is a target object of \tcode{g}\iref{func.def} + of type \tcode{FD}, + initialized with initializer \tcode{(std::forward(f))}, +\item \tcode{call_args} is an argument pack + used in a function call expression of \tcode{g}. +\end{itemize} -\begin{itemdecl} -explicit @\placeholdernc{call-wrapper}@(F&& f); -\end{itemdecl} +\pnum +\mandates +\tcode{is_constructible_v \&\& is_move_constructible_v} +shall be true. -\begin{itemdescr} \pnum -\requires -\tcode{FD} shall satisfy the \oldconcept{MoveConstructible} requirements. -\tcode{is_constructible_v} shall be \tcode{true}. -\tcode{fd} shall be a callable object\iref{func.def}. +\expects +\tcode{FD} shall meet the requirements of \oldconcept{MoveConstructible}. \pnum -\effects -Initializes \tcode{fd} from \tcode{std::forward(f)}. +\returns +A perfect forwarding call wrapper \tcode{g} +with call pattern \tcode{!invoke(fd, call_args...)}. \pnum \throws -Any exception thrown by construction of \tcode{fd}. +Any exception thrown by the initialization of \tcode{fd}. \end{itemdescr} +\rSec2[func.bind_front]{Function template \tcode{bind_front}} + +\indexlibrary{\idxcode{bind_front}}% \begin{itemdecl} -template - auto operator()(Args&&... args) & - -> decltype(!declval>()); -template - auto operator()(Args&&... args) const& - -> decltype(!declval>()); +template + @\unspec@ bind_front(F&& f, Args&&... args); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Equivalent to: +In the text that follows: +\begin{itemize} +\item \tcode{g} is a value of the result of a \tcode{bind_front} invocation, +\item \tcode{FD} is the type \tcode{decay_t}, +\item \tcode{fd} is a target object of \tcode{g}\iref{func.def} + of type \tcode{FD} initialized with initializer \tcode{(std::forward(f))}, +\item \tcode{BoundArgs} is a pack of types + equivalent to \tcode{\placeholdernc{DECAY_UNWRAP}(Args)...}, +\item \tcode{bound_args} is + a pack of bound argument entities of \tcode{g}\iref{func.def} + of types \tcode{BoundArgs...}, + initialized with initializers \tcode{(std::forward(args))...}, + respectively, +\item \tcode{call_args} is an argument pack used in + a function call expression of \tcode{g}, +\end{itemize} +where \tcode{\placeholdernc{DECAY_UNWRAP}(T)} is determined as follows: +Let \tcode{U} be \tcode{decay_t}. +Then \tcode{\placeholdernc{DECAY_UNWRAP}(T)} is \tcode{X\&} +if \tcode{U} is a specialization \tcode{reference_wrapper}, +otherwise \tcode{\placeholdernc{DECAY_UNWRAP}(T)} is \tcode{U}. + +\pnum +\mandates \begin{codeblock} -return !@\placeholdernc{INVOKE}@(fd, std::forward(args)...); // see \ref{func.require} +conjunction_v, is_move_constructible, + is_constructible..., is_move_constructible...> \end{codeblock} -\end{itemdescr} +shall be true. -\begin{itemdecl} -template - auto operator()(Args&&... args) && - -> decltype(!declval>()); -template - auto operator()(Args&&... args) const&& - -> decltype(!declval>()); -\end{itemdecl} +\pnum +\expects +\tcode{FD} shall meet the requirements of \oldconcept{MoveConstructible}. +For each $\tcode{T}_i$ in \tcode{BoundArgs}, +if $\tcode{T}_i$ is an object type, +$\tcode{T}_i$ shall meet the requirements of \oldconcept{MoveConstructible}. -\begin{itemdescr} \pnum -\effects -Equivalent to: -\begin{codeblock} -return !@\placeholdernc{INVOKE}@(std::move(fd), std::forward(args)...); // see \ref{func.require} -\end{codeblock} +\returns +A perfect forwarding call wrapper \tcode{g} +with call pattern \tcode{invoke(fd, bound_args..., call_args...)}. + +\pnum +\throws +Any exception thrown by +the initialization of the state entities of \tcode{g}\iref{func.def}. \end{itemdescr} \rSec2[func.bind]{Function object binders}% @@ -15353,7 +15402,7 @@ \item $\tcode{t}_i$ is the $i^\text{th}$ argument in the function parameter pack \tcode{bound_args}, \item $\tcode{td}_i$ is an lvalue of type $\tcode{TD}_i$ constructed from \tcode{std::forward<$\tcode{T}_i$>($\tcode{t}_i$)}, \item $\tcode{U}_j$ is the $j^\text{th}$ deduced type of the \tcode{UnBoundArgs\&\&...} parameter - of the forwarding call wrapper, and + of the argument forwarding call wrapper, and \item $\tcode{u}_j$ is the $j^\text{th}$ argument associated with $\tcode{U}_j$. \end{itemize} @@ -15376,7 +15425,7 @@ as specified below, shall be neither \tcode{volatile} nor \tcode{const volatile}. \pnum\returns -A forwarding call wrapper \tcode{g}\iref{func.require}. +An argument forwarding call wrapper \tcode{g}\iref{func.require}. The effect of \tcode{g($\tcode{u}_1$, $\tcode{u}_2$, $\dotsc$, $\tcode{u}_M$)} shall be \begin{codeblock} @@ -15384,7 +15433,7 @@ \end{codeblock} where the values and types of the bound arguments $\tcode{v}_1$, $\tcode{v}_2$, $\dotsc$, $\tcode{v}_N$ are determined as specified below. -The copy constructor and move constructor of the forwarding call wrapper shall throw an +The copy constructor and move constructor of the argument forwarding call wrapper shall throw an exception if and only if the corresponding constructor of \tcode{FD} or of any of the types $\tcode{TD}_i$ throws an exception. @@ -15419,7 +15468,7 @@ \pnum \returns -A forwarding call wrapper \tcode{g}\iref{func.require}. +An argument forwarding call wrapper \tcode{g}\iref{func.require}. The effect of \tcode{g($\tcode{u}_1$, $\tcode{u}_2$, $\dotsc$, $\tcode{u}_M$)} shall be \begin{codeblock} @@ -15427,7 +15476,7 @@ \end{codeblock} where the values and types of the bound arguments $\tcode{v}_1$, $\tcode{v}_2$, $\dotsc$, $\tcode{v}_N$ are determined as specified below. -The copy constructor and move constructor of the forwarding call wrapper shall throw an +The copy constructor and move constructor of the argument forwarding call wrapper shall throw an exception if and only if the corresponding constructor of \tcode{FD} or of any of the types $\tcode{TD}_i$ throws an exception. From dafbb9445f11ad231abbf72028c29b6dd77c9334 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Mon, 19 Nov 2018 09:44:01 +0100 Subject: [PATCH 2/3] [func.not_fn,func.bind_front] Some clarifications 'a target object' -> 'the target object' render 'initializer' as a grammar term and add a cross-reference to dcl.init add cross-references to expr.call --- source/utilities.tex | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/source/utilities.tex b/source/utilities.tex index b90bb4b1a7..ab3a89a959 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -15247,11 +15247,12 @@ \begin{itemize} \item \tcode{g} is a value of the result of a \tcode{not_fn} invocation, \item \tcode{FD} is the type \tcode{decay_t}, -\item \tcode{fd} is a target object of \tcode{g}\iref{func.def} +\item \tcode{fd} is the target object of \tcode{g}\iref{func.def} of type \tcode{FD}, - initialized with initializer \tcode{(std::forward(f))}, + initialized with + the \grammarterm{initializer} \tcode{(std::forward(f\brk{}))}\iref{dcl.init}, \item \tcode{call_args} is an argument pack - used in a function call expression of \tcode{g}. + used in a function call expression\iref{expr.call} of \tcode{g}. \end{itemize} \pnum @@ -15287,17 +15288,19 @@ \begin{itemize} \item \tcode{g} is a value of the result of a \tcode{bind_front} invocation, \item \tcode{FD} is the type \tcode{decay_t}, -\item \tcode{fd} is a target object of \tcode{g}\iref{func.def} - of type \tcode{FD} initialized with initializer \tcode{(std::forward(f))}, +\item \tcode{fd} is the target object of \tcode{g}\iref{func.def} + of type \tcode{FD} initialized with + the \grammarterm{initializer} \tcode{(std::forward(\brk{}f))}\iref{dcl.init}, \item \tcode{BoundArgs} is a pack of types equivalent to \tcode{\placeholdernc{DECAY_UNWRAP}(Args)...}, \item \tcode{bound_args} is a pack of bound argument entities of \tcode{g}\iref{func.def} of types \tcode{BoundArgs...}, - initialized with initializers \tcode{(std::forward(args))...}, + initialized with + \grammarterm{initializer}{s} \tcode{(std::forward(args))...}, respectively, \item \tcode{call_args} is an argument pack used in - a function call expression of \tcode{g}, + a function call expression\iref{expr.call} of \tcode{g}, \end{itemize} where \tcode{\placeholdernc{DECAY_UNWRAP}(T)} is determined as follows: Let \tcode{U} be \tcode{decay_t}. From e6b8936788decfb6c29ea527f1195ec3679a1195 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Mon, 26 Nov 2018 00:17:04 -0800 Subject: [PATCH 3/3] [func.def] Simplify "references to functions and references to objects" to simply "references". --- source/utilities.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/utilities.tex b/source/utilities.tex index ab3a89a959..5306b67d1e 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -13873,7 +13873,7 @@ \pnum A call wrapper type may additionally hold -a sequence of objects, references to functions, and references to objects, +a sequence of objects and references that may be passed as arguments to the target object. These entities are collectively referred to as \defnx{bound argument entities}{bound argument entity}.