<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>P3533R2: constexpr virtual inheritance</title>
<style>
@media (prefers-color-scheme: dark) {
	:root {
		--text-color: #BBB;
		--found-highlight: blue;
		--found-text-color: white;
		--main-background: 32,32,32;
		--header-color: white;
		--box-shadow-color: rgba(0,0,0,0.5);
    --thin-box-shadow-color: rgba(0,0,0,0.1);
		--nav-background-color: #101010;
		--code-foreground-color: white;
		--code-info-color: rgba(255,255,255,0.1);
		--code-background-color: var(--nav-background-color);
		--link-color: #8ef3ff;
		--visited-link-color: #f0ff89;
		--hover-link-color: #b3f7ff;
		--hover-visited-link-color: #c8ffb3;
		--line-color: 255,255,255;
		--header-background: 0,0,0;
		--quote-left-color: rgba(255,255,255,0.5);
		--highlight: rgba(255,252,0,0.25);
	}
	::selection {
	  color: black;
	  background: lightyellow;
	}
}

@media (prefers-color-scheme: light) {
	:root {
		--text-color: black;
		--found-highlight: yellow;
		--found-text-color: black;
		--main-background: 255,255,255;
		--header-color: black;
		--box-shadow-color: rgba(0,0,0,0.3);
    --thin-box-shadow-color: rgba(0,0,0,0.1);
		--nav-background-color: #F5F5F5;
		--code-foreground-color: black;
		--code-info-color: rgba(0,0,0,0.1);
		--code-background-color: var(--nav-background-color);
		--link-color: #000082;
		--visited-link-color: #508d0f;
		--hover-link-color: #5757c2;
		--hover-visited-link-color: #94c560;
		--line-color: 12,43,75;
		--header-background: 0,0,0;
		--quote-left-color: rgba(0,0,0,0.5);
		--highlight: rgba(255,254,207,0.5);
	}
	/*
	*::selection {
	  color: black;
	  background: #a4c3f6;
	}*/
}

@media (prefers-color-scheme: dark) {
	svg {
		--hana-text: black;
		--hana-outline: black;
		--hana-contrast-text: rgba(255,255,255,0.75);
		--hana-info: rgba(255,255,255,0.6);
		--hana-lines: white;
		--hana-special-boxes: rgba(0,0,0,0.5);
		--hana-special-boxes-outline: rgba(255,255,255,0.5);
		--hana-boxes: rgba(255,255,255,0.6);
		--hana-boxes-background: rgba(255,255,255,0.1);
		--hana-inside-text: white;
		--hana-outside-text: var(--text-color);
		--hana-shadow: white;
		--hana-structures-outline: white;
		--hana-structures-fill: black;
		--hana-structures-fill-meaningless: #444;
		--hana-pink-fill: #a3567e;
		--hana-purple-fill: #4d539d;
		--hana-green-fill: #1e7451;
		--hana-yellow-fill: #727529;
		--hana-orange-fill: #714530;
	}
}

@media (prefers-color-scheme: light) {
	svg {
		--hana-text: black;
		--hana-outline: black;
		--hana-contrast-text: rgba(255,255,255,1);
		--hana-info: rgba(0,0,0,0.6);
		--hana-lines: black;
		--hana-special-boxes: rgba(0,0,0,0.9);
		--hana-special-boxes-outline: rgba(255,255,255,0.5);
		--hana-boxes: rgba(0,0,0,0.6);
		--hana-boxes-background: rgba(0,0,0,0.1);
		--hana-inside-text: var(--text-color);
		--hana-outside-text: var(--text-color);
		--hana-shadow: black;
		--hana-structures-outline: black;
		--hana-structures-fill: white;
		--hana-structures-fill-meaningless: lightgray;
		--hana-pink-fill: #ffacd6;
		--hana-purple-fill: #acacff;
		--hana-green-fill: #acffd5;
		--hana-yellow-fill: #ffffac;
		--hana-orange-fill: #ffc8ad;
	}
}

svg g#boxes * {
	fill: var(--hana-boxes);
	fill-opacity: 0.1;
	stroke: var(--hana-boxes);
}
svg g#special {
	opacity: 0.25;
}
svg g#black-outline * {
	stroke: var(--hana-outline);
}
svg g#text * {
	fill: var(--hana-text);
}
svg g#info * {
	fill: var(--hana-info);
}
svg g#info text {
	fill: var(--hana-info);
}
svg g#contrast-text * {
	fill: var(--hana-contrast-text);
}
svg g#contrast-black-outline * {
	fill: var(--hana-special-boxes);
	stroke: var(--hana-special-boxes-outline);
}
svg g#black-lines * {
	stroke: var(--hana-lines);
}
svg g#black-lines polygon {
	fill: var(--hana-lines);
}

/* inheritance */
svg g#outside-text * {
	fill: var(--hana-outside-text);
}
svg g#inside-text * {
	fill: var(--hana-inside-text);
}
svg g#shadow path {
	fill: var(--hana-shadow);
	opacity: 0.1;
}
svg g#arrows g path, svg g#arrows g line {
	stroke: var(--hana-structures-outline);
}
svg g#arrows g polygon {
	fill: var(--hana-structures-outline);
}
svg g#structures > * {
	stroke: var(--hana-structures-outline);
	fill: var(--hana-structures-fill);
}
svg g#items g#meaningless > * {
	fill: var(--hana-structures-fill-meaningless);
}
svg g#items g#pink > * {
	fill: var(--hana-pink-fill);
}
svg g#items g#orange > * {
	fill: var(--hana-orange-fill);
}
svg g#items g#purple > * {
	fill: var(--hana-purple-fill);
}
svg g#items g#yellow > * {
	fill: var(--hana-yellow-fill);
}
svg g#items g#green > * {
	fill: var(--hana-green-fill);
}
svg g#items * {
	stroke: var(--hana-structures-outline);
}


span:target, p:target, li:target, div:target {
  background: var(--highlight);
}

.name-of-paper {
	font-size: 28px;
	padding-top: 0.5em;
}

span.found {
	text-shadow: 0 0 10px var(--found-highlight),  0 0 10px var(--found-highlight),  0 0 10px var(--found-highlight),  0 0 10px var(--found-highlight);
	color: var(--found-text-color) !important;
}

body {
	font-family: Helvetica;
	padding: 0;
	margin: 0;
	overflow: hidden;
	color: var(--text-color);
	background-color: rgba(var(--main-background), 1);
}

body > div {
	display: flex;
	padding: 0;
	margin: 0;
}

.hide-on-narrow {
	display: inherit;
}

.hide-on-wide {
	display: none;
}

@media only screen and (max-width: 1100px) {
	body {
		overflow: inherit !important;
	}
	.hide-on-narrow {
		display: none;
	}
	.hide-on-wide {
		display: inherit;
	}
	body > div {
		display: block !important;
	}
	article {
		overflow: inherit !important;
		background-image: linear-gradient(to right, transparent,rgba(var(--main-background),0.6), rgba(var(--main-background),0.8), rgba(var(--main-background),0.6), transparent) !important;
	}
	nav, article {
		flex: initial !important;
	}
	nav {
		min-width: initial !important;
		max-width: initial !important;
		min-height: initial !important;
		max-height: initial !important;
		box-shadow: 0 10px 0 var(--box-shadow-color);
	}
	nav > div {
		overflow: inherit !important;
		position: relative !important;
		max-width: initial !important;
		max-height: initial !important;
	}
	div:has(> input[type=search]) {
		display: none;
	}
	div.quote {
		overflow-x: visible;
    overflow-y: visible;
	}
}

nav {
	padding: 0 0.5em;
	margin: 0;
	flex: 1 1 0;
	min-width: 350px;
	max-width: 350px;
	box-shadow: 0 0 10px var(--box-shadow-color);
	background-color: var(--nav-background-color);
}

nav > div {
	position: fixed;
	max-width: 350px;
	max-height: 100%;
	overflow: scroll;
	top: 0;
	left: 0;
	padding: 0 0.5em;
	margin: 0;
}

nav > div > div {
	padding: 0.5em;
	padding-top: 0;
	padding-bottom: 1em;
}

article {
	flex: 3 1 0;
	overflow: scroll;
	height: 100vh;
	text-align: justify;
	background-image: linear-gradient(to bottom, transparent,rgba(var(--main-background),0.6), rgba(var(--main-background),0.8), rgba(var(--main-background),0.6), transparent);
	padding: 0;
	margin: 0;
}

article > div {
	padding-right: 1.5em;
	padding-left: 1.5em;
	padding-bottom: 1em;
}

code {
	
}

div.quote {
	color: var(--code-foreground-color);
	background: var(--code-background-color);
	padding: 1em;
	border-radius: 0px 15px 15px 0px;
	border-left: 5px solid var(--quote-left-color);
	font-style: italic;
	margin: 1em;
}

code:not(pre > code) {
	color: inherit;
	background: var(--code-background-color);
	border-radius: 5px;
	padding: 0 0.2em;
	margin: 0 2px;
	outline: 2px solid var(--code-background-color);
}

pre > code {
	outline: none;
	line-height: 1.4;
	tab-size: 2;
}

pre:has(code) {
	color: var(--code-foreground-color);
	background: var(--code-background-color);
	padding: 1em;
	border-radius: 15px;
	position: relative;
	z-index: 1;
	overflow-x: visible;
	overflow-y: visible;
}

pre:has(code.language-carbon)::before {
	content: "Carbon";
	text-transform: uppercase;
	position: absolute;
	top: 1em;
	right: 1em;
	color: var(--code-info-color);
	font-weight: bold;
}

p, ul > li {
	text-align: justify;
	overflow-wrap: break-word;
	hyphens: auto;
}

article ul > li {
	padding-bottom: 0.25em;
}

div.description ul {
  padding-top: 0.5em;
	padding-bottom: 0.5em;
}

a {
	color: var(--link-color);
	text-decoration-style: dotted;
}

a:hover {
	color: var(--hover-link-color);
	text-decoration-style: solid;
}

a:visited {
	color: var(--visited-link-color);
}

a:visited:hover {
	color: var(--hover-visited-link-color);
	text-decoration-style: solid;
}

h1, h2, h3, h4, h5 {
	text-align: left;
	margin: 0;
	margin-bottom: 10px;
	padding: 0.5em;
	padding-top: 20px;
	padding-bottom: 2px;
	z-index: 2;
	color: var(--header-color) !important;
	a {
		color: var(--header-color) !important;
	}
}

article h1, article h2, article h3, article h4, article h5 {
/*	position: sticky;
	position: -webkit-sticky;
	top: 0;*/
	
}

h1 {
	font-weight: 800;
	border-bottom: rgba(var(--line-color), 1) dotted 2px;
}

h2 {
	font-weight: 800;
	border-bottom: rgba(var(--line-color), 0.75) dotted 2px;
}

h3, h4, h5 {
	font-weight: 600;
	border-bottom: rgba(var(--line-color), 0.33) dotted 2px;
}

h1 > a, h2 > a, h3 > a, h4 > a, h5 > a {
	text-decoration: inherit;
}

h1:target::after, h2:target::after, h3:target::after, h4:target::after, h5:target::after {
	text-decoration: inherit;
	content: " ⚓︎";
  font-size: 14px;
}

h1 > a:hover, h2 > a:hover, h3 > a:hover, h4 > a:hover, h5 > a:hover {
	color: var(--hover-link-color);
}

div:has(> input[type=search]) {
	position: fixed;
	top: 0;
	right: 0;
	z-index: 1000;
	padding: 0.5em;
	background-color: var(--nav-background-color);
	box-shadow: 0 0 10px rgba(0,0,0,0.3);
	border-bottom-left-radius: 10px;
}

div > input[type=search] {
	background-color: var(--nav-background-color);
	border: 2px solid var(--text-color);
	color: var(--text-color);
	width: 300px;
}

div.paper-info {
	padding: 0;
	padding-top: 1em;
	
	.key {
		font-weight: bold;
	}
	
	div {
	}
}

ul {
	padding: 0;
	margin: 0;
	padding-left: 1em;
}

div#toc > ul {
	margin-left: 1em;
}

div#toc ul {
	padding-left: 0.5em;
}

li > ul {
	padding-left: 0.25em;
}

ul > li {
	padding-left: 0.25em;
}

div#toc li {
	text-align: left;
}

code .error, code .before {
	line-height: 1.9;
}

code .error > *, code .before > * {
	background-color: #FF8888 !important;
	color: black !important;
	@media (prefers-color-scheme: dark) {
		color: white;
	}
	border: 3px solid #FF8888;
	font-weight: bold;
}

code .after > * {
	background-color: lightgreen !important;
	color: black !important;
	@media (prefers-color-scheme: dark) {
		color: white;
	}
	border: 3px solid lightgreen;
	font-weight: bold;
}

code .unchanged > * {
	background-color: lightyellow !important;
	color: black !important;
	@media (prefers-color-scheme: dark) {
		color: white;
	}
	border: 3px solid lightyellow;
	font-weight: bold;
}

code .invisible {
	visibility: hidden;
}

.changes {
	display: inline-block;
}

.wording h1, .wording h1 > a, .wording h2, .wording h2 > a {
	font-size: inherit;
	text-decoration: none;
	border: none;
	padding: 0;
	margin: 0;
	@media (prefers-color-scheme: dark) {
		color: white !important;
	}
	@media (prefers-color-scheme: light) {
		color: black !important;
	}
	
	/*color: orange !important;*/
}

.wording p {
	padding: 0;
	padding-top: 0.5em;
	margin: 0;
}

.wording a {
	text-decoration: none;
	color: inherit;
}

.wording a:hover {
	text-decoration: underline;
	color: var(--link-color);
}

.wording a:visited {

}

.wording code {
	background: inherit !important;
	border: none;
	outline: none;
}
	
.wording {
	font-family: "Noto Serif";
	
	padding: 0.5em 1em;
	padding-bottom: 1em;
	color: var(--code-foreground-color);
	background: var(--code-background-color);
	line-height: 1.55;
	
	border-radius: 15px;
	position: relative;
	z-index: 1;
	overflow-x: visible;
	overflow-y: visible;
}
	
.wording .added, pre .added {
	background-color: lightgreen;
	text-decoration: underline;
  text-decoration-color: green;
  text-decoration-thickness: 2px !important;
	z-index: 80;
	padding: 3px;
	@media (prefers-color-scheme: dark) {
		color: black !important;
	}
}

.highlight {
	border-radius: 5px;
	border: 5px solid #fff587;
	background-color: #fff587;
	color: black;
	z-index: -5;
	text-shadow: 0 0 5px white;
	@media (prefers-color-scheme: dark) {
		border: 5px solid #001676;
		background-color: #001676;
		color: white;
		text-shadow: 0 0 10px black;
	}
	
	
}

div.added pre.added *, div.added pre.added {
	text-decoration-color: transparent;
}

.wording .added-item {
	background-color: lightgreen;
  text-decoration: underline;
  text-decoration-color: green;
  text-decoration-thickness: 2px !important;
	@media (prefers-color-scheme: dark) {
		color: black;
	}
}
	
.wording .removed {
	background-color: #FF8888;
	z-index: 50;
	padding: 3px;
  text-decoration: line-through;
  text-decoration-color: rgba(255,0,0,0.75);
  text-decoration-thickness: 2px !important;
	@media (prefers-color-scheme: dark) {
		color: black;
	}
}

.wording li.removed-bullet::before {
	background-color: #FF8888;
	z-index: 50;
	padding: 3px;
  text-decoration: line-through;
  text-decoration-color: rgba(255,0,0,0.75);
  text-decoration-thickness: 2px !important;
	@media (prefers-color-scheme: dark) {
		color: black;
	}
}
	
.wording .note {
	font-size: 0.8em;
}
	
.wording	+ .wording {
	margin-top: 0.5em;
}
	
.wording pre:has(code) {
	border: 1px solid var(--code-info-color);
	border-radius: 0;
	padding: 0em;
	z-index: 1;
	overflow-x: scroll;
}
	
.wording	code .addeded span {
	color: black !important;
}

table.poll {
  border-collapse: collapse;
  margin-top: 20px;
}

table.poll th, table.poll td {
  border: 0;
  padding: 5px 10px;
  text-align: center;
  border: 2px solid rgba(128,128,128,0.2);
}

table.poll td:first-child, table.poll th:first-child {
 border-left: none;
}

table.poll td:last-child, table.poll th:last-child {
 border-right: none;
}

table.poll tr:first-child th, table.poll tr:first-child td {
  border-top: none;
}

table.poll tr:last-child th, table.poll tr:last-child td {
  border-bottom: none;
}

.wording .description {
  padding-bottom: 1em;
}

.wording .caps {
  text-transform: uppercase;
}

table th.table-group {
	max-width: 2em;
}

table th.table-group > span {
	max-width: 2em;
	display: block;
	overflow: visible;
	text-align: center;
	transform: translateX(1em);
}

table th.table-group > span > span {
	display: inline-block;
	transform: translateX(-50%) rotate(-90deg);
	width: auto;
}

table.before-after th, table.before-after td  {
  height: 30px;
}



table.before-after .green {
  color: green;
}

table.before-after .orange {
  color: orange;
}

table.before-after .red-normal {
  color: red;
}

table.before-after .in-progress {
	color: blue;
	background-color: rgba(0,231,255,0.5);
}

table.before-after .proposing {
	color: green;
	background-color: rgba(0,255,0,0.5);
}

table.before-after .not-proposing {
	color: red;
	background-color: rgba(255,0,0,0.25);
}

table.before-after .never-proposing {
	color: red;
	background-color: rgba(255,0,0,0.25);
}

table.before-after .proposed-ready-for-future {
	color: green;
	background-color: rgba(203,229,7,0.5);
}

table.before-after .proposed-ready-for-future2 {
	color: green;
	background-color: rgba(255,198,0,0.5);
}

table.before-after .red {
  color: red;
  font-size: 24px;
  line-height: 16px;
}

td a, td a:visited, td a:hover {
	color: inherit;
}

div.wording-note {
  background: rgb(var(--main-background));
  box-shadow: 5px 0 10px var(--thin-box-shadow-color) inset;
  border-radius: 15px;
  color: var(--text-color);
  padding: 10px;
  margin: 10px 20px;
  font-size: 12px;
}

.parnum {
	font-size: 12px;
	margin-right: 0.25em;
	display: inline-block;
}

li:has(> .parnum) {
	list-style-position: inside;
	position: relative;
}

li > .parnum {
	position: absolute;
	left: -30px;
	bottom: 2px;
}

div.svgimg {
	text-align: left;
}

div.svgimg > div {
	
}

div.svgimg > div > svg {

}

@media (prefers-color-scheme: dark) {
	div.svgimg > div > img {
		border-radius: 10px;
		filter: drop-shadow(0px 0px 5px rgb(255 255 255 / 0.4));
	}
}

table.before-after td.disable-bottom, table.before-after th.disable-bottom {
	border-bottom: none;
}
table.before-after th.left, table.before-after td.left {
	text-align: left;
}

td a.note:after {
	vertical-align: super;
	font-size: 75%;
	margin-left: 0.5em;
}

td a.note.n1:after {
	content: "1";
}

td a.note.n2:after {
	content: "2";
}

td a.note.n3:after {
	content: "3";
}

td a.note.n4:after {
	content: "4";
}

td a.note.n5:after {
	content: "5";
}

blockquote {
	background: rgba(0,0,0,0.10);
	font-style: italic;
	padding: 0.05em 1em;
	margin: 0;
	border-left: rgba(0,0,0,0.5) 5px solid;
}

.wording pre code em, .wording pre code em span {
	color: var(--text-color) !important;
}
</style>
<style>
@media (prefers-color-scheme: light) {

pre code.hljs {

}
code.hljs {

}
/*

XCode style (c) Angel Garcia <angelgarcia.mail@gmail.com>

*/
.hljs {
  color: inherit
}
/* Gray DOCTYPE selectors like WebKit */
.xml .hljs-meta {
  color: #c0c0c0
}
.hljs-comment,
.hljs-quote {
  color: #007400
}
.hljs-tag,
.hljs-attribute,
.hljs-keyword,
.hljs-selector-tag,
.hljs-literal,
.hljs-name {
  color: #aa0d91
}
.hljs-variable,
.hljs-template-variable {
  color: #3F6E74
}
.hljs-code,
.hljs-string,
.hljs-meta .hljs-string {
  color: #c41a16
}
.hljs-regexp,
.hljs-link {
  color: #0E0EFF
}
.hljs-title,
.hljs-symbol,
.hljs-bullet,
.hljs-number {
  color: #1c00cf
}
.hljs-section,
.hljs-meta {
  color: #643820
}
.hljs-title.class_,
.hljs-class .hljs-title,
.hljs-type,
.hljs-built_in,
.hljs-params {
  color: #5c2699
}
.hljs-attr {
  color: #836C28
}
.hljs-subst {
  color: #000
}
.hljs-formula {
  font-style: italic
}
.hljs-addition {

}
.hljs-deletion {

}
.hljs-selector-id,
.hljs-selector-class {
  color: #9b703f
}
.hljs-doctag,
.hljs-strong {
  font-weight: bold
}
.hljs-emphasis {
  font-style: italic
}

}

@media (prefers-color-scheme: dark) {

pre code.hljs {

}
code.hljs {

}
/*

XCode style (c) Angel Garcia <angelgarcia.mail@gmail.com>

*/
.hljs {
  color: inherit
}
/* Gray DOCTYPE selectors like WebKit */
.xml .hljs-meta {
  color: #c0c0c0
}
.hljs-comment,
.hljs-quote {
  color: #007400
}
.hljs-tag,
.hljs-attribute,
.hljs-keyword,
.hljs-selector-tag,
.hljs-literal,
.hljs-name {
  color: #aa0d91
}
.hljs-variable,
.hljs-template-variable {
  color: #3F6E74
}
.hljs-code,
.hljs-string,
.hljs-meta .hljs-string {
  color: #c41a16
}
.hljs-regexp,
.hljs-link {
  color: #0E0EFF
}
.hljs-title,
.hljs-symbol,
.hljs-bullet,
.hljs-number {
  color: #9382ff
}
.hljs-section,
.hljs-meta {
  color: #643820
}
.hljs-title.class_,
.hljs-class .hljs-title,
.hljs-type,
.hljs-built_in,
.hljs-params {
  color: #b879ff
}
.hljs-attr {
  color: #836C28
}
.hljs-subst {
  color: #000
}
.hljs-formula {
  font-style: italic
}
.hljs-addition {

}
.hljs-deletion {

}
.hljs-selector-id,
.hljs-selector-class {
  color: #9b703f
}
.hljs-doctag,
.hljs-strong {
  font-weight: bold
}
.hljs-emphasis {
  font-style: italic
}

}



</style>
<style>
.wording  {
    font-family: 'Noto Serif';
    hyphens: auto;
    line-height: 1.5;
    font-size: 10pt;
    padding-left: 3em;
}

.wording div {
    background: inherit;
}

.wording div.wrapper {
    max-width: 20cm;
    margin: auto;
}

.wording div.texpara {
    margin-top: 3pt;
    margin-bottom: 3pt;
}

.wording table div.texpara {
    margin-top: 0;
    margin-bottom: 0;
}

.wording table.enumerate div.texpara {
    margin-top: 3pt;
    margin-bottom: 3pt;
}

.wording ul {
    list-style-type: none;
    padding-left: 9mm;
    margin-top: 0;
    margin-bottom: 0;
}

.wording ol {
    margin-top: 0;
    margin-bottom: 0;
}

.wording a {
    text-decoration: none;
}

.wording a.hidden_link {
    text-decoration: none;
    color: inherit;
}

.wording li {
    margin-top: 3pt;
    margin-bottom: 3pt;
}

.wording h1 {
    line-height: 1;
    margin-top: 10pt;
    margin-bottom: 10pt;
}

.wording h2 {
    line-height: 1;
    font-size: 14pt;
    margin-top: 10pt;
    margin-bottom: 10pt;
}

.wording h2::after {
    content: "";
    clear: both;
    display: table;
}

.wording h3 {
    line-height: 1;
    margin-top: 10pt;
    margin-bottom: 10pt;
}

.wording h3::after {
    content: "";
    clear: both;
    display: table;
}

.wording h4 {
    line-height: 1;
    margin-top: 10pt;
    margin-bottom: 10pt;
}

.wording h4::after {
    content: "";
    clear: both;
    display: table;
}

.wording ul > li:before {
    content: "\2014";
    position: absolute;
    margin-left: -1.5em;
}

.wording .shy:before {
    content: "\00ad";
    /* This is U+00AD SOFT HYPHEN, same as &shy, but we put it in :before
    	to stop it from being included when the text is copied to the clipboard
    	with Firefox, which is especially annoying when copying to a terminal,
    	where the hyphen characters will show up. */
}


.wording .abbr_ref {
    float: right;
}

.wording .folded_abbr_ref {
    float: right;
}

.wording .unfolded_abbr_ref {
    display: none;
}

.wording .secnum {
    display: inline-block;
    min-width: 35pt;
}

.wording .annexnum {
    display: block;
}

.wording div.sourceLinkParent {
    float: right;
}

.wording a.sourceLink {
    position: absolute;
    opacity: 0;
    margin-left: 10pt;
}

.wording a.sourceLink:hover {
    opacity: 1;
}

.wording a.itemDeclLink {
    position: absolute;
    font-size: 75%;
    text-align: right;
    width: 5em;
    opacity: 0;
}

.wording a.itemDeclLink:hover {
    opacity: 1;
}

.wording div.marginalizedparent {
    position: relative;
    left: -18mm;
}

.wording a.marginalized {
    width: 15mm;
    position: absolute;
    font-size: 7pt;
    text-align: right;
}

.wording a.enumerated_item_num {
    display: block;
    margin-top: 3pt;
    margin-bottom: 3pt;
    margin-right: 6pt;
}

.wording div.para {
    margin-bottom: 6pt;
    margin-top: 6pt;
    text-align: justify;
    min-height: 1.2em;
}

.wording div.section {
    text-align: justify;
}

.wording div.sentence {
    display: inline;
}

.wording a.index {
    position: relative;
    float: right;
    right: -1em;
    display: none;
}

.wording a.index:before {
    position: absolute;
    content: "⟵";
    background-color: #C9FBC9;
}


.wording .indexitems {
    margin-left: 2em;
    text-indent: -2em;
}

.wording div.itemdescr {
    margin-left: 12mm;
}

.wording .bnf {
    font-family: 'Noto Sans';
    font-size: 10pt;
    font-style: italic;
    margin-left: 25pt;
    margin-top: 0.5em;
    margin-bottom: 0.5em;
    text-indent: -3em;
    padding-left: 3em;
    line-height: 1.5;
}

.wording div.bnf span.texttt {
    font-family: 'Noto Sans Mono';
    font-style: normal;
}

.wording .rebnf {
    font-family: 'Noto Serif';
    font-style: italic;
    margin-top: 0.5em;
    margin-bottom: 0.5em;
    margin-left: 30pt;
    text-indent: -3em;
    padding-left: 3em;
    line-height: 1.5;
}

.wording .simplebnf {
    font-family: 'Noto Serif';
    font-style: italic;
    font-size: 10pt;
    margin-top: 0.5em;
    margin-bottom: 0.5em;
    margin-left: 30pt;
    line-height: 1.5;
}

.wording span.textnormal {
    font-style: normal;
    font-family: 'Noto Serif';
    font-size: 10pt;
    white-space: normal;
}

.wording .bnf span.textnormal {
    font-style: normal;
    font-family: 'Noto Serif';
    font-size: 10pt;
    white-space: normal;
}

.wording p {
    margin-top: 4pt;
    margin-bottom: 4pt;
}

.wording span.rlap {
    display: inline-block;
    width: 0px;
    text-indent: 0;
}

.wording span.terminal {
    font-family: 'Noto Sans Mono';
    font-style: normal;
    font-size: 9pt;
    white-space: pre-wrap;
}

.wording span.noncxxterminal {
    font-family: 'Noto Sans Mono';
    font-style: normal;
    font-size: 9pt;
}

.wording span.term {
    font-style: italic;
}

.wording span.tcode {
    font-family: 'Noto Sans Mono';
    font-style: normal;
}

.wording span.textbf {
    font-weight: bold;
}

.wording span.textsf {
    font-family: 'Noto Sans';
    font-size: 10pt;
}

.wording div.footnote span.textsf {
    font-family: 'Noto Sans';
    font-size: 8pt;
}

.wording .bnf span.textsf {
    font-family: 'Noto Sans';
    font-size: 10pt;
}

.wording .simplebnf span.textsf {
    font-family: 'Noto Sans';
    font-size: 10pt;
}

.wording .example span.textsf {
    font-family: 'Noto Sans';
    font-size: 10pt;
}

.wording span.textsc {
    font-variant: small-caps;
}

.wording span.nontermdef {
    font-style: italic;
    font-family: 'Noto Sans';
    font-size: 10pt;
}

.wording .rebnf a.nontermdef {
    font-style: italic;
    font-family: 'Noto Serif';
}

.wording span.emph {
    font-style: italic;
}

.wording span.techterm {
    font-style: italic;
}

.wording span.mathit {
    font-style: italic;
}

.wording span.mathsf {
    font-family: 'Noto Sans';
}

.wording span.mathrm {
    font-family: 'Noto Serif';
    font-style: normal;
}

.wording span.textrm {
    font-family: 'Noto Serif';
    font-size: 10pt;
}

.wording span.textsl {
    font-style: italic;
}

.wording span.mathtt {
    font-family: 'Noto Sans Mono';
    font-style: normal;
}

.wording span.mbox {
    font-family: 'Noto Serif';
    font-style: normal;
}

.wording span.ungap {
    display: inline-block;
    width: 2pt;
}

.wording span.texttt {
    font-family: 'Noto Sans Mono';
}

.wording span.textit {
    font-style: italic;
}

.wording div.footnote span.texttt {
    font-family: 'Noto Sans Mono';
}

.wording span.tcode_in_codeblock {
    font-family: 'Noto Sans Mono';
    font-style: normal;
    font-size: 9pt;
}

.wording span.phantom {
    color: white;
}
/* Unfortunately, this way the text is still selectable. Another
	option is display:none, but then we lose the nice layout.
	Todo: find proper solution. */

.wording span.math {
    font-style: normal;
    font-family: 'Noto Serif';
    font-size: 10pt;
}

.wording span.mathblock {
    display: block;
    margin-left: auto;
    margin-right: auto;
    margin-top: 1.2em;
    margin-bottom: 1.2em;
    text-align: center;
}

.wording span.mathalpha {
    font-style: italic;
}

.wording span.synopsis {
    font-weight: bold;
    margin-top: 0.5em;
    display: block;
}

.wording span.definition {
    font-weight: bold;
    display: block;
}

.wording .codeblock {
    font-family: 'Noto Sans Mono';
    margin-left: 1.2em;
    line-height: 1.5;
    font-size: 9pt;
    white-space: pre;
    display: block;
    margin-top: 3pt;
    margin-bottom: 3pt;
		overflow-x: visible;
		overflow-y: default;
}

.wording table .codeblock {
    margin-right: 0;
}

.wording .outputblock {
    margin-left: 1.2em;
    line-height: 1.5;
    font-family: 'Noto Sans Mono';
    font-size: 9pt;
}

.wording code {
    font-family: 'Noto Sans Mono';
    font-style: normal;
}

.wording div.itemdecl {
    margin-top: 2ex;
}

.wording code.itemdeclcode {
    white-space: pre;
    font-family: 'Noto Sans Mono';
    font-size: 9pt;
    display: block;
		overflow-x: visible;
		overflow-y: default;
}

.wording .comment {
    color: green;
    font-style: italic;
    font-family: 'Noto Serif';
    font-size: 10pt;
}

.wording .footnote .comment {
    color: green;
    font-style: italic;
    font-family: 'Noto Serif';
    font-size: 8pt;
}

.wording .example .comment {
    color: green;
    font-style: italic;
    font-family: 'Noto Serif';
    font-size: 9pt;
}

.wording .note .comment {
    color: green;
    font-style: italic;
    font-family: 'Noto Serif';
    font-size: 9pt;
}

.wording span.keyword {
    color: #00607c;
    font-style: normal;
}

.wording span.parenthesis {
    color: #af1915;
}

.wording span.curlybracket {
    color: #af1915;
}

.wording span.squarebracket {
    color: #af1915;
}

.wording span.literal {
    color: #9F6807;
}

.wording span.literalterminal {
    color: #9F6807;
    font-family: 'Noto Sans Mono';
    font-style: normal;
}

.wording span.operator {
    color: #570057;
}

.wording span.anglebracket {
    color: #570057;
}

.wording span.preprocessordirective {
    color: #6F4E37;
}

.wording span.textsuperscript {
    vertical-align: super;
    font-size: smaller;
    line-height: 0;
}

.wording .footnoteref {
    vertical-align: super;
    font-size: smaller;
    line-height: 0;
}

.wording .footnote {
    font-size: 8pt;
}

.wording .footnote .math {
    font-size: 8pt;
}

.wording .footnotenum {
    display: inline-block;
    text-align: right;
    margin-right: 1mm;
    width: 4ch;
}

.wording .footnoteBacklink {
    display: none;
}

.wording .footnoteSeparator {
    background: black;
    margin-top: 5mm;
    height: 1px;
    width: 6cm;
}

.wording div.minipage {
    display: inline-block;
    margin-right: 3em;
}

.wording div.numberedTable {
    text-align: center;
    margin-left: 1em;
    margin-right: 1em;
    margin-bottom: 12pt;
    margin-top: 8pt;
}

.wording div.figure {
    text-align: center;
    margin-left: 2em;
    margin-right: 2em;
    margin-bottom: 12pt;
    margin-top: 3pt;
}

.wording table {
    border: 1px solid black;
    border-collapse: collapse;
    margin-left: auto;
    margin-right: auto;
    margin-top: 7pt;
    text-align: left;
}

.wording td, .wording th {
    padding-left: 8pt;
    padding-right: 8pt;
    vertical-align: top;
}

.wording td.empty {
    padding: 0px;
    padding-left: 1px;
}

.wording td.left {
    text-align: left;
}

.wording td.hidden {
    padding: 0;
    width: 0;
}

.wording td.right {
    text-align: right;
}

.wording td.center {
    text-align: center;
}

.wording td.justify {
    text-align: justify;
}

.wording td.border {
    border-left: 1px solid black;
}

.wording tr.rowsep, .wording td.cline {
    border-top: 1px solid black;
}

.wording tr.capsep {
    border-top: 3px solid black;
    border-top-style: double;
}

.wording th {
    border-bottom: 1px solid black;
}

.wording span.centry {
    font-weight: bold;
}

.wording div.table {
    display: block;
    margin-left: auto;
    margin-right: auto;
    text-align: center;
    width: 90%;
}

.wording span.indented {
    background: inherit;
    display: block;
    margin-left: 2em;
    margin-bottom: 1em;
    margin-top: 1em;
}

.wording span.uppercase {
    text-transform: uppercase;
}

.wording span.ucode {
    font-variant: small-caps;
    text-transform: uppercase;
    font-size: 90%;
}

.wording span.uname {
    font-variant: small-caps;
    text-transform: uppercase;
    font-size: 90%;
}

.wording table.enumerate {
    border: 0;
    margin: 0;
}

.wording table.enumerate td {
    padding: 0;
}

.wording table.enumerate td:first-child {
    width: 1cm;
    text-align: right;
}

@media (prefers-color-scheme: dark) {
    .wording {
        background-color: #171717;
        color: #d0d0d0;
    }

    .wording span.mjx-mstyle {
        color: #d0d0d0 !important
    }

    .wording a:link {
        color: #64adff;
    }

    .wording a:visited {
        color: #a36ae6;
    }

    .wording a.hidden_link {
        text-decoration: none;
        color: inherit;
    }

    .wording span.phantom {
        color: #171717;
    }

    .wording a.index:before {
        color: #d0d0d0;
        background-color: #4b6353;
    }

    .wording .comment {
        color: #35da00;
    }

    .wording .footnote .comment {
        color: #35da00;
    }

    .wording .example .comment {
        color: #35da00;
    }

    .wording .note .comment {
        color: #35da00;
    }

    .wording span.keyword {
        color: #12cabe;
    }

    .wording span.parenthesis {
        color: #ff1515;
    }

    .wording span.curlybracket {
        color: #ff1515;
    }

    .wording span.squarebracket {
        color: #ff1515;
    }

    .wording span.literal {
        color: #dfa837;
    }

    .wording span.literalterminal {
        color: #dfa837;
    }

    .wording span.operator {
        color: #baa6b9;
    }

    .wording span.anglebracket {
        color: #baa6b9;
    }

    .wording span.preprocessordirective {
        color: #b27c58;
    }

    .wording table {
        border-color: #d0d0d0;
    }

    .wording td.border {
        border-color: #d0d0d0;
    }

    .wording td.border {
        border-left-color: #d0d0d0;
    }

    .wording tr.rowsep, td.cline {
        border-top-color: #d0d0d0;
    }

    .wording tr.capsep {
        border-top-color: #d0d0d0;
    }

    .wording th {
        border-bottom-color: #d0d0d0;
    }

    .wording .footnoteSeparator {
        background-color: #d0d0d0;
    }

    .wording text {
        fill: #d0d0d0;
    }

    .wording path {
        stroke: #d0d0d0;
    }

    .wording polygon {
        stroke: #d0d0d0;
        fill: #d0d0d0;
    }

    .wording ellipse {
        stroke: #d0d0d0;
    }

}

.wording .mjx-chtml {
    display: inline-block;
    line-height: 0;
    text-indent: 0;
    text-align: left;
    text-transform: none;
    font-style: normal;
    font-weight: normal;
    font-size: 100%;
    font-size-adjust: none;
    letter-spacing: normal;
    word-wrap: normal;
    word-spacing: normal;
    white-space: nowrap;
    float: none;
    direction: ltr;
    max-width: none;
    max-height: none;
    min-width: 0;
    min-height: 0;
    border: 0;
    margin: 0;
    padding: 1px 0
}

.wording .MJXc-display {
    display: block;
    background: inherit;
    text-align: center;
    margin: 1em 0;
    padding: 0
}

.wording .mjx-chtml[tabindex]:focus, .wording  :focus .mjx-chtml[tabindex] {
    display: inline-table
}

.wording .mjx-full-width {
    text-align: center;
    display: table-cell !important;
    width: 10000em
}

.wording .mjx-math {
    display: inline-block;
    border-collapse: separate;
    border-spacing: 0
}

.wording .mjx-math * {
    display: inline-block;
    -webkit-box-sizing: content-box !important;
    -moz-box-sizing: content-box !important;
    box-sizing: content-box !important;
    text-align: left
}

.wording .mjx-numerator {
    display: block;
    background: inherit;
    text-align: center
}

.wording .mjx-denominator {
    display: block;
    background: inherit;
    text-align: center
}

.wording .MJXc-stacked {
    height: 0;
    position: relative
}

.wording .MJXc-stacked > * {
    position: absolute
}

.wording .MJXc-bevelled > * {
    display: inline-block
}

.wording .mjx-stack {
    display: inline-block
}

.wording .mjx-op {
    display: block;
    background: inherit
}

.wording .mjx-under {
    display: table-cell
}

.wording .mjx-over {
    display: block;
    background: inherit
}

.wording .mjx-over > * {
    padding-left: 0px !important;
    padding-right: 0px !important
}

.wording .mjx-under > * {
    padding-left: 0px !important;
    padding-right: 0px !important
}

.wording .mjx-stack > .mjx-sup {
    display: block;
    background: inherit
}

.wording .mjx-stack > .mjx-sub {
    display: block;
    background: inherit
}

.wording .mjx-prestack > .mjx-presup {
    display: block;
    background: inherit
}

.wording .mjx-prestack > .mjx-presub {
    display: block;
    background: inherit
}

.wording .mjx-delim-h > .mjx-char {
    display: inline-block
}

.wording .mjx-surd {
    vertical-align: top
}

.wording .mjx-mphantom * {
    visibility: hidden
}

.wording .mjx-merror {
    background-color: #FFFF88;
    color: #CC0000;
    border: 1px solid #CC0000;
    padding: 2px 3px;
    font-style: normal;
    font-size: 90%
}

.wording .mjx-annotation-xml {
    line-height: normal
}

.wording .mjx-menclose > svg {
    fill: none;
    stroke: currentColor
}

.wording .mjx-mtr {
    display: table-row
}

.wording .mjx-mlabeledtr {
    display: table-row
}

.wording .mjx-mtd {
    display: table-cell;
    text-align: center
}

.wording .mjx-label {
    display: table-row
}

.wording .mjx-box {
    display: inline-block
}

.wording .mjx-block {
    display: block;
    background: inherit
}

.wording .mjx-span {
    display: inline
}

.wording .mjx-char {
    display: block;
    background: inherit;
    white-space: pre
}

.wording .mjx-itable {
    display: inline-table;
    width: auto
}

.wording .mjx-row {
    display: table-row
}

.wording .mjx-cell {
    display: table-cell
}

.wording .mjx-table {
    display: table;
    width: 100%
}

.wording .mjx-line {
    display: block;
    background: inherit;
    height: 0
}

.wording .mjx-strut {
    width: 0;
    padding-top: 1em
}

.wording .mjx-vsize {
    width: 0
}

.wording .MJXc-space1 {
    margin-left: .167em
}

.wording .MJXc-space2 {
    margin-left: .222em
}

.wording .MJXc-space3 {
    margin-left: .278em
}

.wording .mjx-ex-box-test {
    position: absolute;
		overflow-x: visible;
		overflow-y: default;
    width: 1px;
    height: 60ex
}

.wording .mjx-line-box-test {
    display: table !important
}

.wording .mjx-line-box-test span {
    display: table-cell !important;
    width: 10000em !important;
    min-width: 0;
    max-width: none;
    padding: 0;
    border: 0;
    margin: 0
}

.wording .MJXc-TeX-unknown-R {
    font-family: monospace;
    font-style: normal;
    font-weight: normal
}

.wording .MJXc-TeX-unknown-I {
    font-family: monospace;
    font-style: italic;
    font-weight: normal
}

.wording .MJXc-TeX-unknown-B {
    font-family: monospace;
    font-style: normal;
    font-weight: bold
}

.wording .MJXc-TeX-unknown-BI {
    font-family: monospace;
    font-style: italic;
    font-weight: bold
}

.wording .MJXc-TeX-ams-R {
    font-family: MJXc-TeX-ams-R, MJXc-TeX-ams-Rw
}

.wording .MJXc-TeX-cal-B {
    font-family: MJXc-TeX-cal-B, MJXc-TeX-cal-Bx, MJXc-TeX-cal-Bw
}

.wording .MJXc-TeX-frak-R {
    font-family: MJXc-TeX-frak-R, MJXc-TeX-frak-Rw
}

.wording .MJXc-TeX-frak-B {
    font-family: MJXc-TeX-frak-B, MJXc-TeX-frak-Bx, MJXc-TeX-frak-Bw
}

.wording .MJXc-TeX-math-BI {
    font-family: MJXc-TeX-math-BI, MJXc-TeX-math-BIx, MJXc-TeX-math-BIw
}

.wording .MJXc-TeX-sans-R {
    font-family: 'Noto Sans';
    font-size: 10pt;
}

.wording .MJXc-TeX-sans-B {
    font-family: MJXc-TeX-sans-B, MJXc-TeX-sans-Bx, MJXc-TeX-sans-Bw
}

.wording .MJXc-TeX-sans-I {
    font-family: MJXc-TeX-sans-I, MJXc-TeX-sans-Ix, MJXc-TeX-sans-Iw
}

.wording .MJXc-TeX-script-R {
    font-family: MJXc-TeX-script-R, MJXc-TeX-script-Rw
}

.wording .MJXc-TeX-type-R {
    font-family: 'Noto Sans Mono';
    font-size: 10pt;
}

.wording .MJXc-TeX-cal-R {
    font-family: MJXc-TeX-cal-R, MJXc-TeX-cal-Rw
}

.wording .MJXc-TeX-main-B {
    font-family: MJXc-TeX-main-B, MJXc-TeX-main-Bx, MJXc-TeX-main-Bw
}

.wording .MJXc-TeX-main-I {
    font-style: italic
}

.wording .MJXc-TeX-main-R {
}

.wording .MJXc-TeX-math-I {
    font-style: italic
}

.wording .MJXc-TeX-size1-R {
    font-family: MJXc-TeX-size1-R, MJXc-TeX-size1-Rw
}

.wording .MJXc-TeX-size2-R {
    font-family: MJXc-TeX-size2-R, MJXc-TeX-size2-Rw
}

.wording .MJXc-TeX-size3-R {
    font-family: MJXc-TeX-size3-R, MJXc-TeX-size3-Rw
}

.wording .MJXc-TeX-size4-R {
    font-family: MJXc-TeX-size4-R, MJXc-TeX-size4-Rw
}

.wording .MJXc-TeX-vec-R {
    font-family: MJXc-TeX-vec-R, MJXc-TeX-vec-Rw
}

.wording .MJXc-TeX-vec-B {
    font-family: MJXc-TeX-vec-B, MJXc-TeX-vec-Bx, MJXc-TeX-vec-Bw
}

@font-face {
    font-family: MJXc-TeX-ams-R;
    src: local('MathJax_AMS'), local('MathJax_AMS-Regular')
}

@font-face {
    font-family: MJXc-TeX-ams-Rw;
    src /*1*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/eot/MathJax_AMS-Regular.eot');
    src /*2*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/woff/MathJax_AMS-Regular.woff') format('woff'), url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/otf/MathJax_AMS-Regular.otf') format('opentype')
}

@font-face {
    font-family: MJXc-TeX-cal-B;
    src: local('MathJax_Caligraphic Bold'), local('MathJax_Caligraphic-Bold')
}

@font-face {
    font-family: MJXc-TeX-cal-Bx;
    src: local('MathJax_Caligraphic');
    font-weight: bold
}

@font-face {
    font-family: MJXc-TeX-cal-Bw;
    src /*1*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/eot/MathJax_Caligraphic-Bold.eot');
    src /*2*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/woff/MathJax_Caligraphic-Bold.woff') format('woff'), url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/otf/MathJax_Caligraphic-Bold.otf') format('opentype')
}

@font-face {
    font-family: MJXc-TeX-frak-R;
    src: local('MathJax_Fraktur'), local('MathJax_Fraktur-Regular')
}

@font-face {
    font-family: MJXc-TeX-frak-Rw;
    src /*1*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/eot/MathJax_Fraktur-Regular.eot');
    src /*2*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/woff/MathJax_Fraktur-Regular.woff') format('woff'), url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/otf/MathJax_Fraktur-Regular.otf') format('opentype')
}

@font-face {
    font-family: MJXc-TeX-frak-B;
    src: local('MathJax_Fraktur Bold'), local('MathJax_Fraktur-Bold')
}

@font-face {
    font-family: MJXc-TeX-frak-Bx;
    src: local('MathJax_Fraktur');
    font-weight: bold
}

@font-face {
    font-family: MJXc-TeX-frak-Bw;
    src /*1*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/eot/MathJax_Fraktur-Bold.eot');
    src /*2*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/woff/MathJax_Fraktur-Bold.woff') format('woff'), url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/otf/MathJax_Fraktur-Bold.otf') format('opentype')
}

@font-face {
    font-family: MJXc-TeX-math-BI;
    src: local('MathJax_Math BoldItalic'), local('MathJax_Math-BoldItalic')
}

@font-face {
    font-family: MJXc-TeX-math-BIx;
    src: local('MathJax_Math');
    font-weight: bold;
    font-style: italic
}

@font-face {
    font-family: MJXc-TeX-math-BIw;
    src /*1*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/eot/MathJax_Math-BoldItalic.eot');
    src /*2*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/woff/MathJax_Math-BoldItalic.woff') format('woff'), url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/otf/MathJax_Math-BoldItalic.otf') format('opentype')
}

@font-face {
    font-family: MJXc-TeX-sans-R;
    src: local('MathJax_SansSerif'), local('MathJax_SansSerif-Regular')
}

@font-face {
    font-family: MJXc-TeX-sans-Rw;
    src /*1*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/eot/MathJax_SansSerif-Regular.eot');
    src /*2*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/woff/MathJax_SansSerif-Regular.woff') format('woff'), url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/otf/MathJax_SansSerif-Regular.otf') format('opentype')
}

@font-face {
    font-family: MJXc-TeX-sans-B;
    src: local('MathJax_SansSerif Bold'), local('MathJax_SansSerif-Bold')
}

@font-face {
    font-family: MJXc-TeX-sans-Bx;
    src: local('MathJax_SansSerif');
    font-weight: bold
}

@font-face {
    font-family: MJXc-TeX-sans-Bw;
    src /*1*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/eot/MathJax_SansSerif-Bold.eot');
    src /*2*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/woff/MathJax_SansSerif-Bold.woff') format('woff'), url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/otf/MathJax_SansSerif-Bold.otf') format('opentype')
}

@font-face {
    font-family: MJXc-TeX-sans-I;
    src: local('MathJax_SansSerif Italic'), local('MathJax_SansSerif-Italic')
}

@font-face {
    font-family: MJXc-TeX-sans-Ix;
    src: local('MathJax_SansSerif');
    font-style: italic
}

@font-face {
    font-family: MJXc-TeX-sans-Iw;
    src /*1*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/eot/MathJax_SansSerif-Italic.eot');
    src /*2*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/woff/MathJax_SansSerif-Italic.woff') format('woff'), url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/otf/MathJax_SansSerif-Italic.otf') format('opentype')
}

@font-face {
    font-family: MJXc-TeX-script-R;
    src: local('MathJax_Script'), local('MathJax_Script-Regular')
}

@font-face {
    font-family: MJXc-TeX-script-Rw;
    src /*1*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/eot/MathJax_Script-Regular.eot');
    src /*2*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/woff/MathJax_Script-Regular.woff') format('woff'), url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/otf/MathJax_Script-Regular.otf') format('opentype')
}

@font-face {
    font-family: MJXc-TeX-type-R;
    src: local('MathJax_Typewriter'), local('MathJax_Typewriter-Regular')
}

@font-face {
    font-family: MJXc-TeX-type-Rw;
    src /*1*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/eot/MathJax_Typewriter-Regular.eot');
    src /*2*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/woff/MathJax_Typewriter-Regular.woff') format('woff'), url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/otf/MathJax_Typewriter-Regular.otf') format('opentype')
}

@font-face {
    font-family: MJXc-TeX-cal-R;
    src: local('MathJax_Caligraphic'), local('MathJax_Caligraphic-Regular')
}

@font-face {
    font-family: MJXc-TeX-cal-Rw;
    src /*1*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/eot/MathJax_Caligraphic-Regular.eot');
    src /*2*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/woff/MathJax_Caligraphic-Regular.woff') format('woff'), url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/otf/MathJax_Caligraphic-Regular.otf') format('opentype')
}

@font-face {
    font-family: MJXc-TeX-main-B;
    src: local('MathJax_Main Bold'), local('MathJax_Main-Bold')
}

@font-face {
    font-family: MJXc-TeX-main-Bx;
    src: local('MathJax_Main');
    font-weight: bold
}

@font-face {
    font-family: MJXc-TeX-main-Bw;
    src /*1*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/eot/MathJax_Main-Bold.eot');
    src /*2*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/woff/MathJax_Main-Bold.woff') format('woff'), url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/otf/MathJax_Main-Bold.otf') format('opentype')
}

@font-face {
    font-family: MJXc-TeX-main-I;
    src: local('MathJax_Main Italic'), local('MathJax_Main-Italic')
}

@font-face {
    font-family: MJXc-TeX-main-Ix;
    src: local('MathJax_Main');
    font-style: italic
}

@font-face {
    font-family: MJXc-TeX-main-Iw;
    src /*1*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/eot/MathJax_Main-Italic.eot');
    src /*2*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/woff/MathJax_Main-Italic.woff') format('woff'), url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/otf/MathJax_Main-Italic.otf') format('opentype')
}

@font-face {
    font-family: MJXc-TeX-main-R;
    src: local('MathJax_Main'), local('MathJax_Main-Regular')
}

@font-face {
    font-family: MJXc-TeX-main-Rw;
    src /*1*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/eot/MathJax_Main-Regular.eot');
    src /*2*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/woff/MathJax_Main-Regular.woff') format('woff'), url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/otf/MathJax_Main-Regular.otf') format('opentype')
}

@font-face {
    font-family: MJXc-TeX-math-I;
    src: local('MathJax_Math Italic'), local('MathJax_Math-Italic')
}

@font-face {
    font-family: MJXc-TeX-math-Ix;
    src: local('MathJax_Math');
    font-style: italic
}

@font-face {
    font-family: MJXc-TeX-math-Iw;
    src /*1*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/eot/MathJax_Math-Italic.eot');
    src /*2*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/woff/MathJax_Math-Italic.woff') format('woff'), url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/otf/MathJax_Math-Italic.otf') format('opentype')
}

@font-face {
    font-family: MJXc-TeX-size1-R;
    src: local('MathJax_Size1'), local('MathJax_Size1-Regular')
}

@font-face {
    font-family: MJXc-TeX-size1-Rw;
    src /*1*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/eot/MathJax_Size1-Regular.eot');
    src /*2*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/woff/MathJax_Size1-Regular.woff') format('woff'), url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/otf/MathJax_Size1-Regular.otf') format('opentype')
}

@font-face {
    font-family: MJXc-TeX-size2-R;
    src: local('MathJax_Size2'), local('MathJax_Size2-Regular')
}

@font-face {
    font-family: MJXc-TeX-size2-Rw;
    src /*1*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/eot/MathJax_Size2-Regular.eot');
    src /*2*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/woff/MathJax_Size2-Regular.woff') format('woff'), url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/otf/MathJax_Size2-Regular.otf') format('opentype')
}

@font-face {
    font-family: MJXc-TeX-size3-R;
    src: local('MathJax_Size3'), local('MathJax_Size3-Regular')
}

@font-face {
    font-family: MJXc-TeX-size3-Rw;
    src /*1*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/eot/MathJax_Size3-Regular.eot');
    src /*2*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/woff/MathJax_Size3-Regular.woff') format('woff'), url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/otf/MathJax_Size3-Regular.otf') format('opentype')
}

@font-face {
    font-family: MJXc-TeX-size4-R;
    src: local('MathJax_Size4'), local('MathJax_Size4-Regular')
}

@font-face {
    font-family: MJXc-TeX-size4-Rw;
    src /*1*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/eot/MathJax_Size4-Regular.eot');
    src /*2*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/woff/MathJax_Size4-Regular.woff') format('woff'), url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/otf/MathJax_Size4-Regular.otf') format('opentype')
}

@font-face {
    font-family: MJXc-TeX-vec-R;
    src: local('MathJax_Vector'), local('MathJax_Vector-Regular')
}

@font-face {
    font-family: MJXc-TeX-vec-Rw;
    src /*1*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/eot/MathJax_Vector-Regular.eot');
    src /*2*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/woff/MathJax_Vector-Regular.woff') format('woff'), url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/otf/MathJax_Vector-Regular.otf') format('opentype')
}

@font-face {
    font-family: MJXc-TeX-vec-B;
    src: local('MathJax_Vector Bold'), local('MathJax_Vector-Bold')
}

@font-face {
    font-family: MJXc-TeX-vec-Bx;
    src: local('MathJax_Vector');
    font-weight: bold
}

@font-face {
    font-family: MJXc-TeX-vec-Bw;
    src /*1*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/eot/MathJax_Vector-Bold.eot');
    src /*2*/: url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/woff/MathJax_Vector-Bold.woff') format('woff'), url('https://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/otf/MathJax_Vector-Bold.otf') format('opentype')
}

.wording div.example {
	display: block;
	margin-top: 5pt;
	margin-bottom: 5pt;
	font-size: 11pt;
	color: #bb00bb;
}

.wording div.note {
	display: block;
	margin-top: 5pt;
	margin-bottom: 5pt;
	font-size: 11pt;
	color: #bb00bb;
}

.wording div.example {
	display: block;
	margin-top: 5pt;
	margin-bottom: 5pt;
	font-size: 9pt;
}

.wording div.note {
	display: block;
	margin-top: 5pt;
	margin-bottom: 5pt;
	font-size: 9pt;
}

.wording div.note .texttt { font-size: 9pt; }
.wording div.example .texttt { font-size: 9pt; }

.wording div.note .textsf { font-family: 'Noto Sans'; font-size: 9pt; }
.wording div.example .textsf { font-family: 'Noto Sans'; font-size: 9pt; }

.wording div.note .math { font-size: 9pt; }
.wording div.example .math { font-size: 9pt; }

.wording a.footnotenum { display: none; }
.wording div.footnote { display: none; }
.wording div.footnoteSeparator { display: none; }
.wording .footnoteref { display: none; }

.wording div.nonNormativeOnly { display: none; }


</style>
<link href="https://fonts.googleapis.com/css?family=Noto+Serif" rel='stylesheet'>
<link href="https://fonts.googleapis.com/css?family=Noto+Sans" rel='stylesheet'>
<link href="https://fonts.googleapis.com/css?family=Noto+Sans+Mono" rel='stylesheet'>
<script language='javascript'>
/*!
  Highlight.js v11.9.0 (git: b7ec4bfafc)
  (c) 2006-2024 undefined and other contributors
  License: BSD-3-Clause
 */
var hljs=function(){"use strict";function e(t){
return t instanceof Map?t.clear=t.delete=t.set=()=>{
throw Error("map is read-only")}:t instanceof Set&&(t.add=t.clear=t.delete=()=>{
throw Error("set is read-only")
}),Object.freeze(t),Object.getOwnPropertyNames(t).forEach((n=>{
const i=t[n],s=typeof i;"object"!==s&&"function"!==s||Object.isFrozen(i)||e(i)
})),t}class t{constructor(e){
void 0===e.data&&(e.data={}),this.data=e.data,this.isMatchIgnored=!1}
ignoreMatch(){this.isMatchIgnored=!0}}function n(e){
return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;")
}function i(e,...t){const n=Object.create(null);for(const t in e)n[t]=e[t]
;return t.forEach((e=>{for(const t in e)n[t]=e[t]})),n}const s=e=>!!e.scope
;class o{constructor(e,t){
this.buffer="",this.classPrefix=t.classPrefix,e.walk(this)}addText(e){
this.buffer+=n(e)}openNode(e){if(!s(e))return;const t=((e,{prefix:t})=>{
if(e.startsWith("language:"))return e.replace("language:","language-")
;if(e.includes(".")){const n=e.split(".")
;return[`${t}${n.shift()}`,...n.map(((e,t)=>`${e}${"_".repeat(t+1)}`))].join(" ")
}return`${t}${e}`})(e.scope,{prefix:this.classPrefix});this.span(t)}
closeNode(e){s(e)&&(this.buffer+="</span>")}value(){return this.buffer}span(e){
this.buffer+=`<span class="${e}">`}}const r=(e={})=>{const t={children:[]}
;return Object.assign(t,e),t};class a{constructor(){
this.rootNode=r(),this.stack=[this.rootNode]}get top(){
return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){
this.top.children.push(e)}openNode(e){const t=r({scope:e})
;this.add(t),this.stack.push(t)}closeNode(){
if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){
for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}
walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,t){
return"string"==typeof t?e.addText(t):t.children&&(e.openNode(t),
t.children.forEach((t=>this._walk(e,t))),e.closeNode(t)),e}static _collapse(e){
"string"!=typeof e&&e.children&&(e.children.every((e=>"string"==typeof e))?e.children=[e.children.join("")]:e.children.forEach((e=>{
a._collapse(e)})))}}class c extends a{constructor(e){super(),this.options=e}
addText(e){""!==e&&this.add(e)}startScope(e){this.openNode(e)}endScope(){
this.closeNode()}__addSublanguage(e,t){const n=e.root
;t&&(n.scope="language:"+t),this.add(n)}toHTML(){
return new o(this,this.options).value()}finalize(){
return this.closeAllNodes(),!0}}function l(e){
return e?"string"==typeof e?e:e.source:null}function g(e){return h("(?=",e,")")}
function u(e){return h("(?:",e,")*")}function d(e){return h("(?:",e,")?")}
function h(...e){return e.map((e=>l(e))).join("")}function f(...e){const t=(e=>{
const t=e[e.length-1]
;return"object"==typeof t&&t.constructor===Object?(e.splice(e.length-1,1),t):{}
})(e);return"("+(t.capture?"":"?:")+e.map((e=>l(e))).join("|")+")"}
function p(e){return RegExp(e.toString()+"|").exec("").length-1}
const b=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./
;function m(e,{joinWith:t}){let n=0;return e.map((e=>{n+=1;const t=n
;let i=l(e),s="";for(;i.length>0;){const e=b.exec(i);if(!e){s+=i;break}
s+=i.substring(0,e.index),
i=i.substring(e.index+e[0].length),"\\"===e[0][0]&&e[1]?s+="\\"+(Number(e[1])+t):(s+=e[0],
"("===e[0]&&n++)}return s})).map((e=>`(${e})`)).join(t)}
const E="[a-zA-Z]\\w*",x="[a-zA-Z_]\\w*",w="\\b\\d+(\\.\\d+)?",y="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",_="\\b(0b[01]+)",O={
begin:"\\\\[\\s\\S]",relevance:0},v={scope:"string",begin:"'",end:"'",
illegal:"\\n",contains:[O]},k={scope:"string",begin:'"',end:'"',illegal:"\\n",
contains:[O]},N=(e,t,n={})=>{const s=i({scope:"comment",begin:e,end:t,
contains:[]},n);s.contains.push({scope:"doctag",
begin:"[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)",
end:/(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,excludeBegin:!0,relevance:0})
;const o=f("I","a","is","so","us","to","at","if","in","it","on",/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,/[A-Za-z]+[-][a-z]+/,/[A-Za-z][a-z]{2,}/)
;return s.contains.push({begin:h(/[ ]+/,"(",o,/[.]?[:]?([.][ ]|[ ])/,"){3}")}),s
},S=N("//","$"),M=N("/\\*","\\*/"),R=N("#","$");var j=Object.freeze({
__proto__:null,APOS_STRING_MODE:v,BACKSLASH_ESCAPE:O,BINARY_NUMBER_MODE:{
scope:"number",begin:_,relevance:0},BINARY_NUMBER_RE:_,COMMENT:N,
C_BLOCK_COMMENT_MODE:M,C_LINE_COMMENT_MODE:S,C_NUMBER_MODE:{scope:"number",
begin:y,relevance:0},C_NUMBER_RE:y,END_SAME_AS_BEGIN:e=>Object.assign(e,{
"on:begin":(e,t)=>{t.data._beginMatch=e[1]},"on:end":(e,t)=>{
t.data._beginMatch!==e[1]&&t.ignoreMatch()}}),HASH_COMMENT_MODE:R,IDENT_RE:E,
MATCH_NOTHING_RE:/\b\B/,METHOD_GUARD:{begin:"\\.\\s*"+x,relevance:0},
NUMBER_MODE:{scope:"number",begin:w,relevance:0},NUMBER_RE:w,
PHRASAL_WORDS_MODE:{
begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/
},QUOTE_STRING_MODE:k,REGEXP_MODE:{scope:"regexp",begin:/\/(?=[^/\n]*\/)/,
end:/\/[gimuy]*/,contains:[O,{begin:/\[/,end:/\]/,relevance:0,contains:[O]}]},
RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",
SHEBANG:(e={})=>{const t=/^#![ ]*\//
;return e.binary&&(e.begin=h(t,/.*\b/,e.binary,/\b.*/)),i({scope:"meta",begin:t,
end:/$/,relevance:0,"on:begin":(e,t)=>{0!==e.index&&t.ignoreMatch()}},e)},
TITLE_MODE:{scope:"title",begin:E,relevance:0},UNDERSCORE_IDENT_RE:x,
UNDERSCORE_TITLE_MODE:{scope:"title",begin:x,relevance:0}});function A(e,t){
"."===e.input[e.index-1]&&t.ignoreMatch()}function I(e,t){
void 0!==e.className&&(e.scope=e.className,delete e.className)}function T(e,t){
t&&e.beginKeywords&&(e.begin="\\b("+e.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)",
e.__beforeBegin=A,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords,
void 0===e.relevance&&(e.relevance=0))}function L(e,t){
Array.isArray(e.illegal)&&(e.illegal=f(...e.illegal))}function B(e,t){
if(e.match){
if(e.begin||e.end)throw Error("begin & end are not supported with match")
;e.begin=e.match,delete e.match}}function P(e,t){
void 0===e.relevance&&(e.relevance=1)}const D=(e,t)=>{if(!e.beforeMatch)return
;if(e.starts)throw Error("beforeMatch cannot be used with starts")
;const n=Object.assign({},e);Object.keys(e).forEach((t=>{delete e[t]
})),e.keywords=n.keywords,e.begin=h(n.beforeMatch,g(n.begin)),e.starts={
relevance:0,contains:[Object.assign(n,{endsParent:!0})]
},e.relevance=0,delete n.beforeMatch
},H=["of","and","for","in","not","or","if","then","parent","list","value"],C="keyword"
;function $(e,t,n=C){const i=Object.create(null)
;return"string"==typeof e?s(n,e.split(" ")):Array.isArray(e)?s(n,e):Object.keys(e).forEach((n=>{
Object.assign(i,$(e[n],t,n))})),i;function s(e,n){
t&&(n=n.map((e=>e.toLowerCase()))),n.forEach((t=>{const n=t.split("|")
;i[n[0]]=[e,U(n[0],n[1])]}))}}function U(e,t){
return t?Number(t):(e=>H.includes(e.toLowerCase()))(e)?0:1}const z={},W=e=>{
console.error(e)},X=(e,...t)=>{console.log("WARN: "+e,...t)},G=(e,t)=>{
z[`${e}/${t}`]||(console.log(`Deprecated as of ${e}. ${t}`),z[`${e}/${t}`]=!0)
},K=Error();function F(e,t,{key:n}){let i=0;const s=e[n],o={},r={}
;for(let e=1;e<=t.length;e++)r[e+i]=s[e],o[e+i]=!0,i+=p(t[e-1])
;e[n]=r,e[n]._emit=o,e[n]._multi=!0}function Z(e){(e=>{
e.scope&&"object"==typeof e.scope&&null!==e.scope&&(e.beginScope=e.scope,
delete e.scope)})(e),"string"==typeof e.beginScope&&(e.beginScope={
_wrap:e.beginScope}),"string"==typeof e.endScope&&(e.endScope={_wrap:e.endScope
}),(e=>{if(Array.isArray(e.begin)){
if(e.skip||e.excludeBegin||e.returnBegin)throw W("skip, excludeBegin, returnBegin not compatible with beginScope: {}"),
K
;if("object"!=typeof e.beginScope||null===e.beginScope)throw W("beginScope must be object"),
K;F(e,e.begin,{key:"beginScope"}),e.begin=m(e.begin,{joinWith:""})}})(e),(e=>{
if(Array.isArray(e.end)){
if(e.skip||e.excludeEnd||e.returnEnd)throw W("skip, excludeEnd, returnEnd not compatible with endScope: {}"),
K
;if("object"!=typeof e.endScope||null===e.endScope)throw W("endScope must be object"),
K;F(e,e.end,{key:"endScope"}),e.end=m(e.end,{joinWith:""})}})(e)}function V(e){
function t(t,n){
return RegExp(l(t),"m"+(e.case_insensitive?"i":"")+(e.unicodeRegex?"u":"")+(n?"g":""))
}class n{constructor(){
this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}
addRule(e,t){
t.position=this.position++,this.matchIndexes[this.matchAt]=t,this.regexes.push([t,e]),
this.matchAt+=p(e)+1}compile(){0===this.regexes.length&&(this.exec=()=>null)
;const e=this.regexes.map((e=>e[1]));this.matcherRe=t(m(e,{joinWith:"|"
}),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex
;const t=this.matcherRe.exec(e);if(!t)return null
;const n=t.findIndex(((e,t)=>t>0&&void 0!==e)),i=this.matchIndexes[n]
;return t.splice(0,n),Object.assign(t,i)}}class s{constructor(){
this.rules=[],this.multiRegexes=[],
this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){
if(this.multiRegexes[e])return this.multiRegexes[e];const t=new n
;return this.rules.slice(e).forEach((([e,n])=>t.addRule(e,n))),
t.compile(),this.multiRegexes[e]=t,t}resumingScanAtSamePosition(){
return 0!==this.regexIndex}considerAll(){this.regexIndex=0}addRule(e,t){
this.rules.push([e,t]),"begin"===t.type&&this.count++}exec(e){
const t=this.getMatcher(this.regexIndex);t.lastIndex=this.lastIndex
;let n=t.exec(e)
;if(this.resumingScanAtSamePosition())if(n&&n.index===this.lastIndex);else{
const t=this.getMatcher(0);t.lastIndex=this.lastIndex+1,n=t.exec(e)}
return n&&(this.regexIndex+=n.position+1,
this.regexIndex===this.count&&this.considerAll()),n}}
if(e.compilerExtensions||(e.compilerExtensions=[]),
e.contains&&e.contains.includes("self"))throw Error("ERR: contains `self` is not supported at the top-level of a language.  See documentation.")
;return e.classNameAliases=i(e.classNameAliases||{}),function n(o,r){const a=o
;if(o.isCompiled)return a
;[I,B,Z,D].forEach((e=>e(o,r))),e.compilerExtensions.forEach((e=>e(o,r))),
o.__beforeBegin=null,[T,L,P].forEach((e=>e(o,r))),o.isCompiled=!0;let c=null
;return"object"==typeof o.keywords&&o.keywords.$pattern&&(o.keywords=Object.assign({},o.keywords),
c=o.keywords.$pattern,
delete o.keywords.$pattern),c=c||/\w+/,o.keywords&&(o.keywords=$(o.keywords,e.case_insensitive)),
a.keywordPatternRe=t(c,!0),
r&&(o.begin||(o.begin=/\B|\b/),a.beginRe=t(a.begin),o.end||o.endsWithParent||(o.end=/\B|\b/),
o.end&&(a.endRe=t(a.end)),
a.terminatorEnd=l(a.end)||"",o.endsWithParent&&r.terminatorEnd&&(a.terminatorEnd+=(o.end?"|":"")+r.terminatorEnd)),
o.illegal&&(a.illegalRe=t(o.illegal)),
o.contains||(o.contains=[]),o.contains=[].concat(...o.contains.map((e=>(e=>(e.variants&&!e.cachedVariants&&(e.cachedVariants=e.variants.map((t=>i(e,{
variants:null},t)))),e.cachedVariants?e.cachedVariants:q(e)?i(e,{
starts:e.starts?i(e.starts):null
}):Object.isFrozen(e)?i(e):e))("self"===e?o:e)))),o.contains.forEach((e=>{n(e,a)
})),o.starts&&n(o.starts,r),a.matcher=(e=>{const t=new s
;return e.contains.forEach((e=>t.addRule(e.begin,{rule:e,type:"begin"
}))),e.terminatorEnd&&t.addRule(e.terminatorEnd,{type:"end"
}),e.illegal&&t.addRule(e.illegal,{type:"illegal"}),t})(a),a}(e)}function q(e){
return!!e&&(e.endsWithParent||q(e.starts))}class J extends Error{
constructor(e,t){super(e),this.name="HTMLInjectionError",this.html=t}}
const Y=n,Q=i,ee=Symbol("nomatch"),te=n=>{
const i=Object.create(null),s=Object.create(null),o=[];let r=!0
;const a="Could not find the language '{}', did you forget to load/include a language module?",l={
disableAutodetect:!0,name:"Plain text",contains:[]};let p={
ignoreUnescapedHTML:!1,throwUnescapedHTML:!1,noHighlightRe:/^(no-?highlight)$/i,
languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-",
cssSelector:"pre code",languages:null,__emitter:c};function b(e){
return p.noHighlightRe.test(e)}function m(e,t,n){let i="",s=""
;"object"==typeof t?(i=e,
n=t.ignoreIllegals,s=t.language):(G("10.7.0","highlight(lang, code, ...args) has been deprecated."),
G("10.7.0","Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277"),
s=e,i=t),void 0===n&&(n=!0);const o={code:i,language:s};N("before:highlight",o)
;const r=o.result?o.result:E(o.language,o.code,n)
;return r.code=o.code,N("after:highlight",r),r}function E(e,n,s,o){
const c=Object.create(null);function l(){if(!N.keywords)return void M.addText(R)
;let e=0;N.keywordPatternRe.lastIndex=0;let t=N.keywordPatternRe.exec(R),n=""
;for(;t;){n+=R.substring(e,t.index)
;const s=_.case_insensitive?t[0].toLowerCase():t[0],o=(i=s,N.keywords[i]);if(o){
const[e,i]=o
;if(M.addText(n),n="",c[s]=(c[s]||0)+1,c[s]<=7&&(j+=i),e.startsWith("_"))n+=t[0];else{
const n=_.classNameAliases[e]||e;u(t[0],n)}}else n+=t[0]
;e=N.keywordPatternRe.lastIndex,t=N.keywordPatternRe.exec(R)}var i
;n+=R.substring(e),M.addText(n)}function g(){null!=N.subLanguage?(()=>{
if(""===R)return;let e=null;if("string"==typeof N.subLanguage){
if(!i[N.subLanguage])return void M.addText(R)
;e=E(N.subLanguage,R,!0,S[N.subLanguage]),S[N.subLanguage]=e._top
}else e=x(R,N.subLanguage.length?N.subLanguage:null)
;N.relevance>0&&(j+=e.relevance),M.__addSublanguage(e._emitter,e.language)
})():l(),R=""}function u(e,t){
""!==e&&(M.startScope(t),M.addText(e),M.endScope())}function d(e,t){let n=1
;const i=t.length-1;for(;n<=i;){if(!e._emit[n]){n++;continue}
const i=_.classNameAliases[e[n]]||e[n],s=t[n];i?u(s,i):(R=s,l(),R=""),n++}}
function h(e,t){
return e.scope&&"string"==typeof e.scope&&M.openNode(_.classNameAliases[e.scope]||e.scope),
e.beginScope&&(e.beginScope._wrap?(u(R,_.classNameAliases[e.beginScope._wrap]||e.beginScope._wrap),
R=""):e.beginScope._multi&&(d(e.beginScope,t),R="")),N=Object.create(e,{parent:{
value:N}}),N}function f(e,n,i){let s=((e,t)=>{const n=e&&e.exec(t)
;return n&&0===n.index})(e.endRe,i);if(s){if(e["on:end"]){const i=new t(e)
;e["on:end"](n,i),i.isMatchIgnored&&(s=!1)}if(s){
for(;e.endsParent&&e.parent;)e=e.parent;return e}}
if(e.endsWithParent)return f(e.parent,n,i)}function b(e){
return 0===N.matcher.regexIndex?(R+=e[0],1):(T=!0,0)}function m(e){
const t=e[0],i=n.substring(e.index),s=f(N,e,i);if(!s)return ee;const o=N
;N.endScope&&N.endScope._wrap?(g(),
u(t,N.endScope._wrap)):N.endScope&&N.endScope._multi?(g(),
d(N.endScope,e)):o.skip?R+=t:(o.returnEnd||o.excludeEnd||(R+=t),
g(),o.excludeEnd&&(R=t));do{
N.scope&&M.closeNode(),N.skip||N.subLanguage||(j+=N.relevance),N=N.parent
}while(N!==s.parent);return s.starts&&h(s.starts,e),o.returnEnd?0:t.length}
let w={};function y(i,o){const a=o&&o[0];if(R+=i,null==a)return g(),0
;if("begin"===w.type&&"end"===o.type&&w.index===o.index&&""===a){
if(R+=n.slice(o.index,o.index+1),!r){const t=Error(`0 width match regex (${e})`)
;throw t.languageName=e,t.badRule=w.rule,t}return 1}
if(w=o,"begin"===o.type)return(e=>{
const n=e[0],i=e.rule,s=new t(i),o=[i.__beforeBegin,i["on:begin"]]
;for(const t of o)if(t&&(t(e,s),s.isMatchIgnored))return b(n)
;return i.skip?R+=n:(i.excludeBegin&&(R+=n),
g(),i.returnBegin||i.excludeBegin||(R=n)),h(i,e),i.returnBegin?0:n.length})(o)
;if("illegal"===o.type&&!s){
const e=Error('Illegal lexeme "'+a+'" for mode "'+(N.scope||"<unnamed>")+'"')
;throw e.mode=N,e}if("end"===o.type){const e=m(o);if(e!==ee)return e}
if("illegal"===o.type&&""===a)return 1
;if(I>1e5&&I>3*o.index)throw Error("potential infinite loop, way more iterations than matches")
;return R+=a,a.length}const _=O(e)
;if(!_)throw W(a.replace("{}",e)),Error('Unknown language: "'+e+'"')
;const v=V(_);let k="",N=o||v;const S={},M=new p.__emitter(p);(()=>{const e=[]
;for(let t=N;t!==_;t=t.parent)t.scope&&e.unshift(t.scope)
;e.forEach((e=>M.openNode(e)))})();let R="",j=0,A=0,I=0,T=!1;try{
if(_.__emitTokens)_.__emitTokens(n,M);else{for(N.matcher.considerAll();;){
I++,T?T=!1:N.matcher.considerAll(),N.matcher.lastIndex=A
;const e=N.matcher.exec(n);if(!e)break;const t=y(n.substring(A,e.index),e)
;A=e.index+t}y(n.substring(A))}return M.finalize(),k=M.toHTML(),{language:e,
value:k,relevance:j,illegal:!1,_emitter:M,_top:N}}catch(t){
if(t.message&&t.message.includes("Illegal"))return{language:e,value:Y(n),
illegal:!0,relevance:0,_illegalBy:{message:t.message,index:A,
context:n.slice(A-100,A+100),mode:t.mode,resultSoFar:k},_emitter:M};if(r)return{
language:e,value:Y(n),illegal:!1,relevance:0,errorRaised:t,_emitter:M,_top:N}
;throw t}}function x(e,t){t=t||p.languages||Object.keys(i);const n=(e=>{
const t={value:Y(e),illegal:!1,relevance:0,_top:l,_emitter:new p.__emitter(p)}
;return t._emitter.addText(e),t})(e),s=t.filter(O).filter(k).map((t=>E(t,e,!1)))
;s.unshift(n);const o=s.sort(((e,t)=>{
if(e.relevance!==t.relevance)return t.relevance-e.relevance
;if(e.language&&t.language){if(O(e.language).supersetOf===t.language)return 1
;if(O(t.language).supersetOf===e.language)return-1}return 0})),[r,a]=o,c=r
;return c.secondBest=a,c}function w(e){let t=null;const n=(e=>{
let t=e.className+" ";t+=e.parentNode?e.parentNode.className:""
;const n=p.languageDetectRe.exec(t);if(n){const t=O(n[1])
;return t||(X(a.replace("{}",n[1])),
X("Falling back to no-highlight mode for this block.",e)),t?n[1]:"no-highlight"}
return t.split(/\s+/).find((e=>b(e)||O(e)))})(e);if(b(n))return
;if(N("before:highlightElement",{el:e,language:n
}),e.dataset.highlighted)return void console.log("Element previously highlighted. To highlight again, first unset `dataset.highlighted`.",e)
;if(e.children.length>0&&(p.ignoreUnescapedHTML||(console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."),
console.warn("https://github.com/highlightjs/highlight.js/wiki/security"),
console.warn("The element with unescaped HTML:"),
console.warn(e)),p.throwUnescapedHTML))throw new J("One of your code blocks includes unescaped HTML.",e.innerHTML)
;t=e;const i=t.textContent,o=n?m(i,{language:n,ignoreIllegals:!0}):x(i)
;e.innerHTML=o.value,e.dataset.highlighted="yes",((e,t,n)=>{const i=t&&s[t]||n
;e.classList.add("hljs"),e.classList.add("language-"+i)
})(e,n,o.language),e.result={language:o.language,re:o.relevance,
relevance:o.relevance},o.secondBest&&(e.secondBest={
language:o.secondBest.language,relevance:o.secondBest.relevance
}),N("after:highlightElement",{el:e,result:o,text:i})}let y=!1;function _(){
"loading"!==document.readyState?document.querySelectorAll(p.cssSelector).forEach(w):y=!0
}function O(e){return e=(e||"").toLowerCase(),i[e]||i[s[e]]}
function v(e,{languageName:t}){"string"==typeof e&&(e=[e]),e.forEach((e=>{
s[e.toLowerCase()]=t}))}function k(e){const t=O(e)
;return t&&!t.disableAutodetect}function N(e,t){const n=e;o.forEach((e=>{
e[n]&&e[n](t)}))}
"undefined"!=typeof window&&window.addEventListener&&window.addEventListener("DOMContentLoaded",(()=>{
y&&_()}),!1),Object.assign(n,{highlight:m,highlightAuto:x,highlightAll:_,
highlightElement:w,
highlightBlock:e=>(G("10.7.0","highlightBlock will be removed entirely in v12.0"),
G("10.7.0","Please use highlightElement now."),w(e)),configure:e=>{p=Q(p,e)},
initHighlighting:()=>{
_(),G("10.6.0","initHighlighting() deprecated.  Use highlightAll() now.")},
initHighlightingOnLoad:()=>{
_(),G("10.6.0","initHighlightingOnLoad() deprecated.  Use highlightAll() now.")
},registerLanguage:(e,t)=>{let s=null;try{s=t(n)}catch(t){
if(W("Language definition for '{}' could not be registered.".replace("{}",e)),
!r)throw t;W(t),s=l}
s.name||(s.name=e),i[e]=s,s.rawDefinition=t.bind(null,n),s.aliases&&v(s.aliases,{
languageName:e})},unregisterLanguage:e=>{delete i[e]
;for(const t of Object.keys(s))s[t]===e&&delete s[t]},
listLanguages:()=>Object.keys(i),getLanguage:O,registerAliases:v,
autoDetection:k,inherit:Q,addPlugin:e=>{(e=>{
e["before:highlightBlock"]&&!e["before:highlightElement"]&&(e["before:highlightElement"]=t=>{
e["before:highlightBlock"](Object.assign({block:t.el},t))
}),e["after:highlightBlock"]&&!e["after:highlightElement"]&&(e["after:highlightElement"]=t=>{
e["after:highlightBlock"](Object.assign({block:t.el},t))})})(e),o.push(e)},
removePlugin:e=>{const t=o.indexOf(e);-1!==t&&o.splice(t,1)}}),n.debugMode=()=>{
r=!1},n.safeMode=()=>{r=!0},n.versionString="11.9.0",n.regex={concat:h,
lookahead:g,either:f,optional:d,anyNumberOfTimes:u}
;for(const t in j)"object"==typeof j[t]&&e(j[t]);return Object.assign(n,j),n
},ne=te({});return ne.newInstance=()=>te({}),ne}()
;"object"==typeof exports&&"undefined"!=typeof module&&(module.exports=hljs);/*! `cpp` grammar compiled for Highlight.js 11.9.0 */
(()=>{var e=(()=>{"use strict";return e=>{const t=e.regex,a=e.COMMENT("//","$",{
contains:[{begin:/\\\n/}]
}),n="decltype\\(auto\\)",r="[a-zA-Z_]\\w*::",i="(?!struct)("+n+"|"+t.optional(r)+"[a-zA-Z_]\\w*"+t.optional("<[^<>]+>")+")",s={
className:"type",begin:"\\b[a-z\\d_]*_t\\b"},c={className:"string",variants:[{
begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{
begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)",
end:"'",illegal:"."},e.END_SAME_AS_BEGIN({
begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},o={
className:"number",variants:[{
begin:"[+-]?(?:(?:[0-9](?:'?[0-9])*\\.(?:[0-9](?:'?[0-9])*)?|\\.[0-9](?:'?[0-9])*)(?:[Ee][+-]?[0-9](?:'?[0-9])*)?|[0-9](?:'?[0-9])*[Ee][+-]?[0-9](?:'?[0-9])*|0[Xx](?:[0-9A-Fa-f](?:'?[0-9A-Fa-f])*(?:\\.(?:[0-9A-Fa-f](?:'?[0-9A-Fa-f])*)?)?|\\.[0-9A-Fa-f](?:'?[0-9A-Fa-f])*)[Pp][+-]?[0-9](?:'?[0-9])*)(?:[Ff](?:16|32|64|128)?|(BF|bf)16|[Ll]|)"
},{
begin:"[+-]?\\b(?:0[Bb][01](?:'?[01])*|0[Xx][0-9A-Fa-f](?:'?[0-9A-Fa-f])*|0(?:'?[0-7])*|[1-9](?:'?[0-9])*)(?:[Uu](?:LL?|ll?)|[Uu][Zz]?|(?:LL?|ll?)[Uu]?|[Zz][Uu]|)"
}],relevance:0},l={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{
keyword:"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include"
},contains:[{begin:/\\\n/,relevance:0},e.inherit(c,{className:"string"}),{
className:"string",begin:/<.*?>/},a,e.C_BLOCK_COMMENT_MODE]},u={
className:"title",begin:t.optional(r)+e.IDENT_RE,relevance:0
},d=t.optional(r)+e.IDENT_RE+"\\s*\\(",p={
type:["bool","char","char16_t","char32_t","char8_t","double","float","int","long","short","void","wchar_t","unsigned","signed","const","static"],
keyword:["alignas","alignof","and","and_eq","asm","atomic_cancel","atomic_commit","atomic_noexcept","auto","bitand","bitor","break","case","catch","class","co_await","co_return","co_yield","compl","concept","const_cast|10","consteval","constexpr","constinit","continue","decltype","default","delete","do","dynamic_cast|10","else","enum","explicit","export","extern","false","final","for","friend","goto","if","import","inline","module","mutable","namespace","new","noexcept","not","not_eq","nullptr","operator","or","or_eq","override","private","protected","public","reflexpr","register","reinterpret_cast|10","requires","return","sizeof","static_assert","static_cast|10","struct","switch","synchronized","template","this","thread_local","throw","transaction_safe","transaction_safe_dynamic","true","try","typedef","typeid","typename","union","using","virtual","volatile","while","xor","xor_eq"],
literal:["NULL","false","nullopt","nullptr","true"],built_in:["_Pragma"],
_type_hints:["any","auto_ptr","barrier","binary_semaphore","bitset","complex","condition_variable","condition_variable_any","counting_semaphore","deque","false_type","future","imaginary","initializer_list","istringstream","jthread","latch","lock_guard","multimap","multiset","mutex","optional","ostringstream","packaged_task","pair","promise","priority_queue","queue","recursive_mutex","recursive_timed_mutex","scoped_lock","set","shared_future","shared_lock","shared_mutex","shared_timed_mutex","shared_ptr","stack","string_view","stringstream","timed_mutex","thread","true_type","tuple","unique_lock","unique_ptr","unordered_map","unordered_multimap","unordered_multiset","unordered_set","variant","vector","weak_ptr","wstring","wstring_view"]
},_={className:"function.dispatch",relevance:0,keywords:{
_hint:["abort","abs","acos","apply","as_const","asin","atan","atan2","calloc","ceil","cerr","cin","clog","cos","cosh","cout","declval","endl","exchange","exit","exp","fabs","floor","fmod","forward","fprintf","fputs","free","frexp","fscanf","future","invoke","isalnum","isalpha","iscntrl","isdigit","isgraph","islower","isprint","ispunct","isspace","isupper","isxdigit","labs","launder","ldexp","log","log10","make_pair","make_shared","make_shared_for_overwrite","make_tuple","make_unique","malloc","memchr","memcmp","memcpy","memset","modf","move","pow","printf","putchar","puts","realloc","scanf","sin","sinh","snprintf","sprintf","sqrt","sscanf","std","stderr","stdin","stdout","strcat","strchr","strcmp","strcpy","strcspn","strlen","strncat","strncmp","strncpy","strpbrk","strrchr","strspn","strstr","swap","tan","tanh","terminate","to_underlying","tolower","toupper","vfprintf","visit","vprintf","vsprintf"]
},
begin:t.concat(/\b/,/(?!decltype)/,/(?!if)/,/(?!for)/,/(?!switch)/,/(?!while)/,e.IDENT_RE,t.lookahead(/(<[^<>]+>|)\s*\(/))
},m=[_,l,s,a,e.C_BLOCK_COMMENT_MODE,o,c],f={variants:[{begin:/=/,end:/;/},{
begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}],
keywords:p,contains:m.concat([{begin:/\(/,end:/\)/,keywords:p,
contains:m.concat(["self"]),relevance:0}]),relevance:0},g={className:"function",
begin:"("+i+"[\\*&\\s]+)+"+d,returnBegin:!0,end:/[{;=]/,excludeEnd:!0,
keywords:p,illegal:/[^\w\s\*&:<>.]/,contains:[{begin:n,keywords:p,relevance:0},{
begin:d,returnBegin:!0,contains:[u],relevance:0},{begin:/::/,relevance:0},{
begin:/:/,endsWithParent:!0,contains:[c,o]},{relevance:0,match:/,/},{
className:"params",begin:/\(/,end:/\)/,keywords:p,relevance:0,
contains:[a,e.C_BLOCK_COMMENT_MODE,c,o,s,{begin:/\(/,end:/\)/,keywords:p,
relevance:0,contains:["self",a,e.C_BLOCK_COMMENT_MODE,c,o,s]}]
},s,a,e.C_BLOCK_COMMENT_MODE,l]};return{name:"C++",
aliases:["cc","c++","h++","hpp","hh","hxx","cxx"],keywords:p,illegal:"</",
classNameAliases:{"function.dispatch":"built_in"},
contains:[].concat(f,g,_,m,[l,{
begin:"\\b(deque|list|queue|priority_queue|pair|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array|tuple|optional|variant|function)\\s*<(?!<)",
end:">",keywords:p,contains:["self",s]},{begin:e.IDENT_RE+"::",keywords:p},{
match:[/\b(?:enum(?:\s+(?:class|struct))?|class|struct|union)/,/\s+/,/\w+/],
className:{1:"keyword",3:"title.class"}}])}}})();hljs.registerLanguage("cpp",e)
})();
</script>
<script language='javascript'>
var mergeHTMLPlugin = (function () {
  'use strict';

  var originalStream;

  /**
   * @param {string} value
   * @returns {string}
   */
  function escapeHTML(value) {
    return value
      .replace(/&/g, '&amp;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;')
      .replace(/"/g, '&quot;')
      .replace(/'/g, '&#x27;');
  }

  /* plugin itself */

  /** @type {HLJSPlugin} */
  const mergeHTMLPlugin = {
    // preserve the original HTML token stream
    "before:highlightElement": ({ el }) => {
      originalStream = nodeStream(el);
    },
    // merge it afterwards with the highlighted token stream
    "after:highlightElement": ({ el, result, text }) => {
      if (!originalStream.length) return;

      const resultNode = document.createElement('div');
      resultNode.innerHTML = result.value;
      result.value = mergeStreams(originalStream, nodeStream(resultNode), text);
      el.innerHTML = result.value;
    }
  };

  /* Stream merging support functions */

  /**
   * @typedef Event
   * @property {'start'|'stop'} event
   * @property {number} offset
   * @property {Node} node
   */

  /**
   * @param {Node} node
   */
  function tag(node) {
    return node.nodeName.toLowerCase();
  }

  /**
   * @param {Node} node
   */
  function nodeStream(node) {
    /** @type Event[] */
    const result = [];
    (function _nodeStream(node, offset) {
      for (let child = node.firstChild; child; child = child.nextSibling) {
        if (child.nodeType === 3) {
          offset += child.nodeValue.length;
        } else if (child.nodeType === 1) {
          result.push({
            event: 'start',
            offset: offset,
            node: child
          });
          offset = _nodeStream(child, offset);
          // Prevent void elements from having an end tag that would actually
          // double them in the output. There are more void elements in HTML
          // but we list only those realistically expected in code display.
          if (!tag(child).match(/br|hr|img|input/)) {
            result.push({
              event: 'stop',
              offset: offset,
              node: child
            });
          }
        }
      }
      return offset;
    })(node, 0);
    return result;
  }

  /**
   * @param {any} original - the original stream
   * @param {any} highlighted - stream of the highlighted source
   * @param {string} value - the original source itself
   */
  function mergeStreams(original, highlighted, value) {
    let processed = 0;
    let result = '';
    const nodeStack = [];

    function selectStream() {
      if (!original.length || !highlighted.length) {
        return original.length ? original : highlighted;
      }
      if (original[0].offset !== highlighted[0].offset) {
        return (original[0].offset < highlighted[0].offset) ? original : highlighted;
      }

      /*
      To avoid starting the stream just before it should stop the order is
      ensured that original always starts first and closes last:

      if (event1 == 'start' && event2 == 'start')
        return original;
      if (event1 == 'start' && event2 == 'stop')
        return highlighted;
      if (event1 == 'stop' && event2 == 'start')
        return original;
      if (event1 == 'stop' && event2 == 'stop')
        return highlighted;

      ... which is collapsed to:
      */
      return highlighted[0].event === 'start' ? original : highlighted;
    }

    /**
     * @param {Node} node
     */
    function open(node) {
      /** @param {Attr} attr */
      function attributeString(attr) {
        return ' ' + attr.nodeName + '="' + escapeHTML(attr.value) + '"';
      }
      // @ts-ignore
      result += '<' + tag(node) + [].map.call(node.attributes, attributeString).join('') + '>';
    }

    /**
     * @param {Node} node
     */
    function close(node) {
      result += '</' + tag(node) + '>';
    }

    /**
     * @param {Event} event
     */
    function render(event) {
      (event.event === 'start' ? open : close)(event.node);
    }

    while (original.length || highlighted.length) {
      let stream = selectStream();
      result += escapeHTML(value.substring(processed, stream[0].offset));
      processed = stream[0].offset;
      if (stream === original) {
        /*
        On any opening or closing tag of the original markup we first close
        the entire highlighted node stack, then render the original tag along
        with all the following original tags at the same offset and then
        reopen all the tags on the highlighted stack.
        */
        nodeStack.reverse().forEach(close);
        do {
          render(stream.splice(0, 1)[0]);
          stream = selectStream();
        } while (stream === original && stream.length && stream[0].offset === processed);
        nodeStack.reverse().forEach(open);
      } else {
        if (stream[0].event === 'start') {
          nodeStack.push(stream[0].node);
        } else {
          nodeStack.pop();
        }
        render(stream.splice(0, 1)[0]);
      }
    }
    return result + escapeHTML(value.substr(processed));
  }

  return mergeHTMLPlugin;

}());
</script>
</head>
<body><div>
<nav><div><div>
<h1 class="hide-on-wide name-of-paper">constexpr virtual inheritance</h1>
<div class="paper-info">
	<div><span class="key">Number:</span> P3533R2</div>
	<div><span class="key">Date:</span> <time>2025-02-17</time></div>
	<div><span class="key">Audience:</span> CWG</div>
	<div><span class="key">Reply-to:</span> <a href="mailto:cpp@hanicka.net">Hana Dusíková</a></div>
</div>

<div id='toc'><h2 id='_toc'><a href='#_toc'>Table of contents</a></h2>
<ul>
<li><a href='#changes'>Changes</a></li><li><a href='#motivation'>Motivation</a><ul>
<ul>
<li><a href='#example-of-allowed-code'>Example of allowed code</a><ul>
<ul>
<li><a href='#hierarchy'>Hierarchy</a></li><li><a href='#clang's-representation'>Clang's representation</a></li></ul>
</ul>
</li></ul>
</ul>
</li><li><a href='#implementation-experience'>Implementation experience</a></li><li><a href='#library-impact'>Library impact</a></li><li><a href='#proposed-changes-to-wording'>Proposed changes to wording</a><ul>
<ul>
<li><a href='#based-on-current-draft'>Based on current draft</a></li><li><a href='#feature-test-macro'>Feature test macro</a></li></ul>
</ul>
</li></ul>
</div>
</div></div></nav>
<article>
<div><div>
	
	
	<h1 class="hide-on-narrow name-of-paper" id="introduction">constexpr virtual inheritance</h1>
	<p>This paper proposes allowing usage of virtual inheritance. This will allow in future <code>constexpr</code>-ification of <code>std::ios_base</code>, and streams, removing final limitation for making most of stream formatting <code>constexpr</code>.</p>
	<p>This will also remove definition of <em>constexpr-suitable</em> as it will be meaningless and clean all references across draft of the standard (if this paper land after <a href="https://wg21.link/P3367">P3367: constexpr coroutines</a>). </p>
	<h2 id='changes'><a href='#changes'>Changes</a></h2>
	<ul>
    <li><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3533r1.html">R1</a>&#x2005;→&#x2005;<a href="">R2</a>: Removed wording based on <a href="https://wg21.link/P3367">P3367: constexpr coroutines</a> as this paper targets C++26, and coroutines C++29.</li>
		<li><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3533r0.html">R0</a>&#x2005;→&#x2005;<a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3533r1.html">R1</a>: Added <a href="#based-on-current-draft">alternative wording</a> in case it will land before <a href="https://wg21.link/P3367">P3367: constexpr coroutines</a>.</li>
	</ul>
	<h2 id='motivation'><a href='#motivation'>Motivation</a></h2>
	<p>Last language syntax thing which is disallowed in <a href="https://eel.is/c++draft/dcl.constexpr#3">[dcl.constexpr]</a> which blocks us from making <code>std::stringstream</code> constant evaluatable, which blocks us from making exception types for <code>&lt;chrono&gt;</code> (<code>chrono::nonexistent_local_time</code> and <code>chrono::ambiguous_local_time</code>). Stream formatting <code>&lt;chrono&gt;</code>. Using <code>basic_istream_view</code> in range code for compile-time parsing.</p>
	<p>When we remove this limitations, language will only have limit on evaluation properties of code in <a href="https://eel.is/c++draft/expr.const">[expr.const]</a>, and not syntactical (with exception of <code>reinterpret_cast</code>, but this is also defined as not constant evaluatable.)</p> 
	<p>Then keyword <code>constexpr</code> can be seen only as an opt-in into constant evaluatable and can be <em>later</em> removed and replaced with an opt-out attribute (this is not propesed here.)</p>
	<h3 id='example-of-allowed-code'><a href='#example-of-allowed-code'>Example of allowed code</a></h3>
	<pre><code class="language-cpp">struct Superbase {
	string id{"name"};
};

struct Common: Superbase {
	unsigned counter{0};
};

struct Left: virtual Common {
	unsigned value{0};
	constexpr const unsigned & get_counter() const {
		return Common::counter;
	}
};

struct Right: virtual Common {
	unsigned value{0};
	constexpr const unsigned & get_counter() const {
		return Common::counter;
	}
};

struct Child: Left, Right {
	unsigned x{0};
	unsigned y{0};
	// ...
};

constexpr auto ch = Child{}; <span class="before">// before: not allowed to even construct</span>
                             <span class="after">// after: works as expected</span>

static_assert(&ch.Left::get_counter() == &ch.Right::get_counter());</code></pre>
	<h4 id='hierarchy'><a href='#hierarchy'>Hierarchy</a></h4>
	<div class='svgimg'><div><?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 180.4 231.72" width="360.8" height="463.44">
  <g id="structures">
    <rect x="46.14" y="199.92" width="50.2" height="26.5" fill="#fff" stroke="#231f20" stroke-miterlimit="10"/>
    <rect x="111.92" y="134.51" width="26.5" height="26.5" fill="#fff" stroke="#231f20" stroke-miterlimit="10"/>
    <rect x="4.3" y="134.51" width="26.5" height="26.5" fill="#fff" stroke="#231f20" stroke-miterlimit="10"/>
    <rect x="57.76" y="69.79" width="26.5" height="26.5" fill="#fff" stroke="#231f20" stroke-miterlimit="10"/>
    <rect x="57.76" y="5.06" width="26.5" height="26.5" fill="#fff" stroke="#231f20" stroke-miterlimit="10"/>
  </g>
  <g id="items">
    <g id="orange">
      <rect x="60.56" y="7.86" width="20.9" height="20.9" fill="#ffc8ad" stroke="#231f20" stroke-miterlimit="10"/>
    </g>
    <g id="green">
      <rect x="48.94" y="202.71" width="20.9" height="20.9" fill="#acffd5" stroke="#231f20" stroke-miterlimit="10"/>
      <rect x="72.64" y="202.72" width="20.9" height="20.9" fill="#acffd5" stroke="#231f20" stroke-miterlimit="10"/>
    </g>
    <g id="purple">
      <rect x="114.72" y="137.31" width="20.9" height="20.9" fill="#acacff" stroke="#231f20" stroke-miterlimit="10"/>
    </g>
    <g id="pink">
      <rect x="7.1" y="137.31" width="20.9" height="20.9" fill="#ffacd6" stroke="#231f20" stroke-miterlimit="10"/>
    </g>
    <g id="yellow">
      <rect x="60.56" y="72.59" width="20.9" height="20.9" fill="#ffffac" stroke="#231f20" stroke-miterlimit="10"/>
    </g>
  </g>
  <g id="arrows">
    <g>
      <path d="M17.55,161.01c0,24.37,42.6,14.52,49.79,33.03" fill="none" stroke="#231f20" stroke-miterlimit="10"/>
      <polygon points="62.94 192.1 66.88 192.88 70.19 190.58 68.36 199.93 62.94 192.1" fill="#231f20"/>
    </g>
    <g>
      <path d="M125.17,161.01c0,24-42.34,14.45-49.72,33.05" fill="none" stroke="#231f20" stroke-miterlimit="10"/>
      <polygon points="72.63 190.56 75.91 192.9 79.87 192.16 74.36 199.93 72.63 190.56" fill="#231f20"/>
    </g>
    <g>
      <path d="M18.62,128.64c.13-.31.26-.62.41-.91" fill="none" stroke="#231f20" stroke-miterlimit="10"/>
      <path d="M20.04,126.03c9.86-13.94,45.71-7.25,47.87-27.75" fill="none" stroke="#231f20" stroke-dasharray="1.98 1.98" stroke-miterlimit="10"/>
      <path d="M67.99,97.29c.02-.33.02-.66.02-1" fill="none" stroke="#231f20" stroke-miterlimit="10"/>
      <polygon points="23.05 126.73 19.1 127.48 15.82 125.15 17.55 134.51 23.05 126.73" fill="#231f20"/>
    </g>
    <g>
      <path d="M124.11,128.64c-.13-.31-.26-.62-.41-.91" fill="none" stroke="#231f20" stroke-miterlimit="10"/>
      <path d="M122.67,126.01c-9.95-14.08-46.36-7.22-48.56-27.72" fill="none" stroke="#231f20" stroke-dasharray="2 2" stroke-miterlimit="10"/>
      <path d="M74.04,97.29c-.02-.33-.03-.66-.03-1" fill="none" stroke="#231f20" stroke-miterlimit="10"/>
      <polygon points="126.91 125.15 123.63 127.47 119.68 126.73 125.17 134.51 126.91 125.15" fill="#231f20"/>
    </g>
    <g>
      <line x1="71.01" y1="31.56" x2="71.01" y2="63.82" fill="none" stroke="#231f20" stroke-miterlimit="10"/>
      <polygon points="67.31 61.01 71.01 62.58 74.71 61.01 71.01 69.79 67.31 61.01" fill="#231f20"/>
    </g>
  </g>
  <g id="inside-text">
    <text transform="translate(64.05 92.51) rotate(-45)" font-family="Helvetica, Helvetica" font-size="7"><tspan x="0" y="0">counter</tspan></text>
    <text transform="translate(12.02 157.51) rotate(-45)" font-family="Helvetica, Helvetica" font-size="9"><tspan x="0" y="0">value</tspan></text>
    <text transform="translate(119.64 157.51) rotate(-45)" font-family="Helvetica, Helvetica" font-size="9"><tspan x="0" y="0">value</tspan></text>
    <text transform="translate(80.09 216.17)" font-family="Helvetica, Helvetica" font-size="12"><tspan x="0" y="0">y</tspan></text>
    <text transform="translate(56.39 216.16)" font-family="Helvetica, Helvetica" font-size="12"><tspan x="0" y="0">x</tspan></text>
    <text transform="translate(66.11 25.72) rotate(-45)" font-family="Helvetica, Helvetica" font-size="7"><tspan x="0" y="0">name</tspan></text>
  </g>
  <g id="outside-text">
    <text transform="translate(105.19 216.6)" font-family="Helvetica, Helvetica" font-size="12"><tspan x="0" y="0">Child</tspan></text>
    <text transform="translate(147.27 151.2)" font-family="Helvetica, Helvetica" font-size="12"><tspan x="0" y="0">Right</tspan></text>
    <text transform="translate(39.65 151.2)" font-family="Helvetica, Helvetica" font-size="12"><tspan x="0" y="0">Left</tspan></text>
    <text transform="translate(93.11 86.47)" font-family="Helvetica, Helvetica" font-size="12"><tspan x="0" y="0">Common</tspan></text>
    <text transform="translate(93.11 21.74)" font-family="Helvetica, Helvetica" font-size="12"><tspan x="0" y="0">Superbase</tspan></text>
  </g>
</svg></div></div>	<h4 id='clang's-representation'><a href='#clang's-representation'>Clang's representation</a></h4>
	<div class='svgimg'><div><?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 237.56 318.3" width="475.12" height="636.6">
  <g id="structures">
    <rect x="100.12" y="69.41" width="121.29" height="26.5" fill="#fff" stroke="#231f20" stroke-miterlimit="10"/>
    <rect x="97.74" y="136.94" width="26.5" height="26.5" fill="#fff" stroke="#231f20" stroke-miterlimit="10"/>
    <rect x="173.59" y="212.79" width="50.2" height="26.5" fill="#fff" stroke="#231f20" stroke-miterlimit="10"/>
    <rect x="154.72" y="281.83" width="26.5" height="26.5" fill="#fff" stroke="#231f20" stroke-miterlimit="10"/>
    <rect x="135.66" y="174.87" width="26.5" height="26.5" fill="#fff" stroke="#231f20" stroke-miterlimit="10"/>
  </g>
  <g id="items">
    <g id="meaningless">
      <rect x="102.92" y="72.21" width="20.9" height="20.9" fill="#d1d3d4" stroke="#231f20" stroke-miterlimit="10"/>
      <rect x="126.61" y="72.21" width="20.9" height="20.9" fill="#d1d3d4" stroke="#231f20" stroke-miterlimit="10"/>
      <rect x="150.31" y="72.21" width="20.9" height="20.9" fill="#d1d3d4" stroke="#231f20" stroke-miterlimit="10"/>
      <rect x="176.39" y="215.59" width="20.9" height="20.9" fill="#d1d3d4" stroke="#231f20" stroke-miterlimit="10"/>
    </g>
    <g id="yellow">
      <rect x="200.09" y="215.59" width="20.9" height="20.9" fill="#ffffac" stroke="#231f20" stroke-miterlimit="10"/>
    </g>
    <g id="orange">
      <rect x="157.52" y="284.63" width="20.9" height="20.9" fill="#ffc8ad" stroke="#231f20" stroke-miterlimit="10"/>
    </g>
    <g id="purple">
      <rect x="138.46" y="177.67" width="20.9" height="20.9" fill="#acacff" stroke="#231f20" stroke-miterlimit="10"/>
    </g>
    <g id="green">
      <rect x="174.01" y="72.21" width="20.9" height="20.9" fill="#acffd5" stroke="#231f20" stroke-miterlimit="10"/>
      <rect x="197.71" y="72.21" width="20.9" height="20.9" fill="#acffd5" stroke="#231f20" stroke-miterlimit="10"/>
    </g>
    <g id="pink">
      <rect x="100.54" y="139.74" width="20.9" height="20.9" fill="#ffacd6" stroke="#231f20" stroke-miterlimit="10"/>
    </g>
  </g>
  <g id="black-lines">
    <path d="M102.92,66.41c0-11.68,22.3-11.68,22.3-23.37,0,11.68,22.3,11.68,22.3,23.37" fill="none" stroke="#231f20" stroke-linecap="round" stroke-linejoin="round"/>
    <path d="M150.31,66.41c0-17.12,10.45-17.18,10.45-36.44,0,19.27,10.45,19.36,10.45,36.44" fill="none" stroke="#231f20" stroke-linecap="round" stroke-linejoin="round"/>
    <path d="M174.01,66.41c0-11.68,22.3-11.68,22.3-23.37,0,11.68,22.3,11.68,22.3,23.37" fill="none" stroke="#231f20" stroke-linecap="round" stroke-linejoin="round"/>
    <path d="M200.09,209.84c0-11.68,10.45-11.68,10.45-23.37,0,11.68,10.45,11.68,10.45,23.37" fill="none" stroke="#231f20" stroke-linecap="round" stroke-linejoin="round"/>
    <path d="M138.46,171.53c0-11.68,10.45-11.68,10.45-23.37,0,11.68,10.45,11.68,10.45,23.37" fill="none" stroke="#231f20" stroke-linecap="round" stroke-linejoin="round"/>
    <path d="M100.12,134.14c0-11.68,10.45-11.68,10.45-23.37,0,11.68,10.45,11.68,10.45,23.37" fill="none" stroke="#231f20" stroke-linecap="round" stroke-linejoin="round"/>
    <path d="M176.39,209.84c0-6.45,10.45-6.45,10.45-12.89,0,6.45,10.45,6.45,10.45,12.89" fill="none" stroke="#231f20" stroke-linecap="round" stroke-linejoin="round"/>
    <path d="M157.52,279.01c0-6.45,10.45-6.45,10.45-12.89,0,6.45,10.45,6.45,10.45,12.89" fill="none" stroke="#231f20" stroke-linecap="round" stroke-linejoin="round"/>
  </g>
  <g id="shadow">
    <path d="M102.92,93.11c0,21.91-5.18,21.91-5.18,43.83h26.5c0-21.91-.42-21.83-.42-43.83h-20.9Z" fill="#231f20"/>
    <path d="M126.61,93.11c0,40.88,9.05,41.03,9.05,81.76h26.5c0-40.88-14.65-40.88-14.65-81.76h-20.9Z" fill="#231f20"/>
    <path d="M173.59,212.79c0-59.84-23.28-78.81-23.28-119.68h20.9c0,40.88,52.58,59.84,52.58,119.68h-50.2Z" fill="#231f20"/>
    <path d="M176.39,236.49c0,22.67-21.67,22.95-21.67,45.34h26.5c0-22.67,16.07-22.67,16.07-45.34h-20.9Z" fill="#231f20"/>
  </g>
  <g id="outside-text">
    <text transform="translate(6.19 87.02)" font-family="Helvetica, Helvetica" font-size="12"><tspan x="0" y="0">instance of Child</tspan></text>
    <text transform="translate(111.87 40.66)" font-family="Helvetica, Helvetica" font-size="10"><tspan x="0" y="0">bases</tspan></text>
    <text transform="translate(147.42 16.21)" font-family="Helvetica, Helvetica" font-size="10"><tspan x="0" y="0">virtual</tspan><tspan x="0" y="11">bases</tspan></text>
    <text transform="translate(175.47 40.9)" font-family="Helvetica, Helvetica" font-size="10"><tspan x="0" y="0">members</tspan></text>
    <text transform="translate(189.7 184.45)" font-family="Helvetica, Helvetica" font-size="10"><tspan x="0" y="0">members</tspan></text>
    <text transform="translate(128.07 146.14)" font-family="Helvetica, Helvetica" font-size="10"><tspan x="0" y="0">members</tspan></text>
    <text transform="translate(89.73 108.74)" font-family="Helvetica, Helvetica" font-size="10"><tspan x="0" y="0">members</tspan></text>
    <text transform="translate(173.75 194.04)" font-family="Helvetica, Helvetica" font-size="10"><tspan x="0" y="0">bases</tspan></text>
    <text transform="translate(147.39 263.2)" font-family="Helvetica, Helvetica" font-size="10"><tspan x="0" y="0">members</tspan></text>
    <text transform="translate(28.9 153.32)" font-family="Helvetica, Helvetica" font-size="10"><tspan x="0" y="0">subobject Left</tspan></text>
    <text transform="translate(61.04 191.46)" font-family="Helvetica, Helvetica" font-size="10"><tspan x="0" y="0">subobject Right</tspan></text>
    <text transform="translate(81.82 229.73)" font-family="Helvetica, Helvetica" font-size="10"><tspan x="0" y="0">subobject Common</tspan></text>
    <text transform="translate(53.56 297.91)" font-family="Helvetica, Helvetica" font-size="10"><tspan x="0" y="0">subobject Superbase</tspan></text>
  </g>
  <g id="inside-text">
    <text transform="translate(181.46 85.66)" font-family="Helvetica, Helvetica" font-size="12"><tspan x="0" y="0">x</tspan></text>
    <text transform="translate(105.25 160.02) rotate(-45)" font-family="Helvetica, Helvetica" font-size="9"><tspan x="0" y="0">value</tspan></text>
    <text transform="translate(143.17 197.95) rotate(-45)" font-family="Helvetica, Helvetica" font-size="9"><tspan x="0" y="0">value</tspan></text>
    <text transform="translate(205.16 85.66)" font-family="Helvetica, Helvetica" font-size="12"><tspan x="0" y="0">y</tspan></text>
    <text transform="translate(203.57 235.51) rotate(-45)" font-family="Helvetica, Helvetica" font-size="7"><tspan x="0" y="0">counter</tspan></text>
    <text transform="translate(163.07 302.49) rotate(-45)" font-family="Helvetica, Helvetica" font-size="7"><tspan x="0" y="0">name</tspan></text>
  </g>
</svg></div></div>	<h2 id='implementation-experience'><a href='#implementation-experience'>Implementation experience</a></h2>
	<p>In progress in clang's fork. Currently structures are represented as <code>APValue</code> object with type field <code>struct</code> and pointer to an array of <code>APValue</code>-s containing <code>n</code> <code>APValue</code>-s representing base types and <code>k</code> <code>APValue</code> representing each member subobject.</p>
	<p>Lookup for outermost object is already implemented in clang in order to implement <code>virtual</code> function calls. So only changes needed are:</p>
	<ul>
		<li>Allow functions to be constexpr if they are within type with virtual bases (in <a href="https://github.com/llvm/llvm-project/blob/f85579fb510faa0a57500b8fd3642f0269c4a4a1/clang/lib/Sema/SemaDeclCXX.cpp#L1795-L1807">SemaDeclCXX.cpp</a>, note: clang currently disallows not just constructor/destructor but all member functions to be constexpr)</li>
		<li>Allow default constructors for types with virtual bases (in <a href="https://github.com/llvm/llvm-project/blob/f85579fb510faa0a57500b8fd3642f0269c4a4a1/clang/lib/Sema/SemaType.cpp#L9467-L9472">SemaType.cpp</a>)</li>
		<li>Allow computing dynamic type for objects (in <a href="https://github.com/llvm/llvm-project/blob/f85579fb510faa0a57500b8fd3642f0269c4a4a1/clang/lib/AST/ExprConstant.cpp#L5987-L5998">ExprConstant.cpp</a>)</li>
		<li>Extend <code>APValue</code> to contain number of virtual bases (in <a href="https://github.com/llvm/llvm-project/blob/6a9279ca407132eec848eb5c55c2222ce605df81/clang/include/clang/AST/APValue.h#L283-L291">APValue.h</a>)</li>
		<li>Make construction of outermost object contain subobject representing virtual bases (in <a href="https://github.com/llvm/llvm-project/blob/f85579fb510faa0a57500b8fd3642f0269c4a4a1/clang/lib/AST/ExprConstant.cpp#L6538-L6542">ExprConstant.cpp</a>)</a></li>
		<li>Handle destruction of outermost object to properly destroy also virtual bases (in <a href="https://github.com/llvm/llvm-project/blob/f85579fb510faa0a57500b8fd3642f0269c4a4a1/clang/lib/AST/ExprConstant.cpp#L6823-L6826">ExprConstant.cpp</a>)</li>
		<li>Handle zero-initialization of outermost object (in <a href="https://github.com/llvm/llvm-project/blob/f85579fb510faa0a57500b8fd3642f0269c4a4a1/clang/lib/AST/ExprConstant.cpp#L10549-L10552">ExprConstant.cpp</a>)
	</ul>
	<p>I spoke with other implementors and they don't seem to have any major concern about implementability.</p>
	
	<h2 id='library-impact'><a href='#library-impact'>Library impact</a></h2>
	<p>Removing last limitation on <em>constexpr-suitable</em> as defined in <a href="https://eel.is/c++draft/dcl.constexpr#3">[dcl.constexpr]</a> will make it a tautology as <em>every</em> function will now be <em>constexpr-suitable</em> hence this paper contains changes to removal of it across wording.</p>
	<p>But this term was used somehow badly to make specify what must be constant evaluatable. It's a subject of <a href="https://cplusplus.github.io/LWG/issue2833">LWG issue 2833</a>. Library needs to invent wording specifying something like <em>"implementation must make sure this functionality is constant evaluatable by avoiding constructs disallowed in <a href="https://eel.is/c++draft/expr.const">[expr.const]</a>"</em>. As <code>constexpr</code> keyword doesn't mean something must be constant-evaluatable, it's just an opt-in into evaluation for some (or none) code-paths.</p>
	<p>I still kept removal of all references to <em>constexpr-suitable</em> in this paper for the project editor's convenience but I guess LWG will do some changes there as they will resolve the issue 2833.</p>
	<h2 id='proposed-changes-to-wording'><a href='#proposed-changes-to-wording'>Proposed changes to wording</a></h2>
	<p>Paper contains two sets of wordings. One is based on current draft and one is based on changes in <a href="https://wg21.link/P3367">P3367 constexpr coroutines</a>.</p>
	<h3 id='based-on-current-draft'><a href='#based-on-current-draft'>Based on current draft</a></h3>
	
	<div class='wording'>

	
	<h3 ><a class='secnum' style='min-width:80pt'>9.2.6</a> The <span class='texttt'>constexpr</span> and <span class='texttt'>consteval</span> specifiers <a class='abbr_ref'>[dcl.constexpr]</a></h3><div class='texpara'><a class='index' id=':specifier,constexpr'></a>
<a class='index' id=':specifier,consteval'></a></div>



<div class='para' id='2'><div class='marginalizedparent'><a class='marginalized' href='#2'>2</a></div><div class='sourceLinkParent'><a class='sourceLink' href='http://github.com/Eelis/draft/tree/eb3b44202e7ac0c1ade1d69df3adba5fe496b94b/source/declarations.tex#L903'>#</a></div><div class='texpara'><div id='2.sentence-1' class='sentence'>A <span id=':constexpr______'><span class='texttt'><span class='keyword'>constexpr</span></span></span> or <span id=':consteval____'><span class='texttt'><span class='keyword'>consteval</span></span></span> specifier
used in the declaration of a function
declares that function to be
a <a class='hidden_link' href='#def:specifier,constexpr,function' title='9.2.6&emsp;The constexpr and consteval specifiers&emsp;[dcl.constexpr]'><span id='def:specifier,constexpr,function'><i >constexpr function</i></span></a><a class='hidden_link' href='#2.sentence-1'>.</a></div> <div id='note-3' class='note'><div class='texpara'>[<i>Note&nbsp;<a href='#note-3'>3</a></i>:&ensp;<div id='2.sentence-2' class='sentence'>A function or constructor declared with the <span id=':consteval_____'><span class='texttt'><span class='keyword'>consteval</span></span></span> specifier
is an immediate function (<a href='expr.const' title='7.7&emsp;Constant expressions'>[expr.<span class='shy'></span>const]</a>)<a class='hidden_link' href='#2.sentence-2'>.</a></div> —&nbsp;<i>end note</i>]</div></div> <div id='2.sentence-3' class='sentence'>
A destructor, an allocation function, or a deallocation function
shall not be declared with the <span id=':consteval______'><span class='texttt'><span class='keyword'>consteval</span></span></span> specifier<a class='hidden_link' href='#2.sentence-3'>.</a></div></div></div><div class='para' id='3'><div class='marginalizedparent'><a class='marginalized' href='#3'>3</a></div><div class='sourceLinkParent'><a class='sourceLink' href='http://github.com/Eelis/draft/tree/eb3b44202e7ac0c1ade1d69df3adba5fe496b94b/source/declarations.tex#L915'>#</a></div><div class='texpara'><div id='3.sentence-1' class='sentence'><a class='index' id=':specifier,constexpr,function'></a><a class='index' id=':constexpr_function'></a>A function is <a class='hidden_link' href='#def:constexpr-suitable' title='9.2.6&emsp;The constexpr and consteval specifiers&emsp;[dcl.constexpr]'><span id='def:constexpr-suitable'><i >constexpr-suitable</i></span></a> if <span class="removed">&nbsp;</span>


<ul class='itemize'><li id='3.1' class="removed-bullet"><div class='marginalizedparent' style='left:-27mm'><a class='marginalized' href='#3.1'><span class="removed">(3.1)</span></a></div>it is not a coroutine (<a href='dcl.fct.def.coroutine' title='9.5.4&emsp;Coroutine definitions'>[dcl.<span class='shy'></span>fct.<span class='shy'></span>def.<span class='shy'></span>coroutine]</a>)<span class="removed">, and</span><span class="added">.</span></li><li id='3.2' class="removed-bullet"><div class='marginalizedparent' style='left:-27mm'><a class='marginalized' href='#3.2'><span class="removed">(3.2)</span></a></div><span class="removed">if the function is a constructor or destructor,
its class does not have any virtual base classes<a class='hidden_link' href='#3.sentence-1'>.</a></span></li></ul>

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



</div>	
		
	<h3 id='feature-test-macro'><a href='#feature-test-macro'>Feature test macro</a></h3>
<div class="wording"><h2><a href="http://eel.is/c++draft/cpp.predefined">15.11 Predefined macro names [cpp.predefined]</a></h2><div class="description"><span class="added"><code>__cpp_constexpr_virtual_inheritance 2025??L</code></span></div></div>
</div></div></article>
</div><script>
	hljs.addPlugin(mergeHTMLPlugin);
	hljs.highlightAll();
</script>
</body>
</html>
