<!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" />
  <title>[RE]YetAnother</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%;}
  </style>
  <style>
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 { } /* 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 { } /* 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;
}
:not(pre) > code {
background-color: #f6f8fa;
padding: 2px 4px 2px 4px;
}
div.sourceCode {
padding: 4px;
}
blockquote {
color: #666666;
margin: 0;
padding-left: 1em;
border-left: 0.5em #f2f4f7 solid;
}
ol.enumeratea { list-style-type: none; background: inherit; }
ol.enumerate { list-style-type: none; background: inherit; }

code.sourceCode > span { display: inline; }

div#refs p { padding-left: 32px; text-indent: -32px; }
</style>
  <link href="data:image/vnd.microsoft.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">
<div style="clear:both">
<p>Document number: P1324R1<br />
Date: 2023-1-05<br />
Audience: EWG<br />
Reply-To: Mihail Naydenov &lt;mihailnajdenov at gmail dot com&gt;</p>
<hr />
<h1 align="center">
RE: Yet another approach for constrained declarations
</h1>
<section id="revisions" data-number="1">
<h1 data-number="1"><span class="header-section-number">1</span> Revisions<a href="#revisions" class="self-link"></a></h1>
<p><strong>R1</strong></p>
<ul>
<li>Updated in the context of <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2677r2.pdf">Reconsidering concepts in-place syntax (P2677)</a></li>
<li>Added comparison to other languages</li>
<li>Added “Details” section</li>
<li>Removed discussion, related to out-of-date proposals.</li>
</ul>
<p><strong>R0 (2018)</strong></p>
<p>Initial release, not presented.</p>
</section>
<section id="abstract" data-number="2">
<h1 data-number="2"><span class="header-section-number">2</span> Abstract<a href="#abstract" class="self-link"></a></h1>
<p>This proposal is direct continuation (a “reply”) to <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2018/p1141r0.html">Yet another approach for constrained declarations (P1141)</a>.<br />
It proposes to go “one step further” and allow specifying a type in the place of <code>auto</code> in all constrained declarations, suggested by P1141. In other words <code>void sort(Sortable auto&amp; c);</code> becomes <code>void sort(Sortable S&amp; c);</code> and as a result the specified typename <code>S</code> is introduced for the current function.</p>
</section>
<section id="summary" data-number="3">
<h1 data-number="3"><span class="header-section-number">3</span> Summary<a href="#summary" class="self-link"></a></h1>
<p>This proposal is a pure extension of P1141.<br />
In a nutshell, allow</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1"></a><span class="dt">void</span> f<span class="op">(</span>Sortable <span class="kw">auto</span> x<span class="op">)</span>;</span>
<span id="cb1-2"><a href="#cb1-2"></a>Sortable <span class="kw">auto</span> f<span class="op">()</span>; </span>
<span id="cb1-3"><a href="#cb1-3"></a>Sortable <span class="kw">auto</span> x <span class="op">=</span> f<span class="op">()</span>; </span>
<span id="cb1-4"><a href="#cb1-4"></a><span class="kw">template</span> <span class="op">&lt;</span>Sortable <span class="kw">auto</span> N<span class="op">&gt;</span> <span class="dt">void</span> f<span class="op">()</span>;</span></code></pre></div>
<p><strong>to also be written as:</strong></p>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1"></a><span class="dt">void</span> f<span class="op">(</span>Sortable S x<span class="op">)</span>;</span>
<span id="cb2-2"><a href="#cb2-2"></a>Sortable S f<span class="op">()</span>; </span>
<span id="cb2-3"><a href="#cb2-3"></a>Sortable S x <span class="op">=</span> f<span class="op">()</span>; </span>
<span id="cb2-4"><a href="#cb2-4"></a><span class="kw">template</span> <span class="op">&lt;</span>Sortable S N<span class="op">&gt;</span> <span class="dt">void</span> f<span class="op">()</span>;</span></code></pre></div>
<p>Where <code>S</code> will be equivalent to a call to <code>decltype</code>, given the original P1141 declaration, or using the standard syntax:</p>
<div class="columns">
<div class="column" style="width:50%;">
<p><strong>Current</strong></p>
<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1"></a><span class="dt">void</span> f<span class="op">(</span>Sortable <span class="kw">auto</span><span class="op">&amp;&amp;</span> x<span class="op">)</span></span>
<span id="cb3-2"><a href="#cb3-2"></a><span class="op">{</span></span>
<span id="cb3-3"><a href="#cb3-3"></a>  <span class="kw">using</span> S <span class="op">=</span> <span class="kw">decltype</span><span class="op">(</span>x<span class="op">)</span>; <span class="co">//&lt; introduce S</span></span>
<span id="cb3-4"><a href="#cb3-4"></a>  <span class="co">// use S</span></span>
<span id="cb3-5"><a href="#cb3-5"></a><span class="op">}</span></span>
<span id="cb3-6"><a href="#cb3-6"></a></span>
<span id="cb3-7"><a href="#cb3-7"></a><span class="co">// OR, using the standard template syntax</span></span>
<span id="cb3-8"><a href="#cb3-8"></a></span>
<span id="cb3-9"><a href="#cb3-9"></a><span class="kw">template</span><span class="op">&lt;</span>Sortable S<span class="op">&gt;</span> <span class="co">//&lt; introduce S</span></span>
<span id="cb3-10"><a href="#cb3-10"></a><span class="dt">void</span> f<span class="op">(</span>S<span class="op">&amp;&amp;</span> x<span class="op">)</span></span>
<span id="cb3-11"><a href="#cb3-11"></a><span class="op">{</span></span>
<span id="cb3-12"><a href="#cb3-12"></a>  <span class="co">// use S</span></span>
<span id="cb3-13"><a href="#cb3-13"></a><span class="op">}</span></span></code></pre></div>
</div><div class="column" style="width:50%;">
<p><strong>Proposed</strong></p>
<div class="sourceCode" id="cb4"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb4-1"><a href="#cb4-1"></a><span class="dt">void</span> f<span class="op">(</span>Sortable S<span class="op">&amp;&amp;</span> x<span class="op">)</span> <span class="co">//&lt; introduce S</span></span>
<span id="cb4-2"><a href="#cb4-2"></a><span class="op">{</span></span>
<span id="cb4-3"><a href="#cb4-3"></a>  <span class="co">// use S</span></span>
<span id="cb4-4"><a href="#cb4-4"></a><span class="op">}</span></span></code></pre></div>
</div>
</div>
</section>
<section id="motivation" data-number="4">
<h1 data-number="4"><span class="header-section-number">4</span> Motivation<a href="#motivation" class="self-link"></a></h1>
<p>The main motivation is explored in many other papers, like for example <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2018/p0745r0.pdf">Concepts in-place syntax (P0745R0)</a>.<br />
It basically boils down to the fact, it is often just too convenient to have the type be known as it makes the already verbose generic code slightly less so:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb5-1"><a href="#cb5-1"></a><span class="kw">auto</span> f<span class="op">(</span>Concept <span class="kw">auto</span><span class="op">&amp;&amp;</span> x<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> something<span class="op">(</span>std<span class="op">::</span>forward<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">(</span>x<span class="op">)&gt;(</span>x<span class="op">))</span>; <span class="op">}</span> <span class="co">//&lt; current</span></span>
<span id="cb5-2"><a href="#cb5-2"></a><span class="kw">auto</span> f<span class="op">(</span>Concept T<span class="op">&amp;&amp;</span> x<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> something<span class="op">(</span>std<span class="op">::</span>forward<span class="op">&lt;</span>T<span class="op">&gt;(</span>x<span class="op">))</span>; <span class="op">}</span> <span class="co">//&lt; **proposed**</span></span>
<span id="cb5-3"><a href="#cb5-3"></a></span>
<span id="cb5-4"><a href="#cb5-4"></a><span class="kw">template</span><span class="op">&lt;</span>Number N<span class="op">&gt;</span> <span class="dt">void</span> f<span class="op">(</span>N x, N y<span class="op">)</span> <span class="op">{</span> <span class="op">}</span> <span class="co">//&lt; current</span></span>
<span id="cb5-5"><a href="#cb5-5"></a><span class="dt">void</span> f<span class="op">(</span>Number N x, N y<span class="op">)</span> <span class="op">{</span> <span class="op">}</span>` <span class="co">//&lt; **proposed**</span></span></code></pre></div>
<p>Also, when we need to constrain multiple arguments, terse form becomes impractical</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb6-1"><a href="#cb6-1"></a><span class="dt">void</span> f<span class="op">(</span>Number <span class="kw">auto</span> a, Concept <span class="kw">auto</span> b<span class="op">)</span> <span class="kw">requires</span> additional_constraint<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">(</span>a<span class="op">)</span>, <span class="kw">decltype</span><span class="op">(</span>b<span class="op">)&gt;</span> <span class="co">//&lt; current </span></span>
<span id="cb6-2"><a href="#cb6-2"></a><span class="kw">template</span><span class="op">&lt;</span>Number N, Concept C<span class="op">&gt;</span> <span class="dt">void</span> f<span class="op">(</span>N a, C b<span class="op">)</span> <span class="kw">requires</span> additional_constraint<span class="op">&lt;</span>N, C<span class="op">&gt;</span> <span class="co">//&lt; current </span></span>
<span id="cb6-3"><a href="#cb6-3"></a></span>
<span id="cb6-4"><a href="#cb6-4"></a><span class="dt">void</span> f<span class="op">(</span>Number N a, Concept C b<span class="op">)</span> <span class="kw">requires</span> additional_constraint<span class="op">&lt;</span>N, C<span class="op">&gt;</span> <span class="co">//&lt; **proposed**</span></span></code></pre></div>
<p>And sometimes it is even impossible to create a declaration using the terse form alone:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-1"></a>Concept <span class="kw">auto</span> f<span class="op">(</span>Number <span class="kw">auto</span> a, AnotherConcept<span class="op">&lt;</span><span class="co">/*?decltype(return)?*/</span><span class="op">&gt;</span> <span class="kw">auto</span> b<span class="op">)</span>;  <span class="co">//&lt; impossible</span></span>
<span id="cb7-2"><a href="#cb7-2"></a>Concept R f<span class="op">(</span>Number N a, AnotherConcept<span class="op">&lt;</span>R<span class="op">&gt;</span> U b<span class="op">)</span>; <span class="co">//&lt; **proposed**</span></span></code></pre></div>
<section id="why-this-syntax" data-number="4.1">
<h2 data-number="4.1"><span class="header-section-number">4.1</span> Why this syntax<a href="#why-this-syntax" class="self-link"></a></h2>
<section id="preserving-established-declaration-rules" data-number="4.1.1">
<h3 data-number="4.1.1"><span class="header-section-number">4.1.1</span> Preserving established declaration rules<a href="#preserving-established-declaration-rules" class="self-link"></a></h3>
<p>Consider what an <code>int n</code> states, reading it <em>right to left</em>.</p>
<p><em>“An object named ‘n’ of type integer.”</em></p>
<p>But what is a type here? A type is representation in memory - technically - but a <em>constraint</em> semantically. In the case here the value can only be in certain range and only whole numbers. One can say, the value of a variable is constrained by its type.<br />
In a way, we have been writing constrains for decades, constrains on values. Let’s rephrase the above with that in mind:</p>
<p><em>“Object named ‘n’, that can have [only] values, belonging to the set of the ‘int’ type.”</em></p>
<p>Ok, given the above, why should <em>constrains on types</em> be expressed any different?</p>
<p>Consider now <code>Number Num n</code>:</p>
<p><em>“Object named ‘n’, that can have [only] values, belonging to the set named ‘Num’, ‘Num’ can [only] be a type, belonging to the set of the ‘Number’ concept.”</em></p>
<p>As You can see, we are not inventing anything, we are just_ recursively applying a constraint,_ right to left, as we always have!<br />
In the case of constrained <code>auto</code>, we are simply <em>omitting</em> the name, effectively stating, we don’t needed it - <code>Number auto n</code>.</p>
<blockquote>
<p>Sidenote, there are proposals, advertising the possibility to be able to omit the variable name also. Using the syntax from <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2018/p1110r0.html">P1110R0</a>, we can have fully unnamed, fully unconstrained declaration - <code>auto __</code> - alongside the fully named, fully constrained declaration we just described, <em>or</em> any combination b/w named/unnamed variable, named/unnamed type, constrained/unconstrained type and constrained/unconstrained variable.</p>
</blockquote>
</section>
<section id="preserving-established-relationship-bw-auto-and-a-type-name" data-number="4.1.2">
<h3 data-number="4.1.2"><span class="header-section-number">4.1.2</span> Preserving established relationship b/w <code>auto</code> and a type name<a href="#preserving-established-relationship-bw-auto-and-a-type-name" class="self-link"></a></h3>
<p>It must be pointed out, <code>auto</code> already stands-in for an omitted type! At the moment in all, but one case (structured bindings), if we replace <code>auto</code> with a type we end up with a valid declaration, the meaning might change, but the declaration will be valid. This means the user already associates <code>auto</code> with a “type stand-in”, <em>even if</em> the declaration meaning changes by the substituting one with the other.<br />
There is no reason not to continue this relationship - if the user sees an <code>auto</code>, he <em>should</em> be able to write a type name in its place. What this name represents will be new (a name introduction), but the context is also new; besides we don’t stride <em>too</em> much away from the established usage.</p>
</section>
<section id="it-is-actually-the-tersest-form-possible-ever" data-number="4.1.3">
<h3 data-number="4.1.3"><span class="header-section-number">4.1.3</span> It is actually the tersest form possible <em>ever</em>!<a href="#it-is-actually-the-tersest-form-possible-ever" class="self-link"></a></h3>
<div class="sourceCode" id="cb8"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb8-1"><a href="#cb8-1"></a><span class="kw">auto</span> copy<span class="op">(</span>InputIterator <span class="kw">auto</span> begin, <span class="kw">decltype</span><span class="op">(</span>begin<span class="op">)</span> end, OutputIterator <span class="kw">auto</span> out<span class="op">)</span> <span class="op">-&gt;</span> <span class="kw">decltype</span><span class="op">(</span>out<span class="op">)</span>;</span>
<span id="cb8-2"><a href="#cb8-2"></a><span class="kw">template</span><span class="op">&lt;</span>InputIterator It, OutputIterator OIt<span class="op">&gt;</span> copy<span class="op">(</span>It begin, It end, OIt out<span class="op">)</span> <span class="op">-&gt;</span> OIt; </span>
<span id="cb8-3"><a href="#cb8-3"></a><span class="kw">auto</span> copy<span class="op">(</span>InputIterator It begin, It end, OutputIterator OIt out<span class="op">)</span> <span class="op">-&gt;</span> OIt;  <span class="co">//&lt; **proposed**</span></span>
<span id="cb8-4"><a href="#cb8-4"></a></span>
<span id="cb8-5"><a href="#cb8-5"></a><span class="co">// Even compared to the original, concepts-instead-of-types syntax!</span></span>
<span id="cb8-6"><a href="#cb8-6"></a><span class="kw">auto</span> copy<span class="op">(</span>InputIterator being, <span class="kw">decltype</span><span class="op">(</span>begin<span class="op">)</span> end, OutputIterator out<span class="op">)</span> <span class="op">-&gt;</span> <span class="kw">decltype</span><span class="op">(</span>out<span class="op">)</span>; </span></code></pre></div>
<p>Compared to other contemporary languages, this syntax holds its ground. This is because we have <strong>zero extra syntactical noise.</strong></p>
<div class="columns">
<div class="column" style="width:50%;">
<p><strong>Rust</strong></p>
<div class="sourceCode" id="cb1"><pre class="sourceCode rust"><code class="sourceCode rust"><span id="cb1-1"><a href="#cb1-1"></a>notify(item: &amp;<span class="kw">impl</span> Summary)</span></code></pre></div>
</div><div class="column" style="width:50%;">
<p><strong>Proposed</strong></p>
<div class="sourceCode" id="cb10"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb10-1"><a href="#cb10-1"></a>notify<span class="op">(</span>Summary S<span class="op">&amp;</span> item<span class="op">)</span></span></code></pre></div>
</div>
</div>
<div class="columns">
<div class="column" style="width:50%;">
<p><strong>Carbon</strong></p>
<div class="sourceCode" id="cb2"><pre class="sourceCode rust"><code class="sourceCode rust"><span id="cb2-1"><a href="#cb2-1"></a>PrintIt<span class="op">[</span>T:! Printable<span class="op">]</span>(p: T*)</span></code></pre></div>
</div><div class="column" style="width:50%;">
<p><strong>Proposed</strong></p>
<div class="sourceCode" id="cb12"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb12-1"><a href="#cb12-1"></a>PrintIt<span class="op">(</span>Printable T<span class="op">*</span> p<span class="op">)</span></span></code></pre></div>
</div>
</div>
<div class="columns">
<div class="column" style="width:50%;">
<p><strong>Swift</strong></p>
<div class="sourceCode" id="cb3"><pre class="sourceCode rust"><code class="sourceCode rust"><span id="cb3-1"><a href="#cb3-1"></a>someFunction&lt;T: SomeThing&gt;(someT: T)</span></code></pre></div>
</div><div class="column" style="width:50%;">
<p><strong>Proposed</strong></p>
<div class="sourceCode" id="cb14"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb14-1"><a href="#cb14-1"></a>someFunction<span class="op">(</span>SomeThing T someT<span class="op">)</span></span></code></pre></div>
</div>
</div>
<p>C++ has long been considered verbose, when it comes to metaprogramming. Now the tables have turned and it is actually the cleanest.<br />
In fact <strong>the cleanest possible.</strong></p>
<blockquote>
<p>One can argue, if we had concepts-instead-of-types, <em>then</em> we would have “the cleanest possible” form. This is true as long as there are no extra constrains that need to be applied. In that case, a <code>decltype</code> would be needed and the results will not be as pretty.</p>
</blockquote>
</section>
<section id="ok-but-still-two-declarations-in-one-expression-this-is-madness" data-number="4.1.4">
<h3 data-number="4.1.4"><span class="header-section-number">4.1.4</span> “OK, but still two declarations in one expression, this is madness!”<a href="#ok-but-still-two-declarations-in-one-expression-this-is-madness" class="self-link"></a></h3>
<p>Type and variable declaration have always been in C++, inherited from C. And they still have their uses.</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb15-1"><a href="#cb15-1"></a></span>
<span id="cb15-2"><a href="#cb15-2"></a><span class="dt">void</span> process<span class="op">(</span><span class="kw">class</span> C<span class="op">&amp;</span> c<span class="op">)</span>;</span>
<span id="cb15-3"><a href="#cb15-3"></a><span class="co">//...</span></span>
<span id="cb15-4"><a href="#cb15-4"></a><span class="dt">void</span> something<span class="op">()</span></span>
<span id="cb15-5"><a href="#cb15-5"></a><span class="op">{</span></span>
<span id="cb15-6"><a href="#cb15-6"></a>  process<span class="op">(</span>get_c<span class="op">())</span>;</span>
<span id="cb15-7"><a href="#cb15-7"></a><span class="op">}</span></span>
<span id="cb15-8"><a href="#cb15-8"></a><span class="co">// ...</span></span>
<span id="cb15-9"><a href="#cb15-9"></a><span class="kw">class</span> C <span class="op">{...}</span>;</span>
<span id="cb15-10"><a href="#cb15-10"></a><span class="co">// ...</span></span>
<span id="cb15-11"><a href="#cb15-11"></a><span class="dt">void</span> process<span class="op">(</span>C<span class="op">&amp;</span> c<span class="op">)</span></span>
<span id="cb15-12"><a href="#cb15-12"></a><span class="op">{</span></span>
<span id="cb15-13"><a href="#cb15-13"></a>  <span class="co">// definition</span></span>
<span id="cb15-14"><a href="#cb15-14"></a><span class="op">}</span></span></code></pre></div>
<p>also</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb16-1"><a href="#cb16-1"></a><span class="kw">class</span> C</span>
<span id="cb16-2"><a href="#cb16-2"></a><span class="op">{</span></span>
<span id="cb16-3"><a href="#cb16-3"></a>  <span class="co">// ...</span></span>
<span id="cb16-4"><a href="#cb16-4"></a><span class="kw">private</span><span class="op">:</span></span>
<span id="cb16-5"><a href="#cb16-5"></a>  <span class="kw">const</span> <span class="kw">class</span> Helper<span class="op">*</span> sos<span class="op">()</span> <span class="kw">const</span>; </span>
<span id="cb16-6"><a href="#cb16-6"></a><span class="op">}</span>;</span></code></pre></div>
<p>As shown, two-in-one declaration is nothing new and although the above expressions can be written separately, this does not change the fact, an extremely similar syntax, with de facto the same meaning (introduce a typename inline) is already here - we just reinvent it for the new era.</p>
<blockquote>
<p>In contrast to the elaborate type specifier the declaration is limited to the current function declaration, as-if the type was declared as template parameter!</p>
</blockquote>
<p>By this point it should be evident, enabling type name introduction in the proposed way, not only does not introduce new constructs and concepts, but <em>serve to reinforce established ones.</em></p>
</section>
</section>
</section>
<section id="details" data-number="5">
<h1 data-number="5"><span class="header-section-number">5</span> Details<a href="#details" class="self-link"></a></h1>
<p>In order to prevent confusion in the case, parameter names are omitted from a function declaration, <strong>proposed</strong> is to always treat function signatures, with two identifiers for a parameter, as the well known typename + param name pair.</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb17-1"><a href="#cb17-1"></a><span class="dt">void</span> f<span class="op">(</span>Number N<span class="op">)</span>; <span class="co">//&lt; type and param name</span></span></code></pre></div>
<p>In case <code>Number</code> is a <strong>concept</strong>, <em>this will fail to compile.</em><br />
The user will have to use a different syntax:</p>
<div class="sourceCode" id="cb18"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb18-1"><a href="#cb18-1"></a><span class="dt">void</span> f<span class="op">(</span>Number <span class="kw">auto</span><span class="op">)</span>; <span class="co">//&lt; Not introdusing a typename</span></span>
<span id="cb18-2"><a href="#cb18-2"></a><span class="dt">void</span> f<span class="op">(</span>Number N __<span class="op">)</span>; <span class="co">//&lt; Using a placeholder syntax (P1110)</span></span>
<span id="cb18-3"><a href="#cb18-3"></a></span>
<span id="cb18-4"><a href="#cb18-4"></a><span class="co">// (or any of the complete syntax options)</span></span></code></pre></div>
<p>With the above limitation, generic functions will remain recognizable at a glance, even when using the terse syntax:</p>
<div class="sourceCode" id="cb19"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb19-1"><a href="#cb19-1"></a><span class="dt">void</span> f<span class="op">(</span>Foo<span class="op">)</span>       <span class="co">//&lt; one id: standard function</span></span>
<span id="cb19-2"><a href="#cb19-2"></a><span class="dt">void</span> f<span class="op">(</span><span class="kw">class</span> Foo<span class="op">)</span> <span class="co">//&lt; one id and class: standard function</span></span>
<span id="cb19-3"><a href="#cb19-3"></a><span class="dt">void</span> f<span class="op">(</span>Foo <span class="kw">auto</span><span class="op">)</span>  <span class="co">//&lt; one id and auto: generic function</span></span>
<span id="cb19-4"><a href="#cb19-4"></a></span>
<span id="cb19-5"><a href="#cb19-5"></a><span class="dt">void</span> f<span class="op">(</span>Foo V<span class="op">)</span>     <span class="co">//&lt; two ids: standard function (as always)</span></span>
<span id="cb19-6"><a href="#cb19-6"></a><span class="dt">void</span> f<span class="op">(</span>Foo F V<span class="op">)</span>   <span class="co">//&lt; *three* ids: generic function (proposed)</span></span></code></pre></div>
</section>
<section id="not-proposed-but-worth-mentioning" data-number="6">
<h1 data-number="6"><span class="header-section-number">6</span> Not proposed, but worth mentioning<a href="#not-proposed-but-worth-mentioning" class="self-link"></a></h1>
<p>Having return type name introduction, <em>combined</em> with trailing return type could enable us to have an interesting usage:</p>
<div class="sourceCode" id="cb20"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb20-1"><a href="#cb20-1"></a>Number Ret  <span class="co">//&lt; introduce Ret typename</span></span>
<span id="cb20-2"><a href="#cb20-2"></a>function<span class="op">(</span>Number N a, N b<span class="op">)</span> <span class="op">-&gt;</span> <span class="kw">decltype</span><span class="op">(</span>something<span class="op">(</span>x, b<span class="op">))</span></span>
<span id="cb20-3"><a href="#cb20-3"></a><span class="op">{</span></span>
<span id="cb20-4"><a href="#cb20-4"></a>  Ret ret; <span class="co">//&lt; easily declare and use the ret variable</span></span>
<span id="cb20-5"><a href="#cb20-5"></a>  <span class="op">...</span></span>
<span id="cb20-6"><a href="#cb20-6"></a>  <span class="cf">return</span> ret;</span>
<span id="cb20-7"><a href="#cb20-7"></a><span class="op">}</span></span></code></pre></div>
<p>also</p>
<div class="sourceCode" id="cb21"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb21-1"><a href="#cb21-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span></span>
<span id="cb21-2"><a href="#cb21-2"></a>Container Ret <span class="co">//&lt; introduce Ret typename</span></span>
<span id="cb21-3"><a href="#cb21-3"></a>function<span class="op">()</span> <span class="op">-&gt;</span> std<span class="op">::</span>map<span class="op">&lt;</span>Key, T, <span class="op">[](</span><span class="kw">const</span> T<span class="op">&amp;</span> a, <span class="kw">const</span> T<span class="op">&amp;</span> b<span class="op">){</span> <span class="op">...</span> <span class="op">}</span>, MyAllocator<span class="op">&gt;</span></span>
<span id="cb21-4"><a href="#cb21-4"></a><span class="op">{</span></span>
<span id="cb21-5"><a href="#cb21-5"></a>  Ret ret; <span class="co">//&lt; easily declare and use the ret variable</span></span>
<span id="cb21-6"><a href="#cb21-6"></a>  <span class="op">...</span></span>
<span id="cb21-7"><a href="#cb21-7"></a>  <span class="cf">return</span> ret;</span>
<span id="cb21-8"><a href="#cb21-8"></a><span class="op">}</span></span></code></pre></div>
<p>Pretty neat.<br />
Current alternatives are all inferior:</p>
<div class="sourceCode" id="cb22"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb22-1"><a href="#cb22-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span></span>
<span id="cb22-2"><a href="#cb22-2"></a>Container <span class="kw">auto</span> </span>
<span id="cb22-3"><a href="#cb22-3"></a>function<span class="op">()</span> <span class="op">-&gt;</span> std<span class="op">::</span>map<span class="op">&lt;</span>Key, T, <span class="op">[](</span><span class="kw">const</span> T<span class="op">&amp;</span> a, <span class="kw">const</span> T<span class="op">&amp;</span> b<span class="op">){</span> <span class="op">...</span> <span class="op">}</span>, MyAllocator<span class="op">&gt;</span></span>
<span id="cb22-4"><a href="#cb22-4"></a><span class="op">{</span></span>
<span id="cb22-5"><a href="#cb22-5"></a>  std<span class="op">::</span>map<span class="op">&lt;</span>Key, T, <span class="op">[](</span><span class="kw">const</span> T<span class="op">&amp;</span> a, <span class="kw">const</span> T<span class="op">&amp;</span> b<span class="op">){</span> <span class="op">...</span> <span class="op">}</span>, MyAllocator<span class="op">&gt;</span> ret; <span class="co">//&lt; duplication </span></span>
<span id="cb22-6"><a href="#cb22-6"></a>  <span class="op">...</span></span>
<span id="cb22-7"><a href="#cb22-7"></a>  <span class="cf">return</span> ret;</span>
<span id="cb22-8"><a href="#cb22-8"></a><span class="op">}</span></span></code></pre></div>
<p>or</p>
<div class="sourceCode" id="cb23"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb23-1"><a href="#cb23-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span></span>
<span id="cb23-2"><a href="#cb23-2"></a>Container <span class="kw">auto</span> </span>
<span id="cb23-3"><a href="#cb23-3"></a>function<span class="op">()</span> <span class="co">//&lt; Return type, hidden, not part of the signature</span></span>
<span id="cb23-4"><a href="#cb23-4"></a><span class="op">{</span></span>
<span id="cb23-5"><a href="#cb23-5"></a>  std<span class="op">::</span>map<span class="op">&lt;</span>Key, T, <span class="op">[](</span><span class="kw">const</span> T<span class="op">&amp;</span> a, <span class="kw">const</span> T<span class="op">&amp;</span> b<span class="op">){</span> <span class="op">...</span> <span class="op">}</span>, MyAllocator<span class="op">&gt;</span> ret; </span>
<span id="cb23-6"><a href="#cb23-6"></a>  <span class="op">...</span></span>
<span id="cb23-7"><a href="#cb23-7"></a>  <span class="cf">return</span> ret;</span>
<span id="cb23-8"><a href="#cb23-8"></a><span class="op">}</span></span></code></pre></div>
</section>
<section id="related-work" data-number="7">
<h1 data-number="7"><span class="header-section-number">7</span> Related work<a href="#related-work" class="self-link"></a></h1>
<p>P2677<a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a> has similar if not the same goals to current proposal. Here is side by side comparison:</p>
<div class="columns">
<div class="column" style="width:33%;">
<p><strong>Current</strong></p>
<div class="sourceCode" id="cb24"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb24-1"><a href="#cb24-1"></a></span>
<span id="cb24-2"><a href="#cb24-2"></a><span class="kw">template</span><span class="op">&lt;</span>integral T<span class="op">&gt;</span></span>
<span id="cb24-3"><a href="#cb24-3"></a>T gcd<span class="op">(</span>T l, T r<span class="op">)</span>;</span>
<span id="cb24-4"><a href="#cb24-4"></a></span>
<span id="cb24-5"><a href="#cb24-5"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">typename</span> X, <span class="kw">typename</span> <span class="op">...</span>Ts<span class="op">&gt;</span></span>
<span id="cb24-6"><a href="#cb24-6"></a><span class="dt">void</span> wrap<span class="op">(</span>X x, Ts<span class="op">&amp;&amp;</span> <span class="op">...</span>ts<span class="op">)</span>;</span>
<span id="cb24-7"><a href="#cb24-7"></a></span>
<span id="cb24-8"><a href="#cb24-8"></a><span class="kw">template</span><span class="op">&lt;</span>Animal Predator, Animal Prey<span class="op">&gt;</span></span>
<span id="cb24-9"><a href="#cb24-9"></a><span class="dt">void</span></span>
<span id="cb24-10"><a href="#cb24-10"></a>simulate<span class="op">(</span>Predator <span class="op">&amp;</span>predator, Prey <span class="op">&amp;</span>prey<span class="op">)</span>;</span>
<span id="cb24-11"><a href="#cb24-11"></a></span>
<span id="cb24-12"><a href="#cb24-12"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">typename</span> T, <span class="kw">typename</span> U<span class="op">&gt;</span></span>
<span id="cb24-13"><a href="#cb24-13"></a>  <span class="kw">requires</span> convertible_to<span class="op">&lt;</span>T, U<span class="op">&gt;</span></span>
<span id="cb24-14"><a href="#cb24-14"></a><span class="dt">void</span> f<span class="op">(</span>T t, U u<span class="op">)</span>;</span>
<span id="cb24-15"><a href="#cb24-15"></a></span>
<span id="cb24-16"><a href="#cb24-16"></a>arithmetic <span class="kw">auto</span> a <span class="op">=</span> calculation<span class="op">()</span>;</span>
<span id="cb24-17"><a href="#cb24-17"></a><span class="kw">using</span> A <span class="op">=</span> <span class="kw">decltype</span><span class="op">(</span>a<span class="op">)</span>;</span>
<span id="cb24-18"><a href="#cb24-18"></a>A a2 <span class="op">=</span> refine<span class="op">(</span>a<span class="op">)</span>;</span></code></pre></div>
</div><div class="column" style="width:33%;">
<p><strong>P2677</strong></p>
<div class="sourceCode" id="cb25"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb25-1"><a href="#cb25-1"></a></span>
<span id="cb25-2"><a href="#cb25-2"></a><span class="co">// No more semantic change</span></span>
<span id="cb25-3"><a href="#cb25-3"></a><span class="kw">auto</span> gcd<span class="op">(</span>integral <span class="kw">auto</span><span class="op">:</span>T l, T r<span class="op">)</span> <span class="op">-&gt;</span> T;</span>
<span id="cb25-4"><a href="#cb25-4"></a></span>
<span id="cb25-5"><a href="#cb25-5"></a><span class="co">// Forwarding only needs typenames for ts</span></span>
<span id="cb25-6"><a href="#cb25-6"></a><span class="dt">void</span> wrap<span class="op">(</span><span class="kw">auto</span> x, <span class="kw">auto</span><span class="op">:</span>Ts<span class="op">&amp;&amp;</span> <span class="op">...</span>ts<span class="op">)</span>;</span>
<span id="cb25-7"><a href="#cb25-7"></a></span>
<span id="cb25-8"><a href="#cb25-8"></a></span>
<span id="cb25-9"><a href="#cb25-9"></a><span class="dt">void</span></span>
<span id="cb25-10"><a href="#cb25-10"></a>simulate<span class="op">(</span>Animal <span class="kw">auto</span><span class="op">:</span>Predator <span class="op">&amp;</span>predator,</span>
<span id="cb25-11"><a href="#cb25-11"></a>         Animal <span class="kw">auto</span><span class="op">:</span>Prey <span class="op">&amp;</span>prey<span class="op">)</span>;</span>
<span id="cb25-12"><a href="#cb25-12"></a></span>
<span id="cb25-13"><a href="#cb25-13"></a><span class="dt">void</span> f<span class="op">(</span><span class="kw">auto</span><span class="op">:</span>T t, <span class="kw">auto</span><span class="op">:</span>U u<span class="op">)</span></span>
<span id="cb25-14"><a href="#cb25-14"></a>  <span class="kw">requires</span> convertible_to<span class="op">&lt;</span>T, U<span class="op">&gt;</span>;</span>
<span id="cb25-15"><a href="#cb25-15"></a></span>
<span id="cb25-16"><a href="#cb25-16"></a></span>
<span id="cb25-17"><a href="#cb25-17"></a>arithmetic <span class="kw">auto</span><span class="op">:</span>A a <span class="op">=</span> calculation<span class="op">()</span>;</span>
<span id="cb25-18"><a href="#cb25-18"></a>A a2 <span class="op">=</span> refine<span class="op">(</span>a<span class="op">)</span>;</span></code></pre></div>
</div><div class="column" style="width:33%;">
<p><strong>This Proposal</strong></p>
<div class="sourceCode" id="cb26"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb26-1"><a href="#cb26-1"></a></span>
<span id="cb26-2"><a href="#cb26-2"></a><span class="co">// No more semantic change</span></span>
<span id="cb26-3"><a href="#cb26-3"></a><span class="kw">auto</span> gcd<span class="op">(</span>integral T l, T r<span class="op">)</span> <span class="op">-&gt;</span> T;</span>
<span id="cb26-4"><a href="#cb26-4"></a></span>
<span id="cb26-5"><a href="#cb26-5"></a><span class="co">// Forwarding only needs typenames for ts</span></span>
<span id="cb26-6"><a href="#cb26-6"></a><span class="dt">void</span> wrap<span class="op">(</span><span class="kw">auto</span> x, Any Ts<span class="op">&amp;&amp;</span> <span class="op">...</span>ts<span class="op">)</span>;</span>
<span id="cb26-7"><a href="#cb26-7"></a></span>
<span id="cb26-8"><a href="#cb26-8"></a></span>
<span id="cb26-9"><a href="#cb26-9"></a><span class="dt">void</span></span>
<span id="cb26-10"><a href="#cb26-10"></a>simulate<span class="op">(</span>Animal Predator <span class="op">&amp;</span>predator,</span>
<span id="cb26-11"><a href="#cb26-11"></a>         Animal Prey <span class="op">&amp;</span>prey<span class="op">)</span>;</span>
<span id="cb26-12"><a href="#cb26-12"></a></span>
<span id="cb26-13"><a href="#cb26-13"></a><span class="dt">void</span> f<span class="op">(</span>Any T t, Any U u<span class="op">)</span></span>
<span id="cb26-14"><a href="#cb26-14"></a>  <span class="kw">requires</span> convertible_to<span class="op">&lt;</span>T, U<span class="op">&gt;</span>;</span>
<span id="cb26-15"><a href="#cb26-15"></a></span>
<span id="cb26-16"><a href="#cb26-16"></a></span>
<span id="cb26-17"><a href="#cb26-17"></a>arithmetic A a <span class="op">=</span> calculation<span class="op">()</span>;</span>
<span id="cb26-18"><a href="#cb26-18"></a>A a2 <span class="op">=</span> refine<span class="op">(</span>a<span class="op">)</span>;</span></code></pre></div>
</div>
</div>
<p>As you can see, both solutions strive to achieve similar goals. There are few differences.<br />
First, P2677 is considerably more verbose. It also relies on introducing a new variable introduction syntax and a new use of <code>auto</code>. In contrast, current solution is a natural extension of the language (see <strong>Why this syntax</strong>).<br />
Second, P2677 has the ability to introduce names for unconstrained types. This proposal does not consider this a desirable feature. Unconstrained types are at this point <em>legacy.</em> All new types should be constrained. If the user really wants an unconstrained type, he/she is free to use a pass-all concept, like the above suggested <code>Any</code>, and <em>be explicit about it</em>. Later one can trivially track and replace the <code>Any</code> concept with a more constrained one, lessening the loose typing if desired.</p>
</section>
<section id="conclusion" data-number="8">
<h1 data-number="8"><span class="header-section-number">8</span> Conclusion<a href="#conclusion" class="self-link"></a></h1>
<p>Allowing concepts to introduce the type they constrain will radically change the the way we write generic code. Doing it so with effectively <strong>zero new constructs, reusing established practices</strong>, will ease the adoption of the terse form as the preferred one, possibly even for <em>unconstrained cases.</em></p>
</section>
<section class="footnotes" role="doc-endnotes">
<hr />
<ol>
<li id="fn1" role="doc-endnote"><p>Reconsidering concepts in-place syntax: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2677r2.pdf">Reconsidering concepts in-place syntax (P2677)</a><a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
</div>
</div>
</body>
</html>
