<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<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="2025-05-19" />
  <title>Error Handling in Reflection</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;
}
td > div > 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.addu td pre { background-color: inherit; }
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.rm li {
text-decoration: line-through;
color: #000000;
}
div.std blockquote del, div.rm {
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">Error Handling in
Reflection</h1>
<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P3560R1 <a href="https://wg21.link/P3560">[Latest]</a> <a href="https://wg21.link/P3560/status">[Status]</a></td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2025-05-19</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>
      EWG, LEWG<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to:</td>
    <td>
      Peter Dimov<br>&lt;<a href="mailto:pdimov@gmail.com" class="email">pdimov@gmail.com</a>&gt;<br>
      Barry Revzin<br>&lt;<a href="mailto:barry.revzin@gmail.com" class="email">barry.revzin@gmail.com</a>&gt;<br>
    </td>
  </tr>
</table>
</header>
<div style="clear:both">
<div id="TOC" role="doc-toc">
<h1 id="toctitle">Contents</h1>
<ul>
<li><a href="#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="#exception-type" id="toc-exception-type"><span class="toc-section-number">3</span> Exception Type<span></span></a>
<ul>
<li><a href="#encoding" id="toc-encoding"><span class="toc-section-number">3.1</span> Encoding<span></span></a></li>
<li><a href="#single-or-multiple-types" id="toc-single-or-multiple-types"><span class="toc-section-number">3.2</span> Single or Multiple
Types<span></span></a></li>
<li><a href="#derivation-from-stdexception" id="toc-derivation-from-stdexception"><span class="toc-section-number">3.3</span> Derivation from <code class="sourceCode cpp">std<span class="op">::</span>exception</code><span></span></a></li>
</ul></li>
<li><a href="#recoverable-or-unrecoverable" id="toc-recoverable-or-unrecoverable"><span class="toc-section-number">4</span> Recoverable or
Unrecoverable<span></span></a></li>
<li><a href="#proposed-wording" id="toc-proposed-wording"><span class="toc-section-number">5</span> Proposed Wording<span></span></a>
<ul>
<li><a href="#meta.reflection.synop" id="toc-meta.reflection.synop"><span class="toc-section-number">5.1</span>
[meta.reflection.synop]<span></span></a></li>
<li><a href="#meta.reflection.exception" id="toc-meta.reflection.exception"><span class="toc-section-number">5.2</span>
[meta.reflection.exception]<span></span></a></li>
<li><a href="#meta.reflection.operators" id="toc-meta.reflection.operators"><span class="toc-section-number">5.3</span>
[meta.reflection.operators]<span></span></a></li>
<li><a href="#meta.reflection.names" id="toc-meta.reflection.names"><span class="toc-section-number">5.4</span>
[meta.reflection.names]<span></span></a></li>
<li><a href="#meta.reflection.queries" id="toc-meta.reflection.queries"><span class="toc-section-number">5.5</span>
[meta.reflection.queries]<span></span></a></li>
<li><a href="#meta.reflection.member.queries" id="toc-meta.reflection.member.queries"><span class="toc-section-number">5.6</span>
[meta.reflection.member.queries]<span></span></a></li>
<li><a href="#meta.reflection.layout" id="toc-meta.reflection.layout"><span class="toc-section-number">5.7</span>
[meta.reflection.layout]<span></span></a></li>
<li><a href="#meta.reflection.extract" id="toc-meta.reflection.extract"><span class="toc-section-number">5.8</span>
[meta.reflection.extract]<span></span></a></li>
<li><a href="#meta.reflection.substitute" id="toc-meta.reflection.substitute"><span class="toc-section-number">5.9</span>
[meta.reflection.substitute]<span></span></a></li>
<li><a href="#meta.reflection.result" id="toc-meta.reflection.result"><span class="toc-section-number">5.10</span>
[meta.reflection.result]<span></span></a></li>
<li><a href="#meta.reflection.define.aggregate" id="toc-meta.reflection.define.aggregate"><span class="toc-section-number">5.11</span>
[meta.reflection.define.aggregate]<span></span></a></li>
<li><a href="#meta.reflection.traits" id="toc-meta.reflection.traits"><span class="toc-section-number">5.12</span>
[meta.reflection.traits]<span></span></a></li>
<li><a href="#feature-test-macro" id="toc-feature-test-macro"><span class="toc-section-number">5.13</span> Feature-Test
Macro<span></span></a></li>
</ul></li>
<li><a href="#bibliography" id="toc-bibliography"><span class="toc-section-number">6</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="P3560R0"><a href="https://wg21.link/p3560r0" role="doc-biblioref">[P3560R0]</a></span>:</p>
<ul>
<li>after discussion in an SG16 telecon, LEWG discussion, and <span class="title"><span class="citation" data-cites="P3637R0"><a href="https://wg21.link/p3637r0" role="doc-biblioref">[P3637R0] (Inherit
std::meta::exception from std::exception)</a></span></span>, we changed
the proposed <code class="sourceCode cpp">std<span class="op">::</span>meta<span class="op">::</span>exception</code>
type to inherit from <code class="sourceCode cpp">std<span class="op">::</span>exception</code> (<a href="#derivation-from-stdexception">see below</a>), and thus have a
<code class="sourceCode cpp"><span class="dt">char</span> <span class="kw">const</span><span class="op">*</span> what<span class="op">()</span></code>
accessor in addition to the <code class="sourceCode cpp">u8string_view u8what<span class="op">()</span></code>
one.</li>
<li>rebased on <span class="citation" data-cites="P2996R12"><a href="https://wg21.link/p2996r12" role="doc-biblioref">[P2996R12]</a></span></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>In <span class="title"><span class="citation" data-cites="P2996R12"><a href="https://wg21.link/p2996r12" role="doc-biblioref">[P2996R12] (Reflection for
C++26)</a></span></span>, we had to answer the question of what the
error handling mechanism should be. We considered four options:</p>
<ol type="1">
<li>Returning an invalid reflection (similar to
<code class="sourceCode cpp">NaN</code> for floating point)</li>
<li>Returning a <code class="sourceCode cpp">std<span class="op">::</span>expected<span class="op">&lt;</span>T, E<span class="op">&gt;</span></code>
for some reflection-specific error type
<code class="sourceCode cpp">E</code></li>
<li>Failing to be a constant expression</li>
<li>Throwing an exception of type <code class="sourceCode cpp">E</code>,
for some type <code class="sourceCode cpp">E</code>.</li>
</ol>
<p>Option (1) doesn’t work well, because not all reflection functions
return <code class="sourceCode cpp">std<span class="op">::</span>meta<span class="op">::</span>info</code>.
Some (such as <code class="sourceCode cpp">members_of</code>) return
<code class="sourceCode cpp">vector<span class="op">&lt;</span>info<span class="op">&gt;</span></code>,
some (such as <code class="sourceCode cpp">identifier_of</code>) return
<code class="sourceCode cpp">string_view</code>, and <code class="sourceCode cpp">extract<span class="op">&lt;</span>T<span class="op">&gt;</span></code>
even returns <code class="sourceCode cpp">T</code>. A
<code class="sourceCode cpp">NaN</code> reflection doesn’t solve the
problem.</p>
<p>Option (2) places a heavy syntactic burden on user code, because
<code class="sourceCode cpp">std<span class="op">::</span>expected</code>
needs to be unwrapped manually, without help from the language.</p>
<p>Option (3) doesn’t provide any means for user code to recover from an
error.</p>
<p>At the time we had to make the decision, option (4) was essentially
equivalent to (3), because throwing an exception wasn’t a constant
expression, so we settled on option (3). However, since the adoption of
<span class="title"><span class="citation" data-cites="P3068R6"><a href="https://wg21.link/p3068r6" role="doc-biblioref">[P3068R6]
(Allowing exception throwing in constant-evaluation)</a></span></span>,
that has changed, and option (4) has become viable.</p>
<p>Using exceptions to signal errors doesn’t suffer from the problem
with option (1), because it’s a strategy that can be used regardless of
the return type. It also doesn’t require syntactic changes to the user
code.</p>
<p>Ordinarily, for runtime functions, exception handling might be
avoided for reasons of binary size and runtime overhead; it also imposes
the requirement that the API can’t be used with exceptions disabled
(which is nonstandard, but nevertheless highly popular.)</p>
<p>However, none of these objections apply to exceptions used at compile
time. They have no binary footprint, don’t affect the run time, and
there is no reason for a compiler to not allow them even in “no
exceptions” mode (because they are entirely contained to program
compilation.)</p>
<p>Therefore, we believe that we need to adopt option (4) as the error
handling strategy for reflection functions.</p>
<h1 data-number="3" style="border-bottom:1px solid #cccccc" id="exception-type"><span class="header-section-number">3</span>
Exception Type<a href="#exception-type" class="self-link"></a></h1>
<p>To signal errors via throwing an exception, we need to settle on an
exception type (or types) which to throw.</p>
<p>Since these exceptions will never escape to runtime, we don’t need to
be concerned with deriving their type(s) from <code class="sourceCode cpp">std<span class="op">::</span>exception</code>.
However, it would be desirable for the exceptions to carry enough
information for error recovery (when caught), enough information for
high quality error messages (when uncaught), and for them to be suitable
for error handling in user
<code class="sourceCode cpp"><span class="kw">constexpr</span></code>
and
<code class="sourceCode cpp"><span class="kw">consteval</span></code>
functions as well, in addition to standard ones.</p>
<p>To that end, we proposed the following exception type:</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">namespace</span> std<span class="op">::</span>meta <span class="op">{</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> exception</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">consteval</span> exception<span class="op">(</span>u8string_view what,</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>                        info from,</span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>                        source_location where <span class="op">=</span> source_location<span class="op">::</span>current<span class="op">())</span>;</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">consteval</span> u8string_view what<span class="op">()</span> <span class="kw">const</span>;</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>    <span class="kw">consteval</span> info from<span class="op">()</span> <span class="kw">const</span>;</span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">consteval</span> source_location where<span class="op">()</span> <span class="kw">const</span>;</span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p><code class="sourceCode cpp">exception<span class="op">::</span>what<span class="op">()</span></code>
is a string describing the error; <code class="sourceCode cpp">exception<span class="op">::</span>from<span class="op">()</span></code>
is a reflection of the function (or function template) from a call to
which the error originated; and <code class="sourceCode cpp">exception<span class="op">::</span>where<span class="op">()</span></code>
is the source location of the call to that function.</p>
<p>For example, the following function</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">consteval</span> <span class="kw">auto</span> f<span class="op">()</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> members_of<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></code></pre></div>
</blockquote>
</div>
<p>will throw an exception of type <code class="sourceCode cpp">std<span class="op">::</span>meta<span class="op">::</span>exception</code>
for which
<code class="sourceCode cpp">what<span class="op">()</span></code> will
return (for example) <code class="sourceCode cpp"><span class="st">u8&quot;invalid reflection operand&quot;</span></code>,
<code class="sourceCode cpp">from<span class="op">()</span></code> will
return <code class="sourceCode cpp"><span class="op">^^</span>std<span class="op">::</span>meta<span class="op">::</span>members_of</code>,
and <code class="sourceCode cpp">where<span class="op">()</span></code>
will return a <code class="sourceCode cpp">std<span class="op">::</span>source_location</code>
object pointing at the call to
<code class="sourceCode cpp">members_of</code> inside
<code class="sourceCode cpp">f</code>.</p>
<p>Suppose a user wishes to write a
<code class="sourceCode cpp"><span class="kw">consteval</span></code>
function that only accepts class type reflections. It would be possible
to use <code class="sourceCode cpp">std<span class="op">::</span>meta<span class="op">::</span>exception</code>
to signal errors as follows:</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">consteval</span> <span class="kw">auto</span> user_fn<span class="op">(</span>info type, source_location where <span class="op">=</span> source_location<span class="op">::</span>current<span class="op">())</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span><span class="op">(</span> <span class="op">!</span>is_class_type<span class="op">(</span>type<span class="op">)</span> <span class="op">)</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>        <span class="cf">throw</span> std<span class="op">::</span>meta<span class="op">::</span>exception<span class="op">(</span><span class="st">u8&quot;not a class type&quot;</span>, <span class="op">^^</span>user_fn, where<span class="op">)</span>;</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>    <span class="co">// carry on</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<h2 data-number="3.1" id="encoding"><span class="header-section-number">3.1</span> Encoding<a href="#encoding" class="self-link"></a></h2>
<p>What encoding should we use for the string describing the error, and
what character type?</p>
<p>The encoding is left unspecified in the runtime case (<code class="sourceCode cpp">std<span class="op">::</span>exception<span class="op">::</span>what<span class="op">()</span></code>),
which is generally regarded as a defect (<span class="citation" data-cites="LWG4087"><a href="https://wg21.link/lwg4087" role="doc-biblioref">[LWG4087]</a></span>). Since we are designing a new
component, we should not repeat that mistake, and specify the encoding
of <code class="sourceCode cpp">meta<span class="op">::</span>exception<span class="op">::</span>what<span class="op">()</span></code>.</p>
<p>Since the string describing the error can be constructed from
components coming from multiple sources, it should use an encoding that
can represent any of these substrings. That is, it should use UTF-8.</p>
<p>The principled way to reflect this fact in the type system is to use
<code class="sourceCode cpp">u8string_view</code>. However, there are
strong, purely pragmatic, arguments in favor of using
<code class="sourceCode cpp">string_view</code> instead.</p>
<p><code class="sourceCode cpp"><span class="dt">char8_t</span></code>
has nearly zero support in the standard library, which makes it
<em>very</em> inconvenient to use. Suppose, for example, that we are
writing a function <code class="sourceCode cpp">member_of<span class="op">(</span>info x, <span class="dt">size_t</span> i<span class="op">)</span></code>
that returns <code class="sourceCode cpp">members_of<span class="op">(</span>x<span class="op">)[</span>i<span class="op">]</span></code>:</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">consteval</span> info member_of<span class="op">(</span>info x, <span class="dt">size_t</span> i, source_location where <span class="op">=</span> source_location<span class="op">::</span>current<span class="op">())</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> v <span class="op">=</span> members_of<span class="op">(</span>x<span class="op">)</span>;</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span><span class="op">(</span> i <span class="op">&gt;=</span> v<span class="op">.</span>size<span class="op">()</span> <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="cf">throw</span> meta<span class="op">::</span>exception<span class="op">(</span> <span class="st">u8&quot;invalid member index&quot;</span>, <span class="op">^^</span>member_of, where <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="cf">return</span> v<span class="op">[</span>i<span class="op">]</span>;</span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>Further suppose that we want to provide a more descriptive error
string, e.g. <code class="sourceCode cpp"><span class="st">&quot;152 is not a valid member index&quot;</span></code>,
where 152 is the value of <code class="sourceCode cpp">i</code>.</p>
<p>There’s basically no way to easily do that today. We can’t use
<code class="sourceCode cpp">std<span class="op">::</span>format</code>
to create a <code class="sourceCode cpp">u8string</code>, there is no
<code class="sourceCode cpp">std<span class="op">::</span>to_u8string</code>,
there is even no equivalent of
<code class="sourceCode cpp">to_chars</code> that would produce a
<code class="sourceCode cpp"><span class="dt">char8_t</span></code>
sequence.</p>
<p>In contrast, if the constructor took <code class="sourceCode cpp">std<span class="op">::</span>string_view</code>,
we could have used any of these.</p>
<p>So maybe we should just use
<code class="sourceCode cpp">string_view</code>? But that’s not
consistent with the current state of <span class="citation" data-cites="P2996R12"><a href="https://wg21.link/p2996r12" role="doc-biblioref">[P2996R12]</a></span>. It did start out using
<code class="sourceCode cpp">string_view</code> everywhere, and had to
be rewritten to supply additional
<code class="sourceCode cpp">u8string_view</code> interfaces, for good
reasons.</p>
<p>Consider, for instance, <code class="sourceCode cpp">std<span class="op">::</span>meta<span class="op">::</span>identifier_of<span class="op">(</span>x<span class="op">)</span></code>.
It can fail for two reasons: if the entity to which
<code class="sourceCode cpp">x</code> refers has no associated
identifier, or if it does, but that identifier is not representable in
the literal encoding.</p>
<p>We are changing these failures from hard errors (not a constant
expression) to throwing <code class="sourceCode cpp">meta<span class="op">::</span>exception</code>. A
sketch implementation of
<code class="sourceCode cpp">identifier_of</code>, then, would look like
this:</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">consteval</span> string_view identifier_of<span class="op">(</span>info x<span class="op">)</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span><span class="op">(</span> <span class="op">!</span>has_identifier<span class="op">(</span>x<span class="op">)</span> <span class="op">)</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>        <span class="cf">throw</span> meta<span class="op">::</span>exception<span class="op">(</span><span class="st">u8&quot;entity has no identifier&quot;</span>, <span class="op">^^</span>identifier_of, <span class="op">...)</span>;</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> id <span class="op">=</span> u8identifier_of<span class="op">(</span>x<span class="op">)</span>;</span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span><span class="op">(</span> <span class="op">!</span>is_representable<span class="op">(</span>id<span class="op">)</span> <span class="op">)</span></span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a>        <span class="cf">throw</span> meta<span class="op">::</span>exception<span class="op">(</span><span class="st">u8&quot;identifier &#39;&quot;</span><span class="bu">s</span> <span class="op">+</span> id <span class="op">+</span> <span class="st">u8&quot;&#39;is not representable&quot;</span>, <span class="op">^^</span>identifier_of, <span class="op">...)</span>;</span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-15"><a href="#cb5-15" aria-hidden="true" tabindex="-1"></a>    <span class="co">// convert id to the literal encoding and return it</span></span>
<span id="cb5-16"><a href="#cb5-16" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>For quality of implementation reasons, we want to include the
identifier in the error description string we pass to the exception
constructor, so that the subsequent error message will say <code class="sourceCode cpp"><span class="st">&quot;the identifier &#39;риба&#39; is not representable&quot;</span></code>
and not just <code class="sourceCode cpp"><span class="st">&quot;identifier not representable&quot;</span></code>.</p>
<p>There is no way to do that if we take and return
<code class="sourceCode cpp">string_view</code> from the exception
constructor and
<code class="sourceCode cpp">what<span class="op">()</span></code>.
Since the failure is caused by the identifier not being representable in
the literal encoding, it trivially follows that we can’t put it into an
error string that uses the literal encoding.</p>
<p>That is why we believe that taking and returning
<code class="sourceCode cpp">u8string_view</code> is essential in order
to maintain consistency with the current design of <span class="citation" data-cites="P2996R12"><a href="https://wg21.link/p2996r12" role="doc-biblioref">[P2996R12]</a></span>, which is the result of
extensive discussions in SG16.</p>
<p>To address the usability question, after the SG16 telecon on February
5th, 2025, we decided to provide a dual API, like the rest of <span class="citation" data-cites="P2996R12"><a href="https://wg21.link/p2996r12" role="doc-biblioref">[P2996R12]</a></span>, and have two constructors,
one taking <code class="sourceCode cpp">u8string_view</code> and one
taking <code class="sourceCode cpp">string_view</code>:</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">namespace</span> std<span class="op">::</span>meta <span class="op">{</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> exception</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a><span class="kw">private</span><span class="op">:</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>  u8string <em>what_</em>;         <span class="co">// exposition only</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>  info <em>from_</em>;             <span class="co">// exposition only</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>  source_location <em>where_</em>; <span class="co">// exposition only</span></span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a>  <span class="kw">consteval</span> exception<span class="op">(</span>u8string_view what, info from,</span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true" tabindex="-1"></a>    source_location where <span class="op">=</span> source_location<span class="op">::</span>current<span class="op">())</span> <span class="kw">noexcept</span></span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true" tabindex="-1"></a>    <span class="op">:</span> <em>what_</em><span class="op">(</span>what<span class="op">)</span>, <em>from_</em><span class="op">(</span>from<span class="op">)</span>, <em>where_</em><span class="op">(</span>where<span class="op">)</span> <span class="op">{}</span></span>
<span id="cb6-14"><a href="#cb6-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-15"><a href="#cb6-15" aria-hidden="true" tabindex="-1"></a>  <span class="kw">consteval</span> exception<span class="op">(</span>string_view what, info from,</span>
<span id="cb6-16"><a href="#cb6-16" aria-hidden="true" tabindex="-1"></a>    source_location where <span class="op">=</span> source_location<span class="op">::</span>current<span class="op">())</span> <span class="kw">noexcept</span></span>
<span id="cb6-17"><a href="#cb6-17" aria-hidden="true" tabindex="-1"></a>    <span class="op">:</span> <em>what_</em><span class="op">(</span><em>ordinary-to-u8</em><span class="op">(</span>what<span class="op">))</span>, <em>from_</em><span class="op">(</span>from<span class="op">)</span>, <em>where_</em><span class="op">(</span>where<span class="op">)</span> <span class="op">{}</span></span>
<span id="cb6-18"><a href="#cb6-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-19"><a href="#cb6-19" aria-hidden="true" tabindex="-1"></a>  <span class="kw">consteval</span> u8string_view u8what<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span> <span class="op">{</span></span>
<span id="cb6-20"><a href="#cb6-20" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <em>what_</em>;</span>
<span id="cb6-21"><a href="#cb6-21" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb6-22"><a href="#cb6-22" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-23"><a href="#cb6-23" aria-hidden="true" tabindex="-1"></a>  <span class="kw">consteval</span> string what<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span> <span class="op">{</span></span>
<span id="cb6-24"><a href="#cb6-24" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <em>u8-to-ordinary</em><span class="op">(</span><em>what_</em><span class="op">)</span>;</span>
<span id="cb6-25"><a href="#cb6-25" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb6-26"><a href="#cb6-26" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-27"><a href="#cb6-27" aria-hidden="true" tabindex="-1"></a>  <span class="co">// ...</span></span>
<span id="cb6-28"><a href="#cb6-28" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb6-29"><a href="#cb6-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-30"><a href="#cb6-30" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>where
<code class="sourceCode cpp">what<span class="op">()</span></code> fails
to be constant if it cannot transcode. It would be nice if we had at
least <code class="sourceCode cpp"><em>u8-to-ordinary</em></code> and
<code class="sourceCode cpp"><em>ordinary-to-u8</em></code> already
specified and present but, well, today is better than tomorrow.</p>
<p>This gives us a maximally usable API — since the standard library has
plenty of support for <code class="sourceCode cpp">string</code>
formatting and that can be used here, the conversion from ordinary to
UTF-8 is fine. It does still mean that attempting to call
<code class="sourceCode cpp">what<span class="op">()</span></code> could
fail, but… so be it.</p>
<h2 data-number="3.2" id="single-or-multiple-types"><span class="header-section-number">3.2</span> Single or Multiple Types<a href="#single-or-multiple-types" class="self-link"></a></h2>
<p>We are proposing a single exception type. The runtime analogy is
<code class="sourceCode cpp">std<span class="op">::</span>system_error</code>
as opposed to a hierarchy of exception types.</p>
<p>This in principle makes user code that wishes to inspect the failure
reason and do different things depending on it less convenient to write.
It would have to look like this</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="cf">catch</span><span class="op">(</span> meta<span class="op">::</span>exception <span class="kw">const</span><span class="op">&amp;</span> x <span class="op">)</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span><span class="op">(</span> x<span class="op">.</span>from<span class="op">()</span> <span class="op">==</span> <span class="op">^^</span>identifier_of <span class="op">)</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>        <span class="co">// handle errors originating from identifier_of</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>    <span class="cf">else</span> <span class="cf">if</span><span class="op">(</span> x<span class="op">.</span>from<span class="op">()</span> <span class="op">==</span> <span class="op">^^</span>members_of <span class="op">)</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a>        <span class="co">// handle errors originating from members_of</span></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>instead of, hypothetically, like this</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="cf">catch</span><span class="op">(</span> meta<span class="op">::</span>identifier_exception <span class="kw">const</span><span class="op">&amp;</span> x <span class="op">)</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>    <span class="co">// handle errors originating from identifier_of</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a><span class="cf">catch</span><span class="op">(</span> meta<span class="op">::</span>members_exception <span class="kw">const</span><span class="op">&amp;</span> x <span class="op">)</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>    <span class="co">// handle errors originating from members_of</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a><span class="co">// ...</span></span></code></pre></div>
</blockquote>
</div>
<p>(exception type names are illustrative.)</p>
<p>We don’t propose an exception hierarchy here. Designing a proper
exception hierarchy is not something we can realistically do in the
C++26 timeframe. It’s not as straightforward as just using an exception
per function because functions can fail for multiple reasons, and client
code may well wish to distinguish between these.</p>
<p>Furthermore, an exception hierarchy can be designed at a later date,
with the functions changed to throw an appropriate type derived from the
currently proposed <code class="sourceCode cpp">meta<span class="op">::</span>exception</code>.
Code written against this proposal will continue to work unmodified, and
new code would be able to use more specific catch clauses.</p>
<h2 data-number="3.3" id="derivation-from-stdexception"><span class="header-section-number">3.3</span> Derivation from <code class="sourceCode cpp">std<span class="op">::</span>exception</code><a href="#derivation-from-stdexception" class="self-link"></a></h2>
<p>Our initial proposal did not derive <code class="sourceCode cpp">std<span class="op">::</span>meta<span class="op">::</span>exception</code>
from <code class="sourceCode cpp">std<span class="op">::</span>exception</code>,
because <code class="sourceCode cpp">meta<span class="op">::</span>exception</code>
only exists at compile time, whereas <code class="sourceCode cpp">std<span class="op">::</span>exception</code>-derived
exceptions inhabit the runtime domain.</p>
<p>However, we repeatedly received suggestions to the contrary, and we
now think that the derivation would be desirable for consistency with
all other standard exceptions, some of which will end up being used at
compile time as well.</p>
<p><code class="sourceCode cpp">std<span class="op">::</span>exception<span class="op">::</span>what</code>
returns <code class="sourceCode cpp"><span class="dt">char</span> <span class="kw">const</span><span class="op">*</span></code>,
rather than
<code class="sourceCode cpp">std<span class="op">::</span>string</code>
as in the interface listed above, but this is surmountable by a slight
modification. We just need to keep an <code class="sourceCode cpp">optional<span class="op">&lt;</span>string<span class="op">&gt;</span></code>
member with the <code class="sourceCode cpp">what</code> string in the
ordinary encoding, in addition to the
<code class="sourceCode cpp">u8string</code> member that holds the
<code class="sourceCode cpp">what</code> string in UTF-8. If the
conversion from UTF-8 to ordinary fails, we leave the
<code class="sourceCode cpp">optional</code> disengaged and in that case
<code class="sourceCode cpp">what<span class="op">()</span></code>
fails.</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">namespace</span> std<span class="op">::</span>meta <span class="op">{</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> exception</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a><span class="kw">private</span><span class="op">:</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>  u8string <em>u8what_</em>;         <span class="co">// exposition only</span></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>  optional<span class="op">&lt;</span>string<span class="op">&gt;</span> <em>what_</em>;   <span class="co">// exposition only</span></span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a>  info <em>from_</em>  ;             <span class="co">// exposition only</span></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a>  source_location <em>where_</em>;   <span class="co">// exposition only</span></span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true" tabindex="-1"></a>  <span class="kw">consteval</span> exception<span class="op">(</span>u8string_view what, info from,</span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true" tabindex="-1"></a>    source_location where <span class="op">=</span> source_location<span class="op">::</span>current<span class="op">())</span> <span class="kw">noexcept</span></span>
<span id="cb9-14"><a href="#cb9-14" aria-hidden="true" tabindex="-1"></a>    <span class="op">:</span> <em>u8what_</em><span class="op">(</span>what<span class="op">)</span>, <em>from_</em><span class="op">(</span>from<span class="op">)</span>, <em>where_</em><span class="op">(</span>where<span class="op">)</span> <span class="op">{</span></span>
<span id="cb9-15"><a href="#cb9-15" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span><span class="op">(</span><em>u8-to-ordinary-would-succeed</em><span class="op">(</span>what<span class="op">))</span></span>
<span id="cb9-16"><a href="#cb9-16" aria-hidden="true" tabindex="-1"></a>        <em>what_</em> <span class="op">=</span> <em>u8-to-ordinary</em><span class="op">(</span>what<span class="op">)</span>;</span>
<span id="cb9-17"><a href="#cb9-17" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb9-18"><a href="#cb9-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-19"><a href="#cb9-19" aria-hidden="true" tabindex="-1"></a>  <span class="kw">consteval</span> exception<span class="op">(</span>string_view what, info from,</span>
<span id="cb9-20"><a href="#cb9-20" aria-hidden="true" tabindex="-1"></a>    source_location where <span class="op">=</span> source_location<span class="op">::</span>current<span class="op">())</span> <span class="kw">noexcept</span></span>
<span id="cb9-21"><a href="#cb9-21" aria-hidden="true" tabindex="-1"></a>    <span class="op">:</span> <em>u8what_</em><span class="op">(</span><em>ordinary-to-u8</em><span class="op">(</span>what<span class="op">))</span>, <em>what_</em><span class="op">(</span>what<span class="op">)</span>, <em>from_</em><span class="op">(</span>from<span class="op">)</span>, <em>where_</em><span class="op">(</span>where<span class="op">)</span> <span class="op">{}</span></span>
<span id="cb9-22"><a href="#cb9-22" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-23"><a href="#cb9-23" aria-hidden="true" tabindex="-1"></a>  <span class="kw">consteval</span> u8string_view u8what<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span> <span class="op">{</span></span>
<span id="cb9-24"><a href="#cb9-24" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <em>u8what_</em>;</span>
<span id="cb9-25"><a href="#cb9-25" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb9-26"><a href="#cb9-26" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-27"><a href="#cb9-27" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> <span class="dt">char</span> <span class="kw">const</span><span class="op">*</span> what<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span> <span class="op">{</span></span>
<span id="cb9-28"><a href="#cb9-28" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <em>what_</em><span class="op">-&gt;</span>c_str<span class="op">()</span>;</span>
<span id="cb9-29"><a href="#cb9-29" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb9-30"><a href="#cb9-30" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-31"><a href="#cb9-31" aria-hidden="true" tabindex="-1"></a>  <span class="co">// ...</span></span>
<span id="cb9-32"><a href="#cb9-32" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb9-33"><a href="#cb9-33" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-34"><a href="#cb9-34" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<h1 data-number="4" style="border-bottom:1px solid #cccccc" id="recoverable-or-unrecoverable"><span class="header-section-number">4</span> Recoverable or Unrecoverable<a href="#recoverable-or-unrecoverable" class="self-link"></a></h1>
<p>We went through the proposed API in <span class="citation" data-cites="P2996R12"><a href="https://wg21.link/p2996r12" role="doc-biblioref">[P2996R12]</a></span> and we think that all of the
library functions should be recoverable — that is failing to meet the
requirements of the function should be an exception rather than constant
evaluation failure — with a single exception, <code class="sourceCode cpp">std<span class="op">::</span>meta<span class="op">::</span>define_aggregate</code>.</p>
<p><code class="sourceCode cpp">define_aggregate</code> isn’t likely to
be used from a context from which recovery is meaningful, and even if it
were, for meaningful recovery we would have to guarantee that the
partial effects of a failure have been rolled back (as a definition
containing some of the members may already have been produced at the
point where the error is detected.) We don’t believe that imposing this
requirement is warranted or worth the cost.</p>
<p>The rest of the library functions are straightforwardly fallible, so
the ability to recover from them is desirable.</p>
<h1 data-number="5" style="border-bottom:1px solid #cccccc" id="proposed-wording"><span class="header-section-number">5</span>
Proposed Wording<a href="#proposed-wording" class="self-link"></a></h1>
<p>The wording here introduces a new type <code class="sourceCode cpp">std<span class="op">::</span>meta<span class="op">::</span>exception</code>
and defines it.</p>
<p>Otherwise it’s pretty rote changing all the error handling from
something of the form “<em>Constant When</em>:
<code class="sourceCode cpp"><em>C</em></code>” to “<em>Throws</em>:
<code class="sourceCode cpp">meta<span class="op">::</span>exception</code>
unless <code class="sourceCode cpp"><em>C</em></code>”.</p>
<h2 data-number="5.1" id="meta.reflection.synop"><span class="header-section-number">5.1</span> [meta.reflection.synop]<a href="#meta.reflection.synop" class="self-link"></a></h2>
<p>Add to the synopsis in [meta.reflection.synop:]</p>
<div class="std">
<blockquote>
<div>
<div class="sourceCode" id="cb10"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>namespace std::meta {</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>  using info = decltype(^^::);</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a><span class="va">+ // [meta.reflection.exception], class exception</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a><span class="va">+ class exception;</span></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>  // ...</span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
</div>
</blockquote>
</div>
<h2 data-number="5.2" id="meta.reflection.exception"><span class="header-section-number">5.2</span> [meta.reflection.exception]<a href="#meta.reflection.exception" class="self-link"></a></h2>
<p>Add a new subclause as follows:</p>
<p><strong>Class exception, [meta.reflection.exception]</strong></p>
<div class="std">
<blockquote>
<div class="addu">
<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">class</span> exception <span class="op">:</span> std<span class="op">::</span>exception</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a><span class="kw">private</span><span class="op">:</span></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>  optional<span class="op">&lt;</span>string<span class="op">&gt;</span> <em>what_</em>;   <span class="co">// exposition only</span></span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a>  u8string <em>u8what_</em>;         <span class="co">// exposition only</span></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a>  info <em>from_</em>;               <span class="co">// exposition only</span></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a>  source_location <em>where_</em>;   <span class="co">// exposition only</span></span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb11-10"><a href="#cb11-10" aria-hidden="true" tabindex="-1"></a>  <span class="kw">consteval</span> exception<span class="op">(</span>u8string_view what, info from,</span>
<span id="cb11-11"><a href="#cb11-11" aria-hidden="true" tabindex="-1"></a>    source_location where <span class="op">=</span> source_location<span class="op">::</span>current<span class="op">())</span> <span class="kw">noexcept</span>;</span>
<span id="cb11-12"><a href="#cb11-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-13"><a href="#cb11-13" aria-hidden="true" tabindex="-1"></a>  <span class="kw">consteval</span> exception<span class="op">(</span>string_view what, info from,</span>
<span id="cb11-14"><a href="#cb11-14" aria-hidden="true" tabindex="-1"></a>    source_location where <span class="op">=</span> source_location<span class="op">::</span>current<span class="op">())</span> <span class="kw">noexcept</span>;</span>
<span id="cb11-15"><a href="#cb11-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-16"><a href="#cb11-16" aria-hidden="true" tabindex="-1"></a>  exception<span class="op">(</span>exception <span class="kw">const</span><span class="op">&amp;)</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb11-17"><a href="#cb11-17" aria-hidden="true" tabindex="-1"></a>  exception<span class="op">(</span>exception<span class="op">&amp;&amp;)</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb11-18"><a href="#cb11-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-19"><a href="#cb11-19" aria-hidden="true" tabindex="-1"></a>  exception<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span>exception <span class="kw">const</span><span class="op">&amp;)</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb11-20"><a href="#cb11-20" aria-hidden="true" tabindex="-1"></a>  exception<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span>exception<span class="op">&amp;&amp;)</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb11-21"><a href="#cb11-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-22"><a href="#cb11-22" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> <span class="kw">const</span> <span class="dt">char</span><span class="op">*</span> what<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span> <span class="kw">override</span>;</span>
<span id="cb11-23"><a href="#cb11-23" aria-hidden="true" tabindex="-1"></a>  <span class="kw">consteval</span> u8string_view u8what<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb11-24"><a href="#cb11-24" aria-hidden="true" tabindex="-1"></a>  <span class="kw">consteval</span> info from<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb11-25"><a href="#cb11-25" aria-hidden="true" tabindex="-1"></a>  <span class="kw">consteval</span> source_location where<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb11-26"><a href="#cb11-26" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_1" id="pnum_1">1</a></span>
Reflection functions throw exceptions of type <code class="sourceCode cpp">std<span class="op">::</span>meta<span class="op">::</span>exception</code>
to signal an error. <code class="sourceCode cpp">std<span class="op">::</span>meta<span class="op">::</span>exception</code>
is a consteval-only type.</p>
<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">consteval</span> exception<span class="op">(</span>u8string_view what, info from,</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>    source_location where <span class="op">=</span> source_location<span class="op">::</span>current<span class="op">())</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_2" id="pnum_2">2</a></span>
<em>Effects</em>: Initializes
<code class="sourceCode cpp"><em>u8what_</em></code> with
<code class="sourceCode cpp">what</code>,
<code class="sourceCode cpp"><em>from_</em></code> with
<code class="sourceCode cpp">from</code> and
<code class="sourceCode cpp"><em>where_</em></code> with
<code class="sourceCode cpp">where</code>. If
<code class="sourceCode cpp"><em>what_</em></code> can be represented in
the ordinary literal encoding, initializes
<code class="sourceCode cpp"><em>what_</em></code> with
<code class="sourceCode cpp">what</code>, transcoded from UTF-8 to the
ordinary literal encoding.</p>
<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> exception<span class="op">(</span>string_view what, info from,</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>    source_location where <span class="op">=</span> source_location<span class="op">::</span>current<span class="op">())</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_3" id="pnum_3">3</a></span>
<em>Effects</em>: Initializes
<code class="sourceCode cpp"><em>what_</em></code> with
<code class="sourceCode cpp">what</code>,
<code class="sourceCode cpp"><em>u8what_</em></code> with
<code class="sourceCode cpp">what</code> transcoded from the ordinary
literal encoding to UTF-8,
<code class="sourceCode cpp"><em>from_</em></code> with
<code class="sourceCode cpp">from</code> and
<code class="sourceCode cpp"><em>where_</em></code> with
<code class="sourceCode cpp">where</code>.</p>
<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">constexpr</span> <span class="kw">const</span> <span class="dt">char</span><span class="op">*</span> what<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span> <span class="kw">override</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_4" id="pnum_4">4</a></span>
<em>Constant When</em>: <code class="sourceCode cpp"><em>what_</em><span class="op">.</span>has_value<span class="op">()</span></code>
is <code class="sourceCode cpp"><span class="kw">true</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_5" id="pnum_5">5</a></span>
<em>Returns</em>: <code class="sourceCode cpp"><em>what_</em><span class="op">-&gt;</span>c_str<span class="op">()</span></code>.</p>
<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">consteval</span> u8string_view u8what<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_6" id="pnum_6">6</a></span>
<em>Returns</em>:
<code class="sourceCode cpp"><em>what_</em></code>.</p>
<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> info from<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_7" id="pnum_7">7</a></span>
<em>Returns</em>:
<code class="sourceCode cpp"><em>from_</em></code>.</p>
<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">consteval</span> source_location where<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_8" id="pnum_8">8</a></span>
<em>Returns</em>:
<code class="sourceCode cpp"><em>where_</em></code>.</p>
</div>
</blockquote>
</div>
<h2 data-number="5.3" id="meta.reflection.operators"><span class="header-section-number">5.3</span> [meta.reflection.operators]<a href="#meta.reflection.operators" class="self-link"></a></h2>
<p>Replace the error handling in this subclause:</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> operators operator_of<span class="op">(</span>info r<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_9" id="pnum_9">2</a></span>
<span class="rm" style="color: #bf0303"><del><em>Constant
When</em></del></span> <span class="addu"><em>Throws</em></span>: <span class="addu"><code class="sourceCode cpp">meta<span class="op">::</span>exception</code>
unless</span> <code class="sourceCode cpp">r</code> represents an
operator function or operator function template.</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_10" id="pnum_10">3</a></span>
<em>Returns</em>: The value of the enumerator from
<code class="sourceCode cpp">operators</code> whose corresponding
<code class="sourceCode cpp"><em>operator-function-id</em></code> is the
unqualified name of the entity represented by
<code class="sourceCode cpp">r</code>.</p>
<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="kw">consteval</span> string_view symbol_of<span class="op">(</span>operators op<span class="op">)</span>;</span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> u8string_view u8symbol_of<span class="op">(</span>operators op<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_11" id="pnum_11">4</a></span>
<span class="rm" style="color: #bf0303"><del><em>Constant
When</em></del></span> <span class="addu"><em>Throws</em></span>: <span class="addu"><code class="sourceCode cpp">meta<span class="op">::</span>exception</code>
unless the</span> <span class="rm" style="color: #bf0303"><del>The</del></span> value of
<code class="sourceCode cpp">op</code> corresponds to one of the
enumerators in <code class="sourceCode cpp">operators</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_12" id="pnum_12">5</a></span>
<em>Returns</em>: <code class="sourceCode cpp">string_view</code> or
<code class="sourceCode cpp">u8string_view</code> containing the
characters of the operator symbol name corresponding to
<code class="sourceCode cpp">op</code>, respectively encoded with the
ordinary literal encoding or with UTF-8.</p>
</blockquote>
</div>
<h2 data-number="5.4" id="meta.reflection.names"><span class="header-section-number">5.4</span> [meta.reflection.names]<a href="#meta.reflection.names" class="self-link"></a></h2>
<p>Replace the error handling in this subclause:</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">consteval</span> string_view identifier_of<span class="op">(</span>info r<span class="op">)</span>;</span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> u8string_view u8identifier_of<span class="op">(</span>info r<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_13" id="pnum_13">1</a></span>
Let <em>E</em> be UTF-8 if returning a
<code class="sourceCode cpp">u8string_view</code>, and otherwise the
ordinary literal encoding.</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_14" id="pnum_14">2</a></span>
<span class="rm" style="color: #bf0303"><del><em>Constant
When</em></del></span> <span class="addu"><em>Throws</em></span>: <span class="addu"><code class="sourceCode cpp">meta<span class="op">::</span>exception</code>
unless</span> <code class="sourceCode cpp">has_identifier<span class="op">(</span>r<span class="op">)</span></code>
is <code class="sourceCode cpp"><span class="kw">true</span></code> and
the identifier that would be returned (see below) is representable by
<code class="sourceCode cpp"><em>E</em></code>.</p>
</blockquote>
</div>
<h2 data-number="5.5" id="meta.reflection.queries"><span class="header-section-number">5.5</span> [meta.reflection.queries]<a href="#meta.reflection.queries" class="self-link"></a></h2>
<p>Replace the error handling in this subclause:</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">consteval</span> info type_of<span class="op">(</span>info r<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_15" id="pnum_15">1</a></span>
<span class="rm" style="color: #bf0303"><del><em>Constant
When</em></del></span> <span class="addu"><em>Throws</em></span>: <span class="addu"><code class="sourceCode cpp">meta<span class="op">::</span>exception</code>
unless</span> <code class="sourceCode cpp"><em>has-type</em><span class="op">(</span>r<span class="op">)</span></code>
is <code class="sourceCode cpp"><span class="kw">true</span></code>.</p>
</blockquote>
</div>
<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">consteval</span> info object_of<span class="op">(</span>info r<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_16" id="pnum_16">2</a></span>
<span class="rm" style="color: #bf0303"><del><em>Constant
When</em></del></span> <span class="addu"><em>Throws</em></span>: <span class="addu"><code class="sourceCode cpp">meta<span class="op">::</span>exception</code>
unless</span> <code class="sourceCode cpp">r</code> is a reflection
representing either</p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_17" id="pnum_17">(2.1)</a></span>
an object with static storage duration ([basic.stc.general]), or</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_18" id="pnum_18">(2.2)</a></span>
a variable that either declares or refers to such an object, and if that
variable is a reference <code class="sourceCode cpp"><em>R</em></code>
then either
<ul>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_19" id="pnum_19">(2.2.1)</a></span>
<code class="sourceCode cpp"><em>R</em></code> is usable in constant
expressions ([expr.const]), or</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_20" id="pnum_20">(2.2.2)</a></span>
the lifetime of <code class="sourceCode cpp"><em>R</em></code> began
within the core constant expression currently under evaluation.</li>
</ul></li>
</ul>
</blockquote>
</div>
<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> info value_of<span class="op">(</span>info r<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_21" id="pnum_21">3</a></span>
Let <code class="sourceCode cpp"><em>R</em></code> be a constant
expression of type <code class="sourceCode cpp">info</code> such that
<code class="sourceCode cpp"><em>R</em> <span class="op">==</span> r</code>
is <code class="sourceCode cpp"><span class="kw">true</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_22" id="pnum_22">4</a></span>
<span class="rm" style="color: #bf0303"><del><em>Constant
When</em></del></span> <span class="addu"><em>Throws</em></span>: <span class="addu"><code class="sourceCode cpp">meta<span class="op">::</span>exception</code>
unless</span> <code class="sourceCode cpp"><span class="op">[:</span> <em>R</em> <span class="op">:]</span></code>
is a valid
<code class="sourceCode cpp"><em>splice-expression</em></code>
([expr.prim.splice]).</p>
</blockquote>
</div>
<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> info parent_of<span class="op">(</span>info r<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_23" id="pnum_23">5</a></span>
<span class="rm" style="color: #bf0303"><del><em>Constant
When</em></del></span> <span class="addu"><em>Throws</em></span>: <span class="addu"><code class="sourceCode cpp">meta<span class="op">::</span>exception</code>
unless</span> <code class="sourceCode cpp">has_parent<span class="op">(</span>r<span class="op">)</span></code>
is <code class="sourceCode cpp"><span class="kw">true</span></code>.</p>
</blockquote>
</div>
<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">consteval</span> info template_of<span class="op">(</span>info r<span class="op">)</span>;</span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> vector<span class="op">&lt;</span>info<span class="op">&gt;</span> template_arguments_of<span class="op">(</span>info r<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_24" id="pnum_24">6</a></span>
<span class="rm" style="color: #bf0303"><del><em>Constant
When</em></del></span> <span class="addu"><em>Throws</em></span>: <span class="addu"><code class="sourceCode cpp">meta<span class="op">::</span>exception</code>
unless</span> <code class="sourceCode cpp">has_template_arguments<span class="op">(</span>r<span class="op">)</span></code>
is <code class="sourceCode cpp"><span class="kw">true</span></code>.</p>
</blockquote>
</div>
<h2 data-number="5.6" id="meta.reflection.member.queries"><span class="header-section-number">5.6</span>
[meta.reflection.member.queries]<a href="#meta.reflection.member.queries" class="self-link"></a></h2>
<p>Replace the error handling in this subclause:</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><span class="kw">consteval</span> vector<span class="op">&lt;</span>info<span class="op">&gt;</span> members_of<span class="op">(</span>info r, access_context ctx<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_25" id="pnum_25">1</a></span>
<span class="rm" style="color: #bf0303"><del><em>Constant
When</em></del></span> <span class="addu"><em>Throws</em></span>: <span class="addu"><code class="sourceCode cpp">meta<span class="op">::</span>exception</code>
unless</span> <code class="sourceCode cpp">r</code> is a reflection
representing either a class type that is complete from some point in the
evaluation context or a namespace.</p>
</blockquote>
</div>
<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">consteval</span> vector<span class="op">&lt;</span>info<span class="op">&gt;</span> bases_of<span class="op">(</span>info type, access_context ctx<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_26" id="pnum_26">2</a></span>
<span class="rm" style="color: #bf0303"><del><em>Constant
When</em></del></span> <span class="addu"><em>Throws</em></span>: <span class="addu"><code class="sourceCode cpp">meta<span class="op">::</span>exception</code>
unless</span> <code class="sourceCode cpp">dealias<span class="op">(</span>type<span class="op">)</span></code>
is a reflection representing a complete class type.</p>
</blockquote>
</div>
<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> vector<span class="op">&lt;</span>info<span class="op">&gt;</span> static_data_members_of<span class="op">(</span>info type, access_context ctx<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_27" id="pnum_27">3</a></span>
<span class="rm" style="color: #bf0303"><del><em>Constant
When</em></del></span> <span class="addu"><em>Throws</em></span>: <span class="addu"><code class="sourceCode cpp">meta<span class="op">::</span>exception</code>
unless</span> <code class="sourceCode cpp">dealias<span class="op">(</span>type<span class="op">)</span></code>
represents a complete class type.</p>
</blockquote>
</div>
<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> vector<span class="op">&lt;</span>info<span class="op">&gt;</span> nonstatic_data_members_of<span class="op">(</span>info type, access_context ctx<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_28" id="pnum_28">4</a></span>
<span class="rm" style="color: #bf0303"><del><em>Constant
When</em></del></span> <span class="addu"><em>Throws</em></span>: <span class="addu"><code class="sourceCode cpp">meta<span class="op">::</span>exception</code>
unless</span> <code class="sourceCode cpp">dealias<span class="op">(</span>type<span class="op">)</span></code>
represents a complete class type.</p>
</blockquote>
</div>
<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> vector<span class="op">&lt;</span>info<span class="op">&gt;</span> enumerators_of<span class="op">(</span>info type_enum<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_29" id="pnum_29">5</a></span>
<span class="rm" style="color: #bf0303"><del><em>Constant
When</em></del></span> <span class="addu"><em>Throws</em></span>: <span class="addu"><code class="sourceCode cpp">meta<span class="op">::</span>exception</code>
unless</span> <code class="sourceCode cpp">dealias<span class="op">(</span>type_enum<span class="op">)</span></code>
represents an enumeration type and <code class="sourceCode cpp">is_enumerable_type<span class="op">(</span>type_enum<span class="op">)</span></code>
is <code class="sourceCode cpp"><span class="kw">true</span></code>.</p>
</blockquote>
</div>
<h2 data-number="5.7" id="meta.reflection.layout"><span class="header-section-number">5.7</span> [meta.reflection.layout]<a href="#meta.reflection.layout" class="self-link"></a></h2>
<p>Replace the error handling in this subclause:</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> member_offset offset_of<span class="op">(</span>info r<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_30" id="pnum_30">1</a></span>
<span class="rm" style="color: #bf0303"><del><em>Constant
When</em></del></span> <span class="addu"><em>Throws</em></span>: <span class="addu"><code class="sourceCode cpp">meta<span class="op">::</span>exception</code>
unless</span> <code class="sourceCode cpp">r</code> represents a
non-static data member, unnamed bit-field, or direct base class
relationship other than a virtual base class of an abstract class.</p>
</blockquote>
</div>
<div class="std">
<blockquote>
<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="dt">size_t</span> size_of<span class="op">(</span>info r<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_31" id="pnum_31">2</a></span>
<span class="rm" style="color: #bf0303"><del><em>Constant
When</em></del></span> <span class="addu"><em>Throws</em></span>: <span class="addu"><code class="sourceCode cpp">meta<span class="op">::</span>exception</code>
unless</span> <code class="sourceCode cpp">dealias<span class="op">(</span>r<span class="op">)</span></code>
is a reflection of a type, object, value, variable of non-reference
type, non-static data member that is not a bit-field, direct base class
relationship, or data member description
(<code class="sourceCode cpp"><em>T</em></code>,
<code class="sourceCode cpp"><em>N</em></code>,
<code class="sourceCode cpp"><em>A</em></code>,
<code class="sourceCode cpp"><em>W</em></code>,
<code class="sourceCode cpp"><em>NUA</em></code>) ([class.mem.general])
where <code class="sourceCode cpp"><em>W</em></code> is not ⊥. If <code class="sourceCode cpp">dealias<span class="op">(</span>r<span class="op">)</span></code>
represents a type, then <code class="sourceCode cpp">is_complete_type<span class="op">(</span>r<span class="op">)</span></code>
is <code class="sourceCode cpp"><span class="kw">true</span></code>.</p>
</blockquote>
</div>
<div class="std">
<blockquote>
<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="dt">size_t</span> alignment_of<span class="op">(</span>info r<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_32" id="pnum_32">3</a></span>
<span class="rm" style="color: #bf0303"><del><em>Constant
When</em></del></span> <span class="addu"><em>Throws</em></span>: <span class="addu"><code class="sourceCode cpp">meta<span class="op">::</span>exception</code>
unless</span> <code class="sourceCode cpp">dealias<span class="op">(</span>r<span class="op">)</span></code>
is a reflection representing a type, object, variable of non-reference
type, non-static data member that is not a bit-field, direct base class
relationship, or data member description. If <code class="sourceCode cpp">dealias<span class="op">(</span>r<span class="op">)</span></code>
represents a type, then <code class="sourceCode cpp">is_complete_type<span class="op">(</span>r<span class="op">)</span></code>
is <code class="sourceCode cpp"><span class="kw">true</span></code>.</p>
</blockquote>
</div>
<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="kw">consteval</span> <span class="dt">size_t</span> bit_size_of<span class="op">(</span>info r<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_33" id="pnum_33">4</a></span>
<span class="rm" style="color: #bf0303"><del><em>Constant
When</em></del></span> <span class="addu"><em>Throws</em></span>: <span class="addu"><code class="sourceCode cpp">meta<span class="op">::</span>exception</code>
unless</span> <code class="sourceCode cpp">dealias<span class="op">(</span>r<span class="op">)</span></code>
is a reflection of a type, object, value, variable of non-reference
type, non-static data member, unnamed bit-field, direct base class
relationship, or data member description. If <code class="sourceCode cpp">dealias<span class="op">(</span>r<span class="op">)</span></code>
represents a type <code class="sourceCode cpp"><em>T</em></code>, there
is a point within the evaluation context from which
<code class="sourceCode cpp"><em>T</em></code> is not incomplete.</p>
</blockquote>
</div>
<h2 data-number="5.8" id="meta.reflection.extract"><span class="header-section-number">5.8</span> [meta.reflection.extract]<a href="#meta.reflection.extract" class="self-link"></a></h2>
<p>Replace the error handling in this subclause:</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">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span></span>
<span id="cb35-2"><a href="#cb35-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">consteval</span> T <em>extract-ref</em><span class="op">(</span>info r<span class="op">)</span>; <span class="co">// exposition only</span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_34" id="pnum_34">1</a></span>
<span class="note"><span>[ <em>Note 1:</em>
</span><code class="sourceCode cpp">T</code> is a reference type.<span>
— <em>end note</em> ]</span></span></p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_35" id="pnum_35">2</a></span>
<span class="rm" style="color: #bf0303"><del><em>Constant
When</em></del></span> <span class="addu"><em>Throws</em></span>: <span class="addu"><code class="sourceCode cpp">meta<span class="op">::</span>exception</code>
unless</span></p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_36" id="pnum_36">(2.1)</a></span>
<code class="sourceCode cpp">r</code> represents a variable or object of
type <code class="sourceCode cpp">U</code>,</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_37" id="pnum_37">(2.2)</a></span>
<code class="sourceCode cpp">is_convertible_v<span class="op">&lt;</span>remove_reference_t<span class="op">&lt;</span>U<span class="op">&gt;(*)[]</span>, remove_reference_t<span class="op">&lt;</span>T<span class="op">&gt;(*)[]&gt;</span></code>
is <code class="sourceCode cpp"><span class="kw">true</span></code>, and
<span class="note"><span>[ <em>Note 2:</em> </span>The intent is to
allow only qualification conversions from
<code class="sourceCode cpp">U</code> to
<code class="sourceCode cpp">T</code>.<span> — <em>end
note</em> ]</span></span></li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_38" id="pnum_38">(2.3)</a></span>
if <code class="sourceCode cpp">r</code> represents a variable, then
either that variable is usable in constant expressions or its lifetime
began within the core constant expression currently under
evaluation.</li>
</ul>
</blockquote>
</div>
<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="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span></span>
<span id="cb36-2"><a href="#cb36-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">consteval</span> T <em>extract-member-or-function</em><span class="op">(</span>info r<span class="op">)</span>; <span class="co">// exposition only</span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_39" id="pnum_39">3</a></span>
<span class="rm" style="color: #bf0303"><del><em>Constant
When</em></del></span> <span class="addu"><em>Throws</em></span>: <span class="addu"><code class="sourceCode cpp">meta<span class="op">::</span>exception</code>
unless</span></p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_40" id="pnum_40">(3.1)</a></span>
<code class="sourceCode cpp">r</code> represents a non-static data
member with type <code class="sourceCode cpp">X</code>, that is not a
bit-field, that is a direct member of a class
<code class="sourceCode cpp">C</code> and
<code class="sourceCode cpp">T</code> is
<code class="sourceCode cpp">X C<span class="op">::*</span></code>;</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_41" id="pnum_41">(3.2)</a></span>
<code class="sourceCode cpp">r</code> represents an implicit object
member function with type <code class="sourceCode cpp">F</code> or
<code class="sourceCode cpp">F <span class="kw">noexcept</span></code>
that is a direct member of a class <code class="sourceCode cpp">C</code>
and <code class="sourceCode cpp">T</code> is
<code class="sourceCode cpp">F C<span class="op">::*</span></code>;
or</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_42" id="pnum_42">(3.3)</a></span>
<code class="sourceCode cpp">r</code> represents a non-member function,
static member function, or explicit object member function of function
type <code class="sourceCode cpp">F</code> or
<code class="sourceCode cpp">F <span class="kw">noexcept</span></code>
and <code class="sourceCode cpp">T</code> is
<code class="sourceCode cpp">F<span class="op">*</span></code>.</li>
</ul>
</blockquote>
</div>
<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="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span></span>
<span id="cb37-2"><a href="#cb37-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">consteval</span> T <em>extract-val</em><span class="op">(</span>info r<span class="op">)</span>; <span class="co">// exposition only</span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_43" id="pnum_43">4</a></span>
Let <code class="sourceCode cpp">U</code> be the type of the value that
<code class="sourceCode cpp">r</code> represents.</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_44" id="pnum_44">5</a></span>
<span class="rm" style="color: #bf0303"><del><em>Constant
When</em></del></span> <span class="addu"><em>Throws</em></span>: <span class="addu"><code class="sourceCode cpp">meta<span class="op">::</span>exception</code>
unless</span></p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_45" id="pnum_45">(5.1)</a></span>
<code class="sourceCode cpp">U</code> is a pointer type,
<code class="sourceCode cpp">T</code> and
<code class="sourceCode cpp">U</code> are similar types ([conv.qual]),
and <code class="sourceCode cpp">is_convertible_v<span class="op">&lt;</span>U, T<span class="op">&gt;</span></code>
is
<code class="sourceCode cpp"><span class="kw">true</span></code>,</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_46" id="pnum_46">(5.2)</a></span>
<code class="sourceCode cpp">U</code> is not a pointer type and the
cv-unqualified types of <code class="sourceCode cpp">T</code> and
<code class="sourceCode cpp">U</code> are the same, or</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_47" id="pnum_47">(5.3)</a></span>
<code class="sourceCode cpp">U</code> is a closure type,
<code class="sourceCode cpp">T</code> is a function pointer type, and
the value that <code class="sourceCode cpp">r</code> represents is
convertible to <code class="sourceCode cpp">T</code>.</li>
</ul>
</blockquote>
</div>
<h2 data-number="5.9" id="meta.reflection.substitute"><span class="header-section-number">5.9</span> [meta.reflection.substitute]<a href="#meta.reflection.substitute" class="self-link"></a></h2>
<p>Replace the error handling in this subclause:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb38"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb38-1"><a href="#cb38-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span>reflection_range R <span class="op">=</span> initializer_list<span class="op">&lt;</span>info<span class="op">&gt;&gt;</span></span>
<span id="cb38-2"><a href="#cb38-2" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="dt">bool</span> can_substitute<span class="op">(</span>info templ, R<span class="op">&amp;&amp;</span> arguments<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_48" id="pnum_48">1</a></span>
<span class="rm" style="color: #bf0303"><del><em>Constant
When</em></del></span> <span class="addu"><em>Throws</em></span>: <span class="addu"><code class="sourceCode cpp">meta<span class="op">::</span>exception</code>
unless</span> <code class="sourceCode cpp">templ</code> represents a
template and every reflection in
<code class="sourceCode cpp">arguments</code> represents a construct
usable as a template argument ([temp.arg]).</p>
</blockquote>
</div>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb39"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb39-1"><a href="#cb39-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span>reflection_range R <span class="op">=</span> initializer_list<span class="op">&lt;</span>info<span class="op">&gt;&gt;</span></span>
<span id="cb39-2"><a href="#cb39-2" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> info substitute<span class="op">(</span>info templ, R<span class="op">&amp;&amp;</span> arguments<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_49" id="pnum_49">2</a></span>
<span class="rm" style="color: #bf0303"><del><em>Constant
When</em></del></span> <span class="addu"><em>Throws</em></span>: <span class="addu"><code class="sourceCode cpp">meta<span class="op">::</span>exception</code>
unless</span> <code class="sourceCode cpp">can_substitute<span class="op">(</span>templ, arguments<span class="op">)</span></code>
is <code class="sourceCode cpp"><span class="kw">true</span></code>.</p>
</blockquote>
</div>
<h2 data-number="5.10" id="meta.reflection.result"><span class="header-section-number">5.10</span> [meta.reflection.result]<a href="#meta.reflection.result" class="self-link"></a></h2>
<p>Replace the error handling in this subclause:</p>
<div class="std">
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_50" id="pnum_50">1</a></span>
An object <code class="sourceCode cpp"><em>O</em></code> of type
<code class="sourceCode cpp"><em>T</em></code> is
<em>meta-reflectable</em> if an lvalue expression denoting
<code class="sourceCode cpp"><em>O</em></code> is suitable for use as a
constant template argument for a constant template parameter of type
<code class="sourceCode cpp"><em>T</em><span class="op">&amp;</span></code>
([temp.arg.nontype]).</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_51" id="pnum_51">2</a></span>
The following are defined for exposition only to aid in the
specification of <code class="sourceCode cpp">reflect_value</code>:</p>
<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">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb40-2"><a href="#cb40-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">consteval</span> info <em>reflect-value-scalar</em><span class="op">(</span>T expr<span class="op">)</span>; <span class="co">// exposition only</span></span></code></pre></div>
<p>Let <code class="sourceCode cpp"><em>V</em></code> be the value
computed by an lvalue-to-rvalue conversion applied to
<code class="sourceCode cpp">expr</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_52" id="pnum_52">3</a></span>
<span class="rm" style="color: #bf0303"><del><em>Constant
When</em></del></span> <span class="addu"><em>Throws</em></span>: <span class="addu"><code class="sourceCode cpp">meta<span class="op">::</span>exception</code>
unless</span> <code class="sourceCode cpp"><em>V</em></code> satisfies
the constraints for the result of a prvalue constant expression
([expr.const]) and, if <code class="sourceCode cpp"><em>V</em></code> is
a pointer to an object, then that object is meta-reflectable.</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_53" id="pnum_53">4</a></span>
<em>Returns</em>: A reflection of a value of type
<code class="sourceCode cpp"><em>T</em></code> associated with the
computed value <code class="sourceCode cpp"><em>V</em></code>.</p>
<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">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb41-2"><a href="#cb41-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">consteval</span> info <em>reflect-value-class</em><span class="op">(</span>T <span class="kw">const</span><span class="op">&amp;</span> expr<span class="op">)</span>; <span class="co">// exposition only</span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_54" id="pnum_54">5</a></span>
<em>Mandates</em>: <code class="sourceCode cpp">T</code> is copy
constructible and structural ([temp.param]).</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_55" id="pnum_55">6</a></span>
Let <code class="sourceCode cpp"><em>O</em></code> be an object
copy-initialized from <code class="sourceCode cpp">expr</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_56" id="pnum_56">7</a></span>
<span class="rm" style="color: #bf0303"><del><em>Constant
When</em></del></span> <span class="addu"><em>Throws</em></span>: <span class="addu"><code class="sourceCode cpp">meta<span class="op">::</span>exception</code>
unless</span></p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_57" id="pnum_57">(7.1)</a></span>
<code class="sourceCode cpp"><em>O</em></code> satisfies the constraints
for the result of a glvalue constant expression ([expr.const]),</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_58" id="pnum_58">(7.2)</a></span>
every object referred to by a constituent reference of
<code class="sourceCode cpp"><em>O</em></code>, or pointed to by a
constituent pointer value of
<code class="sourceCode cpp"><em>O</em></code>, is
meta-reflectable.</li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_59" id="pnum_59">8</a></span>
<em>Returns</em>: A reflection of a value of type
<code class="sourceCode cpp">T</code> associated with a template
parameter object that is template-argument-equivalent to
<code class="sourceCode cpp"><em>O</em></code>.</p>
<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">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb42-2"><a href="#cb42-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">consteval</span> info reflect_value<span class="op">(</span><span class="kw">const</span> T<span class="op">&amp;</span> expr<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_60" id="pnum_60">*</a></span>
<em>Effects</em>: […]</p>
<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">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb43-2"><a href="#cb43-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">consteval</span> info reflect_object<span class="op">(</span>T<span class="op">&amp;</span> expr<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_61" id="pnum_61">9</a></span>
<em>Mandates</em>: <code class="sourceCode cpp">T</code> is not a
function type.</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_62" id="pnum_62">10</a></span>
<span class="rm" style="color: #bf0303"><del><em>Constant
When</em></del></span> <span class="addu"><em>Throws</em></span>: <span class="addu"><code class="sourceCode cpp">meta<span class="op">::</span>exception</code>
unless</span> <code class="sourceCode cpp">expr</code> designates a
meta-reflectable object.</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_63" id="pnum_63">11</a></span>
<em>Returns</em>: A reflection of the object designated by
<code class="sourceCode cpp">expr</code>.</p>
</blockquote>
</div>
<h2 data-number="5.11" id="meta.reflection.define.aggregate"><span class="header-section-number">5.11</span>
[meta.reflection.define.aggregate]<a href="#meta.reflection.define.aggregate" class="self-link"></a></h2>
<p>Replace the error handling in this subclause:</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="kw">consteval</span> info data_member_spec<span class="op">(</span>info type,</span>
<span id="cb44-2"><a href="#cb44-2" aria-hidden="true" tabindex="-1"></a>                                data_member_options options<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_64" id="pnum_64">1</a></span>
<span class="rm" style="color: #bf0303"><del><em>Constant
When</em></del></span> <span class="addu"><em>Throws</em></span>: <span class="addu"><code class="sourceCode cpp">meta<span class="op">::</span>exception</code>
unless the following conditions are met:</span></p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_65" id="pnum_65">(1.1)</a></span>
<code class="sourceCode cpp">dealias<span class="op">(</span>type<span class="op">)</span></code>
represents a type <code class="sourceCode cpp">cv <em>T</em></code>
where <code class="sourceCode cpp"><em>T</em></code> is either an object
type or a reference type;</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_66" id="pnum_66">(1.2)</a></span>
if
<code class="sourceCode cpp">options<span class="op">.</span>name</code>
contains a value, then:
<ul>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_67" id="pnum_67">(1.2.1)</a></span>
<code class="sourceCode cpp">holds_alternative<span class="op">&lt;</span>u8string<span class="op">&gt;(</span>options<span class="op">.</span>name<span class="op">-&gt;</span><em>contents</em><span class="op">)</span></code>
is <code class="sourceCode cpp"><span class="kw">true</span></code> and
<code class="sourceCode cpp">get<span class="op">&lt;</span>u8string<span class="op">&gt;(</span>options<span class="op">.</span>name<span class="op">-&gt;</span><em>contents</em><span class="op">)</span></code>
contains a valid identifier when interpreted with UTF-8, or</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_68" id="pnum_68">(1.2.2)</a></span>
<code class="sourceCode cpp">holds_alternative<span class="op">&lt;</span>string<span class="op">&gt;(</span>options<span class="op">.</span>name<span class="op">-&gt;</span><em>contents</em><span class="op">)</span></code>
is <code class="sourceCode cpp"><span class="kw">true</span></code> and
<code class="sourceCode cpp">get<span class="op">&lt;</span>string<span class="op">&gt;(</span>options<span class="op">.</span>name<span class="op">-&gt;</span><em>contents</em><span class="op">)</span></code>
contains a valid identifier when interpreted with the ordinary literal
encoding;</li>
</ul></li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_69" id="pnum_69">(1.3)</a></span>
otherwise, if
<code class="sourceCode cpp">options<span class="op">.</span>name</code>
does not contain a value, then <code class="sourceCode cpp">options<span class="op">.</span>bit_width</code>
contains a value;</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_70" id="pnum_70">(1.4)</a></span>
if <code class="sourceCode cpp">options<span class="op">.</span>alignment</code>
contains a value, it is an alignment value ([basic.align]) not less than
<code class="sourceCode cpp">alignment_of<span class="op">(</span>type<span class="op">)</span></code>;
and</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_71" id="pnum_71">(1.5)</a></span>
if <code class="sourceCode cpp">options<span class="op">.</span>bit_width</code>
contains a value <code class="sourceCode cpp"><em>V</em></code>, then
<ul>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_72" id="pnum_72">(1.5.1)</a></span>
<code class="sourceCode cpp">is_integral_type<span class="op">(</span>type<span class="op">)</span> <span class="op">||</span> is_enumeration_type<span class="op">(</span>type<span class="op">)</span></code>
is
<code class="sourceCode cpp"><span class="kw">true</span></code>,</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_73" id="pnum_73">(1.5.2)</a></span>
<code class="sourceCode cpp">options<span class="op">.</span>alignment</code>
does not contain a value,</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_74" id="pnum_74">(1.5.3)</a></span>
<code class="sourceCode cpp">options<span class="op">.</span>no_unique_address</code>
is <code class="sourceCode cpp"><span class="kw">false</span></code>,
and</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_75" id="pnum_75">(1.5.4)</a></span>
if <code class="sourceCode cpp"><em>V</em></code> equals
<code class="sourceCode cpp"><span class="dv">0</span></code> then
<code class="sourceCode cpp">options<span class="op">.</span>name</code>
does not contain a value.</li>
</ul></li>
</ul>
</blockquote>
</div>
<h2 data-number="5.12" id="meta.reflection.traits"><span class="header-section-number">5.12</span> [meta.reflection.traits]<a href="#meta.reflection.traits" class="self-link"></a></h2>
<p>Replace the error handling for all the type traits:</p>
<div class="std">
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_76" id="pnum_76">1</a></span>
Subclause [meta.reflection.traits] specifies consteval functions to
query the properties of types ([meta.unary]), query the relationships
between types ([meta.rel]), or transform types ([meta.trans]) at compile
time. Each consteval function declared in this class has an associated
class template declared elsewhere in this document.</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_77" id="pnum_77">2</a></span>
Every function and function template declared in this clause <span class="rm" style="color: #bf0303"><del>has the following conditions
required for a call to that function or function template to be a
constant subexpression ([defns.const.subexpr])</del></span> <span class="addu">throws an exception of type <code class="sourceCode cpp">std<span class="op">::</span>meta<span class="op">::</span>exception</code>
unless the following conditions hold:</span></p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_78" id="pnum_78">(2.1)</a></span>
For every parameter <code class="sourceCode cpp">p</code> of type
<code class="sourceCode cpp">info</code>, <code class="sourceCode cpp">is_type<span class="op">(</span>p<span class="op">)</span></code>
is
<code class="sourceCode cpp"><span class="kw">true</span></code>.</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_79" id="pnum_79">(2.2)</a></span>
For every parameter <code class="sourceCode cpp">r</code> whose type is
constrained on <code class="sourceCode cpp">reflection_range</code>,
<code class="sourceCode cpp">ranges<span class="op">::</span>all_of<span class="op">(</span>r, is_type<span class="op">)</span></code>
is
<code class="sourceCode cpp"><span class="kw">true</span></code>.</li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_80" id="pnum_80">3</a></span>
[…]</p>
</blockquote>
</div>
<h2 data-number="5.13" id="feature-test-macro"><span class="header-section-number">5.13</span> Feature-Test Macro<a href="#feature-test-macro" class="self-link"></a></h2>
<p>Bump <code class="sourceCode cpp">__cpp_lib_reflection</code> in
<span>17.3.2 <a href="https://wg21.link/version.syn">[version.syn]</a></span> (which
isn’t there yet) to some new value:</p>
<div class="std">
<blockquote>
<div>
<div class="sourceCode" id="cb45"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb45-1"><a href="#cb45-1" aria-hidden="true" tabindex="-1"></a><span class="va">+ #define __cpp_lib_reflection 2025XXL // also in &lt;meta&gt;</span></span></code></pre></div>
</div>
</blockquote>
</div>
<h1 data-number="6" style="border-bottom:1px solid #cccccc" id="bibliography"><span class="header-section-number">6</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-LWG4087" class="csl-entry" role="doc-biblioentry">
[LWG4087] Victor Zverovich. Standard exception messages have unspecified
encoding. <a href="https://wg21.link/lwg4087"><div class="csl-block">https://wg21.link/lwg4087</div></a>
</div>
<div id="ref-P2996R12" class="csl-entry" role="doc-biblioentry">
[P2996R12] Barry Revzin, Wyatt Childers, Peter Dimov, Andrew Sutton,
Faisal Vali, Daveed Vandevoorde, and Dan Katz. 2025-05-11. Reflection
for C++26. <a href="https://wg21.link/p2996r12"><div class="csl-block">https://wg21.link/p2996r12</div></a>
</div>
<div id="ref-P3068R6" class="csl-entry" role="doc-biblioentry">
[P3068R6] Hana Dusíková. 2024-11-19. Allowing exception throwing in
constant-evaluation. <a href="https://wg21.link/p3068r6"><div class="csl-block">https://wg21.link/p3068r6</div></a>
</div>
<div id="ref-P3560R0" class="csl-entry" role="doc-biblioentry">
[P3560R0] Barry Revzin, Peter Dimov. 2025-01-12. Error Handling in
Reflection. <a href="https://wg21.link/p3560r0"><div class="csl-block">https://wg21.link/p3560r0</div></a>
</div>
<div id="ref-P3637R0" class="csl-entry" role="doc-biblioentry">
[P3637R0] Victor Zverovich, Nevin Liber, Michael Hava. 2025-03-08.
Inherit std::meta::exception from std::exception. <a href="https://wg21.link/p3637r0"><div class="csl-block">https://wg21.link/p3637r0</div></a>
</div>
</div>
</div>
</div>
</body>
</html>
