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

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

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

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

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

div.rm pre, div.add pre { background-color: #f6f8fa; }
div.addu pre { background-color: var(--diff-ins); }
div.add, div.add pre { 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); }
</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">Missing <code class="sourceCode cpp"><span class="kw">constexpr</span></code> in <code class="sourceCode cpp">std<span class="op">::</span>optional</code> and <code class="sourceCode cpp">std<span class="op">::</span>variant</code></h1>

<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P2231R0</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2020-10-08</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>
      LEWG<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to:</td>
    <td>
      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">
<h1 data-number="1" style="border-bottom:1px solid #cccccc" id="introduction" data-number="1" style="border-bottom:1px solid #cccccc"><span class="header-section-number">1</span> Introduction<a href="#introduction" class="self-link"></a></h1>
<p>Each new language standard has increased the kinds of operations that we can do during constant evaluation time. C++20 was no different. With the adoption of <span class="citation" data-cites="P1330R0">[<a href="#ref-P1330R0" role="doc-biblioref">P1330R0</a>]</span>, C++20 added the ability to change the active member of a union inside constexpr (the paper specifically mentions <code class="sourceCode cpp">std<span class="op">::</span>optional</code>). And with the adoption of <span class="citation" data-cites="P0784R7">[<a href="#ref-P0784R7" role="doc-biblioref">P0784R7</a>]</span>, C++20 added the ability to do placement new inside constexpr (by way of <code class="sourceCode cpp">std<span class="op">::</span>construct_at</code>).</p>
<p>But even though the language provided the tools to make <code class="sourceCode cpp">std<span class="op">::</span>optional</code> and <code class="sourceCode cpp">std<span class="op">::</span>variant</code> completely constexpr-able, there was no such update to the library. This paper seeks to remedy that omission by simply adding <code class="sourceCode cpp"><span class="kw">constexpr</span></code> to all the relevant places.</p>
<h2 data-number="1.1" id="implementing-stdoptional" data-number="1.1"><span class="header-section-number">1.1</span> Implementing <code class="sourceCode cpp">std<span class="op">::</span>optional</code><a href="#implementing-stdoptional" class="self-link"></a></h2>
<p>I updated libstdc++’s implementation of <code class="sourceCode cpp">std<span class="op">::</span>optional</code> to add these <code class="sourceCode cpp"><span class="kw">constexpr</span></code>s (and replace the placement <code class="sourceCode cpp"><span class="kw">new</span></code> calls with calls to <code class="sourceCode cpp">std<span class="op">::</span>construct_at</code>) as follows, which compiles with both gcc and clang (<a href="https://godbolt.org/z/fE6aob">demo</a>):</p>
<div>
<div class="sourceCode" id="cb1"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb1-1"><a href="#cb1-1"></a><span class="dt">-13,6 +11,7</span></span>
<span id="cb1-2"><a href="#cb1-2"></a> #include &lt;bits/exception_defines.h&gt;</span>
<span id="cb1-3"><a href="#cb1-3"></a> #include &lt;bits/functional_hash.h&gt;</span>
<span id="cb1-4"><a href="#cb1-4"></a> #include &lt;bits/enable_special_members.h&gt;</span>
<span id="cb1-5"><a href="#cb1-5"></a><span class="va">+#include &lt;bits/stl_construct.h&gt;</span></span>
<span id="cb1-6"><a href="#cb1-6"></a> #if __cplusplus &gt; 201703L</span>
<span id="cb1-7"><a href="#cb1-7"></a> # include &lt;compare&gt;</span>
<span id="cb1-8"><a href="#cb1-8"></a> #endif</span>
<span id="cb1-9"><a href="#cb1-9"></a><span class="dt">-206,7 +205,7</span></span>
<span id="cb1-10"><a href="#cb1-10"></a>         { }</span>
<span id="cb1-11"><a href="#cb1-11"></a> </span>
<span id="cb1-12"><a href="#cb1-12"></a>         // User-provided destructor is needed when _Up has non-trivial dtor.</span>
<span id="cb1-13"><a href="#cb1-13"></a><span class="st">-        ~_Storage() { }</span></span>
<span id="cb1-14"><a href="#cb1-14"></a><span class="va">+        constexpr ~_Storage() { }</span></span>
<span id="cb1-15"><a href="#cb1-15"></a> </span>
<span id="cb1-16"><a href="#cb1-16"></a>         _Empty_byte _M_empty;</span>
<span id="cb1-17"><a href="#cb1-17"></a>         _Up _M_value;</span>
<span id="cb1-18"><a href="#cb1-18"></a><span class="dt">-217,12 +216,12</span></span>
<span id="cb1-19"><a href="#cb1-19"></a>     bool _M_engaged = false;</span>
<span id="cb1-20"><a href="#cb1-20"></a> </span>
<span id="cb1-21"><a href="#cb1-21"></a>     template&lt;typename... _Args&gt;</span>
<span id="cb1-22"><a href="#cb1-22"></a><span class="st">-    void</span></span>
<span id="cb1-23"><a href="#cb1-23"></a><span class="va">+    constexpr void</span></span>
<span id="cb1-24"><a href="#cb1-24"></a>     _M_construct(_Args&amp;&amp;... __args)</span>
<span id="cb1-25"><a href="#cb1-25"></a>     noexcept(is_nothrow_constructible_v&lt;_Stored_type, _Args...&gt;)</span>
<span id="cb1-26"><a href="#cb1-26"></a>     {</span>
<span id="cb1-27"><a href="#cb1-27"></a><span class="st">-        ::new ((void *) std::__addressof(this-&gt;_M_payload))</span></span>
<span id="cb1-28"><a href="#cb1-28"></a><span class="st">-        _Stored_type(std::forward&lt;_Args&gt;(__args)...);</span></span>
<span id="cb1-29"><a href="#cb1-29"></a><span class="va">+        std::construct_at(std::__addressof(this-&gt;_M_payload),</span></span>
<span id="cb1-30"><a href="#cb1-30"></a><span class="va">+            std::forward&lt;_Args&gt;(__args)...);</span></span>
<span id="cb1-31"><a href="#cb1-31"></a>         this-&gt;_M_engaged = true;</span>
<span id="cb1-32"><a href="#cb1-32"></a>     }</span>
<span id="cb1-33"><a href="#cb1-33"></a> </span>
<span id="cb1-34"><a href="#cb1-34"></a><span class="dt">-371,7 +370,7</span></span>
<span id="cb1-35"><a href="#cb1-35"></a>     _Optional_payload&amp; operator=(_Optional_payload&amp;&amp;) = default;</span>
<span id="cb1-36"><a href="#cb1-36"></a> </span>
<span id="cb1-37"><a href="#cb1-37"></a>     // Destructor needs to destroy the contained value:</span>
<span id="cb1-38"><a href="#cb1-38"></a><span class="st">-    ~_Optional_payload()</span></span>
<span id="cb1-39"><a href="#cb1-39"></a><span class="va">+    constexpr ~_Optional_payload()</span></span>
<span id="cb1-40"><a href="#cb1-40"></a>     {</span>
<span id="cb1-41"><a href="#cb1-41"></a>         this-&gt;_M_reset();</span>
<span id="cb1-42"><a href="#cb1-42"></a>     }</span>
<span id="cb1-43"><a href="#cb1-43"></a><span class="dt">-388,17 +387,16</span></span>
<span id="cb1-44"><a href="#cb1-44"></a>     // The _M_construct operation has !_M_engaged as a precondition</span>
<span id="cb1-45"><a href="#cb1-45"></a>     // while _M_destruct has _M_engaged as a precondition.</span>
<span id="cb1-46"><a href="#cb1-46"></a>     template&lt;typename... _Args&gt;</span>
<span id="cb1-47"><a href="#cb1-47"></a><span class="st">-    void</span></span>
<span id="cb1-48"><a href="#cb1-48"></a><span class="va">+    constexpr void</span></span>
<span id="cb1-49"><a href="#cb1-49"></a>     _M_construct(_Args&amp;&amp;... __args)</span>
<span id="cb1-50"><a href="#cb1-50"></a>     noexcept(is_nothrow_constructible_v&lt;_Stored_type, _Args...&gt;)</span>
<span id="cb1-51"><a href="#cb1-51"></a>     {</span>
<span id="cb1-52"><a href="#cb1-52"></a><span class="st">-        ::new</span></span>
<span id="cb1-53"><a href="#cb1-53"></a><span class="st">-        (std::__addressof(static_cast&lt;_Dp*&gt;(this)-&gt;_M_payload._M_payload))</span></span>
<span id="cb1-54"><a href="#cb1-54"></a><span class="st">-        _Stored_type(std::forward&lt;_Args&gt;(__args)...);</span></span>
<span id="cb1-55"><a href="#cb1-55"></a><span class="va">+        std::construct_at(std::__addressof(static_cast&lt;_Dp*&gt;(this)-&gt;_M_payload._M_payload._M_value),</span></span>
<span id="cb1-56"><a href="#cb1-56"></a><span class="va">+            std::forward&lt;_Args&gt;(__args)...);</span></span>
<span id="cb1-57"><a href="#cb1-57"></a>         static_cast&lt;_Dp*&gt;(this)-&gt;_M_payload._M_engaged = true;</span>
<span id="cb1-58"><a href="#cb1-58"></a>     }</span>
<span id="cb1-59"><a href="#cb1-59"></a> </span>
<span id="cb1-60"><a href="#cb1-60"></a><span class="st">-    void</span></span>
<span id="cb1-61"><a href="#cb1-61"></a><span class="va">+    constexpr void</span></span>
<span id="cb1-62"><a href="#cb1-62"></a>     _M_destruct() noexcept</span>
<span id="cb1-63"><a href="#cb1-63"></a>     {</span>
<span id="cb1-64"><a href="#cb1-64"></a>         static_cast&lt;_Dp*&gt;(this)-&gt;_M_payload._M_destroy();</span>
<span id="cb1-65"><a href="#cb1-65"></a><span class="dt">-754,7 +752,7</span></span>
<span id="cb1-66"><a href="#cb1-66"></a>         : _Base(std::in_place, __il, std::forward&lt;_Args&gt;(__args)...) { }</span>
<span id="cb1-67"><a href="#cb1-67"></a> </span>
<span id="cb1-68"><a href="#cb1-68"></a>     // Assignment operators.</span>
<span id="cb1-69"><a href="#cb1-69"></a><span class="st">-    optional&amp;</span></span>
<span id="cb1-70"><a href="#cb1-70"></a><span class="va">+    constexpr optional&amp;</span></span>
<span id="cb1-71"><a href="#cb1-71"></a>     operator=(nullopt_t) noexcept</span>
<span id="cb1-72"><a href="#cb1-72"></a>     {</span>
<span id="cb1-73"><a href="#cb1-73"></a>         this-&gt;_M_reset();</span>
<span id="cb1-74"><a href="#cb1-74"></a><span class="dt">-762,6 +760,7</span></span>
<span id="cb1-75"><a href="#cb1-75"></a>     }</span>
<span id="cb1-76"><a href="#cb1-76"></a> </span>
<span id="cb1-77"><a href="#cb1-77"></a>     template&lt;typename _Up = _Tp&gt;</span>
<span id="cb1-78"><a href="#cb1-78"></a><span class="va">+    constexpr</span></span>
<span id="cb1-79"><a href="#cb1-79"></a>     enable_if_t&lt;__and_v&lt;__not_self&lt;_Up&gt;,</span>
<span id="cb1-80"><a href="#cb1-80"></a>                         __not_&lt;__and_&lt;is_scalar&lt;_Tp&gt;,</span>
<span id="cb1-81"><a href="#cb1-81"></a>                                       is_same&lt;_Tp, decay_t&lt;_Up&gt;&gt;&gt;&gt;,</span>
<span id="cb1-82"><a href="#cb1-82"></a><span class="dt">-780,6 +779,7</span></span>
<span id="cb1-83"><a href="#cb1-83"></a>     }</span>
<span id="cb1-84"><a href="#cb1-84"></a> </span>
<span id="cb1-85"><a href="#cb1-85"></a>     template&lt;typename _Up&gt;</span>
<span id="cb1-86"><a href="#cb1-86"></a><span class="va">+    constexpr</span></span>
<span id="cb1-87"><a href="#cb1-87"></a>     enable_if_t&lt;__and_v&lt;__not_&lt;is_same&lt;_Tp, _Up&gt;&gt;,</span>
<span id="cb1-88"><a href="#cb1-88"></a>                         is_constructible&lt;_Tp, const _Up&amp;&gt;,</span>
<span id="cb1-89"><a href="#cb1-89"></a>                         is_assignable&lt;_Tp&amp;, _Up&gt;,</span>
<span id="cb1-90"><a href="#cb1-90"></a><span class="dt">-801,6 +801,7</span></span>
<span id="cb1-91"><a href="#cb1-91"></a>     }</span>
<span id="cb1-92"><a href="#cb1-92"></a> </span>
<span id="cb1-93"><a href="#cb1-93"></a>     template&lt;typename _Up&gt;</span>
<span id="cb1-94"><a href="#cb1-94"></a><span class="va">+    constexpr</span></span>
<span id="cb1-95"><a href="#cb1-95"></a>     enable_if_t&lt;__and_v&lt;__not_&lt;is_same&lt;_Tp, _Up&gt;&gt;,</span>
<span id="cb1-96"><a href="#cb1-96"></a>                         is_constructible&lt;_Tp, _Up&gt;,</span>
<span id="cb1-97"><a href="#cb1-97"></a>                         is_assignable&lt;_Tp&amp;, _Up&gt;,</span>
<span id="cb1-98"><a href="#cb1-98"></a><span class="dt">-823,6 +824,7</span></span>
<span id="cb1-99"><a href="#cb1-99"></a>     }</span>
<span id="cb1-100"><a href="#cb1-100"></a> </span>
<span id="cb1-101"><a href="#cb1-101"></a>     template&lt;typename... _Args&gt;</span>
<span id="cb1-102"><a href="#cb1-102"></a><span class="va">+    constexpr</span></span>
<span id="cb1-103"><a href="#cb1-103"></a>     enable_if_t&lt;is_constructible_v&lt;_Tp, _Args&amp;&amp;...&gt;, _Tp&amp;&gt;</span>
<span id="cb1-104"><a href="#cb1-104"></a>     emplace(_Args&amp;&amp;... __args)</span>
<span id="cb1-105"><a href="#cb1-105"></a>     {</span>
<span id="cb1-106"><a href="#cb1-106"></a><span class="dt">-832,6 +834,7</span></span>
<span id="cb1-107"><a href="#cb1-107"></a>     }</span>
<span id="cb1-108"><a href="#cb1-108"></a> </span>
<span id="cb1-109"><a href="#cb1-109"></a>     template&lt;typename _Up, typename... _Args&gt;</span>
<span id="cb1-110"><a href="#cb1-110"></a><span class="va">+    constexpr</span></span>
<span id="cb1-111"><a href="#cb1-111"></a>     enable_if_t&lt;is_constructible_v&lt;_Tp, initializer_list&lt;_Up&gt;&amp;,</span>
<span id="cb1-112"><a href="#cb1-112"></a>                                    _Args&amp;&amp;...&gt;, _Tp&amp;&gt;</span>
<span id="cb1-113"><a href="#cb1-113"></a>     emplace(initializer_list&lt;_Up&gt; __il, _Args&amp;&amp;... __args)</span>
<span id="cb1-114"><a href="#cb1-114"></a><span class="dt">-844,7 +847,7</span></span>
<span id="cb1-115"><a href="#cb1-115"></a>     // Destructor is implicit, implemented in _Optional_base.</span>
<span id="cb1-116"><a href="#cb1-116"></a> </span>
<span id="cb1-117"><a href="#cb1-117"></a>     // Swap.</span>
<span id="cb1-118"><a href="#cb1-118"></a><span class="st">-    void</span></span>
<span id="cb1-119"><a href="#cb1-119"></a><span class="va">+    constexpr void</span></span>
<span id="cb1-120"><a href="#cb1-120"></a>     swap(optional&amp; __other)</span>
<span id="cb1-121"><a href="#cb1-121"></a>     noexcept(is_nothrow_move_constructible_v&lt;_Tp&gt;</span>
<span id="cb1-122"><a href="#cb1-122"></a>              &amp;&amp; is_nothrow_swappable_v&lt;_Tp&gt;)</span>
<span id="cb1-123"><a href="#cb1-123"></a><span class="dt">-957,7 +960,7</span></span>
<span id="cb1-124"><a href="#cb1-124"></a>         : static_cast&lt;_Tp&gt;(std::forward&lt;_Up&gt;(__u));</span>
<span id="cb1-125"><a href="#cb1-125"></a>     }</span>
<span id="cb1-126"><a href="#cb1-126"></a> </span>
<span id="cb1-127"><a href="#cb1-127"></a><span class="st">-    void reset() noexcept</span></span>
<span id="cb1-128"><a href="#cb1-128"></a><span class="va">+    constexpr void reset() noexcept</span></span>
<span id="cb1-129"><a href="#cb1-129"></a>     {</span>
<span id="cb1-130"><a href="#cb1-130"></a>         this-&gt;_M_reset();</span>
<span id="cb1-131"><a href="#cb1-131"></a>     }</span>
<span id="cb1-132"><a href="#cb1-132"></a><span class="dt">-1187,7 +1190,7</span></span>
<span id="cb1-133"><a href="#cb1-133"></a> // _GLIBCXX_RESOLVE_LIB_DEFECTS</span>
<span id="cb1-134"><a href="#cb1-134"></a> // 2748. swappable traits for optionals</span>
<span id="cb1-135"><a href="#cb1-135"></a> template&lt;typename _Tp&gt;</span>
<span id="cb1-136"><a href="#cb1-136"></a><span class="st">-inline enable_if_t&lt;is_move_constructible_v&lt;_Tp&gt; &amp;&amp; is_swappable_v&lt;_Tp&gt;&gt;</span></span>
<span id="cb1-137"><a href="#cb1-137"></a><span class="va">+constexpr inline enable_if_t&lt;is_move_constructible_v&lt;_Tp&gt; &amp;&amp; is_swappable_v&lt;_Tp&gt;&gt;</span></span>
<span id="cb1-138"><a href="#cb1-138"></a> swap(optional&lt;_Tp&gt;&amp; __lhs, optional&lt;_Tp&gt;&amp; __rhs)</span>
<span id="cb1-139"><a href="#cb1-139"></a> noexcept(noexcept(__lhs.swap(__rhs))) {</span>
<span id="cb1-140"><a href="#cb1-140"></a>     __lhs.swap(__rhs);</span></code></pre></div>
</div>
<h2 data-number="1.2" id="implementing-stdvariant" data-number="1.2"><span class="header-section-number">1.2</span> Implementing <code class="sourceCode cpp">std<span class="op">::</span>variant</code><a href="#implementing-stdvariant" class="self-link"></a></h2>
<p>And likewise, here is a diff against libstdc++’s implementation of <code class="sourceCode cpp">std<span class="op">::</span>variant</code> for the changes proposed in this paper, which also compiles on both gcc and clang (<a href="https://godbolt.org/z/E5dcj9">demo</a>). This is slightly more complicated as we have to take more care with constructing and accessing the recursive union:</p>
<div>
<div class="sourceCode" id="cb2"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb2-1"><a href="#cb2-1"></a><span class="dt">-121,7 +121,7</span></span>
<span id="cb2-2"><a href="#cb2-2"></a> __do_visit(_Visitor&amp;&amp; __visitor, _Variants&amp;&amp;... __variants);</span>
<span id="cb2-3"><a href="#cb2-3"></a> </span>
<span id="cb2-4"><a href="#cb2-4"></a> template &lt;typename... _Types, typename _Tp&gt;</span>
<span id="cb2-5"><a href="#cb2-5"></a><span class="st">-decltype(auto)</span></span>
<span id="cb2-6"><a href="#cb2-6"></a><span class="va">+constexpr decltype(auto)</span></span>
<span id="cb2-7"><a href="#cb2-7"></a> __variant_cast(_Tp&amp;&amp; __rhs) {</span>
<span id="cb2-8"><a href="#cb2-8"></a>     if constexpr (is_lvalue_reference_v&lt;_Tp&gt;) {</span>
<span id="cb2-9"><a href="#cb2-9"></a>         if constexpr (is_const_v&lt;remove_reference_t&lt;_Tp&gt;&gt;) {</span>
<span id="cb2-10"><a href="#cb2-10"></a><span class="dt">-329,6 +329,11</span></span>
<span id="cb2-11"><a href="#cb2-11"></a>         : _M_rest(in_place_index&lt;_Np-1&gt;, std::forward&lt;_Args&gt;(__args)...)</span>
<span id="cb2-12"><a href="#cb2-12"></a>     { }</span>
<span id="cb2-13"><a href="#cb2-13"></a> </span>
<span id="cb2-14"><a href="#cb2-14"></a><span class="va">+    constexpr ~_Variadic_union() {}</span></span>
<span id="cb2-15"><a href="#cb2-15"></a><span class="va">+    constexpr ~_Variadic_union() </span></span>
<span id="cb2-16"><a href="#cb2-16"></a><span class="va">+        requires (std::is_trivially_destructible_v&lt;_First&gt; &amp;&amp; ... &amp;&amp;</span></span>
<span id="cb2-17"><a href="#cb2-17"></a><span class="va">+                  std::is_trivially_destructible_v&lt;_Rest&gt;)  = default;</span></span>
<span id="cb2-18"><a href="#cb2-18"></a><span class="va">+</span></span>
<span id="cb2-19"><a href="#cb2-19"></a>     _Uninitialized&lt;_First&gt; _M_first;</span>
<span id="cb2-20"><a href="#cb2-20"></a>     _Variadic_union&lt;_Rest...&gt; _M_rest;</span>
<span id="cb2-21"><a href="#cb2-21"></a> };</span>
<span id="cb2-22"><a href="#cb2-22"></a><span class="dt">-380,7 +385,7</span></span>
<span id="cb2-23"><a href="#cb2-23"></a>           _M_index(_Np)</span>
<span id="cb2-24"><a href="#cb2-24"></a>     { }</span>
<span id="cb2-25"><a href="#cb2-25"></a> </span>
<span id="cb2-26"><a href="#cb2-26"></a><span class="st">-    void _M_reset()</span></span>
<span id="cb2-27"><a href="#cb2-27"></a><span class="va">+    constexpr void _M_reset()</span></span>
<span id="cb2-28"><a href="#cb2-28"></a>     {</span>
<span id="cb2-29"><a href="#cb2-29"></a>         if (!_M_valid()) [[unlikely]]</span>
<span id="cb2-30"><a href="#cb2-30"></a>             return;</span>
<span id="cb2-31"><a href="#cb2-31"></a><span class="dt">-392,7 +397,7</span></span>
<span id="cb2-32"><a href="#cb2-32"></a>         _M_index = variant_npos;</span>
<span id="cb2-33"><a href="#cb2-33"></a>     }</span>
<span id="cb2-34"><a href="#cb2-34"></a> </span>
<span id="cb2-35"><a href="#cb2-35"></a><span class="st">-    ~_Variant_storage()</span></span>
<span id="cb2-36"><a href="#cb2-36"></a><span class="va">+    constexpr ~_Variant_storage()</span></span>
<span id="cb2-37"><a href="#cb2-37"></a>     {</span>
<span id="cb2-38"><a href="#cb2-38"></a>         _M_reset();</span>
<span id="cb2-39"><a href="#cb2-39"></a>     }</span>
<span id="cb2-40"><a href="#cb2-40"></a><span class="dt">-420,6 +425,10</span></span>
<span id="cb2-41"><a href="#cb2-41"></a> </span>
<span id="cb2-42"><a href="#cb2-42"></a> template&lt;typename... _Types&gt;</span>
<span id="cb2-43"><a href="#cb2-43"></a> struct _Variant_storage&lt;true, _Types...&gt; {</span>
<span id="cb2-44"><a href="#cb2-44"></a><span class="va">+    template&lt;typename _Tp&gt;</span></span>
<span id="cb2-45"><a href="#cb2-45"></a><span class="va">+    static constexpr size_t __index_of =</span></span>
<span id="cb2-46"><a href="#cb2-46"></a><span class="va">+        __detail::__variant::__index_of_v&lt;_Tp, _Types...&gt;;</span></span>
<span id="cb2-47"><a href="#cb2-47"></a><span class="va">+</span></span>
<span id="cb2-48"><a href="#cb2-48"></a>     constexpr _Variant_storage() : _M_index(variant_npos) { }</span>
<span id="cb2-49"><a href="#cb2-49"></a> </span>
<span id="cb2-50"><a href="#cb2-50"></a>     template&lt;size_t _Np, typename... _Args&gt;</span>
<span id="cb2-51"><a href="#cb2-51"></a><span class="dt">-428,7 +437,7</span></span>
<span id="cb2-52"><a href="#cb2-52"></a>           _M_index(_Np)</span>
<span id="cb2-53"><a href="#cb2-53"></a>     { }</span>
<span id="cb2-54"><a href="#cb2-54"></a> </span>
<span id="cb2-55"><a href="#cb2-55"></a><span class="st">-    void _M_reset() noexcept</span></span>
<span id="cb2-56"><a href="#cb2-56"></a><span class="va">+    constexpr void _M_reset() noexcept</span></span>
<span id="cb2-57"><a href="#cb2-57"></a>     {</span>
<span id="cb2-58"><a href="#cb2-58"></a>         _M_index = variant_npos;</span>
<span id="cb2-59"><a href="#cb2-59"></a>     }</span>
<span id="cb2-60"><a href="#cb2-60"></a><span class="dt">-459,13 +468,16</span></span>
<span id="cb2-61"><a href="#cb2-61"></a>     _Variant_storage&lt;_Traits&lt;_Types...&gt;::_S_trivial_dtor, _Types...&gt;;</span>
<span id="cb2-62"><a href="#cb2-62"></a> </span>
<span id="cb2-63"><a href="#cb2-63"></a> template&lt;typename _Tp, typename _Up&gt;</span>
<span id="cb2-64"><a href="#cb2-64"></a><span class="st">-void __variant_construct_single(_Tp&amp;&amp; __lhs, _Up&amp;&amp; __rhs_mem)</span></span>
<span id="cb2-65"><a href="#cb2-65"></a><span class="va">+constexpr void __variant_construct_single(_Tp&amp;&amp; __lhs, _Up&amp;&amp; __rhs_mem)</span></span>
<span id="cb2-66"><a href="#cb2-66"></a> {</span>
<span id="cb2-67"><a href="#cb2-67"></a><span class="st">-    void* __storage = std::addressof(__lhs._M_u);</span></span>
<span id="cb2-68"><a href="#cb2-68"></a>     using _Type = remove_reference_t&lt;decltype(__rhs_mem)&gt;;</span>
<span id="cb2-69"><a href="#cb2-69"></a><span class="st">-    if constexpr (!is_same_v&lt;_Type, __variant_cookie&gt;)</span></span>
<span id="cb2-70"><a href="#cb2-70"></a><span class="st">-        ::new (__storage)</span></span>
<span id="cb2-71"><a href="#cb2-71"></a><span class="st">-        _Type(std::forward&lt;decltype(__rhs_mem)&gt;(__rhs_mem));</span></span>
<span id="cb2-72"><a href="#cb2-72"></a><span class="va">+    constexpr auto index = remove_reference_t&lt;_Tp&gt;::template __index_of&lt;_Type&gt;;</span></span>
<span id="cb2-73"><a href="#cb2-73"></a><span class="va">+</span></span>
<span id="cb2-74"><a href="#cb2-74"></a><span class="va">+    if constexpr (!is_same_v&lt;_Type, __variant_cookie&gt;) {</span></span>
<span id="cb2-75"><a href="#cb2-75"></a><span class="va">+        std::construct_at(std::addressof(__lhs._M_u),</span></span>
<span id="cb2-76"><a href="#cb2-76"></a><span class="va">+            in_place_index&lt;index&gt;,</span></span>
<span id="cb2-77"><a href="#cb2-77"></a><span class="va">+            _Type(std::forward&lt;decltype(__rhs_mem)&gt;(__rhs_mem)));</span></span>
<span id="cb2-78"><a href="#cb2-78"></a><span class="va">+    }</span></span>
<span id="cb2-79"><a href="#cb2-79"></a> }</span>
<span id="cb2-80"><a href="#cb2-80"></a> </span>
<span id="cb2-81"><a href="#cb2-81"></a> template&lt;typename... _Types, typename _Tp, typename _Up&gt;</span>
<span id="cb2-82"><a href="#cb2-82"></a><span class="dt">-519,7 +531,7</span></span>
<span id="cb2-83"><a href="#cb2-83"></a>     }</span>
<span id="cb2-84"><a href="#cb2-84"></a> </span>
<span id="cb2-85"><a href="#cb2-85"></a>     template&lt;typename _Up&gt;</span>
<span id="cb2-86"><a href="#cb2-86"></a><span class="st">-    void _M_destructive_move(unsigned short __rhs_index, _Up&amp;&amp; __rhs)</span></span>
<span id="cb2-87"><a href="#cb2-87"></a><span class="va">+    constexpr void _M_destructive_move(unsigned short __rhs_index, _Up&amp;&amp; __rhs)</span></span>
<span id="cb2-88"><a href="#cb2-88"></a>     {</span>
<span id="cb2-89"><a href="#cb2-89"></a>         this-&gt;_M_reset();</span>
<span id="cb2-90"><a href="#cb2-90"></a>         __variant_construct_single(*this, std::forward&lt;_Up&gt;(__rhs));</span>
<span id="cb2-91"><a href="#cb2-91"></a><span class="dt">-527,7 +539,7</span></span>
<span id="cb2-92"><a href="#cb2-92"></a>     }</span>
<span id="cb2-93"><a href="#cb2-93"></a> </span>
<span id="cb2-94"><a href="#cb2-94"></a>     template&lt;typename _Up&gt;</span>
<span id="cb2-95"><a href="#cb2-95"></a><span class="st">-    void _M_destructive_copy(unsigned short __rhs_index, const _Up&amp; __rhs)</span></span>
<span id="cb2-96"><a href="#cb2-96"></a><span class="va">+    constexpr void _M_destructive_copy(unsigned short __rhs_index, const _Up&amp; __rhs)</span></span>
<span id="cb2-97"><a href="#cb2-97"></a>     {</span>
<span id="cb2-98"><a href="#cb2-98"></a>         this-&gt;_M_reset();</span>
<span id="cb2-99"><a href="#cb2-99"></a>         __variant_construct_single(*this, __rhs);</span>
<span id="cb2-100"><a href="#cb2-100"></a><span class="dt">-545,7 +557,7</span></span>
<span id="cb2-101"><a href="#cb2-101"></a>     using _Base::_Base;</span>
<span id="cb2-102"><a href="#cb2-102"></a> </span>
<span id="cb2-103"><a href="#cb2-103"></a>     template&lt;typename _Up&gt;</span>
<span id="cb2-104"><a href="#cb2-104"></a><span class="st">-    void _M_destructive_move(unsigned short __rhs_index, _Up&amp;&amp; __rhs)</span></span>
<span id="cb2-105"><a href="#cb2-105"></a><span class="va">+    constexpr void _M_destructive_move(unsigned short __rhs_index, _Up&amp;&amp; __rhs)</span></span>
<span id="cb2-106"><a href="#cb2-106"></a>     {</span>
<span id="cb2-107"><a href="#cb2-107"></a>         this-&gt;_M_reset();</span>
<span id="cb2-108"><a href="#cb2-108"></a>         __variant_construct_single(*this, std::forward&lt;_Up&gt;(__rhs));</span>
<span id="cb2-109"><a href="#cb2-109"></a><span class="dt">-553,7 +565,7</span></span>
<span id="cb2-110"><a href="#cb2-110"></a>     }</span>
<span id="cb2-111"><a href="#cb2-111"></a> </span>
<span id="cb2-112"><a href="#cb2-112"></a>     template&lt;typename _Up&gt;</span>
<span id="cb2-113"><a href="#cb2-113"></a><span class="st">-    void _M_destructive_copy(unsigned short __rhs_index, const _Up&amp; __rhs)</span></span>
<span id="cb2-114"><a href="#cb2-114"></a><span class="va">+    constexpr void _M_destructive_copy(unsigned short __rhs_index, const _Up&amp; __rhs)</span></span>
<span id="cb2-115"><a href="#cb2-115"></a>     {</span>
<span id="cb2-116"><a href="#cb2-116"></a>         this-&gt;_M_reset();</span>
<span id="cb2-117"><a href="#cb2-117"></a>         __variant_construct_single(*this, __rhs);</span>
<span id="cb2-118"><a href="#cb2-118"></a><span class="dt">-570,7 +582,7</span></span>
<span id="cb2-119"><a href="#cb2-119"></a>     using _Base = _Move_ctor_alias&lt;_Types...&gt;;</span>
<span id="cb2-120"><a href="#cb2-120"></a>     using _Base::_Base;</span>
<span id="cb2-121"><a href="#cb2-121"></a> </span>
<span id="cb2-122"><a href="#cb2-122"></a><span class="st">-    _Copy_assign_base&amp;</span></span>
<span id="cb2-123"><a href="#cb2-123"></a><span class="va">+    constexpr _Copy_assign_base&amp;</span></span>
<span id="cb2-124"><a href="#cb2-124"></a>     operator=(const _Copy_assign_base&amp; __rhs)</span>
<span id="cb2-125"><a href="#cb2-125"></a>     noexcept(_Traits&lt;_Types...&gt;::_S_nothrow_copy_assign)</span>
<span id="cb2-126"><a href="#cb2-126"></a>     {</span>
<span id="cb2-127"><a href="#cb2-127"></a><span class="dt">-625,7 +637,7</span></span>
<span id="cb2-128"><a href="#cb2-128"></a>     using _Base = _Copy_assign_alias&lt;_Types...&gt;;</span>
<span id="cb2-129"><a href="#cb2-129"></a>     using _Base::_Base;</span>
<span id="cb2-130"><a href="#cb2-130"></a> </span>
<span id="cb2-131"><a href="#cb2-131"></a><span class="st">-    _Move_assign_base&amp;</span></span>
<span id="cb2-132"><a href="#cb2-132"></a><span class="va">+    constexpr _Move_assign_base&amp;</span></span>
<span id="cb2-133"><a href="#cb2-133"></a>     operator=(_Move_assign_base&amp;&amp; __rhs)</span>
<span id="cb2-134"><a href="#cb2-134"></a>     noexcept(_Traits&lt;_Types...&gt;::_S_nothrow_move_assign)</span>
<span id="cb2-135"><a href="#cb2-135"></a>     {</span>
<span id="cb2-136"><a href="#cb2-136"></a><span class="dt">-1033,12 +1045,10</span></span>
<span id="cb2-137"><a href="#cb2-137"></a> } // namespace __detail</span>
<span id="cb2-138"><a href="#cb2-138"></a> </span>
<span id="cb2-139"><a href="#cb2-139"></a> template&lt;size_t _Np, typename _Variant, typename... _Args&gt;</span>
<span id="cb2-140"><a href="#cb2-140"></a><span class="st">-void __variant_construct_by_index(_Variant&amp; __v, _Args&amp;&amp;... __args) {</span></span>
<span id="cb2-141"><a href="#cb2-141"></a><span class="st">-    __v._M_index = _Np;</span></span>
<span id="cb2-142"><a href="#cb2-142"></a><span class="st">-    auto&amp;&amp; __storage = __detail::__variant::__get&lt;_Np&gt;(__v);</span></span>
<span id="cb2-143"><a href="#cb2-143"></a><span class="st">-    ::new ((void*)std::addressof(__storage))</span></span>
<span id="cb2-144"><a href="#cb2-144"></a><span class="st">-    remove_reference_t&lt;decltype(__storage)&gt;</span></span>
<span id="cb2-145"><a href="#cb2-145"></a><span class="st">-    (std::forward&lt;_Args&gt;(__args)...);</span></span>
<span id="cb2-146"><a href="#cb2-146"></a><span class="va">+constexpr void __variant_construct_by_index(_Variant&amp; __v, _Args&amp;&amp;... __args) {</span></span>
<span id="cb2-147"><a href="#cb2-147"></a><span class="va">+    std::construct_at(std::addressof(__v), </span></span>
<span id="cb2-148"><a href="#cb2-148"></a><span class="va">+        in_place_index&lt;_Np&gt;,</span></span>
<span id="cb2-149"><a href="#cb2-149"></a><span class="va">+        std::forward&lt;_Args&gt;(__args)...);</span></span>
<span id="cb2-150"><a href="#cb2-150"></a> }</span>
<span id="cb2-151"><a href="#cb2-151"></a> </span>
<span id="cb2-152"><a href="#cb2-152"></a> template&lt;typename _Tp, typename... _Types&gt;</span>
<span id="cb2-153"><a href="#cb2-153"></a><span class="dt">-1220,6 +1230,7</span></span>
<span id="cb2-154"><a href="#cb2-154"></a> constexpr decltype(auto) visit(_Visitor&amp;&amp;, _Variants&amp;&amp;...);</span>
<span id="cb2-155"><a href="#cb2-155"></a> </span>
<span id="cb2-156"><a href="#cb2-156"></a> template&lt;typename... _Types&gt;</span>
<span id="cb2-157"><a href="#cb2-157"></a><span class="va">+constexpr</span></span>
<span id="cb2-158"><a href="#cb2-158"></a> inline enable_if_t&lt;(is_move_constructible_v&lt;_Types&gt; &amp;&amp; ...)</span>
<span id="cb2-159"><a href="#cb2-159"></a>                    &amp;&amp; (is_swappable_v&lt;_Types&gt; &amp;&amp; ...)&gt;</span>
<span id="cb2-160"><a href="#cb2-160"></a> swap(variant&lt;_Types...&gt;&amp; __lhs, variant&lt;_Types...&gt;&amp; __rhs)</span>
<span id="cb2-161"><a href="#cb2-161"></a><span class="dt">-1281,9 +1292,9</span></span>
<span id="cb2-162"><a href="#cb2-162"></a> {</span>
<span id="cb2-163"><a href="#cb2-163"></a> private:</span>
<span id="cb2-164"><a href="#cb2-164"></a>     template &lt;typename... _UTypes, typename _Tp&gt;</span>
<span id="cb2-165"><a href="#cb2-165"></a><span class="st">-    friend decltype(auto) __variant_cast(_Tp&amp;&amp;);</span></span>
<span id="cb2-166"><a href="#cb2-166"></a><span class="va">+    friend constexpr decltype(auto) __variant_cast(_Tp&amp;&amp;);</span></span>
<span id="cb2-167"><a href="#cb2-167"></a>     template&lt;size_t _Np, typename _Variant, typename... _Args&gt;</span>
<span id="cb2-168"><a href="#cb2-168"></a><span class="st">-    friend void __variant_construct_by_index(_Variant&amp; __v,</span></span>
<span id="cb2-169"><a href="#cb2-169"></a><span class="va">+    friend constexpr void __variant_construct_by_index(_Variant&amp; __v,</span></span>
<span id="cb2-170"><a href="#cb2-170"></a>             _Args&amp;&amp;... __args);</span>
<span id="cb2-171"><a href="#cb2-171"></a> </span>
<span id="cb2-172"><a href="#cb2-172"></a>     static_assert(sizeof...(_Types) &gt; 0,</span>
<span id="cb2-173"><a href="#cb2-173"></a><span class="dt">-1397,6 +1408,7</span></span>
<span id="cb2-174"><a href="#cb2-174"></a>     { }</span>
<span id="cb2-175"><a href="#cb2-175"></a> </span>
<span id="cb2-176"><a href="#cb2-176"></a>     template&lt;typename _Tp&gt;</span>
<span id="cb2-177"><a href="#cb2-177"></a><span class="va">+    constexpr</span></span>
<span id="cb2-178"><a href="#cb2-178"></a>     enable_if_t&lt;__exactly_once&lt;__accepted_type&lt;_Tp&amp;&amp;&gt;&gt;</span>
<span id="cb2-179"><a href="#cb2-179"></a>                 &amp;&amp; is_constructible_v&lt;__accepted_type&lt;_Tp&amp;&amp;&gt;, _Tp&gt;</span>
<span id="cb2-180"><a href="#cb2-180"></a>                 &amp;&amp; is_assignable_v&lt;__accepted_type&lt;_Tp&amp;&amp;&gt;&amp;, _Tp&gt;,</span>
<span id="cb2-181"><a href="#cb2-181"></a><span class="dt">-1421,6 +1433,7</span></span>
<span id="cb2-182"><a href="#cb2-182"></a>     }</span>
<span id="cb2-183"><a href="#cb2-183"></a> </span>
<span id="cb2-184"><a href="#cb2-184"></a>     template&lt;typename _Tp, typename... _Args&gt;</span>
<span id="cb2-185"><a href="#cb2-185"></a><span class="va">+    constexpr</span></span>
<span id="cb2-186"><a href="#cb2-186"></a>     enable_if_t&lt;is_constructible_v&lt;_Tp, _Args...&gt; &amp;&amp; __exactly_once&lt;_Tp&gt;,</span>
<span id="cb2-187"><a href="#cb2-187"></a>                 _Tp&amp;&gt;</span>
<span id="cb2-188"><a href="#cb2-188"></a>     emplace(_Args&amp;&amp;... __args)</span>
<span id="cb2-189"><a href="#cb2-189"></a><span class="dt">-1430,6 +1443,7</span></span>
<span id="cb2-190"><a href="#cb2-190"></a>     }</span>
<span id="cb2-191"><a href="#cb2-191"></a> </span>
<span id="cb2-192"><a href="#cb2-192"></a>     template&lt;typename _Tp, typename _Up, typename... _Args&gt;</span>
<span id="cb2-193"><a href="#cb2-193"></a><span class="va">+    constexpr</span></span>
<span id="cb2-194"><a href="#cb2-194"></a>     enable_if_t&lt;is_constructible_v&lt;_Tp, initializer_list&lt;_Up&gt;&amp;, _Args...&gt;</span>
<span id="cb2-195"><a href="#cb2-195"></a>                 &amp;&amp; __exactly_once&lt;_Tp&gt;,</span>
<span id="cb2-196"><a href="#cb2-196"></a>                 _Tp&amp;&gt;</span>
<span id="cb2-197"><a href="#cb2-197"></a><span class="dt">-1440,6 +1454,7</span></span>
<span id="cb2-198"><a href="#cb2-198"></a>     }</span>
<span id="cb2-199"><a href="#cb2-199"></a> </span>
<span id="cb2-200"><a href="#cb2-200"></a>     template&lt;size_t _Np, typename... _Args&gt;</span>
<span id="cb2-201"><a href="#cb2-201"></a><span class="va">+    constexpr</span></span>
<span id="cb2-202"><a href="#cb2-202"></a>     enable_if_t&lt;is_constructible_v&lt;variant_alternative_t&lt;_Np, variant&gt;,</span>
<span id="cb2-203"><a href="#cb2-203"></a>                                    _Args...&gt;,</span>
<span id="cb2-204"><a href="#cb2-204"></a>                 variant_alternative_t&lt;_Np, variant&gt;&amp;&gt;</span>
<span id="cb2-205"><a href="#cb2-205"></a><span class="dt">-1484,6 +1499,7</span></span>
<span id="cb2-206"><a href="#cb2-206"></a>     }</span>
<span id="cb2-207"><a href="#cb2-207"></a> </span>
<span id="cb2-208"><a href="#cb2-208"></a>     template&lt;size_t _Np, typename _Up, typename... _Args&gt;</span>
<span id="cb2-209"><a href="#cb2-209"></a><span class="va">+    constexpr</span></span>
<span id="cb2-210"><a href="#cb2-210"></a>     enable_if_t&lt;is_constructible_v&lt;variant_alternative_t&lt;_Np, variant&gt;,</span>
<span id="cb2-211"><a href="#cb2-211"></a>                                    initializer_list&lt;_Up&gt;&amp;, _Args...&gt;,</span>
<span id="cb2-212"><a href="#cb2-212"></a>                 variant_alternative_t&lt;_Np, variant&gt;&amp;&gt;</span>
<span id="cb2-213"><a href="#cb2-213"></a><span class="dt">-1540,7 +1556,7</span></span>
<span id="cb2-214"><a href="#cb2-214"></a>         }</span>
<span id="cb2-215"><a href="#cb2-215"></a>     }</span>
<span id="cb2-216"><a href="#cb2-216"></a> </span>
<span id="cb2-217"><a href="#cb2-217"></a><span class="st">-    void</span></span>
<span id="cb2-218"><a href="#cb2-218"></a><span class="va">+    constexpr void</span></span>
<span id="cb2-219"><a href="#cb2-219"></a>     swap(variant&amp; __rhs)</span>
<span id="cb2-220"><a href="#cb2-220"></a>     noexcept((__is_nothrow_swappable&lt;_Types&gt;::value &amp;&amp; ...)</span>
<span id="cb2-221"><a href="#cb2-221"></a>              &amp;&amp; is_nothrow_move_constructible_v&lt;variant&gt;)</span></code></pre></div>
</div>
<h1 data-number="2" style="border-bottom:1px solid #cccccc" id="wording" data-number="2" style="border-bottom:1px solid #cccccc"><span class="header-section-number">2</span> Wording<a href="#wording" class="self-link"></a></h1>
<p><span class="ednote" style="color: #0000ff">[ Editor&#39;s note: The wording here just shows the added <code class="sourceCode default">constexpr</code>s in the synopses. They all need to be repeated in the specific wording for each function. ]</span></p>
<p>Add <code class="sourceCode cpp"><span class="kw">constexpr</span></code> to the <code class="sourceCode cpp">swap</code> in <span>20.6.2 <a href="https://wg21.link/optional.syn">[optional.syn]</a></span> (and in <span>20.6.9 <a href="https://wg21.link/optional.specalg">[optional.specalg]</a></span>):</p>
<div>
<div class="sourceCode" id="cb3"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb3-1"><a href="#cb3-1"></a>namespace std {</span>
<span id="cb3-2"><a href="#cb3-2"></a>  // [optional.optional], class template optional</span>
<span id="cb3-3"><a href="#cb3-3"></a>  template&lt;class T&gt;</span>
<span id="cb3-4"><a href="#cb3-4"></a>    class optional;</span>
<span id="cb3-5"><a href="#cb3-5"></a>    </span>
<span id="cb3-6"><a href="#cb3-6"></a>  [...]</span>
<span id="cb3-7"><a href="#cb3-7"></a>  </span>
<span id="cb3-8"><a href="#cb3-8"></a>  // [optional.specalg], specialized algorithms</span>
<span id="cb3-9"><a href="#cb3-9"></a>  template&lt;class T&gt;</span>
<span id="cb3-10"><a href="#cb3-10"></a><span class="st">-   void swap(optional&lt;T&gt;&amp;, optional&lt;T&gt;&amp;) noexcept(<em>see below</em>);  </span></span>
<span id="cb3-11"><a href="#cb3-11"></a><span class="va">+   <span class="diffins">constexpr</span> void swap(optional&lt;T&gt;&amp;, optional&lt;T&gt;&amp;) noexcept(<em>see below</em>);  </span></span>
<span id="cb3-12"><a href="#cb3-12"></a></span>
<span id="cb3-13"><a href="#cb3-13"></a>  [...]</span>
<span id="cb3-14"><a href="#cb3-14"></a></span>
<span id="cb3-15"><a href="#cb3-15"></a>}</span></code></pre></div>
</div>
<p>Add <code class="sourceCode cpp"><span class="kw">constexpr</span></code> to the rest of the functions in <span>20.6.3.1 <a href="https://wg21.link/optional.optional.general">[optional.optional.general]</a></span> (and likewise in <span>20.6.3.2 <a href="https://wg21.link/optional.ctor">[optional.ctor]</a></span>, <span>20.6.3.3 <a href="https://wg21.link/optional.dtor">[optional.dtor]</a></span>, <span>20.6.3.4 <a href="https://wg21.link/optional.assign">[optional.assign]</a></span>, <span>20.6.3.5 <a href="https://wg21.link/optional.swap">[optional.swap]</a></span>, and <span>20.6.3.7 <a href="https://wg21.link/optional.mod">[optional.mod]</a></span>):</p>
<div>
<div class="sourceCode" id="cb4"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb4-1"><a href="#cb4-1"></a>namespace std {</span>
<span id="cb4-2"><a href="#cb4-2"></a>  template&lt;class T&gt;</span>
<span id="cb4-3"><a href="#cb4-3"></a>  class optional {</span>
<span id="cb4-4"><a href="#cb4-4"></a>  public:</span>
<span id="cb4-5"><a href="#cb4-5"></a>    using value_type = T;</span>
<span id="cb4-6"><a href="#cb4-6"></a></span>
<span id="cb4-7"><a href="#cb4-7"></a>    // [optional.ctor], constructors</span>
<span id="cb4-8"><a href="#cb4-8"></a>    constexpr optional() noexcept;</span>
<span id="cb4-9"><a href="#cb4-9"></a>    constexpr optional(nullopt_t) noexcept;</span>
<span id="cb4-10"><a href="#cb4-10"></a>    constexpr optional(const optional&amp;);</span>
<span id="cb4-11"><a href="#cb4-11"></a>    constexpr optional(optional&amp;&amp;) noexcept(<em>see below</em>);</span>
<span id="cb4-12"><a href="#cb4-12"></a>    template&lt;class... Args&gt;</span>
<span id="cb4-13"><a href="#cb4-13"></a>      constexpr explicit optional(in_place_t, Args&amp;&amp;...);</span>
<span id="cb4-14"><a href="#cb4-14"></a>    template&lt;class U, class... Args&gt;</span>
<span id="cb4-15"><a href="#cb4-15"></a>      constexpr explicit optional(in_place_t, initializer_list&lt;U&gt;, Args&amp;&amp;...);</span>
<span id="cb4-16"><a href="#cb4-16"></a>    template&lt;class U = T&gt;</span>
<span id="cb4-17"><a href="#cb4-17"></a>      constexpr explicit(<em>see below</em>) optional(U&amp;&amp;);</span>
<span id="cb4-18"><a href="#cb4-18"></a>    template&lt;class U&gt;</span>
<span id="cb4-19"><a href="#cb4-19"></a><span class="st">-     explicit(<em>see below</em>) optional(const optional&lt;U&gt;&amp;);</span></span>
<span id="cb4-20"><a href="#cb4-20"></a><span class="va">+     <span class="diffins">constexpr</span> explicit(<em>see below</em>) optional(const optional&lt;U&gt;&amp;);</span></span>
<span id="cb4-21"><a href="#cb4-21"></a>    template&lt;class U&gt;</span>
<span id="cb4-22"><a href="#cb4-22"></a><span class="st">-     explicit(<em>see below</em>) optional(optional&lt;U&gt;&amp;&amp;);</span></span>
<span id="cb4-23"><a href="#cb4-23"></a><span class="va">+     <span class="diffins">constexpr</span> explicit(<em>see below</em>) optional(optional&lt;U&gt;&amp;&amp;);</span></span>
<span id="cb4-24"><a href="#cb4-24"></a></span>
<span id="cb4-25"><a href="#cb4-25"></a>    // [optional.dtor], destructor</span>
<span id="cb4-26"><a href="#cb4-26"></a><span class="st">-   ~optional();</span></span>
<span id="cb4-27"><a href="#cb4-27"></a><span class="va">+   <span class="diffins">constexpr</span> ~optional();</span></span>
<span id="cb4-28"><a href="#cb4-28"></a></span>
<span id="cb4-29"><a href="#cb4-29"></a>    // [optional.assign], assignment</span>
<span id="cb4-30"><a href="#cb4-30"></a><span class="st">-   optional&amp; operator=(nullopt_t) noexcept;</span></span>
<span id="cb4-31"><a href="#cb4-31"></a><span class="va">+   <span class="diffins">constexpr</span> optional&amp; operator=(nullopt_t) noexcept;</span></span>
<span id="cb4-32"><a href="#cb4-32"></a>    constexpr optional&amp; operator=(const optional&amp;);</span>
<span id="cb4-33"><a href="#cb4-33"></a>    constexpr optional&amp; operator=(optional&amp;&amp;) noexcept(<em>see below</em>);</span>
<span id="cb4-34"><a href="#cb4-34"></a><span class="st">-   template&lt;class U = T&gt; optional&amp; operator=(U&amp;&amp;);</span></span>
<span id="cb4-35"><a href="#cb4-35"></a><span class="st">-   template&lt;class U&gt; optional&amp; operator=(const optional&lt;U&gt;&amp;);</span></span>
<span id="cb4-36"><a href="#cb4-36"></a><span class="st">-   template&lt;class U&gt; optional&amp; operator=(optional&lt;U&gt;&amp;&amp;);</span></span>
<span id="cb4-37"><a href="#cb4-37"></a><span class="st">-   template&lt;class... Args&gt; T&amp; emplace(Args&amp;&amp;...);</span></span>
<span id="cb4-38"><a href="#cb4-38"></a><span class="st">-   template&lt;class U, class... Args&gt; T&amp; emplace(initializer_list&lt;U&gt;, Args&amp;&amp;...);</span></span>
<span id="cb4-39"><a href="#cb4-39"></a><span class="va">+   template&lt;class U = T&gt; <span class="diffins">constexpr</span> optional&amp; operator=(U&amp;&amp;);</span></span>
<span id="cb4-40"><a href="#cb4-40"></a><span class="va">+   template&lt;class U&gt; <span class="diffins">constexpr</span> optional&amp; operator=(const optional&lt;U&gt;&amp;);</span></span>
<span id="cb4-41"><a href="#cb4-41"></a><span class="va">+   template&lt;class U&gt; <span class="diffins">constexpr</span> optional&amp; operator=(optional&lt;U&gt;&amp;&amp;);</span></span>
<span id="cb4-42"><a href="#cb4-42"></a><span class="va">+   template&lt;class... Args&gt; <span class="diffins">constexpr</span> T&amp; emplace(Args&amp;&amp;...);</span></span>
<span id="cb4-43"><a href="#cb4-43"></a><span class="va">+   template&lt;class U, class... Args&gt; <span class="diffins">constexpr</span> T&amp; emplace(initializer_list&lt;U&gt;, Args&amp;&amp;...);</span></span>
<span id="cb4-44"><a href="#cb4-44"></a></span>
<span id="cb4-45"><a href="#cb4-45"></a>    // [optional.swap], swap</span>
<span id="cb4-46"><a href="#cb4-46"></a><span class="st">-   void swap(optional&amp;) noexcept(<em>see below</em>);</span></span>
<span id="cb4-47"><a href="#cb4-47"></a><span class="va">+   <span class="diffins">constexpr</span> void swap(optional&amp;) noexcept(<em>see below</em>);</span></span>
<span id="cb4-48"><a href="#cb4-48"></a></span>
<span id="cb4-49"><a href="#cb4-49"></a>    // [optional.observe], observers</span>
<span id="cb4-50"><a href="#cb4-50"></a>    constexpr const T* operator-&gt;() const;</span>
<span id="cb4-51"><a href="#cb4-51"></a>    constexpr T* operator-&gt;();</span>
<span id="cb4-52"><a href="#cb4-52"></a>    constexpr const T&amp; operator*() const&amp;;</span>
<span id="cb4-53"><a href="#cb4-53"></a>    constexpr T&amp; operator*() &amp;;</span>
<span id="cb4-54"><a href="#cb4-54"></a>    constexpr T&amp;&amp; operator*() &amp;&amp;;</span>
<span id="cb4-55"><a href="#cb4-55"></a>    constexpr const T&amp;&amp; operator*() const&amp;&amp;;</span>
<span id="cb4-56"><a href="#cb4-56"></a>    constexpr explicit operator bool() const noexcept;</span>
<span id="cb4-57"><a href="#cb4-57"></a>    constexpr bool has_value() const noexcept;</span>
<span id="cb4-58"><a href="#cb4-58"></a>    constexpr const T&amp; value() const&amp;;</span>
<span id="cb4-59"><a href="#cb4-59"></a>    constexpr T&amp; value() &amp;;</span>
<span id="cb4-60"><a href="#cb4-60"></a>    constexpr T&amp;&amp; value() &amp;&amp;;</span>
<span id="cb4-61"><a href="#cb4-61"></a>    constexpr const T&amp;&amp; value() const&amp;&amp;;</span>
<span id="cb4-62"><a href="#cb4-62"></a>    template&lt;class U&gt; constexpr T value_or(U&amp;&amp;) const&amp;;</span>
<span id="cb4-63"><a href="#cb4-63"></a>    template&lt;class U&gt; constexpr T value_or(U&amp;&amp;) &amp;&amp;;</span>
<span id="cb4-64"><a href="#cb4-64"></a></span>
<span id="cb4-65"><a href="#cb4-65"></a>    // [optional.mod], modifiers</span>
<span id="cb4-66"><a href="#cb4-66"></a><span class="st">-   void reset() noexcept;</span></span>
<span id="cb4-67"><a href="#cb4-67"></a><span class="va">+   <span class="diffins">constexpr</span> void reset() noexcept;</span></span>
<span id="cb4-68"><a href="#cb4-68"></a></span>
<span id="cb4-69"><a href="#cb4-69"></a>  private:</span>
<span id="cb4-70"><a href="#cb4-70"></a>    T *val;         // exposition only</span>
<span id="cb4-71"><a href="#cb4-71"></a>  };</span>
<span id="cb4-72"><a href="#cb4-72"></a></span>
<span id="cb4-73"><a href="#cb4-73"></a>  template&lt;class T&gt;</span>
<span id="cb4-74"><a href="#cb4-74"></a>    optional(T) -&gt; optional&lt;T&gt;;</span>
<span id="cb4-75"><a href="#cb4-75"></a>}</span></code></pre></div>
</div>
<p>Add <code class="sourceCode cpp"><span class="kw">constexpr</span></code> to <code class="sourceCode cpp">swap</code> in <span>20.7.2 <a href="https://wg21.link/variant.syn">[variant.syn]</a></span> (and likewise in <span>20.7.10 <a href="https://wg21.link/variant.specalg">[variant.specalg]</a></span>):</p>
<div>
<div class="sourceCode" id="cb5"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb5-1"><a href="#cb5-1"></a>namespace std {</span>
<span id="cb5-2"><a href="#cb5-2"></a>  // [variant.variant], class template variant</span>
<span id="cb5-3"><a href="#cb5-3"></a>  template&lt;class... Types&gt;</span>
<span id="cb5-4"><a href="#cb5-4"></a>    class variant;</span>
<span id="cb5-5"><a href="#cb5-5"></a></span>
<span id="cb5-6"><a href="#cb5-6"></a>  [...]</span>
<span id="cb5-7"><a href="#cb5-7"></a>  </span>
<span id="cb5-8"><a href="#cb5-8"></a>  // [variant.specalg], specialized algorithms</span>
<span id="cb5-9"><a href="#cb5-9"></a>  template&lt;class... Types&gt;</span>
<span id="cb5-10"><a href="#cb5-10"></a><span class="st">-   void swap(variant&lt;Types...&gt;&amp;, variant&lt;Types...&gt;&amp;) noexcept(<em>see below</em>);</span></span>
<span id="cb5-11"><a href="#cb5-11"></a><span class="va">+   <span class="diffins">constexpr</span> void swap(variant&lt;Types...&gt;&amp;, variant&lt;Types...&gt;&amp;) noexcept(<em>see below</em>);</span></span>
<span id="cb5-12"><a href="#cb5-12"></a></span>
<span id="cb5-13"><a href="#cb5-13"></a>  [...]</span>
<span id="cb5-14"><a href="#cb5-14"></a>}    </span></code></pre></div>
</div>
<p>Add <code class="sourceCode cpp"><span class="kw">constexpr</span></code> to the rest of the functions in <span>20.7.3.1 <a href="https://wg21.link/variant.variant.general">[variant.variant.general]</a></span> (and likewise in <span>20.7.3.3 <a href="https://wg21.link/variant.dtor">[variant.dtor]</a></span>, <span>20.7.3.4 <a href="https://wg21.link/variant.assign">[variant.assign]</a></span>, <span>20.7.3.5 <a href="https://wg21.link/variant.mod">[variant.mod]</a></span>, and <span>20.7.3.7 <a href="https://wg21.link/variant.swap">[variant.swap]</a></span>):</p>
<div>
<div class="sourceCode" id="cb6"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb6-1"><a href="#cb6-1"></a>namespace std {</span>
<span id="cb6-2"><a href="#cb6-2"></a>  template&lt;class... Types&gt;</span>
<span id="cb6-3"><a href="#cb6-3"></a>  class variant {</span>
<span id="cb6-4"><a href="#cb6-4"></a>  public:</span>
<span id="cb6-5"><a href="#cb6-5"></a>    // [variant.ctor], constructors</span>
<span id="cb6-6"><a href="#cb6-6"></a>    constexpr variant() noexcept(<em>see below</em>);</span>
<span id="cb6-7"><a href="#cb6-7"></a>    constexpr variant(const variant&amp;);</span>
<span id="cb6-8"><a href="#cb6-8"></a>    constexpr variant(variant&amp;&amp;) noexcept(<em>see below</em>);</span>
<span id="cb6-9"><a href="#cb6-9"></a></span>
<span id="cb6-10"><a href="#cb6-10"></a>    template&lt;class T&gt;</span>
<span id="cb6-11"><a href="#cb6-11"></a>      constexpr variant(T&amp;&amp;) noexcept(<em>see below</em>);</span>
<span id="cb6-12"><a href="#cb6-12"></a></span>
<span id="cb6-13"><a href="#cb6-13"></a>    template&lt;class T, class... Args&gt;</span>
<span id="cb6-14"><a href="#cb6-14"></a>      constexpr explicit variant(in_place_type_t&lt;T&gt;, Args&amp;&amp;...);</span>
<span id="cb6-15"><a href="#cb6-15"></a>    template&lt;class T, class U, class... Args&gt;</span>
<span id="cb6-16"><a href="#cb6-16"></a>      constexpr explicit variant(in_place_type_t&lt;T&gt;, initializer_list&lt;U&gt;, Args&amp;&amp;...);</span>
<span id="cb6-17"><a href="#cb6-17"></a></span>
<span id="cb6-18"><a href="#cb6-18"></a>    template&lt;size_t I, class... Args&gt;</span>
<span id="cb6-19"><a href="#cb6-19"></a>      constexpr explicit variant(in_place_index_t&lt;I&gt;, Args&amp;&amp;...);</span>
<span id="cb6-20"><a href="#cb6-20"></a>    template&lt;size_t I, class U, class... Args&gt;</span>
<span id="cb6-21"><a href="#cb6-21"></a>      constexpr explicit variant(in_place_index_t&lt;I&gt;, initializer_list&lt;U&gt;, Args&amp;&amp;...);</span>
<span id="cb6-22"><a href="#cb6-22"></a></span>
<span id="cb6-23"><a href="#cb6-23"></a>    // [variant.dtor], destructor</span>
<span id="cb6-24"><a href="#cb6-24"></a><span class="st">-   ~variant();</span></span>
<span id="cb6-25"><a href="#cb6-25"></a><span class="va">+   <span class="diffins">constexpr</span> ~variant();</span></span>
<span id="cb6-26"><a href="#cb6-26"></a></span>
<span id="cb6-27"><a href="#cb6-27"></a>    // [variant.assign], assignment</span>
<span id="cb6-28"><a href="#cb6-28"></a>    constexpr variant&amp; operator=(const variant&amp;);</span>
<span id="cb6-29"><a href="#cb6-29"></a>    constexpr variant&amp; operator=(variant&amp;&amp;) noexcept(<em>see below</em>);</span>
<span id="cb6-30"><a href="#cb6-30"></a></span>
<span id="cb6-31"><a href="#cb6-31"></a><span class="st">-   template&lt;class T&gt; variant&amp; operator=(T&amp;&amp;) noexcept(<em>see below</em>);</span></span>
<span id="cb6-32"><a href="#cb6-32"></a><span class="va">+   template&lt;class T&gt; <span class="diffins">constexpr</span> variant&amp; operator=(T&amp;&amp;) noexcept(<em>see below</em>);</span></span>
<span id="cb6-33"><a href="#cb6-33"></a></span>
<span id="cb6-34"><a href="#cb6-34"></a>    // [variant.mod], modifiers</span>
<span id="cb6-35"><a href="#cb6-35"></a><span class="st">-   template&lt;class T, class... Args&gt;</span></span>
<span id="cb6-36"><a href="#cb6-36"></a><span class="st">-     T&amp; emplace(Args&amp;&amp;...);</span></span>
<span id="cb6-37"><a href="#cb6-37"></a><span class="st">-   template&lt;class T, class U, class... Args&gt;</span></span>
<span id="cb6-38"><a href="#cb6-38"></a><span class="st">-     T&amp; emplace(initializer_list&lt;U&gt;, Args&amp;&amp;...);</span></span>
<span id="cb6-39"><a href="#cb6-39"></a><span class="st">-   template&lt;size_t I, class... Args&gt;</span></span>
<span id="cb6-40"><a href="#cb6-40"></a><span class="st">-     variant_alternative_t&lt;I, variant&lt;Types...&gt;&gt;&amp; emplace(Args&amp;&amp;...);</span></span>
<span id="cb6-41"><a href="#cb6-41"></a><span class="st">-   template&lt;size_t I, class U, class... Args&gt;</span></span>
<span id="cb6-42"><a href="#cb6-42"></a><span class="st">-     variant_alternative_t&lt;I, variant&lt;Types...&gt;&gt;&amp; emplace(initializer_list&lt;U&gt;, Args&amp;&amp;...);</span></span>
<span id="cb6-43"><a href="#cb6-43"></a><span class="va">+   template&lt;class T, class... Args&gt;</span></span>
<span id="cb6-44"><a href="#cb6-44"></a><span class="va">+     <span class="diffins">constexpr</span> T&amp; emplace(Args&amp;&amp;...);</span></span>
<span id="cb6-45"><a href="#cb6-45"></a><span class="va">+   template&lt;class T, class U, class... Args&gt;</span></span>
<span id="cb6-46"><a href="#cb6-46"></a><span class="va">+     <span class="diffins">constexpr</span> T&amp; emplace(initializer_list&lt;U&gt;, Args&amp;&amp;...);</span></span>
<span id="cb6-47"><a href="#cb6-47"></a><span class="va">+   template&lt;size_t I, class... Args&gt;</span></span>
<span id="cb6-48"><a href="#cb6-48"></a><span class="va">+     <span class="diffins">constexpr</span> variant_alternative_t&lt;I, variant&lt;Types...&gt;&gt;&amp; emplace(Args&amp;&amp;...);</span></span>
<span id="cb6-49"><a href="#cb6-49"></a><span class="va">+   template&lt;size_t I, class U, class... Args&gt;</span></span>
<span id="cb6-50"><a href="#cb6-50"></a><span class="va">+     <span class="diffins">constexpr</span> variant_alternative_t&lt;I, variant&lt;Types...&gt;&gt;&amp; emplace(initializer_list&lt;U&gt;, Args&amp;&amp;...);</span></span>
<span id="cb6-51"><a href="#cb6-51"></a></span>
<span id="cb6-52"><a href="#cb6-52"></a>    // [variant.status], value status</span>
<span id="cb6-53"><a href="#cb6-53"></a>    constexpr bool valueless_by_exception() const noexcept;</span>
<span id="cb6-54"><a href="#cb6-54"></a>    constexpr size_t index() const noexcept;</span>
<span id="cb6-55"><a href="#cb6-55"></a></span>
<span id="cb6-56"><a href="#cb6-56"></a>    // [variant.swap], swap</span>
<span id="cb6-57"><a href="#cb6-57"></a><span class="st">-   void swap(variant&amp;) noexcept(<em>see below</em>);</span></span>
<span id="cb6-58"><a href="#cb6-58"></a><span class="va">+   <span class="diffins">constexpr</span> void swap(variant&amp;) noexcept(<em>see below</em>);</span></span>
<span id="cb6-59"><a href="#cb6-59"></a>  };</span>
<span id="cb6-60"><a href="#cb6-60"></a>}</span></code></pre></div>
</div>
<h1 data-number="3" style="border-bottom:1px solid #cccccc" id="acknowledgements" data-number="3" style="border-bottom:1px solid #cccccc"><span class="header-section-number">3</span> Acknowledgements<a href="#acknowledgements" class="self-link"></a></h1>
<p>Thanks to Tim Song for all the help. Thanks to Jonathan Wakely for looking over the paper, pointing out how repetitive the introduction was, and pointing out how repetitive the introduction was.</p>
<h1 data-number="4" style="border-bottom:1px solid #cccccc" id="bibliography" data-number="4" style="border-bottom:1px solid #cccccc"><span class="header-section-number">4</span> References<a href="#bibliography" class="self-link"></a></h1>
<div id="refs" class="references hanging-indent" role="doc-bibliography">
<div id="ref-P0784R7">
<p>[P0784R7] Daveed Vandevoorde, Peter Dimov,Louis Dionne, Nina Ranns, Richard Smith, Daveed Vandevoorde. 2019. More constexpr containers. <br />
<a href="https://wg21.link/p0784r7">https://wg21.link/p0784r7</a></p>
</div>
<div id="ref-P1330R0">
<p>[P1330R0] Louis Dionne, David Vandevoorde. 2018. Changing the active member of a union inside constexpr. <br />
<a href="https://wg21.link/p1330r0">https://wg21.link/p1330r0</a></p>
</div>
</div>
</div>
</div>
</body>
</html>
