<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 3133: Modernizing numeric type requirements</title>
<meta property="og:title" content="Issue 3133: Modernizing numeric type requirements">
<meta property="og:description" content="C++ library issue. Status: C++20">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue3133.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#C++20">C++20</a> status.</em></p>
<h3 id="3133"><a href="lwg-defects.html#3133">3133</a>. Modernizing numeric type requirements</h3>
<p><b>Section:</b> 29.2 <a href="https://wg21.link/numeric.requirements">[numeric.requirements]</a> <b>Status:</b> <a href="lwg-active.html#C++20">C++20</a>
 <b>Submitter:</b> Tim Song <b>Opened:</b> 2018-07-05 <b>Last modified:</b> 2021-02-25</p>
<p><b>Priority: </b>0
</p>
<p><b>View all other</b> <a href="lwg-index.html#numeric.requirements">issues</a> in [numeric.requirements].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++20">C++20</a> status.</p>
<p><b>Discussion:</b></p>
<p>
29.2 <a href="https://wg21.link/numeric.requirements">[numeric.requirements]</a> contains some very old wording that hasn't been changed since C++98
except for issue <a href="lwg-defects.html#2699" title="Missing restriction in [numeric.requirements] (Status: C++17)">2699</a><sup><a href="https://cplusplus.github.io/LWG/issue2699" title="Latest snapshot">(i)</a></sup>. As a result, it is at once over- and under-restrictive. For example:
</p>
<ul>
  <li>It requires a class to have various member functions, but not that said member functions be actually
      callable (non-ambiguous, non-deleted) or called by the applicable operations;</li>
  <li>It doesn't disallow function or array types;</li>
  <li>It disallows <i>ref-qualifier</i>s on the assignment operator by restricting the signature;</li>
  <li>It bans unary <code>operator&amp;</code> for class types, but not enumeration types; and</li>
  <li>It tries to impose semantic equivalence requirements on <code>T</code>'s special member functions, but
      doesn't require that copying produces an equivalent value to the original.</li>
</ul>
<p>
We can significantly clean up this wording by using the existing named requirements. For ease of review,
the following table provides a side-by-side comparison of the current and proposed wording.
</p>
<table border="1">
<tr style="text-align:center">
  <th>Before</th>
  <th>After</th>
</tr>
<tr>
  <td>A C++ program shall instantiate these components only with a type <code>T</code>
      that satisfies the following requirements: [<i>Footnote</i> &hellip; ]</td>
  <td>A C++ program shall instantiate these components only with a <ins>cv-unqualified object</ins> type <code>T</code>
      that satisfies the <ins><i>Cpp17DefaultConstructible</i>, <i>Cpp17CopyConstructible</i>, <i>Cpp17CopyAssignable</i>,
      and <i>Cpp17Destructible</i></ins><del>following</del> requirements<ins> (16.4.4.2 <a href="https://wg21.link/utility.arg.requirements">[utility.arg.requirements]</a>).</ins><del>:</del></td>
</tr>
<tr>
  <td>(1.1) &mdash; <code>T</code> is not an abstract class (it has no pure virtual member functions);</td>
  <td><i>Cpp17DefaultConstructible</i></td>
</tr>
<tr>
  <td>(1.2) &mdash; <code>T</code> is not a reference type; <br/>
      (1.3) &mdash; <code>T</code> is not cv-qualified; </td>
  <td>Implied by "cv-unqualified object type"</td>
</tr>
<tr>
  <td>(1.4) &mdash; If <code>T</code> is a class, it has a public default constructor;</td>
  <td><i>Cpp17DefaultConstructible</i></td>
</tr>
<tr>
  <td>(1.5) &mdash; If <code>T</code> is a class, it has a public copy constructor 
      with the signature <code>T::T(const T&amp;)</code>;</td>
  <td><i>Cpp17CopyConstructible</i></td>
</tr>
<tr>
  <td>(1.6) &mdash; If <code>T</code> is a class, it has a public destructor;</td>
  <td><i>Cpp17Destructible</i></td>
</tr>
<tr>
  <td>(1.7) &mdash; If <code>T</code> is a class, it has a public copy assignment operator whose signature is either
      <code>T&amp; T::operator=(const T&amp;)</code> or <code>T&amp; T::operator=(T);</code></td>
  <td><i>Cpp17CopyAssignable</i></td>
</tr>
<tr>
  <td>(1.8) &mdash; If <code>T</code> is a class,  its assignment operator, copy and default constructors, and destructor
      shall correspond to each other in the following sense:<br/>
      (1.8.1) &mdash; Initialization of raw storage using the copy constructor on the value of <code>T()</code>, however 
      obtained, is semantically equivalent to value-initialization of the same raw storage.<br/>
      (1.8.2) &mdash; Initialization of raw storage using the default constructor, followed by assignment, is 
      semantically equivalent to initialization of raw storage using the copy constructor.<br/>
      (1.8.3) &mdash; Destruction of an object, followed by initialization of its raw storage using the copy constructor,
      is semantically equivalent to assignment to the original object.<br/>
      [<i>Note:</i> [&hellip;] &mdash; <i>end note</i>]
  </td>
  <td>These requirements are implied by <i>Cpp17CopyConstructible</i> and <i>Cpp17CopyAssignable</i>'s requirement that 
      the value of the copy is equivalent to the source.
  </td>
</tr>
<tr>
  <td>(1.9) &mdash; If <code>T</code> is a class, it does not overload unary <code>operator&amp;</code>.</td>
  <td><i>omitted now that we have <code>std::addressof</code></i></td>
</tr>
</table>

<p><i>[2019-01-20 Reflector prioritization]</i></p>

<p>Set Priority to 0 and status to Tentatively Ready</p>


<p id="res-3133"><b>Proposed resolution:</b></p>
<p>
This wording is relative to the post-Rapperswil 2018 working draft.
</p>

<ol>
<li>
<p>
Edit 29.2 <a href="https://wg21.link/numeric.requirements">[numeric.requirements]</a> p1 as indicated, striking the entire bulleted list:
</p>
<blockquote>
<p>
-1- The <code>complex</code> and <code>valarray</code> components are parameterized by the type of information they contain and manipulate.
A C++ program shall instantiate these components only with a <ins>cv-unqualified object</ins> type <code>T</code>
that satisfies the <ins><i>Cpp17DefaultConstructible</i>, <i>Cpp17CopyConstructible</i>, <i>Cpp17CopyAssignable</i>,
and <i>Cpp17Destructible</i></ins><del>following</del> requirements<ins> (16.4.4.2 <a href="https://wg21.link/utility.arg.requirements">[utility.arg.requirements]</a>).</ins>
<del>:</del>[<i>Footnote:</i> &hellip; ]
</p>
<blockquote>
<p><del>(1.1) &mdash; <code>T</code> is not an abstract class (it has no pure virtual member functions);</del>
<p/>
<del>[&hellip;]</del>
<p/>
<del>(1.9) &mdash; If <code>T</code> is a class, it does not overload unary <code>operator&amp;</code>.</del>
</p>
</blockquote>
</blockquote>
</li>
<li>
<p>
Edit 29.6.2.4 <a href="https://wg21.link/valarray.access">[valarray.access]</a> p3-4 as indicated:
</p>
<blockquote>
<pre>
const T&amp;  operator[](size_t n) const;
T&amp; operator[](size_t n);
</pre>
<blockquote>
<p> 
-1- <i>Requires:</i> <code>n &lt; size()</code>.
<p/>
-2- <i>Returns:</i> [&hellip;]
<p/>
-3- <i>Remarks</i>: The expression <code><del>&amp;</del><ins>addressof(</ins>a[i+j]<ins>)</ins> ==
    <del>&amp;</del><ins>addressof(</ins>a[i]<ins>)</ins> + j</code> evaluates to <code>true</code> for all <code>size_t i</code>
    and <code>size_t j</code> such that <code>i+j &lt; a.size()</code>.
<p/>
-4- The expression <code><del>&amp;</del><ins>addressof(</ins>a[i]<ins>)</ins> !=
    <del>&amp;</del><ins>addressof(</ins>b[j]<ins>)</ins></code> evaluates to <code>true</code> for any two arrays <code>a</code> 
    and <code>b</code> and for any <code>size_t i</code> and <code>size_t j</code> such that <code>i &lt; a.size()</code> and <code>j &lt; b.size()</code>.
    [<i>Note:</i> [&hellip;] &mdash; <i>end note</i> ]
</p>
</blockquote>
</blockquote>
</li>
</ol>





</body>
</html>
