<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<meta name="author" content="Hana+Dus%C3%ADkov%C3%A1">
	<meta name="description" content="">
	<meta name="generator" content="hatemplate/v2">
	<title>P3818R1: constexpr exception fix for potentially constant initialization</title>
	
	<link rel="preconnect" href="https://fonts.googleapis.com">
	<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
	
	
<!-- highlight.min.js -->
<script>
/*!
  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,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>

<!-- merge-html.js -->
<script>
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>

<!-- trim-nicely.js -->
<script>
var trimNicely = (function () {
  'use strict';

	// this is code from reveal.js under following license:
	
	// Copyright (C) 2011-2024 Hakim El Hattab, http://hakim.se, and reveal.js contributors
  // 
	// Permission is hereby granted, free of charge, to any person obtaining a copy
	// of this software and associated documentation files (the "Software"), to deal
	// in the Software without restriction, including without limitation the rights
	// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
	// copies of the Software, and to permit persons to whom the Software is
	// furnished to do so, subject to the following conditions:
  // 
	// The above copyright notice and this permission notice shall be included in
	// all copies or substantial portions of the Software.
  // 
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
	// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
	// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
	// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
	// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
	// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
	// THE SOFTWARE.

	// Function to perform a better "data-trim" on code snippets
	// Will slice an indentation amount on each line of the snippet (amount based on the line having the lowest indentation length)
	function betterTrim(snippetEl) {
		// Helper functions
		function trimLeft(val) {
			// Adapted from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim#Polyfill
			return val.replace(/^[\s\uFEFF\xA0]+/g, '');
		}
		function trimLineBreaks(input) {
			//console.log(input);
			var lines = input.split("\n");

			// Trim line-breaks from the beginning
			for (var i = 0; i < lines.length; i++) {
				if (lines[i].trim() === '') {
					lines.splice(i--, 1);
				} else break;
			}

			// Trim line-breaks from the end
			for (var i = lines.length-1; i >= 0; i--) {
				if (lines[i].trim() === '') {
					lines.splice(i, 1);
				} else break;
			}

			return lines.join("\n");
		}

		// Main function for betterTrim()
		return (function(snippetEl) {
			var content = trimLineBreaks(snippetEl.innerHTML);
			var lines = content.split("\n");
			// Calculate the minimum amount to remove on each line start of the snippet (can be 0)
			var pad = lines.reduce(function(acc, line) {
				if (line.length > 0 && trimLeft(line).length > 0 && acc > line.length - trimLeft(line).length) {
					return line.length - trimLeft(line).length;
				}
				return acc;
			}, Number.POSITIVE_INFINITY);
			// Slice each line with this amount
			return lines.map(function(line, index) {
				return line.slice(pad);
			})
			.join("\n");
		})(snippetEl);
	}
	

  /** @type {HLJSPlugin} */
  const trimNicely = {
    // preserve the original HTML token stream
    "before:highlightElement": ({ el }) => {
			if (!el.hasAttribute("no-data-trim")) {
				el.innerHTML = betterTrim(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 */

  

  return trimNicely;

}());
</script>

	
<!-- Noto Serif (external font) -->
<link href="https://fonts.googleapis.com/css?family=Noto+Serif" rel="stylesheet" blocking="render"></link>
	
<!-- Noto Sans (external font) -->
<link href="https://fonts.googleapis.com/css?family=Noto+Sans" rel="stylesheet" blocking="render"></link>
	
	
<!-- Fira Code (external font) -->
<link href="https://fonts.googleapis.com/css?family=Fira+Code" rel="stylesheet" blocking="render"></link>
	
<!-- eel-hana.css -->
<style>
.wording  {
    font-family: 'Noto Serif';
    hyphens: auto;
    line-height: 1.5;
    font-size: var(--base-font-size-10);
    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: var(--base-font-size-14);
    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: var(--base-font-size-7);
    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: var(--base-font-size-10);
    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: var(--base-font-size-10);
    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: var(--base-font-size-10);
    white-space: normal;
}

.wording .bnf span.textnormal {
    font-style: normal;
    font-family: 'Noto Serif';
    font-size: var(--base-font-size-10);
    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: var(--base-font-size-9);
    white-space: pre-wrap;
}

.wording span.noncxxterminal {
    font-family: 'Noto Sans Mono';
    font-style: normal;
    font-size: var(--base-font-size-9);
}

.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: var(--base-font-size-10);
}

.wording div.footnote span.textsf {
    font-family: 'Noto Sans';
    font-size: var(--base-font-size-8);
}

.wording .bnf span.textsf {
    font-family: 'Noto Sans';
    font-size: var(--base-font-size-10);
}

.wording .simplebnf span.textsf {
    font-family: 'Noto Sans';
    font-size: var(--base-font-size-10);
}

.wording .example span.textsf {
    font-family: 'Noto Sans';
    font-size: var(--base-font-size-10);
}

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

.wording span.nontermdef {
    font-style: italic;
    font-family: 'Noto Sans';
    font-size: var(--base-font-size-10);
}

.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: var(--base-font-size-10);
}

.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: var(--base-font-size-9);
}

.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: var(--base-font-size-10);
}

.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: var(--base-font-size-9);
    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: var(--base-font-size-9);
}

.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: var(--base-font-size-9);
    display: block;
		overflow-x: visible;
		overflow-y: default;
}

.wording .comment {
    color: green;
    font-style: italic;
    font-family: 'Noto Serif';
    font-size: var(--base-font-size-10);
}

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

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

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

.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: var(--base-font-size-8);
}

.wording .footnote .math {
    font-size: var(--base-font-size-8);
}

.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.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: var(--base-font-size-10);
}

.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: var(--base-font-size-10);
}

.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: var(--base-font-size-11);
}

.wording div.note {
	display: block;
	margin-top: 5pt;
	margin-bottom: 5pt;
	font-size: var(--base-font-size-11);
}

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

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

.wording div.note .texttt { font-size: var(--base-font-size-9); }
.wording div.example .texttt { font-size: var(--base-font-size-9); }

.wording div.note .textsf { font-family: 'Noto Sans'; font-size: var(--base-font-size-9); }
.wording div.example .textsf { font-family: 'Noto Sans'; font-size: var(--base-font-size-9); }

.wording div.note .math { font-size: var(--base-font-size-9); }
.wording div.example .math { font-size: var(--base-font-size-9); }

.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>
	
<!-- may.css -->
<style>
:root {
	--hana-nav-size: 300px;
	--hana-article-left-padding: 300px;
	--hana-background: white;
	--hana-foreground: black;
	--hana-accent: hsl(215, 100%, 35%);
	--hana-hsl-saturated-bright: hsl(0 100% 75%);
	--hana-hsl-saturated-bright-contrast: hsl(0 100% 0%);
	--hana-nav-hide-transform: translate(-300px, 0px);
	--hana-selected-color: hsl(from var(--hana-hsl-saturated-bright) 220 s l);
	--hana-selected-background: color-mix(in hsl, var(--hana-selected-color), var(--hana-background) 70%);
}

@media (prefers-color-scheme: dark) {
	:root {
		--hana-background: #111;
		--hana-foreground: #DDD;
		--hana-accent: hsl(215, 50%, 73%);
		--hana-hsl-saturated-bright: hsl(0 25% 25%);
		--hana-hsl-saturated-bright-contrast: hsl(0 100% 50%);
	}
}

@media print {
	:root {
		--hana-accent: hsl(215, 100%, 23%);
	}
}

@media screen and (prefers-reduced-motion: reduce) {
	html {
		scroll-behavior: auto;
	}
}

@media only screen and (width >= 1000px) {
body:has(#hide.enabled) {
	--hana-article-left-padding: 0;
}
:root {
	--hana-paper-title-visibility: none;
	
		&:has(body #hide.enabled) {
			--hana-paper-title-visibility: initial;
		}
	}
}
}


@media only screen and (width < 1000px) {
	body {
		font-size: 150%;
	}
}

/* derived and named colors */
:root {
	--hana-menu-background: color-mix(in hsl, var(--hana-background), var(--hana-foreground) 3%);
	--hana-title-background: var(--hana-background);
	--hana-accent-foreground: color-mix(in lab, var(--hana-accent), var(--hana-foreground) 50%);
}

:root {
  overscroll-behavior: none;
}

body {
	overscroll-behavior: none;
	background-color: var(--hana-background);
	color: var(--hana-foreground);
	padding: 0;
	margin: 0;
	font-family: "Noto Serif", "CMU Sans Serif", "Times New Roman";
}

body::backdrop {
	background-color: var(--hana-background);
}

code {
	font-family: "Fira Code", "CMU Typewriter Text", "Times New Roman";
	font-size: 90%;
}

#hide {
	position: fixed;
	left: calc(var(--hana-nav-size) - 2em);
	bottom: 0.5em;
	cursor: pointer;
	z-index: 2000;
	transition: left 0.5s, color 0.5s, transform 0.5s ease-in-out;
	color: color-mix(in hsl, var(--hana-foreground), var(--hana-background) 80%);
	font-size: 20px;
}




@media only screen and (width >= 1000px) {
	#hide.enabled {
		left: 1em;
		transform: rotate(-180deg);
	}
	
	body {
		&:has(#hide.enabled) nav {
			transform: var(--hana-nav-hide-transform);
		}
	}
}



#paper-id {
	display: var(--hana-paper-title-visibility);
	font-size: 80%;
}

nav {
	position: fixed;
	top: 0;
	left: 0;
	bottom: 0;
	width: var(--hana-nav-size);
	padding: 1em;
	background: var(--hana-menu-background);
	color: var(--hana-foreground);
	box-sizing: border-box;
	
	overflow-wrap: break-word;
	hyphens: auto;
	word-spacing: 0;
	font-size: 90%;
	overflow-y: scroll;
	
	h1 {
		margin-top: 0;
		margin-bottom: 0;
	}
	
	.side {
		font-size: 80%;
	}
	
	.paper-info {
		display: grid;
		grid-template-columns: auto 1fr;
		.key {
			text-align: right;
			font-weight: bold;
			padding-right: 0.5em;
		}
		padding-right: 1em;
	}
	
	#toc {
		display: grid;
		grid-template-columns: 1fr;
		padding-top: 0.5lh;
		padding-bottom: 1lh;
		h1 {
			margin-bottom: 0.5em;
		}
		ul {
			padding-left: 1em;
			list-style-type: square;
		}
		> ul {
			padding-left: 2em;
			margin: 0;
		}
		
	}
}

@media only screen and (width < 1000px) {
	:root {
		--hana-article-left-padding: 0;
		--hana-title-background: var(--hana-menu-background);
	}
	nav {
		position: static;
		width: 100vw;
		margin: 0;
	}
	#hide {
		display: none;
	}
}

@media print {
	:root {
		--hana-article-left-padding: 0;
		--hana-title-background: var(--hana-menu-background);
	}
	nav {
		position: static;
		width: 100vw;
		margin: 0;
		transform: none !important;
	}
	section > p, section > pre {
		break-inside: avoid;
	}
	#toc {
		display: none;
	}
	#hide {
		display: none;
	}
}


article {	
	color: var(--hana-foreground);
	padding: 1em;
	margin-left: var(--hana-article-left-padding);
	max-width: 100vw;
	
	p:has(+section) {
		margin-bottom: 0;
	}
	
	section {
		> *:last-child {
			margin-bottom: 0;
		}
	}
	
	.wording, pre, code {
		background: color-mix(in lab, var(--hana-accent), var(--hana-background) 98%);
		&code {
			color: var(--hana-accent-foreground);
		}
	}
	
	.wording, pre {
		padding: 1em;
		border-radius: 1em;
		> *:first-child {
			margin-top: 0
		}
		> *:last-child {
			margin-bottom: 0
		}
	}
	
	.wording pre {
		padding: 0;
	}
	
	&.transitionable {
		/*transition: margin-left 0.5s;*/
	}
	
	pre {
		tab-size: 2;
		
		text-align: left;
		white-space: pre-wrap;
	  word-break: break-all;
		overflow-x: wrap;
		overflow-wrap: anywhere;
		
		code.hljs {
			.added, .removed, .before, .after {
				line-height: 1.3;
			}
			
			font-variant-ligatures: none;
			line-height: 1.3;
			* {
				font-size-adjust: 0.5;
			}
			.hljs-keyword, .hljs-built_in, .hljs-type {
				font-weight: bold;
			}
			.hljs-string {
				font-style: italic;
				text-decoration: underline;
			}
			.hljs-comment {
				color: color-mix(in hsl, currentcolor, var(--hana-background) 50%);
			}
		}
	}
	
	p:first-child {
		margin-top: 0;
	}
	
	p {
		color: color-mix(in hsl, var(--hana-foreground), var(--hana-background) 15%);
		text-align: left;
		overflow-wrap: break-word;
		hyphens: auto;
		word-spacing: 0;
		text-wrap: pretty;
	}
	
	.before {
		--hana-context-background: hsl(from var(--hana-hsl-saturated-bright) 0 s l);
		--hana-context-accent: hsl(from var(--hana-hsl-saturated-bright-contrast) 0 s l);
		z-index: 10;
		padding: 0 0.5em;
	}
	.after {
		--hana-context-background: hsl(from var(--hana-hsl-saturated-bright) 90 s l);
		--hana-context-accent: hsl(from var(--hana-hsl-saturated-bright-contrast) 90 s l);
		z-index: 20;
		padding: 0 0.5em;
	}
	.removed, .rem {
		--hana-context-background: hsl(from var(--hana-hsl-saturated-bright) 0 s l);
		--hana-context-accent: hsl(from var(--hana-hsl-saturated-bright-contrast) 0 s l);
		--hana-context-decoration: hsl(from var(--hana-hsl-saturated-bright) 0 s 40);
		--hana-context-text-decoration: hsl(from var(--hana-hsl-saturated-bright) 0 s 40 / 0.75);
		text-decoration: line-through;
	}
	.added, .add, .change {
		--hana-context-background: hsl(from var(--hana-hsl-saturated-bright) 90 s l);
		--hana-context-accent: hsl(from var(--hana-hsl-saturated-bright-contrast) 90 s l);
		--hana-context-decoration: hsl(from var(--hana-hsl-saturated-bright) 90 s 40);
		--hana-context-text-decoration: hsl(from var(--hana-hsl-saturated-bright) 90 s 40 / 0.75);
		&.alt {
			--hana-context-background: hsl(from var(--hana-hsl-saturated-bright) 50 s l);
			--hana-context-accent: hsl(from var(--hana-hsl-saturated-bright-contrast) 50 s l);
			--hana-context-decoration: hsl(from var(--hana-hsl-saturated-bright) 50 s 40);
			--hana-context-text-decoration: hsl(from var(--hana-hsl-saturated-bright) 50 s 40 / 0.75);
		}
	}
	.important {
		--hana-context-background: hsl(from var(--hana-hsl-saturated-bright) 60 s l);
		--hana-context-accent: hsl(from var(--hana-hsl-saturated-bright-contrast) 60 s l);
		--hana-context-decoration: hsl(from var(--hana-hsl-saturated-bright) 60 s 40);
		--hana-context-text-decoration: hsl(from var(--hana-hsl-saturated-bright) 60 s 40 / 0.75);
	}
	.removed, .rem, .added, .add {
		&, * {
			text-decoration-thickness: 3px;
			text-decoration-color: var(--hana-context-text-decoration);
		}
	}
	.removed, .rem, .added, .add, .change, .important {
		border-radius: 0.5em;
	}
	.before, .after, .removed, .rem, .added, .add, .important {
		print-color-adjust:exact;
		border: none;
		margin: 0;
		padding: 1px 0;
		background: var(--hana-context-background);
		h1, h2, h3, h4, h5, .note, .example, pre, code {
			background: inherit;
		}
		&, * {
			color: var(--hana-context-accent) !important;
		}
	}
}

body:fullscreen {
	overflow-y: scroll;
}

body:fullscreen article {
	overflow-y: scroll;
}

.added, .removed, .change {
	print-color-adjust:exact;
	&:has(&.selected-current) {
		z-index: 5006;
		position: relative;
		outline: 2px solid var(--hana-context-decoration);

		&, .added, .removed, change {
			&:not(.selected-current) {
				--hana-local-background: hsl(from var(--hana-context-background) calc(h - 15) calc(s) l);
				background: var(--hana-local-background) !important;
				outline: 1px solid var(--hana-local-background);
			}
		}
	}
}

.selected-current, .wording .texpara:has(.selected-current), .context:has(.selected-current) {
	z-index: 5005;
	position: relative;
	outline: 2px solid var(--hana-context-decoration);
	background: var(--hana-context-background);
	--special-hana: hana;
}

section:has(.selected-current) {
	& > h1 {
		z-index: 5030;
	}
	& > h2 {
		z-index: 5025;
	}
	& > h3 {
		z-index: 5020;
	}
	& > h4 {
		z-index: 5015;
	}
	& > h5 {
		z-index: 5010;
	}
}

#overlay {
	display: block;
	position: fixed;
	top: 0;
	bottom: 0;
	left: 0;
	right: 0;
	z-index: 5000;
	background-color: rgb(from var(--hana-background) r g b / 0.75);
	pointer-events: none;
}

/* links are all defined here! */
a {
	color: var(--hana-accent);
	&:visited {
		color: hsl(from var(--hana-accent) calc(h - 120) s l);
	}
	&:hover {
		color: hsl(from var(--hana-accent) calc(h + 120) s l) !important;
	}
	&::after {
		margin-left: 0.2em;
		display: inline-block;
		font-size: 80%;
		width: 1em;
		height: 1em;
	}
	&:target {
		outline: none;
		&::after {
			content: "⚓︎";
		}
	}
	&[href^="https://"], &[href^="http://"] {
		&:not(&.revision):not([href^="http://eel.is"]):not([href^="https://eel.is"]):not([href^="http://github.com/Eelis/"]) {
			@media only screen {
				&::after {
					font-family: "Noto Serif", "CMU Sans Serif", "Times New Roman";
					font-size: 14px;
					content: "⎋";
					transform: scale(-1, 1);
				}
			}
		}
	}
}

section {
	position: relative;
}

h1, h2, h3, h4, h5, hr {
	word-break: keep-all;
	white-space: nowrap;
	--hana-header-color: color-mix(in hsl, var(--hana-foreground), var(--hana-background) 15%);
	--hana-header-decoration-color: color-mix(in hsl, var(--hana-foreground), var(--hana-background) 75%);
	text-decoration: none;
	margin-bottom: 0;
	margin-top: 0;
	&:not(hr) {
		padding-top: 1lh;
	}
	line-height: 1.1;
	a {
		text-decoration: none;
		&, &:visited, &:hover, &:target {
			color: var(--hana-header-color) !important;
		}
	}
}

div:has(>h2) + p {
	margin-top: 0.5em;
}

hr {
	margin-top: 0.8em;
	height: 2px;
  background-color: none;
  border:none;
	border-top: 2px dotted var(--hana-header-decoration-color);
}

article {
	padding-top: 0;
}

h1#name-of-paper {
	/*position: sticky;*/
	top: 0lh;
	left: 16px;
	margin-top: 0;
	z-index: 5950;
	padding-top: 0.5lh;
	padding-bottom: 0.25lh;
}

body {
	position: relative;
}

article {
	position: relative;
	overflow-x: clip;
	/* text-wrap: pretty; // this will crash chrome */
	h1, h2, h3, h4, h5 {
		background-color: var(--hana-background);
		/*position: sticky;*/
		top: 0.5lh;
		z-index: 2000;
		box-shadow: 0 10px 10px var(--hana-background);
	}
	.wording {
		h1, h2, h3, h4, h5 {
			--hana-background: transparent;
			background-color: none;
			position: static;
			box-shadow: none;
		}
		.para:has(.marginalizedparent) {
			margin-left: 2em;
			.marginalizedparent {
				top: 1mm;
				* {
					font-size: 50%;
					color: orange;
				}
			}
		}
		code.itemdeclcode {
			overflow-wrap: anywhere !important;
			word-break: break-word;
			hyphens: auto;
			white-space: pre-wrap;
		}
	}
	h2 {
		top: 1lh;
		z-index: 1900;
		padding-left: 3px;
	}
	h3 {
		top: 2.25lh;
		z-index: 1800;
		padding-left: 6px;
	}
	h4 {
		top: 3.5lh;
		z-index: 1700;
		padding-left: 9px;
	}
	h5 {
		top: 6.5lh;
		z-index: 1800;
		padding-left: 12px;
	}
	.columns {
		display: flex;
		& > div {
			flex: auto;
			min-width: 300px;
		}
	}
}

.wording {
	h1, h2, h3, h4, h5 {
		position: static;
	}
}

@media only screen and (width < 1000px) {
	.wording {
		padding-left: 0em !important;
		padding-right: 0em !important;
	}
	body {
		overflow-x: hidden;
	}
	article {
		padding: 0 0.5em;
	}
	p {
		padding: 0 0.5em;
	}
	h1,h2,h3,h4,h5 {
		position: static !important;
		overflow-wrap: anywhere !important;
		word-break: break-word;
		hyphens: auto;
		white-space: pre-wrap;
	}
}


article section > h1, article > h1 {
	border-bottom: 2px solid var(--hana-header-decoration-color);
}

article section > h2 {
	border-bottom: 2px solid var(--hana-header-decoration-color);
}

article section > h3 {
	border-bottom: 2px dotted var(--hana-header-decoration-color);
}

article section > h4, article section > h5 {
	border-bottom: none;
}

.wording {
	padding-left: 2em;
	
	span.codeblock  {
		text-align: left;
		white-space: pre-wrap;
	  word-break: break-all;
		overflow-x: wrap !important;
		overflow-wrap: anywhere;
	}
	
	.comment {
		color: color-mix(in hsl, var(--hana-background), var(--hana-foreground) 75%) !important;
	}
	
	.note, .example {
		background-color: rgba(from var(--hana-foreground) r g b / 3%);
		padding: 0 0.3em;
		margin: 0.3em;
		border-radius: 0.3em;
		font-size: 95% !important;
		*:not(.note):not(.example) {
			background: none;
		}
	}
	
	code {
		text-align: left;
		white-space: pre-wrap;
	  word-break: break-all;
		overflow-x: wrap;
		overflow-wrap: anywhere;
		
		em {
			& * {
				font-style: italic;
				font-weight: normal !important;
			}
		}
	}
}

code, .wording .codeblock, .wording span.texttt, .wording span.terminal, .wording span.noncxxterminal .wording span.tcode, .wording span.mathtt, .wording div.footnote span.texttt, .wording span.tcode_in_codeblock, .wording .outputblock, .wording code.itemdeclcode, .wording span.literalterminal, .wording .MJXc-TeX-type-R {
	font-family: "Fira Code", "Noto Sans Mono", monospace !important;
	font-variant-ligatures: no-contextual;
	line-height: 1.3;
	* {
		font-size-adjust: 0.5;
	}
}

.hana_wording  {
	pre {
		padding-top: 1lh !important;
	}
	h2 {
    line-height: 1 !important;
    font-size: var(--base-font-size-16) !important;
    margin-top: 10pt !important;
    margin-bottom: 10pt !important;
	}
	h3 {
    line-height: 1 !important;
    margin-top: 10pt !important;
    margin-bottom: 10pt !important;
	}
}

@media screen {
	#draft-warning {
		position: fixed;
		bottom: 0;
		right: 0;
		background: red;
		font-family: "Fira Code", "Noto Sans Mono", monospace !important;
		font-size: 150%;
		padding: 8px 100px;
		text-transform: uppercase;
		transform: translateY(-30px) translateX(80px) rotate(-45deg);
		z-index: 50000;
		color: white;
	}
}
@media print {
	#draft-warning {
		display: none;
	}
}

ul {
	&:has(label) {
		padding-left: 0;
	}
	li:has(label) {
		list-style: none;
		list-style-position: inside;
	}
}

label:has(input[type="radio"]) {
	cursor: pointer;

	padding-left: 0.5em;
	
	line-height: 1.5;
	code {
		font-size-adjust: 0.5;
	}
	
	
	
	span {
		transition: background-color 0.2s ease-out;
		padding-left: 0.5em;
		padding-right: 0.5em;
		border-radius: 0.5em;
	}
	
	&:has(input:checked) {
		text-decoration: underline;
		text-decoration-style: dotted;
		text-decoration-thickness: 2px;
		span {
			background: var(--hana-background);
		}
		/*font-weight: bold;*/
	}
	
	&:has(input:disabled:not(:checked)) {
		color: color-mix(in hsl, var(--hana-foreground), var(--hana-background) 60%);
	}
	
	input {
		vertical-align: middle;
		-webkit-appearance: none;
		appearance: none;
		background-color: transparent;
		margin: 0;
		
		box-sizing: border-box;
		width: 1lh;
		height: 1lh;
	  padding: 0;
		margin-right: 0.5em;
		transition: border 0.2s ease-out, background 0.2s ease-out;
	  border: 2px solid color-mix(in hsl, var(--hana-foreground), var(--hana-background) 25%);
	  border-radius: 50%;
	  appearance: none;
	  background-color: transparent;
	  outline: none;
		&:checked {
			background: var(--hana-selected-color);
		}
		&:disabled {
			border: 2px solid color-mix(in hsl, var(--hana-foreground), var(--hana-background) 80%);
		}
	}
}

.poll_condition {
	&.discard {
		display: none;
	}
}

span.note {
	font-size: 80%;
	color: 2px solid color-mix(in hsl, var(--hana-foreground), var(--hana-background) 25%);
}

.wording {
	section:first-child[data-related] {
		> h1, > h2, > h3, > h4, > h5 {
			margin-top: 0;
			padding-top: 0;
		}
	}
}

.wording .example {
	& > span {
		font-style: italic;
	}
}

.wording .grammar {
	padding: 0em 1em;
	ul {
		padding-left: 4em;
		li:before {
			content: "";
		}
		li {
			list-style: none !important;
			list-style-position: inside;
		}
	}
}

div.poll {
	--poll-color: hsl(from var(--hana-hsl-saturated-bright) 45 s l);
	--poll-accent-color: hsl(from var(--poll-color) h 100% l);
	background-color: color-mix(in oklch, var(--hana-background), var(--poll-color) 25%);
	padding: 0.5em 1em;
	padding-bottom: 1em;
	margin-bottom: 0.5em !important;
	border-radius: 0.5em;
	
	code {
		background: transparent;
	}
	
	> div:not(.note) {
		> span:first-child {
			font-weight: bold;
		}
	}
	div.note {
		font-size: 75%;
	}
	
	.preferred {
		padding-left: 0.5em;
		font-size: 75%;
		display: inline-block;
		transform: translate(0, -0.05em);
	}
	
	label:has(input[type="radio"]) {
		&:has(input:checked) {
			text-decoration-color: var(--poll-accent-color);
			span {
				background: var(--poll-accent-color);
			}
		}
	}
}

table.before-after {
	border-collapse: collapse;
	margin: 1em;
	th, td {
		border-top: 1px solid rgba(from var(--hana-foreground) r g b / 0.2);
		border-bottom: 1px solid rgba(from var(--hana-foreground) r g b / 0.2);
		border-left: 1px solid rgba(from var(--hana-foreground) r g b / 0.1);
		border-right: 1px solid rgba(from var(--hana-foreground) r g b / 0.1);
		padding: 0.25em;
	}
	td.problem {
		--hana-context-background: hsl(from var(--hana-hsl-saturated-bright) 0 s l);
		--hana-context-accent: hsl(from var(--hana-hsl-saturated-bright-contrast) 0 s l);
		color: var(--hana-context-accent);
		background-color: var(--hana-context-background);
	}
	td.slightproblem {
		--hana-context-background: hsl(from var(--hana-hsl-saturated-bright) 20 s l);
		--hana-context-accent: hsl(from var(--hana-hsl-saturated-bright-contrast) 20 s l);
		color: var(--hana-context-accent);
		background-color: var(--hana-context-background);
	}
	td.fixed {
		--hana-context-background: hsl(from var(--hana-hsl-saturated-bright) 90 s l);
		--hana-context-accent: hsl(from var(--hana-hsl-saturated-bright-contrast) 90 s l);
		color: var(--hana-context-accent);
		background-color: var(--hana-context-background);
	}
	td.expected {
		--hana-context-background: hsl(from var(--hana-hsl-saturated-bright) 190 s l);
		--hana-context-accent: hsl(from var(--hana-hsl-saturated-bright-contrast) 190 s l);
		color: var(--hana-context-accent);
		background-color: var(--hana-context-background);
	}
	td.problem, td.slightproblem, td.fixed, td.expected {
		code {
			background-color: color-mix(in lab, var(--hana-context-background), var(--hana-background) 20%);
		}
	}
	.tinynote {
		font-size: 75%;
	}
	.na {
		text-transform: uppercase;
		color: rgba(from var(--hana-foreground) r g b / 0.5);
	}
	ul {
		padding: 0;
		margin: 0;
		margin-left: 2em;
	}
	&.const_int_exception {
		th:first-child {
			text-align: left;
		}
		td {
			text-align: center;
		}
		strong {
			text-decoration: underline;
		}
	}
	&.positives-negatives {
		td:has(> ul) {
			vertical-align: top;
		}
		th.positive, ul.positive li::marker {
			--hana-local-color: hsl(from var(--hana-hsl-saturated-bright) 90 s l);
		}
		th.negative, ul.negative li::marker {
			--hana-local-color: hsl(from var(--hana-hsl-saturated-bright) 0 s l);
		}
		ul.positive, ul.negative {
			li::marker {
				color: var(--hana-local-color);
			}
		}
		th.positive, th.negative {
			background-color: var(--hana-local-color);
		}
	}
	th.table-section {
		text-align: center !important;
		padding-top: 1.5em;
	}
}
</style>
</head>
<body>

<!-- navigation sidebar -->
	
<nav>
<div class="paper-info">
	<span class="key">Number:</span><span>P3818R1</span>
	<span class="key">Date:</span><span><time>2025-09-03</time></span>
	<span class="key">Audience:</span><span><a href="mailto:Library&nbsp;Evolution (YOU-NEED-JAVASCRIPT-ENABLED) #TGlicmFyeSZuYnNwO0V2b2x1dGlvbiA8bGliLWV4dEBsaXN0cy5pc29jcHAub3JnPj9zdWJqZWN0PVAzODE4UjE6IGNvbnN0ZXhwciBleGNlcHRpb24gZml4IGZvciBwb3RlbnRpYWxseSBjb25zdGFudCBpbml0aWFsaXphdGlvbg==" onclick="return send_email(this)">Library&nbsp;Evolution</a></span>
	<span class='key'>Target:</span><span>C++26</span>	<span class="key">Author:</span><span><a href="mailto:hana dusikova (YOU-NEED-JAVASCRIPT-ENABLED) #SGFuYStEdXMlQzMlQURrb3YlQzMlQTEgPGhhbmlja2FAaGFuaWNrYS5uZXQ+P3N1YmplY3Q9UDM4MThSMTogY29uc3RleHByIGV4Y2VwdGlvbiBmaXggZm9yIHBvdGVudGlhbGx5IGNvbnN0YW50IGluaXRpYWxpemF0aW9u" onclick="return send_email(this)">Hana Dusíková</a><span>
</div>
<hr/>
<div id="toc">
<ul>
<li><a href="#revision-history">Revision history</a></li>
<li><a href="#the-problem-to-fix">The problem to fix</a></li>
<ul>
<li><a href="#explainer-table">Explainer table</a></li>
<li><a href="#constexpr-variables-are-not-a-problem"><code>constexpr</code> variables are not a problem</a></li>
</ul>
<li><a href="#proposed-solution">Proposed solution</a></li>
<li><a href="#possible-alternatives">Possible alternatives</a></li>
<ul>
<li><a href="#much-larger-but-probably-breaking-solution">Much larger but probably breaking solution</a></li>
<li><a href="#alternative-and-somehow-arbitrary-solution">Alternative and somehow arbitrary solution</a></li>
<li><a href="#duplicate-functions-under-different-name-specially-for-constant-evaluation">Duplicate functions under different name specially for constant evaluation</a></li>
<ul>
<li><a href="#runtime-and-constexpr-exception-don%27t-have-different-semantic">Runtime and constexpr exception don't have different semantic</a></li>
<li><a href="#one-function-name-is-needed">One function name is needed</a></li>
</ul>
</ul>
<li><a href="#positive-%2F-negative-comparison">Positive / negative comparison</a></li>
<li><a href="#implementation-experience">Implementation experience</a></li>
<li><a href="#wording">Wording</a></li>
<ul>
<li><a href="#feature-test-macros">Feature test macros</a></li>
</ul>
</ul></div><div class="side"></div>
</nav>
<div id="hide">◀︎</div>
<!-- main content -->
<article spellcheck="true">
	<h1 id="name-of-paper"><span id="paper-id">P3818R1: </span>constexpr exception fix for potentially constant initialization</h1>
<p>This paper proposes fix to surprising silent code breakage introduced by <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3068r6.html">P3068 <em>"constexpr exceptions"</em></a> interacting with <a href="https://eel.is/c++draft/expr.const#8">potentially-constant initialization [expr.const]</a>. This was <a href="https://lists.isocpp.org/lib/2025/08/32521.php">found</a> by Lénárd Szolnoki and discussed at library and core wording groups reflectors.</p>
<p>Problem described in this paper is a significant silent breakage with simple fix, I'm asking chairs of LEWG and LWG to treat this with high-priority, as there will probably be some NB comments asking WG21 to fix the described issue.</p>
<section data-related="revision-history"><h2><a href="#revision-history" id="revision-history">Revision history</a></h2>	<ul>
		<li><a class="revision" href="https://isocpp.org/files/papers/P3818R0.html">R0</a>&#x2005;→&#x2005;R1: added <a href="#duplicate-functions-under-different-name-specially-for-constant-evaluation">section discussing changes proposed in P3820</a>, added <a href="#explainer-table">comparison table</a> to explaing subtle differences between various types of variables and their initialization, added <a href="#positive-%2F-negative-comparison">comparison table</a> between P3818 and P3820 proposals.</li>
	</ul>
</section><section data-related="the-problem-to-fix"><h2><a href="#the-problem-to-fix" id="the-problem-to-fix">The problem to fix</a></h2><p>C++ has many corner cases and this one is one of them. A constant variable (marked <code>const</code>) which is integral or enumeration type is upgraded to <code>constexpr</code> variable silently if its initialization succeed in constant evaluation. This is usually unobservable, because you can't reference anything around to succeed.</p>
<pre class="lang-cpp"><code>auto function_returning_empty_array() {
	const int n = calculate_size_needed(); // this needs to be a constant evaluated =&gt; constexpr
	return std::array&lt;int, n&gt;{}; // so we can change type based on `n`
}</code></pre>
<p>This is a problem for <code>constexpr</code> exceptions, which needs <code>constexpr</code> marked functions in order for them work inside constant evaluation. But once marked <code>constexpr</code> a function can be evaluated there, which is a problem for two functions added by<a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3068r6.html">P3068</a> (<code>std::uncaught_exceptions</code> and <code>std::current_exceptions</code>) as these don't have dependency on  any local variable which would disallow constant evaluation. These have only an implicit dependency on local context which allows them to be succesfully evaluated in <code>const</code> variable potentially-constant initialization.</p>
<p>This potentially-constant initialization starts as any constant evaluation a new context, in which there are no unrolling or current exception, so these function will return constant which is something else user wants.</p>
<pre class="lang-cpp"><code>try {
	// some exception throwing code
} catch (const std::exception &amp; exc) {
	const bool has_exception = (std::current_exception() != nullptr); <span class="before">// no current exception in a catch handler?!</span>
	static_assert(has_exception == false); // success here
}</code></pre>
<p>Variable <code>has_exception</code> is silently upgraded to a <code>constexpr</code> variable. And records different context than a user expects. Another even more scary example:</p>
<pre class="lang-cpp"><code>struct transaction {
	// ...
	void cancel() { /* revert changes */ }
	
	~transaction() {
		const bool unrolling = std::uncaught_exceptions() &gt; 0;
		
		if (unrolling) { <span class="before">// this will never be evaluated</span>
			log("exception was thrown in a transaction => cancel()");
			cancel();
		}
	}
}</code></pre>
<p>Note: I know this example should contain call in <code>std::uncaught_exceptions()</code> so we can actually know if an there is a new exception, but in order to simplify it I did what I did.</p>
<p>In previous example <code>std::uncaught_exceptions() &gt; 0</code> is constant evaluated in a vacuum, even sooner than the destructor <code>transaction::~transaction()</code> is finished parsing. And because in that specific constant evaluation, there is no uncaught exception, it will return 0, <em>obviously</em>. The whole <code>unrolling</code> becomes <code>constexpr</code>, and your transactions will <b>never</b> cancels. This is really scary.</p>
<section data-related="explainer-table"><h3><a href="#explainer-table" id="explainer-table">Explainer table</a></h3><table class="before-after const_int_exception">
	<tr><th colspan="5" class="table-section">potentially-constant initialization<div class="tinynote">(sometimes constant evaluated without visible clue)</div></th></tr>
	<tr>
		<th></th>
		<th>C++23</th>
		<th>C++26<div class="tinynote">(status quo)</div></th>
		<th>P3818<div class="tinynote">(this paper)</div></th>
		<th>P3820<div class="tinynote">(Lénárd's paper)</div></th>
	</tr>
	<tr>
		<th><code>const int n = uncaught_exception()</code><div class="tinynote">(local variable)</div></th>
		<td>number of exceptions<div class="tinynote">(during runtime evaluation)</div></td>
		<td class="problem">always <code>0</code><div class="tinynote">(constant evaluated during parsing)</div></td>
		<td class="fixed">number of exceptions<div class="tinynote">(during runtime <strong>and constant</strong> evaluation)</div></td>
		<td class="slightproblem">number of exceptions<div class="tinynote">(during <strong>runtime evaluation only</strong>, failure to compile in constant evaluated code)</div></td>
	</tr>
	<tr>
		<th><code>static const int n = uncaught_exception()</code><div class="tinynote">(local static variable)</div></th>
		<td>number of exceptions<div class="tinynote">(during <strong>first</strong> runtime evaluation)</div></td>
		<td class="problem">always <code>0</code><div class="tinynote">(constant evaluated during parsing)</div></td>
		<td class="fixed" colspan="2">number of exceptions<div class="tinynote">(during <strong>first</strong> runtime evaluation, <code>static const</code> variables are not available in constant evaluated functions)</div></td>
	</tr>
	<tr>
		<th><code>const int n = uncaught_exception()</code><div class="tinynote">(object member variable)</div></th>
		<td colspan="4">number of exceptions<br/>(during evaluation of object's constructor, never was a constant evaluation, unchanged)</td>
	</tr>
	<tr><th colspan="5" class="table-section">explicit constant evaluation</th></tr>
	<tr>
		<th></th>
		<th>C++23</th>
		<th>C++26<div class="tinynote">(status quo)</div></th>
		<th>P3818<div class="tinynote">(this paper)</div></th>
		<th>P3820<div class="tinynote">(Lénárd's paper)</div></th>
	</tr>
	<tr>
		<th><code>constexpr int n = uncaught_exception()</code><div class="tinynote">(local constant)</div></th>
		<td class="na">n/a</td>
		<td colspan="2" class="expected">always <code>0</code><div class="tinynote">(constant evaluated during parsing)</div></td>
		<td rowspan="4" class="slightproblem">failure to compiler, due removed <code>constexpr</code> on <code>uncaught_exception()</code>, user must use new <code>consteval_uncaught_exception()</code> function</td>
	</tr>
	<tr>
		<th><code>static constexpr int n = uncaught_exception()</code><div class="tinynote">(static constant)</div></th>
		<td class="na">n/a</td>
		<td colspan="2" class="expected">always <code>0</code><div class="tinynote">(constant evaluated during parsing)</div></td>
	</tr>
	<tr>
		<th><code>static_assert(uncaught_exception() == 0)</code></th>
		<td class="na">n/a</td>
		<td colspan="2" class="expected">always <code>true</code><div class="tinynote">(constant evaluated during parsing)</div></td>
	</tr>
	<tr>
		<th><code>auto obj = some_template&lt;uncaught_exception()&gt;{}</code></th>
		<td class="na">n/a</td>
		<td colspan="2" class="expected"><code>some_template&lt;0&gt;</code><div class="tinynote">(constant evaluated during parsing)</div></td>
	</tr>
</table>
<p>The code in table is intentionally visible, I don't expect users to write <code>constexpr int n = std::uncaught_exceptions()</code> but I do expect users to write code which is using the function deep inside the code, not visibly.</p>
</section><section data-related="constexpr-variables-are-not-a-problem"><h3><a href="#constexpr-variables-are-not-a-problem" id="constexpr-variables-are-not-a-problem"><code>constexpr</code> variables are not a problem</a></h3><p>It can be surprising to some users a local <code>constexpr</code> variables are not observing local evaluated context. But it's long established all <code>constexpr</code> variables are starting completely new evaluation without any evaluation context at site of declaration (it can use template variables, other <code>constexpr</code> variables, but not any local variable).</p>
<p>We need to keep <code>constexpr</code> marked functions in order to have the constexpr exception functionality fully working during constant evaluation (storing exceptions temporarily). Failing to do so would make a somehow arbitrary functionality of language again impossible to use and for users to go around, which I strongly prefer to avoid so.</p>
<p>In order to do we must make the potentially-constant initialization evaluation fail when it reaches these two function in question. It's a small surgical and mostly inobservable change which saves us from the silent code change when upgrading to 26. But also it's much better than just removing <code>constexpr</code>.</p>
</section></section><section data-related="proposed-solution"><h2><a href="#proposed-solution" id="proposed-solution">Proposed solution</a></h2><p><strong>Keep <code>constexpr</code> on both methods</strong> (<code>std::uncaught_exceptions()</code> and <code>std::current_exceptions</code>) and <strong>disallow them</strong> to be constant evaluated explicitly only <strong>in</strong> <a href="https://eel.is/c++draft/expr.const#8"><strong>potential-constant initialization</strong> [expr.const]</a>.</p>
<p>This is a minimal and implemented solution which doesn't limit functionality, but removes the break.</p>
</section><section data-related="possible-alternatives"><h2><a href="#possible-alternatives" id="possible-alternatives">Possible alternatives</a></h2><section data-related="much-larger-but-probably-breaking-solution"><h3><a href="#much-larger-but-probably-breaking-solution" id="much-larger-but-probably-breaking-solution">Much larger but probably breaking solution</a></h3><p>We could deprecate and later remove <code>potentially-constant</code> from language. This would make C++ much less surprising, but it will be probably a significant breaking change, altrough not really hard to fix (just make your <code>const</code> variables which suddenly failed to compile <code>constexpr</code> and you are good to go.)</p>
<p>Because of the large impact, this is not proposed.</p>
</section><section data-related="alternative-and-somehow-arbitrary-solution"><h3><a href="#alternative-and-somehow-arbitrary-solution" id="alternative-and-somehow-arbitrary-solution">Alternative and somehow arbitrary solution</a></h3><p>Alternative solution would be to disallow these two functions not just in potentially-constant initialization, but in any initialization. But that would make the functionalily severely limited and arbitrary for users and they would need to go around it, which would lead to more complicated code as <code>constexpr</code> variables are most common form of current meta-programming where it's used to precalculated values and tables.</p>
</section><section data-related="duplicate-functions-under-different-name-specially-for-constant-evaluation"><h3><a href="#duplicate-functions-under-different-name-specially-for-constant-evaluation" id="duplicate-functions-under-different-name-specially-for-constant-evaluation">Duplicate functions under different name specially for constant evaluation</a></h3><p>This is what P3820R0 proposes. Removing <code>constexpr</code> from <code>uncaught_exceptions</code> (not from <code>currrent_exception</code> as that one is not touched by the paper) and introduce a same function under similar name. I think that's a bad solution, because these functions are doing same thing, problem is interaction with language rules. Also I really don't think we should introduce same functionality which then would need to be <code>if consteval</code>-ed on every place where we want to use code for both runtime and constant evaluation. It will lead to code like this:</p>
<pre class="lang-cpp"><code>constexpr foo::~foo() {
	if consteval {
		/* const */ int num_of_exceptions = std::consteval_uncaught_exceptions();
		if (num_of_exceptions != num_of_exceptions_before) {
			// do something now we know there is an exception unrolling
		}
 	} else {
		const int num_of_exceptions = std::uncaught_exceptions();
		if (num_of_exceptions != num_of_exceptions_before) {
			// do something now we know there is an exception unrolling
		}
	}
}</code></pre>
<p>Previous example shows multiple problems, even if we do introduce new function, we can still can't use it in <code>const int</code> variable initialization, because it would create new constant evaluation and fold into constant. We must avoid <code>const int</code> there completely and we must teach it then.</p>
<p>I fully expect users to write something like following function:</p>
<pre class="lang-cpp"><code>
constexpr int my_uncaught_exceptions() {
	if consteval {
		// for some reason committee gave us this function, 
		// but I need this to initialize variable, so I can't use
		// if consteval there
		return std::consteval_uncaught_exceptions();
	} else {
		return std::uncaught_exceptions();
	}
}</code></pre>
<p>And later someone will use this function in <code>const int n = my_uncaught_exceptions</code> initialization and gets burned anyway. Therefore I argue against creating new variable, instead I propose taking proposal of this paper, which will make sure there is no breaking change.</p>
<section data-related="runtime-and-constexpr-exception-don%27t-have-different-semantic"><h4><a href="#runtime-and-constexpr-exception-don%27t-have-different-semantic" id="runtime-and-constexpr-exception-don%27t-have-different-semantic">Runtime and constexpr exception don't have different semantic</a></h4><p>There is no difference semantic in how runtime and constexpr exceptions behave. Hence providing different namely function to do the same just in different context will lead to confusion and previously describe problems. Difference is on the language level between local variables (<code>int n = ...</code>) and local constants (<code>constexpr int n = ...</code>) and when these are initialized and evaluated. With future support for compile time debug printing from <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2758r5.html">P2758</a> users will be able observe when is what code evaluated, and will understand that code evaluated in their compiler can't logically know about number of uncaught exceptions during runtime evaluation.</p>
</section><section data-related="one-function-name-is-needed"><h4><a href="#one-function-name-is-needed" id="one-function-name-is-needed">One function name is needed</a></h4><p>If we split functions to two, we are forcing users to write their own "one common function". If they want to continue support both types of their exceptions in pattern where number of unrolling exceptions is stored in a member variable for later comparison in destructor. This shows it's same functionality and it would burden users.</p>
</section></section></section><section data-related="positive-%2F-negative-comparison"><h2><a href="#positive-%2F-negative-comparison" id="positive-%2F-negative-comparison">Positive / negative comparison</a></h2><p>Following table compare positives and negatives of this paper and P3820.</p>
<table class="before-after positives-negatives">
	<tr><th class="table-section" colspan="2">C++26's status quo</th></tr>
	<tr><th class="positive">positives</th><th class="negative">negatives</th></tr>
	<tr>
		<td>
			<ul class="positive">
				<li>constexpr and runtime exceptions utility functions works same in both environments</li>
			</ul>
		</td><td>
			<ul class="negative">
				<li>silent breakage of code for "always use <code>const</code>" people<br/><code>const int n = std::uncaught_exceptions()</code> is constant evaluated during parsing</li>
				<li><code>constexpr int n = std::uncaught_exceptions()</code> can be confusing for some</li>
			</ul>
		</td>
	</tr>
	<tr><th class="table-section" colspan="2">P3818: "constant when: not within potentially-constant initialization"</th></tr>
	<tr><th class="positive">positives</th><th class="negative">negatives</th></tr>
	<tr>
		<td>
			<ul class="positive">
				<li>no breakage in existing code</li>
				<li>constexpr and runtime exceptions utility functions works <strong>mostly</strong> same in both environments</li>
				<li><code>const int n = std::uncaught_exceptions()</code> is runtime evaluated</li>
				<li>no change in user code to support <code>exception_ptr</code>'s functionality (only add constexpr)</li>
			</ul>
		</td><td>
			<ul class="negative">
				<li><code>constexpr int n = std::uncaught_exceptions()</code> can be confusing for some</li>
			</ul>
		</td>
	</tr>
	<tr><th class="table-section" colspan="2">P3820: split functions to runtime and consteval variant</th></tr>
	<tr><th class="positive">positives</th><th class="negative">negatives</th></tr>
	<tr>
		<td>
			<ul class="positive">
				<li>no breakage in existing code</li>
				<li><code>const int n = std::uncaught_exceptions()</code> is runtime evaluated</li>
				<li><code>constexpr int n = std::uncaught_exceptions()</code> fails to compile</li>
			</ul>
		</td><td>
			<ul class="negative">
				<li>user code needs to accomodate duality of functions and use <code>if consteval</code> to select right function</li>
				<li><code>const int n = std::consteval_uncaught_exceptions()</code> is still problematic</li>
				<li><code>constexpr int n = std::consteval_uncaught_exceptions()</code> still can confuse some</li>
			</ul>
		</td>
	</tr>
	<tr><th class="table-section" colspan="2">P3820: <a href="https://lists.isocpp.org/lib-ext/2025/09/30623.php">"constant when there is currently handled exception"</a></th></tr>
	<tr><th class="positive">positives</th><th class="negative">negatives</th></tr>
	<tr>
		<td>
			<ul class="positive">
				<li><code>const bool e = std::current_exception() != nullptr</code> is runtime evaluated</li>
				<li><code>const bool e = [] { try { ... } catch (...) { return std::current_exception() != nullptr; }}</code> is constant evaluated</li>
				<li><code>constexpr int n = std::uncaught_exceptions()</code> won't compile so it won't confuse anyone</li>
			</ul>
		</td><td>
			<ul class="negative">
				<li><strong>changes semantic of functions</strong> and limits usability of using these to detect non-exceptional state</li>
				<li><code>std::current_exception() != nullptr</code> as detection if code is run inside exception handler will fail to <strong>constant evaluate</strong> outside exception handler, without workaround.</li>
				<li><code>const int n = ...</code> complex code with internal <code>std::uncaught_exception</code> can still be constant evaluated and it won't count runtime exception, which is <strong>still a breaking change</strong></li>
			</ul>
		</td>
	</tr>
	<tr><th class="table-section" colspan="2"><a href="https://lists.isocpp.org/lib-ext/2025/09/30629.php">Ville's nuke constexpr</a> from <code>uncaught_exceptions</code> and <code>current_exception</code> and add it later (in some form)</th></tr>
	<tr><th class="positive">positives</th><th class="negative">negatives</th></tr>
	<tr>
		<td>
			<ul class="positive">
				<li><code>const int n = std::uncaught_exceptions()</code> is runtime evaluated</li>
				<li><code>constexpr int n = std::uncaught_exceptions()</code> fails to compile, no one is getting confused</li>
			</ul>
		</td><td>
			<ul class="negative">
				<li>limiting to basic functionality of throwing / catching / rethrowing</li>
				<li><code>std::uncaught_exceptions()</code> and <code>std::current_exception()</code> doesn't work in constant evaluated code at all</li>
				<li>inability to temporary store exception and decide if it should be rethrow later, thus forcing existing code which could be easily upgraded to <code>constexpr</code> to invent workarounds to missing functionality</li>
				<li>unless we change language rules significantly for <code>constexpr</code> local variables <strong>the confusion will still be there, just later</strong></li>
			</ul>
		</td>
	</tr>
</table>
</section><section data-related="implementation-experience"><h2><a href="#implementation-experience" id="implementation-experience">Implementation experience</a></h2><p>The proposed solution was implemented in <a href="https://github.com/hanickadot/llvm-project/commit/03fec7d6fc43d88e2d406201392c748d28f34357">my clang prototype of <code>constexpr</code> exception</a> for <code>std::uncaught_exceptions()</code>, and you can experiment with <a href="https://compiler-explorer.com/z/Gsa3r74hr">it at the compiler explorer</a>.</p>
<p>The change itself was add to clang know in its evaluation state the evaluation is potentially-constant. And then the builtins implementing the exception handling function to detect it and fail to evaluate in that case.</p>
<p>There was a minor problem around initialization of a local <code>constexpr</code> variables, which for some reason are not cached, and are reinitialized as part of evaluation with same evaluation state. This lead to a funny error when following code didn't compile (reported to me by Ville):</p>
<pre class="lang-cpp"><code>const int n = []{
	constexpr int x = std::uncaught_exceptions(); // initialized twice, once during parsing 
																								// and second time during evaluation of the lambda
	return x;
}();</code></pre>
<p>Clang when it sees initialization of a local <code>constexpr</code> variable it evaluates its initialization again, even when the value could be cached. This second evaluation in my first version was in potentially-constant state, and then the exception support function didn't work silently. Fix was changing the state of evaluation for initializers of local <code>constexpr</code> variables, and restoring previous one when the initialization is finished.</p> 
</section><section data-related="wording"><h2><a href="#wording" id="wording">Wording</a></h2><p>Change is add a new <em>Constant when</em> to <code>std::uncaught_exceptions()</code> and <code>std::current_exception()</code>.</p>

<!-- propagation.html (wording) -->
<div class="wording">
<h2 ><a class='secnum' style='min-width:65pt'>17.9</a> Exception handling <a class='abbr_ref' href='support.exception#propagation'>[support.exception]</a></h2><h3 ><a class='secnum' style='min-width:80pt'>17.9.7</a> Exception propagation <a class='abbr_ref'>[propagation]</a></h3><div class='texpara'><div id='lib:exception_ptr'><div class='itemdecl'><div class='marginalizedparent'><a class='itemDeclLink' href='#lib:exception_ptr'>🔗</a></div><code class='itemdeclcode'><span class='keyword'>using</span> exception_ptr <span class='operator'>=</span> <i ><span class='texttt'>unspecified</span></i>;
</code></div></div></div><div class='para' id='1'><div class='marginalizedparent'><a class='marginalized' href='#1'>1</a></div><div class='itemdescr'><div class='sourceLinkParent'><a class='sourceLink' href='http://github.com/Eelis/draft/tree/013e3cf53bf4977caaed57274bbd0d28b4914bef/source/support.tex#L4121'>#</a></div><div class='texpara'><div id='1.sentence-1' class='sentence'>The type <span class='texttt'>exception_<span class='shy'></span>ptr</span> can be used to refer to an exception object<a class='hidden_link' href='#1.sentence-1'>.</a></div></div></div></div><div class='para' id='2'><div class='marginalizedparent'><a class='marginalized' href='#2'>2</a></div><div class='itemdescr'><div class='sourceLinkParent'><a class='sourceLink' href='http://github.com/Eelis/draft/tree/013e3cf53bf4977caaed57274bbd0d28b4914bef/source/support.tex#L4124'>#</a></div><div class='texpara'><div id='2.sentence-1' class='sentence'><span class='texttt'>exception_<span class='shy'></span>ptr</span> meets the requirements of
<a href='nullablepointer.requirements#:Cpp17NullablePointer' title='16.4.4.4&emsp;Cpp17NullablePointer requirements&emsp;[nullablepointer.requirements]'><i >Cpp17NullablePointer</i></a> (Table <a href='nullablepointer.requirements#tab:cpp17.nullablepointer' title='Table 36: Cpp17NullablePointer requirements'>36</a>)<a class='hidden_link' href='#2.sentence-1'>.</a></div></div></div></div><div class='para' id='3'><div class='marginalizedparent'><a class='marginalized' href='#3'>3</a></div><div class='itemdescr'><div class='sourceLinkParent'><a class='sourceLink' href='http://github.com/Eelis/draft/tree/013e3cf53bf4977caaed57274bbd0d28b4914bef/source/support.tex#L4128'>#</a></div><div class='texpara'><div id='3.sentence-1' class='sentence'>Two non-null values of type <span class='texttt'>exception_<span class='shy'></span>ptr</span> are equivalent and compare equal if and
only if they refer to the same exception<a class='hidden_link' href='#3.sentence-1'>.</a></div></div></div></div><div class='para' id='4'><div class='marginalizedparent'><a class='marginalized' href='#4'>4</a></div><div class='itemdescr'><div class='sourceLinkParent'><a class='sourceLink' href='http://github.com/Eelis/draft/tree/013e3cf53bf4977caaed57274bbd0d28b4914bef/source/support.tex#L4132'>#</a></div><div class='texpara'><div id='4.sentence-1' class='sentence'>The default constructor of <span class='texttt'>exception_<span class='shy'></span>ptr</span> produces the null value of the
type<a class='hidden_link' href='#4.sentence-1'>.</a></div></div></div></div><div class='para' id='5'><div class='marginalizedparent'><a class='marginalized' href='#5'>5</a></div><div class='itemdescr'><div class='sourceLinkParent'><a class='sourceLink' href='http://github.com/Eelis/draft/tree/013e3cf53bf4977caaed57274bbd0d28b4914bef/source/support.tex#L4136'>#</a></div><div class='texpara'><div id='5.sentence-1' class='sentence'><span class='texttt'>exception_<span class='shy'></span>ptr</span> shall not be implicitly convertible to any arithmetic,
enumeration, or pointer type<a class='hidden_link' href='#5.sentence-1'>.</a></div></div></div></div><div class='para nonNormativeOnly' id='6'><div class='marginalizedparent'><a class='marginalized' href='#6'>6</a></div><div class='itemdescr'><div class='sourceLinkParent'><a class='sourceLink' href='http://github.com/Eelis/draft/tree/013e3cf53bf4977caaed57274bbd0d28b4914bef/source/support.tex#L4140'>#</a></div><div class='texpara'><div id='note-1' class='note'><div class='texpara'>[<i>Note&nbsp;<a href='#note-1'>1</a></i>:&ensp;<div id='6.sentence-1' class='sentence'>An implementation can use a reference-counted smart
pointer as <span class='texttt'>exception_<span class='shy'></span>ptr</span><a class='hidden_link' href='#6.sentence-1'>.</a></div> —&nbsp;<i>end note</i>]</div></div></div></div></div><div class='para' id='7'><div class='marginalizedparent'><a class='marginalized' href='#7'>7</a></div><div class='itemdescr'><div class='sourceLinkParent'><a class='sourceLink' href='http://github.com/Eelis/draft/tree/013e3cf53bf4977caaed57274bbd0d28b4914bef/source/support.tex#L4146'>#</a></div><div class='texpara'><div id='7.sentence-1' class='sentence'>For purposes of determining the presence of a data race, operations on
<span class='texttt'>exception_<span class='shy'></span>ptr</span> objects shall access and modify only the
<span class='texttt'>exception_<span class='shy'></span>ptr</span> objects themselves and not the exceptions they refer to<a class='hidden_link' href='#7.sentence-1'>.</a></div> <div id='7.sentence-2' class='sentence'>Use of <span class='texttt'>rethrow_<span class='shy'></span>exception</span> or <span class='texttt'>exception_<span class='shy'></span>ptr_<span class='shy'></span>cast</span>
on <span class='texttt'>exception_<span class='shy'></span>ptr</span> objects that refer to
the same exception object shall not introduce a data race<a class='hidden_link' href='#7.sentence-2'>.</a></div> <div id='note-2' class='note'><div class='texpara'>[<i>Note&nbsp;<a href='#note-2'>2</a></i>:&ensp;<div id='7.sentence-3' class='sentence'>If
<span class='texttt'>rethrow_<span class='shy'></span>exception</span> rethrows the same exception object (rather than a copy),
concurrent access to that rethrown exception object can introduce a data race<a class='hidden_link' href='#7.sentence-3'>.</a></div> <div id='7.sentence-4' class='sentence'>Changes in the number of <span class='texttt'>exception_<span class='shy'></span>ptr</span> objects that refer to a
particular exception do not introduce a data race<a class='hidden_link' href='#7.sentence-4'>.</a></div> —&nbsp;<i>end note</i>]</div></div></div></div></div>
<div class='para' id='8'><div class='marginalizedparent'><a class='marginalized' href='#8'>8</a></div><div class='itemdescr'><div class='sourceLinkParent'><a class='sourceLink' href='http://github.com/Eelis/draft/tree/013e3cf53bf4977caaed57274bbd0d28b4914bef/source/support.tex#L4161'>#</a></div><div class='texpara'><div id='8.sentence-1' class='sentence'>All member functions are marked <span class='texttt'><span class='keyword'>constexpr</span></span><a class='hidden_link' href='#8.sentence-1'>.</a></div></div></div></div><div class='texpara'><div id='lib:current_exception'><div class='itemdecl'><div class='marginalizedparent'><a class='itemDeclLink' href='#lib:current_exception'>🔗</a></div><code class='itemdeclcode'><span class='keyword'>constexpr</span> exception_ptr current_exception<span class='parenthesis'>(</span><span class='parenthesis'>)</span> <span class='keyword'>noexcept</span>;
</code></div></div></div>

<div class="para added" id="current_exception"><div class="marginalizedparent"><a class="marginalized" href="#current_exception">?</a></div><div class="itemdescr"><div class="sourceLinkParent"></div><div class="texpara"><div id="current_exception.sentence-1" class="sentence"><i>Constant When</i>: not evaluated within potentially-constant [expr.const] initialization.</div></div></div></div>

<div class='para' id='9'><div class='marginalizedparent'><a class='marginalized' href='#9'>9</a></div><div class='itemdescr'><div class='sourceLinkParent'><a class='sourceLink' href='http://github.com/Eelis/draft/tree/013e3cf53bf4977caaed57274bbd0d28b4914bef/source/support.tex#L4171'>#</a></div><div class='texpara'><div id='9.sentence-1' class='sentence'><i >Returns</i>: An <span class='texttt'>exception_<span class='shy'></span>ptr</span> object that refers to the
<a href='except.handle#def:exception_handling,currently_handled_exception' title='14.4&emsp;Handling an exception&emsp;[except.handle]'>currently handled exception</a>
or a copy of the currently
handled exception, or a null <span class='texttt'>exception_<span class='shy'></span>ptr</span> object if no exception is being
handled<a class='hidden_link' href='#9.sentence-1'>.</a></div> <div id='9.sentence-2' class='sentence'>The referenced object shall remain valid at least as long as there is an
<span class='texttt'>exception_<span class='shy'></span>ptr</span> object that refers to it<a class='hidden_link' href='#9.sentence-2'>.</a></div> <div id='9.sentence-3' class='sentence'>If the function needs to allocate memory and the attempt fails, it returns an
<span class='texttt'>exception_<span class='shy'></span>ptr</span> object that refers to an instance of <span class='texttt'>bad_<span class='shy'></span>alloc</span><a class='hidden_link' href='#9.sentence-3'>.</a></div> <div id='9.sentence-4' class='sentence'>It is unspecified whether the return values of two successive calls to
<span class='texttt'>current_<span class='shy'></span>exception</span> refer to the same exception object<a class='hidden_link' href='#9.sentence-4'>.</a></div> <div id='note-3' class='note'><div class='texpara'>[<i>Note&nbsp;<a href='#note-3'>3</a></i>:&ensp;<div id='9.sentence-5' class='sentence'>That is, it is unspecified whether <span class='texttt'>current_<span class='shy'></span>exception</span>
creates a new copy each time it is called<a class='hidden_link' href='#9.sentence-5'>.</a></div> —&nbsp;<i>end note</i>]</div></div> <div id='9.sentence-6' class='sentence'>
If the attempt to copy the current exception object throws an exception, the function
returns an <span class='texttt'>exception_<span class='shy'></span>ptr</span> object that refers to the thrown exception or,
if this is not possible, to an instance of <span class='texttt'>bad_<span class='shy'></span>exception</span><a class='hidden_link' href='#9.sentence-6'>.</a></div> <div id='note-4' class='note'><div class='texpara'>[<i>Note&nbsp;<a href='#note-4'>4</a></i>:&ensp;<div id='9.sentence-7' class='sentence'>The copy constructor of the thrown exception can also fail,
so the implementation can substitute a <span class='texttt'>bad_<span class='shy'></span>exception</span> object
to avoid infinite recursion<a class='hidden_link' href='#9.sentence-7'>.</a></div> —&nbsp;<i>end note</i>]</div></div></div></div></div><div class='texpara'><div id='lib:rethrow_exception'><div class='itemdecl'><div class='marginalizedparent'><a class='itemDeclLink' href='#lib:rethrow_exception'>🔗</a></div><code class='itemdeclcode'><span class='squarebracket'>[</span><span class='squarebracket'>[</span>noreturn<span class='squarebracket'>]</span><span class='squarebracket'>]</span> <span class='keyword'>constexpr</span> <span class='keyword'>void</span> rethrow_exception<span class='parenthesis'>(</span>exception_ptr p<span class='parenthesis'>)</span>;
</code></div></div></div><div class='para' id='10'><div class='marginalizedparent'><a class='marginalized' href='#10'>10</a></div><div class='itemdescr'><div class='sourceLinkParent'><a class='sourceLink' href='http://github.com/Eelis/draft/tree/013e3cf53bf4977caaed57274bbd0d28b4914bef/source/support.tex#L4203'>#</a></div><div class='texpara'><div id='10.sentence-1' class='sentence'><i >Preconditions</i>: <span class='texttt'>p</span> is not a null pointer<a class='hidden_link' href='#10.sentence-1'>.</a></div></div></div></div><div class='para' id='11'><div class='marginalizedparent'><a class='marginalized' href='#11'>11</a></div><div class='itemdescr'><div class='sourceLinkParent'><a class='sourceLink' href='http://github.com/Eelis/draft/tree/013e3cf53bf4977caaed57274bbd0d28b4914bef/source/support.tex#L4207'>#</a></div><div class='texpara'><div id='11.sentence-1' class='sentence'><i >Effects</i>: Let <span class='math'><span class='mathalpha'>u</span></span> be the exception object to which <span class='texttt'>p</span> refers, or
a copy of that exception object<a class='hidden_link' href='#11.sentence-1'>.</a></div> <div id='11.sentence-2' class='sentence'>It is unspecified whether a copy is made, and
memory for the copy is allocated in an unspecified way<a class='hidden_link' href='#11.sentence-2'>.</a></div> <ul class='itemize'><li id='11.1'><div class='marginalizedparent' style='left:-39mm'><a class='marginalized' href='#11.1'>(11.1)</a></div>If allocating memory to form <span class='math'><span class='mathalpha'>u</span></span> fails,
throws an instance of <span class='texttt'>bad_<span class='shy'></span>alloc</span>;</li><li id='11.2'><div class='marginalizedparent' style='left:-39mm'><a class='marginalized' href='#11.2'>(11.2)</a></div>otherwise, if copying the exception to which <span class='texttt'>p</span> refers
to form <span class='math'><span class='mathalpha'>u</span></span> throws an exception, throws that exception;</li><li id='11.3'><div class='marginalizedparent' style='left:-39mm'><a class='marginalized' href='#11.3'>(11.3)</a></div>otherwise, throws <span class='math'><span class='mathalpha'>u</span></span>.</li></ul></div></div></div><div class='texpara'><div id='lib:make_exception_ptr'><div class='itemdecl'><div class='marginalizedparent'><a class='itemDeclLink' href='#lib:make_exception_ptr'>🔗</a></div><code class='itemdeclcode'><span class='keyword'>template</span><span class='anglebracket'>&lt;</span><span class='keyword'>class</span> E<span class='anglebracket'>&gt;</span> <span class='keyword'>constexpr</span> exception_ptr make_exception_ptr<span class='parenthesis'>(</span>E e<span class='parenthesis'>)</span> <span class='keyword'>noexcept</span>;
</code></div></div></div><div class='para' id='12'><div class='marginalizedparent'><a class='marginalized' href='#12'>12</a></div><div class='itemdescr'><div class='sourceLinkParent'><a class='sourceLink' href='http://github.com/Eelis/draft/tree/013e3cf53bf4977caaed57274bbd0d28b4914bef/source/support.tex#L4231'>#</a></div><div class='texpara'><div id='12.sentence-1' class='sentence'><i >Effects</i>: Creates an <span class='texttt'>exception_<span class='shy'></span>ptr</span> object that refers to a copy of <span class='texttt'>e</span>, as if:
<span class='codeblock'><span class='keyword'>try</span> <span class='curlybracket'>{</span>
  <span class='keyword'>throw</span> e;
<span class='curlybracket'>}</span> <span class='keyword'>catch</span><span class='parenthesis'>(</span><span class='operator'>.</span><span class='operator'>.</span><span class='operator'>.</span><span class='parenthesis'>)</span> <span class='curlybracket'>{</span>
  <span class='keyword'>return</span> current_exception<span class='parenthesis'>(</span><span class='parenthesis'>)</span>;
<span class='curlybracket'>}</span>
</span></div></div></div></div><div class='para nonNormativeOnly' id='13'><div class='marginalizedparent'><a class='marginalized' href='#13'>13</a></div><div class='itemdescr'><div class='sourceLinkParent'><a class='sourceLink' href='http://github.com/Eelis/draft/tree/013e3cf53bf4977caaed57274bbd0d28b4914bef/source/support.tex#L4242'>#</a></div><div class='texpara'><div id='note-5' class='note'><div class='texpara'>[<i>Note&nbsp;<a href='#note-5'>5</a></i>:&ensp;<div id='13.sentence-1' class='sentence'>This function is provided for convenience and
efficiency reasons<a class='hidden_link' href='#13.sentence-1'>.</a></div> —&nbsp;<i>end note</i>]</div></div></div></div></div><div class='texpara'><div id='lib:exception_ptr_cast'><div class='itemdecl'><div class='marginalizedparent'><a class='itemDeclLink' href='#lib:exception_ptr_cast'>🔗</a></div><code class='itemdeclcode'><span class='keyword'>template</span><span class='anglebracket'>&lt;</span><span class='keyword'>class</span> E<span class='anglebracket'>&gt;</span> <span class='keyword'>constexpr</span> <span class='keyword'>const</span> E<span class='operator'>*</span> exception_ptr_cast<span class='parenthesis'>(</span><span class='keyword'>const</span> exception_ptr<span class='operator'>&amp;</span> p<span class='parenthesis'>)</span> <span class='keyword'>noexcept</span>;
</code></div></div></div><div class='para' id='14'><div class='marginalizedparent'><a class='marginalized' href='#14'>14</a></div><div class='itemdescr'><div class='sourceLinkParent'><a class='sourceLink' href='http://github.com/Eelis/draft/tree/013e3cf53bf4977caaed57274bbd0d28b4914bef/source/support.tex#L4255'>#</a></div><div class='texpara'><div id='14.sentence-1' class='sentence'><i >Mandates</i>: <span class='texttt'>E</span> is a cv-unqualified complete object type<a class='hidden_link' href='#14.sentence-1'>.</a></div> <div id='14.sentence-2' class='sentence'><span class='texttt'>E</span> is not an array type<a class='hidden_link' href='#14.sentence-2'>.</a></div> <div id='14.sentence-3' class='sentence'><span class='texttt'>E</span> is not a pointer or pointer-to-member type<a class='hidden_link' href='#14.sentence-3'>.</a></div> <div id='note-6' class='note'><div class='texpara'>[<i>Note&nbsp;<a href='#note-6'>6</a></i>:&ensp;<div id='14.sentence-4' class='sentence'>When <span class='texttt'>E</span> is a pointer or pointer-to-member type,
a handler of type <span class='texttt'><span class='keyword'>const</span> E<span class='operator'>&amp;</span></span> can match
without binding to the exception object itself<a class='hidden_link' href='#14.sentence-4'>.</a></div> —&nbsp;<i>end note</i>]</div></div></div></div></div><div class='para' id='15'><div class='marginalizedparent'><a class='marginalized' href='#15'>15</a></div><div class='itemdescr'><div class='sourceLinkParent'><a class='sourceLink' href='http://github.com/Eelis/draft/tree/013e3cf53bf4977caaed57274bbd0d28b4914bef/source/support.tex#L4266'>#</a></div><div class='texpara'><div id='15.sentence-1' class='sentence'><i >Returns</i>: A pointer to the exception object referred to by <span class='texttt'>p</span>,
if <span class='texttt'>p</span> is not null and
a handler of type <span class='texttt'><span class='keyword'>const</span> E<span class='operator'>&amp;</span></span>
would be a match (<a href='except.handle' title='14.4&emsp;Handling an exception'>[except.<span class='shy'></span>handle]</a>) for that exception object<a class='hidden_link' href='#15.sentence-1'>.</a></div> <div id='15.sentence-2' class='sentence'>Otherwise, <span class='texttt'><span class='literal'>nullptr</span></span><a class='hidden_link' href='#15.sentence-2'>.</a></div></div></div></div>
</div>

<!-- uncaught.exceptions.html (wording) -->
<div class="wording">
<h3 ><a class='secnum' style='min-width:80pt'>17.9.6</a> <span class='texttt'>uncaught_<span class='shy'></span>exceptions</span> <a class='abbr_ref'>[uncaught.exceptions]</a></h3><div class='texpara'><div id='lib:uncaught_exceptions'><div class='itemdecl'><div class='marginalizedparent'><a class='itemDeclLink' href='#lib:uncaught_exceptions'>🔗</a></div><code class='itemdeclcode'><span class='keyword'>constexpr</span> <span class='keyword'>int</span> uncaught_exceptions<span class='parenthesis'>(</span><span class='parenthesis'>)</span> <span class='keyword'>noexcept</span>;
</code></div></div></div>

<div class="para added" id="uncaught_exceptions"><div class="marginalizedparent"><a class="marginalized" href="#uncaught_exceptions">?</a></div><div class="itemdescr"><div class="sourceLinkParent"></div><div class="texpara"><div id="uncaught_exceptions.sentence-1" class="sentence"><i>Constant When</i>: not evaluated within potentially-constant [expr.const] initialization.</div></div></div></div>

<div class='para' id='1'><div class='marginalizedparent'><a class='marginalized' href='#1'>1</a></div><div class='itemdescr'><div class='sourceLinkParent'><a class='sourceLink' href='http://github.com/Eelis/draft/tree/013e3cf53bf4977caaed57274bbd0d28b4914bef/source/support.tex#L4102'>#</a></div><div class='texpara'><div id='1.sentence-1' class='sentence'><i >Returns</i>: The number of uncaught exceptions (<a href='except.throw' title='14.2&emsp;Throwing an exception'>[except.<span class='shy'></span>throw]</a>) in the current thread<a class='hidden_link' href='#1.sentence-1'>.</a></div></div></div></div><div class='para' id='2'><div class='marginalizedparent'><a class='marginalized' href='#2'>2</a></div><div class='itemdescr'><div class='sourceLinkParent'><a class='sourceLink' href='http://github.com/Eelis/draft/tree/013e3cf53bf4977caaed57274bbd0d28b4914bef/source/support.tex#L4106'>#</a></div><div class='texpara'><div id='2.sentence-1' class='sentence'><i >Remarks</i>: When <span class='texttt'>uncaught_<span class='shy'></span>exceptions<span class='parenthesis'>(</span><span class='parenthesis'>)</span> <span class='anglebracket'>&gt;</span> <span class='literal'>0</span></span>,
throwing an exception can result in a call of the function
<a href='except.terminate' title='14.6.2&emsp;The std&#x200b;::&#x200b;terminate function&emsp;[except.terminate]'><span class='texttt'>std&#x200b;::&#x200b;terminate</span></a><a class='hidden_link' href='#2.sentence-1'>.</a></div></div></div></div>
</div>
<section data-related="feature-test-macros"><h3><a href="#feature-test-macros" id="feature-test-macros">Feature test macros</a></h3><p>No feature test macro added as this is a bugfix. I'm happy to add if LEWG asks.</p></section></section></article>

<script>
	const all_changes = document.querySelectorAll(".wording .added, .wording .removed, .wording .change");
	let position = null;
	
	function set_hash(id) {
		const elem = document.getElementById(id);
		if (elem) {
			elem.id = `${id}-tmp`;
		}
		window.location.hash = id;
		if (elem) {
			elem.id = id;
		}
		return elem;
	}
	
	function disable_highlight_on_previous() {
		if (position != null) {
			//window.location.href.match(/([^#]++)#.++/);
			//window.location.
			set_hash("no-change-selected");
			// hljs is messing with me
			document.getElementById(all_changes[position].id).classList.remove("selected-current");
		}
	}
	
	function scroll_into_view_if_needed(el, scroll_there = true) {
		if (scroll_there) {
			if (!element_is_visible_in_viewport(el)) {
				el.scrollIntoView({behavior: "smooth", block: "center", inline: "center" });
			} else {
				console.log("doesn't need to scroll?!");
			}
		}
		
		return el;
	}
	
	function highlight_index(i = null, scroll_there = true) {
		if (position !== null && i === position) {
			console.log(`disabling overlay: ${i} === ${position}`);
			disable_highlight_on_previous();
			let overlay = document.querySelector("#overlay");
			overlay.remove();
			position = null;
			return;
		}
		
		if (i !== null) {
			disable_highlight_on_previous();
			position = i;
		}
		
		
		let overlay = document.querySelector("#overlay");
		if (!overlay) {
			let overlay = document.createElement("div");
			overlay.id = "overlay";
			document.querySelector("body").appendChild(overlay);
		}
		
		set_hash(`change-${position}`);
		
		
		const current = document.getElementById(all_changes[position].id);
		current.classList.add("selected-current");
		const scroll_anchor = current.querySelector(".scroll-here")
		
		if (scroll_anchor) {
			return scroll_into_view_if_needed(scroll_anchor, scroll_there);
		}
		
		return scroll_into_view_if_needed(current, scroll_there);
	}
	
	function element_is_visible_in_viewport(el) {
	  const { top, left, bottom, right } = el.getBoundingClientRect();
	  const { innerHeight, innerWidth } = window;
		const zoneHeight = innerHeight/5;
		const zoneWidth = innerWidth/5;
		
	  return top >= zoneHeight && bottom <= (innerHeight-zoneHeight);
	};
	
	all_changes.forEach((e, i) => {
		e.style.cursor = "pointer";
		e.id = `change-${i}-real`;
		e.onclick = (ev) => {
			current = highlight_index(i);
			
			ev.alreadyProcessed = true;
		}
	});
	
	document.body.onclick = (ev) => {
		if (position !== null && !ev.alreadyProcessed) {
			highlight_index(position, false);
		}
	};
	
	function next_or_previous_change(step) {
		disable_highlight_on_previous();

		const first = 0;
		const last =  all_changes.length - 1;
		
		if (position === null) {
			if (step < 0) {
				position = last;
			} else if (step > 0) {
				position = first;
			}
		} else {
			position += step;
		}
		
		if (position >= all_changes.length) {
			position = first;
		} else if (position < 0) {
			position = last;
		}
		highlight_index();
	}
	
	
	set_hash(window.location.hash);
	
	window.addEventListener("load", function () {
		const active_change = window.location.hash.match(/change-(?<id>[0-9]+)/);
		if (active_change) {
			const el = highlight_index(Number(active_change[1]), false);
			//console.log("scrolling there!");
			el.scrollIntoView({behavior: "instant", block: "center", inline: "center" });
		}
		window.setTimeout(() => {
			document.querySelector("html").style["scroll-behavior"] = "smooth";
		}, 500);
	});
	
	window.addEventListener("keydown", function (e) {
		if ((e.altKey) && e.code == "ArrowRight") {
			next_or_previous_change(1);
		} else if (position != null && e.code == "ArrowRight") {
			next_or_previous_change(1);
		} else if ((e.altKey) && e.code == "ArrowLeft") {
			next_or_previous_change(-1);
		} else if (position != null && e.code == "ArrowLeft") {
			next_or_previous_change(-1);
		} else if ((e.altKey) && e.code == "KeyF") {
			document.documentElement.requestFullscreen();
		}
	});
	
	const hide_button = document.getElementById("hide");
	hide_button.onclick = (e) => {
		if (hide_button.classList.contains("enabled")) {
			hide_button.classList.remove("enabled");
		} else {
			hide_button.classList.add("enabled");
		}
	};
	
	function navigate(e, elem) {
		//e.preventDefault();
		//return true;
		const target = elem.getAttribute("href");
		history.pushState(null, null, target);
		const target_element = document.getElementById(target.substr(1));
	}
	
	window.setTimeout(() => document.querySelector("article").classList.add("transitionable"), 500);
	
	document.querySelectorAll("a[href^=\"#\"]").forEach((elem) => { elem.onclick = (e) => navigate(e, elem); } );
	
	function send_email(link) {
		const [prefix, encoded] = link.getAttribute("href").split("#",2);
		window.location = "mailto:"+window.atob(encoded);
		return false;
	}
	
	document.querySelectorAll("a").forEach(link => {
		const relative = link.getAttribute("href");
		if (relative && !relative.startsWith("#") && !relative.startsWith("http://") && !relative.startsWith("https://")) {
			link.href= `https://eel.is/c++draft/${relative}`;
		}
		
	})
	
	const current_url = new URL(window.location.href);
	
	const replace_url_with_current_setting = () => {
    window.history.replaceState({path:current_url.toString()},'', current_url.toString());
	};
	
	const update_poll_dependencies = (poll_id, value) => {
		const selection = document.querySelectorAll(`span.poll_value[x-poll-id="${poll_id}"]`);
		selection.forEach((el) => {
			el.innerText = value;
		});
		
		const discardable = document.querySelectorAll(`.poll_condition[x-poll-id="${poll_id}"]`);
		discardable.forEach((el) => {
			if (el.getAttribute("x-poll-value") == value) {
				el.classList.remove("discard");
			} else {
				el.classList.add("discard");
			}
		});
	}

	const change_poll_dependencies = (poll_id, object) => {
		console.log(`changing poll ${poll_id} dependecies to value ${object.value}`);
		const value = object.value;
		update_poll_dependencies(poll_id, value);
		current_url.searchParams.set(`poll_${poll_id}`, value);
		replace_url_with_current_setting();
	};
	
	
	for (const [key, value] of current_url.searchParams) {
		const m = key.match(/poll_([a-z\-]+)/);
		console.log(`search params = ${key}=${value}`);
		const name = m?.[1];
		if (name) {
			const selection = document.querySelector(`input[type="radio"][name="${name}"][value="${value}"]:not([disabled])`);
			if (selection) {
				update_poll_dependencies(name, value);
				selection.checked = true;
			} else {
				console.error(`poll query variable! ${name}=${value}`);
			}
		}
	}
</script>

<!-- init-hljs.js -->
<script>
// trim must be first, before merge
hljs.addPlugin(trimNicely);
hljs.addPlugin(mergeHTMLPlugin);
hljs.highlightAll();

</script>
</body>
</html>
