<!DOCTYPE html>
<html>
<head>
  <meta charset=UTF-8 /><meta name=viewport content="width=device-width, initial-scale=1"/><link rel=preconnent href=https://fonts%2egoogleapis%2ecom />
  <link rel=preconnent href=https://fonts%2egstatic%2ecom crossorigin/>
  <link rel=stylesheet href="https://fonts%2egoogleapis%2ecom/css2?family=Fira+Code:wght@300%2e%2e700&family=Noto+Sans:ital,wght@0,100%2e%2e900;1,100%2e%2e900&family=Noto+Serif:ital,wght@0,100%2e%2e900;1,100%2e%2e900&display=swap"/>
  <style>
html {
    --sans-serif-family: "Noto Sans", sans-serif;
    --serif-family: "Noto Serif", serif;
    --monospace-family: "Fira Code", monospace;

    --light-background-color: white;
    --light-deep-background-color: #fafafa;
    --light-text-color: black;
    --light-border-color: #aaa;
    --light-table-border-color: #777;
    --light-del-color: #be1621;
    --light-del-background-color: #fbe6e8;
    --light-ins-color: #17752d;
    --light-ins-background-color: #e4faea;
    --light-para-color: rgb(10, 73, 136);
    --light-a-color: rgb(10, 73, 136);
    --light-a-visited-color: rgb(44, 10, 136);
    --light-a-hover-color: rgb(15, 93, 170);
    --light-mark-color: black;
    --light-mark-background-color: #ffff85;
    --light-abstract-border-color: #707070;
    --light-abstract-background-color: #f0f0f0;
    --light-abstract-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="%23707070"><path d="M660-160h40v-160h-40v160Zm20-200q8 0 14-6t6-14q0-8-6-14t-14-6q-8 0-14 6t-6 14q0 8 6 14t14 6ZM200-800v640-640 200-200Zm80 400h147q11-23 25.5-43t32.5-37H280v80Zm0 160h123q-3-20-3-40t3-40H280v80ZM200-80q-33 0-56.5-23.5T120-160v-640q0-33 23.5-56.5T200-880h320l240 240v92q-19-6-39-9t-41-3v-40H480v-200H200v640h227q11 23 25.5 43T485-80H200Zm480-400q83 0 141.5 58.5T880-280q0 83-58.5 141.5T680-80q-83 0-141.5-58.5T480-280q0-83 58.5-141.5T680-480Z"/></svg>');
    --light-blockquote-border-color: #707070;
    --light-blockquote-background-color: #f0f0f0;
    --light-blockquote-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="%23707070"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M7.17 17c.51 0 .98-.29 1.2-.74l1.42-2.84c.14-.28.21-.58.21-.89V8c0-.55-.45-1-1-1H5c-.55 0-1 .45-1 1v4c0 .55.45 1 1 1h2l-1.03 2.06c-.45.89.2 1.94 1.2 1.94zm10 0c.51 0 .98-.29 1.2-.74l1.42-2.84c.14-.28.21-.58.21-.89V8c0-.55-.45-1-1-1h-4c-.55 0-1 .45-1 1v4c0 .55.45 1 1 1h2l-1.03 2.06c-.45.89.2 1.94 1.2 1.94z"/></svg>');
    --light-bug-block-border-color: #9f7b5d;
    --light-bug-block-background-color: #f0e2d9;
    --light-bug-block-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="%239f7b5d"><path d="M480-120q-64 0-114.5-33T283-240l-95 54-40-69 103-60q-3-11-5-22.5t-4-22.5H120v-80h122q2-12 4-23.5t5-22.5l-103-60 40-69 94 55q8-14 18.5-27.5T322-612q-2-7-2-14v-14q0-24 7-46t19-41l-66-66 56-57 70 68q17-9 35.5-13.5T480-800q20 0 39 5t36 14l69-69 56 57-66 66q12 19 18.5 41t6.5 46v13.5q0 6.5-2 13.5 11 11 21.5 25t18.5 28l95-54 40 69-104 59q3 11 5.5 22.5T718-440h122v80H718q-2 12-4 23.5t-5 22.5l103 60-40 69-95-55q-32 54-82.5 87T480-120Zm-76-546q17-7 36.5-10.5T480-680q20 0 38.5 3t35.5 10q-8-23-28-38t-46-15q-26 0-47 15.5T404-666Zm76 466q73 0 116.5-61T640-400q0-70-40.5-135T480-600q-78 0-119 64.5T320-400q0 78 43.5 139T480-200Zm-40-80v-240h80v240h-80Z"/></svg>');
    --light-decision-block-border-color: #ab6fa2;
    --light-decision-block-background-color: #f4e6f4;
    --light-decision-block-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="%23ab6fa2"><path d="M160-120v-80h480v80H160Zm226-194L160-540l84-86 228 226-86 86Zm254-254L414-796l86-84 226 226-86 86Zm184 408L302-682l56-56 522 522-56 56Z"/></svg>');
    --light-del-block-border-color: #be1621;
    --light-del-block-background-color: #fbe6e8;
    --light-del-block-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="%23be1621"><path d="M280-120q-33 0-56.5-23.5T200-200v-520h-40v-80h200v-40h240v40h200v80h-40v520q0 33-23.5 56.5T680-120H280Zm400-600H280v520h400v-520ZM360-280h80v-360h-80v360Zm160 0h80v-360h-80v360ZM280-720v520-520Z"/></svg>');
    --light-details-border-color: #707070;
    --light-details-background-color: #f0f0f0;
    --light-details-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="%23707070"><path d="M440-280h80v-240h-80v240Zm40-320q17 0 28.5-11.5T520-640q0-17-11.5-28.5T480-680q-17 0-28.5 11.5T440-640q0 17 11.5 28.5T480-600Zm0 520q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>');
    --light-diff-block-border-color: #707070;
    --light-diff-block-background-color: #f0f0f0;
    --light-diff-block-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="%23707070"><path d="M500-520h80v-80h80v-80h-80v-80h-80v80h-80v80h80v80Zm-80 160h240v-80H420v80ZM320-200q-33 0-56.5-23.5T240-280v-560q0-33 23.5-56.5T320-920h280l240 240v400q0 33-23.5 56.5T760-200H320Zm0-80h440v-360L560-840H320v560ZM160-40q-33 0-56.5-23.5T80-120v-560h80v560h440v80H160Zm160-240v-560 560Z"/></svg>');
    --light-example-block-border-color: #6f8aab;
    --light-example-block-background-color: #e6e9f4;
    --light-example-block-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="%236f8aab"><path d="M300-80q-58 0-99-41t-41-99v-520q0-58 41-99t99-41h500v600q-25 0-42.5 17.5T740-220q0 25 17.5 42.5T800-160v80H300Zm-60-267q14-7 29-10t31-3h20v-440h-20q-25 0-42.5 17.5T240-740v393Zm160-13h320v-440H400v440Zm-160 13v-453 453Zm60 187h373q-6-14-9.5-28.5T660-220q0-16 3-31t10-29H300q-26 0-43 17.5T240-220q0 26 17 43t43 17Z"/></svg>');
    --light-important-block-border-color: #b05252;
    --light-important-block-background-color: #f4e6e6;
    --light-important-block-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="%23ab6f6f"><path d="M480-120q-33 0-56.5-23.5T400-200q0-33 23.5-56.5T480-280q33 0 56.5 23.5T560-200q0 33-23.5 56.5T480-120Zm-80-240v-480h160v480H400Z"/></svg>');
    --light-ins-block-border-color: #17752d;
    --light-ins-block-background-color: #e4faea;
    --light-ins-block-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="%2317752d"><path d="M440-240h80v-120h120v-80H520v-120h-80v120H320v80h120v120ZM240-80q-33 0-56.5-23.5T160-160v-640q0-33 23.5-56.5T240-880h320l240 240v480q0 33-23.5 56.5T720-80H240Zm280-520v-200H240v640h480v-440H520ZM240-800v200-200 640-640Z"/></svg>');
    --light-note-block-border-color: #6fab6f;
    --light-note-block-background-color: #e6f4e9;
    --light-note-block-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="%236fab6f"><path d="M440-280h80v-240h-80v240Zm40-320q17 0 28.5-11.5T520-640q0-17-11.5-28.5T480-680q-17 0-28.5 11.5T440-640q0 17 11.5 28.5T480-600Zm0 520q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>');
    --light-tip-block-border-color: #b0a029;
    --light-tip-block-background-color: #f4f4e6;
    --light-tip-block-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="%23b0a029"><path d="M480-80q-33 0-56.5-23.5T400-160h160q0 33-23.5 56.5T480-80ZM320-200v-80h320v80H320Zm10-120q-69-41-109.5-110T180-580q0-125 87.5-212.5T480-880q125 0 212.5 87.5T780-580q0 81-40.5 150T630-320H330Zm24-80h252q45-32 69.5-79T700-580q0-92-64-156t-156-64q-92 0-156 64t-64 156q0 54 24.5 101t69.5 79Zm126 0Z"/></svg>');
    --light-todo-block-border-color: #6faba0;
    --light-todo-block-background-color: #e6f4f3;
    --light-todo-block-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="%236faba0"><path d="M680-80q-83 0-141.5-58.5T480-280q0-83 58.5-141.5T680-480q83 0 141.5 58.5T880-280q0 83-58.5 141.5T680-80Zm67-105 28-28-75-75v-112h-40v128l87 87Zm-547 65q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h167q11-35 43-57.5t70-22.5q40 0 71.5 22.5T594-840h166q33 0 56.5 23.5T840-760v250q-18-13-38-22t-42-16v-212h-80v120H280v-120h-80v560h212q7 22 16 42t22 38H200Zm280-640q17 0 28.5-11.5T520-800q0-17-11.5-28.5T480-840q-17 0-28.5 11.5T440-800q0 17 11.5 28.5T480-760Z"/></svg>');
    --light-warning-block-border-color: #af8141;
    --light-warning-block-background-color: #f4eee6;
    --light-warning-block-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="%23af8141"><path d="M109-120q-11 0-20-5.5T75-140q-5-9-5.5-19.5T75-180l370-640q6-10 15.5-15t19.5-5q10 0 19.5 5t15.5 15l370 640q6 10 5.5 20.5T885-140q-5 9-14 14.5t-20 5.5H109Zm69-80h604L480-720 178-200Zm302-40q17 0 28.5-11.5T520-280q0-17-11.5-28.5T480-320q-17 0-28.5 11.5T440-280q0 17 11.5 28.5T480-240Zm0-120q17 0 28.5-11.5T520-400v-120q0-17-11.5-28.5T480-560q-17 0-28.5 11.5T440-520v120q0 17 11.5 28.5T480-360Zm0-100Z"/></svg>');
    --light-theme-icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="black"><path d="M480-360q50 0 85-35t35-85q0-50-35-85t-85-35q-50 0-85 35t-35 85q0 50 35 85t85 35Zm0 80q-83 0-141.5-58.5T280-480q0-83 58.5-141.5T480-680q83 0 141.5 58.5T680-480q0 83-58.5 141.5T480-280ZM200-440H40v-80h160v80Zm720 0H760v-80h160v80ZM440-760v-160h80v160h-80Zm0 720v-160h80v160h-80ZM256-650l-101-97 57-59 96 100-52 56Zm492 496-97-101 53-55 101 97-57 59Zm-98-550 97-101 59 57-100 96-56-52ZM154-212l101-97 55 53-97 101-59-57Zm326-268Z"/></svg>');

    --dark-background-color: #202020;
    --dark-deep-background-color: #1a1a1a;
    --dark-text-color: #f0f0f0;
    --dark-border-color: #505050;
    --dark-table-border-color: #777;
    --dark-del-background-color: #67060c;
    --dark-del-color: #ffdcd7;
    --dark-ins-background-color: #033a16;
    --dark-ins-color: #aff5b4;
    --dark-para-color: #5bc0ff;
    --dark-a-color: #5bc0ff;
    --dark-a-visited-color: #c6a8ff;
    --dark-a-hover-color: #afd7ff;
    --dark-mark-color: #ededa8;
    --dark-mark-background-color: #525230;
    --dark-abstract-border-color: #999999;
    --dark-abstract-background-color: #2c2c2c;
    --dark-abstract-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="%23999999"><path d="M660-160h40v-160h-40v160Zm20-200q8 0 14-6t6-14q0-8-6-14t-14-6q-8 0-14 6t-6 14q0 8 6 14t14 6ZM200-800v640-640 200-200Zm80 400h147q11-23 25.5-43t32.5-37H280v80Zm0 160h123q-3-20-3-40t3-40H280v80ZM200-80q-33 0-56.5-23.5T120-160v-640q0-33 23.5-56.5T200-880h320l240 240v92q-19-6-39-9t-41-3v-40H480v-200H200v640h227q11 23 25.5 43T485-80H200Zm480-400q83 0 141.5 58.5T880-280q0 83-58.5 141.5T680-80q-83 0-141.5-58.5T480-280q0-83 58.5-141.5T680-480Z"/></svg>');
    --dark-blockquote-border-color: #707070;
    --dark-blockquote-background-color: #2c2c2c;
    --dark-blockquote-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="%23707070"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M7.17 17c.51 0 .98-.29 1.2-.74l1.42-2.84c.14-.28.21-.58.21-.89V8c0-.55-.45-1-1-1H5c-.55 0-1 .45-1 1v4c0 .55.45 1 1 1h2l-1.03 2.06c-.45.89.2 1.94 1.2 1.94zm10 0c.51 0 .98-.29 1.2-.74l1.42-2.84c.14-.28.21-.58.21-.89V8c0-.55-.45-1-1-1h-4c-.55 0-1 .45-1 1v4c0 .55.45 1 1 1h2l-1.03 2.06c-.45.89.2 1.94 1.2 1.94z"/></svg>');
    --dark-bug-block-border-color: #ab866f;
    --dark-bug-block-background-color: #373028;
    --dark-bug-block-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="%23ab866f"><path d="M480-120q-64 0-114.5-33T283-240l-95 54-40-69 103-60q-3-11-5-22.5t-4-22.5H120v-80h122q2-12 4-23.5t5-22.5l-103-60 40-69 94 55q8-14 18.5-27.5T322-612q-2-7-2-14v-14q0-24 7-46t19-41l-66-66 56-57 70 68q17-9 35.5-13.5T480-800q20 0 39 5t36 14l69-69 56 57-66 66q12 19 18.5 41t6.5 46v13.5q0 6.5-2 13.5 11 11 21.5 25t18.5 28l95-54 40 69-104 59q3 11 5.5 22.5T718-440h122v80H718q-2 12-4 23.5t-5 22.5l103 60-40 69-95-55q-32 54-82.5 87T480-120Zm-76-546q17-7 36.5-10.5T480-680q20 0 38.5 3t35.5 10q-8-23-28-38t-46-15q-26 0-47 15.5T404-666Zm76 466q73 0 116.5-61T640-400q0-70-40.5-135T480-600q-78 0-119 64.5T320-400q0 78 43.5 139T480-200Zm-40-80v-240h80v240h-80Z"/></svg>');
    --dark-details-border-color: #707070;
    --dark-details-background-color: #2c2c2c;
    --dark-details-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="%23707070"><path d="M440-280h80v-240h-80v240Zm40-320q17 0 28.5-11.5T520-640q0-17-11.5-28.5T480-680q-17 0-28.5 11.5T440-640q0 17 11.5 28.5T480-600Zm0 520q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>');
    --dark-decision-block-border-color: #ab6fa2;
    --dark-decision-block-background-color: #30232d;
    --dark-decision-block-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="%23ab6fa2"><path d="M160-120v-80h480v80H160Zm226-194L160-540l84-86 228 226-86 86Zm254-254L414-796l86-84 226 226-86 86Zm184 408L302-682l56-56 522 522-56 56Z"/></svg>');
    --dark-del-block-border-color: #be5e64;
    --dark-del-block-background-color: #302323;
    --dark-del-block-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="%23be5e64"><path d="M280-120q-33 0-56.5-23.5T200-200v-520h-40v-80h200v-40h240v40h200v80h-40v520q0 33-23.5 56.5T680-120H280Zm400-600H280v520h400v-520ZM360-280h80v-360h-80v360Zm160 0h80v-360h-80v360ZM280-720v520-520Z"/></svg>');
    --dark-diff-block-border-color: #707070;
    --dark-diff-block-background-color: #2c2c2c;
    --dark-diff-block-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="%23707070"><path d="M500-520h80v-80h80v-80h-80v-80h-80v80h-80v80h80v80Zm-80 160h240v-80H420v80ZM320-200q-33 0-56.5-23.5T240-280v-560q0-33 23.5-56.5T320-920h280l240 240v400q0 33-23.5 56.5T760-200H320Zm0-80h440v-360L560-840H320v560ZM160-40q-33 0-56.5-23.5T80-120v-560h80v560h440v80H160Zm160-240v-560 560Z"/></svg>');
    --dark-example-block-border-color: #6f81ab;
    --dark-example-block-background-color: #232630;
    --dark-example-block-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="%236f81ab"><path d="M300-80q-58 0-99-41t-41-99v-520q0-58 41-99t99-41h500v600q-25 0-42.5 17.5T740-220q0 25 17.5 42.5T800-160v80H300Zm-60-267q14-7 29-10t31-3h20v-440h-20q-25 0-42.5 17.5T240-740v393Zm160-13h320v-440H400v440Zm-160 13v-453 453Zm60 187h373q-6-14-9.5-28.5T660-220q0-16 3-31t10-29H300q-26 0-43 17.5T240-220q0 26 17 43t43 17Z"/></svg>');
    --dark-important-block-border-color: #b06262;
    --dark-important-block-background-color: #302323;
    --dark-important-block-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="%23b06262"><path d="M480-120q-33 0-56.5-23.5T400-200q0-33 23.5-56.5T480-280q33 0 56.5 23.5T560-200q0 33-23.5 56.5T480-120Zm-80-240v-480h160v480H400Z"/></svg>');
    --dark-ins-block-border-color: #5bab6d;
    --dark-ins-block-background-color: #233023;
    --dark-ins-block-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="%235bab6d"><path d="M440-240h80v-120h120v-80H520v-120h-80v120H320v80h120v120ZM240-80q-33 0-56.5-23.5T160-160v-640q0-33 23.5-56.5T240-880h320l240 240v480q0 33-23.5 56.5T720-80H240Zm280-520v-200H240v640h480v-440H520ZM240-800v200-200 640-640Z"/></svg>');
    --dark-note-block-border-color: #6fab76;
    --dark-note-block-background-color: #233025;
    --dark-note-block-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="%236fab76"><path d="M440-280h80v-240h-80v240Zm40-320q17 0 28.5-11.5T520-640q0-17-11.5-28.5T480-680q-17 0-28.5 11.5T440-640q0 17 11.5 28.5T480-600Zm0 520q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>');
    --dark-tip-block-border-color: #a2ab6f;
    --dark-tip-block-background-color: #2f3023;
    --dark-tip-block-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="%23a2ab6f"><path d="M480-80q-33 0-56.5-23.5T400-160h160q0 33-23.5 56.5T480-80ZM320-200v-80h320v80H320Zm10-120q-69-41-109.5-110T180-580q0-125 87.5-212.5T480-880q125 0 212.5 87.5T780-580q0 81-40.5 150T630-320H330Zm24-80h252q45-32 69.5-79T700-580q0-92-64-156t-156-64q-92 0-156 64t-64 156q0 54 24.5 101t69.5 79Zm126 0Z"/></svg>');
    --dark-todo-block-border-color: #6fab98;
    --dark-todo-block-background-color: #23302e;
    --dark-todo-block-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="%236fab98"><path d="M680-80q-83 0-141.5-58.5T480-280q0-83 58.5-141.5T680-480q83 0 141.5 58.5T880-280q0 83-58.5 141.5T680-80Zm67-105 28-28-75-75v-112h-40v128l87 87Zm-547 65q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h167q11-35 43-57.5t70-22.5q40 0 71.5 22.5T594-840h166q33 0 56.5 23.5T840-760v250q-18-13-38-22t-42-16v-212h-80v120H280v-120h-80v560h212q7 22 16 42t22 38H200Zm280-640q17 0 28.5-11.5T520-800q0-17-11.5-28.5T480-840q-17 0-28.5 11.5T440-800q0 17 11.5 28.5T480-760Z"/></svg>');
    --dark-warning-block-border-color: #ab9c6f;
    --dark-warning-block-background-color: #302b23;
    --dark-warning-block-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="%23ab9c6f"><path d="M109-120q-11 0-20-5.5T75-140q-5-9-5.5-19.5T75-180l370-640q6-10 15.5-15t19.5-5q10 0 19.5 5t15.5 15l370 640q6 10 5.5 20.5T885-140q-5 9-14 14.5t-20 5.5H109Zm69-80h604L480-720 178-200Zm302-40q17 0 28.5-11.5T520-280q0-17-11.5-28.5T480-320q-17 0-28.5 11.5T440-280q0 17 11.5 28.5T480-240Zm0-120q17 0 28.5-11.5T520-400v-120q0-17-11.5-28.5T480-560q-17 0-28.5 11.5T440-520v120q0 17 11.5 28.5T480-360Zm0-100Z"/></svg>');
    --dark-theme-icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="%23f0f0f0"><path d="M480-120q-150 0-255-105T120-480q0-150 105-255t255-105q14 0 27.5 1t26.5 3q-41 29-65.5 75.5T444-660q0 90 63 153t153 63q55 0 101-24.5t75-65.5q2 13 3 26.5t1 27.5q0 150-105 255T480-120Zm0-80q88 0 158-48.5T740-375q-20 5-40 8t-40 3q-123 0-209.5-86.5T364-660q0-20 3-40t8-40q-78 32-126.5 102T200-480q0 116 82 198t198 82Zm-10-270Z"/></svg>');

    --indent: 2.5em;
    --border-radius: 0.25em;
}

/* BEGIN LIGHT AND DARK THEME */

@media (prefers-color-scheme: light) {
    html {
        --background-color: var(--light-background-color);
        --deep-background-color: var(--light-deep-background-color);
        --text-color: var(--light-text-color);
        --border-color: var(--light-border-color);
        --table-border-color: var(--light-table-border-color);
        --del-color: var(--light-del-color);
        --del-background-color: var(--light-del-background-color);
        --ins-color: var(--light-ins-color);
        --ins-background-color: var(--light-ins-background-color);
        --para-color: var(--light-para-color);
        --a-color: var(--light-a-color);
        --a-visited-color: var(--light-a-visited-color);
        --a-hover-color: var(--light-a-hover-color);
        --mark-color: var(--light-mark-color);
        --mark-background-color: var(--light-mark-background-color);
        --abstract-border-color: var(--light-abstract-border-color);
        --abstract-background-color: var(--light-abstract-background-color);
        --abstract-image: var(--light-abstract-image);
        --blockquote-border-color: var(--light-blockquote-border-color);
        --blockquote-background-color: var(--light-blockquote-background-color);
        --blockquote-image: var(--light-blockquote-image);
        --bug-block-border-color: var(--light-bug-block-border-color);
        --bug-block-background-color: var(--light-bug-block-background-color);
        --bug-block-image: var(--light-bug-block-image);
        --decision-block-border-color: var(--light-decision-block-border-color);
        --decision-block-background-color: var(--light-decision-block-background-color);
        --decision-block-image: var(--light-decision-block-image);
        --del-block-border-color: var(--light-del-block-border-color);
        --del-block-background-color: var(--light-del-block-background-color);
        --del-block-image: var(--light-del-block-image);
        --details-border-color: var(--light-details-border-color);
        --details-background-color: var(--light-details-background-color);
        --details-image: var(--light-details-image);
        --diff-block-border-color: var(--light-diff-block-border-color);
        --diff-block-background-color: var(--light-diff-block-background-color);
        --diff-block-image: var(--light-diff-block-image);
        --example-block-border-color: var(--light-example-block-border-color);
        --example-block-background-color: var(--light-example-block-background-color);
        --example-block-image: var(--light-example-block-image);
        --important-block-border-color: var(--light-important-block-border-color);
        --important-block-background-color: var(--light-important-block-background-color);
        --important-block-image: var(--light-important-block-image);
        --ins-block-border-color: var(--light-ins-block-border-color);
        --ins-block-background-color: var(--light-ins-block-background-color);
        --ins-block-image: var(--light-ins-block-image);
        --note-block-border-color: var(--light-note-block-border-color);
        --note-block-background-color: var(--light-note-block-background-color);
        --note-block-image: var(--light-note-block-image);
        --tip-block-border-color: var(--light-tip-block-border-color);
        --tip-block-background-color: var(--light-tip-block-background-color);
        --tip-block-image: var(--light-tip-block-image);
        --todo-block-border-color: var(--light-todo-block-border-color);
        --todo-block-background-color: var(--light-todo-block-background-color);
        --todo-block-image: var(--light-todo-block-image);
        --warning-block-border-color: var(--light-warning-block-border-color);
        --warning-block-background-color: var(--light-warning-block-background-color);
        --warning-block-image: var(--light-warning-block-image);
        --theme-icon: var(--light-theme-icon);
    }
}

@media (prefers-color-scheme: dark) {
    html {
        --background-color: var(--dark-background-color);
        --deep-background-color: var(--dark-deep-background-color);
        --text-color: var(--dark-text-color);
        --border-color: var(--dark-border-color);
        --table-border-color: var(--dark-table-border-color);
        --del-color: var(--dark-del-color);
        --del-background-color: var(--dark-del-background-color);
        --ins-color: var(--dark-ins-color);
        --ins-background-color: var(--dark-ins-background-color);
        --para-color: var(--dark-para-color);
        --a-color: var(--dark-a-color);
        --a-visited-color: var(--dark-a-visited-color);
        --a-hover-color: var(--dark-a-hover-color);
        --mark-color: var(--dark-mark-color);
        --mark-background-color: var(--dark-mark-background-color);
        --abstract-border-color: var(--dark-abstract-border-color);
        --abstract-background-color: var(--dark-abstract-background-color);
        --abstract-image: var(--dark-abstract-image);
        --blockquote-border-color: var(--dark-blockquote-border-color);
        --blockquote-background-color: var(--dark-blockquote-background-color);
        --blockquote-image: var(--dark-blockquote-image);
        --bug-block-border-color: var(--dark-bug-block-border-color);
        --bug-block-background-color: var(--dark-bug-block-background-color);
        --bug-block-image: var(--dark-bug-block-image);
        --decision-block-border-color: var(--dark-decision-block-border-color);
        --decision-block-background-color: var(--dark-decision-block-background-color);
        --decision-block-image: var(--dark-decision-block-image);
        --del-block-border-color: var(--dark-del-block-border-color);
        --del-block-background-color: var(--dark-del-block-background-color);
        --del-block-image: var(--dark-del-block-image);
        --details-border-color: var(--dark-details-border-color);
        --details-background-color: var(--dark-details-background-color);
        --details-image: var(--dark-details-image);
        --diff-block-border-color: var(--dark-diff-block-border-color);
        --diff-block-background-color: var(--dark-diff-block-background-color);
        --diff-block-image: var(--dark-diff-block-image);
        --example-block-border-color: var(--dark-example-block-border-color);
        --example-block-background-color: var(--dark-example-block-background-color);
        --example-block-image: var(--dark-example-block-image);
        --important-block-border-color: var(--dark-important-block-border-color);
        --important-block-background-color: var(--dark-important-block-background-color);
        --important-block-image: var(--dark-important-block-image);
        --ins-block-border-color: var(--dark-ins-block-border-color);
        --ins-block-background-color: var(--dark-ins-block-background-color);
        --ins-block-image: var(--dark-ins-block-image);
        --note-block-border-color: var(--dark-note-block-border-color);
        --note-block-background-color: var(--dark-note-block-background-color);
        --note-block-image: var(--dark-note-block-image);
        --tip-block-border-color: var(--dark-tip-block-border-color);
        --tip-block-background-color: var(--dark-tip-block-background-color);
        --tip-block-image: var(--dark-tip-block-image);
        --todo-block-border-color: var(--dark-todo-block-border-color);
        --todo-block-background-color: var(--dark-todo-block-background-color);
        --todo-block-image: var(--dark-todo-block-image);
        --warning-block-border-color: var(--dark-warning-block-border-color);
        --warning-block-background-color: var(--dark-warning-block-background-color);
        --warning-block-image: var(--dark-warning-block-image);
        --theme-icon: var(--dark-theme-icon);
    }
}

html.light {
    --background-color: var(--light-background-color);
    --deep-background-color: var(--light-deep-background-color);
    --text-color: var(--light-text-color);
    --border-color: var(--light-border-color);
    --table-border-color: var(--light-table-border-color);
    --del-color: var(--light-del-color);
    --del-background-color: var(--light-del-background-color);
    --ins-color: var(--light-ins-color);
    --ins-background-color: var(--light-ins-background-color);
    --para-color: var(--light-para-color);
    --a-color: var(--light-a-color);
    --a-visited-color: var(--light-a-visited-color);
    --a-hover-color: var(--light-a-hover-color);
    --mark-color: var(--light-mark-color);
    --mark-background-color: var(--light-mark-background-color);
    --abstract-border-color: var(--light-abstract-border-color);
    --abstract-background-color: var(--light-abstract-background-color);
    --abstract-image: var(--light-abstract-image);
    --blockquote-border-color: var(--light-blockquote-border-color);
    --blockquote-background-color: var(--light-blockquote-background-color);
    --blockquote-image: var(--light-blockquote-image);
    --bug-block-border-color: var(--light-bug-block-border-color);
    --bug-block-background-color: var(--light-bug-block-background-color);
    --bug-block-image: var(--light-bug-block-image);
    --decision-block-border-color: var(--light-decision-block-border-color);
    --decision-block-background-color: var(--light-decision-block-background-color);
    --decision-block-image: var(--light-decision-block-image);
    --del-block-border-color: var(--light-del-block-border-color);
    --del-block-background-color: var(--light-del-block-background-color);
    --del-block-image: var(--light-del-block-image);
    --details-border-color: var(--light-details-border-color);
    --details-background-color: var(--light-details-background-color);
    --details-image: var(--light-details-image);
    --diff-block-border-color: var(--light-diff-block-border-color);
    --diff-block-background-color: var(--light-diff-block-background-color);
    --diff-block-image: var(--light-diff-block-image);
    --example-block-border-color: var(--light-example-block-border-color);
    --example-block-background-color: var(--light-example-block-background-color);
    --example-block-image: var(--light-example-block-image);
    --important-block-border-color: var(--light-important-block-border-color);
    --important-block-background-color: var(--light-important-block-background-color);
    --important-block-image: var(--light-important-block-image);
    --ins-block-border-color: var(--light-ins-block-border-color);
    --ins-block-background-color: var(--light-ins-block-background-color);
    --ins-block-image: var(--light-ins-block-image);
    --note-block-border-color: var(--light-note-block-border-color);
    --note-block-background-color: var(--light-note-block-background-color);
    --note-block-image: var(--light-note-block-image);
    --tip-block-border-color: var(--light-tip-block-border-color);
    --tip-block-background-color: var(--light-tip-block-background-color);
    --tip-block-image: var(--light-tip-block-image);
    --todo-block-border-color: var(--light-todo-block-border-color);
    --todo-block-background-color: var(--light-todo-block-background-color);
    --todo-block-image: var(--light-todo-block-image);
    --warning-block-border-color: var(--light-warning-block-border-color);
    --warning-block-background-color: var(--light-warning-block-background-color);
    --warning-block-image: var(--light-warning-block-image);
    --theme-icon: var(--light-theme-icon);
}

html.dark {
    --background-color: var(--dark-background-color);
    --deep-background-color: var(--dark-deep-background-color);
    --text-color: var(--dark-text-color);
    --border-color: var(--dark-border-color);
    --table-border-color: var(--dark-table-border-color);
    --del-color: var(--dark-del-color);
    --del-background-color: var(--dark-del-background-color);
    --ins-color: var(--dark-ins-color);
    --ins-background-color: var(--dark-ins-background-color);
    --para-color: var(--dark-para-color);
    --a-color: var(--dark-a-color);
    --a-visited-color: var(--dark-a-visited-color);
    --a-hover-color: var(--dark-a-hover-color);
    --mark-color: var(--dark-mark-color);
    --mark-background-color: var(--dark-mark-background-color);
    --abstract-border-color: var(--dark-abstract-border-color);
    --abstract-background-color: var(--dark-abstract-background-color);
    --abstract-image: var(--dark-abstract-image);
    --blockquote-border-color: var(--dark-blockquote-border-color);
    --blockquote-background-color: var(--dark-blockquote-background-color);
    --blockquote-image: var(--dark-blockquote-image);
    --bug-block-border-color: var(--dark-bug-block-border-color);
    --bug-block-background-color: var(--dark-bug-block-background-color);
    --bug-block-image: var(--dark-bug-block-image);
    --decision-block-border-color: var(--dark-decision-block-border-color);
    --decision-block-background-color: var(--dark-decision-block-background-color);
    --decision-block-image: var(--dark-decision-block-image);
    --del-block-border-color: var(--dark-del-block-border-color);
    --del-block-background-color: var(--dark-del-block-background-color);
    --del-block-image: var(--dark-del-block-image);
    --details-border-color: var(--dark-details-border-color);
    --details-background-color: var(--dark-details-background-color);
    --details-image: var(--dark-details-image);
    --diff-block-border-color: var(--dark-diff-block-border-color);
    --diff-block-background-color: var(--dark-diff-block-background-color);
    --diff-block-image: var(--dark-diff-block-image);
    --example-block-border-color: var(--dark-example-block-border-color);
    --example-block-background-color: var(--dark-example-block-background-color);
    --example-block-image: var(--dark-example-block-image);
    --important-block-border-color: var(--dark-important-block-border-color);
    --important-block-background-color: var(--dark-important-block-background-color);
    --important-block-image: var(--dark-important-block-image);
    --ins-block-border-color: var(--dark-ins-block-border-color);
    --ins-block-background-color: var(--dark-ins-block-background-color);
    --ins-block-image: var(--dark-ins-block-image);
    --note-block-border-color: var(--dark-note-block-border-color);
    --note-block-background-color: var(--dark-note-block-background-color);
    --note-block-image: var(--dark-note-block-image);
    --tip-block-border-color: var(--dark-tip-block-border-color);
    --tip-block-background-color: var(--dark-tip-block-background-color);
    --tip-block-image: var(--dark-tip-block-image);
    --todo-block-border-color: var(--dark-todo-block-border-color);
    --todo-block-background-color: var(--dark-todo-block-background-color);
    --todo-block-image: var(--dark-todo-block-image);
    --warning-block-border-color: var(--dark-warning-block-border-color);
    --warning-block-background-color: var(--dark-warning-block-background-color);
    --warning-block-image: var(--dark-warning-block-image);
    --theme-icon: var(--dark-theme-icon);
}

/* END LIGHT AND DARK THEME */

html {
    margin: 0;
    width: 100%;
    font-family: var(--serif-family);
    font-size: 11pt;

    border-left: var(--border-thickness) solid var(--border-color);
    color: var(--text-color);
    background-color: var(--background-color);
}

body {
    --vertical-margin: 2rem;
    --margin-left: 3rem;
    --margin-right: 2rem;

    margin: var(--vertical-margin) var(--margin-right) var(--vertical-margin) var(--margin-left);
    width: calc(100% - var(--margin-left) - var(--margin-right));
    box-sizing: border-box;
}

main {
    max-width: 60rem;
    margin-left: auto;
    margin-right: auto;
}

p {
    text-align: justify;
}

abstract-block,
blockquote,
bug-block,
code-block,
decision-block,
del-block,
details,
dl,
diff-block,
example-block,
hr,
ol,
important-block,
ins-block,
math[display=block],
note-block,
p,
pre,
tip-block,
todo-block,
ul,
warning-block,
.indent {
    display: block;
    margin-top: 1em;
    margin-bottom: 1em;
}

a {
    color: var(--a-color);
    text-decoration: unset;
}

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

a:hover,
a:focus {
    color: var(--a-hover-color);
}

a:hover {
    text-decoration: underline;
}

ol,
ul {
    padding-left: var(--indent);
}

li {
    margin: 0.5em 0;
}

dt {
    margin-top: 0.25em;
    font-style: italic;
    font-weight: bold;
}

dd {
    margin-bottom: 0.25em;
    margin-left: var(--indent);
}

abstract-block,
blockquote,
bug-block,
del-block,
details,
decision-block,
diff-block,
example-block,
important-block,
ins-block,
note-block,
tip-block,
todo-block,
warning-block {
    --border-thickness: 0.25em;
    --padding: 0.5em;

    position: relative;
    width: calc(100% - var(--indent));
    box-sizing: border-box;
    padding: var(--padding);
    margin-left: var(--indent);

    border-top-right-radius: var(--border-radius);
    border-bottom-right-radius: var(--border-radius);
}

abstract-block>:first-child,
blockquote>:first-child,
bug-block>:first-child,
del-block>:first-child,
details>:first-child,
decision-block>:first-child,
diff-block>:first-child,
example-block>:first-child,
important-block>:first-child,
ins-block>:first-child,
note-block>:first-child,
tip-block>:first-child,
todo-block>:first-child,
warning-block>:first-child {
    margin-top: 0;
}

abstract-block>:last-child,
blockquote>:last-child,
bug-block>:last-child,
del-block>:last-child,
details>:last-child,
decision-block>:last-child,
diff-block>:last-child,
example-block>:last-child,
important-block>:last-child,
ins-block>:last-child,
note-block>:last-child,
todo-block>:last-child,
tip-block>:last-child,
warning-block>:last-child {
    margin-bottom: 0;
}

abstract-block::before,
blockquote::before,
bug-block::before,
del-block::before,
details::before,
decision-block::before,
diff-block::before,
example-block::before,
important-block::before,
ins-block::before,
note-block::before,
todo-block::before,
tip-block::before,
warning-block::before {
    position: absolute;
    left: -2.5em;
    top: 0.25em;
    width: 2em;
    height: 2em;

    content: "";
    display: inline-block;
    background-size: contain;
    background-repeat: no-repeat;

}

code,
code-block,
pre,
samp,
tt,
tt-,
.mono {
    font-family: var(--monospace-family);
    font-style: normal;
    font-variant-ligatures: none;
}

code-block:not(.borderless),
pre {
    padding: 0.5em;
    border-radius: var(--border-radius);
    box-sizing: border-box;

    background-color: var(--deep-background-color);
    border: 1px solid var(--border-color);
}

code-block,
pre {
    font-size: 95%;
    width: 100%;
}

code-block,
pre {
    white-space: pre;
    overflow-x: auto;
}

/* INSERTIONS AND DELETIONS */

ins,
ins-lines {
    text-decoration: underline;
    font-weight: 600;
    color: var(--ins-color);
    background-color: var(--ins-background-color);
}

code-block ins,
code-block ins-lines {
    text-decoration: inherit;
}

del {
    text-decoration: line-through;
}

del,
del-lines {
    color: var(--del-color);
    background-color: var(--del-background-color);
}

ins-lines,
del-lines {
    display: inline-block;
    width: 100%;
}

ins h-,
ins-lines h-,
del h-,
del-lines h- {
    color: inherit !important;
    background-color: inherit !important;
}

kbd {
    font-family: var(--sans-serif-family);

    display: inline-block;
    padding: 0 0.25em 0.15em 0.25em;
    border-radius: 0.25em;
    white-space: nowrap;

    background-color: var(--deep-background-color);
    border: 1px solid var(--border-color);
    box-shadow: inset 0 -0.1em 0 var(--border-color);
}

mark {
    color: var(--mark-color);
    background-color: var(--mark-background-color);
}

math:not([display=block]) {
    font-size: 120%;
}

math[display=block] {
    width: fit-content;
    margin-left: var(--indent);

    font-size: 110%;
}

g-term,
f-sans,
f-serif,
wg21-block {
    display: inline;
}

f-sans,
.sans {
    font-family: var(--sans-serif-family);
}

f-serif,
.serif {
    font-family: var(--serif-family);
}

.grammar dd,
g-term {
    font-family: var(--sans-serif-family);
    font-style: oblique;
}

.grammar {
    margin-left: var(--indent);
}

.grammar dt {
    font-weight: normal;
    font-style: normal;
}

.oblique {
    font-style: oblique;
}

.word {
    white-space: nowrap;
}

.wg21-head {
    margin-bottom: 4em;
}

.wg21-head dl {
    font-family: var(--sans-serif-family);
}

.wg21-head dt {
    font-style: normal;
}

/* HEADINGS */

h1,
h2,
h3,
h4,
h5,
h6 {
    position: relative;
    margin: 1rem 0;
}

h1 {
    margin: 2rem 0 1.5rem 0;
    font-size: 250%;
}

h2 {
    margin: 2.5rem 0 1.5rem 0;
    font-size: 166%;
}

h3 {
    margin: 2rem 0 1rem 0;
    font-size: 133%;
}

h4 {
    margin: 1.5rem 0 0.5rem 0;
    font-size: 100%;
}

h5 {
    margin: 1rem 0 0.5rem 0;
    font-size: 100%;
    font-weight: normal;
}

h6 {
    margin: 1rem 0 0.5rem 0;
    font-size: 90%;
    font-weight: normal;
}

table {
    --border: 1px solid var(--table-border-color);

    margin-top: 1em;
    margin-bottom: 1em;
    border-collapse: collapse;
}

table,
tbody,
thead,
th {
    border: var(--border);
}

td {
    border-left: var(--border);
    border-right: var(--border);
}

td,
th {
    padding: 0.1em 0.5em;
}

.para {
    cursor: pointer;
    font-weight: normal;
    font-family: var(--monospace-family);
    text-decoration: none;
    opacity: 0.25;

    position: absolute;
    top: 0.05em;
    left: calc(-1rem - 0.5ch);
}

.para,
.para::before {
    color: var(--para-color);
}

.para:hover,
.para:focus,
:target .para {
    opacity: 1;
}

.para::before {
    content: "§";
}

/* TABLE OF CONTENTS */

.toc {
    --h-indent: 0.75em;

    display: grid;
    grid-template-columns: min-content auto;
}

.toc-num {
    display: inline-block;
    align-self: end;
    padding-right: 3em;

    letter-spacing: 0em;
}

.toc h1,
.toc h2,
.toc h3,
.toc h4,
.toc h5,
.toc h6 {
    display: inline-block;

    font-weight: 500;
    font-size: 12pt;

    margin-top: 0;
    margin-bottom: 0;
}

.toc a,
.toc-num {
    border-bottom: 1px solid rgba(0, 0, 0, 0);
    color: var(--text-color);
}

.toc h1,
.toc-num[data-level="1"] {
    font-size: 125%;
    font-weight: 900;
}

.toc h2,
.toc-num[data-level="2"] {
    font-weight: 700;
}

.toc h3,
.toc-num[data-level="3"] {
    font-weight: 500;
}

.toc h4,
.toc-num[data-level="4"] {
    font-size: 95%;
    font-weight: 400;
}

.toc h5,
.toc-num[data-level="5"] {
    font-size: 90%;
    font-weight: 300;
}

.toc h6,
.toc-num[data-level="6"] {
    font-size: 90%;
    font-weight: 100;
}

.toc a:hover {
    display: inline-block;
    width: 100%;

    color: var(--a-hover-color);
    border-bottom: 1px dashed var(--a-hover-color);
}

.toc h1:not(:nth-child(2)>h1) {
    margin-top: 1.5em;
}

.toc h2:not(:nth-child(2)>h2) {
    margin-top: 0.75em;
}

/** BIBLIOGRAPHY */

.bib {
    display: block;
    margin: 1em 0;
}

.bib-item {
    display: inline-block;
    width: 100%;
    margin: 0.25em 0;
}

.bib-item>* {
    padding: 0 0.125em;
}

.bib-author {
    font-style: italic;
}

.bib-title {
    font-weight: 500;
}

.bib-date {
    font-family: var(--monospace-family);
}

.bib-date::before {
    font-family: var(--serif-family);
    content: "(";
}

.bib-date::after {
    font-family: var(--serif-family);
    content: ")";
}

.bib-link {
    display: block;
    margin-left: var(--indent);

    font-family: var(--sans-serif-family);
    font-style: normal;
}

/* SPECIAL BLOCKS */

intro- {
    display: inline-block;

    font-weight: 600;
    text-transform: uppercase;
    font-family: var(--sans-serif-family);
}

abstract-block {
    background-color: var(--abstract-background-color);
    border-left: var(--border-thickness) solid var(--abstract-border-color);
}

abstract-block::before {
    background-image: var(--abstract-image);
}

abstract-block intro-::before {
    content: "Abstract:";
    color: var(--abstract-border-color);
}

blockquote {
    background-color: var(--blockquote-background-color);
    border-left: var(--border-thickness) solid var(--blockquote-border-color);
}

blockquote::before {
    background-image: var(--blockquote-image);
    top: -0.25em;
}

blockquote intro-::before {
    content: "Quote:";
    color: var(--blockquote-border-color);
}

bug-block {
    background-color: var(--bug-block-background-color);
    border-left: var(--border-thickness) solid var(--bug-block-border-color);
}

bug-block::before {
    background-image: var(--bug-block-image);
}

bug-block intro-::before {
    content: "Bug:";
    color: var(--bug-block-border-color);
}

del-block {
    background-color: var(--del-block-background-color);
    border-left: var(--border-thickness) solid var(--del-block-border-color);
    color: var(--del-color);
}

del-block::before {
    background-image: var(--del-block-image);
}

del-block intro-::before {
    content: "Deleted:";
    color: var(--del-block-border-color);
}

del-block code,
del-block code-block {
    color: var(--text-color);
}

details {
    background-color: var(--details-background-color);
    border-left: var(--border-thickness) solid var(--details-border-color);
}

details::before {
    background-image: var(--details-image);
}

summary {
    font-family: var(--sans-serif-family);
    color: var(--details-border-color);
    user-select: none;
    cursor: pointer;
}

details[open]>summary {
    margin-bottom: 0.5em;
}

decision-block {
    background-color: var(--decision-block-background-color);
    border-left: var(--border-thickness) solid var(--decision-block-border-color);
}

decision-block::before {
    background-image: var(--decision-block-image);
}

decision-block intro-::before {
    content: "Decision:";
    color: var(--decision-block-border-color);
}

diff-block {
    background-color: var(--diff-block-background-color);
    border-left: var(--border-thickness) solid var(--diff-block-border-color);
}

diff-block::before {
    background-image: var(--diff-block-image);
}

diff-block intro-::before {
    content: "Difference:";
    color: var(--diff-block-border-color);
}

example-block {
    background-color: var(--example-block-background-color);
    border-left: var(--border-thickness) solid var(--example-block-border-color);
}

example-block::before {
    background-image: var(--example-block-image);
}

example-block intro-::before {
    content: "Example:";
    color: var(--example-block-border-color);
}

important-block {
    background-color: var(--important-block-background-color);
    border-left: var(--border-thickness) solid var(--important-block-border-color);
}

important-block::before {
    background-image: var(--important-block-image);
}

important-block intro-::before {
    content: "Important:";
    color: var(--important-block-border-color);
}

ins-block {
    background-color: var(--ins-block-background-color);
    border-left: var(--border-thickness) solid var(--ins-block-border-color);
    color: var(--ins-color);
}

ins-block code,
ins-block code-block {
    color: var(--text-color);
}

ins-block::before {
    background-image: var(--ins-block-image);
}

ins-block intro-::before {
    content: "Inserted:";
    color: var(--ins-block-border-color);
}

note-block {
    background-color: var(--note-block-background-color);
    border-left: var(--border-thickness) solid var(--note-block-border-color);
}

note-block::before {
    background-image: var(--note-block-image);
}

note-block intro-::before {
    content: "Note:";
    color: var(--note-block-border-color);
}

tip-block {
    background-color: var(--tip-block-background-color);
    border-left: var(--border-thickness) solid var(--tip-block-border-color);
}

tip-block::before {
    background-image: var(--tip-block-image);
}

tip-block intro-::before {
    content: "Tip:";
    color: var(--tip-block-border-color);
}

todo-block {
    background-color: var(--todo-block-background-color);
    border-left: var(--border-thickness) solid var(--todo-block-border-color);
}

todo-block::before {
    background-image: var(--todo-block-image);
}

todo-block intro-::before {
    content: "Todo:";
    color: var(--todo-block-border-color);
}

warning-block {
    background-color: var(--warning-block-background-color);
    border-left: var(--border-thickness) solid var(--warning-block-border-color);
}

warning-block::before {
    background-image: var(--warning-block-image);
}

warning-block intro-::before {
    content: "Warning:";
    color: var(--warning-block-border-color);
}

.indent {
    margin-left: var(--indent);
}

/* SETTINGS MENU */

#settings:not(.js) {
    display: none;
}

#settings {
    z-index: 999;
    position: fixed;
    display: inline-block;
    top: 1em;
    right: 1em;
}

#theme-icon {
    display: block;
    width: 2.5em;
    height: 2.5em;
    cursor: pointer;
    background-image: var(--theme-icon);
    background-size: contain;
    opacity: 0.25;
}

#theme-icon:hover,
#theme-icon:focus {
    opacity: 1;
}
  </style>
  <style>
@media (prefers-color-scheme: light) {
h-[data-h^=err] { color:#ff0000; }
h-[data-h^=cmt] { color:green; font-style:italic; }
h-[data-h^=cmt_dlim] { font-style:normal; }
h-[data-h^=val] { color:#9f6807; }
h-[data-h^=num] { color:#9f6807; }
h-[data-h^=str] { color:#9f6807; }
h-[data-h^=esc] { color:#9f6807; }
h-[data-h^=null] { color:#00607c; }
h-[data-h^=bool] { color:#9f6807; }
h-[data-h^=this] { color:#00607c; }
h-[data-h^=mac] { color:#6f4e37; }
h-[data-h^=id] { color:#000000; }
h-[data-h^=id_labl] { color:#517a0b; }
h-[data-h^=kw] { color:#00607c; }
h-[data-h^=sym] { color:#570057; }
h-[data-h^=sym_punc] { color:#000000; }
h-[data-h^=sym_par] { color:#af1915; }
h-[data-h^=sym_sqr] { color:#af1915; }
h-[data-h^=sym_brac] { color:#af1915; }
h-[data-h^=diff_head] { color:#777777; }
h-[data-h^=diff_head_hunk] { color:#5c477e; }
h-[data-h^=diff_eq] { color:#000000; }
h-[data-h^=diff_del] { color:#b31d28; background-color:#ffeef0; }
h-[data-h^=diff_ins] { color:#22863a; background-color:#f0fff4; }
h-[data-h^=diff_mod] { color:#7a680d; background-color:#fffdee; }
h-[data-h^=mk_tag] { color:#00607c; }
h-[data-h^=mk_attr] { color:#5c477e; }
h-[data-h^=mk_del] { color:#ce9178; text-decoration:line-through; }
h-[data-h^=mk_ins] { color:#b5cea8; text-decoration:underline; }
h-[data-h^=mk_emph] { font-style:italic; }
h-[data-h^=mk_stro] { font-weight:bold; }
h-[data-h^=mk_emph_stro] { font-style:italic; font-weight:bold; }
h-[data-h^=mk_ulin] { text-decoration:underline; }
h-[data-h^=mk_emph_ulin] { font-style:italic; text-decoration:underline; }
h-[data-h^=mk_stro_ulin] { font-weight:bold; text-decoration:underline; }
h-[data-h^=mk_emph_stro_ulin] { font-weight:bold; font-style:italic; text-decoration:underline; }
h-[data-h^=mk_strk] { text-decoration:line-through; }
h-[data-h^=mk_emph_strk] { font-style:italic; text-decoration:line-through; }
h-[data-h^=mk_stro_strk] { font-weight:bold; text-decoration:line-through; }
h-[data-h^=mk_emph_stro_strk] { font-weight:bold; font-style:italic; text-decoration:line-through; }
h-[data-h^=mk_ulin_strk] { text-decoration:underline line-through; }
h-[data-h^=mk_emph_ulin_strk] { font-style:italic; text-decoration:underline line-through; }
h-[data-h^=mk_stro_ulin_strk] { font-weight:bold; text-decoration:underline line-through; }
h-[data-h^=mk_emph_stro_ulin_strk] { font-weight:bold; font-style:italic; text-decoration:underline line-through; }
h-[data-h^=sh_cmd] { color:#00607c; }
h-[data-h^=sh-opt] { color:#000000; }
h-[data-h^=asm_ins] { color:#00607c; }
h-[data-h^=asm_ins_psu] { color:#9f6807; }
}
@media (prefers-color-scheme: dark) {
h-[data-h^=err] { color:#ff0000; }
h-[data-h^=cmt] { color:#a2e08d; font-style:italic; }
h-[data-h^=cmt_dlim] { font-style:normal; }
h-[data-h^=val] { color:#f2d18d; }
h-[data-h^=num] { color:#f2d18d; }
h-[data-h^=num_dlim] { color:#e6b191; }
h-[data-h^=num_deco] { color:#e6b191; }
h-[data-h^=str] { color:#f2d18d; }
h-[data-h^=str_dlim] { color:#e6b191; }
h-[data-h^=str_deco] { color:#e6b191; }
h-[data-h^=esc] { color:#e6aee6; }
h-[data-h^=null] { color:#62ded6; }
h-[data-h^=bool] { color:#f2d18d; }
h-[data-h^=this] { color:#62ded6; }
h-[data-h^=mac] { color:#cc946e; }
h-[data-h^=id] { color:#f0f0f0; }
h-[data-h^=id_labl] { color:#d8eda6; }
h-[data-h^=kw] { color:#62ded6; }
h-[data-h^=sym] { color:#baa6b9; }
h-[data-h^=sym_punc] { color:#d0d0d0; }
h-[data-h^=sym_par] { color:#fa7878; }
h-[data-h^=sym_sqr] { color:#fa7878; }
h-[data-h^=sym_brac] { color:#fa7878; }
h-[data-h^=diff_head] { color:#777777; }
h-[data-h^=diff_head_hunk] { color:#edc385; }
h-[data-h^=diff_eq] { color:#e7e7e7; }
h-[data-h^=diff_del] { color:#ffdcd7; background-color:#67060c; }
h-[data-h^=diff_ins] { color:#aff5b4; background-color:#033a16; }
h-[data-h^=diff_mod] { color:#fff4d7; background-color:#674d06; }
h-[data-h^=mk_tag] { color:#62ded6; }
h-[data-h^=mk_attr] { color:#a4c4de; }
h-[data-h^=mk_del] { color:#ce9178; text-decoration:line-through; }
h-[data-h^=mk_ins] { color:#b5cea8; text-decoration:underline; }
h-[data-h^=mk_emph] { font-style:italic; }
h-[data-h^=mk_stro] { font-weight:bold; }
h-[data-h^=mk_emph_stro] { font-style:italic; font-weight:bold; }
h-[data-h^=mk_ulin] { text-decoration:underline; }
h-[data-h^=mk_emph_ulin] { font-style:italic; text-decoration:underline; }
h-[data-h^=mk_stro_ulin] { font-weight:bold; text-decoration:underline; }
h-[data-h^=mk_emph_stro_ulin] { font-weight:bold; font-style:italic; text-decoration:underline; }
h-[data-h^=mk_strk] { text-decoration:line-through; }
h-[data-h^=mk_emph_strk] { font-style:italic; text-decoration:line-through; }
h-[data-h^=mk_stro_strk] { font-weight:bold; text-decoration:line-through; }
h-[data-h^=mk_emph_stro_strk] { font-weight:bold; font-style:italic; text-decoration:line-through; }
h-[data-h^=mk_ulin_strk] { text-decoration:underline line-through; }
h-[data-h^=mk_emph_ulin_strk] { font-style:italic; text-decoration:underline line-through; }
h-[data-h^=mk_stro_ulin_strk] { font-weight:bold; text-decoration:underline line-through; }
h-[data-h^=mk_emph_stro_ulin_strk] { font-weight:bold; font-style:italic; text-decoration:underline line-through; }
h-[data-h^=sh_cmd] { color:#62ded6; }
h-[data-h^=sh-opt] { color:#f0f0f0; }
h-[data-h^=asm_ins] { color:#62ded6; }
h-[data-h^=asm_ins_psu] { color:#e6aee6; }
}

html.light h-[data-h^=err] { color:#ff0000; }
html.light h-[data-h^=cmt] { color:green; font-style:italic; }
html.light h-[data-h^=cmt_dlim] { font-style:normal; }
html.light h-[data-h^=val] { color:#9f6807; }
html.light h-[data-h^=num] { color:#9f6807; }
html.light h-[data-h^=str] { color:#9f6807; }
html.light h-[data-h^=esc] { color:#9f6807; }
html.light h-[data-h^=null] { color:#00607c; }
html.light h-[data-h^=bool] { color:#9f6807; }
html.light h-[data-h^=this] { color:#00607c; }
html.light h-[data-h^=mac] { color:#6f4e37; }
html.light h-[data-h^=id] { color:#000000; }
html.light h-[data-h^=id_labl] { color:#517a0b; }
html.light h-[data-h^=kw] { color:#00607c; }
html.light h-[data-h^=sym] { color:#570057; }
html.light h-[data-h^=sym_punc] { color:#000000; }
html.light h-[data-h^=sym_par] { color:#af1915; }
html.light h-[data-h^=sym_sqr] { color:#af1915; }
html.light h-[data-h^=sym_brac] { color:#af1915; }
html.light h-[data-h^=diff_head] { color:#777777; }
html.light h-[data-h^=diff_head_hunk] { color:#5c477e; }
html.light h-[data-h^=diff_eq] { color:#000000; }
html.light h-[data-h^=diff_del] { color:#b31d28; background-color:#ffeef0; }
html.light h-[data-h^=diff_ins] { color:#22863a; background-color:#f0fff4; }
html.light h-[data-h^=diff_mod] { color:#7a680d; background-color:#fffdee; }
html.light h-[data-h^=mk_tag] { color:#00607c; }
html.light h-[data-h^=mk_attr] { color:#5c477e; }
html.light h-[data-h^=mk_del] { color:#ce9178; text-decoration:line-through; }
html.light h-[data-h^=mk_ins] { color:#b5cea8; text-decoration:underline; }
html.light h-[data-h^=mk_emph] { font-style:italic; }
html.light h-[data-h^=mk_stro] { font-weight:bold; }
html.light h-[data-h^=mk_emph_stro] { font-style:italic; font-weight:bold; }
html.light h-[data-h^=mk_ulin] { text-decoration:underline; }
html.light h-[data-h^=mk_emph_ulin] { font-style:italic; text-decoration:underline; }
html.light h-[data-h^=mk_stro_ulin] { font-weight:bold; text-decoration:underline; }
html.light h-[data-h^=mk_emph_stro_ulin] { font-weight:bold; font-style:italic; text-decoration:underline; }
html.light h-[data-h^=mk_strk] { text-decoration:line-through; }
html.light h-[data-h^=mk_emph_strk] { font-style:italic; text-decoration:line-through; }
html.light h-[data-h^=mk_stro_strk] { font-weight:bold; text-decoration:line-through; }
html.light h-[data-h^=mk_emph_stro_strk] { font-weight:bold; font-style:italic; text-decoration:line-through; }
html.light h-[data-h^=mk_ulin_strk] { text-decoration:underline line-through; }
html.light h-[data-h^=mk_emph_ulin_strk] { font-style:italic; text-decoration:underline line-through; }
html.light h-[data-h^=mk_stro_ulin_strk] { font-weight:bold; text-decoration:underline line-through; }
html.light h-[data-h^=mk_emph_stro_ulin_strk] { font-weight:bold; font-style:italic; text-decoration:underline line-through; }
html.light h-[data-h^=sh_cmd] { color:#00607c; }
html.light h-[data-h^=sh-opt] { color:#000000; }
html.light h-[data-h^=asm_ins] { color:#00607c; }
html.light h-[data-h^=asm_ins_psu] { color:#9f6807; }

html.dark h-[data-h^=err] { color:#ff0000; }
html.dark h-[data-h^=cmt] { color:#a2e08d; font-style:italic; }
html.dark h-[data-h^=cmt_dlim] { font-style:normal; }
html.dark h-[data-h^=val] { color:#f2d18d; }
html.dark h-[data-h^=num] { color:#f2d18d; }
html.dark h-[data-h^=num_dlim] { color:#e6b191; }
html.dark h-[data-h^=num_deco] { color:#e6b191; }
html.dark h-[data-h^=str] { color:#f2d18d; }
html.dark h-[data-h^=str_dlim] { color:#e6b191; }
html.dark h-[data-h^=str_deco] { color:#e6b191; }
html.dark h-[data-h^=esc] { color:#e6aee6; }
html.dark h-[data-h^=null] { color:#62ded6; }
html.dark h-[data-h^=bool] { color:#f2d18d; }
html.dark h-[data-h^=this] { color:#62ded6; }
html.dark h-[data-h^=mac] { color:#cc946e; }
html.dark h-[data-h^=id] { color:#f0f0f0; }
html.dark h-[data-h^=id_labl] { color:#d8eda6; }
html.dark h-[data-h^=kw] { color:#62ded6; }
html.dark h-[data-h^=sym] { color:#baa6b9; }
html.dark h-[data-h^=sym_punc] { color:#d0d0d0; }
html.dark h-[data-h^=sym_par] { color:#fa7878; }
html.dark h-[data-h^=sym_sqr] { color:#fa7878; }
html.dark h-[data-h^=sym_brac] { color:#fa7878; }
html.dark h-[data-h^=diff_head] { color:#777777; }
html.dark h-[data-h^=diff_head_hunk] { color:#edc385; }
html.dark h-[data-h^=diff_eq] { color:#e7e7e7; }
html.dark h-[data-h^=diff_del] { color:#ffdcd7; background-color:#67060c; }
html.dark h-[data-h^=diff_ins] { color:#aff5b4; background-color:#033a16; }
html.dark h-[data-h^=diff_mod] { color:#fff4d7; background-color:#674d06; }
html.dark h-[data-h^=mk_tag] { color:#62ded6; }
html.dark h-[data-h^=mk_attr] { color:#a4c4de; }
html.dark h-[data-h^=mk_del] { color:#ce9178; text-decoration:line-through; }
html.dark h-[data-h^=mk_ins] { color:#b5cea8; text-decoration:underline; }
html.dark h-[data-h^=mk_emph] { font-style:italic; }
html.dark h-[data-h^=mk_stro] { font-weight:bold; }
html.dark h-[data-h^=mk_emph_stro] { font-style:italic; font-weight:bold; }
html.dark h-[data-h^=mk_ulin] { text-decoration:underline; }
html.dark h-[data-h^=mk_emph_ulin] { font-style:italic; text-decoration:underline; }
html.dark h-[data-h^=mk_stro_ulin] { font-weight:bold; text-decoration:underline; }
html.dark h-[data-h^=mk_emph_stro_ulin] { font-weight:bold; font-style:italic; text-decoration:underline; }
html.dark h-[data-h^=mk_strk] { text-decoration:line-through; }
html.dark h-[data-h^=mk_emph_strk] { font-style:italic; text-decoration:line-through; }
html.dark h-[data-h^=mk_stro_strk] { font-weight:bold; text-decoration:line-through; }
html.dark h-[data-h^=mk_emph_stro_strk] { font-weight:bold; font-style:italic; text-decoration:line-through; }
html.dark h-[data-h^=mk_ulin_strk] { text-decoration:underline line-through; }
html.dark h-[data-h^=mk_emph_ulin_strk] { font-style:italic; text-decoration:underline line-through; }
html.dark h-[data-h^=mk_stro_ulin_strk] { font-weight:bold; text-decoration:underline line-through; }
html.dark h-[data-h^=mk_emph_stro_ulin_strk] { font-weight:bold; font-style:italic; text-decoration:underline line-through; }
html.dark h-[data-h^=sh_cmd] { color:#62ded6; }
html.dark h-[data-h^=sh-opt] { color:#f0f0f0; }
html.dark h-[data-h^=asm_ins] { color:#62ded6; }
html.dark h-[data-h^=asm_ins_psu] { color:#e6aee6; }
  </style>
  <script>
const theme = localStorage.getItem("cowel-theme");
if (theme !== null) {
    document.documentElement.className = theme;
}
  </script>
<title>Rename std::nontype,and make it broadly useful</title></head>
<body>
<div id=settings tabindex=0>
    <div id=theme-icon></div>
    <script>
        const settings = document.getElementById("settings");
        const htmlClasses = document.documentElement.classList;
        const themeIcon = document.getElementById("theme-icon");

        settings.classList.add("js");
        themeIcon.onclick = () => {
            const prefersDark = window.matchMedia("(prefers-color-scheme: dark)");
            const overrideClass = prefersDark.matches ? "light" : "dark";
            if (htmlClasses.contains("light")) {
                htmlClasses.remove("light");
                localStorage.removeItem("cowel-theme");
            } else if (htmlClasses.contains("dark")) {
                htmlClasses.remove("dark");
                localStorage.removeItem("cowel-theme");
            } else {
                htmlClasses.add(overrideClass);
                // to avoid legal issues or controversy in general,
                // we don't mess with local storage when the page is hosted in arbitrary places
                if (window.location.protocol === "file:") {
                    localStorage.setItem("cowel-theme", overrideClass);
                }
            }
        };
        settings.onkeydown = (e) => {
            if (e.key === "Enter" || e.key === " ") {
                event.preventDefault();
                themeIcon.onclick();
            }
        };
    </script>
</div>
<main>
<style>
  ins-block .para::before {
    display: none;
  }

  .stable-ref {
    float: right;
  }

  .five-way-poll {
    table-layout: fixed;
  }
  .five-way-poll td {
    width: 20%;
    text-align: center;
  }
</style>

<p><div class=wg21-head><h1>Rename <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code>,<br/>and make it broadly useful</h1>

<dl>
    <dt>Document number:</dt> <dd><a href=https://wg21%2elink/P3774R0>P3774R0</a></dd>
    <dt>Date:</dt>            <dd><tt->2025-07-15</tt-></dd>
    <dt>Audience:</dt>        <dd>LEWG</dd>
    <dt>Project:</dt>         <dd>ISO/IEC 14882 Programming Languages — C++, ISO/IEC JTC1/SC22/WG21</dd>
    <dt>Reply-to:</dt>        <dd>Jan Schultke &lt;<a href=mailto:janschultke@gmail%2ecom class=sans>janschultke@gmail.com</a>&gt;</dd>
    <dt>Co-authors:</dt>      <dd>Bronek Kozicki &lt;<a href=mailto:brok@incorrekt%2ecom class=sans>brok@incorrekt.com</a>&gt;,<br/>Tomasz Kamiński &lt;<a href=mailto:tomaszkam@gmail%2ecom class=sans>tomaszkam@gmail.com</a>&gt;</dd>
    <dt>GitHub Issue:</dt>    <dd><a href=https://wg21%2elink/P3774/github class=sans>wg21.link/P3774/github</a></dd>
    <dt>Source:</dt>          <dd><a href=https://github%2ecom/Eisenwave/cpp-proposals/blob/master/src/nontype-again%2ecow class=sans>github.com/Eisenwave/cpp-proposals/blob/master/src/nontype-again.cow</a></dd>
</dl>
<hr/>
</div></p>

<abstract-block><p><intro-></intro-> 
<a href="https://isocpp%2eorg/files/papers/P3740R1%2ehtml">[P3740R1]</a> proposed to rename <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> to <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>constant_arg</h-></code>,
now that the term "non-type template parameter" no longer exists in the C++26 standard.
This solution found weak consensus in LEWG,
but there was no time in LWG to review the change,
so it did not make it into C++26.
</p>
<p>We now propose to rename it to <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>fn</h-></code> in C++26.
We also propose to make it more broadly useful in C++29 by adding further members.
</p></abstract-block>

<h2 id=contents><a class=para href=#contents></a>Contents</h2>

<div class=toc><div class=toc-num data-level=2>1</div>
<a href=#introduction><h2>Introduction</h2></a>
<div class=toc-num data-level=3>1.1</div>
<a href=#why-did-we-need-nontype><h3>Why did we need a new <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> type?</h3></a>
<div class=toc-num data-level=3>1.2</div>
<a href=#nontype-refresher><h3>Refresher on what <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> accomplishes</h3></a>
<div class=toc-num data-level=2>2</div>
<a href=#proposed-solution><h2>Proposed solution</h2></a>
<div class=toc-num data-level=3>2.1</div>
<a href=#impact-on-std::function_ref><h3>Impact on <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>function_ref</h-></code></h3></a>
<div class=toc-num data-level=3>2.2</div>
<a href=#making-std::nontype-useful-for-use-in-algorithms-and-function-wrappers><h3>Making <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> useful for use in algorithms and function wrappers</h3></a>
<div class=toc-num data-level=3>2.3</div>
<a href=#making-std::nontype-useful-for-producing-function-pointers><h3>Making <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> useful for producing function pointers</h3></a>
<div class=toc-num data-level=3>2.4</div>
<a href=#naming><h3>Naming</h3></a>
<div class=toc-num data-level=3>2.5</div>
<a href=#change-of-header><h3>Change of header</h3></a>
<div class=toc-num data-level=3>2.6</div>
<a href=#interoperability-with-third-party-function_refs><h3>Interoperability with third-party <code><h- data-h=id>function_ref</h-></code>s</h3></a>
<div class=toc-num data-level=2>3</div>
<a href=#alternatives-considered><h2>Alternatives considered</h2></a>
<div class=toc-num data-level=3>3.1</div>
<a href=#stateless><h3>Using a <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>stateless</h-></code> constructor tag instead</h3></a>
<div class=toc-num data-level=3>3.2</div>
<a href=#removing-std::nontype-with-no-replacement-revisiting-for-c29><h3>Removing <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> with no replacement, revisiting for C++29</h3></a>
<div class=toc-num data-level=3>3.3</div>
<a href=#waiting-for-constexpr-function-parameters><h3>Waiting for <code><h- data-h=kw>constexpr</h-></code> function parameters</h3></a>
<div class=toc-num data-level=3>3.4</div>
<a href=#using-constant-wrapper><h3>Replacing <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> with <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>constant_wrapper</h-></code></h3></a>
<div class=toc-num data-level=2>4</div>
<a href=#implementation-experience><h2>Implementation experience</h2></a>
<div class=toc-num data-level=3>4.1</div>
<a href=#simple-rename-for-c26><h3>Simple rename for C++26</h3></a>
<div class=toc-num data-level=3>4.2</div>
<a href=#implementation-for-29><h3>Possible implementation of <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>fn</h-></code> for C++29</h3></a>
<div class=toc-num data-level=2>5</div>
<a href=#wording><h2>Wording</h2></a>
<div class=toc-num data-level=2>6</div>
<a href=#references><h2>References</h2></a>
<div class=toc-num data-level=2>7</div>
<a href=#wording-29><h2>Appendix — Follow-up wording for C++29</h2></a>
</div>

<h2 id=introduction><a class=para href=#introduction></a>1. Introduction</h2>

<p><a href="https://wg21%2elink/p2472r3">[P2472R3]</a> proposed additional overloads for the <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>function_ref</h-></code>
constructor which utilize a helper type <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code>.
This paper was merged into <a href="https://wg21%2elink/p0792r14">[P0792R14]</a>,
which was plenary-approved at Varna 2023 for C++26.
</p>
<p>The naming choice <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> makes very little sense
following <a href="https://wg21%2elink/p2841r1">[P2841R1]</a>, which introduced concept and variable template parameters.
Since those are not types either, what the standard used to call
"non-type template parameter" has been renamed to "constant template parameter".
</p>
<note-block><p><intro-></intro-> 
The class template is called <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id_type>nontype_t</h-></code>,
and the corresponding variable template is called <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code>.
This document refers to the feature as a whole as <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code>.
</p></note-block>

<p>Furthermore, the <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>constant_wrapper</h-></code> from <a href="https://wg21%2elink/p2781r9">[P2781R9]</a>
was accepted into C++26, and it seems like a good replacement for <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code>
at first glance.
At Sofia 2025, the choice to rename <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> to <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>constant_arg</h-></code>
instead of replacing it with <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>constant_wrapper</h-></code> achieved consensus,
by the narrowest of margins
(see <a href=https://wiki%2eedg%2ecom/bin/view/Wg21sofia2025/P3740>P3740 minutes</a>):
</p>
<blockquote>
<p><b>ACTION</b>:
Get feedback on the decision from standard library implementers.
</p>
<p><b>POLL</b>:
Forward “P3740R1: Last chance to fix std::nontype” selecting Option A
(change from nontype to constant_wrapper, also add overloads to other function wrappers (std::function))
to LWG for C++26 (if possible)
</p>
<table class=five-way-poll>
<tr><th>SF</th><th>F</th><th>N</th><th>A</th><th>SA</th></tr>
<tr><td>0</td> <td>4</td> <td>0</td> <td>7</td> <td>8</td></tr>
</table>

<p>Outcome: No consensus for change
</p>
<p><b>POLL</b>:
Forward “P3740R1: Last chance to fix std::nontype” selecting Option A
(change from nontype to constant_wrapper, DO NOT add overloads to other function wrappers (std::function))
to LWG for C++26 (if possible)
</p>
<table class=five-way-poll>
<tr><th>SF</th><th>F</th><th>N</th><th>A</th><th>SA</th></tr>
<tr><td>6</td> <td>7</td> <td>2</td> <td>6</td> <td>0</td></tr>
</table>

<p>Outcome: Weak consensus in favor
</p>
<p><b>POLL</b>:
Forward “P3740R1: Last chance to fix std::nontype” selecting Option B
(rename “std::nontype” to “std::constant_arg”)
to LWG for C++26 (if possible)
</p>
<table class=five-way-poll>
<tr><th>SF</th><th>F</th><th>N</th><th>A</th><th>SA</th></tr>
<tr><td>7</td> <td>9</td> <td>2</td> <td>2</td> <td>1</td></tr>
</table>

<p><mark>Outcome: Consensus in favor</mark></p>

<p><b>POLL</b>:
Forward “P3740R1: Last chance to fix std::nontype” selecting Option A
(change from nontype to constant_wrapper, DO NOT add overloads to other function wrappers (std::function))
instead of Option B (rename `std::nontype` to `std::constant_arg`)
to LWG for C++26 (if possible)
</p>
<table class=five-way-poll>
<tr><th>SF</th><th>F</th><th>N</th><th>A</th><th>SA</th></tr>
<tr><td>9</td> <td>4</td> <td>2</td> <td>4</td> <td>4</td></tr>
</table>

<p>Outcome: No consensus for change
</p></blockquote>

<p>However, LWG had no time to review this <em>extremely</em> last-minute change,
so it did not make it into C++26.
</p>
<note-block><p><intro-></intro-> 
The reason why the last poll does not change the LEWG decision
is that after the <mark>marked decision</mark>,
renaming <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> became the status quo,
and the last poll did not have enough votes to change that status quo.
</p></note-block>

<h3 id=why-did-we-need-nontype><a class=para href=#why-did-we-need-nontype></a>1.1. Why did we need a new <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> type?</h3>

<p>An obvious question may be why the existing <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>integral_constant</h-></code>
cannot be used instead.
This has multiple reasons:
</p><ul>
  <li><code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>integral_constant</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>class</h-> <h- data-h=id>T</h-><h- data-h=sym_punc>,</h-> <h- data-h=id>T</h-> <h- data-h=id>v</h-><h- data-h=sym_op>&gt;</h-></code> requires specifying the type separately.</li>
  <li><code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>integral_constant</h-></code> has a lengthy name.</li>
  <li><code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>integral_constant</h-></code> has a call operator which returns <code><h- data-h=id>v</h-></code>,
  which produces friction with the other constructors.</li>
</ul>

<h3 id=nontype-refresher><a class=para href=#nontype-refresher></a>1.2. Refresher on what <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> accomplishes</h3>

<p><code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> is used only within constructors of <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>function_ref</h-></code>:
</p>
<code-block><h- data-h=cmt_dlim>//</h-><h- data-h=cmt> constexpr and noexcept omitted for simplicity</h->
<h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>class</h-> <h- data-h=id>F</h-><h- data-h=sym_op>&gt;</h->         <h- data-h=id>function_ref</h-><h- data-h=sym_par>(</h-><h- data-h=id>F</h-><h- data-h=sym_op>*</h-><h- data-h=sym_par>)</h-><h- data-h=sym_punc>;</h->
<h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>class</h-> <h- data-h=id>F</h-><h- data-h=sym_op>&gt;</h->         <h- data-h=id>function_ref</h-><h- data-h=sym_par>(</h-><h- data-h=id>F</h-><h- data-h=sym_op>&amp;&amp;</h-><h- data-h=sym_par>)</h-><h- data-h=sym_punc>;</h->
<h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>auto</h-> <h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h->          <h- data-h=id>function_ref</h-><h- data-h=sym_par>(</h-><h- data-h=id_type>nontype_t</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h-><h- data-h=sym_par>)</h-><h- data-h=sym_punc>;</h->
<h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>auto</h-> <h- data-h=id>f</h-><h- data-h=sym_punc>,</h-> <h- data-h=kw>class</h-> <h- data-h=id>U</h-><h- data-h=sym_op>&gt;</h-> <h- data-h=id>function_ref</h-><h- data-h=sym_par>(</h-><h- data-h=id_type>nontype_t</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h-><h- data-h=sym_punc>,</h-> <h- data-h=id>U</h-><h- data-h=sym_op>&amp;&amp;</h-><h- data-h=sym_par>)</h-><h- data-h=sym_punc>;</h->
<h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>auto</h-> <h- data-h=id>f</h-><h- data-h=sym_punc>,</h-> <h- data-h=kw>class</h-> <h- data-h=id>T</h-><h- data-h=sym_op>&gt;</h-> <h- data-h=id>function_ref</h-><h- data-h=sym_par>(</h-><h- data-h=id_type>nontype_t</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h-><h- data-h=sym_punc>,</h-> <i><h- data-h=id>cv</h-></i> <h- data-h=id>T</h-><h- data-h=sym_op>*</h-><h- data-h=sym_par>)</h-><h- data-h=sym_punc>;</h-></code-block>

<p>Intuitively, <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>function_ref</h-></code> is the C++ counterpart to the C idiom of passing
<code><h- data-h=kw_type>void</h-><h- data-h=sym_op>*</h-></code> and a function pointer which that <code><h- data-h=kw_type>void</h-><h- data-h=sym_op>*</h-></code> is fed into,
as seen in <code><h- data-h=id>qsort</h-></code>.
It is common practice to provide a null pointer to <code><h- data-h=id>qsort</h-></code>
and thus rely on a "capture-less" comparison.
</p>
<p>With <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code>, <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>function_ref</h-></code> can support such use "capture-less" uses:
</p>
<code-block><h- data-h=cmt_dlim>//</h-><h- data-h=cmt> once again, some simplifications (no noexcept, no invoke, etc.) ...</h->
<h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>auto</h-> <h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h->
<h- data-h=id>function_ref</h-><h- data-h=sym_par>(</h-><h- data-h=id_type>nontype_t</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h-><h- data-h=sym_par>)</h-> <h- data-h=sym_brac>{</h->
  <h- data-h=cmt_dlim>//</h-><h- data-h=cmt> bound-entity is similar to the void* we would have stored in C.</h->
  <h- data-h=cmt_dlim>//</h-><h- data-h=cmt> We can leave it empty since we are constructing from some global callable.</h->
  <h- data-h=this>this</h-><h- data-h=sym_op>-&gt;</h-><i><h- data-h=id>bound-entity</h-></i> <h- data-h=sym_op>=</h-> <h- data-h=sym_brac>{</h-><h- data-h=sym_brac>}</h-><h- data-h=sym_punc>;</h->
  <h- data-h=cmt_dlim>//</h-><h- data-h=cmt> Note that lambdas with no captures can be converted to function pointers.</h->
  <h- data-h=this>this</h-><h- data-h=sym_op>-&gt;</h-><i><h- data-h=id>thunk-ptr</h-></i> <h- data-h=sym_op>=</h-> <h- data-h=sym_sqr>[</h-><h- data-h=sym_sqr>]</h-><h- data-h=sym_par>(</h-><i><h- data-h=id>BoundEntityType</h-></i><h- data-h=sym_punc>,</h-> <h- data-h=id>Args</h-><h- data-h=sym_op>&amp;&amp;</h-><h- data-h=sym_op>...</h-> <h- data-h=id>args</h-><h- data-h=sym_par>)</h-> <h- data-h=sym_op>-&gt;</h-> <h- data-h=id>R</h-> <h- data-h=sym_brac>{</h->
    <h- data-h=cmt_dlim>//</h-><h- data-h=cmt> Notice that we don't need to capture f.</h->
    <h- data-h=cmt_dlim>//</h-><h- data-h=cmt> This is only possible because f is a constant template parameter.</h->
    <h- data-h=kw_ctrl>return</h-> <h- data-h=id>f</h-><h- data-h=sym_par>(</h-><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>forward</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>Args</h-><h- data-h=sym_op>&amp;&amp;</h-><h- data-h=sym_op>&gt;</h-><h- data-h=sym_par>(</h-><h- data-h=id>args</h-><h- data-h=sym_par>)</h-><h- data-h=sym_op>...</h-><h- data-h=sym_par>)</h-><h- data-h=sym_punc>;</h->
  <h- data-h=sym_brac>}</h-><h- data-h=sym_punc>;</h->
<h- data-h=sym_brac>}</h-></code-block>

<p>Crucially, it would be impossible to create a <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>function_ref</h-></code>
from a function directly without this helper.
At best, we could store function pointer within <tt-><i><h- data-h=id>bound-entity</h-></i></tt->
and call that function pointer from within <tt-><i><h- data-h=id>bound-entity</h-></i></tt->.
This would introduce entirely unnecessary overhead.
</p>
<p>Besides overhead, we need <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> constructors to make a <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>function_ref</h-></code>
which has the functionality provided by a lambda,
but does not reference any specific lambda.
This is crucial for being able to store <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>function_ref</h-></code> somewhere long-term
without paying attention to the lifetime of the callable type it has been initialized with.
</p>
<h2 id=proposed-solution><a class=para href=#proposed-solution></a>2. Proposed solution</h2>

<p>We propose to rename <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id_type>nontype_t</h-></code> and <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code>
to <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id_type>fn_t</h-></code> and <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>fn</h-></code>.
Such a rename is well within the scope of an NB comment,
so it can be applied to C++26.
Furthermore, we make the type more broadly useful for C++29 by
</p><ul>
  <li>making <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id_type>fn_t</h-></code> convertible to function pointers, and</li>
  <li>
    giving it a call operator, which makes it usable in function wrappers
    other than <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>function_ref</h-></code> (with the same effect),
    as well as algorithms.
  </li>
</ul>

<p>Expressed in code, this would look as follows:
</p>
<diff-block>
<code-block class=borderless><h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>auto</h-> <h- data-h=id>V</h-><h- data-h=sym_op>&gt;</h->
  <h- data-h=kw>struct</h-> <del><h- data-h=id_type>nontype_t</h-></del> <ins><h- data-h=id_type>fn_t</h-></ins> <h- data-h=sym_brac>{</h->
    <h- data-h=kw>explicit</h-> <del><h- data-h=id_type>nontype_t</h-></del> <ins><h- data-h=id_type>fn_t</h-></ins><h- data-h=sym_par>(</h-><h- data-h=sym_par>)</h-> <h- data-h=sym_op>=</h-> <h- data-h=kw>default</h-><h- data-h=sym_punc>;</h->

    <ins><h- data-h=cmt_dlim>//</h-><h- data-h=cmt> </h-><f-serif><strong><h- data-h=cmt>SINCE C++29:</h-></strong></f-serif>
    <i><h- data-h=id>various new members …</h-></i></ins>
  <h- data-h=sym_brac>}</h-><h- data-h=sym_punc>;</h->
<del><h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>auto</h-> <h- data-h=id>V</h-><h- data-h=sym_op>&gt;</h-> <h- data-h=kw>constexpr</h-> <h- data-h=id_type>nontype_t</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>V</h-><h- data-h=sym_op>&gt;</h-> <h- data-h=id>nontype</h-><h- data-h=sym_brac>{</h-><h- data-h=sym_brac>}</h-><h- data-h=sym_punc>;</h-></del>
<ins><h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>auto</h-> <h- data-h=id>V</h-><h- data-h=sym_op>&gt;</h-> <h- data-h=kw>constexpr</h-> <h- data-h=id_type>fn_t</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>V</h-><h- data-h=sym_op>&gt;</h-> <h- data-h=id>fn</h-><h- data-h=sym_brac>{</h-><h- data-h=sym_brac>}</h-><h- data-h=sym_punc>;</h-></ins></code-block>
</diff-block>

<p>Among other reasons, keeping <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> instead of using <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>constant_wrapper</h-></code>
in its place was controversial because there was not enough motivation to keep both.
This is mainly because <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> provides no distinct functionality;
it is effectively <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>constant_wrapper</h-></code> without all of the extra operator overloads.
What we propose addresses this problem.
</p>
<h3 id=impact-on-std::function_ref><a class=para href=#impact-on-std::function_ref></a>2.1. Impact on <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>function_ref</h-></code></h3>

<p><code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>function_ref</h-></code> would handle <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>fn</h-></code> exactly the same as <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code>,
whether it has this C++29 functionality or not.
No C++26 code would be broken by adding those new members later.
That is because there are special constructors
for <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>function_ref</h-></code> taking <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code>,
and these always win in overload resolution,
whether <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> has a call operator or other members, or not.
</p>
<p>Furthermore, <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>function_ref</h-></code> needs to special-case <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> to provide the
<code><h- data-h=sym_par>(</h-><h- data-h=id_type>nontype_t</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h-><h- data-h=sym_punc>,</h-> <h- data-h=id>U</h-><h- data-h=sym_op>*</h-><h- data-h=sym_par>)</h-></code> and <code><h- data-h=sym_par>(</h-><h- data-h=id_type>nontype_t</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h-><h- data-h=sym_punc>,</h-> <h- data-h=id>U</h-><h- data-h=sym_op>&amp;&amp;</h-><h- data-h=sym_par>)</h-></code> constructors.
That is because only <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> provides the guarantee that its address
is irrelevant to <code><h- data-h=kw>operator</h-><h- data-h=sym_par>(</h-><h- data-h=sym_par>)</h-></code>, and that it is empty.
Thanks to that guarantee, <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>function_ref</h-></code> can use the
<code><i><h- data-h=id>bound-entity</h-></i></code> pointer to refer to some user-specified entity,
or simply make it <code><h- data-h=null>nullptr</h-></code>.
</p>
<h3 id=making-std::nontype-useful-for-use-in-algorithms-and-function-wrappers><a class=para href=#making-std::nontype-useful-for-use-in-algorithms-and-function-wrappers></a>2.2. Making <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> useful for use in algorithms and function wrappers</h3>

<p>A common recommendation when using standard library algorithms
is to avoid the use of function pointers.
That is because all invocations of of say,
<code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>for_each</h-></code> with function pointers of the same type
also result in identical instantiations.
</p>
<p>Therefore, rather than making easily inlined direct calls to lambda <code><h- data-h=kw>operator</h-><h- data-h=sym_par>(</h-><h- data-h=sym_par>)</h-></code>s,
<code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>for_each</h-><h- data-h=sym_op>&lt;</h-><h- data-h=cmt_dlim>/*</h-><h- data-h=cmt> ... </h-><h- data-h=cmt_dlim>*/</h-><h- data-h=sym_punc>,</h-> <h- data-h=kw_type>void</h-><h- data-h=sym_par>(</h-><h- data-h=sym_op>*</h-><h- data-h=sym_par>)</h-><h- data-h=sym_par>(</h-><h- data-h=kw_type>int</h-><h- data-h=sym_par>)</h-><h- data-h=sym_op>&gt;</h-></code> makes indirect calls through a function pointer,
and unless the algorithm is inlined and the function pointer is constant-folded,
this may result in degraded performance.
</p>
<p>The C++29 <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>fn</h-></code> solves this problem by "elevating"
the function pointer into the type system:
</p><code-block><h- data-h=kw_type>void</h-> <h- data-h=id>f</h-><h- data-h=sym_par>(</h-><h- data-h=kw_type>int</h-><h- data-h=sym_par>)</h-><h- data-h=sym_punc>;</h->
<h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>ranges</h-><h- data-h=sym_op>::</h-><h- data-h=id>for_each</h-><h- data-h=sym_par>(</h-><h- data-h=id>r</h-><h- data-h=sym_punc>,</h-> <h- data-h=id>f</h-><h- data-h=sym_par>)</h-><h- data-h=sym_punc>;</h->                           <h- data-h=cmt_dlim>//</h-><h- data-h=cmt> bad, passing function pointer</h->
<h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>ranges</h-><h- data-h=sym_op>::</h-><h- data-h=id>for_each</h-><h- data-h=sym_par>(</h-><h- data-h=id>r</h-><h- data-h=sym_punc>,</h-> <h- data-h=sym_sqr>[</h-><h- data-h=sym_sqr>]</h-><h- data-h=sym_par>(</h-><h- data-h=kw_type>int</h-> <h- data-h=id>x</h-><h- data-h=sym_par>)</h-> <h- data-h=sym_brac>{</h-> <h- data-h=kw_ctrl>return</h-> <h- data-h=id>f</h-><h- data-h=sym_par>(</h-><h- data-h=id>x</h-><h- data-h=sym_par>)</h-><h- data-h=sym_punc>;</h-> <h- data-h=sym_brac>}</h-><h- data-h=sym_par>)</h-><h- data-h=sym_punc>;</h->  <h- data-h=cmt_dlim>//</h-><h- data-h=cmt> OK, but clunky</h->
<h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>ranges</h-><h- data-h=sym_op>::</h-><h- data-h=id>for_each</h-><h- data-h=sym_par>(</h-><h- data-h=id>r</h-><h- data-h=sym_punc>,</h-> <h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>fn</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h-><h- data-h=sym_par>)</h-><h- data-h=sym_punc>;</h->                  <h- data-h=cmt_dlim>//</h-><h- data-h=cmt> OK, and less verbose</h-></code-block>

<note-block><p><intro-></intro-> 
<code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>constant_wrapper</h-></code> is not intended to address this use case.
The goal of <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>constant_wrapper</h-></code> is to accept
other <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>constant_wrapper</h-></code>s in its operator overloads,
and to return <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>constant_wrapper</h-></code>s from them,
so that computations are performed <em>entirely</em> within the type system.
</p>
<p>On the contrary, <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>fn</h-></code> would simply invoke the callable type it wraps,
forwarding arguments to it, and return the result of that invocation.
</p></note-block>

<p>Furthermore, C++29 <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>fn</h-></code> with a call operator could provide the same functionality
to <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>function</h-></code>, <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>move_</h->­only_function</code>,
and <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>copyable_</h->­function</code>;
it would simply be invocable like function pointers or lambdas.
Even without any constructors added to the standard wording,
implementations are free to apply small-object optimization,
i.e. no allocations are necessary,
which may improve quality of implementation further.
This optimization is simply part of the "as-if rule".
</p>
<p>A <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>fn</h-></code> with a call operator <em>just works</em>
with all function wrappers and algorithms,
exactly as expected,
and with the same semantics as it has in <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>function_ref</h-></code>.
</p>
<h3 id=making-std::nontype-useful-for-producing-function-pointers><a class=para href=#making-std::nontype-useful-for-producing-function-pointers></a>2.3. Making <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> useful for producing function pointers</h3>

<p>Since the C++29 <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>fn</h-></code> would be convertible to a function pointer,
it could also be used for producing and converting function pointers.
<code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>fn</h-></code> would be convertible to a function pointer type,
possibly with conversions of parameters and the returned value being applied,
not just if there is an "exact match" in signature.
</p>
<example-block><p><intro-></intro-> 
In the following code, <code><h- data-h=id>is_prime</h-></code> is wrapped in <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>fn</h-></code>,
which is convertible to <code><h- data-h=kw_type>bool</h-><h- data-h=sym_par>(</h-><h- data-h=sym_op>*</h-><h- data-h=sym_par>)</h-><h- data-h=sym_par>(</h-><h- data-h=kw_type>int</h-><h- data-h=sym_par>)</h-></code>, not just <code><h- data-h=kw_type>bool</h-><h- data-h=sym_par>(</h-><h- data-h=sym_op>*</h-><h- data-h=sym_par>)</h-><h- data-h=sym_par>(</h-><h- data-h=kw_type>long</h-><h- data-h=sym_par>)</h-></code>,
because <code><h- data-h=kw_type>int</h-></code> is convertible to <code><h- data-h=kw_type>long</h-> <h- data-h=kw_type>long</h-></code>.
</p>
<code-block><h- data-h=kw_type>bool</h-> <h- data-h=id>is_prime</h-><h- data-h=sym_par>(</h-><h- data-h=kw_type>long</h-> <h- data-h=kw_type>long</h-> <h- data-h=id>x</h-><h- data-h=sym_par>)</h-><h- data-h=sym_punc>;</h->
<h- data-h=kw_type>bool</h-><h- data-h=sym_par>(</h-><h- data-h=sym_op>*</h-><h- data-h=id>p</h-><h- data-h=sym_par>)</h-><h- data-h=sym_par>(</h-><h- data-h=kw_type>int</h-><h- data-h=sym_par>)</h-> <h- data-h=sym_op>=</h-> <h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>fn</h-><h- data-h=sym_op>&lt;</h-><h- data-h=sym_op>&amp;</h-><h- data-h=id>is_prime</h-><h- data-h=sym_op>&gt;</h-><h- data-h=sym_punc>;</h-></code-block>

<p>This may be useful for passing function pointers to C APIs when on the C++ side,
there is a slight mismatch between the C++ function signature
and the expected function pointer type.
</p></example-block>

<p>Similarly, C++29 <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>fn</h-></code> could be used to produce function pointers
to arbitrary callable types such as lambdas,
<code><h- data-h=kw>struct</h-></code>s with a call operator, etc.
All of this is feasible by creating a function "on the fly"
within a conversion operator template.
See <a href=#implementation-for-29>§4.2. Possible implementation of <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>fn</h-></code> for C++29</a> for specifics.
</p>
<h3 id=naming><a class=para href=#naming></a>2.4. Naming</h3>

<p>While using such a short and valuable name as <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>fn</h-></code>
would make little sense if <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> was simply being renamed with no further plans,
we have <em>big</em> plans.
<code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>fn</h-></code> would be <em>the</em> idiomatic way of lifting function pointers into
the type system.
</p>
<p><code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>fn</h-></code> is inspired by the <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>not_fn</h-></code> and <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>mem_fn</h-></code> function templates.
The future C++29 <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>fn</h-></code> would have similar purpose to <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>not_fn</h-></code>;
it just wouldn't negate the result of an invocation.
</p>
<p>However, such a short and valuable name is likely controversial.
A plausible alternative is to use
<code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>fw</h-></code> and <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>function_wrapper</h-></code>, analogous to
<code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>cw</h-></code> and <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>constant_wrapper</h-></code>,
or <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>const_fn</h-></code> and <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id_type>const_fn_t</h-></code>, analogous to <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>not_fn</h-></code>.
</p>
<note-block><p><intro-></intro-> 
Some authors initially had concerns about <code><h- data-h=id>fn</h-></code> possibly being used as a namespace
for functional programming in the future.
However, the standard library generally has verbose namespaces (e.g. <code><h- data-h=id>filesystem</h-></code>),
and suggestion to add shorthands (e.g. <code><h- data-h=id>fs</h-></code>) were historically rejected.
</p></note-block>

<h3 id=change-of-header><a class=para href=#change-of-header></a>2.5. Change of header</h3>

<p>Consider that <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>fn</h-></code> is a more "functional name"
than <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code>,
and that the goal is to follow up the rename with a call operator added in C++29,
<code><h- data-h=str>&lt;functional&gt;</h-></code> is a more appropriate header than <code><h- data-h=str>&lt;utility&gt;</h-></code>.
</p>
<p>Since <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>function_ref</h-></code> is located in <code><h- data-h=str>&lt;functional&gt;</h-></code> anyway,
this change is largely inconsequential.
It just means that users wouldn't be able to obtain <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>fn</h-></code>
through <code><h- data-h=str>&lt;utility&gt;</h-></code> on its own,
but we don't see strong motivation to do so.
</p>
<h3 id=interoperability-with-third-party-function_refs><a class=para href=#interoperability-with-third-party-function_refs></a>2.6. Interoperability with third-party <code><h- data-h=id>function_ref</h-></code>s</h3>

<p>It is worth noting that the proposed C++29 <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>fn</h-></code>
would work out-of-the-box with third-party <code><h- data-h=id>function_ref</h-></code> implementations
such as <code><h- data-h=id>llvm</h-><h- data-h=sym_op>::</h-><h- data-h=id>function_ref</h-></code>.
Notably, <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>fn</h-></code> would be a variable template,
meaning objects of type <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id_type>fn_t</h-></code> have static storage duration.
Therefore, binding an <code><h- data-h=id>llvm</h-><h- data-h=sym_op>::</h-><h- data-h=id>function_ref</h-></code> to <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>fn</h-></code>
does not risk creating a dangling reference.
</p>
<p>However, it is still possible to produce a dangling reference to <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>fn</h-></code>
by deliberately copying it and creating a temporary object:
</p>
<code-block><h- data-h=kw_type>void</h-> <h- data-h=id>f</h-><h- data-h=sym_par>(</h-><h- data-h=sym_par>)</h-><h- data-h=sym_punc>;</h->
<h- data-h=id>llvm</h-><h- data-h=sym_op>::</h-><h- data-h=id>function_ref</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw_type>void</h-><h- data-h=sym_par>(</h-><h- data-h=sym_par>)</h-><h- data-h=sym_op>&gt;</h-> <h- data-h=id>x</h-> <h- data-h=sym_op>=</h-> <h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>fn</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h-><h- data-h=sym_punc>;</h->       <h- data-h=cmt_dlim>//</h-><h- data-h=cmt> OK, safe</h->
<h- data-h=id>llvm</h-><h- data-h=sym_op>::</h-><h- data-h=id>function_ref</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw_type>void</h-><h- data-h=sym_par>(</h-><h- data-h=sym_par>)</h-><h- data-h=sym_op>&gt;</h-> <h- data-h=id>y</h-> <h- data-h=sym_op>=</h-> <h- data-h=kw>auto</h-><h- data-h=sym_par>(</h-><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>fn</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h-><h- data-h=sym_par>)</h-><h- data-h=sym_punc>;</h-> <h- data-h=cmt_dlim>//</h-><h- data-h=cmt> dangling reference</h-></code-block>

<p>This is also one of the reasons why <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>function_ref</h-></code>
should special-case <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id_type>fn_t</h-></code> in its set of constructors.
Other function wrappers need no special cases because they take ownership
over the wrapped callable anyway.
</p>
<h2 id=alternatives-considered><a class=para href=#alternatives-considered></a>3. Alternatives considered</h2>

<p>Besides the proposed approach,
there are other possible solutions.
However, the author position is that every one of them is worse than what is proposed.
</p>
<h3 id=stateless><a class=para href=#stateless></a>3.1. Using a <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>stateless</h-></code> constructor tag instead</h3>

<p><a href="https://isocpp%2eorg/files/papers/P3740R0%2ehtml">[P3740R0]</a> proposed to replace <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code>
with a set of constructors that take a <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>stateless</h-></code> constructor tag.
This idea essentially died the moment LEWG saw the Tony Table
which compares how users would pass function pointers to <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>function_ref</h-></code>
with <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>stateless</h-></code> tags compared to <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code>.
</p>
<p>This alternative was not polled,
but it was obvious during discussion that this option would not achieve consensus.
See <a href="https://isocpp%2eorg/files/papers/P3740R0%2ehtml">[P3740R0]</a> for details.
</p>
<h3 id=removing-std::nontype-with-no-replacement-revisiting-for-c29><a class=para href=#removing-std::nontype-with-no-replacement-revisiting-for-c29></a>3.2. Removing <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> with no replacement, revisiting for C++29</h3>

<p>Since there is a lot of active work in this area,
perhaps we could simply shove <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> into C++29 and deal with the problem later.
As demonstrated in <a href=#nontype-refresher>§1.2. Refresher on what <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> accomplishes</a>,
<code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> covers crucial use cases such as
</p>
<ul>
  <li>constructing <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>function_ref</h-></code> from a free function with no overhead, or</li>
  <li>constructing <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>function_ref</h-></code> from an existing function pointer and <code><h- data-h=kw_type>void</h-><h- data-h=sym_op>*</h-></code>,
  in the style of <code><h- data-h=id>qsort</h-></code>.</li>
</ul>

<p>This functionality is important to <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>function_ref</h-></code>,
and it has shipped in C++26 already.
None of the authors see it as reasonable to rip this functionality out entirely for C++26.
</p>
<h3 id=waiting-for-constexpr-function-parameters><a class=para href=#waiting-for-constexpr-function-parameters></a>3.3. Waiting for <code><h- data-h=kw>constexpr</h-></code> function parameters</h3>

<p><code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>integral_constant</h-></code>, <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>constant_wrapper</h-></code>, and <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code>
are – to an extent – temporary hacks.
If we were able to write
</p><code-block><h- data-h=id>function_ref</h-><h- data-h=sym_par>(</h-><h- data-h=kw>constexpr</h-> <h- data-h=id>F</h-><h- data-h=sym_op>*</h-><h- data-h=sym_par>)</h-><h- data-h=sym_punc>;</h-></code-block>
<p>… then the workaround of <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> would be obsolete.
</p>
<p>At Kona 2023, EWG showed enthusiasm for this option
when discussing <a href="https://wg21%2elink/p1045r1">[P1045R1]</a> "<code><h- data-h=kw>constexpr</h-></code> Function parameters".
</p>
<blockquote>
<p>Poll: P2781R3 “std::constexpr_v” and P1045R1 “constexpr function parameters”
EWG would like to solve th eproblem solved by std::constexpr_v in the language,
for example as proposed by P1045R1 or with “expression aliases”,
rather than solving it in library.
An implementation is desired. C++26 seems ambitious.
</p>
<table class=five-way-poll>
<tr><th>SF</th><th>F</th><th>N</th><th>A</th><th>SA</th></tr>
<tr><td>6</td> <td>8</td> <td>5</td> <td>1</td> <td>0</td></tr>
</table>
</blockquote>

<p>However, <a href="https://wg21%2elink/p1045r1">[P1045R1]</a> has been abandoned by the original author,
but picked up by a new author (proposal pending).
Nonetheless, <code><h- data-h=kw>constexpr</h-></code> function parameters do not entirely obsolete our design,
it is unclear if they will be in C++29, and
the <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> functionality has already shipped in C++26.
Therefore, it makes very little sense to wait for this feature.
</p>
<h3 id=using-constant-wrapper><a class=para href=#using-constant-wrapper></a>3.4. Replacing <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> with <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>constant_wrapper</h-></code></h3>

<p>The seemingly obvious solution is to use <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>constant_wrapper</h-></code> from <a href="https://wg21%2elink/p2781r9">[P2781R9]</a>.
The option to use <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>constant_</h->­wrapper</code> as a replacement for <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code>
was discussed during an LEWG telecon 2025-03-11.
</p>
<p>In short, the problems stem from the fact that <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>constant_wrapper</h-></code>
is already invocable; it already has a call operator,
whose semantics would be ignored by <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>function_ref</h-></code>,
in a way that is inconsistent with how <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>constant_wrapper</h-></code> behaves anywhere else.
</p>
<p>More details can be found in <a href="https://isocpp%2eorg/files/papers/P3740R1%2ehtml">[P3740R1]</a>,
as well as in <a href="https://wg21%2elink/P3792R0">[P3792R0]</a>
"Why <code><h- data-h=id>constant_wrapper</h-></code> is not a usable replacement for <code><h- data-h=id>nontype</h-></code>".
</p>
<p>In any case, LEWG already decided (with paper-thin consensus)
not to pursue this path.
</p>
<h2 id=implementation-experience><a class=para href=#implementation-experience></a>4. Implementation experience</h2>

<h3 id=simple-rename-for-c26><a class=para href=#simple-rename-for-c26></a>4.1. Simple rename for C++26</h3>

<p>Renaming <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> requires no implementation experience
because it is merely changing the name of a symbol;
it obviously works.
This is what we are proposing for C++26.
</p>
<h3 id=implementation-for-29><a class=para href=#implementation-for-29></a>4.2. Possible implementation of <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>fn</h-></code> for C++29</h3>

<p>An implementation for illustration purposes of the full C++29 <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>fn</h-></code>
may look as follows:
</p>
<code-block><h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>auto</h-> <h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h->
<h- data-h=kw>struct</h-> <h- data-h=id_type>fn_t</h->
<h- data-h=sym_brac>{</h->
  <h- data-h=kw>using</h-> <h- data-h=id>type</h-> <h- data-h=sym_op>=</h-> <h- data-h=kw>decltype</h-><h- data-h=sym_par>(</h-><h- data-h=id>f</h-><h- data-h=sym_par>)</h-><h- data-h=sym_punc>;</h->
  <h- data-h=kw>static</h-> <h- data-h=kw>constexpr</h-> <h- data-h=kw_type>bool</h-> <h- data-h=id>is_function_ptr</h->
    <h- data-h=sym_op>=</h-> <h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>is_function_v</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id_type>remove_pointer_t</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>type</h-><h- data-h=sym_op>&gt;&gt;</h-><h- data-h=sym_punc>;</h->

  <h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw_type>bool</h-> <h- data-h=id>Noex</h-><h- data-h=sym_punc>,</h-> <h- data-h=kw>typename</h-> <h- data-h=id>Ret</h-><h- data-h=sym_punc>,</h-> <h- data-h=kw>typename</h-><h- data-h=sym_op>...</h-> <h- data-h=id>Args</h-><h- data-h=sym_op>&gt;</h->
  <h- data-h=kw>using</h-> <h- data-h=id>func_type</h-> <h- data-h=sym_op>=</h-> <h- data-h=id>Ret</h-><h- data-h=sym_par>(</h-><h- data-h=sym_op>*</h-><h- data-h=sym_par>)</h-><h- data-h=sym_par>(</h-><h- data-h=id>Args</h-><h- data-h=sym_op>...</h-><h- data-h=sym_par>)</h-> <h- data-h=kw>noexcept</h-><h- data-h=sym_par>(</h-><h- data-h=id>Noex</h-><h- data-h=sym_par>)</h-><h- data-h=sym_punc>;</h->

  <h- data-h=kw>constexpr</h-> 
  <h- data-h=kw>operator</h-> <h- data-h=id>type</h-><h- data-h=sym_par>(</h-><h- data-h=sym_par>)</h-> <h- data-h=kw>const</h-> <h- data-h=kw>noexcept</h->
    <h- data-h=kw>requires</h-> <h- data-h=id>is_function_ptr</h->
  <h- data-h=sym_brac>{</h-> <h- data-h=kw_ctrl>return</h-> <h- data-h=id>f</h-><h- data-h=sym_punc>;</h-> <h- data-h=sym_brac>}</h->

  <h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw_type>bool</h-> <h- data-h=id>Noex</h-><h- data-h=sym_punc>,</h-> <h- data-h=kw>typename</h-> <h- data-h=id>Ret</h-><h- data-h=sym_punc>,</h-> <h- data-h=kw>typename</h-><h- data-h=sym_op>...</h-> <h- data-h=id>Args</h-><h- data-h=sym_op>&gt;</h->
    <h- data-h=kw>requires</h-> <h- data-h=sym_par>(</h-><h- data-h=id>Noex</h-> <h- data-h=sym_op>?</h-> <h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>is_nothrow_invocable_v</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>Ret</h-><h- data-h=sym_punc>,</h-> <h- data-h=id>type</h-> <h- data-h=kw>const</h-><h- data-h=sym_op>&amp;</h-><h- data-h=sym_punc>,</h-> <h- data-h=id>Args</h-><h- data-h=sym_op>...</h-><h- data-h=sym_op>&gt;</h-> 
                   <h- data-h=sym_punc>:</h-> <h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>is_invocable_r_v</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>Ret</h-><h- data-h=sym_punc>,</h-> <h- data-h=id>type</h-> <h- data-h=kw>const</h-><h- data-h=sym_op>&amp;</h-><h- data-h=sym_punc>,</h-> <h- data-h=id>Args</h-><h- data-h=sym_op>...</h-><h- data-h=sym_op>&gt;</h-><h- data-h=sym_par>)</h->
  <h- data-h=kw>constexpr</h-> 
  <h- data-h=kw>operator</h-> <h- data-h=id>func_type</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>Noex</h-><h- data-h=sym_punc>,</h-> <h- data-h=id>Ret</h-><h- data-h=sym_punc>,</h-> <h- data-h=id>Args</h-><h- data-h=sym_op>...</h-><h- data-h=sym_op>&gt;</h-><h- data-h=sym_par>(</h-><h- data-h=sym_par>)</h-> <h- data-h=kw>const</h->
  <h- data-h=sym_brac>{</h->
    <h- data-h=kw_ctrl>if</h-> <h- data-h=kw>constexpr</h-> <h- data-h=sym_par>(</h-><h- data-h=id>is_function_ptr</h-> <h- data-h=sym_op>&amp;&amp;</h-> <h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>is_convertible_v</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>type</h-><h- data-h=sym_punc>,</h-> <h- data-h=id>func_type</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>Noex</h-><h- data-h=sym_punc>,</h-> <h- data-h=id>Ret</h-><h- data-h=sym_punc>,</h-> <h- data-h=id>Args</h-><h- data-h=sym_op>...</h-><h- data-h=sym_op>&gt;&gt;</h-><h- data-h=sym_par>)</h->
      <h- data-h=kw_ctrl>return</h-> <h- data-h=id>f</h-><h- data-h=sym_punc>;</h->
    <h- data-h=kw_ctrl>else</h->
      <h- data-h=kw_ctrl>return</h-> <h- data-h=sym_sqr>[</h-><h- data-h=sym_sqr>]</h-><h- data-h=sym_par>(</h-><h- data-h=id>Args</h-><h- data-h=sym_op>...</h-> <h- data-h=id>args</h-><h- data-h=sym_par>)</h-> <h- data-h=kw>noexcept</h-><h- data-h=sym_par>(</h-><h- data-h=id>Noex</h-><h- data-h=sym_par>)</h-> <h- data-h=sym_op>-&gt;</h-> <h- data-h=id>Ret</h->
      <h- data-h=sym_brac>{</h-> <h- data-h=kw_ctrl>return</h-> <h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>invoke</h-><h- data-h=sym_par>(</h-><h- data-h=id>f</h-><h- data-h=sym_punc>,</h-> <h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>forward</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>Args</h-><h- data-h=sym_op>&gt;</h-><h- data-h=sym_par>(</h-><h- data-h=id>args</h-><h- data-h=sym_par>)</h-><h- data-h=sym_op>...</h-><h- data-h=sym_par>)</h-><h- data-h=sym_punc>;</h-> <h- data-h=sym_brac>}</h-><h- data-h=sym_punc>;</h->
  <h- data-h=sym_brac>}</h->

  <h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>typename</h-><h- data-h=sym_op>...</h-> <h- data-h=id>Args</h-><h- data-h=sym_op>&gt;</h->
    <h- data-h=kw>requires</h-> <h- data-h=sym_par>(</h-><h- data-h=sym_op>!</h-><h- data-h=id>is_function_ptr</h-><h- data-h=sym_par>)</h->
  <h- data-h=kw>static</h-> <h- data-h=kw>constexpr</h->
  <h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id_type>invoke_result_t</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>type</h-> <h- data-h=kw>const</h-><h- data-h=sym_op>&amp;</h-><h- data-h=sym_punc>,</h-> <h- data-h=id>Args</h-><h- data-h=sym_op>...</h-><h- data-h=sym_op>&gt;</h->
  <h- data-h=kw>operator</h-><h- data-h=sym_par>(</h-><h- data-h=sym_par>)</h-><h- data-h=sym_par>(</h-><h- data-h=id>Args</h-><h- data-h=sym_op>&amp;&amp;</h-><h- data-h=sym_op>...</h-> <h- data-h=id>args</h-><h- data-h=sym_par>)</h->
  <h- data-h=kw>noexcept</h-><h- data-h=sym_par>(</h-><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>is_nothrow_invocable_v</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>type</h-> <h- data-h=kw>const</h-><h- data-h=sym_op>&amp;</h-><h- data-h=sym_punc>,</h-> <h- data-h=id>Args</h-><h- data-h=sym_op>...</h-><h- data-h=sym_op>&gt;</h-><h- data-h=sym_par>)</h->
  <h- data-h=sym_brac>{</h-> <h- data-h=kw_ctrl>return</h-> <h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>invoke</h-><h- data-h=sym_par>(</h-><h- data-h=id>f</h-><h- data-h=sym_punc>,</h-> <h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>forward</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>Args</h-><h- data-h=sym_op>&gt;</h-><h- data-h=sym_par>(</h-><h- data-h=id>args</h-><h- data-h=sym_par>)</h-><h- data-h=sym_op>...</h-><h- data-h=sym_par>)</h-><h- data-h=sym_punc>;</h-> <h- data-h=sym_brac>}</h->
<h- data-h=sym_brac>}</h-><h- data-h=sym_punc>;</h->

<h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>auto</h-> <h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h->
<h- data-h=kw>constexpr</h-> <h- data-h=id_type>fn_t</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h-> <h- data-h=id>fn</h-><h- data-h=sym_punc>;</h-></code-block>

<p>Note that the wording strategy for <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id_type>fn_t</h-></code> in C++29
would leave its details largely unspecified,
which would allow for not implementing <code><h- data-h=kw>operator</h-><h- data-h=sym_par>(</h-><h- data-h=sym_par>)</h-></code> at all,
and for making <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id_type>fn_t</h-></code> invocable via surrogate function call
(implicit conversion to function pointer, then calling that pointer).
See <a href=#wording-29>§ Appendix — Follow-up wording for C++29</a></p>

<h2 id=wording><a class=para href=#wording></a>5. Wording</h2>

<style>
diff-block h-[data-h=cmt],
diff-block h-[data-h=cmt_dlim] {
  color: inherit !important;
}
</style>

<p>The following changes are relative to <a href="https://wg21%2elink/n5008">[N5008]</a>.
</p>





<p>In <a href=https://eel%2eis/c++draft/version%2esyn>[version.syn]</a>, update the feature-test macro:
</p>
<diff-block>
<code-block class=borderless><h- data-h=mac>#define __cpp_lib_function_ref </h-><del><h- data-h=mac>202306L</h-></del><h- data-h=mac> </h-><ins><h- data-h=mac>20XXXXL</h-></ins><h- data-h=mac> </h-><h- data-h=cmt_dlim>//</h-><h- data-h=cmt> </h-><f-serif><h- data-h=cmt>also in </h-><tt-><h- data-h=cmt>&lt;functional&gt;</h-></tt-></f-serif></code-block>
</diff-block>

<p>In <a href=https://eel%2eis/c++draft/utility%2esyn>[utility.syn]</a>,
delete the declarations of <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>nontype</h-></code> and <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id_type>nontype_t</h-></code>:
</p>
<del-block>
<code-block class=borderless><h- data-h=cmt_dlim>//</h-><h- data-h=cmt> </h-><f-serif><h- data-h=cmt>nontype argument tag</h-></f-serif>
<h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>auto</h-> <h- data-h=id>V</h-><h- data-h=sym_op>&gt;</h->
  <h- data-h=kw>struct</h-> <h- data-h=id_type>nontype_t</h-> <h- data-h=sym_brac>{</h->
    <h- data-h=kw>explicit</h-> <h- data-h=id_type>nontype_t</h-><h- data-h=sym_par>(</h-><h- data-h=sym_par>)</h-> <h- data-h=sym_op>=</h-> <h- data-h=kw>default</h-><h- data-h=sym_punc>;</h->
  <h- data-h=sym_brac>}</h-><h- data-h=sym_punc>;</h->
<h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>auto</h-> <h- data-h=id>V</h-><h- data-h=sym_op>&gt;</h-> <h- data-h=kw>constexpr</h-> <h- data-h=id_type>nontype_t</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>V</h-><h- data-h=sym_op>&gt;</h-> <h- data-h=id>nontype</h-><h- data-h=sym_brac>{</h-><h- data-h=sym_brac>}</h-><h- data-h=sym_punc>;</h-></code-block>
</del-block>

<p>In <a href=https://eel%2eis/c++draft/functional%2esyn>[functional.syn]</a>,
change the synopsis as follows:
</p>
<diff-block>
<code-block class=borderless><h- data-h=kw>namespace</h-> <h- data-h=id>std</h-> <h- data-h=sym_brac>{</h->
  […]

  <h- data-h=cmt_dlim>//</h-><h- data-h=cmt> </h-><f-serif><a href=https://eel%2eis/c++draft/func%2eidentity>[func.identity]</a><h- data-h=cmt>, identity</h-></f-serif>
  <h- data-h=kw>struct</h-> <h- data-h=id>identity</h-><h- data-h=sym_punc>;</h->                                                  <h- data-h=cmt_dlim>//</h-><h- data-h=cmt> </h-><f-serif><h- data-h=cmt>freestanding</h-></f-serif>

<ins>  <h- data-h=cmt_dlim>//</h-><h- data-h=cmt> </h-><f-serif><h- data-h=cmt>constant function wrapper</h-></f-serif>
  <h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>auto</h-> <h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h->
    <h- data-h=kw>struct</h-> <h- data-h=id_type>fn_t</h-> <h- data-h=sym_brac>{</h->
      <h- data-h=kw>explicit</h-> <h- data-h=id_type>fn_t</h-><h- data-h=sym_par>(</h-><h- data-h=sym_par>)</h-> <h- data-h=sym_op>=</h-> <h- data-h=kw>default</h-><h- data-h=sym_punc>;</h->
    <h- data-h=sym_brac>}</h-><h- data-h=sym_punc>;</h->
  <h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>auto</h-> <h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h-> <h- data-h=kw>constexpr</h-> <h- data-h=id_type>fn_t</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h-> <h- data-h=id>fn</h-><h- data-h=sym_punc>;</h-></ins>
  
  <h- data-h=cmt_dlim>//</h-><h- data-h=cmt> </h-><f-serif><a href=https://eel%2eis/c++draft/func%2enot%2efn>[func.not.fn]</a><h- data-h=cmt>, function template </h-><code><h- data-h=id>not_fn</h-></code></f-serif>
  <h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>class</h-> <h- data-h=id>F</h-><h- data-h=sym_op>&gt;</h-> <h- data-h=kw>constexpr</h-> <i><h- data-h=id>unspecified</h-></i> <h- data-h=id>not_fn</h-><h- data-h=sym_par>(</h-><h- data-h=id>F</h-><h- data-h=sym_op>&amp;&amp;</h-> <h- data-h=id>f</h-><h- data-h=sym_par>)</h-><h- data-h=sym_punc>;</h->            <h- data-h=cmt_dlim>//</h-><h- data-h=cmt> </h-><f-serif><h- data-h=cmt>freestanding</h-></f-serif>
  <h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>auto</h-> <h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h-> <h- data-h=kw>constexpr</h-> <i><h- data-h=id>unspecified</h-></i> <h- data-h=id>not_fn</h-><h- data-h=sym_par>(</h-><h- data-h=sym_par>)</h-> <h- data-h=kw>noexcept</h-><h- data-h=sym_punc>;</h->         <h- data-h=cmt_dlim>//</h-><h- data-h=cmt> </h-><f-serif><h- data-h=cmt>freestanding</h-></f-serif>

  […]
<h- data-h=sym_brac>}</h-></code-block>
</diff-block>

<p>In <a href=https://eel%2eis/c++draft/func%2ewrap%2eref%2eclass>[func.wrap.ref.class]</a>,
replace every occurrence of <code><h- data-h=id_type>nontype_t</h-></code> with <code><h- data-h=id_type>fn_t</h-></code>:
</p>
<diff-block>
<code-block class=borderless><h- data-h=kw>namespace</h-> <h- data-h=id>std</h-> <h- data-h=sym_brac>{</h->
  <h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>class</h-> <h- data-h=id>R</h-><h- data-h=sym_punc>,</h-> <h- data-h=kw>class</h-><h- data-h=sym_op>...</h-> <h- data-h=id>ArgTypes</h-><h- data-h=sym_op>&gt;</h->
  <h- data-h=kw>class</h-> <h- data-h=id>function_ref</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>R</h-><h- data-h=sym_par>(</h-><h- data-h=id>ArgTypes</h-><h- data-h=sym_op>...</h-><h- data-h=sym_par>)</h-> <i><h- data-h=id>cv</h-></i> <h- data-h=kw>noexcept</h-><h- data-h=sym_par>(</h-><i><h- data-h=id>noex</h-></i><h- data-h=sym_par>)</h-><h- data-h=sym_op>&gt;</h-> <h- data-h=sym_brac>{</h->
  <h- data-h=kw>public</h-><h- data-h=sym_punc>:</h->
    <h- data-h=cmt_dlim>//</h-><h- data-h=cmt> </h-><f-serif><h- data-h=cmt>[func.wrap.ref.ctor], constructors and assignment operators</h-></f-serif>
    <h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>class</h-> <h- data-h=id>F</h-><h- data-h=sym_op>&gt;</h-> <h- data-h=id>function_ref</h-><h- data-h=sym_par>(</h-><h- data-h=id>F</h-><h- data-h=sym_op>*</h-><h- data-h=sym_par>)</h-> <h- data-h=kw>noexcept</h-><h- data-h=sym_punc>;</h->
    <h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>class</h-> <h- data-h=id>F</h-><h- data-h=sym_op>&gt;</h-> <h- data-h=kw>constexpr</h-> <h- data-h=id>function_ref</h-><h- data-h=sym_par>(</h-><h- data-h=id>F</h-><h- data-h=sym_op>&amp;&amp;</h-><h- data-h=sym_par>)</h-> <h- data-h=kw>noexcept</h-><h- data-h=sym_punc>;</h->
    <h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>auto</h-> <h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h-> <h- data-h=kw>constexpr</h-> <h- data-h=id>function_ref</h-><h- data-h=sym_par>(</h-><del><h- data-h=id_type>nontype_t</h-></del> <ins><h- data-h=id_type>fn_t</h-></ins><h- data-h=sym_op>&lt;</h-><h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h-><h- data-h=sym_par>)</h-> <h- data-h=kw>noexcept</h-><h- data-h=sym_punc>;</h->
    <h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>auto</h-> <h- data-h=id>f</h-><h- data-h=sym_punc>,</h-> <h- data-h=kw>class</h-> <h- data-h=id>U</h-><h- data-h=sym_op>&gt;</h-> <h- data-h=kw>constexpr</h-> <h- data-h=id>function_ref</h-><h- data-h=sym_par>(</h-><del><h- data-h=id_type>nontype_t</h-></del> <ins><h- data-h=id_type>fn_t</h-></ins><h- data-h=sym_op>&lt;</h-><h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h-><h- data-h=sym_punc>,</h-> <h- data-h=id>U</h-><h- data-h=sym_op>&amp;&amp;</h-><h- data-h=sym_par>)</h-> <h- data-h=kw>noexcept</h-><h- data-h=sym_punc>;</h->
    <h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>auto</h-> <h- data-h=id>f</h-><h- data-h=sym_punc>,</h-> <h- data-h=kw>class</h-> <h- data-h=id>T</h-><h- data-h=sym_op>&gt;</h-> <h- data-h=kw>constexpr</h-> <h- data-h=id>function_ref</h-><h- data-h=sym_par>(</h-><del><h- data-h=id_type>nontype_t</h-></del> <ins><h- data-h=id_type>fn_t</h-></ins><h- data-h=sym_op>&lt;</h-><h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h-><h- data-h=sym_punc>,</h-> <i><h- data-h=id>cv</h-></i> <h- data-h=id>T</h-><h- data-h=sym_op>*</h-><h- data-h=sym_par>)</h-> <h- data-h=kw>noexcept</h-><h- data-h=sym_punc>;</h->

    <h- data-h=kw>constexpr</h-> <h- data-h=id>function_ref</h-><h- data-h=sym_par>(</h-><h- data-h=kw>const</h-> <h- data-h=id>function_ref</h-><h- data-h=sym_op>&amp;</h-><h- data-h=sym_par>)</h-> <h- data-h=kw>noexcept</h-> <h- data-h=sym_op>=</h-> <h- data-h=kw>default</h-><h- data-h=sym_punc>;</h->
    <h- data-h=kw>constexpr</h-> <h- data-h=id>function_ref</h-><h- data-h=sym_op>&amp;</h-> <h- data-h=kw>operator</h-><h- data-h=sym_op>=</h-><h- data-h=sym_par>(</h-><h- data-h=kw>const</h-> <h- data-h=id>function_ref</h-><h- data-h=sym_op>&amp;</h-><h- data-h=sym_par>)</h-> <h- data-h=kw>noexcept</h-> <h- data-h=sym_op>=</h-> <h- data-h=kw>default</h-><h- data-h=sym_punc>;</h->
    <h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>class</h-> <h- data-h=id>T</h-><h- data-h=sym_op>&gt;</h-> <h- data-h=id>function_ref</h-><h- data-h=sym_op>&amp;</h-> <h- data-h=kw>operator</h-><h- data-h=sym_op>=</h-><h- data-h=sym_par>(</h-><h- data-h=id>T</h-><h- data-h=sym_par>)</h-> <h- data-h=sym_op>=</h-> <h- data-h=kw>delete</h-><h- data-h=sym_punc>;</h->

    <h- data-h=cmt_dlim>//</h-><h- data-h=cmt> </h-><f-serif><h- data-h=cmt>[func.wrap.ref.inv], invocation</h-></f-serif>
    <h- data-h=id>R</h-> <h- data-h=kw>operator</h-><h- data-h=sym_par>(</h-><h- data-h=sym_par>)</h-><h- data-h=sym_par>(</h-><h- data-h=id>ArgTypes</h-><h- data-h=sym_op>...</h-><h- data-h=sym_par>)</h-> <h- data-h=kw>const</h-> <h- data-h=kw>noexcept</h-><h- data-h=sym_par>(</h-><i><h- data-h=id>noex</h-></i><h- data-h=sym_par>)</h-><h- data-h=sym_punc>;</h->

  <h- data-h=kw>private</h-><h- data-h=sym_punc>:</h->
    <h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>class</h-><h- data-h=sym_op>...</h-> <h- data-h=id>T</h-><h- data-h=sym_op>&gt;</h->
      <h- data-h=kw>static</h-> <h- data-h=kw>constexpr</h-> <h- data-h=kw_type>bool</h-> <i><h- data-h=id>is-invocable-using</h-></i> <h- data-h=sym_op>=</h-> <i><h- data-h=id>see below</h-></i><h- data-h=sym_punc>;</h->     <h- data-h=cmt_dlim>//</h-><h- data-h=cmt> </h-><f-serif><h- data-h=cmt>exposition only</h-></f-serif>

    <h- data-h=id>R</h-> <h- data-h=sym_par>(</h-><h- data-h=sym_op>*</h-><i><h- data-h=id>thunk-ptr</h-></i><h- data-h=sym_par>)</h-><h- data-h=sym_par>(</h-><i><h- data-h=id>BoundEntityType</h-></i><h- data-h=sym_punc>,</h-> <h- data-h=id>Args</h-><h- data-h=sym_op>&amp;&amp;</h-><h- data-h=sym_op>...</h-><h- data-h=sym_par>)</h-> <h- data-h=kw>noexcept</h-><h- data-h=sym_par>(</h-><i><h- data-h=id>noex</h-></i><h- data-h=sym_par>)</h-><h- data-h=sym_punc>;</h->  <h- data-h=cmt_dlim>//</h-><h- data-h=cmt> </h-><f-serif><h- data-h=cmt>exposition only</h-></f-serif>
    <i><h- data-h=id>BoundEntityType</h-></i> <i><h- data-h=id>bound-entity</h-></i><h- data-h=sym_punc>;</h->                               <h- data-h=cmt_dlim>//</h-><h- data-h=cmt> </h-><f-serif><h- data-h=cmt>exposition only</h-></f-serif>
  <h- data-h=sym_brac>}</h-><h- data-h=sym_punc>;</h->

  <h- data-h=cmt_dlim>//</h-><h- data-h=cmt> </h-><f-serif><h- data-h=cmt>[func.wrap.ref.deduct], deduction guides</h-></f-serif>
  <h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>class</h-> <h- data-h=id>F</h-><h- data-h=sym_op>&gt;</h->
    <h- data-h=id>function_ref</h-><h- data-h=sym_par>(</h-><h- data-h=id>F</h-><h- data-h=sym_op>*</h-><h- data-h=sym_par>)</h-> <h- data-h=sym_op>-&gt;</h-> <h- data-h=id>function_ref</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>F</h-><h- data-h=sym_op>&gt;</h-><h- data-h=sym_punc>;</h->
  <h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>auto</h-> <h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h->
    <h- data-h=id>function_ref</h-><h- data-h=sym_par>(</h-><del><h- data-h=id_type>nontype_t</h-></del> <ins><h- data-h=id_type>fn_t</h-></ins><h- data-h=sym_op>&lt;</h-><h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h-><h- data-h=sym_par>)</h-> <h- data-h=sym_op>-&gt;</h-> <h- data-h=id>function_ref</h-><h- data-h=sym_op>&lt;</h-><i><h- data-h=id>see below</h-></i><h- data-h=sym_op>&gt;</h-><h- data-h=sym_punc>;</h->
  <h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>auto</h-> <h- data-h=id>f</h-><h- data-h=sym_punc>,</h-> <h- data-h=kw>class</h-> <h- data-h=id>T</h-><h- data-h=sym_op>&gt;</h->
    <h- data-h=id>function_ref</h-><h- data-h=sym_par>(</h-><del><h- data-h=id_type>nontype_t</h-></del> <ins><h- data-h=id_type>fn_t</h-></ins><h- data-h=sym_op>&lt;</h-><h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h-><h- data-h=sym_punc>,</h-> <h- data-h=id>T</h-><h- data-h=sym_op>&amp;&amp;</h-><h- data-h=sym_par>)</h-> <h- data-h=sym_op>-&gt;</h-> <h- data-h=id>function_ref</h-><h- data-h=sym_op>&lt;</h-><i><h- data-h=id>see below</h-></i><h- data-h=sym_op>&gt;</h-><h- data-h=sym_punc>;</h->
<h- data-h=sym_brac>}</h-></code-block>
</diff-block>

<p>In <a href=https://eel%2eis/c++draft/func%2ewrap%2eref%2ector>[func.wrap.ref.ctor]</a>,
replace every occurrence of <code><h- data-h=id_type>nontype_t</h-></code> with <code><h- data-h=id_type>fn_t</h-></code>:
</p>
<diff-block>
<p>[…]</p>

<code-block class=borderless><h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>auto</h-> <h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h-> <h- data-h=kw>constexpr</h-> <h- data-h=id>function_ref</h-><h- data-h=sym_par>(</h-><del><h- data-h=id_type>nontype_t</h-></del> <ins><h- data-h=id_type>fn_t</h-></ins><h- data-h=sym_op>&lt;</h-><h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h-><h- data-h=sym_par>)</h-> <h- data-h=kw>noexcept</h-><h- data-h=sym_punc>;</h-></code-block>

<p>[…]</p>

<code-block class=borderless><h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>auto</h-> <h- data-h=id>f</h-><h- data-h=sym_punc>,</h-> <h- data-h=kw>class</h-> <h- data-h=id>U</h-><h- data-h=sym_op>&gt;</h->
  <h- data-h=kw>constexpr</h-> <h- data-h=id>function_ref</h-><h- data-h=sym_par>(</h-><del><h- data-h=id_type>nontype_t</h-></del> <ins><h- data-h=id_type>fn_t</h-></ins><h- data-h=sym_op>&lt;</h-><h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h-><h- data-h=sym_punc>,</h-> <h- data-h=id>U</h-><h- data-h=sym_op>&amp;&amp;</h-> <h- data-h=id>obj</h-><h- data-h=sym_par>)</h-> <h- data-h=kw>noexcept</h-><h- data-h=sym_punc>;</h-></code-block>

<p>[…]</p>

<code-block class=borderless><h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>auto</h-> <h- data-h=id>f</h-><h- data-h=sym_punc>,</h-> <h- data-h=kw>class</h-> <h- data-h=id>T</h-><h- data-h=sym_op>&gt;</h->
  <h- data-h=kw>constexpr</h-> <h- data-h=id>function_ref</h-><h- data-h=sym_par>(</h-><del><h- data-h=id_type>nontype_t</h-></del> <ins><h- data-h=id_type>fn_t</h-></ins><h- data-h=sym_op>&lt;</h-><h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h-><h- data-h=sym_punc>,</h-> <i><h- data-h=id>cv</h-></i> <h- data-h=id>T</h-><h- data-h=sym_op>*</h-> <h- data-h=id>obj</h-><h- data-h=sym_par>)</h-> <h- data-h=kw>noexcept</h-><h- data-h=sym_punc>;</h-></code-block>

<p>[…]</p>

<code-block class=borderless><h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>class</h-> <h- data-h=id>T</h-><h- data-h=sym_op>&gt;</h-> <h- data-h=id>function_ref</h-><h- data-h=sym_op>&amp;</h-> <h- data-h=kw>operator</h-><h- data-h=sym_op>=</h-><h- data-h=sym_par>(</h-><h- data-h=id>T</h-><h- data-h=sym_par>)</h-> <h- data-h=sym_op>=</h-> <h- data-h=kw>delete</h-><h- data-h=sym_punc>;</h-></code-block>
<div class=indent>
<p>21 <i>Constraints</i>:
</p><ul>
  <li><code><h- data-h=id>T</h-></code> is not the same type as <code><h- data-h=id>function_ref</h-></code>,</li>
  <li><code><h- data-h=id>is_pointer_v</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>T</h-><h- data-h=sym_op>&gt;</h-></code> is <code><h- data-h=bool>false</h-></code>, and</li>  
  <li><code><h- data-h=id>T</h-></code> is not a specialization of <del>nontype_t</del> <ins>fn_t</ins>.</li>  
</ul>
</div>
</diff-block>

<p>In <a href=https://eel%2eis/c++draft/func%2ewrap%2eref%2ededuct>[func.wrap.ref.deduct]</a>,
replace every occurrence of <code><h- data-h=id_type>nontype_t</h-></code> with <code><h- data-h=id_type>fn_t</h-></code>:
</p>
<diff-block>

<p>[…]</p>

<code-block class=borderless><h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>auto</h-> <h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h->
  <h- data-h=id>function_ref</h-><h- data-h=sym_par>(</h-><del><h- data-h=id_type>nontype_t</h-></del> <ins><h- data-h=id_type>fn_t</h-></ins><h- data-h=sym_op>&lt;</h-><h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h-><h- data-h=sym_par>)</h-> <h- data-h=sym_op>-&gt;</h-> <h- data-h=id>function_ref</h-><h- data-h=sym_op>&lt;</h-><i><h- data-h=id>see below</h-></i><h- data-h=sym_op>&gt;</h-><h- data-h=sym_punc>;</h-></code-block>

<p>[…]</p>

<code-block class=borderless><h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>auto</h-> <h- data-h=id>f</h-><h- data-h=sym_punc>,</h-> <h- data-h=kw>class</h-> <h- data-h=id>T</h-><h- data-h=sym_op>&gt;</h->
  <h- data-h=id>function_ref</h-><h- data-h=sym_par>(</h-><del><h- data-h=id_type>nontype_t</h-></del> <ins><h- data-h=id_type>fn_t</h-></ins><h- data-h=sym_op>&lt;</h-><h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h-><h- data-h=sym_punc>,</h-> <h- data-h=id>T</h-><h- data-h=sym_op>&amp;&amp;</h-><h- data-h=sym_par>)</h-> <h- data-h=sym_op>-&gt;</h-> <h- data-h=id>function_ref</h-><h- data-h=sym_op>&lt;</h-><i><h- data-h=id>see below</h-></i><h- data-h=sym_op>&gt;</h-><h- data-h=sym_punc>;</h-></code-block>

<p>[…]
</p></diff-block>

<h2 id=references><a class=para href=#references></a>6. References</h2>

<div class=bib><div id=bib-item-N5008 class=bib-item>
<a href="https://wg21%2elink/n5008">[N5008]</a>
<span class=bib-author>Thomas Köppe.</span>
<span class=bib-title>Working Draft, Programming Languages — C++</span>
<span class=bib-date>2025-03-15</span>
<a href="https://www%2eopen-std%2eorg/jtc1/sc22/wg21/docs/papers/2025/n5008%2epdf" class=bib-link>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/n5008.pdf</a></div><div id=bib-item-P0792R14 class=bib-item>
<a href="https://wg21%2elink/p0792r14">[P0792R14]</a>
<span class=bib-author>Vittorio Romeo, Zhihao Yuan, Jarrad Waterloo.</span>
<span class=bib-title>function_ref: a type-erased callable reference</span>
<span class=bib-date>2022-02-08</span>
<a href="https://www%2eopen-std%2eorg/jtc1/sc22/wg21/docs/papers/2023/p0792r14%2ehtml" class=bib-link>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p0792r14.html</a></div><div id=bib-item-P1045R1 class=bib-item>
<a href="https://wg21%2elink/p1045r1">[P1045R1]</a>
<span class=bib-author>David Stone.</span>
<span class=bib-title>constexpr Function Parameters</span>
<span class=bib-date>2019-09-27</span>
<a href="https://open-std%2eorg/JTC1/SC22/WG21/docs/papers/2019/p1045r1%2ehtml" class=bib-link>https://open-std.org/JTC1/SC22/WG21/docs/papers/2019/p1045r1.html</a></div><div id=bib-item-P2472R3 class=bib-item>
<a href="https://wg21%2elink/p2472r3">[P2472R3]</a>
<span class=bib-author>Jarrad J. Waterloo, Zhihao Yuan.</span>
<span class=bib-title>make function_ref more functional</span>
<span class=bib-date>2022-05-12</span>
<a href="https://www%2eopen-std%2eorg/jtc1/sc22/wg21/docs/papers/2022/p2472r3%2ehtml" class=bib-link>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2472r3.html</a></div><div id=bib-item-P2781R9 class=bib-item>
<a href="https://wg21%2elink/p2781r9">[P2781R9]</a>
<span class=bib-author>Hana Dusíková, Matthias Kretz, Zach Laine.</span>
<span class=bib-title>std::constant_wrapper</span>
<span class=bib-date>2025-06-17</span>
<a href="https://www%2eopen-std%2eorg/jtc1/sc22/wg21/docs/papers/2025/p2781r9%2ehtml" class=bib-link>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2781r9.html</a></div><div id=bib-item-P2841R1 class=bib-item>
<a href="https://wg21%2elink/p2841r1">[P2841R1]</a>
<span class=bib-author>Corentin Jabot.</span>
<span class=bib-title>Concept and variable-template template-parameters</span>
<span class=bib-date>2023-10-14</span>
<a href="https://www%2eopen-std%2eorg/jtc1/sc22/wg21/docs/papers/2023/p2841r1%2epdf" class=bib-link>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2841r1.pdf</a></div><div id=bib-item-P3312R1 class=bib-item>
<a href="https://wg21%2elink/p3312r1">[P3312R1]</a>
<span class=bib-author>Bengt Gustafsson.</span>
<span class=bib-title>Overload Set Types</span>
<span class=bib-date>2025-04-16</span>
<a href="https://www%2eopen-std%2eorg/jtc1/sc22/wg21/docs/papers/2025/p3312r1%2epdf" class=bib-link>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3312r1.pdf</a></div><div id=bib-item-P3740R0 class=bib-item>
<a href="https://isocpp%2eorg/files/papers/P3740R0%2ehtml">[P3740R0]</a>
<span class=bib-author>Jan Schultke.</span>
<span class=bib-title>Last chance to fix std::nontype</span>
<span class=bib-date>2025-06-14</span>
<a href="https://isocpp%2eorg/files/papers/P3740R0%2ehtml" class=bib-link>https://isocpp.org/files/papers/P3740R0.html</a></div><div id=bib-item-P3740R1 class=bib-item>
<a href="https://isocpp%2eorg/files/papers/P3740R1%2ehtml">[P3740R1]</a>
<span class=bib-author>Jan Schultke.</span>
<span class=bib-title>Last chance to fix std::nontype</span>
<span class=bib-date>2025-06-20</span>
<a href="https://isocpp%2eorg/files/papers/P3740R1%2ehtml" class=bib-link>https://isocpp.org/files/papers/P3740R1.html</a></div><div id=bib-item-P3792R0 class=bib-item>
<a href="https://wg21%2elink/P3792R0">[P3792R0]</a>
<span class=bib-author>Bronek Kozicki.</span>
<span class=bib-title>Why constant_wrapper is not a usable replacement for nontype</span>
<a href="https://wg21%2elink/P3792R0" class=bib-link>https://wg21.link/P3792R0</a></div><div id=bib-item-GitHub1 class=bib-item>
<a href="https://github%2ecom/MFHava/P2548/compare/master%2e%2e%2eBronek:P2548:bronek/with_constant_wrapper">[GitHub1]</a>
<span class=bib-author>Bronek Kozicki.</span>
<span class=bib-title>Reference implementation of function wrappers with std::constant_wrapper</span>
<span class=bib-date>2025-06-19</span>
<a href="https://github%2ecom/MFHava/P2548/compare/master%2e%2e%2eBronek:P2548:bronek/with_constant_wrapper" class=bib-link>https://github.com/MFHava/P2548/compare/master...Bronek:P2548:bronek/with_constant_wrapper</a></div><div id=bib-item-GitHub2 class=bib-item>
<a href="https://github%2ecom/Eisenwave/nontype_functional">[GitHub2]</a>
<span class=bib-author>Jan Schultke.</span>
<span class=bib-title>Reference implementation of std::function_ref with std::stateless</span>
<span class=bib-date>2025-06-14</span>
<a href="https://github%2ecom/Eisenwave/nontype_functional" class=bib-link>https://github.com/Eisenwave/nontype_functional</a></div></div>

<h2 id=wording-29><a class=para href=#wording-29></a>Appendix — Follow-up wording for C++29</h2>

<p>The following changes are relative to <a href="https://wg21%2elink/n5008">[N5008]</a>,
with the changes in <a href=#wording>§5. Wording</a> applied.
</p>
<p>In <a href=https://eel%2eis/c++draft/version%2esyn>[version.syn]</a>, create a feature-test macro:
</p>
<ins-block>
<code-block class=borderless><h- data-h=mac>#define __cpp_lib_fn 20XXXXL </h-><h- data-h=cmt_dlim>//</h-><h- data-h=cmt> </h-><f-serif><h- data-h=cmt>also in </h-><tt-><h- data-h=cmt>&lt;functional&gt;</h-></tt-></f-serif></code-block>
</ins-block>

<p>In <a href=https://eel%2eis/c++draft/functional%2esyn>[functional.syn]</a>,
change the declaration of <code><h- data-h=id>fn</h-></code> and <code><h- data-h=id_type>fn_t</h-></code> as follows:
</p>
<diff-block>
<code-block class=borderless><h- data-h=cmt_dlim>//</h-><h- data-h=cmt> </h-><f-serif><ins><h- data-h=cmt>[func.fn], </h-></ins><h- data-h=cmt>constant function wrapper</h-></f-serif>
<h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>auto</h-> <h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h->
  <h- data-h=kw>struct</h-> <h- data-h=id_type>fn_t</h-><del> <h- data-h=sym_brac>{</h->
    <h- data-h=kw>explicit</h-> <h- data-h=id_type>fn_t</h-><h- data-h=sym_par>(</h-><h- data-h=sym_par>)</h-> <h- data-h=sym_op>=</h-> <h- data-h=kw>default</h-><h- data-h=sym_punc>;</h->
  <h- data-h=sym_brac>}</h-></del><h- data-h=sym_punc>;</h->
<h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>auto</h-> <h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h-> <h- data-h=kw>constexpr</h-> <h- data-h=id_type>fn_t</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h-> <h- data-h=id>fn</h-><h- data-h=sym_punc>;</h-></code-block>
</diff-block>

<p>Between <a href=https://eel%2eis/c++draft/func%2eidentity>[func.identity]</a> and <a href=https://eel%2eis/c++draft/func%2enot%2efn>[func.not.fn]</a>,
insert a new subclause:
</p>
<ins-block>
<h3>Constant function wrapper <span class=stable-ref>[func.fn]</span></h3>

<code-block class=borderless><h- data-h=kw>template</h-><h- data-h=sym_op>&lt;</h-><h- data-h=kw>auto</h-> <h- data-h=id>f</h-><h- data-h=sym_op>&gt;</h->
  <h- data-h=kw>struct</h-> <h- data-h=id_type>fn_t</h-> <h- data-h=sym_brac>{</h->
    <h- data-h=kw>explicit</h-> <h- data-h=id_type>fn_t</h-><h- data-h=sym_par>(</h-><h- data-h=sym_par>)</h-> <h- data-h=sym_op>=</h-> <h- data-h=kw>default</h-><h- data-h=sym_punc>;</h->

    <i><h- data-h=id>see below</h-></i>
  <h- data-h=sym_brac>}</h-><h- data-h=sym_punc>;</h-></code-block>

<p>1
Let <code><h- data-h=id>ft</h-></code> be an object of type <code><h- data-h=id>FT</h-></code>
that is a (possibly const) specialization of <code><h- data-h=id_type>fn_t</h-></code>,
and let <code><h- data-h=id>cf</h-></code> be a template parameter object (<a href=https://eel%2eis/c++draft/temp%2eparam>[temp.param]</a>)
corresponding to the constant template argument of <code><h- data-h=id>FT</h-></code>.
Then:
</p><ul>
<li>
  <code><h- data-h=id>FT</h-></code> is a trivially copyable type,
  such that <code><h- data-h=id>FT</h-></code> models <code><h- data-h=id>semiregular</h-></code> and
  <code><h- data-h=id>is_empty_v</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>FT</h-><h- data-h=sym_op>&gt;</h-></code> is <code><h- data-h=bool>true</h-></code>;
</li>
<li>
  <code><h- data-h=id>ft</h-></code> is a simple call wrapper (<a href=https://eel%2eis/c++draft/func%2erequire>[func.require]</a>)
  with no state entities
  and with the call pattern <code><h- data-h=id>invoke</h-><h- data-h=sym_par>(</h-><h- data-h=id>cf</h-><h- data-h=sym_punc>,</h-> <h- data-h=id>call_args</h-><h- data-h=sym_op>...</h-><h- data-h=sym_par>)</h-></code>,
  where <code><h- data-h=id>call_args</h-></code> is an argument pack used in a function call expression (<a href=https://eel%2eis/c++draft/expr%2ecall>[expr.call]</a>),
  except that any parameter of the function selected by overload resolution
  may be initialized from the corresponding element of <code><h- data-h=id>call_args</h-></code>
  if that element is a prvalue;
</li>
<li>
  for any type <code><h- data-h=id>R</h-></code> and pack of types <code><h- data-h=id>Args</h-></code>,
  both <code><h- data-h=id>cf</h-></code> and <code><h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=id>move</h-><h- data-h=sym_par>(</h-><h- data-h=id>ft</h-><h- data-h=sym_par>)</h-></code> are convertible to:
  <ul>
    <li><code><h- data-h=id>R</h-><h- data-h=sym_par>(</h-><h- data-h=sym_op>*</h-><h- data-h=sym_par>)</h-><h- data-h=sym_par>(</h-><h- data-h=id>Args</h-><h- data-h=sym_op>...</h-><h- data-h=sym_par>)</h-></code> if <code><h- data-h=id>is_invocable_r_v</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>R</h-><h- data-h=sym_punc>,</h-> <h- data-h=kw>decltype</h-><h- data-h=sym_par>(</h-><h- data-h=id>cf</h-><h- data-h=sym_par>)</h-><h- data-h=sym_punc>,</h-> <h- data-h=id>Args</h-><h- data-h=sym_op>...</h-><h- data-h=sym_op>&gt;</h-></code> is <code><h- data-h=bool>true</h-></code>;</li>
    <li><code><h- data-h=id>R</h-><h- data-h=sym_par>(</h-><h- data-h=sym_op>*</h-><h- data-h=sym_par>)</h-><h- data-h=sym_par>(</h-><h- data-h=id>Args</h-><h- data-h=sym_op>...</h-><h- data-h=sym_par>)</h-> <h- data-h=kw>noexcept</h-></code> if <code><h- data-h=id>is_nothrow_invocable_r_v</h-><h- data-h=sym_op>&lt;</h-><h- data-h=id>R</h-><h- data-h=sym_punc>,</h-> <h- data-h=kw>decltype</h-><h- data-h=sym_par>(</h-><h- data-h=id>cf</h-><h- data-h=sym_par>)</h-><h- data-h=sym_punc>,</h-> <h- data-h=id>Args</h-><h- data-h=sym_op>...</h-></code> is <code><h- data-h=bool>true</h-></code>.</li>
  </ul>
  <wg21-block>[<i>Example</i>: 
  <code><br/>
  <h- data-h=kw_type>bool</h-> <h- data-h=id>is_even</h-><h- data-h=sym_par>(</h-><h- data-h=kw_type>long</h-><h- data-h=sym_par>)</h-><h- data-h=sym_punc>;</h-><br/>
  <h- data-h=kw_type>bool</h-><h- data-h=sym_par>(</h-><h- data-h=sym_op>*</h-><h- data-h=id>ptr</h-><h- data-h=sym_par>)</h-><h- data-h=sym_par>(</h-><h- data-h=kw_type>int</h-><h- data-h=sym_par>)</h-> <h- data-h=sym_op>=</h-> <h- data-h=id>std</h-><h- data-h=sym_op>::</h-><h- data-h=sym_punc>:</h-><h- data-h=id>fn</h-><h- data-h=sym_op>&lt;</h-><h- data-h=sym_op>&amp;</h-><h- data-h=id>is_even</h-><h- data-h=sym_op>&gt;</h-><h- data-h=sym_punc>;</h-><br/>
  </code>
   — <i>end example</i>]</wg21-block>
</li>
</ul>
</ins-block>













</main></body>
</html>
