<!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="2022-01-25" />
  <title>generator&lt;T&gt; should have T&amp;&amp; reference_type</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;
text-align: justify;
}
@media screen and (max-width: 30em) {
body {
margin: 1.5em;
}
}
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>
  <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">generator<T> should have T&amp;&amp; reference_type</h1>

<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P2529R0</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2022-01-25</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>
      Library Evolution Working Group<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to:</td>
    <td>
      Mathias Stearn<br>&lt;<a href="mailto:redbeard0531@gmail.com" class="email">redbeard0531@gmail.com</a>&gt;<br>
    </td>
  </tr>
</table>

</header>
<div style="clear:both">
<div id="TOC" role="doc-toc">
<h1 id="toctitle">Contents</h1>
<ul>
<li><a href="#introduction"><span class="toc-section-number">1</span> Introduction<span></span></a></li>
<li><a href="#starting-point"><span class="toc-section-number">2</span> Starting point<span></span></a>
<ul>
<li><a href="#things-that-we-probably-all-agree-about"><span class="toc-section-number">2.1</span> Things that we (probably) all agree about<span></span></a></li>
<li><a href="#major-point-of-disagreement"><span class="toc-section-number">2.2</span> Major point of disagreement<span></span></a></li>
</ul></li>
<li><a href="#justification"><span class="toc-section-number">3</span> Justification<span></span></a>
<ul>
<li><a href="#performance-and-move-only-type-support"><span class="toc-section-number">3.1</span> Performance and move-only type support<span></span></a></li>
<li><a href="#consistency-with-the-rest-of-the-language."><span class="toc-section-number">3.2</span> Consistency with the rest of the language.<span></span></a></li>
<li><a href="#best-match-for-the-generatort-use-cases"><span class="toc-section-number">3.3</span> Best match for the <code class="sourceCode cpp">generator<span class="op">&lt;</span>T<span class="op">&gt;</span></code> use cases<span></span></a></li>
<li><a href="#simplicity"><span class="toc-section-number">3.4</span> Simplicity<span></span></a></li>
</ul></li>
<li><a href="#responses-to-objections"><span class="toc-section-number">4</span> Responses to objections<span></span></a>
<ul>
<li><a href="#returning-an-rvalue-reference-from-it-violates-input_or_output_iterator-semantic-requirements"><span class="toc-section-number">4.1</span> Returning an rvalue reference from <code class="sourceCode cpp"><span class="op">*</span>it</code> violates <code class="sourceCode cpp">input_or_output_iterator</code> semantic requirements<span></span></a></li>
<li><a href="#even-if-valid-rvalue-returning-ranges-are-unsafe-to-consume"><span class="toc-section-number">4.2</span> Even if valid, rvalue-returning ranges are unsafe to consume<span></span></a></li>
<li><a href="#implicitly-moves-in-body-of-generator"><span class="toc-section-number">4.3</span> Implicitly moves in body of generator<span></span></a></li>
<li><a href="#implicitly-copies-in-body-of-generator"><span class="toc-section-number">4.4</span> Implicitly copies in body of generator<span></span></a></li>
<li><a href="#we-have-generatort-for-people-that-want-moves-and-it-is-more-explicit"><span class="toc-section-number">4.5</span> We have <code class="sourceCode cpp">generator<span class="op">&lt;</span>T<span class="op">&amp;&amp;&gt;</span></code> for people that want moves and it is more explicit<span></span></a></li>
</ul></li>
<li><a href="#example-implementation"><span class="toc-section-number">5</span> Example implementation<span></span></a></li>
<li><a href="#bibliography"><span class="toc-section-number">6</span> References<span></span></a></li>
</ul>
</div>
<style>
dt {
  margin-top: 1em;
  font-weight: bold;
}
dd > p { margin: 0; }
pre.sourceCode { padding: .5em; }

body          code { background: #f6f8fa; }
body .wording code { background: inherit; }
body .wording code * { color: inherit; }

code span.co { font-style: normal; }

blockquote {
  background: #f9f9f9;
  border-left: 10px solid #ccc;
  margin: 1.5em 10px;
  padding: 0.5em 10px;
  quotes: "\201C""\201D""\2018""\2019";
}
blockquote:before {
  color: #ccc;
  content: open-quote;
  font-size: 4em;
  line-height: 0.1em;
  margin-right: 0.25em;
  vertical-align: -0.4em;
}
blockquote p {
  display: inline;
}

#hide_rm:checked ~ .wording .rm {
  display: none;
}

.wording {
  margin-left: 40px;
}
.wording .instruction {
  font-size: large;
  margin-left: -40px;
}

.wording .grammar {
  padding-left: 4em;
  word-spacing: .33em;
}

label { font-weight: bold; }

</style>
<h1 data-number="1" id="introduction"><span class="header-section-number">1</span> Introduction<a href="#introduction" class="self-link"></a></h1>
<p>This paper attempts to make the case that the <code class="sourceCode cpp">generator<span class="op">&lt;</span>T<span class="op">&gt;</span></code>, as proposed in <span class="citation" data-cites="P2502R0">[<a href="#ref-P2502R0" role="doc-biblioref">P2502R0</a>]</span> (and earlier in <span class="citation" data-cites="P2168R3">[<a href="#ref-P2168R3" role="doc-biblioref">P2168R3</a>]</span>), should use <code class="sourceCode cpp">T<span class="op">&amp;&amp;</span></code> as its <code class="sourceCode cpp">reference_type</code>. While this paper is critiquing a specific design choice in that paper, I would like to be clear that it is not intended in any way as a slight against its author. I very much appreciate the work that Casey has done both specifically on <code class="sourceCode cpp">generator</code> and on ranges in general.</p>
<p><em>Note:</em> An updated draft of D2502R1 was sent out after this paper was completed, and I have not had time to fully process the changes and modify this paper (other than this paragraph) to reflect the update. I think the most notable change is that now <code class="sourceCode cpp">generator<span class="op">&lt;</span>T<span class="op">&amp;&amp;&gt;</span></code> in that proposal has the <code class="sourceCode cpp"><span class="kw">co_yield</span></code> behavior I am proposing for <code class="sourceCode cpp">generator<span class="op">&lt;</span>T<span class="op">&gt;</span></code>, but <em>not</em> proposing for <code class="sourceCode cpp">generator<span class="op">&lt;</span>T<span class="op">&amp;&amp;&gt;</span></code>. I think it is inconsistent with my model to have it for both <code class="sourceCode cpp">generator<span class="op">&lt;</span>T<span class="op">&gt;</span></code> and <code class="sourceCode cpp">generator<span class="op">&lt;</span>T<span class="op">&amp;&amp;&gt;</span></code>, since you cannot currently pass a <code class="sourceCode cpp">T</code> lvalue to a function taking <code class="sourceCode cpp">T<span class="op">&amp;&amp;</span></code>.</p>
<h1 data-number="2" id="starting-point"><span class="header-section-number">2</span> Starting point<a href="#starting-point" class="self-link"></a></h1>
<h2 data-number="2.1" id="things-that-we-probably-all-agree-about"><span class="header-section-number">2.1</span> Things that we (probably) all agree about<a href="#things-that-we-probably-all-agree-about" class="self-link"></a></h2>
<ul>
<li>Everything about <code class="sourceCode cpp">generator<span class="op">&lt;</span>U<span class="op">&gt;</span></code> where <code class="sourceCode cpp">U</code> is <code class="sourceCode cpp">T<span class="op">&amp;</span></code>, <code class="sourceCode cpp"><span class="kw">const</span> T<span class="op">&amp;</span></code>, or <code class="sourceCode cpp">T<span class="op">&amp;&amp;</span></code>
<ul>
<li><code class="sourceCode cpp">reference_type</code> should be <code class="sourceCode cpp">U</code> and the default <code class="sourceCode cpp">value_type</code> should be <code class="sourceCode cpp">remove_cvref<span class="op">&lt;</span>U<span class="op">&gt;</span></code></li>
<li>The signature of <code class="sourceCode cpp">promise_type<span class="op">::</span>yield_value</code> should be <code class="sourceCode cpp">yield_value<span class="op">(</span>U<span class="op">)</span></code>, which may restrict what can be passed to <code class="sourceCode cpp"><span class="kw">co_yield</span></code></li>
</ul></li>
<li>We don’t care about <code class="sourceCode cpp">generator<span class="op">&lt;</span>U<span class="op">&gt;</span></code> where <code class="sourceCode cpp">U</code> is <code class="sourceCode cpp"><span class="kw">const</span> T</code>, <code class="sourceCode cpp"><span class="kw">const</span> T<span class="op">&amp;&amp;</span></code> or has <code class="sourceCode cpp"><span class="kw">volatile</span></code> anywhere
<ul>
<li>Perhaps some of these should <em>work</em>, but it isn’t worth spending any committee time to make them work <em>well</em></li>
</ul></li>
<li>For <code class="sourceCode cpp">generator<span class="op">&lt;</span>T<span class="op">&gt;</span></code> where <code class="sourceCode cpp">T</code> has no cvref qualifications:
<ul>
<li>default <code class="sourceCode cpp">value_type</code> should be <code class="sourceCode cpp">T</code></li>
<li><code class="sourceCode cpp">reference_type</code> should NOT be <code class="sourceCode cpp">T</code>, <code class="sourceCode cpp"><span class="kw">const</span> T</code>, or <code class="sourceCode cpp"><span class="kw">const</span> T<span class="op">&amp;&amp;</span></code>
<ul>
<li><code class="sourceCode cpp">T</code> was proposed in <span class="citation" data-cites="P2168R3">[<a href="#ref-P2168R3" role="doc-biblioref">P2168R3</a>]</span>, but the authors have agreed that it is not the right choice</li>
<li>This leaves <code class="sourceCode cpp">T<span class="op">&amp;</span></code>, <code class="sourceCode cpp"><span class="kw">const</span> T<span class="op">&amp;</span></code> and <code class="sourceCode cpp">T<span class="op">&amp;&amp;</span></code> as options worth considering</li>
</ul></li>
<li>support <code class="sourceCode cpp"><span class="kw">co_yield</span> EXPR</code> where <code class="sourceCode cpp">EXPR</code> is either an lvalue or rvalue
<ul>
<li>note that this is different from <code class="sourceCode cpp">generator<span class="op">&lt;</span>T<span class="op">&amp;&amp;&gt;</span></code> which only allows yielding rvalues</li>
<li>lvalues and constant rvalues passed to <code class="sourceCode cpp"><span class="kw">co_yield</span></code> must not be able to be mutated from outside the function</li>
<li>non-const rvalues passed to <code class="sourceCode cpp"><span class="kw">co_yield</span></code> may be modified or at least moved from (that isn’t to say that we agree that they must be, only that I do not anticipate objections to rvalues being mutated)</li>
</ul></li>
</ul></li>
</ul>
<h2 data-number="2.2" id="major-point-of-disagreement"><span class="header-section-number">2.2</span> Major point of disagreement<a href="#major-point-of-disagreement" class="self-link"></a></h2>
<ul>
<li>For <code class="sourceCode cpp">generator<span class="op">&lt;</span>T<span class="op">&gt;</span></code> where <code class="sourceCode cpp">T</code> has no cvref qualifications:
<ul>
<li>Should <code class="sourceCode cpp">reference_type</code> be <code class="sourceCode cpp">T<span class="op">&amp;&amp;</span></code> (this paper) or <code class="sourceCode cpp"><span class="kw">const</span> T<span class="op">&amp;</span></code> (<span class="citation" data-cites="P2502R0">[<a href="#ref-P2502R0" role="doc-biblioref">P2502R0</a>]</span>)
<ul>
<li>while <code class="sourceCode cpp">T<span class="op">&amp;</span></code> is a valid option to discuss, I don’t think anyone has proposed it for <code class="sourceCode cpp">std<span class="op">::</span>generator</code>, even though it is existing practice for some generator implementations</li>
</ul></li>
<li>What should we do when an lvalue is passed to <code class="sourceCode cpp"><span class="kw">co_yield</span></code>?
<ul>
<li><span class="citation" data-cites="P2502R0">[<a href="#ref-P2502R0" role="doc-biblioref">P2502R0</a>]</span> proposes to hand out a <code class="sourceCode cpp"><span class="kw">const</span><span class="op">&amp;</span></code> directly to it</li>
<li>This paper proposes to copy it and hand out an rvalue-reference to the copy (see the <a href="#impl_technique">example implementation</a> for how this works).</li>
</ul></li>
</ul></li>
</ul>
<h1 data-number="3" id="justification"><span class="header-section-number">3</span> Justification<a href="#justification" class="self-link"></a></h1>
<h2 data-number="3.1" id="performance-and-move-only-type-support"><span class="header-section-number">3.1</span> Performance and move-only type support<a href="#performance-and-move-only-type-support" class="self-link"></a></h2>
<p>These are really two different issues, but the example code is the same for both.</p>
<table>
<caption><code class="sourceCode cpp">make_gen<span class="op">()</span></code> is a stand-in for a function returning <code class="sourceCode cpp">generator<span class="op">&lt;</span>T<span class="op">&gt;</span></code></caption>
<thead>
<tr class="header">
<th><div style="text-align:center">
<strong><code class="sourceCode cpp">T<span class="op">&amp;&amp;</span></code></strong>
</div></th>
<th><div style="text-align:center">
<strong><code class="sourceCode cpp"><span class="kw">const</span> T<span class="op">&amp;</span></code></strong>
</div></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1"></a>ranges<span class="op">::</span>copy<span class="op">(</span>generator, output<span class="op">)</span>; <span class="co">// no copies</span></span>
<span id="cb1-2"><a href="#cb1-2"></a></span>
<span id="cb1-3"><a href="#cb1-3"></a>make_gen<span class="op">()</span> <span class="op">|</span> to<span class="op">&lt;</span>vector<span class="op">&gt;</span>; <span class="co">// no copies</span></span></code></pre></div></td>
<td><div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1"></a>ranges<span class="op">::</span>copy<span class="op">(</span>generator, output<span class="op">)</span>; <span class="co">// copies</span></span>
<span id="cb2-2"><a href="#cb2-2"></a></span>
<span id="cb2-3"><a href="#cb2-3"></a>make_gen<span class="op">()</span> <span class="op">|</span> to<span class="op">&lt;</span>vector<span class="op">&gt;</span>; <span class="co">// copies</span></span>
<span id="cb2-4"><a href="#cb2-4"></a>make_gen<span class="op">()</span> <span class="op">|</span> views<span class="op">::</span>move <span class="op">|</span> to<span class="op">&lt;</span>vector<span class="op">&gt;</span>; <span class="co">// still copies</span></span></code></pre></div></td>
</tr>
<tr class="even">
<td><div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1"></a><span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span> s <span class="op">:</span> make_gen<span class="op">())</span> <span class="op">{}</span> <span class="co">// no copies</span></span>
<span id="cb3-2"><a href="#cb3-2"></a></span>
<span id="cb3-3"><a href="#cb3-3"></a><span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span><span class="op">&amp;&amp;</span> s <span class="op">:</span> make_gen<span class="op">())</span> <span class="op">{</span></span>
<span id="cb3-4"><a href="#cb3-4"></a>    consume<span class="op">(</span>s<span class="op">)</span>; <span class="co">// copies (as it should!)</span></span>
<span id="cb3-5"><a href="#cb3-5"></a>    consume<span class="op">(</span>std<span class="op">::</span>forward<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">(</span>s<span class="op">)&gt;(</span>s<span class="op">))</span>; <span class="co">// no copies</span></span>
<span id="cb3-6"><a href="#cb3-6"></a><span class="op">}</span></span></code></pre></div></td>
<td><div class="sourceCode" id="cb4"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb4-1"><a href="#cb4-1"></a><span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span> s <span class="op">:</span> make_gen<span class="op">())</span> <span class="op">{}</span> <span class="co">// copies</span></span>
<span id="cb4-2"><a href="#cb4-2"></a></span>
<span id="cb4-3"><a href="#cb4-3"></a><span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span><span class="op">&amp;&amp;</span> s <span class="op">:</span> make_gen<span class="op">())</span> <span class="op">{</span></span>
<span id="cb4-4"><a href="#cb4-4"></a>    consume<span class="op">(</span>s<span class="op">)</span>; <span class="co">// copies (as it should!)</span></span>
<span id="cb4-5"><a href="#cb4-5"></a>    consume<span class="op">(</span>std<span class="op">::</span>forward<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">(</span>s<span class="op">)&gt;(</span>s<span class="op">))</span>; <span class="co">// copies</span></span>
<span id="cb4-6"><a href="#cb4-6"></a>    consume<span class="op">(</span>std<span class="op">::</span>move<span class="op">(</span>s<span class="op">))</span>; <span class="co">// still copies;</span></span>
<span id="cb4-7"><a href="#cb4-7"></a><span class="op">}</span></span></code></pre></div></td>
</tr>
</tbody>
</table>
<p>If this generator produced a move-only type, then every copy above would be a compilation failure, rather than a performance issue. If the generator function was in a third-party library or code that was otherwise unable to be changed, you would be stuck.</p>
<h2 data-number="3.2" id="consistency-with-the-rest-of-the-language."><span class="header-section-number">3.2</span> Consistency with the rest of the language.<a href="#consistency-with-the-rest-of-the-language." class="self-link"></a></h2>
<p>For various reasons, using an actual non-reference <code class="sourceCode cpp">T</code> as the argument to <code class="sourceCode cpp">yield_value<span class="op">()</span></code> and the return from <code class="sourceCode cpp"><span class="kw">operator</span><span class="op">*()</span></code> are not good ideas. That leaves use trying to emulate with the best analog we can.</p>
<h3 data-number="3.2.1" id="inside-the-generator-function"><span class="header-section-number">3.2.1</span> Inside the generator function<a href="#inside-the-generator-function" class="self-link"></a></h3>
<p>Inside a <code class="sourceCode cpp">generator<span class="op">&lt;</span>T<span class="op">&gt;</span></code> function, I think <code class="sourceCode cpp"><span class="kw">co_yield</span> EXPR</code> is best thought of similarly to either <code class="sourceCode cpp">f<span class="op">(</span>EXPR<span class="op">)</span></code> where <code class="sourceCode cpp">f</code> takes a <code class="sourceCode cpp">T</code> or <code class="sourceCode cpp"><span class="cf">return</span> EXPR</code> inside of a function returning <code class="sourceCode cpp">T</code>. In both of those cases, <code class="sourceCode cpp">EXPR</code> will be copied if an lvalue, but not if it is an rvalue.</p>
<p>For function arguments, it is generally accepted that the equivalent to <code class="sourceCode cpp">T</code> is to have overloads for <code class="sourceCode cpp">T<span class="op">&amp;&amp;</span></code> and <code class="sourceCode cpp"><span class="kw">const</span> T<span class="op">&amp;</span></code>. They aren’t <em>exactly</em> equivalent, since the final state of an xvalue argument depends on what the callee does with it, but that is generally ignored since it is usually a bad idea to depend on a specific state of a variable after passing it to <code class="sourceCode cpp">std<span class="op">::</span>move<span class="op">()</span></code>. Additionally, you are able to pass immobile xvalues to <code class="sourceCode cpp">T<span class="op">&amp;&amp;</span></code>/<code class="sourceCode cpp"><span class="kw">const</span> T<span class="op">&amp;</span></code> functions as long as they don’t try to move or copy, while you can’t even pass them to <code class="sourceCode cpp">T</code>-taking functions.</p>
<p>This is what I propose doing for <code class="sourceCode cpp">generator<span class="op">&lt;</span>T<span class="op">&gt;::</span>promise_type<span class="op">::</span>yield_value<span class="op">()</span></code>. Unfortunately, it cannot take a <code class="sourceCode cpp">T</code> because the lifetime is too short. So the next best thing is to have it take a <code class="sourceCode cpp">T<span class="op">&amp;&amp;</span></code> (which also does the right thing when <code class="sourceCode cpp">T</code> is a reference) and offer a <code class="sourceCode cpp"><span class="kw">const</span> T<span class="op">&amp;</span></code> overload for copyable, non-reference <code class="sourceCode cpp">T</code> types that yields a copy of the passed in object.</p>
<h3 data-number="3.2.2" id="consuming-a-generator"><span class="header-section-number">3.2.2</span> Consuming a generator<a href="#consuming-a-generator" class="self-link"></a></h3>
<table>
<thead>
<tr class="header">
<th><div style="text-align:center">
<strong><code class="sourceCode cpp">T func<span class="op">()</span></code></strong>
</div></th>
<th><div style="text-align:center">
<strong><code class="sourceCode cpp">generator<span class="op">&lt;</span>T<span class="op">&gt;</span> gen<span class="op">()</span></code></strong>
</div></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><div class="sourceCode" id="cb5"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb5-1"><a href="#cb5-1"></a>func<span class="op">().</span>mutableMethod<span class="op">()</span>;</span></code></pre></div></td>
<td><div class="sourceCode" id="cb6"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb6-1"><a href="#cb6-1"></a><span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span><span class="op">&amp;&amp;</span> val <span class="op">:</span> gen<span class="op">())</span> <span class="op">{</span></span>
<span id="cb6-2"><a href="#cb6-2"></a>    val<span class="op">.</span>mutableMethod<span class="op">()</span>;</span>
<span id="cb6-3"><a href="#cb6-3"></a><span class="op">}</span></span></code></pre></div></td>
</tr>
<tr class="even">
<td><div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-1"></a>consume<span class="op">(</span>func<span class="op">())</span>;</span></code></pre></div></td>
<td><div class="sourceCode" id="cb8"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb8-1"><a href="#cb8-1"></a>ranges<span class="op">::</span>for_each<span class="op">(</span>gen<span class="op">()</span>, consume<span class="op">)</span>;</span></code></pre></div></td>
</tr>
<tr class="odd">
<td><div class="sourceCode" id="cb9"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb9-1"><a href="#cb9-1"></a><span class="kw">auto</span> var <span class="op">=</span> func<span class="op">()</span>;</span>
<span id="cb9-2"><a href="#cb9-2"></a>use<span class="op">(</span>var<span class="op">)</span>;</span>
<span id="cb9-3"><a href="#cb9-3"></a>consume<span class="op">(</span>std<span class="op">::</span>move<span class="op">(</span>var<span class="op">))</span>;</span></code></pre></div></td>
<td><div class="sourceCode" id="cb10"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb10-1"><a href="#cb10-1"></a><span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span><span class="op">&amp;&amp;</span> var <span class="op">:</span> gen<span class="op">())</span> <span class="op">{</span></span>
<span id="cb10-2"><a href="#cb10-2"></a>    use<span class="op">(</span>var<span class="op">)</span>;</span>
<span id="cb10-3"><a href="#cb10-3"></a>    consume<span class="op">(</span>std<span class="op">::</span>move<span class="op">(</span>var<span class="op">))</span>;</span>
<span id="cb10-4"><a href="#cb10-4"></a><span class="op">}</span></span>
<span id="cb10-5"><a href="#cb10-5"></a></span>
<span id="cb10-6"><a href="#cb10-6"></a><span class="co">// Note: for generator&lt;T&gt; specifically,</span></span>
<span id="cb10-7"><a href="#cb10-7"></a><span class="co">// is is safe to move from an auto&amp;&amp;</span></span>
<span id="cb10-8"><a href="#cb10-8"></a><span class="co">// induction variable, even if that</span></span>
<span id="cb10-9"><a href="#cb10-9"></a><span class="co">// isn&#39;t valid for all ranges</span></span></code></pre></div></td>
</tr>
<tr class="even">
<td><div class="sourceCode" id="cb13"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb13-1"><a href="#cb13-1"></a><span class="kw">auto</span><span class="op">&amp;&amp;</span> var <span class="op">=</span> func<span class="op">()</span>;</span>
<span id="cb13-2"><a href="#cb13-2"></a>use<span class="op">(</span>var<span class="op">)</span>;</span>
<span id="cb13-3"><a href="#cb13-3"></a>consume<span class="op">(</span>std<span class="op">::</span>forward<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">(</span>var<span class="op">)&gt;(</span>var<span class="op">))</span>;</span></code></pre></div></td>
<td><div class="sourceCode" id="cb14"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb14-1"><a href="#cb14-1"></a><span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span><span class="op">&amp;&amp;</span> var <span class="op">:</span> gen<span class="op">())</span> <span class="op">{</span> </span>
<span id="cb14-2"><a href="#cb14-2"></a>    use<span class="op">(</span>var<span class="op">)</span>;</span>
<span id="cb14-3"><a href="#cb14-3"></a>    consume<span class="op">(</span>std<span class="op">::</span>forward<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">(</span>var<span class="op">)&gt;(</span>var<span class="op">))</span>;</span>
<span id="cb14-4"><a href="#cb14-4"></a><span class="op">}</span></span></code></pre></div></td>
</tr>
</tbody>
</table>
<p>Using the model from section 4.1 of <span class="citation" data-cites="P1362R0">[<a href="#ref-P1362R0" role="doc-biblioref">P1362R0</a>]</span>, a <code class="sourceCode cpp">generator<span class="op">&lt;</span>T<span class="op">&gt;</span> function<span class="op">()</span></code> is conceptually like a plain-old function that synchronously returns a <code class="sourceCode cpp">T</code>, except rather than returning a value once, it returns a sequence of values computed on demand. When a function returns a <code class="sourceCode cpp">T</code> I don’t have to pay for a copy to assign it to a variable, and that should work even if it is move only. Because it is providing me with my own <code class="sourceCode cpp">T</code>, I should be free to <code class="sourceCode cpp">move<span class="op">()</span></code> it along to where I want it to go.</p>
<p>I should also be free to mutate the return value. I know some would prefer a <code class="sourceCode cpp"><span class="kw">const</span></code>-by-default language, but that isn’t where C++ is. <code class="sourceCode cpp">func<span class="op">().</span>mutableMethod<span class="op">()</span></code> is specifically made legal in C++, even when <code class="sourceCode cpp">func<span class="op">()</span></code> returns a prvalue. I think it is inconsistent with that for <span class="citation" data-cites="P2502R0">[<a href="#ref-P2502R0" role="doc-biblioref">P2502R0</a>]</span> to propose that <code class="sourceCode cpp">generator<span class="op">&lt;</span>T<span class="op">&gt;</span></code> disallow mutating operations on the results.</p>
<p>If the API for consuming a <code class="sourceCode cpp">range</code> looked more like <code class="sourceCode cpp">optional<span class="op">&lt;</span>T<span class="op">&gt;</span> next<span class="op">()</span></code>, then we could just return a <code class="sourceCode cpp">T</code> by value from that function and be done. For better or worse, the API for <code class="sourceCode cpp">input_range</code> differs from that API in two key ways: 1) the functions to get the current value and advance the current position are separated, and 2) if the current position isn’t changed, it is required that <code class="sourceCode cpp"><span class="op">*</span>it</code> can be called multiple times and return equal results. This largely rules out returning <code class="sourceCode cpp">T</code> here, unless it is possible and cheap to copy.</p>
<p>For callers, <code class="sourceCode cpp">f<span class="op">()</span></code> generally behaves the same regardless of whether it returns <code class="sourceCode cpp">T</code> or <code class="sourceCode cpp">T<span class="op">&amp;&amp;</span></code> because in both cases the expression is an rvalue. The main exceptions are the result of <code class="sourceCode cpp"><span class="kw">decltype</span><span class="op">(</span>f<span class="op">())</span></code> introspection, and that unqualified <code class="sourceCode cpp">T</code> returns are more useful for immobile types.</p>
<h2 data-number="3.3" id="best-match-for-the-generatort-use-cases"><span class="header-section-number">3.3</span> Best match for the <code class="sourceCode cpp">generator<span class="op">&lt;</span>T<span class="op">&gt;</span></code> use cases<a href="#best-match-for-the-generatort-use-cases" class="self-link"></a></h2>
<p><code class="sourceCode cpp">generator<span class="op">&lt;</span>T<span class="op">&gt;</span></code>, as the name implies is a great tool when you want to generate some <code class="sourceCode cpp">T</code> objects. When making new <code class="sourceCode cpp">T</code> objects it is wasteful to have the caller copy them. <code class="sourceCode cpp">generator<span class="op">&lt;</span>T<span class="op">&gt;</span></code> isn’t going to be the best tool for making iterators over existing data structures, because it is limited (by necessity) to <code class="sourceCode cpp">input_range</code> while data structure iterators should at least provide <code class="sourceCode cpp">forward_range</code>. Additionally, even if you were OK with that limitation, you would probably want to yield <code class="sourceCode cpp">T<span class="op">&amp;</span></code> rather than <code class="sourceCode cpp"><span class="kw">const</span> T<span class="op">&amp;</span></code>, so you could use <code class="sourceCode cpp">generator<span class="op">&lt;</span>T<span class="op">&amp;&gt;</span></code> which this paper isn’t proposing to change.</p>
<p>While we haven’t used a coroutine-based generator in our production code base<a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a>, we use a similar pattern in many places. Rather than STL-style iterators, code that generates a sequence of values implements an (often <code class="sourceCode cpp"><span class="kw">virtual</span></code>, but not always) <code class="sourceCode cpp">optional<span class="op">&lt;</span>T<span class="op">&gt;</span> getNext<span class="op">()</span></code> method. Our experience is that nearly everything returned by these functions are either rvalues, or are locals that would be safe to move from (and with the latest rules will be implicitly moved). The initial plan to adopt that API also allowed <code class="sourceCode cpp">T<span class="op">*</span></code> return if you wanted to output objects owned by the callee but as far as I know, nobody has ever tried to use that option.</p>
<h2 data-number="3.4" id="simplicity"><span class="header-section-number">3.4</span> Simplicity<a href="#simplicity" class="self-link"></a></h2>
<p>The primary point of this proposal can be stated simply as <code class="sourceCode cpp">generator<span class="op">&lt;</span>FirstArg<span class="op">&gt;::</span>iterator<span class="op">::</span><span class="kw">operator</span><span class="op">*()</span></code> should always return <code class="sourceCode cpp">FirstArg<span class="op">&amp;&amp;</span></code>. There are no exceptions or special cases. This uses the existing reference collapsing rules in the language to ensure it does the right thing in all cases, including when <code class="sourceCode cpp">FirstArg</code> is a reference type. This simplicity also caries into the implementation. The end of this paper includes an example implementation which does not need any use of <code class="sourceCode cpp">conditional_t</code>.</p>
<p>For comparison, <span class="citation" data-cites="P2502R0">[<a href="#ref-P2502R0" role="doc-biblioref">P2502R0</a>]</span> uses the following definition of its reference type:</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb15-1"><a href="#cb15-1"></a>conditional_t<span class="op">&lt;</span>is_void_v<span class="op">&lt;</span>U<span class="op">&gt;</span>,</span>
<span id="cb15-2"><a href="#cb15-2"></a>    conditional_t<span class="op">&lt;</span>is_reference_v<span class="op">&lt;</span>T<span class="op">&gt;</span>, T, <span class="kw">const</span> T<span class="op">&amp;&gt;</span>,</span>
<span id="cb15-3"><a href="#cb15-3"></a>    T<span class="op">&gt;</span></span></code></pre></div>
<p>While not the ultimate decider, I think we should tend to favor designs without exceptions or special cases.</p>
<h1 data-number="4" id="responses-to-objections"><span class="header-section-number">4</span> Responses to objections<a href="#responses-to-objections" class="self-link"></a></h1>
<h2 data-number="4.1" id="returning-an-rvalue-reference-from-it-violates-input_or_output_iterator-semantic-requirements"><span class="header-section-number">4.1</span> Returning an rvalue reference from <code class="sourceCode cpp"><span class="op">*</span>it</code> violates <code class="sourceCode cpp">input_or_output_iterator</code> semantic requirements<a href="#returning-an-rvalue-reference-from-it-violates-input_or_output_iterator-semantic-requirements" class="self-link"></a></h2>
<p>Specifically, the argument was that it violates the requirement that <code class="sourceCode cpp"><span class="op">*</span>it</code> be equality preserving. This argument not true, because <code class="sourceCode cpp"><span class="op">*</span>it</code> itself <em>is</em> equality preserving, it is only some <em>usages</em> of that expression that are not. And there is no requirement that, eg, <code class="sourceCode cpp"><span class="kw">auto</span> copy <span class="op">=</span> <span class="op">*</span>it;</code> be equality preserving.</p>
<p>While this was at one time a matter for debate, I think it is now settled that rvalue ranges <em>are</em> in fact valid <code class="sourceCode cpp">range</code>s and at least valid <code class="sourceCode cpp">input_range</code>s. <span class="citation" data-cites="P2520R0">[<a href="#ref-P2520R0" role="doc-biblioref">P2520R0</a>]</span> argues that they are also valid forward-or-better ranges, which is still under debate, however, that concern doesn’t apply here because <code class="sourceCode cpp">generator</code> can only ever be an <code class="sourceCode cpp">input_range</code>. Assuming that <span class="citation" data-cites="P2446R1">[<a href="#ref-P2446R1" role="doc-biblioref">P2446R1</a>]</span> (<code class="sourceCode cpp">views<span class="op">::</span>move</code>) lands, I think rvalue-returning ranges will no longer be a rare edge case, and will be something that anyone writing range algorithms will need to handle anyway.</p>
<h2 data-number="4.2" id="even-if-valid-rvalue-returning-ranges-are-unsafe-to-consume"><span class="header-section-number">4.2</span> Even if valid, rvalue-returning ranges are unsafe to consume<a href="#even-if-valid-rvalue-returning-ranges-are-unsafe-to-consume" class="self-link"></a></h2>
<p>Any generic algorithm that works with ranges or iterators (for now, lets restrict this to <code class="sourceCode cpp">input_range</code> and <code class="sourceCode cpp">input_iterator</code>) should be prepared to handle rvalue-returning ranges, or add additional constraints to disallow them. This is already the case in the standard library. If any algorithms that accept such ranges or iterators do not meet their contract, then they have a bug.</p>
<p>But what about “normal users” who can’t be expected to follow all of the guidelines for writing generic range algorithms, and just want to get their job done? Luckily for them, most things they do should still be safe! I will consider the 3 ways the people will consume generators separately, in the order of my best guestimate of frequency that they will be used.</p>
<h3 data-number="4.2.1" id="range-for-loops"><span class="header-section-number">4.2.1</span> Range-for loops<a href="#range-for-loops" class="self-link"></a></h3>
<p>I expect this to be &gt;90% of how <code class="sourceCode cpp">generator</code> is consumed.</p>
<p>Range-for loops are <em>always</em> safe to use with rvalue-returning ranges, because the name that is visible to users is an lvalue (even if it is an rvalue reference). That means there will be no implicit moves within the body of the loop. The only additional moves are:</p>
<ol type="1">
<li>In <code class="sourceCode cpp"><span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span> val <span class="op">:</span> gen<span class="op">)</span> <span class="op">{...}</span></code> the generated values will be moved into <code class="sourceCode cpp">val</code> rather than copied. This is safe, and ideal because it avoids a performance trap. Admittedly, one that should be avoided in general by always using <code class="sourceCode cpp"><span class="kw">auto</span><span class="op">&amp;&amp;</span></code> in range-for loops.</li>
<li>In <code class="sourceCode cpp"><span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span><span class="op">&amp;&amp;</span> ref <span class="op">:</span> gen<span class="op">)</span> <span class="op">{</span> consume<span class="op">(</span>std<span class="op">::</span>forward<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">(</span>ref<span class="op">)&gt;(</span>ref<span class="op">))</span>; <span class="op">}</span></code> the object referred to by <code class="sourceCode cpp">ref</code> will be moved into <code class="sourceCode cpp">consume<span class="op">()</span></code>. But that isn’t really an “implicit” move, and I think better reflects the intent of this code.</li>
<li><code class="sourceCode cpp"><span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span><span class="op">&amp;&amp;</span> ref <span class="op">:</span> gen<span class="op">)</span> <span class="op">{</span> consume<span class="op">(</span>std<span class="op">::</span>move<span class="op">(</span>ref<span class="op">))</span>; <span class="op">}</span></code> will move into <code class="sourceCode cpp">consume<span class="op">()</span></code> with either a <code class="sourceCode cpp">T<span class="op">&amp;&amp;</span></code> or a <code class="sourceCode cpp">T<span class="op">&amp;</span></code> reference type, but not with <code class="sourceCode cpp"><span class="kw">const</span>    T<span class="op">&amp;</span></code>. The other two cases only move with <code class="sourceCode cpp">T<span class="op">&amp;&amp;</span></code>.</li>
</ol>
<p><span class="citation" data-cites="P2502R0">[<a href="#ref-P2502R0" role="doc-biblioref">P2502R0</a>]</span> incorrectly claims they are unsafe even when used with range-for loops:</p>
<blockquote>
<p><em>Using <code class="sourceCode cpp">T<span class="op">&amp;&amp;</span></code> as the default</em>: This avoids a copy when doing <code class="sourceCode cpp"><span class="kw">auto</span> object <span class="op">=</span> <span class="op">*</span>it</code> (where <code class="sourceCode cpp">it</code> is a <code class="sourceCode cpp">std<span class="op">::</span>generator<span class="op">::</span>iterator</code>), but it is very easy to misuse, consider:</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">auto</span> f <span class="op">=</span> <span class="op">[]()</span> <span class="op">-&gt;</span> std<span class="op">::</span>generator<span class="op">&lt;</span>std<span class="op">::</span>string<span class="op">&gt;</span> <span class="op">{</span> <span class="kw">co_yield</span> <span class="st">&quot;footgun&quot;</span>; <span class="op">}()</span>;</span>
<span id="cb16-2"><a href="#cb16-2"></a><span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span><span class="op">&amp;&amp;</span> x <span class="op">:</span> f<span class="op">)</span> <span class="op">{</span></span>
<span id="cb16-3"><a href="#cb16-3"></a>    <span class="kw">auto</span> y <span class="op">=</span> x; <span class="co">// nothing suggest a move</span></span>
<span id="cb16-4"><a href="#cb16-4"></a>    y<span class="op">.</span>transform<span class="op">()</span>;</span>
<span id="cb16-5"><a href="#cb16-5"></a>    <span class="cf">if</span> <span class="op">(</span>x <span class="op">!=</span> y<span class="op">)</span> <span class="op">{</span></span>
<span id="cb16-6"><a href="#cb16-6"></a>        <span class="co">// always triggers, likely to be surprising</span></span>
<span id="cb16-7"><a href="#cb16-7"></a>    <span class="op">}</span></span>
<span id="cb16-8"><a href="#cb16-8"></a><span class="op">}</span></span></code></pre></div>
<p>We rejected this option.</p>
</blockquote>
<p>However, this analysis is incorrect. There is no move on the line <code class="sourceCode cpp"><span class="kw">auto</span> y <span class="op">=</span> x;</code>. As explained above, the expression <code class="sourceCode cpp">x</code> is an lvalue, even if its declared type is <code class="sourceCode cpp">string<span class="op">&amp;&amp;</span></code>. Separately, I don’t see why it would be surprising that <code class="sourceCode cpp">x <span class="op">!=</span> y</code> after <code class="sourceCode cpp">y</code> was modified, so I’m not sure what this example is trying to show. I think this is the only part of the paper that argues against <code class="sourceCode cpp">T<span class="op">&amp;&amp;</span></code>.</p>
<h3 data-number="4.2.2" id="passing-to-std-algorithms"><span class="header-section-number">4.2.2</span> Passing to <code class="sourceCode cpp">std</code> algorithms<a href="#passing-to-std-algorithms" class="self-link"></a></h3>
<p>I expect this to be ~9% of how <code class="sourceCode cpp">generator</code> is consumed.</p>
<p>As discussed above, the generic algorithms already need to be prepared to work with rvalue-returning input ranges.</p>
<p>One possible counter example is something like <code class="sourceCode cpp">views<span class="op">::</span>filter<span class="op">([](</span>string byValue<span class="op">)</span> <span class="op">{...})</span></code>. This isn’t a case of <code class="sourceCode cpp">filter</code> behaving incorrectly, it is a case of the user passing a predicate function that does not meet the <a href="http://eel.is/c++draft/concept.regularinvocable#1">semantic requirements</a> of <code class="sourceCode cpp">predicate<span class="op">&lt;</span>string<span class="op">&amp;&amp;&gt;</span></code>. If we wish to prevent this issue, I think it would be better to require algorithms to pass lvalues (ideally <code class="sourceCode cpp"><span class="kw">const</span></code>-qualified, but that may be a breaking change) to predicates. That would solve the problem in general, while making <code class="sourceCode cpp">generator<span class="op">&lt;</span>T<span class="op">&gt;</span></code> yield <code class="sourceCode cpp"><span class="kw">const</span> T<span class="op">&amp;</span></code> would only solve it for generators.</p>
<p>Additionally, it seems possible that <code class="sourceCode cpp">rvalue_returning_input_range <span class="op">|</span> views<span class="op">::</span>filter<span class="op">(...)</span> <span class="op">|</span> to<span class="op">&lt;</span>vector<span class="op">&gt;</span></code> may run afoul of <a href="http://eel.is/c++draft/range.filter#iterator-1">[range.filter.iterator]/1</a>, since moving from an object may modify it in a way that it would no longer match the predicate. However, that paragraph both seems to both be insufficient to achieve its goals (it doesn’t protect against modifications to the base range before the cached first match) and is underspecified (it doesn’t say when the predicate would logically be evaluated, and if you assume it is at every modification, that leads to some nonsensical results). So I think there are some underlying specification issues there. I hope we can address that, at least for <code class="sourceCode cpp">input_range</code>s, separately from consideration of <code class="sourceCode cpp">std<span class="op">::</span>generator</code>.</p>
<h3 data-number="4.2.3" id="using-the-iterators-directly"><span class="header-section-number">4.2.3</span> Using the iterators directly<a href="#using-the-iterators-directly" class="self-link"></a></h3>
<p>This is where users <em>could</em> have issues. In particular, if they are passing <code class="sourceCode cpp"><span class="op">*</span>it</code> multiple times to functions that accept a <code class="sourceCode cpp">T</code> by value or have a <code class="sourceCode cpp">T<span class="op">&amp;&amp;</span></code> overload.</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb17-1"><a href="#cb17-1"></a>use<span class="op">(*</span>it<span class="op">)</span>; <span class="co">// moves</span></span>
<span id="cb17-2"><a href="#cb17-2"></a>use<span class="op">(*</span>it<span class="op">)</span>; <span class="co">// already moved from!</span></span></code></pre></div>
<p>However, many common patterns avoid that already.</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="co">// Pretend the code also checks end() where needed. Also, assume that each chunk</span></span>
<span id="cb18-2"><a href="#cb18-2"></a><span class="co">// of code is in its own loop with its own iterator.</span></span>
<span id="cb18-3"><a href="#cb18-3"></a></span>
<span id="cb18-4"><a href="#cb18-4"></a>use<span class="op">(*</span>it<span class="op">++)</span>; <span class="co">// moves, but that is good!</span></span>
<span id="cb18-5"><a href="#cb18-5"></a></span>
<span id="cb18-6"><a href="#cb18-6"></a><span class="kw">auto</span> val <span class="op">=</span> <span class="op">*</span>it; <span class="co">// move here</span></span>
<span id="cb18-7"><a href="#cb18-7"></a>use<span class="op">(</span>val<span class="op">)</span>; <span class="co">// no move</span></span>
<span id="cb18-8"><a href="#cb18-8"></a>use<span class="op">(</span>val<span class="op">)</span>; <span class="co">// no move</span></span>
<span id="cb18-9"><a href="#cb18-9"></a>use<span class="op">(</span>move<span class="op">(</span>val<span class="op">))</span>; <span class="co">// explicit move from val</span></span>
<span id="cb18-10"><a href="#cb18-10"></a></span>
<span id="cb18-11"><a href="#cb18-11"></a><span class="kw">auto</span><span class="op">&amp;&amp;</span> ref <span class="op">=</span> <span class="op">*</span>it; <span class="co">// no move or copy</span></span>
<span id="cb18-12"><a href="#cb18-12"></a>use<span class="op">(</span>ref<span class="op">)</span>; <span class="co">// no move</span></span>
<span id="cb18-13"><a href="#cb18-13"></a>use<span class="op">(</span>ref<span class="op">)</span>; <span class="co">// no move</span></span>
<span id="cb18-14"><a href="#cb18-14"></a>use<span class="op">(</span>FWD<span class="op">(</span>ref<span class="op">))</span>; <span class="co">// move from object refered to by ref and *it</span></span>
<span id="cb18-15"><a href="#cb18-15"></a></span>
<span id="cb18-16"><a href="#cb18-16"></a>it<span class="op">-&gt;</span>func<span class="op">()</span>; <span class="co">// never calls &amp;&amp;-qualified overload (unlike `<code class="sourceCode cpp"><span class="op">(*</span>it<span class="op">).</span>func<span class="op">()</span></code>`)</span></span>
<span id="cb18-17"><a href="#cb18-17"></a>use<span class="op">(</span>it<span class="op">-&gt;</span>mem<span class="op">)</span>; <span class="co">// never calls &amp;&amp;-qualified overload (unlike `<code class="sourceCode cpp">use<span class="op">((*</span>it<span class="op">).</span>mem<span class="op">)</span></code>`)</span></span></code></pre></div>
<p>All of those patterns are safe, and widely used already. And I think we should start treating multiple calls to <code class="sourceCode cpp"><span class="op">*</span>it</code> as an anti-pattern that people should be taught to avoid anyway. It assumes that the expression <code class="sourceCode cpp"><span class="op">*</span>it</code> is cheap or free, but that isn’t necessarily the case. For example, <code class="sourceCode cpp">views<span class="op">::</span>tranform<span class="op">(</span>expensive<span class="op">)</span></code> will invoke <code class="sourceCode cpp">expensive<span class="op">(*</span>base_iterator<span class="op">)</span></code> on every call to its <code class="sourceCode cpp"><span class="op">*</span>it</code>.</p>
<p>Additionally, I hope that we can relegate raw iterator usage to an expert or upper-intermediate level feature. At least in the code that I see people writing, we got 90% of the way there in C++11 with range-for loops. C++20 brings us closer to 99% since you no longer need to touch iterators in order to use algorithms like sort. I very rarely see “normal developers” write code that actually iterates iterators anymore rather than passing them along. Even among experts, it can be a once-in-a-while thing (of course, this does not apply to people working on standard libraries…)</p>
<h2 data-number="4.3" id="implicitly-moves-in-body-of-generator"><span class="header-section-number">4.3</span> Implicitly moves in body of generator<a href="#implicitly-moves-in-body-of-generator" class="self-link"></a></h2>
<p>Some people were concerned about implicit moves in the body of the generator function. However, at least as I am proposing it, that will not happen. I agree that it would be broken if it did implicitly move.</p>
<div class="sourceCode" id="cb19"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb19-1"><a href="#cb19-1"></a>generator<span class="op">&lt;</span>string<span class="op">&gt;</span> exes<span class="op">()</span> <span class="op">{</span></span>
<span id="cb19-2"><a href="#cb19-2"></a>    string out <span class="op">=</span> <span class="st">&quot;x&quot;</span>;</span>
<span id="cb19-3"><a href="#cb19-3"></a>    <span class="cf">while</span> <span class="op">(</span><span class="kw">true</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb19-4"><a href="#cb19-4"></a>        <span class="kw">co_yield</span> out; <span class="co">// will <em>copy</em> not move!</span></span>
<span id="cb19-5"><a href="#cb19-5"></a>        out <span class="op">+=</span> <span class="ch">&#39;x&#39;</span>;</span>
<span id="cb19-6"><a href="#cb19-6"></a>    <span class="op">}</span></span>
<span id="cb19-7"><a href="#cb19-7"></a><span class="op">}</span></span></code></pre></div>
<p>That function would not perform its intended task if <code class="sourceCode cpp"><span class="kw">co_yield</span> out</code> moved from <code class="sourceCode cpp">out</code>. Of course, this function might be better returning a <code class="sourceCode cpp">generator<span class="op">&lt;</span><span class="kw">const</span> string<span class="op">&amp;&gt;</span></code> so that the caller copies if it needs to, but it is <em>correct</em> either way.</p>
<h2 data-number="4.4" id="implicitly-copies-in-body-of-generator"><span class="header-section-number">4.4</span> Implicitly copies in body of generator<a href="#implicitly-copies-in-body-of-generator" class="self-link"></a></h2>
<p>I know some people have expressed concern about how <code class="sourceCode cpp"><span class="kw">co_yield</span> lvalue</code> will implicit copy. However, this is consistent with what happens in many other parts of the language so people should be expecting it. I would be more surprised if something that was yielding an unqualified <code class="sourceCode cpp">T</code> <em>didn’t</em> copy when passed an lvalue.</p>
<div class="sourceCode" id="cb20"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb20-1"><a href="#cb20-1"></a>T lvalue;</span>
<span id="cb20-2"><a href="#cb20-2"></a><span class="dt">void</span> consume<span class="op">(</span>T<span class="op">)</span>;</span>
<span id="cb20-3"><a href="#cb20-3"></a></span>
<span id="cb20-4"><a href="#cb20-4"></a><span class="dt">void</span> f<span class="op">()</span> <span class="op">{</span></span>
<span id="cb20-5"><a href="#cb20-5"></a>    consume<span class="op">(</span>lvalue<span class="op">)</span>; <span class="co">// copies</span></span>
<span id="cb20-6"><a href="#cb20-6"></a>    consume<span class="op">(</span>move<span class="op">(</span>lvalue<span class="op">))</span>; <span class="co">// avoids copy</span></span>
<span id="cb20-7"><a href="#cb20-7"></a></span>
<span id="cb20-8"><a href="#cb20-8"></a>    T local;</span>
<span id="cb20-9"><a href="#cb20-9"></a>    consume<span class="op">(</span>local<span class="op">)</span>; <span class="co">// copies</span></span>
<span id="cb20-10"><a href="#cb20-10"></a><span class="op">}</span></span>
<span id="cb20-11"><a href="#cb20-11"></a></span>
<span id="cb20-12"><a href="#cb20-12"></a>T f<span class="op">()</span> <span class="op">{</span></span>
<span id="cb20-13"><a href="#cb20-13"></a>    <span class="cf">return</span> lvalue; <span class="co">// copies</span></span>
<span id="cb20-14"><a href="#cb20-14"></a>    <span class="cf">return</span> move<span class="op">(</span>lvalue<span class="op">)</span>; <span class="co">// avoids copy</span></span>
<span id="cb20-15"><a href="#cb20-15"></a></span>
<span id="cb20-16"><a href="#cb20-16"></a>    T local;</span>
<span id="cb20-17"><a href="#cb20-17"></a>    <span class="cf">return</span> local; <span class="co">// no copy because we know `local` is going out of scope</span></span>
<span id="cb20-18"><a href="#cb20-18"></a><span class="op">}</span></span>
<span id="cb20-19"><a href="#cb20-19"></a></span>
<span id="cb20-20"><a href="#cb20-20"></a><span class="co">// As I propose:</span></span>
<span id="cb20-21"><a href="#cb20-21"></a>generator<span class="op">&lt;</span>T<span class="op">&gt;</span> f<span class="op">()</span> <span class="op">{</span></span>
<span id="cb20-22"><a href="#cb20-22"></a>    <span class="kw">co_yield</span> lvalue; <span class="co">// copies</span></span>
<span id="cb20-23"><a href="#cb20-23"></a>    <span class="kw">co_yield</span> move<span class="op">(</span>lvalue<span class="op">)</span>; <span class="co">// avoids copy</span></span>
<span id="cb20-24"><a href="#cb20-24"></a></span>
<span id="cb20-25"><a href="#cb20-25"></a>    T local;</span>
<span id="cb20-26"><a href="#cb20-26"></a>    <span class="kw">co_yield</span> local; <span class="co">// copies, which is good!</span></span>
<span id="cb20-27"><a href="#cb20-27"></a>    <span class="kw">co_yield</span> local; <span class="co">// unfortunately also copies.</span></span>
<span id="cb20-28"><a href="#cb20-28"></a><span class="op">}</span></span></code></pre></div>
<p>The last line seems to be the only unfortunate case. I’m not proposing it at this time, but if we find that this is a common problem, we could consider a core-language change in the future to allow <code class="sourceCode cpp"><span class="kw">co_yield</span></code> of an <a href="http://eel.is/c++draft/class.copy.elision#def:entity,implicitly_movable">implicitly movable entity</a> that is about to go out of scope to implicitly move with similar rationale as for <code class="sourceCode cpp"><span class="cf">return</span></code>, <code class="sourceCode cpp"><span class="kw">co_return</span></code>, and <code class="sourceCode cpp"><span class="cf">throw</span></code>.</p>
<p>Also, in the inverse to the next point, the return type is by necessity both close to and (usually) under the control of the author of the generator function. <code class="sourceCode cpp">generator<span class="op">&lt;</span>T<span class="op">&gt;</span></code> should be used when you can provide the consumer with their own <code class="sourceCode cpp">T</code> objects. If you don’t want to do that, then it is easy for the function author to choose to return a <code class="sourceCode cpp">generator<span class="op">&lt;</span>T<span class="op">&amp;&gt;</span></code> or <code class="sourceCode cpp">generator<span class="op">&lt;</span><span class="kw">const</span> T<span class="op">&amp;&gt;</span></code> depending on whether they want the consumer to be allowed to modify the yielded objects.</p>
<h2 data-number="4.5" id="we-have-generatort-for-people-that-want-moves-and-it-is-more-explicit"><span class="header-section-number">4.5</span> We have <code class="sourceCode cpp">generator<span class="op">&lt;</span>T<span class="op">&amp;&amp;&gt;</span></code> for people that want moves and it is more explicit<a href="#we-have-generatort-for-people-that-want-moves-and-it-is-more-explicit" class="self-link"></a></h2>
<p>There are really two similar arguments here. First, that if someone wants moves, they can just use <code class="sourceCode cpp">generator<span class="op">&lt;</span>T<span class="op">&amp;&amp;&gt;</span></code>. The problem I have with this is that usually the caller is the one who would need the moves, but they are not necessarily in control of the signatures of the functions they call. They may be part of a third party library. Or they may just not want to do the audit to ensure that all other callers will be ok with it.</p>
<p>The second argument is that using <code class="sourceCode cpp">generator<span class="op">&lt;</span>T<span class="op">&amp;&amp;&gt;</span></code> as the return type makes it no longer a “hidden” move. The problem here is that the return type is usually stated very far away from the call site, often in a separate file. This is doubly true for iterators which A) are an extra layer removed from the underlying range, and B) are often processed in separate generic functions. When you see code like <code class="sourceCode cpp">use<span class="op">(*</span>it<span class="op">)</span>; use<span class="op">(*</span>it<span class="op">)</span>;</code> it looks identical regardless of whether <code class="sourceCode cpp">it</code> came from a <code class="sourceCode cpp">generator<span class="op">&lt;</span>T<span class="op">&gt;</span></code> or a <code class="sourceCode cpp">generator<span class="op">&lt;</span>T<span class="op">&amp;&amp;&gt;</span></code>, so I don’t think the latter is actually any more explicit <em>where it matters</em>.</p>
<h1 data-number="5" id="example-implementation"><span class="header-section-number">5</span> Example implementation<a href="#example-implementation" class="self-link"></a></h1>
<p>This is an example implementation of what I am proposing. It does not support allocators, but adding support for them should be simple and orthogonal. It also does not support recursive yielding via <code class="sourceCode cpp">elements_of</code>, since I do not think that should be included in the main <code class="sourceCode cpp">std<span class="op">::</span>generator</code> type (but that discussion isn’t the point of this paper). It is also available on <a href="https://godbolt.org/z/9hn1vdf17">godbolt</a>, along with some examples, if you want to try it out. The same examples with the reference impl from <span class="citation" data-cites="P2502R0">[<a href="#ref-P2502R0" role="doc-biblioref">P2502R0</a>]</span> are available <a href="https://godbolt.org/z/xEc15cYff">here</a> if you would like to compare (the move-only example is commented out because it doesn’t compile).</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">typename</span> T, <span class="kw">typename</span> ValueType <span class="op">=</span> std<span class="op">::</span>remove_cvref<span class="op">&lt;</span>T<span class="op">&gt;&gt;</span></span>
<span id="cb21-2"><a href="#cb21-2"></a><span class="kw">struct</span> generator <span class="op">{</span></span>
<span id="cb21-3"><a href="#cb21-3"></a>    <span class="kw">using</span> value_type <span class="op">=</span> ValueType;</span>
<span id="cb21-4"><a href="#cb21-4"></a>    <span class="kw">using</span> Pointer <span class="op">=</span> std<span class="op">::</span>add_pointer_t<span class="op">&lt;</span>T<span class="op">&gt;</span>;</span>
<span id="cb21-5"><a href="#cb21-5"></a></span>
<span id="cb21-6"><a href="#cb21-6"></a>    <span class="kw">struct</span> promise_type <span class="op">{</span></span>
<span id="cb21-7"><a href="#cb21-7"></a>        std<span class="op">::</span>suspend_always initial_suspend<span class="op">()</span> <span class="op">{</span></span>
<span id="cb21-8"><a href="#cb21-8"></a>            <span class="cf">return</span> <span class="op">{}</span>;</span>
<span id="cb21-9"><a href="#cb21-9"></a>        <span class="op">}</span></span>
<span id="cb21-10"><a href="#cb21-10"></a>        std<span class="op">::</span>suspend_always final_suspend<span class="op">()</span> <span class="kw">noexcept</span> <span class="op">{</span></span>
<span id="cb21-11"><a href="#cb21-11"></a>            <span class="cf">return</span> <span class="op">{}</span>;</span>
<span id="cb21-12"><a href="#cb21-12"></a>        <span class="op">}</span></span>
<span id="cb21-13"><a href="#cb21-13"></a>        <a id="impl_technique"></a></span>
<span id="cb21-14"><a href="#cb21-14"></a>        <span class="co">// This overload copies v to a temporary, then yields a pointer to that.</span></span>
<span id="cb21-15"><a href="#cb21-15"></a>        <span class="co">// This allows passing an lvalue to co_yield for a generator&lt;NotReference&gt;.</span></span>
<span id="cb21-16"><a href="#cb21-16"></a>        <span class="kw">auto</span> yield_value<span class="op">(</span><span class="kw">const</span> T<span class="op">&amp;</span> v<span class="op">)</span> <span class="kw">requires</span><span class="op">(!</span>std<span class="op">::</span>is_reference_v<span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="op">&amp;&amp;</span></span>
<span id="cb21-17"><a href="#cb21-17"></a>                                              std<span class="op">::</span>copy_constructible<span class="op">&lt;</span>T<span class="op">&gt;)</span> <span class="op">{</span></span>
<span id="cb21-18"><a href="#cb21-18"></a>            <span class="kw">struct</span> Owner <span class="op">:</span> std<span class="op">::</span>suspend_always <span class="op">{</span></span>
<span id="cb21-19"><a href="#cb21-19"></a>                Owner<span class="op">(</span><span class="kw">const</span> T<span class="op">&amp;</span> val, Pointer<span class="op">&amp;</span> out<span class="op">)</span> <span class="op">:</span> v<span class="op">(</span>val<span class="op">)</span> <span class="op">{</span></span>
<span id="cb21-20"><a href="#cb21-20"></a>                    out <span class="op">=</span> <span class="op">&amp;</span>v;</span>
<span id="cb21-21"><a href="#cb21-21"></a>                <span class="op">}</span></span>
<span id="cb21-22"><a href="#cb21-22"></a>                Owner<span class="op">(</span>Owner<span class="op">&amp;&amp;)</span> <span class="op">=</span> <span class="kw">delete</span>;</span>
<span id="cb21-23"><a href="#cb21-23"></a>                T v;</span>
<span id="cb21-24"><a href="#cb21-24"></a>            <span class="op">}</span>;</span>
<span id="cb21-25"><a href="#cb21-25"></a>            <span class="cf">return</span> Owner<span class="op">(</span>v, ptr<span class="op">)</span>;</span>
<span id="cb21-26"><a href="#cb21-26"></a>        <span class="op">}</span></span>
<span id="cb21-27"><a href="#cb21-27"></a></span>
<span id="cb21-28"><a href="#cb21-28"></a>        <span class="kw">auto</span> yield_value<span class="op">(</span>T<span class="op">&amp;&amp;</span> v<span class="op">)</span> <span class="op">{</span>  <span class="co">// lval ref if T is lval ref</span></span>
<span id="cb21-29"><a href="#cb21-29"></a>            ptr <span class="op">=</span> <span class="op">&amp;</span>v;</span>
<span id="cb21-30"><a href="#cb21-30"></a>            <span class="cf">return</span> std<span class="op">::</span>suspend_always<span class="op">()</span>;</span>
<span id="cb21-31"><a href="#cb21-31"></a>        <span class="op">}</span></span>
<span id="cb21-32"><a href="#cb21-32"></a></span>
<span id="cb21-33"><a href="#cb21-33"></a>        <span class="kw">auto</span> get_return_object<span class="op">()</span> <span class="op">{</span></span>
<span id="cb21-34"><a href="#cb21-34"></a>            <span class="cf">return</span> generator<span class="op">(</span><span class="kw">this</span><span class="op">)</span>;</span>
<span id="cb21-35"><a href="#cb21-35"></a>        <span class="op">}</span></span>
<span id="cb21-36"><a href="#cb21-36"></a></span>
<span id="cb21-37"><a href="#cb21-37"></a>        <span class="dt">void</span> return_void<span class="op">()</span> <span class="op">{}</span></span>
<span id="cb21-38"><a href="#cb21-38"></a>        <span class="dt">void</span> unhandled_exception<span class="op">()</span> <span class="op">{</span></span>
<span id="cb21-39"><a href="#cb21-39"></a>            <span class="cf">throw</span>;</span>
<span id="cb21-40"><a href="#cb21-40"></a>        <span class="op">}</span></span>
<span id="cb21-41"><a href="#cb21-41"></a></span>
<span id="cb21-42"><a href="#cb21-42"></a>        <span class="kw">auto</span> coro<span class="op">()</span> <span class="op">{</span></span>
<span id="cb21-43"><a href="#cb21-43"></a>            <span class="cf">return</span> std<span class="op">::</span>coroutine_handle<span class="op">&lt;</span>promise_type<span class="op">&gt;::</span>from_promise<span class="op">(*</span><span class="kw">this</span><span class="op">)</span>;</span>
<span id="cb21-44"><a href="#cb21-44"></a>        <span class="op">}</span></span>
<span id="cb21-45"><a href="#cb21-45"></a></span>
<span id="cb21-46"><a href="#cb21-46"></a>        Pointer ptr <span class="op">=</span> <span class="op">{}</span>;</span>
<span id="cb21-47"><a href="#cb21-47"></a>    <span class="op">}</span>;</span>
<span id="cb21-48"><a href="#cb21-48"></a></span>
<span id="cb21-49"><a href="#cb21-49"></a>    generator<span class="op">(</span>generator<span class="op">&amp;&amp;</span> source<span class="op">)</span> <span class="op">:</span> p<span class="op">(</span>std<span class="op">::</span>exchange<span class="op">(</span>source<span class="op">.</span>p, <span class="kw">nullptr</span><span class="op">))</span> <span class="op">{}</span></span>
<span id="cb21-50"><a href="#cb21-50"></a>    <span class="kw">explicit</span> generator<span class="op">(</span>promise_type<span class="op">*</span> p<span class="op">)</span> <span class="op">:</span> p<span class="op">(</span>p<span class="op">)</span> <span class="op">{}</span></span>
<span id="cb21-51"><a href="#cb21-51"></a>    <span class="op">~</span>generator<span class="op">()</span> <span class="op">{</span></span>
<span id="cb21-52"><a href="#cb21-52"></a>        <span class="cf">if</span> <span class="op">(</span>p<span class="op">)</span></span>
<span id="cb21-53"><a href="#cb21-53"></a>            p<span class="op">-&gt;</span>coro<span class="op">().</span>destroy<span class="op">()</span>;</span>
<span id="cb21-54"><a href="#cb21-54"></a>    <span class="op">}</span></span>
<span id="cb21-55"><a href="#cb21-55"></a></span>
<span id="cb21-56"><a href="#cb21-56"></a>    <span class="kw">using</span> sentinel <span class="op">=</span> std<span class="op">::</span>default_sentinel_t;</span>
<span id="cb21-57"><a href="#cb21-57"></a>    <span class="kw">struct</span> iterator <span class="op">{</span></span>
<span id="cb21-58"><a href="#cb21-58"></a>        <span class="kw">using</span> iterator_concept <span class="op">=</span> std<span class="op">::</span>input_iterator_tag;</span>
<span id="cb21-59"><a href="#cb21-59"></a>        <span class="kw">using</span> difference_type <span class="op">=</span> <span class="dt">ptrdiff_t</span>;</span>
<span id="cb21-60"><a href="#cb21-60"></a>        <span class="kw">using</span> value_type <span class="op">=</span> std<span class="op">::</span>remove_cvref_t<span class="op">&lt;</span>T<span class="op">&gt;</span>;</span>
<span id="cb21-61"><a href="#cb21-61"></a></span>
<span id="cb21-62"><a href="#cb21-62"></a>        <span class="dt">bool</span> <span class="kw">operator</span><span class="op">==(</span>sentinel<span class="op">)</span> <span class="kw">const</span> <span class="op">{</span></span>
<span id="cb21-63"><a href="#cb21-63"></a>            <span class="cf">return</span> p<span class="op">-&gt;</span>coro<span class="op">().</span>done<span class="op">()</span>;</span>
<span id="cb21-64"><a href="#cb21-64"></a>        <span class="op">}</span></span>
<span id="cb21-65"><a href="#cb21-65"></a>        iterator<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">++()</span> <span class="op">{</span></span>
<span id="cb21-66"><a href="#cb21-66"></a>            p<span class="op">-&gt;</span>ptr <span class="op">=</span> <span class="op">{}</span>;</span>
<span id="cb21-67"><a href="#cb21-67"></a>            p<span class="op">-&gt;</span>coro<span class="op">().</span>resume<span class="op">()</span>;</span>
<span id="cb21-68"><a href="#cb21-68"></a>            <span class="cf">return</span> <span class="op">*</span><span class="kw">this</span>;</span>
<span id="cb21-69"><a href="#cb21-69"></a>        <span class="op">}</span></span>
<span id="cb21-70"><a href="#cb21-70"></a>        <span class="dt">void</span> <span class="kw">operator</span><span class="op">++(</span><span class="dt">int</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb21-71"><a href="#cb21-71"></a>            <span class="kw">operator</span><span class="op">++()</span>;</span>
<span id="cb21-72"><a href="#cb21-72"></a>        <span class="op">}</span></span>
<span id="cb21-73"><a href="#cb21-73"></a>        Pointer <span class="kw">operator</span><span class="op">-&gt;()</span> <span class="kw">const</span> <span class="op">{</span></span>
<span id="cb21-74"><a href="#cb21-74"></a>            <span class="cf">return</span> p<span class="op">-&gt;</span>ptr;</span>
<span id="cb21-75"><a href="#cb21-75"></a>        <span class="op">}</span></span>
<span id="cb21-76"><a href="#cb21-76"></a>        T<span class="op">&amp;&amp;</span> <span class="kw">operator</span><span class="op">*()</span> <span class="kw">const</span> <span class="op">{</span>  <span class="co">// lval ref if T is lval ref</span></span>
<span id="cb21-77"><a href="#cb21-77"></a>            <span class="cf">return</span> <span class="kw">static_cast</span><span class="op">&lt;</span>T<span class="op">&amp;&amp;&gt;(*</span>p<span class="op">-&gt;</span>ptr<span class="op">)</span>;</span>
<span id="cb21-78"><a href="#cb21-78"></a>        <span class="op">}</span></span>
<span id="cb21-79"><a href="#cb21-79"></a></span>
<span id="cb21-80"><a href="#cb21-80"></a>        promise_type<span class="op">*</span> p;</span>
<span id="cb21-81"><a href="#cb21-81"></a>    <span class="op">}</span>;</span>
<span id="cb21-82"><a href="#cb21-82"></a>    <span class="kw">auto</span> begin<span class="op">()</span> <span class="op">{</span></span>
<span id="cb21-83"><a href="#cb21-83"></a>        p<span class="op">-&gt;</span>coro<span class="op">().</span>resume<span class="op">()</span>;</span>
<span id="cb21-84"><a href="#cb21-84"></a>        <span class="cf">return</span> iterator<span class="op">{</span>p<span class="op">}</span>;</span>
<span id="cb21-85"><a href="#cb21-85"></a>    <span class="op">}</span></span>
<span id="cb21-86"><a href="#cb21-86"></a>    <span class="kw">auto</span> end<span class="op">()</span> <span class="op">{</span></span>
<span id="cb21-87"><a href="#cb21-87"></a>        <span class="cf">return</span> sentinel<span class="op">()</span>;</span>
<span id="cb21-88"><a href="#cb21-88"></a>    <span class="op">}</span></span>
<span id="cb21-89"><a href="#cb21-89"></a></span>
<span id="cb21-90"><a href="#cb21-90"></a>    promise_type<span class="op">*</span> p;</span>
<span id="cb21-91"><a href="#cb21-91"></a><span class="op">}</span>;</span></code></pre></div>
<!-- vim: set ft=pandoc sw=4 sts=4 tw=80: -->
<h1 data-number="6" id="bibliography"><span class="header-section-number">6</span> References<a href="#bibliography" class="self-link"></a></h1>
<div id="refs" class="references hanging-indent" role="doc-bibliography">
<div id="ref-P1362R0">
<p>[P1362R0] Gor Nishanov. 2018-11-15. Incremental Approach: Coroutine TS + Core Coroutines. <br />
<a href="https://wg21.link/p1362r0">https://wg21.link/p1362r0</a></p>
</div>
<div id="ref-P2168R3">
<p>[P2168R3] Corentin Jabot, Lewis Baker. 2021-04-19. generator: A Synchronous Coroutine Generator Compatible With Ranges. <br />
<a href="https://wg21.link/p2168r3">https://wg21.link/p2168r3</a></p>
</div>
<div id="ref-P2446R1">
<p>[P2446R1] Barry Revzin. 2021-11-17. views::all_move. <br />
<a href="https://wg21.link/p2446r1">https://wg21.link/p2446r1</a></p>
</div>
<div id="ref-P2502R0">
<p>[P2502R0] Casey Carter. 2021-12-13. std::generator: Synchronous Coroutine Generator for Ranges. <br />
<a href="https://wg21.link/p2502r0">https://wg21.link/p2502r0</a></p>
</div>
<div id="ref-P2520R0">
<p>[P2520R0] Barry Revzin. 2022-01-16. move_iterator should be a random access iterator. <br />
<a href="https://wg21.link/p2520r0">https://wg21.link/p2520r0</a></p>
</div>
</div>
<section class="footnotes" role="doc-endnotes">
<hr />
<ol>
<li id="fn1" role="doc-endnote"><p>However, I have used the <code class="sourceCode cpp">generator<span class="op">&lt;</span>T<span class="op">&gt;</span></code> implementation included in this paper in a long running POC<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
</div>
</div>
</body>
</html>
