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

div.rm pre, div.add pre { background-color: #f6f8fa; }
div.addu pre { background-color: var(--diff-ins); }
div.add, div.add pre { background-color: var(--diff-ins); }
div.addu blockquote {
border-left: 4px solid #00a000;
padding: 0 15px;
color: #006e28;
text-decoration: none;
}
div.addu blockquote code.sourceCode { text-decoration: none; }
div.addu blockquote pre { text-decoration: none; }
div.addu blockquote pre code { text-decoration: none; }
div.quote {
border-left: 7px solid #ccc;
background: #f9f9f9;
margin: 1.5em 10px;
padding-left: 20px;
}
code.diff span.va { color: #000000; background-color: var(--diff-ins); }
code.diff span.st { color: #000000; background-color: var(--diff-del); }
div.std blockquote { color: #000000; background-color: #F1F1F1;
border: 1px solid #D1D1D1;
padding-left: 0.5em; padding-right: 0.5em; }
div.std.ins blockquote {
color: #000000; background-color: #C8FFC8;
border: 1px solid #B3EBB3;
}
div.ins > div.example {
color: #000000; background-color: #C8FFC8;
border: 1px solid #B3EBB3;
}
div.std div.sourceCode { background-color: inherit; margin-left: 1em; }
div.std blockquote del { text-decoration: line-through;
color: #000000; background-color: var(--diff-del);
border: none; }
code del { border: 1px solid #ECB3C7; }
span.orange {
background-color: #ffa500;
}
span.yellow {
background-color: #ffff00;
}</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">Code Injection with Token
Sequences</h1>
<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P3294R1</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2024-07-16</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>
      SG7, EWG<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to:</td>
    <td>
      Andrei Alexandrescu, NVIDIA<br>&lt;<a href="mailto:andrei@nvidia.com" class="email">andrei@nvidia.com</a>&gt;<br>
      Barry Revzin<br>&lt;<a href="mailto:barry.revzin@gmail.com" class="email">barry.revzin@gmail.com</a>&gt;<br>
      Daveed Vandevoorde<br>&lt;<a href="mailto:daveed@edg.com" class="email">daveed@edg.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="#revision-history" id="toc-revision-history"><span class="toc-section-number">1</span> Revision
History<span></span></a></li>
<li><a href="#introduction" id="toc-introduction"><span class="toc-section-number">2</span> Introduction<span></span></a></li>
<li><a href="#a-comparison-of-injection-models" id="toc-a-comparison-of-injection-models"><span class="toc-section-number">3</span> A Comparison of Injection
Models<span></span></a>
<ul>
<li><a href="#the-spec-api" id="toc-the-spec-api"><span class="toc-section-number">3.1</span> The Spec API<span></span></a></li>
<li><a href="#the-codereckons-api" id="toc-the-codereckons-api"><span class="toc-section-number">3.2</span> The CodeReckons
API<span></span></a></li>
<li><a href="#string-injection" id="toc-string-injection"><span class="toc-section-number">3.3</span> String
Injection<span></span></a></li>
<li><a href="#fragments" id="toc-fragments"><span class="toc-section-number">3.4</span> Fragments<span></span></a></li>
</ul></li>
<li><a href="#token-sequences" id="toc-token-sequences"><span class="toc-section-number">4</span> Token Sequences<span></span></a>
<ul>
<li><a href="#token-sequence-expression" id="toc-token-sequence-expression"><span class="toc-section-number">4.1</span> Token Sequence
Expression<span></span></a></li>
<li><a href="#interpolating-into-a-token-sequence" id="toc-interpolating-into-a-token-sequence"><span class="toc-section-number">4.2</span> Interpolating into a Token
Sequence<span></span></a></li>
<li><a href="#phase-of-translation" id="toc-phase-of-translation"><span class="toc-section-number">4.3</span> Phase of
Translation<span></span></a></li>
<li><a href="#injection" id="toc-injection"><span class="toc-section-number">4.4</span> Injection<span></span></a></li>
<li><a href="#token-sequence-type" id="toc-token-sequence-type"><span class="toc-section-number">4.5</span> Token Sequence
Type<span></span></a></li>
<li><a href="#implementation-status" id="toc-implementation-status"><span class="toc-section-number">4.6</span> Implementation
Status<span></span></a></li>
<li><a href="#examples" id="toc-examples"><span class="toc-section-number">4.7</span> Examples<span></span></a></li>
<li><a href="#type-erasure" id="toc-type-erasure"><span class="toc-section-number">4.8</span> Type Erasure<span></span></a></li>
<li><a href="#logging-vector-cloning-a-type" id="toc-logging-vector-cloning-a-type"><span class="toc-section-number">4.9</span> Logging Vector: Cloning a
Type<span></span></a></li>
<li><a href="#logging-vector-ii-cloning-with-modifications" id="toc-logging-vector-ii-cloning-with-modifications"><span class="toc-section-number">4.10</span> Logging Vector II: Cloning with
Modifications<span></span></a></li>
</ul></li>
<li><a href="#scoped-macros" id="toc-scoped-macros"><span class="toc-section-number">5</span> Scoped Macros<span></span></a>
<ul>
<li><a href="#design-approach" id="toc-design-approach"><span class="toc-section-number">5.1</span> Design
Approach<span></span></a></li>
<li><a href="#forwarding" id="toc-forwarding"><span class="toc-section-number">5.2</span> Forwarding<span></span></a></li>
<li><a href="#assertion" id="toc-assertion"><span class="toc-section-number">5.3</span> Assertion<span></span></a></li>
<li><a href="#macro-parsing" id="toc-macro-parsing"><span class="toc-section-number">5.4</span> Macro
Parsing<span></span></a></li>
<li><a href="#hygienic-macros" id="toc-hygienic-macros"><span class="toc-section-number">5.5</span> Hygienic
Macros<span></span></a></li>
<li><a href="#string-interpolation" id="toc-string-interpolation"><span class="toc-section-number">5.6</span> String
Interpolation<span></span></a></li>
<li><a href="#abbreviated-lambdas" id="toc-abbreviated-lambdas"><span class="toc-section-number">5.7</span> Abbreviated
Lambdas<span></span></a></li>
<li><a href="#a-control-flow-operator" id="toc-a-control-flow-operator"><span class="toc-section-number">5.8</span> A control flow
operator<span></span></a></li>
<li><a href="#operator-support" id="toc-operator-support"><span class="toc-section-number">5.9</span> Operator
Support<span></span></a></li>
<li><a href="#alternate-syntax" id="toc-alternate-syntax"><span class="toc-section-number">5.10</span> Alternate
Syntax<span></span></a></li>
</ul></li>
<li><a href="#proposal" id="toc-proposal"><span class="toc-section-number">6</span> Proposal<span></span></a></li>
<li><a href="#bibliography" id="toc-bibliography"><span class="toc-section-number">7</span> References<span></span></a></li>
</ul>
</div>
<h1 data-number="1" style="border-bottom:1px solid #cccccc" id="revision-history"><span class="header-section-number">1</span>
Revision History<a href="#revision-history" class="self-link"></a></h1>
<p>Since <span class="citation" data-cites="P3294R0">[<a href="https://wg21.link/p3294r0" role="doc-biblioref">P3294R0</a>]</span>:</p>
<ul>
<li>Changed syntax for introducing token sequences to <code class="sourceCode cpp"><span class="op">^{</span> <span class="op">...</span> <span class="op">}</span></code></li>
<li>Refined the interpolator syntax to <code class="sourceCode cpp">\<span class="op">(</span>e<span class="op">)</span></code>,
<code class="sourceCode cpp">\id<span class="op">(</span>e<span class="op">)</span></code>,
and <code class="sourceCode cpp">\tokens<span class="op">(</span>e<span class="op">)</span></code>
(parens mandatory in all cases)</li>
<li>Dropped the <code class="sourceCode cpp">declare <span class="op">[:</span> e <span class="op">:]</span></code>
splicer</li>
<li>Implemented much of the proposal with links to examples (including a
new <a href="#type-erasure">type erasure example</a>)</li>
<li>Changed syntax for macros, since the parameters can just be <code class="sourceCode cpp">std<span class="op">::</span>meta<span class="op">::</span>info</code>,
and extended discussion of them.</li>
</ul>
<h1 data-number="2" style="border-bottom:1px solid #cccccc" id="introduction"><span class="header-section-number">2</span>
Introduction<a href="#introduction" class="self-link"></a></h1>
<p>This paper is proposing augmenting <span class="citation" data-cites="P2996R4">[<a href="https://wg21.link/p2996r4" role="doc-biblioref">P2996R4</a>]</span> to add code injection in the
form of token sequences.</p>
<p>We consider the motivation for this feature to some degree pretty
obvious, so we will not repeat it here, since there are plenty of other
things to cover here. Instead we encourage readers to read some other
papers on the topic (e.g. <span class="citation" data-cites="P0707R4">[<a href="https://wg21.link/p0707r4" role="doc-biblioref">P0707R4</a>]</span>, <span class="citation" data-cites="P0712R0">[<a href="https://wg21.link/p0712r0" role="doc-biblioref">P0712R0</a>]</span>, <span class="citation" data-cites="P1717R0">[<a href="https://wg21.link/p1717r0" role="doc-biblioref">P1717R0</a>]</span>, <span class="citation" data-cites="P2237R0">[<a href="https://wg21.link/p2237r0" role="doc-biblioref">P2237R0</a>]</span>).</p>
<h1 data-number="3" style="border-bottom:1px solid #cccccc" id="a-comparison-of-injection-models"><span class="header-section-number">3</span> A Comparison of Injection
Models<a href="#a-comparison-of-injection-models" class="self-link"></a></h1>
<p>There are a lot of things that make code injection in C++ difficult,
and the most important problem to solve first is: what will the actual
injection mechanism look like? Not its syntax specifically, but what is
the shape of the API that we want to expose to users? We hope in this
section to do a thorough job of comparing the various semantic models
we’re aware of to help explain why we came to the conclusion that we
came to.</p>
<p>If you’re not interested in this journey, you can simply skip to the
<a href="#token-sequences">next section</a>.</p>
<p>Here, we will look at a few interesting examples for injection and
how different models can implement them. The examples aren’t necessarily
intended to be the most compelling examples that exist in the wild.
Instead, they’re hopefully representative enough to cover a wide class
of problems. They are:</p>
<ol type="1">
<li>Implementing the storage for <code class="sourceCode cpp">std<span class="op">::</span>tuple<span class="op">&lt;</span>Ts<span class="op">...&gt;</span></code></li>
<li>Implementing <code class="sourceCode cpp">std<span class="op">::</span>enable_if</code>
without resorting to class template specialization</li>
<li>Implementing properties (i.e. given a name like <code class="sourceCode cpp"><span class="st">&quot;author&quot;</span></code>
and a type like
<code class="sourceCode cpp">std<span class="op">::</span>string</code>,
emit a member <code class="sourceCode cpp">std<span class="op">::</span>string m_author</code>,
a getter
<code class="sourceCode cpp">get_author<span class="op">()</span></code>
which returns a <code class="sourceCode cpp">std<span class="op">::</span>string <span class="kw">const</span><span class="op">&amp;</span></code>
to that member, and a setter
<code class="sourceCode cpp">set_author<span class="op">()</span></code>
which takes a new value of type <code class="sourceCode cpp">std<span class="op">::</span>string <span class="kw">const</span><span class="op">&amp;</span></code>
and assigns the member).</li>
<li>Implementing the postfix increment operator in terms of an existing
prefix increment operator (a pure boilerplate annoyance).</li>
</ol>
<h2 data-number="3.1" id="the-spec-api"><span class="header-section-number">3.1</span> The Spec API<a href="#the-spec-api" class="self-link"></a></h2>
<p>In P2996, the injection API is based on a function <code class="sourceCode cpp">define_class<span class="op">()</span></code>
which takes a range of <code class="sourceCode cpp">spec</code> objects.
In P2996, we only currently have
<code class="sourceCode cpp">data_member_spec</code> - but this can
conceivably be extended to have a
<code class="sourceCode cpp">meow_spec</code> function for more aspects
of the C++ API. Hence the name.</p>
<p>But <code class="sourceCode cpp">define_class<span class="op">()</span></code> is
a really clunky API, because invoking it is an expression - but we want
to do it in contexts that want a declaration. So a simple example of
injecting a single member
<code class="sourceCode cpp"><span class="dt">int</span></code> named
<code class="sourceCode cpp">x</code> is:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> C;</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="kw">static_assert</span><span class="op">(</span>is_type<span class="op">(</span>define_class<span class="op">(^</span>C,</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span>data_member_spec<span class="op">{.</span>name<span class="op">=</span><span class="st">&quot;x&quot;</span>, <span class="op">.</span>type<span class="op">=^</span><span class="dt">int</span><span class="op">}})))</span>;</span></code></pre></div>
</blockquote>
</div>
<p>We are already separately proposing
<code class="sourceCode cpp"><span class="kw">consteval</span></code>
blocks <span class="citation" data-cites="P3289R0">[<a href="https://wg21.link/p3289r0" role="doc-biblioref">P3289R0</a>]</span> and we would like to inject
each spec more directly, without having to complete
<code class="sourceCode cpp">C</code> in one ago. As in:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> C <span class="op">{</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">consteval</span> <span class="op">{</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>        inject<span class="op">(</span>data_member_spec<span class="op">{.</span>name<span class="op">=</span><span class="st">&quot;x&quot;</span>, <span class="op">.</span>type<span class="op">=^</span><span class="dt">int</span><span class="op">})</span>;</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
</div>
<p>Here, <code class="sourceCode cpp">std<span class="op">::</span>meta<span class="op">::</span>inject</code>
is a new metafunction that takes a spec, which gets injected into the
context of the
<code class="sourceCode cpp"><span class="kw">consteval</span></code>
block which began our evaluation as a side-effect.</p>
<p>We already think of this as an improvement. But let’s go through
several use-cases to expand the API and see how well it holds up.</p>
<h3 data-number="3.1.1" id="stdtuple"><span class="header-section-number">3.1.1</span>
<code class="sourceCode cpp">std<span class="op">::</span>tuple</code><a href="#stdtuple" class="self-link"></a></h3>
<p>The tuple use-case was already supported by P2996 directly with <code class="sourceCode cpp">define_class<span class="op">()</span></code>
(even though we think it would be better as a member pack), but it’s
worth just showing what it looks like with a direct injection API
instead:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> Ts<span class="op">&gt;</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Tuple <span class="op">{</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">consteval</span> <span class="op">{</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>        std<span class="op">::</span>array types<span class="op">{^</span>Ts<span class="op">...}</span>;</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>        <span class="cf">for</span> <span class="op">(</span><span class="dt">size_t</span> i <span class="op">=</span> <span class="dv">0</span>; i <span class="op">!=</span> types<span class="op">.</span>size<span class="op">()</span> ;<span class="op">++</span>i<span class="op">)</span> <span class="op">{</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>            inject<span class="op">(</span>data_member_spec<span class="op">{.</span>name<span class="op">=</span>std<span class="op">::</span>format<span class="op">(</span><span class="st">&quot;_{}&quot;</span>, i<span class="op">)</span>,</span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>                                    <span class="op">.</span>type<span class="op">=</span>types<span class="op">[</span>i<span class="op">]})</span>;</span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
</div>
<h3 data-number="3.1.2" id="stdenable_if"><span class="header-section-number">3.1.2</span> <code class="sourceCode cpp">std<span class="op">::</span>enable_if</code><a href="#stdenable_if" class="self-link"></a></h3>
<p>Now, <code class="sourceCode cpp">std<span class="op">::</span>enable_if</code> has
already been obsolete technology since C++20. So implementing it,
specifically, is not entirely a motivating example. However, the general
idea of <code class="sourceCode cpp">std<span class="op">::</span>enable_if</code> as
<em>conditionally</em> having a member type is a problem that has no
good solution in C++ today.</p>
<p>The spec API along with injection does allow for a clean solution
here. We would just need to add an
<code class="sourceCode cpp">alias_spec</code> construct to get the job
done:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb4"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="dt">bool</span> B, <span class="kw">class</span> T<span class="op">=</span><span class="dt">void</span><span class="op">&gt;</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> enable_if <span class="op">{</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">consteval</span> <span class="op">{</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(</span>B<span class="op">)</span> <span class="op">{</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>            inject<span class="op">(</span>alias_spec<span class="op">{.</span>name<span class="op">=</span><span class="st">&quot;type&quot;</span>, <span class="op">.</span>type<span class="op">=^</span>T<span class="op">})</span>;</span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
</div>
<p>So far so good.</p>
<h3 data-number="3.1.3" id="properties"><span class="header-section-number">3.1.3</span> Properties<a href="#properties" class="self-link"></a></h3>
<p>Now is when the spec API really goes off the rails. We’ve shown data
members and extended it to member aliases. But how do we support member
functions?</p>
<p>We want to be able to add a
<code class="sourceCode cpp">property</code> with a given
<code class="sourceCode cpp">name</code> and
<code class="sourceCode cpp">type</code> that adds a member of that type
and a getter and setter for it. For instance, we want this code:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb5"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Book <span class="op">{</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">consteval</span> <span class="op">{</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>        property<span class="op">(</span><span class="st">&quot;author&quot;</span>, <span class="op">^</span>std<span class="op">::</span>string<span class="op">)</span>;</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>        property<span class="op">(</span><span class="st">&quot;title&quot;</span>, <span class="op">^</span>std<span class="op">::</span>string<span class="op">)</span>;</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
</div>
<p>to emit a class with two members
(<code class="sourceCode cpp">m_author</code> and
<code class="sourceCode cpp">m_title</code>), two getters that each
return a <code class="sourceCode cpp">std<span class="op">::</span>string <span class="kw">const</span><span class="op">&amp;</span></code>
(<code class="sourceCode cpp">get_author<span class="op">()</span></code>
and
<code class="sourceCode cpp">get_title<span class="op">()</span></code>)
and two setters that each take a <code class="sourceCode cpp">std<span class="op">::</span>string <span class="kw">const</span><span class="op">&amp;</span></code>
(<code class="sourceCode cpp">set_author<span class="op">()</span></code>
and
<code class="sourceCode cpp">set_title<span class="op">()</span></code>).
Fairly basic properties.</p>
<p>We start by injecting the member:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb6"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> property<span class="op">(</span>string_view name, meta<span class="op">::</span>info type<span class="op">)</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>    <span class="op">-&gt;</span> <span class="dt">void</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>    inject<span class="op">(</span>data_member_spec<span class="op">{.</span>name<span class="op">=</span>std<span class="op">::</span>format<span class="op">(</span><span class="st">&quot;m_{}&quot;</span>, name<span class="op">)</span>,</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>                            <span class="op">.</span>type<span class="op">=</span>type<span class="op">})</span>;</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>Now, we need to inject two functions. We’ll need a new kind of
<code class="sourceCode cpp">spec</code> for that case. For the function
body, we can use a lambda. Let’s start with the getter:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> property<span class="op">(</span>string_view name, meta<span class="op">::</span>info type<span class="op">)</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>    <span class="op">-&gt;</span> <span class="dt">void</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>    inject<span class="op">(</span>data_member_spec<span class="op">{.</span>name<span class="op">=</span>std<span class="op">::</span>format<span class="op">(</span><span class="st">&quot;m_{}&quot;</span>, name<span class="op">)</span>,</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>                            <span class="op">.</span>type<span class="op">=</span>type<span class="op">})</span>;</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a>    inject<span class="op">(</span>function_member_spec<span class="op">{</span></span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>name<span class="op">=</span>std<span class="op">::</span>format<span class="op">(</span><span class="st">&quot;get_{}&quot;</span>, name<span class="op">)</span>,</span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>body<span class="op">=^[](</span><span class="kw">auto</span> <span class="kw">const</span><span class="op">&amp;</span> self<span class="op">)</span> <span class="op">-&gt;</span> <span class="kw">auto</span> <span class="kw">const</span><span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> self<span class="op">.</span><span class="co">/* ????? */</span>;</span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb7-13"><a href="#cb7-13" aria-hidden="true" tabindex="-1"></a>    <span class="op">})</span>;</span>
<span id="cb7-14"><a href="#cb7-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-15"><a href="#cb7-15" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="cb7-16"><a href="#cb7-16" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>Okay. Uh. What do we return? For the title property, this needs to be
<code class="sourceCode cpp"><span class="cf">return</span> self<span class="op">.</span>m_title;</code>,
but how do we spell that? We just… can’t. We have our member right there
(the <code class="sourceCode cpp">data_member_spec</code> we’re
injecting), so you might think we could try to capture it:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb8"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> property<span class="op">(</span>string_view name, meta<span class="op">::</span>info type<span class="op">)</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>    <span class="op">-&gt;</span> <span class="dt">void</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> member <span class="op">=</span> inject<span class="op">(</span>data_member_spec<span class="op">{</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>name<span class="op">=</span>std<span class="op">::</span>format<span class="op">(</span><span class="st">&quot;m_{}&quot;</span>, name<span class="op">)</span>,</span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>type<span class="op">=</span>type</span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">})</span>;</span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>    inject<span class="op">(</span>function_member_spec<span class="op">{</span></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>name<span class="op">=</span>std<span class="op">::</span>format<span class="op">(</span><span class="st">&quot;get_{}&quot;</span>, name<span class="op">)</span>,</span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>body<span class="op">=^[</span>member<span class="op">](</span><span class="kw">auto</span> <span class="kw">const</span><span class="op">&amp;</span> self<span class="op">)</span> <span class="op">-&gt;</span> <span class="kw">auto</span> <span class="kw">const</span><span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> self<span class="op">.[:</span>member<span class="op">:]</span>;</span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a>    <span class="op">})</span>;</span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-16"><a href="#cb8-16" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="cb8-17"><a href="#cb8-17" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>But that doesn’t work - in order to splice
<code class="sourceCode cpp">member</code>, it needs to be a constant
expression - and it’s not in this context.</p>
<p>Now, the body of the lambda isn’t going to be evaluted in this
constant evaluation, so it’s possible to maybe come up with some
mechanism to pass a context through - such that from the body we
<em>can</em> simply splice <code class="sourceCode cpp">member</code>.
We basically need to come up with a way to defer this instantiation.</p>
<p>For now, let’s try a spelling like this:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb9"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> property<span class="op">(</span>string_view name, meta<span class="op">::</span>info type<span class="op">)</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>    <span class="op">-&gt;</span> <span class="dt">void</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> member <span class="op">=</span> inject<span class="op">(</span>data_member_spec<span class="op">{</span></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>name<span class="op">=</span>std<span class="op">::</span>format<span class="op">(</span><span class="st">&quot;m_{}&quot;</span>, name<span class="op">)</span>,</span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>type<span class="op">=</span>type</span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">})</span>;</span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a>    inject<span class="op">(</span>function_member_spec<span class="op">{</span></span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>name<span class="op">=</span>std<span class="op">::</span>format<span class="op">(</span><span class="st">&quot;get_{}&quot;</span>, name<span class="op">)</span>,</span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>body<span class="op">=</span>defer<span class="op">(</span>member, <span class="op">^[]&lt;</span>std<span class="op">::</span>meta<span class="op">::</span>info M<span class="op">&gt;(</span><span class="kw">auto</span> <span class="kw">const</span><span class="op">&amp;</span> self<span class="op">)</span> <span class="op">-&gt;</span> <span class="kw">auto</span> <span class="kw">const</span><span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> self<span class="op">.[:</span>M<span class="op">:]</span>;</span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true" tabindex="-1"></a>        <span class="op">})</span></span>
<span id="cb9-14"><a href="#cb9-14" aria-hidden="true" tabindex="-1"></a>    <span class="op">})</span>;</span>
<span id="cb9-15"><a href="#cb9-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-16"><a href="#cb9-16" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="cb9-17"><a href="#cb9-17" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>and we can do something similar with the setter:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb10"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> property<span class="op">(</span>string_view name, meta<span class="op">::</span>info type<span class="op">)</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>    <span class="op">-&gt;</span> <span class="dt">void</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> member <span class="op">=</span> inject<span class="op">(</span>data_member_spec<span class="op">{</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>name<span class="op">=</span>std<span class="op">::</span>format<span class="op">(</span><span class="st">&quot;m_{}&quot;</span>, name<span class="op">)</span>,</span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>type<span class="op">=</span>type</span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">})</span>;</span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a>    inject<span class="op">(</span>function_member_spec<span class="op">{</span></span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>name<span class="op">=</span>std<span class="op">::</span>format<span class="op">(</span><span class="st">&quot;get_{}&quot;</span>, name<span class="op">)</span>,</span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>body<span class="op">=</span>defer<span class="op">(</span>member, <span class="op">^[]&lt;</span>std<span class="op">::</span>meta<span class="op">::</span>info M<span class="op">&gt;(</span><span class="kw">auto</span> <span class="kw">const</span><span class="op">&amp;</span> self<span class="op">)</span> <span class="op">-&gt;</span> <span class="kw">auto</span> <span class="kw">const</span><span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> self<span class="op">.[:</span>M<span class="op">:]</span>;</span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true" tabindex="-1"></a>        <span class="op">})</span></span>
<span id="cb10-14"><a href="#cb10-14" aria-hidden="true" tabindex="-1"></a>    <span class="op">})</span>;</span>
<span id="cb10-15"><a href="#cb10-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-16"><a href="#cb10-16" aria-hidden="true" tabindex="-1"></a>    inject<span class="op">(</span>function_member_spec<span class="op">{</span></span>
<span id="cb10-17"><a href="#cb10-17" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>name<span class="op">=</span>std<span class="op">::</span>format<span class="op">(</span><span class="st">&quot;set_{}&quot;</span>, name<span class="op">)</span>,</span>
<span id="cb10-18"><a href="#cb10-18" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>body<span class="op">=</span>defer<span class="op">(</span>member, <span class="op">^[]&lt;</span>std<span class="op">::</span>meta<span class="op">::</span>info M<span class="op">&gt;(</span><span class="kw">auto</span><span class="op">&amp;</span> self, <span class="kw">typename</span> <span class="op">[:</span>type_of<span class="op">(</span>M<span class="op">):]</span> <span class="kw">const</span><span class="op">&amp;</span> x<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">void</span> <span class="op">{</span></span>
<span id="cb10-19"><a href="#cb10-19" aria-hidden="true" tabindex="-1"></a>            self<span class="op">.[:</span>M<span class="op">:]</span> <span class="op">=</span> x;</span>
<span id="cb10-20"><a href="#cb10-20" aria-hidden="true" tabindex="-1"></a>        <span class="op">})</span></span>
<span id="cb10-21"><a href="#cb10-21" aria-hidden="true" tabindex="-1"></a>    <span class="op">})</span>;</span>
<span id="cb10-22"><a href="#cb10-22" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>Now we run into the next problem: what actual signature is the
compiler going to inject for
<code class="sourceCode cpp">get_author<span class="op">()</span></code>
and
<code class="sourceCode cpp">set_author<span class="op">()</span></code>?
First, we’re introducing this extra non-type template parameter which we
have to know to strip off somehow. Secondly, we’re always taking the
object parameter as a deduced parameter. How does the API know what we
mean by that?</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb11"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Book <span class="op">{</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>    <span class="co">// do we mean this</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> get_author<span class="op">(</span><span class="kw">this</span> Book <span class="kw">const</span><span class="op">&amp;</span> self<span class="op">)</span> <span class="op">-&gt;</span> <span class="kw">auto</span> <span class="kw">const</span><span class="op">&amp;</span> <span class="op">{</span> <span class="cf">return</span> self<span class="op">.</span>m_author; <span class="op">}</span></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> set_author<span class="op">(</span><span class="kw">this</span> Book<span class="op">&amp;</span> self, string <span class="kw">const</span><span class="op">&amp;</span> x<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">void</span> <span class="op">{</span> self<span class="op">.</span>m_author <span class="op">=</span> x; <span class="op">}</span></span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a>    <span class="co">// or this</span></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> get_author<span class="op">(</span><span class="kw">this</span> <span class="kw">auto</span> <span class="kw">const</span><span class="op">&amp;</span> self<span class="op">)</span> <span class="op">-&gt;</span> <span class="kw">auto</span> <span class="kw">const</span><span class="op">&amp;</span> <span class="op">{</span> <span class="cf">return</span> self<span class="op">.</span>m_author; <span class="op">}</span></span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> set_author<span class="op">(</span><span class="kw">this</span> <span class="kw">auto</span><span class="op">&amp;</span> self, string <span class="kw">const</span><span class="op">&amp;</span> x<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">void</span> <span class="op">{</span> self<span class="op">.</span>m_author <span class="op">=</span> x; <span class="op">}</span></span>
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
</div>
<p>That is: how does the compiler know whether we’re injecting a member
function or a member function template? Our lambda has to be generic
either way. Moreover, even if we actually wanted to inject a function
template, it’s possible that we might want some parameter to be
dependent but <em>not</em> the object parameter.</p>
<p>Well, we could provide another piece of information to
<code class="sourceCode cpp">function_member_spec</code>: the signature
directly:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb12"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span> <span class="kw">using</span> getter_type <span class="op">=</span> <span class="kw">auto</span><span class="op">()</span> <span class="kw">const</span> <span class="op">-&gt;</span> T <span class="kw">const</span><span class="op">&amp;</span>;</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span> <span class="kw">using</span> setter_type <span class="op">=</span> <span class="kw">auto</span><span class="op">(</span>T <span class="kw">const</span><span class="op">&amp;)</span> <span class="op">-&gt;</span> <span class="dt">void</span>;</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> property<span class="op">(</span>string_view name, meta<span class="op">::</span>info type<span class="op">)</span></span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">-&gt;</span> <span class="dt">void</span></span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> member <span class="op">=</span> inject<span class="op">(</span>data_member_spec<span class="op">{</span></span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>name<span class="op">=</span>std<span class="op">::</span>format<span class="op">(</span><span class="st">&quot;m_{}&quot;</span>, name<span class="op">)</span>,</span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>type<span class="op">=</span>type</span>
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a>    <span class="op">})</span>;</span>
<span id="cb12-11"><a href="#cb12-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-12"><a href="#cb12-12" aria-hidden="true" tabindex="-1"></a>    inject<span class="op">(</span>function_member_spec<span class="op">{</span></span>
<span id="cb12-13"><a href="#cb12-13" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>name<span class="op">=</span>std<span class="op">::</span>format<span class="op">(</span><span class="st">&quot;get_{}&quot;</span>, name<span class="op">)</span>,</span>
<span id="cb12-14"><a href="#cb12-14" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>signature<span class="op">=</span>substitute<span class="op">(^</span>getter_type, <span class="op">{^</span>type<span class="op">})</span>,</span>
<span id="cb12-15"><a href="#cb12-15" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>body<span class="op">=</span>defer<span class="op">(</span>member, <span class="op">^[]&lt;</span>std<span class="op">::</span>meta<span class="op">::</span>info M<span class="op">&gt;(</span><span class="kw">auto</span> <span class="kw">const</span><span class="op">&amp;</span> self<span class="op">)</span> <span class="op">-&gt;</span> <span class="kw">auto</span> <span class="kw">const</span><span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb12-16"><a href="#cb12-16" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> self<span class="op">.[:</span>M<span class="op">:]</span>;</span>
<span id="cb12-17"><a href="#cb12-17" aria-hidden="true" tabindex="-1"></a>        <span class="op">})</span></span>
<span id="cb12-18"><a href="#cb12-18" aria-hidden="true" tabindex="-1"></a>    <span class="op">})</span>;</span>
<span id="cb12-19"><a href="#cb12-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-20"><a href="#cb12-20" aria-hidden="true" tabindex="-1"></a>    inject<span class="op">(</span>function_member_spec<span class="op">{</span></span>
<span id="cb12-21"><a href="#cb12-21" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>name<span class="op">=</span>std<span class="op">::</span>format<span class="op">(</span><span class="st">&quot;set_{}&quot;</span>, name<span class="op">)</span>,</span>
<span id="cb12-22"><a href="#cb12-22" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>signature<span class="op">=</span>substitute<span class="op">(^</span>setter_type, <span class="op">{^</span>type<span class="op">})</span>,</span>
<span id="cb12-23"><a href="#cb12-23" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>body<span class="op">=</span>defer<span class="op">(</span>member, <span class="op">^[]&lt;</span>std<span class="op">::</span>meta<span class="op">::</span>info M<span class="op">&gt;(</span><span class="kw">auto</span><span class="op">&amp;</span> self, <span class="kw">typename</span> <span class="op">[:</span>type_of<span class="op">(</span>M<span class="op">):]</span> <span class="kw">const</span><span class="op">&amp;</span> x<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">void</span> <span class="op">{</span></span>
<span id="cb12-24"><a href="#cb12-24" aria-hidden="true" tabindex="-1"></a>            self<span class="op">.[:</span>M<span class="op">:]</span> <span class="op">=</span> x;</span>
<span id="cb12-25"><a href="#cb12-25" aria-hidden="true" tabindex="-1"></a>        <span class="op">})</span></span>
<span id="cb12-26"><a href="#cb12-26" aria-hidden="true" tabindex="-1"></a>    <span class="op">})</span>;</span>
<span id="cb12-27"><a href="#cb12-27" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>Which then maybe feels like the correct spelling is actually more
like this, so that we can actually properly infer all the
information:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb13"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> property<span class="op">(</span>string_view name, meta<span class="op">::</span>info type<span class="op">)</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>    <span class="op">-&gt;</span> <span class="dt">void</span></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> member <span class="op">=</span> inject<span class="op">(</span>data_member_spec<span class="op">{</span></span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>name<span class="op">=</span>std<span class="op">::</span>format<span class="op">(</span><span class="st">&quot;m_{}&quot;</span>, name<span class="op">)</span>,</span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>type<span class="op">=</span>type</span>
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">})</span>;</span>
<span id="cb13-8"><a href="#cb13-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-9"><a href="#cb13-9" aria-hidden="true" tabindex="-1"></a>    <span class="co">// note that this type is structural</span></span>
<span id="cb13-10"><a href="#cb13-10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">struct</span> Context <span class="op">{</span></span>
<span id="cb13-11"><a href="#cb13-11" aria-hidden="true" tabindex="-1"></a>        std<span class="op">::</span>meta<span class="op">::</span>info type;</span>
<span id="cb13-12"><a href="#cb13-12" aria-hidden="true" tabindex="-1"></a>        std<span class="op">::</span>meta<span class="op">::</span>info member;</span>
<span id="cb13-13"><a href="#cb13-13" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span>;</span>
<span id="cb13-14"><a href="#cb13-14" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> pctx <span class="op">=</span> Context<span class="op">{</span></span>
<span id="cb13-15"><a href="#cb13-15" aria-hidden="true" tabindex="-1"></a>      <span class="co">// get the type of the current context that we&#39;re injecting into</span></span>
<span id="cb13-16"><a href="#cb13-16" aria-hidden="true" tabindex="-1"></a>      <span class="op">.</span>type<span class="op">=</span>type_of<span class="op">(</span>std<span class="op">::</span>meta<span class="op">::</span>current<span class="op">())</span>,</span>
<span id="cb13-17"><a href="#cb13-17" aria-hidden="true" tabindex="-1"></a>      <span class="op">.</span>member<span class="op">=</span>member</span>
<span id="cb13-18"><a href="#cb13-18" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span>;</span>
<span id="cb13-19"><a href="#cb13-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-20"><a href="#cb13-20" aria-hidden="true" tabindex="-1"></a>    inject<span class="op">(</span>function_member_spec<span class="op">{</span></span>
<span id="cb13-21"><a href="#cb13-21" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>name<span class="op">=</span>std<span class="op">::</span>format<span class="op">(</span><span class="st">&quot;get_{}&quot;</span>, name<span class="op">)</span>,</span>
<span id="cb13-22"><a href="#cb13-22" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>body<span class="op">=</span>defer<span class="op">(</span>context, <span class="op">^[]&lt;</span>Context C<span class="op">&gt;(){</span></span>
<span id="cb13-23"><a href="#cb13-23" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> <span class="op">[](</span><span class="kw">typename</span> <span class="op">[:</span>C<span class="op">.</span>type<span class="op">:]</span> <span class="kw">const</span><span class="op">&amp;</span> self<span class="op">)</span> <span class="op">-&gt;</span> <span class="kw">auto</span> <span class="kw">const</span><span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb13-24"><a href="#cb13-24" aria-hidden="true" tabindex="-1"></a>                <span class="cf">return</span> self<span class="op">.[:</span>C<span class="op">.</span>member<span class="op">:]</span>;</span>
<span id="cb13-25"><a href="#cb13-25" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span>;</span>
<span id="cb13-26"><a href="#cb13-26" aria-hidden="true" tabindex="-1"></a>        <span class="op">})</span></span>
<span id="cb13-27"><a href="#cb13-27" aria-hidden="true" tabindex="-1"></a>    <span class="op">})</span>;</span>
<span id="cb13-28"><a href="#cb13-28" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-29"><a href="#cb13-29" aria-hidden="true" tabindex="-1"></a>    inject<span class="op">(</span>function_member_spec<span class="op">{</span></span>
<span id="cb13-30"><a href="#cb13-30" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>name<span class="op">=</span>std<span class="op">::</span>format<span class="op">(</span><span class="st">&quot;set_{}&quot;</span>, name<span class="op">)</span>,</span>
<span id="cb13-31"><a href="#cb13-31" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>body<span class="op">=</span>defer<span class="op">(</span>context, <span class="op">^[]&lt;</span>Context C<span class="op">&gt;(){</span></span>
<span id="cb13-32"><a href="#cb13-32" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> <span class="op">[](</span><span class="kw">typename</span> <span class="op">[:</span>C<span class="op">.</span>type<span class="op">:]&amp;</span> self, <span class="kw">typename</span> <span class="op">[:</span>type_of<span class="op">(</span>C<span class="op">.</span>member<span class="op">):]</span> <span class="kw">const</span><span class="op">&amp;</span> x<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">void</span> <span class="op">{</span></span>
<span id="cb13-33"><a href="#cb13-33" aria-hidden="true" tabindex="-1"></a>                self<span class="op">.[:</span>C<span class="op">.</span>member<span class="op">:]</span> <span class="op">=</span> x;</span>
<span id="cb13-34"><a href="#cb13-34" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span>;</span>
<span id="cb13-35"><a href="#cb13-35" aria-hidden="true" tabindex="-1"></a>        <span class="op">})</span></span>
<span id="cb13-36"><a href="#cb13-36" aria-hidden="true" tabindex="-1"></a>    <span class="op">})</span>;</span>
<span id="cb13-37"><a href="#cb13-37" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>That is, we create a custom context type that we pass in as a
non-type template parameter into a lambda, so that it <em>it</em> can
return a new lambda with all the types and names properly substituted in
when that can actually be made to work.</p>
<p>This solution… might be workable. But it’s already pretty complicated
and the problem we’re trying to solve really isn’t. As a result, we
believe that the spec API is somewhat of a dead end when it comes to
extending injection support.</p>
<h3 data-number="3.1.4" id="disposition"><span class="header-section-number">3.1.4</span> Disposition<a href="#disposition" class="self-link"></a></h3>
<p>It’s hard to view favorably a design for the long-term future of code
injection with which we cannot even figure out how to inject functions.
Even if we could, this design scales poorly with the language: we need a
library API for many language constructs, and C++ is a language with a
lot of kinds. That makes for a large barrier to entry for
metaprogramming that we would like to avoid.</p>
<p>Nevertheless, the spec API does have one thing going for it: it is
quite simple. At the very least, we think we should extend the spec
model in P2996 in the following ways:</p>
<ul>
<li>extend <code class="sourceCode cpp">data_member_spec</code> to
support all data members (static/constexpr/inline, attributes, access,
and initializer).</li>
<li>add <code class="sourceCode cpp">alias_spec</code> and
<code class="sourceCode cpp">base_class_spec</code></li>
</ul>
<p>These are the simple cases, and we can get a lot done with the simple
cases, even without a full solution.</p>
<h2 data-number="3.2" id="the-codereckons-api"><span class="header-section-number">3.2</span> The CodeReckons API<a href="#the-codereckons-api" class="self-link"></a></h2>
<p>The <a href="https://lists.isocpp.org/sg7/2024/04/0507.php">CodeReckons</a>
approach provides a very different injection mechanism than what is in
P2996 or what has been described in any of the metaprogramming papers.
We can run through these three examples and see what they look like.
Here, we will use the actual syntax as implemented in that compiler.</p>
<h3 data-number="3.2.1" id="stdtuple-1"><span class="header-section-number">3.2.1</span>
<code class="sourceCode cpp">std<span class="op">::</span>tuple</code><a href="#stdtuple-1" class="self-link"></a></h3>
<p>The initial CodeReckons article provides <a href="https://cppmeta.codereckons.com/tools/z/j74nc4">an
implementation</a> for adding the data members of a tuple like so:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb14"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> Ts<span class="op">&gt;</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> tuple <span class="op">{</span></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">%</span> <span class="op">[](</span>class_builder<span class="op">&amp;</span> b<span class="op">){</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> k <span class="op">=</span> <span class="dv">0</span>;</span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> <span class="op">(</span>type T <span class="op">:</span> std<span class="op">::</span>meta<span class="op">::</span>type_list<span class="op">{^</span>Ts<span class="op">...})</span> <span class="op">{</span></span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a>        append_field<span class="op">(</span>b, cat<span class="op">(</span><span class="st">&quot;m&quot;</span>, k<span class="op">++)</span>, T<span class="op">)</span>;</span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a>  <span class="op">}()</span>;</span>
<span id="cb14-9"><a href="#cb14-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
</div>
<p>This isn’t too different from what we showed in the earlier section
with <code class="sourceCode cpp">data_member_spec</code>. Different
spelling and API, but it’s the same model
(<code class="sourceCode cpp">append_field</code> is equivalent to
injecting a <code class="sourceCode cpp">data_member_spec</code>).</p>
<h3 data-number="3.2.2" id="stdenable_if-1"><span class="header-section-number">3.2.2</span> <code class="sourceCode cpp">std<span class="op">::</span>enable_if</code><a href="#stdenable_if-1" class="self-link"></a></h3>
<p>Likewise, we have just a <a href="https://cppmeta.codereckons.com/tools/z/rh8zef">difference of
spelling</a>:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb15"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="dt">bool</span> B, <span class="kw">typename</span> T<span class="op">=</span><span class="dt">void</span><span class="op">&gt;</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> enable_if <span class="op">{</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">%</span> <span class="op">[](</span>class_builder<span class="op">&amp;</span> b<span class="op">){</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(</span>B<span class="op">)</span> <span class="op">{</span></span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>            append_alias<span class="op">(</span>b, identifier<span class="op">{</span><span class="st">&quot;type&quot;</span><span class="op">}</span>, <span class="op">^</span>T<span class="op">)</span>;</span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">}()</span>;</span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
</div>
<h3 data-number="3.2.3" id="properties-1"><span class="header-section-number">3.2.3</span> Properties<a href="#properties-1" class="self-link"></a></h3>
<p>Here is where the CodeReckons approach differs greatly from the
potential spec API, and it’s worth examining how they <a href="https://cppmeta.codereckons.com/tools/z/znjs3f">got it
working</a>:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb16"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> property<span class="op">(</span>class_builder<span class="op">&amp;</span> b, type type, std<span class="op">::</span>string name<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">void</span> <span class="op">{</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> member_name <span class="op">=</span> identifier<span class="op">{(</span><span class="st">&quot;m_&quot;</span> <span class="op">+</span> name<span class="op">).</span>c_str<span class="op">()}</span>;</span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a>    append_field<span class="op">(</span>b, member_name, type<span class="op">)</span>;</span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>    <span class="co">// getter</span></span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a>        method_prototype mp;</span>
<span id="cb16-8"><a href="#cb16-8" aria-hidden="true" tabindex="-1"></a>        object_type<span class="op">(</span>mp, make_const<span class="op">(</span>decl_of<span class="op">(</span>b<span class="op">)))</span>;</span>
<span id="cb16-9"><a href="#cb16-9" aria-hidden="true" tabindex="-1"></a>        return_type<span class="op">(</span>mp, make_lvalue_reference<span class="op">(</span>make_const<span class="op">(</span>type<span class="op">)))</span>;</span>
<span id="cb16-10"><a href="#cb16-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-11"><a href="#cb16-11" aria-hidden="true" tabindex="-1"></a>        append_method<span class="op">(</span>b, identifier<span class="op">{(</span><span class="st">&quot;get_&quot;</span> <span class="op">+</span> name<span class="op">).</span>c_str<span class="op">()}</span>, mp,</span>
<span id="cb16-12"><a href="#cb16-12" aria-hidden="true" tabindex="-1"></a>            <span class="op">[</span>member_name<span class="op">](</span>method_builder<span class="op">&amp;</span> b<span class="op">){</span></span>
<span id="cb16-13"><a href="#cb16-13" aria-hidden="true" tabindex="-1"></a>                append_return<span class="op">(</span>b,</span>
<span id="cb16-14"><a href="#cb16-14" aria-hidden="true" tabindex="-1"></a>                    make_field_expr<span class="op">(</span></span>
<span id="cb16-15"><a href="#cb16-15" aria-hidden="true" tabindex="-1"></a>                        make_deref_expr<span class="op">(</span>make_this_expr<span class="op">(</span>b<span class="op">))</span>,</span>
<span id="cb16-16"><a href="#cb16-16" aria-hidden="true" tabindex="-1"></a>                        member_name<span class="op">))</span>;</span>
<span id="cb16-17"><a href="#cb16-17" aria-hidden="true" tabindex="-1"></a>            <span class="op">})</span>;</span>
<span id="cb16-18"><a href="#cb16-18" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb16-19"><a href="#cb16-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-20"><a href="#cb16-20" aria-hidden="true" tabindex="-1"></a>    <span class="co">// setter</span></span>
<span id="cb16-21"><a href="#cb16-21" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="cb16-22"><a href="#cb16-22" aria-hidden="true" tabindex="-1"></a>        method_prototype mp;</span>
<span id="cb16-23"><a href="#cb16-23" aria-hidden="true" tabindex="-1"></a>        append_parameter<span class="op">(</span>mp, <span class="st">&quot;x&quot;</span>, make_lvalue_reference<span class="op">(</span>make_const<span class="op">(</span>type<span class="op">)))</span>;</span>
<span id="cb16-24"><a href="#cb16-24" aria-hidden="true" tabindex="-1"></a>        object_type<span class="op">(</span>mp, decl_of<span class="op">(</span>b<span class="op">))</span>;</span>
<span id="cb16-25"><a href="#cb16-25" aria-hidden="true" tabindex="-1"></a>        return_type<span class="op">(</span>mp, <span class="op">^</span><span class="dt">void</span><span class="op">)</span>;</span>
<span id="cb16-26"><a href="#cb16-26" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-27"><a href="#cb16-27" aria-hidden="true" tabindex="-1"></a>        append_method<span class="op">(</span>b, identifier<span class="op">{(</span><span class="st">&quot;set_&quot;</span> <span class="op">+</span> name<span class="op">).</span>c_str<span class="op">()}</span>, mp,</span>
<span id="cb16-28"><a href="#cb16-28" aria-hidden="true" tabindex="-1"></a>            <span class="op">[</span>member_name<span class="op">](</span>method_builder<span class="op">&amp;</span> b<span class="op">){</span></span>
<span id="cb16-29"><a href="#cb16-29" aria-hidden="true" tabindex="-1"></a>                append_expr<span class="op">(</span>b,</span>
<span id="cb16-30"><a href="#cb16-30" aria-hidden="true" tabindex="-1"></a>                    make_operator_expr<span class="op">(</span></span>
<span id="cb16-31"><a href="#cb16-31" aria-hidden="true" tabindex="-1"></a>                        operator_kind<span class="op">::</span>assign,</span>
<span id="cb16-32"><a href="#cb16-32" aria-hidden="true" tabindex="-1"></a>                        make_field_expr<span class="op">(</span>make_deref_expr<span class="op">(</span>make_this_expr<span class="op">(</span>b<span class="op">))</span>, member_name<span class="op">)</span>,</span>
<span id="cb16-33"><a href="#cb16-33" aria-hidden="true" tabindex="-1"></a>                        make_decl_ref_expr<span class="op">(</span>parameters<span class="op">(</span>decl_of<span class="op">(</span>b<span class="op">))[</span><span class="dv">1</span><span class="op">])</span></span>
<span id="cb16-34"><a href="#cb16-34" aria-hidden="true" tabindex="-1"></a>                        <span class="op">))</span>;</span>
<span id="cb16-35"><a href="#cb16-35" aria-hidden="true" tabindex="-1"></a>            <span class="op">})</span>;</span>
<span id="cb16-36"><a href="#cb16-36" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb16-37"><a href="#cb16-37" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb16-38"><a href="#cb16-38" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-39"><a href="#cb16-39" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Book <span class="op">{</span></span>
<span id="cb16-40"><a href="#cb16-40" aria-hidden="true" tabindex="-1"></a>    <span class="op">%</span> property<span class="op">(^</span>std<span class="op">::</span>string, <span class="st">&quot;author&quot;</span><span class="op">)</span>;</span>
<span id="cb16-41"><a href="#cb16-41" aria-hidden="true" tabindex="-1"></a>    <span class="op">%</span> property<span class="op">(^</span>std<span class="op">::</span>string, <span class="st">&quot;title&quot;</span><span class="op">)</span>;</span>
<span id="cb16-42"><a href="#cb16-42" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
</div>
<p>In this model, we have to provide the signature of the two member
functions (via <code class="sourceCode cpp">method_prototype</code>),
and the bodies of the two member functions are provided as lambdas. But
the lambda bodies here are not the C++ code that will be evaluated at
runtime - it’s still part of the AST building process. We have to
define, at the AST level, what these member functions do.</p>
<p>In the spec API, we struggled how to write a function that takes a
<code class="sourceCode cpp">string <span class="kw">const</span><span class="op">&amp;</span></code>
and whose body is <code class="sourceCode cpp">self<span class="op">.{</span>member name<span class="op">}</span> <span class="op">=</span> x;</code>.
Here, because we don’t need to access any of our reflections as constant
expressions, we can make use of them directly.</p>
<p>But the result is… extremely verbose. This is a lot of code, that
doesn’t seem like it would scale very well. The setter alone (which is
just trying to do something like <code class="sourceCode cpp">self<span class="op">.</span>m_author <span class="op">=</span> x;</code>)
is already 14 lines of code and is fairly complicated. We think it’s
important that code injection still look like writing C++ code, not live
at the AST level.</p>
<p>Nevertheless, this API does actually work. Whereas the spec API is
still, at best, just a guess.</p>
<h3 data-number="3.2.4" id="postfix-increment"><span class="header-section-number">3.2.4</span> Postfix Increment<a href="#postfix-increment" class="self-link"></a></h3>
<p>For postfix increment, we want to inject the single function:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb17"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> <span class="kw">operator</span><span class="op">++(</span><span class="dt">int</span><span class="op">)</span> <span class="op">-&gt;</span> T <span class="op">{</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> tmp <span class="op">=</span> <span class="op">*</span><span class="kw">this</span>;</span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">++*</span><span class="kw">this</span>;</span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> tmp;</span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>We rely on the type to provide the correct prefix increment. With the
CodeReckons API, that looks <a href="https://cppmeta.codereckons.com/tools/z/71To7o">like this</a>:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb18"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> postfix_increment<span class="op">(</span>class_builder<span class="op">&amp;</span> b<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">void</span> <span class="op">{</span></span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>    method_prototype mp;</span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>    append_parameter<span class="op">(</span>mp, <span class="st">&quot;x&quot;</span>, <span class="op">^</span><span class="dt">int</span><span class="op">)</span>;</span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a>    object_type<span class="op">(</span>mp, decl_of<span class="op">(</span>b<span class="op">))</span>;</span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a>    return_type<span class="op">(</span>mp, decl_of<span class="op">(</span>b<span class="op">))</span>;</span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a>    append_method<span class="op">(</span>b, operator_kind<span class="op">::</span>post_inc, mp,</span>
<span id="cb18-8"><a href="#cb18-8" aria-hidden="true" tabindex="-1"></a>        <span class="op">[](</span>method_builder<span class="op">&amp;</span> b<span class="op">){</span></span>
<span id="cb18-9"><a href="#cb18-9" aria-hidden="true" tabindex="-1"></a>            <span class="co">// auto tmp = *this;</span></span>
<span id="cb18-10"><a href="#cb18-10" aria-hidden="true" tabindex="-1"></a>            <span class="kw">auto</span> tmp <span class="op">=</span> append_var<span class="op">(</span>b, <span class="st">&quot;tmp&quot;</span>, auto_ty,</span>
<span id="cb18-11"><a href="#cb18-11" aria-hidden="true" tabindex="-1"></a>                make_deref_expr<span class="op">(</span>make_this_expr<span class="op">(</span>b<span class="op">)))</span>;</span>
<span id="cb18-12"><a href="#cb18-12" aria-hidden="true" tabindex="-1"></a>            <span class="co">// ++*this;</span></span>
<span id="cb18-13"><a href="#cb18-13" aria-hidden="true" tabindex="-1"></a>            append_expr<span class="op">(</span>b,</span>
<span id="cb18-14"><a href="#cb18-14" aria-hidden="true" tabindex="-1"></a>                make_operator_expr<span class="op">(</span></span>
<span id="cb18-15"><a href="#cb18-15" aria-hidden="true" tabindex="-1"></a>                    operator_kind<span class="op">::</span>pre_inc,</span>
<span id="cb18-16"><a href="#cb18-16" aria-hidden="true" tabindex="-1"></a>                    make_deref_expr<span class="op">(</span>make_this_expr<span class="op">(</span>b<span class="op">))))</span>;</span>
<span id="cb18-17"><a href="#cb18-17" aria-hidden="true" tabindex="-1"></a>            <span class="co">// return tmp;</span></span>
<span id="cb18-18"><a href="#cb18-18" aria-hidden="true" tabindex="-1"></a>            append_return<span class="op">(</span>b, make_decl_ref_expr<span class="op">(</span>tmp<span class="op">))</span>;</span>
<span id="cb18-19"><a href="#cb18-19" aria-hidden="true" tabindex="-1"></a>        <span class="op">})</span>;</span>
<span id="cb18-20"><a href="#cb18-20" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb18-21"><a href="#cb18-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-22"><a href="#cb18-22" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> C <span class="op">{</span></span>
<span id="cb18-23"><a href="#cb18-23" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> i;</span>
<span id="cb18-24"><a href="#cb18-24" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-25"><a href="#cb18-25" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> <span class="kw">operator</span><span class="op">++()</span> <span class="op">-&gt;</span> C<span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb18-26"><a href="#cb18-26" aria-hidden="true" tabindex="-1"></a>        <span class="op">++</span>i;</span>
<span id="cb18-27"><a href="#cb18-27" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="op">*</span><span class="kw">this</span>;</span>
<span id="cb18-28"><a href="#cb18-28" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb18-29"><a href="#cb18-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-30"><a href="#cb18-30" aria-hidden="true" tabindex="-1"></a>    <span class="op">%</span> postfix_increment<span class="op">()</span>;</span>
<span id="cb18-31"><a href="#cb18-31" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
</div>
<p>As with the property example above, having an AST-based API is
extremely verbose. It might be useful to simply compare the statement we
want to generate with the code that we require to write to generate that
statement:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb19"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="co">// auto tmp = *this;</span></span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>   <span class="kw">auto</span> tmp <span class="op">=</span> append_var<span class="op">(</span>b, <span class="st">&quot;tmp&quot;</span>, auto_ty, make_deref_expr<span class="op">(</span>make_this_expr<span class="op">(</span>b<span class="op">)))</span>;</span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a><span class="co">// ++*this;</span></span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a>   append_expr<span class="op">(</span>b, make_operator_expr<span class="op">(</span>operator_kind<span class="op">::</span>pre_inc, make_deref_expr<span class="op">(</span>make_this_expr<span class="op">(</span>b<span class="op">))))</span>;</span>
<span id="cb19-6"><a href="#cb19-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb19-7"><a href="#cb19-7" aria-hidden="true" tabindex="-1"></a><span class="co">// return tmp;</span></span>
<span id="cb19-8"><a href="#cb19-8" aria-hidden="true" tabindex="-1"></a>   append_return<span class="op">(</span>b, make_decl_ref_expr<span class="op">(</span>tmp<span class="op">))</span>;</span></code></pre></div>
</blockquote>
</div>
<h3 data-number="3.2.5" id="disposition-1"><span class="header-section-number">3.2.5</span> Disposition<a href="#disposition-1" class="self-link"></a></h3>
<p>We believe an important goal for code injection is that the code
being injected looks like C++. This is the best way to ensure both a low
barrier to entry for using the facility as well as easing language
evolution in the future. We do not want to have to have to add a mirror
API to the reflection library for every language facility we add.</p>
<p>The CodeReckons API has the significant and not-to-be-minimized
property that it, unlike the Spec API, works. It is also arguably easy
to <em>read</em> the code in question to figure out what is going on. In
our experiments with simply giving people code snippets to people with
no context and asking them what the snippet does, people were able to
figure it out.</p>
<p>However, in our experience it is pretty difficult to <em>write</em>
the code precisely because it needs to be written at a different layer
than C++ code usually is written in and the abstraction penalty (in
terms of code length) is so large. We will compare this AST-based API to
a few other ideas in the following sections to give a sense of what we
mean here.</p>
<h2 data-number="3.3" id="string-injection"><span class="header-section-number">3.3</span> String Injection<a href="#string-injection" class="self-link"></a></h2>
<p>If we go back all the way to the beginning - we’re trying to inject
code. Perhaps the simplest possible model for how to inject code would
be: just inject strings.</p>
<p>The advantage of strings is clear: everyone already knows how to
build up strings. This makes implementing the three use-cases presented
thus far is pretty straightforward.</p>
<h3 data-number="3.3.1" id="stdtuple-2"><span class="header-section-number">3.3.1</span>
<code class="sourceCode cpp">std<span class="op">::</span>tuple</code><a href="#stdtuple-2" class="self-link"></a></h3>
<p>We could just do tuple this way:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb20"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> Ts<span class="op">&gt;</span></span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Tuple <span class="op">{</span></span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">consteval</span> <span class="op">{</span></span>
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a>        std<span class="op">::</span>array types<span class="op">{^</span>Ts<span class="op">...}</span>;</span>
<span id="cb20-5"><a href="#cb20-5" aria-hidden="true" tabindex="-1"></a>        <span class="cf">for</span> <span class="op">(</span><span class="dt">size_t</span> i <span class="op">=</span> <span class="dv">0</span>; i <span class="op">!=</span> types<span class="op">.</span>size<span class="op">()</span>; <span class="op">++</span>i<span class="op">)</span> <span class="op">{</span></span>
<span id="cb20-6"><a href="#cb20-6" aria-hidden="true" tabindex="-1"></a>            inject<span class="op">(</span>std<span class="op">::</span>format<span class="op">(</span></span>
<span id="cb20-7"><a href="#cb20-7" aria-hidden="true" tabindex="-1"></a>                <span class="st">&quot;[[no_unique_address]] {} _{};&quot;</span>,</span>
<span id="cb20-8"><a href="#cb20-8" aria-hidden="true" tabindex="-1"></a>                qualified_name_of<span class="op">(</span>types<span class="op">[</span>i<span class="op">])</span>,</span>
<span id="cb20-9"><a href="#cb20-9" aria-hidden="true" tabindex="-1"></a>                i<span class="op">))</span>;</span>
<span id="cb20-10"><a href="#cb20-10" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb20-11"><a href="#cb20-11" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb20-12"><a href="#cb20-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
</div>
<p>Note that here we even added support for <code class="sourceCode cpp"><span class="op">[[</span><span class="at">no_unique_address</span><span class="op">]]</span></code>,
which we haven’t done in either of the previous models. Although we
could come up with a way to add it to either of the two previous APIs,
the fact that with string injection we don’t even have to come up with a
way to do this is a pretty significant upside. Everything just
works.</p>
<p>Now, this would work - we’d have to be careful to use
<code class="sourceCode cpp">qualified_name_of</code> here to avoid any
question of name lookup. But it would be better to simply avoid these
questions altogether by actually being able to splice in the type rather
than referring to it by name.</p>
<p>We can do that by very slightly extending the API to take, as its
first argument, an environment. And then we can reduce it again by
having the API itself be a <code class="sourceCode cpp">format</code>
API:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb21"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> Ts<span class="op">&gt;</span></span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Tuple <span class="op">{</span></span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">consteval</span> <span class="op">{</span></span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a>        std<span class="op">::</span>array types<span class="op">{^</span>Ts<span class="op">...}</span>;</span>
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a>        <span class="cf">for</span> <span class="op">(</span><span class="dt">size_t</span> i <span class="op">=</span> <span class="dv">0</span>; i <span class="op">!=</span> types<span class="op">.</span>size<span class="op">()</span>; <span class="op">++</span>i<span class="op">)</span> <span class="op">{</span></span>
<span id="cb21-6"><a href="#cb21-6" aria-hidden="true" tabindex="-1"></a>            inject<span class="op">(</span></span>
<span id="cb21-7"><a href="#cb21-7" aria-hidden="true" tabindex="-1"></a>                <span class="op">{{</span><span class="st">&quot;type&quot;</span>, types<span class="op">[</span>i<span class="op">]}}</span>,</span>
<span id="cb21-8"><a href="#cb21-8" aria-hidden="true" tabindex="-1"></a>                <span class="st">&quot;[[no_unique_address]] [:type:] _{};&quot;</span>,</span>
<span id="cb21-9"><a href="#cb21-9" aria-hidden="true" tabindex="-1"></a>                i<span class="op">)</span>;</span>
<span id="cb21-10"><a href="#cb21-10" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb21-11"><a href="#cb21-11" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb21-12"><a href="#cb21-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
</div>
<h3 data-number="3.3.2" id="stdenable_if-2"><span class="header-section-number">3.3.2</span> <code class="sourceCode cpp">std<span class="op">::</span>enable_if</code><a href="#stdenable_if-2" class="self-link"></a></h3>
<p>This one is even simpler, since we don’t even need to bother with
name lookup questions or splicing:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb22"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="dt">bool</span> B, <span class="kw">class</span> T<span class="op">=</span><span class="dt">void</span><span class="op">&gt;</span></span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> enable_if <span class="op">{</span></span>
<span id="cb22-3"><a href="#cb22-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">consteval</span> <span class="op">{</span></span>
<span id="cb22-4"><a href="#cb22-4" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(</span>B<span class="op">)</span> <span class="op">{</span></span>
<span id="cb22-5"><a href="#cb22-5" aria-hidden="true" tabindex="-1"></a>            inject<span class="op">(</span><span class="st">&quot;using type = T;&quot;</span><span class="op">)</span>;</span>
<span id="cb22-6"><a href="#cb22-6" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb22-7"><a href="#cb22-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span>;</span>
<span id="cb22-8"><a href="#cb22-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
</div>
<h3 data-number="3.3.3" id="properties-2"><span class="header-section-number">3.3.3</span> Properties<a href="#properties-2" class="self-link"></a></h3>
<p>Unlike with the spec API, implementing a property by way of code is
straightforward. And unlike the CodeReckons API, we can write what looks
like C++ code:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb23"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> property<span class="op">(</span>info type, string_view name<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">void</span> <span class="op">{</span></span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a>    inject<span class="op">(</span>meta<span class="op">::</span>format_with_environment<span class="op">(</span></span>
<span id="cb23-3"><a href="#cb23-3" aria-hidden="true" tabindex="-1"></a>        <span class="op">{{</span><span class="st">&quot;T&quot;</span>, type<span class="op">}}</span>,</span>
<span id="cb23-4"><a href="#cb23-4" aria-hidden="true" tabindex="-1"></a>        <span class="st">R&quot;(</span></span>
<span id="cb23-5"><a href="#cb23-5" aria-hidden="true" tabindex="-1"></a><span class="st">        private:</span></span>
<span id="cb23-6"><a href="#cb23-6" aria-hidden="true" tabindex="-1"></a><span class="st">            [:T:] m_{0};</span></span>
<span id="cb23-7"><a href="#cb23-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb23-8"><a href="#cb23-8" aria-hidden="true" tabindex="-1"></a><span class="st">        public:</span></span>
<span id="cb23-9"><a href="#cb23-9" aria-hidden="true" tabindex="-1"></a><span class="st">            auto get_{0}() const -&gt; [:T:] const&amp; {{</span></span>
<span id="cb23-10"><a href="#cb23-10" aria-hidden="true" tabindex="-1"></a><span class="st">                return m_{0};</span></span>
<span id="cb23-11"><a href="#cb23-11" aria-hidden="true" tabindex="-1"></a><span class="st">            }}</span></span>
<span id="cb23-12"><a href="#cb23-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb23-13"><a href="#cb23-13" aria-hidden="true" tabindex="-1"></a><span class="st">            auto set_{0}(typename [:T:] const&amp; x) -&gt; void {{</span></span>
<span id="cb23-14"><a href="#cb23-14" aria-hidden="true" tabindex="-1"></a><span class="st">                m_{0} = x;</span></span>
<span id="cb23-15"><a href="#cb23-15" aria-hidden="true" tabindex="-1"></a><span class="st">            }}</span></span>
<span id="cb23-16"><a href="#cb23-16" aria-hidden="true" tabindex="-1"></a><span class="st">        )&quot;</span>,</span>
<span id="cb23-17"><a href="#cb23-17" aria-hidden="true" tabindex="-1"></a>        name<span class="op">))</span>;</span>
<span id="cb23-18"><a href="#cb23-18" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb23-19"><a href="#cb23-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb23-20"><a href="#cb23-20" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Book <span class="op">{</span></span>
<span id="cb23-21"><a href="#cb23-21" aria-hidden="true" tabindex="-1"></a>    <span class="kw">consteval</span> <span class="op">{</span></span>
<span id="cb23-22"><a href="#cb23-22" aria-hidden="true" tabindex="-1"></a>        property<span class="op">(^</span>string, <span class="st">&quot;author&quot;</span><span class="op">)</span>;</span>
<span id="cb23-23"><a href="#cb23-23" aria-hidden="true" tabindex="-1"></a>        property<span class="op">(^</span>string, <span class="st">&quot;title&quot;</span><span class="op">)</span>;</span>
<span id="cb23-24"><a href="#cb23-24" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb23-25"><a href="#cb23-25" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<h3 data-number="3.3.4" id="postfix-increment-1"><span class="header-section-number">3.3.4</span> Postfix Increment<a href="#postfix-increment-1" class="self-link"></a></h3>
<p>Similarly, the postfix increment implementation just writes itself.
In this case, we can even return
<code class="sourceCode cpp"><span class="kw">auto</span></code> so
don’t even need to bother with how to spell the return type:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb24"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> postfix_increment<span class="op">()</span> <span class="op">-&gt;</span> <span class="dt">void</span> <span class="op">{</span></span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a>    inject<span class="op">(</span><span class="st">R&quot;(</span></span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a><span class="st">        auto operator++(int) {</span></span>
<span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a><span class="st">            auto tmp = *this;</span></span>
<span id="cb24-5"><a href="#cb24-5" aria-hidden="true" tabindex="-1"></a><span class="st">            ++*this;</span></span>
<span id="cb24-6"><a href="#cb24-6" aria-hidden="true" tabindex="-1"></a><span class="st">            return tmp;</span></span>
<span id="cb24-7"><a href="#cb24-7" aria-hidden="true" tabindex="-1"></a><span class="st">        }</span></span>
<span id="cb24-8"><a href="#cb24-8" aria-hidden="true" tabindex="-1"></a><span class="st">    )&quot;</span><span class="op">)</span>;</span>
<span id="cb24-9"><a href="#cb24-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb24-10"><a href="#cb24-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb24-11"><a href="#cb24-11" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> C <span class="op">{</span></span>
<span id="cb24-12"><a href="#cb24-12" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> i;</span>
<span id="cb24-13"><a href="#cb24-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb24-14"><a href="#cb24-14" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> <span class="kw">operator</span><span class="op">++()</span> <span class="op">-&gt;</span> C<span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb24-15"><a href="#cb24-15" aria-hidden="true" tabindex="-1"></a>        <span class="op">++</span>i;</span>
<span id="cb24-16"><a href="#cb24-16" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="op">*</span><span class="kw">this</span>;</span>
<span id="cb24-17"><a href="#cb24-17" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb24-18"><a href="#cb24-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb24-19"><a href="#cb24-19" aria-hidden="true" tabindex="-1"></a>    <span class="kw">consteval</span> <span class="op">{</span> postfix_increment<span class="op">()</span>; <span class="op">}</span></span>
<span id="cb24-20"><a href="#cb24-20" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
</div>
<h3 data-number="3.3.5" id="disposition-2"><span class="header-section-number">3.3.5</span> Disposition<a href="#disposition-2" class="self-link"></a></h3>
<p>Can pretty much guarantee that strings have the lowest possible
barrier to entry of any code injection API. Which is a benefit that is
not to be taken lightly! It is not surprising that D and Jai both have
string-based injection mechanisms.</p>
<p>But string injection is hardly perfect, and several of the issues
with it might be clear already:</p>
<ol type="1">
<li>String injection does let you write what looks like C++ code, but it
wouldn’t let you use any macros - as those don’t affect the contents of
string literals and we can’t run another preprocessing step later.</li>
<li>Our main string formatting mechanism,
<code class="sourceCode cpp">format</code>, uses
<code class="sourceCode cpp"><span class="op">{}</span></code> for
replacement fields, which means actual braces - which show up in C++ a
lot - have to be escaped. It also likely isn’t the most compile-time
efficient API, so driving reflection off of it might be suboptimal.</li>
<li>You don’t get syntax highlighting for injected code strings. They’re
just strings. Perhaps we could introduce a new kind of string literal
that syntax highlighters could recognize, but that seems like
pre-emptively admitting defeat.</li>
<li>Errors happen at the point of <em>injection</em>, not at the point
where you’re writing the code. And the injection could happen very far
away from the code.</li>
<li>There is no natural way to interpolate reflection values, and that
is quite desirable (e.g. we attempted to use <code class="sourceCode cpp">qualified_name_of<span class="op">()</span></code>
to inject a type name, but that’s not robust - and <code class="sourceCode cpp">qualified_name_of<span class="op">()</span></code>
is hard to get right anyway).</li>
</ol>
<p>But string injection offers an extremely significant advantage that’s
not to be underestimated: everyone can deal with strings and strings
already just support everything, for all future evolution, without the
need for a large API.</p>
<p>Can we do better?</p>
<h2 data-number="3.4" id="fragments"><span class="header-section-number">3.4</span> Fragments<a href="#fragments" class="self-link"></a></h2>
<p><span class="citation" data-cites="P1717R0">[<a href="https://wg21.link/p1717r0" role="doc-biblioref">P1717R0</a>]</span> introduced the concept of
fragments. It introduced many different kinds of fragments, under syntax
that changed a bit in <span class="citation" data-cites="P2050R0">[<a href="https://wg21.link/p2050r0" role="doc-biblioref">P2050R0</a>]</span> and <span class="citation" data-cites="P2237R0">[<a href="https://wg21.link/p2237r0" role="doc-biblioref">P2237R0</a>]</span>. We’ll use what the linked
implementation uses, but feel free to change it as you read.</p>
<h3 data-number="3.4.1" id="stdtuple-3"><span class="header-section-number">3.4.1</span>
<code class="sourceCode cpp">std<span class="op">::</span>tuple</code><a href="#stdtuple-3" class="self-link"></a></h3>
<p>The initial fragments paper itself led off with an implementation of
<code class="sourceCode cpp">std<span class="op">::</span>tuple</code>
storage and the concept of a
<code class="sourceCode cpp"><span class="kw">consteval</span></code>
block (now also <span class="citation" data-cites="P3289R0">[<a href="https://wg21.link/p3289r0" role="doc-biblioref">P3289R0</a>]</span>). That <a href="https://godbolt.org/z/E19rezx6T">looks like this</a> (the linked
implementation looks a little different, due to an implementation
bug):</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb25"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> Ts<span class="op">&gt;</span></span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Tuple <span class="op">{</span></span>
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">consteval</span> <span class="op">{</span></span>
<span id="cb25-4"><a href="#cb25-4" aria-hidden="true" tabindex="-1"></a>        std<span class="op">::</span>array types<span class="op">{^</span>Ts<span class="op">...}</span>;</span>
<span id="cb25-5"><a href="#cb25-5" aria-hidden="true" tabindex="-1"></a>        <span class="cf">for</span> <span class="op">(</span><span class="dt">size_t</span> i <span class="op">=</span> <span class="dv">0</span>; i <span class="op">!=</span> types<span class="op">.</span>size<span class="op">()</span>; <span class="op">++</span>i<span class="op">)</span> <span class="op">{</span></span>
<span id="cb25-6"><a href="#cb25-6" aria-hidden="true" tabindex="-1"></a>            <span class="op">-&gt;</span> fragment <span class="kw">struct</span> <span class="op">{</span></span>
<span id="cb25-7"><a href="#cb25-7" aria-hidden="true" tabindex="-1"></a>                <span class="op">[[</span><span class="at">no_unique_address</span><span class="op">]]</span> <span class="kw">typename</span><span class="op">(%{</span>types<span class="op">[</span>i<span class="op">]})</span> unqualid<span class="op">(</span><span class="st">&quot;_&quot;</span>, <span class="op">%{</span>i<span class="op">})</span>;</span>
<span id="cb25-8"><a href="#cb25-8" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span>;</span>
<span id="cb25-9"><a href="#cb25-9" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb25-10"><a href="#cb25-10" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb25-11"><a href="#cb25-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
</div>
<p>Now, the big advantage of fragments is that it’s just C++ code in the
middle there (maybe it feels a bit messy in this particular example, but
it will be more clear in other examples). The leading
<code class="sourceCode cpp"><span class="op">-&gt;</span></code> is the
injection operator.</p>
<p>One big problem that fragments need to solve is how to get context
information into them. For instance, how do we get the type <code class="sourceCode cpp">types<span class="op">[</span>i<span class="op">]</span></code>
and how do we produce the names <code class="sourceCode cpp">_0</code>,
<code class="sourceCode cpp">_1</code>, …, for all of these members? We
need a way to capture context, and it needs to be interpolated
differently.</p>
<p>In the above example, the design uses the operator
<code class="sourceCode cpp">unqualid</code> (to create an unqualified
id) concatenating the string literal <code class="sourceCode cpp"><span class="st">&quot;_&quot;</span></code> with
the interpolated value <code class="sourceCode cpp"><span class="op">%{</span>i<span class="op">}</span></code>
(a later revision used <code class="sourceCode cpp"><span class="op">|</span><span class="er"># #|</span></code>
instead). We need distinct operators to differentiate between the case
where we want to use a string as an identifier and as an actual
string.</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb26"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a>std<span class="op">::</span>string name <span class="op">=</span> <span class="st">&quot;hello&quot;</span>;</span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a><span class="op">-&gt;</span> fragment <span class="kw">struct</span> <span class="op">{</span></span>
<span id="cb26-3"><a href="#cb26-3" aria-hidden="true" tabindex="-1"></a>    <span class="co">// std::string name = &quot;name&quot;;</span></span>
<span id="cb26-4"><a href="#cb26-4" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>string unqualid<span class="op">(%{</span>name<span class="op">})</span> <span class="op">=</span> <span class="op">%{</span>name<span class="op">}</span>;</span>
<span id="cb26-5"><a href="#cb26-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
</div>
<h3 data-number="3.4.2" id="stdenable_if-3"><span class="header-section-number">3.4.2</span> <code class="sourceCode cpp">std<span class="op">::</span>enable_if</code><a href="#stdenable_if-3" class="self-link"></a></h3>
<p>It is very hard to compete <a href="https://godbolt.org/z/nf8nPnnh4">with this</a>:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb27"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="dt">bool</span> B, <span class="kw">class</span> T<span class="op">=</span><span class="dt">void</span><span class="op">&gt;</span></span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> enable_if <span class="op">{</span></span>
<span id="cb27-3"><a href="#cb27-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">consteval</span> <span class="op">{</span></span>
<span id="cb27-4"><a href="#cb27-4" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(</span>B<span class="op">)</span> <span class="op">{</span></span>
<span id="cb27-5"><a href="#cb27-5" aria-hidden="true" tabindex="-1"></a>            <span class="op">-&gt;</span> fragment <span class="kw">struct</span> <span class="op">{</span> <span class="kw">using</span> type <span class="op">=</span> T; <span class="op">}</span>;</span>
<span id="cb27-6"><a href="#cb27-6" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb27-7"><a href="#cb27-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span>;</span>
<span id="cb27-8"><a href="#cb27-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
</div>
<p>Sure, you might want to simplify this just having a class scope
<code class="sourceCode cpp"><span class="cf">if</span></code> directly
and then putting the contents of the
<code class="sourceCode cpp">fragment</code> in there. But this is very
nice.</p>
<h3 data-number="3.4.3" id="properties-3"><span class="header-section-number">3.4.3</span> Properties<a href="#properties-3" class="self-link"></a></h3>
<p>The <a href="https://godbolt.org/z/ddbsYWsvr">implementation here</a>
isn’t too different from the <a href="#properties-2">string
implementation</a> (this was back when the reflection operator was
<code class="sourceCode cpp">reflexpr</code>, before it changed to
<code class="sourceCode cpp"><span class="op">^</span></code>):</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb28"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> property<span class="op">(</span>meta<span class="op">::</span>info type, <span class="dt">char</span> <span class="kw">const</span><span class="op">*</span> name<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">void</span> <span class="op">{</span></span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a>    <span class="op">-&gt;</span> fragment <span class="kw">struct</span> <span class="op">{</span></span>
<span id="cb28-3"><a href="#cb28-3" aria-hidden="true" tabindex="-1"></a>        <span class="kw">typename</span><span class="op">(%{</span>type<span class="op">})</span> unqualid<span class="op">(</span><span class="st">&quot;m_&quot;</span>, <span class="op">%{</span>name<span class="op">})</span>;</span>
<span id="cb28-4"><a href="#cb28-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb28-5"><a href="#cb28-5" aria-hidden="true" tabindex="-1"></a>        <span class="kw">auto</span> unqualid<span class="op">(</span><span class="st">&quot;get_&quot;</span>, <span class="op">%{</span>name<span class="op">})()</span> <span class="op">-&gt;</span> <span class="kw">typename</span><span class="op">(%{</span>type<span class="op">})</span> <span class="kw">const</span><span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb28-6"><a href="#cb28-6" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> unqualid<span class="op">(</span><span class="st">&quot;m_&quot;</span>, <span class="op">%{</span>name<span class="op">})</span>;</span>
<span id="cb28-7"><a href="#cb28-7" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb28-8"><a href="#cb28-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb28-9"><a href="#cb28-9" aria-hidden="true" tabindex="-1"></a>        <span class="kw">auto</span> unqualid<span class="op">(</span><span class="st">&quot;set_&quot;</span>, <span class="op">%{</span>name<span class="op">})(</span><span class="kw">typename</span><span class="op">(%{</span>type<span class="op">})</span> <span class="kw">const</span><span class="op">&amp;</span> x<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">void</span> <span class="op">{</span></span>
<span id="cb28-10"><a href="#cb28-10" aria-hidden="true" tabindex="-1"></a>            unqualid<span class="op">(</span><span class="st">&quot;m_&quot;</span>, <span class="op">%{</span>name<span class="op">})</span> <span class="op">=</span> x;</span>
<span id="cb28-11"><a href="#cb28-11" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb28-12"><a href="#cb28-12" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span>;</span>
<span id="cb28-13"><a href="#cb28-13" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb28-14"><a href="#cb28-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb28-15"><a href="#cb28-15" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Book <span class="op">{</span></span>
<span id="cb28-16"><a href="#cb28-16" aria-hidden="true" tabindex="-1"></a>    <span class="kw">consteval</span> <span class="op">{</span></span>
<span id="cb28-17"><a href="#cb28-17" aria-hidden="true" tabindex="-1"></a>        property<span class="op">(</span>reflexpr<span class="op">(</span>std<span class="op">::</span>string<span class="op">)</span>, <span class="st">&quot;author&quot;</span><span class="op">)</span>;</span>
<span id="cb28-18"><a href="#cb28-18" aria-hidden="true" tabindex="-1"></a>        property<span class="op">(</span>reflexpr<span class="op">(</span>std<span class="op">::</span>string<span class="op">)</span>, <span class="st">&quot;title&quot;</span><span class="op">)</span>;</span>
<span id="cb28-19"><a href="#cb28-19" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb28-20"><a href="#cb28-20" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
</div>
<p>It’s a bit busy because nearly everything in properties involves
interpolating outside context, so seemingly everything here is
interpolated.</p>
<p>Now, there’s one very important property that fragments (as designed
in these papers) adhere to: every fragment must be parsable in its
context. A fragment does not leak its declarations out of its context;
only out of the context where it is injected. Not only that, we get full
name lookup and everything.</p>
<p>On the one hand, this seems like a big advantage: the fragment is
checked at the point of its declaration, not at the point of its use.
With the string model above, that was not the case - you can write
whatever garbage string you want and it’s still a perfectly valid
string, it only becomes invalid C++ code when it’s injected.</p>
<p>On the other, it has some consequences for how we can code using
fragments. In the above implementation, we inject the whole property in
one go. But let’s say we wanted to split it up for whatever reason. We
can’t. This is invalid:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb29"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb29-1"><a href="#cb29-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> property<span class="op">(</span>meta<span class="op">::</span>info type, <span class="dt">char</span> <span class="kw">const</span><span class="op">*</span> name<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">void</span></span>
<span id="cb29-2"><a href="#cb29-2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb29-3"><a href="#cb29-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">-&gt;</span> fragment <span class="kw">struct</span> <span class="op">{</span></span>
<span id="cb29-4"><a href="#cb29-4" aria-hidden="true" tabindex="-1"></a>        <span class="kw">typename</span><span class="op">(%{</span>type<span class="op">})</span> unqualid<span class="op">(</span><span class="st">&quot;m_&quot;</span>, <span class="op">%{</span>name<span class="op">})</span>;</span>
<span id="cb29-5"><a href="#cb29-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span>;</span>
<span id="cb29-6"><a href="#cb29-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb29-7"><a href="#cb29-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">-&gt;</span> fragment <span class="kw">struct</span> <span class="op">{</span></span>
<span id="cb29-8"><a href="#cb29-8" aria-hidden="true" tabindex="-1"></a>        <span class="kw">auto</span> unqualid<span class="op">(</span><span class="st">&quot;get_&quot;</span>, <span class="op">%{</span>name<span class="op">})()</span> <span class="op">-&gt;</span> <span class="kw">typename</span><span class="op">(%{</span>type<span class="op">})</span> <span class="kw">const</span><span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb29-9"><a href="#cb29-9" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> unqualid<span class="op">(</span><span class="st">&quot;m_&quot;</span>, <span class="op">%{</span>name<span class="op">})</span>; <span class="co">// error</span></span>
<span id="cb29-10"><a href="#cb29-10" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb29-11"><a href="#cb29-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb29-12"><a href="#cb29-12" aria-hidden="true" tabindex="-1"></a>        <span class="kw">auto</span> unqualid<span class="op">(</span><span class="st">&quot;set_&quot;</span>, <span class="op">%{</span>name<span class="op">})(</span><span class="kw">typename</span><span class="op">(%{</span>type<span class="op">})</span> <span class="kw">const</span><span class="op">&amp;</span> x<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">void</span> <span class="op">{</span></span>
<span id="cb29-13"><a href="#cb29-13" aria-hidden="true" tabindex="-1"></a>            unqualid<span class="op">(</span><span class="st">&quot;m_&quot;</span>, <span class="op">%{</span>name<span class="op">})</span> <span class="op">=</span> x; <span class="co">// error</span></span>
<span id="cb29-14"><a href="#cb29-14" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb29-15"><a href="#cb29-15" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span>;</span>
<span id="cb29-16"><a href="#cb29-16" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>In this second fragment, name lookup for
<code class="sourceCode cpp">m_author</code> fails in both function
bodies. We can’t do that. We have to teach the fragment how to find the
name, which requires writing this (note the added
<code class="sourceCode cpp"><span class="kw">requires</span></code>
statement):</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb30"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> property<span class="op">(</span>meta<span class="op">::</span>info type, <span class="dt">char</span> <span class="kw">const</span><span class="op">*</span> name<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">void</span></span>
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb30-3"><a href="#cb30-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">-&gt;</span> fragment <span class="kw">struct</span> <span class="op">{</span></span>
<span id="cb30-4"><a href="#cb30-4" aria-hidden="true" tabindex="-1"></a>        <span class="kw">typename</span><span class="op">(%{</span>type<span class="op">})</span> unqualid<span class="op">(</span><span class="st">&quot;m_&quot;</span>, <span class="op">%{</span>name<span class="op">})</span>;</span>
<span id="cb30-5"><a href="#cb30-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span>;</span>
<span id="cb30-6"><a href="#cb30-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-7"><a href="#cb30-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">-&gt;</span> fragment <span class="kw">struct</span> <span class="op">{</span></span>
<span id="cb30-8"><a href="#cb30-8" aria-hidden="true" tabindex="-1"></a>        <span class="kw">requires</span> <span class="kw">typename</span><span class="op">(%{</span>type<span class="op">})</span> unqualid<span class="op">(</span><span class="st">&quot;m_&quot;</span>, <span class="op">%{</span>name<span class="op">})</span>;</span>
<span id="cb30-9"><a href="#cb30-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-10"><a href="#cb30-10" aria-hidden="true" tabindex="-1"></a>        <span class="kw">auto</span> unqualid<span class="op">(</span><span class="st">&quot;get_&quot;</span>, <span class="op">%{</span>name<span class="op">})()</span> <span class="op">-&gt;</span> <span class="kw">typename</span><span class="op">(%{</span>type<span class="op">})</span> <span class="kw">const</span><span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb30-11"><a href="#cb30-11" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> unqualid<span class="op">(</span><span class="st">&quot;m_&quot;</span>, <span class="op">%{</span>name<span class="op">})</span>; <span class="co">// error</span></span>
<span id="cb30-12"><a href="#cb30-12" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb30-13"><a href="#cb30-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-14"><a href="#cb30-14" aria-hidden="true" tabindex="-1"></a>        <span class="kw">auto</span> unqualid<span class="op">(</span><span class="st">&quot;set_&quot;</span>, <span class="op">%{</span>name<span class="op">})(</span><span class="kw">typename</span><span class="op">(%{</span>type<span class="op">})</span> <span class="kw">const</span><span class="op">&amp;</span> x<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">void</span> <span class="op">{</span></span>
<span id="cb30-15"><a href="#cb30-15" aria-hidden="true" tabindex="-1"></a>            unqualid<span class="op">(</span><span class="st">&quot;m_&quot;</span>, <span class="op">%{</span>name<span class="op">})</span> <span class="op">=</span> x; <span class="co">// error</span></span>
<span id="cb30-16"><a href="#cb30-16" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb30-17"><a href="#cb30-17" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span>;</span>
<span id="cb30-18"><a href="#cb30-18" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<h3 data-number="3.4.4" id="postfix-increment-2"><span class="header-section-number">3.4.4</span> Postfix increment<a href="#postfix-increment-2" class="self-link"></a></h3>
<p>Postfix increment ends up being <a href="https://godbolt.org/z/r1v3e43sd">much simpler to implement</a>
with fragments than properties - due to not having to deal with any
interpolated names. But it does surface the issue of name lookup in
fragments.</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb31"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb31-1"><a href="#cb31-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> postfix_increment<span class="op">()</span> <span class="op">{</span></span>
<span id="cb31-2"><a href="#cb31-2" aria-hidden="true" tabindex="-1"></a>    <span class="op">-&gt;</span> fragment <span class="kw">struct</span> T <span class="op">{</span></span>
<span id="cb31-3"><a href="#cb31-3" aria-hidden="true" tabindex="-1"></a>        <span class="kw">requires</span> T<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">++()</span>;</span>
<span id="cb31-4"><a href="#cb31-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb31-5"><a href="#cb31-5" aria-hidden="true" tabindex="-1"></a>        <span class="kw">auto</span> <span class="kw">operator</span><span class="op">++(</span><span class="dt">int</span><span class="op">)</span> <span class="op">-&gt;</span> T <span class="op">{</span></span>
<span id="cb31-6"><a href="#cb31-6" aria-hidden="true" tabindex="-1"></a>            <span class="kw">auto</span> tmp <span class="op">=</span> <span class="op">*</span><span class="kw">this</span>;</span>
<span id="cb31-7"><a href="#cb31-7" aria-hidden="true" tabindex="-1"></a>            <span class="op">++*</span><span class="kw">this</span>;</span>
<span id="cb31-8"><a href="#cb31-8" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> tmp;</span>
<span id="cb31-9"><a href="#cb31-9" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb31-10"><a href="#cb31-10" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span>;</span>
<span id="cb31-11"><a href="#cb31-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb31-12"><a href="#cb31-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb31-13"><a href="#cb31-13" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> C <span class="op">{</span></span>
<span id="cb31-14"><a href="#cb31-14" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> i;</span>
<span id="cb31-15"><a href="#cb31-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb31-16"><a href="#cb31-16" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> <span class="kw">operator</span><span class="op">++()</span> <span class="op">-&gt;</span> C<span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb31-17"><a href="#cb31-17" aria-hidden="true" tabindex="-1"></a>        <span class="op">++</span>i;</span>
<span id="cb31-18"><a href="#cb31-18" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="op">*</span><span class="kw">this</span>;</span>
<span id="cb31-19"><a href="#cb31-19" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb31-20"><a href="#cb31-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb31-21"><a href="#cb31-21" aria-hidden="true" tabindex="-1"></a>    <span class="kw">consteval</span> <span class="op">{</span> postfix_increment<span class="op">()</span>; <span class="op">}</span></span>
<span id="cb31-22"><a href="#cb31-22" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
</div>
<p>Now, the rule in the fragments implementation is that the fragments
themselves are checked. This includes name lookup. So any name used in
the body of the fragment has to be found and pre-declared, which is what
we’re doing in the
<code class="sourceCode cpp"><span class="kw">requires</span></code>
clause there. The implementation right now appears to have a bug with
respect to operators (if you change the body to calling <code class="sourceCode cpp">inc<span class="op">(*</span><span class="kw">this</span><span class="op">)</span></code>,
it does get flagged), which is why it’s commented out in the link.</p>
<h3 data-number="3.4.5" id="disposition-3"><span class="header-section-number">3.4.5</span> Disposition<a href="#disposition-3" class="self-link"></a></h3>
<p>The fragment model seems substantially easier to program in than the
CodeReckons model. We’re actually writing C++ code. Consider the
difference here between the CodeReckons solution and the Fragments
solution to postfix increment:</p>
<table>
<thead>
<tr class="header">
<th><div style="text-align:center">
<strong><a href="https://cppmeta.codereckons.com/tools/z/71To7o">CodeReckons</a></strong>
</div></th>
<th><div style="text-align:center">
<strong><a href="https://godbolt.org/z/r1v3e43sd">Fragments</a></strong>
</div></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><div>

<div class="sourceCode" id="cb32"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb32-1"><a href="#cb32-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> postfix_increment<span class="op">(</span>class_builder<span class="op">&amp;</span> b<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">void</span> <span class="op">{</span></span>
<span id="cb32-2"><a href="#cb32-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-3"><a href="#cb32-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-4"><a href="#cb32-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-5"><a href="#cb32-5" aria-hidden="true" tabindex="-1"></a>    method_prototype mp;</span>
<span id="cb32-6"><a href="#cb32-6" aria-hidden="true" tabindex="-1"></a>    append_parameter<span class="op">(</span>mp, <span class="st">&quot;x&quot;</span>, <span class="op">^</span><span class="dt">int</span><span class="op">)</span>;</span>
<span id="cb32-7"><a href="#cb32-7" aria-hidden="true" tabindex="-1"></a>    object_type<span class="op">(</span>mp, decl_of<span class="op">(</span>b<span class="op">))</span>;</span>
<span id="cb32-8"><a href="#cb32-8" aria-hidden="true" tabindex="-1"></a>    return_type<span class="op">(</span>mp, decl_of<span class="op">(</span>b<span class="op">))</span>;</span>
<span id="cb32-9"><a href="#cb32-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-10"><a href="#cb32-10" aria-hidden="true" tabindex="-1"></a>    append_method<span class="op">(</span>b, operator_kind<span class="op">::</span>post_inc, mp,</span>
<span id="cb32-11"><a href="#cb32-11" aria-hidden="true" tabindex="-1"></a>        <span class="op">[](</span>method_builder<span class="op">&amp;</span> b<span class="op">){</span></span>
<span id="cb32-12"><a href="#cb32-12" aria-hidden="true" tabindex="-1"></a>            <span class="kw">auto</span> tmp <span class="op">=</span> append_var<span class="op">(</span>b, <span class="st">&quot;tmp&quot;</span>, auto_ty,</span>
<span id="cb32-13"><a href="#cb32-13" aria-hidden="true" tabindex="-1"></a>                make_deref_expr<span class="op">(</span>make_this_expr<span class="op">(</span>b<span class="op">)))</span>;</span>
<span id="cb32-14"><a href="#cb32-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-15"><a href="#cb32-15" aria-hidden="true" tabindex="-1"></a>            append_expr<span class="op">(</span>b,</span>
<span id="cb32-16"><a href="#cb32-16" aria-hidden="true" tabindex="-1"></a>                make_operator_expr<span class="op">(</span></span>
<span id="cb32-17"><a href="#cb32-17" aria-hidden="true" tabindex="-1"></a>                    operator_kind<span class="op">::</span>pre_inc,</span>
<span id="cb32-18"><a href="#cb32-18" aria-hidden="true" tabindex="-1"></a>                    make_deref_expr<span class="op">(</span>make_this_expr<span class="op">(</span>b<span class="op">))))</span>;</span>
<span id="cb32-19"><a href="#cb32-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-20"><a href="#cb32-20" aria-hidden="true" tabindex="-1"></a>            append_return<span class="op">(</span>b, make_decl_ref_expr<span class="op">(</span>tmp<span class="op">))</span>;</span>
<span id="cb32-21"><a href="#cb32-21" aria-hidden="true" tabindex="-1"></a>        <span class="op">})</span>;</span>
<span id="cb32-22"><a href="#cb32-22" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb32-23"><a href="#cb32-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-24"><a href="#cb32-24" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-25"><a href="#cb32-25" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> C <span class="op">{</span></span>
<span id="cb32-26"><a href="#cb32-26" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> i;</span>
<span id="cb32-27"><a href="#cb32-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-28"><a href="#cb32-28" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> <span class="kw">operator</span><span class="op">++()</span> <span class="op">-&gt;</span> C<span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb32-29"><a href="#cb32-29" aria-hidden="true" tabindex="-1"></a>        <span class="op">++</span>i;</span>
<span id="cb32-30"><a href="#cb32-30" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="op">*</span><span class="kw">this</span>;</span>
<span id="cb32-31"><a href="#cb32-31" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb32-32"><a href="#cb32-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-33"><a href="#cb32-33" aria-hidden="true" tabindex="-1"></a>    <span class="op">%</span> postfix_increment<span class="op">()</span>;</span>
<span id="cb32-34"><a href="#cb32-34" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>

</div></td>
<td><div>

<div class="sourceCode" id="cb33"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb33-1"><a href="#cb33-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> postfix_increment<span class="op">()</span> <span class="op">{</span></span>
<span id="cb33-2"><a href="#cb33-2" aria-hidden="true" tabindex="-1"></a>    <span class="op">-&gt;</span> fragment <span class="kw">struct</span> T <span class="op">{</span></span>
<span id="cb33-3"><a href="#cb33-3" aria-hidden="true" tabindex="-1"></a>        <span class="kw">requires</span> T<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">++()</span>;</span>
<span id="cb33-4"><a href="#cb33-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-5"><a href="#cb33-5" aria-hidden="true" tabindex="-1"></a>        <span class="kw">auto</span> <span class="kw">operator</span><span class="op">++(</span><span class="dt">int</span><span class="op">)</span> <span class="op">-&gt;</span> T <span class="op">{</span></span>
<span id="cb33-6"><a href="#cb33-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-7"><a href="#cb33-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-8"><a href="#cb33-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-9"><a href="#cb33-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-10"><a href="#cb33-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-11"><a href="#cb33-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-12"><a href="#cb33-12" aria-hidden="true" tabindex="-1"></a>            <span class="kw">auto</span> tmp <span class="op">=</span> <span class="op">*</span><span class="kw">this</span>;</span>
<span id="cb33-13"><a href="#cb33-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-14"><a href="#cb33-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-15"><a href="#cb33-15" aria-hidden="true" tabindex="-1"></a>            <span class="op">++*</span><span class="kw">this</span>;</span>
<span id="cb33-16"><a href="#cb33-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-17"><a href="#cb33-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-18"><a href="#cb33-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-19"><a href="#cb33-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-20"><a href="#cb33-20" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> tmp;</span>
<span id="cb33-21"><a href="#cb33-21" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb33-22"><a href="#cb33-22" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span>;</span>
<span id="cb33-23"><a href="#cb33-23" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb33-24"><a href="#cb33-24" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-25"><a href="#cb33-25" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> C <span class="op">{</span></span>
<span id="cb33-26"><a href="#cb33-26" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> i;</span>
<span id="cb33-27"><a href="#cb33-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-28"><a href="#cb33-28" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> <span class="kw">operator</span><span class="op">++()</span> <span class="op">-&gt;</span> C<span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb33-29"><a href="#cb33-29" aria-hidden="true" tabindex="-1"></a>        <span class="op">++</span>i;</span>
<span id="cb33-30"><a href="#cb33-30" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="op">*</span><span class="kw">this</span>;</span>
<span id="cb33-31"><a href="#cb33-31" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb33-32"><a href="#cb33-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-33"><a href="#cb33-33" aria-hidden="true" tabindex="-1"></a>    <span class="kw">consteval</span> <span class="op">{</span> postfix_increment<span class="op">()</span>; <span class="op">}</span></span>
<span id="cb33-34"><a href="#cb33-34" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>

</div></td>
</tr>
</tbody>
</table>
<p>We lined up the fragment implementation to roughly correspond to the
CodeReckons API on the left. With the code written out like this, it’s
easy to understand the CodeReckons API. But it takes no time at all to
understand (or write) the fragments code on the right - it’s just C++
already.</p>
<p>We also think it’s a better idea than the string injection model,
since we want something with structure that isn’t just missing some
parts of the language (the preprocessor) and plays nicely with tools
(like syntax highlighters).</p>
<p>But we think the fragment model still isn’t quite right. By nobly
trying to diagnose errors at the point of fragment declaration, it adds
a complexity to the fragment model in a way that we don’t think carries
its weight. The fragment papers (<span class="citation" data-cites="P1717R0">[<a href="https://wg21.link/p1717r0" role="doc-biblioref">P1717R0</a>]</span> and <span class="citation" data-cites="P2237R0">[<a href="https://wg21.link/p2237r0" role="doc-biblioref">P2237R0</a>]</span>) each go into some detail of
different approaches of how to do name checking at the point of fragment
declaration. They are all complicated.</p>
<p>We basically want something between strings and fragments.</p>
<h1 data-number="4" style="border-bottom:1px solid #cccccc" id="token-sequences"><span class="header-section-number">4</span> Token
Sequences<a href="#token-sequences" class="self-link"></a></h1>
<p>Generation of code from low-level syntactic elements such as strings
or token sequences may be considered quite unsophisticated. Indeed,
previous proposals for code synthesis in C++ have studiously avoided
using strings or tokens as input, instead resorting to AST-based APIs,
expansion statements, or code fragments, as shown above. As noted by
Andrew Sutton in <span class="citation" data-cites="P2237R0">[<a href="https://wg21.link/p2237r0" role="doc-biblioref">P2237R0</a>]</span>:</p>
<div class="quote">
<p>synthesizing new code from strings is straightforward, especially
when the language/library has robust tools for compile-time string
manipulation […] the strings or tokens are syntactically and
semantically unanalyzed until they are injected</p>
</div>
<p>whereas the central premise—and purported advantage—of a code
fragment is it</p>
<div class="quote">
<p>should be fully syntactically and semantically validated prior to its
injection</p>
</div>
<p>Due to the lack of consensus for a code synthesis mechanism, some C++
reflection proposals shifted focus to the query side of reflection and
left room for scant code synthesis capabilities.</p>
<p>After extensive study and experimentation (as seen above), we
concluded that a form of token-based synthesis is crucially important
for practical code generation, and that insisting upon early syntactic
and semantic validation of generated code is a net liability. The very
nature of code synthesis involves assembling meaningful constructs out
of pieces that have little or no meaning in isolation. Using
concatenation and deferring syntax/semantics analysis to offer said
concatenation is by far the simplest, most direct approach to code
synthesis.</p>
<p>Generally, we think that imposing early checking on generated code is
likely to complicate and restrict the ways in which users can use the
facility — particularly when it comes to composing larger constructs
from smaller ones — and also be difficult for implementers, thus hurting
everyone involved.</p>
<p>We therefore choose the notion of <em>token sequence</em> as the core
building block for generating code. Unparsed token sequences allow for
flexible composition, while deferring semantic analysis (lookup, etc.)
to the point of injection avoids complexities in trying to re-create the
context of the point of injection at the point of composition.</p>
<h2 data-number="4.1" id="token-sequence-expression"><span class="header-section-number">4.1</span> Token Sequence Expression<a href="#token-sequence-expression" class="self-link"></a></h2>
<p>We propose the introduction of a new kind of expression with the
following syntax (the specific introducer can be decided later):</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb34"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb34-1"><a href="#cb34-1" aria-hidden="true" tabindex="-1"></a><span class="op">^{</span> <em>balanced-brace-tokens</em> <span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>where
<code class="sourceCode cpp"><em>balanced-brace-tokens</em></code> is an
arbitrary sequence of C++ tokens with the sole requirement that the
<code class="sourceCode cpp"><span class="op">{</span></code> and
<code class="sourceCode cpp"><span class="op">}</span></code> pairs are
balanced. Parentheses and square brackets may be unbalanced. The opening
and closing
<code class="sourceCode cpp"><span class="op">{</span></code>/<code class="sourceCode cpp"><span class="op">}</span></code>
are not part of the token sequence. The type of a token sequence
expression is <code class="sourceCode cpp">std<span class="op">::</span>meta<span class="op">::</span>info</code>.</p>
<p>The choice of syntax is motivated by two notions:</p>
<ol type="1">
<li>If we could reflect on the body of a function template, the only
thing that could be yielded back is a token sequence - since the
template hasn’t been instantiated yet. And the syntax for reflecting on
that body would look like <code class="sourceCode cpp"><span class="op">^{</span> <em>body</em> <span class="op">}</span></code></li>
<li>This maintains the property that the only built-in operator that
produces a <code class="sourceCode cpp">std<span class="op">::</span>meta<span class="op">::</span>info</code>
value is the prefix
<code class="sourceCode cpp"><span class="op">^</span></code>.</li>
</ol>
<p>For example:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb35"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb35-1"><a href="#cb35-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="kw">auto</span> t1 <span class="op">=</span> <span class="op">^{</span> a <span class="op">+</span> b <span class="op">}</span>;      <span class="co">// three tokens</span></span>
<span id="cb35-2"><a href="#cb35-2" aria-hidden="true" tabindex="-1"></a><span class="kw">static_assert</span><span class="op">(</span>std<span class="op">::</span>is_same_v<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">(</span>t1<span class="op">)</span>, <span class="kw">const</span> std<span class="op">::</span>meta<span class="op">::</span>info<span class="op">&gt;)</span>;</span>
<span id="cb35-3"><a href="#cb35-3" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="kw">auto</span> t2 <span class="op">=</span> <span class="op">^{</span> a <span class="op">+=</span> <span class="op">(</span> <span class="op">}</span>;     <span class="co">// code does not have to be meaningful</span></span>
<span id="cb35-4"><a href="#cb35-4" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="kw">auto</span> t3 <span class="op">=</span> <span class="op">^{</span> abc <span class="op">{</span> def <span class="op">}</span>;  <span class="co">// Error, unpaired brace</span></span></code></pre></div>
</blockquote>
</div>
<p><span class="ednote" style="color: #0000ff">[ Editor&#39;s note: We are
aware of the conflict with Objective-C/C++ blocks that makes this syntax
untenable. For now, the paper is written still using
<code class="sourceCode default">^</code> and a subsequent version will
have to find something else, probably still choosing the same prefix
operator as reflection. ]</span></p>
<h2 data-number="4.2" id="interpolating-into-a-token-sequence"><span class="header-section-number">4.2</span> Interpolating into a Token
Sequence<a href="#interpolating-into-a-token-sequence" class="self-link"></a></h2>
<p>There’s still the issue that we need to access outside context from
within a token sequence. For that we introduce dedicated interpolation
syntax using three kinds of interpolators:</p>
<ul>
<li><code class="sourceCode cpp">\<span class="op">(</span><em>expression</em><span class="op">)</span></code></li>
<li><code class="sourceCode cpp">\id<span class="op">(</span><em>string</em>, <em>string-or-int</em><sub>opt</sub><span class="op">...)</span></code></li>
<li><code class="sourceCode cpp">\tokens<span class="op">(</span><em>expression</em><span class="op">)</span></code></li>
</ul>
<p>The implementation model for this is that we collect the tokens
within a <code class="sourceCode cpp"><span class="op">^{</span> <span class="op">...</span> <span class="op">}</span></code>
literal, but every time we run into an interpolator, we parse the
expressions within. When the token sequence is evaluated (always a
compile-time operation since it produces a <code class="sourceCode cpp">std<span class="op">::</span>meta<span class="op">::</span>info</code>
value), the expressions are evaluated and the corresponding
interpolators are replaced as follows:</p>
<ul>
<li><code class="sourceCode cpp">\id<span class="op">(</span>e<span class="op">)</span></code>
for <code class="sourceCode cpp">e</code> being string-like is replaced
with that string as a new
<code class="sourceCode cpp"><em>identifier</em></code>. <code class="sourceCode cpp">\id<span class="op">(</span>e<span class="op">...)</span></code>
can concatenate multiple string-like or integral values into a single
<code class="sourceCode cpp"><em>identifier</em></code> (the first
argument must be string-like).</li>
<li><code class="sourceCode cpp">\<span class="op">(</span>e<span class="op">)</span></code>
is replaced by a pseudo-literal token holding the value of
<code class="sourceCode cpp">e</code>. The parentheses are
mandatory.</li>
<li><code class="sourceCode cpp">\tokens<span class="op">(</span>e<span class="op">)</span></code>
is replaced by the — possibly empty — tokens
<code class="sourceCode cpp">e</code>
(<code class="sourceCode cpp">e</code> must be a reflection of an
evaluated token sequence).</li>
</ul>
<p>The value and <code class="sourceCode cpp">id</code> interpolators
need to be distinct because a given string could be intended to be
injected as a <em>string</em>, like <code class="sourceCode cpp"><span class="st">&quot;var&quot;</span></code>,
or as an <em>identifier</em>, like
<code class="sourceCode cpp">var</code>. There’s no way to determine
which one is intended, so they have to be spelled differently.</p>
<p>We initially considered
<code class="sourceCode cpp"><span class="op">+</span></code> for token
concatenation, but we need token sequence interpolation anyway. Consider
wanting to build up the token sequence <code class="sourceCode cpp">T<span class="op">{</span>a, b, c<span class="op">}</span></code>
where <code class="sourceCode cpp">a, b, c</code> is the contents of
another token sequence. With interpolation, that is straightforward:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb36"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb36-1"><a href="#cb36-1" aria-hidden="true" tabindex="-1"></a><span class="op">^{</span> T<span class="op">{</span>\tokens<span class="op">(</span>args<span class="op">)}</span> <span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>but with concatenation, we run into a problem:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb37"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb37-1"><a href="#cb37-1" aria-hidden="true" tabindex="-1"></a><span class="op">^{</span> <span class="orange">T{</span> <span class="op">}</span> <span class="op">+</span> args <span class="op">+</span> <span class="op">^{</span> <span class="orange">}</span> <span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>This doesn’t produce the intended effect because it is a token
sequence containing the tokens <code class="sourceCode cpp">T <span class="op">{</span> <span class="op">}</span> <span class="op">+</span> args <span class="op">+</span> <span class="op">^</span> <span class="op">{</span> <span class="op">}</span></code>
instead of an expression containing two additions involving two token
sequences as desired.</p>
<p>Given that we need <code class="sourceCode cpp">\tokens</code>
anyway, additionally adding concatenation with
<code class="sourceCode cpp"><span class="op">+</span></code> and
<code class="sourceCode cpp"><span class="op">+=</span></code> doesn’t
seem as necessary, especially since keeping the proposal minimal has a
lot of value.</p>
<p>Using <code class="sourceCode cpp">\</code> as an interpolator has at
least some prior art. Swift uses <code class="sourceCode cpp">\<span class="op">(</span>e<span class="op">)</span></code>
in their <a href="https://docs.swift.org/swift-book/documentation/the-swift-programming-language/stringsandcharacters/#String-Interpolation">string
interpolation syntax</a>.</p>
<h3 data-number="4.2.1" id="alternate-interpolation-syntax"><span class="header-section-number">4.2.1</span> Alternate Interpolation
Syntax<a href="#alternate-interpolation-syntax" class="self-link"></a></h3>
<p>Currently, we are proposing three interpolators:
<code class="sourceCode cpp">\</code>,
<code class="sourceCode cpp">\id</code>, and
<code class="sourceCode cpp">\tokens</code>. That might seem like a lot,
especially <code class="sourceCode cpp">\tokens</code> is a lot of
characters, but we feel that this is the complete necessary set. A
simple alternative is to spell <code class="sourceCode cpp">\tokens<span class="op">(</span>e<span class="op">)</span></code>
instead as <code class="sourceCode cpp">\<span class="op">{</span>e<span class="op">}</span></code>
(i.e. braces instead of parentheses). This is a lot shorter, but it’s
still three interpolators (and the visual distinction might be too
subtle).</p>
<p>A bigger alternative would be to overload interpolation on types. In
Rust, for instance, interpolation into a procedural macro always is
spelled <code class="sourceCode cpp"><span class="pp">#</span><span class="er">var</span></code>
- and opting in to interpolation is implementing the trait <a href="https://docs.rs/proc-quote/latest/proc_quote/trait.ToTokens.html"><code class="sourceCode cpp">ToTokens</code></a>.
The way to interpolate an identifier is to interpolate an object of type
<code class="sourceCode cpp">syn<span class="op">::</span>Ident</code>.
Going that route (and making tokens sequences <a href="#token-sequence-type">their own type</a>) might mean that the
approach becomes:</p>
<div class="std">
<blockquote>
<div>
<div class="sourceCode" id="cb38"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb38-1"><a href="#cb38-1" aria-hidden="true" tabindex="-1"></a>  auto seq = ^{</span>
<span id="cb38-2"><a href="#cb38-2" aria-hidden="true" tabindex="-1"></a><span class="st">-     auto \id(&quot;_&quot;, x) = \tokens(e);</span></span>
<span id="cb38-3"><a href="#cb38-3" aria-hidden="true" tabindex="-1"></a><span class="va">+     auto \(std::meta::token::id(&quot;_&quot;, 1)) = \(e);</span></span>
<span id="cb38-4"><a href="#cb38-4" aria-hidden="true" tabindex="-1"></a>  };</span></code></pre></div>
</div>
</blockquote>
</div>
<p>Or, with a handy using-directive or using-declaration:</p>
<div class="std">
<blockquote>
<div>
<div class="sourceCode" id="cb39"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb39-1"><a href="#cb39-1" aria-hidden="true" tabindex="-1"></a>  auto seq = ^{</span>
<span id="cb39-2"><a href="#cb39-2" aria-hidden="true" tabindex="-1"></a><span class="st">-     auto \id(&quot;_&quot;, x) = \tokens(e);</span></span>
<span id="cb39-3"><a href="#cb39-3" aria-hidden="true" tabindex="-1"></a><span class="va">+     auto \(id(&quot;_&quot;, 1)) = \(e);</span></span>
<span id="cb39-4"><a href="#cb39-4" aria-hidden="true" tabindex="-1"></a>  };</span></code></pre></div>
</div>
</blockquote>
</div>
<p>This loses some orthogonality, namely what if we want to inject a
<em>value</em> of type
<code class="sourceCode cpp">token_sequence</code>. But for that we can
always resort to <code class="sourceCode cpp">\<span class="op">(</span>reflect_value<span class="op">(</span>tokens<span class="op">))</span></code>,
which is probably a rare use-case.</p>
<h2 data-number="4.3" id="phase-of-translation"><span class="header-section-number">4.3</span> Phase of Translation<a href="#phase-of-translation" class="self-link"></a></h2>
<p>Token sequences are a construct that is processed in translation
phase 7 (<span>5.2 <a href="https://wg21.link/lex.phases">[lex.phases]</a></span>). This has
some natural consequences detailed below.</p>
<p>The result of interpolating with
<code class="sourceCode cpp">\tokens</code> is a token sequence
consisting of all the tokens of both sequences:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb40"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb40-1"><a href="#cb40-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="kw">auto</span> t1 <span class="op">=</span> <span class="op">^{</span> c <span class="op">=</span>  <span class="op">}</span>;</span>
<span id="cb40-2"><a href="#cb40-2" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="kw">auto</span> t2 <span class="op">=</span> <span class="op">^{</span> a <span class="op">+</span> b; <span class="op">}</span>;</span>
<span id="cb40-3"><a href="#cb40-3" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="kw">auto</span> t3 <span class="op">=</span> <span class="op">^{</span> \tokens<span class="op">(</span>t1<span class="op">)</span> \tokens<span class="op">(</span>t2<span class="op">)</span> <span class="op">}</span>;</span>
<span id="cb40-4"><a href="#cb40-4" aria-hidden="true" tabindex="-1"></a><span class="kw">static_assert</span><span class="op">(</span>t3 <span class="op">==</span> <span class="op">^{</span> c <span class="op">=</span> a <span class="op">+</span> b; <span class="op">})</span>;</span></code></pre></div>
</blockquote>
</div>
<p>It is unclear if we want to support
<code class="sourceCode cpp"><span class="op">==</span></code> for token
sequences, but it is easier to express the intent if we use it. So this
paper will use
<code class="sourceCode cpp"><span class="op">==</span></code> at least
for exposition purposes.</p>
<p>The concatenation is not textual - two tokens concatenated together
preserve their identity, they are not pasted together into a single
token. For example:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb41"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb41-1"><a href="#cb41-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="kw">auto</span> t1 <span class="op">=</span> <span class="op">^{</span> abc <span class="op">}</span>;</span>
<span id="cb41-2"><a href="#cb41-2" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="kw">auto</span> t2 <span class="op">=</span> <span class="op">^{</span> def <span class="op">}</span>;</span>
<span id="cb41-3"><a href="#cb41-3" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="kw">auto</span> t3 <span class="op">=</span> <span class="op">^{</span> \tokens<span class="op">(</span>t1<span class="op">)</span> \tokens<span class="op">(</span>t2<span class="op">)</span> <span class="op">}</span>;</span>
<span id="cb41-4"><a href="#cb41-4" aria-hidden="true" tabindex="-1"></a><span class="kw">static_assert</span><span class="op">(</span>t3 <span class="op">!=</span> <span class="op">^{</span> abcdef <span class="op">})</span>;</span>
<span id="cb41-5"><a href="#cb41-5" aria-hidden="true" tabindex="-1"></a><span class="kw">static_assert</span><span class="op">(</span>t3 <span class="op">==</span> <span class="op">^{</span> abc def <span class="op">})</span>;</span></code></pre></div>
</blockquote>
</div>
<p>Whitespace and comments are treated just like in regular code - they
are not significant beyond their role as token separator. For
example:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb42"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb42-1"><a href="#cb42-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="kw">auto</span> t1 <span class="op">=</span> <span class="op">^{</span> hello  <span class="op">=</span> <span class="co">/* world */</span>   <span class="st">&quot;world&quot;</span> <span class="op">}</span>;</span>
<span id="cb42-2"><a href="#cb42-2" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="kw">auto</span> t2 <span class="op">=</span> <span class="op">^{</span> <span class="co">/* again */</span> hello<span class="op">=</span><span class="st">&quot;world&quot;</span> <span class="op">}</span>;</span>
<span id="cb42-3"><a href="#cb42-3" aria-hidden="true" tabindex="-1"></a><span class="kw">static_assert</span><span class="op">(</span>t1 <span class="op">==</span> t2<span class="op">)</span>;</span></code></pre></div>
</blockquote>
</div>
<p>Tokens are handled after the initial phases of preprocessing: macros
and string concatenation can apply, but occur before the implementation
assembles a token sequence. You therefore have to be careful with macros
because they won’t work the way you might want to:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb43"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb43-1"><a href="#cb43-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> <span class="kw">operator</span><span class="op">+(</span>info t1, info t2<span class="op">)</span> <span class="op">-&gt;</span> info <span class="op">{</span></span>
<span id="cb43-2"><a href="#cb43-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="op">^{</span> \tokens<span class="op">(</span>t1<span class="op">)</span> \tokens<span class="op">(</span>t2<span class="op">)</span> <span class="op">}</span>;</span>
<span id="cb43-3"><a href="#cb43-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb43-4"><a href="#cb43-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb43-5"><a href="#cb43-5" aria-hidden="true" tabindex="-1"></a><span class="kw">static_assert</span><span class="op">(^{</span> <span class="st">&quot;abc&quot;</span> <span class="st">&quot;def&quot;</span> <span class="op">}</span> <span class="op">==</span> <span class="op">^{</span> <span class="st">&quot;abcdef&quot;</span> <span class="op">})</span>;</span>
<span id="cb43-6"><a href="#cb43-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb43-7"><a href="#cb43-7" aria-hidden="true" tabindex="-1"></a><span class="co">// this concatenation produces the token sequence &quot;abc&quot; &quot;def&quot;, not &quot;abcdef&quot;</span></span>
<span id="cb43-8"><a href="#cb43-8" aria-hidden="true" tabindex="-1"></a><span class="co">// when this token sequence will be injected, that will be ill-formed</span></span>
<span id="cb43-9"><a href="#cb43-9" aria-hidden="true" tabindex="-1"></a><span class="kw">static_assert</span><span class="op">(^{</span> <span class="st">&quot;abc&quot;</span> <span class="op">}</span> <span class="op">+</span> <span class="op">^{</span> <span class="st">&quot;def&quot;</span> <span class="op">}</span> <span class="op">!=</span> <span class="op">^{</span> <span class="st">&quot;abcdef&quot;</span> <span class="op">})</span>;</span>
<span id="cb43-10"><a href="#cb43-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb43-11"><a href="#cb43-11" aria-hidden="true" tabindex="-1"></a><span class="pp">#define PLUS_ONE</span><span class="op">(</span>x<span class="op">)</span><span class="pp"> </span><span class="op">((</span>x<span class="op">)</span><span class="pp"> </span><span class="op">+</span><span class="pp"> </span><span class="dv">1</span><span class="op">)</span></span>
<span id="cb43-12"><a href="#cb43-12" aria-hidden="true" tabindex="-1"></a><span class="kw">static_assert</span><span class="op">(^{</span> PLUS_ONE<span class="op">(</span>x<span class="op">)</span> <span class="op">}</span> <span class="op">==</span> <span class="op">^{</span> <span class="op">((</span>x<span class="op">)</span> <span class="op">+</span> <span class="dv">1</span><span class="op">)</span> <span class="op">})</span>;</span>
<span id="cb43-13"><a href="#cb43-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb43-14"><a href="#cb43-14" aria-hidden="true" tabindex="-1"></a><span class="co">// amusingly this version also still works but not for the reason you think</span></span>
<span id="cb43-15"><a href="#cb43-15" aria-hidden="true" tabindex="-1"></a><span class="co">// on the left-hand-side the macro PLUS_ONE is still invoked...</span></span>
<span id="cb43-16"><a href="#cb43-16" aria-hidden="true" tabindex="-1"></a><span class="co">// but as PLUS_ONE(x} +^{)</span></span>
<span id="cb43-17"><a href="#cb43-17" aria-hidden="true" tabindex="-1"></a><span class="co">// which produces ((x} +^{) + 1)</span></span>
<span id="cb43-18"><a href="#cb43-18" aria-hidden="true" tabindex="-1"></a><span class="co">// which leads to ^{ ((x } + ^{) + 1) }</span></span>
<span id="cb43-19"><a href="#cb43-19" aria-hidden="true" tabindex="-1"></a><span class="co">// which is ^{ ((x) + 1)}</span></span>
<span id="cb43-20"><a href="#cb43-20" aria-hidden="true" tabindex="-1"></a><span class="kw">static_assert</span><span class="op">(^{</span> PLUS_ONE<span class="op">(</span>x <span class="op">}</span> <span class="op">+</span> <span class="op">^{</span> <span class="op">)</span> <span class="op">}</span> <span class="op">==</span> <span class="op">^{</span> PLUS_ONE<span class="op">(</span>x<span class="op">)</span> <span class="op">})</span>;</span>
<span id="cb43-21"><a href="#cb43-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb43-22"><a href="#cb43-22" aria-hidden="true" tabindex="-1"></a><span class="co">// But this one finally fails, because the macro isn&#39;t actually invoked</span></span>
<span id="cb43-23"><a href="#cb43-23" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="kw">auto</span> tok2 <span class="op">=</span> <span class="op">[]{</span></span>
<span id="cb43-24"><a href="#cb43-24" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> t <span class="op">=</span> <span class="op">^{</span> PLUS_ONE<span class="op">(</span>x <span class="op">}</span>;</span>
<span id="cb43-25"><a href="#cb43-25" aria-hidden="true" tabindex="-1"></a>    constexpr_print_str<span class="op">(</span><span class="st">&quot;Logging...</span><span class="sc">\n</span><span class="st">&quot;</span><span class="op">)</span>;</span>
<span id="cb43-26"><a href="#cb43-26" aria-hidden="true" tabindex="-1"></a>    t <span class="op">+=</span> <span class="op">^{</span> <span class="op">)</span> <span class="op">}</span></span>
<span id="cb43-27"><a href="#cb43-27" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> t;</span>
<span id="cb43-28"><a href="#cb43-28" aria-hidden="true" tabindex="-1"></a><span class="op">}()</span>;</span>
<span id="cb43-29"><a href="#cb43-29" aria-hidden="true" tabindex="-1"></a><span class="kw">static_assert</span><span class="op">(</span>tok2 <span class="op">!=</span> <span class="op">^{</span> PLUS_ONE<span class="op">(</span>x<span class="op">)</span> <span class="op">})</span>;</span></code></pre></div>
</blockquote>
</div>
<p>A token sequence has no meaning by itself, until injected. But
because (hopefully) users will write valid C++ code, the resulting
injection actually does look like C++ code.</p>
<h2 data-number="4.4" id="injection"><span class="header-section-number">4.4</span> Injection<a href="#injection" class="self-link"></a></h2>
<p>Once we have a token sequence, we need to do something with it. We
need to inject it somewhere to get parsed and become part of the
program.</p>
<p>We propose two injection functions.</p>
<p><code class="sourceCode cpp">std<span class="op">::</span>meta<span class="op">::</span>queue_injection<span class="op">(</span>e<span class="op">)</span></code>,
where <code class="sourceCode cpp">e</code> is a token sequence, will
queue up a token sequence to be injected at the end of the current
constant evaluation - typically the end of the
<code class="sourceCode cpp"><span class="kw">consteval</span></code>
block that the call is made from.</p>
<p><code class="sourceCode cpp">std<span class="op">::</span>meta<span class="op">::</span>namespace_inject<span class="op">(</span>ns, e<span class="op">)</span></code>,
where <code class="sourceCode cpp">ns</code> is a reflection of a
namespace and <code class="sourceCode cpp">e</code> is a token sequence,
will immediately inject the contents of
<code class="sourceCode cpp">e</code> into the namespace designated by
<code class="sourceCode cpp">ns</code>.</p>
<p>We can inject into a namespace since namespaces are open - we cannot
inject into any other context other than the one we’re currently in.</p>
<p>As a <a href="https://godbolt.org/z/Ehnhxde3K">simple
example</a>:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb44"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb44-1"><a href="#cb44-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;experimental/meta&gt;</span></span>
<span id="cb44-2"><a href="#cb44-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb44-3"><a href="#cb44-3" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> f<span class="op">(</span>std<span class="op">::</span>meta<span class="op">::</span>info r, <span class="dt">int</span> val, std<span class="op">::</span>string_view name<span class="op">)</span> <span class="op">{</span></span>
<span id="cb44-4"><a href="#cb44-4" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> <span class="op">^{</span> <span class="kw">constexpr</span> <span class="op">[:</span>\<span class="op">(</span>r<span class="op">):]</span> \id<span class="op">(</span>name<span class="op">)</span> <span class="op">=</span> \<span class="op">(</span>val<span class="op">)</span>; <span class="op">}</span>;</span>
<span id="cb44-5"><a href="#cb44-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb44-6"><a href="#cb44-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb44-7"><a href="#cb44-7" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="kw">auto</span> r <span class="op">=</span> f<span class="op">(^</span><span class="dt">int</span>, <span class="dv">42</span>, <span class="st">&quot;x&quot;</span><span class="op">)</span>;</span>
<span id="cb44-8"><a href="#cb44-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb44-9"><a href="#cb44-9" aria-hidden="true" tabindex="-1"></a><span class="kw">namespace</span> N <span class="op">{}</span></span>
<span id="cb44-10"><a href="#cb44-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb44-11"><a href="#cb44-11" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="op">{</span></span>
<span id="cb44-12"><a href="#cb44-12" aria-hidden="true" tabindex="-1"></a>  <span class="co">// this static assertion will be injected at the end of the block</span></span>
<span id="cb44-13"><a href="#cb44-13" aria-hidden="true" tabindex="-1"></a>  queue_injection<span class="op">(^{</span> <span class="kw">static_assert</span><span class="op">(</span>N<span class="op">::</span>x <span class="op">==</span> <span class="dv">42</span><span class="op">)</span>; <span class="op">})</span>;</span>
<span id="cb44-14"><a href="#cb44-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb44-15"><a href="#cb44-15" aria-hidden="true" tabindex="-1"></a>  <span class="co">// this declaration will be injected right into ::N right now</span></span>
<span id="cb44-16"><a href="#cb44-16" aria-hidden="true" tabindex="-1"></a>  namespace_inject<span class="op">(^</span>N, r<span class="op">)</span>;</span>
<span id="cb44-17"><a href="#cb44-17" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb44-18"><a href="#cb44-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb44-19"><a href="#cb44-19" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> main<span class="op">()</span> <span class="op">{</span></span>
<span id="cb44-20"><a href="#cb44-20" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> N<span class="op">::</span>x <span class="op">!=</span> <span class="dv">42</span>;</span>
<span id="cb44-21"><a href="#cb44-21" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>With that out of the way, we can now go through our examples from
earlier.</p>
<h2 data-number="4.5" id="token-sequence-type"><span class="header-section-number">4.5</span> Token Sequence Type<a href="#token-sequence-type" class="self-link"></a></h2>
<p>In this paper (and the current implementation), the type of a token
sequence is also <code class="sourceCode cpp">std<span class="op">::</span>meta<span class="op">::</span>info</code>.
This follows the general <span class="citation" data-cites="P2996R4">[<a href="https://wg21.link/p2996r4" role="doc-biblioref">P2996R4</a>]</span> design that all types that are
opaque handles into the compiler have type <code class="sourceCode cpp">std<span class="op">::</span>meta<span class="op">::</span>info</code>.
And that is appealing for its simplicity.</p>
<p>However, unlike reflections of source constructs, token sequence
manipulation is a completely disjoint set of operations. The only kinds
of reflection that can produce token sequences can only ever produce
token sequences (e.g. getting the
<code class="sourceCode cpp"><span class="kw">noexcept</span></code>
specifier of a function template).</p>
<p>Some APIs only make sense to do on a token sequence - for instance
while we described
<code class="sourceCode cpp"><span class="op">+</span></code> as not
being essential, we could certainly still provide it - but from an API
perspective it’d be nicer if it took two objects of type
<code class="sourceCode cpp">token_sequence</code> rather than two of
type <code class="sourceCode cpp">info</code> (and asserted that they
were <code class="sourceCode cpp">token_sequence</code>s). Either way,
misuse would be a compile error, but it might be better to only provide
the operator when we know it’s viable.</p>
<p>A dedicated <code class="sourceCode cpp">token_sequence</code> type
would also make macros (as introduced <a href="#scoped-macros">below</a>) stand out more from other reflection
functions, since there will be a lot of functions that take a
<code class="sourceCode cpp">meta<span class="op">::</span>info</code>
and return a
<code class="sourceCode cpp">meta<span class="op">::</span>info</code>
and such functions are quite different from macros.</p>
<h2 data-number="4.6" id="implementation-status"><span class="header-section-number">4.6</span> Implementation Status<a href="#implementation-status" class="self-link"></a></h2>
<p>A significant amount of this proposal is already implemented in EDG
and is available for experimentation on Compiler Explorer. The examples
we will demonstrate provide links.</p>
<p>The implementation provides a <code class="sourceCode cpp">__report_tokens<span class="op">(</span>e<span class="op">)</span></code>
function that can be used to dump the contents of a token sequence
during constant evaluation to aid in debugging.</p>
<p>Two things to note with the implementation:</p>
<ul>
<li>While we intend <code class="sourceCode cpp">\id<span class="op">(</span><span class="st">&quot;hello&quot;</span>, <span class="dv">1</span><span class="op">)</span></code>
to work, currently the string-like pieces must actually have type <code class="sourceCode cpp">std<span class="op">::</span>string_view</code> -
<code class="sourceCode cpp">\id<span class="op">(</span><span class="st">&quot;hello&quot;</span><span class="bu">sv</span>, <span class="dv">1</span><span class="op">)</span></code>
does work and will produce the identifier
<code class="sourceCode cpp">hello1</code>.</li>
<li>Injecting into a class template is currently very limited. Attempts
to inject member function definitions will lead to linker errors and
attempts to inject nested class definitions will fail. Currently, this
will require using <code class="sourceCode cpp">namespace_inject</code>
to inject the entire class template specialization in one go. You can
see this approach in action with the <a href="#type-erasure">type
erasure example</a>.</li>
</ul>
<h2 data-number="4.7" id="examples"><span class="header-section-number">4.7</span> Examples<a href="#examples" class="self-link"></a></h2>
<p>Now, the
<code class="sourceCode cpp">std<span class="op">::</span>tuple</code>
and <code class="sourceCode cpp">std<span class="op">::</span>enable_if</code>
cases look nearly-identical to their corresponding implementations with
<a href="#fragments">fragments</a>. In both cases, we are injecting
complete code fragments that require no other name lookup, so there is
not really any difference between a token sequence and a proper
fragment.</p>
<p><a href="https://godbolt.org/z/861MsqzPx">Implementing <code class="sourceCode cpp">Tuple<span class="op">&lt;</span>Ts<span class="op">...&gt;</span></code></a>
requires using both the value interpolator and the identifier
interpolator (in this case we’re naming the members
<code class="sourceCode cpp">_0</code>,
<code class="sourceCode cpp">_1</code>, etc.):</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb45"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb45-1"><a href="#cb45-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> Ts<span class="op">&gt;</span></span>
<span id="cb45-2"><a href="#cb45-2" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Tuple <span class="op">{</span></span>
<span id="cb45-3"><a href="#cb45-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">consteval</span> <span class="op">{</span></span>
<span id="cb45-4"><a href="#cb45-4" aria-hidden="true" tabindex="-1"></a>        std<span class="op">::</span>meta<span class="op">::</span>info types<span class="op">[]</span> <span class="op">=</span> <span class="op">{^</span>Ts<span class="op">...}</span>;</span>
<span id="cb45-5"><a href="#cb45-5" aria-hidden="true" tabindex="-1"></a>        <span class="cf">for</span> <span class="op">(</span><span class="dt">size_t</span> i <span class="op">=</span> <span class="dv">0</span>; i <span class="op">!=</span> <span class="kw">sizeof</span><span class="op">...(</span>Ts<span class="op">)</span>; <span class="op">++</span>i<span class="op">)</span> <span class="op">{</span></span>
<span id="cb45-6"><a href="#cb45-6" aria-hidden="true" tabindex="-1"></a>            queue_injection<span class="op">(^{</span> <span class="op">[[</span><span class="at">no_unique_address</span><span class="op">]]</span> <span class="op">[:</span>\<span class="op">(</span>types<span class="op">[</span>i<span class="op">]):]</span> \id<span class="op">(</span><span class="st">&quot;_&quot;</span>, i<span class="op">)</span>; <span class="op">})</span>;</span>
<span id="cb45-7"><a href="#cb45-7" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb45-8"><a href="#cb45-8" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb45-9"><a href="#cb45-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
</div>
<p>whereas <a href="https://godbolt.org/z/jfMoe34Ea">implementing <code class="sourceCode cpp">enable_if<span class="op">&lt;</span>B, T<span class="op">&gt;</span></code></a>
doesn’t require any interpolation at all:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb46"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb46-1"><a href="#cb46-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="dt">bool</span> B, <span class="kw">class</span> T<span class="op">=</span><span class="dt">void</span><span class="op">&gt;</span></span>
<span id="cb46-2"><a href="#cb46-2" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> enable_if <span class="op">{</span></span>
<span id="cb46-3"><a href="#cb46-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">consteval</span> <span class="op">{</span></span>
<span id="cb46-4"><a href="#cb46-4" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(</span>B<span class="op">)</span> <span class="op">{</span></span>
<span id="cb46-5"><a href="#cb46-5" aria-hidden="true" tabindex="-1"></a>            queue_injection<span class="op">(^{</span> <span class="kw">using</span> type <span class="op">=</span> T; <span class="op">})</span>;</span>
<span id="cb46-6"><a href="#cb46-6" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb46-7"><a href="#cb46-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb46-8"><a href="#cb46-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
</div>
<p>The property example likewise could be identical to the fragment
implementation, but we do not run into any name lookup issues, so we can
write it any way we want - either as injecting one token sequence or
even injecting three. Both work fine without needing any additional
declarations.</p>
<p>But we may want to restrict injection to one declaration at a time
for error reporting purposes (this is currently enforced by the EDG
implementation).</p>
<p>That implementation <a href="https://godbolt.org/z/sqKs6eKzG">looks
like this</a>:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb47"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb47-1"><a href="#cb47-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> property<span class="op">(</span>std<span class="op">::</span>meta<span class="op">::</span>info type, std<span class="op">::</span>string_view name<span class="op">)</span></span>
<span id="cb47-2"><a href="#cb47-2" aria-hidden="true" tabindex="-1"></a>    <span class="op">-&gt;</span> <span class="dt">void</span></span>
<span id="cb47-3"><a href="#cb47-3" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb47-4"><a href="#cb47-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> member <span class="op">=</span> <span class="op">^{</span> \id<span class="op">(</span><span class="st">&quot;m_&quot;</span><span class="bu">sv</span>, name<span class="op">)</span> <span class="op">}</span>;</span>
<span id="cb47-5"><a href="#cb47-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb47-6"><a href="#cb47-6" aria-hidden="true" tabindex="-1"></a>    queue_injection<span class="op">(^{</span> <span class="op">[:</span>\<span class="op">(</span>type<span class="op">):]</span> \tokens<span class="op">(</span>member<span class="op">)</span>; <span class="op">})</span>;</span>
<span id="cb47-7"><a href="#cb47-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb47-8"><a href="#cb47-8" aria-hidden="true" tabindex="-1"></a>    queue_injection<span class="op">(^{</span></span>
<span id="cb47-9"><a href="#cb47-9" aria-hidden="true" tabindex="-1"></a>        <span class="kw">auto</span> \id<span class="op">(</span><span class="st">&quot;get_&quot;</span><span class="bu">sv</span>, name<span class="op">)()</span> <span class="op">-&gt;</span> <span class="op">[:</span>\<span class="op">(</span>type<span class="op">):]</span> <span class="kw">const</span><span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb47-10"><a href="#cb47-10" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> \tokens<span class="op">(</span>member<span class="op">)</span>;</span>
<span id="cb47-11"><a href="#cb47-11" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb47-12"><a href="#cb47-12" aria-hidden="true" tabindex="-1"></a>    <span class="op">})</span>;</span>
<span id="cb47-13"><a href="#cb47-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb47-14"><a href="#cb47-14" aria-hidden="true" tabindex="-1"></a>    queue_injection<span class="op">(^{</span></span>
<span id="cb47-15"><a href="#cb47-15" aria-hidden="true" tabindex="-1"></a>        <span class="kw">auto</span> \id<span class="op">(</span><span class="st">&quot;set_&quot;</span><span class="bu">sv</span>, name<span class="op">)(</span><span class="kw">typename</span> <span class="op">[:</span>\<span class="op">(</span>type<span class="op">):]</span> <span class="kw">const</span><span class="op">&amp;</span> x<span class="op">)</span></span>
<span id="cb47-16"><a href="#cb47-16" aria-hidden="true" tabindex="-1"></a>            <span class="op">-&gt;</span> <span class="dt">void</span> <span class="op">{</span></span>
<span id="cb47-17"><a href="#cb47-17" aria-hidden="true" tabindex="-1"></a>            \tokens<span class="op">(</span>member<span class="op">)</span> <span class="op">=</span> x;</span>
<span id="cb47-18"><a href="#cb47-18" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb47-19"><a href="#cb47-19" aria-hidden="true" tabindex="-1"></a>    <span class="op">})</span>;</span>
<span id="cb47-20"><a href="#cb47-20" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb47-21"><a href="#cb47-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb47-22"><a href="#cb47-22" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Book <span class="op">{</span></span>
<span id="cb47-23"><a href="#cb47-23" aria-hidden="true" tabindex="-1"></a>    <span class="kw">consteval</span> <span class="op">{</span></span>
<span id="cb47-24"><a href="#cb47-24" aria-hidden="true" tabindex="-1"></a>        property<span class="op">(^</span>std<span class="op">::</span>string, <span class="st">&quot;title&quot;</span><span class="op">)</span>;</span>
<span id="cb47-25"><a href="#cb47-25" aria-hidden="true" tabindex="-1"></a>        property<span class="op">(^</span>std<span class="op">::</span>string, <span class="st">&quot;author&quot;</span><span class="op">)</span>;</span>
<span id="cb47-26"><a href="#cb47-26" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb47-27"><a href="#cb47-27" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
</div>
<p>With the postfix increment example, we see some more interesting
difference. We are not proposing any special-case syntax for getting at
the type that we are injecting into, so it would have to be pulled out
from the context (we’ll name it <code class="sourceCode cpp">T</code> in
both places for consistency):</p>
<table>
<thead>
<tr class="header">
<th><div style="text-align:center">
<strong>Fragment</strong>
</div></th>
<th><div style="text-align:center">
<strong><a href="https://godbolt.org/z/bTxPvb8cn">Token
Sequence</a></strong>
</div></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><div>

<div class="sourceCode" id="cb48"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb48-1"><a href="#cb48-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> postfix_increment<span class="op">()</span> <span class="op">-&gt;</span> <span class="dt">void</span> <span class="op">{</span></span>
<span id="cb48-2"><a href="#cb48-2" aria-hidden="true" tabindex="-1"></a>    <span class="op">-&gt;</span> fragment <span class="kw">struct</span> T <span class="op">{</span></span>
<span id="cb48-3"><a href="#cb48-3" aria-hidden="true" tabindex="-1"></a>        <span class="kw">requires</span> T<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">++()</span>;</span>
<span id="cb48-4"><a href="#cb48-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb48-5"><a href="#cb48-5" aria-hidden="true" tabindex="-1"></a>        <span class="kw">auto</span> <span class="kw">operator</span><span class="op">++(</span><span class="dt">int</span><span class="op">)</span> <span class="op">-&gt;</span> T <span class="op">{</span></span>
<span id="cb48-6"><a href="#cb48-6" aria-hidden="true" tabindex="-1"></a>            <span class="kw">auto</span> tmp <span class="op">=</span> <span class="op">*</span><span class="kw">this</span>;</span>
<span id="cb48-7"><a href="#cb48-7" aria-hidden="true" tabindex="-1"></a>            <span class="op">++*</span><span class="kw">this</span>;</span>
<span id="cb48-8"><a href="#cb48-8" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> tmp;</span>
<span id="cb48-9"><a href="#cb48-9" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb48-10"><a href="#cb48-10" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span>;</span>
<span id="cb48-11"><a href="#cb48-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>

</div></td>
<td><div>

<div class="sourceCode" id="cb49"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb49-1"><a href="#cb49-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> postfix_increment<span class="op">()</span> <span class="op">-&gt;</span> <span class="dt">void</span> <span class="op">{</span></span>
<span id="cb49-2"><a href="#cb49-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> T <span class="op">=</span> std<span class="op">::</span>meta<span class="op">::</span>nearest_class_or_namespace<span class="op">()</span>;</span>
<span id="cb49-3"><a href="#cb49-3" aria-hidden="true" tabindex="-1"></a>    queue_injection<span class="op">(^{</span></span>
<span id="cb49-4"><a href="#cb49-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb49-5"><a href="#cb49-5" aria-hidden="true" tabindex="-1"></a>        <span class="kw">auto</span> <span class="kw">operator</span><span class="op">++(</span><span class="dt">int</span><span class="op">)</span> <span class="op">-&gt;</span> <span class="op">[:</span>\<span class="op">(</span>T<span class="op">):]</span> <span class="op">{</span></span>
<span id="cb49-6"><a href="#cb49-6" aria-hidden="true" tabindex="-1"></a>            <span class="kw">auto</span> tmp <span class="op">=</span> <span class="op">*</span><span class="kw">this</span>;</span>
<span id="cb49-7"><a href="#cb49-7" aria-hidden="true" tabindex="-1"></a>            <span class="op">++*</span><span class="kw">this</span>;</span>
<span id="cb49-8"><a href="#cb49-8" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> tmp;</span>
<span id="cb49-9"><a href="#cb49-9" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb49-10"><a href="#cb49-10" aria-hidden="true" tabindex="-1"></a>    <span class="op">})</span>;</span>
<span id="cb49-11"><a href="#cb49-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>

</div></td>
</tr>
</tbody>
</table>
<p>The syntax here is, unsurprisingly, largely the same. We’re mostly
writing C++ code. The difference is that we no longer need to
pre-declare the functions we’re using and the feature set is smaller.
While declaring <code class="sourceCode cpp">T</code> as part of the
fragment is certainly convenient, we’re shooting for a smaller
feature.</p>
<h2 data-number="4.8" id="type-erasure"><span class="header-section-number">4.8</span> Type Erasure<a href="#type-erasure" class="self-link"></a></h2>
<p>Given a type, whose declaration only contains member functions that
aren’t templates, it is possible to mechanically produce a type-erased
version of that interface.</p>
<p>For instance:</p>
<table>
<thead>
<tr class="header">
<th><div style="text-align:center">
<strong>Interface</strong>
</div></th>
<th><div style="text-align:center">
<strong>Type-Erased</strong>
</div></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><div>

<div class="sourceCode" id="cb50"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb50-1"><a href="#cb50-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Interface <span class="op">{</span></span>
<span id="cb50-2"><a href="#cb50-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">void</span> draw<span class="op">(</span>std<span class="op">::</span>ostream<span class="op">&amp;)</span> <span class="kw">const</span>;</span>
<span id="cb50-3"><a href="#cb50-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>

</div></td>
<td><div>

<div class="sourceCode" id="cb51"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb51-1"><a href="#cb51-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;&gt;</span></span>
<span id="cb51-2"><a href="#cb51-2" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Dyn<span class="op">&lt;</span>Interface<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb51-3"><a href="#cb51-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">struct</span> VTable <span class="op">{</span></span>
<span id="cb51-4"><a href="#cb51-4" aria-hidden="true" tabindex="-1"></a>        <span class="co">// 1. convert each function in Interface to a</span></span>
<span id="cb51-5"><a href="#cb51-5" aria-hidden="true" tabindex="-1"></a>        <span class="co">//    function pointer with an extra void*</span></span>
<span id="cb51-6"><a href="#cb51-6" aria-hidden="true" tabindex="-1"></a>        <span class="dt">void</span> <span class="op">(*</span>draw<span class="op">)(</span><span class="dt">void</span><span class="op">*</span>, std<span class="op">::</span>ostream<span class="op">&amp;)</span>;</span>
<span id="cb51-7"><a href="#cb51-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span>;</span>
<span id="cb51-8"><a href="#cb51-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb51-9"><a href="#cb51-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span></span>
<span id="cb51-10"><a href="#cb51-10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> <span class="kw">constexpr</span> VTable vtable_for <span class="op">=</span> VTable <span class="op">{</span></span>
<span id="cb51-11"><a href="#cb51-11" aria-hidden="true" tabindex="-1"></a>        <span class="co">// 2. convert each function in Interface to a</span></span>
<span id="cb51-12"><a href="#cb51-12" aria-hidden="true" tabindex="-1"></a>        <span class="co">//    forwarding, static-casting lambda</span></span>
<span id="cb51-13"><a href="#cb51-13" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>draw <span class="op">=</span> <span class="op">+[](</span><span class="dt">void</span><span class="op">*</span> data, std<span class="op">::</span>ostream<span class="op">&amp;</span> p0<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">void</span> <span class="op">{</span></span>
<span id="cb51-14"><a href="#cb51-14" aria-hidden="true" tabindex="-1"></a>            <span class="co">// NB: the const here because Interface::draw() is const</span></span>
<span id="cb51-15"><a href="#cb51-15" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> <span class="kw">static_cast</span><span class="op">&lt;</span>T <span class="kw">const</span><span class="op">*&gt;(</span>data<span class="op">)-&gt;</span>draw<span class="op">(</span>p0<span class="op">)</span>;</span>
<span id="cb51-16"><a href="#cb51-16" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb51-17"><a href="#cb51-17" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span>;</span>
<span id="cb51-18"><a href="#cb51-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb51-19"><a href="#cb51-19" aria-hidden="true" tabindex="-1"></a>    VTable <span class="kw">const</span><span class="op">*</span> vtable;</span>
<span id="cb51-20"><a href="#cb51-20" aria-hidden="true" tabindex="-1"></a>    <span class="dt">void</span><span class="op">*</span> data;</span>
<span id="cb51-21"><a href="#cb51-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb51-22"><a href="#cb51-22" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb51-23"><a href="#cb51-23" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span></span>
<span id="cb51-24"><a href="#cb51-24" aria-hidden="true" tabindex="-1"></a>        <span class="co">// 3. convert each function in Interface to its</span></span>
<span id="cb51-25"><a href="#cb51-25" aria-hidden="true" tabindex="-1"></a>        <span class="co">//    appropriate requires clause</span></span>
<span id="cb51-26"><a href="#cb51-26" aria-hidden="true" tabindex="-1"></a>        <span class="co">//    NB: the remove_cvref_t&lt;T&gt; const here because</span></span>
<span id="cb51-27"><a href="#cb51-27" aria-hidden="true" tabindex="-1"></a>        <span class="co">//        Interface::draw() is const</span></span>
<span id="cb51-28"><a href="#cb51-28" aria-hidden="true" tabindex="-1"></a>        <span class="kw">requires</span> <span class="kw">requires</span> <span class="op">(</span>std<span class="op">::</span>remove_cvref_t<span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="kw">const</span> t,</span>
<span id="cb51-29"><a href="#cb51-29" aria-hidden="true" tabindex="-1"></a>                           std<span class="op">::</span>ostream<span class="op">&amp;</span> p0<span class="op">)</span> <span class="op">{</span></span>
<span id="cb51-30"><a href="#cb51-30" aria-hidden="true" tabindex="-1"></a>            <span class="op">{</span> t<span class="op">.</span>draw<span class="op">(</span>p0<span class="op">)</span> <span class="op">}</span> <span class="op">-&gt;</span> std<span class="op">::</span>convertible_to<span class="op">&lt;</span><span class="dt">void</span><span class="op">&gt;</span>;</span>
<span id="cb51-31"><a href="#cb51-31" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb51-32"><a href="#cb51-32" aria-hidden="true" tabindex="-1"></a>    Dyn<span class="op">(</span>T<span class="op">&amp;&amp;</span> t<span class="op">)</span></span>
<span id="cb51-33"><a href="#cb51-33" aria-hidden="true" tabindex="-1"></a>        <span class="op">:</span> vtable<span class="op">(&amp;</span>vtable_for<span class="op">&lt;</span>std<span class="op">::</span>remove_cvref_t<span class="op">&lt;</span>T<span class="op">&gt;&gt;)</span></span>
<span id="cb51-34"><a href="#cb51-34" aria-hidden="true" tabindex="-1"></a>        , data<span class="op">(&amp;</span>t<span class="op">)</span></span>
<span id="cb51-35"><a href="#cb51-35" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span> <span class="op">}</span></span>
<span id="cb51-36"><a href="#cb51-36" aria-hidden="true" tabindex="-1"></a>    Dyn<span class="op">(</span>Dyn<span class="op">&amp;)</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb51-37"><a href="#cb51-37" aria-hidden="true" tabindex="-1"></a>    Dyn<span class="op">(</span>Dyn <span class="kw">const</span><span class="op">&amp;)</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb51-38"><a href="#cb51-38" aria-hidden="true" tabindex="-1"></a>    <span class="op">~</span>Dyn<span class="op">()</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb51-39"><a href="#cb51-39" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb51-40"><a href="#cb51-40" aria-hidden="true" tabindex="-1"></a>    <span class="co">// 4. convert each function in Interface to a function</span></span>
<span id="cb51-41"><a href="#cb51-41" aria-hidden="true" tabindex="-1"></a>    <span class="co">//    that forwards through the vtable</span></span>
<span id="cb51-42"><a href="#cb51-42" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> draw<span class="op">(</span>std<span class="op">::</span>ostream<span class="op">&amp;</span> p0<span class="op">)</span> <span class="kw">const</span> <span class="op">-&gt;</span> <span class="dt">void</span> <span class="op">{</span></span>
<span id="cb51-43"><a href="#cb51-43" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> vtable<span class="op">-&gt;</span>draw<span class="op">(</span>data, p0<span class="op">)</span>;</span>
<span id="cb51-44"><a href="#cb51-44" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb51-45"><a href="#cb51-45" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>

</div></td>
</tr>
</tbody>
</table>
<p>That implementation is currently non-owning, but it isn’t that much
of a difference to make it owning, move-only, have a small buffer
optimized storage, etc.</p>
<p>There is a lot of code on the right (especially compared to the
left), but the transformation is <em>purely</em> mechanical. It is so
mechanical, in fact, that it lends itself very nicely to precisely the
kind of code injection being proposed in this paper.</p>
<p>You can find the implementation <a href="https://godbolt.org/z/8hqTPhje4">here</a>. Note that the current
implementation uses <code class="sourceCode cpp">namespace_inject</code>
to produce the entire template specialization of
<code class="sourceCode cpp">Dyn</code>. We hope to not have to require
that approach, but at the moment EDG cannot inject nested type
defintions in a class template. It’s a healthy amount of code, but it’s
actually fairly straightforward.</p>
<h2 data-number="4.9" id="logging-vector-cloning-a-type"><span class="header-section-number">4.9</span> Logging Vector: Cloning a
Type<a href="#logging-vector-cloning-a-type" class="self-link"></a></h2>
<p>The goal here is we want to implement a type <code class="sourceCode cpp">LoggingVector<span class="op">&lt;</span>T<span class="op">&gt;</span></code>
which behaves like <code class="sourceCode cpp">std<span class="op">::</span>vector<span class="op">&lt;</span>T<span class="op">&gt;</span></code>
in all respects except that it prints the function being called.</p>
<p>We start with this:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb52"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb52-1"><a href="#cb52-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb52-2"><a href="#cb52-2" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> LoggingVector <span class="op">{</span></span>
<span id="cb52-3"><a href="#cb52-3" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>vector<span class="op">&lt;</span>T<span class="op">&gt;</span> impl;</span>
<span id="cb52-4"><a href="#cb52-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb52-5"><a href="#cb52-5" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb52-6"><a href="#cb52-6" aria-hidden="true" tabindex="-1"></a>    LoggingVector<span class="op">(</span>std<span class="op">::</span>vector<span class="op">&lt;</span>T<span class="op">&gt;</span> v<span class="op">)</span> <span class="op">:</span> impl<span class="op">(</span>std<span class="op">::</span>move<span class="op">(</span>v<span class="op">))</span> <span class="op">{</span> <span class="op">}</span></span>
<span id="cb52-7"><a href="#cb52-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb52-8"><a href="#cb52-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">consteval</span> <span class="op">{</span></span>
<span id="cb52-9"><a href="#cb52-9" aria-hidden="true" tabindex="-1"></a>        <span class="cf">for</span> <span class="op">(</span>std<span class="op">::</span>meta<span class="op">::</span>info fun <span class="op">:</span> <span class="co">/* public, non-special member functions */</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb52-10"><a href="#cb52-10" aria-hidden="true" tabindex="-1"></a>            queue_injection<span class="op">(^{</span></span>
<span id="cb52-11"><a href="#cb52-11" aria-hidden="true" tabindex="-1"></a>                \tokens<span class="op">(</span>make_decl_of<span class="op">(</span>fun<span class="op">))</span> <span class="op">{</span></span>
<span id="cb52-12"><a href="#cb52-12" aria-hidden="true" tabindex="-1"></a>                    <span class="co">// ...</span></span>
<span id="cb52-13"><a href="#cb52-13" aria-hidden="true" tabindex="-1"></a>                <span class="op">}</span></span>
<span id="cb52-14"><a href="#cb52-14" aria-hidden="true" tabindex="-1"></a>            <span class="op">})</span>;</span>
<span id="cb52-15"><a href="#cb52-15" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb52-16"><a href="#cb52-16" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb52-17"><a href="#cb52-17" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
</div>
<p>We want to clone every member function, which requires copying the
declaration. We don’t want to actually have to spell out the declaration
in the token sequence that we inject - that would be a tremendous amount
of work given the complexity of C++ declarations. But the nice thing
about token sequence injection is that we really only have to do that
<em>one</em> time and stuff it into a function. <code class="sourceCode cpp">make_decl_of<span class="op">()</span></code> can
just be a function that takes a reflection of a function and returns a
token sequence for its declaration. We’ll probably want to put this in
the standard library.</p>
<p>Now, we have two problems to solve in the body (as well as a few more
problems we’ll get to later).</p>
<p>First, we need to print the name of the function we’re calling. This
is easy, since we have the function and can just ask for its name.</p>
<p>Second, we need to actually forward the parameters of the function
into our member <code class="sourceCode cpp">impl</code>. This is,
seemingly, very hard:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb53"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb53-1"><a href="#cb53-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="op">{</span></span>
<span id="cb53-2"><a href="#cb53-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> <span class="op">(</span>std<span class="op">::</span>meta<span class="op">::</span>info fun <span class="op">:</span> <span class="co">/* public, non-special member functions */</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb53-3"><a href="#cb53-3" aria-hidden="true" tabindex="-1"></a>        queue_injection<span class="op">(^{</span></span>
<span id="cb53-4"><a href="#cb53-4" aria-hidden="true" tabindex="-1"></a>            \tokens<span class="op">(</span>make_decl_of<span class="op">(</span>fun<span class="op">))</span> <span class="op">{</span></span>
<span id="cb53-5"><a href="#cb53-5" aria-hidden="true" tabindex="-1"></a>                std<span class="op">::</span>println<span class="op">(</span><span class="st">&quot;Calling {}&quot;</span>, \<span class="op">(</span>name_of<span class="op">(</span>fun<span class="op">)))</span>;</span>
<span id="cb53-6"><a href="#cb53-6" aria-hidden="true" tabindex="-1"></a>                <span class="cf">return</span> impl<span class="op">.[:</span>\<span class="op">(</span>fun<span class="op">):](</span><span class="co">/* ???? */</span><span class="op">)</span>;</span>
<span id="cb53-7"><a href="#cb53-7" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="cb53-8"><a href="#cb53-8" aria-hidden="true" tabindex="-1"></a>        <span class="op">})</span>;</span>
<span id="cb53-9"><a href="#cb53-9" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb53-10"><a href="#cb53-10" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>This is where the ability of token sequences to be concatenated from
purely sequences of tokens really gives us a lot of value. How do we
forward the parameters along? We don’t even have the parameter names
here - the declaration that we’re cloning might not even <em>have</em>
parameter names.</p>
<p>So there are two approaches that we can use here:</p>
<h3 data-number="4.9.1" id="reflections-of-parameters"><span class="header-section-number">4.9.1</span> Reflections of Parameters<a href="#reflections-of-parameters" class="self-link"></a></h3>
<p>We need the ability to just ask for the parameters themselves (which
<span class="citation" data-cites="P3096R1">[<a href="https://wg21.link/p3096r1" role="doc-biblioref">P3096R1</a>]</span> should provide). And then the
goal here is to inject the tokens for the call:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb54"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb54-1"><a href="#cb54-1" aria-hidden="true" tabindex="-1"></a><span class="cf">return</span> impl<span class="op">.[:</span>fun<span class="op">:]([:</span>p<sub>0</sub><span class="op">:]</span>, <span class="op">[:</span>p<sub>1</sub><span class="op">:]</span>, <span class="op">...</span>, <span class="op">[:</span>p<sub>n</sub><span class="op">:])</span></span></code></pre></div>
</blockquote>
</div>
<p>But the tricky part is that we can’t ask for the parameters of the
function we’re cloning (i.e. <code class="sourceCode cpp">fun</code> in
the loop above - which is a reflection of a non-static member function
of <code class="sourceCode cpp">std<span class="op">::</span>vector<span class="op">&lt;</span>T<span class="op">&gt;</span></code>),
we have to ask for the parameters of the function that we’re
<em>currently</em> defining. Which we haven’t defined yet so we can’t
reflect on it.</p>
<p>But we could split this in pieces and ask
<code class="sourceCode cpp">inject</code> to give us back a reflection
of what it injected, since <code class="sourceCode cpp">inject</code>
must operate on full token boundaries.</p>
<p>So that might be:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb55"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb55-1"><a href="#cb55-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb55-2"><a href="#cb55-2" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> LoggingVector <span class="op">{</span></span>
<span id="cb55-3"><a href="#cb55-3" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>vector<span class="op">&lt;</span>T<span class="op">&gt;</span> impl;</span>
<span id="cb55-4"><a href="#cb55-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb55-5"><a href="#cb55-5" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb55-6"><a href="#cb55-6" aria-hidden="true" tabindex="-1"></a>    LoggingVector<span class="op">(</span>std<span class="op">::</span>vector<span class="op">&lt;</span>T<span class="op">&gt;</span> v<span class="op">)</span> <span class="op">:</span> impl<span class="op">(</span>std<span class="op">::</span>move<span class="op">(</span>v<span class="op">))</span> <span class="op">{</span> <span class="op">}</span></span>
<span id="cb55-7"><a href="#cb55-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb55-8"><a href="#cb55-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">consteval</span> <span class="op">{</span></span>
<span id="cb55-9"><a href="#cb55-9" aria-hidden="true" tabindex="-1"></a>        <span class="cf">for</span> <span class="op">(</span>std<span class="op">::</span>meta<span class="op">::</span>info fun <span class="op">:</span> <span class="co">/* public, non-special member functions */</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb55-10"><a href="#cb55-10" aria-hidden="true" tabindex="-1"></a>            <span class="co">// note that this one doesn&#39;t even require a token sequence</span></span>
<span id="cb55-11"><a href="#cb55-11" aria-hidden="true" tabindex="-1"></a>            <span class="kw">auto</span> log_fun <span class="op">=</span> queue_injection<span class="op">(</span>decl_of<span class="op">(</span>fun<span class="op">))</span>;</span>
<span id="cb55-12"><a href="#cb55-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb55-13"><a href="#cb55-13" aria-hidden="true" tabindex="-1"></a>            <span class="co">// convenience type for building a comma-delimited sequence</span></span>
<span id="cb55-14"><a href="#cb55-14" aria-hidden="true" tabindex="-1"></a>            <span class="kw">auto</span> argument_list <span class="op">=</span> list_builder<span class="op">()</span>;</span>
<span id="cb55-15"><a href="#cb55-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb55-16"><a href="#cb55-16" aria-hidden="true" tabindex="-1"></a>            <span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span> param <span class="op">:</span> parameters_of<span class="op">(</span>log_fun<span class="op">))</span> <span class="op">{</span> <span class="co">// &lt;== NB, not fun</span></span>
<span id="cb55-17"><a href="#cb55-17" aria-hidden="true" tabindex="-1"></a>                argument_list <span class="op">+=</span> <span class="op">^{</span></span>
<span id="cb55-18"><a href="#cb55-18" aria-hidden="true" tabindex="-1"></a>                    <span class="kw">static_cast</span><span class="op">&lt;[:</span>\<span class="op">(</span>type_of<span class="op">(</span>param<span class="op">)):]&amp;&amp;&gt;([:</span> \<span class="op">(</span>param<span class="op">)</span> <span class="op">:])</span></span>
<span id="cb55-19"><a href="#cb55-19" aria-hidden="true" tabindex="-1"></a>                <span class="op">}</span>;</span>
<span id="cb55-20"><a href="#cb55-20" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="cb55-21"><a href="#cb55-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb55-22"><a href="#cb55-22" aria-hidden="true" tabindex="-1"></a>            queue_injection<span class="op">(^{</span></span>
<span id="cb55-23"><a href="#cb55-23" aria-hidden="true" tabindex="-1"></a>                \tokens<span class="op">(</span>make_decl_of<span class="op">(</span>fun<span class="op">))</span> <span class="op">{</span></span>
<span id="cb55-24"><a href="#cb55-24" aria-hidden="true" tabindex="-1"></a>                    std<span class="op">::</span>println<span class="op">(</span><span class="st">&quot;Calling {}&quot;</span>, \<span class="op">(</span>name_of<span class="op">(</span>fun<span class="op">)))</span>;</span>
<span id="cb55-25"><a href="#cb55-25" aria-hidden="true" tabindex="-1"></a>                    <span class="cf">return</span> impl<span class="op">.[:</span>\<span class="op">(</span>fun<span class="op">):](</span> <span class="op">[:</span>\tokens<span class="op">(</span>argument_list<span class="op">):]</span> <span class="op">)</span>;</span>
<span id="cb55-26"><a href="#cb55-26" aria-hidden="true" tabindex="-1"></a>                <span class="op">}</span></span>
<span id="cb55-27"><a href="#cb55-27" aria-hidden="true" tabindex="-1"></a>            <span class="op">})</span>;</span>
<span id="cb55-28"><a href="#cb55-28" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb55-29"><a href="#cb55-29" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb55-30"><a href="#cb55-30" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
</div>
<p>The <code class="sourceCode cpp">argument_list</code> is simply
building up the token sequence <code class="sourceCode cpp"><span class="op">[:</span> p<sub>0</sub> <span class="op">:]</span>, <span class="op">[:</span> p<sub>1</sub> <span class="op">:]</span>, <span class="op">...</span>, <span class="op">[:</span> p<sub>N</sub> <span class="op">:]</span></code>
for each parameter (except forwarded). There is no name lookup going on,
no checking of fragment correctness. Just building up the right
tokens.</p>
<p>Once we have those tokens, we can concatenate this token sequence
using the same interpolator that we’ve used for other problems and then
splice them in. In the same way that splicing a reflection of a type
produces a type, splicing a reflection of a token sequence produces
those tokens.</p>
<p>Note that we didn’t actually have to implement it using a separate
<code class="sourceCode cpp">argument_list</code> local variable - we
could’ve concatenated the entire token sequence piecewise. But this
structure allows factoring out parameter-forwarding into its own
function:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb56"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb56-1"><a href="#cb56-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> forward_parameters<span class="op">(</span>std<span class="op">::</span>meta<span class="op">::</span>info fun<span class="op">)</span> <span class="op">-&gt;</span> std<span class="op">::</span>meta<span class="op">::</span>info <span class="op">{</span></span>
<span id="cb56-2"><a href="#cb56-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> argument_list <span class="op">=</span> list_builder<span class="op">()</span>;</span>
<span id="cb56-3"><a href="#cb56-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span> param <span class="op">:</span> parameters_of<span class="op">(</span>fun<span class="op">))</span> <span class="op">{</span></span>
<span id="cb56-4"><a href="#cb56-4" aria-hidden="true" tabindex="-1"></a>        argument_list <span class="op">+=</span> <span class="op">^{</span></span>
<span id="cb56-5"><a href="#cb56-5" aria-hidden="true" tabindex="-1"></a>            <span class="kw">static_cast</span><span class="op">&lt;[:</span>\<span class="op">(</span>type_of<span class="op">(</span>param<span class="op">)):]&amp;&amp;&gt;([:</span>\param<span class="op">:])</span></span>
<span id="cb56-6"><a href="#cb56-6" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span>;</span>
<span id="cb56-7"><a href="#cb56-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb56-8"><a href="#cb56-8" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> argument_list;</span>
<span id="cb56-9"><a href="#cb56-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>And then:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb57"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb57-1"><a href="#cb57-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="op">{</span></span>
<span id="cb57-2"><a href="#cb57-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> <span class="op">(</span>std<span class="op">::</span>meta<span class="op">::</span>info fun <span class="op">:</span> <span class="co">/* public, non-special member functions */</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb57-3"><a href="#cb57-3" aria-hidden="true" tabindex="-1"></a>        <span class="kw">auto</span> log_fun <span class="op">=</span> queue_injection<span class="op">(</span>decl_of<span class="op">(</span>fun<span class="op">))</span>;</span>
<span id="cb57-4"><a href="#cb57-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb57-5"><a href="#cb57-5" aria-hidden="true" tabindex="-1"></a>        queue_injection<span class="op">(^{</span></span>
<span id="cb57-6"><a href="#cb57-6" aria-hidden="true" tabindex="-1"></a>            \tokens<span class="op">(</span>make_decl_of<span class="op">(</span>fun<span class="op">))</span> <span class="op">:]</span> <span class="op">{</span></span>
<span id="cb57-7"><a href="#cb57-7" aria-hidden="true" tabindex="-1"></a>                std<span class="op">::</span>println<span class="op">(</span><span class="st">&quot;Calling {}&quot;</span>, \<span class="op">(</span>name_of<span class="op">(</span>fun<span class="op">)))</span>;</span>
<span id="cb57-8"><a href="#cb57-8" aria-hidden="true" tabindex="-1"></a>                <span class="cf">return</span> impl<span class="op">.[:</span>\<span class="op">(</span>fun<span class="op">):](</span> <span class="op">[:</span> \tokens<span class="op">(</span>forward_parameters<span class="op">(</span>log_fun<span class="op">))</span> <span class="op">:]</span> <span class="op">)</span>;</span>
<span id="cb57-9"><a href="#cb57-9" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="cb57-10"><a href="#cb57-10" aria-hidden="true" tabindex="-1"></a>        <span class="op">})</span>;</span>
<span id="cb57-11"><a href="#cb57-11" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb57-12"><a href="#cb57-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>The problem is - this direction isn’t really viable. Injection queues
up requests for later. It may not be feasible for us to get back a
reflection of <code class="sourceCode cpp">log_fun</code> in the way
that we are using this example, so we probably cannot actually get back
and access the reflections of the parameters as described in this
example.</p>
<h3 data-number="4.9.2" id="introducing-parameter-names"><span class="header-section-number">4.9.2</span> Introducing Parameter Names<a href="#introducing-parameter-names" class="self-link"></a></h3>
<p>We said we have the problem that the functions we’re cloning might
not have parameter names. So what? We’re creating a new function, we can
pick our names!</p>
<p>Since our approach to cloning function declarations is just writing
our function that creates the tokens:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb58"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb58-1"><a href="#cb58-1" aria-hidden="true" tabindex="-1"></a>\tokens<span class="op">(</span>make_decl_of<span class="op">(</span>fun<span class="op">))</span> <span class="op">{</span> <span class="co">/* ... */</span> <span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>We can simply pass another argument to
<code class="sourceCode cpp">make_decl_of</code> that gives us a prefix
for each parameter name. So maybe <code class="sourceCode cpp">make_decl_of<span class="op">(</span>fun, <span class="st">&quot;p&quot;</span><span class="op">)</span></code>
would give us parameter names of <code class="sourceCode cpp">p0</code>,
<code class="sourceCode cpp">p1</code>, and so forth. That gives us a
similar looking solution, but now we never need the reflection of the
new function - just the old one:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb59"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb59-1"><a href="#cb59-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb59-2"><a href="#cb59-2" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> LoggingVector <span class="op">{</span></span>
<span id="cb59-3"><a href="#cb59-3" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>vector<span class="op">&lt;</span>T<span class="op">&gt;</span> impl;</span>
<span id="cb59-4"><a href="#cb59-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb59-5"><a href="#cb59-5" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb59-6"><a href="#cb59-6" aria-hidden="true" tabindex="-1"></a>    LoggingVector<span class="op">(</span>std<span class="op">::</span>vector<span class="op">&lt;</span>T<span class="op">&gt;</span> v<span class="op">)</span> <span class="op">:</span> impl<span class="op">(</span>std<span class="op">::</span>move<span class="op">(</span>v<span class="op">))</span> <span class="op">{</span> <span class="op">}</span></span>
<span id="cb59-7"><a href="#cb59-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb59-8"><a href="#cb59-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">consteval</span> <span class="op">{</span></span>
<span id="cb59-9"><a href="#cb59-9" aria-hidden="true" tabindex="-1"></a>        <span class="cf">for</span> <span class="op">(</span>std<span class="op">::</span>meta<span class="op">::</span>info fun <span class="op">:</span> <span class="co">/* public, non-special member functions */</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb59-10"><a href="#cb59-10" aria-hidden="true" tabindex="-1"></a>            <span class="kw">auto</span> argument_list <span class="op">=</span> list_builder<span class="op">()</span>;</span>
<span id="cb59-11"><a href="#cb59-11" aria-hidden="true" tabindex="-1"></a>            <span class="cf">for</span> <span class="op">(</span><span class="dt">size_t</span> i <span class="op">=</span> <span class="dv">0</span>; i <span class="op">!=</span> parameters_of<span class="op">(</span>fun<span class="op">).</span>size<span class="op">()</span>; <span class="op">++</span>i<span class="op">)</span> <span class="op">{</span></span>
<span id="cb59-12"><a href="#cb59-12" aria-hidden="true" tabindex="-1"></a>                argument_list <span class="op">+=</span> <span class="op">^{</span></span>
<span id="cb59-13"><a href="#cb59-13" aria-hidden="true" tabindex="-1"></a>                    <span class="co">// we could get the nth parameter&#39;s type (we can&#39;t splice</span></span>
<span id="cb59-14"><a href="#cb59-14" aria-hidden="true" tabindex="-1"></a>                    <span class="co">// the other function&#39;s parameters but we CAN query them)</span></span>
<span id="cb59-15"><a href="#cb59-15" aria-hidden="true" tabindex="-1"></a>                    <span class="co">// or we could just write decltype(p0)</span></span>
<span id="cb59-16"><a href="#cb59-16" aria-hidden="true" tabindex="-1"></a>                    <span class="kw">static_cast</span><span class="op">&lt;</span><span class="kw">decltype</span><span class="op">(</span>\id<span class="op">(</span><span class="st">&quot;p&quot;</span>, i<span class="op">))&amp;&amp;&gt;(</span>\id<span class="op">(</span><span class="st">&quot;p&quot;</span>, i<span class="op">))</span></span>
<span id="cb59-17"><a href="#cb59-17" aria-hidden="true" tabindex="-1"></a>                <span class="op">}</span>;</span>
<span id="cb59-18"><a href="#cb59-18" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="cb59-19"><a href="#cb59-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb59-20"><a href="#cb59-20" aria-hidden="true" tabindex="-1"></a>            queue_injection<span class="op">(^{</span></span>
<span id="cb59-21"><a href="#cb59-21" aria-hidden="true" tabindex="-1"></a>                \tokens<span class="op">(</span>make_decl_of<span class="op">(</span>fun, <span class="st">&quot;p&quot;</span><span class="op">))</span> <span class="op">{</span></span>
<span id="cb59-22"><a href="#cb59-22" aria-hidden="true" tabindex="-1"></a>                    std<span class="op">::</span>println<span class="op">(</span><span class="st">&quot;Calling {}&quot;</span>, \<span class="op">(</span>name_of<span class="op">(</span>fun<span class="op">)))</span>;</span>
<span id="cb59-23"><a href="#cb59-23" aria-hidden="true" tabindex="-1"></a>                    <span class="cf">return</span> impl<span class="op">.[:</span>\<span class="op">(</span>fun<span class="op">):](</span> <span class="op">[:</span>\<span class="op">(</span>argument_list<span class="op">):]</span> <span class="op">)</span>;</span>
<span id="cb59-24"><a href="#cb59-24" aria-hidden="true" tabindex="-1"></a>                <span class="op">}</span></span>
<span id="cb59-25"><a href="#cb59-25" aria-hidden="true" tabindex="-1"></a>            <span class="op">})</span>;</span>
<span id="cb59-26"><a href="#cb59-26" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb59-27"><a href="#cb59-27" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb59-28"><a href="#cb59-28" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
</div>
<p>This approach is arguably simpler than reflecting on parameter names
and requires no extra implementation effort to get there.</p>
<h2 data-number="4.10" id="logging-vector-ii-cloning-with-modifications"><span class="header-section-number">4.10</span> Logging Vector II: Cloning
with Modifications<a href="#logging-vector-ii-cloning-with-modifications" class="self-link"></a></h2>
<p>However, we’ve still got some work to do. The above implementation
already gets us a great deal of functionality, and should create code
that looks something like this:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb60"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb60-1"><a href="#cb60-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb60-2"><a href="#cb60-2" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> LoggingVector <span class="op">{</span></span>
<span id="cb60-3"><a href="#cb60-3" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>vector<span class="op">&lt;</span>T<span class="op">&gt;</span> impl;</span>
<span id="cb60-4"><a href="#cb60-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb60-5"><a href="#cb60-5" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb60-6"><a href="#cb60-6" aria-hidden="true" tabindex="-1"></a>    LoggingVector<span class="op">(</span>std<span class="op">::</span>vector<span class="op">&lt;</span>T<span class="op">&gt;</span> v<span class="op">)</span> <span class="op">:</span> impl<span class="op">(</span>std<span class="op">::</span>move<span class="op">(</span>v<span class="op">))</span> <span class="op">{</span> <span class="op">}</span></span>
<span id="cb60-7"><a href="#cb60-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb60-8"><a href="#cb60-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> clear<span class="op">()</span> <span class="op">-&gt;</span> <span class="dt">void</span> <span class="op">{</span></span>
<span id="cb60-9"><a href="#cb60-9" aria-hidden="true" tabindex="-1"></a>        std<span class="op">::</span>println<span class="op">(</span><span class="st">&quot;Calling {}&quot;</span>, <span class="st">&quot;clear&quot;</span><span class="op">)</span>;</span>
<span id="cb60-10"><a href="#cb60-10" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> impl<span class="op">.</span>clear<span class="op">()</span>;</span>
<span id="cb60-11"><a href="#cb60-11" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb60-12"><a href="#cb60-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb60-13"><a href="#cb60-13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> push_back<span class="op">(</span>T <span class="kw">const</span><span class="op">&amp;</span> value<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">void</span> <span class="op">{</span></span>
<span id="cb60-14"><a href="#cb60-14" aria-hidden="true" tabindex="-1"></a>        std<span class="op">::</span>println<span class="op">(</span><span class="st">&quot;Calling {}&quot;</span>, <span class="st">&quot;push_back&quot;</span><span class="op">)</span>;</span>
<span id="cb60-15"><a href="#cb60-15" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> impl<span class="op">.</span>push_back<span class="op">(</span><span class="kw">static_cast</span><span class="op">&lt;</span>T <span class="kw">const</span><span class="op">&amp;&gt;(</span>value<span class="op">))</span>;</span>
<span id="cb60-16"><a href="#cb60-16" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb60-17"><a href="#cb60-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb60-18"><a href="#cb60-18" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> push_back<span class="op">(</span>T<span class="op">&amp;&amp;</span> value<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">void</span> <span class="op">{</span></span>
<span id="cb60-19"><a href="#cb60-19" aria-hidden="true" tabindex="-1"></a>        std<span class="op">::</span>println<span class="op">(</span><span class="st">&quot;Calling {}&quot;</span>, <span class="st">&quot;push_back&quot;</span><span class="op">)</span>;</span>
<span id="cb60-20"><a href="#cb60-20" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> impl<span class="op">.</span>push_back<span class="op">(</span><span class="kw">static_cast</span><span class="op">&lt;</span>T<span class="op">&amp;&amp;&gt;(</span>value<span class="op">))</span>;</span>
<span id="cb60-21"><a href="#cb60-21" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb60-22"><a href="#cb60-22" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb60-23"><a href="#cb60-23" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="cb60-24"><a href="#cb60-24" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
</div>
<p>For a lot of <code class="sourceCode cpp">std<span class="op">::</span>vector<span class="ch">&#39;</span></code>s
member functions, we’re done. But some need some more work. One of the
functions we’re emitting is member
<code class="sourceCode cpp">swap</code>:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb61"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb61-1"><a href="#cb61-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb61-2"><a href="#cb61-2" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> LoggingVector <span class="op">{</span></span>
<span id="cb61-3"><a href="#cb61-3" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>vector<span class="op">&lt;</span>T<span class="op">&gt;</span> impl;</span>
<span id="cb61-4"><a href="#cb61-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb61-5"><a href="#cb61-5" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb61-6"><a href="#cb61-6" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="cb61-7"><a href="#cb61-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb61-8"><a href="#cb61-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> swap<span class="op">(</span>std<span class="op">::</span>vector<span class="op">&lt;</span>T<span class="op">&gt;&amp;</span> other<span class="op">)</span> <span class="kw">noexcept</span><span class="op">(</span><span class="co">/* ... */</span><span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">void</span> <span class="op">{</span></span>
<span id="cb61-9"><a href="#cb61-9" aria-hidden="true" tabindex="-1"></a>        std<span class="op">::</span>println<span class="op">(</span><span class="st">&quot;Calling {}&quot;</span>, <span class="st">&quot;swap&quot;</span><span class="op">)</span>;</span>
<span id="cb61-10"><a href="#cb61-10" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> impl<span class="op">.</span>swap<span class="op">(</span>other<span class="op">)</span>; <span class="co">// &lt;== omitting the cast here for readability</span></span>
<span id="cb61-11"><a href="#cb61-11" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb61-12"><a href="#cb61-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb61-13"><a href="#cb61-13" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="cb61-14"><a href="#cb61-14" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
</div>
<p>But this… isn’t right. Or rather, it could potentially be right in
some design, but it’s not what we want to do. We don’t want <code class="sourceCode cpp">LoggingVector<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span></code>
to be swappable with <code class="sourceCode cpp">std<span class="op">::</span>vector<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span></code>…
we want it to be swappable with itself. What we actually want to do is
emit this:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb62"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb62-1"><a href="#cb62-1" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> swap<span class="op">(</span>LoggingVector<span class="op">&lt;</span>T<span class="op">&gt;&amp;</span> other<span class="op">)</span> <span class="kw">noexcept</span><span class="op">(</span><span class="co">/* ... */</span><span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">void</span> <span class="op">{</span></span>
<span id="cb62-2"><a href="#cb62-2" aria-hidden="true" tabindex="-1"></a>        std<span class="op">::</span>println<span class="op">(</span><span class="st">&quot;Calling {}&quot;</span>, <span class="st">&quot;swap&quot;</span><span class="op">)</span>;</span>
<span id="cb62-3"><a href="#cb62-3" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> impl<span class="op">.</span>swap<span class="op">(</span>other<span class="op">.</span>impl<span class="op">)</span>;</span>
<span id="cb62-4"><a href="#cb62-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>Two changes here: the parameter needs to change from <code class="sourceCode cpp">std<span class="op">::</span>vector<span class="op">&lt;</span>T<span class="op">&gt;&amp;</span></code>
to <code class="sourceCode cpp">LoggingVector<span class="op">&lt;</span>T<span class="op">&gt;&amp;</span></code>,
and then in the call-forwarding we need to forward not
<code class="sourceCode cpp">other</code> (which is now the wrong type)
but rather
<code class="sourceCode cpp">other<span class="op">.</span>impl</code>.
How can we do that? We don’t quite have a good answer yet. But this is
much farther than we’ve come with any other design.</p>
<h1 data-number="5" style="border-bottom:1px solid #cccccc" id="scoped-macros"><span class="header-section-number">5</span> Scoped
Macros<a href="#scoped-macros" class="self-link"></a></h1>
<p>C macros have a (well-deserved) bad reputation in the C++ community.
This is because they have some intractable problems:</p>
<ul>
<li>C macros don’t follow any scoping rules, and can change any code,
anywhere. This is why they do not leak into or out of C++ modules.</li>
<li>The C preprocessor is a language unto itself, that doesn’t
understand C++ syntax, with limited functionality that is very tedious
to program in. Even what we would consider to be very basic language
constructs like
<code class="sourceCode cpp"><span class="cf">if</span></code> or
<code class="sourceCode cpp"><span class="cf">for</span></code> are
expert-level features in the preprocessor, and even then are highly
limited.</li>
</ul>
<p>We think that C++ does need a code manipulation mechanism, and that
token sequences can provide a much better solution than C macros.</p>
<h2 data-number="5.1" id="design-approach"><span class="header-section-number">5.1</span> Design Approach<a href="#design-approach" class="self-link"></a></h2>
<p>One way to think about a macro is that it is a function that takes
<em>code</em> and produces <em>code</em>, without necessarily evaluating
or even parsing the code (indeed the code that is input to the macro
need not even be valid C++ at all).</p>
<p>With token sequences, we suddenly gain a way to represent macros in
C++ proper: a macro is a function that takes a token sequence and
returns a token sequence, whereby it can be automatically injected (with
some syntax marker at the call site).</p>
<p>This is already implicitly the way that macros operate in LISPs like
Scheme and Racket, and is explicitly how they work in Rust and Swift. In
Rust, <a href="https://doc.rust-lang.org/reference/procedural-macros.html">procedural
macros</a> have the form:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb1"><pre class="sourceCode rust"><code class="sourceCode rust"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="at">#[</span>proc_macro<span class="at">]</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="kw">pub</span> <span class="kw">fn</span> macro(input<span class="op">:</span> TokenStream) <span class="op">-&gt;</span> TokenStream <span class="op">{</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">...</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>Whereas in Swift, <a href="https://docs.swift.org/swift-book/documentation/the-swift-programming-language/macros/">macros</a>
have the form (<a href="https://github.com/swiftlang/swift-evolution/blob/main/proposals/0382-expression-macros.md">proposal</a>):</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb2"><pre class="sourceCode swift"><code class="sourceCode swift"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">struct</span> FourCharacterCode<span class="op">:</span> <span class="dt">ExpressionMacro</span> <span class="op">{</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">static</span> <span class="kw">func</span> <span class="fu">expansion</span><span class="op">(</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>        <span class="va">of</span> <span class="va">node</span><span class="op">:</span> <span class="dt">some</span> <span class="va">FreestandingMacroExpansionSyntax</span><span class="op">,</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>        <span class="va">in</span> <span class="va">context</span><span class="op">:</span> <span class="dt">some</span> <span class="va">MacroExpansionContext</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">)</span> <span class="kw">throws</span> -&gt; <span class="fu">ExprSyntax</span> <span class="op">{</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>        <span class="op">...</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>Either way, unevaluated raw code in, unevaluated raw code out.</p>
<p>Now that we have the ability to represent code in code (using token
sequences) and can inject said code that is produced by regular C++
functions, we can do in the same in C++ as well.</p>
<h2 data-number="5.2" id="forwarding"><span class="header-section-number">5.2</span> Forwarding<a href="#forwarding" class="self-link"></a></h2>
<p>Consider the problem of forwarding. Forwarding an argument in C++, in
the vast majority of uses, looks like <code class="sourceCode cpp">std<span class="op">::</span>forward<span class="op">&lt;</span>T<span class="op">&gt;(</span>t<span class="op">)</span></code>,
where <code class="sourceCode cpp">T</code> is actually the type <code class="sourceCode cpp"><span class="kw">decltype</span><span class="op">(</span>t<span class="op">)</span></code>.
This is annoying to write, the operation is simply forwarding an
argument but we have to duplicate that argument nonetheless. And it
requires the instantiation of a template (although compilers are moving
towards making that a builtin).</p>
<p>Barry at some point proposed a specific language feature for this
use-case (<span class="citation" data-cites="P0644R1">[<a href="https://wg21.link/p0644r1" role="doc-biblioref">P0644R1</a>]</span>). Later, there was a proposal
for a hygienic macro system <span class="citation" data-cites="P1221R1">[<a href="https://wg21.link/p1221r1" role="doc-biblioref">P1221R1</a>]</span> in which forwarding would be
implemented like this:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb63"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb63-1"><a href="#cb63-1" aria-hidden="true" tabindex="-1"></a><span class="kw">using</span> fwd<span class="op">(</span><span class="kw">using</span> <span class="kw">auto</span> x<span class="op">)</span> <span class="op">{</span></span>
<span id="cb63-2"><a href="#cb63-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="kw">static_cast</span><span class="op">&lt;</span><span class="kw">decltype</span><span class="op">(</span>x<span class="op">)&amp;&amp;&gt;(</span>x<span class="op">)</span>;</span>
<span id="cb63-3"><a href="#cb63-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb63-4"><a href="#cb63-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb63-5"><a href="#cb63-5" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> old_f <span class="op">=</span> <span class="op">[](</span><span class="kw">auto</span><span class="op">&amp;&amp;</span> x<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> std<span class="op">::</span>forward<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">(</span>x<span class="op">)&gt;(</span>x<span class="op">)</span>; <span class="op">}</span>;</span>
<span id="cb63-6"><a href="#cb63-6" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> new_f <span class="op">=</span> <span class="op">[](</span><span class="kw">auto</span><span class="op">&amp;&amp;</span> x<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> fwd<span class="op">(</span>x<span class="op">)</span>; <span class="op">}</span>;</span></code></pre></div>
</blockquote>
</div>
<p>With token sequences, using the design described earlier that we
accept code in and return code out, we can achieve similar syntax:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb64"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb64-1"><a href="#cb64-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> fwd2<span class="op">(</span>meta<span class="op">::</span>info x<span class="op">)</span> <span class="op">-&gt;</span> meta<span class="op">::</span>info <span class="op">{</span></span>
<span id="cb64-2"><a href="#cb64-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="op">^{</span></span>
<span id="cb64-3"><a href="#cb64-3" aria-hidden="true" tabindex="-1"></a>        <span class="kw">static_cast</span><span class="op">&lt;</span><span class="kw">decltype</span><span class="op">([:</span>\tokens<span class="op">(</span>x<span class="op">):])&amp;&amp;&gt;([:</span>\tokens<span class="op">(</span>x<span class="op">):])</span>;</span>
<span id="cb64-4"><a href="#cb64-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span>;</span>
<span id="cb64-5"><a href="#cb64-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb64-6"><a href="#cb64-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb64-7"><a href="#cb64-7" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> new_f2 <span class="op">=</span> <span class="op">[](</span><span class="kw">auto</span><span class="op">&amp;&amp;</span> x<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> fwd2<span class="op">!(</span>x<span class="op">)</span>; <span class="op">}</span>;</span></code></pre></div>
</blockquote>
</div>
<p>The logic here is that <code class="sourceCode cpp">fwd2<span class="op">!(</span>x<span class="op">)</span></code>
is syntactic sugar for <code class="sourceCode cpp">immediately_inject<span class="op">(</span>fwd2<span class="op">(^{</span> x <span class="op">}))</span></code>
(which requires a new mechanism for injecting into an expression). We’re
taking a page out of Rust’s book and suggesting that invoking a “macro”
with an exclamation point does the injection. Seems nice to both have
convenient syntax for token manipulation and a syntactic marker for it
on the call-site.</p>
<p>The first revision of this paper used the placeholder syntax
<code class="sourceCode cpp"><span class="op">@</span>tokens x</code> to
declare the parameter of <code class="sourceCode cpp">fwd2</code>, but
it turns out that this is just a token sequence - so it can just have
type <code class="sourceCode cpp">std<span class="op">::</span>meta<span class="op">::</span>info</code>.
The call-site syntax of
<code class="sourceCode cpp">fwd2<span class="op">!</span></code> should
be all you need to request tokenization.</p>
<p>Of course, <code class="sourceCode cpp">fwd2</code> is a regular C++
function. You have to invoke it through the usual C++ scoping rules, so
it does not suffer that problem from C macros. And then the body is a
regular C++ function too, so writing complex token manipulation is just
a matter of writing complex C++ code - which is a lot easier than
writing complex C preprocessor code.</p>
<p>Note that the invocation of a macro like <code class="sourceCode cpp">macro<span class="op">!(</span>std<span class="op">::</span>pair<span class="op">&lt;</span><span class="dt">int</span>, <span class="dt">int</span><span class="op">&gt;{</span><span class="dv">1</span>, <span class="dv">2</span><span class="op">})</span></code>
would just work fine - the argument passed to
<code class="sourceCode cpp">macro</code> would be <code class="sourceCode cpp"><span class="op">^{</span> std<span class="op">::</span>pair<span class="op">&lt;</span><span class="dt">int</span>, <span class="dt">int</span><span class="op">&gt;{</span><span class="dv">1</span>, <span class="dv">2</span><span class="op">}</span> <span class="op">}</span></code>.
But that leads us to the question of parsing…</p>
<h2 data-number="5.3" id="assertion"><span class="header-section-number">5.3</span> Assertion<a href="#assertion" class="self-link"></a></h2>
<p>Consider a different example (borrowed from <a href="https://www.forrestthewoods.com/blog/learning-jai-via-advent-of-code/">here</a>):</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb65"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb65-1"><a href="#cb65-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> assert_eq<span class="op">(</span>meta<span class="op">::</span>info a, meta<span class="op">::</span>info b<span class="op">)</span> <span class="op">-&gt;</span> meta<span class="op">::</span>info <span class="op">{</span></span>
<span id="cb65-2"><a href="#cb65-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="op">^{</span></span>
<span id="cb65-3"><a href="#cb65-3" aria-hidden="true" tabindex="-1"></a>        <span class="cf">do</span> <span class="op">{</span></span>
<span id="cb65-4"><a href="#cb65-4" aria-hidden="true" tabindex="-1"></a>            <span class="kw">auto</span> sa <span class="op">=</span> \<span class="op">(</span>stringify<span class="op">(</span>a<span class="op">))</span>;</span>
<span id="cb65-5"><a href="#cb65-5" aria-hidden="true" tabindex="-1"></a>            <span class="kw">auto</span> va <span class="op">=</span> \tokens<span class="op">(</span>a<span class="op">)</span>;</span>
<span id="cb65-6"><a href="#cb65-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb65-7"><a href="#cb65-7" aria-hidden="true" tabindex="-1"></a>            <span class="kw">auto</span> sb <span class="op">=</span> \<span class="op">(</span>stringify<span class="op">(</span>b<span class="op">))</span>;</span>
<span id="cb65-8"><a href="#cb65-8" aria-hidden="true" tabindex="-1"></a>            <span class="kw">auto</span> vb <span class="op">=</span> \tokens<span class="op">(</span>b<span class="op">)</span>;</span>
<span id="cb65-9"><a href="#cb65-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb65-10"><a href="#cb65-10" aria-hidden="true" tabindex="-1"></a>            <span class="cf">if</span> <span class="op">(</span><span class="kw">not</span> <span class="op">(</span>va <span class="op">==</span> vb<span class="op">))</span> <span class="op">{</span></span>
<span id="cb65-11"><a href="#cb65-11" aria-hidden="true" tabindex="-1"></a>                std<span class="op">::</span>println<span class="op">(</span></span>
<span id="cb65-12"><a href="#cb65-12" aria-hidden="true" tabindex="-1"></a>                    stderr,</span>
<span id="cb65-13"><a href="#cb65-13" aria-hidden="true" tabindex="-1"></a>                    <span class="st">&quot;{} ({}) == {} ({}) failed at {}&quot;</span>,</span>
<span id="cb65-14"><a href="#cb65-14" aria-hidden="true" tabindex="-1"></a>                    sa, va,</span>
<span id="cb65-15"><a href="#cb65-15" aria-hidden="true" tabindex="-1"></a>                    sb, vb,</span>
<span id="cb65-16"><a href="#cb65-16" aria-hidden="true" tabindex="-1"></a>                    \<span class="op">(</span>source_location_of<span class="op">(</span>a<span class="op">)))</span>;</span>
<span id="cb65-17"><a href="#cb65-17" aria-hidden="true" tabindex="-1"></a>                std<span class="op">::</span>abort<span class="op">()</span>;</span>
<span id="cb65-18"><a href="#cb65-18" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="cb65-19"><a href="#cb65-19" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span> <span class="cf">while</span> <span class="op">(</span><span class="kw">false</span><span class="op">)</span>;</span>
<span id="cb65-20"><a href="#cb65-20" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span>;</span>
<span id="cb65-21"><a href="#cb65-21" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>With the expectation that:</p>
<table>
<thead>
<tr class="header">
<th><div style="text-align:center">
<strong>Written Code</strong>
</div></th>
<th><div style="text-align:center">
<strong>Injected Code</strong>
</div></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><div>

<div class="sourceCode" id="cb66"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb66-1"><a href="#cb66-1" aria-hidden="true" tabindex="-1"></a>assert_eq<span class="op">!(</span><span class="dv">42</span>, factorial<span class="op">(</span><span class="dv">3</span><span class="op">))</span>;</span></code></pre></div>

</div></td>
<td><div>

<div class="sourceCode" id="cb67"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb67-1"><a href="#cb67-1" aria-hidden="true" tabindex="-1"></a><span class="cf">do</span> <span class="op">{</span></span>
<span id="cb67-2"><a href="#cb67-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> sa <span class="op">=</span> <span class="st">&quot;42&quot;</span>;</span>
<span id="cb67-3"><a href="#cb67-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> va <span class="op">=</span> <span class="dv">42</span>;</span>
<span id="cb67-4"><a href="#cb67-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb67-5"><a href="#cb67-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> sb <span class="op">=</span> <span class="st">&quot;factorial(3)&quot;</span>;</span>
<span id="cb67-6"><a href="#cb67-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> vb <span class="op">=</span> factorial<span class="op">(</span><span class="dv">3</span><span class="op">)</span>;</span>
<span id="cb67-7"><a href="#cb67-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb67-8"><a href="#cb67-8" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="op">(</span><span class="kw">not</span> <span class="op">(</span>va <span class="op">==</span> vb<span class="op">))</span> <span class="op">{</span></span>
<span id="cb67-9"><a href="#cb67-9" aria-hidden="true" tabindex="-1"></a>        std<span class="op">::</span>println<span class="op">(</span></span>
<span id="cb67-10"><a href="#cb67-10" aria-hidden="true" tabindex="-1"></a>            stderr,</span>
<span id="cb67-11"><a href="#cb67-11" aria-hidden="true" tabindex="-1"></a>            <span class="st">&quot;{} ({}) == {} ({}) failed at {}&quot;</span>,</span>
<span id="cb67-12"><a href="#cb67-12" aria-hidden="true" tabindex="-1"></a>            sa, va,</span>
<span id="cb67-13"><a href="#cb67-13" aria-hidden="true" tabindex="-1"></a>            sb, vb,</span>
<span id="cb67-14"><a href="#cb67-14" aria-hidden="true" tabindex="-1"></a>            <span class="co">/* some source location */</span><span class="op">)</span>;</span>
<span id="cb67-15"><a href="#cb67-15" aria-hidden="true" tabindex="-1"></a>        std<span class="op">::</span>abort<span class="op">()</span>;</span>
<span id="cb67-16"><a href="#cb67-16" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb67-17"><a href="#cb67-17" aria-hidden="true" tabindex="-1"></a><span class="op">}</span> <span class="cf">while</span><span class="op">(</span><span class="kw">false</span><span class="op">)</span>;</span></code></pre></div>

</div></td>
</tr>
</tbody>
</table>
<p>You can write this as a regular C macro today, but we bet it’s a
little nicer to read using this language facility.</p>
<p>However, this macro brings up two problems that we have to talk
about: parsing and hygiene.</p>
<h2 data-number="5.4" id="macro-parsing"><span class="header-section-number">5.4</span> Macro Parsing<a href="#macro-parsing" class="self-link"></a></h2>
<p>The signature of the <a href="#assertion"><code class="sourceCode cpp">assert_eq<span class="op">!</span></code></a>
macro we have above was:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb68"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb68-1"><a href="#cb68-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> assert_eq<span class="op">(</span>meta<span class="op">::</span>info a, meta<span class="op">::</span>info b<span class="op">)</span> <span class="op">-&gt;</span> meta<span class="op">::</span>info;</span></code></pre></div>
</blockquote>
</div>
<p>Earlier we described the design as taking <em>a single</em> token
sequence and producing a token sequence output. We’d of course want to
express <code class="sourceCode cpp">assert_eq</code> as a function
taking two token sequences, but how does the compiler know when to end
one token seequence and start the next? That requires parsing. If the
user writes <code class="sourceCode cpp">assert_eq<span class="op">!(</span>std<span class="op">::</span>pair<span class="op">&lt;</span><span class="dt">int</span>, <span class="dt">int</span><span class="op">&gt;{</span><span class="dv">1</span>, <span class="dv">2</span><span class="op">}</span>, x<span class="op">)</span></code>,
the compiler needs to figure out which comma in there is actually an
argument delimiter (or how to fail if there is only one argument).</p>
<p>There are a couple ways that we could approach this.</p>
<p>We could always require that a macro takes a single token-sequence
argument and provide a parser library to help pull out the pieces. For
instance, <a href="https://docs.rs/syn/latest/syn/parse/index.html">in
Rust</a>, you would write something like this:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb3"><pre class="sourceCode rust"><code class="sourceCode rust"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="co">// Parse a possibly empty sequence of expressions terminated by commas with</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="co">// an optional trailing punctuation.</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> parser <span class="op">=</span> <span class="pp">Punctuated::</span><span class="op">&lt;</span>Expr<span class="op">,</span> <span class="pp">Token!</span>[<span class="op">,</span>]<span class="op">&gt;</span><span class="pp">::</span>parse_terminated<span class="op">;</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> _args <span class="op">=</span> parser<span class="op">.</span>parse(tokens)<span class="op">?;</span></span></code></pre></div>
</blockquote>
</div>
<p>And then for
<code class="sourceCode cpp">assert_eq<span class="op">!</span></code>,
verify that there are two such expressions and then do the rest of the
work.</p>
<p>Alternatively, we could push this more into the signature of the
macro - choosing how to tokenize the input based on the parameter type
list:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb69"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb69-1"><a href="#cb69-1" aria-hidden="true" tabindex="-1"></a><span class="co">// this parses f!(1+2, f(3, 4))</span></span>
<span id="cb69-2"><a href="#cb69-2" aria-hidden="true" tabindex="-1"></a><span class="co">// into f(^{1+2}, ^{f(3, 4)})</span></span>
<span id="cb69-3"><a href="#cb69-3" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> f<span class="op">(</span>meta<span class="op">::</span>token<span class="op">::</span>expr lhs, meta<span class="op">::</span>token<span class="op">::</span>expr rhs<span class="op">)</span> <span class="op">-&gt;</span> meta<span class="op">::</span>info;</span>
<span id="cb69-4"><a href="#cb69-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb69-5"><a href="#cb69-5" aria-hidden="true" tabindex="-1"></a><span class="co">// this parses g!(1+2, f(3, 4))</span></span>
<span id="cb69-6"><a href="#cb69-6" aria-hidden="true" tabindex="-1"></a><span class="co">// into g(^{ 1+2, f(3, 4) })</span></span>
<span id="cb69-7"><a href="#cb69-7" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> g<span class="op">(</span>meta<span class="op">::</span>info xs<span class="op">)</span> <span class="op">-&gt;</span> meta<span class="op">::</span>info;</span>
<span id="cb69-8"><a href="#cb69-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb69-9"><a href="#cb69-9" aria-hidden="true" tabindex="-1"></a><span class="co">// this parses h!(1+2, f(3, 4))</span></span>
<span id="cb69-10"><a href="#cb69-10" aria-hidden="true" tabindex="-1"></a><span class="co">// into h!({ ^{1+2}, ^{f(3, 4)}})</span></span>
<span id="cb69-11"><a href="#cb69-11" aria-hidden="true" tabindex="-1"></a><span class="co">// so that xs.size() == 2</span></span>
<span id="cb69-12"><a href="#cb69-12" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> h<span class="op">(</span>meta<span class="op">::</span>token<span class="op">::</span>expr_list xs<span class="op">)</span> <span class="op">-&gt;</span> meta<span class="op">::</span>info</span></code></pre></div>
</blockquote>
</div>
<p>The last example here with <code class="sourceCode cpp">h</code> is
roughly the same idea as the parser example - except changing who does
what work, where.</p>
<h2 data-number="5.5" id="hygienic-macros"><span class="header-section-number">5.5</span> Hygienic Macros<a href="#hygienic-macros" class="self-link"></a></h2>
<p>Regardless of how we parse the two expressions that are input into
our macro, this still suffers from at least one C macro problem: naming.
If instead of <code class="sourceCode cpp">assert_eq<span class="op">!(</span><span class="dv">42</span>, factorial<span class="op">(</span><span class="dv">3</span><span class="op">))</span></code>
we wrote <code class="sourceCode cpp">assert_eq<span class="op">!(</span><span class="dv">42</span>, sa <span class="op">*</span> <span class="dv">2</span><span class="op">)</span></code>,
then this would not compile - because name lookup in the
<code class="sourceCode cpp"><span class="cf">do</span></code>-<code class="sourceCode cpp"><span class="cf">while</span></code>
loop would end up finding the local variable
<code class="sourceCode cpp">sa</code> declared by the macro.</p>
<p>There are broadly two approaches to solve this problem:</p>
<p>Macros are hygienic by default: names introduced in macros are (at
least by default) distinct from names that are injected into those
macros. This is the case in Racket and Scheme, as well as declarative
Macros in Rust. For instance, in Rust, this code:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb4"><pre class="sourceCode rust"><code class="sourceCode rust"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="pp">macro_rules!</span> using_a <span class="op">{</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>    (<span class="op">$</span>e<span class="op">:</span>expr) <span class="op">=&gt;</span> <span class="op">{</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>        <span class="op">{</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>            <span class="kw">let</span> a <span class="op">=</span> <span class="dv">42</span><span class="op">;</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>            <span class="op">$</span>e</span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> four <span class="op">=</span> <span class="pp">using_a!</span>(a <span class="op">/</span> <span class="dv">10</span>)<span class="op">;</span></span></code></pre></div>
</blockquote>
</div>
<p>emits</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb70"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb70-1"><a href="#cb70-1" aria-hidden="true" tabindex="-1"></a>let four <span class="op">=</span> <span class="op">{</span></span>
<span id="cb70-2"><a href="#cb70-2" aria-hidden="true" tabindex="-1"></a>    let <span class="orange">a</span> <span class="op">=</span> <span class="dv">42</span>;</span>
<span id="cb70-3"><a href="#cb70-3" aria-hidden="true" tabindex="-1"></a>    a <span class="op">/</span> <span class="dv">10</span></span>
<span id="cb70-4"><a href="#cb70-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>Note that the two <code class="sourceCode cpp">a</code>s are spelled
the same, but one is orange. That coloring is how hygienic macros work -
names get an extra kind of scope depending on where they are used. So
here the <code class="sourceCode cpp">a</code> in the
<code class="sourceCode cpp">using_a</code> macro is in a different
<em>span</em> than the <code class="sourceCode cpp">a</code> in the
<code class="sourceCode cpp">a <span class="op">/</span> <span class="dv">10</span></code>
tokens that were passed into the macro, so they are considered different
names.</p>
<p>Sometimes an unhygienic macro is useful though, to deliberately
create an <em>anaphoric macro</em>. The canonical example is wanting to
write an anaphoric if which takes an expression and, if it’s truthy,
passes that expression as the name
<code class="sourceCode cpp">it</code> to the
<code class="sourceCode cpp">then</code> callable:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb5"><pre class="sourceCode scheme"><code class="sourceCode scheme"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>(aif <span class="dv">#t</span> (displayln it) (void))</span></code></pre></div>
</blockquote>
</div>
<p>Scheme/Racket have
<code class="sourceCode cpp">syntax<span class="op">-</span>rules</code>
to be able to provide such an unhygienic parameter.</p>
<p>A more familiar example of an anaphoric macro in C++ would be the
ability to declare a unary lambda whose parameter is named
<code class="sourceCode cpp">it</code> in a very abbreviated form, as
in:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb71"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb71-1"><a href="#cb71-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> positive <span class="op">=</span> std<span class="op">::</span>ranges<span class="op">::</span>count_if<span class="op">(</span>r, λ<span class="op">!(</span>it <span class="op">&gt;</span> <span class="dv">0</span><span class="op">))</span>;</span></code></pre></div>
</blockquote>
</div>
<p>which we can declare as:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb72"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb72-1"><a href="#cb72-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> λ<span class="op">(</span>meta<span class="op">::</span>info body<span class="op">)</span> <span class="op">-&gt;</span> meta<span class="op">::</span>info <span class="op">{</span></span>
<span id="cb72-2"><a href="#cb72-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="op">^{</span></span>
<span id="cb72-3"><a href="#cb72-3" aria-hidden="true" tabindex="-1"></a>        <span class="op">[&amp;](</span><span class="kw">auto</span><span class="op">&amp;&amp;</span> it<span class="op">)</span></span>
<span id="cb72-4"><a href="#cb72-4" aria-hidden="true" tabindex="-1"></a>            <span class="kw">noexcept</span><span class="op">(</span><span class="kw">noexcept</span><span class="op">(</span>\tokens<span class="op">(</span>body<span class="op">)))</span></span>
<span id="cb72-5"><a href="#cb72-5" aria-hidden="true" tabindex="-1"></a>            <span class="op">-&gt;</span> <span class="kw">decltype</span><span class="op">(</span>\tokens<span class="op">(</span>body<span class="op">))</span></span>
<span id="cb72-6"><a href="#cb72-6" aria-hidden="true" tabindex="-1"></a>        <span class="op">{</span></span>
<span id="cb72-7"><a href="#cb72-7" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> \tokens<span class="op">(</span>body<span class="op">)</span>;</span>
<span id="cb72-8"><a href="#cb72-8" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb72-9"><a href="#cb72-9" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb72-10"><a href="#cb72-10" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>Such a macro would not work in a hygienic system, because the
<code class="sourceCode cpp">it</code> in the expression <code class="sourceCode cpp">it <span class="op">&gt;</span> <span class="dv">0</span></code>
would not find the parameter declared
<code class="sourceCode cpp">it</code> as they live in different
spans.</p>
<p>Alternatively, macros are <em>not</em> hygienic by default. This is
the case for Rust procedural macros, Swift’s macros, and to a very
extreme degree, C. In order to make unhygienic macros usable, you need
<em>some</em> mechanism of coming up with unique names if the language
won’t do it for you. The LISP approach to this is a function named
<code class="sourceCode cpp">gensym</code> which generates a unique
symbol name. This takes more effort on the macro writer (who has to
remember to use <code class="sourceCode cpp">gensym</code>) when they
want hygienic variables - which is likely the overwhelmingly common
case, unlike the anaphoric case in a hygienic system where the macro
writer needs to opt out of hygiene.</p>
<p>With hygienic macros, the assertion example is already correct. With
unhygienic macros, we’d need to do something like this:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb73"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb73-1"><a href="#cb73-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> assert_eq<span class="op">(</span>meta<span class="op">::</span>info a, meta<span class="op">::</span>info b<span class="op">)</span> <span class="op">-&gt;</span> meta<span class="op">::</span>info <span class="op">{</span></span>
<span id="cb73-2"><a href="#cb73-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> <span class="op">[</span>sa, va, sb, vb<span class="op">]</span> <span class="op">=</span> std<span class="op">::</span>meta<span class="op">::</span>make_unique_names<span class="op">&lt;</span><span class="dv">4</span><span class="op">&gt;()</span>;</span>
<span id="cb73-3"><a href="#cb73-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb73-4"><a href="#cb73-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="op">^{</span></span>
<span id="cb73-5"><a href="#cb73-5" aria-hidden="true" tabindex="-1"></a>        <span class="cf">do</span> <span class="op">{</span></span>
<span id="cb73-6"><a href="#cb73-6" aria-hidden="true" tabindex="-1"></a>            <span class="kw">auto</span> \id<span class="op">(</span>sa<span class="op">)</span> <span class="op">=</span> \<span class="op">(</span>stringify<span class="op">(</span>a<span class="op">))</span>;</span>
<span id="cb73-7"><a href="#cb73-7" aria-hidden="true" tabindex="-1"></a>            <span class="kw">auto</span> \id<span class="op">(</span>va<span class="op">)</span> <span class="op">=</span> \tokens<span class="op">(</span>a<span class="op">)</span>;</span>
<span id="cb73-8"><a href="#cb73-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb73-9"><a href="#cb73-9" aria-hidden="true" tabindex="-1"></a>            <span class="kw">auto</span> \id<span class="op">(</span>sb<span class="op">)</span> <span class="op">=</span> \<span class="op">(</span>stringify<span class="op">(</span>b<span class="op">))</span>;</span>
<span id="cb73-10"><a href="#cb73-10" aria-hidden="true" tabindex="-1"></a>            <span class="kw">auto</span> \id<span class="op">(</span>vb<span class="op">)</span> <span class="op">=</span> \tokens<span class="op">(</span>b<span class="op">)</span>;</span>
<span id="cb73-11"><a href="#cb73-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb73-12"><a href="#cb73-12" aria-hidden="true" tabindex="-1"></a>            <span class="cf">if</span> <span class="op">(</span><span class="kw">not</span> <span class="op">(</span>\id<span class="op">(</span>va<span class="op">)</span> <span class="op">==</span> \id<span class="op">(</span>vb<span class="op">)))</span> <span class="op">{</span></span>
<span id="cb73-13"><a href="#cb73-13" aria-hidden="true" tabindex="-1"></a>                std<span class="op">::</span>println<span class="op">(</span></span>
<span id="cb73-14"><a href="#cb73-14" aria-hidden="true" tabindex="-1"></a>                    stderr,</span>
<span id="cb73-15"><a href="#cb73-15" aria-hidden="true" tabindex="-1"></a>                    <span class="st">&quot;{} ({}) == {} ({}) failed at {}&quot;</span>,</span>
<span id="cb73-16"><a href="#cb73-16" aria-hidden="true" tabindex="-1"></a>                    \id<span class="op">(</span>sa<span class="op">)</span>, \id<span class="op">(</span>va<span class="op">)</span>,</span>
<span id="cb73-17"><a href="#cb73-17" aria-hidden="true" tabindex="-1"></a>                    \id<span class="op">(</span>sb<span class="op">)</span>, \id<span class="op">(</span>vb<span class="op">)</span>,</span>
<span id="cb73-18"><a href="#cb73-18" aria-hidden="true" tabindex="-1"></a>                    \<span class="op">(</span>source_location_of<span class="op">(</span>a<span class="op">)))</span>;</span>
<span id="cb73-19"><a href="#cb73-19" aria-hidden="true" tabindex="-1"></a>                std<span class="op">::</span>abort<span class="op">()</span>;</span>
<span id="cb73-20"><a href="#cb73-20" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="cb73-21"><a href="#cb73-21" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span> <span class="cf">while</span> <span class="op">(</span><span class="kw">false</span><span class="op">)</span>;</span>
<span id="cb73-22"><a href="#cb73-22" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span>;</span>
<span id="cb73-23"><a href="#cb73-23" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>That is, all the uses of local variables like
<code class="sourceCode cpp">va</code> instead turn into <code class="sourceCode cpp">\id<span class="op">(</span>va<span class="op">)</span></code>.
It’s not a huge amount of work, but it does get you into the same level
of ugliness that we’re used to seeing in standard library
implementations with all uses of
<code class="sourceCode cpp">__name</code> instead of
<code class="sourceCode cpp">name</code> to avoid collisions. Although
this particular example might oversell the issue, since
<code class="sourceCode cpp">sa</code> and
<code class="sourceCode cpp">sb</code> don’t really need to be local
variables - we could have just directly formatted <code class="sourceCode cpp">\<span class="op">(</span>stringify<span class="op">(</span>a<span class="op">))</span></code>
and <code class="sourceCode cpp">\<span class="op">(</span>stringify<span class="op">(</span>b<span class="op">))</span></code>,
respectively.</p>
<p>Obviously, an unhygienic system is much easier to implement and
specify - since hygiene would add complexity (and likely some overhead)
to how name lookup works.</p>
<h2 data-number="5.6" id="string-interpolation"><span class="header-section-number">5.6</span> String Interpolation<a href="#string-interpolation" class="self-link"></a></h2>
<p>Many programming languages support string interpolation. The ability
to write something like <code class="sourceCode cpp">format<span class="op">!(</span><span class="st">&quot;x={x}&quot;</span><span class="op">)</span></code>
instead of <code class="sourceCode cpp">format<span class="op">(</span><span class="st">&quot;x={}&quot;</span>, x<span class="op">)</span></code>.
It’s a pretty significant feature when it comes to the ergonomics of
formatting.</p>
<p>We can write it as a library:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb74"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb74-1"><a href="#cb74-1" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb74-2"><a href="#cb74-2" aria-hidden="true" tabindex="-1"></a><span class="co">// the actual parsing isn&#39;t interesting here.</span></span>
<span id="cb74-3"><a href="#cb74-3" aria-hidden="true" tabindex="-1"></a><span class="co">// the goal is to take a string like &quot;x={this-&gt;x:02} y={this-&gt;y:02}&quot;</span></span>
<span id="cb74-4"><a href="#cb74-4" aria-hidden="true" tabindex="-1"></a><span class="co">// and return {.format_str=&quot;x={:02} y={:02}&quot;, .args={&quot;this-&gt;x&quot;, &quot;this-&gt;y&quot;}}</span></span>
<span id="cb74-5"><a href="#cb74-5" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> FormatParts <span class="op">{</span></span>
<span id="cb74-6"><a href="#cb74-6" aria-hidden="true" tabindex="-1"></a>    string_view format_str;</span>
<span id="cb74-7"><a href="#cb74-7" aria-hidden="true" tabindex="-1"></a>    vector<span class="op">&lt;</span>string_view<span class="op">&gt;</span> args;</span>
<span id="cb74-8"><a href="#cb74-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb74-9"><a href="#cb74-9" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> parse_format_string<span class="op">(</span>string_view<span class="op">)</span> <span class="op">-&gt;</span> FormatParts;</span>
<span id="cb74-10"><a href="#cb74-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb74-11"><a href="#cb74-11" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> format<span class="op">(</span>string_view str<span class="op">)</span> <span class="op">-&gt;</span> meta<span class="op">::</span>info <span class="op">{</span></span>
<span id="cb74-12"><a href="#cb74-12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> parts <span class="op">=</span> parse_format_string<span class="op">(</span>str<span class="op">)</span>;</span>
<span id="cb74-13"><a href="#cb74-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb74-14"><a href="#cb74-14" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> tok <span class="op">=</span> <span class="op">^{</span></span>
<span id="cb74-15"><a href="#cb74-15" aria-hidden="true" tabindex="-1"></a>        <span class="co">// NB: there&#39;s no close paren yet</span></span>
<span id="cb74-16"><a href="#cb74-16" aria-hidden="true" tabindex="-1"></a>        <span class="co">// we&#39;re allowed to build up a partial fragment like this</span></span>
<span id="cb74-17"><a href="#cb74-17" aria-hidden="true" tabindex="-1"></a>        <span class="op">::</span>std<span class="op">::</span>format<span class="op">(</span>\<span class="op">(</span>parts<span class="op">.</span>format_str<span class="op">)</span></span>
<span id="cb74-18"><a href="#cb74-18" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span>;</span>
<span id="cb74-19"><a href="#cb74-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb74-20"><a href="#cb74-20" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> <span class="op">(</span>string_view arg <span class="op">:</span> parts<span class="op">.</span>args<span class="op">)</span> <span class="op">{</span></span>
<span id="cb74-21"><a href="#cb74-21" aria-hidden="true" tabindex="-1"></a>        tok <span class="op">=</span> <span class="op">^{</span> \tokens<span class="op">(</span>tok<span class="op">)</span>, \tokens<span class="op">(</span>tokenize<span class="op">(</span>arg<span class="op">))</span> <span class="op">}</span>;</span>
<span id="cb74-22"><a href="#cb74-22" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb74-23"><a href="#cb74-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb74-24"><a href="#cb74-24" aria-hidden="true" tabindex="-1"></a>    <span class="co">// now finally here&#39;s our close paren</span></span>
<span id="cb74-25"><a href="#cb74-25" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="op">^{</span> \tokens<span class="op">(</span>tok<span class="op">)</span> <span class="op">)</span> <span class="op">}</span>;</span>
<span id="cb74-26"><a href="#cb74-26" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>In the previous example, we demonstrated the need for a way to
convert a token sequence to a string. In this example, we need a way to
convert a string to a token sequence. This doesn’t involve parsing or
any semantic analysis. It’s <em>just</em> lexing.</p>
<p>Of course, this approach has limitations. We cannot fully faithfully
parse the format string because at this layer we don’t have types - we
can’t stop and look up what type <code class="sourceCode cpp"><span class="kw">this</span><span class="op">-&gt;</span>x</code>
was, instantiate the appropriate <code class="sourceCode cpp">std<span class="op">::</span>formatter<span class="op">&lt;</span>X<span class="op">&gt;</span></code>
and use it tell us where the end of its formatter is. We can just count
balanced <code class="sourceCode cpp"><span class="op">{}</span></code>s
and hope for the best.</p>
<p>Similarly, something like <code class="sourceCode cpp">format<span class="op">!(</span><span class="st">&quot;{SOME_MACRO(x)}&quot;</span><span class="op">)</span></code>
can’t work since we’re not going to rerun the preprocessor during
tokenization. But I doubt anybody would even expect that to work.</p>
<p>But realistically, this would handily cover the 90%, if not the 99%
case. Not to mention could easily adopt other nice features of string
interpolation that show up in other languages (like Python’s
<code class="sourceCode cpp">f<span class="st">&quot;{x =}</span></code>
which formats as <code class="sourceCode cpp"><span class="st">&quot;x = 42&quot;</span></code>)
as library features. And, importantly, this isn’t a language feature
tied to
<code class="sourceCode cpp">std<span class="op">::</span>format</code>.
It could easily be made into a library to be used by any logging
framework.</p>
<p>Note here that unlike previous examples, the
<code class="sourceCode cpp">format</code> macro just took a
<code class="sourceCode cpp">string_view</code>. This is in contrast to
the earlier examples where the macro had to take a token sequence
(possibly with some <a href="#macro-parsing">parsing</a> involved).
Depending on how we approach parsing, the design could simply be that
any implicit tokenization only occurs if the macro’s parameters actually
expect token sequences. Or it could be that the
<code class="sourceCode cpp">format<span class="op">!</span></code>
macro needs to take a token sequence too and parse a string literal out
of it.</p>
<h2 data-number="5.7" id="abbreviated-lambdas"><span class="header-section-number">5.7</span> Abbreviated Lambdas<a href="#abbreviated-lambdas" class="self-link"></a></h2>
<p>In the hygiene section, we had an example of an abbreviated, unary
lambda using a parameter named <code class="sourceCode cpp">it</code>.
That is something that could already be done in a C macro today.
However, one thing that cannot easily be done in a C macro is to
generalize this to writing a lambda macro that can take a specified
number of parameters. As in:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb75"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb75-1"><a href="#cb75-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> λ<span class="op">(</span><span class="dt">int</span> n, meta<span class="op">::</span>info body<span class="op">)</span> <span class="op">-&gt;</span> meta<span class="op">::</span>info <span class="op">{</span></span>
<span id="cb75-2"><a href="#cb75-2" aria-hidden="true" tabindex="-1"></a>    <span class="co">// our parameters are _1, _2, ..., _n</span></span>
<span id="cb75-3"><a href="#cb75-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> params <span class="op">=</span> list_builder<span class="op">()</span>;</span>
<span id="cb75-4"><a href="#cb75-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> <span class="op">(</span><span class="dt">int</span> i <span class="op">=</span> <span class="dv">0</span>; i <span class="op">&lt;</span> n; <span class="op">++</span>i<span class="op">)</span> <span class="op">{</span></span>
<span id="cb75-5"><a href="#cb75-5" aria-hidden="true" tabindex="-1"></a>        params <span class="op">+=</span> <span class="op">^{</span> <span class="kw">auto</span><span class="op">&amp;&amp;</span> \id<span class="op">(</span><span class="st">&quot;_&quot;</span>, i<span class="op">+</span><span class="dv">1</span><span class="op">)</span> <span class="op">}</span>;</span>
<span id="cb75-6"><a href="#cb75-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb75-7"><a href="#cb75-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb75-8"><a href="#cb75-8" aria-hidden="true" tabindex="-1"></a>    <span class="co">// and then the rest is just repeating the body</span></span>
<span id="cb75-9"><a href="#cb75-9" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="op">^{</span></span>
<span id="cb75-10"><a href="#cb75-10" aria-hidden="true" tabindex="-1"></a>        <span class="op">[&amp;](</span>\tokens<span class="op">(</span>params<span class="op">))</span></span>
<span id="cb75-11"><a href="#cb75-11" aria-hidden="true" tabindex="-1"></a>            <span class="kw">noexcept</span><span class="op">(</span><span class="kw">noexcept</span><span class="op">(</span>\tokens<span class="op">(</span>body<span class="op">)))</span></span>
<span id="cb75-12"><a href="#cb75-12" aria-hidden="true" tabindex="-1"></a>            <span class="op">-&gt;</span> <span class="kw">decltype</span><span class="op">(</span>\tokens<span class="op">(</span>body<span class="op">))</span></span>
<span id="cb75-13"><a href="#cb75-13" aria-hidden="true" tabindex="-1"></a>        <span class="op">{</span></span>
<span id="cb75-14"><a href="#cb75-14" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> \tokens<span class="op">(</span>body<span class="op">)</span>;</span>
<span id="cb75-15"><a href="#cb75-15" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb75-16"><a href="#cb75-16" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span>;</span>
<span id="cb75-17"><a href="#cb75-17" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>As with the string interpolation example, here we’re now taking one
parameter of type
<code class="sourceCode cpp"><span class="dt">int</span></code> (that
doesn’t need to be tokenized) and another parameter that are the actual
tokens. The usage here might be something like <code class="sourceCode cpp">λ<span class="op">!(</span><span class="dv">2</span>, _1 <span class="op">&gt;</span> _2<span class="op">)</span></code>
- which is a lambda version of <code class="sourceCode cpp">std<span class="op">::</span>greater<span class="op">{}</span></code>.</p>
<p>Of course it’d be nice to do even better. That is: we can infer the
arity of the lambda based on the parameters that are used. This paper
does not yet have an API for iterating over a token sequence - but this
particular problem would not involve parsing. Simply iterate over the
tokens and find the largest <code class="sourceCode cpp">n</code> for
which there exists an identifier of the form
<code class="sourceCode cpp">_<em>n</em></code> and use that as the
arity. That would allow <code class="sourceCode cpp">λ<span class="op">!(</span>_1 <span class="op">&gt;</span> _2<span class="op">)</span></code>
by itself to be a binary lambda (or a lambda that takes at least two
parameters). Can’t do that with a C macro!</p>
<h2 data-number="5.8" id="a-control-flow-operator"><span class="header-section-number">5.8</span> A control flow operator<a href="#a-control-flow-operator" class="self-link"></a></h2>
<p>Two papers currently in flight propose extensions to C++’s set of
expressions: <span class="citation" data-cites="P2806R2">[<a href="https://wg21.link/p2806r2" role="doc-biblioref">P2806R2</a>]</span> proposes
<code class="sourceCode cpp"><span class="cf">do</span></code>
expressions as a way to have multiple statements in a single expression,
and <span class="citation" data-cites="P2561R2">[<a href="https://wg21.link/p2561r2" role="doc-biblioref">P2561R2</a>]</span> proposes a control flow
operator for better ergonomics with types like <code class="sourceCode cpp">std<span class="op">::</span>expected<span class="op">&lt;</span>T, E<span class="op">&gt;</span></code>.</p>
<p>Now, the proposed control flow operator nearly lowers into a
<code class="sourceCode cpp"><span class="cf">do</span></code>
expression - with one exception that is covered <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2806r2.html#lifetime">in
the paper</a>: lifetime. It would be nice if <code class="sourceCode cpp">f<span class="op">().</span><span class="cf">try</span><span class="op">?</span></code>,
for a function returning <code class="sourceCode cpp">expected<span class="op">&lt;</span>T, E<span class="op">&gt;</span></code>,
evaluated to
<code class="sourceCode cpp">T<span class="op">&amp;&amp;</span></code>
rather than <code class="sourceCode cpp">T</code> - to save an
unnecessary move. But doing so requires actually storing that result…
somewhere. What if macro injection allowed us to create such a
somewhere?</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb76"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb76-1"><a href="#cb76-1" aria-hidden="true" tabindex="-1"></a><span class="co">// an extremely lightweight Optional, only for use in deferring storage</span></span>
<span id="cb76-2"><a href="#cb76-2" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span></span>
<span id="cb76-3"><a href="#cb76-3" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Storage <span class="op">{</span></span>
<span id="cb76-4"><a href="#cb76-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">union</span> <span class="op">{</span> T value; <span class="op">}</span>; <span class="co">// assume P3074 trivial union</span></span>
<span id="cb76-5"><a href="#cb76-5" aria-hidden="true" tabindex="-1"></a>    <span class="dt">bool</span> initialized <span class="op">=</span> <span class="kw">false</span>;</span>
<span id="cb76-6"><a href="#cb76-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb76-7"><a href="#cb76-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> <span class="op">~</span>Storage<span class="op">()</span> <span class="op">{</span></span>
<span id="cb76-8"><a href="#cb76-8" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(</span>initialized<span class="op">)</span> <span class="op">{</span></span>
<span id="cb76-9"><a href="#cb76-9" aria-hidden="true" tabindex="-1"></a>            value<span class="op">.~</span>T<span class="op">()</span>;</span>
<span id="cb76-10"><a href="#cb76-10" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb76-11"><a href="#cb76-11" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb76-12"><a href="#cb76-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb76-13"><a href="#cb76-13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> F<span class="op">&gt;</span></span>
<span id="cb76-14"><a href="#cb76-14" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> <span class="kw">auto</span> construct<span class="op">(</span>F f<span class="op">)</span> <span class="op">-&gt;</span> T<span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb76-15"><a href="#cb76-15" aria-hidden="true" tabindex="-1"></a>        <span class="ot">assert</span><span class="op">(</span><span class="kw">not</span> initialized<span class="op">)</span>;</span>
<span id="cb76-16"><a href="#cb76-16" aria-hidden="true" tabindex="-1"></a>        <span class="kw">auto</span> p <span class="op">=</span> <span class="kw">new</span> <span class="op">(&amp;</span>value<span class="op">)</span> T<span class="op">(</span>f<span class="op">())</span>;</span>
<span id="cb76-17"><a href="#cb76-17" aria-hidden="true" tabindex="-1"></a>        initialized <span class="op">=</span> <span class="kw">true</span>;</span>
<span id="cb76-18"><a href="#cb76-18" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="op">*</span>p;</span>
<span id="cb76-19"><a href="#cb76-19" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb76-20"><a href="#cb76-20" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb76-21"><a href="#cb76-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb76-22"><a href="#cb76-22" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> try_<span class="op">(</span>meta<span class="op">::</span>info body<span class="op">)</span> <span class="op">-&gt;</span> meta<span class="op">::</span>info <span class="op">{</span></span>
<span id="cb76-23"><a href="#cb76-23" aria-hidden="true" tabindex="-1"></a>    <span class="co">// 1. we need the type of the body</span></span>
<span id="cb76-24"><a href="#cb76-24" aria-hidden="true" tabindex="-1"></a>    meta<span class="op">::</span>info T <span class="op">=</span> type_of<span class="op">(</span>body<span class="op">)</span>;</span>
<span id="cb76-25"><a href="#cb76-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb76-26"><a href="#cb76-26" aria-hidden="true" tabindex="-1"></a>    <span class="co">// 2. we create a local variable in the nearest enclosing scope</span></span>
<span id="cb76-27"><a href="#cb76-27" aria-hidden="true" tabindex="-1"></a>    <span class="co">//    that is of type Storage&lt;T&gt;</span></span>
<span id="cb76-28"><a href="#cb76-28" aria-hidden="true" tabindex="-1"></a>    meta<span class="op">::</span>info storage <span class="op">=</span> create_local_variable<span class="op">(</span>substitute<span class="op">(^</span>Storage, <span class="op">{</span>T<span class="op">}))</span>;</span>
<span id="cb76-29"><a href="#cb76-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb76-30"><a href="#cb76-30" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="op">^{</span></span>
<span id="cb76-31"><a href="#cb76-31" aria-hidden="true" tabindex="-1"></a>        <span class="cf">do</span> <span class="op">-&gt;</span> <span class="kw">decltype</span><span class="op">(</span><span class="kw">auto</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb76-32"><a href="#cb76-32" aria-hidden="true" tabindex="-1"></a>            <span class="co">// 3. we construct the &quot;body&quot; of the macro into that storage</span></span>
<span id="cb76-33"><a href="#cb76-33" aria-hidden="true" tabindex="-1"></a>            <span class="kw">auto</span><span class="op">&amp;</span> r <span class="op">=</span> <span class="op">[:</span> \<span class="op">(</span>storage<span class="op">)</span> <span class="op">:].</span>construct<span class="op">(</span></span>
<span id="cb76-34"><a href="#cb76-34" aria-hidden="true" tabindex="-1"></a>                <span class="op">[&amp;]()</span> <span class="op">-&gt;</span> <span class="kw">decltype</span><span class="op">(</span><span class="kw">auto</span><span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> <span class="op">(</span>\tokens<span class="op">(</span>body<span class="op">))</span>; <span class="op">}</span></span>
<span id="cb76-35"><a href="#cb76-35" aria-hidden="true" tabindex="-1"></a>            <span class="op">)</span>;</span>
<span id="cb76-36"><a href="#cb76-36" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb76-37"><a href="#cb76-37" aria-hidden="true" tabindex="-1"></a>            <span class="co">// 4. and then do the usual dance with returning the error</span></span>
<span id="cb76-38"><a href="#cb76-38" aria-hidden="true" tabindex="-1"></a>            <span class="cf">if</span> <span class="op">(</span><span class="kw">not</span> r<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> std<span class="op">::</span>move<span class="op">(</span>r<span class="op">).</span>error<span class="op">()</span>; <span class="op">}</span></span>
<span id="cb76-39"><a href="#cb76-39" aria-hidden="true" tabindex="-1"></a>            <span class="kw">do_return</span> <span class="op">*</span>std<span class="op">::</span>move<span class="op">(</span>r<span class="op">)</span>;</span>
<span id="cb76-40"><a href="#cb76-40" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb76-41"><a href="#cb76-41" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb76-42"><a href="#cb76-42" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>There is plenty of novelty here. First, we need to get the type of
the <code class="sourceCode cpp">body</code>.
<code class="sourceCode cpp">body</code> are just some tokens - this
might be called like <code class="sourceCode cpp">try_<span class="op">!(</span>f<span class="op">(</span><span class="dv">1</span>, <span class="dv">2</span><span class="op">))</span></code>
or <code class="sourceCode cpp">try_<span class="op">!(</span>var<span class="op">)</span></code>,
and we want <code class="sourceCode cpp"><span class="kw">decltype</span><span class="op">(</span>f<span class="op">(</span><span class="dv">1</span>, <span class="dv">2</span><span class="op">))</span></code>
and <code class="sourceCode cpp"><span class="kw">decltype</span><span class="op">(</span>var<span class="op">)</span></code>,
respectively, as evaluated from the context where the macro was invoked.
Actually what we really want is <code class="sourceCode cpp"><span class="kw">decltype</span><span class="op">((</span>f<span class="op">(</span><span class="dv">1</span>, <span class="dv">2</span><span class="op">)))</span></code>
and <code class="sourceCode cpp"><span class="kw">decltype</span><span class="op">((</span>var<span class="op">))</span></code>,
respectively. For now, we’ll use the existing
<code class="sourceCode cpp">type_of</code> as a placeholder to achieve
that type.</p>
<p>Second, <code class="sourceCode cpp">create_local_variable</code>
returns a reflection to an unnamed (and thus not otherwise accessible)
local variable that is created as close as possible to the injection
site, of the provided type (which must be default constructible). This
of course opens the door for lots of havoc, but in this case gives us a
convenient place to just grab some storage that we need for later.</p>
<p>Ocne we have those two pieces, the rest is actually straightforward.
The body of the
<code class="sourceCode cpp"><span class="cf">do</span></code>
expression constructs our <code class="sourceCode cpp">expected<span class="op">&lt;</span>T, E<span class="op">&gt;</span></code>
into the local storage we just carved out, and then uses it directly. We
do all of this dance instead of just <code class="sourceCode cpp"><span class="kw">auto</span><span class="op">&amp;&amp;</span> r <span class="op">=</span> \tokens<span class="op">(</span>body<span class="op">)</span>;</code>
simply to be able to return a reference from the
<code class="sourceCode cpp"><span class="cf">do</span></code>
expression.</p>
<p>Importantly though, macros coupled with this kind of storage
injection allows <span class="citation" data-cites="P2561R2">[<a href="https://wg21.link/p2561r2" role="doc-biblioref">P2561R2</a>]</span> to be shipped as a library.</p>
<h2 data-number="5.9" id="operator-support"><span class="header-section-number">5.9</span> Operator Support<a href="#operator-support" class="self-link"></a></h2>
<p>One advantage of the trailing
<code class="sourceCode cpp"><span class="op">!</span></code> syntax
used here is that it provides a clear signal to the compiler and the
reader that something new is going on. Using such a syntax means we
cannot support operators though - <code class="sourceCode cpp">x <span class="op">&amp;&amp;!</span> y</code>
already has valid meaning today, and it is not macro-invoking <code class="sourceCode cpp"><span class="kw">operator</span><span class="op">&amp;&amp;</span></code>.</p>
<p>If we want to support operators (and we are not sure if we do), then
one approach would be to introduce a new syntax for a macro declaration
(which we may want to do anyway). Such a macro could work like this:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb77"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb77-1"><a href="#cb77-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> C <span class="op">{</span></span>
<span id="cb77-2"><a href="#cb77-2" aria-hidden="true" tabindex="-1"></a>   <span class="dt">bool</span> b;</span>
<span id="cb77-3"><a href="#cb77-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb77-4"><a href="#cb77-4" aria-hidden="true" tabindex="-1"></a>   macro <span class="kw">operator</span><span class="op">&amp;&amp;(</span><span class="kw">this</span> std<span class="op">::</span>meta<span class="op">::</span>info self, std<span class="op">::</span>meta<span class="op">::</span>info rhs<span class="op">)</span> <span class="op">{</span></span>
<span id="cb77-5"><a href="#cb77-5" aria-hidden="true" tabindex="-1"></a>       <span class="cf">return</span> <span class="op">^{</span> <span class="op">[:</span>\<span class="op">(</span>self<span class="op">):].</span>b <span class="op">&amp;&amp;</span> \tokens<span class="op">(</span>rhs<span class="op">)</span>; <span class="op">}</span></span>
<span id="cb77-6"><a href="#cb77-6" aria-hidden="true" tabindex="-1"></a>   <span class="op">}</span></span>
<span id="cb77-7"><a href="#cb77-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb77-8"><a href="#cb77-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb77-9"><a href="#cb77-9" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> x <span class="op">=</span> C<span class="op">{</span><span class="kw">false</span><span class="op">}</span> <span class="op">&amp;&amp;</span> some_call<span class="op">()</span>;</span></code></pre></div>
</blockquote>
</div>
<p>Here, the macro would evaluate <code class="sourceCode cpp">C<span class="op">{</span><span class="kw">false</span><span class="op">}</span></code>
and pass a reflection to that expression as the first parameter, then
the second parameter is just tokenized. Thus the call effectively
evaluates as <code class="sourceCode cpp">C<span class="op">{</span><span class="kw">false</span><span class="op">}.</span>b <span class="op">&amp;&amp;</span> some_call<span class="op">()</span></code>,
which does short-circuit as desired.</p>
<p>It’s unclear if macro operators are worth pursuing. Dedicated
<code class="sourceCode cpp">macro</code> syntax declarations might be
beneficial though.</p>
<h2 data-number="5.10" id="alternate-syntax"><span class="header-section-number">5.10</span> Alternate Syntax<a href="#alternate-syntax" class="self-link"></a></h2>
<p>We have two forms of injection in this paper:</p>
<ul>
<li>metafunctions <code class="sourceCode cpp">std<span class="op">::</span>meta<span class="op">::</span>queue_injection</code>
and <code class="sourceCode cpp">std<span class="op">::</span>meta<span class="op">::</span>namespace_inject</code>
that take an <code class="sourceCode cpp">info</code>, used through <a href="#token-sequences">token sequences</a>.</li>
<li>a trailing
<code class="sourceCode cpp"><span class="op">!</span></code> used for
<a href="#scoped-macros">scoped macros</a>.</li>
</ul>
<p>But these really are similar - both are requests to take a token
sequence and inject it in the current context. The bigger token sequence
injection doesn’t really have any particular reason to require terse
syntax. Prior papers did use some punctuation marks
(e.g. <code class="sourceCode cpp"><span class="op">-&gt;</span></code>,
<code class="sourceCode cpp"><span class="op">&lt;&lt;</span></code>),
but a named function seems better. But the macros <em>really</em> do
want to have terse invocation syntax. Having to write <code class="sourceCode cpp">immediately_inject<span class="op">(</span>forward<span class="op">(</span>x<span class="op">))</span></code>
somewhat defeats the purpose and nobody would write it.</p>
<p>Using one of the arrows for the macro use-case is weird, so one
option might be prefix
<code class="sourceCode cpp"><span class="op">@</span></code>. As in
<code class="sourceCode cpp"><span class="op">@</span>forward<span class="op">(</span>x<span class="op">)</span></code>,
<code class="sourceCode cpp"><span class="op">@</span>assert_eq<span class="op">(</span>a, b<span class="op">)</span></code>,
and <code class="sourceCode cpp"><span class="op">@</span>format<span class="op">(</span><span class="st">&quot;x={this-&gt;x}&quot;</span><span class="op">)</span></code>.
This is what Swift does, except using prefix
<code class="sourceCode cpp"><span class="er">#</span></code> (which
isn’t really a viable option for us as <code class="sourceCode cpp"><span class="pp">#</span><span class="er">x</span></code>
already has meaning in the existing C preprocessor and we wouldn’t want
to completely prevent using new macros inside of old macros).</p>
<p>Or we could stick with two syntaxes - the longer one for the bigger
reflection cases where terseness is arguably bad, and the short one for
the macro use case where terseness is essential.</p>
<p>Likewise, macros could be declared as regular functions that take a
token sequence and return a token sequence (or <a href="#macro-parsing">other parameters</a>). Or perhaps we introduce a
new context-sensitive keyword instead:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb78"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb78-1"><a href="#cb78-1" aria-hidden="true" tabindex="-1"></a><span class="co">// regular function</span></span>
<span id="cb78-2"><a href="#cb78-2" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="kw">auto</span> fwd<span class="op">(</span>meta<span class="op">::</span>info x<span class="op">)</span> <span class="op">-&gt;</span> meta<span class="op">::</span>info <span class="op">{</span> <span class="cf">return</span> <span class="op">^{</span> <span class="co">/* ... */</span> <span class="op">}</span>; <span class="op">}</span></span>
<span id="cb78-3"><a href="#cb78-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb78-4"><a href="#cb78-4" aria-hidden="true" tabindex="-1"></a><span class="co">// dedicated declaration</span></span>
<span id="cb78-5"><a href="#cb78-5" aria-hidden="true" tabindex="-1"></a>macro fwd<span class="op">(</span>meta<span class="op">::</span>info x<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> <span class="op">^{</span> <span class="co">/* ... */</span> <span class="op">}</span>; <span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<h1 data-number="6" style="border-bottom:1px solid #cccccc" id="proposal"><span class="header-section-number">6</span> Proposal<a href="#proposal" class="self-link"></a></h1>
<p>We propose a code injection mechanism using token sequences.</p>
<p>The fragment model initially introduced in <span class="citation" data-cites="P1717R0">[<a href="https://wg21.link/p1717r0" role="doc-biblioref">P1717R0</a>]</span> is great for allowing writing
code-to-be-injected to actually look like regular C++ code, which has
the benefit of being both familiar and being already recognizable to
tools like syntax highlighters. But the early checking adds complexity
to the model and the implementation which makes it harder to use and
limits its usefulness. Hence, we propose raw token sequences that are
unparsed until the point of injection.</p>
<p>This proposal consists of several pieces:</p>
<ul>
<li>a mechanism to introduce a token sequence (in this paper <code class="sourceCode cpp"><span class="op">^{</span> <em>balanced-brace-tokens</em> <span class="op">}</span></code>)</li>
<li>three interpolators to add outside context to a token sequence, one
for identifiers (<code class="sourceCode cpp">\id<span class="op">(</span>e<span class="op">...)</span></code>),
one for values (<code class="sourceCode cpp">\<span class="op">(</span>e<span class="op">)</span></code>
- parens mandatory), and one for token sequences (<code class="sourceCode cpp">\tokens<span class="op">(</span>e<span class="op">)</span></code>)</li>
<li>new metafunctions to inject a token sequence (<code class="sourceCode cpp">std<span class="op">::</span>meta<span class="op">::</span>queue_injection<span class="op">()</span></code>
and <code class="sourceCode cpp">std<span class="op">::</span>meta<span class="op">::</span>namespace_inject<span class="op">()</span></code>)</li>
<li>new metaprogramming facilities for dealing with token sequences:
<ul>
<li>converting a string to a token sequence and a token sequence to a
string</li>
<li>splitting a token sequence into a range of tokens and
querying/mutating those tokens</li>
</ul></li>
<li>macros would benefit syntactically from:
<ul>
<li>a mechanism to accept a tokens sequence as a function parameter</li>
<li>a mechanism to inject a token sequence directly as returned by a
function (trailing
<code class="sourceCode cpp"><span class="op">!</span></code>)</li>
</ul></li>
</ul>
<p>Note that the macro proposal, and even the facilities for
splitting/iterating/querying/mutating tokens, can be split off as well.
We feel that even the core proposal of injecting token sequences in
declaration contexts only can provide a tremendous amount of value.</p>
<h1 data-number="7" style="border-bottom:1px solid #cccccc" id="bibliography"><span class="header-section-number">7</span>
References<a href="#bibliography" class="self-link"></a></h1>
<div id="refs" class="references csl-bib-body hanging-indent" data-entry-spacing="1" role="doc-bibliography">
<div id="ref-P0644R1" class="csl-entry" role="doc-biblioentry">
[P0644R1] Barry Revzin. 2017-10-08. Forward without forward. <a href="https://wg21.link/p0644r1"><div class="csl-block">https://wg21.link/p0644r1</div></a>
</div>
<div id="ref-P0707R4" class="csl-entry" role="doc-biblioentry">
[P0707R4] Herb Sutter. 2019-06-17. Metaclasses: Generative C++. <a href="https://wg21.link/p0707r4"><div class="csl-block">https://wg21.link/p0707r4</div></a>
</div>
<div id="ref-P0712R0" class="csl-entry" role="doc-biblioentry">
[P0712R0] Andrew Sutton, Herb Sutter. 2017-06-18. Implementing language
support for compile-time programming. <a href="https://wg21.link/p0712r0"><div class="csl-block">https://wg21.link/p0712r0</div></a>
</div>
<div id="ref-P1221R1" class="csl-entry" role="doc-biblioentry">
[P1221R1] Jason Rice. 2018-10-03. Parametric Expressions. <a href="https://wg21.link/p1221r1"><div class="csl-block">https://wg21.link/p1221r1</div></a>
</div>
<div id="ref-P1717R0" class="csl-entry" role="doc-biblioentry">
[P1717R0] Andrew Sutton, Wyatt Childers. 2019-06-17. Compile-time
Metaprogramming in C++. <a href="https://wg21.link/p1717r0"><div class="csl-block">https://wg21.link/p1717r0</div></a>
</div>
<div id="ref-P2050R0" class="csl-entry" role="doc-biblioentry">
[P2050R0] Andrew Sutton, Wyatt Childers. 2020-01-13. Tweaks to the
design of source code fragments. <a href="https://wg21.link/p2050r0"><div class="csl-block">https://wg21.link/p2050r0</div></a>
</div>
<div id="ref-P2237R0" class="csl-entry" role="doc-biblioentry">
[P2237R0] Andrew Sutton. 2020-10-15. Metaprogramming. <a href="https://wg21.link/p2237r0"><div class="csl-block">https://wg21.link/p2237r0</div></a>
</div>
<div id="ref-P2561R2" class="csl-entry" role="doc-biblioentry">
[P2561R2] Barry Revzin. 2023-05-18. A control flow operator. <a href="https://wg21.link/p2561r2"><div class="csl-block">https://wg21.link/p2561r2</div></a>
</div>
<div id="ref-P2806R2" class="csl-entry" role="doc-biblioentry">
[P2806R2] Barry Revzin, Bruno Cardoso Lopez, Zach Laine, Michael Park.
2023-11-16. do expressions. <a href="https://wg21.link/p2806r2"><div class="csl-block">https://wg21.link/p2806r2</div></a>
</div>
<div id="ref-P2996R4" class="csl-entry" role="doc-biblioentry">
[P2996R4] Wyatt Childers, Dan Katz, Barry Revzin, Andrew Sutton, Faisal
Vali, and Daveed Vandevoorde. 2024-06-26. Reflection for C++26. <a href="https://wg21.link/p2996r4"><div class="csl-block">https://wg21.link/p2996r4</div></a>
</div>
<div id="ref-P3096R1" class="csl-entry" role="doc-biblioentry">
[P3096R1] Adam Lach, Walter Genovese. 2024-05-15. Function Parameter
Reflection in Reflection for C++26. <a href="https://wg21.link/p3096r1"><div class="csl-block">https://wg21.link/p3096r1</div></a>
</div>
<div id="ref-P3289R0" class="csl-entry" role="doc-biblioentry">
[P3289R0] Daveed Vandevoorde, Wyatt Childers, Barry Revzin. 2024-05-21.
Consteval blocks. <a href="https://wg21.link/p3289r0"><div class="csl-block">https://wg21.link/p3289r0</div></a>
</div>
<div id="ref-P3294R0" class="csl-entry" role="doc-biblioentry">
[P3294R0] Barry Revzin, Andrei Alexandrescu, Daveed Vandevoorde.
2024-05-22. Code Injection with Token Sequences. <a href="https://wg21.link/p3294r0"><div class="csl-block">https://wg21.link/p3294r0</div></a>
</div>
</div>
</div>
</div>
</body>
</html>
