<!DOCTYPE html>
<!-- Sources at https://github.com/cplusplus/fundamentals-ts -->
<html lang="en"><head><!--[if lte IE 8]><script>document.createElement("nav");document.createElement("section");document.createElement("time");document.createElement("CXX-TITLEPAGE");document.createElement("CXX-DOCNUM");document.createElement("CXX-REVISES");document.createElement("CXX-EDITOR");document.createElement("CXX-EMAIL");document.createElement("CXX-TOC");document.createElement("CXX-CLAUSE");document.createElement("CXX-SECTION");document.createElement("CXX-REF");document.createElement("CXX-FOREIGN-INDEX");document.createElement("CXX-EXAMPLE");document.createElement("CXX-NOTE");document.createElement("CXX-FUNCTION");document.createElement("CXX-SIGNATURE");document.createElement("CXX-REMARKS");document.createElement("CXX-17CONCEPT");document.createElement("CXX-CONSTRAINTS");document.createElement("CXX-EFFECTS");document.createElement("CXX-RETURNS");document.createElement("CXX-PRECONDITIONS");document.createElement("CXX-MANDATES");document.createElement("CXX-THROWS");document.createElement("CXX-POSTCONDITIONS");document.createElement("CXX-TERM");document.createElement("W-BR");document.createElement("CXX-EDNOTE");document.createElement("CXX-COMPLEXITY");document.createElement("CXX-PUBLISH-BUTTON");</script><![endif]--><style>template {display: none !important;} /* injected by platform.js */</style><style>body {transition: opacity ease-in 0.2s; } 
body[unresolved] {opacity: 0; display: block; overflow: hidden; position: relative; } 
</style><style shim-shadowdom-css="">style { display: none !important; }
cxx-function {
	display: block; break-inside: avoid;
}

cxx-function:not(:last-child) {
	margin-bottom: 3ex;
}

cxx-function > dl {
	margin: 0px 0px 0px 2em;
}

cxx-function > pre {
	margin: 0px;
}cxx-signature {
	padding-left: 2em; display: block; text-indent: -2em;
}

cxx-signature.formatted {
	text-indent: 0px;
}cxx-attribute {
	display: block; margin-top: 0.5em; margin-bottom: 0.5em;
}

cxx-attribute dt {
	float: left; font-style: italic; font-weight: normal; padding-right: 1ex;
}

cxx-attribute dd {
	margin-left: 0em;
}

cxx-attribute dd > ul, cxx-attribute dd > ol {
	clear: left;
}cxx-constraints {
	display: block; margin-top: 0.5em; margin-bottom: 0.5em;
}

cxx-constraints dt {
	float: left; font-style: italic; font-weight: normal; padding-right: 1ex;
}

cxx-constraints dd {
	margin-left: 0em;
}

cxx-constraints dd > ul, cxx-constraints dd > ol {
	clear: left;
}cxx-mandates {
	display: block; margin-top: 0.5em; margin-bottom: 0.5em;
}

cxx-mandates dt {
	float: left; font-style: italic; font-weight: normal; padding-right: 1ex;
}

cxx-mandates dd {
	margin-left: 0em;
}

cxx-mandates dd > ul, cxx-mandates dd > ol {
	clear: left;
}cxx-preconditions {
	display: block; margin-top: 0.5em; margin-bottom: 0.5em;
}

cxx-preconditions dt {
	float: left; font-style: italic; font-weight: normal; padding-right: 1ex;
}

cxx-preconditions dd {
	margin-left: 0em;
}

cxx-preconditions dd > ul, cxx-preconditions dd > ol {
	clear: left;
}cxx-effects {
	display: block; margin-top: 0.5em; margin-bottom: 0.5em;
}

cxx-effects dt {
	float: left; font-style: italic; font-weight: normal; padding-right: 1ex;
}

cxx-effects dd {
	margin-left: 0em;
}

cxx-effects dd > ul, cxx-effects dd > ol {
	clear: left;
}cxx-synchronization {
	display: block; margin-top: 0.5em; margin-bottom: 0.5em;
}

cxx-synchronization dt {
	float: left; font-style: italic; font-weight: normal; padding-right: 1ex;
}

cxx-synchronization dd {
	margin-left: 0em;
}

cxx-synchronization dd > ul, cxx-synchronization dd > ol {
	clear: left;
}cxx-postconditions {
	display: block; margin-top: 0.5em; margin-bottom: 0.5em;
}

cxx-postconditions dt {
	float: left; font-style: italic; font-weight: normal; padding-right: 1ex;
}

cxx-postconditions dd {
	margin-left: 0em;
}

cxx-postconditions dd > ul, cxx-postconditions dd > ol {
	clear: left;
}cxx-returns {
	display: block; margin-top: 0.5em; margin-bottom: 0.5em;
}

cxx-returns dt {
	float: left; font-style: italic; font-weight: normal; padding-right: 1ex;
}

cxx-returns dd {
	margin-left: 0em;
}

cxx-returns dd > ul, cxx-returns dd > ol {
	clear: left;
}cxx-throws {
	display: block; margin-top: 0.5em; margin-bottom: 0.5em;
}

cxx-throws dt {
	float: left; font-style: italic; font-weight: normal; padding-right: 1ex;
}

cxx-throws dd {
	margin-left: 0em;
}

cxx-throws dd > ul, cxx-throws dd > ol {
	clear: left;
}cxx-complexity {
	display: block; margin-top: 0.5em; margin-bottom: 0.5em;
}

cxx-complexity dt {
	float: left; font-style: italic; font-weight: normal; padding-right: 1ex;
}

cxx-complexity dd {
	margin-left: 0em;
}

cxx-complexity dd > ul, cxx-complexity dd > ol {
	clear: left;
}cxx-exception-safety {
	display: block; margin-top: 0.5em; margin-bottom: 0.5em;
}

cxx-exception-safety dt {
	float: left; font-style: italic; font-weight: normal; padding-right: 1ex;
}

cxx-exception-safety dd {
	margin-left: 0em;
}

cxx-exception-safety dd > ul, cxx-exception-safety dd > ol {
	clear: left;
}cxx-remarks {
	display: block; margin-top: 0.5em; margin-bottom: 0.5em;
}

cxx-remarks dt {
	float: left; font-style: italic; font-weight: normal; padding-right: 1ex;
}

cxx-remarks dd {
	margin-left: 0em;
}

cxx-remarks dd > ul, cxx-remarks dd > ol {
	clear: left;
}cxx-error-conditions {
	display: block; margin-top: 0.5em; margin-bottom: 0.5em;
}

cxx-error-conditions dt {
	float: left; font-style: italic; font-weight: normal; padding-right: 1ex;
}

cxx-error-conditions dd {
	margin-left: 0em;
}

cxx-error-conditions dd > ul, cxx-error-conditions dd > ol {
	clear: left;
}cxx-notes {
	display: block; margin-top: 0.5em; margin-bottom: 0.5em;
}

cxx-notes dt {
	float: left; font-style: italic; font-weight: normal; padding-right: 1ex;
}

cxx-notes dd {
	margin-left: 0em;
}

cxx-notes dd > ul, cxx-notes dd > ol {
	clear: left;
}cxx-section {
	display: block;
}

cxx-section:target {
	background-color: inherit;
}

cxx-section:target > section > h1 {
	background-color: rgb(255, 238, 221);
}

cxx-section header > h1 {
	display: inline; font-size: 100%;
}

cxx-section header {
	font-weight: bold; margin-top: 20px; margin-bottom: 20px; break-inside: avoid; break-after: avoid;
}

cxx-section header::after {
	clear: both; display: block; content: " "; height: 0px;
}cxx-clause {
	display: block;
}

cxx-clause:target {
	background-color: inherit;
}

cxx-clause:target > section > h1 {
	background-color: rgb(255, 238, 221);
}

cxx-clause header > h1 {
	display: inline; font-size: 100%;
}

cxx-clause header {
	font-weight: bold; margin-top: 20px; margin-bottom: 20px; break-inside: avoid; break-after: avoid;
}

cxx-clause header::after {
	clear: both; display: block; content: " "; height: 0px;
}[is=cxx-table] {
	margin-left: auto; margin-right: auto; border-collapse: collapse; border: thin solid black;
}

[is=cxx-table] caption {
	white-space: nowrap;
}

[is=cxx-table] caption caption {
	display: inline;
}

[is=cxx-table] th, [is=cxx-table] td {
	border-style: solid none; border-color: black; border-width: thin; padding: 0px 0.25em;
}

[is=cxx-table].column-rules th, [is=cxx-table].column-rules td {
	border-left-style: solid; border-right-style: solid;
}

[is=cxx-table] th {
	border-bottom: medium double;
}

[is=cxx-table].single-border th {
	border-bottom: thin solid;
}

[is=cxx-table].center td {
	text-align: center;
}

[is=cxx-table].list td {
	border: medium none; vertical-align: top;
}

[is=cxx-table].list ul {
	padding-left: 0px; margin: 0px;
}

[is=cxx-table].list ul li::before {
	content: "";
}cxx-figure {
	margin-left: auto; margin-right: auto;
}

cxx-figure figcaption {
	white-space: nowrap; text-align: center;
}

cxx-figure figcaption figcaption {
	display: inline;
}[is=cxx-definition-section] dt {
	font-weight: bold;
}

[is=cxx-definition-section] dd {
	margin-left: 0px;
}cxx-toc {
	display: block;
}

cxx-toc nav > ol {
	font-weight: bold;
}

cxx-toc ol {
	font-weight: normal; padding-left: 0px; margin-left: 0px;
}

cxx-toc li {
	list-style-type: none;
}

cxx-toc .marker {
	display: inline-block;
}

cxx-toc li .marker {
	width: 2em; text-align: left;
}

cxx-toc ol ol {
	margin-left: 2em;
}

cxx-toc li li .marker {
	width: 3em;
}

cxx-toc ol ol ol {
	margin-left: 3em;
}

cxx-toc li li li .marker {
	width: 3.5em;
}

cxx-toc ol ol ol ol {
	margin-left: 3.5em;
}

cxx-toc li li li li .marker {
	width: 4.5em;
}cxx-get-element-by-id {
	display: none;
}cxx-foreign-index {
	display: none;
}cxx-titlepage, cxx-titlepage .page {
	display: block; min-height: 100%;
}

cxx-titlepage .page {
	break-before: page; break-after: page; min-height: 100vh; margin-bottom: 2em;
}

@media print {
cxx-titlepage .page {
	height: 8.8in;
}


}

cxx-titlepage .page {
	position: relative;
}

cxx-titlepage table td, cxx-titlepage table th {
	border: medium none;
}

cxx-titlepagebody.cxx-draft .header, body.cxx-draft cxx-titlepage .header {
	position: absolute; right: 0px; top: 0px;
}

cxx-titlepagebody.cxx-draft h1, body.cxx-draft cxx-titlepage h1 {
	position: absolute; top: 40%; text-align: center;
}

cxx-titlepagebody.cxx-draft p.warning, body.cxx-draft cxx-titlepage p.warning {
	position: absolute; bottom: 5%;
}

cxx-titlepagebody.cxx-pdts .header, body.cxx-pdts cxx-titlepage .header, cxx-titlepagebody.cxx-dts .header, body.cxx-dts cxx-titlepage .header, cxx-titlepagebody.cxx-ts .header, body.cxx-ts cxx-titlepage .header {
	position: absolute; right: 0px; top: 0px; text-align: right;
}

cxx-titlepagebody.cxx-pdts .header cxx-docnum, body.cxx-pdts cxx-titlepage .header cxx-docnum, cxx-titlepagebody.cxx-dts .header cxx-docnum, body.cxx-dts cxx-titlepage .header cxx-docnum, cxx-titlepagebody.cxx-ts .header cxx-docnum, body.cxx-ts cxx-titlepage .header cxx-docnum {
	font-size: 150%;
}

cxx-titlepagebody.cxx-pdts .header cxx-docnum, body.cxx-pdts cxx-titlepage .header cxx-docnum, cxx-titlepagebody.cxx-dts .header cxx-docnum, body.cxx-dts cxx-titlepage .header cxx-docnum, cxx-titlepagebody.cxx-ts .header cxx-docnum, body.cxx-ts cxx-titlepage .header cxx-docnum {
	font-size: 150%;
}

cxx-titlepagebody.cxx-pdts hgroup, body.cxx-pdts cxx-titlepage hgroup, cxx-titlepagebody.cxx-dts hgroup, body.cxx-dts cxx-titlepage hgroup, cxx-titlepagebody.cxx-ts hgroup, body.cxx-ts cxx-titlepage hgroup {
	position: absolute; top: 30%;
}

cxx-titlepagebody.cxx-pdts hgroup *, body.cxx-pdts cxx-titlepage hgroup *, cxx-titlepagebody.cxx-dts hgroup *, body.cxx-dts cxx-titlepage hgroup *, cxx-titlepagebody.cxx-ts hgroup *, body.cxx-ts cxx-titlepage hgroup * {
	margin: 0px;
}

cxx-titlepagebody.cxx-pdts hgroup h1, body.cxx-pdts cxx-titlepage hgroup h1, cxx-titlepagebody.cxx-dts hgroup h1, body.cxx-dts cxx-titlepage hgroup h1, cxx-titlepagebody.cxx-ts hgroup h1, body.cxx-ts cxx-titlepage hgroup h1 {
	font-size: 150%; font-weight: bold;
}

cxx-titlepagebody.cxx-pdts hgroup h2, body.cxx-pdts cxx-titlepage hgroup h2, cxx-titlepagebody.cxx-dts hgroup h2, body.cxx-dts cxx-titlepage hgroup h2, cxx-titlepagebody.cxx-ts hgroup h2, body.cxx-ts cxx-titlepage hgroup h2 {
	font-size: 100%; font-weight: normal;
}

cxx-titlepagebody.cxx-pdts .footer, body.cxx-pdts cxx-titlepage .footer, cxx-titlepagebody.cxx-dts .footer, body.cxx-dts cxx-titlepage .footer, cxx-titlepagebody.cxx-ts .footer, body.cxx-ts cxx-titlepage .footer {
	position: absolute; left: 0px; bottom: 5%;
}

cxx-titlepagebody.cxx-pdts figure, body.cxx-pdts cxx-titlepage figure, cxx-titlepagebody.cxx-dts figure, body.cxx-dts cxx-titlepage figure, cxx-titlepagebody.cxx-ts figure, body.cxx-ts cxx-titlepage figure {
	border: 1px solid rgb(17, 17, 17); padding: 10px; margin-left: auto; margin-right: auto;
}

cxx-titlepagebody.cxx-pdts figcaption, body.cxx-pdts cxx-titlepage figcaption, cxx-titlepagebody.cxx-dts figcaption, body.cxx-dts cxx-titlepage figcaption, cxx-titlepagebody.cxx-ts figcaption, body.cxx-ts cxx-titlepage figcaption {
	text-align: center; font-weight: bold;
}

cxx-titlepagebody.cxx-pdts .warning, body.cxx-pdts cxx-titlepage .warning, cxx-titlepagebody.cxx-dts .warning, body.cxx-dts cxx-titlepage .warning, cxx-titlepagebody.cxx-ts .warning, body.cxx-ts cxx-titlepage .warning {
	position: absolute; bottom: 20%;
}

cxx-titlepagebody.cxx-pdts .copyright address, body.cxx-pdts cxx-titlepage .copyright address, cxx-titlepagebody.cxx-dts .copyright address, body.cxx-dts cxx-titlepage .copyright address, cxx-titlepagebody.cxx-ts .copyright address, body.cxx-ts cxx-titlepage .copyright address {
	font-style: normal; margin-left: 2em;
}

cxx-titlepagebody.cxx-pdts .copyright address a, body.cxx-pdts cxx-titlepage .copyright address a, cxx-titlepagebody.cxx-dts .copyright address a, body.cxx-dts cxx-titlepage .copyright address a, cxx-titlepagebody.cxx-ts .copyright address a, body.cxx-ts cxx-titlepage .copyright address a {
	color: inherit; text-decoration: inherit;
}

cxx-titlepage th {
	text-align: left; vertical-align: top;
}cxx-foreword {
	display: block; min-height: 100%;
}

cxx-foreword {
	break-before: page; break-after: page; min-height: 100vh; margin-bottom: 2em;
}

cxx-forewordbody.cxx-draft cxx-foreword -no-combinator, body.cxx-draft cxx-foreword cxx-foreword -no-combinator {
	display: none;
}cxx-ednote {
	display: none;
}

cxx-ednotebody.cxx-draft, body.cxx-draft cxx-ednote {
	display: block;
}

cxx-ednote aside {
	float: right; max-width: 40%; margin: 1ex; border: 1px dashed rgb(136, 136, 136); padding: 1ex; background-color: rgb(238, 238, 238);
}

cxx-ednote.para aside {
	float: none; max-width: none;
}cxx-note .nowrap {
	white-space: nowrap;
}cxx-footnote {
	font-family: serif; white-space: normal; text-indent: initial;textIndent: initial; text-indent: initial; 
}

@media screen {
cxx-footnote aside {
	float: right; max-width: 30%; margin-left: 1em;
}


}

@media print {
cxx-footnote sup, cxx-footnote .marker {
	display: none;
}

cxx-footnote aside {
	
}


}cxx-example {
	display: block;
}

cxx-example.inline {
	display: inline;
}

cxx-example .nowrap {
	white-space: nowrap;
}cxx-publish-button {
	display: block;
}cxx-codeblock {
	display: block;
}bnf-grammar {
	display: block; font-style: italic; margin-left: 0.35in;
}bnf-rule {
	display: block; margin-left: 0.6in;
}bnf-alt {
	display: block; margin-left: 1.2in;
}bnf-terminal {
	font-style: normal;
}w-br {
	white-space: normal;
}

w-br::after {
	content: "​";
}</style>
  <meta charset="utf-8">
  
  <style shim-shadowdom-css="">/* Copyright 2014 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

@page {
    margin: 10%;
}
@page :left {
    @top-left { content: string(docname); font-weight: bold; font-size: 10pt; }
    @top-right { content: normal; }
    @bottom-left { content: counter(page); font-size: 10pt; }
    @bottom-right { content: "© ISO/IEC " string(pubyear) " — All rights reserved";
                    font-size: 10pt; }
}
@page :right {
    @top-left { content: normal; }
    @top-right { content: string(docname); font-weight: bold; font-size: 10pt; }
    @bottom-left { content: "© ISO/IEC " string(pubyear) " — All rights reserved";
                   font-size: 10pt; }
    @bottom-right { content: counter(page); font-size: 10pt; }
}
@page :first {
    @top-left { content: normal; }
    @top-right { content: normal; }
    @bottom-left { content: normal; }
    @bottom-right { content: normal; }
}

body { margin: 0; }

@media screen {
    body { max-width: 7in;
           /* Make room for paragraph numbers. */
           margin-left: 2em }
}

@media print {
    html { font-size: 10pt; }
    *   code { font-size: 80%; }
    /* Note that only Prince generates clickable links. */
    *   a[href] { text-decoration:none; }
}

@media screen {
    /* Needed to make the <cxx-titlepage>'s vertical spacing work.
       For print see the <cxx-titlepage> definition. */
    html, body {height: 100%}
}

*   .docname { string-set: docname content(); }
*   .pubyear { string-set: pubyear content(); }

cxx-clause, cxx-foreword { page-break-before: always; }
@media screen {
    cxx-clause, cxx-toc, cxx-foreword { margin-top: 3em; }
}

cxx-clause  header, cxx-foreword  h1 { font-size: 150%; }
cxx-toc  h1 { font-size: 150%; }
cxx-clause cxx-section  header { font-size: 117%; }
cxx-clause cxx-section cxx-section  header { font-size: 100%; }

[data-bookmark-label] { bookmark-label: attr(data-bookmark-label); }
h1 { bookmark-level: 1; }
cxx-toc  h1 { bookmark-level: 2; }
cxx-clause h1, cxx-foreword h1 { bookmark-level: 2; }
cxx-clause cxx-section h1 { bookmark-level: 3; }
cxx-clause cxx-section cxx-section h1 { bookmark-level: 4; }
/* The <h2> is a subtitle, which shouldn't get a PDF bookmark. */
cxx-titlepage  h2 { bookmark-level: none; }

*  .section-number { string-set: current-section "§ " content(); }

p {margin-top: .5em; margin-bottom: .5em}
p:first-child, ul, ol {margin-top: 0}

[para_num]::before { content: attr(para_num); float: left;
                     font-size: 70%; margin-left: -2.5em; width: 1.5em; text-align: right; }

del {text-decoration: line-through; color: #8B0040;}
ins {text-decoration: underline; color: #005100;}

pre {
    margin-left: 1em;
    margin-top: .5em;
    margin-bottom: .5em;
}

*   wbr::after {
    white-space: normal;
    content: '\200B';
}
*   code {
    /* Make inline code avoid line wraps unless we override it with <wbr>. */
    white-space: nowrap;
}
*   pre code {
    /* Keep block-code wrapping according to its context. */
    white-space: inherit;
}

*   table {
    border-collapse: collapse;
}
*   td, th {
    padding-left: .2em;
    padding-right: .2em;
    border: thin solid black;
}

/* Use an em-dash for the list bullet.
   'print' is a proxy for supporting ::marker. */
@media screen {
    ul {
        list-style: none;
        /* Relative positioning on the 'ul' lets the absolutely-positioned
           marker align relative to it.*/
        position: relative;
    }
    ul li:before {
        content: "\2014";
        position: absolute; left: 10px;
    }
}
@media print {
    ul li::marker {
        content: "\2014";
    }
    [is=cxx-table].list ul li::marker {
        content: none;
    }
}

/* This is here rather than inside elements/toc.html because browsers
   don't understand leader() or target-counter(), so they drop them
   inside the CSSOM. */
@media print {
    /* Generate page numbers in the table of contents. */
    cxx-toc  a[href]::after { content: leader(" . ") target-counter(attr(href), page); }

    cxx-footnote  aside { float: footnote; footnote-policy: line; }
}</style><style shim-shadowdom-css="">/*******************************
          Flex Layout
*******************************/

html   [layout][horizontal], html   [layout][vertical] {
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
}

html   [layout][horizontal][inline], html   [layout][vertical][inline] {
  display: -ms-inline-flexbox;
  display: -webkit-inline-flex;
  display: inline-flex;
}

html   [layout][horizontal] {
  -ms-flex-direction: row;
  -webkit-flex-direction: row;
  flex-direction: row;
}

html   [layout][horizontal][reverse] {
  -ms-flex-direction: row-reverse;
  -webkit-flex-direction: row-reverse;
  flex-direction: row-reverse;
}

html   [layout][vertical] {
  -ms-flex-direction: column;
  -webkit-flex-direction: column;
  flex-direction: column;
}

html   [layout][vertical][reverse] {
  -ms-flex-direction: column-reverse;
  -webkit-flex-direction: column-reverse;
  flex-direction: column-reverse;
}

html   [layout][wrap] {
  -ms-flex-wrap: wrap;
  -webkit-flex-wrap: wrap;
  flex-wrap: wrap;
}

html   [layout][wrap-reverse] {
  -ms-flex-wrap: wrap-reverse;
  -webkit-flex-wrap: wrap-reverse;
  flex-wrap: wrap-reverse;
}

html   [flex] {
  -ms-flex: 1 1 0.000000001px;
  -webkit-flex: 1;
  flex: 1;
  -webkit-flex-basis: 0.000000001px;
  flex-basis: 0.000000001px;
}

html   [vertical][layout] > [flex][auto-vertical], html   [vertical][layout]  [flex][auto-vertical] {
  -ms-flex: 1 1 auto;
  -webkit-flex-basis: auto;
  flex-basis: auto;
}

html   [flex][auto] {
  -ms-flex: 1 1 auto;
  -webkit-flex-basis: auto;
  flex-basis: auto;
}

html   [flex][none] {
  -ms-flex: none;
  -webkit-flex: none;
  flex: none;
}

html   [flex][one] {
  -ms-flex: 1;
  -webkit-flex: 1;
  flex: 1;
}

html   [flex][two] {
  -ms-flex: 2;
  -webkit-flex: 2;
  flex: 2;
}

html   [flex][three] {
  -ms-flex: 3;
  -webkit-flex: 3;
  flex: 3;
}

html   [flex][four] {
  -ms-flex: 4;
  -webkit-flex: 4;
  flex: 4;
}

html   [flex][five] {
  -ms-flex: 5;
  -webkit-flex: 5;
  flex: 5;
}

html   [flex][six] {
  -ms-flex: 6;
  -webkit-flex: 6;
  flex: 6;
}

html   [flex][seven] {
  -ms-flex: 7;
  -webkit-flex: 7;
  flex: 7;
}

html   [flex][eight] {
  -ms-flex: 8;
  -webkit-flex: 8;
  flex: 8;
}

html   [flex][nine] {
  -ms-flex: 9;
  -webkit-flex: 9;
  flex: 9;
}

html   [flex][ten] {
  -ms-flex: 10;
  -webkit-flex: 10;
  flex: 10;
}

html   [flex][eleven] {
  -ms-flex: 11;
  -webkit-flex: 11;
  flex: 11;
}

html   [flex][twelve] {
  -ms-flex: 12;
  -webkit-flex: 12;
  flex: 12;
}

/* alignment in cross axis */

html   [layout][start] {
  -ms-flex-align: start;
  -webkit-align-items: flex-start;
  align-items: flex-start;
}

html   [layout][center], html   [layout][center-center] {
  -ms-flex-align: center;
  -webkit-align-items: center;
  align-items: center;
}

html   [layout][end] {
  -ms-flex-align: end;
  -webkit-align-items: flex-end;
  align-items: flex-end;
}

/* alignment in main axis */

html   [layout][start-justified] {
  -ms-flex-pack: start;
  -webkit-justify-content: flex-start;
  justify-content: flex-start;
}

html   [layout][center-justified], html   [layout][center-center] {
  -ms-flex-pack: center;
  -webkit-justify-content: center;
  justify-content: center;
}

html   [layout][end-justified] {
  -ms-flex-pack: end;
  -webkit-justify-content: flex-end;
  justify-content: flex-end;
}

html   [layout][around-justified] {
  -ms-flex-pack: distribute;
  -webkit-justify-content: space-around;
  justify-content: space-around;
}

html   [layout][justified] {
  -ms-flex-pack: justify;
  -webkit-justify-content: space-between;
  justify-content: space-between;
}

/* self alignment */

html   [self-start] {
  -ms-align-self: flex-start;
  -webkit-align-self: flex-start;
  align-self: flex-start;
}

html   [self-center] {
  -ms-align-self: center;
  -webkit-align-self: center;
  align-self: center;
}

html   [self-end] {
  -ms-align-self: flex-end;
  -webkit-align-self: flex-end;
  align-self: flex-end;
}

html   [self-stretch] {
  -ms-align-self: stretch;
  -webkit-align-self: stretch;
  align-self: stretch;
}

/*******************************
          Other Layout
*******************************/

html   [block] {
  display: block;
}

/* ie support for hidden */
html   [hidden] {
  display: none !important;
}

html   [relative] {
  position: relative;
}

html   [fit] {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

body[fullbleed] {
  margin: 0;
  height: 100vh;
}

/*******************************
            Other
*******************************/

html   [segment], html   segment {
  display: block;
  position: relative;
  -webkit-box-sizing: border-box;
  -ms-box-sizing: border-box;
  box-sizing: border-box;
  margin: 1em 0.5em;
  padding: 1em;
  background-color: white;
  -webkit-box-shadow: 0px 0px 0px 1px rgba(0, 0, 0, 0.1);
  box-shadow: 0px 0px 0px 1px rgba(0, 0, 0, 0.1);
  border-radius: 5px 5px 5px 5px;
}</style>
<style>[touch-action="none"]{ -ms-touch-action: none; touch-action: none;}
[touch-action="auto"]{ -ms-touch-action: auto; touch-action: auto;}
[touch-action="pan-x"]{ -ms-touch-action: pan-x; touch-action: pan-x;}
[touch-action="pan-y"]{ -ms-touch-action: pan-y; touch-action: pan-y;}
[touch-action="pan-x pan-y"],[touch-action="pan-y pan-x"]{ -ms-touch-action: pan-x pan-y; touch-action: pan-x pan-y;}
[touch-action="manipulation"]{ -ms-touch-action: manipulation; touch-action: manipulation;}
</style><title>C++ Extensions for Library Fundamentals, Version 3, Working Draft</title></head>
<body class="cxx-draft">
<cxx-titlepage>
    
    
      <div class="page">
        <table class="header">
          
            <tr><th>Document Number:</th><td><cxx-docnum class="docname">N4920</cxx-docnum></td></tr>
          
          
            <tr><th>Date:</th><td><time pubdate=""><span class="pubyear">2022</span>-08-15</time></td></tr>
          
          
            <tr><th>Revises:</th><td><cxx-revises><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/n4908.html">N4908</a></cxx-revises></td></tr>
          
          
            <tr><th>Editor:</th><td><cxx-editor>
    Thomas Köppe<br>
    Google DeepMind<br>
    <cxx-email><a href="mailto:tkoeppe@google.com">tkoeppe@google.com</a></cxx-email>
  </cxx-editor></td></tr>
          
        </table>
        <h1>Working Draft, C++ Extensions for Library Fundamentals, Version 3</h1>
        <p class="warning"><strong>Note: this is an early draft. It’s known to be
        incomplet and incorrekt, and it has lots of b<span style="margin-left: -1.2pt; margin-right: 1pt">a</span>d<span style="width:1.5em"> </span>for<span style="margin-left:-3pt; margin-right:0.6pt">mat</span>ti<span style="position:relative; top:-0.15ex">n</span>g.</strong></p>
      </div>
    

    

    
  </cxx-titlepage>

<cxx-toc>
    
    <nav>
      <h1>Contents</h1>
      
        
          <ol>
            
              <li><span class="marker">1</span><a href="#general">General</a>
        
          <ol>
            
              <li><span class="marker">1.1</span><a href="#general.scope">Scope</a>
        
      </li>
            
              <li><span class="marker">1.2</span><a href="#general.references">Normative references</a>
        
      </li>
            
              <li><span class="marker">1.3</span><a href="#general.namespaces">Namespaces, headers, and modifications to standard classes</a>
        
      </li>
            
              <li><span class="marker">1.4</span><a href="#general.plans">Future plans (Informative)</a>
        
      </li>
            
              <li><span class="marker">1.5</span><a href="#general.feature.test">Feature-testing recommendations (Informative)</a>
        
      </li>
            
          </ol>
        
      </li>
            
              <li><span class="marker">2</span><a href="#mods">Modifications to the C++ Standard Library</a>
        
          <ol>
            
              <li><span class="marker">2.1</span><a href="#mods.exception.requirements">Exception Requirements</a>
        
      </li>
            
              <li><span class="marker">2.2</span><a href="#mods.allocator.uses">Uses-allocator construction</a>
        
      </li>
            
          </ol>
        
      </li>
            
              <li><span class="marker">3</span><a href="#utilities">General utilities library</a>
        
          <ol>
            
              <li><span class="marker">3.1</span><a href="#utility">Utility components</a>
        
          <ol>
            
              <li><span class="marker">3.1.1</span><a href="#utility.syn">Header &lt;experimental/utility&gt; synopsis</a>
        
      </li>
            
              <li><span class="marker">3.1.2</span><a href="#utility.erased.type">Class erased_type</a>
        
      </li>
            
          </ol>
        
      </li>
            
              <li><span class="marker">3.2</span><a href="#propagate_const">Constness propagation</a>
        
          <ol>
            
              <li><span class="marker">3.2.1</span><a href="#propagate_const.syn">Header &lt;experimental/propagate_const&gt; synopsis</a>
        
      </li>
            
              <li><span class="marker">3.2.2</span><a href="#propagate_const">Class template propagate_const</a>
        
          <ol>
            
              <li><span class="marker">3.2.2.1</span><a href="#propagate_const.overview">Class template propagate_const overview</a>
        
      </li>
            
              <li><span class="marker">3.2.2.2</span><a href="#propagate_const.requirements">propagate_const general requirements on T</a>
        
      </li>
            
              <li><span class="marker">3.2.2.3</span><a href="#propagate_const.class_type_requirements">propagate_const requirements on class type T</a>
        
      </li>
            
              <li><span class="marker">3.2.2.4</span><a href="#propagate_const.ctor">propagate_const constructors</a>
        
      </li>
            
              <li><span class="marker">3.2.2.5</span><a href="#propagate_const.assignment">propagate_const assignment</a>
        
      </li>
            
              <li><span class="marker">3.2.2.6</span><a href="#propagate_const.const_observers">propagate_const const observers</a>
        
      </li>
            
              <li><span class="marker">3.2.2.7</span><a href="#propagate_const.non_const_observers">propagate_const non-const observers</a>
        
      </li>
            
              <li><span class="marker">3.2.2.8</span><a href="#propagate_const.modifiers">propagate_const modifiers</a>
        
      </li>
            
              <li><span class="marker">3.2.2.9</span><a href="#propagate_const.relational">propagate_const relational operators</a>
        
      </li>
            
              <li><span class="marker">3.2.2.10</span><a href="#propagate_const.algorithms">propagate_const specialized algorithms</a>
        
      </li>
            
              <li><span class="marker">3.2.2.11</span><a href="#propagate_const.underlying">propagate_const underlying pointer access</a>
        
      </li>
            
              <li><span class="marker">3.2.2.12</span><a href="#propagate_const.hash">propagate_const hash support</a>
        
      </li>
            
              <li><span class="marker">3.2.2.13</span><a href="#propagate_const.comparison_function_objects">propagate_const comparison function objects</a>
        
      </li>
            
          </ol>
        
      </li>
            
          </ol>
        
      </li>
            
              <li><span class="marker">3.3</span><a href="#scopeguard">Scope guard support</a>
        
          <ol>
            
              <li><span class="marker">3.3.1</span><a href="#scope.syn">Header &lt;experimental/scope&gt; synopsis</a>
        
      </li>
            
              <li><span class="marker">3.3.2</span><a href="#scopeguard.exit">Class templates scope_exit, scope_fail, and scope_success</a>
        
      </li>
            
              <li><span class="marker">3.3.3</span><a href="#scopeguard.uniqueres">Class template unique_resource</a>
        
          <ol>
            
              <li><span class="marker">3.3.3.1</span><a href="#scopeguard.uniqueres.overview">Overview</a>
        
      </li>
            
              <li><span class="marker">3.3.3.2</span><a href="#scopeguard.uniqueres.ctor">Constructors</a>
        
      </li>
            
              <li><span class="marker">3.3.3.3</span><a href="#scopeguard.uniqueres.dtor">Destructor</a>
        
      </li>
            
              <li><span class="marker">3.3.3.4</span><a href="#scopeguard.uniqueres.assign">Assignment</a>
        
      </li>
            
              <li><span class="marker">3.3.3.5</span><a href="#scopeguard.uniqueres.members">Other member functions</a>
        
      </li>
            
              <li><span class="marker">3.3.3.6</span><a href="#scopeguard.uniqueres.create">unique_resource creation</a>
        
      </li>
            
          </ol>
        
      </li>
            
          </ol>
        
      </li>
            
              <li><span class="marker">3.4</span><a href="#meta">Metaprogramming and type traits</a>
        
          <ol>
            
              <li><span class="marker">3.4.1</span><a href="#meta.type.syn">Header &lt;experimental/type_traits&gt; synopsis</a>
        
      </li>
            
              <li><span class="marker">3.4.2</span><a href="#meta.trans.other">Other type transformations</a>
        
      </li>
            
              <li><span class="marker">3.4.3</span><a href="#meta.detect">Detection idiom</a>
        
      </li>
            
          </ol>
        
      </li>
            
          </ol>
        
      </li>
            
              <li><span class="marker">4</span><a href="#func">Function objects</a>
        
          <ol>
            
              <li><span class="marker">4.1</span><a href="#functional.syn">Header &lt;experimental/functional&gt; synopsis</a>
        
      </li>
            
              <li><span class="marker">4.2</span><a href="#func.wrap.func">Class template function</a>
        
          <ol>
            
              <li><span class="marker">4.2.1</span><a href="#func.wrap.func.overview">Overview</a>
        
      </li>
            
              <li><span class="marker">4.2.2</span><a href="#func.wrap.func.con">function construct/copy/destroy</a>
        
      </li>
            
              <li><span class="marker">4.2.3</span><a href="#func.wrap.func.mod">function modifiers</a>
        
      </li>
            
          </ol>
        
      </li>
            
          </ol>
        
      </li>
            
              <li><span class="marker">5</span><a href="#memory">Memory</a>
        
          <ol>
            
              <li><span class="marker">5.1</span><a href="#memory.syn">Header &lt;experimental/memory&gt; synopsis</a>
        
      </li>
            
              <li><span class="marker">5.2</span><a href="#memory.observer.ptr">Non-owning (observer) pointers</a>
        
          <ol>
            
              <li><span class="marker">5.2.1</span><a href="#memory.observer.ptr.overview">Class template observer_ptr overview</a>
        
      </li>
            
              <li><span class="marker">5.2.2</span><a href="#memory.observer.ptr.ctor">observer_ptr constructors</a>
        
      </li>
            
              <li><span class="marker">5.2.3</span><a href="#memory.observer.ptr.obs">observer_ptr observers</a>
        
      </li>
            
              <li><span class="marker">5.2.4</span><a href="#memory.observer.ptr.conv">observer_ptr conversions</a>
        
      </li>
            
              <li><span class="marker">5.2.5</span><a href="#memory.observer.ptr.mod">observer_ptr modifiers</a>
        
      </li>
            
              <li><span class="marker">5.2.6</span><a href="#memory.observer.ptr.special">observer_ptr specialized algorithms</a>
        
      </li>
            
              <li><span class="marker">5.2.7</span><a href="#memory.observer.ptr.hash">observer_ptr hash support</a>
        
      </li>
            
          </ol>
        
      </li>
            
              <li><span class="marker">5.3</span><a href="#memory.type.erased.allocator">Type-erased allocator</a>
        
      </li>
            
              <li><span class="marker">5.4</span><a href="#memory.resource.syn">Header &lt;experimental/memory_resource&gt; synopsis</a>
        
      </li>
            
              <li><span class="marker">5.5</span><a href="#memory.resource.adaptor">Alias template resource_adaptor</a>
        
          <ol>
            
              <li><span class="marker">5.5.1</span><a href="#memory.resource.adaptor.overview">resource_adaptor</a>
        
      </li>
            
              <li><span class="marker">5.5.2</span><a href="#memory.resource.adaptor.ctor">resource_adaptor_imp constructors</a>
        
      </li>
            
              <li><span class="marker">5.5.3</span><a href="#memory.resource.adaptor.mem">resource_adaptor_imp member functions</a>
        
      </li>
            
          </ol>
        
      </li>
            
          </ol>
        
      </li>
            
              <li><span class="marker">6</span><a href="#iterator">Iterators library</a>
        
          <ol>
            
              <li><span class="marker">6.1</span><a href="#iterator.syn">Header &lt;experimental/iterator&gt; synopsis</a>
        
      </li>
            
              <li><span class="marker">6.2</span><a href="#iterator.ostream.joiner">Class template ostream_joiner</a>
        
          <ol>
            
              <li><span class="marker">6.2.1</span><a href="#iterator.ostream.joiner.overview">Overview</a>
        
      </li>
            
              <li><span class="marker">6.2.2</span><a href="#iterator.ostream.joiner.cons">ostream_joiner constructor</a>
        
      </li>
            
              <li><span class="marker">6.2.3</span><a href="#iterator.ostream.joiner.ops">ostream_joiner operations</a>
        
      </li>
            
              <li><span class="marker">6.2.4</span><a href="#iterator.ostream.joiner.creation">ostream_joiner creation function</a>
        
      </li>
            
          </ol>
        
      </li>
            
          </ol>
        
      </li>
            
              <li><span class="marker">7</span><a href="#futures">Futures</a>
        
          <ol>
            
              <li><span class="marker">7.1</span><a href="#future.syn">Header &lt;experimental/future&gt; synopsis</a>
        
      </li>
            
              <li><span class="marker">7.2</span><a href="#futures.promise">Class template promise</a>
        
      </li>
            
              <li><span class="marker">7.3</span><a href="#futures.task">Class template packaged_task</a>
        
      </li>
            
          </ol>
        
      </li>
            
              <li><span class="marker">8</span><a href="#algorithms">Algorithms library</a>
        
          <ol>
            
              <li><span class="marker">8.1</span><a href="#algorithm.syn">Header &lt;experimental/algorithm&gt; synopsis</a>
        
      </li>
            
              <li><span class="marker">8.2</span><a href="#alg.random.sample">Sampling</a>
        
      </li>
            
              <li><span class="marker">8.3</span><a href="#alg.random.shuffle">Shuffle</a>
        
      </li>
            
          </ol>
        
      </li>
            
              <li><span class="marker">9</span><a href="#numeric">Numerics library</a>
        
          <ol>
            
              <li><span class="marker">9.1</span><a href="#rand">Random number generation</a>
        
          <ol>
            
              <li><span class="marker">9.1.1</span><a href="#rand.syn">Header &lt;experimental/random&gt; synopsis</a>
        
      </li>
            
              <li><span class="marker">9.1.2</span><a href="#rand.randint">Function template randint</a>
        
      </li>
            
          </ol>
        
      </li>
            
          </ol>
        
      </li>
            
          </ol>
        
      
    </nav>
  </cxx-toc>

<!-- cxx-foreword id="foreword">
<p>This document was prepared by Joint Technical Committee ISO/IEC JTC 1,
  Information Technology, Subcommittee SC 22, Programming languages, their
  environments and system software interfaces. This edition of ISO/IEC
  19568:20?? cancels and replaces the edition ISO/IEC 19568:2017, which has
  been technically revised and includes the following changes:</p>

<ul>
  <li>[to be provided]</li>
</ul>
</cxx-foreword -->
<cxx-clause id="general">
    

    <section>
      <header><span class="section-number">1</span> <h1 data-bookmark-label="1 General">General</h1> <span style="float:right"><a href="#general">[general]</a></span></header>
      
  
  <cxx-section id="general.scope">
    

    <section>
      <header><span class="section-number">1.1</span> <h1 data-bookmark-label="1.1 Scope">Scope</h1> <span style="float:right"><a href="#general.scope">[general.scope]</a></span></header>
      
    
    <p id="general.scope.1" para_num="1">This technical specification describes extensions to the C++
    Standard Library (<cxx-ref to="general.references"><a title="general.references" href="#general.references">1.2</a></cxx-ref>). These extensions are classes
    and functions that are likely to be used widely within a program
    and/or on the interface boundaries between libraries written by
    different organizations.</p>

    <p id="general.scope.2" para_num="2">This technical specification is non-normative. Some of the
    library components in this technical specification may be
    considered for standardization in a future version of C++, but
    they are not currently part of any C++ standard. Some of the
    components in this technical specification may never be
    standardized, and others may be standardized in a substantially
    changed form.</p>

    <p id="general.scope.3" para_num="3">The goal of this technical specification is to build more
    widespread existing practice for an expanded C++ standard
    library. It gives advice on extensions to those vendors who wish
    to provide them.</p>
  
    </section>
  </cxx-section>

  <cxx-section id="general.references">
    

    <section>
      <header><span class="section-number">1.2</span> <h1 data-bookmark-label="1.2 Normative references">Normative references</h1> <span style="float:right"><a href="#general.references">[general.references]</a></span></header>
      
    

    <p id="general.references.1" para_num="1">The following referenced document is indispensable for the
    application of this document. For dated references, only the
    edition cited applies. For undated references, the latest edition
    of the referenced document (including any amendments) applies.</p>

    <ul>
      <li>ISO/IEC 14882:2020, <cite>Programming Languages — C++</cite>
      </li>
    </ul>

    <p id="general.references.2" para_num="2">ISO/IEC 14882:2020 is herein called the <dfn>C++ Standard</dfn>.
    References to clauses within the C++ Standard are written as "C++20
    §3.2". The library described in ISO/IEC 14882:2020 clauses 16–32 is
    herein called the <dfn>C++ Standard Library</dfn>.</p>

    <p id="general.references.3" para_num="3">Unless otherwise specified, the whole of the C++ Standard's Library
    introduction (<cxx-ref in="cxx" to="library">C++20 <span title="library">§16</span></cxx-ref>) is included into this
    Technical Specification by reference.</p>
  
    </section>
  </cxx-section>

  <cxx-section id="general.namespaces">
    

    <section>
      <header><span class="section-number">1.3</span> <h1 data-bookmark-label="1.3 Namespaces, headers, and modifications to standard classes">Namespaces, headers, and modifications to standard classes</h1> <span style="float:right"><a href="#general.namespaces">[general.namespaces]</a></span></header>
      
    

    <p id="general.namespaces.1" para_num="1">Since the extensions described in this technical specification
    are experimental and not part of the C++ standard library, they
    should not be declared directly within namespace
    <code>std</code>.
    Unless otherwise specified, all components described in this technical specification either:
    </p>
    <ul>
      <li>modify an existing interface in the C++ Standard Library in-place,</li>
      <li>
        are declared in a namespace whose name appends <code>::experimental::fundamentals_v3</code>
        to a namespace defined in the C++ Standard Library,
        such as <code>std</code> or <code>std::chrono</code>, or
      </li>
      <li>
        are declared in a subnamespace of a namespace described in the previous bullet,
        whose name is not the same as an existing subnamespace of namespace <code>std</code>.
      </li>
    </ul>

    <cxx-example>
    
    <span class="nowrap">[ <em>Example:</em></span>
    
      This TS does not define <code>std::experimental::fundamentals_v3::pmr</code>
      because the C++ Standard Library defines <code>std::pmr</code>.
    
    <span class="nowrap">— <em>end example</em> ]</span>
  </cxx-example>

    <p id="general.namespaces.2" para_num="2">Each header described in this technical
    specification shall import the contents of
    <code>std::experimental::fundamentals_v3</code> into
    <code>std::experimental</code> as if by</p>

    <pre><code>namespace std::experimental::inline fundamentals_v3 {}</code></pre>

    <p id="general.namespaces.3" para_num="3">
      This technical specification also describes some experimental modifications to existing interfaces in the C++ Standard Library.
      These modifications are described by quoting the affected parts of the standard
      and using <ins>underlining</ins> to represent added text and <del>strike-through</del> to represent deleted text.
    </p>

    <p id="general.namespaces.4" para_num="4">Unless otherwise specified, references to other entities
    described in this technical specification are assumed to be
    qualified with <code>std::experimental::fundamentals_v3::</code>,
    and references to entities described in the standard are assumed
    to be qualified with <code>std::</code>.</p>

    <p id="general.namespaces.5" para_num="5">Extensions that are expected to eventually be added to an
    existing header <code>&lt;meow&gt;</code> are provided inside the
    <code>&lt;experimental/meow&gt;</code> header, which shall include
    the standard contents of <code>&lt;meow&gt;</code> as if by</p>
    <pre><code>#include &lt;meow&gt;</code></pre>

    <p id="general.namespaces.6" para_num="6">New headers are also provided in the
    <code>&lt;experimental/&gt;</code> directory, but without such an
    <code>#include</code>.</p>

    <table is="cxx-table" id="tab.cxx.headers" class="list" columns="3" role="presentation">
    

    <caption>Table 1 — <wbr><span>C++ library headers</span></caption>
    
      
      <tbody><tr><td><ul><li><code>&lt;experimental/algorithm&gt;</code></li><li><code>&lt;experimental/functional&gt;</code></li><li><code>&lt;experimental/future&gt;</code></li><li><code>&lt;experimental/iterator&gt;</code></li></ul></td><td><ul><li><code>&lt;experimental/memory&gt;</code></li><li><code>&lt;experimental/memory_resource&gt;</code></li><li><code>&lt;experimental/propagate_const&gt;</code></li><li><code>&lt;experimental/random&gt;</code></li></ul></td><td><ul><li><code>&lt;experimental/scope&gt;</code></li><li><code>&lt;experimental/type_traits&gt;</code></li><li><code>&lt;experimental/utility&gt;</code></li></ul></td></tr>
    </tbody>
  </table>
  
    </section>
  </cxx-section>

  <cxx-section id="general.plans">
    

    <section>
      <header><span class="section-number">1.4</span> <h1 data-bookmark-label="1.4 Future plans (Informative)">Future plans (Informative)</h1> <span style="float:right"><a href="#general.plans">[general.plans]</a></span></header>
      
    

    <p id="general.plans.1" para_num="1">This section describes tentative plans for future versions of
    this technical specification and plans for moving content into
    future versions of the C++ Standard.</p>

    <p id="general.plans.2" para_num="2">The C++ committee intends to release new versions of this
    technical specification periodically, containing the
    library extensions we hope to add to a near-future version of the
    C++ Standard. Future versions will define their contents in
    <code>std::experimental::fundamentals_v4</code>,
    <code>std::experimental::fundamentals_v5</code>, etc., with the
    most recent implemented version inlined into
    <code>std::experimental</code>.</p>

    <p id="general.plans.3" para_num="3">When an extension defined in this or a future version of this
    technical specification represents enough existing practice, it
    will be moved into the next version of the C++ Standard by
    removing the <code>experimental::fundamentals_v<var>N</var></code>
    segment of its namespace and by removing the
    <code>experimental/</code> prefix from its header's path.</p>
  
    </section>
  </cxx-section>

  <cxx-section id="general.feature.test">
    

    <section>
      <header><span class="section-number">1.5</span> <h1 data-bookmark-label="1.5 Feature-testing recommendations (Informative)">Feature-testing recommendations (Informative)</h1> <span style="float:right"><a href="#general.feature.test">[general.feature.test]</a></span></header>
      
    

    <p id="general.feature.test.1" para_num="1">
      For the sake of improved portability between partial implementations of various C++ standards,
      WG21 (the ISO technical committee for the C++ programming language) recommends
      that implementers and programmers follow the guidelines in this section concerning feature-test macros.
      <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    <a href="http://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations">WG21's SD-6</a> makes similar recommendations for the C++ Standard itself.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
    </p>

    <p id="general.feature.test.2" para_num="2">
      Implementers who provide a new standard feature should define a macro with the recommended name,
      in the same circumstances under which the feature is available (for example, taking into account relevant command-line options),
      to indicate the presence of support for that feature.
      Implementers should define that macro with the value specified in
      the most recent version of this technical specification that they have implemented.
      The recommended macro name is "<code>__cpp_lib_experimental_</code>" followed by the string in the "Macro Name Suffix" column.
    </p>

    <p id="general.feature.test.3" para_num="3">
      Programmers who wish to determine whether a feature is available in an implementation should base that determination on
      the presence of the header (determined with <code>__has_include(&lt;header/name&gt;)</code>) and
      the state of the macro with the recommended name.
      (The absence of a tested feature may result in a program with decreased functionality, or the relevant functionality may be provided in a different way.
      A program that strictly depends on support for a feature can just try to use the feature unconditionally;
      presumably, on an implementation lacking necessary support, translation will fail.)
    </p>

    <table is="cxx-table" class="column-rules">
    

    <caption>Table 2 — <wbr><span>Significant features in this technical specification</span></caption>
    
      

      <thead>
        <tr>
          <th>Doc. No.</th>
          <th>Title</th>
          <th>Primary Section</th>
          <th>Macro Name Suffix</th>
          <th>Value</th>
          <th>Header</th>
        </tr>
      </thead>

      <!-- These rows are in the same order as their feature appears in this document. -->
      <tbody><tr>
        <td>N4388</td>
        <td>A Proposal to Add a Const-Propagating Wrapper to the Standard Library
        </td><td><cxx-ref to="propagate_const"><a title="propagate_const" href="#propagate_const">3.2</a></cxx-ref>
        </td><td><code>propagate_const</code>
        </td><td>201505
        </td><td><code>&lt;experimental/propagate_const&gt;</code>
      </td></tr>
      <tr>
        <td>P0052R10</td>
        <td>Generic Scope Guard and RAII Wrapper for the Standard Library
        </td><td><cxx-ref to="scopeguard"><a title="scopeguard" href="#scopeguard">3.3</a></cxx-ref>
        </td><td><code>scope</code>
        </td><td>201902
        </td><td><code>&lt;experimental/scope&gt;</code>
      </td></tr>
      <tr>
        <td>N3866</td>
        <td>Invocation type traits</td>
        <td><cxx-ref to="meta.trans.other"><a title="meta.trans.other" href="#meta.trans.other">3.4.2</a></cxx-ref></td>
        <td><code>invocation_type</code></td>
        <td>201406</td>
        <td><code>&lt;experimental/type_traits&gt;</code></td>
      </tr>
      <tr>
        <td>N4502</td>
        <td>The C++ Detection Idiom</td>
        <td><cxx-ref to="meta.detect"><a title="meta.detect" href="#meta.detect">3.4.3</a></cxx-ref></td>
        <td><code>detect</code></td>
        <td>201505</td>
        <td><code>&lt;experimental/type_traits&gt;</code></td>
      </tr>
      <tr>
        <td>N3916</td>
        <td>Type-erased allocator for <code>std::function</code></td>
        <td><cxx-ref to="func.wrap.func"><a title="func.wrap.func" href="#func.wrap.func">4.2</a></cxx-ref></td>
        <td><code>function_erased_allocator</code></td>
        <td>201406</td>
        <td>
          <code>&lt;experimental/functional&gt;</code>,
          <code>&lt;experimental/utility&gt;</code></td>
      </tr>
      <tr>
        <td>N3916</td>
        <td>Polymorphic Memory Resources</td>
        <td><cxx-ref to="memory.resource.syn"><a title="memory.resource.syn" href="#memory.resource.syn">5.4</a></cxx-ref></td>
        <td><code>memory_resources</code></td>
        <td>201803</td>
        <td><code>&lt;experimental/memory_resouce&gt;</code></td>
      </tr>
      <tr>
        <td>N4282</td>
        <td>The World’s Dumbest Smart Pointer
        </td><td><cxx-ref to="memory.observer.ptr"><a title="memory.observer.ptr" href="#memory.observer.ptr">5.2</a></cxx-ref>
        </td><td><code>observer_ptr</code>
        </td><td>201411
        </td><td><code>&lt;experimental/memory&gt;</code>
      </td></tr>
      <tr>
        <td>N4257</td>
        <td>Delimited iterators</td>
        <td><cxx-ref to="iterator.ostream.joiner"><a title="iterator.ostream.joiner" href="#iterator.ostream.joiner">6.2</a></cxx-ref></td>
        <td><code>ostream_joiner</code></td>
        <td>201411</td>
        <td><code>&lt;experimental/iterator&gt;</code></td>
      </tr>
      <tr>
        <td>N3916</td>
        <td>Type-erased allocator for <code>std::promise</code></td>
        <td><cxx-ref to="futures.promise"><a title="futures.promise" href="#futures.promise">7.2</a></cxx-ref></td>
        <td><code>promise_erased_allocator</code></td>
        <td>201406</td>
        <td>
          <code>&lt;experimental/future&gt;</code>,
          <code>&lt;experimental/utility&gt;</code></td>
      </tr>
      <tr>
        <td>N3916</td>
        <td>Type-erased allocator for <code>std::packaged_task</code></td>
        <td><cxx-ref to="futures.task"><a title="futures.task" href="#futures.task">7.3</a></cxx-ref></td>
        <td><code>packaged_task_erased_allocator</code></td>
        <td>201406</td>
        <td>
          <code>&lt;experimental/future&gt;</code>,
          <code>&lt;experimental/utility&gt;</code></td>
      </tr>
      <tr>
        <td>N3925</td>
        <td>A <code>sample</code> Proposal</td>
        <td><cxx-ref to="alg.random.sample"><a title="alg.random.sample" href="#alg.random.sample">8.2</a></cxx-ref></td>
        <td><code>sample</code></td>
        <td>201402</td>
        <td><code>&lt;experimental/algorithm&gt;</code></td>
      </tr>
      <tr>
        <td>N4531</td>
        <td><code>std::rand</code> replacement</td>
        <td><cxx-ref to="rand.randint"><a title="rand.randint" href="#rand.randint">9.1.2</a></cxx-ref></td>
        <td><code>randint</code></td>
        <td>201511</td>
        <td><code>&lt;experimental/random&gt;</code></td>
      </tr>
    </tbody>
  </table>
  
    </section>
  </cxx-section>

    </section>
  </cxx-clause>

<cxx-clause id="mods">
    

    <section>
      <header><span class="section-number">2</span> <h1 data-bookmark-label="2 Modifications to the C++ Standard Library">Modifications to the C++ Standard Library</h1> <span style="float:right"><a href="#mods">[mods]</a></span></header>
      
  

  <p id="mods.1" para_num="1">
    Implementations that conform to this technical specification shall
    behave as if the modifications contained in this section are made to the C++ Standard.
  </p>

  <cxx-section id="mods.exception.requirements">
    

    <section>
      <header><span class="section-number">2.1</span> <h1 data-bookmark-label="2.1 Exception Requirements">Exception Requirements</h1> <span style="float:right"><a href="#mods.exception.requirements">[mods.exception.requirements]</a></span></header>
      
    
    <p id="mods.exception.requirements.1" para_num="1">The following changes to the library introduction allow the destructor
      of <code>scope_success</code> to throw exceptions.</p>
    <blockquote>
      <p><b>16.5.4.8 Other functions [res.on.functions]</b></p>
      <p para_num="1">In certain cases […]</p>
      <p para_num="2">In particular, the effects are undefined in the following cases:</p>
      <ul>
        <li>[…]</li>
        <li>if any replacement function or handler function or destructor operation
          exits via an exception, unless specifically allowed in the applicable
          <i>Required behavior:</i><ins> or <i>Throws:</i></ins> paragraph.
        </li>
        <li>if an incomplete type (6.9) is used as a template argument when instantiating
          a template component, unless specifically allowed for that component.</li>
      </ul>
      <p><b>16.5.5.13 Restrictions on exception handling [res.on.exception.handling]</b></p>
      <p para_num="1">[…]</p>
      <p para_num="2">Functions from the C standard library shall not throw exceptions<sup>181</sup>
        except when such a function calls a program-supplied function that throws an exception.<sup>182</sup></p>
      <p para_num="3"><ins>Unless otherwise specified, destructor</ins><del>Destructor</del>
        operations defined in the C++ standard library shall not throw exceptions.
        Every destructor<ins> without an exception specification</ins> in the C++ standard library
        shall behave as if it had a non-throwing exception specification.</p>
      <p para_num="4">Functions defined in the C++ standard library […]</p>
    </blockquote>
  
    </section>
  </cxx-section>

  <cxx-section id="mods.allocator.uses">
    

    <section>
      <header><span class="section-number">2.2</span> <h1 data-bookmark-label="2.2 Uses-allocator construction">Uses-allocator construction</h1> <span style="float:right"><a href="#mods.allocator.uses">[mods.allocator.uses]</a></span></header>
      
    

    <p id="mods.allocator.uses.1" para_num="1">
      The following changes to the <code>uses_allocator</code> trait and to the description of uses-allocator construction
      allow a <code>memory_resource</code> pointer act as an allocator in many circumstances.
      <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    Existing programs that use standard allocators would be unaffected by this change.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
    </p>

    <blockquote>
      <p><b>20.10.8 uses_allocator [allocator.uses]</b></p>
      <p><b>20.10.8.1 uses_allocator trait [allocator.uses.trait]</b></p>

      <cxx-function>
    
    <pre><code><cxx-signature>template &lt;class T, class Alloc&gt; struct uses_allocator;</cxx-signature></code></pre>

    <dl>
      
        
        <cxx-remarks para_num="1">
    
    <dt>Remarks:</dt><dd>
          Automatically detects whether <code>T</code> has a nested <code>allocator_type</code> that is convertible from <code>Alloc</code>.
          Meets the <cxx-17concept><i>Cpp17BinaryTypeTrait</i></cxx-17concept> requirements (<cxx-ref in="cxx" to="meta.rqmts">C++20 <span title="meta.rqmts">§20.15.1</span></cxx-ref>).
          The implementation shall provide a definition that is derived from <code>true_type</code> if a type <code>T::allocator_type</code> exists
          and <ins>either</ins> <code>is_convertible_v&lt;Alloc, T::allocator_type&gt; != false</code>
          <ins>or <code>T::allocator_type</code> is an alias for <code>std::experimental::erased_type</code> (<cxx-ref to="utility.erased.type"><a title="utility.erased.type" href="#utility.erased.type">3.1.2</a></cxx-ref>)</ins>,
          otherwise it shall be derived from <code>false_type</code>.
          A program may specialize this template to derive from <code>true_type</code> for a user-defined type <code>T</code> that does not have a nested <code>allocator_type</code> but nonetheless can be constructed with an allocator where either:
          <ul>
            <li>the first argument of a constructor has type <code>allocator_arg_t</code> and the second argument has type <code>Alloc</code> or</li>
            <li>the last argument of a constructor has type <code>Alloc</code>.</li>
          </ul>
        </dd>
  </cxx-remarks>
      
    </dl>
  </cxx-function>

      <p><b>20.10.8.2 uses-allocator construction [allocator.uses.construction]</b></p>

      <p para_num="1">
        <dfn>Uses-allocator construction</dfn> with allocator <code>Alloc</code> refers to the construction of an object <code>obj</code> of type <code>T</code>,
        using constructor arguments <code>v1, v2, ..., vN</code> of types <code>V1, V2, ..., VN</code>, respectively,
        and an allocator <code>alloc</code> of type <code>Alloc</code>,
        <ins>where <code>Alloc</code> either (1) meets the requirements of an allocator (<cxx-ref in="cxx" to="allocator.requirements">C++20 <span title="allocator.requirements">§16.5.3.5</span></cxx-ref>),
        or (2) is a pointer type convertible to <code>std::pmr::memory_resource*</code> (<cxx-ref in="cxx" to="mem.res">C++20 <span title="mem.res">§20.12</span></cxx-ref>),</ins>
        according to the following rules:
      </p>
    </blockquote>
  
    </section>
  </cxx-section>

    </section>
  </cxx-clause>

<cxx-clause id="utilities">
    

    <section>
      <header><span class="section-number">3</span> <h1 data-bookmark-label="3 General utilities library">General utilities library</h1> <span style="float:right"><a href="#utilities">[utilities]</a></span></header>
      
  

  <cxx-section id="utility">
    

    <section>
      <header><span class="section-number">3.1</span> <h1 data-bookmark-label="3.1 Utility components">Utility components</h1> <span style="float:right"><a href="#utility">[utility]</a></span></header>
      
    

    <cxx-section id="utility.syn">
    

    <section>
      <header><span class="section-number">3.1.1</span> <h1 data-bookmark-label="3.1.1 Header <experimental/utility> synopsis">Header <code>&lt;experimental/utility&gt;</code> synopsis</h1> <span style="float:right"><a href="#utility.syn">[utility.syn]</a></span></header>
      
      

<pre><code>#include &lt;utility&gt;

namespace std::experimental::inline fundamentals_v3 {

  <cxx-ref insynopsis="" to="utility.erased.type">// <i><a title="utility.erased.type" href="#utility.erased.type">3.1.2</a>, Class erased_type</i></cxx-ref>
  struct erased_type { };

} // namespace std::experimental::inline fundamentals_v3</code></pre>

    
    </section>
  </cxx-section>

    <cxx-section id="utility.erased.type">
    

    <section>
      <header><span class="section-number">3.1.2</span> <h1 data-bookmark-label="3.1.2 Class erased_type">Class <code>erased_type</code></h1> <span style="float:right"><a href="#utility.erased.type">[utility.erased.type]</a></span></header>
      
      

      <cxx-function id="utility.erased.type.1" para_num="1">
    
    <pre><code><cxx-signature>struct erased_type { };</cxx-signature></code></pre>

    <dl>
      
        

        <p id="utility.erased.type.2" para_num="2">
          The <code>erased_type</code> <code>struct</code> is an empty <code>struct</code> that serves as a placeholder for a type <code>T</code> in situations where the actual type <code>T</code> is determined at runtime.
          For example, the nested type, <code>allocator_type</code>, is an alias for <code>erased_type</code> in classes that use <i>type-erased allocators</i> (see <cxx-ref to="memory.type.erased.allocator"><a title="memory.type.erased.allocator" href="#memory.type.erased.allocator">5.3</a></cxx-ref>).
        </p>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

  
    </section>
  </cxx-section>

  <cxx-section id="propagate_const">
    

    <section>
      <header><span class="section-number">3.2</span> <h1 data-bookmark-label="3.2 Constness propagation">Constness propagation</h1> <span style="float:right"><a href="#propagate_const">[propagate_const]</a></span></header>
      
    

    <cxx-section id="propagate_const.syn">
    

    <section>
      <header><span class="section-number">3.2.1</span> <h1 data-bookmark-label="3.2.1 Header <experimental/propagate_const> synopsis">Header <code>&lt;experimental/propagate_const&gt;</code> synopsis</h1> <span style="float:right"><a href="#propagate_const.syn">[propagate_const.syn]</a></span></header>
      
      

      <pre><code>namespace std {
  namespace experimental::inline fundamentals_v3 {

    <cxx-ref insynopsis="" to="propagate_const.overview">// <i><a title="propagate_const.overview" href="#propagate_const.overview">3.2.2.1</a>, Class template propagate_const overview</i></cxx-ref>
    template &lt;class T&gt; class propagate_const;

    <cxx-ref insynopsis="" to="propagate_const.relational">// <i><a title="propagate_const.relational" href="#propagate_const.relational">3.2.2.9</a>, propagate_const relational operators</i></cxx-ref>
    template &lt;class T&gt;
      constexpr bool operator==(const propagate_const&lt;T&gt;&amp; pt, nullptr_t);
    template &lt;class T&gt;
      constexpr bool operator==(nullptr_t, const propagate_const&lt;T&gt;&amp; pu);

    template &lt;class T&gt;
      constexpr bool operator!=(const propagate_const&lt;T&gt;&amp; pt, nullptr_t);
    template &lt;class T&gt;
      constexpr bool operator!=(nullptr_t, const propagate_const&lt;T&gt;&amp; pu);

    template &lt;class T, class U&gt;
      constexpr bool operator==(const propagate_const&lt;T&gt;&amp; pt, const propagate_const&lt;U&gt;&amp; pu);
    template &lt;class T, class U&gt;
      constexpr bool operator!=(const propagate_const&lt;T&gt;&amp; pt, const propagate_const&lt;U&gt;&amp; pu);
    template &lt;class T, class U&gt;
      constexpr bool operator&lt;(const propagate_const&lt;T&gt;&amp; pt, const propagate_const&lt;U&gt;&amp; pu);
    template &lt;class T, class U&gt;
      constexpr bool operator&gt;(const propagate_const&lt;T&gt;&amp; pt, const propagate_const&lt;U&gt;&amp; pu);
    template &lt;class T, class U&gt;
      constexpr bool operator&lt;=(const propagate_const&lt;T&gt;&amp; pt, const propagate_const&lt;U&gt;&amp; pu);
    template &lt;class T, class U&gt;
      constexpr bool operator&gt;=(const propagate_const&lt;T&gt;&amp; pt, const propagate_const&lt;U&gt;&amp; pu);

    template &lt;class T, class U&gt;
      constexpr bool operator==(const propagate_const&lt;T&gt;&amp; pt, const U&amp; u);
    template &lt;class T, class U&gt;
      constexpr bool operator!=(const propagate_const&lt;T&gt;&amp; pt, const U&amp; u);
    template &lt;class T, class U&gt;
      constexpr bool operator&lt;(const propagate_const&lt;T&gt;&amp; pt, const U&amp; u);
    template &lt;class T, class U&gt;
      constexpr bool operator&gt;(const propagate_const&lt;T&gt;&amp; pt, const U&amp; u);
    template &lt;class T, class U&gt;
      constexpr bool operator&lt;=(const propagate_const&lt;T&gt;&amp; pt, const U&amp; u);
    template &lt;class T, class U&gt;
      constexpr bool operator&gt;=(const propagate_const&lt;T&gt;&amp; pt, const U&amp; u);

    template &lt;class T, class U&gt;
      constexpr bool operator==(const T&amp; t, const propagate_const&lt;U&gt;&amp; pu);
    template &lt;class T, class U&gt;
      constexpr bool operator!=(const T&amp; t, const propagate_const&lt;U&gt;&amp; pu);
    template &lt;class T, class U&gt;
      constexpr bool operator&lt;(const T&amp; t, const propagate_const&lt;U&gt;&amp; pu);
    template &lt;class T, class U&gt;
      constexpr bool operator&gt;(const T&amp; t, const propagate_const&lt;U&gt;&amp; pu);
    template &lt;class T, class U&gt;
      constexpr bool operator&lt;=(const T&amp; t, const propagate_const&lt;U&gt;&amp; pu);
    template &lt;class T, class U&gt;
      constexpr bool operator&gt;=(const T&amp; t, const propagate_const&lt;U&gt;&amp; pu);

    <cxx-ref insynopsis="" to="propagate_const.algorithms">// <i><a title="propagate_const.algorithms" href="#propagate_const.algorithms">3.2.2.10</a>, propagate_const specialized algorithms</i></cxx-ref>
    template &lt;class T&gt;
      constexpr void swap(propagate_const&lt;T&gt;&amp; pt, propagate_const&lt;T&gt;&amp; pt2) noexcept(<i>see below</i>);

    <cxx-ref insynopsis="" to="propagate_const.underlying">// <i><a title="propagate_const.underlying" href="#propagate_const.underlying">3.2.2.11</a>, propagate_const underlying pointer access</i></cxx-ref>
    template &lt;class T&gt;
      constexpr const T&amp; get_underlying(const propagate_const&lt;T&gt;&amp; pt) noexcept;
    template &lt;class T&gt;
      constexpr T&amp; get_underlying(propagate_const&lt;T&gt;&amp; pt) noexcept;

  } // namespace experimental::inline fundamentals_v3

  <cxx-ref insynopsis="" to="propagate_const.hash">// <i><a title="propagate_const.hash" href="#propagate_const.hash">3.2.2.12</a>, propagate_const hash support</i></cxx-ref>
  template &lt;class T&gt; struct hash;
  template &lt;class T&gt;
    struct hash&lt;experimental::fundamentals_v3::propagate_const&lt;T&gt;&gt;;

  <cxx-ref insynopsis="" to="propagate_const.comparison_function_objects">// <i><a title="propagate_const.comparison_function_objects" href="#propagate_const.comparison_function_objects">3.2.2.13</a>, propagate_const comparison function objects</i></cxx-ref>
  template &lt;class T&gt; struct equal_to;
  template &lt;class T&gt;
    struct equal_to&lt;experimental::fundamentals_v3::propagate_const&lt;T&gt;&gt;;
  template &lt;class T&gt; struct not_equal_to;
  template &lt;class T&gt;
    struct not_equal_to&lt;experimental::fundamentals_v3::propagate_const&lt;T&gt;&gt;;
  template &lt;class T&gt; struct less;
  template &lt;class T&gt;
    struct less&lt;experimental::fundamentals_v3::propagate_const&lt;T&gt;&gt;;
  template &lt;class T&gt; struct greater;
  template &lt;class T&gt;
    struct greater&lt;experimental::fundamentals_v3::propagate_const&lt;T&gt;&gt;;
  template &lt;class T&gt; struct less_equal;
  template &lt;class T&gt;
    struct less_equal&lt;experimental::fundamentals_v3::propagate_const&lt;T&gt;&gt;;
  template &lt;class T&gt; struct greater_equal;
  template &lt;class T&gt;
    struct greater_equal&lt;experimental::fundamentals_v3::propagate_const&lt;T&gt;&gt;;

} // namespace std</code></pre>
    
    </section>
  </cxx-section>

    <cxx-section id="propagate_const">
    

    <section>
      <header><span class="section-number">3.2.2</span> <h1 data-bookmark-label="3.2.2 Class template propagate_const">Class template <code>propagate_const</code></h1> <span style="float:right"><a href="#propagate_const">[propagate_const]</a></span></header>
      
      

      <cxx-section id="propagate_const.overview">
    

    <section>
      <header><span class="section-number">3.2.2.1</span> <h1 data-bookmark-label="3.2.2.1 Class template propagate_const overview">Class template <code>propagate_const</code> overview</h1> <span style="float:right"><a href="#propagate_const.overview">[propagate_const.overview]</a></span></header>
      
        

        <pre><code>namespace std::experimental::inline fundamentals_v3 {

  template &lt;class T&gt; class propagate_const {
  public:
    using element_type = remove_reference_t&lt;decltype(*declval&lt;T&amp;&gt;())&gt;;

    <cxx-ref insynopsis="" to="propagate_const.ctor">// <i><a title="propagate_const.ctor" href="#propagate_const.ctor">3.2.2.4</a>, propagate_const constructors</i></cxx-ref>
    constexpr propagate_const() = default;
    propagate_const(const propagate_const&amp; p) = delete;
    constexpr propagate_const(propagate_const&amp;&amp; p) = default;
    template &lt;class U&gt;
      explicit(!is_convertible_v&lt;U, T&gt;) constexpr propagate_const(propagate_const&lt;U&gt;&amp;&amp; pu);
    template &lt;class U&gt;
      explicit(!is_convertible_v&lt;U, T&gt;) constexpr propagate_const(U&amp;&amp; u);

    <cxx-ref insynopsis="" to="propagate_const.assignment">// <i><a title="propagate_const.assignment" href="#propagate_const.assignment">3.2.2.5</a>, propagate_const assignment</i></cxx-ref>
    propagate_const&amp; operator=(const propagate_const&amp; p) = delete;
    constexpr propagate_const&amp; operator=(propagate_const&amp;&amp; p) = default;
    template &lt;class U&gt;
      constexpr propagate_const&amp; operator=(propagate_const&lt;U&gt;&amp;&amp; pu);
    template &lt;class U&gt;
      constexpr propagate_const&amp; operator=(U&amp;&amp; u);

    <cxx-ref insynopsis="" to="propagate_const.const_observers">// <i><a title="propagate_const.const_observers" href="#propagate_const.const_observers">3.2.2.6</a>, propagate_const const observers</i></cxx-ref>
    explicit constexpr operator bool() const;
    constexpr const element_type* operator-&gt;() const;
    constexpr operator const element_type*() const; // <i>Not always defined</i>
    constexpr const element_type&amp; operator*() const;
    constexpr const element_type* get() const;

    <cxx-ref insynopsis="" to="propagate_const.non_const_observers">// <i><a title="propagate_const.non_const_observers" href="#propagate_const.non_const_observers">3.2.2.7</a>, propagate_const non-const observers</i></cxx-ref>
    constexpr element_type* operator-&gt;();
    constexpr operator element_type*(); // <i>Not always defined</i>
    constexpr element_type&amp; operator*();
    constexpr element_type* get();

    <cxx-ref insynopsis="" to="propagate_const.modifiers">// <i><a title="propagate_const.modifiers" href="#propagate_const.modifiers">3.2.2.8</a>, propagate_const modifiers</i></cxx-ref>
    constexpr void swap(propagate_const&amp; pt) noexcept(is_nothrow_swappable&lt;T&gt;);

  private:
    T t_; //<i>exposition only</i>
  };

} // namespace std::experimental::inline fundamentals_v3</code></pre>

        <p id="propagate_const.overview.1" para_num="1">
          <code>propagate_const</code> is a wrapper around a pointer-like object type <code>T</code>
          which treats the wrapped pointer as a pointer to <code>const</code> when
          the wrapper is accessed through a <code>const</code> access path.
        </p>
      
    </section>
  </cxx-section>

      <cxx-section id="propagate_const.requirements">
    

    <section>
      <header><span class="section-number">3.2.2.2</span> <h1 data-bookmark-label="3.2.2.2 propagate_const general requirements on T"><code>propagate_const</code> general requirements on <code>T</code></h1> <span style="float:right"><a href="#propagate_const.requirements">[propagate_const.requirements]</a></span></header>
      
        

        <p id="propagate_const.requirements.1" para_num="1">
          <code>T</code> shall be an object pointer type or a class type for which
          <code>decltype(*declval&lt;T&amp;&gt;())</code> is an lvalue reference; otherwise
          the program is ill-formed.
        </p>
        <p id="propagate_const.requirements.2" para_num="2">
          If <code>T</code> is an array type, reference type, pointer to function type or
          pointer to (possibly cv-qualified) <code>void</code>, then the program is
          ill-formed.
        </p>
        <p id="propagate_const.requirements.3" para_num="3">
          <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    <code>propagate_const&lt;const int*&gt;</code> is well-formed
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
        </p>

      
    </section>
  </cxx-section>

      <cxx-section id="propagate_const.class_type_requirements">
    

    <section>
      <header><span class="section-number">3.2.2.3</span> <h1 data-bookmark-label="3.2.2.3 propagate_const requirements on class type T"><code>propagate_const</code> requirements on class type <code>T</code></h1> <span style="float:right"><a href="#propagate_const.class_type_requirements">[propagate_const.class_type_requirements]</a></span></header>
      
        

        <p id="propagate_const.class_type_requirements.1" para_num="1">
          If <code>T</code> is class
          type then it shall satisfy the following requirements. In this subclause
          <code>t</code> denotes a non-<code>const</code> lvalue of type <code>T</code>, <code>ct</code>
          is a <code>const T&amp;</code> bound to <code>t</code>,  <code>element_type</code> denotes
          an object type.
        </p>

        <p id="propagate_const.class_type_requirements.2" para_num="2">
          <code>T</code> and <code>const T</code> shall be contextually convertible to <code>bool</code>.
        </p>
        <p id="propagate_const.class_type_requirements.3" para_num="3">If <code>T</code> is implicitly convertible to <code>element_type*</code>,
          <code>(element_type*)t == t.get()</code> shall be <code>true</code>.
        </p>
        <p id="propagate_const.class_type_requirements.4" para_num="4">
          If <code>const T</code> is implicitly convertible to <code>const element_type*</code>,
          <code>(const element_type*)ct == ct.get()</code> shall be <code>true</code>.
        </p>

        <table is="cxx-table">
    

    <caption>Table 3 — <wbr><span>Requirements on class types <code>T</code></span></caption>
    
          
          <tbody><tr>
            <th>Expression</th>
            <th>Return type</th>
            <th>Pre-conditions</th>
            <th>Operational semantics</th>
          </tr>
          <tr>
            <td><code>t.get()</code></td>
            <td><code>element_type*</code></td>
            <td></td>
            <td></td>
          </tr>
          <tr>
            <td><code>ct.get()</code></td>
            <td><code>const element_type*</code> or <code>element_type*</code></td>
            <td><code></code></td>
            <td><code>t.get() == ct.get()</code>.</td>
          </tr>
          <tr>
            <td><code>*t</code></td>
            <td><code>element_type&amp;</code></td>
            <td><code>t.get() != nullptr</code></td>
            <td><code>*t</code> refers to the same object as <code>*(t.get())</code></td>
          </tr>
          <tr>
            <td><code>*ct</code></td>
            <td><code>const element_type&amp;</code> or <code>element_type&amp;</code></td>
            <td><code>ct.get() != nullptr</code></td>
            <td><code>*ct</code> refers to the same object as <code>*(ct.get())</code></td>
          </tr>
          <tr>
            <td><code>t.operator-&gt;()</code></td>
            <td><code>element_type*</code></td>
            <td><code>t.get() != nullptr</code></td>
            <td><code>t.operator-&gt;() == t.get()</code></td></tr>
          <tr>
            <td><code>ct.operator-&gt;()</code></td>
            <td><code>const element_type*</code> or <code>element_type*</code></td>
            <td><code>ct.get() != nullptr</code></td>
            <td><code>ct.operator-&gt;() == ct.get()</code></td></tr>
          <tr>
            <td><code>(bool)t</code></td>
            <td><code>bool</code></td>
            <td><code></code></td>
            <td><code>(bool)t</code> is equivalent to <code>t.get() != nullptr</code></td>
          </tr>
          <tr>
            <td><code>(bool)ct</code></td>
            <td><code>bool</code></td>
            <td><code></code></td>
            <td><code>(bool)ct</code> is equivalent to <code>ct.get() != nullptr</code></td>
          </tr>
        </tbody>
  </table>
      
    </section>
  </cxx-section>

      <cxx-section id="propagate_const.ctor">
    

    <section>
      <header><span class="section-number">3.2.2.4</span> <h1 data-bookmark-label="3.2.2.4 propagate_const constructors"><code>propagate_const</code> constructors</h1> <span style="float:right"><a href="#propagate_const.ctor">[propagate_const.ctor]</a></span></header>
      
        

        <cxx-function id="propagate_const.ctor.1" para_num="1">
    
    <pre><code><cxx-signature>template &lt;class U&gt;
explicit(!is_convertible_v&lt;U, T&gt;) constexpr propagate_const(propagate_const&lt;U&gt;&amp;&amp; pu);</cxx-signature></code></pre>

    <dl>
      
          

          <cxx-constraints id="propagate_const.ctor.2" para_num="2">
    
    <dt>Constraints:</dt><dd>
            <code>is_constructible_v&lt;T, U&gt;</code> is true.
          </dd>
  </cxx-constraints>
          <cxx-effects id="propagate_const.ctor.3" para_num="3">
    
    <dt>Effects:</dt><dd>
            Initializes <code>t_</code> as if
            direct-non-list-initializing an object of type <code>T</code> with the
            expression <code>std::move(pu.t_)</code>.
          </dd>
  </cxx-effects>
        
    </dl>
  </cxx-function>

        <cxx-function id="propagate_const.ctor.4" para_num="4">
    
    <pre><code><cxx-signature>template &lt;class U&gt;
explicit(!is_convertible_v&lt;U, T&gt;) constexpr propagate_const(U&amp;&amp; u);</cxx-signature></code></pre>

    <dl>
      
          

          <cxx-constraints id="propagate_const.ctor.5" para_num="5">
    
    <dt>Constraints:</dt><dd>
            <code>is_constructible_v&lt;T, U&gt;</code> is true
            and <code>decay_t&lt;U&gt;</code> is not a specialization of <code>propagate_const</code>.
          </dd>
  </cxx-constraints>
          <cxx-effects id="propagate_const.ctor.6" para_num="6">
    
    <dt>Effects:</dt><dd>
            Initializes <code>t_</code> as if
            direct-non-list-initializing an object of type <code>T</code> with
            the expression <code>std::forward&lt;U&gt;(u)</code>.
          </dd>
  </cxx-effects>
        
    </dl>
  </cxx-function>
      
    </section>
  </cxx-section>

      <cxx-section id="propagate_const.assignment">
    

    <section>
      <header><span class="section-number">3.2.2.5</span> <h1 data-bookmark-label="3.2.2.5 propagate_const assignment"><code>propagate_const</code> assignment</h1> <span style="float:right"><a href="#propagate_const.assignment">[propagate_const.assignment]</a></span></header>
      
        

        <cxx-function id="propagate_const.assignment.1" para_num="1">
    
    <pre><code><cxx-signature>template &lt;class U&gt;
constexpr propagate_const&amp; operator=(propagate_const&lt;U&gt;&amp;&amp; pu);</cxx-signature></code></pre>

    <dl>
      
          

          <cxx-constraints id="propagate_const.assignment.2" para_num="2">
    
    <dt>Constraints:</dt><dd>
            <code>U</code> is implicitly convertible to <code>T</code>.
          </dd>
  </cxx-constraints>
          <cxx-effects id="propagate_const.assignment.3" para_num="3">
    
    <dt>Effects:</dt><dd><code>t_ = std::move(pu.t_)</code>.</dd>
  </cxx-effects>
          <cxx-returns id="propagate_const.assignment.4" para_num="4">
    
    <dt>Returns:</dt><dd><code>*this</code>.</dd>
  </cxx-returns>
        
    </dl>
  </cxx-function>

        <cxx-function id="propagate_const.assignment.5" para_num="5">
    
    <pre><code><cxx-signature>template &lt;class U&gt;
constexpr propagate_const&amp; operator=(U&amp;&amp; u);</cxx-signature></code></pre>

    <dl>
      
          

          <cxx-constraints id="propagate_const.assignment.6" para_num="6">
    
    <dt>Constraints:</dt><dd>
            <code>U</code> is implicitly convertible to <code>T</code> and
            <code>decay_t&lt;U&gt;</code> is not a specialization of <code>propagate_const</code>.
          </dd>
  </cxx-constraints>
          <cxx-effects id="propagate_const.assignment.7" para_num="7">
    
    <dt>Effects:</dt><dd><code>t_ = std::forward&lt;U&gt;(u)</code>.</dd>
  </cxx-effects>
          <cxx-returns id="propagate_const.assignment.8" para_num="8">
    
    <dt>Returns:</dt><dd><code>*this</code>.</dd>
  </cxx-returns>
        
    </dl>
  </cxx-function>
      
    </section>
  </cxx-section>

      <cxx-section id="propagate_const.const_observers">
    

    <section>
      <header><span class="section-number">3.2.2.6</span> <h1 data-bookmark-label="3.2.2.6 propagate_const const observers"><code>propagate_const</code> const observers</h1> <span style="float:right"><a href="#propagate_const.const_observers">[propagate_const.const_observers]</a></span></header>
      
        

        <cxx-function id="propagate_const.const_observers.1" para_num="1">
    
    <pre><code><cxx-signature>explicit constexpr operator bool() const;</cxx-signature></code></pre>

    <dl>
      
          

          <cxx-returns id="propagate_const.const_observers.2" para_num="2">
    
    <dt>Returns:</dt><dd><code>(bool)t_</code>.</dd>
  </cxx-returns>
        
    </dl>
  </cxx-function>

        <cxx-function id="propagate_const.const_observers.3" para_num="3">
    
    <pre><code><cxx-signature>constexpr const element_type* operator-&gt;() const;</cxx-signature></code></pre>

    <dl>
      
          

          <cxx-preconditions id="propagate_const.const_observers.4" para_num="4">
    
    <dt>Preconditions:</dt><dd><code>get() != nullptr</code>.</dd>
  </cxx-preconditions>
          <cxx-returns id="propagate_const.const_observers.5" para_num="5">
    
    <dt>Returns:</dt><dd><code>get()</code>.</dd>
  </cxx-returns>
        
    </dl>
  </cxx-function>

        <cxx-function id="propagate_const.const_observers.6" para_num="6">
    
    <pre><code><cxx-signature>constexpr operator const element_type*() const;</cxx-signature></code></pre>

    <dl>
      
          

          <cxx-constraints id="propagate_const.const_observers.7" para_num="7">
    
    <dt>Constraints:</dt><dd>
            <code>T</code> is an object pointer type or
            has an implicit conversion to <code>const element_type*</code>.
          </dd>
  </cxx-constraints>
          <cxx-returns id="propagate_const.const_observers.8" para_num="8">
    
    <dt>Returns:</dt><dd><code>get()</code>.</dd>
  </cxx-returns>
        
    </dl>
  </cxx-function>

        <cxx-function id="propagate_const.const_observers.9" para_num="9">
    
    <pre><code><cxx-signature>constexpr const element_type&amp; operator*() const;</cxx-signature></code></pre>

    <dl>
      
          

          <cxx-preconditions id="propagate_const.const_observers.10" para_num="10">
    
    <dt>Preconditions:</dt><dd><code>get() != nullptr</code>.</dd>
  </cxx-preconditions>
          <cxx-returns id="propagate_const.const_observers.11" para_num="11">
    
    <dt>Returns:</dt><dd><code>*get()</code>.</dd>
  </cxx-returns>
        
    </dl>
  </cxx-function>

        <cxx-function id="propagate_const.const_observers.12" para_num="12">
    
    <pre><code><cxx-signature>constexpr const element_type* get() const;</cxx-signature></code></pre>

    <dl>
      
          

          <cxx-returns id="propagate_const.const_observers.13" para_num="13">
    
    <dt>Returns:</dt><dd>
            <code>t_</code> if <code>T</code> is an object pointer type,
            otherwise <code>t_.get()</code>.
          </dd>
  </cxx-returns>
        
    </dl>
  </cxx-function>
      
    </section>
  </cxx-section>

    <cxx-section id="propagate_const.non_const_observers">
    

    <section>
      <header><span class="section-number">3.2.2.7</span> <h1 data-bookmark-label="3.2.2.7 propagate_const non-const observers"><code>propagate_const</code> non-const observers</h1> <span style="float:right"><a href="#propagate_const.non_const_observers">[propagate_const.non_const_observers]</a></span></header>
      
      

      <cxx-function id="propagate_const.non_const_observers.1" para_num="1">
    
    <pre><code><cxx-signature>constexpr element_type* operator-&gt;();</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-preconditions id="propagate_const.non_const_observers.2" para_num="2">
    
    <dt>Preconditions:</dt><dd><code>get() != nullptr</code>.</dd>
  </cxx-preconditions>
        <cxx-returns id="propagate_const.non_const_observers.3" para_num="3">
    
    <dt>Returns:</dt><dd><code>get()</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="propagate_const.non_const_observers.4" para_num="4">
    
    <pre><code><cxx-signature>constexpr operator element_type*();</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-constraints id="propagate_const.non_const_observers.5" para_num="5">
    
    <dt>Constraints:</dt><dd>
          <code>T</code> is an object pointer type or
          has an implicit conversion to <code>element_type*</code>.
        </dd>
  </cxx-constraints>
        <cxx-returns id="propagate_const.non_const_observers.6" para_num="6">
    
    <dt>Returns:</dt><dd><code>get()</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="propagate_const.non_const_observers.7" para_num="7">
    
    <pre><code><cxx-signature>constexpr element_type&amp; operator*();</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-preconditions id="propagate_const.non_const_observers.8" para_num="8">
    
    <dt>Preconditions:</dt><dd><code>get() != nullptr</code>.</dd>
  </cxx-preconditions>
        <cxx-returns id="propagate_const.non_const_observers.9" para_num="9">
    
    <dt>Returns:</dt><dd><code>*get()</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="propagate_const.non_const_observers.10" para_num="10">
    
    <pre><code><cxx-signature>constexpr element_type* get();</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="propagate_const.non_const_observers.11" para_num="11">
    
    <dt>Returns:</dt><dd>
          <code>t_</code> if <code>T</code> is an object pointer type,
          otherwise <code>t_.get()</code>.
        </dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

    <cxx-section id="propagate_const.modifiers">
    

    <section>
      <header><span class="section-number">3.2.2.8</span> <h1 data-bookmark-label="3.2.2.8 propagate_const modifiers"><code>propagate_const</code> modifiers</h1> <span style="float:right"><a href="#propagate_const.modifiers">[propagate_const.modifiers]</a></span></header>
      
      

      <cxx-function id="propagate_const.modifiers.1" para_num="1">
    
    <pre><code><cxx-signature>constexpr void swap(propagate_const&amp; pt) noexcept(is_nothrow_swappable&lt;T&gt;);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-preconditions id="propagate_const.modifiers.2" para_num="2">
    
    <dt>Preconditions:</dt><dd>
          Lvalues of type <code>T</code> are swappable
          (<cxx-ref in="cxx" to="swappable.requirements">C++20 <span title="swappable.requirements">§16.5.3.2</span></cxx-ref>).
        </dd>
  </cxx-preconditions>
        <cxx-effects id="propagate_const.modifiers.3" para_num="3">
    
    <dt>Effects:</dt><dd><code>swap(t_, pt.t_)</code>.</dd>
  </cxx-effects>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

    <cxx-section id="propagate_const.relational">
    

    <section>
      <header><span class="section-number">3.2.2.9</span> <h1 data-bookmark-label="3.2.2.9 propagate_const relational operators"><code>propagate_const</code> relational operators</h1> <span style="float:right"><a href="#propagate_const.relational">[propagate_const.relational]</a></span></header>
      
      

      <cxx-function id="propagate_const.relational.1" para_num="1">
    
    <pre><code><cxx-signature>template &lt;class T&gt;
constexpr bool operator==(const propagate_const&lt;T&gt;&amp; pt, nullptr_t);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="propagate_const.relational.2" para_num="2">
    
    <dt>Returns:</dt><dd><code>pt.t_ == nullptr</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="propagate_const.relational.3" para_num="3">
    
    <pre><code><cxx-signature>template &lt;class T&gt;
constexpr bool operator==(nullptr_t, const propagate_const&lt;T&gt;&amp; pt);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="propagate_const.relational.4" para_num="4">
    
    <dt>Returns:</dt><dd><code>nullptr == pt.t_</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="propagate_const.relational.5" para_num="5">
    
    <pre><code><cxx-signature>template &lt;class T&gt;
constexpr bool operator!=(const propagate_const&lt;T&gt;&amp; pt, nullptr_t);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="propagate_const.relational.6" para_num="6">
    
    <dt>Returns:</dt><dd><code>pt.t_ != nullptr</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="propagate_const.relational.7" para_num="7">
    
    <pre><code><cxx-signature>template &lt;class T&gt;
constexpr bool operator!=(nullptr_t, const propagate_const&lt;T&gt;&amp; pt);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="propagate_const.relational.8" para_num="8">
    
    <dt>Returns:</dt><dd><code>nullptr != pt.t_</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="propagate_const.relational.9" para_num="9">
    
    <pre><code><cxx-signature>template &lt;class T, class U&gt;
constexpr bool operator==(const propagate_const&lt;T&gt;&amp; pt, const propagate_const&lt;U&gt;&amp; pu);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="propagate_const.relational.10" para_num="10">
    
    <dt>Returns:</dt><dd><code>pt.t_ == pu.t_</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="propagate_const.relational.11" para_num="11">
    
    <pre><code><cxx-signature>template &lt;class T, class U&gt;
constexpr bool operator!=(const propagate_const&lt;T&gt;&amp; pt, const propagate_const&lt;U&gt;&amp; pu);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="propagate_const.relational.12" para_num="12">
    
    <dt>Returns:</dt><dd><code>pt.t_ != pu.t_</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="propagate_const.relational.13" para_num="13">
    
    <pre><code><cxx-signature>template &lt;class T, class U&gt;
constexpr bool operator&lt;(const propagate_const&lt;T&gt;&amp; pt, const propagate_const&lt;U&gt;&amp; pu);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="propagate_const.relational.14" para_num="14">
    
    <dt>Returns:</dt><dd><code>pt.t_ &lt; pu.t_</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="propagate_const.relational.15" para_num="15">
    
    <pre><code><cxx-signature>template &lt;class T, class U&gt;
constexpr bool operator&gt;(const propagate_const&lt;T&gt;&amp; pt, const propagate_const&lt;U&gt;&amp; pu);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="propagate_const.relational.16" para_num="16">
    
    <dt>Returns:</dt><dd><code>pt.t_ &gt; pu.t_</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="propagate_const.relational.17" para_num="17">
    
    <pre><code><cxx-signature>template &lt;class T, class U&gt;
constexpr bool operator&lt;=(const propagate_const&lt;T&gt;&amp; pt, const propagate_const&lt;U&gt;&amp; pu);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="propagate_const.relational.18" para_num="18">
    
    <dt>Returns:</dt><dd><code>pt.t_ &lt;= pu.t_</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="propagate_const.relational.19" para_num="19">
    
    <pre><code><cxx-signature>template &lt;class T, class U&gt;
constexpr bool operator&gt;=(const propagate_const&lt;T&gt;&amp; pt, const propagate_const&lt;U&gt;&amp; pu);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="propagate_const.relational.20" para_num="20">
    
    <dt>Returns:</dt><dd><code>pt.t_ &gt;= pu.t_</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="propagate_const.relational.21" para_num="21">
    
    <pre><code><cxx-signature>template &lt;class T, class U&gt;
constexpr bool operator==(const propagate_const&lt;T&gt;&amp; pt, const U&amp; u);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="propagate_const.relational.22" para_num="22">
    
    <dt>Returns:</dt><dd><code>pt.t_ == u</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="propagate_const.relational.23" para_num="23">
    
    <pre><code><cxx-signature>template &lt;class T, class U&gt;
constexpr bool operator!=(const propagate_const&lt;T&gt;&amp; pt, const U&amp; u);</cxx-signature></code></pre>

    <dl>
      
        
        <cxx-returns id="propagate_const.relational.24" para_num="24">
    
    <dt>Returns:</dt><dd><code>pt.t_ != u</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="propagate_const.relational.25" para_num="25">
    
    <pre><code><cxx-signature>template &lt;class T, class U&gt;
constexpr bool operator&lt;(const propagate_const&lt;T&gt;&amp; pt, const U&amp; u);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="propagate_const.relational.26" para_num="26">
    
    <dt>Returns:</dt><dd><code>pt.t_ &lt; u</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="propagate_const.relational.27" para_num="27">
    
    <pre><code><cxx-signature>template &lt;class T, class U&gt;
constexpr bool operator&gt;(const propagate_const&lt;T&gt;&amp; pt, const U&amp; u);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="propagate_const.relational.28" para_num="28">
    
    <dt>Returns:</dt><dd><code>pt.t_ &gt; u</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="propagate_const.relational.29" para_num="29">
    
    <pre><code><cxx-signature>template &lt;class T, class U&gt;
constexpr bool operator&lt;=(const propagate_const&lt;T&gt;&amp; pt, const U&amp; u);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="propagate_const.relational.30" para_num="30">
    
    <dt>Returns:</dt><dd><code>pt.t_ &lt;= u</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="propagate_const.relational.31" para_num="31">
    
    <pre><code><cxx-signature>template &lt;class T, class U&gt;
constexpr bool operator&gt;=(const propagate_const&lt;T&gt;&amp; pt, const U&amp; u);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="propagate_const.relational.32" para_num="32">
    
    <dt>Returns:</dt><dd><code>pt.t_ &gt;= u</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="propagate_const.relational.33" para_num="33">
    
    <pre><code><cxx-signature>template &lt;class T, class U&gt;
constexpr bool operator==(const T&amp; t, const propagate_const&lt;U&gt;&amp; pu);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="propagate_const.relational.34" para_num="34">
    
    <dt>Returns:</dt><dd><code>t == pu.t_</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="propagate_const.relational.35" para_num="35">
    
    <pre><code><cxx-signature>template &lt;class T, class U&gt;
constexpr bool operator!=(const T&amp; t, const propagate_const&lt;U&gt;&amp; pu);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="propagate_const.relational.36" para_num="36">
    
    <dt>Returns:</dt><dd><code>t != pu.t_</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="propagate_const.relational.37" para_num="37">
    
    <pre><code><cxx-signature>template &lt;class T, class U&gt;
constexpr bool operator&lt;(const T&amp; t, const propagate_const&lt;U&gt;&amp; pu);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="propagate_const.relational.38" para_num="38">
    
    <dt>Returns:</dt><dd><code>t &lt; pu.t_</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="propagate_const.relational.39" para_num="39">
    
    <pre><code><cxx-signature>template &lt;class T, class U&gt;
constexpr bool operator&gt;(const T&amp; t, const propagate_const&lt;U&gt;&amp; pu);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="propagate_const.relational.40" para_num="40">
    
    <dt>Returns:</dt><dd><code>t &gt; pu.t_</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="propagate_const.relational.41" para_num="41">
    
    <pre><code><cxx-signature>template &lt;class T, class U&gt;
constexpr bool operator&lt;=(const T&amp; t, const propagate_const&lt;U&gt;&amp; pu);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="propagate_const.relational.42" para_num="42">
    
    <dt>Returns:</dt><dd><code>t &lt;= pu.t_</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="propagate_const.relational.43" para_num="43">
    
    <pre><code><cxx-signature>template &lt;class T, class U&gt;
constexpr bool operator&gt;=(const T&amp; t, const propagate_const&lt;U&gt;&amp; pu);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="propagate_const.relational.44" para_num="44">
    
    <dt>Returns:</dt><dd><code>t &gt;= pu.t_</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>
    <cxx-section id="propagate_const.algorithms">
    

    <section>
      <header><span class="section-number">3.2.2.10</span> <h1 data-bookmark-label="3.2.2.10 propagate_const specialized algorithms"><code>propagate_const</code> specialized algorithms</h1> <span style="float:right"><a href="#propagate_const.algorithms">[propagate_const.algorithms]</a></span></header>
      
      

      <cxx-function id="propagate_const.algorithms.1" para_num="1">
    
    <pre><code><cxx-signature>template &lt;class T&gt;
constexpr void swap(propagate_const&lt;T&gt;&amp; pt1, propagate_const&lt;T&gt;&amp; pt2) noexcept(<i>see below</i>);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-constraints id="propagate_const.algorithms.2" para_num="2">
    
    <dt>Constraints:</dt><dd><code>is_swappable_v&lt;T&gt;</code> is <code>true</code>.</dd>
  </cxx-constraints>
        <cxx-effects id="propagate_const.algorithms.3" para_num="3">
    
    <dt>Effects:</dt><dd>Equivalent to: <code>pt1.swap(pt2)</code>.</dd>
  </cxx-effects>
        <cxx-remarks id="propagate_const.algorithms.4" para_num="4">
    
    <dt>Remarks:</dt><dd>The expression inside <code>noexcept</code> is equivalent to:
          <pre><code>noexcept(pt1.swap(pt2))</code></pre>
        </dd>
  </cxx-remarks>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

    <cxx-section id="propagate_const.underlying">
    

    <section>
      <header><span class="section-number">3.2.2.11</span> <h1 data-bookmark-label="3.2.2.11 propagate_const underlying pointer access"><code>propagate_const</code> underlying pointer access</h1> <span style="float:right"><a href="#propagate_const.underlying">[propagate_const.underlying]</a></span></header>
      
      

      <p id="propagate_const.underlying.1" para_num="1">
        Access to the underlying object pointer type is
        through free functions rather than member functions.
        These functions are intended to resemble cast operations to encourage caution when using them.
      </p>

      <cxx-function id="propagate_const.underlying.2" para_num="2">
    
    <pre><code><cxx-signature>template &lt;class T&gt;
constexpr const T&amp; get_underlying(const propagate_const&lt;T&gt;&amp; pt) noexcept;</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="propagate_const.underlying.3" para_num="3">
    
    <dt>Returns:</dt><dd>
          a reference to the underlying object pointer type.
        </dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="propagate_const.underlying.4" para_num="4">
    
    <pre><code><cxx-signature>template &lt;class T&gt;
constexpr T&amp; get_underlying(propagate_const&lt;T&gt;&amp; pt) noexcept;</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="propagate_const.underlying.5" para_num="5">
    
    <dt>Returns:</dt><dd>
          a reference to the underlying object pointer type.
        </dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

    <cxx-section id="propagate_const.hash">
    

    <section>
      <header><span class="section-number">3.2.2.12</span> <h1 data-bookmark-label="3.2.2.12 propagate_const hash support"><code>propagate_const</code> hash support</h1> <span style="float:right"><a href="#propagate_const.hash">[propagate_const.hash]</a></span></header>
      
      

      <cxx-function id="propagate_const.hash.1" para_num="1">
    
    <pre><code><cxx-signature>template &lt;class T&gt;
struct hash&lt;experimental::fundamentals_v3::propagate_const&lt;T&gt;&gt;;</cxx-signature></code></pre>

    <dl>
      
        

        <p id="propagate_const.hash.2" para_num="2">
          The specialization <code>hash&lt;experimental::fundamentals_v3::propagate_const&lt;T&gt;&gt;</code>
          is enabled (<cxx-ref in="cxx" to="unord.hash">C++20 <span title="unord.hash">§20.14.18</span></cxx-ref>) if and only if <code>hash&lt;T&gt;</code> is enabled.
          When enabled, for an object <code>p</code> of type <code>propagate_const&lt;T&gt;</code>,
          <code>hash&lt;experimental::fundamentals_v3::propagate_const&lt;T&gt;&gt;()(p)</code>
          evaluates to the same value as <code>hash&lt;T&gt;()(p.t_)</code>.
        </p>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

    <cxx-section id="propagate_const.comparison_function_objects">
    

    <section>
      <header><span class="section-number">3.2.2.13</span> <h1 data-bookmark-label="3.2.2.13 propagate_const comparison function objects"><code>propagate_const</code> comparison function objects</h1> <span style="float:right"><a href="#propagate_const.comparison_function_objects">[propagate_const.comparison_function_objects]</a></span></header>
      
      

      <cxx-function id="propagate_const.comparison_function_objects.1" para_num="1">
    
    <pre><code><cxx-signature>template &lt;class T&gt;
struct equal_to&lt;experimental::fundamentals_v3::propagate_const&lt;T&gt;&gt;;</cxx-signature></code></pre>

    <dl>
      
        

        <p id="propagate_const.comparison_function_objects.2" para_num="2">
          For objects <code>p, q</code> of type <code>propagate_const&lt;T&gt;</code>,
          <code>equal_to&lt;experimental::fundamentals_v3::propagate_const&lt;T&gt;&gt;()(p,
q)</code>
          shall evaluate to the same value as <code>equal_to&lt;T&gt;()(p.t_,
q.t_)</code>.
        </p>

        <cxx-mandates id="propagate_const.comparison_function_objects.3" para_num="3">
    
    <dt>Mandates:</dt><dd>
          The specialization <code>equal_to&lt;T&gt;</code> is well-formed
        </dd>
  </cxx-mandates>
        <cxx-preconditions id="propagate_const.comparison_function_objects.4" para_num="4">
    
    <dt>Preconditions:</dt><dd>
          The specialization <code>equal_to&lt;T&gt;</code> is well-defined.
        </dd>
  </cxx-preconditions>
      
    </dl>
  </cxx-function>

      <cxx-function id="propagate_const.comparison_function_objects.5" para_num="5">
    
    <pre><code><cxx-signature>template &lt;class T&gt;
struct not_equal_to&lt;experimental::fundamentals_v3::propagate_const&lt;T&gt;&gt;;</cxx-signature></code></pre>

    <dl>
      
        

        <p id="propagate_const.comparison_function_objects.6" para_num="6">
          For objects <code>p, q</code> of type <code>propagate_const&lt;T&gt;</code>,
          <code>not_equal_to&lt;experimental::fundamentals_v3::propagate_const&lt;T&gt;&gt;()(p, q)</code>
          shall evaluate to the same value as <code>not_equal_to&lt;T&gt;()(p.t_, q.t_)</code>.
        </p>

        <cxx-mandates id="propagate_const.comparison_function_objects.7" para_num="7">
    
    <dt>Mandates:</dt><dd>
          The specialization <code>not_equal_to&lt;T&gt;</code> is well-formed
        </dd>
  </cxx-mandates>
        <cxx-preconditions id="propagate_const.comparison_function_objects.8" para_num="8">
    
    <dt>Preconditions:</dt><dd>
          The specialization <code>not_equal_to&lt;T&gt;</code> is well-defined.
        </dd>
  </cxx-preconditions>
      
    </dl>
  </cxx-function>

      <cxx-function id="propagate_const.comparison_function_objects.9" para_num="9">
    
    <pre><code><cxx-signature>template &lt;class T&gt;
struct less&lt;experimental::fundamentals_v3::propagate_const&lt;T&gt;&gt;;</cxx-signature></code></pre>

    <dl>
      
        

        <p id="propagate_const.comparison_function_objects.10" para_num="10">
          For objects <code>p, q</code> of type <code>propagate_const&lt;T&gt;</code>,
          <code>less&lt;experimental::fundamentals_v3::propagate_const&lt;T&gt;&gt;()(p, q)</code>
          shall evaluate to the same value as <code>less&lt;T&gt;()(p.t_, q.t_)</code>.
        </p>

        <cxx-mandates id="propagate_const.comparison_function_objects.11" para_num="11">
    
    <dt>Mandates:</dt><dd>
          The specialization <code>less&lt;T&gt;</code> is well-formed
        </dd>
  </cxx-mandates>
        <cxx-preconditions id="propagate_const.comparison_function_objects.12" para_num="12">
    
    <dt>Preconditions:</dt><dd>
          The specialization <code>less&lt;T&gt;</code> is well-defined.
        </dd>
  </cxx-preconditions>
      
    </dl>
  </cxx-function>

      <cxx-function id="propagate_const.comparison_function_objects.13" para_num="13">
    
    <pre><code><cxx-signature>template &lt;class T&gt;
struct greater&lt;experimental::fundamentals_v3::propagate_const&lt;T&gt;&gt;;</cxx-signature></code></pre>

    <dl>
      
        

        <p id="propagate_const.comparison_function_objects.14" para_num="14">
          For objects <code>p, q</code> of type <code>propagate_const&lt;T&gt;</code>,
          <code>greater&lt;experimental::fundamentals_v3::propagate_const&lt;T&gt;&gt;()(p, q)</code>
          shall evaluate to the same value as <code>greater&lt;T&gt;()(p.t_, q.t_)</code>.
        </p>

        <cxx-mandates id="propagate_const.comparison_function_objects.15" para_num="15">
    
    <dt>Mandates:</dt><dd>
          The specialization <code>greater&lt;T&gt;</code> is well-formed
        </dd>
  </cxx-mandates>
        <cxx-preconditions id="propagate_const.comparison_function_objects.16" para_num="16">
    
    <dt>Preconditions:</dt><dd>
          The specialization <code>greater&lt;T&gt;</code> is well-defined.
        </dd>
  </cxx-preconditions>
      
    </dl>
  </cxx-function>

      <cxx-function id="propagate_const.comparison_function_objects.17" para_num="17">
    
    <pre><code><cxx-signature>template &lt;class T&gt;
struct less_equal&lt;experimental::fundamentals_v3::propagate_const&lt;T&gt;&gt;;</cxx-signature></code></pre>

    <dl>
      
        

        <p id="propagate_const.comparison_function_objects.18" para_num="18">
          For objects <code>p, q</code> of type <code>propagate_const&lt;T&gt;</code>,
          <code>less_equal&lt;experimental::fundamentals_v3::propagate_const&lt;T&gt;&gt;()(p, q)</code>
          shall evaluate to the same value as <code>less_equal&lt;T&gt;()(p.t_, q.t_)</code>.
        </p>

        <cxx-mandates id="propagate_const.comparison_function_objects.19" para_num="19">
    
    <dt>Mandates:</dt><dd>
          The specialization <code>less_equal&lt;T&gt;</code> is well-formed
        </dd>
  </cxx-mandates>
        <cxx-preconditions id="propagate_const.comparison_function_objects.20" para_num="20">
    
    <dt>Preconditions:</dt><dd>
          The specialization <code>less_equal&lt;T&gt;</code> is well-defined.
        </dd>
  </cxx-preconditions>
      
    </dl>
  </cxx-function>

      <cxx-function id="propagate_const.comparison_function_objects.21" para_num="21">
    
    <pre><code><cxx-signature>template &lt;class T&gt;
struct greater_equal&lt;experimental::fundamentals_v3::propagate_const&lt;T&gt;&gt;;</cxx-signature></code></pre>

    <dl>
      
        

        <p id="propagate_const.comparison_function_objects.22" para_num="22">
          For objects <code>p, q</code> of type <code>propagate_const&lt;T&gt;</code>,
          <code>greater_equal&lt;experimental::fundamentals_v3::propagate_const&lt;T&gt;&gt;()(p, q)</code>
          shall evaluate to the same value as <code>greater_equal&lt;T&gt;()(p.t_, q.t_)</code>.
        </p>

        <cxx-mandates id="propagate_const.comparison_function_objects.23" para_num="23">
    
    <dt>Mandates:</dt><dd>
          The specialization <code>greater_equal&lt;T&gt;</code> is well-formed
        </dd>
  </cxx-mandates>
        <cxx-preconditions id="propagate_const.comparison_function_objects.24" para_num="24">
    
    <dt>Preconditions:</dt><dd>
          The specialization <code>greater_equal&lt;T&gt;</code> is well-defined.
        </dd>
  </cxx-preconditions>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>
  
    </section>
  </cxx-section>
  
    </section>
  </cxx-section>

  <cxx-section id="scopeguard">
    

    <section>
      <header><span class="section-number">3.3</span> <h1 data-bookmark-label="3.3 Scope guard support">Scope guard support</h1> <span style="float:right"><a href="#scopeguard">[scopeguard]</a></span></header>
      
    

    <cxx-section id="scope.syn">
    

    <section>
      <header><span class="section-number">3.3.1</span> <h1 data-bookmark-label="3.3.1 Header <experimental/scope> synopsis">Header <code>&lt;experimental/scope&gt;</code> synopsis</h1> <span style="float:right"><a href="#scope.syn">[scope.syn]</a></span></header>
      
      

      <pre><code>namespace std::experimental::inline fundamentals_v3 {

  <cxx-ref insynopsis="" to="scopeguard.exit">// <i><a title="scopeguard.exit" href="#scopeguard.exit">3.3.2</a>, Class templates scope_exit, scope_fail, and scope_success</i></cxx-ref>
  template &lt;class EF&gt;
    class scope_exit;
  template &lt;class EF&gt;
    class scope_fail;
  template &lt;class EF&gt;
    class scope_success;

  <cxx-ref insynopsis="" to="scopeguard.uniqueres">// <i><a title="scopeguard.uniqueres" href="#scopeguard.uniqueres">3.3.3</a>, Class template unique_resource</i></cxx-ref>
  template &lt;class R, class D&gt;
    class unique_resource;

  <cxx-ref insynopsis="" to="scopeguard.uniqueres.create">// <i><a title="scopeguard.uniqueres.create" href="#scopeguard.uniqueres.create">3.3.3.6</a>, unique_resource creation</i></cxx-ref>
  template &lt;class R, class D, class S=decay_t&lt;R&gt;&gt;
    unique_resource&lt;decay_t&lt;R&gt;, decay_t&lt;D&gt;&gt;
      make_unique_resource_checked(R&amp;&amp; r, const S&amp; invalid, D&amp;&amp; d) noexcept(<i>see below</i>);

} // namespace std::experimental::inline fundamentals_v3</code></pre>

    
    </section>
  </cxx-section>

    <cxx-section id="scopeguard.exit">
    

    <section>
      <header><span class="section-number">3.3.2</span> <h1 data-bookmark-label="3.3.2 Class templates scope_exit, scope_fail, and scope_success">Class templates <code>scope_exit</code>, <code>scope_fail</code>, and <code>scope_success</code></h1> <span style="float:right"><a href="#scopeguard.exit">[scopeguard.exit]</a></span></header>
      
      

      <p id="scopeguard.exit.1" para_num="1">The class templates <code>scope_exit</code>, <code>scope_fail</code>,
        and <code>scope_success</code> define scope guards that wrap a
        function object to be called on their destruction.</p>

      <p id="scopeguard.exit.2" para_num="2">In this subclause, the placeholder <code><i>scope-guard</i></code>
        denotes each of these class templates. In descriptions of the
        class members, <code><i>scope-guard</i></code> refers to the enclosing
        class.</p>

      <pre><code>namespace std::experimental::inline fundamentals_v3 {

  template &lt;class EF&gt; class <i>scope-guard</i> {
  public:
    template &lt;class EFP&gt;
      explicit <i>scope-guard</i>(EFP&amp;&amp; f) noexcept(<i>see below</i>);
    <i>scope-guard</i>(<i>scope-guard</i>&amp;&amp; rhs) noexcept(<i>see below</i>);

    <i>scope-guard</i>(const <i>scope-guard</i>&amp;) = delete;
    <i>scope-guard</i>&amp; operator=(const <i>scope-guard</i>&amp;) = delete;
    <i>scope-guard</i>&amp; operator=(<i>scope-guard</i>&amp;&amp;) = delete;

    ~<i>scope-guard</i> () noexcept(<i>see below</i>);

    void release() noexcept;

  private:
    EF exit_function;                                 // <i>exposition only</i>
    bool execute_on_destruction{true};                // <i>exposition only</i>
    int uncaught_on_creation{uncaught_exceptions()};  // <i>exposition only</i>
  };

  template &lt;class EF&gt;
    <i>scope-guard</i>(EF) -&gt; <i>scope-guard</i>&lt;EF&gt;;

}  // namespace std::experimental::inline fundamentals_v3</code></pre>

      <p id="scopeguard.exit.3" para_num="3">The class template <code>scope_exit</code> is a general-purpose
        scope guard that calls its exit function when a scope is exited. The
        class templates <code>scope_fail</code> and <code>scope_success</code>
        share the <code>scope_exit</code> interface, only the situation when the
        exit function is called differs.</p>
      <cxx-example>
    
    <span class="nowrap">[ <em>Example:</em></span>
    <pre><code>void grow(vector&lt;int&gt;&amp; v) {
  scope_success guard([]{ cout &lt;&lt; "Good!" &lt;&lt; endl; });
  v.resize(1024);
}</code></pre>
    <span class="nowrap">— <em>end example</em> ]</span>
  </cxx-example>

      <p id="scopeguard.exit.4" para_num="4"><cxx-note><span class="nowrap">[ <em>Note:</em></span>
    If the exit function object of a <code>scope_success</code>
          or <code>scope_exit</code> object refers to a local variable
          of the function where it is defined, e.g., as a lambda capturing
          the variable by reference, and that variable is used as a return
          operand in that function, that variable might have already been
          returned when the <code><i>scope-guard</i></code>’s destructor
          executes, calling the exit function. This can lead to surprising
          behavior.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note></p>

      <p id="scopeguard.exit.5" para_num="5">Template argument <code>EF</code> shall be a function object type
        (<cxx-ref in="cxx" to="function.objects">C++20 <span title="function.objects">§20.14</span></cxx-ref>), lvalue reference
        to function, or lvalue reference to function object type. If <code>EF</code>
        is an object type, it shall meet the <cxx-17concept><i>Cpp17Destructible</i></cxx-17concept>
        requirements (C++20 Table 30). Given an lvalue <code>g</code> of type
        <code>remove_reference_t&lt;EF&gt;</code>, the expression
        <code>g()</code> shall be well-formed.</p>

      <p id="scopeguard.exit.6" para_num="6">The constructor parameter <code>f</code> in the following constructors
        shall be a reference to a function or a reference to a function
        object (<cxx-ref in="cxx" to="function.objects">C++20 <span title="function.objects">§20.14</span></cxx-ref>).</p>

      <cxx-function id="scopeguard.exit.7" para_num="7">
    
    <pre><code><cxx-signature>template &lt;class EFP&gt;
explicit <i>scope-guard</i>(EFP&amp;&amp; f) noexcept(
    is_nothrow_constructible_v&lt;EF, EFP&gt; ||
    is_nothrow_constructible_v&lt;EF, EFP&amp;&gt;);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-constraints id="scopeguard.exit.8" para_num="8">
    
    <dt>Constraints:</dt><dd>
          <code>is_same_v&lt;remove_cvref_t&lt;EFP&gt;,
          <i>scope-guard</i>&gt;</code> is <code>false</code> and
          <code>is_constructible_v&lt;EF, EFP&gt;</code> is <code>true</code>.
        </dd>
  </cxx-constraints>

        <cxx-mandates id="scopeguard.exit.9" para_num="9">
    
    <dt>Mandates:</dt><dd>
          The expression <code>f()</code> is well-formed.
        </dd>
  </cxx-mandates>

        <cxx-preconditions id="scopeguard.exit.10" para_num="10">
    
    <dt>Preconditions:</dt><dd>
          Calling <code>f()</code> has well-defined behavior.
          For <code>scope_exit</code> and <code>scope_fail</code>,
          calling <code>f()</code> does not throw an exception.
        </dd>
  </cxx-preconditions>

        <cxx-effects id="scopeguard.exit.11" para_num="11">
    
    <dt>Effects:</dt><dd>
          If <code>EFP</code> is not an lvalue reference type and
          <code>is_nothrow_constructible_v&lt;EF, EFP&gt;</code>
          is <code>true</code>, initialize <code>exit_function</code>
          with <code>std::forward&lt;EFP&gt;(f)</code>;
          otherwise initialize <code>exit_function</code> with <code>f</code>.
          For <code>scope_exit</code> and <code>scope_fail</code>,
          if the initialization of <code>exit_function</code> throws an exception,
          calls <code>f()</code>.
          <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    For <code>scope_success</code>, <code>f()</code> will not be
          called if the initialization fails.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
        </dd>
  </cxx-effects>

        <cxx-throws id="scopeguard.exit.12" para_num="12">
    
    <dt>Throws:</dt><dd>
          Any exception thrown during the initialization of <code>exit_function</code>.
        </dd>
  </cxx-throws>
      
    </dl>
  </cxx-function>

      <cxx-function id="scopeguard.exit.13" para_num="13">
    
    <pre><code><cxx-signature><i>scope-guard</i>(<i>scope-guard</i>&amp;&amp; rhs) noexcept(<i>see below</i>)</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-constraints id="scopeguard.exit.14" para_num="14">
    
    <dt>Constraints:</dt><dd>
          <code>(is_nothrow_move_constructible_v&lt;EF&gt; || is_copy_constructible_v&lt;EF&gt;)</code>
          is <code>true</code>.
        </dd>
  </cxx-constraints>

        <cxx-preconditions id="scopeguard.exit.15" para_num="15">
    
    <dt>Preconditions:</dt><dd>
          If <code>EF</code> is an object type:
          <ul>
            <li>if <code>is_nothrow_move_constructible_v&lt;EF&gt;</code> is <code>true</code>,
              <code>EF</code> meets the <cxx-17concept><i>Cpp17MoveConstructible</i></cxx-17concept> requirements (C++20 Table 26),</li>
            <li>otherwise <code>EF</code> meets the <cxx-17concept><i>Cpp17CopyConstructible</i></cxx-17concept> requirements (C++20 Table 27).</li>
          </ul>
        </dd>
  </cxx-preconditions>

        <cxx-effects id="scopeguard.exit.16" para_num="16">
    
    <dt>Effects:</dt><dd>
          If <code>is_nothrow_move_constructible_v&lt;EF&gt;</code> is <code>true</code>,
          initializes <code>exit_function</code> with <code>std::forward&lt;EF&gt;(rhs.exit_function)</code>,
          otherwise initializes <code>exit_function</code> with <code>rhs.exit_function</code>.
          Initializes <code>execute_on_destruction</code> from <code>rhs.execute_on_destruction</code> and
          <code>uncaught_on_creation</code> from <code>rhs.uncaught_on_creation</code>.
          If construction succeeds, call <code>rhs.release()</code>.
          <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    Copying instead of moving provides the strong exception guarantee.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
        </dd>
  </cxx-effects>

        <cxx-postconditions id="scopeguard.exit.17" para_num="17">
    
    <dt>Postconditions:</dt><dd>
          <code>execute_on_destruction</code> yields the value <code>rhs.execute_on_destruction</code>
          yielded before the construction. <code>uncaught_on_creation</code> yields the value
          <code>rhs.uncaught_on_creation</code> yielded before the construction.
        </dd>
  </cxx-postconditions>

        <cxx-throws id="scopeguard.exit.18" para_num="18">
    
    <dt>Throws:</dt><dd>
          Any exception thrown during the initialization of <code>exit_function</code>.
        </dd>
  </cxx-throws>

        <cxx-remarks id="scopeguard.exit.19" para_num="19">
    
    <dt>Remarks:</dt><dd>
          The expression inside <code>noexcept</code> is equivalent to:
          <pre><code>is_nothrow_move_constructible_v&lt;EF&gt; || is_nothrow_copy_constructible_v&lt;EF&gt;</code></pre>
        </dd>
  </cxx-remarks>
      
    </dl>
  </cxx-function>

      <cxx-function id="scopeguard.exit.20" para_num="20">
    
    <pre><code><cxx-signature>~scope_exit() noexcept(true);</cxx-signature></code></pre>

    <dl>
      
        
        <cxx-effects id="scopeguard.exit.21" para_num="21">
    
    <dt>Effects:</dt><dd>
          Equivalent to:
          <pre><code>if (execute_on_destruction)
  exit_function();</code></pre>
        </dd>
  </cxx-effects>
      
    </dl>
  </cxx-function>

      <cxx-function id="scopeguard.exit.22" para_num="22">
    
    <pre><code><cxx-signature>~scope_fail() noexcept(true);</cxx-signature></code></pre>

    <dl>
      
        
        <cxx-effects id="scopeguard.exit.23" para_num="23">
    
    <dt>Effects:</dt><dd>
          Equivalent to:
          <pre><code>if (execute_on_destruction &amp;&amp; uncaught_exceptions() &gt; uncaught_on_creation)
  exit_function();</code></pre>
        </dd>
  </cxx-effects>
      
    </dl>
  </cxx-function>

      <cxx-function id="scopeguard.exit.24" para_num="24">
    
    <pre><code><cxx-signature>~scope_success() noexcept(noexcept(exit_function()));</cxx-signature></code></pre>

    <dl>
      
        
        <cxx-effects id="scopeguard.exit.25" para_num="25">
    
    <dt>Effects:</dt><dd>
          Equivalent to:
          <pre><code>if (execute_on_destruction &amp;&amp; uncaught_exceptions() &lt;= uncaught_on_creation)
  exit_function();</code></pre>
          <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    
            If <code>noexcept(exit_function())</code> is <code>false</code>,
            <code>exit_function()</code> may throw an exception,
            notwithstanding the restrictions of <cxx-ref in="cxx" to="res.on.exception.handling">C++20 <span title="res.on.exception.handling">§16.5.5.13</span></cxx-ref>.
          
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
        </dd>
  </cxx-effects>
        <cxx-throws id="scopeguard.exit.26" para_num="26">
    
    <dt>Throws:</dt><dd>
          Any exception thrown by <code>exit_function()</code>.
        </dd>
  </cxx-throws>
      
    </dl>
  </cxx-function>

      <cxx-function id="scopeguard.exit.27" para_num="27">
    
    <pre><code><cxx-signature>void release() noexcept;</cxx-signature></code></pre>

    <dl>
      
        
        <cxx-effects id="scopeguard.exit.28" para_num="28">
    
    <dt>Effects:</dt><dd>
          Equivalent to <code>execute_on_destruction = false</code>.
        </dd>
  </cxx-effects>
      
    </dl>
  </cxx-function>

    
    </section>
  </cxx-section>

    <cxx-section id="scopeguard.uniqueres">
    

    <section>
      <header><span class="section-number">3.3.3</span> <h1 data-bookmark-label="3.3.3 Class template unique_resource">Class template <code>unique_resource</code></h1> <span style="float:right"><a href="#scopeguard.uniqueres">[scopeguard.uniqueres]</a></span></header>
      

      

      <cxx-section id="scopeguard.uniqueres.overview">
    

    <section>
      <header><span class="section-number">3.3.3.1</span> <h1 data-bookmark-label="3.3.3.1 Overview">Overview</h1> <span style="float:right"><a href="#scopeguard.uniqueres.overview">[scopeguard.uniqueres.overview]</a></span></header>
      
        

        <pre><code>namespace std::experimental::inline fundamentals_v3 {

  template &lt;class R, class D&gt; class unique_resource {
  public:
    <cxx-ref insynopsis="" to="scopeguard.uniqueres.ctor">// <i><a title="scopeguard.uniqueres.ctor" href="#scopeguard.uniqueres.ctor">3.3.3.2</a>, Constructors</i></cxx-ref>
    unique_resource();
    template &lt;class RR, class DD&gt;
      unique_resource(RR&amp;&amp; r, DD&amp;&amp; d) noexcept(<i>see below</i>);
    unique_resource(unique_resource&amp;&amp; rhs) noexcept(<i>see below</i>);

    <cxx-ref insynopsis="" to="scopeguard.uniqueres.dtor">// <i><a title="scopeguard.uniqueres.dtor" href="#scopeguard.uniqueres.dtor">3.3.3.3</a>, Destructor</i></cxx-ref>
    ~unique_resource();

    <cxx-ref insynopsis="" to="scopeguard.uniqueres.assign">// <i><a title="scopeguard.uniqueres.assign" href="#scopeguard.uniqueres.assign">3.3.3.4</a>, Assignment</i></cxx-ref>
    unique_resource&amp; operator=(unique_resource&amp;&amp; rhs) noexcept(<i>see below</i>);

    <cxx-ref insynopsis="" to="scopeguard.uniqueres.members">// <i><a title="scopeguard.uniqueres.members" href="#scopeguard.uniqueres.members">3.3.3.5</a>, Other member functions</i></cxx-ref>
    void reset() noexcept;
    template &lt;class RR&gt;
      void reset(RR&amp;&amp; r);
    void release() noexcept;
    const R&amp; get() const noexcept;
    <i>see below</i> operator*() const noexcept;
    R operator-&gt;() const noexcept;
    const D&amp; get_deleter() const noexcept;

  private:
    using R1 = conditional_t&lt;is_reference_v&lt;R&gt;, reference_wrapper&lt;remove_reference_t&lt;R&gt;&gt;, R&gt;;  // <i>exposition only</i>
    R1 resource;                  // <i>exposition only</i>
    D deleter;                    // <i>exposition only</i>
    bool execute_on_reset{true};  // <i>exposition only</i>
  };

  template&lt;class R, class D&gt;
    unique_resource(R, D) -&gt; unique_resource&lt;R, D&gt;;

}  // namespace std::experimental::inline fundamentals_v3</code></pre>

        <p id="scopeguard.uniqueres.overview.1" para_num="1">
          <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    <code>unique_resource</code> is a universal RAII wrapper for resource handles.
            Typically, such resource handles are of trivial type and come with a factory function
            and a clean-up or deleter function that do not throw exceptions. The clean-up function
            together with the result of the creation function is used to create a <code>unique_resource</code>
            variable, that on destruction will call the clean-up function. Access to the underlying
            resource handle is achieved through <code>get()</code> and in case of a pointer type
            resource through a set of convenience pointer operator functions.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
        </p>

        <p id="scopeguard.uniqueres.overview.2" para_num="2">
          The template argument <code>D</code> shall meet the requirements of a
          <cxx-17concept><i>Cpp17Destructible</i></cxx-17concept> (C++20 Table 30) function object type
          (<cxx-ref in="cxx" to="function.objects">C++20 <span title="function.objects">§20.14</span></cxx-ref>), for which,
          given a lvalue <code>d</code> of type <code>D</code> and a lvalue <code>r</code> of
          type <code>R</code>, the expression <code>d(r)</code> shall be well-formed.
          <code>D</code> shall either meet the <cxx-17concept><i>Cpp17CopyConstructible</i></cxx-17concept> requirements
          (C++20 Table 27), or <code>D</code> shall meet the <cxx-17concept><i>Cpp17MoveConstructible</i></cxx-17concept> requirements
          (C++20 Table 26) and <code>is_nothrow_move_constructible_v&lt;D&gt;</code> shall be <code>true</code>.
        </p>

        <p id="scopeguard.uniqueres.overview.3" para_num="3">
          For the purpose of this subclause, a resource type <code>T</code>
          is an object type that meets the requirements of <cxx-17concept><i>Cpp17CopyConstructible</i></cxx-17concept>
          (C++20 Table 27), or is an object type that meets the requirements of <cxx-17concept><i>Cpp17MoveConstructible</i></cxx-17concept>
          (C++20 Table 26) and <code>is_nothrow_move_constructible_v&lt;T&gt;</code> is <code>true</code>,
          or is an lvalue reference to a resource type. <code>R</code> shall be a resource type.
        </p>

        <p id="scopeguard.uniqueres.overview.4" para_num="4">
          For the scope of the adjacent subclauses,
          let <code><i>RESOURCE</i></code> be defined as follows:
          </p><ul>
            <li><code>resource.get()</code> if <code>is_reference_v&lt;R&gt;</code> is <code>true</code>,</li>
            <li><code>resource</code> otherwise.</li>
          </ul>
        <p id="scopeguard.uniqueres.overview.5" para_num="5"></p>
      
    </section>
  </cxx-section>

      <cxx-section id="scopeguard.uniqueres.ctor">
    

    <section>
      <header><span class="section-number">3.3.3.2</span> <h1 data-bookmark-label="3.3.3.2 Constructors">Constructors</h1> <span style="float:right"><a href="#scopeguard.uniqueres.ctor">[scopeguard.uniqueres.ctor]</a></span></header>
      
        

        <cxx-function id="scopeguard.uniqueres.ctor.1" para_num="1">
    
    <pre><code><cxx-signature>unique_resource()</cxx-signature></code></pre>

    <dl>
      
          
          <cxx-constraints id="scopeguard.uniqueres.ctor.2" para_num="2">
    
    <dt>Constraints:</dt><dd>
            <code>is_default_constructible_v&lt;R&gt; &amp;&amp;
            is_default_constructible_v&lt;D&gt;</code> is <code>true</code>.
          </dd>
  </cxx-constraints>
          <cxx-effects id="scopeguard.uniqueres.ctor.3" para_num="3">
    
    <dt>Effects:</dt><dd>
            Value-initializes <code>resource</code> and <code>deleter</code>;
            <code>execute_on_reset</code> is initialized with <code>false</code>.
          </dd>
  </cxx-effects>
        
    </dl>
  </cxx-function>

        <cxx-function id="scopeguard.uniqueres.ctor.4" para_num="4">
    
    <pre><code><cxx-signature>template &lt;class RR, class DD&gt;
unique_resource(RR&amp;&amp; r, DD&amp;&amp; d) noexcept(<i>see below</i>)</cxx-signature></code></pre>

    <dl>
      
          

          <cxx-constraints id="scopeguard.uniqueres.ctor.5" para_num="5">
    
    <dt>Constraints:</dt><dd>
            <pre><code>is_constructible_v&lt;R1, RR&gt; &amp;&amp;
is_constructible_v&lt;D , DD&gt; &amp;&amp;
(is_nothrow_constructible_v&lt;R1, RR&gt; || is_constructible_v&lt;R1,RR&amp;&gt;) &amp;&amp;
(is_nothrow_constructible_v&lt;D , DD&gt; || is_constructible_v&lt;D ,DD&amp;&gt;)</code></pre>
            is <code>true</code>.
            <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    
              The first two conditions prohibit initialization from an rvalue reference when either <code>R1</code>
              or <code>D</code> is a specialization of <code>reference_wrapper</code>.
            
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
          </dd>
  </cxx-constraints>

          <cxx-mandates id="scopeguard.uniqueres.ctor.6" para_num="6">
    
    <dt>Mandates:</dt><dd>
            The expressions <code>d(r)</code>, <code>d(<i>RESOURCE</i>)</code>
            and <code>deleter(<i>RESOURCE</i>)</code> are well-formed.
          </dd>
  </cxx-mandates>

          <cxx-preconditions id="scopeguard.uniqueres.ctor.7" para_num="7">
    
    <dt>Preconditions:</dt><dd>
            Calling <code>d(r)</code>, <code>d(<i>RESOURCE</i>)</code>
            or <code>deleter(<i>RESOURCE</i>)</code> has well-defined behavior and
            does not throw an exception.
          </dd>
  </cxx-preconditions>

          <cxx-effects id="scopeguard.uniqueres.ctor.8" para_num="8">
    
    <dt>Effects:</dt><dd>
            If <code>is_nothrow_constructible_v&lt;R1, RR&gt;</code> is <code>true</code>,
            initializes <code>resource</code> with <code>std::forward&lt;RR&gt;(r)</code>,
            otherwise initializes <code>resource</code> with <code>r</code>.
            Then, if <code>is_nothrow_constructible_v&lt;D, DD&gt;</code> is true,
            initializes <code>deleter</code> with <code>std::forward&lt;DD&gt;(d)</code>,
            otherwise initializes <code>deleter</code> with <code>d</code>.
            If initialization of <code>resource</code> throws an exception,
            calls <code>d(r)</code>.
            If initialization of <code>deleter</code> throws an exception, calls <code>d(<i>RESOURCE</i>)</code>.
            <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    
              The explained mechanism ensures no leaking of resources.
            
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
          </dd>
  </cxx-effects>

          <cxx-throws id="scopeguard.uniqueres.ctor.9" para_num="9">
    
    <dt>Throws:</dt><dd>
            Any exception thrown during initialization of <code>resource</code> or <code>deleter</code>.
          </dd>
  </cxx-throws>

          <cxx-remarks id="scopeguard.uniqueres.ctor.10" para_num="10">
    
    <dt>Remarks:</dt><dd>
            The expression inside <code>noexcept</code> is equivalent to:
            <pre><code>(is_nothrow_constructible_v&lt;R1, RR&gt; || is_nothrow_constructible_v&lt;R1, RR&amp;&gt;) &amp;&amp;
(is_nothrow_constructible_v&lt;D , DD&gt; || is_nothrow_constructible_v&lt;D , DD&amp;&gt;)</code></pre>
          </dd>
  </cxx-remarks>
        
    </dl>
  </cxx-function>

        <cxx-function id="scopeguard.uniqueres.ctor.11" para_num="11">
    
    <pre><code><cxx-signature>unique_resource(unique_resource&amp;&amp; rhs) noexcept(<i>see below</i>);</cxx-signature></code></pre>

    <dl>
      
          

          <cxx-effects id="scopeguard.uniqueres.ctor.12" para_num="12">
    
    <dt>Effects:</dt><dd>
            First, initialize <code>resource</code> as follows:
            <ul>
              <li>If <code>is_nothrow_move_constructible_v&lt;R1&gt;</code> is
                <code>true</code>, from <code>std::move(rhs.resource)</code>;</li>
              <li>otherwise, from <code>rhs.resource</code>.</li>
            </ul>
            <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    
              If initialization of <code>resource</code> throws an exception,
              <code>rhs</code> is left owning the resource and will free it in due time.
            
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
            Then, initialize <code>deleter</code> as follows:
            <ul>
              <li>If <code>is_nothrow_move_constructible_v&lt;D&gt;</code> is
                <code>true</code>, from <code>std::move(rhs.deleter)</code>;</li>
              <li>otherwise, from <code>rhs.deleter</code>.</li>
            </ul>
            If initialization of <code>deleter</code> throws an exception and
            <code>is_nothrow_move_constructible_v&lt;R1&gt;</code> is <code>true</code>
            and <code>rhs.execute_on_reset</code> is true:
            <pre><code>rhs.deleter(<i>RESOURCE</i>);
rhs.release();</code></pre>
            Finally, <code>execute_on_reset</code> is initialized with
            <code>exchange(rhs.execute_on_reset, false)</code>.
            <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    
              The explained mechanism ensures no leaking and no double release of resources.
            
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
          </dd>
  </cxx-effects>

          <cxx-remarks id="scopeguard.uniqueres.ctor.13" para_num="13">
    
    <dt>Remarks:</dt><dd>
            The expression inside <code>noexcept</code> is equivalent to:
            <pre><code>is_nothrow_move_constructible_v&lt;R1&gt; &amp;&amp; is_nothrow_move_constructible_v&lt;D&gt;</code></pre>
          </dd>
  </cxx-remarks>
        
    </dl>
  </cxx-function>
      
    </section>
  </cxx-section>

      <cxx-section id="scopeguard.uniqueres.dtor">
    

    <section>
      <header><span class="section-number">3.3.3.3</span> <h1 data-bookmark-label="3.3.3.3 Destructor">Destructor</h1> <span style="float:right"><a href="#scopeguard.uniqueres.dtor">[scopeguard.uniqueres.dtor]</a></span></header>
      
        

        <cxx-function id="scopeguard.uniqueres.dtor.1" para_num="1">
    
    <pre><code><cxx-signature>~unique_resource();</cxx-signature></code></pre>

    <dl>
      
          
          <cxx-effects id="scopeguard.uniqueres.dtor.2" para_num="2">
    
    <dt>Effects:</dt><dd>Equivalent to <code>reset()</code>.</dd>
  </cxx-effects>
        
    </dl>
  </cxx-function>
      
    </section>
  </cxx-section>

      <cxx-section id="scopeguard.uniqueres.assign">
    

    <section>
      <header><span class="section-number">3.3.3.4</span> <h1 data-bookmark-label="3.3.3.4 Assignment">Assignment</h1> <span style="float:right"><a href="#scopeguard.uniqueres.assign">[scopeguard.uniqueres.assign]</a></span></header>
      
        

        <cxx-function id="scopeguard.uniqueres.assign.1" para_num="1">
    
    <pre><code><cxx-signature>unique_resource&amp; operator=(unique_resource&amp;&amp; rhs) noexcept(<i>see below</i>);</cxx-signature></code></pre>

    <dl>
      
          

          <cxx-preconditions id="scopeguard.uniqueres.assign.2" para_num="2">
    
    <dt>Preconditions:</dt><dd>
            If <code>is_nothrow_move_assignable_v&lt;R1&gt;</code> is <code>true</code>,
            <code>R1</code> meets the <cxx-17concept><i>Cpp17MoveAssignable</i></cxx-17concept> (C++20 Table 28)
            requirements; otherwise <code>R1</code>
            meets the <cxx-17concept><i>Cpp17CopyAssignable</i></cxx-17concept> (C++20 Table 29) requirements.
            If <code>is_nothrow_move_assignable_v&lt;D&gt;</code> is <code>true</code>,
            <code>D</code> meets the <cxx-17concept><i>Cpp17MoveAssignable</i></cxx-17concept> (C++20 Table 28) requirements;
            otherwise <code>D</code> meets the <cxx-17concept><i>Cpp17CopyAssignable</i></cxx-17concept> (C++20 Table 29) requirements.
          </dd>
  </cxx-preconditions>

          <cxx-effects id="scopeguard.uniqueres.assign.3" para_num="3">
    
    <dt>Effects:</dt><dd>
            Equivalent to:
            <pre><code>reset();
if constexpr (is_nothrow_move_assignable_v&lt;R1&gt;) {
  if constexpr (is_nothrow_move_assignable_v&lt;D&gt;) {
    resource = std::move(rhs.resource);
    deleter = std::move(rhs.deleter);
  } else {
    deleter = rhs.deleter;
    resource = std::move(rhs.resource);
  }
} else {
  if constexpr (is_nothrow_move_assignable_v&lt;D&gt;) {
    resource = rhs.resource;
    deleter = std::move(rhs.deleter);
  } else {
    resource = rhs.resource;
    deleter = rhs.deleter;
  }
}
execute_on_reset = exchange(rhs.execute_on_reset, false);</code></pre>
            <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    
              If a copy of a member throws an exception, this mechanism leaves
              <code>rhs</code> intact and <code>*this</code> in the released state.
            
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
          </dd>
  </cxx-effects>

          <cxx-returns id="scopeguard.uniqueres.assign.4" para_num="4">
    
    <dt>Returns:</dt><dd><code>*this</code>.</dd>
  </cxx-returns>

          <cxx-throws id="scopeguard.uniqueres.assign.5" para_num="5">
    
    <dt>Throws:</dt><dd>
            Any exception thrown during a copy-assignment of a member that
            cannot be moved without an exception.
          </dd>
  </cxx-throws>

          <cxx-remarks id="scopeguard.uniqueres.assign.6" para_num="6">
    
    <dt>Remarks:</dt><dd>
            The expression inside <code>noexcept</code> is equivalent to:
            <pre><code>is_nothrow_move_assignable_v&lt;R1&gt; &amp;&amp; is_nothrow_move_assignable_v&lt;D&gt;</code></pre>
          </dd>
  </cxx-remarks>
        
    </dl>
  </cxx-function>
      
    </section>
  </cxx-section>

      <cxx-section id="scopeguard.uniqueres.members">
    

    <section>
      <header><span class="section-number">3.3.3.5</span> <h1 data-bookmark-label="3.3.3.5 Other member functions">Other member functions</h1> <span style="float:right"><a href="#scopeguard.uniqueres.members">[scopeguard.uniqueres.members]</a></span></header>
      
        

        <cxx-function id="scopeguard.uniqueres.members.1" para_num="1">
    
    <pre><code><cxx-signature>void reset() noexcept;</cxx-signature></code></pre>

    <dl>
      
          

          <cxx-effects id="scopeguard.uniqueres.members.2" para_num="2">
    
    <dt>Effects:</dt><dd>
            Equivalent to:
            <pre><code>if (execute_on_reset) {
  execute_on_reset = false;
  deleter(<i>RESOURCE</i>);
}</code></pre>
          </dd>
  </cxx-effects>
        
    </dl>
  </cxx-function>

        <cxx-function id="scopeguard.uniqueres.members.3" para_num="3">
    
    <pre><code><cxx-signature>template &lt;class RR&gt; void reset(RR&amp;&amp; r);</cxx-signature></code></pre>

    <dl>
      
          

          <cxx-constraints id="scopeguard.uniqueres.members.4" para_num="4">
    
    <dt>Constraints:</dt><dd>
            the selected assignment expression statement assigning <code>resource</code> is well-formed.
          </dd>
  </cxx-constraints>

          <cxx-mandates id="scopeguard.uniqueres.members.5" para_num="5">
    
    <dt>Mandates:</dt><dd>
            The expression <code>deleter(r)</code> is well-formed.
          </dd>
  </cxx-mandates>

          <cxx-preconditions id="scopeguard.uniqueres.members.6" para_num="6">
    
    <dt>Preconditions:</dt><dd>
            Calling <code>deleter(r)</code> has well-defined behavior
            and does not throw an exception.
          </dd>
  </cxx-preconditions>

          <cxx-effects id="scopeguard.uniqueres.members.7" para_num="7">
    
    <dt>Effects:</dt><dd>
            Equivalent to:
            <pre><code>reset();
if constexpr (is_nothrow_assignable_v&lt;R1&amp;, RR&gt;) {
  resource = std::forward&lt;RR&gt;(r);
} else {
  resource = as_const(r);
}
execute_on_reset = true;</code></pre>
            If copy-assignment of <code>resource</code> throws an exception,
            calls <code>deleter(r)</code>.
          </dd>
  </cxx-effects>
        
    </dl>
  </cxx-function>

        <cxx-function id="scopeguard.uniqueres.members.8" para_num="8">
    
    <pre><code><cxx-signature>void release() noexcept;</cxx-signature></code></pre>

    <dl>
      
          
          <cxx-effects id="scopeguard.uniqueres.members.9" para_num="9">
    
    <dt>Effects:</dt><dd>Equivalent to <code>execute_on_reset = false</code>.</dd>
  </cxx-effects>
        
    </dl>
  </cxx-function>

        <cxx-function id="scopeguard.uniqueres.members.10" para_num="10">
    
    <pre><code><cxx-signature>const R&amp; get() const noexcept;</cxx-signature></code></pre>

    <dl>
      
          
          <cxx-returns id="scopeguard.uniqueres.members.11" para_num="11">
    
    <dt>Returns:</dt><dd><code>resource</code>.</dd>
  </cxx-returns>
        
    </dl>
  </cxx-function>

        <cxx-function id="scopeguard.uniqueres.members.12" para_num="12">
    
    <pre><code><cxx-signature><i>see below</i> operator*() const noexcept;</cxx-signature></code></pre>

    <dl>
      
          
          <cxx-constraints id="scopeguard.uniqueres.members.13" para_num="13">
    
    <dt>Constraints:</dt><dd>
            <code>is_pointer_v&lt;R&gt;</code> is <code>true</code> and
            <code>is_void_v&lt;remove_pointer_t&lt;R&gt;&gt;</code> is <code>false</code>.
          </dd>
  </cxx-constraints>
          <cxx-effects id="scopeguard.uniqueres.members.14" para_num="14">
    
    <dt>Effects:</dt><dd>Equivalent to: <code>return *get();</code></dd>
  </cxx-effects>
          <cxx-remarks id="scopeguard.uniqueres.members.15" para_num="15">
    
    <dt>Remarks:</dt><dd>
            The return type is <code>add_lvalue_reference_t&lt;remove_pointer_t&lt;R&gt;&gt;</code>.
          </dd>
  </cxx-remarks>
        
    </dl>
  </cxx-function>

        <cxx-function id="scopeguard.uniqueres.members.16" para_num="16">
    
    <pre><code><cxx-signature>R operator-&gt;() const noexcept;</cxx-signature></code></pre>

    <dl>
      
          
          <cxx-constraints id="scopeguard.uniqueres.members.17" para_num="17">
    
    <dt>Constraints:</dt><dd>
            <code>is_pointer_v&lt;R&gt;</code> is <code>true</code>.
          </dd>
  </cxx-constraints>
          <cxx-returns id="scopeguard.uniqueres.members.18" para_num="18">
    
    <dt>Returns:</dt><dd><code>get()</code>.</dd>
  </cxx-returns>
        
    </dl>
  </cxx-function>

        <cxx-function id="scopeguard.uniqueres.members.19" para_num="19">
    
    <pre><code><cxx-signature>const D&amp; get_deleter() const noexcept;</cxx-signature></code></pre>

    <dl>
      
          
          <cxx-returns id="scopeguard.uniqueres.members.20" para_num="20">
    
    <dt>Returns:</dt><dd><code>deleter</code>.</dd>
  </cxx-returns>
        
    </dl>
  </cxx-function>
      
    </section>
  </cxx-section>

      <cxx-section id="scopeguard.uniqueres.create">
    

    <section>
      <header><span class="section-number">3.3.3.6</span> <h1 data-bookmark-label="3.3.3.6 unique_resource creation"><code>unique_resource</code> creation</h1> <span style="float:right"><a href="#scopeguard.uniqueres.create">[scopeguard.uniqueres.create]</a></span></header>
      
        

        <cxx-function id="scopeguard.uniqueres.create.1" para_num="1">
    
    <pre><code><cxx-signature>template &lt;class R, class D, class S=decay_t&lt;R&gt;&gt;
unique_resource&lt;decay_t&lt;R&gt;, decay_t&lt;D&gt;&gt;
  make_unique_resource_checked(R&amp;&amp; resource, const S&amp; invalid, D&amp;&amp; d)
  noexcept(is_nothrow_constructible_v&lt;decay_t&lt;R&gt;, R&gt; &amp;&amp;
           is_nothrow_constructible_v&lt;decay_t&lt;D&gt;, D&gt;);</cxx-signature></code></pre>

    <dl>
      
          

          <cxx-mandates id="scopeguard.uniqueres.create.2" para_num="2">
    
    <dt>Mandates:</dt><dd>
            The expression <code>(resource == invalid ? true : false)</code> is well-formed.
          </dd>
  </cxx-mandates>
          <cxx-preconditions id="scopeguard.uniqueres.create.3" para_num="3">
    
    <dt>Preconditions:</dt><dd>
            Evaluation of the expression <code>(resource == invalid ? true : false)</code>
            has well-defined behavior and does not throw an exception.
          </dd>
  </cxx-preconditions>

          <cxx-effects id="scopeguard.uniqueres.create.4" para_num="4">
    
    <dt>Effects:</dt><dd>
            Returns an object constructed with members initialized from
            <code>std::forward&lt;R&gt;(resource), std::forward&lt;D&gt;(d)</code>,
            and <code>!bool(resource == invalid)</code>.
            Any failure during construction of the return value will not call <code>d(resource)</code>
            if <code>bool(resource == invalid)</code> is <code>true</code>.
          </dd>
  </cxx-effects>
        
    </dl>
  </cxx-function>

        <p id="scopeguard.uniqueres.create.5" para_num="5">
          <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    
            This creation function exists to avoid calling a deleter function
            with an invalid argument.
          
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
        </p>
        <cxx-example>
    
    <span class="nowrap">[ <em>Example:</em></span>
    
          The following example shows its use to avoid calling <code>fclose</code>
          when <code>fopen</code> fails.
          <pre><code>auto file = make_unique_resource_checked(
    ::fopen("potentially_nonexistent_file.txt", "r"),
    nullptr,
    [](auto fptr){ ::fclose(fptr); });</code></pre>
        
    <span class="nowrap">— <em>end example</em> ]</span>
  </cxx-example>
      
    </section>
  </cxx-section>
    
    </section>
  </cxx-section>
  
    </section>
  </cxx-section>

  <cxx-section id="meta">
    

    <section>
      <header><span class="section-number">3.4</span> <h1 data-bookmark-label="3.4 Metaprogramming and type traits">Metaprogramming and type traits</h1> <span style="float:right"><a href="#meta">[meta]</a></span></header>
      
    

    <cxx-section id="meta.type.syn">
    

    <section>
      <header><span class="section-number">3.4.1</span> <h1 data-bookmark-label="3.4.1 Header <experimental/type_traits> synopsis">Header &lt;experimental/type_traits&gt; synopsis</h1> <span style="float:right"><a href="#meta.type.syn">[meta.type.syn]</a></span></header>
      
      

<pre><code>#include &lt;type_traits&gt;

namespace std::experimental::inline fundamentals_v3 {

  <cxx-ref insynopsis="" to="meta.trans.other">// <i><a title="meta.trans.other" href="#meta.trans.other">3.4.2</a>, Other type transformations</i></cxx-ref>
  template &lt;class&gt; class invocation_type; // <i>not defined</i>
  template &lt;class F, class... ArgTypes&gt; class invocation_type&lt;F(ArgTypes...)&gt;;
  template &lt;class&gt; class raw_invocation_type; // <i>not defined</i>
  template &lt;class F, class... ArgTypes&gt; class raw_invocation_type&lt;F(ArgTypes...)&gt;;

  template &lt;class T&gt;
    using invocation_type_t = typename invocation_type&lt;T&gt;::type;
  template &lt;class T&gt;
    using raw_invocation_type_t = typename raw_invocation_type&lt;T&gt;::type;

  <cxx-ref insynopsis="" to="meta.detect">// <i><a title="meta.detect" href="#meta.detect">3.4.3</a>, Detection idiom</i></cxx-ref>
  struct nonesuch;

  template &lt;template&lt;class...&gt; class Op, class... Args&gt;
    using is_detected = <i>see below</i>;
  template &lt;template&lt;class...&gt; class Op, class... Args&gt;
    inline constexpr bool is_detected_v
      = is_detected&lt;Op, Args...&gt;::value;
  template &lt;template&lt;class...&gt; class Op, class... Args&gt;
    using detected_t = <i>see below</i>;
  template &lt;class Default, template&lt;class...&gt; class Op, class... Args&gt;
    using detected_or = <i>see below</i>;
  template &lt;class Default, template&lt;class...&gt; class Op, class... Args&gt;
    using detected_or_t = typename detected_or&lt;Default, Op, Args...&gt;::type;
  template &lt;class Expected, template&lt;class...&gt; class Op, class... Args&gt;
    using is_detected_exact = is_same&lt;Expected, detected_t&lt;Op, Args...&gt;&gt;;
  template &lt;class Expected, template&lt;class...&gt; class Op, class... Args&gt;
    inline constexpr bool is_detected_exact_v
      = is_detected_exact&lt;Expected, Op, Args...&gt;::value;
  template &lt;class To, template&lt;class...&gt; class Op, class... Args&gt;
    using is_detected_convertible = is_convertible&lt;detected_t&lt;Op, Args...&gt;, To&gt;;
  template &lt;class To, template&lt;class...&gt; class Op, class... Args&gt;
    inline constexpr bool is_detected_convertible_v
      = is_detected_convertible&lt;To, Op, Args...&gt;::value;

} // namespace std::experimental::inline fundamentals_v3</code></pre>

    
    </section>
  </cxx-section>

    <cxx-section id="meta.trans.other">
    

    <section>
      <header><span class="section-number">3.4.2</span> <h1 data-bookmark-label="3.4.2 Other type transformations">Other type transformations</h1> <span style="float:right"><a href="#meta.trans.other">[meta.trans.other]</a></span></header>
      
      

      <p id="meta.trans.other.1" para_num="1">
        This subclause contains templates that may be used to transform one type to another following some predefined rule.
      </p>

      <p id="meta.trans.other.2" para_num="2">
        Each of the templates in this subclause shall be a <cxx-term><i>TransformationTrait</i></cxx-term> (<cxx-ref in="cxx" to="meta.rqmts">C++20 <span title="meta.rqmts">§20.15.1</span></cxx-ref>).
      </p>

      <p id="meta.trans.other.3" para_num="3">
        Within this section, define the <dfn>invocation parameters</dfn> of <code><em>INVOKE</em>(f, t1, t2, ..., tN)</code> as follows,
        in which <code>T1</code> is the possibly <var>cv</var>-qualified type of <code>t1</code>
        and <code>U1</code> denotes <code>T1&amp;</code> if <code>t1</code> is an lvalue
        or <code>T1&amp;&amp;</code> if <code>t1</code> is an rvalue:
      </p>
      <ul>
        <li>
          When <code>f</code> is a pointer to a member function of a class <code>T</code>
          the <cxx-term><i>invocation parameters</i></cxx-term> are <code>U1</code> followed by
          the parameters of <code>f</code> matched by <code>t2</code>, ..., <code>tN</code>.
        </li>
        <li>
          When <code>N == 1</code> and <code>f</code> is a pointer to member data of a class <code>T</code>
          the <cxx-term><i>invocation parameter</i></cxx-term> is <code>U1</code>.
        </li>
        <li>
          If <code>f</code> is a class object,
          the <cxx-term><i>invocation parameters</i></cxx-term> are the parameters matching <code>t1</code>, ..., <code>tN</code>
          of the best viable function (<cxx-ref in="cxx" to="over.match.best">C++20 <span title="over.match.best">§12.4.3</span></cxx-ref>)
          for the arguments <code>t1</code>, ..., <code>tN</code>
          among the function call operators and surrogate call functions of <code>f</code>.
        </li>
        <li>
          In all other cases,
          the <cxx-term><i>invocation parameters</i></cxx-term> are the parameters of <code>f</code>
          matching <code>t1</code>, ... <code>tN</code>.
        </li>
      </ul>
      <p id="meta.trans.other.4" para_num="4">
        In all of the above cases,
        if an argument <code>tI</code> matches the ellipsis in the function's <cxx-term><i>parameter-declaration-clause</i></cxx-term>,
        the corresponding <cxx-term><i>invocation parameter</i></cxx-term> is defined to be
        the result of applying the default argument promotions (<cxx-ref in="cxx" to="expr.call">C++20 <span title="expr.call">§7.6.1.2</span></cxx-ref>) to <code>tI</code>.
      </p>

      <cxx-example>
    
    <span class="nowrap">[ <em>Example:</em></span>
    
        Assume <code>S</code> is defined as
        <pre><code>struct S {
  int f(double const &amp;) const;
  void operator()(int, int);
  void operator()(char const *, int i = 2, int j = 3);
  void operator()(...);
};</code></pre>
        <ul>
          <li>The invocation parameters of <code><em>INVOKE</em>(&amp;S::f, S(), 3.5)</code> are <code>(S &amp;&amp;, double const &amp;)</code>.</li>
          <li>The invocation parameters of <code><em>INVOKE</em>(S(), 1, 2)</code> are <code>(int, int)</code>.</li>
          <li>The invocation parameters of <code><em>INVOKE</em>(S(), "abc", 5)</code> are <code>(const char *, int)</code>.
          The defaulted parameter <code>j</code> does not correspond to an argument.</li>
          <li>The invocation parameters of <code><em>INVOKE</em>(S(), locale(), 5)</code> are <code>(locale, int)</code>.
          Arguments corresponding to ellipsis maintain their types.</li>
        </ul>
      
    <span class="nowrap">— <em>end example</em> ]</span>
  </cxx-example>

      <table is="cxx-table" id="tab:meta.trans.other">
    

    <caption>Table 4 — <wbr><span>Other type transformations</span></caption>
    
        
        <thead>
          <tr><th>Template</th><th>Condition</th><th>Comments</th></tr>
        </thead>
        <tbody><tr>
          <td>
            <code>template &lt;class Fn, class... ArgTypes&gt;<br>
            struct raw_invocation_type&lt;<w-br><wbr></w-br>Fn(ArgTypes...)&gt;;</code>
          </td>
          <td>
            <code>Fn</code> and all types in the parameter pack <code>ArgTypes</code>
            shall be complete types, (possibly cv-qualified) <code>void</code>, or arrays of unknown bound.
          </td>

          <td>
            <em>see below</em>
          </td>
        </tr>
        <tr>
          <td>
            <code>template &lt;class Fn, class... ArgTypes&gt;<br>
            struct invocation_type&lt;<w-br><wbr></w-br>Fn(ArgTypes...)&gt;;</code>
          </td>
          <td>
            <code>Fn</code> and all types in the parameter pack <code>ArgTypes</code>
            shall be complete types, (possibly cv-qualified) <code>void</code>,
            or arrays of unknown bound.
          </td>
          <td>
            <em>see below</em>
          </td>
        </tr>
      </tbody>
  </table>

      <p id="meta.trans.other.5" para_num="5">
        Access checking is performed as if in a context unrelated to <code>Fn</code> and <code>ArgTypes</code>.
        Only the validity of the immediate context of the expression is considered.
        <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    The compilation of the expression can result in side effects
        such as the instantiation of class template specializations and function template specializations,
        the generation of implicitly-defined functions, and so on.
        Such side effects are not in the "immediate context"
        and can result in the program being ill-formed.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
      </p>

      <p id="meta.trans.other.6" para_num="6">
        The member <code>raw_invocation_type&lt;Fn(ArgTypes...)&gt;::type</code> shall be defined as follows.
        If the expression <code><em>INVOKE</em>(declval&lt;Fn&gt;(), declval&lt;ArgTypes&gt;()...)</code>
        is ill-formed when treated as an unevaluated operand (<cxx-ref in="cxx" to="expr">C++20 <span title="expr">§7</span></cxx-ref>),
        there shall be no member <code>type</code>. Otherwise:
      </p>
      <ul>
        <li>Let <code>R</code> denote <code>result_of_t&lt;Fn(ArgTypes...)&gt;</code>.</li>
        <li>Let the types <code>Ti</code> be the <cxx-term><i>invocation parameters</i></cxx-term>
        of <code><em>INVOKE</em>(declval&lt;Fn&gt;(), <nobr>declval&lt;ArgTypes&gt;()...)</nobr></code>.</li>
        <li>Then the member <code>type</code> shall name the function type <code>R(T1, T2, ...)</code>.</li>
      </ul>

      <p id="meta.trans.other.7" para_num="7">
        The member <code>invocation_type&lt;Fn(ArgTypes...)&gt;::type</code> shall be defined as follows.
        If <code>raw_invocation_type&lt;Fn(ArgTypes...)&gt;::type</code> does not exist, there shall be no member <code>type</code>.
        Otherwise:
      </p>
      <ul>
        <li>Let <code>A1, A2,</code> … denote <code>ArgTypes...</code></li>
        <li>Let <code>R(T1, T2, …)</code> denote <code>raw_invocation_type_t&lt;Fn(ArgTypes...)&gt;</code></li>
        <li>
          Then the member <code>type</code> shall name the function type <code>R(U1, U2, …)</code>
          where <code>Ui</code> is <code>decay_t&lt;Ai&gt;</code> if <code>declval&lt;Ai&gt;()</code> is an rvalue
          otherwise <code>Ti</code>.
        </li>
      </ul>
    
    </section>
  </cxx-section>

    <cxx-section id="meta.detect">
    

    <section>
      <header><span class="section-number">3.4.3</span> <h1 data-bookmark-label="3.4.3 Detection idiom">Detection idiom</h1> <span style="float:right"><a href="#meta.detect">[meta.detect]</a></span></header>
      
      

      <pre><code>struct nonesuch {
  ~nonesuch() = delete;
  nonesuch(nonesuch const&amp;) = delete;
  void operator=(nonesuch const&amp;) = delete;
};</code></pre>
      <p id="meta.detect.1" para_num="1">
        <code>nonesuch</code> has no default constructor
        (<cxx-ref in="cxx" to="class.ctor">C++20 <span title="class.ctor">§11.4.4</span></cxx-ref>) or initializer-list constructor
        (<cxx-ref in="cxx" to="dcl.init.list">C++20 <span title="dcl.init.list">§9.4.4</span></cxx-ref>), and is not an aggregate
        (<cxx-ref in="cxx" to="dcl.init.aggr">C++20 <span title="dcl.init.aggr">§9.4.1</span></cxx-ref>).
      </p>

      <pre><code>template &lt;class Default, class AlwaysVoid,
          template&lt;class...&gt; class Op, class... Args&gt;
struct DETECTOR { // <i>exposition only</i>
  using value_t = false_type;
  using type = Default;
};

template &lt;class Default, template&lt;class...&gt; class Op, class... Args&gt;
struct DETECTOR&lt;Default, void_t&lt;Op&lt;Args...&gt;&gt;, Op, Args...&gt; { // <i>exposition only</i>
  using value_t = true_type;
  using type = Op&lt;Args...&gt;;
};

template &lt;template&lt;class...&gt; class Op, class... Args&gt;
  using is_detected = typename DETECTOR&lt;nonesuch, void, Op, Args...&gt;::value_t;

template &lt;template&lt;class...&gt; class Op, class... Args&gt;
  using detected_t = typename DETECTOR&lt;nonesuch, void, Op, Args...&gt;::type;

template &lt;class Default, template&lt;class...&gt; class Op, class... Args&gt;
  using detected_or = DETECTOR&lt;Default, void, Op, Args...&gt;;</code></pre>

      <cxx-example>
    
    <span class="nowrap">[ <em>Example:</em></span>
    
        <pre><code>// <i>archetypal helper alias for a copy assignment operation:</i>
template &lt;class T&gt;
  using copy_assign_t = decltype(declval&lt;T&amp;&gt;() = declval&lt;T const &amp;&gt;());

// <i>plausible implementation for the is_assignable type trait:</i>
template &lt;class T&gt;
  using is_copy_assignable = is_detected&lt;copy_assign_t, T&gt;;

// <i>plausible implementation for an augmented is_assignable type trait</i>
// <i>that also checks the return type:</i>
template &lt;class T&gt;
  using is_canonical_copy_assignable = is_detected_exact&lt;T&amp;, copy_assign_t, T&gt;;</code></pre>
      
    <span class="nowrap">— <em>end example</em> ]</span>
  </cxx-example>

      <cxx-example>
    
    <span class="nowrap">[ <em>Example:</em></span>
    
        <pre><code>// <i>archetypal helper alias for a particular type member:</i>
template &lt;class T&gt;
  using diff_t = typename T::difference_type;

// <i>alias the type member, if it exists, otherwise alias </i>ptrdiff_t<i>:</i>
template &lt;class Ptr&gt;
  using difference_type = detected_or_t&lt;ptrdiff_t, diff_t, Ptr&gt;;</code></pre>
      
    <span class="nowrap">— <em>end example</em> ]</span>
  </cxx-example>
    
    </section>
  </cxx-section>
  
    </section>
  </cxx-section>

    </section>
  </cxx-clause>

<cxx-clause id="func">
    

    <section>
      <header><span class="section-number">4</span> <h1 data-bookmark-label="4 Function objects">Function objects</h1> <span style="float:right"><a href="#func">[func]</a></span></header>
      
  

  <cxx-section id="functional.syn">
    

    <section>
      <header><span class="section-number">4.1</span> <h1 data-bookmark-label="4.1 Header <experimental/functional> synopsis">Header <code>&lt;experimental/functional&gt;</code> synopsis</h1> <span style="float:right"><a href="#functional.syn">[functional.syn]</a></span></header>
      
    

<pre><code>#include &lt;functional&gt;

namespace std {
  namespace experimental::inline fundamentals_v3 {

    <cxx-ref insynopsis="" to="func.wrap.func">// <i><a title="func.wrap.func" href="#func.wrap.func">4.2</a>, Class template function</i></cxx-ref>
    template&lt;class&gt; class function; <i>// undefined</i>
    template&lt;class R, class... ArgTypes&gt; class function&lt;R(ArgTypes...)&gt;;

    template&lt;class R, class... ArgTypes&gt;
    void swap(function&lt;R(ArgTypes...)&gt;&amp;, function&lt;R(ArgTypes...)&gt;&amp;);

    template&lt;class R, class... ArgTypes&gt;
    bool operator==(const function&lt;R(ArgTypes...)&gt;&amp;, nullptr_t) noexcept;
    template&lt;class R, class... ArgTypes&gt;
    bool operator==(nullptr_t, const function&lt;R(ArgTypes...)&gt;&amp;) noexcept;
    template&lt;class R, class... ArgTypes&gt;
    bool operator!=(const function&lt;R(ArgTypes...)&gt;&amp;, nullptr_t) noexcept;
    template&lt;class R, class... ArgTypes&gt;
    bool operator!=(nullptr_t, const function&lt;R(ArgTypes...)&gt;&amp;) noexcept;

  } // namespace experimental::inline fundamentals_v3

  template&lt;class R, class... ArgTypes, class Alloc&gt;
  struct uses_allocator&lt;experimental::function&lt;R(ArgTypes...)&gt;, Alloc&gt;;

} // namespace std</code></pre>

  
    </section>
  </cxx-section>

  <cxx-section id="func.wrap.func">
    

    <section>
      <header><span class="section-number">4.2</span> <h1 data-bookmark-label="4.2 Class template function">Class template <code>function</code></h1> <span style="float:right"><a href="#func.wrap.func">[func.wrap.func]</a></span></header>
      
    

    <cxx-section id="func.wrap.func.overview">
    

    <section>
      <header><span class="section-number">4.2.1</span> <h1 data-bookmark-label="4.2.1 Overview">Overview</h1> <span style="float:right"><a href="#func.wrap.func.overview">[func.wrap.func.overview]</a></span></header>
      
      

      <p id="func.wrap.func.overview.1" para_num="1">
        The specification of all declarations within subclause <cxx-ref to="func.wrap.func"><a title="func.wrap.func" href="#func.wrap.func">4.2</a></cxx-ref>
        are the same as the corresponding declarations, as specified in <cxx-ref in="cxx" to="func.wrap.func">C++20 <span title="func.wrap.func">§20.14.16.2</span></cxx-ref>,
        unless explicitly specified otherwise. <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    <code>std::experimental::function</code> uses
        <code>std::bad_function_call</code>, there is no additional type <code>std::experimental::bad_function_call</code>
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>.
      </p>

<pre><code>namespace std {
  namespace experimental::inline fundamentals_v3 {

    template&lt;class&gt; class function; <i>// undefined</i>

    template&lt;class R, class... ArgTypes&gt;
    class function&lt;R(ArgTypes...)&gt; {
    public:
      using result_type = R;
      using argument_type = T1;
      using first_argument_type T1;
      using second_argument_type = T2;

      using allocator_type = erased_type;

      function() noexcept;
      function(nullptr_t) noexcept;
      function(const function&amp;);
      function(function&amp;&amp;);
      template&lt;class F&gt; function(F);
      template&lt;class A&gt; function(allocator_arg_t, const A&amp;) noexcept;
      template&lt;class A&gt; function(allocator_arg_t, const A&amp;,
        nullptr_t) noexcept;
      template&lt;class A&gt; function(allocator_arg_t, const A&amp;,
        const function&amp;);
      template&lt;class A&gt; function(allocator_arg_t, const A&amp;,
        function&amp;&amp;);
      template&lt;class F, class A&gt; function(allocator_arg_t, const A&amp;, F);

      function&amp; operator=(const function&amp;);
      function&amp; operator=(function&amp;&amp;);
      function&amp; operator=(nullptr_t) noexcept;
      template&lt;class F&gt; function&amp; operator=(F&amp;&amp;);
      template&lt;class F&gt; function&amp; operator=(reference_wrapper&lt;F&gt;);

      ~function();

      void swap(function&amp;);

      explicit operator bool() const noexcept;

      R operator()(ArgTypes...) const;

      const type_info&amp; target_type() const noexcept;
      template&lt;class T&gt; T* target() noexcept;
      template&lt;class T&gt; const T* target() const noexcept;

      pmr::memory_resource* get_memory_resource() const noexcept;
    };

    template &lt;class R, class... ArgTypes&gt;
    bool operator==(const function&lt;R(ArgTypes...)&gt;&amp;, nullptr_t) noexcept;
    template &lt;class R, class... ArgTypes&gt;
    bool operator==(nullptr_t, const function&lt;R(ArgTypes...)&gt;&amp;) noexcept;

    template &lt;class R, class... ArgTypes&gt;
    bool operator!=(const function&lt;R(ArgTypes...)&gt;&amp;, nullptr_t) noexcept;
    template &lt;class R, class... ArgTypes&gt;
    bool operator!=(nullptr_t, const function&lt;R(ArgTypes...)&gt;&amp;) noexcept;

    template &lt;class R, class... ArgTypes&gt;
    void swap(function&lt;R(ArgTypes...)&gt;&amp;, function&lt;R(ArgTypes...)&gt;&amp;);

  } // namespace experimental::inline fundamentals_v3

  template &lt;class R, class... ArgTypes, class Alloc&gt;
  struct uses_allocator&lt;experimental::function&lt;R(ArgTypes...)&gt;, Alloc&gt;
    : true_type { };

} // namespace std</code></pre>

    
    </section>
  </cxx-section>

    <cxx-section id="func.wrap.func.con">
    

    <section>
      <header><span class="section-number">4.2.2</span> <h1 data-bookmark-label="4.2.2 function construct/copy/destroy"><code>function</code> construct/copy/destroy</h1> <span style="float:right"><a href="#func.wrap.func.con">[func.wrap.func.con]</a></span></header>
      
      

      <cxx-ednote>
    
    <aside><strong>Editor's note:</strong> 
        The following first paragraph has been slightly editorially improved to
        (a) make the difference between <code>std::function</code> and <code>std::experimental::function</code> clearer
        (which seems necessary due to the "including" wording that can be parsed in two different ways) and
        (b) to make intended normative wording clearer, that had been put into parenthesis before, by simply removing these parenthesis.
      </aside>
  </cxx-ednote>

      <p id="func.wrap.func.con.1" para_num="1">
        When a <code>function</code> constructor that takes a first argument of type <code>allocator_arg_t</code> is invoked,
        the second argument is treated as a <cxx-term><i>type-erased allocator</i></cxx-term> (<cxx-ref to="memory.type.erased.allocator"><a title="memory.type.erased.allocator" href="#memory.type.erased.allocator">5.3</a></cxx-ref>).
        If the constructor moves or makes a copy
        of a function object (<cxx-ref in="cxx" to="function.objects">C++20 <span title="function.objects">§20.14</span></cxx-ref>),
        including an instance of the <code>experimental::function</code> class template,
        then that move or copy is performed by <cxx-term><i>using-allocator construction</i></cxx-term> with allocator <code>get_memory_resource()</code>.
      </p>

      <p id="func.wrap.func.con.2" para_num="2">
        In the following descriptions, let <code><em>ALLOCATOR_OF</em>(f)</code> be the allocator specified in the construction of <code>function</code> <code>f</code>,
        or the value of <code>experimental::<wbr>pmr::<wbr>get_default_resource()</code> at the time of the construction of <code>f</code> if no allocator was specified.
      </p>

      <cxx-function id="func.wrap.func.con.3" para_num="3">
    
    <pre><code><cxx-signature>function&amp; operator=(const function&amp; f);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-effects id="func.wrap.func.con.4" para_num="4">
    
    <dt>Effects:</dt><dd><code>function(allocator_arg, <em>ALLOCATOR_OF</em>(*this), f).swap(*this);</code></dd>
  </cxx-effects>
        <cxx-returns id="func.wrap.func.con.5" para_num="5">
    
    <dt>Returns:</dt><dd><code>*this</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="func.wrap.func.con.6" para_num="6">
    
    <pre><code><cxx-signature>function&amp; operator=(function&amp;&amp; f);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-effects id="func.wrap.func.con.7" para_num="7">
    
    <dt>Effects:</dt><dd><code>function(allocator_arg, <em>ALLOCATOR_OF</em>(*this), std::move(f)).swap(*this);</code></dd>
  </cxx-effects>
        <cxx-returns id="func.wrap.func.con.8" para_num="8">
    
    <dt>Returns:</dt><dd><code>*this</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="func.wrap.func.con.9" para_num="9">
    
    <pre><code><cxx-signature>function&amp; operator=(nullptr_t) noexcept;</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-effects id="func.wrap.func.con.10" para_num="10">
    
    <dt>Effects:</dt><dd>If <code>*this != nullptr</code>, destroys the target of <code>this</code>.</dd>
  </cxx-effects>
        <cxx-postconditions id="func.wrap.func.con.11" para_num="11">
    
    <dt>Postconditions:</dt><dd><code>!(*this)</code>.
        The memory resource returned by <code>get_memory_resource()</code> after the assignment is equivalent to the memory resource before the assignment.
        <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    the address returned by <code>get_memory_resource()</code> might change
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note></dd>
  </cxx-postconditions>
        <cxx-returns id="func.wrap.func.con.12" para_num="12">
    
    <dt>Returns:</dt><dd><code>*this</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="func.wrap.func.con.13" para_num="13">
    
    <pre><code><cxx-signature>template&lt;class F&gt; function&amp; operator=(F&amp;&amp; f);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-constraints id="func.wrap.func.con.14" para_num="14">
    
    <dt>Constraints:</dt><dd>
          <code>declval&lt;decay_t&lt;F&gt;&amp;&gt;()</code> is <cxx-17concept><i>Lvalue-Callable</i></cxx-17concept> (<cxx-ref in="cxx" to="func.wrap.func">C++20 <span title="func.wrap.func">§20.14.16.2</span></cxx-ref>)
          for argument types <code>ArgTypes...</code> and return type <code>R</code>.
        </dd>
  </cxx-constraints>
        <cxx-effects id="func.wrap.func.con.15" para_num="15">
    
    <dt>Effects:</dt><dd><code>function(allocator_arg, <em>ALLOCATOR_OF</em>(*this), std::forward&lt;F&gt;(f)).swap(*this);</code></dd>
  </cxx-effects>
        <cxx-returns id="func.wrap.func.con.16" para_num="16">
    
    <dt>Returns:</dt><dd><code>*this</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="func.wrap.func.con.17" para_num="17">
    
    <pre><code><cxx-signature>template&lt;class F&gt; function&amp; operator=(reference_wrapper&lt;F&gt; f);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-effects id="func.wrap.func.con.18" para_num="18">
    
    <dt>Effects:</dt><dd><code>function(allocator_arg, <em>ALLOCATOR_OF</em>(*this), f).swap(*this);</code></dd>
  </cxx-effects>
        <cxx-returns id="func.wrap.func.con.19" para_num="19">
    
    <dt>Returns:</dt><dd><code>*this</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

    <cxx-section id="func.wrap.func.mod">
    

    <section>
      <header><span class="section-number">4.2.3</span> <h1 data-bookmark-label="4.2.3 function modifiers"><code>function</code> modifiers</h1> <span style="float:right"><a href="#func.wrap.func.mod">[func.wrap.func.mod]</a></span></header>
      
      

      <cxx-function id="func.wrap.func.mod.1" para_num="1">
    
    <pre><code><cxx-signature>void swap(function&amp; other);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-preconditions id="func.wrap.func.mod.2" para_num="2">
    
    <dt>Preconditions:</dt><dd><code>*this-&gt;get_memory_resource() == *other.get_memory_resource()</code>.</dd>
  </cxx-preconditions>
        <cxx-effects id="func.wrap.func.mod.3" para_num="3">
    
    <dt>Effects:</dt><dd>Interchanges the targets of <code>*this</code> and <code>other</code>.</dd>
  </cxx-effects>
        <cxx-remarks id="func.wrap.func.mod.4" para_num="4">
    
    <dt>Remarks:</dt><dd>The allocators of <code>*this</code> and <code>other</code> are not interchanged.</dd>
  </cxx-remarks>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>
  
    </section>
  </cxx-section>

    </section>
  </cxx-clause>

<cxx-clause id="memory">
    

    <section>
      <header><span class="section-number">5</span> <h1 data-bookmark-label="5 Memory">Memory</h1> <span style="float:right"><a href="#memory">[memory]</a></span></header>
      
  

  <cxx-section id="memory.syn">
    

    <section>
      <header><span class="section-number">5.1</span> <h1 data-bookmark-label="5.1 Header <experimental/memory> synopsis">Header &lt;experimental/memory&gt; synopsis</h1> <span style="float:right"><a href="#memory.syn">[memory.syn]</a></span></header>
      
    

<pre><code>#include &lt;memory&gt;

namespace std {
  namespace experimental::inline fundamentals_v3 {

    <cxx-ref insynopsis="" to="memory.observer.ptr">// <i><a title="memory.observer.ptr" href="#memory.observer.ptr">5.2</a>, Non-owning (observer) pointers</i></cxx-ref>
    template &lt;class W&gt; class observer_ptr;

    <cxx-ref insynopsis="" to="memory.observer.ptr.special">// <i><a title="memory.observer.ptr.special" href="#memory.observer.ptr.special">5.2.6</a>, observer_ptr specialized algorithms</i></cxx-ref>
    template &lt;class W&gt;
    void swap(observer_ptr&lt;W&gt;&amp;, observer_ptr&lt;W&gt;&amp;) noexcept;
    template &lt;class W&gt;
    observer_ptr&lt;W&gt; make_observer(W*) noexcept;
    // (in)equality operators
    template &lt;class W1, class W2&gt;
    bool operator==(observer_ptr&lt;W1&gt;, observer_ptr&lt;W2&gt;);

    template &lt;class W1, class W2&gt;
    bool operator!=(observer_ptr&lt;W1&gt;, observer_ptr&lt;W2&gt;);
    template &lt;class W&gt;
    bool operator==(observer_ptr&lt;W&gt;, nullptr_t) noexcept;
    template &lt;class W&gt;
    bool operator!=(observer_ptr&lt;W&gt;, nullptr_t) noexcept;
    template &lt;class W&gt;
    bool operator==(nullptr_t, observer_ptr&lt;W&gt;) noexcept;
    template &lt;class W&gt;
    bool operator!=(nullptr_t, observer_ptr&lt;W&gt;) noexcept;
    // ordering operators
    template &lt;class W1, class W2&gt;
    bool operator&lt;(observer_ptr&lt;W1&gt;, observer_ptr&lt;W2&gt;);
    template &lt;class W1, class W2&gt;
    bool operator&gt;(observer_ptr&lt;W1&gt;, observer_ptr&lt;W2&gt;);
    template &lt;class W1, class W2&gt;
    bool operator&lt;=(observer_ptr&lt;W1&gt;, observer_ptr&lt;W2&gt;);
    template &lt;class W1, class W2&gt;
    bool operator&gt;=(observer_ptr&lt;W1&gt;, observer_ptr&lt;W2&gt;);

  } // namespace experimental::inline fundamentals_v3

  <cxx-ref insynopsis="" to="memory.observer.ptr.hash">// <i><a title="memory.observer.ptr.hash" href="#memory.observer.ptr.hash">5.2.7</a>, observer_ptr hash support</i></cxx-ref>
  template &lt;class T&gt; struct hash;
  template &lt;class T&gt; struct hash&lt;experimental::observer_ptr&lt;T&gt;&gt;;

} // namespace std</code></pre>
  
    </section>
  </cxx-section>

  <cxx-section id="memory.observer.ptr">
    

    <section>
      <header><span class="section-number">5.2</span> <h1 data-bookmark-label="5.2 Non-owning (observer) pointers">Non-owning (observer) pointers</h1> <span style="float:right"><a href="#memory.observer.ptr">[memory.observer.ptr]</a></span></header>
      
    

    <cxx-section id="memory.observer.ptr.overview">
    

    <section>
      <header><span class="section-number">5.2.1</span> <h1 data-bookmark-label="5.2.1 Class template observer_ptr overview">Class template <code>observer_ptr</code> overview</h1> <span style="float:right"><a href="#memory.observer.ptr.overview">[memory.observer.ptr.overview]</a></span></header>
      
      

<pre><code>namespace std::experimental::inline fundamentals_v3 {

  template &lt;class W&gt; class observer_ptr {
    using pointer = add_pointer_t&lt;W&gt;;            <i>// exposition-only</i>
    using reference = add_lvalue_reference_t&lt;W&gt;; <i>// exposition-only</i>
  public:
    // publish our template parameter and variations thereof
    using element_type = W;

    <cxx-ref insynopsis="" to="memory.observer.ptr.ctor">// <i><a title="memory.observer.ptr.ctor" href="#memory.observer.ptr.ctor">5.2.2</a>, observer_ptr constructors</i></cxx-ref>
    // default constructor
    constexpr observer_ptr() noexcept;

    // pointer-accepting constructors
    constexpr observer_ptr(nullptr_t) noexcept;
    constexpr explicit observer_ptr(pointer) noexcept;

    // copying constructors (in addition to the implicit copy constructor)
    template &lt;class W2&gt; constexpr observer_ptr(observer_ptr&lt;W2&gt;) noexcept;

    <cxx-ref insynopsis="" to="memory.observer.ptr.obs">// <i><a title="memory.observer.ptr.obs" href="#memory.observer.ptr.obs">5.2.3</a>, observer_ptr observers</i></cxx-ref>
    constexpr pointer get() const noexcept;
    constexpr reference operator*() const;
    constexpr pointer operator-&gt;() const noexcept;
    constexpr explicit operator bool() const noexcept;

    <cxx-ref insynopsis="" to="memory.observer.ptr.conv">// <i><a title="memory.observer.ptr.conv" href="#memory.observer.ptr.conv">5.2.4</a>, observer_ptr conversions</i></cxx-ref>
    constexpr explicit operator pointer() const noexcept;

    <cxx-ref insynopsis="" to="memory.observer.ptr.mod">// <i><a title="memory.observer.ptr.mod" href="#memory.observer.ptr.mod">5.2.5</a>, observer_ptr modifiers</i></cxx-ref>
    constexpr pointer release() noexcept;
    constexpr void reset(pointer = nullptr) noexcept;
    constexpr void swap(observer_ptr&amp;) noexcept;
  }; // observer_ptr&lt;&gt;

} // namespace std::experimental::inline fundamentals_v3</code></pre>

      <p id="memory.observer.ptr.overview.1" para_num="1">
        A non-owning pointer, known as an <dfn>observer</dfn>, is an object <code>o</code> that stores a pointer to a second object, <code>w</code>.
        In this context, <code>w</code> is known as a <dfn>watched</dfn> object.
        <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    There is no watched object when the stored pointer is <code>nullptr</code>.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
        An observer takes no responsibility or ownership of any kind for its watched object, if any;
        in particular, there is no inherent relationship between the lifetimes of <code>o</code> and <code>w</code>.
      </p>

      <p id="memory.observer.ptr.overview.2" para_num="2">
        Specializations of <code>observer_ptr</code> shall meet the requirements
        of a <cxx-17concept><i>Cpp17CopyConstructible</i></cxx-17concept>
        and <cxx-17concept><i>Cpp17CopyAssignable</i></cxx-17concept> type.
        The template parameter <code>W</code> of an <code>observer_ptr</code>
        shall not be a reference type, but may be an incomplete type.
      </p>

      <p id="memory.observer.ptr.overview.3" para_num="3">
        <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    The uses of <code>observer_ptr</code> include clarity of interface specification in new code,
          and interoperability with pointer-based legacy code.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
      </p>
    
    </section>
  </cxx-section>

    <cxx-section id="memory.observer.ptr.ctor">
    

    <section>
      <header><span class="section-number">5.2.2</span> <h1 data-bookmark-label="5.2.2 observer_ptr constructors"><code>observer_ptr</code> constructors</h1> <span style="float:right"><a href="#memory.observer.ptr.ctor">[memory.observer.ptr.ctor]</a></span></header>
      
      

      <cxx-function id="memory.observer.ptr.ctor.1" para_num="1">
    
    <pre><code><cxx-signature>constexpr observer_ptr() noexcept;</cxx-signature><cxx-signature>constexpr observer_ptr(nullptr_t) noexcept;</cxx-signature></code></pre>

    <dl>
      
        
        

        <cxx-effects id="memory.observer.ptr.ctor.2" para_num="2">
    
    <dt>Effects:</dt><dd>Constructs an observer_ptr object that has no corresponding watched object.</dd>
  </cxx-effects>
        <cxx-postconditions id="memory.observer.ptr.ctor.3" para_num="3">
    
    <dt>Postconditions:</dt><dd><code>get() == nullptr</code>.</dd>
  </cxx-postconditions>
      
    </dl>
  </cxx-function>

      <cxx-function id="memory.observer.ptr.ctor.4" para_num="4">
    
    <pre><code><cxx-signature>constexpr explicit observer_ptr(pointer other) noexcept;</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-postconditions id="memory.observer.ptr.ctor.5" para_num="5">
    
    <dt>Postconditions:</dt><dd><code>get() == other</code>.</dd>
  </cxx-postconditions>
      
    </dl>
  </cxx-function>

      <cxx-function id="memory.observer.ptr.ctor.6" para_num="6">
    
    <pre><code><cxx-signature>template &lt;class W2&gt; constexpr observer_ptr(observer_ptr&lt;W2&gt; other) noexcept;</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-constraints id="memory.observer.ptr.ctor.7" para_num="7">
    
    <dt>Constraints:</dt><dd><code>W2*</code> is convertible to <code>W*</code>.</dd>
  </cxx-constraints>
        <cxx-postconditions id="memory.observer.ptr.ctor.8" para_num="8">
    
    <dt>Postconditions:</dt><dd><code>get() == other.get()</code>.</dd>
  </cxx-postconditions>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

    <cxx-section id="memory.observer.ptr.obs">
    

    <section>
      <header><span class="section-number">5.2.3</span> <h1 data-bookmark-label="5.2.3 observer_ptr observers"><code>observer_ptr</code> observers</h1> <span style="float:right"><a href="#memory.observer.ptr.obs">[memory.observer.ptr.obs]</a></span></header>
      
      

      <cxx-function id="memory.observer.ptr.obs.1" para_num="1">
    
    <pre><code><cxx-signature>constexpr pointer get() const noexcept;</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="memory.observer.ptr.obs.2" para_num="2">
    
    <dt>Returns:</dt><dd>The stored pointer.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="memory.observer.ptr.obs.3" para_num="3">
    
    <pre><code><cxx-signature>constexpr reference operator*() const;</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-preconditions id="memory.observer.ptr.obs.4" para_num="4">
    
    <dt>Preconditions:</dt><dd><code>get() != nullptr</code> is <code>true</code>.</dd>
  </cxx-preconditions>
        <cxx-returns id="memory.observer.ptr.obs.5" para_num="5">
    
    <dt>Returns:</dt><dd><code>*get()</code>.</dd>
  </cxx-returns>
        <cxx-throws id="memory.observer.ptr.obs.6" para_num="6">
    
    <dt>Throws:</dt><dd>Nothing.</dd>
  </cxx-throws>
      
    </dl>
  </cxx-function>

      <cxx-function id="memory.observer.ptr.obs.7" para_num="7">
    
    <pre><code><cxx-signature>constexpr pointer operator-&gt;() const noexcept;</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="memory.observer.ptr.obs.8" para_num="8">
    
    <dt>Returns:</dt><dd><code>get()</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="memory.observer.ptr.obs.9" para_num="9">
    
    <pre><code><cxx-signature>constexpr explicit operator bool() const noexcept;</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="memory.observer.ptr.obs.10" para_num="10">
    
    <dt>Returns:</dt><dd><code>get() != nullptr</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

    <cxx-section id="memory.observer.ptr.conv">
    

    <section>
      <header><span class="section-number">5.2.4</span> <h1 data-bookmark-label="5.2.4 observer_ptr conversions"><code>observer_ptr</code> conversions</h1> <span style="float:right"><a href="#memory.observer.ptr.conv">[memory.observer.ptr.conv]</a></span></header>
      
      

      <cxx-function id="memory.observer.ptr.conv.1" para_num="1">
    
    <pre><code><cxx-signature>constexpr explicit operator pointer() const noexcept;</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="memory.observer.ptr.conv.2" para_num="2">
    
    <dt>Returns:</dt><dd><code>get()</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

    <cxx-section id="memory.observer.ptr.mod">
    

    <section>
      <header><span class="section-number">5.2.5</span> <h1 data-bookmark-label="5.2.5 observer_ptr modifiers"><code>observer_ptr</code> modifiers</h1> <span style="float:right"><a href="#memory.observer.ptr.mod">[memory.observer.ptr.mod]</a></span></header>
      
      

      <cxx-function id="memory.observer.ptr.mod.1" para_num="1">
    
    <pre><code><cxx-signature>constexpr pointer release() noexcept;</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-postconditions id="memory.observer.ptr.mod.2" para_num="2">
    
    <dt>Postconditions:</dt><dd><code>get() == nullptr</code>.</dd>
  </cxx-postconditions>
        <cxx-returns id="memory.observer.ptr.mod.3" para_num="3">
    
    <dt>Returns:</dt><dd>The value <code>get()</code> had at the start of the call to <code>release</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="memory.observer.ptr.mod.4" para_num="4">
    
    <pre><code><cxx-signature>constexpr void reset(pointer p = nullptr) noexcept;</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-postconditions id="memory.observer.ptr.mod.5" para_num="5">
    
    <dt>Postconditions:</dt><dd><code>get() == p</code>.</dd>
  </cxx-postconditions>
      
    </dl>
  </cxx-function>

      <cxx-function id="memory.observer.ptr.mod.6" para_num="6">
    
    <pre><code><cxx-signature>constexpr void swap(observer_ptr&amp; other) noexcept;</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-effects id="memory.observer.ptr.mod.7" para_num="7">
    
    <dt>Effects:</dt><dd>Invokes <code>swap</code> on the stored pointers of <code>*this</code> and <code>other</code>.</dd>
  </cxx-effects>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

    <cxx-section id="memory.observer.ptr.special">
    

    <section>
      <header><span class="section-number">5.2.6</span> <h1 data-bookmark-label="5.2.6 observer_ptr specialized algorithms"><code>observer_ptr</code> specialized algorithms</h1> <span style="float:right"><a href="#memory.observer.ptr.special">[memory.observer.ptr.special]</a></span></header>
      
      

      <cxx-function id="memory.observer.ptr.special.1" para_num="1">
    
    <pre><code><cxx-signature>template &lt;class W&gt;
void swap(observer_ptr&lt;W&gt;&amp; p1, observer_ptr&lt;W&gt;&amp; p2) noexcept;</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-effects id="memory.observer.ptr.special.2" para_num="2">
    
    <dt>Effects:</dt><dd><code>p1.swap(p2)</code>.</dd>
  </cxx-effects>
      
    </dl>
  </cxx-function>

      <cxx-function id="memory.observer.ptr.special.3" para_num="3">
    
    <pre><code><cxx-signature>template &lt;class W&gt; observer_ptr&lt;W&gt; make_observer(W* p) noexcept;</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="memory.observer.ptr.special.4" para_num="4">
    
    <dt>Returns:</dt><dd><code>observer_ptr&lt;W&gt;{p}</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="memory.observer.ptr.special.5" para_num="5">
    
    <pre><code><cxx-signature>template &lt;class W1, class W2&gt;
bool operator==(observer_ptr&lt;W1&gt; p1, observer_ptr&lt;W2&gt; p2);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="memory.observer.ptr.special.6" para_num="6">
    
    <dt>Returns:</dt><dd><code>p1.get() == p2.get()</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="memory.observer.ptr.special.7" para_num="7">
    
    <pre><code><cxx-signature>template &lt;class W1, class W2&gt;
bool operator!=(observer_ptr&lt;W1&gt; p1, observer_ptr&lt;W2&gt; p2);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="memory.observer.ptr.special.8" para_num="8">
    
    <dt>Returns:</dt><dd><code>not (p1 == p2)</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="memory.observer.ptr.special.9" para_num="9">
    
    <pre><code><cxx-signature>template &lt;class W&gt;
bool operator==(observer_ptr&lt;W&gt; p, nullptr_t) noexcept;</cxx-signature><cxx-signature>template &lt;class W&gt;
bool operator==(nullptr_t, observer_ptr&lt;W&gt; p) noexcept;</cxx-signature></code></pre>

    <dl>
      
        
        

        <cxx-returns id="memory.observer.ptr.special.10" para_num="10">
    
    <dt>Returns:</dt><dd><code>not p</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="memory.observer.ptr.special.11" para_num="11">
    
    <pre><code><cxx-signature>template &lt;class W&gt;
bool operator!=(observer_ptr&lt;W&gt; p, nullptr_t) noexcept;</cxx-signature><cxx-signature>template &lt;class W&gt;
bool operator!=(nullptr_t, observer_ptr&lt;W&gt; p) noexcept;</cxx-signature></code></pre>

    <dl>
      
        
        

        <cxx-returns id="memory.observer.ptr.special.12" para_num="12">
    
    <dt>Returns:</dt><dd><code>(bool)p</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="memory.observer.ptr.special.13" para_num="13">
    
    <pre><code><cxx-signature>template &lt;class W1, class W2&gt;
bool operator&lt;(observer_ptr&lt;W1&gt; p1, observer_ptr&lt;W2&gt; p2);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="memory.observer.ptr.special.14" para_num="14">
    
    <dt>Returns:</dt><dd>
          <code>less&lt;W3&gt;()(p1.get(), p2.get())</code>,
          where <code>W3</code> is the composite pointer type (<cxx-ref in="cxx" to="expr">C++20 <span title="expr">§7</span></cxx-ref>) of <code>W1*</code> and <code>W2*</code>.
        </dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="memory.observer.ptr.special.15" para_num="15">
    
    <pre><code><cxx-signature>template &lt;class W1, class W2&gt;
bool operator&gt;(observer_ptr&lt;W1&gt; p1, observer_ptr&lt;W2&gt; p2);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="memory.observer.ptr.special.16" para_num="16">
    
    <dt>Returns:</dt><dd><code>p2 &lt; p1</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="memory.observer.ptr.special.17" para_num="17">
    
    <pre><code><cxx-signature>template &lt;class W1, class W2&gt;
bool operator&lt;=(observer_ptr&lt;W1&gt; p1, observer_ptr&lt;W2&gt; p2);</cxx-signature></code></pre>

    <dl>
      
        

         <cxx-returns id="memory.observer.ptr.special.18" para_num="18">
    
    <dt>Returns:</dt><dd><code>not (p2 &lt; p1)</code>.</dd>
  </cxx-returns>
        
    </dl>
  </cxx-function>

      <cxx-function id="memory.observer.ptr.special.19" para_num="19">
    
    <pre><code><cxx-signature>template &lt;class W1, class W2&gt;
bool operator&gt;=(observer_ptr&lt;W1&gt; p1, observer_ptr&lt;W2&gt; p2);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="memory.observer.ptr.special.20" para_num="20">
    
    <dt>Returns:</dt><dd><code>not (p1 &lt; p2)</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

    <cxx-section id="memory.observer.ptr.hash">
    

    <section>
      <header><span class="section-number">5.2.7</span> <h1 data-bookmark-label="5.2.7 observer_ptr hash support"><code>observer_ptr</code> hash support</h1> <span style="float:right"><a href="#memory.observer.ptr.hash">[memory.observer.ptr.hash]</a></span></header>
      
      

      <cxx-function id="memory.observer.ptr.hash.1" para_num="1">
    
    <pre><code><cxx-signature>template &lt;class T&gt; struct hash&lt;experimental::observer_ptr&lt;T&gt;&gt;;</cxx-signature></code></pre>

    <dl>
      
        

        <p id="memory.observer.ptr.hash.2" para_num="2">
          The specialization is enabled (<cxx-ref in="cxx" to="unord.hash">C++20 <span title="unord.hash">§20.14.18</span></cxx-ref>).
          For an object <code>p</code> of type <code>observer_ptr&lt;T&gt;</code>,
          <code>hash&lt;observer_ptr&lt;T&gt;&gt;()(p)</code> evaluates to the same value as <code>hash&lt;T*&gt;()(p.get())</code>.
        </p>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>
  
    </section>
  </cxx-section>

  <cxx-section id="memory.type.erased.allocator">
    

    <section>
      <header><span class="section-number">5.3</span> <h1 data-bookmark-label="5.3 Type-erased allocator">Type-erased allocator</h1> <span style="float:right"><a href="#memory.type.erased.allocator">[memory.type.erased.allocator]</a></span></header>
      
    

    <p id="memory.type.erased.allocator.1" para_num="1">
      A <dfn>type-erased allocator</dfn> is an allocator or memory resource, <code>alloc</code>,
      used to allocate internal data structures for an object <code>X</code> of type <code>C</code>,
      but where <code>C</code> is not dependent on the type of <code>alloc</code>.
      Once <code>alloc</code> has been supplied to <code>X</code> (typically as a constructor argument),
      <code>alloc</code> can be retrieved from <code>X</code> only as a pointer <code>rptr</code> of static type <code>std::pmr::memory_resource*</code> (<cxx-ref in="cxx" to="mem.res.class">C++20 <span title="mem.res.class">§20.12.2</span></cxx-ref>).
      The process by which <code>rptr</code> is computed from <code>alloc</code> depends on the type of <code>alloc</code> as described in <cxx-ref to="tab:memory.resource.type.erased.allocator"><a title="tab:memory.resource.type.erased.allocator" href="#tab:memory.resource.type.erased.allocator">Table 5</a></cxx-ref>:
    </p>

    <table is="cxx-table" id="tab:memory.resource.type.erased.allocator">
    

    <caption>Table 5 — <wbr><span>Computed <code>memory_resource</code> for type-erased allocator</span></caption>
    
      
      <thead>
        <tr>
          <th>If the type of <code>alloc</code> is</th>
          <th>then the value of <code>rptr</code> is</th>
        </tr>
      </thead>
      <tbody><tr>
        <td>non-existent — no <code>alloc</code> specified</td>
        <td>The value of <code>pmr::get_default_resource()</code> at the time of construction.</td>
      </tr>
      <tr>
        <td><code>nullptr_t</code></td>
        <td>The value of <code>pmr::get_default_resource()</code> at the time of construction.</td>
      </tr>
      <tr>
        <td>a pointer type convertible to <code>pmr::memory_resource*</code></td>
        <td><code>static_cast&lt;pmr::memory_resource*&gt;(alloc)</code></td>
      </tr>
      <tr>
        <td><code>pmr::polymorphic_allocator&lt;U&gt;</code></td>
        <td><code>alloc.resource()</code></td>
      </tr>
      <tr>
        <td>any other type meeting the <cxx-17concept><i>Cpp17Allocator</i></cxx-17concept> requirements (<cxx-ref in="cxx" to="allocator.requirements">C++20 <span title="allocator.requirements">§16.5.3.5</span></cxx-ref>)</td>
        <td>a pointer to a value of type <code>pmr::resource_adaptor&lt;A&gt;</code> where <code>A</code> is the type of <code>alloc</code>.
        <code>rptr</code> remains valid only for the lifetime of <code>X</code>.</td>
      </tr>
      <tr>
        <td>None of the above</td>
        <td>The program is ill-formed.</td>
      </tr>
    </tbody>
  </table>

    <p id="memory.type.erased.allocator.2" para_num="2">Additionally, class <code>C</code> meets the following requirements:</p>
    <ul>
      <li><code>C::allocator_type</code> denotes <code>std::experimental::erased_type</code>.</li>
      <li><code>X.get_memory_resource()</code> returns <code>rptr</code>.</li>
    </ul>
  
    </section>
  </cxx-section>

  <cxx-section id="memory.resource.syn">
    

    <section>
      <header><span class="section-number">5.4</span> <h1 data-bookmark-label="5.4 Header <experimental/memory_resource> synopsis">Header <code>&lt;experimental/memory_resource&gt;</code> synopsis</h1> <span style="float:right"><a href="#memory.resource.syn">[memory.resource.syn]</a></span></header>
      
    

    <pre><code>namespace std::experimental::inline fundamentals_v3::pmr {

  // The name <var>resource_adaptor_imp</var> is for exposition only.
  template &lt;class Allocator&gt; class <var>resource_adaptor_imp</var>;

  template &lt;class Allocator&gt;
    using resource_adaptor = <var>resource_adaptor_imp</var>&lt;
      typename allocator_traits&lt;Allocator&gt;::template rebind_alloc&lt;char&gt;&gt;;

} // namespace std::experimental::inline fundamentals_v3::pmr</code></pre>
  
    </section>
  </cxx-section>

  <cxx-section id="memory.resource.adaptor">
    

    <section>
      <header><span class="section-number">5.5</span> <h1 data-bookmark-label="5.5 Alias template resource_adaptor">Alias template <code>resource_adaptor</code></h1> <span style="float:right"><a href="#memory.resource.adaptor">[memory.resource.adaptor]</a></span></header>
      
    

    <cxx-section id="memory.resource.adaptor.overview">
    

    <section>
      <header><span class="section-number">5.5.1</span> <h1 data-bookmark-label="5.5.1 resource_adaptor"><code>resource_adaptor</code></h1> <span style="float:right"><a href="#memory.resource.adaptor.overview">[memory.resource.adaptor.overview]</a></span></header>
      
      

      <p id="memory.resource.adaptor.overview.1" para_num="1">
        An instance of <code>resource_adaptor&lt;Allocator&gt;</code> is an adaptor that wraps a <code>memory_resource</code> interface around <code>Allocator</code>.
        In order that <code>resource_adaptor&lt;X&lt;T&gt;&gt;</code> and <code>resource_adaptor&lt;X&lt;U&gt;&gt;</code> are the same type for any allocator template <code>X</code> and types <code>T</code> and <code>U</code>,
        <code>resource_adaptor&lt;Allocator&gt;</code> is rendered as an alias to a class template such that <code>Allocator</code> is rebound to a <code>char</code> value type in every specialization of the class template.
        The requirements on this class template are defined below.
        The name <code><var>resource_adaptor_imp</var></code> is for exposition only and is not normative,
        but the definitions of the members of that class, whatever its name, are normative.
        In addition to the <cxx-17concept><i>Cpp17Allocator</i></cxx-17concept> requirements (<cxx-ref in="cxx" to="allocator.requirements">C++20 <span title="allocator.requirements">§16.5.3.5</span></cxx-ref>), the parameter to <code>resource_adaptor</code> shall meet the following additional requirements:
      </p>
      <ul>
        <li><code>typename allocator_traits&lt;Allocator&gt;::pointer</code> shall be identical to <code>typename allocator_traits&lt;Allocator&gt;::value_type*</code>.</li>
        <li><code>typename allocator_traits&lt;Allocator&gt;::const_pointer</code> shall be identical to <code>typename allocator_traits&lt;Allocator&gt;::value_type const*</code>.</li>
        <li><code>typename allocator_traits&lt;Allocator&gt;::void_pointer</code> shall be identical to <code>void*</code>.</li>
        <li><code>typename allocator_traits&lt;Allocator&gt;::const_void_pointer</code> shall be identical to <code>void const*</code>.</li>
      </ul>

      <pre><code>
// The name <var>resource_adaptor_imp</var> is for exposition only.
template &lt;class Allocator&gt;
class <var>resource_adaptor_imp</var> : public memory_resource {
  // for exposition only
  Allocator m_alloc;

public:
  using allocator_type = Allocator;

  <var>resource_adaptor_imp</var>() = default;
  <var>resource_adaptor_imp</var>(const <var>resource_adaptor_imp</var>&amp;) = default;
  <var>resource_adaptor_imp</var>(<var>resource_adaptor_imp</var>&amp;&amp;) = default;

  explicit <var>resource_adaptor_imp</var>(const Allocator&amp; a2);
  explicit <var>resource_adaptor_imp</var>(Allocator&amp;&amp; a2);

  <var>resource_adaptor_imp</var>&amp; operator=(const <var>resource_adaptor_imp</var>&amp;) = default;

  allocator_type get_allocator() const { return m_alloc; }

protected:
  virtual void* do_allocate(size_t bytes, size_t alignment);
  virtual void do_deallocate(void* p, size_t bytes, size_t alignment);

  virtual bool do_is_equal(const memory_resource&amp; other) const noexcept;
};

template &lt;class Allocator&gt;
  using resource_adaptor = typename <var>resource_adaptor_imp</var>&lt;
    typename allocator_traits&lt;Allocator&gt;::template rebind_alloc&lt;char&gt;&gt;;</code></pre>
    
    </section>
  </cxx-section>

    <cxx-section id="memory.resource.adaptor.ctor">
    

    <section>
      <header><span class="section-number">5.5.2</span> <h1 data-bookmark-label="5.5.2 resource_adaptor_imp constructors"><code><var>resource_adaptor_imp</var></code> constructors</h1> <span style="float:right"><a href="#memory.resource.adaptor.ctor">[memory.resource.adaptor.ctor]</a></span></header>
      
      

      <cxx-function id="memory.resource.adaptor.ctor.1" para_num="1">
    
    <pre><code><cxx-signature>explicit <var>resource_adaptor_imp</var>(const Allocator&amp; a2);</cxx-signature></code></pre>

    <dl>
      
        
        <cxx-effects id="memory.resource.adaptor.ctor.2" para_num="2">
    
    <dt>Effects:</dt><dd>Initializes <code>m_alloc</code> with <code>a2</code>.</dd>
  </cxx-effects>
      
    </dl>
  </cxx-function>

      <cxx-function id="memory.resource.adaptor.ctor.3" para_num="3">
    
    <pre><code><cxx-signature>explicit <var>resource_adaptor_imp</var>(Allocator&amp;&amp; a2);</cxx-signature></code></pre>

    <dl>
      
        
        <cxx-effects id="memory.resource.adaptor.ctor.4" para_num="4">
    
    <dt>Effects:</dt><dd>Initializes <code>m_alloc</code> with <code>std::move(a2)</code>.</dd>
  </cxx-effects>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

    <cxx-section id="memory.resource.adaptor.mem">
    

    <section>
      <header><span class="section-number">5.5.3</span> <h1 data-bookmark-label="5.5.3 resource_adaptor_imp member functions"><code><var>resource_adaptor_imp</var></code> member functions</h1> <span style="float:right"><a href="#memory.resource.adaptor.mem">[memory.resource.adaptor.mem]</a></span></header>
      
      

      <cxx-function id="memory.resource.adaptor.mem.1" para_num="1">
    
    <pre><code><cxx-signature>void* do_allocate(size_t bytes, size_t alignment);</cxx-signature></code></pre>

    <dl>
      
        
        <cxx-returns id="memory.resource.adaptor.mem.2" para_num="2">
    
    <dt>Returns:</dt><dd>Allocated memory obtained by calling <code>m_alloc.allocate</code>.
          The size and alignment of the allocated memory shall meet the requirements
          for a class derived from <code>memory_resource</code> (<cxx-ref in="cxx" to="mem.res.class">C++20 <span title="mem.res.class">§20.12.2</span></cxx-ref>).</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="memory.resource.adaptor.mem.3" para_num="3">
    
    <pre><code><cxx-signature>void do_deallocate(void* p, size_t bytes, size_t alignment);</cxx-signature></code></pre>

    <dl>
      
        
        <cxx-preconditions id="memory.resource.adaptor.mem.4" para_num="4">
    
    <dt>Preconditions:</dt><dd><code>p</code> was previously allocated using <code>A.allocate</code>, where <code>A == m_alloc</code>, and not subsequently deallocated.</dd>
  </cxx-preconditions>
        <cxx-effects id="memory.resource.adaptor.mem.5" para_num="5">
    
    <dt>Effects:</dt><dd>Returns memory to the allocator using <code>m_alloc.deallocate()</code>.</dd>
  </cxx-effects>
      
    </dl>
  </cxx-function>

      <cxx-function id="memory.resource.adaptor.mem.6" para_num="6">
    
    <pre><code><cxx-signature>bool do_is_equal(const memory_resource&amp; other) const noexcept;</cxx-signature></code></pre>

    <dl>
      
        
        <p id="memory.resource.adaptor.mem.7" para_num="7">Let <code>p</code> be <code>dynamic_cast&lt;const <var>resource_adaptor_imp</var>*&gt;(&amp;other)</code>.</p>
        <cxx-returns id="memory.resource.adaptor.mem.8" para_num="8">
    
    <dt>Returns:</dt><dd><code>false</code> if <code>p</code> is null, otherwise the value of <code>m_alloc == p-&gt;m_alloc</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>
  
    </section>
  </cxx-section>

    </section>
  </cxx-clause>

<cxx-clause id="iterator">
    

    <section>
      <header><span class="section-number">6</span> <h1 data-bookmark-label="6 Iterators library">Iterators library</h1> <span style="float:right"><a href="#iterator">[iterator]</a></span></header>
      
  

  <cxx-section id="iterator.syn">
    

    <section>
      <header><span class="section-number">6.1</span> <h1 data-bookmark-label="6.1 Header <experimental/iterator> synopsis">Header <code>&lt;experimental/iterator&gt;</code> synopsis</h1> <span style="float:right"><a href="#iterator.syn">[iterator.syn]</a></span></header>
      
    

<pre><code>#include &lt;iterator&gt;

namespace std::experimental::inline fundamentals_v3 {

  <cxx-ref insynopsis="" to="iterator.ostream.joiner">// <i><a title="iterator.ostream.joiner" href="#iterator.ostream.joiner">6.2</a>, Class template ostream_joiner</i></cxx-ref>
  template &lt;class DelimT, class charT = char, class traits = char_traits&lt;charT&gt; &gt;
      class ostream_joiner;
  template &lt;class charT, class traits, class DelimT&gt;
    ostream_joiner&lt;decay_t&lt;DelimT&gt;, charT, traits&gt;
    make_ostream_joiner(basic_ostream&lt;charT, traits&gt;&amp; os, DelimT&amp;&amp; delimiter);

} // namespace std::experimental::inline fundamentals_v3</code></pre>
  
    </section>
  </cxx-section>

  <cxx-section id="iterator.ostream.joiner">
    

    <section>
      <header><span class="section-number">6.2</span> <h1 data-bookmark-label="6.2 Class template ostream_joiner">Class template <code>ostream_joiner</code></h1> <span style="float:right"><a href="#iterator.ostream.joiner">[iterator.ostream.joiner]</a></span></header>
      
    

    <cxx-section id="iterator.ostream.joiner.overview">
    

    <section>
      <header><span class="section-number">6.2.1</span> <h1 data-bookmark-label="6.2.1 Overview">Overview</h1> <span style="float:right"><a href="#iterator.ostream.joiner.overview">[iterator.ostream.joiner.overview]</a></span></header>
      
      

      <p id="iterator.ostream.joiner.overview.1" para_num="1">
        <code>ostream_joiner</code> writes (using <code>operator&lt;&lt;</code>) successive elements onto the output stream from which it was constructed.
        The delimiter that it was constructed with is written to the stream between every two <code>T</code>s that are written.
        It is not possible to get a value out of the output iterator.
        Its only use is as an output iterator in situations like
      </p>
      <pre><code>while (first != last)
  *result++ = *first++;</code></pre>

      <p id="iterator.ostream.joiner.overview.2" para_num="2">
        <code>ostream_joiner</code> is defined as
      </p>
      <pre><code>namespace std::experimental::inline fundamentals_v3 {

  template &lt;class DelimT, class charT = char, class traits = char_traits&lt;charT&gt; &gt;
  class ostream_joiner {
  public:
    using char_type = charT;
    using traits_type = traits;
    using ostream_type = basic_ostream&lt;charT, traits&gt;;
    using iterator_category = output_iterator_tag;
    using value_type = void;
    using difference_type = void;
    using pointer = void;
    using reference = void;

    ostream_joiner(ostream_type&amp; s, const DelimT&amp; delimiter);
    ostream_joiner(ostream_type&amp; s, DelimT&amp;&amp; delimiter);
    template&lt;typename T&gt;
    ostream_joiner&amp; operator=(const T&amp; value);
    ostream_joiner&amp; operator*() noexcept;
    ostream_joiner&amp; operator++() noexcept;
    ostream_joiner&amp; operator++(int) noexcept;

  private:
    ostream_type* out_stream; <i>// exposition only</i>
    DelimT delim;             <i>// exposition only</i>
    bool first_element;       <i>// exposition only</i>
  };

} // namespace std::experimental::inline fundamentals_v3</code></pre>
    
    </section>
  </cxx-section>

    <cxx-section id="iterator.ostream.joiner.cons">
    

    <section>
      <header><span class="section-number">6.2.2</span> <h1 data-bookmark-label="6.2.2 ostream_joiner constructor"><code>ostream_joiner</code> constructor</h1> <span style="float:right"><a href="#iterator.ostream.joiner.cons">[iterator.ostream.joiner.cons]</a></span></header>
      
      

      <cxx-function id="iterator.ostream.joiner.cons.1" para_num="1">
    
    <pre><code><cxx-signature>ostream_joiner(ostream_type&amp; s, const DelimT&amp; delimiter);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-effects id="iterator.ostream.joiner.cons.2" para_num="2">
    
    <dt>Effects:</dt><dd>
          Initializes <code>out_stream</code> with <code>std::addressof(s)</code>,
          <code>delim</code> with <code>delimiter</code>,
          and <code>first_element</code> with <code>true</code>.
        </dd>
  </cxx-effects>
      
    </dl>
  </cxx-function>

      <cxx-function id="iterator.ostream.joiner.cons.3" para_num="3">
    
    <pre><code><cxx-signature>ostream_joiner(ostream_type&amp; s, DelimT&amp;&amp; delimiter);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-effects id="iterator.ostream.joiner.cons.4" para_num="4">
    
    <dt>Effects:</dt><dd>
          Initializes <code>out_stream</code> with <code>std::addressof(s)</code>,
          <code>delim</code> with <code>move(delimiter)</code>,
          and <code>first_element</code> with <code>true</code>.
        </dd>
  </cxx-effects>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

    <cxx-section id="iterator.ostream.joiner.ops">
    

    <section>
      <header><span class="section-number">6.2.3</span> <h1 data-bookmark-label="6.2.3 ostream_joiner operations"><code>ostream_joiner</code> operations</h1> <span style="float:right"><a href="#iterator.ostream.joiner.ops">[iterator.ostream.joiner.ops]</a></span></header>
      
      

      <cxx-function id="iterator.ostream.joiner.ops.1" para_num="1">
    
    <pre><code><cxx-signature>template&lt;typename T&gt;
ostream_joiner&amp; operator=(const T&amp; value);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-effects id="iterator.ostream.joiner.ops.2" para_num="2">
    
    <dt>Effects:</dt><dd>
          <pre style="clear:left"><code>if (!first_element)
  *out_stream &lt;&lt; delim;
first_element = false;
*out_stream &lt;&lt; value;
return *this;</code></pre>
        </dd>
  </cxx-effects>
      
    </dl>
  </cxx-function>

      <cxx-function id="iterator.ostream.joiner.ops.3" para_num="3">
    
    <pre><code><cxx-signature>ostream_joiner&amp; operator*() noexcept;</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="iterator.ostream.joiner.ops.4" para_num="4">
    
    <dt>Returns:</dt><dd><code>*this</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="iterator.ostream.joiner.ops.5" para_num="5">
    
    <pre><code><cxx-signature>ostream_joiner&amp; operator++() noexcept;</cxx-signature><cxx-signature>ostream_joiner&amp; operator++(int) noexcept;</cxx-signature></code></pre>

    <dl>
      
        
        

        <cxx-returns id="iterator.ostream.joiner.ops.6" para_num="6">
    
    <dt>Returns:</dt><dd><code>*this</code>.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

    <cxx-section id="iterator.ostream.joiner.creation">
    

    <section>
      <header><span class="section-number">6.2.4</span> <h1 data-bookmark-label="6.2.4 ostream_joiner creation function"><code>ostream_joiner</code> creation function</h1> <span style="float:right"><a href="#iterator.ostream.joiner.creation">[iterator.ostream.joiner.creation]</a></span></header>
      
      

      <cxx-function id="iterator.ostream.joiner.creation.1" para_num="1">
    
    <pre><code><cxx-signature>template &lt;class charT, class traits, class DelimT&gt;
ostream_joiner&lt;decay_t&lt;DelimT&gt;, charT, traits&gt;
make_ostream_joiner(basic_ostream&lt;charT, traits&gt;&amp; os, DelimT&amp;&amp; delimiter);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="iterator.ostream.joiner.creation.2" para_num="2">
    
    <dt>Returns:</dt><dd><code>ostream_joiner&lt;decay_t&lt;DelimT&gt;, charT, traits&gt;(os, forward&lt;DelimT&gt;(delimiter));</code></dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>
  
    </section>
  </cxx-section>

    </section>
  </cxx-clause>

<cxx-clause id="futures">
    

    <section>
      <header><span class="section-number">7</span> <h1 data-bookmark-label="7 Futures">Futures</h1> <span style="float:right"><a href="#futures">[futures]</a></span></header>
      
  

  <cxx-section id="future.syn">
    

    <section>
      <header><span class="section-number">7.1</span> <h1 data-bookmark-label="7.1 Header <experimental/future> synopsis">Header &lt;experimental/future&gt; synopsis</h1> <span style="float:right"><a href="#future.syn">[future.syn]</a></span></header>
      
    

    <pre><code>#include &lt;future&gt;

namespace std {
  namespace experimental::inline fundamentals_v3 {

    template &lt;class R&gt; class promise;
    template &lt;class R&gt; class promise&lt;R&amp;&gt;;
    template &lt;&gt; class promise&lt;void&gt;;

    template &lt;class R&gt;
    void swap(promise&lt;R&gt;&amp; x, promise&lt;R&gt;&amp; y) noexcept;

    template &lt;class&gt; class packaged_task; // undefined
    template &lt;class R, class... ArgTypes&gt;
    class packaged_task&lt;R(ArgTypes...)&gt;;

    template &lt;class R, class... ArgTypes&gt;
    void swap(packaged_task&lt;R(ArgTypes...)&gt;&amp;, packaged_task&lt;R(ArgTypes...)&gt;&amp;) noexcept;

  } // namespace experimental::inline fundamentals_v3

  template &lt;class R, class Alloc&gt;
  struct uses_allocator&lt;experimental::promise&lt;R&gt;, Alloc&gt;;

  template &lt;class R, class Alloc&gt;
  struct uses_allocator&lt;experimental::packaged_task&lt;R&gt;, Alloc&gt;;

} // namespace std</code></pre>
  
    </section>
  </cxx-section>
  <cxx-section id="futures.promise">
    

    <section>
      <header><span class="section-number">7.2</span> <h1 data-bookmark-label="7.2 Class template promise">Class template <code>promise</code></h1> <span style="float:right"><a href="#futures.promise">[futures.promise]</a></span></header>
      
    

    <p id="futures.promise.1" para_num="1">
      The specification of all declarations within this subclause <cxx-ref to="futures.promise"><a title="futures.promise" href="#futures.promise">7.2</a></cxx-ref>
      are the same as the corresponding declarations,
      as specified in <cxx-ref in="cxx" to="futures.promise">C++20 <span title="futures.promise">§32.9.6</span></cxx-ref>,
      unless explicitly specified otherwise.
    </p>

    <pre><code>namespace std {
  namespace experimental::inline fundamentals_v3 {

    template &lt;class R&gt;
    class promise {
    public:
      using allocator_type = erased_type;

      promise();
      template &lt;class Allocator&gt;
      promise(allocator_arg_t, const Allocator&amp; a);
      promise(promise&amp;&amp; rhs) noexcept;
      promise(const promise&amp; rhs) = delete;
      ~promise();

      promise&amp; operator=(promise&amp;&amp; rhs) noexcept;
      promise&amp; operator=(const promise&amp; rhs) = delete;
      void swap(promise&amp; other) noexcept;

      future&lt;R&gt; get_future();

      void set_value(<em>see below</em>);
      void set_exception(exception_ptr p);

      void set_value_at_thread_exit(const R&amp; r);
      void set_value_at_thread_exit(<em>see below</em>);
      void set_exception_at_thread_exit(exception_ptr p);

      pmr::memory_resource* get_memory_resource() const noexcept;
    };

    template &lt;class R&gt;
    void swap(promise&lt;R&gt;&amp; x, promise&lt;R&gt;&amp; y) noexcept;

  } // namespace experimental::inline fundamentals_v3

  template &lt;class R, class Alloc&gt;
  struct uses_allocator&lt;experimental::promise&lt;R&gt;, Alloc&gt;;

} // namespace std</code></pre>

    <p id="futures.promise.2" para_num="2">
      When a <code>promise</code> constructor that takes a first argument of type <code>allocator_arg_t</code> is invoked,
      the second argument is treated as a type-erased allocator (<cxx-ref to="memory.type.erased.allocator"><a title="memory.type.erased.allocator" href="#memory.type.erased.allocator">5.3</a></cxx-ref>).
    </p>
  
    </section>
  </cxx-section>

  <cxx-section id="futures.task">
    

    <section>
      <header><span class="section-number">7.3</span> <h1 data-bookmark-label="7.3 Class template packaged_task">Class template <code>packaged_task</code></h1> <span style="float:right"><a href="#futures.task">[futures.task]</a></span></header>
      
    

    <p id="futures.task.1" para_num="1">
      The specification of all declarations within this subclause <cxx-ref to="futures.task"><a title="futures.task" href="#futures.task">7.3</a></cxx-ref>
      are the same as the corresponding declarations,
      as specified in <cxx-ref in="cxx" to="futures.task">C++20 <span title="futures.task">§32.9.10</span></cxx-ref>,
      unless explicitly specified otherwise.
    </p>

    <pre><code>namespace std {
  namespace experimental::inline fundamentals_v3 {

    template &lt;class R, class... ArgTypes&gt;
    class packaged_task&lt;R(ArgTypes...)&gt; {
    public:
      using allocator_type = erased_type;

      packaged_task() noexcept;
      template &lt;class F&gt;
      explicit packaged_task(F&amp;&amp; f);
      template &lt;class F, class Allocator&gt;
      explicit packaged_task(allocator_arg_t, const Allocator&amp; a, F&amp;&amp; f);
      ~packaged_task();

      packaged_task(const packaged_task&amp;) = delete;
      packaged_task&amp; operator=(const packaged_task&amp;) = delete;

      packaged_task(packaged_task&amp;&amp; rhs) noexcept;
      packaged_task&amp; operator=(packaged_task&amp;&amp; rhs) noexcept;
      void swap(packaged_task&amp; other) noexcept;

      bool valid() const noexcept;

      future&lt;R&gt; get_future();

      void operator()(ArgTypes... );
      void make_ready_at_thread_exit(ArgTypes...);

      void reset();

      pmr::memory_resource* get_memory_resource() const noexcept;
    };

    template &lt;class R, class... ArgTypes&gt;
    void swap(packaged_task&lt;R(ArgTypes...)&gt;&amp;, packaged_task&lt;R(ArgTypes...)&gt;&amp;) noexcept;

  } // namespace experimental::inline fundamentals_v3

  template &lt;class R, class Alloc&gt;
  struct uses_allocator&lt;experimental::packaged_task&lt;R&gt;, Alloc&gt;;

} // namespace std</code></pre>

    <p id="futures.task.2" para_num="2">
      When a <code>packaged_task</code> constructor that takes a first argument of type <code>allocator_arg_t</code> is invoked,
      the second argument is treated as a type-erased allocator (<cxx-ref to="memory.type.erased.allocator"><a title="memory.type.erased.allocator" href="#memory.type.erased.allocator">5.3</a></cxx-ref>).
    </p>
  
    </section>
  </cxx-section>

    </section>
  </cxx-clause>

<cxx-clause id="algorithms">
    

    <section>
      <header><span class="section-number">8</span> <h1 data-bookmark-label="8 Algorithms library">Algorithms library</h1> <span style="float:right"><a href="#algorithms">[algorithms]</a></span></header>
      
  

  <cxx-section id="algorithm.syn">
    

    <section>
      <header><span class="section-number">8.1</span> <h1 data-bookmark-label="8.1 Header <experimental/algorithm> synopsis">Header <code>&lt;experimental/algorithm&gt;</code> synopsis</h1> <span style="float:right"><a href="#algorithm.syn">[algorithm.syn]</a></span></header>
      
    

<pre><code>#include &lt;algorithm&gt;

namespace std::experimental::inline fundamentals_v3 {

  <cxx-ref insynopsis="" to="alg.random.sample">// <i><a title="alg.random.sample" href="#alg.random.sample">8.2</a>, Sampling</i></cxx-ref>
  template&lt;class PopulationIterator, class SampleIterator, class Distance&gt;
  SampleIterator sample(PopulationIterator first, PopulationIterator last,
                        SampleIterator out, Distance n);

  <cxx-ref insynopsis="" to="alg.random.shuffle">// <i><a title="alg.random.shuffle" href="#alg.random.shuffle">8.3</a>, Shuffle</i></cxx-ref>
  template&lt;class RandomAccessIterator&gt;
  void shuffle(RandomAccessIterator first, RandomAccessIterator last);

} // namespace std::experimental::inline fundamentals_v3</code></pre>

  
    </section>
  </cxx-section>

  <cxx-section id="alg.random.sample">
    

    <section>
      <header><span class="section-number">8.2</span> <h1 data-bookmark-label="8.2 Sampling">Sampling</h1> <span style="float:right"><a href="#alg.random.sample">[alg.random.sample]</a></span></header>
      
    

    <cxx-function id="alg.random.sample.1" para_num="1">
    
    <pre><code><cxx-signature class="formatted">template&lt;class PopulationIterator, class SampleIterator, class Distance&gt;
SampleIterator sample(PopulationIterator first, PopulationIterator last,
                      SampleIterator out, Distance n);</cxx-signature></code></pre>

    <dl>
      
      
      <cxx-effects id="alg.random.sample.2" para_num="2">
    
    <dt>Effects:</dt><dd>
        Equivalent to:
        <pre><code>return ::std::sample(first, last, out, n, g);</code></pre>
        where <code>g</code> denotes
        the per-thread engine (<cxx-ref to="rand.util.randint"><a title="rand.util.randint" href="#rand.util.randint"></a></cxx-ref>).
        To the extent that the implementation of this function makes use of
        random numbers, the object <code>g</code> serves as the
        implementation’s source of randomness.
      </dd>
  </cxx-effects>
    
    </dl>
  </cxx-function>
  
    </section>
  </cxx-section>

  <cxx-section id="alg.random.shuffle">
    

    <section>
      <header><span class="section-number">8.3</span> <h1 data-bookmark-label="8.3 Shuffle">Shuffle</h1> <span style="float:right"><a href="#alg.random.shuffle">[alg.random.shuffle]</a></span></header>
      
    
    <cxx-function id="alg.random.shuffle.1" para_num="1">
    
    <pre><code><cxx-signature>template&lt;class RandomAccessIterator&gt;
  void shuffle(RandomAccessIterator first, RandomAccessIterator last);</cxx-signature></code></pre>

    <dl>
      
      
      <cxx-preconditions id="alg.random.shuffle.2" para_num="2">
    
    <dt>Preconditions:</dt><dd><code>RandomAccessIterator</code> meets the
        <cxx-17concept><i>Cpp17ValueSwappable</i></cxx-17concept> requirements (<cxx-ref in="cxx" to="swappable.requirements">C++20 <span title="swappable.requirements">§16.5.3.2</span></cxx-ref>).
      </dd>
  </cxx-preconditions>
      <cxx-effects id="alg.random.shuffle.3" para_num="3">
    
    <dt>Effects:</dt><dd>Permutes the elements in the range <code>[first,last)</code>
        such that each possible permutation of those elements has equal
        probability of appearance.</dd>
  </cxx-effects>
      <cxx-complexity id="alg.random.shuffle.4" para_num="4">
    
    <dt>Complexity:</dt><dd>Exactly <code>(last - first) - 1</code> swaps.</dd>
  </cxx-complexity>
      <cxx-remarks id="alg.random.shuffle.5" para_num="5">
    
    <dt>Remarks:</dt><dd>To the extent that the implementation of this function
        makes use of random numbers, the per-thread engine (<cxx-ref to="rand.randint"><a title="rand.randint" href="#rand.randint">9.1.2</a></cxx-ref>)
        serves as the implementation's source of randomness.
      </dd>
  </cxx-remarks>
    
    </dl>
  </cxx-function>
  
    </section>
  </cxx-section>

    </section>
  </cxx-clause>

<cxx-clause id="numeric">
    

    <section>
      <header><span class="section-number">9</span> <h1 data-bookmark-label="9 Numerics library">Numerics library</h1> <span style="float:right"><a href="#numeric">[numeric]</a></span></header>
      
  

  <cxx-section id="rand">
    

    <section>
      <header><span class="section-number">9.1</span> <h1 data-bookmark-label="9.1 Random number generation">Random number generation</h1> <span style="float:right"><a href="#rand">[rand]</a></span></header>
      
    
    <cxx-section id="rand.syn">
    

    <section>
      <header><span class="section-number">9.1.1</span> <h1 data-bookmark-label="9.1.1 Header <experimental/random> synopsis">Header <code>&lt;experimental/random&gt;</code> synopsis</h1> <span style="float:right"><a href="#rand.syn">[rand.syn]</a></span></header>
      
      
      <pre><code>#include &lt;random&gt;

namespace std::experimental::inline fundamentals_v3 {

  <cxx-ref insynopsis="" to="rand.randint">// <i><a title="rand.randint" href="#rand.randint">9.1.2</a>, Function template randint</i></cxx-ref>
  template &lt;class IntType&gt;
  IntType randint(IntType a, IntType b);
  void reseed();
  void reseed(default_random_engine::result_type value);

} // namespace std::experimental::inline fundamentals_v3</code></pre>
    
    </section>
  </cxx-section>
    <cxx-section id="rand.randint">
    

    <section>
      <header><span class="section-number">9.1.2</span> <h1 data-bookmark-label="9.1.2 Function template randint">Function template <code>randint</code></h1> <span style="float:right"><a href="#rand.randint">[rand.randint]</a></span></header>
      
      
      <p id="rand.randint.1" para_num="1">A separate <dfn>per-thread engine</dfn> of type <code>default_random_engine</code>
        (<cxx-ref in="cxx" to="rand.predef">C++20 <span title="rand.predef">§26.6.5</span></cxx-ref>), initialized to an
        unpredictable state, shall be maintained for each thread.</p>
      <cxx-function id="rand.randint.2" para_num="2">
    
    <pre><code><cxx-signature>template&lt;class IntType&gt;
IntType randint(IntType a, IntType b);</cxx-signature></code></pre>

    <dl>
      
        
        <cxx-mandates id="rand.randint.3" para_num="3">
    
    <dt>Mandates:</dt><dd>
          The template argument meets the requirements for a template parameter named
          <code>IntType</code> in <cxx-ref in="cxx" to="rand.req.genl">C++20 <span title="rand.req.genl">§26.6.2.1</span></cxx-ref>.
        </dd>
  </cxx-mandates>
        <cxx-preconditions id="rand.randint.4" para_num="4">
    
    <dt>Preconditions:</dt><dd><code>a</code> ≤ <code>b</code>.</dd>
  </cxx-preconditions>
        <cxx-returns id="rand.randint.5" para_num="5">
    
    <dt>Returns:</dt><dd>A random integer <var>i</var>, <code>a</code> ≤ <var>i</var> ≤ <code>b</code>,
          produced from a thread-local instance of <code>uniform_int_distribution&lt;IntType&gt;</code>
          (<cxx-ref in="cxx" to="rand.dist.uni.int">C++20 <span title="rand.dist.uni.int">§26.6.8.2.1</span></cxx-ref>) invoked with the
          per-thread engine.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>
      <cxx-function id="rand.randint.6" para_num="6">
    
    <pre><code><cxx-signature>void reseed();</cxx-signature><cxx-signature>void reseed(default_random_engine::result_type value);</cxx-signature></code></pre>

    <dl>
      
        
        
        <cxx-effects id="rand.randint.7" para_num="7">
    
    <dt>Effects:</dt><dd>Let <code>g</code> be the per-thread engine. The first
          form sets <code>g</code> to an unpredictable state. The second form
          invokes <code>g.seed(value)</code>.</dd>
  </cxx-effects>
        <cxx-postconditions id="rand.randint.8" para_num="8">
    
    <dt>Postconditions:</dt><dd>Subsequent calls to <code>randint</code> do not
          depend on values produced by <code>g</code> before calling <code>reseed</code>.
          <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    <code>reseed</code> also resets any instances of <code>uniform_int_distribution</code>
            used by <code>randint</code>.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note></dd>
  </cxx-postconditions>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>
  
    </section>
  </cxx-section>

    </section>
  </cxx-clause>





</body></html>