<!DOCTYPE html>
<html><head><meta http-equiv="Content-Type" content="text/html; 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-TOC");document.createElement("CXX-FOREIGN-INDEX");document.createElement("CXX-CLAUSE");document.createElement("CXX-SECTION");document.createElement("CXX-EDNOTE");document.createElement("CXX-NOTE");document.createElement("CXX-REF");document.createElement("CXX-FUNCTION");document.createElement("CXX-SIGNATURE");document.createElement("CXX-EFFECTS");document.createElement("CXX-POSTCONDITIONS");document.createElement("CXX-REQUIRES");document.createElement("CXX-RETURNS");document.createElement("CXX-EXAMPLE");document.createElement("CXX-REMARKS");document.createElement("CXX-CODEBLOCK");document.createElement("CXX-SYNCHRONIZATION");document.createElement("CXX-THROWS");document.createElement("CXX-NOTES");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; 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>

  <!--
  <script src="bower_components/platform/platform.js"></script>
  <link rel="import" href="bower_components/cxx-html-doc-framework/framework.html"/>
  -->

  <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;}
*/
del {text-decoration: line-through; background-color: red; color: #8B0040;}
ins {text-decoration: underline; background-color: yellow; 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>

<title>C++ Latches and Barriers</title></head>
<body class="cxx-dts">
      <div class="page">
        <div class="header">

            <strong>ISO/IEC JTC1 SC22 WG21 <cxx-docnum class="docname">P0666R0</cxx-docnum></strong><br>
            Date: <time pubdate=""><span class="pubyear">2017</span>-06-19</time><br>
            Reply-to: Alasdair Mackintosh <a href="mailto:alasdair@google.com">alasdair@google.com</a><br>
            Audience: WG21
        </div>
        <hgroup>
          <h1>C++ Latches and Barriers</h1>
        </hgroup>
      </div>

<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.history">History</a>

          </li>

          <li><span class="marker">1.2</span><a href="#general.changes">Changes</a>

          </li>

          <li><span class="marker">1.3</span><a href="#general.proposals">Additional
              Proposed Changes</a>
          </li>

          <li><span class="marker">1.4</span><a href="#general.main">Main Proposal</a>
          </li>

        </ol>

      </li>

      <li><span class="marker">33.7</span><a href="#coordination">Latches and Barriers</a>

        <ol>

          <li><span class="marker">33.7.1</span><a href="#coordination.general">General</a>

          </li>

          <li><span class="marker">33.7.2</span><a href="#coordination.terminology">Terminology</a>

          </li>

          <li><span class="marker">33.7.3</span><a href="#coordination.latch">Latches</a>

          </li>

          <li><span class="marker">33.7.4</span><a href="#coordination.latch.synopsis">Header &lt;latch&gt; synopsis</a>

          </li>

          <li><span class="marker">33.7.5</span><a href="#coordination.latch.class">Class latch</a>

          </li>

          <li><span class="marker">33.7.6</span><a href="#coordination.barrier">Barrier types</a>

          </li>

          <li><span class="marker">33.7.7</span><a href="#coordination.barrier.synopsis">Header &lt;barrier&gt; synopsis</a>

          </li>

          <li><span class="marker">33.7.8</span><a href="#coordination.barrier.class">Class barrier</a>

          </li>

          <li><span class="marker">33.7.9</span><a href="#coordination.flexbarrier.class">Class flex_barrier</a>

          </li>

        </ol>

      </li>
    </ol>
  </nav>
</cxx-toc>




<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.history">

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

        <p para_num="1" id="general.history.1">This paper has been taken from
          Section 3
          of <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0159r0.html">P0159R0</a>,
          which describes proposed extensions for concurrency. We propose the section numbered
          33.7 below for inclusion in the C++ standard, after 33.6 [futures]. As P0159R0 has been available since
          2015 without any recorded objections, and since it represents commonly used
          concurrency features, we believe it is suitable for inclusion as-is.
        </p>

        <p para_num="2" id="general.history.2">
          A previous version of this paper was published as <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4392.pdf">N4392</a>
      </section>
    </cxx-section>

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

        <p para_num="1" id="general.changes.1">The following changes have been made
          to P0159R0.</p>

        <p para_num="2" id="general.changes.2">The main section has been renumbered
          to reflect its proposed position in the standard.</p>
        <p para_num="3" id="general.changes.3">All functions and classes have been
          moved into the <code>std</code> namespace.
      </section>
    </cxx-section>

    <cxx-section id="general.proposals">
      <section>
        <header><span class="section-number">1.3</span>
          <h1 data-bookmark-label="1.3 Proposals">Additional Proposed Changes</h1> <span style="float:right"><a href="#general.changes">[general.proposals]</a></span></header>

        <p para_num="1" id="general.proposals.1">We propose the following
          additional wording beyond P0159R0 that clarifies some ambiguities in the
          original wording. This has been added in the paragraph below so that the
          committee has the option of accepting P0159R0 as written without any
          additions, or of including this change.

        <p para_num="2" id="general.proposals.2">The wording for <code>arrive_and_drop</code>
          in <a href="#coordination.barrier">Section 33.7.6</a> is ambiguous, as it
          implies that the first action is to remove the thread from the set
          of participating threads. Because the completion phase is defined to run in
          one of the participating threads, this wording would imply that
          the phase cannot run in any thread that calls  <code>arrive_and_drop</code>.

        <p para_num="3" id="proposals.arrive_and_drop.2">
          We propose the following wording to replace paragraph 13 in Section 33.7.6.
        </p>
          <cxx-effects para_num="4" id="proposals.arrive_and_drop.3">
            <dt>Effects:</dt>
            <dd>
              Removes the current thread from the set of participating threads. If
              this causes the set to become empty, the barrier type's completion
              phase is executed. It is unspecified whether the function blocks until
              the completion phase is ended.
              <cxx-note><span class="nowrap">[ <em>Note:</em></span>
                If no other thread is blocked in this function, the completion phase
                executes in the calling thread.
                <span class="nowrap">— <em>end note</em> ]</span>
              </cxx-note>
            </dd>
          </cxx-effects>
      </section>
    </cxx-section>
    <cxx-section id="general.main">
      <section>
        <header><span class="section-number">1.4</span>
          <h1 data-bookmark-label="1.4 Main Proposal">Main Proposal</h1> <span style="float:right"><a href="#general.main">[general.main]</a></span></header>
          <p para_num="1" id="general.main.1">We propose to add the following clause from the Concurrency TS to the C++20 working draft, as described below.
      </section>
    </cxx-section>
  </section>
</cxx-clause>


<cxx-clause id="coordination">


    <section>
      <header><span class="section-number">33.7</span> <h1 data-bookmark-label="33.7 Latches and Barriers">Latches and Barriers</h1> <span style="float:right"><a href="#coordination">[coordination]</a></span></header>



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


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


<p para_num="1" id="coordination.general.1">
This section describes various concepts related to thread coordination, and defines the <code>latch</code>, <code>barrier</code> and <code>flex_barrier</code> classes.
</p>



    </section>
  </cxx-section>

<cxx-section id="coordination.terminology">


    <section>
      <header><span class="section-number">33.7.2</span> <h1 data-bookmark-label="33.7.2 Terminology">Terminology</h1> <span style="float:right"><a href="#coordination.terminology">[coordination.terminology]</a></span></header>


<p para_num="1" id="coordination.terminology.1">
In this subclause, a <em>synchronization point</em> represents a point at which a thread may block until a given condition has been reached.
</p>

    </section>
  </cxx-section>

<cxx-section id="coordination.latch">


    <section>
      <header><span class="section-number">33.7.3</span> <h1 data-bookmark-label="33.7.3 Latches">Latches</h1> <span style="float:right"><a href="#coordination.latch">[coordination.latch]</a></span></header>


<p para_num="1" id="coordination.latch.1">
Latches are a thread coordination mechanism that allow one or more
threads to block until an operation is completed. An individual latch is
 a single-use object; once the operation has been completed, the latch
cannot be reused.
</p>

    </section>
  </cxx-section>

<cxx-section id="coordination.latch.synopsis">


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


<pre><code>
namespace std {
  class latch {
   public:
    explicit latch(ptrdiff_t count);
    latch(const latch&amp;) = delete;

    latch&amp; operator=(const latch&amp;) = delete;
    ~latch();


    void count_down_and_wait();
    void count_down(ptrdiff_t n = 1);

    bool is_ready() const noexcept;
    void wait() const;

   private:
    ptrdiff_t counter_; // <em>exposition only</em>
  };
} // namespace std
</code></pre>

    </section>
  </cxx-section>

<cxx-section id="coordination.latch.class">


    <section>
      <header><span class="section-number">33.7.5</span> <h1 data-bookmark-label="33.7.5 Class latch">Class <code>latch</code></h1> <span style="float:right"><a href="#coordination.latch.class">[coordination.latch.class]</a></span></header>


<p para_num="1" id="coordination.latch.class.1">
A latch maintains an internal <code>counter_</code> that is initialized when the latch is created. Threads may block at a synchronization point waiting for <code>counter_</code> to be decremented to <code>0</code>. When <code>counter_</code> reaches <code>0</code>, all such blocked threads are released.
</p>
<p para_num="2" id="coordination.latch.class.2">
Calls to <code>count_down_and_wait()</code>, <code>count_down()</code>, <code>wait()</code>, and <code>is_ready()</code> behave as atomic operations.
</p>

<cxx-function para_num="3" id="coordination.latch.class.3">

    <pre><code><cxx-signature>explicit latch(ptrdiff_t count);</cxx-signature></code></pre>

    <dl>


  <cxx-requires para_num="4" id="coordination.latch.class.4">

    <dt>Requires:</dt><dd><code>count &gt;= 0.</code></dd>
  </cxx-requires>
  <cxx-synchronization para_num="5" id="coordination.latch.class.5">

    <dt>Synchronization:</dt><dd>None.</dd>
  </cxx-synchronization>
  <cxx-postconditions para_num="6" id="coordination.latch.class.6">

    <dt>Postconditions:</dt><dd><code>counter_ == count</code>.</dd>
  </cxx-postconditions>

    </dl>
  </cxx-function>

<cxx-function para_num="7" id="coordination.latch.class.7">

    <pre><code><cxx-signature>~latch();</cxx-signature></code></pre>

    <dl>


  <cxx-requires para_num="8" id="coordination.latch.class.8">

    <dt>Requires:</dt><dd>No threads are blocked at the synchronization point.</dd>
  </cxx-requires>
  <cxx-remarks para_num="9" id="coordination.latch.class.9">

    <dt>Remarks:</dt><dd>May be called even if some threads have not yet returned from <code>wait()</code> or <code>count_down_and_wait()</code> provided that <code>counter_</code> is <code>0</code>. <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    The destructor might not return until all threads have exited <code>wait()</code> or <code>count_down_and_wait()</code>.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note></dd>
  </cxx-remarks>

    </dl>
  </cxx-function>

<cxx-function para_num="10" id="coordination.latch.class.10">

    <pre><code><cxx-signature>void count_down_and_wait();</cxx-signature></code></pre>

    <dl>


  <cxx-requires para_num="11" id="coordination.latch.class.11">

    <dt>Requires:</dt><dd><code>counter_ &gt; 0.</code></dd>
  </cxx-requires>
  <cxx-effects para_num="12" id="coordination.latch.class.12">

    <dt>Effects:</dt><dd>Decrements <code>counter_</code> by <code>1</code>. Blocks at the synchronization point until <code>counter_</code> reaches <code>0</code>. </dd>
  </cxx-effects>
  <cxx-synchronization para_num="13" id="coordination.latch.class.13">

    <dt>Synchronization:</dt><dd>Synchronizes with all calls that block on this latch and with all <code>is_ready</code> calls on this latch that return true.</dd>
  </cxx-synchronization>
  <cxx-throws para_num="14" id="coordination.latch.class.14">

    <dt>Throws:</dt><dd>Nothing.</dd>
  </cxx-throws>

    </dl>
  </cxx-function>

<cxx-function para_num="15" id="coordination.latch.class.15">

    <pre><code><cxx-signature>void count_down(ptrdiff_t n = 1);</cxx-signature></code></pre>

    <dl>


  <cxx-requires para_num="16" id="coordination.latch.class.16">

    <dt>Requires:</dt><dd><code>counter_ &gt;= n</code> and <code>n &gt;= 0</code>.</dd>
  </cxx-requires>
  <cxx-effects para_num="17" id="coordination.latch.class.17">

    <dt>Effects:</dt><dd>Decrements <code>counter_</code> by <code>n</code>. Does not block.</dd>
  </cxx-effects>
  <cxx-synchronization para_num="18" id="coordination.latch.class.18">

    <dt>Synchronization:</dt><dd>Synchronizes with all calls that block on this latch and with all <code>is_ready</code> calls on this latch that return true.</dd>
  </cxx-synchronization>
  <cxx-throws para_num="19" id="coordination.latch.class.19">

    <dt>Throws:</dt><dd>Nothing.</dd>
  </cxx-throws>

    </dl>
  </cxx-function>

<cxx-function para_num="20" id="coordination.latch.class.20">

    <pre><code><cxx-signature>void wait() const;</cxx-signature></code></pre>

    <dl>


  <cxx-effects para_num="21" id="coordination.latch.class.21">

    <dt>Effects:</dt><dd>If <code>counter_</code> is <code>0</code>, returns immediately. Otherwise, blocks the calling thread at the synchronization point until <code>counter_</code> reaches <code>0</code>.</dd>
  </cxx-effects>
  <cxx-throws para_num="22" id="coordination.latch.class.22">

    <dt>Throws:</dt><dd>Nothing.</dd>
  </cxx-throws>


    </dl>
  </cxx-function>

<cxx-function para_num="23" id="coordination.latch.class.23">

    <pre><code><cxx-signature>is_ready() const noexcept;</cxx-signature></code></pre>

    <dl>


  <cxx-returns para_num="24" id="coordination.latch.class.24">

    <dt>Returns:</dt><dd><code>counter_ == 0</code>. Does not block.</dd>
  </cxx-returns>

    </dl>
  </cxx-function>

    </section>
  </cxx-section>

<cxx-section id="coordination.barrier">


    <section>
      <header><span class="section-number">33.7.6</span> <h1 data-bookmark-label="33.7.6 Barrier types">Barrier types</h1> <span style="float:right"><a href="#coordination.barrier">[coordination.barrier]</a></span></header>


<p para_num="1" id="coordination.barrier.1">
Barriers are a thread coordination mechanism that allow a <em>set of participating threads</em>
 to block until an operation is completed. Unlike a latch, a barrier is
reusable: once the participating threads are released from a barrier's
synchronization point, they can re-use the same barrier. It is thus
useful for managing repeated tasks, or phases of a larger task, that are
 handled by multiple threads.
</p>
<p para_num="2" id="coordination.barrier.2">
The <em>barrier types</em> are the standard library types <code>barrier</code> and <code>flex_barrier</code>. They shall meet the requirements set out in this subclause. In this description, <code>b</code> denotes an object of a barrier type.
</p>
<p para_num="3" id="coordination.barrier.3">
Each barrier type defines a <em>completion phase</em> as a (possibly empty) set of effects. When the member functions defined in this subclause <em>arrive at the barrier's synchronization point</em>, they have the following effects:
</p>
<ol>
<li>
When all threads in the barrier's set of participating threads are
blocked at its synchronization point, one participating thread is
unblocked and executes the barrier type's completion phase.
</li>
<li>
When the completion phase is completed, all other participating threads
are unblocked. The end of the completion phase synchronizes with the
returns from all calls unblocked by its completion.
</li>
</ol>
<p para_num="4" id="coordination.barrier.4">
The expression <code>b.arrive_and_wait()</code> shall be well-formed and have the following semantics:
</p>
<cxx-function para_num="5" id="coordination.barrier.5">

    <pre><code><cxx-signature>void arrive_and_wait();</cxx-signature></code></pre>

    <dl>


  <cxx-requires para_num="6" id="coordination.barrier.6">

    <dt>Requires:</dt><dd>The current thread is a member of the set of participating threads.</dd>
  </cxx-requires>
  <cxx-effects para_num="7" id="coordination.barrier.7">

    <dt>Effects:</dt><dd>Blocks and arrives at the barrier's synchronization point. <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    It is safe for a thread to call <code>arrive_and_wait()</code> or <code>arrive_and_drop()</code> again immediately. It is not necessary to ensure that all blocked threads have exited <code>arrive_and_wait()</code> before one thread calls it again.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note></dd>
  </cxx-effects>
  <cxx-synchronization para_num="8" id="coordination.barrier.8">

    <dt>Synchronization:</dt><dd>The call to <code>arrive_and_wait()</code> synchronizes with the start of the completion phase.</dd>
  </cxx-synchronization>
  <cxx-throws para_num="9" id="coordination.barrier.9">

    <dt>Throws:</dt><dd>Nothing.</dd>
  </cxx-throws>

    </dl>
  </cxx-function>
<p para_num="10" id="coordination.barrier.10">
The expression <code>b.arrive_and_drop()</code> shall be well-formed and have the following semantics:
</p>
<cxx-function para_num="11" id="coordination.barrier.11">

    <pre><code><cxx-signature>void arrive_and_drop();</cxx-signature></code></pre>

    <dl>


  <cxx-requires para_num="12" id="coordination.barrier.12">

    <dt>Requires:</dt><dd>The current thread is a member of the set of participating threads.</dd>
  </cxx-requires>
  <cxx-effects para_num="13" id="coordination.barrier.13">

    <dt>Effects:</dt><dd>
    Removes the current thread from the set of participating threads. Arrives at
    the barrier's synchronization point. It is unspecified whether the function blocks until
    the completion phase has ended. <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    If the function blocks, the calling
    thread may be chosen to execute the completion phase.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
  </dd>
  </cxx-effects>

  <cxx-synchronization para_num="14" id="coordination.barrier.14">

    <dt>Synchronization:</dt><dd>The call to <code>arrive_and_drop()</code> synchronizes with the start of the completion phase.</dd>
  </cxx-synchronization>
  <cxx-throws para_num="15" id="coordination.barrier.15">

    <dt>Throws:</dt><dd>Nothing.</dd>
  </cxx-throws>
  <cxx-notes para_num="16" id="coordination.barrier.16">

    <dt>Notes:</dt><dd>If all participating threads call <code>arrive_and_drop()</code>, any further operations on the barrier are undefined, apart from calling the destructor.
If a thread that has called <code>arrive_and_drop()</code> calls another method on the same barrier, other than the destructor, the results are undefined.</dd>
  </cxx-notes>

    </dl>
  </cxx-function>
<p para_num="17" id="coordination.barrier.17">
Calls to <code>arrive_and_wait()</code> and <code>arrive_and_drop()</code> never introduce data races with themselves or each other.
</p>

    </section>
  </cxx-section>

<cxx-section id="coordination.barrier.synopsis">


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


<pre><code>
namespace std {
  class barrier;
  class flex_barrier;
} // namespace std
</code></pre>

    </section>
  </cxx-section>

<cxx-section id="coordination.barrier.class">


    <section>
      <header><span class="section-number">33.7.8</span> <h1 data-bookmark-label="33.7.8 Class barrier">Class <code>barrier</code></h1> <span style="float:right"><a href="#coordination.barrier.class">[coordination.barrier.class]</a></span></header>


<p para_num="1" id="coordination.barrier.class.1">
<code>barrier</code> is a barrier type whose completion phase has no
effects. Its constructor takes a parameter representing the initial size
 of its set of participating threads.
</p>

<pre><code>
class barrier {
 public:
  explicit barrier(ptrdiff_t num_threads);
  barrier(const barrier&amp;) = delete;

  barrier&amp; operator=(const barrier&amp;) = delete;
  ~barrier();

  void arrive_and_wait();
  void arrive_and_drop();
};
</code></pre>

<cxx-function para_num="2" id="coordination.barrier.class.2">

    <pre><code><cxx-signature>explicit barrier(ptrdiff_t num_threads);</cxx-signature></code></pre>

    <dl>


  <cxx-requires para_num="3" id="coordination.barrier.class.3">

    <dt>Requires:</dt><dd><code>num_threads &gt;= 0.</code> <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    If <code>num_threads</code> is zero, the barrier may only be destroyed.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note></dd>
  </cxx-requires>
  <cxx-effects para_num="4" id="coordination.barrier.class.4">

    <dt>Effects:</dt><dd>Initializes the barrier for <code>num_threads</code> participating threads. <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    The set of participating threads is the first <code>num_threads</code> threads to arrive at the synchronization point.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note></dd>
  </cxx-effects>

    </dl>
  </cxx-function>

<cxx-function para_num="5" id="coordination.barrier.class.5">

    <pre><code><cxx-signature>~barrier();</cxx-signature></code></pre>

    <dl>


  <cxx-requires para_num="6" id="coordination.barrier.class.6">

    <dt>Requires:</dt><dd>No threads are blocked at the synchronization point.</dd>
  </cxx-requires>
  <cxx-effects para_num="7" id="coordination.barrier.class.7">

    <dt>Effects:</dt><dd>Destroys the barrier.</dd>
  </cxx-effects>

    </dl>
  </cxx-function>


    </section>
  </cxx-section>

<cxx-section id="coordination.flexbarrier.class">


    <section>
      <header><span class="section-number">33.7.9</span> <h1 data-bookmark-label="33.7.9 Class flex_barrier">Class <code>flex_barrier</code></h1> <span style="float:right"><a href="#coordination.flexbarrier.class">[coordination.flexbarrier.class]</a></span></header>


<p para_num="1" id="coordination.flexbarrier.class.1">
<code>flex_barrier</code> is a barrier type whose completion phase can be controlled
by a  function object.
</p>

<pre><code>
class flex_barrier {
 public:
  template &lt;class F&gt;
    flex_barrier(ptrdiff_t num_threads, F completion);
  explicit flex_barrier(ptrdiff_t num_threads);
  flex_barrier(const flex_barrier&amp;) = delete;
  flex_barrier&amp; operator=(const flex_barrier&amp;) = delete;

  ~flex_barrier();

  void arrive_and_wait();
  void arrive_and_drop();

 private:
  function&lt;ptrdiff_t()&gt; completion_;  // <em>exposition only</em>
};

</code></pre>
<p para_num="2" id="coordination.flexbarrier.class.2">
The completion phase calls <code>completion_()</code>. If this returns <code>-1</code>,
 then the set of participating threads is unchanged. Otherwise, the set
of participating threads becomes a new set with a size equal to the
returned value. <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    If <code>completion_()</code> returns <code>0</code> then the set of participating threads becomes empty, and this object may only be destroyed.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
</p>
<cxx-function para_num="3" id="coordination.flexbarrier.class.3">

    <pre><code><cxx-signature>
template &lt;class F&gt;
flex_barrier(ptrdiff_t num_threads, F completion);
  </cxx-signature></code></pre>

    <dl>


  <cxx-requires para_num="4" id="coordination.flexbarrier.class.4">

    <dt>Requires:</dt><dd>
  <ul>
    <li>
    <code>num_threads &gt;= 0.</code>
    </li><li>
    <code>F</code> shall be <code>CopyConstructible</code>.
    </li><li>
    <code>completion</code> shall be Callable (C++14 §[func.wrap.func]) with no arguments and return type  <code>ptrdiff_t</code>.
    </li><li>
    Invoking <code>completion</code> shall return a value greater than or equal to <code>-1</code> and shall not exit via an exception.
    </li>
  </ul></dd>
  </cxx-requires>



  <cxx-effects para_num="5" id="coordination.flexbarrier.class.5">

    <dt>Effects:</dt><dd>
  Initializes the <code>flex_barrier</code> for <code>num_threads</code> participating threads,
  and initializes <code>completion_</code> with <code>std::move(completion)</code>.
  <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    The set of participating threads consists of the first <code>num_threads</code> threads to arrive at the
  synchronization point.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
  <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    If <code>num_threads</code> is <code>0</code> the set of participating threads is empty, and this object may only be destroyed.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
  </dd>
  </cxx-effects>


    </dl>
  </cxx-function>

<cxx-function para_num="6" id="coordination.flexbarrier.class.6">

    <pre><code><cxx-signature>explicit flex_barrier(ptrdiff_t num_threads);</cxx-signature></code></pre>

    <dl>



  <cxx-requires para_num="7" id="coordination.flexbarrier.class.7">

    <dt>Requires:</dt><dd><code>num_threads &gt;= 0.</code></dd>
  </cxx-requires>
  <cxx-effects para_num="8" id="coordination.flexbarrier.class.8">

    <dt>Effects:</dt><dd>Has the same effect as creating a <code>flex_barrier</code> with <code>num_threads</code> and with a callable object whose invocation returns <code>-1</code> and has no side effects.</dd>
  </cxx-effects>

    </dl>
  </cxx-function>

<cxx-function para_num="9" id="coordination.flexbarrier.class.9">

    <pre><code><cxx-signature>~flex_barrier();</cxx-signature></code></pre>

    <dl>


  <cxx-requires para_num="10" id="coordination.flexbarrier.class.10">

    <dt>Requires:</dt><dd>No threads are blocked at the synchronization point.</dd>
  </cxx-requires>
  <cxx-effects para_num="11" id="coordination.flexbarrier.class.11">

    <dt>Effects:</dt><dd>Destroys the barrier.</dd>
  </cxx-effects>

    </dl>
  </cxx-function>


    </section>
  </cxx-section>

<!-- End clause id="coordination" -->

    </section>
  </cxx-clause>


</body></html>
