<!DOCTYPE html>
<!-- Sources at https://github.com/cplusplus/fundamentals-ts -->
<html lang="en"><head><meta charset="utf-8">

<!--[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-EFFECTS");document.createElement("CXX-RETURNS");document.createElement("CXX-REQUIRES");document.createElement("CXX-TERM");document.createElement("W-BR");document.createElement("CXX-EDNOTE");document.createElement("CXX-POSTCONDITIONS");document.createElement("CXX-THROWS");document.createElement("CXX-COMPLEXITY");document.createElement("CXX-GRAMMARTERM");document.createElement("CXX-PUBLISH-BUTTON");</script><![endif]-->

<style>
  p {text-align:justify}
  li {text-align:justify}
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
</style>

<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; page-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-requires {
	display: block; margin-top: 0.5em; margin-bottom: 0.5em;
}

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

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

cxx-requires dd > ul, cxx-requires 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; page-break-inside: avoid; page-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; page-break-inside: avoid; page-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 {
	page-break-before: always; page-break-after: always; 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 {
	page-break-before: always; page-break-after: always; 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>

  <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>Adopt Consistent Container Erasure from Library Fundamentals 2 for C++20</title>
</head>

<body>

<table>
<tr>
  <td align="left">Doc. no.</td>
  <td align="left">P1209R0</td>
</tr>
<tr>
  <td align="left">Date:</td>
  <td align="left">2018-10-04</td>
</tr>
<tr>
  <td align="left">Project:</td>
  <td align="left">Programming Language C++</td>
</tr>
<tr>
  <td align="left">Reply to:</td>
  <td align="left">Alisdair Meredith &lt;<a href="mailto:ameredith1@bloomberg.net">ameredith1@bloomberg.net</a>&gt;</td>
</tr>
<tr>
  <td align="left"></td>
  <td align="left">Stephan T. Lavavej &lt;<a href="mailto:stl@microsoft.com">stl@microsoft.com</a>&gt;</td>
</tr>
<tr>
  <td align="left">Audience:</td>
  <td align="left">Library Evolution</td>
</tr>
</table>

<h1>Adopt Consistent Container Erasure from Library Fundamentals 2 for C++20</h1>

<h2><a name="0.0">Revision History</a></h2>

<h3><a name="0.1">Revision 0</a></h3>
<p>
Original version of the paper for the 2018 pre-San Diego mailing.
</p>

<h2>Table of Contents</h2>
<ol start="0">
<li><a href="#0.0">Revision History</a>
  <ul>
  <li><a href="#0.1">Revision 0</a></li>
  </ul></li>
<li><a href="#1.0">Introduction</a></li>
<li><a href="#2.0">Problems to be addressed</a></li>
<li><a href="#3.0">Proposed Resolution</a>
  <ul>
  <li><a href="#3.1">Annotated Original Wording</a></li>
  </ul></li>
<li><a href="#4.0">Alternatives Considered</a></li>
<li><a href="#5.0">Implementation Experience</a></li>
<li><a href="#6.0">Formal Wording</a></li>
<li><a href="#7.0">Acknowledgements</a></li>
<li><a href="#8.0">References</a></li>
</ol>


<h2><a name="1.0">1. Introduction</a></h2>
<p>
This paper proposes landing the consistent container erasure APIs from the
Library Fundamentals v2 TS into C++20.
</p>


<h2><a name="2.0">2. Problems to be addressed</a></h2>
<p>
Erasing members of a container that satisfy some condition seems like it would
be an easy problem to solve, yet it contains many subtle traps for the careless
and unwary.  The simplest correct pattern involves walking the container, and
<i>either</i> erasing an element to produce the next iterator <i>or</i>
incrementing the current iterator to advance to the next element.  This simple
code yields errors far too often, while providing poor performance on popular
sequence containers.  The appropriate pattern for those sequence containers is
quite different, applying the standard algorithm <tt>remove_if</tt> before
calling the member <tt>erase</tt> to prune the tail of the sequence.  However,
this method is not the most appropriate choice (or even applicable) for other
containers.
</p>

<p>
A more extensive rationale for why this problem was deemed worth solving for
the Fundamentals TS can be found in the paper
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4009">N4009</a>.
</p>


<h2><a name="3.0">3. Proposed Resolution</a></h2>
<p>
The proposal is to land the wording from the Library Fundamentals TS directly.
This is slightly tweaked, as the wording in the Fundamentals TS is mostly
editorial guidance, so the words cannot be transcribed precisely as laid out in
the TS.  Instead, we apply that editorial guidance to the current working
paper; see the <a href="#6.0">Formal Wording</a> below.
</p>


<h3><a name="3.1">3.1 Annotated Original Wording</a></h3>
<p>
Below is the latest wording from the Fundamentals TS (v3) for this feature,
marked up with diff-marks that correspond to the edits made while moving this
wording directly into the affected standard clauses.  The <del>strikeout</del>
markup indicates wording that is dropped as part of the transition of landing
this proposal into the main standard.  Mostly it refers to removing the
<tt>experimental</tt> headers and namespace, but also some commentary does not
make the transition.
</p>

<p>
Not marked up is the renaming of template parameters to match the naming
convention in the corresponding standard clause.  One final tiny tweak, that is
not marked up, is that <tt>erase</tt> will now precede <tt>erase_if</tt> in the
formal wording, even in the case that <tt>erase</tt> is specified in terms of
<tt>erase_if</tt>.  This follows existing library precedent that the 'simpler'
identifier goes first.
</p>

<p>
Also not marked up is the addition of a feature-test macro (present in the <a href="#6.0">Formal Wording</a> below).
</p>

<blockquote class="note">
<cxx-clause id="container">


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



  <cxx-section id="container.erasure">


    <section>
      <header><span class="section-number"><del>6.1</del></span> <h1 data-bookmark-label="6.1 Uniform container erasure"><del>Uniform container erasure</del></h1> <span style="float:right"><a href="#container.erasure"><del>[container.erasure]</del></a></span></header>



    <cxx-section id="container.erasure.syn">


    <section>
      <header><span class="section-number">6.1.1</span> <h1 data-bookmark-label="6.1.1 Header synopsis">Header synopsis</h1> <span style="float:right"><a href="#container.erasure.syn">[container.erasure.syn]</a></span></header>



      <p id="container.erasure.syn.1" para_num="1"><del>
        For brevity, this section specifies the contents of 9 headers,
        each of which behaves as described by <cxx-ref to="general.namespaces"><a title="general.namespaces" href="#general.namespaces">1.3</a></cxx-ref>.
      </del></p>

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

  <del><cxx-ref insynopsis="" to="container.erasure.erase_if">// <i><a title="container.erasure.erase_if" href="#container.erasure.erase_if">6.1.2</a>, Function template erase_if</i></cxx-ref></del>
  <del><cxx-ref insynopsis="" to="container.erasure.erase">// <i><a title="container.erasure.erase" href="#container.erasure.erase">6.1.3</a>, Function template erase</i></cxx-ref></del>

  // &lt;<del>experimental/</del>string&gt;
  template &lt;class charT, class traits, class A, class Predicate&gt;
    void erase_if(basic_string&lt;charT, traits, A&gt;&amp; c, Predicate pred);
  template &lt;class charT, class traits, class A, class U&gt;
    void erase(basic_string&lt;charT, traits, A&gt;&amp; c, const U&amp; value);

  // &lt;<del>experimental/</del>deque&gt;
  template &lt;class T, class A, class Predicate&gt;
    void erase_if(deque&lt;T, A&gt;&amp; c, Predicate pred);
  template &lt;class T, class A, class U&gt;
    void erase(deque&lt;T, A&gt;&amp; c, const U&amp; value);

  // &lt;<del>experimental/</del>vector&gt;
  template &lt;class T, class A, class Predicate&gt;
    void erase_if(vector&lt;T, A&gt;&amp; c, Predicate pred);
  template &lt;class T, class A, class U&gt;
    void erase(vector&lt;T, A&gt;&amp; c, const U&amp; value);

  // &lt;<del>experimental/</del>forward_list&gt;
  template &lt;class T, class A, class Predicate&gt;
    void erase_if(forward_list&lt;T, A&gt;&amp; c, Predicate pred);
  template &lt;class T, class A, class U&gt;
    void erase(forward_list&lt;T, A&gt;&amp; c, const U&amp; value);

  // &lt;<del>experimental/</del>list&gt;
  template &lt;class T, class A, class Predicate&gt;
    void erase_if(list&lt;T, A&gt;&amp; c, Predicate pred);
  template &lt;class T, class A, class U&gt;
    void erase(list&lt;T, A&gt;&amp; c, const U&amp; value);

  // &lt;<del>experimental/</del>map&gt;
  template &lt;class K, class T, class C, class A, class Predicate&gt;
    void erase_if(map&lt;K, T, C, A&gt;&amp; c, Predicate pred);
  template &lt;class K, class T, class C, class A, class Predicate&gt;
    void erase_if(multimap&lt;K, T, C, A&gt;&amp; c, Predicate pred);

  // &lt;<del>experimental/</del>set&gt;
  template &lt;class K, class C, class A, class Predicate&gt;
    void erase_if(set&lt;K, C, A&gt;&amp; c, Predicate pred);
  template &lt;class K, class C, class A, class Predicate&gt;
    void erase_if(multiset&lt;K, C, A&gt;&amp; c, Predicate pred);

  // &lt;<del>experimental/</del>unordered_map&gt;
  template &lt;class K, class T, class H, class P, class A, class Predicate&gt;
    void erase_if(unordered_map&lt;K, T, H, P, A&gt;&amp; c, Predicate pred);
  template &lt;class K, class T, class H, class P, class A, class Predicate&gt;
    void erase_if(unordered_multimap&lt;K, T, H, P, A&gt;&amp; c, Predicate pred);

  // &lt;<del>experimental/</del>unordered_set&gt;
  template &lt;class K, class H, class P, class A, class Predicate&gt;
    void erase_if(unordered_set&lt;K, H, P, A&gt;&amp; c, Predicate pred);
  template &lt;class K, class H, class P, class A, class Predicate&gt;
    void erase_if(unordered_multiset&lt;K, H, P, A&gt;&amp; c, Predicate pred);

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

    </section>
  </cxx-section>

    <cxx-section id="container.erasure.erase_if">


    <section>
      <header><span class="section-number">6.1.2</span> <h1 data-bookmark-label="6.1.2 Function template erase_if">Function template <code>erase_if</code></h1> <span style="float:right"><a href="#container.erasure.erase_if">[container.erasure.erase_if]</a></span></header>



      <cxx-function id="container.erasure.erase_if.1" para_num="1">

    <pre><code><cxx-signature>template &lt;class charT, class traits, class A, class Predicate&gt;
void erase_if(basic_string&lt;charT, traits, A&gt;&amp; c, Predicate pred);</cxx-signature><cxx-signature>template &lt;class T, class A, class Predicate&gt;
void erase_if(deque&lt;T, A&gt;&amp; c, Predicate pred);</cxx-signature><cxx-signature>template &lt;class T, class A, class Predicate&gt;
void erase_if(vector&lt;T, A&gt;&amp; c, Predicate pred);</cxx-signature></code></pre>

    <dl>
        <cxx-effects id="container.erasure.erase_if.2" para_num="2">

    <dt>Effects:</dt><dd>Equivalent to: <code>c.erase(remove_if(c.begin(), c.end(), pred), c.end());</code></dd>
  </cxx-effects>

    </dl>
  </cxx-function>

      <cxx-function id="container.erasure.erase_if.3" para_num="3">

    <pre><code><cxx-signature>template &lt;class T, class A, class Predicate&gt;
void erase_if(forward_list&lt;T, A&gt;&amp; c, Predicate pred);</cxx-signature><cxx-signature>template &lt;class T, class A, class Predicate&gt;
void erase_if(list&lt;T, A&gt;&amp; c, Predicate pred);</cxx-signature></code></pre>

    <dl>
        <cxx-effects id="container.erasure.erase_if.4" para_num="4">

    <dt>Effects:</dt><dd>Equivalent to: <code>c.remove_if(pred);</code></dd>
  </cxx-effects>

    </dl>
  </cxx-function>

      <cxx-function id="container.erasure.erase_if.5" para_num="5">

    <pre><code><cxx-signature>template &lt;class K, class T, class C, class A, class Predicate&gt;
void erase_if(map&lt;K, T, C, A&gt;&amp; c, Predicate pred);</cxx-signature><cxx-signature>template &lt;class K, class T, class C, class A, class Predicate&gt;
void erase_if(multimap&lt;K, T, C, A&gt;&amp; c, Predicate pred);</cxx-signature><cxx-signature>template &lt;class K, class C, class A, class Predicate&gt;
void erase_if(set&lt;K, C, A&gt;&amp; c, Predicate pred);</cxx-signature><cxx-signature>template &lt;class K, class C, class A, class Predicate&gt;
void erase_if(multiset&lt;K, C, A&gt;&amp; c, Predicate pred);</cxx-signature><cxx-signature>template &lt;class K, class T, class H, class P, class A, class Predicate&gt;
void erase_if(unordered_map&lt;K, T, H, P, A&gt;&amp; c, Predicate pred);</cxx-signature><cxx-signature>template &lt;class K, class T, class H, class P, class A, class Predicate&gt;
void erase_if(unordered_multimap&lt;K, T, H, P, A&gt;&amp; c, Predicate pred);</cxx-signature><cxx-signature>template &lt;class K, class H, class P, class A, class Predicate&gt;
void erase_if(unordered_set&lt;K, H, P, A&gt;&amp; c, Predicate pred);</cxx-signature><cxx-signature>template &lt;class K, class H, class P, class A, class Predicate&gt;
void erase_if(unordered_multiset&lt;K, H, P, A&gt;&amp; c, Predicate pred);</cxx-signature></code></pre>

    <dl>
        <cxx-effects id="container.erasure.erase_if.6" para_num="6">

    <dt>Effects:</dt><dd>Equivalent to:
<pre><code>for (auto i = c.begin(), last = c.end(); i != last; ) {
  if (pred(*i)) {
    i = c.erase(i);
  } else {
    ++i;
  }
}</code></pre></dd>
  </cxx-effects>

    </dl>
  </cxx-function>

    </section>
  </cxx-section>

    <cxx-section id="container.erasure.erase">


    <section>
      <header><span class="section-number">6.1.3</span> <h1 data-bookmark-label="6.1.3 Function template erase">Function template erase</h1> <span style="float:right"><a href="#container.erasure.erase">[container.erasure.erase]</a></span></header>



      <cxx-function id="container.erasure.erase.1" para_num="1">

    <pre><code><cxx-signature>template &lt;class charT, class traits, class A, class U&gt;
void erase(basic_string&lt;charT, traits, A&gt;&amp; c, const U&amp; value);</cxx-signature><cxx-signature>template &lt;class T, class A, class U&gt;
void erase(deque&lt;T, A&gt;&amp; c, const U&amp; value);</cxx-signature><cxx-signature>template &lt;class T, class A, class U&gt;
void erase(vector&lt;T, A&gt;&amp; c, const U&amp; value);</cxx-signature></code></pre>

    <dl>
        <cxx-effects id="container.erasure.erase.2" para_num="2">

    <dt>Effects:</dt><dd>Equivalent to: <code>c.erase(remove(c.begin(), c.end(), value), c.end());</code></dd>
  </cxx-effects>

    </dl>
  </cxx-function>

      <cxx-function id="container.erasure.erase.3" para_num="3">

    <pre><code><cxx-signature>template &lt;class T, class A, class U&gt;
void erase(forward_list&lt;T, A&gt;&amp; c, const U&amp; value);</cxx-signature><cxx-signature>template &lt;class T, class A, class U&gt;
void erase(list&lt;T, A&gt;&amp; c, const U&amp; value);</cxx-signature></code></pre>

    <dl>
        <cxx-effects id="container.erasure.erase.4" para_num="4">

    <dt>Effects:</dt><dd>Equivalent to: <code>erase_if(c, [&amp;](auto&amp; elem) { return elem == value; });</code></dd>
  </cxx-effects>

    </dl>
  </cxx-function>

  <cxx-note><del><span class="nowrap">[ <em>Note:</em></span>

        Overloads of <code>erase()</code> for associative containers and unordered associative containers are intentionally not provided.

    <span class="nowrap">— <em>end note</em> ]</span>
  </del></cxx-note>

    </section>
  </cxx-section>

    </section>
  </cxx-section>

    </section>
  </cxx-clause>
</blockquote>


<h2><a name="4.0">4. Alternatives Considered</a></h2>
<p>
A couple of design points were considered and rejected for this proposal.
</p>

<p>
The first idea is that these operations should be member functions, rather
than free functions.  This is rejected as we desire a level of uniformity
of interface that would not be cleanly expressed in the container requirements
tables, which are the closest notion of a container concept that we have.
<tt>std::array</tt> would be a sequence container not supporting these
operations, adding yet more special cases to a taxed special case.  The
requirements would need to be at the top of the hierarchy, under Container
Requirements, or we end up repeating them for Sequence, Associative, and
Unordered Associative Container Requirements, and the interface itself is
not particularly simpler, while a free function extends and adapts user
supplied containers more easily. Additionally, <tt>erase</tt> is already
heavily overloaded as a member function; it would be confusing to further
overload <tt>c.erase(position)</tt>, <tt>c.erase(first, last)</tt>, and
<tt>assoc.erase(key)</tt>. Finally, these operations gain nothing
from private access to the container, being expressible entirely through
the public API with no loss of efficiency, so we prefer a coupling no
stronger than is necessary.
</p>

<p>
The second idea is that these operations are acting on a range, and might
more properly belong as part of the Ranges library proposal.  That notion
is rejected as these are more properly Container operations, that rely on
container ownership semantics, and control the lifetime of elements and
size on containers in ways that are inappropriate for the ranges library.
</p>


<h2><a name="5.0">5. Implementation Experience</a></h2>
<p>
N4273 was implemented in VS 2015 RTM and GCC 6.1.
</p>



<h2><a name="6.0">6. Formal Wording</a></h2>
<p>
This paper applies edits against
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/n4762.pdf">N4762</a>.
</p>



<cxx-clause id="language.support">
    <section>
      <header><span class="section-number">16</span> <h1 data-bookmark-label="16 Language support">Language support library</h1> <span style="float:right"><a href="#language.support">[language.support]</a></span></header>

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

<table>
  <tr>
    <td><b>Macro name</b></td>
    <td><b>Value</b></td>
    <td><b>Header(s)</b></td>
  </tr>
  <tr>
    <td> ... </td>
    <td> ... </td>
    <td> ... </td>
  </tr>
  <tr>
    <td>__cpp_lib_enable_shared_from_this</td>
    <td>201603L</td>
    <td>&lt;memory&gt;</td>
  </tr>

  <tr>
    <td><ins>__cpp_lib_erase_if</ins></td>
    <td><ins>201811L</ins></td>
    <td><ins>&lt;string&gt; &lt;deque&gt; &lt;forward_list&gt; &lt;list&gt; &lt;vector&gt; &lt;map&gt; &lt;set&gt;
        &lt;unordered_map&gt; &lt;unordered_set&gt;</ins>
    </td>
  </tr>

  <tr>
    <td>__cpp_lib_exchange_function</td>
    <td>201304L</td>
    <td>&lt;utility&gt;</td>
  </tr>
  <tr>
    <td> ... </td>
    <td> ... </td>
    <td> ... </td>
  </tr>
</table>

    </section>
  </cxx-section>

    </section>
</cxx-clause>



<cxx-clause id="strings">

    <section>
      <header><span class="section-number">20</span> <h1 data-bookmark-label="20 Strings">Strings Library</h1> <span style="float:right"><a href="#strings">[strings]</a></span></header>

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

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

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

namespace std {

  // 20.2, character traits
  template&lt;class charT&gt; struct char_traits;
  template&lt;&gt; struct char_traits&lt;char&gt;;
  template&lt;&gt; struct char_traits&lt;char16_t&gt;;
  template&lt;&gt; struct char_traits&lt;char32_t&gt;;
  template&lt;&gt; struct char_traits&lt;wchar_t&gt;;

  // 20.3.2, basic_string
  template&lt;class charT, class traits = char_traits&lt;charT&gt;, class Allocator = allocator&lt;charT&gt;&gt;
    class basic_string;

...

  // 20.3.3.9, inserters and extractors
  ...
  template&lt;class charT, class traits, class Allocator&gt;
  basic_istream&lt;charT, traits&gt;&amp;
    getline(basic_istream&lt;charT, traits&gt;&amp;&amp; is,
            basic_string&lt;charT, traits, Allocator&gt;&amp; str);


  <ins>// 20.3.3.X, string erasure</ins>
  <ins>template&lt;class charT, class traits, class Allocator, class U&gt;</ins>
    <ins>void erase(basic_string&lt;charT, traits, Allocator&gt;&amp; c, const U&amp; value);</ins>
  <ins>template&lt;class charT, class traits, class Allocator, class Predicate&gt;</ins>
    <ins>void erase_if(basic_string&lt;charT, traits, Allocator&gt;&amp; c, Predicate pred);</ins>


  // basic_string typedef names
  using string = basic_string&lt;char&gt;;
  using u16string = basic_string&lt;char16_t&gt;;
  using u32string = basic_string&lt;char32_t&gt;;
  using wstring = basic_string&lt;wchar_t&gt;;

  // 20.3.4, numeric conversions
  ...

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

    </section>
  </cxx-section>


    <cxx-section id="string.erasure"><ins>


    <section>
      <header><span class="section-number">20.3.3.X</span> <h1 data-bookmark-label="20.3.3.X String Erasure">String Erasure</h1> <span style="float:right"><a href="#string.erasure">[string.erasure]</a></span></header>

  <cxx-function id="string.erasure">

<pre><code><cxx-signature>template &lt;class charT, class traits, class Allocator, class U&gt;
void erase(basic_string&lt;charT, traits, Allocator&gt;&amp; c, const U&amp; value);</cxx-signature></code></pre>

    <dl>
    <cxx-effects id="string.erasure.1" para_num="1">
      <dt>Effects:</dt> <dd>Equivalent to: <code>c.erase(remove(c.begin(), c.end(), value), c.end());</code></dd>
    </cxx-effects>
    </dl>

  </cxx-function>

   <cxx-function id="string.erasure">

<pre><code><cxx-signature>template &lt;class charT, class traits, class Allocator, class Predicate&gt;
void erase_if(basic_string&lt;charT, traits, Allocator&gt;&amp; c, Predicate pred);</cxx-signature>
</code></pre>

    <dl>
    <cxx-effects id="string.erasure.2" para_num="2">
      <dt>Effects:</dt><dd>Equivalent to: <code>c.erase(remove_if(c.begin(), c.end(), pred), c.end());</code></dd>
    </cxx-effects>

    </dl>

  </cxx-function>

    </section>
  </ins></cxx-section>

    </section>


</cxx-clause>



<cxx-clause id="containers">
     <section>
      <header><span class="section-number">21</span> <h1 data-bookmark-label="21 Containers">Containers Library</h1> <span style="float:right"><a href="#containers">[containers]</a></span></header>

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

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

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

namespace std {
  // 21.3.8, class template deque
  template&lt;class T, class Allocator = allocator&lt;T&gt;&gt; class deque;

...

  template&lt;class T, class Allocator&gt;
    void swap(deque&lt;T, Allocator&gt;&amp; x, deque&lt;T, Allocator&gt;&amp; y)
      noexcept(noexcept(x.swap(y)));

  <ins>template &lt;class T, class Allocator, class U&gt;</ins>
    <ins>void erase(deque&lt;T, Allocator&gt;&amp; c, const U&amp; value);</ins>
  <ins>template &lt;class T, class Allocator, class Predicate&gt;</ins>
    <ins>void erase_if(deque&lt;T, Allocator&gt;&amp; c, Predicate pred);</ins>

  namespace pmr {
    template&lt;class T&gt;
      using deque = std::deque&lt;T, polymorphic_allocator&lt;T&gt;&gt;;
  }
} // namespace std
</code></pre>

    </section>
  </cxx-section>


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

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

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

namespace std {
  // 21.3.9, class template forward_list
  template&lt;class T, class Allocator = allocator&lt;T&gt;&gt; class forward_list;

...

  template&lt;class T, class Allocator&gt;
    void swap(forward_list&lt;T, Allocator&gt;&amp; x, forward_list&lt;T, Allocator&gt;&amp; y)
      noexcept(noexcept(x.swap(y)));

  <ins>template &lt;class T, class Allocator, class U&gt;</ins>
    <ins>void erase(forward_list&lt;T, Allocator&gt;&amp; c, const U&amp; value);</ins>
  <ins>template &lt;class T, class Allocator, class Predicate&gt;</ins>
    <ins>void erase_if(forward_list&lt;T, Allocator&gt;&amp; c, Predicate pred);</ins>

  namespace pmr {
    template&lt;class T&gt;
      using forward_list = std::forward_list&lt;T, polymorphic_allocator&lt;T&gt;&gt;;
  }
} // namespace std
</code></pre>

    </section>
  </cxx-section>



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

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

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

namespace std {
  // 21.3.10, class template list
  template&lt;class T, class Allocator = allocator&lt;T&gt;&gt; class list;

...

  template&lt;class T, class Allocator&gt;
    void swap(list&lt;T, Allocator&gt;&amp; x, list&lt;T, Allocator&gt;&amp; y)
      noexcept(noexcept(x.swap(y)));

  <ins>template &lt;class T, class Allocator, class U&gt;</ins>
    <ins>void erase(list&lt;T, Allocator&gt;&amp; c, const U&amp; value);</ins>
  <ins>template &lt;class T, class Allocator, class Predicate&gt;</ins>
    <ins>void erase_if(list&lt;T, Allocator&gt;&amp; c, Predicate pred);</ins>

  namespace pmr {
    template&lt;class T&gt;
      using list = std::list&lt;T, polymorphic_allocator&lt;T&gt;&gt;;
  }
} // namespace std
</code></pre>

    </section>
  </cxx-section>


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

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

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

namespace std {
  // 21.3.11, class template vector
  template&lt;class T, class Allocator = allocator&lt;T&gt;&gt; class vector;

...

  template&lt;class T, class Allocator&gt;
    void swap(vector&lt;T, Allocator&gt;&amp; x, vector&lt;T, Allocator&gt;&amp; y)
      noexcept(noexcept(x.swap(y)));

  <ins>template &lt;class T, class Allocator, class U&gt;</ins>
    <ins>void erase(vector&lt;T, Allocator&gt;&amp; c, const U&amp; value);</ins>
  <ins>template &lt;class T, class Allocator, class Predicate&gt;</ins>
    <ins>void erase_if(vector&lt;T, Allocator&gt;&amp; c, Predicate pred);</ins>

  // 21.3.12, class vector&lt;bool&gt;
  template&lt;class Allocator&gt; class vector&lt;bool, Allocator&gt;;

  // hash support
  template&lt;class T&gt; struct hash;
  template&lt;class Allocator&gt; struct hash&lt;vector&lt;bool, Allocator&gt;&gt;;

  namespace pmr {
    template&lt;class T&gt;
      using vector = std::vector&lt;T, polymorphic_allocator&lt;T&gt;&gt;;
  }
} // namespace std
</code></pre>

    </section>
  </cxx-section>


  <cxx-section id="deque.erasure"><ins>

    <section>
      <header><span class="section-number">21.3.8.X</span> <h1 data-bookmark-label="21.3.8.X Deque Erasure">Deque Erasure</h1> <span style="float:right"><a href="#deque.erasure">[deque.erasure]</a></span></header>

  <cxx-function id="deque.erasure">

<pre><code><cxx-signature>template &lt;class T, class Allocator, class U&gt;
void erase(deque&lt;T, Allocator&gt;&amp; c, const U&amp; value);</cxx-signature></code></pre>

    <dl>
    <cxx-effects id="deque.erasure.1" para_num="1">
      <dt>Effects:</dt> <dd>Equivalent to: <code>c.erase(remove(c.begin(), c.end(), value), c.end());</code></dd>
    </cxx-effects>
    </dl>

  </cxx-function>

  <cxx-function id="deque.erasure">

<pre><code><cxx-signature>template &lt;class T, class Allocator, class Predicate&gt;
void erase_if(deque&lt;T, Allocator&gt;&amp; c, Predicate pred);</cxx-signature></code></pre>

    <dl>
    <cxx-effects id="deque.erasure.2" para_num="2">
      <dt>Effects:</dt><dd>Equivalent to: <code>c.erase(remove_if(c.begin(), c.end(), pred), c.end());</code></dd>
    </cxx-effects>

    </dl>

  </cxx-function>

    </section>
  </ins></cxx-section>


  <cxx-section id="forward_list.erasure"><ins>

    <section>
      <header><span class="section-number">21.3.9.X</span> <h1 data-bookmark-label="21.3.9.X Forward List Erasure">Forward List Erasure</h1> <span style="float:right"><a href="#forward_list.erasure">[forward_list.erasure]</a></span></header>

  <cxx-function id="forward_list.erasure">

<pre><code><cxx-signature>template &lt;class T, class Allocator, class U&gt;
void erase(forward_list&lt;T, Allocator&gt;&amp; c, const U&amp; value);</cxx-signature></code></pre>

    <dl>
    <cxx-effects id="forward_list.erasure.1" para_num="1">
      <dt>Effects:</dt> <dd>Equivalent to: <code>erase_if(c, [&amp;](auto&amp; elem) { return elem == value; });</code></dd>
    </cxx-effects>
    </dl>

  </cxx-function>

  <cxx-function id="forward_list.erasure">

<pre><code><cxx-signature>template &lt;class T, class Allocator, class Predicate&gt;
void erase_if(forward_list&lt;T, Allocator&gt;&amp; c, Predicate pred);</cxx-signature></code></pre>

    <dl>
    <cxx-effects id="forward_list.erasure.2" para_num="2">
      <dt>Effects:</dt> <dd>Equivalent to: <code>c.remove_if(pred);</code></dd>
    </cxx-effects>
    </dl>

  </cxx-function>

    </section>
  </ins></cxx-section>


  <cxx-section id="list.erasure"><ins>

    <section>
      <header><span class="section-number">21.3.10.X</span> <h1 data-bookmark-label="21.3.10.X List Erasure">List Erasure</h1> <span style="float:right"><a href="#list.erasure">[list.erasure]</a></span></header>

  <cxx-function id="list.erasure">

<pre><code><cxx-signature>template &lt;class T, class Allocator, class U&gt;
void erase(list&lt;T, Allocator&gt;&amp; c, const U&amp; value);</cxx-signature></code></pre>

    <dl>
    <cxx-effects id="list.erasure.1" para_num="1">
      <dt>Effects:</dt> <dd>Equivalent to: <code>erase_if(c, [&amp;](auto&amp; elem) { return elem == value; });</code></dd>
    </cxx-effects>
    </dl>

  </cxx-function>

  <cxx-function id="list.erasure">

<pre><code><cxx-signature>template &lt;class T, class Allocator, class Predicate&gt;
void erase_if(list&lt;T, Allocator&gt;&amp; c, Predicate pred);</cxx-signature></code></pre>

    <dl>
    <cxx-effects id="list.erasure.2" para_num="2">
      <dt>Effects:</dt> <dd>Equivalent to: <code>c.remove_if(pred);</code></dd>
    </cxx-effects>
    </dl>

  </cxx-function>

    </section>
  </ins></cxx-section>


  <cxx-section id="vector.erasure"><ins>

    <section>
      <header><span class="section-number">21.3.11.X</span> <h1 data-bookmark-label="21.3.11.X Vector Erasure">Vector Erasure</h1> <span style="float:right"><a href="#vector.erasure">[vector.erasure]</a></span></header>

  <cxx-function id="vector.erasure">

<pre><code><cxx-signature>template &lt;class T, class Allocator, class U&gt;
void erase(vector&lt;T, Allocator&gt;&amp; c, const U&amp; value);</cxx-signature></code></pre>

    <dl>
    <cxx-effects id="vector.erasure.1" para_num="1">
      <dt>Effects:</dt> <dd>Equivalent to: <code>c.erase(remove(c.begin(), c.end(), value), c.end());</code></dd>
    </cxx-effects>
    </dl>

  </cxx-function>

  <cxx-function id="vector.erasure">

<pre><code><cxx-signature>template &lt;class T, class Allocator, class Predicate&gt;
void erase_if(vector&lt;T, Allocator&gt;&amp; c, Predicate pred);</cxx-signature></code></pre>

    <dl>
    <cxx-effects id="vector.erasure.2" para_num="2">
      <dt>Effects:</dt><dd>Equivalent to: <code>c.erase(remove_if(c.begin(), c.end(), pred), c.end());</code></dd>
    </cxx-effects>

    </dl>

  </cxx-function>

    </section>
  </ins></cxx-section>


  <cxx-section id="associative.map.syn">

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

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

namespace std {
  // 21.4.4, class template map
  template&lt;class Key, class T, class Compare = less&lt;Key&gt;,
           class Allocator = allocator&lt;pair&lt;const Key, T&gt;&gt;&gt;
    class map;

...

  template&lt;class Key, class T, class Compare, class Allocator&gt;
    void swap(map&lt;Key, T, Compare, Allocator&gt;&amp; x,
              map&lt;Key, T, Compare, Allocator&gt;&amp; y)
      noexcept(noexcept(x.swap(y)));

  <ins>template &lt;class Key, class T, class Compare, class Allocator, class Predicate&gt;</ins>
    <ins>void erase_if(map&lt;Key, T, Compare, Allocator&gt;&amp; c, Predicate pred);</ins>


  // 21.4.5, class template multimap
  template&lt;class Key, class T, class Compare = less&lt;Key&gt;,
           class Allocator = allocator&lt;pair&lt;const Key, T&gt;&gt;&gt;
    class multimap;

...

  template&lt;class Key, class T, class Compare, class Allocator&gt;
    void swap(multimap&lt;Key, T, Compare, Allocator&gt;&amp; x,
              multimap&lt;Key, T, Compare, Allocator&gt;&amp; y)
      noexcept(noexcept(x.swap(y)));

  <ins>template &lt;class Key, class T, class Compare, class Allocator, class Predicate&gt;</ins>
    <ins>void erase_if(multimap&lt;Key, T, Compare, Allocator&gt;&amp; c, Predicate pred);</ins>

  namespace pmr {
    template&lt;class Key, class T, class Compare = less&lt;Key&gt;&gt;
      using map = std::map&lt;Key, T, Compare,
                           polymorphic_allocator&lt;pair&lt;const Key, T&gt;&gt;&gt;;
    template&lt;class Key, class T, class Compare = less&lt;Key&gt;&gt;
      using multimap = std::multimap&lt;Key, T, Compare,
                                     polymorphic_allocator&lt;pair&lt;const Key, T&gt;&gt;&gt;;
  }
} // namespace std
</code></pre>

    </section>
  </cxx-section>



  <cxx-section id="associative.set.syn">

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

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

namespace std {
  // 21.4.6, class template set
  template&lt;class Key, class Compare = less&lt;Key&gt;, class Allocator = allocator&lt;Key&gt;&gt;
    class set;

...

  template&lt;class Key, class Compare, class Allocator&gt;
    void swap(set&lt;Key, Compare, Allocator&gt;&amp; x,
              set&lt;Key, Compare, Allocator&gt;&amp; y)
      noexcept(noexcept(x.swap(y)));

  <ins>template &lt;class Key, class Compare, class Allocator, class Predicate&gt;</ins>
    <ins>void erase_if(set&lt;Key, Compare, Allocator&gt;&amp; c, Predicate pred);</ins>


  // 21.4.7, class template multiset
  template&lt;class Key, class Compare = less&lt;Key&gt;, class Allocator = allocator&lt;Key&gt;&gt;
    class multiset;

...

  template&lt;class Key, class Compare, class Allocator&gt;
    void swap(multiset&lt;Key, Compare, Allocator&gt;&amp; x,
              multiset&lt;Key, Compare, Allocator&gt;&amp; y)
      noexcept(noexcept(x.swap(y)));

  <ins>template &lt;class Key, class Compare, class Allocator, class Predicate&gt;</ins>
    <ins>void erase_if(multiset&lt;Key, Compare, Allocator&gt;&amp; c, Predicate pred);</ins>

  namespace pmr {
    template&lt;class Key, class Compare = less&lt;Key&gt;&gt;
      using set = std::set&lt;Key, Compare, polymorphic_allocator&lt;Key&gt;&gt;;
    template&lt;class Key, class Compare = less&lt;Key&gt;&gt;
      using multiset = std::multiset&lt;Key, Compare, polymorphic_allocator&lt;Key&gt;&gt;;
  }
} // namespace std
</code></pre>

    </section>
  </cxx-section>


  <cxx-section id="map.erasure"><ins>

    <section>
      <header><span class="section-number">21.4.4.X</span> <h1 data-bookmark-label="21.4.4.X Map Erasure">Map Erasure</h1> <span style="float:right"><a href="#map.erasure">[map.erasure]</a></span></header>

  <cxx-function id="map.erasure">

<pre><code><cxx-signature>template &lt;class Key, class T, class Compare, class Allocator, class Predicate&gt;
void erase_if(map&lt;Key, T, Compare, Allocator&gt;&amp; c, Predicate pred);</cxx-signature></code></pre>

    <dl>
    <cxx-effects id="map.erasure.1" para_num="1">
      <dt>Effects:</dt><dd>Equivalent to:
<pre><code>for (auto i = c.begin(), last = c.end(); i != last; ) {
  if (pred(*i)) {
    i = c.erase(i);
  } else {
    ++i;
  }
}</code></pre></dd>
    </cxx-effects>
    </dl>

  </cxx-function>

    </section>
  </ins></cxx-section>


  <cxx-section id="multimap.erasure"><ins>

    <section>
      <header><span class="section-number">21.4.5.X</span> <h1 data-bookmark-label="21.4.5.X Multimap Erasure">Multimap Erasure</h1> <span style="float:right"><a href="#multimap.erasure">[multimap.erasure]</a></span></header>

  <cxx-function id="multimap.erasure">

<pre><code><cxx-signature>template &lt;class Key, class T, class Compare, class Allocator, class Predicate&gt;
void erase_if(multimap&lt;Key, T, Compare, Allocator&gt;&amp; c, Predicate pred);</cxx-signature></code></pre>

    <dl>
    <cxx-effects id="multimap.erasure.1" para_num="1">
      <dt>Effects:</dt><dd>Equivalent to:
<pre><code>for (auto i = c.begin(), last = c.end(); i != last; ) {
  if (pred(*i)) {
    i = c.erase(i);
  } else {
    ++i;
  }
}</code></pre></dd>
    </cxx-effects>
    </dl>

  </cxx-function>

    </section>
  </ins></cxx-section>


  <cxx-section id="set.erasure"><ins>

    <section>
      <header><span class="section-number">21.4.6.X</span> <h1 data-bookmark-label="21.4.6.X Set Erasure">Set Erasure</h1> <span style="float:right"><a href="#set.erasure">[set.erasure]</a></span></header>

  <cxx-function id="set.erasure">

<pre><code><cxx-signature>template &lt;class Key, class Compare, class Allocator, class Predicate&gt;
void erase_if(set&lt;Key, Compare, Allocator&gt;&amp; c, Predicate pred);</cxx-signature></code></pre>

    <dl>
    <cxx-effects id="set.erasure.1" para_num="1">
      <dt>Effects:</dt><dd>Equivalent to:
<pre><code>for (auto i = c.begin(), last = c.end(); i != last; ) {
  if (pred(*i)) {
    i = c.erase(i);
  } else {
    ++i;
  }
}</code></pre></dd>
    </cxx-effects>
    </dl>

  </cxx-function>

    </section>
  </ins></cxx-section>


  <cxx-section id="multiset.erasure"><ins>

    <section>
      <header><span class="section-number">21.4.7.X</span> <h1 data-bookmark-label="21.4.7.X Multiset Erasure">Multiset Erasure</h1> <span style="float:right"><a href="#multiset.erasure">[multiset.erasure]</a></span></header>

  <cxx-function id="multiset.erasure">

<pre><code><cxx-signature>template &lt;class Key, class Compare, class Allocator, class Predicate&gt;
void erase_if(multiset&lt;Key, Compare, Allocator&gt;&amp; c, Predicate pred);</cxx-signature></code></pre>

    <dl>
    <cxx-effects id="multiset.erasure.1" para_num="1">
      <dt>Effects:</dt><dd>Equivalent to:
<pre><code>for (auto i = c.begin(), last = c.end(); i != last; ) {
  if (pred(*i)) {
    i = c.erase(i);
  } else {
    ++i;
  }
}</code></pre></dd>
    </cxx-effects>
    </dl>

  </cxx-function>

    </section>
  </ins></cxx-section>


  <cxx-section id="unord.map.syn">

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


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

namespace std {
  // 21.5.4, class template unordered_map
  template&lt;class Key,
           class T,
           class Hash = hash&lt;Key&gt;,
           class Pred = equal_to&lt;Key&gt;,
           class Alloc = allocator&lt;pair&lt;const Key, T&gt;&gt;&gt;
    class unordered_map;

  // 21.5.5, class template unordered_multimap
  template&lt;class Key,
           class T,
           class Hash = hash&lt;Key&gt;,
           class Pred = equal_to&lt;Key&gt;,
           class Alloc = allocator&lt;pair&lt;const Key, T&gt;&gt;&gt;
    class unordered_multimap;

...

  template&lt;class Key, class T, class Hash, class Pred, class Alloc&gt;
    void swap(unordered_map&lt;Key, T, Hash, Pred, Alloc&gt;&amp; x,
              unordered_map&lt;Key, T, Hash, Pred, Alloc&gt;&amp; y)
      noexcept(noexcept(x.swap(y)));

  template&lt;class Key, class T, class Hash, class Pred, class Alloc&gt;
    void swap(unordered_multimap&lt;Key, T, Hash, Pred, Alloc&gt;&amp; x,
              unordered_multimap&lt;Key, T, Hash, Pred, Alloc&gt;&amp; y)
      noexcept(noexcept(x.swap(y)));

  <ins>template &lt;class K, class T, class H, class P, class A, class Predicate&gt;</ins>
    <ins>void erase_if(unordered_map&lt;K, T, H, P, A&gt;&amp; c, Predicate pred);</ins>

  <ins>template &lt;class K, class T, class H, class P, class A, class Predicate&gt;</ins>
    <ins>void erase_if(unordered_multimap&lt;K, T, H, P, A&gt;&amp; c, Predicate pred);</ins>

  namespace pmr {
    template&lt;class Key,
             class T,
             class Hash = hash&lt;Key&gt;,
             class Pred = equal_to&lt;Key&gt;&gt;
      using unordered_map =
        std::unordered_map&lt;Key, T, Hash, Pred,
                           polymorphic_allocator&lt;pair&lt;const Key, T&gt;&gt;&gt;;

    template&lt;class Key,
             class T,
             class Hash = hash&lt;Key&gt;,
             class Pred = equal_to&lt;Key&gt;&gt;
      using unordered_multimap =
          std::unordered_multimap&lt;Key, T, Hash, Pred,
                                  polymorphic_allocator&lt;pair&lt;const Key, T&gt;&gt;&gt;;
  }
} // namespace std
</code></pre>

    </section>
  </cxx-section>


  <cxx-section id="unord.set.syn">

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

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

namespace std {
  // 21.5.6, class template unordered_set
  template&lt;class Key,
           class Hash = hash&lt;Key&gt;,
           class Pred = equal_to&lt;Key&gt;,
           class Alloc = allocator&lt;Key&gt;&gt;
    class unordered_set;

  // 21.5.7, class template unordered_multiset
  template&lt;class Key,
           class Hash = hash&lt;Key&gt;,
           class Pred = equal_to&lt;Key&gt;,
           class Alloc = allocator&lt;Key&gt;&gt;
    class unordered_multiset;

...

  template&lt;class Key, class Hash, class Pred, class Alloc&gt;
    void swap(unordered_set&lt;Key, Hash, Pred, Alloc&gt;&amp; x,
              unordered_set&lt;Key, Hash, Pred, Alloc&gt;&amp; y)
      noexcept(noexcept(x.swap(y)));

  template&lt;class Key, class Hash, class Pred, class Alloc&gt;
    void swap(unordered_multiset&lt;Key, Hash, Pred, Alloc&gt;&amp; x,
              unordered_multiset&lt;Key, Hash, Pred, Alloc&gt;&amp; y)
      noexcept(noexcept(x.swap(y)));

  <ins>template &lt;class K, class H, class P, class A, class Predicate&gt;</ins>
    <ins>void erase_if(unordered_set&lt;K, H, P, A&gt;&amp; c, Predicate pred);</ins>

  <ins>template &lt;class K, class H, class P, class A, class Predicate&gt;</ins>
    <ins>void erase_if(unordered_multiset&lt;K, H, P, A&gt;&amp; c, Predicate pred);</ins>

  namespace pmr {
    template&lt;class Key,
             class Hash = hash&lt;Key&gt;,
             class Pred = equal_to&lt;Key&gt;&gt;
      using unordered_set = std::unordered_set&lt;Key, Hash, Pred,
                                               polymorphic_allocator&lt;Key&gt;&gt;;

    template&lt;class Key,
             class Hash = hash&lt;Key&gt;,
             class Pred = equal_to&lt;Key&gt;&gt;
      using unordered_multiset = std::unordered_multiset&lt;Key, Hash, Pred,
                                                         polymorphic_allocator&lt;Key&gt;&gt;;
  }
} // namespace std
</code></pre>

    </section>
  </cxx-section>








  <cxx-section id="unord.map.erasure"><ins>

    <section>
      <header><span class="section-number">21.5.4.X</span> <h1 data-bookmark-label="21.5.4.X Unordered Map Erasure">Unordered Map Erasure</h1> <span style="float:right"><a href="#unord.map.erasure">[unord.map.erasure]</a></span></header>

  <cxx-function id="map.erasure">

<pre><code><cxx-signature>template &lt;class K, class T, class H, class P, class A, class Predicate&gt;
void erase_if(unordered_map&lt;K, T, H, P, A&gt;&amp; c, Predicate pred);</cxx-signature></code></pre>

    <dl>
    <cxx-effects id="unord.map.erasure.1" para_num="1">
      <dt>Effects:</dt><dd>Equivalent to:
<pre><code>for (auto i = c.begin(), last = c.end(); i != last; ) {
  if (pred(*i)) {
    i = c.erase(i);
  } else {
    ++i;
  }
}</code></pre></dd>
    </cxx-effects>
    </dl>

  </cxx-function>

    </section>
  </ins></cxx-section>


  <cxx-section id="unord.multimap.erasure"><ins>

    <section>
      <header><span class="section-number">21.5.5.X</span> <h1 data-bookmark-label="21.5.5.X Unordered Multimap Erasure">Unordered Multimap Erasure</h1> <span style="float:right"><a href="#unord.multimap.erasure">[unord.multimap.erasure]</a></span></header>

  <cxx-function id="multimap.erasure">

<pre><code><cxx-signature>template &lt;class K, class T, class H, class P, class A, class Predicate&gt;
void erase_if(unordered_multimap&lt;K, T, H, P, A&gt;&amp; c, Predicate pred);</cxx-signature></code></pre>

    <dl>
    <cxx-effects id="unord.multimap.erasure.1" para_num="1">
      <dt>Effects:</dt><dd>Equivalent to:
<pre><code>for (auto i = c.begin(), last = c.end(); i != last; ) {
  if (pred(*i)) {
    i = c.erase(i);
  } else {
    ++i;
  }
}</code></pre></dd>
    </cxx-effects>
    </dl>

  </cxx-function>

    </section>
  </ins></cxx-section>


  <cxx-section id="unord.set.erasure"><ins>

    <section>
      <header><span class="section-number">21.5.6.X</span> <h1 data-bookmark-label="21.5.6.X Unordered Set Erasure">Unordered Set Erasure</h1> <span style="float:right"><a href="#unord.set.erasure">[unord.set.erasure]</a></span></header>

  <cxx-function id="unord.set.erasure">

<pre><code><cxx-signature>template &lt;class K, class H, class P, class A, class Predicate&gt;
void erase_if(unordered_set&lt;K, H, P, A&gt;&amp; c, Predicate pred);</cxx-signature></code></pre>

    <dl>
    <cxx-effects id="unord.set.erasure.1" para_num="1">
      <dt>Effects:</dt><dd>Equivalent to:
<pre><code>for (auto i = c.begin(), last = c.end(); i != last; ) {
  if (pred(*i)) {
    i = c.erase(i);
  } else {
    ++i;
  }
}</code></pre></dd>
    </cxx-effects>
    </dl>

  </cxx-function>

    </section>
  </ins></cxx-section>


  <cxx-section id="unord.multiset.erasure"><ins>

    <section>
      <header><span class="section-number">21.5.7.X</span> <h1 data-bookmark-label="21.5.7.X Unordered Multiset Erasure">Unordered Multiset Erasure</h1> <span style="float:right"><a href="#unord.multiset.erasure">[unord.multiset.erasure]</a></span></header>

  <cxx-function id="unord.multiset.erasure">

<pre><code><cxx-signature>template &lt;class K, class H, class P, class A, class Predicate&gt;
void erase_if(unordered_multiset&lt;K, H, P, A&gt;&amp; c, Predicate pred);</cxx-signature></code></pre>

    <dl>
    <cxx-effects id="unord.multiset.erasure.1" para_num="1">
      <dt>Effects:</dt><dd>Equivalent to:
<pre><code>for (auto i = c.begin(), last = c.end(); i != last; ) {
  if (pred(*i)) {
    i = c.erase(i);
  } else {
    ++i;
  }
}</code></pre></dd>
    </cxx-effects>
    </dl>

  </cxx-function>

    </section>
  </ins></cxx-section>


  </section>
</cxx-clause>


<h2><a name="7.0">7. Acknowledgements</a></h2>
<p>
Thanks to Timur Doumler for encouraging this proposal.
</p>


<h2><a name="8.0">8. References</a></h2>
<ul>
  <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4009">N4009</a> Uniform Container Erasure, Stephan T. Lavavej</li>
  <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4273">N4273</a> Uniform Container Erasure (Revision 2), Stephan T. Lavavej</li>
</ul>

</body>
</html>
