<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang xml:lang>
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="mpark/wg21" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  <meta name="dcterms.date" content="2021-06-12" />
  <title>Cleaning up integer-class types</title>
  <style>
      code{white-space: pre-wrap;}
      span.smallcaps{font-variant: small-caps;}
      span.underline{text-decoration: underline;}
      div.column{display: inline-block; vertical-align: top; width: 50%;}
      div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
      ul.task-list{list-style: none;}
      pre > code.sourceCode { white-space: pre; position: relative; }
      pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
      pre > code.sourceCode > span:empty { height: 1.2em; }
      code.sourceCode > span { color: inherit; text-decoration: inherit; }
      div.sourceCode { margin: 1em 0; }
      pre.sourceCode { margin: 0; }
      @media screen {
      div.sourceCode { overflow: auto; }
      }
      @media print {
      pre > code.sourceCode { white-space: pre-wrap; }
      pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
      }
      pre.numberSource code
        { counter-reset: source-line 0; }
      pre.numberSource code > span
        { position: relative; left: -4em; counter-increment: source-line; }
      pre.numberSource code > span > a:first-child::before
        { content: counter(source-line);
          position: relative; left: -1em; text-align: right; vertical-align: baseline;
          border: none; display: inline-block;
          -webkit-touch-callout: none; -webkit-user-select: none;
          -khtml-user-select: none; -moz-user-select: none;
          -ms-user-select: none; user-select: none;
          padding: 0 4px; width: 4em;
          color: #aaaaaa;
        }
      pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
      div.sourceCode
        {  background-color: #f6f8fa; }
      @media screen {
      pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
      }
      code span. { } /* Normal */
      code span.al { color: #ff0000; } /* Alert */
      code span.an { } /* Annotation */
      code span.at { } /* Attribute */
      code span.bn { color: #9f6807; } /* BaseN */
      code span.bu { color: #9f6807; } /* BuiltIn */
      code span.cf { color: #00607c; } /* ControlFlow */
      code span.ch { color: #9f6807; } /* Char */
      code span.cn { } /* Constant */
      code span.co { color: #008000; font-style: italic; } /* Comment */
      code span.cv { color: #008000; font-style: italic; } /* CommentVar */
      code span.do { color: #008000; } /* Documentation */
      code span.dt { color: #00607c; } /* DataType */
      code span.dv { color: #9f6807; } /* DecVal */
      code span.er { color: #ff0000; font-weight: bold; } /* Error */
      code span.ex { } /* Extension */
      code span.fl { color: #9f6807; } /* Float */
      code span.fu { } /* Function */
      code span.im { } /* Import */
      code span.in { color: #008000; } /* Information */
      code span.kw { color: #00607c; } /* Keyword */
      code span.op { color: #af1915; } /* Operator */
      code span.ot { } /* Other */
      code span.pp { color: #6f4e37; } /* Preprocessor */
      code span.re { } /* RegionMarker */
      code span.sc { color: #9f6807; } /* SpecialChar */
      code span.ss { color: #9f6807; } /* SpecialString */
      code span.st { color: #9f6807; } /* String */
      code span.va { } /* Variable */
      code span.vs { color: #9f6807; } /* VerbatimString */
      code span.wa { color: #008000; font-weight: bold; } /* Warning */
      code.diff {color: #898887}
      code.diff span.va {color: #006e28}
      code.diff span.st {color: #bf0303}
  </style>
  <style type="text/css">
body {
margin: 5em;
font-family: serif;

hyphens: auto;
line-height: 1.35;
}
div.wrapper {
max-width: 60em;
margin: auto;
}
ul {
list-style-type: none;
padding-left: 2em;
margin-top: -0.2em;
margin-bottom: -0.2em;
}
a {
text-decoration: none;
color: #4183C4;
}
a.hidden_link {
text-decoration: none;
color: inherit;
}
li {
margin-top: 0.6em;
margin-bottom: 0.6em;
}
h1, h2, h3, h4 {
position: relative;
line-height: 1;
}
a.self-link {
position: absolute;
top: 0;
left: calc(-1 * (3.5rem - 26px));
width: calc(3.5rem - 26px);
height: 2em;
text-align: center;
border: none;
transition: opacity .2s;
opacity: .5;
font-family: sans-serif;
font-weight: normal;
font-size: 83%;
}
a.self-link:hover { opacity: 1; }
a.self-link::before { content: "§"; }
ul > li:before {
content: "\2014";
position: absolute;
margin-left: -1.5em;
}
:target { background-color: #C9FBC9; }
:target .codeblock { background-color: #C9FBC9; }
:target ul { background-color: #C9FBC9; }
.abbr_ref { float: right; }
.folded_abbr_ref { float: right; }
:target .folded_abbr_ref { display: none; }
:target .unfolded_abbr_ref { float: right; display: inherit; }
.unfolded_abbr_ref { display: none; }
.secnum { display: inline-block; min-width: 35pt; }
.header-section-number { display: inline-block; min-width: 35pt; }
.annexnum { display: block; }
div.sourceLinkParent {
float: right;
}
a.sourceLink {
position: absolute;
opacity: 0;
margin-left: 10pt;
}
a.sourceLink:hover {
opacity: 1;
}
a.itemDeclLink {
position: absolute;
font-size: 75%;
text-align: right;
width: 5em;
opacity: 0;
}
a.itemDeclLink:hover { opacity: 1; }
span.marginalizedparent {
position: relative;
left: -5em;
}
li span.marginalizedparent { left: -7em; }
li ul > li span.marginalizedparent { left: -9em; }
li ul > li ul > li span.marginalizedparent { left: -11em; }
li ul > li ul > li ul > li span.marginalizedparent { left: -13em; }
div.footnoteNumberParent {
position: relative;
left: -4.7em;
}
a.marginalized {
position: absolute;
font-size: 75%;
text-align: right;
width: 5em;
}
a.enumerated_item_num {
position: relative;
left: -3.5em;
display: inline-block;
margin-right: -3em;
text-align: right;
width: 3em;
}
div.para { margin-bottom: 0.6em; margin-top: 0.6em; text-align: justify; }
div.section { text-align: justify; }
div.sentence { display: inline; }
span.indexparent {
display: inline;
position: relative;
float: right;
right: -1em;
}
a.index {
position: absolute;
display: none;
}
a.index:before { content: "⟵"; }

a.index:target {
display: inline;
}
.indexitems {
margin-left: 2em;
text-indent: -2em;
}
div.itemdescr {
margin-left: 3em;
}
.bnf {
font-family: serif;
margin-left: 40pt;
margin-top: 0.5em;
margin-bottom: 0.5em;
}
.ncbnf {
font-family: serif;
margin-top: 0.5em;
margin-bottom: 0.5em;
margin-left: 40pt;
}
.ncsimplebnf {
font-family: serif;
font-style: italic;
margin-top: 0.5em;
margin-bottom: 0.5em;
margin-left: 40pt;
background: inherit; 
}
span.textnormal {
font-style: normal;
font-family: serif;
white-space: normal;
display: inline-block;
}
span.rlap {
display: inline-block;
width: 0px;
}
span.descr { font-style: normal; font-family: serif; }
span.grammarterm { font-style: italic; }
span.term { font-style: italic; }
span.terminal { font-family: monospace; font-style: normal; }
span.nonterminal { font-style: italic; }
span.tcode { font-family: monospace; font-style: normal; }
span.textbf { font-weight: bold; }
span.textsc { font-variant: small-caps; }
a.nontermdef { font-style: italic; font-family: serif; }
span.emph { font-style: italic; }
span.techterm { font-style: italic; }
span.mathit { font-style: italic; }
span.mathsf { font-family: sans-serif; }
span.mathrm { font-family: serif; font-style: normal; }
span.textrm { font-family: serif; }
span.textsl { font-style: italic; }
span.mathtt { font-family: monospace; font-style: normal; }
span.mbox { font-family: serif; font-style: normal; }
span.ungap { display: inline-block; width: 2pt; }
span.textit { font-style: italic; }
span.texttt { font-family: monospace; }
span.tcode_in_codeblock { font-family: monospace; font-style: normal; }
span.phantom { color: white; }

span.math { font-style: normal; }
span.mathblock {
display: block;
margin-left: auto;
margin-right: auto;
margin-top: 1.2em;
margin-bottom: 1.2em;
text-align: center;
}
span.mathalpha {
font-style: italic;
}
span.synopsis {
font-weight: bold;
margin-top: 0.5em;
display: block;
}
span.definition {
font-weight: bold;
display: block;
}
.codeblock {
margin-left: 1.2em;
line-height: 127%;
}
.outputblock {
margin-left: 1.2em;
line-height: 127%;
}
div.itemdecl {
margin-top: 2ex;
}
code.itemdeclcode {
white-space: pre;
display: block;
}
span.textsuperscript {
vertical-align: super;
font-size: smaller;
line-height: 0;
}
.footnotenum { vertical-align: super; font-size: smaller; line-height: 0; }
.footnote {
font-size: small;
margin-left: 2em;
margin-right: 2em;
margin-top: 0.6em;
margin-bottom: 0.6em;
}
div.minipage {
display: inline-block;
margin-right: 3em;
}
div.numberedTable {
text-align: center;
margin: 2em;
}
div.figure {
text-align: center;
margin: 2em;
}
table {
border: 1px solid black;
border-collapse: collapse;
margin-left: auto;
margin-right: auto;
margin-top: 0.8em;
text-align: left;
hyphens: none; 
}
td, th {
padding-left: 1em;
padding-right: 1em;
vertical-align: top;
}
td.empty {
padding: 0px;
padding-left: 1px;
}
td.left {
text-align: left;
}
td.right {
text-align: right;
}
td.center {
text-align: center;
}
td.justify {
text-align: justify;
}
td.border {
border-left: 1px solid black;
}
tr.rowsep, td.cline {
border-top: 1px solid black;
}
tr.even, tr.odd {
border-bottom: 1px solid black;
}
tr.capsep {
border-top: 3px solid black;
border-top-style: double;
}
tr.header {
border-bottom: 3px solid black;
border-bottom-style: double;
}
th {
border-bottom: 1px solid black;
}
span.centry {
font-weight: bold;
}
div.table {
display: block;
margin-left: auto;
margin-right: auto;
text-align: center;
width: 90%;
}
span.indented {
display: block;
margin-left: 2em;
margin-bottom: 1em;
margin-top: 1em;
}
ol.enumeratea { list-style-type: none; background: inherit; }
ol.enumerate { list-style-type: none; background: inherit; }

code.sourceCode > span { display: inline; }
</style>
  <style type="text/css">a {
color : #4183C4;
text-decoration: underline;
}
a.marginalized {
text-decoration: none;
}
a.self-link {
text-decoration: none;
}
h1#toctitle {
border-bottom: 1px solid #cccccc;
}
#TOC li {
margin-top: 1px;
margin-bottom: 1px;
}
#TOC ul>li:before { display: none; }
h3.subtitle { margin-top: -15px; }
h1:target { background-color: transparent; }
h2:target { background-color: transparent; }
h3:target { background-color: transparent; }
h4:target { background-color: transparent; }
h5:target { background-color: transparent; }
h6:target { background-color: transparent; }
.marginalized:target { background-color: transparent; }
code span.co { font-family: monospace; }
table tr {
background-color: white;
}
table tr:nth-child(2n) {
background-color: #f6f8fa;
}
#title-block-header > table tr:nth-child(2n) {
background-color: white;
}
td > div.sourceCode {
background-color: inherit;
}
table {
border-collapse: collapse;
}
table td, table th {
border: 1px solid #cccccc;
}
table th {
border-bottom: 1px solid black;
text-align: center;
}
table tr:first-child th {
border-top: 0;
}
table tr:last-child td {
border-bottom: 0;
}
table tr td:first-child,
table tr th:first-child {
border-left: 0;
}
table tr td:last-child,
table tr th:last-child {
border-right: 0;
}
table tbody tr:first-child td {
border-top: 1px solid black;
}
#title-block-header td { border: 0; }
@media all {
body {
margin: 2em;
}
}
@media screen and (min-width: 480px) {
body {
margin: 5em;
}
}
#refs code{padding-left: 0px; text-indent: 0px;}
:root {
--diff-ins: #e6ffed;
--diff-strongins: #acf2bd;
--diff-del: #ffdddd;
--diff-strongdel: #ff8888;
}
span.diffins {
background-color: var(--diff-strongins);
}
span.diffdel {
background-color: var(--diff-strongdel);
}
div.rm { text-decoration: line-through; }
div.rm code.sourceCode { text-decoration: line-through; }
div.addu, span.addu {
color: #006e28;
background-color: var(--diff-ins);
}

div.rm pre, div.add pre { background-color: #f6f8fa; }
div.addu pre { background-color: var(--diff-ins); }
div.add, div.add pre, div.add blockquote { background-color: var(--diff-ins); }
div.addu blockquote {
border-left: 4px solid #00a000;
padding: 0 15px;
color: #006e28;
text-decoration: none;
}
div.addu blockquote code.sourceCode { text-decoration: none; }
div.addu blockquote pre { text-decoration: none; }
div.addu blockquote pre code { text-decoration: none; }
code.diff span.va { color: #000000; background-color: var(--diff-ins); }
code.diff span.st { color: #000000; background-color: var(--diff-del); }
blockquote { background-color: #f6f8fa; }
</style>
  <link href="data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAVoJEAN6CRADegkQAWIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wCCRAAAgkQAAIJEAACCRAAsgkQAvoJEAP+CRAD/gkQA/4JEAP+CRADAgkQALoJEAACCRAAAgkQAAP///wD///8AgkQAAIJEABSCRACSgkQA/IJEAP99PQD/dzMA/3czAP99PQD/gkQA/4JEAPyCRACUgkQAFIJEAAD///8A////AHw+AFiBQwDqgkQA/4BBAP9/PxP/uZd6/9rJtf/bybX/upd7/39AFP+AQQD/gkQA/4FDAOqAQgBc////AP///wDKklv4jlEa/3o7AP+PWC//8+3o///////////////////////z7un/kFox/35AAP+GRwD/mVYA+v///wD///8A0Zpk+NmibP+0d0T/8evj///////+/fv/1sKz/9bCs//9/fr//////+/m2/+NRwL/nloA/5xYAPj///8A////ANKaZPjRmGH/5cKh////////////k149/3UwAP91MQD/lmQ//86rhv+USg3/m1YA/5hSAP+bVgD4////AP///wDSmmT4zpJY/+/bx///////8+TV/8mLT/+TVx//gkIA/5lVAP+VTAD/x6B//7aEVv/JpH7/s39J+P///wD///8A0ppk+M6SWP/u2sf///////Pj1f/Nj1T/2KFs/8mOUv+eWhD/lEsA/8aee/+0glT/x6F7/7J8Rvj///8A////ANKaZPjRmGH/48Cf///////+/v7/2qt//82PVP/OkFX/37KJ/86siv+USg7/mVQA/5hRAP+bVgD4////AP///wDSmmT40ppk/9CVXP/69O////////7+/v/x4M//8d/P//7+/f//////9u7n/6tnJf+XUgD/nFgA+P///wD///8A0ppk+NKaZP/RmWL/1qNy//r07///////////////////////+vXw/9akdP/Wnmn/y5FY/6JfFvj///8A////ANKaZFTSmmTo0ppk/9GYYv/Ql1//5cWm//Hg0P/x4ND/5cWm/9GXYP/RmGH/0ppk/9KaZOjVnmpY////AP///wDSmmQA0ppkEtKaZI7SmmT60ppk/9CWX//OkVb/zpFW/9CWX//SmmT/0ppk/NKaZJDSmmQS0ppkAP///wD///8A0ppkANKaZADSmmQA0ppkKtKaZLrSmmT/0ppk/9KaZP/SmmT/0ppkvNKaZCrSmmQA0ppkANKaZAD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkUtKaZNzSmmTc0ppkVNKaZADSmmQA0ppkANKaZADSmmQA////AP5/AAD4HwAA4AcAAMADAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAMADAADgBwAA+B8AAP5/AAAoAAAAIAAAAEAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAyCRACMgkQA6oJEAOqCRACQgkQAEIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRABigkQA5oJEAP+CRAD/gkQA/4JEAP+CRADqgkQAZoJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAA4gkQAwoJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQAxIJEADyCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAP///wD///8A////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAWgkQAmIJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAJyCRAAYgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAdIJEAPCCRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAPSCRAB4gkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQASoJEANKCRAD/gkQA/4JEAP+CRAD/g0YA/39AAP9zLgD/bSQA/2shAP9rIQD/bSQA/3MuAP9/PwD/g0YA/4JEAP+CRAD/gkQA/4JEAP+CRADUgkQAToJEAACCRAAAgkQAAP///wD///8A////AP///wB+PwAAgkUAIoJEAKiCRAD/gkQA/4JEAP+CRAD/hEcA/4BBAP9sIwD/dTAA/5RfKv+viF7/vp56/76ee/+wiF7/lWAr/3YxAP9sIwD/f0AA/4RHAP+CRAD/gkQA/4JEAP+CRAD/gkQArIJEACaBQwAA////AP///wD///8A////AIBCAEBzNAD6f0EA/4NFAP+CRAD/gkQA/4VIAP92MwD/bSUA/6N1Tv/ezsL/////////////////////////////////38/D/6V3Uv9uJgD/dTEA/4VJAP+CRAD/gkQA/4JEAP+BQwD/fUAA/4FDAEj///8A////AP///wD///8AzJRd5qBlKf91NgD/dDUA/4JEAP+FSQD/cy4A/3YyAP/PuKP//////////////////////////////////////////////////////9K7qP94NQD/ciwA/4VJAP+CRAD/fkEA/35BAP+LSwD/mlYA6v///wD///8A////AP///wDdpnL/4qx3/8KJUv+PUhf/cTMA/3AsAP90LgD/4dK+/////////////////////////////////////////////////////////////////+TYxf91MAD/dTIA/31CAP+GRwD/llQA/6FcAP+gWwD8////AP///wD///8A////ANGZY/LSm2X/4ap3/92mcP+wdT3/byQA/8mwj////////////////////////////////////////////////////////////////////////////+LYxv9zLgP/jUoA/59bAP+hXAD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/RmWL/1p9q/9ubXv/XqXj////////////////////////////7+fD/vZyG/6BxS/+gcUr/vJuE//r37f//////////////////////3MOr/5dQBf+dVQD/nVkA/5xYAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmWP/yohJ//jo2P//////////////////////4NTG/4JDFf9lGAD/bSQA/20kAP9kGAD/fz8S/+Xb0f//////5NG9/6txN/+LOgD/m1QA/51aAP+cWAD/m1cA/5xYAP+cWADy////AP///wD///8A////ANKaZPLSmmT/0ppk/8+TWf/Unmv//v37//////////////////////+TWRr/VwsA/35AAP+ERgD/g0UA/4JGAP9lHgD/kFga/8KXX/+TRwD/jT4A/49CAP+VTQD/n10A/5xYAP+OQQD/lk4A/55cAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/y4tO/92yiP//////////////////////8NnE/8eCQP+rcTT/ez0A/3IyAP98PgD/gEMA/5FSAP+USwD/jj8A/5lUAP+JNwD/yqV2/694Mf+HNQD/jkAA/82rf/+laBj/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/LiUr/4byY///////////////////////gupX/0I5P/+Wuev/Lklz/l1sj/308AP+QSwD/ol0A/59aAP+aVQD/k0oA/8yoh///////+fXv/6pwO//Lp3v///////Pr4f+oay7y////AP///wD///8A////ANKaZPLSmmT/0ppk/8uJSv/hvJj//////////////////////+G7l//Jhkb/0ppk/96nc//fqXX/x4xO/6dkFP+QSQD/llEA/5xXAP+USgD/yaOA///////38uv/qG05/8ijdv//////8efb/6ZpLPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/zIxO/9yxh///////////////////////7dbA/8iEQf/Sm2X/0Zlj/9ScZv/eqHf/2KJv/7yAQf+XTgD/iToA/5lSAP+JNgD/yKFv/611LP+HNQD/jT8A/8qmeP+kZRT/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/Pk1n/1J5q//78+//////////////////+/fv/1aFv/8iEQv/Tm2b/0ppl/9GZY//Wn2z/1pZc/9eldf/Bl2b/kUcA/4w9AP+OQAD/lUwA/59eAP+cWQD/jT8A/5ZOAP+eXADy////AP///wD///8A////ANKaZPLSmmT/0ppk/9KZY//KiEn/8d/P///////////////////////47+f/05tm/8iCP//KiEj/yohJ/8eCP//RmGH//vfy///////n1sP/rXQ7/4k4AP+TTAD/nVoA/5xYAP+cVwD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/0ptl/8uLTf/aq37////////////////////////////+/fz/6c2y/961jv/etY7/6Myx//78+v//////////////////////3MWv/5xXD/+ORAD/mFQA/51ZAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmmT/0ppk/8mFRP/s1b//////////////////////////////////////////////////////////////////////////////+PD/0JFU/7NzMv+WUQD/kUsA/5tXAP+dWQDy////AP///wD///8A////ANKaZP/SmmT/0ppk/9KaZP/Sm2X/z5NZ/8yMT//z5NX/////////////////////////////////////////////////////////////////9Ofa/8yNUP/UmGH/36p5/8yTWv+qaSD/kksA/5ROAPz///8A////AP///wD///8A0ppk5NKaZP/SmmT/0ppk/9KaZP/TnGf/zY9T/82OUv/t1sD//////////////////////////////////////////////////////+7Yw//OkFX/zI5R/9OcZ//SmmP/26V0/9ymdf/BhUf/ol8R6P///wD///8A////AP///wDSmmQ80ppk9tKaZP/SmmT/0ppk/9KaZP/TnGj/zpFW/8qJSv/dson/8uHS//////////////////////////////////Lj0//etIv/y4lL/86QVf/TnGj/0ppk/9KaZP/RmWP/05xn/9ymdfjUnWdC////AP///wD///8A////ANKaZADSmmQc0ppkotKaZP/SmmT/0ppk/9KaZP/Tm2b/0Zli/8qJSf/NjlH/16Z3/+G8mP/myKr/5siq/+G8mP/Xp3f/zY5S/8qISf/RmGH/05tm/9KaZP/SmmT/0ppk/9KaZP/SmmSm0pljINWdaQD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkQtKaZMrSmmT/0ppk/9KaZP/SmmT/0ptl/9GYYf/Nj1P/y4lL/8qISP/KiEj/y4lK/82PU//RmGH/0ptl/9KaZP/SmmT/0ppk/9KaZP/SmmTO0ppkRtKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZGzSmmTu0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmTw0ppkcNKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZBLSmmSQ0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppklNKaZBTSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQy0ppkutKaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppkvtKaZDbSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkXNKaZODSmmT/0ppk/9KaZP/SmmT/0ppk5NKaZGDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkBtKaZIbSmmTo0ppk6tKaZIrSmmQK0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP/8P///+B///+AH//+AAf//AAD//AAAP/AAAA/gAAAHwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA+AAAAfwAAAP/AAAP/8AAP//gAH//+AH///4H////D//" rel="icon" />
  <!--[if lt IE 9]>
    <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
  <![endif]-->
  
</head>
<body>
<div class="wrapper">
<header id="title-block-header">
<h1 class="title" style="text-align:center">Cleaning up integer-class types</h1>

<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P2393R0</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2021-06-12</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Project:</td>
    <td>Programming Language C++</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Audience:</td>
    <td>
      LWG<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to:</td>
    <td>
      Tim Song<br>&lt;<a href="mailto:t.canens.cpp@gmail.com" class="email">t.canens.cpp@gmail.com</a>&gt;<br>
    </td>
  </tr>
</table>

</header>
<div style="clear:both">
<h1 data-number="1" style="border-bottom:1px solid #cccccc" id="abstract"><span class="header-section-number">1</span> Abstract<a href="#abstract" class="self-link"></a></h1>
<p>This paper revamps the specification and use of integer-class types to resolve a number of issues, including <span class="citation" data-cites="LWG3366">[<a href="#ref-LWG3366" role="doc-biblioref">LWG3366</a>]</span> and <span class="citation" data-cites="LWG3376">[<a href="#ref-LWG3376" role="doc-biblioref">LWG3376</a>]</span>.</p>
<h1 data-number="2" style="border-bottom:1px solid #cccccc" id="discussion"><span class="header-section-number">2</span> Discussion<a href="#discussion" class="self-link"></a></h1>
<p>Integer-class types, introduced in <span class="citation" data-cites="P1522R1">[<a href="#ref-P1522R1" role="doc-biblioref">P1522R1</a>]</span>, are implementation-defined class types that are supposed to “behave as integers do”. Unfortunately, they are not yet required to do that, and the failure to do so leads to a number of issues in the library specification. For example:</p>
<ul>
<li>Two integer-class types are not required to have a <code class="sourceCode cpp">common_type</code>, which causes issues in various ranges components such as <code class="sourceCode cpp">zip_view</code> (<span class="citation" data-cites="P2321R1">[<a href="#ref-P2321R1" role="doc-biblioref">P2321R1</a>]</span>) and <code class="sourceCode cpp">join_view</code> (<span>24.7.11.3 <a href="https://wg21.link/range.join.iterator">[range.join.iterator]</a></span>) that uses <code class="sourceCode cpp">common_type_t</code> to determine the difference type of a range resulting from the composition of multiple ranges.</li>
<li>Integer-class types are not required to be convertible or comparable to each other, so it is unclear how algorithms (such as <code class="sourceCode cpp">ranges<span class="op">::</span>equal</code>) that may need to compare distances obtained from two ranges can even be implemented.</li>
<li>The range of representable values of integer-class types, and their conversion to/from integer types, is ill-defined.</li>
</ul>
<p>Additionally, there’s a pervasive problem in the ranges and algorithms clauses in that the wording fails to take into account the fact that random access iterator operations are only required to work with the iterator’s difference type, and not any other integer-like type. This was not a major issue in practice before C++20 because reasonable users (and even somewhat less reasonable ones) do not normally go out of the way to define deleted overloads for other integer types (or constrain their overload to require exactly the same type), but now that integer-class types can require explicit conversions, things are more problematic.</p>
<h2 data-number="2.1" id="approach"><span class="header-section-number">2.1</span> Approach<a href="#approach" class="self-link"></a></h2>
<p>First, tighten the specification of integer-class types to mandate support for what algorithms and range adaptors require, and clean up several library issues in the process.</p>
<ul>
<li>Specify that integer-class types are two’s complement, just like built-in integers, and are wider than any built-in integer type. This resolves <span class="citation" data-cites="LWG3366">[<a href="#ref-LWG3366" role="doc-biblioref">LWG3366</a>]</span>.</li>
<li>Allow integer-class types to be non-class types, which resolves <span class="citation" data-cites="LWG3376">[<a href="#ref-LWG3376" role="doc-biblioref">LWG3376</a>]</span>.</li>
<li>Specify that two integer-like types always have a common type, and that common type is signed if both are signed, to support the use of <code class="sourceCode cpp">common_type_t</code> to compute the difference type of a range. (Only the signed case is considered because a) there is no corresponding use case for unsigned and b) the property doesn’t hold for some built-in unsigned integer types that could be promoted to a signed type by integral promotion.)</li>
<li>Specify that integer-class types are implicitly convertible to another integer-class type of the same signedness and equal or greater width; and are explicitly convertible to all integer-class types.</li>
<li>Permit heterogeneous binary operations between integer-like types where one is implicitly convertible to the other; this allows arithmetic and comparison on the difference types of different ranges.</li>
</ul>
<p>Next, clean up the ranges wording (again) to explicitly cast to the difference type where required.</p>
<p>Finally, add blanket wording in the algorithms clause that <code class="sourceCode cpp">i <span class="op">+</span> n</code> and <code class="sourceCode cpp">i <span class="op">-</span> n</code> for iterator <code class="sourceCode cpp">i</code> and integer-like type <code class="sourceCode cpp">n</code> in the wording behave as-if <code class="sourceCode cpp">n</code> is first cast to <code class="sourceCode cpp">i</code>’s difference type. This allows the spec to have things like <code class="sourceCode cpp">first1 <span class="op">+</span> <span class="op">(</span>last2 <span class="op">-</span> first2<span class="op">)</span></code> without worrying about having to cast them (a fully correct implementation would still need to cast, however).</p>
<h1 data-number="3" style="border-bottom:1px solid #cccccc" id="wording"><span class="header-section-number">3</span> Wording<a href="#wording" class="self-link"></a></h1>
<p>This wording is relative to <span class="citation" data-cites="N4885">[<a href="#ref-N4885" role="doc-biblioref">N4885</a>]</span> after the application of <span class="citation" data-cites="P2367R0">[<a href="#ref-P2367R0" role="doc-biblioref">P2367R0</a>]</span>.</p>
<div>
<ol type="1">
<li>Edit <span>23.3.4.4 <a href="https://wg21.link/iterator.concept.winc">[iterator.concept.winc]</a></span>, as indicated:</li>
</ol>
<blockquote>
<p><span class="draftnote" style="color: #01796F">[ Drafting note: Because <em>integer-class type</em> is only used in this subclause (the rest of the standard uses <em>integer-like</em>), I did not rename it. Cf. <code class="sourceCode cpp"><span class="kw">enum</span> <span class="kw">class</span></code>. ]</span></p>
<p><span class="ednote" style="color: #0000ff">[ Editor&#39;s note: P2321R2 § 5.4 also contains edits to this subclause. The wording below subsumes those edits and should be applied instead if both papers are adopted. ]</span></p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_1" id="pnum_1">2</a></span> A type <code class="sourceCode cpp">I</code> is an <em>integer-class</em> type if it is in a set of implementation-defined <span class="diffdel">class</span> types that behave as integer types do, as defined below. <span class="diffins"><span class="note-"><span>[ <em>Note ?:</em> </span>An integer-class type is not necessarily a class type.<span> — <em>end note</em> ]</span></span></span></p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_2" id="pnum_2">3</a></span> The range of representable values of an integer-class type is the continuous set of values over which it is defined. <span class="diffdel">The values 0 and 1 are part of the range of every integer-class type. If any negative numbers are part of the range, the type is a <em>signed-integer-class</em> type; otherwise, it is an <em>unsigned-integer-class</em> type.</span> <span class="diffins">For any integer-class type, its range of representable values is either -2<sup><em>N-1</em></sup> to 2<sup><em>N-1</em></sup>-1 (inclusive) for some integer <em>N</em>, in which case it is a <em>signed-integer-class</em> type, or 0 to 2<sup><em>N</em></sup>-1 (inclusive) for some integer <em>N</em>, in which case it is an <em>unsigned-integer-class</em> type. In both cases, <em>N</em> is called the <em>width</em> of the integer-class type. The width of an integer-class type is greater than that of every integral type of the same signedness.</span></p>
<p><span class="ednote" style="color: #0000ff">[ Editor&#39;s note: Move paragraph 11 here to make <em>integer-like</em> available for use in subsequent wording. ]</span></p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_3" id="pnum_3">11</a></span> A type <code class="sourceCode cpp">I</code> other than <em>cv</em> <code class="sourceCode cpp"><span class="dt">bool</span></code> is <em>integer-like</em> if it models <code class="sourceCode cpp">integral<span class="op">&lt;</span>I<span class="op">&gt;</span></code> or if it is an integer-class type. An integer-like type I is <em>signed-integer-like</em> if it models <code class="sourceCode cpp">signed_integral<span class="op">&lt;</span>I<span class="op">&gt;</span></code> or if it is a signed-integer-class type. An integer-like type <code class="sourceCode cpp">I</code> is <em>unsigned-integer-like</em> if it models <code class="sourceCode cpp">unsigned_integral<span class="op">&lt;</span>I<span class="op">&gt;</span></code> or if it is an unsigned-integer-class type.</p>
<p><span class="draftnote" style="color: #01796F">[ Drafting note: The <em>unique</em> addition ensures that even if an implementation decides to provide two integer-class types of the same signedness and width, the result of binary operators are still well-defined. ]</span></p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_4" id="pnum_4">4</a></span> For every integer-class type <code class="sourceCode cpp">I</code>, let <code class="sourceCode cpp">B<span class="op">(</span>I<span class="op">)</span></code> be a <span class="diffins">unique</span> hypothetical extended integer type of the same signedness with <span><span class="diffins">the same width (<span>6.8.2 <a href="https://wg21.link/basic.fundamental">[basic.fundamental]</a></span>) as <code class="sourceCode cpp">I</code> </span><span class="diffdel">the smallest width (<span>6.8.2 <a href="https://wg21.link/basic.fundamental">[basic.fundamental]</a></span>) capable of representing the same range of values. The width of <code class="sourceCode cpp">I</code> is equal to the width of <code class="sourceCode cpp">B<span class="op">(</span>I<span class="op">)</span></code></span></span>. <span class="diffins">For every integral type <code class="sourceCode cpp">J</code>, let <code class="sourceCode cpp">B<span class="op">(</span>J<span class="op">)</span></code> be the same type as <code class="sourceCode cpp">J</code>.</span></p>
<p><span class="ednote" style="color: #0000ff">[ Editor&#39;s note: Reorder paragraph 6 before 5. ]</span></p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_5" id="pnum_5">6</a></span> Expressions of integer-class type are explicitly convertible to any <span><span class="diffins">integer-like</span><span class="diffdel">integral</span></span> type<span class="diffins">, and implicitly convertible to any integer-class type of equal or greater width and the same signedness</span>. Expressions of integral type are both implicitly and explicitly convertible to any integer-class type. Conversions between integral and integer-class types <span class="diffins">and between two integer-class types</span> do not exit via an exception. <span class="diffins">The result of such a conversion is the unique value of the destination type that is congruent to the source modulo 2<sup><em>N</em></sup>, where <em>N</em> is the width of the destination type.</span></p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_6" id="pnum_6">5</a></span> Let <code class="sourceCode cpp">a</code> <span class="diffdel">and <code class="sourceCode cpp">b</code></span> be <span><span class="diffins">an object</span><span class="diffdel">objects</span></span> of integer-class type <code class="sourceCode cpp">I</code>, <span class="diffins">let <code class="sourceCode cpp">b</code> be an object of integer-like type <code class="sourceCode cpp">I2</code> such that the expression <code class="sourceCode cpp">b</code> is implicitly convertible to <code class="sourceCode cpp">I</code>,</span> let <code class="sourceCode cpp">x</code> and <code class="sourceCode cpp">y</code> be <span class="diffins">respectively</span> objects of type <code class="sourceCode cpp">B<span class="op">(</span>I<span class="op">)</span></code> <span class="diffins">and <code class="sourceCode cpp">B<span class="op">(</span>I2<span class="op">)</span></code></span> as described above that represent the same values as <code class="sourceCode cpp">a</code> and <code class="sourceCode cpp">b</code> <span class="diffdel">respectively</span>, and let <code class="sourceCode cpp">c</code> be an lvalue of any integral type.</p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_7" id="pnum_7">(5.1)</a></span> For every unary operator <code class="sourceCode cpp"><span class="op">@</span></code> for which the expression <code class="sourceCode cpp"><span class="op">@</span>x</code> is well-formed, <code class="sourceCode cpp"><span class="op">@</span>a</code> shall also be well-formed and have the same value, effects, and value category as <code class="sourceCode cpp"><span class="op">@</span>x</code> <span class="diffdel">provided that value is representable by <code class="sourceCode cpp">I</code></span>. If <code class="sourceCode cpp"><span class="op">@</span>x</code> has type <code class="sourceCode cpp"><span class="dt">bool</span></code>, so too does <code class="sourceCode cpp"><span class="op">@</span>a</code>; if <code class="sourceCode cpp"><span class="op">@</span>x</code> has type <code class="sourceCode cpp">B<span class="op">(</span>I<span class="op">)</span></code>, then <code class="sourceCode cpp"><span class="op">@</span>a</code> has type <code class="sourceCode cpp">I</code>.</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_8" id="pnum_8">(5.2)</a></span> For every assignment operator <code class="sourceCode cpp"><span class="op">@=</span></code> for which <code class="sourceCode cpp">c <span class="op">@=</span> x</code> is well-formed, <code class="sourceCode cpp">c <span class="op">@=</span> a</code> shall also be well-formed and shall have the same value and effects as <code class="sourceCode cpp">c <span class="op">@=</span> x</code>. The expression <code class="sourceCode cpp">c <span class="op">@=</span> a</code> shall be an lvalue referring to <code class="sourceCode cpp">c</code>.</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_9" id="pnum_9">(5.3)</a></span> For every <span class="diffins">non-assignment</span> binary operator <code class="sourceCode cpp"><span class="op">@</span></code> for which <code class="sourceCode cpp">x <span class="op">@</span> y</code> <span><span class="diffins">and <code class="sourceCode cpp">y <span class="op">@</span> x</code> are</span><span class="diffdel">is</span></span> well-formed, <code class="sourceCode cpp">a <span class="op">@</span> b</code> <span class="diffins">and <code class="sourceCode cpp">b <span class="op">@</span> a</code></span> shall also be well-formed and shall have the same value, effects, and value category as <code class="sourceCode cpp">x <span class="op">@</span> y</code> <span class="diffins">and <code class="sourceCode cpp">y <span class="op">@</span> x</code> respectively</span><span class="diffdel">provided that value is representable by <code class="sourceCode cpp">I</code></span>. If <code class="sourceCode cpp">x <span class="op">@</span> y</code> <span class="diffins">or <code class="sourceCode cpp">y <span class="op">@</span> x</code></span> has type <code class="sourceCode cpp"><span class="dt">bool</span></code>, so too does <code class="sourceCode cpp">a <span class="op">@</span> b</code> <span class="diffins">or <code class="sourceCode cpp">b <span class="op">@</span> a</code>, respectively</span>; if <code class="sourceCode cpp">x <span class="op">@</span> y</code> <span class="diffins">or <code class="sourceCode cpp">y <span class="op">@</span> x</code></span> has type <code class="sourceCode cpp">B<span class="op">(</span>I<span class="op">)</span></code>, then <code class="sourceCode cpp">a <span class="op">@</span> b</code> <span class="diffins">or <code class="sourceCode cpp">b <span class="op">@</span> a</code>, respectively,</span> has type <code class="sourceCode cpp">I</code><span class="diffins">; if <code class="sourceCode cpp">x <span class="op">@</span> y</code> or <code class="sourceCode cpp">y <span class="op">@</span> x</code> has type <code class="sourceCode cpp">B<span class="op">(</span>I2<span class="op">)</span></code>, then <code class="sourceCode cpp">a <span class="op">@</span> b</code> or <code class="sourceCode cpp">b <span class="op">@</span> a</code>, respectively, has type <code class="sourceCode cpp">I2</code>.</span>.</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_10" id="pnum_10">(5.4)</a></span> <span class="diffins">For every assignment operator <code class="sourceCode cpp"><span class="op">@=</span></code> for which <code class="sourceCode cpp">x <span class="op">@=</span> y</code> is well-formed, <code class="sourceCode cpp">a <span class="op">@=</span> b</code> shall also be well-formed and shall have the same value and effects as <code class="sourceCode cpp">x <span class="op">@=</span> y</code>. The expression <code class="sourceCode cpp">a <span class="op">@=</span> b</code> shall be an lvalue referring to <code class="sourceCode cpp">a</code>.</span></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_11" id="pnum_11">7</a></span> An expression <code class="sourceCode cpp">E</code> of integer-class type <code class="sourceCode cpp">I</code> is contextually convertible to <code class="sourceCode cpp"><span class="dt">bool</span></code> as if by <code class="sourceCode cpp"><span class="dt">bool</span><span class="op">(</span>E <span class="op">!=</span> I<span class="op">(</span><span class="dv">0</span><span class="op">))</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_12" id="pnum_12">8</a></span> All integer-class types model <code class="sourceCode cpp">regular</code> (<span>18.6 <a href="https://wg21.link/concepts.object">[concepts.object]</a></span>) and <code class="sourceCode cpp">totally_ordered</code> (<span>18.5.4 <a href="https://wg21.link/concept.totallyordered">[concept.totallyordered]</a></span>).</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_13" id="pnum_13">9</a></span> A value-initialized object of integer-class type has value 0.</p>
<p><span class="draftnote" style="color: #01796F">[ Drafting note: There are some issues with the <code class="sourceCode cpp">numeric_limit</code> specialization: <code class="sourceCode cpp">digits</code> is defined in terms of <code class="sourceCode cpp">radix</code>, so it doesn’t make sense to define the former but not the latter, and the definition of <code class="sourceCode cpp">digits</code> is also incorrect for signed types. Instead of trying to fix this piecemeal and maintain an ever-growing list, we can simply specify this in terms of <code class="sourceCode cpp">B<span class="op">(</span>I<span class="op">)</span></code>. ]</span></p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_14" id="pnum_14">10</a></span> For every (possibly cv-qualified) integer-class type <code class="sourceCode cpp">I</code>, <span class="diffins">let <code class="sourceCode cpp">numeric_limits<span class="op">&lt;</span>B<span class="op">(</span>I<span class="op">)&gt;</span></code> be a hypothetical specialization that meets the requirements for <code class="sourceCode cpp">numeric_limit</code> specializations for arithmetic types (<span>17.3.5 <a href="https://wg21.link/numeric.limits">[numeric.limits]</a></span>).</span> <code class="sourceCode cpp">numeric_limits<span class="op">&lt;</span>I<span class="op">&gt;</span></code> is specialized such that <span><span class="diffins">each static data member <code class="sourceCode cpp"><em>m</em></code> has the same value as <code class="sourceCode cpp">numeric_limits<span class="op">&lt;</span>B<span class="op">(</span>I<span class="op">)&gt;::</span><em>m</em></code>, and each static member function <code class="sourceCode cpp"><em>f</em></code> returns <code class="sourceCode cpp">I<span class="op">(</span>numeric_limits<span class="op">&lt;</span>B<span class="op">(</span>I<span class="op">)&gt;::</span><em>f</em><span class="op">())</span></code>.</span><span class="diffdel">:</span></span></p>
<div class="rm" style="color: #bf0303">

<ul>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_15" id="pnum_15">(10.1)</a></span> <code class="sourceCode default">numeric_limits&lt;I&gt;::is_specialized</code> is <code class="sourceCode default">true</code>,</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_16" id="pnum_16">(10.2)</a></span> <code class="sourceCode default">numeric_limits&lt;I&gt;::is_signed</code> is <code class="sourceCode default">true</code> if and only if <code class="sourceCode default">I</code> is a signed-integer-class type,</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_17" id="pnum_17">(10.3)</a></span> <code class="sourceCode default">numeric_limits&lt;I&gt;::is_integer</code> is <code class="sourceCode default">true</code>,</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_18" id="pnum_18">(10.4)</a></span> <code class="sourceCode default">numeric_limits&lt;I&gt;::is_exact</code> is <code class="sourceCode default">true</code>,</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_19" id="pnum_19">(10.5)</a></span> <code class="sourceCode default">numeric_limits&lt;I&gt;::digits</code> is equal to the width of the integer-class type,</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_20" id="pnum_20">(10.6)</a></span> <code class="sourceCode default">numeric_limits&lt;I&gt;::digits10</code> is equal to <code class="sourceCode default">static_cast&lt;int&gt;(digits * log10(2))</code>, and</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_21" id="pnum_21">(10.7)</a></span> <code class="sourceCode default">numeric_limits&lt;I&gt;::min()</code> and <code class="sourceCode default">numeric_limits&lt;I&gt;::max()</code> return the lowest and highest representable values of <code class="sourceCode default">I</code>, respectively, and <code class="sourceCode default">numeric_limits&lt;I&gt;::lowest()</code> returns <code class="sourceCode default">numeric_limits&lt;I&gt;::min()</code>.</li>
</ul>

</div>
<div class="add" style="color: #006e28">
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_22" id="pnum_22">?</a></span> For any two integer-like types <code class="sourceCode default">I1</code> and <code class="sourceCode default">I2</code>, at least one of which is an integer-class type, <code class="sourceCode default">common_type_t&lt;I1, I2&gt;</code> denotes an integer-class type whose width is not less than that of <code class="sourceCode default">I1</code> or <code class="sourceCode default">I2</code>. If both <code class="sourceCode default">I1</code> and <code class="sourceCode default">I2</code> are signed-integer-like types, then <code class="sourceCode default">common_type_t&lt;I1, I2&gt;</code> is also a signed-integer-like type.</p>
</div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_23" id="pnum_23">12</a></span> <code class="sourceCode cpp"><em>is-integer-like</em><span class="op">&lt;</span>I<span class="op">&gt;</span></code> is true if and only if I is an integer-like type. <code class="sourceCode cpp"><em>is-signed-integer-like</em><span class="op">&lt;</span>I<span class="op">&gt;</span></code> is true if and only if I is a signed-integer-like type.</p>
</blockquote>
<ol start="2" type="1">
<li>Edit <span>24.5.4.2 <a href="https://wg21.link/range.subrange.ctor">[range.subrange.ctor]</a></span> p6 as indicated:</li>
</ol>
<blockquote>
<div>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1"></a><span class="kw">template</span><span class="op">&lt;</span><em>not-same-as</em><span class="op">&lt;</span>subrange<span class="op">&gt;</span> R<span class="op">&gt;</span></span>
<span id="cb1-2"><a href="#cb1-2"></a>  <span class="kw">requires</span> borrowed_range<span class="op">&lt;</span>R<span class="op">&gt;</span> <span class="op">&amp;&amp;</span></span>
<span id="cb1-3"><a href="#cb1-3"></a>           <em>convertible-to-non-slicing</em><span class="op">&lt;</span>iterator_t<span class="op">&lt;</span>R<span class="op">&gt;</span>, I<span class="op">&gt;</span> <span class="op">&amp;&amp;</span></span>
<span id="cb1-4"><a href="#cb1-4"></a>           convertible_to<span class="op">&lt;</span>sentinel_t<span class="op">&lt;</span>R<span class="op">&gt;</span>, S<span class="op">&gt;</span></span>
<span id="cb1-5"><a href="#cb1-5"></a><span class="kw">constexpr</span> subrange<span class="op">(</span>R<span class="op">&amp;&amp;</span> r<span class="op">)</span> <span class="kw">requires</span> <span class="op">(!</span><em>StoreSize</em> <span class="op">||</span> sized_range<span class="op">&lt;</span>R<span class="op">&gt;)</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_24" id="pnum_24">6</a></span> Effects: Equivalent to:</p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_25" id="pnum_25">(6.1)</a></span> If <em><code class="sourceCode cpp">StoreSize</code></em> is <code class="sourceCode cpp"><span class="kw">true</span></code>, <code class="sourceCode cpp">subrange<span class="op">(</span>r, <span class="diffins">static_cast&lt;decltype(<span class="math inline"><em>s</em><em>i</em><em>z</em><em>e</em>_­</span>)&gt;(</span>ranges<span class="op">::</span>size<span class="op">(</span>r<span class="op">)</span><span class="diffins">)</span><span class="op">)</span></code>.</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_26" id="pnum_26">(6.2)</a></span> Otherwise, <code class="sourceCode cpp">subrange<span class="op">(</span>ranges<span class="op">::</span>begin<span class="op">(</span>r<span class="op">)</span>, ranges<span class="op">::</span>end<span class="op">(</span>r<span class="op">))</span></code>.</li>
</ul>
</blockquote>
</div>
</blockquote>
<ol start="3" type="1">
<li>Edit <span>24.7.7.1 <a href="https://wg21.link/range.take.overview">[range.take.overview]</a></span> p2 as indicated:</li>
</ol>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_27" id="pnum_27">2</a></span> The name <code class="sourceCode cpp">views<span class="op">::</span>take</code> denotes a range adaptor object (<span>24.7.2 <a href="https://wg21.link/range.adaptor.object">[range.adaptor.object]</a></span>). Let <code class="sourceCode cpp">E</code> and <code class="sourceCode cpp">F</code> be expressions, let <code class="sourceCode cpp">T</code> be <code class="sourceCode cpp">remove_cvref_t<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">((</span>E<span class="op">))&gt;</span></code>, and let <code class="sourceCode cpp">D</code> be <code class="sourceCode cpp">range_difference_t<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">((</span>E<span class="op">))&gt;</span></code>. If <code class="sourceCode cpp"><span class="kw">decltype</span><span class="op">((</span>F<span class="op">))</span></code> does not model <code class="sourceCode cpp">convertible_to<span class="op">&lt;</span>D<span class="op">&gt;</span></code>, <code class="sourceCode cpp">views<span class="op">::</span>take<span class="op">(</span>E, F<span class="op">)</span></code> is ill-formed. Otherwise, the expression <code class="sourceCode cpp">views<span class="op">::</span>take<span class="op">(</span>E, F<span class="op">)</span></code> is expression-equivalent to:</p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized" href="#pnum_28" id="pnum_28">(2.1)</a></span> If T is a specialization of <code class="sourceCode cpp">ranges<span class="op">::</span>empty_view</code> (<span>24.6.2.2 <a href="https://wg21.link/range.empty.view">[range.empty.view]</a></span>), then <code class="sourceCode cpp"><span class="op">((</span><span class="dt">void</span><span class="op">)</span> F, <em>decay-copy</em><span class="op">(</span>E<span class="op">))</span></code>, except that the evaluations of <code class="sourceCode cpp">E</code> and <code class="sourceCode cpp">F</code> are indeterminately sequenced.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized" href="#pnum_29" id="pnum_29">(2.2)</a></span> Otherwise, if <code class="sourceCode cpp">T</code> models <code class="sourceCode cpp">random_access_range</code> and <code class="sourceCode cpp">sized_range</code> and is</p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_30" id="pnum_30">(2.2.1)</a></span> […]</li>
</ul>
<p>then <code class="sourceCode cpp">T<span class="op">(</span>ranges<span class="op">::</span>begin<span class="op">(</span>E<span class="op">)</span>, ranges<span class="op">::</span>begin<span class="op">(</span>E<span class="op">)</span> <span class="op">+</span> <span class="diffins">std::</span>min<span class="op">&lt;</span>D<span class="op">&gt;(</span>ranges<span class="op">::</span><span><span class="diffins">distance</span><span class="diffdel">size</span></span><span class="op">(</span>E<span class="op">)</span>, F<span class="op">))</span></code>, except that <code class="sourceCode cpp">E</code> is evaluated only once.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized" href="#pnum_31" id="pnum_31">(2.3)</a></span> Otherwise, <code class="sourceCode cpp">ranges<span class="op">::</span>take_view<span class="op">(</span>E, F<span class="op">)</span></code>.</p></li>
</ul>
</blockquote>
<ol start="4" type="1">
<li>Edit <span>24.7.7.2 <a href="https://wg21.link/range.take.view">[range.take.view]</a></span> as indicated:</li>
</ol>
<blockquote>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1"></a><span class="kw">namespace</span> std<span class="op">::</span>ranges <span class="op">{</span></span>
<span id="cb2-2"><a href="#cb2-2"></a>  <span class="kw">template</span><span class="op">&lt;</span>view V<span class="op">&gt;</span></span>
<span id="cb2-3"><a href="#cb2-3"></a>  <span class="kw">class</span> take_view <span class="op">:</span> <span class="kw">public</span> view_interface<span class="op">&lt;</span>take_view<span class="op">&lt;</span>V<span class="op">&gt;&gt;</span> <span class="op">{</span></span>
<span id="cb2-4"><a href="#cb2-4"></a></span>
<span id="cb2-5"><a href="#cb2-5"></a>    <span class="co">// [...]</span></span>
<span id="cb2-6"><a href="#cb2-6"></a></span>
<span id="cb2-7"><a href="#cb2-7"></a>    <span class="kw">constexpr</span> <span class="kw">auto</span> begin<span class="op">()</span> <span class="kw">requires</span> <span class="op">(!</span>simple<span class="op">-</span>view<span class="op">&lt;</span>V<span class="op">&gt;)</span> <span class="op">{</span></span>
<span id="cb2-8"><a href="#cb2-8"></a>      <span class="cf">if</span> <span class="kw">constexpr</span> <span class="op">(</span>sized_range<span class="op">&lt;</span>V<span class="op">&gt;)</span> <span class="op">{</span></span>
<span id="cb2-9"><a href="#cb2-9"></a>        <span class="cf">if</span> <span class="kw">constexpr</span> <span class="op">(</span>random_access_range<span class="op">&lt;</span>V<span class="op">&gt;)</span></span>
<span id="cb2-10"><a href="#cb2-10"></a>          <span class="cf">return</span> ranges<span class="op">::</span>begin<span class="op">(</span><em>base_</em><span class="op">)</span>;</span>
<span id="cb2-11"><a href="#cb2-11"></a>        <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb2-12"><a href="#cb2-12"></a>          <span class="kw">auto</span> sz <span class="op">=</span> <span class="diffins">range_difference_t&lt;V&gt;(</span>size<span class="op">()</span><span class="diffins">)</span>;</span>
<span id="cb2-13"><a href="#cb2-13"></a>          <span class="cf">return</span> counted_iterator<span class="op">((</span>ranges<span class="op">::</span>begin<span class="op">(</span><em>base_</em><span class="op">)</span>, sz<span class="op">)</span>;</span>
<span id="cb2-14"><a href="#cb2-14"></a>        <span class="op">}</span></span>
<span id="cb2-15"><a href="#cb2-15"></a>      <span class="op">}</span> <span class="cf">else</span></span>
<span id="cb2-16"><a href="#cb2-16"></a>        <span class="cf">return</span> counted_iterator<span class="op">(</span>ranges<span class="op">::</span>begin<span class="op">(</span><em>base_</em><span class="op">)</span>, <em>count_</em><span class="op">)</span>;</span>
<span id="cb2-17"><a href="#cb2-17"></a>    <span class="op">}</span></span>
<span id="cb2-18"><a href="#cb2-18"></a></span>
<span id="cb2-19"><a href="#cb2-19"></a>    <span class="kw">constexpr</span> <span class="kw">auto</span> begin<span class="op">()</span> <span class="kw">const</span> <span class="kw">requires</span> range<span class="op">&lt;</span><span class="kw">const</span> V<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb2-20"><a href="#cb2-20"></a>      <span class="cf">if</span> <span class="kw">constexpr</span> <span class="op">(</span>sized_range<span class="op">&lt;</span><span class="kw">const</span> V<span class="op">&gt;)</span> <span class="op">{</span></span>
<span id="cb2-21"><a href="#cb2-21"></a>        <span class="cf">if</span> <span class="kw">constexpr</span> <span class="op">(</span>random_access_range<span class="op">&lt;</span><span class="kw">const</span> V<span class="op">&gt;)</span></span>
<span id="cb2-22"><a href="#cb2-22"></a>          <span class="cf">return</span> ranges<span class="op">::</span>begin<span class="op">(</span><em>base_</em><span class="op">)</span>;</span>
<span id="cb2-23"><a href="#cb2-23"></a>        <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb2-24"><a href="#cb2-24"></a>          <span class="kw">auto</span> sz <span class="op">=</span> <span class="diffins">range_difference_t&lt;const V&gt;(</span>size<span class="op">()</span><span class="diffins">)</span>;</span>
<span id="cb2-25"><a href="#cb2-25"></a>          <span class="cf">return</span> counted_iterator<span class="op">(</span>ranges<span class="op">::</span>begin<span class="op">(</span><em>base_</em><span class="op">)</span>, sz<span class="op">)</span>;</span>
<span id="cb2-26"><a href="#cb2-26"></a>        <span class="op">}</span></span>
<span id="cb2-27"><a href="#cb2-27"></a>      <span class="op">}</span> <span class="cf">else</span></span>
<span id="cb2-28"><a href="#cb2-28"></a>        <span class="cf">return</span> counted_iterator<span class="op">(</span>ranges<span class="op">::</span>begin<span class="op">(</span><em>base_</em><span class="op">)</span>, <em>count_</em><span class="op">)</span>;</span>
<span id="cb2-29"><a href="#cb2-29"></a>    <span class="op">}</span></span>
<span id="cb2-30"><a href="#cb2-30"></a></span>
<span id="cb2-31"><a href="#cb2-31"></a>    <span class="kw">constexpr</span> <span class="kw">auto</span> end<span class="op">()</span> <span class="kw">requires</span> <span class="op">(!</span><em>simple-view</em><span class="op">&lt;</span>V<span class="op">&gt;)</span> <span class="op">{</span></span>
<span id="cb2-32"><a href="#cb2-32"></a>      <span class="cf">if</span> <span class="kw">constexpr</span> <span class="op">(</span>sized_range<span class="op">&lt;</span>V<span class="op">&gt;)</span> <span class="op">{</span></span>
<span id="cb2-33"><a href="#cb2-33"></a>        <span class="cf">if</span> <span class="kw">constexpr</span> <span class="op">(</span>random_access_range<span class="op">&lt;</span>V<span class="op">&gt;)</span></span>
<span id="cb2-34"><a href="#cb2-34"></a>          <span class="cf">return</span> ranges<span class="op">::</span>begin<span class="op">(</span><em>base_</em><span class="op">)</span> <span class="op">+</span> <span class="diffins">range_difference_t&lt;V&gt;(</span>size<span class="op">()</span><span class="diffins">)</span>;</span>
<span id="cb2-35"><a href="#cb2-35"></a>        <span class="cf">else</span></span>
<span id="cb2-36"><a href="#cb2-36"></a>          <span class="cf">return</span> default_sentinel;</span>
<span id="cb2-37"><a href="#cb2-37"></a>      <span class="op">}</span> <span class="cf">else</span></span>
<span id="cb2-38"><a href="#cb2-38"></a>        <span class="cf">return</span> <em>sentinel</em><span class="op">&lt;</span><span class="kw">false</span><span class="op">&gt;{</span>ranges<span class="op">::</span>end<span class="op">(</span><em>base_</em><span class="op">)}</span>;</span>
<span id="cb2-39"><a href="#cb2-39"></a>    <span class="op">}</span></span>
<span id="cb2-40"><a href="#cb2-40"></a></span>
<span id="cb2-41"><a href="#cb2-41"></a>    <span class="kw">constexpr</span> <span class="kw">auto</span> end<span class="op">()</span> <span class="kw">const</span> <span class="kw">requires</span> range<span class="op">&lt;</span><span class="kw">const</span> V<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb2-42"><a href="#cb2-42"></a>      <span class="cf">if</span> <span class="kw">constexpr</span> <span class="op">(</span>sized_range<span class="op">&lt;</span><span class="kw">const</span> V<span class="op">&gt;)</span> <span class="op">{</span></span>
<span id="cb2-43"><a href="#cb2-43"></a>        <span class="cf">if</span> <span class="kw">constexpr</span> <span class="op">(</span>random_access_range<span class="op">&lt;</span><span class="kw">const</span> V<span class="op">&gt;)</span></span>
<span id="cb2-44"><a href="#cb2-44"></a>          <span class="cf">return</span> ranges<span class="op">::</span>begin<span class="op">(</span><em>base_</em><span class="op">)</span> <span class="op">+</span> <span class="diffins">range_difference_t&lt;const V&gt;(</span>size<span class="op">()</span><span class="diffins">)</span>;</span>
<span id="cb2-45"><a href="#cb2-45"></a>        <span class="cf">else</span></span>
<span id="cb2-46"><a href="#cb2-46"></a>          <span class="cf">return</span> default_sentinel;</span>
<span id="cb2-47"><a href="#cb2-47"></a>      <span class="op">}</span> <span class="cf">else</span></span>
<span id="cb2-48"><a href="#cb2-48"></a>        <span class="cf">return</span> <em>sentinel</em><span class="op">&lt;</span><span class="kw">true</span><span class="op">&gt;{</span>ranges<span class="op">::</span>end<span class="op">(</span><em>base_</em><span class="op">)}</span>;</span>
<span id="cb2-49"><a href="#cb2-49"></a>    <span class="op">}</span></span>
<span id="cb2-50"><a href="#cb2-50"></a>    <span class="co">// [...]</span></span>
<span id="cb2-51"><a href="#cb2-51"></a>  <span class="op">}</span>;</span>
<span id="cb2-52"><a href="#cb2-52"></a></span>
<span id="cb2-53"><a href="#cb2-53"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> R<span class="op">&gt;</span></span>
<span id="cb2-54"><a href="#cb2-54"></a>    take_view<span class="op">(</span>R<span class="op">&amp;&amp;</span>, range_difference_t<span class="op">&lt;</span>R<span class="op">&gt;)</span></span>
<span id="cb2-55"><a href="#cb2-55"></a>      <span class="op">-&gt;</span> take_view<span class="op">&lt;</span>views<span class="op">::</span>all_t<span class="op">&lt;</span>R<span class="op">&gt;&gt;</span>;</span>
<span id="cb2-56"><a href="#cb2-56"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
<ol start="5" type="1">
<li>Edit <span>24.7.9.1 <a href="https://wg21.link/range.drop.overview">[range.drop.overview]</a></span> p2 as indicated:</li>
</ol>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_32" id="pnum_32">2</a></span> The name <code class="sourceCode cpp">views<span class="op">::</span>drop</code> denotes a range adaptor object (<span>24.7.2 <a href="https://wg21.link/range.adaptor.object">[range.adaptor.object]</a></span>). Let <code class="sourceCode cpp">E</code> and <code class="sourceCode cpp">F</code> be expressions, let <code class="sourceCode cpp">T</code> be <code class="sourceCode cpp">remove_cvref_t<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">((</span>E<span class="op">))&gt;</span></code>, and let <code class="sourceCode cpp">D</code> be <code class="sourceCode cpp">range_difference_t<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">((</span>E<span class="op">))&gt;</span></code>. If <code class="sourceCode cpp"><span class="kw">decltype</span><span class="op">((</span>F<span class="op">))</span></code> does not model <code class="sourceCode cpp">convertible_to<span class="op">&lt;</span>D<span class="op">&gt;</span></code>, <code class="sourceCode cpp">views<span class="op">::</span>drop<span class="op">(</span>E, F<span class="op">)</span></code> is ill-formed. Otherwise, the expression <code class="sourceCode cpp">views<span class="op">::</span>drop<span class="op">(</span>E, F<span class="op">)</span></code> is expression-equivalent to:</p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized" href="#pnum_33" id="pnum_33">(2.1)</a></span> If T is a specialization of <code class="sourceCode cpp">ranges<span class="op">::</span>empty_view</code> (<span>24.6.2.2 <a href="https://wg21.link/range.empty.view">[range.empty.view]</a></span>), then <code class="sourceCode cpp"><span class="op">((</span><span class="dt">void</span><span class="op">)</span> F, <em>decay-copy</em><span class="op">(</span>E<span class="op">))</span></code>, except that the evaluations of <code class="sourceCode cpp">E</code> and <code class="sourceCode cpp">F</code> are indeterminately sequenced.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized" href="#pnum_34" id="pnum_34">(2.2)</a></span> Otherwise, if <code class="sourceCode cpp">T</code> models <code class="sourceCode cpp">random_access_range</code> and <code class="sourceCode cpp">sized_range</code> and is</p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_35" id="pnum_35">(2.2.1)</a></span> […]</li>
</ul>
<p>then <code class="sourceCode cpp">T<span class="op">(</span>ranges<span class="op">::</span>begin<span class="op">(</span>E<span class="op">)</span> <span class="op">+</span> <span class="diffins">std::</span>min<span class="op">&lt;</span>D<span class="op">&gt;(</span>ranges<span class="op">::</span><span><span class="diffins">distance</span><span class="diffdel">size</span></span><span class="op">(</span>E<span class="op">)</span>, F<span class="op">)</span>, ranges<span class="op">::</span>end<span class="op">(</span>E<span class="op">))</span></code>, except that <code class="sourceCode cpp">E</code> is evaluated only once.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized" href="#pnum_36" id="pnum_36">(2.3)</a></span> Otherwise, <code class="sourceCode cpp">ranges<span class="op">::</span>drop_view<span class="op">(</span>E, F<span class="op">)</span></code>.</p></li>
</ul>
</blockquote>
<ol start="6" type="1">
<li>Edit <span>24.7.13 <a href="https://wg21.link/range.counted">[range.counted]</a></span> p2 as indicated:</li>
</ol>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_37" id="pnum_37">2</a></span> The name <code class="sourceCode cpp">views<span class="op">::</span>counted</code> denotes a customization point object (<span>16.3.3.3.6 <a href="https://wg21.link/customization.point.object">[customization.point.object]</a></span>). Let <code class="sourceCode cpp">E</code> and <code class="sourceCode cpp">F</code> be expressions, let <code class="sourceCode cpp">T</code> be <code class="sourceCode cpp">decay_t<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">((</span>E<span class="op">))&gt;</span></code>, and let <code class="sourceCode cpp">D</code> be <code class="sourceCode cpp">iter_difference_t<span class="op">&lt;</span>T<span class="op">&gt;</span></code>. If <code class="sourceCode cpp"><span class="kw">decltype</span><span class="op">((</span>F<span class="op">))</span></code> does not model <code class="sourceCode cpp">convertible_to<span class="op">&lt;</span>D<span class="op">&gt;</span></code>, <code class="sourceCode cpp">views<span class="op">::</span>counted<span class="op">(</span>E, F<span class="op">)</span></code> is ill-formed.</p>
<p><span class="note1"><span>[ <em>Note 1:</em> </span>This case can result in substitution failure when <code class="sourceCode cpp">views<span class="op">::</span>counted<span class="op">(</span>E, F<span class="op">)</span></code> appears in the immediate context of a template instantiation.<span> — <em>end note</em> ]</span></span></p>
<p>Otherwise, <code class="sourceCode cpp">views<span class="op">::</span>counted<span class="op">(</span>E, F<span class="op">)</span></code> is expression-equivalent to:</p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_38" id="pnum_38">(2.1)</a></span> If <code class="sourceCode cpp">T</code> models <code class="sourceCode cpp">contiguous_iterator</code>, then <code class="sourceCode cpp">span<span class="op">(</span>to_address<span class="op">(</span>E<span class="op">)</span>, <span class="diffins">static_cast&lt;size_t&gt;(</span>static_cast<span class="op">&lt;</span>D<span class="op">&gt;(</span>F<span class="op">)</span><span class="diffins">)</span><span class="op">)</span></code>.</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_39" id="pnum_39">(2.2)</a></span> Otherwise, if <code class="sourceCode cpp">T</code> models <code class="sourceCode cpp">random_access_iterator</code>, then <code class="sourceCode cpp">subrange<span class="op">(</span>E, E <span class="op">+</span> <span class="kw">static_cast</span><span class="op">&lt;</span>D<span class="op">&gt;(</span>F<span class="op">))</span></code>, except that <code class="sourceCode cpp">E</code> is evaluated only once.</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_40" id="pnum_40">(2.3)</a></span> Otherwise, <code class="sourceCode cpp">subrange<span class="op">(</span>counted_iterator<span class="op">(</span>E, F<span class="op">)</span>, default_sentinel<span class="op">)</span></code>.</li>
</ul>
</blockquote>
<ol start="7" type="1">
<li>Add the following to <span>25.2 <a href="https://wg21.link/algorithms.requirements">[algorithms.requirements]</a></span> after p12:</li>
</ol>
<blockquote>
<div class="add" style="color: #006e28">
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_41" id="pnum_41">?</a></span> In the description of the algorithms, given an iterator <code class="sourceCode default">a</code> whose difference type is <code class="sourceCode default">D</code>, and an expression <code class="sourceCode default">n</code> of integer-like type other than <code class="sourceCode default"><em>cv</em> D</code>, the semantics of <code class="sourceCode default">a + n</code> and <code class="sourceCode default">a - n</code> are, respectively, those of <code class="sourceCode default">a + D(n)</code> and <code class="sourceCode default">a - D(n)</code>.</p>
</div>
</blockquote>
</div>
<h1 data-number="4" style="border-bottom:1px solid #cccccc" id="bibliography"><span class="header-section-number">4</span> References<a href="#bibliography" class="self-link"></a></h1>
<div id="refs" class="references hanging-indent" role="doc-bibliography">
<div id="ref-LWG3366">
<p>[LWG3366] Casey Carter. Narrowing conversions between integer and integer-class types. <br />
<a href="https://wg21.link/lwg3366">https://wg21.link/lwg3366</a></p>
</div>
<div id="ref-LWG3376">
<p>[LWG3376] Jonathan Wakely. “integer-like class type” is too restrictive. <br />
<a href="https://wg21.link/lwg3376">https://wg21.link/lwg3376</a></p>
</div>
<div id="ref-N4885">
<p>[N4885] Thomas Köppe. 2021-03-17. Working Draft, Standard for Programming Language C++. <br />
<a href="https://wg21.link/n4885">https://wg21.link/n4885</a></p>
</div>
<div id="ref-P1522R1">
<p>[P1522R1] Eric Niebler. 2019-07-28. Iterator Difference Type and Integer Overflow. <br />
<a href="https://wg21.link/p1522r1">https://wg21.link/p1522r1</a></p>
</div>
<div id="ref-P2321R1">
<p>[P2321R1] Tim Song. 2021-04-11. zip. <br />
<a href="https://wg21.link/p2321r1">https://wg21.link/p2321r1</a></p>
</div>
<div id="ref-P2367R0">
<p>[P2367R0] Tim Song. 2021-04-30. Remove misuses of list-initialization from Clause 24. <br />
<a href="https://wg21.link/p2367r0">https://wg21.link/p2367r0</a></p>
</div>
</div>
</div>
</div>
</body>
</html>
