<html>
<head>
<title>P3247R0: Deprecate the notion of trivial types</title>

<style type="text/css">
  ins { text-decoration:none; font-weight:bold; background-color:#A0FFA0 }
  .new { text-decoration:none; font-weight:bold; background-color:#D0FFD0 }
  del { text-decoration:line-through; background-color:#FFA0A0 }  
  .del { text-decoration:line-through; background-color:#FFC0C0 }  
  strong { font-weight: inherit; color: #2020ff }
  table, td, th { border: 1px solid black; border-collapse:collapse; padding: 5px }
</style>
</head>

<body>
ISO/IEC JTC1 SC22 WG21 P3247R0<br/>
Jens Maurer &lt;Jens.Maurer@gmx.net><br/>
Target audience: LEWG, CWG<br/>
2024-04-16<br/>

<h1>P3247R0: Deprecate the notion of trivial types</h1>

<h2>Introduction</h2>

<p>
The core language defines "trivial types", and in particular, trivial
class types, even though that concept is used mainly for the
definition of the library type trait <TT>is_trivial</TT>.  This
proposal deprecates the type trait <TT>is_trivial</TT> and moves the
definition of "trivial type" next to the new location of the
specification of the type trait.
</p>

<p>
This proposal follows the footsteps of "POD", deprecated with
<A HREF="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0767r1.html">P0767R1</A> (November, 2017).

<p>
This proposal partially addresses
<A HREF="https://cplusplus.github.io/CWG/issues/1808.html">core issue 1808</A>.
</p>


<h2>Wording changes</h2>

<p>Remove from 6.9.1 [basic.types.general] paragraph 9:</p>

<blockquote>
[...] <del>Scalar types, trivial class types (11.2 [class.prop]),
arrays of such types, and cv-qualified versions of these types are
collectively called trivial types.</del> [...]

<p>Change in 11.2 [class.prop] paragraph 2:</p>

<blockquote>
<del>A trivial class is a class that is trivially copyable and has one
or more eligible default constructors (11.4.5.2), all of which are
trivial.  [Note 1: In particular, a trivially copyable or trivial
class does not have virtual functions or virtual base classes. — end
note] </del>
</blockquote>

<p>Change in 11.2 [class.prop] paragraph 7:</p>

<blockquote>
[Example 2 :
<pre>
struct N {   // neither <del>trivial</del> <ins>trivially copyable</ins> nor standard-layout
  int i;
  int j;
  virtual ~N();
};

struct T {  // <del>trivial</del> <ins>trivially copyable</ins> but not standard-layout
  int i;
private:
  int j;
};

struct SL {  // standard-layout but not <del>trivial</del> <ins>trivially copyable</ins>
  int i;
  int j;
  ~SL();
};

struct POD {  // both <del>trivial</del> <ins>trivially copyable</ins> and standard-layout
  int i;
  int j;
};
</pre>
— end example]
</blockquote>

<p>Change in 11.9.5 [class.cdtor] paragraph 1:</p>

<blockquote>
<pre>
extern X xobj;
int* p3 = &xobj.i;    // OK, X <del>is a trivial class</del> <ins>has no non-trivial constructors</ins>
X xobj;
</pre>
</blockquote>

<p>Remove from 23.3.5.4 [meta.unary.prop]:</p>

<blockquote>
<table>
<tr class="del">
<td>
<pre>
template&lt;class T>
struct is_trivial;
</pre>
</td>
<td>
<TT>T</TT> is a trivial type (6.9.1 [basic.types.general])
</td>
<td>
<TT>remove_all_extents_t&lt;T></TT> shall be a complete type
or <I>cv</I> <TT>void</TT>.
</td>
</tr>
</table>
</blockquote>

<p>Change in 24.7.3.4.4 [mdspan.layout.policy.overview] paragraphs 1 and 2:</p>

<blockquote>
<p>Each of <TT>layout_left</TT>, <TT>layout_right</TT>,
and <TT>layout_stride</TT> <ins>, as well as each specialization
of <TT>layout_left_padded</TT> and <TT>layout_right_padded</TT>,</ins>
meets the layout mapping policy requirements and is
a <del>trivial</del> <ins>trivially copyable</ins> type.
<ins>Furthermore, default-initialization of an object of such a type
invokes a trivial default constructor</ins>.
</p>

<p class="del">Each specialization of layout_left_padded and
layout_right_padded meets the layout mapping policy requirements and
is a trivial type.
</blockquote>

<p>Change in D.14 [depr.meta.types]:</p>

<blockquote>
<pre>
namespace std {
<ins>  template&lt;class T> struct is_trivial;
  template&lt;class T> constexpr bool is_trivial_v = is_trivial&lt;T>::value;</ins>
  template&lt;class T> struct is_pod;
  template&lt;class T> constexpr bool is_pod_v = is_pod&lt;T>::value;
...
}
</pre>

<p>The behavior of a program...</p>

<p class="new">A <I>trivial class</I> is a class that is trivially
copyable and <strong>where default-initialization of an object of such
a class type invokes a trivial default constructor</strong> (11.4.5.2
[class.default.ctor]). [Note: In particular, a trivial class does not
have virtual functions or virtual base classes. — end note]
A <I>trivial type</I> is a scalar type, a trivial class, an array of
such a type, or a cv-qualified version of one of these types.
</p>

<p>A POD class is a class that ...</p>

<pre class="new">
  template&lt;class T> struct is_trivial;
</pre>

<p class="new">Preconditions: <TT>remove_all_extents_t&lt;T></TT>
shall be a complete type or <I>cv</I> <TT>void</TT>.</p>

<p class="new">Remarks: <TT>is_trivial&lt;T></TT> is a
Cpp17UnaryTypeTrait (21.3.2 [meta.rqmts]) with a base characteristic
of <TT>true_type</TT> if <TT>T</TT> is a trivial type,
and <TT>false_type</TT> otherwise.
</p>

<p class="new">[Note: It is unspecified whether a closure type
(7.5.5.2 [expr.prim.lambda.closure]) is a trivial type. — end
note]</p>

<pre>
  template&lt;class T> struct is_pod;
</pre>

</blockquote>

</body>
</html>
