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

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

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

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

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

div.rm pre, div.add pre { background-color: #f6f8fa; }
div.addu pre { background-color: var(--diff-ins); }
div.add, div.add pre { background-color: var(--diff-ins); }
div.addu blockquote {
border-left: 4px solid #00a000;
padding: 0 15px;
color: #006e28;
text-decoration: none;
}
div.addu blockquote code.sourceCode { text-decoration: none; }
div.addu blockquote pre { text-decoration: none; }
div.addu blockquote pre code { text-decoration: none; }
div.quote {
border-left: 7px solid #ccc;
background: #f9f9f9;
margin: 1.5em 10px;
padding-left: 20px;
}
code.diff span.va { color: #000000; background-color: var(--diff-ins); }
code.diff span.st { color: #000000; background-color: var(--diff-del); }
</style>
  <link href="data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAVoJEAN6CRADegkQAWIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wCCRAAAgkQAAIJEAACCRAAsgkQAvoJEAP+CRAD/gkQA/4JEAP+CRADAgkQALoJEAACCRAAAgkQAAP///wD///8AgkQAAIJEABSCRACSgkQA/IJEAP99PQD/dzMA/3czAP99PQD/gkQA/4JEAPyCRACUgkQAFIJEAAD///8A////AHw+AFiBQwDqgkQA/4BBAP9/PxP/uZd6/9rJtf/bybX/upd7/39AFP+AQQD/gkQA/4FDAOqAQgBc////AP///wDKklv4jlEa/3o7AP+PWC//8+3o///////////////////////z7un/kFox/35AAP+GRwD/mVYA+v///wD///8A0Zpk+NmibP+0d0T/8evj///////+/fv/1sKz/9bCs//9/fr//////+/m2/+NRwL/nloA/5xYAPj///8A////ANKaZPjRmGH/5cKh////////////k149/3UwAP91MQD/lmQ//86rhv+USg3/m1YA/5hSAP+bVgD4////AP///wDSmmT4zpJY/+/bx///////8+TV/8mLT/+TVx//gkIA/5lVAP+VTAD/x6B//7aEVv/JpH7/s39J+P///wD///8A0ppk+M6SWP/u2sf///////Pj1f/Nj1T/2KFs/8mOUv+eWhD/lEsA/8aee/+0glT/x6F7/7J8Rvj///8A////ANKaZPjRmGH/48Cf///////+/v7/2qt//82PVP/OkFX/37KJ/86siv+USg7/mVQA/5hRAP+bVgD4////AP///wDSmmT40ppk/9CVXP/69O////////7+/v/x4M//8d/P//7+/f//////9u7n/6tnJf+XUgD/nFgA+P///wD///8A0ppk+NKaZP/RmWL/1qNy//r07///////////////////////+vXw/9akdP/Wnmn/y5FY/6JfFvj///8A////ANKaZFTSmmTo0ppk/9GYYv/Ql1//5cWm//Hg0P/x4ND/5cWm/9GXYP/RmGH/0ppk/9KaZOjVnmpY////AP///wDSmmQA0ppkEtKaZI7SmmT60ppk/9CWX//OkVb/zpFW/9CWX//SmmT/0ppk/NKaZJDSmmQS0ppkAP///wD///8A0ppkANKaZADSmmQA0ppkKtKaZLrSmmT/0ppk/9KaZP/SmmT/0ppkvNKaZCrSmmQA0ppkANKaZAD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkUtKaZNzSmmTc0ppkVNKaZADSmmQA0ppkANKaZADSmmQA////AP5/AAD4HwAA4AcAAMADAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAMADAADgBwAA+B8AAP5/AAAoAAAAIAAAAEAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAyCRACMgkQA6oJEAOqCRACQgkQAEIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRABigkQA5oJEAP+CRAD/gkQA/4JEAP+CRADqgkQAZoJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAA4gkQAwoJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQAxIJEADyCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAP///wD///8A////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAWgkQAmIJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAJyCRAAYgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAdIJEAPCCRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAPSCRAB4gkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQASoJEANKCRAD/gkQA/4JEAP+CRAD/g0YA/39AAP9zLgD/bSQA/2shAP9rIQD/bSQA/3MuAP9/PwD/g0YA/4JEAP+CRAD/gkQA/4JEAP+CRADUgkQAToJEAACCRAAAgkQAAP///wD///8A////AP///wB+PwAAgkUAIoJEAKiCRAD/gkQA/4JEAP+CRAD/hEcA/4BBAP9sIwD/dTAA/5RfKv+viF7/vp56/76ee/+wiF7/lWAr/3YxAP9sIwD/f0AA/4RHAP+CRAD/gkQA/4JEAP+CRAD/gkQArIJEACaBQwAA////AP///wD///8A////AIBCAEBzNAD6f0EA/4NFAP+CRAD/gkQA/4VIAP92MwD/bSUA/6N1Tv/ezsL/////////////////////////////////38/D/6V3Uv9uJgD/dTEA/4VJAP+CRAD/gkQA/4JEAP+BQwD/fUAA/4FDAEj///8A////AP///wD///8AzJRd5qBlKf91NgD/dDUA/4JEAP+FSQD/cy4A/3YyAP/PuKP//////////////////////////////////////////////////////9K7qP94NQD/ciwA/4VJAP+CRAD/fkEA/35BAP+LSwD/mlYA6v///wD///8A////AP///wDdpnL/4qx3/8KJUv+PUhf/cTMA/3AsAP90LgD/4dK+/////////////////////////////////////////////////////////////////+TYxf91MAD/dTIA/31CAP+GRwD/llQA/6FcAP+gWwD8////AP///wD///8A////ANGZY/LSm2X/4ap3/92mcP+wdT3/byQA/8mwj////////////////////////////////////////////////////////////////////////////+LYxv9zLgP/jUoA/59bAP+hXAD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/RmWL/1p9q/9ubXv/XqXj////////////////////////////7+fD/vZyG/6BxS/+gcUr/vJuE//r37f//////////////////////3MOr/5dQBf+dVQD/nVkA/5xYAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmWP/yohJ//jo2P//////////////////////4NTG/4JDFf9lGAD/bSQA/20kAP9kGAD/fz8S/+Xb0f//////5NG9/6txN/+LOgD/m1QA/51aAP+cWAD/m1cA/5xYAP+cWADy////AP///wD///8A////ANKaZPLSmmT/0ppk/8+TWf/Unmv//v37//////////////////////+TWRr/VwsA/35AAP+ERgD/g0UA/4JGAP9lHgD/kFga/8KXX/+TRwD/jT4A/49CAP+VTQD/n10A/5xYAP+OQQD/lk4A/55cAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/y4tO/92yiP//////////////////////8NnE/8eCQP+rcTT/ez0A/3IyAP98PgD/gEMA/5FSAP+USwD/jj8A/5lUAP+JNwD/yqV2/694Mf+HNQD/jkAA/82rf/+laBj/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/LiUr/4byY///////////////////////gupX/0I5P/+Wuev/Lklz/l1sj/308AP+QSwD/ol0A/59aAP+aVQD/k0oA/8yoh///////+fXv/6pwO//Lp3v///////Pr4f+oay7y////AP///wD///8A////ANKaZPLSmmT/0ppk/8uJSv/hvJj//////////////////////+G7l//Jhkb/0ppk/96nc//fqXX/x4xO/6dkFP+QSQD/llEA/5xXAP+USgD/yaOA///////38uv/qG05/8ijdv//////8efb/6ZpLPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/zIxO/9yxh///////////////////////7dbA/8iEQf/Sm2X/0Zlj/9ScZv/eqHf/2KJv/7yAQf+XTgD/iToA/5lSAP+JNgD/yKFv/611LP+HNQD/jT8A/8qmeP+kZRT/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/Pk1n/1J5q//78+//////////////////+/fv/1aFv/8iEQv/Tm2b/0ppl/9GZY//Wn2z/1pZc/9eldf/Bl2b/kUcA/4w9AP+OQAD/lUwA/59eAP+cWQD/jT8A/5ZOAP+eXADy////AP///wD///8A////ANKaZPLSmmT/0ppk/9KZY//KiEn/8d/P///////////////////////47+f/05tm/8iCP//KiEj/yohJ/8eCP//RmGH//vfy///////n1sP/rXQ7/4k4AP+TTAD/nVoA/5xYAP+cVwD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/0ptl/8uLTf/aq37////////////////////////////+/fz/6c2y/961jv/etY7/6Myx//78+v//////////////////////3MWv/5xXD/+ORAD/mFQA/51ZAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmmT/0ppk/8mFRP/s1b//////////////////////////////////////////////////////////////////////////////+PD/0JFU/7NzMv+WUQD/kUsA/5tXAP+dWQDy////AP///wD///8A////ANKaZP/SmmT/0ppk/9KaZP/Sm2X/z5NZ/8yMT//z5NX/////////////////////////////////////////////////////////////////9Ofa/8yNUP/UmGH/36p5/8yTWv+qaSD/kksA/5ROAPz///8A////AP///wD///8A0ppk5NKaZP/SmmT/0ppk/9KaZP/TnGf/zY9T/82OUv/t1sD//////////////////////////////////////////////////////+7Yw//OkFX/zI5R/9OcZ//SmmP/26V0/9ymdf/BhUf/ol8R6P///wD///8A////AP///wDSmmQ80ppk9tKaZP/SmmT/0ppk/9KaZP/TnGj/zpFW/8qJSv/dson/8uHS//////////////////////////////////Lj0//etIv/y4lL/86QVf/TnGj/0ppk/9KaZP/RmWP/05xn/9ymdfjUnWdC////AP///wD///8A////ANKaZADSmmQc0ppkotKaZP/SmmT/0ppk/9KaZP/Tm2b/0Zli/8qJSf/NjlH/16Z3/+G8mP/myKr/5siq/+G8mP/Xp3f/zY5S/8qISf/RmGH/05tm/9KaZP/SmmT/0ppk/9KaZP/SmmSm0pljINWdaQD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkQtKaZMrSmmT/0ppk/9KaZP/SmmT/0ptl/9GYYf/Nj1P/y4lL/8qISP/KiEj/y4lK/82PU//RmGH/0ptl/9KaZP/SmmT/0ppk/9KaZP/SmmTO0ppkRtKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZGzSmmTu0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmTw0ppkcNKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZBLSmmSQ0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppklNKaZBTSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQy0ppkutKaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppkvtKaZDbSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkXNKaZODSmmT/0ppk/9KaZP/SmmT/0ppk5NKaZGDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkBtKaZIbSmmTo0ppk6tKaZIrSmmQK0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP/8P///+B///+AH//+AAf//AAD//AAAP/AAAA/gAAAHwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA+AAAAfwAAAP/AAAP/8AAP//gAH//+AH///4H////D//" rel="icon" />
  <!--[if lt IE 9]>
    <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
  <![endif]-->
  
</head>
<body>
<div class="wrapper">
<header id="title-block-header">
<h1 class="title" style="text-align:center">Adding functionality to placeholder types</h1>

<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P3171R0</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2024-03-04</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Project:</td>
    <td>Programming Language C++</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Audience:</td>
    <td>
      LEWG<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to:</td>
    <td>
      Peter Dimov<br>&lt;<a href="mailto:pdimov@gmail.com" class="email">pdimov@gmail.com</a>&gt;<br>
      Barry Revzin<br>&lt;<a href="mailto:barry.revzin@gmail.com" class="email">barry.revzin@gmail.com</a>&gt;<br>
    </td>
  </tr>
</table>

</header>
<div style="clear:both">
<div id="TOC" role="doc-toc">
<h1 id="toctitle">Contents</h1>
<ul>
<li><a href="#introduction"><span class="toc-section-number">1</span> Introduction<span></span></a></li>
<li><a href="#proposal"><span class="toc-section-number">2</span> Proposal<span></span></a>
<ul>
<li><a href="#dealing-with-x"><span class="toc-section-number">2.1</span> Dealing with <code class="sourceCode cpp"><span class="op">&amp;</span>x</code><span></span></a></li>
<li><a href="#additional-details"><span class="toc-section-number">2.2</span> Additional Details<span></span></a></li>
<li><a href="#implementation-experience"><span class="toc-section-number">2.3</span> Implementation Experience<span></span></a></li>
<li><a href="#wording"><span class="toc-section-number">2.4</span> Wording<span></span></a></li>
<li><a href="#feature-test-macro"><span class="toc-section-number">2.5</span> Feature-Test Macro<span></span></a></li>
</ul></li>
<li><a href="#bibliography"><span class="toc-section-number">3</span> References<span></span></a></li>
</ul>
</div>
<h1 data-number="1" style="border-bottom:1px solid #cccccc" id="introduction"><span class="header-section-number">1</span> Introduction<a href="#introduction" class="self-link"></a></h1>
<p>As noted in <span class="citation" data-cites="P2760R0">[<a href="#ref-P2760R0" role="doc-biblioref">P2760R0</a>]</span>, there are a lot of function objects for operators in the standard library, but several operators are missing. This paper proposes to add the functionality for all the missing operators, but to also do it in a different way than simply by adding function objects.</p>
<p><span class="citation" data-cites="Boost.Lambda2">[<a href="#ref-Boost.Lambda2" role="doc-biblioref">Boost.Lambda2</a>]</span> is a Boost library (written by Peter) which makes it possible to write very terse, simple operations, by building upon the <code class="sourceCode cpp">std<span class="op">::</span>bind</code> machinery. When Barry was implementing <code class="sourceCode cpp">std<span class="op">::</span>views<span class="op">::</span>zip</code> <span class="citation" data-cites="P2321R2">[<a href="#ref-P2321R2" role="doc-biblioref">P2321R2</a>]</span>, a range adaptor whose implementation requires forwarding various operators across a <code class="sourceCode cpp">tuple</code>, Boost.Lambda2 provided a very nice way to implement those operations. Here is a comparison between a hand-written lambda solution, function objects, and the placeholder solution that Lambda2 offers:</p>
<table>
<tr>
<th>
Handwritten Lambdas
</th>
<th>
Named Function Objects
</th>
<th>
Boost.Lambda2
</th>
</tr>
<tr>
<td>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1"></a><span class="kw">auto</span> <span class="kw">operator</span><span class="op">*()</span> <span class="kw">const</span> <span class="op">{</span></span>
<span id="cb1-2"><a href="#cb1-2"></a>  <span class="cf">return</span> tuple_transform<span class="op">(</span><em>current_</em>,</span>
<span id="cb1-3"><a href="#cb1-3"></a>    <span class="op">[](</span><span class="kw">auto</span><span class="op">&amp;</span> it<span class="op">)</span> <span class="op">-&gt;</span> <span class="kw">decltype</span><span class="op">(</span><span class="kw">auto</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-4"><a href="#cb1-4"></a>      <span class="cf">return</span> <span class="op">*</span>it;</span>
<span id="cb1-5"><a href="#cb1-5"></a>    <span class="op">})</span>;</span>
<span id="cb1-6"><a href="#cb1-6"></a><span class="op">}</span></span></code></pre></div>
</td>
<td>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1"></a><span class="kw">auto</span> <span class="kw">operator</span><span class="op">*()</span> <span class="kw">const</span> <span class="op">{</span></span>
<span id="cb2-2"><a href="#cb2-2"></a>  <span class="cf">return</span> tuple_transform<span class="op">(</span><em>current_</em>,</span>
<span id="cb2-3"><a href="#cb2-3"></a>    dereference<span class="op">{})</span>;</span>
<span id="cb2-4"><a href="#cb2-4"></a><span class="op">}</span></span></code></pre></div>
</td>
<td>
<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1"></a><span class="kw">auto</span> <span class="kw">operator</span><span class="op">*()</span> <span class="kw">const</span> <span class="op">{</span></span>
<span id="cb3-2"><a href="#cb3-2"></a>  <span class="cf">return</span> tuple_transform<span class="op">(</span><em>current_</em>, <span class="op">*</span>_1<span class="op">)</span>;</span>
<span id="cb3-3"><a href="#cb3-3"></a><span class="op">}</span></span></code></pre></div>
</td>
</tr>
<tr>
<td>
<div class="sourceCode" id="cb4"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb4-1"><a href="#cb4-1"></a><span class="kw">auto</span> <span class="kw">operator</span><span class="op">++()</span> <span class="op">-&gt;</span> iterator<span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb4-2"><a href="#cb4-2"></a>  tuple_for_each<span class="op">(</span><em>current_</em>,</span>
<span id="cb4-3"><a href="#cb4-3"></a>    <span class="op">[](</span><span class="kw">auto</span><span class="op">&amp;</span> it<span class="op">)</span> <span class="op">{</span> <span class="op">++</span>it; <span class="op">})</span>;</span>
<span id="cb4-4"><a href="#cb4-4"></a>  <span class="cf">return</span> <span class="op">*</span><span class="kw">this</span>;</span>
<span id="cb4-5"><a href="#cb4-5"></a><span class="op">}</span></span></code></pre></div>
</td>
<td>
<div class="sourceCode" id="cb5"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb5-1"><a href="#cb5-1"></a><span class="kw">auto</span> <span class="kw">operator</span><span class="op">++()</span> <span class="op">-&gt;</span> iterator<span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb5-2"><a href="#cb5-2"></a>  tuple_for_each<span class="op">(</span><em>current_</em>,</span>
<span id="cb5-3"><a href="#cb5-3"></a>    prefix_increment<span class="op">{})</span>;</span>
<span id="cb5-4"><a href="#cb5-4"></a>  <span class="cf">return</span> <span class="op">*</span><span class="kw">this</span>;</span>
<span id="cb5-5"><a href="#cb5-5"></a><span class="op">}</span></span></code></pre></div>
</td>
<td>
<div class="sourceCode" id="cb6"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb6-1"><a href="#cb6-1"></a><span class="kw">auto</span> <span class="kw">operator</span><span class="op">++()</span> <span class="op">-&gt;</span> iterator<span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb6-2"><a href="#cb6-2"></a>  tuple_for_each<span class="op">(</span><em>current_</em>, <span class="op">++</span>_1<span class="op">)</span>;</span>
<span id="cb6-3"><a href="#cb6-3"></a>  <span class="cf">return</span> <span class="op">*</span><span class="kw">this</span>;</span>
<span id="cb6-4"><a href="#cb6-4"></a><span class="op">}</span></span></code></pre></div>
</td>
</tr>
</table>
<p>It’s not just that the Lambda2 alternatives are overwhelmingly terser (it’s very hard to beat 3 characters for the dereference operation, especially compared to the handwritten lambda that must use <code class="sourceCode cpp"><span class="op">-&gt;</span> <span class="kw">decltype</span><span class="op">(</span><span class="kw">auto</span><span class="op">)</span></code> and is thus 46 characters long), they more directly express exactly the work being done.</p>
<p>Lambda2 also offers a more expressive way of doing common predicates, even in the case where the named function object already exists. Let’s take an example where you want to write a predicate for if the argument is negative (an example Barry previously wrote about on his blog <a href="https://brevzin.github.io/c++/2020/06/18/lambda-lambda-lambda/">here</a>), there are several ways to do it:</p>
<blockquote>
<div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-1"></a><span class="co">// hand-written lambda (28 characters)</span></span>
<span id="cb7-2"><a href="#cb7-2"></a><span class="op">[](</span><span class="kw">auto</span> e<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> e <span class="op">&lt;</span> <span class="dv">0</span>; <span class="op">}</span></span>
<span id="cb7-3"><a href="#cb7-3"></a></span>
<span id="cb7-4"><a href="#cb7-4"></a><span class="co">// attempting to use std::less{} (19 characters, but... uh...)</span></span>
<span id="cb7-5"><a href="#cb7-5"></a>bind<span class="op">(</span>less<span class="op">{}</span>, _1, <span class="dv">0</span><span class="op">)</span></span>
<span id="cb7-6"><a href="#cb7-6"></a></span>
<span id="cb7-7"><a href="#cb7-7"></a><span class="co">// Boost.Lambda2 (6 characters)</span></span>
<span id="cb7-8"><a href="#cb7-8"></a>_1 <span class="op">&lt;</span> <span class="dv">0</span></span></code></pre></div>
</blockquote>
<p>It also allows for an approach to address the question of projections. Let’s say that rather than finding a negative number, we want to find a <code class="sourceCode cpp">Point</code> whose <code class="sourceCode cpp">x</code> coordinate is negative:</p>
<blockquote>
<div class="sourceCode" id="cb8"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb8-1"><a href="#cb8-1"></a><span class="co">// hand-written lambda (30 characters)</span></span>
<span id="cb8-2"><a href="#cb8-2"></a>find_if<span class="op">(</span>points, <span class="op">[](</span>Point p<span class="op">){</span> <span class="cf">return</span> p<span class="op">.</span>x <span class="op">&lt;</span> <span class="dv">0</span>; <span class="op">})</span></span>
<span id="cb8-3"><a href="#cb8-3"></a></span>
<span id="cb8-4"><a href="#cb8-4"></a><span class="co">// Boost.Lambda 2 (18 characters)</span></span>
<span id="cb8-5"><a href="#cb8-5"></a>find_if<span class="op">(</span>points, _1<span class="op">-&gt;*&amp;</span>Point<span class="op">::</span>x <span class="op">&lt;</span> <span class="dv">0</span><span class="op">)</span></span></code></pre></div>
</blockquote>
<p>Or if the <code class="sourceCode cpp">x</code> coordinate is 0:</p>
<blockquote>
<div class="sourceCode" id="cb9"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb9-1"><a href="#cb9-1"></a><span class="co">// hand-written lambda (31 characters)</span></span>
<span id="cb9-2"><a href="#cb9-2"></a>find_if<span class="op">(</span>points, <span class="op">[](</span>Point p<span class="op">){</span> <span class="cf">return</span> p<span class="op">.</span>x <span class="op">==</span> <span class="dv">0</span>; <span class="op">})</span></span>
<span id="cb9-3"><a href="#cb9-3"></a></span>
<span id="cb9-4"><a href="#cb9-4"></a><span class="co">// using projection (12 characters, but cryptic)</span></span>
<span id="cb9-5"><a href="#cb9-5"></a>find<span class="op">(</span>points, <span class="dv">0</span>, <span class="op">&amp;</span>Point<span class="op">::</span>x<span class="op">)</span>;</span>
<span id="cb9-6"><a href="#cb9-6"></a></span>
<span id="cb9-7"><a href="#cb9-7"></a><span class="co">// Boost.Lambda 2 (19 characters)</span></span>
<span id="cb9-8"><a href="#cb9-8"></a>find_if<span class="op">(</span>points, _1<span class="op">-&gt;*&amp;</span>Point<span class="op">::</span>x <span class="op">==</span> <span class="dv">0</span><span class="op">)</span></span></code></pre></div>
</blockquote>
<p>Note that this latter usage could be improved significantly with something like <span class="citation" data-cites="P0060R0">[<a href="#ref-P0060R0" role="doc-biblioref">P0060R0</a>]</span>, which would actually allow for writing the predicate <code class="sourceCode cpp">_1<span class="op">.</span>x <span class="op">==</span> <span class="dv">0</span></code>. Which is difficult to beat.</p>
<p>You can see more examples in the <span class="citation" data-cites="Boost.Lambda2">[<a href="#ref-Boost.Lambda2" role="doc-biblioref">Boost.Lambda2</a>]</span> docs.</p>
<h1 data-number="2" style="border-bottom:1px solid #cccccc" id="proposal"><span class="header-section-number">2</span> Proposal<a href="#proposal" class="self-link"></a></h1>
<p>We propose to solve the issue of missing operator function objects in the standard library, as well as less-than-ergonomic lambda syntax for common predicates, by standardizing Boost.Lambda2. That is not a large proposal. The standard library already provides placeholders, <code class="sourceCode cpp">std<span class="op">::</span>placeholders<span class="op">::</span>_1</code> and friends. The standard library also already provides <code class="sourceCode cpp">std<span class="op">::</span>bind</code>, which is already implemented in a way that supports composition of bind expressions. All we need to do is add operators.</p>
<p>We additionally add the missing operator function objects. Now, most of the missing operator function objects and placeholder operators are easy enough to add, except one: taking an object’s address.</p>
<h2 data-number="2.1" id="dealing-with-x"><span class="header-section-number">2.1</span> Dealing with <code class="sourceCode cpp"><span class="op">&amp;</span>x</code><a href="#dealing-with-x" class="self-link"></a></h2>
<p>Now, this particular operator has two problems. First, making <code class="sourceCode cpp"><span class="op">&amp;</span>_1</code> work requires overload unary <code class="sourceCode cpp"><span class="kw">operator</span><span class="op">&amp;()</span></code> and that seems particularly questionable, even in cases like this. And in order to make this broadly useful, we couldn’t just overload it as a member function, it’d have to be a non-member - to support things like <code class="sourceCode cpp"><span class="op">&amp;*</span>_1</code> or any other combination of operations (which is part of the value of Lambda2). That’s a bit too much code for having <code class="sourceCode cpp"><span class="op">&amp;</span>x</code> not actually mean address-of.</p>
<p>We could potentially address this problem by adding in a function like <code class="sourceCode cpp">std<span class="op">::</span>placeholders<span class="op">::</span>addr<span class="op">(</span>x<span class="op">)</span></code> to mean addressof, so that instead of the cute <code class="sourceCode cpp"><span class="op">&amp;</span>_1</code> syntax you’d have to write <code class="sourceCode cpp">addr<span class="op">(</span>_1<span class="op">)</span></code>, which doesn’t have any issues with <code class="sourceCode cpp"><span class="op">&amp;</span></code>. Note that we cannot call this function <code class="sourceCode cpp">addressof</code> because while <code class="sourceCode cpp">addressof<span class="op">(</span>_1<span class="op">)</span></code> would be okay, <code class="sourceCode cpp">addressof<span class="op">(</span>addressof<span class="op">(</span>_1<span class="op">))</span></code> would become ambiguous (unless we also change <code class="sourceCode cpp">std<span class="op">::</span>addressof</code>, as we’re about to discuss).</p>
<p>Second, the obvious name for a function object taking the address of an object would be <code class="sourceCode cpp">std<span class="op">::</span>addressof</code> - but that already exists, as a function template. We cannot change <code class="sourceCode cpp">std<span class="op">::</span>addressof</code> to be a type - that would break all code that uses it. We could potentially change it to be an object - that would break only ADL uses of it, but given the nature of <code class="sourceCode cpp">std<span class="op">::</span>addressof</code> those seem pretty unlikely to be common, so it’s potentially a feasible route to take. It would also allow <code class="sourceCode cpp">_1<span class="op">-&gt;*</span>std<span class="op">::</span>addressof</code> (in the absence of <code class="sourceCode cpp">addr<span class="op">(</span>_1<span class="op">)</span></code> or similar formulation) as a short-ish way of expressing this.</p>
<p>For now, we’re going to punt on both problems and simply not support either a terse addressof on placeholders or providing an addressof function object.</p>
<h2 data-number="2.2" id="additional-details"><span class="header-section-number">2.2</span> Additional Details<a href="#additional-details" class="self-link"></a></h2>
<p>Boost.Lambda2 additionally provides two helper function objects: <code class="sourceCode cpp">first</code> and <code class="sourceCode cpp">second</code>, such that <code class="sourceCode cpp">_1<span class="op">-&gt;*</span>first</code> gives you the first element of the type (as by <code class="sourceCode cpp">std<span class="op">::</span>get<span class="op">&lt;</span><span class="dv">0</span><span class="op">&gt;</span></code>) and <code class="sourceCode cpp">_1<span class="op">-&gt;*</span>second</code> gives you the second. This is done by just providing function objects that perform these operations, similar to the proposed <code class="sourceCode cpp">get_key</code> and <code class="sourceCode cpp">get_value</code> <span class="citation" data-cites="P2769R1">[<a href="#ref-P2769R1" role="doc-biblioref">P2769R1</a>]</span>.</p>
<p>Also, while most operators take forwarding references, there are two additional overloads of <code class="sourceCode cpp"><span class="op">&gt;&gt;</span></code> and <code class="sourceCode cpp"><span class="op">&lt;&lt;</span></code> which are special-cased such that operations like <code class="sourceCode cpp">std<span class="op">::</span>cout <span class="op">&lt;&lt;</span> _1</code> work and capture <code class="sourceCode cpp">std<span class="op">::</span>cout</code> by reference. The special-casing is necessary because otherwise <code class="sourceCode cpp">std<span class="op">::</span>cout</code> would be captured by value, which is not allowed, and users would have to write <code class="sourceCode cpp">std<span class="op">::</span>ref<span class="op">(</span>std<span class="op">::</span>cout<span class="op">)</span> <span class="op">&lt;&lt;</span> _1</code>.</p>
<h2 data-number="2.3" id="implementation-experience"><span class="header-section-number">2.3</span> Implementation Experience<a href="#implementation-experience" class="self-link"></a></h2>
<p>Has been shipping in Boost since 1.77 (August 2021).</p>
<h2 data-number="2.4" id="wording"><span class="header-section-number">2.4</span> Wording<a href="#wording" class="self-link"></a></h2>
<p>Extend <span>22.10.2 <a href="https://wg21.link/functional.syn">[functional.syn]</a></span> to add the additional function objects:</p>
<blockquote>
<div>
<div class="sourceCode" id="cb10"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb10-1"><a href="#cb10-1"></a>namespace std {</span>
<span id="cb10-2"><a href="#cb10-2"></a></span>
<span id="cb10-3"><a href="#cb10-3"></a>  // ...</span>
<span id="cb10-4"><a href="#cb10-4"></a></span>
<span id="cb10-5"><a href="#cb10-5"></a>  // [bitwise.operations], bitwise operations</span>
<span id="cb10-6"><a href="#cb10-6"></a>  template&lt;class T = void&gt; struct bit_and;                                          // freestanding</span>
<span id="cb10-7"><a href="#cb10-7"></a>  template&lt;class T = void&gt; struct bit_or;                                           // freestanding</span>
<span id="cb10-8"><a href="#cb10-8"></a>  template&lt;class T = void&gt; struct bit_xor;                                          // freestanding</span>
<span id="cb10-9"><a href="#cb10-9"></a>  template&lt;class T = void&gt; struct bit_not;                                          // freestanding</span>
<span id="cb10-10"><a href="#cb10-10"></a>  template&lt;&gt; struct bit_and&lt;void&gt;;                                                  // freestanding</span>
<span id="cb10-11"><a href="#cb10-11"></a>  template&lt;&gt; struct bit_or&lt;void&gt;;                                                   // freestanding</span>
<span id="cb10-12"><a href="#cb10-12"></a>  template&lt;&gt; struct bit_xor&lt;void&gt;;                                                  // freestanding</span>
<span id="cb10-13"><a href="#cb10-13"></a>  template&lt;&gt; struct bit_not&lt;void&gt;;                                                  // freestanding</span>
<span id="cb10-14"><a href="#cb10-14"></a></span>
<span id="cb10-15"><a href="#cb10-15"></a><span class="va">+ // [additional.operations], additional transparent operations</span></span>
<span id="cb10-16"><a href="#cb10-16"></a><span class="va">+ struct subscript;                                                                 // freestanding</span></span>
<span id="cb10-17"><a href="#cb10-17"></a><span class="va">+ struct left_shift;                                                                // freestanding</span></span>
<span id="cb10-18"><a href="#cb10-18"></a><span class="va">+ struct right_shift;                                                               // freestanding</span></span>
<span id="cb10-19"><a href="#cb10-19"></a><span class="va">+ struct unary_plus;                                                                // freestanding</span></span>
<span id="cb10-20"><a href="#cb10-20"></a><span class="va">+ struct dereference;                                                               // freestanding</span></span>
<span id="cb10-21"><a href="#cb10-21"></a><span class="va">+ struct increment;                                                                 // freestanding</span></span>
<span id="cb10-22"><a href="#cb10-22"></a><span class="va">+ struct decrement;                                                                 // freestanding</span></span>
<span id="cb10-23"><a href="#cb10-23"></a><span class="va">+ struct postfix_increment;                                                         // freestanding</span></span>
<span id="cb10-24"><a href="#cb10-24"></a><span class="va">+ struct postfix_decrement;                                                         // freestanding</span></span>
<span id="cb10-25"><a href="#cb10-25"></a><span class="va">+</span></span>
<span id="cb10-26"><a href="#cb10-26"></a><span class="va">+ // [compound.operations], compound assignment operations</span></span>
<span id="cb10-27"><a href="#cb10-27"></a><span class="va">+ struct plus_equal;                                                                // freestanding</span></span>
<span id="cb10-28"><a href="#cb10-28"></a><span class="va">+ struct minus_equal;                                                               // freestanding</span></span>
<span id="cb10-29"><a href="#cb10-29"></a><span class="va">+ struct multiplies_equal;                                                          // freestanding</span></span>
<span id="cb10-30"><a href="#cb10-30"></a><span class="va">+ struct divides_equal;                                                             // freestanding</span></span>
<span id="cb10-31"><a href="#cb10-31"></a><span class="va">+ struct modulus_equal;                                                             // freestanding</span></span>
<span id="cb10-32"><a href="#cb10-32"></a><span class="va">+ struct bit_and_equal;                                                             // freestanding</span></span>
<span id="cb10-33"><a href="#cb10-33"></a><span class="va">+ struct bit_or_equal;                                                              // freestanding</span></span>
<span id="cb10-34"><a href="#cb10-34"></a><span class="va">+ struct bit_xor_equal;                                                             // freestanding</span></span>
<span id="cb10-35"><a href="#cb10-35"></a><span class="va">+ struct left_shift_equal;                                                          // freestanding</span></span>
<span id="cb10-36"><a href="#cb10-36"></a><span class="va">+ struct right_shift_equal;                                                         // freestanding</span></span>
<span id="cb10-37"><a href="#cb10-37"></a></span>
<span id="cb10-38"><a href="#cb10-38"></a>  // ...</span>
<span id="cb10-39"><a href="#cb10-39"></a></span>
<span id="cb10-40"><a href="#cb10-40"></a>}</span></code></pre></div>
</div>
</blockquote>
<p>Extend <span>22.10.2 <a href="https://wg21.link/functional.syn">[functional.syn]</a></span> to add operators:</p>
<blockquote>
<div>
<div class="sourceCode" id="cb11"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb11-1"><a href="#cb11-1"></a>namespace std {</span>
<span id="cb11-2"><a href="#cb11-2"></a>  // ...</span>
<span id="cb11-3"><a href="#cb11-3"></a>  namespace placeholders {</span>
<span id="cb11-4"><a href="#cb11-4"></a>    // M is the implementation-defined number of placeholders</span>
<span id="cb11-5"><a href="#cb11-5"></a>    <em>see below</em> _1;                                                                   // freestanding</span>
<span id="cb11-6"><a href="#cb11-6"></a>    <em>see below</em> _2;                                                                   // freestanding</span>
<span id="cb11-7"><a href="#cb11-7"></a>               .</span>
<span id="cb11-8"><a href="#cb11-8"></a>               .</span>
<span id="cb11-9"><a href="#cb11-9"></a>               .</span>
<span id="cb11-10"><a href="#cb11-10"></a>    <em>see below</em> _M;                                                                   // freestanding</span>
<span id="cb11-11"><a href="#cb11-11"></a></span>
<span id="cb11-12"><a href="#cb11-12"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator+(A&amp;&amp;, B&amp;&amp;);                  // freestanding</span></span>
<span id="cb11-13"><a href="#cb11-13"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator-(A&amp;&amp;, B&amp;&amp;);                  // freestanding</span></span>
<span id="cb11-14"><a href="#cb11-14"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator*(A&amp;&amp;, B&amp;&amp;);                  // freestanding</span></span>
<span id="cb11-15"><a href="#cb11-15"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator/(A&amp;&amp;, B&amp;&amp;);                  // freestanding</span></span>
<span id="cb11-16"><a href="#cb11-16"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator%(A&amp;&amp;, B&amp;&amp;);                  // freestanding</span></span>
<span id="cb11-17"><a href="#cb11-17"></a><span class="va">+   template&lt;class A&gt; constexpr auto operator-(A&amp;&amp;);                                // freestanding</span></span>
<span id="cb11-18"><a href="#cb11-18"></a><span class="va">+</span></span>
<span id="cb11-19"><a href="#cb11-19"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator==(A&amp;&amp;, B&amp;&amp;);                 // freestanding</span></span>
<span id="cb11-20"><a href="#cb11-20"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator!=(A&amp;&amp;, B&amp;&amp;);                 // freestanding</span></span>
<span id="cb11-21"><a href="#cb11-21"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator&lt;(A&amp;&amp;, B&amp;&amp;);                  // freestanding</span></span>
<span id="cb11-22"><a href="#cb11-22"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator&gt;(A&amp;&amp;, B&amp;&amp;);                  // freestanding</span></span>
<span id="cb11-23"><a href="#cb11-23"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator&lt;=(A&amp;&amp;, B&amp;&amp;);                 // freestanding</span></span>
<span id="cb11-24"><a href="#cb11-24"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator&gt;=(A&amp;&amp;, B&amp;&amp;);                 // freestanding</span></span>
<span id="cb11-25"><a href="#cb11-25"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator&lt;=&gt;(A&amp;&amp;, B&amp;&amp;);                // freestanding</span></span>
<span id="cb11-26"><a href="#cb11-26"></a><span class="va">+</span></span>
<span id="cb11-27"><a href="#cb11-27"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator&amp;&amp;(A&amp;&amp;, B&amp;&amp;);                 // freestanding</span></span>
<span id="cb11-28"><a href="#cb11-28"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator||(A&amp;&amp;, B&amp;&amp;);                 // freestanding</span></span>
<span id="cb11-29"><a href="#cb11-29"></a><span class="va">+   template&lt;class A&gt; constexpr auto operator!(A&amp;&amp;);                                // freestanding</span></span>
<span id="cb11-30"><a href="#cb11-30"></a><span class="va">+</span></span>
<span id="cb11-31"><a href="#cb11-31"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator&amp;(A&amp;&amp;, B&amp;&amp;);                  // freestanding</span></span>
<span id="cb11-32"><a href="#cb11-32"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator|(A&amp;&amp;, B&amp;&amp;);                  // freestanding</span></span>
<span id="cb11-33"><a href="#cb11-33"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator^(A&amp;&amp;, B&amp;&amp;);                  // freestanding</span></span>
<span id="cb11-34"><a href="#cb11-34"></a><span class="va">+   template&lt;class A&gt; constexpr auto operator~(A&amp;&amp;);                                // freestanding</span></span>
<span id="cb11-35"><a href="#cb11-35"></a><span class="va">+</span></span>
<span id="cb11-36"><a href="#cb11-36"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator&lt;&lt;(A&amp;&amp;, B&amp;&amp;);                 // freestanding</span></span>
<span id="cb11-37"><a href="#cb11-37"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator&lt;&lt;(A&amp;, B&amp;&amp;);                  // freestanding</span></span>
<span id="cb11-38"><a href="#cb11-38"></a><span class="va">+</span></span>
<span id="cb11-39"><a href="#cb11-39"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator&gt;&gt;(A&amp;&amp;, B&amp;&amp;);                 // freestanding</span></span>
<span id="cb11-40"><a href="#cb11-40"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator&gt;&gt;(A&amp;, B&amp;&amp;);                  // freestanding</span></span>
<span id="cb11-41"><a href="#cb11-41"></a><span class="va">+</span></span>
<span id="cb11-42"><a href="#cb11-42"></a><span class="va">+   template&lt;class A&gt; constexpr auto operator+(A&amp;&amp;);                                // freestanding</span></span>
<span id="cb11-43"><a href="#cb11-43"></a><span class="va">+   template&lt;class A&gt; constexpr auto operator*(A&amp;&amp;);                                // freestanding</span></span>
<span id="cb11-44"><a href="#cb11-44"></a><span class="va">+   template&lt;class A&gt; constexpr auto operator++(A&amp;&amp;);                               // freestanding</span></span>
<span id="cb11-45"><a href="#cb11-45"></a><span class="va">+   template&lt;class A&gt; constexpr auto operator--(A&amp;&amp;);                               // freestanding</span></span>
<span id="cb11-46"><a href="#cb11-46"></a><span class="va">+   template&lt;class A&gt; constexpr auto operator++(A&amp;&amp;, int);                          // freestanding</span></span>
<span id="cb11-47"><a href="#cb11-47"></a><span class="va">+   template&lt;class A&gt; constexpr auto operator--(A&amp;&amp;, int);                          // freestanding</span></span>
<span id="cb11-48"><a href="#cb11-48"></a><span class="va">+</span></span>
<span id="cb11-49"><a href="#cb11-49"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator+=(A&amp;&amp;, B&amp;&amp;);                 // freestanding</span></span>
<span id="cb11-50"><a href="#cb11-50"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator-=(A&amp;&amp;, B&amp;&amp;);                 // freestanding</span></span>
<span id="cb11-51"><a href="#cb11-51"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator*=(A&amp;&amp;, B&amp;&amp;);                 // freestanding</span></span>
<span id="cb11-52"><a href="#cb11-52"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator/=(A&amp;&amp;, B&amp;&amp;);                 // freestanding</span></span>
<span id="cb11-53"><a href="#cb11-53"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator%=(A&amp;&amp;, B&amp;&amp;);                 // freestanding</span></span>
<span id="cb11-54"><a href="#cb11-54"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator&amp;=(A&amp;&amp;, B&amp;&amp;);                 // freestanding</span></span>
<span id="cb11-55"><a href="#cb11-55"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator|=(A&amp;&amp;, B&amp;&amp;);                 // freestanding</span></span>
<span id="cb11-56"><a href="#cb11-56"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator^=(A&amp;&amp;, B&amp;&amp;);                 // freestanding</span></span>
<span id="cb11-57"><a href="#cb11-57"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator&lt;&lt;=(A&amp;&amp;, B&amp;&amp;);                // freestanding</span></span>
<span id="cb11-58"><a href="#cb11-58"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator&gt;&gt;=(A&amp;&amp;, B&amp;&amp;);                // freestanding</span></span>
<span id="cb11-59"><a href="#cb11-59"></a><span class="va">+</span></span>
<span id="cb11-60"><a href="#cb11-60"></a><span class="va">+   template&lt;class A, class B&gt; constexpr auto operator-&gt;*(A&amp;&amp;, B&amp;&amp;);                // freestanding</span></span>
<span id="cb11-61"><a href="#cb11-61"></a><span class="va">+</span></span>
<span id="cb11-62"><a href="#cb11-62"></a><span class="va">+   inline constexpr <em>unspecified</em> first = <em>unspecified</em>;                               // freestanding</span></span>
<span id="cb11-63"><a href="#cb11-63"></a><span class="va">+   inline constexpr <em>unspecified</em> second = <em>unspecifeid</em>;                              // freestanding</span></span>
<span id="cb11-64"><a href="#cb11-64"></a>  }</span>
<span id="cb11-65"><a href="#cb11-65"></a>  // ...</span>
<span id="cb11-66"><a href="#cb11-66"></a>}</span></code></pre></div>
</div>
</blockquote>
<p>Add two new sections after <span>22.10.11 <a href="https://wg21.link/bitwise.operations">[bitwise.operations]</a></span>:</p>
<blockquote>
<div class="addu">
<h3 id="additional-operations-additional.operations">Additional operations [additional.operations]<a href="#additional-operations-additional.operations" class="self-link"></a></h3>
<h4 id="class-subscript-additional.operations.subscript">Class <code class="sourceCode cpp">subscript</code> [additional.operations.subscript]<a href="#class-subscript-additional.operations.subscript" class="self-link"></a></h4>
<div class="sourceCode" id="cb12"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb12-1"><a href="#cb12-1"></a>struct subscript {</span>
<span id="cb12-2"><a href="#cb12-2"></a>  template&lt;class T, class U&gt; constexpr auto operator()(T&amp;&amp; t, U&amp;&amp; u) const</span>
<span id="cb12-3"><a href="#cb12-3"></a>    -&gt; decltype(std::forward&lt;T&gt;(t)[std::forward&lt;U&gt;(u)]);</span>
<span id="cb12-4"><a href="#cb12-4"></a></span>
<span id="cb12-5"><a href="#cb12-5"></a>  using is_transparent = <em>unspecified</em>;</span>
<span id="cb12-6"><a href="#cb12-6"></a>};</span></code></pre></div>
<div class="sourceCode" id="cb13"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb13-1"><a href="#cb13-1"></a>template&lt;class T, class U&gt; constexpr auto operator()(T&amp;&amp; t, U&amp;&amp; u) const</span>
<span id="cb13-2"><a href="#cb13-2"></a>  -&gt; decltype(std::forward&lt;T&gt;(t)[std::forward&lt;U&gt;(u)]);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_1" id="pnum_1">1</a></span> <em>Returns</em>: <code class="sourceCode cpp">std<span class="op">::</span>forward<span class="op">&lt;</span>T<span class="op">&gt;(</span>t<span class="op">)[</span>std<span class="op">::</span>forward<span class="op">&lt;</span>U<span class="op">&gt;(</span>u<span class="op">)]</span></code>.</p>
<h4 id="class-left_shift-additional.operations.left_shift">Class <code class="sourceCode cpp">left_shift</code> [additional.operations.left_shift]<a href="#class-left_shift-additional.operations.left_shift" class="self-link"></a></h4>
<div class="sourceCode" id="cb14"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb14-1"><a href="#cb14-1"></a>struct left_shift {</span>
<span id="cb14-2"><a href="#cb14-2"></a>  template&lt;class T, class U&gt; constexpr auto operator()(T&amp;&amp; t, U&amp;&amp; u) const</span>
<span id="cb14-3"><a href="#cb14-3"></a>    -&gt; decltype(std::forward&lt;T&gt;(t) &lt;&lt; std::forward&lt;U&gt;(u));</span>
<span id="cb14-4"><a href="#cb14-4"></a></span>
<span id="cb14-5"><a href="#cb14-5"></a>  using is_transparent = <em>unspecified</em>;</span>
<span id="cb14-6"><a href="#cb14-6"></a>};</span></code></pre></div>
<div class="sourceCode" id="cb15"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb15-1"><a href="#cb15-1"></a>template&lt;class T, class U&gt; constexpr auto operator()(T&amp;&amp; t, U&amp;&amp; u) const</span>
<span id="cb15-2"><a href="#cb15-2"></a>  -&gt; decltype(std::forward&lt;T&gt;(t) &lt;&lt; std::forward&lt;U&gt;(u));</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_2" id="pnum_2">1</a></span> <em>Returns</em>: <code class="sourceCode cpp">std<span class="op">::</span>forward<span class="op">&lt;</span>T<span class="op">&gt;(</span>t<span class="op">)</span> <span class="op">&lt;&lt;</span> std<span class="op">::</span>forward<span class="op">&lt;</span>U<span class="op">&gt;(</span>u<span class="op">)</span></code>.</p>
<h4 id="class-right_shift-additional.operations.right_shift">Class <code class="sourceCode cpp">right_shift</code> [additional.operations.right_shift]<a href="#class-right_shift-additional.operations.right_shift" class="self-link"></a></h4>
<div class="sourceCode" id="cb16"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb16-1"><a href="#cb16-1"></a>struct right_shift {</span>
<span id="cb16-2"><a href="#cb16-2"></a>  template&lt;class T, class U&gt; constexpr auto operator()(T&amp;&amp; t, U&amp;&amp; u) const</span>
<span id="cb16-3"><a href="#cb16-3"></a>    -&gt; decltype(std::forward&lt;T&gt;(t) &gt;&gt; std::forward&lt;U&gt;(u));</span>
<span id="cb16-4"><a href="#cb16-4"></a></span>
<span id="cb16-5"><a href="#cb16-5"></a>  using is_transparent = <em>unspecified</em>;</span>
<span id="cb16-6"><a href="#cb16-6"></a>};</span></code></pre></div>
<div class="sourceCode" id="cb17"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb17-1"><a href="#cb17-1"></a>template&lt;class T, class U&gt; constexpr auto operator()(T&amp;&amp; t, U&amp;&amp; u) const</span>
<span id="cb17-2"><a href="#cb17-2"></a>  -&gt; decltype(std::forward&lt;T&gt;(t) &gt;&gt; std::forward&lt;U&gt;(u));</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_3" id="pnum_3">1</a></span> <em>Returns</em>: <code class="sourceCode cpp">std<span class="op">::</span>forward<span class="op">&lt;</span>T<span class="op">&gt;(</span>t<span class="op">)</span> <span class="op">&gt;&gt;</span> std<span class="op">::</span>forward<span class="op">&lt;</span>U<span class="op">&gt;(</span>u<span class="op">)</span></code>.</p>
<h4 id="class-unary_plus-additional.operations.unary_plus">Class <code class="sourceCode cpp">unary_plus</code> [additional.operations.unary_plus]<a href="#class-unary_plus-additional.operations.unary_plus" class="self-link"></a></h4>
<div class="sourceCode" id="cb18"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb18-1"><a href="#cb18-1"></a>struct unary_plus {</span>
<span id="cb18-2"><a href="#cb18-2"></a>  template&lt;class T&gt; constexpr auto operator()(T&amp;&amp; t) const</span>
<span id="cb18-3"><a href="#cb18-3"></a>    -&gt; decltype(+std::forward&lt;T&gt;(t));</span>
<span id="cb18-4"><a href="#cb18-4"></a></span>
<span id="cb18-5"><a href="#cb18-5"></a>  using is_transparent = <em>unspecified</em>;</span>
<span id="cb18-6"><a href="#cb18-6"></a>};</span></code></pre></div>
<div class="sourceCode" id="cb19"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb19-1"><a href="#cb19-1"></a>template&lt;class T&gt; constexpr auto operator()(T&amp;&amp; t) const</span>
<span id="cb19-2"><a href="#cb19-2"></a>  -&gt; decltype(+std::forward&lt;T&gt;(t));</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_4" id="pnum_4">1</a></span> <em>Returns</em>: <code class="sourceCode cpp"><span class="op">+</span>std<span class="op">::</span>forward<span class="op">&lt;</span>T<span class="op">&gt;(</span>t<span class="op">)</span></code>.</p>
<h4 id="class-dereference-additional.operations.dereference">Class <code class="sourceCode cpp">dereference</code> [additional.operations.dereference]<a href="#class-dereference-additional.operations.dereference" class="self-link"></a></h4>
<div class="sourceCode" id="cb20"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb20-1"><a href="#cb20-1"></a>struct dereference {</span>
<span id="cb20-2"><a href="#cb20-2"></a>  template&lt;class T&gt; constexpr auto operator()(T&amp;&amp; t) const</span>
<span id="cb20-3"><a href="#cb20-3"></a>    -&gt; decltype(*std::forward&lt;T&gt;(t));</span>
<span id="cb20-4"><a href="#cb20-4"></a></span>
<span id="cb20-5"><a href="#cb20-5"></a>  using is_transparent = <em>unspecified</em>;</span>
<span id="cb20-6"><a href="#cb20-6"></a>};</span></code></pre></div>
<div class="sourceCode" id="cb21"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb21-1"><a href="#cb21-1"></a>template&lt;class T&gt; constexpr auto operator()(T&amp;&amp; t) const</span>
<span id="cb21-2"><a href="#cb21-2"></a>  -&gt; decltype(*std::forward&lt;T&gt;(t));</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_5" id="pnum_5">1</a></span> <em>Returns</em>: <code class="sourceCode cpp"><span class="op">*</span>std<span class="op">::</span>forward<span class="op">&lt;</span>T<span class="op">&gt;(</span>t<span class="op">)</span></code>.</p>
<h4 id="class-increment-additional.operations.increment">Class <code class="sourceCode cpp">increment</code> [additional.operations.increment]<a href="#class-increment-additional.operations.increment" class="self-link"></a></h4>
<div class="sourceCode" id="cb22"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb22-1"><a href="#cb22-1"></a>struct increment {</span>
<span id="cb22-2"><a href="#cb22-2"></a>  template&lt;class T&gt; constexpr auto operator()(T&amp;&amp; t) const</span>
<span id="cb22-3"><a href="#cb22-3"></a>    -&gt; decltype(++std::forward&lt;T&gt;(t));</span>
<span id="cb22-4"><a href="#cb22-4"></a></span>
<span id="cb22-5"><a href="#cb22-5"></a>  using is_transparent = <em>unspecified</em>;</span>
<span id="cb22-6"><a href="#cb22-6"></a>};</span></code></pre></div>
<div class="sourceCode" id="cb23"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb23-1"><a href="#cb23-1"></a>template&lt;class T&gt; constexpr auto operator()(T&amp;&amp; t) const</span>
<span id="cb23-2"><a href="#cb23-2"></a>  -&gt; decltype(++std::forward&lt;T&gt;(t));</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_6" id="pnum_6">1</a></span> <em>Returns</em>: <code class="sourceCode cpp"><span class="op">++</span>std<span class="op">::</span>forward<span class="op">&lt;</span>T<span class="op">&gt;(</span>t<span class="op">)</span></code>.</p>
<h4 id="class-decrement-additional.operations.decrement">Class <code class="sourceCode cpp">decrement</code> [additional.operations.decrement]<a href="#class-decrement-additional.operations.decrement" class="self-link"></a></h4>
<div class="sourceCode" id="cb24"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb24-1"><a href="#cb24-1"></a>struct decrement {</span>
<span id="cb24-2"><a href="#cb24-2"></a>  template&lt;class T&gt; constexpr auto operator()(T&amp;&amp; t) const</span>
<span id="cb24-3"><a href="#cb24-3"></a>    -&gt; decltype(--std::forward&lt;T&gt;(t));</span>
<span id="cb24-4"><a href="#cb24-4"></a></span>
<span id="cb24-5"><a href="#cb24-5"></a>  using is_transparent = <em>unspecified</em>;</span>
<span id="cb24-6"><a href="#cb24-6"></a>};</span></code></pre></div>
<div class="sourceCode" id="cb25"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb25-1"><a href="#cb25-1"></a>template&lt;class T&gt; constexpr auto operator()(T&amp;&amp; t) const</span>
<span id="cb25-2"><a href="#cb25-2"></a>  -&gt; decltype(--std::forward&lt;T&gt;(t));</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_7" id="pnum_7">1</a></span> <em>Returns</em>: <code class="sourceCode cpp"><span class="op">--</span>std<span class="op">::</span>forward<span class="op">&lt;</span>T<span class="op">&gt;(</span>t<span class="op">)</span></code>.</p>
<h4 id="class-postfix_increment-additional.operations.postfix_increment">Class <code class="sourceCode cpp">postfix_increment</code> [additional.operations.postfix_increment]<a href="#class-postfix_increment-additional.operations.postfix_increment" class="self-link"></a></h4>
<div class="sourceCode" id="cb26"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb26-1"><a href="#cb26-1"></a>struct postfix_increment {</span>
<span id="cb26-2"><a href="#cb26-2"></a>  template&lt;class T&gt; constexpr auto operator()(T&amp;&amp; t) const</span>
<span id="cb26-3"><a href="#cb26-3"></a>    -&gt; decltype(std::forward&lt;T&gt;(t)++);</span>
<span id="cb26-4"><a href="#cb26-4"></a></span>
<span id="cb26-5"><a href="#cb26-5"></a>  using is_transparent = <em>unspecified</em>;</span>
<span id="cb26-6"><a href="#cb26-6"></a>};</span></code></pre></div>
<div class="sourceCode" id="cb27"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb27-1"><a href="#cb27-1"></a>template&lt;class T&gt; constexpr auto operator()(T&amp;&amp; t) const</span>
<span id="cb27-2"><a href="#cb27-2"></a>  -&gt; decltype(std::forward&lt;T&gt;(t)++);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_8" id="pnum_8">1</a></span> <em>Returns</em>: <code class="sourceCode cpp">std<span class="op">::</span>forward<span class="op">&lt;</span>T<span class="op">&gt;(</span>t<span class="op">)++</span></code>.</p>
<h4 id="class-postfix_decrement-additional.operations.postfix_decrement">Class <code class="sourceCode cpp">postfix_decrement</code> [additional.operations.postfix_decrement]<a href="#class-postfix_decrement-additional.operations.postfix_decrement" class="self-link"></a></h4>
<div class="sourceCode" id="cb28"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb28-1"><a href="#cb28-1"></a>struct postfix_decrement {</span>
<span id="cb28-2"><a href="#cb28-2"></a>  template&lt;class T&gt; constexpr auto operator()(T&amp;&amp; t) const</span>
<span id="cb28-3"><a href="#cb28-3"></a>    -&gt; decltype(std::forward&lt;T&gt;(t)--);</span>
<span id="cb28-4"><a href="#cb28-4"></a></span>
<span id="cb28-5"><a href="#cb28-5"></a>  using is_transparent = <em>unspecified</em>;</span>
<span id="cb28-6"><a href="#cb28-6"></a>};</span></code></pre></div>
<div class="sourceCode" id="cb29"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb29-1"><a href="#cb29-1"></a>template&lt;class T&gt; constexpr auto operator()(T&amp;&amp; t) const</span>
<span id="cb29-2"><a href="#cb29-2"></a>  -&gt; decltype(std::forward&lt;T&gt;(t)--);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_9" id="pnum_9">1</a></span> <em>Returns</em>: <code class="sourceCode cpp">std<span class="op">::</span>forward<span class="op">&lt;</span>T<span class="op">&gt;(</span>t<span class="op">)--</span></code>.</p>
<h3 id="compound-assignment-operations-compound.operations">Compound assignment operations [compound.operations]<a href="#compound-assignment-operations-compound.operations" class="self-link"></a></h3>
<h4 id="class-plus_equal-compound.operations.plus_equal">Class <code class="sourceCode cpp">plus_equal</code> [compound.operations.plus_equal]<a href="#class-plus_equal-compound.operations.plus_equal" class="self-link"></a></h4>
<div class="sourceCode" id="cb30"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb30-1"><a href="#cb30-1"></a>struct plus_equal {</span>
<span id="cb30-2"><a href="#cb30-2"></a>  template&lt;class T, class U&gt; constexpr auto operator()(T&amp;&amp; t, U&amp;&amp; u) const</span>
<span id="cb30-3"><a href="#cb30-3"></a>    -&gt; decltype(std::forward&lt;T&gt;(t) += std::forward&lt;U&gt;(u));</span>
<span id="cb30-4"><a href="#cb30-4"></a></span>
<span id="cb30-5"><a href="#cb30-5"></a>  using is_transparent = <em>unspecified</em>;</span>
<span id="cb30-6"><a href="#cb30-6"></a>};</span></code></pre></div>
<div class="sourceCode" id="cb31"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb31-1"><a href="#cb31-1"></a>template&lt;class T, class U&gt; constexpr auto operator()(T&amp;&amp; t, U&amp;&amp; u) const</span>
<span id="cb31-2"><a href="#cb31-2"></a>  -&gt; decltype(std::forward&lt;T&gt;(t) += std::forward&lt;U&gt;(u));</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_10" id="pnum_10">1</a></span> <em>Returns</em>: <code class="sourceCode cpp">std<span class="op">::</span>forward<span class="op">&lt;</span>T<span class="op">&gt;(</span>t<span class="op">)</span> <span class="op">+=</span> std<span class="op">::</span>forward<span class="op">&lt;</span>U<span class="op">&gt;(</span>u<span class="op">)</span></code>.</p>
<h4 id="class-minus_equal-compound.operations.minus_equal">Class <code class="sourceCode cpp">minus_equal</code> [compound.operations.minus_equal]<a href="#class-minus_equal-compound.operations.minus_equal" class="self-link"></a></h4>
<div class="sourceCode" id="cb32"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb32-1"><a href="#cb32-1"></a>struct minus_equal {</span>
<span id="cb32-2"><a href="#cb32-2"></a>  template&lt;class T, class U&gt; constexpr auto operator()(T&amp;&amp; t, U&amp;&amp; u) const</span>
<span id="cb32-3"><a href="#cb32-3"></a>    -&gt; decltype(std::forward&lt;T&gt;(t) -= std::forward&lt;U&gt;(u));</span>
<span id="cb32-4"><a href="#cb32-4"></a></span>
<span id="cb32-5"><a href="#cb32-5"></a>  using is_transparent = <em>unspecified</em>;</span>
<span id="cb32-6"><a href="#cb32-6"></a>};</span></code></pre></div>
<div class="sourceCode" id="cb33"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb33-1"><a href="#cb33-1"></a>template&lt;class T, class U&gt; constexpr auto operator()(T&amp;&amp; t, U&amp;&amp; u) const</span>
<span id="cb33-2"><a href="#cb33-2"></a>  -&gt; decltype(std::forward&lt;T&gt;(t) -= std::forward&lt;U&gt;(u));</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_11" id="pnum_11">1</a></span> <em>Returns</em>: <code class="sourceCode cpp">std<span class="op">::</span>forward<span class="op">&lt;</span>T<span class="op">&gt;(</span>t<span class="op">)</span> <span class="op">-=</span> std<span class="op">::</span>forward<span class="op">&lt;</span>U<span class="op">&gt;(</span>u<span class="op">)</span></code>.</p>
<h4 id="class-multiplies_equal-compound.operations.multiplies_equal">Class <code class="sourceCode cpp">multiplies_equal</code> [compound.operations.multiplies_equal]<a href="#class-multiplies_equal-compound.operations.multiplies_equal" class="self-link"></a></h4>
<div class="sourceCode" id="cb34"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb34-1"><a href="#cb34-1"></a>struct multiplies_equal {</span>
<span id="cb34-2"><a href="#cb34-2"></a>  template&lt;class T, class U&gt; constexpr auto operator()(T&amp;&amp; t, U&amp;&amp; u) const</span>
<span id="cb34-3"><a href="#cb34-3"></a>    -&gt; decltype(std::forward&lt;T&gt;(t) *= std::forward&lt;U&gt;(u));</span>
<span id="cb34-4"><a href="#cb34-4"></a></span>
<span id="cb34-5"><a href="#cb34-5"></a>  using is_transparent = <em>unspecified</em>;</span>
<span id="cb34-6"><a href="#cb34-6"></a>};</span></code></pre></div>
<div class="sourceCode" id="cb35"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb35-1"><a href="#cb35-1"></a>template&lt;class T, class U&gt; constexpr auto operator()(T&amp;&amp; t, U&amp;&amp; u) const</span>
<span id="cb35-2"><a href="#cb35-2"></a>  -&gt; decltype(std::forward&lt;T&gt;(t) *= std::forward&lt;U&gt;(u));</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_12" id="pnum_12">1</a></span> <em>Returns</em>: <code class="sourceCode cpp">std<span class="op">::</span>forward<span class="op">&lt;</span>T<span class="op">&gt;(</span>t<span class="op">)</span> <span class="op">*=</span> std<span class="op">::</span>forward<span class="op">&lt;</span>U<span class="op">&gt;(</span>u<span class="op">)</span></code>.</p>
<h4 id="class-divides_equal-compound.operations.divides_equal">Class <code class="sourceCode cpp">divides_equal</code> [compound.operations.divides_equal]<a href="#class-divides_equal-compound.operations.divides_equal" class="self-link"></a></h4>
<div class="sourceCode" id="cb36"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb36-1"><a href="#cb36-1"></a>struct divides_equal {</span>
<span id="cb36-2"><a href="#cb36-2"></a>  template&lt;class T, class U&gt; constexpr auto operator()(T&amp;&amp; t, U&amp;&amp; u) const</span>
<span id="cb36-3"><a href="#cb36-3"></a>    -&gt; decltype(std::forward&lt;T&gt;(t) /= std::forward&lt;U&gt;(u));</span>
<span id="cb36-4"><a href="#cb36-4"></a></span>
<span id="cb36-5"><a href="#cb36-5"></a>  using is_transparent = <em>unspecified</em>;</span>
<span id="cb36-6"><a href="#cb36-6"></a>};</span></code></pre></div>
<div class="sourceCode" id="cb37"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb37-1"><a href="#cb37-1"></a>template&lt;class T, class U&gt; constexpr auto operator()(T&amp;&amp; t, U&amp;&amp; u) const</span>
<span id="cb37-2"><a href="#cb37-2"></a>  -&gt; decltype(std::forward&lt;T&gt;(t) /= std::forward&lt;U&gt;(u));</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_13" id="pnum_13">1</a></span> <em>Returns</em>: <code class="sourceCode cpp">std<span class="op">::</span>forward<span class="op">&lt;</span>T<span class="op">&gt;(</span>t<span class="op">)</span> <span class="op">/=</span> std<span class="op">::</span>forward<span class="op">&lt;</span>U<span class="op">&gt;(</span>u<span class="op">)</span></code>.</p>
<h4 id="class-modulus_equal-compound.operations.modulus_equal">Class <code class="sourceCode cpp">modulus_equal</code> [compound.operations.modulus_equal]<a href="#class-modulus_equal-compound.operations.modulus_equal" class="self-link"></a></h4>
<div class="sourceCode" id="cb38"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb38-1"><a href="#cb38-1"></a>struct modulus_equal {</span>
<span id="cb38-2"><a href="#cb38-2"></a>  template&lt;class T, class U&gt; constexpr auto operator()(T&amp;&amp; t, U&amp;&amp; u) const</span>
<span id="cb38-3"><a href="#cb38-3"></a>    -&gt; decltype(std::forward&lt;T&gt;(t) %= std::forward&lt;U&gt;(u));</span>
<span id="cb38-4"><a href="#cb38-4"></a></span>
<span id="cb38-5"><a href="#cb38-5"></a>  using is_transparent = <em>unspecified</em>;</span>
<span id="cb38-6"><a href="#cb38-6"></a>};</span></code></pre></div>
<div class="sourceCode" id="cb39"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb39-1"><a href="#cb39-1"></a>template&lt;class T, class U&gt; constexpr auto operator()(T&amp;&amp; t, U&amp;&amp; u) const</span>
<span id="cb39-2"><a href="#cb39-2"></a>  -&gt; decltype(std::forward&lt;T&gt;(t) %= std::forward&lt;U&gt;(u));</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_14" id="pnum_14">1</a></span> <em>Returns</em>: <code class="sourceCode cpp">std<span class="op">::</span>forward<span class="op">&lt;</span>T<span class="op">&gt;(</span>t<span class="op">)</span> <span class="op">%=</span> std<span class="op">::</span>forward<span class="op">&lt;</span>U<span class="op">&gt;(</span>u<span class="op">)</span></code>.</p>
<h4 id="class-bit_and_equal-compound.operations.bit_and_equal">Class <code class="sourceCode cpp">bit_and_equal</code> [compound.operations.bit_and_equal]<a href="#class-bit_and_equal-compound.operations.bit_and_equal" class="self-link"></a></h4>
<div class="sourceCode" id="cb40"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb40-1"><a href="#cb40-1"></a>struct bit_and_equal {</span>
<span id="cb40-2"><a href="#cb40-2"></a>  template&lt;class T, class U&gt; constexpr auto operator()(T&amp;&amp; t, U&amp;&amp; u) const</span>
<span id="cb40-3"><a href="#cb40-3"></a>    -&gt; decltype(std::forward&lt;T&gt;(t) &amp;= std::forward&lt;U&gt;(u));</span>
<span id="cb40-4"><a href="#cb40-4"></a></span>
<span id="cb40-5"><a href="#cb40-5"></a>  using is_transparent = <em>unspecified</em>;</span>
<span id="cb40-6"><a href="#cb40-6"></a>};</span></code></pre></div>
<div class="sourceCode" id="cb41"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb41-1"><a href="#cb41-1"></a>template&lt;class T, class U&gt; constexpr auto operator()(T&amp;&amp; t, U&amp;&amp; u) const</span>
<span id="cb41-2"><a href="#cb41-2"></a>  -&gt; decltype(std::forward&lt;T&gt;(t) &amp;= std::forward&lt;U&gt;(u));</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_15" id="pnum_15">1</a></span> <em>Returns</em>: <code class="sourceCode cpp">std<span class="op">::</span>forward<span class="op">&lt;</span>T<span class="op">&gt;(</span>t<span class="op">)</span> <span class="op">&amp;=</span> std<span class="op">::</span>forward<span class="op">&lt;</span>U<span class="op">&gt;(</span>u<span class="op">)</span></code>.</p>
<h4 id="class-bit_or_equal-compound.operations.bit_or_equal">Class <code class="sourceCode cpp">bit_or_equal</code> [compound.operations.bit_or_equal]<a href="#class-bit_or_equal-compound.operations.bit_or_equal" class="self-link"></a></h4>
<div class="sourceCode" id="cb42"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb42-1"><a href="#cb42-1"></a>struct bit_or_equal {</span>
<span id="cb42-2"><a href="#cb42-2"></a>  template&lt;class T, class U&gt; constexpr auto operator()(T&amp;&amp; t, U&amp;&amp; u) const</span>
<span id="cb42-3"><a href="#cb42-3"></a>    -&gt; decltype(std::forward&lt;T&gt;(t) |= std::forward&lt;U&gt;(u));</span>
<span id="cb42-4"><a href="#cb42-4"></a></span>
<span id="cb42-5"><a href="#cb42-5"></a>  using is_transparent = <em>unspecified</em>;</span>
<span id="cb42-6"><a href="#cb42-6"></a>};</span></code></pre></div>
<div class="sourceCode" id="cb43"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb43-1"><a href="#cb43-1"></a>template&lt;class T, class U&gt; constexpr auto operator()(T&amp;&amp; t, U&amp;&amp; u) const</span>
<span id="cb43-2"><a href="#cb43-2"></a>  -&gt; decltype(std::forward&lt;T&gt;(t) |= std::forward&lt;U&gt;(u));</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_16" id="pnum_16">1</a></span> <em>Returns</em>: <code class="sourceCode cpp">std<span class="op">::</span>forward<span class="op">&lt;</span>T<span class="op">&gt;(</span>t<span class="op">)</span> <span class="op">|=</span> std<span class="op">::</span>forward<span class="op">&lt;</span>U<span class="op">&gt;(</span>u<span class="op">)</span></code>.</p>
<h4 id="class-bit_xor_equal-compound.operations.bit_xor_equal">Class <code class="sourceCode cpp">bit_xor_equal</code> [compound.operations.bit_xor_equal]<a href="#class-bit_xor_equal-compound.operations.bit_xor_equal" class="self-link"></a></h4>
<div class="sourceCode" id="cb44"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb44-1"><a href="#cb44-1"></a>struct bit_xor_equal {</span>
<span id="cb44-2"><a href="#cb44-2"></a>  template&lt;class T, class U&gt; constexpr auto operator()(T&amp;&amp; t, U&amp;&amp; u) const</span>
<span id="cb44-3"><a href="#cb44-3"></a>    -&gt; decltype(std::forward&lt;T&gt;(t) ^= std::forward&lt;U&gt;(u));</span>
<span id="cb44-4"><a href="#cb44-4"></a></span>
<span id="cb44-5"><a href="#cb44-5"></a>  using is_transparent = <em>unspecified</em>;</span>
<span id="cb44-6"><a href="#cb44-6"></a>};</span></code></pre></div>
<div class="sourceCode" id="cb45"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb45-1"><a href="#cb45-1"></a>template&lt;class T, class U&gt; constexpr auto operator()(T&amp;&amp; t, U&amp;&amp; u) const</span>
<span id="cb45-2"><a href="#cb45-2"></a>  -&gt; decltype(std::forward&lt;T&gt;(t) ^= std::forward&lt;U&gt;(u));</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_17" id="pnum_17">1</a></span> <em>Returns</em>: <code class="sourceCode cpp">std<span class="op">::</span>forward<span class="op">&lt;</span>T<span class="op">&gt;(</span>t<span class="op">)</span> <span class="op">^=</span> std<span class="op">::</span>forward<span class="op">&lt;</span>U<span class="op">&gt;(</span>u<span class="op">)</span></code>.</p>
<h4 id="class-left_shift_equal-compound.operations.left_shift_equal">Class <code class="sourceCode cpp">left_shift_equal</code> [compound.operations.left_shift_equal]<a href="#class-left_shift_equal-compound.operations.left_shift_equal" class="self-link"></a></h4>
<div class="sourceCode" id="cb46"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb46-1"><a href="#cb46-1"></a>struct left_shift_equal {</span>
<span id="cb46-2"><a href="#cb46-2"></a>  template&lt;class T, class U&gt; constexpr auto operator()(T&amp;&amp; t, U&amp;&amp; u) const</span>
<span id="cb46-3"><a href="#cb46-3"></a>    -&gt; decltype(std::forward&lt;T&gt;(t) &lt;&lt;= std::forward&lt;U&gt;(u));</span>
<span id="cb46-4"><a href="#cb46-4"></a></span>
<span id="cb46-5"><a href="#cb46-5"></a>  using is_transparent = <em>unspecified</em>;</span>
<span id="cb46-6"><a href="#cb46-6"></a>};</span></code></pre></div>
<div class="sourceCode" id="cb47"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb47-1"><a href="#cb47-1"></a>template&lt;class T, class U&gt; constexpr auto operator()(T&amp;&amp; t, U&amp;&amp; u) const</span>
<span id="cb47-2"><a href="#cb47-2"></a>  -&gt; decltype(std::forward&lt;T&gt;(t) &lt;&lt;= std::forward&lt;U&gt;(u));</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_18" id="pnum_18">1</a></span> <em>Returns</em>: <code class="sourceCode cpp">std<span class="op">::</span>forward<span class="op">&lt;</span>T<span class="op">&gt;(</span>t<span class="op">)</span> <span class="op">&lt;&lt;=</span> std<span class="op">::</span>forward<span class="op">&lt;</span>U<span class="op">&gt;(</span>u<span class="op">)</span></code>.</p>
<h4 id="class-right_shift_equal-compound.operations.right_shift_equal">Class <code class="sourceCode cpp">right_shift_equal</code> [compound.operations.right_shift_equal]<a href="#class-right_shift_equal-compound.operations.right_shift_equal" class="self-link"></a></h4>
<div class="sourceCode" id="cb48"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb48-1"><a href="#cb48-1"></a>struct right_shift_equal {</span>
<span id="cb48-2"><a href="#cb48-2"></a>  template&lt;class T, class U&gt; constexpr auto operator()(T&amp;&amp; t, U&amp;&amp; u) const</span>
<span id="cb48-3"><a href="#cb48-3"></a>    -&gt; decltype(std::forward&lt;T&gt;(t) &gt;&gt;= std::forward&lt;U&gt;(u));</span>
<span id="cb48-4"><a href="#cb48-4"></a></span>
<span id="cb48-5"><a href="#cb48-5"></a>  using is_transparent = <em>unspecified</em>;</span>
<span id="cb48-6"><a href="#cb48-6"></a>};</span></code></pre></div>
<div class="sourceCode" id="cb49"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb49-1"><a href="#cb49-1"></a>template&lt;class T, class U&gt; constexpr auto operator()(T&amp;&amp; t, U&amp;&amp; u) const</span>
<span id="cb49-2"><a href="#cb49-2"></a>  -&gt; decltype(std::forward&lt;T&gt;(t) &gt;&gt;= std::forward&lt;U&gt;(u));</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_19" id="pnum_19">1</a></span> <em>Returns</em>: <code class="sourceCode cpp">std<span class="op">::</span>forward<span class="op">&lt;</span>T<span class="op">&gt;(</span>t<span class="op">)</span> <span class="op">&gt;&gt;=</span> std<span class="op">::</span>forward<span class="op">&lt;</span>U<span class="op">&gt;(</span>u<span class="op">)</span></code>.</p>
</div>
</blockquote>
<p>Extend <span>22.10.15.5 <a href="https://wg21.link/func.bind.place">[func.bind.place]</a></span>:</p>
<blockquote>
<div>
<div class="sourceCode" id="cb50"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb50-1"><a href="#cb50-1"></a>namespace std::placeholders {</span>
<span id="cb50-2"><a href="#cb50-2"></a>  // M is the number of placeholders</span>
<span id="cb50-3"><a href="#cb50-3"></a><span class="va">+ template &lt;int J&gt;</span></span>
<span id="cb50-4"><a href="#cb50-4"></a><span class="va">+ struct <em>placeholder</em> { // exposition only</span></span>
<span id="cb50-5"><a href="#cb50-5"></a><span class="va">+   template &lt;class... Args&gt;</span></span>
<span id="cb50-6"><a href="#cb50-6"></a><span class="va">+     constexpr decltype(auto) operator()(Args&amp;&amp;... ) const noexcept;</span></span>
<span id="cb50-7"><a href="#cb50-7"></a><span class="va">+  template &lt;class T&gt;</span></span>
<span id="cb50-8"><a href="#cb50-8"></a><span class="va">+    constexpr auto operator[](T&amp;&amp; ) const;</span></span>
<span id="cb50-9"><a href="#cb50-9"></a><span class="va">+ };</span></span>
<span id="cb50-10"><a href="#cb50-10"></a></span>
<span id="cb50-11"><a href="#cb50-11"></a>  <em>see below</em> _1;</span>
<span id="cb50-12"><a href="#cb50-12"></a>  <em>see below</em> _2;</span>
<span id="cb50-13"><a href="#cb50-13"></a>              .</span>
<span id="cb50-14"><a href="#cb50-14"></a>              .</span>
<span id="cb50-15"><a href="#cb50-15"></a>              .</span>
<span id="cb50-16"><a href="#cb50-16"></a>  <em>see below</em> _M;</span>
<span id="cb50-17"><a href="#cb50-17"></a>}</span></code></pre></div>
</div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_20" id="pnum_20">1</a></span> The number <code class="sourceCode cpp">M</code> of placeholders is implementation-defined.</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_21" id="pnum_21">2</a></span> All placeholder types meet the <em>Cpp17DefaultConstructible</em> and Cpp17CopyConstructible requirements, and their default constructors and copy/move constructors are constexpr functions that do not throw exceptions. It is implementation-defined whether placeholder types meet the <em>Cpp17CopyAssignable</em> requirements, but if so, their copy assignment operators are constexpr functions that do not throw exceptions.</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_22" id="pnum_22">3</a></span> Placeholders should be defined as:</p>
<div>
<div class="sourceCode" id="cb51"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb51-1"><a href="#cb51-1"></a><span class="st">- inline constexpr <em>unspecified</em> _1{};</span></span>
<span id="cb51-2"><a href="#cb51-2"></a><span class="va">+ inline constexpr <em>placeholder</em>&lt;1&gt; _1{};</span></span></code></pre></div>
</div>
<p>If they are not, they are declared as:</p>
<div>
<div class="sourceCode" id="cb52"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb52-1"><a href="#cb52-1"></a><span class="st">- extern <em>unspecified</em> _1;</span></span>
<span id="cb52-2"><a href="#cb52-2"></a><span class="va">+ extern <em>placeholder</em>&lt;1&gt; _1;</span></span></code></pre></div>
</div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_23" id="pnum_23">4</a></span> Placeholders are freestanding items ([freestanding.item]).</p>
<div class="addu">
<div class="sourceCode" id="cb53"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb53-1"><a href="#cb53-1"></a>template &lt;int J&gt;</span>
<span id="cb53-2"><a href="#cb53-2"></a>template &lt;class... Args&gt;</span>
<span id="cb53-3"><a href="#cb53-3"></a>decltype(auto) <em>placeholder</em>&lt;J&gt;::operator()(Args&amp;&amp;... args) const noexcept;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_24" id="pnum_24">5</a></span> <em>Constraints</em>: <code class="sourceCode cpp"><span class="kw">sizeof</span><span class="op">...(</span>Args<span class="op">)</span> <span class="op">&gt;=</span> J</code> is <code class="sourceCode cpp"><span class="kw">true</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_25" id="pnum_25">6</a></span> <em>Returns</em>: <code class="sourceCode cpp">std<span class="op">::</span>forward<span class="op">&lt;</span>Args<span class="op">&gt;(</span>args<span class="op">)...[</span>J <span class="op">-</span> <span class="dv">1</span><span class="op">]</span></code>.</p>
<div class="sourceCode" id="cb54"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb54-1"><a href="#cb54-1"></a>template &lt;int J&gt;</span>
<span id="cb54-2"><a href="#cb54-2"></a>template &lt;class T&gt;</span>
<span id="cb54-3"><a href="#cb54-3"></a>auto <em>placeholder</em>&lt;J&gt;::operator[](T&amp;&amp; t) const;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_26" id="pnum_26">7</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>subscript<span class="op">()</span>, <span class="op">*</span><span class="kw">this</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>T<span class="op">&gt;(</span>t<span class="op">))</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_27" id="pnum_27">8</a></span> Each operator function declared in this clause is constrained on at least one of the parameters having a type <code class="sourceCode cpp">T</code> which satisfies <code class="sourceCode cpp">is_placeholder_v<span class="op">&lt;</span>remove_cvref_t<span class="op">&lt;</span>T<span class="op">&gt;&gt;</span> <span class="op">||</span> is_bind_expression_v<span class="op">&lt;</span>remove_cvref_t<span class="op">&lt;</span>T<span class="op">&gt;&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code>.</p>
<div class="sourceCode" id="cb55"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb55-1"><a href="#cb55-1"></a>template&lt;class A, class B&gt; constexpr auto operator+(A&amp;&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_28" id="pnum_28">9</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>plus<span class="op">&lt;&gt;()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb56"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb56-1"><a href="#cb56-1"></a>template&lt;class A, class B&gt; constexpr auto operator-(A&amp;&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_29" id="pnum_29">10</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>minus<span class="op">&lt;&gt;()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb57"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb57-1"><a href="#cb57-1"></a>template&lt;class A, class B&gt; constexpr auto operator*(A&amp;&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_30" id="pnum_30">11</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>multiplies<span class="op">&lt;&gt;()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb58"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb58-1"><a href="#cb58-1"></a>template&lt;class A, class B&gt; constexpr auto operator/(A&amp;&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_31" id="pnum_31">12</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>divides<span class="op">&lt;&gt;()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb59"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb59-1"><a href="#cb59-1"></a>template&lt;class A, class B&gt; constexpr auto operator%(A&amp;&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_32" id="pnum_32">13</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>modulus<span class="op">&lt;&gt;()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb60"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb60-1"><a href="#cb60-1"></a>template&lt;class A&gt; constexpr auto operator-(A&amp;&amp; a);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_33" id="pnum_33">14</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>negate<span class="op">&lt;&gt;()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb61"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb61-1"><a href="#cb61-1"></a>template&lt;class A, class B&gt; constexpr auto operator==(A&amp;&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_34" id="pnum_34">15</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>equal_to<span class="op">&lt;&gt;()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb62"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb62-1"><a href="#cb62-1"></a>template&lt;class A, class B&gt; constexpr auto operator!=(A&amp;&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_35" id="pnum_35">16</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>not_equal_to<span class="op">&lt;&gt;()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb63"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb63-1"><a href="#cb63-1"></a>template&lt;class A, class B&gt; constexpr auto operator&lt;(A&amp;&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_36" id="pnum_36">17</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>less<span class="op">&lt;&gt;()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb64"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb64-1"><a href="#cb64-1"></a>template&lt;class A, class B&gt; constexpr auto operator&gt;(A&amp;&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_37" id="pnum_37">18</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>greater<span class="op">&lt;&gt;()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb65"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb65-1"><a href="#cb65-1"></a>template&lt;class A, class B&gt; constexpr auto operator&lt;=(A&amp;&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_38" id="pnum_38">19</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>less_equal<span class="op">&lt;&gt;()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb66"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb66-1"><a href="#cb66-1"></a>template&lt;class A, class B&gt; constexpr auto operator&gt;=(A&amp;&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_39" id="pnum_39">20</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>greater_equal<span class="op">&lt;&gt;()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb67"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb67-1"><a href="#cb67-1"></a>template&lt;class A, class B&gt; constexpr auto operator&lt;=&gt;(A&amp;&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_40" id="pnum_40">21</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>compare_three_way<span class="op">()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb68"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb68-1"><a href="#cb68-1"></a>template&lt;class A, class B&gt; constexpr auto operator&amp;&amp;(A&amp;&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_41" id="pnum_41">22</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>logical_and<span class="op">&lt;&gt;()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb69"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb69-1"><a href="#cb69-1"></a>template&lt;class A, class B&gt; constexpr auto operator||(A&amp;&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_42" id="pnum_42">23</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>logical_or<span class="op">&lt;&gt;()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb70"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb70-1"><a href="#cb70-1"></a>template&lt;class A&gt; constexpr auto operator!(A&amp;&amp; a);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_43" id="pnum_43">24</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>logical_not<span class="op">&lt;&gt;()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb71"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb71-1"><a href="#cb71-1"></a>template&lt;class A, class B&gt; constexpr auto operator&amp;(A&amp;&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_44" id="pnum_44">25</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>bit_and<span class="op">&lt;&gt;()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb72"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb72-1"><a href="#cb72-1"></a>template&lt;class A, class B&gt; constexpr auto operator|(A&amp;&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_45" id="pnum_45">26</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>bit_or<span class="op">&lt;&gt;()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb73"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb73-1"><a href="#cb73-1"></a>template&lt;class A, class B&gt; constexpr auto operator^(A&amp;&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_46" id="pnum_46">27</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>bit_xor<span class="op">&lt;&gt;()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb74"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb74-1"><a href="#cb74-1"></a>template&lt;class A&gt; constexpr auto operator~(A&amp;&amp; a);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_47" id="pnum_47">28</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>bit_not<span class="op">&lt;&gt;()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb75"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb75-1"><a href="#cb75-1"></a>template&lt;class A, class B&gt; constexpr auto operator&lt;&lt;(A&amp;&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_48" id="pnum_48">29</a></span> <em>Constraints</em>: <code class="sourceCode cpp">is_base_of_v<span class="op">&lt;</span>ios_base, remove_cvref_t<span class="op">&lt;</span>A<span class="op">&gt;&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">false</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_49" id="pnum_49">30</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>left_shift<span class="op">()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb76"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb76-1"><a href="#cb76-1"></a>template&lt;class A, class B&gt; constexpr auto operator&lt;&lt;(A&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_50" id="pnum_50">31</a></span> <em>Constraints</em>: <code class="sourceCode cpp">is_base_of_v<span class="op">&lt;</span>ios_base, remove_cvref_t<span class="op">&lt;</span>A<span class="op">&gt;&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_51" id="pnum_51">32</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>left_shift<span class="op">()</span>, ref<span class="op">(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_52" id="pnum_52">33</a></span> <em>Remarks</em>: This overload allows expressions like <code class="sourceCode cpp">std<span class="op">::</span>cout <span class="op">&lt;&lt;</span> _1 <span class="op">&lt;&lt;</span> <span class="ch">&#39;</span><span class="sc">\n</span><span class="ch">&#39;</span></code> to work.</p>
<div class="sourceCode" id="cb77"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb77-1"><a href="#cb77-1"></a>template&lt;class A, class B&gt; constexpr auto operator&gt;&gt;(A&amp;&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_53" id="pnum_53">34</a></span> <em>Constraints</em>: <code class="sourceCode cpp">is_base_of_v<span class="op">&lt;</span>ios_base, remove_cvref_t<span class="op">&lt;</span>A<span class="op">&gt;&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">false</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_54" id="pnum_54">35</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>right_shift<span class="op">()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb78"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb78-1"><a href="#cb78-1"></a>template&lt;class A, class B&gt; constexpr auto operator&gt;&gt;(A&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_55" id="pnum_55">36</a></span> <em>Constraints</em>: <code class="sourceCode cpp">is_base_of_v<span class="op">&lt;</span>ios_base, remove_cvref_t<span class="op">&lt;</span>A<span class="op">&gt;&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_56" id="pnum_56">37</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>right_shift<span class="op">()</span>, ref<span class="op">(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb79"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb79-1"><a href="#cb79-1"></a>template&lt;class A&gt; constexpr auto operator+(A&amp;&amp; a);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_57" id="pnum_57">38</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>unary_plus<span class="op">()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb80"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb80-1"><a href="#cb80-1"></a>template&lt;class A&gt; constexpr auto operator*(A&amp;&amp; a);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_58" id="pnum_58">39</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>dereference<span class="op">()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb81"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb81-1"><a href="#cb81-1"></a>template&lt;class A&gt; constexpr auto operator++(A&amp;&amp; a);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_59" id="pnum_59">40</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>increment<span class="op">()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb82"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb82-1"><a href="#cb82-1"></a>template&lt;class A&gt; constexpr auto operator--(A&amp;&amp; a);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_60" id="pnum_60">41</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>decrement<span class="op">()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb83"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb83-1"><a href="#cb83-1"></a>template&lt;class A&gt; constexpr auto operator++(A&amp;&amp; a, int);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_61" id="pnum_61">42</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>postfix_increment<span class="op">()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb84"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb84-1"><a href="#cb84-1"></a>template&lt;class A&gt; constexpr auto operator--(A&amp;&amp; a, int);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_62" id="pnum_62">43</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>postfix_decrement<span class="op">()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb85"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb85-1"><a href="#cb85-1"></a>template&lt;class A, class B&gt; constexpr auto operator+=(A&amp;&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_63" id="pnum_63">44</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>plus_equal<span class="op">()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb86"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb86-1"><a href="#cb86-1"></a>template&lt;class A, class B&gt; constexpr auto operator-=(A&amp;&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_64" id="pnum_64">45</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>minus_equal<span class="op">()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb87"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb87-1"><a href="#cb87-1"></a>template&lt;class A, class B&gt; constexpr auto operator*=(A&amp;&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_65" id="pnum_65">46</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>multiplies_equal<span class="op">()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb88"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb88-1"><a href="#cb88-1"></a>template&lt;class A, class B&gt; constexpr auto operator/=(A&amp;&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_66" id="pnum_66">47</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>divides_equal<span class="op">()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb89"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb89-1"><a href="#cb89-1"></a>template&lt;class A, class B&gt; constexpr auto operator%=(A&amp;&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_67" id="pnum_67">48</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>modulus_equal<span class="op">()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb90"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb90-1"><a href="#cb90-1"></a>template&lt;class A, class B&gt; constexpr auto operator&amp;=(A&amp;&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_68" id="pnum_68">49</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>bit_and_equal<span class="op">()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb91"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb91-1"><a href="#cb91-1"></a>template&lt;class A, class B&gt; constexpr auto operator|=(A&amp;&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_69" id="pnum_69">50</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>bit_or_equal<span class="op">()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb92"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb92-1"><a href="#cb92-1"></a>template&lt;class A, class B&gt; constexpr auto operator^=(A&amp;&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_70" id="pnum_70">51</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>bit_xor_equal<span class="op">()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb93"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb93-1"><a href="#cb93-1"></a>template&lt;class A, class B&gt; constexpr auto operator&lt;&lt;=(A&amp;&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_71" id="pnum_71">52</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>left_shift_equal<span class="op">()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb94"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb94-1"><a href="#cb94-1"></a>template&lt;class A, class B&gt; constexpr auto operator&gt;&gt;=(A&amp;&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_72" id="pnum_72">53</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>right_shift_equal<span class="op">()</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span></code>.</p>
<div class="sourceCode" id="cb95"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb95-1"><a href="#cb95-1"></a>template&lt;class A, class B&gt; constexpr auto operator-&gt;*(A&amp;&amp; a, B&amp;&amp; b);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_73" id="pnum_73">54</a></span> <em>Returns</em>: <code class="sourceCode cpp">bind<span class="op">(</span>std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>A<span class="op">&gt;(</span>a<span class="op">))</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_74" id="pnum_74">55</a></span> The name <code class="sourceCode cpp">first</code> denotes a customization point object ([customization.point.object]). Given a subexpression <code class="sourceCode cpp">E</code>:</p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_75" id="pnum_75">(55.1)</a></span> If <code class="sourceCode cpp">E</code> has class or enumeration type and <code class="sourceCode cpp">get<span class="op">&lt;</span><span class="dv">0</span><span class="op">&gt;(</span>E<span class="op">)</span></code> is a valid expression where the meaning of <code class="sourceCode cpp">get</code> is established by performing argument-dependent lookup only ([basic.lookup.argdep]), then <code class="sourceCode cpp">first<span class="op">(</span>E<span class="op">)</span></code> is expression-equivalent to <code class="sourceCode cpp">get<span class="op">&lt;</span><span class="dv">0</span><span class="op">&gt;(</span>E<span class="op">)</span></code>.</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_76" id="pnum_76">(55.2)</a></span> Otherwise, <code class="sourceCode cpp">first<span class="op">(</span>E<span class="op">)</span></code> is ill-formed.</li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_77" id="pnum_77">56</a></span> The name <code class="sourceCode cpp">second</code> denotes a customization point object ([customization.point.object]). Given a subexpression <code class="sourceCode cpp">E</code>:</p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_78" id="pnum_78">(56.1)</a></span> If <code class="sourceCode cpp">E</code> has class or enumeration type and <code class="sourceCode cpp">get<span class="op">&lt;</span><span class="dv">1</span><span class="op">&gt;(</span>E<span class="op">)</span></code> is a valid expression where the meaning of <code class="sourceCode cpp">get</code> is established by performing argument-dependent lookup only ([basic.lookup.argdep]), then <code class="sourceCode cpp">second<span class="op">(</span>E<span class="op">)</span></code> is expression-equivalent to <code class="sourceCode cpp">get<span class="op">&lt;</span><span class="dv">1</span><span class="op">&gt;(</span>E<span class="op">)</span></code>.</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_79" id="pnum_79">(56.2)</a></span> Otherwise, <code class="sourceCode cpp">second<span class="op">(</span>E<span class="op">)</span></code> is ill-formed.</li>
</ul>
</div>
</blockquote>
<h2 data-number="2.5" id="feature-test-macro"><span class="header-section-number">2.5</span> Feature-Test Macro<a href="#feature-test-macro" class="self-link"></a></h2>
<p>Add an entry to <span>17.3.2 <a href="https://wg21.link/version.syn">[version.syn]</a></span> for this</p>
<blockquote>
<div>
<div class="sourceCode" id="cb96"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb96-1"><a href="#cb96-1"></a><span class="va">+ #define __cpp_lib_placeholder_operators 2024XXL // freestanding, also in &lt;functional&gt;</span></span></code></pre></div>
</div>
</blockquote>
<h1 data-number="3" style="border-bottom:1px solid #cccccc" id="bibliography"><span class="header-section-number">3</span> References<a href="#bibliography" class="self-link"></a></h1>
<div id="refs" class="references hanging-indent" role="doc-bibliography">
<div id="ref-Boost.Lambda2">
<p>[Boost.Lambda2] Peter Dimov. 2020. Lambda2: A C++14 Lambda Library. <br />
<a href="https://www.boost.org/doc/libs/master/libs/lambda2/doc/html/lambda2.html">https://www.boost.org/doc/libs/master/libs/lambda2/doc/html/lambda2.html</a></p>
</div>
<div id="ref-P0060R0">
<p>[P0060R0] Mathias Gaunard, Dietmar Kühl. 2015-09-18. Function Object-Based Overloading of Operator Dot. <br />
<a href="https://wg21.link/p0060r0">https://wg21.link/p0060r0</a></p>
</div>
<div id="ref-P2321R2">
<p>[P2321R2] Tim Song. 2021-06-11. zip. <br />
<a href="https://wg21.link/p2321r2">https://wg21.link/p2321r2</a></p>
</div>
<div id="ref-P2760R0">
<p>[P2760R0] Barry Revzin. 2023-09-17. A Plan for C++26 Ranges. <br />
<a href="https://wg21.link/p2760r0">https://wg21.link/p2760r0</a></p>
</div>
<div id="ref-P2769R1">
<p>[P2769R1] Ruslan Arutyunyan, Alexey Kukanov. 2023-05-17. get_element customization point object. <br />
<a href="https://wg21.link/p2769r1">https://wg21.link/p2769r1</a></p>
</div>
</div>
</div>
</div>
</body>
</html>
