From dbbeeba20bcbdfd9bff06e36064374a215005bca Mon Sep 17 00:00:00 2001 From: Alisdair Meredith Date: Wed, 5 Nov 2025 17:05:31 -1000 Subject: [PATCH] P3920R0 Wording for NB comment resolution on trivial relocation Also fixes NB BDS 2-034, CA-133, CA-136, CA-137, CN 6.9.1p9, FR 002-025, US 9-024, US 10-023, US 44-082, US 45-081, US 46-085, US 47-084, and US 73-131 (C++26 CD). --- source/basic.tex | 9 --- source/classes.tex | 95 ++--------------------------- source/compatibility.tex | 27 --------- source/expressions.tex | 4 +- source/lex.tex | 23 +++---- source/lib-intro.tex | 14 ----- source/memory.tex | 126 --------------------------------------- source/meta.tex | 39 ------------ source/preprocessor.tex | 1 - source/support.tex | 2 - 10 files changed, 17 insertions(+), 323 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index 78a03978cd..4ed6c59142 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -5230,15 +5230,6 @@ Scalar types, trivially copyable class types\iref{class.prop}, arrays of such types, and cv-qualified versions of these types are collectively called \defnadjx{trivially copyable}{types}{type}. -\label{term.trivially.relocatable.type}% -Scalar types, trivially relocatable class types\iref{class.prop}, -arrays of such types, and cv-qualified versions of these -types are collectively called \defnadjx{trivially relocatable}{types}{type}. -\label{term.replaceable.type}% -\indextext{replaceable!type|see{type, replaceable}}% -Cv-unqualified scalar types, replaceable class types\iref{class.prop}, and -arrays of such types are collectively called -\defnx{replaceable types}{type!replaceable}. \label{term.standard.layout.type}% Scalar types, standard-layout class types\iref{class.prop}, arrays of such types, and diff --git a/source/classes.tex b/source/classes.tex index 6f1e64c940..e6d90a886d 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -52,9 +52,7 @@ \begin{bnf} \nontermdef{class-property-specifier}\br - \keyword{final}\br - \keyword{trivially_relocatable_if_eligible}\br - \keyword{replaceable_if_eligible} + \keyword{final} \end{bnf} \begin{bnf} @@ -131,8 +129,7 @@ within a single \grammarterm{class-property-specifier-seq}. Whenever a \grammarterm{class-key} is followed by a \grammarterm{class-head-name}, -one of the identifiers \tcode{final}, \tcode{trivially_relocatable_if_eligible}, -or \tcode{replaceable_if_eligible}, and a colon or left brace, +the identifier \tcode{final}, and a colon or left brace, the identifier is interpreted as a \grammarterm{class-property-specifier}. \begin{example} \begin{codeblock} @@ -142,10 +139,8 @@ struct X { struct C { constexpr operator int() { return 5; } }; - struct B trivially_relocatable_if_eligible : C{}; - // OK, definition of nested class \tcode{B}, - // not declaration of a bit-field member - // \tcode{trivially_relocatable_if_eligible} + struct B final : C{}; // OK, definition of nested class \tcode{B}, + // not declaration of a bit-field member \tcode{final} }; \end{codeblock} \end{example} @@ -187,88 +182,6 @@ \item that has a trivial, non-deleted destructor\iref{class.dtor}. \end{itemize} -\pnum -A class \tcode{C} is \defn{default-movable} if - -\begin{itemize} -\item overload resolution for direct-initializing an object of type \tcode{C} -from an xvalue of type \tcode{C} selects a constructor that is a direct member -of \tcode{C} and is neither user-provided nor deleted, - -\item overload resolution for assigning to an lvalue of type \tcode{C} from an -xvalue of type \tcode{C} selects an assignment operator function that is a -direct member of \tcode{C} and is neither user-provided nor deleted, and - -\item \tcode{C} has a destructor that is neither user-provided nor deleted. -\end{itemize} - -\pnum -A class is \defn{eligible for trivial relocation} unless it -\begin{itemize} -\item has any virtual base classes, -\item has a base class that is not a trivially relocatable class, -\item has a non-static data member of an object type that is not of a -trivially relocatable type, or - -\item has a deleted destructor, -\end{itemize} -except that it is \impldef{whether an otherwise-eligible union having one or -more subobjects of polymorphic class type is eligible for trivial relocation} -whether an otherwise-eligible union having one or more subobjects of -polymorphic class type is eligible for trivial relocation. - -\pnum -A class \tcode{C} is a \defnadj{trivially relocatable}{class} -if it is eligible for trivial relocation and -\begin{itemize} -\item has the \tcode{trivially_relocatable_if_eligible} \grammarterm{class-property-specifier}, -\item is a union with no user-declared special member functions, or -\item is default-movable. -\end{itemize} - -\pnum -\begin{note} -A class with const-qualified or reference non-static data members can be -trivially relocatable. -\end{note} - -\pnum -A class \tcode{C} is \defn{eligible for replacement} unless -\begin{itemize} -\item it has a base class that is not a replaceable class, -\item it has a non-static data member that is not of a replaceable type, -\item overload resolution fails or selects a deleted constructor when -direct-initializing an object of type \tcode{C} from an xvalue of type -\tcode{C}\iref{dcl.init.general}, - -\item overload resolution fails or selects a deleted assignment operator -function when assigning to an lvalue of type \tcode{C} from an xvalue of type -\tcode{C}\iref{expr.assign,over.assign}, or - -\item it has a deleted destructor. -\end{itemize} - -\indextext{replaceable!class|see{class, replaceable}}% -\pnum -A class \tcode{C} is a \defnx{replaceable class}{class!replaceable} if it is -eligible for replacement and -\begin{itemize} -\item has the \tcode{replaceable_if_eligible} \grammarterm{class-property-specifier}, -\item is a union with no user-declared special member functions, or -\item is default-movable. -\end{itemize} - -\pnum -\begin{note} -Accessibility of the special member functions is not considered when -establishing trivial relocatability or replaceability. -\end{note} - -\pnum -\begin{note} -Not all trivially copyable classes are trivially relocatable or replaceable. -\end{note} - \pnum A class \tcode{S} is a \defnadj{standard-layout}{class} if it: \begin{itemize} diff --git a/source/compatibility.tex b/source/compatibility.tex index d0b6bcec85..265c64152f 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -107,22 +107,6 @@ \rSec2[diff.cpp23.dcl.dcl]{\ref{dcl}: declarations} -\diffref{dcl.decl.general} -\change -Introduction of \tcode{trivially_relocatable_if_eligible} and -\tcode{replaceable_if_eligible} as identifiers with special meaning\iref{lex.name}. -\rationale -Support declaration of trivially relocatable and replaceable types\iref{class.prop}. -\effect -Valid \CppXXIII{} code can become ill-formed. -\begin{example} -\begin{codeblock} -struct C {}; -struct C replaceable_if_eligible {}; // was well-formed (new variable \tcode{replaceable_if_eligible}) - // now ill-formed (redefines \tcode{C}) -\end{codeblock} -\end{example} - \diffref{dcl.init.list} \change Pointer comparisons between \tcode{initializer_list} objects' backing arrays @@ -262,17 +246,6 @@ Valid \CppXXIII{} code that \tcode{\#include}{s} headers with these names may be invalid in this revision of \Cpp{}. -\diffref{res.on.macro.definitions} -\change -Additional restrictions on macro names. -\rationale -Avoid hard to diagnose or non-portable constructs. -\effect -Names of special identifiers may not be used as macro names. -Valid \CppXXIII{} code that defines \tcode{replaceable_if_eligible} or -\tcode{trivially_relocatable_if_eligible} as macros is invalid -in this revision of \Cpp{}. - \rSec2[diff.cpp23.mem]{\ref{mem}: memory management library} \diffref{c.malloc} diff --git a/source/expressions.tex b/source/expressions.tex index 2bfc4057de..9e9edf7335 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -2231,9 +2231,7 @@ other than by changing: \begin{itemize} \item the size and/or alignment of the closure type, -\item whether the closure type is trivially copyable\iref{class.prop}, -\item whether the closure type is trivially relocatable\iref{class.prop}, -\item whether the closure type is replaceable\iref{class.prop}, or +\item whether the closure type is trivially copyable\iref{class.prop}, or \item whether the closure type is a standard-layout class\iref{class.prop}. \end{itemize} diff --git a/source/lex.tex b/source/lex.tex index 8005b33374..583a5e250f 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -966,8 +966,6 @@ \indextext{\idxcode{final}}% \indextext{\idxcode{module}}% \indextext{\idxcode{override}}% -\indextext{\idxcode{replaceable_if_eligible}}% -\indextext{\idxcode{trivially_relocatable_if_eligible}}% The identifiers in \tref{lex.name.special} have a special meaning when appearing in a certain context. When referred to in the grammar, these identifiers are used explicitly rather than using the \grammarterm{identifier} grammar production. @@ -976,15 +974,18 @@ token as a regular \grammarterm{identifier}. \begin{multicolfloattable}{Identifiers with special meaning}{lex.name.special} -{llll} -\keyword{final} \\ -\keyword{override} \\\columnbreak -\keyword{import} \\ -\keyword{module} \\\columnbreak -\keyword{post} \\ -\keyword{pre} \\\columnbreak -\keyword{replaceable_if_eligible} \\ -\keyword{trivially_relocatable_if_eligible} \\ +{llllll} +\keyword{final} \\ +\columnbreak +\keyword{import} \\ +\columnbreak +\keyword{module} \\ +\columnbreak +\keyword{override} \\ +\columnbreak +\keyword{post} \\ +\columnbreak +\keyword{pre} \\ \end{multicolfloattable} \pnum diff --git a/source/lib-intro.tex b/source/lib-intro.tex index 2958545e4a..6944a9147f 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -3850,20 +3850,6 @@ \ref{depr} is a trivially copyable class, a standard-layout class, or an implicit-lifetime class\iref{class.prop}. -\pnum -Unless explicitly stated otherwise, it is unspecified whether any class for -which trivial relocation (i.e., the effects of -\tcode{trivially_relocate}\iref{obj.lifetime}) would be semantically equivalent -to move-construction of the destination object followed by destruction of the -source object is a trivially relocatable class\iref{class.prop}. - -\pnum -Unless explicitly stated otherwise, it is unspecified whether a class \tcode{C} -is a replaceable class\iref{class.prop} if assigning an xvalue \tcode{a} of -type \tcode{C} to an object \tcode{b} of type \tcode{C} is semantically -equivalent to destroying \tcode{b} and then constructing from \tcode{a} in -\tcode{b}'s place. - \rSec3[protection.within.classes]{Protection within classes} \pnum diff --git a/source/memory.tex b/source/memory.tex index 1b455e868b..81e72f6b69 100644 --- a/source/memory.tex +++ b/source/memory.tex @@ -105,10 +105,6 @@ template const volatile T* start_lifetime_as_array(const volatile void* p, // freestanding size_t n) noexcept; - template - T* trivially_relocate(T* first, T* last, T* result); // freestanding - template - constexpr T* relocate(T* first, T* last, T* result); // freestanding // \ref{allocator.tag}, allocator argument tag struct allocator_arg_t { explicit allocator_arg_t() = default; }; // freestanding @@ -1135,128 +1131,6 @@ a pointer that compares equal to \tcode{p}\iref{expr.eq}. \end{itemdescr} -\indexlibraryglobal{trivially_relocate}% -\begin{itemdecl} -template - T* trivially_relocate(T* first, T* last, T* result); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\mandates -\tcode{is_trivially_relocatable_v \&\& !is_const_v} is \tcode{true}. -\tcode{T} is not an array of unknown bound. - -\pnum -\expects -\begin{itemize} -\item - \range{first}{last} is a valid range. -\item - \range{result}{result + (last - first)} denotes a region of storage that - is a subset of the region reachable through \tcode{result}\iref{basic.compound} - and suitably aligned for the type \tcode{T}. -\item - No element in the range \range{first}{last} is a potentially-overlapping subobject. -\end{itemize} - -\pnum -\ensures -No effect if \tcode{result == first} is \tcode{true}. -Otherwise, the range denoted by \range{result}{result + (last - first)} -contains objects (including subobjects) whose lifetime has begun and whose -object representations are the original object representations of the -corresponding objects in the source range \range{first}{last} except -for any parts of the object representations used by the implementation to -represent type information\iref{intro.object}. If any of the objects has -union type, its active member is the same as that of the corresponding object -in the source range. If any of the aforementioned objects has a non-static -data member of reference type, that reference refers to the same entity as -does the corresponding reference in the source range. The lifetimes of the -original objects in the source range have ended. - -\pnum -\returns -\tcode{result + (last - first)}. - -\pnum -\throws -Nothing. - -\pnum -\complexity -Linear in the length of the source range. - -\pnum -\remarks -The destination region of storage is considered reused\iref{basic.life}. -No constructors or destructors are invoked. - -\begin{note} -Overlapping ranges are supported. -\end{note} -\end{itemdescr} - -\indexlibraryglobal{relocate}% -\begin{itemdecl} -template - constexpr T* relocate(T* first, T* last, T* result); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\mandates -\tcode{is_nothrow_relocatable_v \&\& !is_const_v} is \tcode{true}. -\tcode{T} is not an array of unknown bound. - -\pnum -\expects -\begin{itemize} -\item - \range{first}{last} is a valid range. -\item - \range{result}{result + (last - first)} denotes a region of storage that is - a subset of the region reachable through \tcode{result}\iref{basic.compound} - and suitably aligned for the type \tcode{T}. -\item - No element in the range \range{first}{last} is a potentially-overlapping - subobject. -\end{itemize} - -\pnum -\effects -\begin{itemize} -\item - If \tcode{result == first} is \tcode{true}, no effect; -\item - otherwise, if not called during constant evaluation and - \tcode{is_trivially_relocatable_v} is \tcode{true}, then has - effects equivalent to: \tcode{trivially_relocate(first, last, result);} -\item - otherwise, for each integer \tcode{i} in \range{0}{last - first}, - \begin{itemize} - \item - if \tcode{T} is an array type, equivalent to: - \tcode{relocate(begin(first[i]), end(first[i]), *start_lifetime_as(result + i));} - \item - otherwise, equivalent to: - \tcode{construct_at(result + i, std::move(first[i])); destroy_at(first + i);} - \end{itemize} -\end{itemize} - -\pnum -\returns -\tcode{result + (last - first)}. - -\pnum -\throws -Nothing. - -\begin{note} -Overlapping ranges are supported. -\end{note} -\end{itemdescr} - \rSec2[allocator.tag]{Allocator argument tag} \indexlibraryglobal{allocator_arg_t}% diff --git a/source/meta.tex b/source/meta.tex index f0bd37f53d..32b3629d67 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -210,8 +210,6 @@ template struct is_const; template struct is_volatile; template struct is_trivially_copyable; - template struct is_trivially_relocatable; - template struct is_replaceable; template struct is_standard_layout; template struct is_empty; template struct is_polymorphic; @@ -263,7 +261,6 @@ template struct is_nothrow_swappable; template struct is_nothrow_destructible; - template struct is_nothrow_relocatable; template struct is_implicit_lifetime; @@ -460,8 +457,6 @@ constexpr bool @\libglobal{is_volatile_v}@ = is_volatile::value; template constexpr bool @\libglobal{is_trivially_copyable_v}@ = is_trivially_copyable::value; - template - constexpr bool @\libglobal{is_trivially_relocatable_v}@ = is_trivially_relocatable::value; template constexpr bool @\libglobal{is_standard_layout_v}@ = is_standard_layout::value; template @@ -544,12 +539,8 @@ constexpr bool @\libglobal{is_nothrow_swappable_v}@ = is_nothrow_swappable::value; template constexpr bool @\libglobal{is_nothrow_destructible_v}@ = is_nothrow_destructible::value; - template - constexpr bool @\libglobal{is_nothrow_relocatable_v}@ = is_nothrow_relocatable::value; template constexpr bool @\libglobal{is_implicit_lifetime_v}@ = is_implicit_lifetime::value; - template - constexpr bool @\libglobal{is_replaceable_v}@ = is_replaceable::value; template constexpr bool @\libglobal{has_virtual_destructor_v}@ = has_virtual_destructor::value; template @@ -1135,20 +1126,6 @@ \tcode{remove_all_extents_t} shall be a complete type or \cv{}~\keyword{void}. \\ \rowsep -\indexlibraryglobal{is_trivially_relocatable}% -\tcode{template}\br - \tcode{struct is_trivially_relocatable;} & - \tcode{T} is a trivially relocatable type\iref{basic.types.general} & - \tcode{remove_all_extents_t} shall be a complete type or - \cv{}~\keyword{void}. \\ \rowsep - -\indexlibraryglobal{is_replaceable}% -\tcode{template}\br - \tcode{struct is_replaceable;} & - \tcode{T} is a replaceable type\iref{basic.types.general} & - \tcode{remove_all_extents_t} shall be a complete type or - \cv{}~\keyword{void}. \\ \rowsep - \indexlibraryglobal{is_standard_layout}% \tcode{template}\br \tcode{struct is_standard_layout;} & @@ -1517,16 +1494,6 @@ \cv{}~\keyword{void}, or an array of unknown bound. \\ \rowsep -\indexlibraryglobal{is_nothrow_relocatable}% -\tcode{template}\br - \tcode{struct is_nothrow_relocatable;} & - \tcode{is_trivially_relocatable_v ||} - \tcode{(is_nothrow_move_constructible_v<} - \tcode{remove_all_extents_t> \&\& is_nothrow_destructible_v<} - \tcode{remove_all_extents_t>)} & - \tcode{remove_all_extents_t} shall be a complete type or - \cv{}~\keyword{void}. \\ \rowsep - \indexlibraryglobal{is_implicit_lifetime}% \tcode{template}\br \tcode{struct is_implicit_lifetime;} & @@ -3152,8 +3119,6 @@ consteval bool is_const_type(info type); consteval bool is_volatile_type(info type); consteval bool is_trivially_copyable_type(info type); - consteval bool is_trivially_relocatable_type(info type); - consteval bool is_replaceable_type(info type); consteval bool is_standard_layout_type(info type); consteval bool is_empty_type(info type); consteval bool is_polymorphic_type(info type); @@ -3207,7 +3172,6 @@ consteval bool is_nothrow_swappable_type(info type); consteval bool is_nothrow_destructible_type(info type); - consteval bool is_nothrow_relocatable_type(info type); consteval bool is_implicit_lifetime_type(info type); @@ -6757,8 +6721,6 @@ consteval bool @\libglobal{is_const_type}@(info type); consteval bool @\libglobal{is_volatile_type}@(info type); consteval bool @\libglobal{is_trivially_copyable_type}@(info type); -consteval bool @\libglobal{is_trivially_relocatable_type}@(info type); -consteval bool @\libglobal{is_replaceable_type}@(info type); consteval bool @\libglobal{is_standard_layout_type}@(info type); consteval bool @\libglobal{is_empty_type}@(info type); consteval bool @\libglobal{is_polymorphic_type}@(info type); @@ -6812,7 +6774,6 @@ consteval bool @\libglobal{is_nothrow_swappable_type}@(info type); consteval bool @\libglobal{is_nothrow_destructible_type}@(info type); -consteval bool @\libglobal{is_nothrow_relocatable_type}@(info type); consteval bool @\libglobal{is_implicit_lifetime_type}@(info type); diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 0822ddd91b..ac67fd195a 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -2398,7 +2398,6 @@ \defnxname{cpp_template_parameters} & \tcode{202502L} \\ \rowsep \defnxname{cpp_template_template_args} & \tcode{201611L} \\ \rowsep \defnxname{cpp_threadsafe_static_init} & \tcode{200806L} \\ \rowsep -\defnxname{cpp_trivial_relocatability} & \tcode{202502L} \\ \rowsep \defnxname{cpp_trivial_union} & \tcode{202502L} \\ \rowsep \defnxname{cpp_unicode_characters} & \tcode{200704L} \\ \rowsep \defnxname{cpp_unicode_literals} & \tcode{200710L} \\ \rowsep diff --git a/source/support.tex b/source/support.tex index c6929d58ff..2cc5f8cdee 100644 --- a/source/support.tex +++ b/source/support.tex @@ -860,8 +860,6 @@ #define @\defnlibxname{cpp_lib_transformation_trait_aliases}@ 201304L // freestanding, also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_transparent_operators}@ 201510L // freestanding, also in \libheader{memory}, \libheader{functional} -#define @\defnlibxname{cpp_lib_trivially_relocatable}@ 202502L - // freestanding, also in \libheader{memory}, \libheader{type_traits} #define @\defnlibxname{cpp_lib_tuple_element_t}@ 201402L // freestanding, also in \libheader{tuple} #define @\defnlibxname{cpp_lib_tuple_like}@ 202311L // also in \libheader{utility}, \libheader{tuple}, \libheader{map}, \libheader{unordered_map}