From 042938b65490383665ba3ac48bdcec472335a435 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Wed, 1 Apr 2026 00:11:43 +0200 Subject: [PATCH] P3961R1 Less double indirection in function_ref (RU-220) - Use code, not English, in definition of is-convertible-from-specialization --- source/support.tex | 2 +- source/utilities.tex | 57 +++++++++++++++++++++++++++++++++++++++----- 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/source/support.tex b/source/support.tex index 203a1bf45f..59c47137ea 100644 --- a/source/support.tex +++ b/source/support.tex @@ -711,7 +711,7 @@ #define @\defnlibxname{cpp_lib_freestanding_utility}@ 202306L // freestanding, also in \libheader{utility} #define @\defnlibxname{cpp_lib_freestanding_variant}@ 202311L // freestanding, also in \libheader{variant} #define @\defnlibxname{cpp_lib_fstream_native_handle}@ 202306L // also in \libheader{fstream} -#define @\defnlibxname{cpp_lib_function_ref}@ 202511L // freestanding, also in \libheader{functional} +#define @\defnlibxname{cpp_lib_function_ref}@ 202603L // freestanding, also in \libheader{functional} #define @\defnlibxname{cpp_lib_gcd_lcm}@ 201606L // freestanding, also in \libheader{numeric} #define @\defnlibxname{cpp_lib_generator}@ 202207L // also in \libheader{generator} #define @\defnlibxname{cpp_lib_generic_associative_lookup}@ 201304L // also in \libheader{map}, \libheader{set} diff --git a/source/utilities.tex b/source/utilities.tex index 09be66f705..6b93e893d7 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -13835,10 +13835,12 @@ \pnum Let \tcode{t} be an object of a type that is a specialization of -\tcode{function}, \tcode{copyable_function}, or \tcode{move_only_function}, +\tcode{function}, \tcode{copyable_function}, \tcode{move_only_function}, +or \tcode{function_ref}, such that the target object \tcode{x} of \tcode{t} has a type that is a specialization of -\tcode{function}, \tcode{copyable_function}, or \tcode{move_only_function}. +\tcode{function}, \tcode{copyable_function}, \tcode{move_only_function}, +or \tcode{function_ref}. Each argument of the invocation of \tcode{x} evaluated as part of the invocation of \tcode{t} may alias an argument in the same position in the invocation of \tcode{t} that @@ -15253,6 +15255,25 @@ \end{codeblock} \end{itemdescr} +\indextext{function_ref::is-convertible-from-specialization@\tcode{function_ref::\exposid{is-convertible-from-\brk{}specialization}}}% +\begin{itemdecl} +template + static constexpr bool @\exposid{is-convertible-from-specialization}@ = @\seebelow@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +If \tcode{F} denotes a specialization +\tcode{function_ref} +for some placeholders \cvqual{cv2} and \placeholder{noex2}, +\tcode{\exposid{is-convertible-from-specialization}} is equal to: +\begin{codeblock} +is_convertible_v && +is_convertible_v. +\end{codeblock} +Otherwise, \tcode{\exposid{is-convertible-from-specialization}} is \tcode{false}. +\end{itemdescr} + \indexlibraryctor{function_ref}% \begin{itemdecl} template function_ref(F* f) noexcept; @@ -15300,13 +15321,37 @@ \pnum \effects -Initializes -\exposid{bound-entity} with \tcode{addressof(f)}, and +If \tcode{\exposid{is-convertible-from-specialization}>} +is \tcode{false}, +initializes +\exposid{bound-en\-tity} with \tcode{addressof(f)}, and \exposid{thunk-ptr} with the address of a function \tcode{\placeholder{thunk}} such that -\tcode{\placeholder{thunk}(\exposid{bound-entity}, \placeholder{call-args}...)} +\tcode{\placeholder{thunk}(\exposid{bound-\brk{}entity}, \placeholder{call-args}...)} is expression-equivalent\iref{defns.expression.equivalent} to \tcode{invoke_r(static_cast<\cv{} T\&>(f), \placeholder{call-args}...)}. +Otherwise, initializes \exposid{bound-entity} +with the value of \tcode{f.\exposid{bound-entity}} and +\exposid{thunk-\brk{}ptr} with the value of \tcode{f.\exposid{thunk-ptr}}. + +\pnum +\remarks +If \tcode{remove_cvref_t} is a specialization of \tcode{function_ref}, +an implementation may initialize \exposid{bound-entity} +with the value of \tcode{f.\exposid{bound-entity}} and \exposid{thunk-ptr} +with the value of \tcode{f.\exposid{thunk-ptr}}. +\begin{example} +\begin{codeblock} +void f1(std::string); +void f2(std::string); + +function_ref r1(&f1); +function_ref r2(r1); +r2(""); // \tcode{f1} is invoked +r1 = &f2; +r2(""); // it is unspecified if \tcode{f1} or \tcode{f2} is invoked +\end{codeblock} +\end{example} \end{itemdescr} \indexlibraryctor{function_ref}% @@ -15417,7 +15462,7 @@ \pnum \constraints \begin{itemize} -\item \tcode{T} is not the same type as \tcode{function_ref}, +\item \tcode{\exposid{is-convertible-from-specialization}} is \tcode{false}, \item \tcode{is_pointer_v} is \tcode{false}, and \item \tcode{T} is not a specialization of \tcode{constant_arg_t}. \end{itemize}