From d34af4247ae8d6bc841ee0100eab2abe7bbe35b1 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 10 Feb 2022 09:04:03 +0100 Subject: [PATCH] P2255R2 A type trait to detect reference binding to temporary --- source/support.tex | 1 + source/utilities.tex | 90 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) diff --git a/source/support.tex b/source/support.tex index 9e116d660a..f3ac0cc663 100644 --- a/source/support.tex +++ b/source/support.tex @@ -674,6 +674,7 @@ #define @\defnlibxname{cpp_lib_ranges_to_container}@ 202202L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_zip}@ 202110L // also in \libheader{ranges}, \libheader{tuple}, \libheader{utility} #define @\defnlibxname{cpp_lib_raw_memory_algorithms}@ 201606L // also in \libheader{memory} +#define @\defnlibxname{cpp_lib_reference_from_temporary}@ 202202L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_remove_cvref}@ 201711L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_result_of_sfinae}@ 201210L // also in \libheader{functional}, \libheader{type_traits} #define @\defnlibxname{cpp_lib_robust_nonmodifying_seq_ops}@ 201304L // also in \libheader{algorithm} diff --git a/source/utilities.tex b/source/utilities.tex index f14fea67fa..800b309a6c 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -872,6 +872,11 @@ \begin{codeblock} !is_convertible_v || !is_convertible_v \end{codeblock} +This constructor is defined as deleted if +\tcode{reference_constructs_from_temporary_v} +is \tcode{true} or +\tcode{reference_constructs_from_temporary_v} +is \tcode{true}. \end{itemdescr} \indexlibraryctor{pair}% @@ -909,6 +914,12 @@ !is_convertible_v(@\exposid{FWD}@(p))), T1> || !is_convertible_v(@\exposid{FWD}@(p))), T2> \end{codeblock} +The constructor is defined as deleted if +\begin{codeblock} +reference_constructs_from_temporary_v(@\exposid{FWD}@(p)))> || +reference_constructs_from_temporary_v(@\exposid{FWD}@(p)))> +\end{codeblock} +is \tcode{true}. \end{itemdescr} \indexlibraryctor{pair}% @@ -936,6 +947,11 @@ \tcode{std::forward(x)}.) This form of construction, whereby constructor arguments for \tcode{first} and \tcode{second} are each provided in a separate \tcode{tuple} object, is called \defn{piecewise construction}. +\begin{note} +If a data member of \tcode{pair} is of reference type and +its initialization binds it to a temporary object, +the program is ill-formed\iref{class.base.init}. +\end{note} \end{itemdescr} \indexlibrarymember{operator=}{pair}% @@ -1731,6 +1747,11 @@ \begin{codeblock} !conjunction_v...> \end{codeblock} +This constructor is defined as deleted if +\begin{codeblock} +(reference_constructs_from_temporary_v || ...) +\end{codeblock} +is \tcode{true}. \end{itemdescr} \indexlibraryctor{tuple}% @@ -1806,6 +1827,11 @@ \begin{codeblock} !(is_convertible_v(@\exposid{FWD}@(u))), Types> && ...) \end{codeblock} +The constructor is defined as deleted if +\begin{codeblock} +(reference_constructs_from_temporary_v(@\exposid{FWD}@(u)))> || ...) +\end{codeblock} +is \tcode{true}. \end{itemdescr} \indexlibraryctor{tuple}% @@ -1843,6 +1869,12 @@ !is_convertible_v(@\exposid{FWD}@(u))), @$\tcode{T}_0$@> || !is_convertible_v(@\exposid{FWD}@(u))), @$\tcode{T}_1$@> \end{codeblock} +The constructor is defined as deleted if +\begin{codeblock} +reference_constructs_from_temporary_v<@$\tcode{T}_0$@, decltype(get<0>(@\exposid{FWD}@(u)))> || +reference_constructs_from_temporary_v<@$\tcode{T}_1$@, decltype(get<1>(@\exposid{FWD}@(u)))> +\end{codeblock} +is \tcode{true}. \end{itemdescr} \indexlibraryctor{tuple}% @@ -2404,6 +2436,13 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\mandates +If \tcode{tuple_size_v>} is 1, +then +\tcode{reference_constructs_from_temporary_v(declval()))>} +is \tcode{false}. + \pnum \effects Given the exposition-only function: @@ -16393,6 +16432,11 @@ if \tcode{R} is \cv{}~\keyword{void}, otherwise \tcode{\placeholdernc{INVOKE}(f, t$_1$, t$_2$, $\dotsc$, t$_N$)} implicitly converted to \tcode{R}. +If +\tcode{reference_converts_from_temporary_v} +is \tcode{true}, +\tcode{\placeholdernc{INVOKE}(f, t$_1$, t$_2$, $\dotsc$, t$_N$)} +is ill-formed. \pnum \indextext{call wrapper}% @@ -19554,6 +19598,9 @@ template struct has_unique_object_representations; + template struct reference_constructs_from_temporary; + template struct reference_converts_from_temporary; + // \ref{meta.unary.prop.query}, type property queries template struct alignment_of; template struct rank; @@ -19826,6 +19873,12 @@ template inline constexpr bool has_unique_object_representations_v = has_unique_object_representations::value; + template + inline constexpr bool @\libglobal{reference_constructs_from_temporary_v}@ + = reference_constructs_from_temporary::value; + template + inline constexpr bool @\libglobal{reference_converts_from_temporary_v}@ + = reference_converts_from_temporary::value; // \ref{meta.unary.prop.query}, type property queries template @@ -20081,6 +20134,24 @@ in the context of the corresponding definition notwithstanding the restrictions of~\ref{declval}. +\pnum +For the purpose of defining the templates in this subclause, +let \tcode{\placeholdernc{VAL}} for some type \tcode{T} be +an expression defined as follows: +\begin{itemize} +\item +If \tcode{T} is a reference or function type, +\tcode{\placeholdernc{VAL}} is an expression +with the same type and value category as \tcode{declval()}. +\item +Otherwise, \tcode{\placeholdernc{VAL}} is a prvalue +that initially has type \tcode{T}. +\begin{note} +If \tcode{T} is cv-qualified, +the cv-qualification is subject to adjustment\iref{expr.type}. +\end{note} +\end{itemize} + \begin{libreqtab3b}{Type property predicates}{meta.unary.prop} \\ \topline \lhdr{Template} & \chdr{Condition} & \rhdr{Preconditions} \\ \capsep @@ -20492,6 +20563,25 @@ \tcode{T} shall be a complete type, \cv{}~\keyword{void}, or an array of unknown bound. \\ \rowsep +\indexlibraryglobal{reference_constructs_from_temporary}% +\tcode{template}\br + \tcode{struct reference_constructs_from_temporary;} & + \tcode{conjunction_v, is_constructible>} + is \tcode{true}, and + the initialization \tcode{T t(\exposidnc{VAL});} binds \tcode{t} to + a temporary object whose lifetime is extended\iref{class.temporary}. & + \tcode{T} and \tcode{U} shall be + complete types, \cv{}~\keyword{void}, or arrays of unknown bound. \\ \rowsep + +\indexlibraryglobal{reference_converts_from_temporary}% +\tcode{template}\br + \tcode{struct reference_converts_from_temporary;} & + \tcode{conjunction_v, is_convertible>} is \tcode{true}, + and the initialization \tcode{T t = \exposidnc{VAL};} binds \tcode{t} to + a temporary object whose lifetime is extended\iref{class.temporary}. & + \tcode{T} and \tcode{U} shall be + complete types, \cv{}~\keyword{void}, or arrays of unknown bound. \\ \rowsep + \end{libreqtab3b} \pnum