<!DOCTYPE html>
<!-- Sources at https://github.com/cplusplus/parallelism-ts -->
<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-REVISES");document.createElement("CXX-EDITOR");document.createElement("CXX-EMAIL");document.createElement("CXX-TOC");document.createElement("CXX-CLAUSE");document.createElement("CXX-FOREIGN-INDEX");document.createElement("CXX-SECTION");document.createElement("CXX-NOTE");document.createElement("CXX-REF");document.createElement("CXX-FUNCTION");document.createElement("CXX-SIGNATURE");document.createElement("CXX-RETURNS");document.createElement("CXX-COMPLEXITY");document.createElement("CXX-REQUIRES");document.createElement("CXX-EXAMPLE");document.createElement("CXX-EFFECTS");document.createElement("CXX-REMARKS");document.createElement("CXX-NOTES");document.createElement("CXX-PRECONDITIONS");document.createElement("CXX-THROWS");document.createElement("CXX-POSTCONDITIONS");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>
  <meta charset="utf-8">
  
  <style shim-shadowdom-css="">/* Copyright 2014 Google Inc. All rights reserved.

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

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

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

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

body { margin: 0; }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/* alignment in cross axis */

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

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

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

/* alignment in main axis */

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

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

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

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

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

/* self alignment */

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

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

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

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

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

html   [block] {
  display: block;
}

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

html   [relative] {
  position: relative;
}

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

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

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

html   [segment], html   segment {
  display: block;
  position: relative;
  -webkit-box-sizing: border-box;
  -ms-box-sizing: border-box;
  box-sizing: border-box;
  margin: 1em 0.5em;
  padding: 1em;
  background-color: white;
  -webkit-box-shadow: 0px 0px 0px 1px rgba(0, 0, 0, 0.1);
  box-shadow: 0px 0px 0px 1px rgba(0, 0, 0, 0.1);
  border-radius: 5px 5px 5px 5px;
}</style>
<style>[touch-action="none"]{ -ms-touch-action: none; touch-action: none;}
[touch-action="auto"]{ -ms-touch-action: auto; touch-action: auto;}
[touch-action="pan-x"]{ -ms-touch-action: pan-x; touch-action: pan-x;}
[touch-action="pan-y"]{ -ms-touch-action: pan-y; touch-action: pan-y;}
[touch-action="pan-x pan-y"],[touch-action="pan-y pan-x"]{ -ms-touch-action: pan-x pan-y; touch-action: pan-x pan-y;}
[touch-action="manipulation"]{ -ms-touch-action: manipulation; touch-action: manipulation;}
</style><title>Technical Specification for C++ Extensions for Parallelism Version 2, Working Draft</title></head>
<body class="cxx-draft">

<cxx-titlepage stage="draft">
    
    
      <div class="page">
        <table class="header">
          
            <tbody><tr><th>Document Number:</th><td><cxx-docnum class="docname">N4725</cxx-docnum></td></tr>
          
          
            <tr><th>Date:</th><td><time pubdate=""><span class="pubyear">2018</span>-02-12</time></td></tr>
          
          
            <tr><th>Revises:</th><td><cxx-revises><a href="http://wg21.link/N4706">N4706</a></cxx-revises></td></tr>
          
          
            <tr><th>Editor:</th><td><cxx-editor>
    Jared Hoberock<br>
    NVIDIA Corporation<br>
    <cxx-email><a href="mailto:jhoberock@nvidia.com">jhoberock@nvidia.com</a></cxx-email>
  </cxx-editor></td></tr>
          
        </tbody></table>
        <h1>Working Draft, Technical Specification for C++ Extensions for Parallelism Version 2</h1>
        <p class="warning"><strong>Note: this is an early draft. It’s known to be
        incomplet and incorrekt, and it has lots of b<span style="margin-left: -1.2pt; margin-right: 1pt">a</span>d<span style="width:1.5em"> </span>for<span style="margin-left:-3pt; margin-right:0.6pt">mat</span>ti<span style="position:relative; top:-0.15ex">n</span>g.</strong></p>
      </div>
    

    

    
  </cxx-titlepage>

<cxx-toc>
    
    <nav>
      <h1>Contents</h1>
      
        
          <ol>
            
              <li><span class="marker">1</span><a href="#parallel.scope">Scope</a>
        
      </li>
            
              <li><span class="marker">2</span><a href="#parallel.references">Normative references</a>
        
      </li>
            
              <li><span class="marker">3</span><a href="#parallel.defns">Terms and definitions</a>
        
      </li>
            
              <li><span class="marker">4</span><a href="#parallel.general">General</a>
        
          <ol>
            
              <li><span class="marker">4.1</span><a href="#parallel.general.namespaces">Namespaces and headers</a>
        
      </li>
            
              <li><span class="marker">4.2</span><a href="#parallel.general.features">Feature-testing recommendations</a>
        
      </li>
            
          </ol>
        
      </li>
            
              <li><span class="marker">5</span><a href="#parallel.execpol">Execution policies</a>
        
          <ol>
            
              <li><span class="marker">5.1</span><a href="#parallel.execpol.synopsis">Header &lt;experimental/execution&gt; synopsis</a>
        
      </li>
            
              <li><span class="marker">5.2</span><a href="#parallel.execpol.unseq">Unsequenced execution policy</a>
        
      </li>
            
              <li><span class="marker">5.3</span><a href="#parallel.execpol.vec">Vector execution policy</a>
        
      </li>
            
              <li><span class="marker">5.4</span><a href="#parallel.execpol.objects">Execution policy objects</a>
        
      </li>
            
          </ol>
        
      </li>
            
              <li><span class="marker">6</span><a href="#parallel.exceptions">Parallel exceptions</a>
        
          <ol>
            
              <li><span class="marker">6.1</span><a href="#parallel.exceptions.synopsis">Header &lt;experimental/exception_list&gt; synopsis</a>
        
      </li>
            
          </ol>
        
      </li>
            
              <li><span class="marker">7</span><a href="#parallel.alg">Parallel algorithms</a>
        
          <ol>
            
              <li><span class="marker">7.1</span><a href="#parallel.alg.wavefront">Wavefront Application</a>
        
      </li>
            
              <li><span class="marker">7.2</span><a href="#parallel.alg.ops">Non-Numeric Parallel Algorithms</a>
        
          <ol>
            
              <li><span class="marker">7.2.1</span><a href="#parallel.alg.ops.synopsis">Header &lt;experimental/algorithm&gt; synopsis</a>
        
      </li>
            
              <li><span class="marker">7.2.2</span><a href="#parallel.alg.reductions">Reductions</a>
        
      </li>
            
              <li><span class="marker">7.2.3</span><a href="#parallel.alg.inductions">Inductions</a>
        
      </li>
            
              <li><span class="marker">7.2.4</span><a href="#parallel.alg.forloop">For loop</a>
        
      </li>
            
              <li><span class="marker">7.2.5</span><a href="#parallel.alg.novec">No vec</a>
        
      </li>
            
              <li><span class="marker">7.2.6</span><a href="#parallel.alg.ordupdate.class">Ordered update class</a>
        
      </li>
            
              <li><span class="marker">7.2.7</span><a href="#parallel.alg.ordupdate.func">Ordered update function template</a>
        
      </li>
            
          </ol>
        
      </li>
            
          </ol>
        
      </li>
            
              <li><span class="marker">8</span><a href="#parallel.task_block">Task Block</a>
        
          <ol>
            
              <li><span class="marker">8.1</span><a href="#parallel.task_block.synopsis">Header &lt;experimental/task_block&gt; synopsis</a>
        
      </li>
            
              <li><span class="marker">8.2</span><a href="#parallel.task_block.task_cancelled_exception">Class task_cancelled_exception</a>
        
          <ol>
            
              <li><span class="marker">8.2.1</span><a href="#parallel.task_block.task_cancelled_exception.what">task_cancelled_exception member function what</a>
        
      </li>
            
          </ol>
        
      </li>
            
              <li><span class="marker">8.3</span><a href="#parallel.task_block.class">Class task_block</a>
        
          <ol>
            
              <li><span class="marker">8.3.1</span><a href="#parallel.task_block.class.run">task_block member function template run</a>
        
      </li>
            
              <li><span class="marker">8.3.2</span><a href="#parallel.task_block.class.wait">task_block member function wait</a>
        
      </li>
            
          </ol>
        
      </li>
            
              <li><span class="marker">8.4</span><a href="#parallel.task_block.define_task_block">Function template define_task_block</a>
        
      </li>
            
              <li><span class="marker">8.5</span><a href="#parallel.task_block.exceptions">Exception Handling</a>
        
      </li>
            
          </ol>
        
      </li>
            
          </ol>
        
      
    </nav>
  </cxx-toc>


<cxx-clause id="parallel.scope">
    

    <section>
      <header><span class="section-number">1</span> <h1 data-bookmark-label="1 Scope">Scope</h1> <span style="float:right"><a href="#parallel.scope">[parallel.scope]</a></span></header>
      
  
    <p id="parallel.scope.1" para_num="1">This Technical Specification describes requirements for implementations of an
    interface that computer programs written in the C++ programming language may
    use to invoke algorithms with parallel execution. The algorithms described by
    this Technical Specification are realizable across a broad class of
    computer architectures.</p>
    
    <p id="parallel.scope.2" para_num="2">This Technical Specification is non-normative. Some of the functionality
    described by this Technical Specification may be considered for standardization
    in a future version of C++, but it is not currently part of any C++ standard.
    Some of the functionality in this Technical Specification may never be
    standardized, and other functionality may be standardized in a substantially
    changed form.</p>
    
    <p id="parallel.scope.3" para_num="3">The goal of this Technical Specification is to build widespread existing
    practice for parallelism in the C++ standard algorithms library. It gives
    advice on extensions to those vendors who wish to provide them.</p>

    </section>
  </cxx-clause>


<cxx-clause id="parallel.references">
    

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

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

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

  <p id="parallel.references.2" para_num="2">ISO/IEC 14882:2017 is herein called the <dfn>C++ Standard</dfn>.
  The library described in ISO/IEC 14882:2017 clauses 20-33 is herein called
  the <dfn>C++ Standard Library</dfn>. The C++ Standard Library components described in
  ISO/IEC 14882:2017 clauses 28, 29.8 and 23.10.10 are herein called the <dfn>C++ Standard
  Algorithms Library</dfn>.</p>

  <p id="parallel.references.3" para_num="3">Unless otherwise specified, the whole of the C++ Standard's Library
  introduction (C++14 §20) is included into this
  Technical Specification by reference.</p>

    </section>
  </cxx-clause>


<cxx-clause id="parallel.defns">
    

    <section>
      <header><span class="section-number">3</span> <h1 data-bookmark-label="3 Terms and definitions">Terms and definitions</h1> <span style="float:right"><a href="#parallel.defns">[parallel.defns]</a></span></header>
      
  

  <ul>
    <li>No terms and definitions are listed in this document.</li>
    <li>ISO and IEC maintained terminological databases for us in standardization at the following addresses:</li>
      <ul>
        <li>IEC Electropedia: available at <a href="http://www.electropedia.org/">http://www.electropedia.org</a></li>
        <li>ISO Online browsing platform: available at <a href="http://www.iso.org/obp">http://www.iso.org/obp</a></li>
      </ul>
  </ul>

    </section>
  </cxx-clause>


<cxx-clause id="parallel.general">
    

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

    <section>
      <header><span class="section-number">4.1</span> <h1 data-bookmark-label="4.1 Namespaces and headers">Namespaces and headers</h1> <span style="float:right"><a href="#parallel.general.namespaces">[parallel.general.namespaces]</a></span></header>
      
    

    <p id="parallel.general.namespaces.1" para_num="1">Since the extensions described in this Technical Specification are
    experimental and not part of the C++ Standard Library, they should not be
    declared directly within namespace <code>std</code>. Unless otherwise specified, all
    components described in this Technical Specification are declared in namespace 
    <code>std::experimental::parallelism_v2</code>.</p>

    <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    
    Once standardized, the components described by this Technical Specification are expected to be promoted to namespace <code>std</code>. 
    
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>

    <p id="parallel.general.namespaces.2" para_num="2">Unless otherwise specified, references to such entities described in this
    Technical Specification are assumed to be qualified with
    <code>std::experimental::parallelism_v2</code>, and references to entities described in the C++
    Standard Library are assumed to be qualified with <code>std::</code>.</p>

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

<pre><code>    #include &lt;meow&gt;</code>
</pre>
  
    </section>
  </cxx-section>

  <cxx-section id="parallel.general.features">
    

    <section>
      <header><span class="section-number">4.2</span> <h1 data-bookmark-label="4.2 Feature-testing recommendations">Feature-testing recommendations</h1> <span style="float:right"><a href="#parallel.general.features">[parallel.general.features]</a></span></header>
      
         
    <p id="parallel.general.features.1" para_num="1">An implementation that provides support for this Technical Specification shall define the feature test macro(s) in Table 1.</p>

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

    <caption>Table 1 — <wbr><span>Feature Test Macro(s)</span></caption>
    
      

      <thead>
        <tr>
          <th>Doc. No.</th>
          <th>Title</th>
          <th>Primary Section</th>
          <th>Macro Name</th>
          <th>Value</th>
          <th>Header</th>
        </tr>
        <tr>
          <td>P0155R0</td>
          <td>Task Block R5</td>
          <td><cxx-ref to="parallel.task_block"><a title="parallel.task_block" href="#parallel.task_block">8</a></cxx-ref></td>
          <td><code>__cpp_lib_experimental_parallel_task_block</code></td>
          <td>201711</td>
          <td>
            <code>&lt;experimental/exception_list&gt;</code><br>
            <code>&lt;experimental/task_block&gt;</code><br>
          </td>
        </tr>
        <tr>
          <td>P0076R4</td>
          <td>Vector and Wavefront Policies</td>
          <td><cxx-ref to="parallel.execpol.unseq" <="" cxx-ref=""><a title="parallel.execpol.unseq" href="#parallel.execpol.unseq">5.2</a></cxx-ref></td>
          <td><code>__cpp_lib_experimental_execution_vector_policy</code></td>
          <td>201711</td>
          <td>
            <code>&lt;experimental/algorithm&gt;</code><br>
            <code>&lt;experimental/execution&gt;</code><br>
          </td>
        </tr>
        <tr>
          <td>P0075R2</td>
          <td>Template Library for Parallel For Loops</td>
          <td><cxx-ref to="parallel.alg.reductions" <="" cxx-ref=""><a title="parallel.alg.reductions" href="#parallel.alg.reductions">7.2.2</a></cxx-ref></td>
          <td><code>__cpp_lib_experimental_parallel_for_loop</code></td>
          <td>201711</td>
          <td><code>&lt;experimental/algorithm&gt;</code></td>
        </tr>
      </thead>
    
  </table>
  
    </section>
  </cxx-section>

    </section>
  </cxx-clause>


<cxx-clause id="parallel.execpol">
    

    <section>
      <header><span class="section-number">5</span> <h1 data-bookmark-label="5 Execution policies">Execution policies</h1> <span style="float:right"><a href="#parallel.execpol">[parallel.execpol]</a></span></header>
      
  

  <cxx-section id="parallel.execpol.synopsis">
    

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

<pre>#include &lt;execution&gt;

namespace std::experimental {
inline namespace parallelism_v2 {
namespace execution {
  <cxx-ref insynopsis="" to="parallel.execpol.unseq">// <i><a title="parallel.execpol.unseq" href="#parallel.execpol.unseq">5.2</a>, Unsequenced execution policy</i></cxx-ref>
  class unsequenced_policy;

  <cxx-ref insynopsis="" to="parallel.execpol.vec">// <i><a title="parallel.execpol.vec" href="#parallel.execpol.vec">5.3</a>, Vector execution policy</i></cxx-ref>
  class vector_policy;

  <cxx-ref insynopsis="" to="parallel.execpol.objects">// <i><a title="parallel.execpol.objects" href="#parallel.execpol.objects">5.4</a>, Execution policy objects</i></cxx-ref>
  inline constexpr unsequenced_policy unseq{ <i>unspecified</i> };
  inline constexpr <ins>vector_policy vec</ins><del>parallel_policy par</del>{ <i>unspecified</i> };
}
}
}
</pre>
  
    </section>
  </cxx-section>

  <cxx-section id="parallel.execpol.unseq">
    

    <section>
      <header><span class="section-number">5.2</span> <h1 data-bookmark-label="5.2 Unsequenced execution policy">Unsequenced execution policy</h1> <span style="float:right"><a href="#parallel.execpol.unseq">[parallel.execpol.unseq]</a></span></header>
      
    

<pre>class unsequenced_policy{ <i>unspecified</i> };
</pre>

    <p id="parallel.execpol.unseq.1" para_num="1">The class <code>unsequenced_policy</code>
 is an execution policy type used as a unique type to disambiguate 
parallel algorithm overloading and indicate that a parallel algorithm's 
execution may be vectorized, e.g., executed on a single thread using 
instructions that operate on multiple data items.</p>

    <p id="parallel.execpol.unseq.2" para_num="2">The invocations of element access functions in parallel algorithms invoked with an execution policy of type <code>unsequenced_policy</code>
 are permitted to execute in an unordered fashion in the calling thread,
 unsequenced with respect to one another within the calling thread.
    <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    This means that multiple function object invocations may be interleaved on a single thread.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note></p>

    <p id="parallel.execpol.unseq.3" para_num="3"><cxx-note><span class="nowrap">[ <em>Note:</em></span>
    This overrides the usual guarantee from the C++ Standard, <cxx-ref in="cxx" to="intro.execution">C++17 <span title="intro.execution">§4.6</span></cxx-ref> [intro.execution] that function executions do not overlap with one another.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note></p>

    <p id="parallel.execpol.unseq.4" para_num="4">During the execution of a parallel algorithm with the <code>experimental::execution::unsequenced_policy</code> policy, if the invocation of an element access function exits via an uncaught exception, <code>terminate()</code> <ins>will</ins><del>shall</del> be called.</p>

  
    </section>
  </cxx-section>

  <cxx-section id="parallel.execpol.vec">
    

    <section>
      <header><span class="section-number">5.3</span> <h1 data-bookmark-label="5.3 Vector execution policy">Vector execution policy</h1> <span style="float:right"><a href="#parallel.execpol.vec">[parallel.execpol.vec]</a></span></header>
      
    

<pre>class vector_policy{ <i>unspecified</i> };
</pre>

    <p id="parallel.execpol.vec.1" para_num="1">The class <code>vector_policy</code>
 is an execution policy type used as a unique type to disambiguate 
parallel algorithm overloading and indicate that a parallel algorithm's 
execution may be vectorized. Additionally, such vectorization will 
result in an execution that respects the sequencing constraints of 
wavefront application ([parallel.alg.general.wavefront]). <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    The implementation thus makes stronger guarantees than for <code>unsequenced_policy</code>, for example.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note></p>

    <p id="parallel.execpol.vec.2" para_num="2">The invocations of element access functions in parallel algorithms invoked with an execution policy of type <code>vector_policy</code>
 are permitted to execute in unordered fashion in the calling thread, 
unsequenced with respect to one another within the calling thread, 
subject to the sequencing constraints of wavefront application (<cxx-ref to="parallel.alg.general.wavefront"><a title="parallel.alg.general.wavefront" href="#parallel.alg.general.wavefront"></a></cxx-ref>) for the last argument to <code>for_loop</code><ins>, for_loop_n,</ins> <del>or </del><code>for_loop_strided</code><ins>, or <code>for_loop_strided_n</code>.</ins></p>

    <p id="parallel.execpol.vec.3" para_num="3">During the execution of a parallel algorithm with the <code>experimental::execution::vector_policy</code> policy, if the invocation of an element access function exits via an uncaught exception, <code>terminate()</code> <ins>will</ins><del>shall</del> be called.</p>

  
    </section>
  </cxx-section>

  <cxx-section id="parallel.execpol.objects">
    

    <section>
      <header><span class="section-number">5.4</span> <h1 data-bookmark-label="5.4 Execution policy objects">Execution policy objects</h1> <span style="float:right"><a href="#parallel.execpol.objects">[parallel.execpol.objects]</a></span></header>
      
    

<pre><ins>inline </ins>constexpr execution::unsequenced_policy unseq{};
<ins>inline </ins>constexpr execution::vector_policy vec{};
</pre>

    <p id="parallel.execpol.objects.1" para_num="1">The header <code>&lt;experimental/execution&gt;</code> declares a global object associated with each type of execution policy defined by this Technical Specification.</p>
  
    </section>
  </cxx-section>

    </section>
  </cxx-clause>

<cxx-clause id="parallel.exceptions">
    

    <section>
      <header><span class="section-number">6</span> <h1 data-bookmark-label="6 Parallel exceptions">Parallel exceptions</h1> <span style="float:right"><a href="#parallel.exceptions">[parallel.exceptions]</a></span></header>
      
  
    <cxx-section id="parallel.exceptions.synopsis">
    

    <section>
      <header><span class="section-number">6.1</span> <h1 data-bookmark-label="6.1 Header &lt;experimental/exception_list&gt; synopsis">Header <code>&lt;experimental/exception_list&gt;</code> synopsis</h1> <span style="float:right"><a href="#parallel.exceptions.synopsis">[parallel.exceptions.synopsis]</a></span></header>
      
      
      <pre>namespace std::experimental {
inline namespace parallelism_v2 {

  class exception_list : public exception
  {
    public:
      using iterator = <em>unspecified</em>;
  
      size_t size() const noexcept;
      iterator begin() const noexcept;
      iterator end() const noexcept;

      const char* what() const noexcept override;
  };
}
}
      </pre>

      <p id="parallel.exceptions.synopsis.1" para_num="1">
        The class <code>exception_list</code> owns a sequence of <code>exception_ptr</code> objects.
      </p>

      <p id="parallel.exceptions.synopsis.2" para_num="2">
        The type <code>exception_list::iterator</code> <ins>fulfills</ins><del>shall fulfill</del> the requirements of
        <code>ForwardIterator</code>.
      </p>

      <cxx-function id="parallel.exceptions.synopsis.3" para_num="3">
    
    <pre><code><cxx-signature>size_t size() const noexcept;</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.exceptions.synopsis.4" para_num="4">
    
    <dt>Returns:</dt><dd>
          The number of <code>exception_ptr</code> objects contained within the <code>exception_list</code>.
        </dd>
  </cxx-returns>

        <cxx-complexity id="parallel.exceptions.synopsis.5" para_num="5">
    
    <dt>Complexity:</dt><dd>
          Constant time.
        </dd>
  </cxx-complexity>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.exceptions.synopsis.6" para_num="6">
    
    <pre><code><cxx-signature>iterator begin() const noexcept;</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.exceptions.synopsis.7" para_num="7">
    
    <dt>Returns:</dt><dd>
          An iterator referring to the first <code>exception_ptr</code> object contained within the <code>exception_list</code>.
        </dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.exceptions.synopsis.8" para_num="8">
    
    <pre><code><cxx-signature>iterator end() const noexcept;</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.exceptions.synopsis.9" para_num="9">
    
    <dt>Returns:</dt><dd>
          An iterator that is past the end of the owned sequence.
        </dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.exceptions.synopsis.10" para_num="10">
    
    <pre><code><cxx-signature>const char* what() const noexcept override;</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.exceptions.synopsis.11" para_num="11">
    
    <dt>Returns:</dt><dd>
          An implementation-defined NTBS.
        </dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

    </section>
  </cxx-clause>

<cxx-clause id="parallel.alg">
    

    <section>
      <header><span class="section-number">7</span> <h1 data-bookmark-label="7 Parallel algorithms">Parallel algorithms</h1> <span style="float:right"><a href="#parallel.alg">[parallel.alg]</a></span></header>
      
  

  <cxx-section id="parallel.alg.wavefront">
    

    <section>
      <header><span class="section-number">7.1</span> <h1 data-bookmark-label="7.1 Wavefront Application">Wavefront Application</h1> <span style="float:right"><a href="#parallel.alg.wavefront">[parallel.alg.wavefront]</a></span></header>
      
    
    <p id="parallel.alg.wavefront.1" para_num="1">
      For the purposes of this section, an <i>evaluation</i> is a value computation or side effect of
      an expression, or an execution of a statement. Initialization of a temporary object is considered a
      subexpression of the expression that necessitates the temporary object.
    </p>

    <p id="parallel.alg.wavefront.2" para_num="2">
      An evaluation A <i>contains</i> an evaluation B if:

      </p><ul>
      <li>A and B are not potentially concurrent ([intro.races]); and</li>
      <li>the start of A is the start of B or the start of A is sequenced before the start of B; and</li>
      <li>the completion of B is the completion of A or the completion of B is sequenced before the completion of A.</li>
      </ul>

      <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    This includes evaluations occurring in function invocations.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
    <p id="parallel.alg.wavefront.3" para_num="3"></p>

    <p id="parallel.alg.wavefront.4" para_num="4">
      An evaluation A is <i>ordered before</i> an evaluation B if A is deterministically
      sequenced before B. <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    If A is indeterminately sequenced with respect to B
      or A and B are unsequenced, then A is not ordered before B and B is not ordered
      before A. The ordered before relationship is transitive.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
    </p>

    <p id="parallel.alg.wavefront.5" para_num="5">
      For an evaluation A ordered before an evaluation B, both contained in the same
      invocation of an element access function, A is a <i>vertical antecedent</i> of B if:

      </p><ul>
      <li>there exists an evaluation S such that:
        <ul>
          <li>S contains A, and</li>
          <li>S contains all evaluations C (if any) such that A is ordered before C and C is ordered before B,</li>
          <li>but S does not contain B, and</li>
        </ul>
      </li>
      <li>
        control reached B from A without executing any of the following:
        <ul>
          <li>a <code>goto</code> statement or <code>asm</code> declaration that jumps to a statement outside of S, or</li>
          <li>a <code>switch</code> statement executed within S that transfers control into a substatement of a nested selection or iteration statement, or</li>
          <li>a <code>throw</code> <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    even if caught
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>, or</li>
          <li>a <code>longjmp</code>.
        </li></ul>
      </li>
      </ul>

      <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    
        Vertical antecedent is an irreflexive, antisymmetric, nontransitive relationship between two evaluations.
        Informally, A is a vertical antecedent of B if A is sequenced immediately before B or A is nested zero or
        more levels within a statement S that immediately precedes B.
      
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
    <p id="parallel.alg.wavefront.6" para_num="6"></p>

    <p id="parallel.alg.wavefront.7" para_num="7">
      In the following, <i>X<sub>i</sub></i> and <i>X<sub>j</sub></i> refer to evaluations of the <i>same</i> expression
      or statement contained in the application of an element access function corresponding to the i<sup>th</sup> and
      j<sup>th</sup> elements of the input sequence. <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    There might be several evaluations <i>X<sub>k</sub></i>,
      <i>Y<sub>k</sub></i>, etc. of a single expression or statement in application <i>k</i>, for example, if the
      expression or statement appears in a loop within the element access function.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
    </p>

    <p id="parallel.alg.wavefront.8" para_num="8">
      <i>Horizontally matched</i> is an equivalence relationship between two evaluations of the same expression. An
      evaluation B<sub>i</sub> is <i>horizontally matched</i> with an evaluation B<sub>j</sub> if:

      </p><ul>
        <li>both are the first evaluations in their respective applications of the element access function, or</li>
        <li>there exist horizontally matched evaluations A<sub>i</sub> and A<sub>j</sub> that are vertical antecedents of evaluations B<sub>i</sub> and B<sub>j</sub>, respectively.
      </li></ul>

      <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    
        <i>Horizontally matched</i> establishes a theoretical <i>lock-step</i> relationship between evaluations in different applications of an element access function.
      
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
    <p id="parallel.alg.wavefront.9" para_num="9"></p>

    <p id="parallel.alg.wavefront.10" para_num="10">
      Let <i>f</i> be a function called for each argument list in a sequence of argument lists.
      <i>Wavefront application</i> of <i>f</i> requires that evaluation A<sub>i</sub> be sequenced
      before evaluation B<sub><ins>j</ins><del>i</del></sub> if i &lt; j and and:

      </p><ul>
        <li>A<sub>i</sub> is sequenced before some evaluation B<sub>i</sub> and B<sub>i</sub> is horizontally matched with B<sub>j</sub>, or</li>
        <li>A<sub>i</sub> is horizontally matched with some evaluation A<sub>j</sub> and A<sub>j</sub> is sequenced before B<sub>j<sub>.</sub></sub></li>
      </ul>

      <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    
        <i>Wavefront application</i> guarantees that parallel applications i and j execute such that progress on application j never gets <i>ahead</i> of application i.
      
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>

      <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    
        The relationships between A<sub>i</sub> and B<sub>i</sub> and between A<sub>j</sub> and B<sub>j</sub> are <i>sequenced before</i>, not <i>vertical antecedent</i>.
      
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
    <p id="parallel.alg.wavefront.11" para_num="11"></p>
  
    </section>
  </cxx-section>

  <cxx-section id="parallel.alg.ops">
    

    <section>
      <header><span class="section-number">7.2</span> <h1 data-bookmark-label="7.2 Non-Numeric Parallel Algorithms">Non-Numeric Parallel Algorithms</h1> <span style="float:right"><a href="#parallel.alg.ops">[parallel.alg.ops]</a></span></header>
      
    

    <cxx-section id="parallel.alg.ops.synopsis">
    

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

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

namespace std::experimental {
inline namespace parallelism_v2 {

namespace execution {
  <cxx-ref insynopsis="" to="parallel.alg.novec">// <i><a title="parallel.alg.novec" href="#parallel.alg.novec">7.2.5</a>, No vec</i></cxx-ref>
  template&lt;class F&gt;
    auto no_vec(F&amp;&amp; f) noexcept -&gt; decltype(std::forward&lt;F&gt;(f)());

  <cxx-ref insynopsis="" to="parallel.alg.ordupdate.class">// <i><a title="parallel.alg.ordupdate.class" href="#parallel.alg.ordupdate.class">7.2.6</a>, Ordered update class</i></cxx-ref>
  template&lt;class T&gt;
    class ordered_update_t;

  <cxx-ref insynopsis="" to="parallel.alg.ordupdate.func">// <i><a title="parallel.alg.ordupdate.func" href="#parallel.alg.ordupdate.func">7.2.7</a>, Ordered update function template</i></cxx-ref>
  template&lt;class T&gt;
    ordered_update_t&lt;T&gt; ordered_update(T&amp; ref) noexcept;
}

// Exposition only: Suppress template argument deduction.
template&lt;class T&gt; struct no_deduce { using type = T; };
template&lt;class T&gt; struct no_dedu<ins>c</ins><del>d</del>e_t = typename no_deduce&lt;T&gt;::type;

<cxx-ref insynopsis="" to="parallel.alg.reductions">// <i><a title="parallel.alg.reductions" href="#parallel.alg.reductions">7.2.2</a>, Reductions</i></cxx-ref> Support for reductions
template&lt;class T, class BinaryOperation&gt;
  <em>unspecified</em> reduction(T&amp; var, const T&amp; identity, BinaryOperation combiner);
template&lt;class T&gt;
  <em>unspecified</em> reduction_plus(T&amp; var);
template&lt;class T&gt;
  <em>unspecified</em> reduction_multiplies(T&amp; var);
template&lt;class T&gt;
  <em>unspecified</em> reduction_bit_and(T&amp; var);
template&lt;class T&gt;
  <em>unspecified</em> reduction_bit_or(T&amp; var);
template&lt;class T&gt;
  <em>unspecified</em> reduction_bit_xor(T&amp; var);
template&lt;class T&gt;
  <em>unspecified</em> reduction_min(T&amp; var);
template&lt;class T&gt;
  <em>unspecified</em> reduction_max(T&amp; var);

<cxx-ref insynopsis="" to="parallel.alg.inductions">// <i><a title="parallel.alg.inductions" href="#parallel.alg.inductions">7.2.3</a>, Inductions</i></cxx-ref> Support for inductions
template&lt;class T&gt;
  <em>unspecified</em> induction(T&amp;&amp; var);
template&lt;class T&gt;
  <em>unspecified</em> induction(T&amp;&amp; var, S stride);

<cxx-ref insynopsis="" to="parallel.alg.forloop">// <i><a title="parallel.alg.forloop" href="#parallel.alg.forloop">7.2.4</a>, For loop</i></cxx-ref> for_loop
template&lt;class I, class... Rest&gt;
  void for_loop(no_deduce_t&lt;I&gt; start, I finish, Rest&amp;&amp;... rest);
template&lt;class ExecutionPolicy,
         class I, class... Rest&gt;
  void for_loop(ExecutionPolicy&amp;&amp; exec,
                no_deduce_t&lt;I&gt; start, I finish, Rest&amp;&amp;... rest);
template&lt;class I, class S, class... Rest&gt;
  void for_loop_strided(no_deduce_t&lt;I&gt; start, I finish,
                        S stride, Rest&amp;&amp;... rest);
template&lt;class ExecutionPolicy,
         class I, class S, class... Rest&gt;
  void for_loop_strided(ExecutionPolicy&amp;&amp; exec,
                        no_deduce_t&lt;I&gt; start, I finish,
                        S stride, Rest&amp;&amp;... rest);
template&lt;class I, class Size, class... Rest&gt;
  void for_loop_n(I start, Size n, Rest&amp;&amp;... rest);
template&lt;class ExecutionPolicy,
         class I, class Size, class... Rest&gt;
  void for_loop_n(ExecutionPolicy&amp;&amp; exec,
                  I start, Size n, Rest&amp;&amp;... rest);
template&lt;class I, class Size, class S, class... Rest&gt;
  void for_loop_n_strided(I start, Size n, S stride, Rest&amp;&amp;... rest);
template&lt;class ExecutionPolicy,
         class I, class Size, class S, class... Rest&gt;
  void for_loop_n_strided(ExecutionPolicy&amp;&amp; exec,
                          I start, Size n, S stride, Rest&amp;&amp;... rest);
}
}
</pre>
    
    </section>
  </cxx-section>

    <cxx-section id="parallel.alg.reductions">
    

    <section>
      <header><span class="section-number">7.2.2</span> <h1 data-bookmark-label="7.2.2 Reductions">Reductions</h1> <span style="float:right"><a href="#parallel.alg.reductions">[parallel.alg.reductions]</a></span></header>
      
      

      <p id="parallel.alg.reductions.1" para_num="1">
        Each of the function templates in this subclause ([parallel.alg.reductions]) returns a <em>reduction object</em>
        of unspecified type having a <em>reduction value type</em> and encapsulating a <em>reduction identity</em> value for the reduction, a
        <em>combiner</em> function object, and a <em>live-out object</em> from which the initial value is obtained and into which the final
        value is stored.
      </p>

      <p id="parallel.alg.reductions.2" para_num="2">
        An algorithm uses reduction objects by allocating an unspecified number of instances, known as <em>accumulators</em>, of the reduction value
        type. <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    An implementation might, for example, allocate an accumulator for each thread in its private thread pool.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
        Each accumulator is initialized with the object’s reduction 
identity, except that the live-out object (which was initialized by the
        caller) comprises one of the accumulators. The algorithm passes a
 reference to an accumulator to each application of an element-access
        function, ensuring that no two concurrently executing 
invocations share the same accumulator. An accumulator can be shared 
between two
        applications that do not execute concurrently, but 
initialization is performed only once per accumulator.
      </p>

      <p id="parallel.alg.reductions.3" para_num="3">
        Modifications to the accumulator by the application of element 
access functions accrue as partial results. At some point before the 
algorithm
        returns, the partial results are combined, two at a time, using 
the reduction object’s combiner operation until a single value remains, 
which
        is then assigned back to the live-out object. <cxx-note><span class="nowrap">[ <em>Note:</em></span>
     in order to produce useful results, modifications to the accumulator should be limited
        to commutative operations closely related to the combiner operation. For example if the combiner is <code>plus&lt;T&gt;</code>, incrementing
        the accumulator would be consistent with the combiner but doubling it or assigning to it would not.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
      </p>

      <cxx-function id="parallel.alg.reductions.4" para_num="4">
    
    <pre><code><cxx-signature>template&lt;class T, class BinaryOperation&gt;
<em>unspecified</em> reduction(T&amp; var, const T&amp; identity, BinaryOperation combiner);</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-requires id="parallel.alg.reductions.5" para_num="5">
    
    <dt>Requires:</dt><dd>T shall meet the requirements of <code>CopyConstructible</code> and <code>MoveAssignable</code>. The expression <code>var = combiner(var, var)</code> shall be well-formed.</dd>
  </cxx-requires>

        <cxx-returns id="parallel.alg.reductions.6" para_num="6">
    
    <dt>Returns:</dt><dd>a reduction object of unspecified type having reduction value type <code>T</code>, reduction identity <code>identity</code>, combiner function object <code>combiner</code>, and using the object referenced by <code>var</code> as its live-out object.</dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.alg.reductions.7" para_num="7">
    
    <pre><code><cxx-signature>template&lt;class T&gt;
<em>unspecified</em> reduction_plus(T&amp; var);</cxx-signature><cxx-signature>template&lt;class T&gt;
<em>unspecified</em> reduction_multiplies(T&amp; var);</cxx-signature><cxx-signature>template&lt;class T&gt;
<em>unspecified</em> reduction_bit_and(T&amp; var);</cxx-signature><cxx-signature>template&lt;class T&gt;
<em>unspecified</em> reduction_bit_or(T&amp; var);</cxx-signature><cxx-signature>template&lt;class T&gt;
<em>unspecified</em> reduction_bit_xor(T&amp; var);</cxx-signature><cxx-signature>template&lt;class T&gt;
<em>unspecified</em> reduction_min(T&amp; var);</cxx-signature><cxx-signature>template&lt;class T&gt;
<em>unspecified</em> reduction_max(T&amp; var);</cxx-signature></code></pre>

    <dl>
      
        
        
        
        
        
        
        

        <cxx-requires id="parallel.alg.reductions.8" para_num="8">
    
    <dt>Requires:</dt><dd>T shall meet the requirements of <code>CopyConstructible</code> and <code>MoveAssignable</code>.&gt;</dd>
  </cxx-requires>

        <cxx-returns id="parallel.alg.reductions.9" para_num="9">
    
    <dt>Returns:</dt><dd>a reduction object of unspecified type having reduction value type <code>T</code>, reduction identity and combiner operation as specified in table <cxx-ref to="reduction-identities-and-combiner-operations"><a title="reduction-identities-and-combiner-operations" href="#reduction-identities-and-combiner-operations">Table 2</a></cxx-ref> and using the object referenced by <code>var</code> as its live-out object.</dd>
  </cxx-returns>

        <table is="cxx-table" class="column-rules" id="reduction-identities-and-combiner-operations">
    

    <caption>Table 2 — <wbr><span>Reduction identities and combiner operations</span></caption>
    
          
          <thead>
            <tr>
              <th>Function</th>
              <th>Reduction Identity</th>
              <th>Combiner Operation</th>
            </tr>
            <tr>
              <th><code>reduction_plus</code></th>
              <th><code>T()</code></th>
              <th><code>x + y</code></th>
            </tr>
            <tr>
              <th><code>reduction_multiplies</code></th>
              <th><code>T(1)</code></th>
              <th><code>x * y</code></th>
            </tr>
            <tr>
              <th><code>reduction_bit_and</code></th>
              <th><code>(~T())</code></th>
              <th><code>X &amp; y</code></th>
            </tr>
            <tr>
              <th><code>reduction_bit_or</code></th>
              <th><code>T()</code></th>
              <th><code>x | y</code></th>
            </tr>
            <tr>
              <th><code>reduction_bit_xor</code></th>
              <th><code>T()</code></th>
              <th><code>x ^ y</code></th>
            </tr>
            <tr>
              <th><code>reduction_min</code></th>
              <th><code>var</code></th>
              <th><code>min(x, y)</code></th>
            </tr>
            <tr>
              <th><code>reduction_max</code></th>
              <th><code>var</code></th>
              <th><code>max(x, y)</code></th>
            </tr>
          </thead>
        
  </table>

        <cxx-example>
    
    <span class="nowrap">[ <em>Example:</em></span>
    The following code updates each element of <code>y</code> and sets <code>s</code> <ins>to</ins><del>ot</del> the sum of the squares.
<pre>extern int n;
extern float x[], y[], a;
float s = 0;
for_loop(execution::vec, 0, n,
    reduction(s, 0.0f, plus&lt;&gt;()),
    [&amp;](int i, float&amp; accum) {
            y[i] += a*x[i];
            accum += y[i]*y[i];
    }
);
</pre>
        
    <span class="nowrap">— <em>end example</em> ]</span>
  </cxx-example>
        
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

    <cxx-section id="parallel.alg.inductions">
    

    <section>
      <header><span class="section-number">7.2.3</span> <h1 data-bookmark-label="7.2.3 Inductions">Inductions</h1> <span style="float:right"><a href="#parallel.alg.inductions">[parallel.alg.inductions]</a></span></header>
      
      

      <p id="parallel.alg.inductions.1" para_num="1">
        Each of the function templates in this section return an <em>induction object</em> of unspecified type having an <em>induction
        value type</em> and encapsulating an initial value <em>i</em> of that type and, optionally, a <em>stride</em>.
      </p>

      <p id="parallel.alg.inductions.2" para_num="2">
        For each element in the input range, an algorithm over input sequence <em>S</em> computes an <em>induction value</em> from an induction variable
        and ordinal position <em>p</em> within <em>S</em> by the formula <em>i + p * stride</em> if a stride was specified or <em>i + p</em> otherwise. This induction value is
        passed to the element access function.
      </p>

      <p id="parallel.alg.inductions.3" para_num="3">
        An induction object may refer to a <em>live-out</em> object to hold the final value of the induction sequence. When the algorithm using the induction
        object completes, the live-out object is assigned the value <em>i + n * stride</em>, where <em>n</em> is the number of elements in the input range.
      </p>

      <cxx-function id="parallel.alg.inductions.4" para_num="4">
    
    <pre><code><cxx-signature>template&lt;class T&gt;
<em>unspecified</em> induction(T&amp;&amp; var);</cxx-signature><cxx-signature>template&lt;class T, class S&gt;
<em>unspecified</em> induction(T&amp;&amp; var, S stride);</cxx-signature></code></pre>

    <dl>
      
        

        

        <cxx-returns id="parallel.alg.inductions.5" para_num="5">
    
    <dt>Returns:</dt><dd>
          an induction object with induction value type <code>remove_cv_t<ins>&lt;</ins><del>&gt;</del>remove_reference_t<ins>&lt;</ins><del>&gt;</del>T<ins>&gt;&gt;</ins><del>&lt;&lt;</del></code>,
          initial value <code>var</code>, and (if specified) stride <code>stride</code>. If <code>T</code> is an lvalue reference
          to non-<code>const</code> type, then the object referenced by <code>var</code> becomes the live-out object for the
          induction object; otherwise there is no live-out object.
        </dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

    <cxx-section id="parallel.alg.forloop">
    

    <section>
      <header><span class="section-number">7.2.4</span> <h1 data-bookmark-label="7.2.4 For loop">For loop</h1> <span style="float:right"><a href="#parallel.alg.forloop">[parallel.alg.forloop]</a></span></header>
      
      

      <cxx-function id="parallel.alg.forloop.1" para_num="1">
    
    <pre><code><cxx-signature>template&lt;class I, class... Rest&gt;
void for_loop(no_deduce_t&lt;I&gt; start, I finish, Rest&amp;&amp;... rest);</cxx-signature><cxx-signature>template&lt;class ExecutionPolicy,
      class I, class... Rest&gt;
void for_loop(ExecutionPolicy&amp;&amp; exec,
              no_deduce_t&lt;I&gt; start, I finish, Rest&amp;&amp;... rest);

</cxx-signature><cxx-signature>template&lt;class I, class S, class... Rest&gt;
void for_loop_strided(no_deduce_t&lt;I&gt; start, I finish,
                      S stride, Rest&amp;&amp;... rest);</cxx-signature><cxx-signature>template&lt;class ExecutionPolicy,
      class I, class S, class... Rest&gt;
void for_loop_strided(ExecutionPolicy&amp;&amp; exec,
                      no_deduce_t&lt;I&gt; start, I finish,
                      S stride, Rest&amp;&amp;... rest);

</cxx-signature><cxx-signature>template&lt;class I, class Size, class... Rest&gt;
void for_loop_n(I start, Size n, Rest&amp;&amp;... rest);</cxx-signature><cxx-signature>template&lt;class ExecutionPolicy,
      class I, class Size, class... Rest&gt;
void for_loop_n(ExecutionPolicy&amp;&amp; exec,
                I start, Size n, Rest&amp;&amp;... rest);
          
</cxx-signature><cxx-signature>template&lt;class I, class Size, class S, class... Rest&gt;
void for_loop_n_strided(I start, Size n, S stride, Rest&amp;&amp;... rest);</cxx-signature><cxx-signature>template&lt;class ExecutionPolicy, 
      class I, class Size, class S, class... Rest&gt;
void for_loop_n_strided(ExecutionPolicy&amp;&amp; exec,
                        I start, Size n, S stride, Rest&amp;&amp;... rest);</cxx-signature></code></pre>

    <dl>
      
        

        

        

        

        

        

        

        

        <cxx-requires id="parallel.alg.forloop.2" para_num="2">
    
    <dt>Requires:</dt><dd>
          For the overloads with an <code>ExecutionPolicy</code>, <code>I</code> shall be an integral type
          or meet the requirements of a forward iterator type; otherwise, <code>I</code> shall be an integral
          type or meet the requirements of an input iterator type. <code>Size</code> shall be an integral type
          and <code>n</code> shall be non-negative. <code>S</code> shall have integral type and <code>stride</code>
          shall have non-zero value. <code>stride</code> shall be negative only if <code>I</code> has integral
          type or meets the requirements of a bidirectional iterator. The <code>rest</code> parameter pack shall
          have at least one element, comprising objects returned by invocations of <code>reduction</code>
          ([parallel.alg.reduction]) and/or <code>induction</code> ([parallel.alg.induction]) function templates
          followed by exactly one invocable element-access function, <em>f</em>. For the overloads with an
          <code>ExecutionPolicy</code>, <em>f</em> shall meet the requirements of <code>CopyConstructible</code>;
          otherwise, <em>f</em> shall meet the requirements of <code>MoveConstructible</code>.
        </dd>
  </cxx-requires>

        <cxx-effects id="parallel.alg.forloop.3" para_num="3">
    
    <dt>Effects:</dt><dd>
          Applies <em>f</em> to each element in the <em>input sequence</em>, as described below, with additional
          arguments corresponding to the reductions and inductions in the <code>rest</code> parameter pack. The
          length of the input sequence is:

          <ul>
            <li>
              <code>n</code>, if specified,
            </li>

            <li>
              otherwise <code>finish - start</code> if neither <code>n</code> nor <code>stride</code> is specified,
            </li>

            <li>
              otherwise <code>1 + (finish-start-1)/stride</code> if <code>stride</code> is positive,
            </li>

            <li>
              otherwise <code>1 + (start-finish-1)/-stride</code>.
            </li>
          </ul>

          The first element in the input sequence is <code>start</code>. Each subsequent element is generated by adding
          <code>stride</code> to the previous element, if <code>stride</code> is specified, otherwise by incrementing
          the previous element. <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    As described in the C++ standard, section [algorithms.general], arithmetic
          on non-random-access iterators is performed using <ins><code>advance</code></ins><del>advance</del> and <ins><code>distance</code></ins><del>distance</del>.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note> <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    The order of the
          elements of the input sequence is important for determining ordinal position of an application of <em>f</em>,
          even though the applications themselves may be unordered.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note><p></p>

          The first argument to <em>f</em> is an element from the input sequence. <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    if <code>I</code> is an
          iterator type, the iterators in the input sequence are not dereferenced before
          being passed to <em>f</em>.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note> For each member of the <ins><code>rest</code></ins><del>rest</del> parameter pack
          excluding <em>f</em>, an additional argument is passed to each application of <em>f</em> as follows:

          <ul>
            <li>
              If the pack member is an object returned by a call to a reduction function listed in section
              [parallel.alg.reductions], then the additional argument is a reference to an accumulator of that reduction
              object.
            </li>

            <li>
              If the pack member is an object returned by a call to <code>induction</code>, then the additional argument is the
              induction value for that induction object corresponding to the position of the application of <em>f</em> in the input
              sequence.
            </li>
          </ul>
        </dd>
  </cxx-effects>

        <cxx-complexity id="parallel.alg.forloop.4" para_num="4">
    
    <dt>Complexity:</dt><dd>
          Applies <em>f</em> exactly once for each element of the input sequence.
        </dd>
  </cxx-complexity>

        <cxx-remarks id="parallel.alg.forloop.5" para_num="5">
    
    <dt>Remarks:</dt><dd>
          If <em>f</em> returns a result, the result is ignored.
        </dd>
  </cxx-remarks>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

    <cxx-section id="parallel.alg.novec">
    

    <section>
      <header><span class="section-number">7.2.5</span> <h1 data-bookmark-label="7.2.5 No vec">No vec</h1> <span style="float:right"><a href="#parallel.alg.novec">[parallel.alg.novec]</a></span></header>
      
      

      <cxx-function id="parallel.alg.novec.1" para_num="1">
    
    <pre><code><cxx-signature>template&lt;class F&gt;
auto no_vec(F&amp;&amp; f) noexcept -&gt; decltype(std::forward&lt;F&gt;(f)());</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-effects id="parallel.alg.novec.2" para_num="2">
    
    <dt>Effects:</dt><dd>
          Evaluates <code>std::forward&gt;F&lt;(f)()</code>. When invoked within an element access function
          in a parallel algorithm using <code>vector_policy</code>, if two calls to <code>no_vec</code> are
          horizontally matched within a wavefront application of an element access function over input
          sequence S, then the execution of <code>f</code> in the application for one element in S is
          sequenced before the execution of <code>f</code> in the application for a subsequent element in
          S; otherwise, there is no effect on sequencing.
        </dd>
  </cxx-effects>

        <cxx-returns id="parallel.alg.novec.3" para_num="3">
    
    <dt>Returns:</dt><dd>
          the result of <code>f</code>.
        </dd>
  </cxx-returns>
        
        <cxx-notes id="parallel.alg.novec.4" para_num="4">
    
    <dt>Notes:</dt><dd>
          If <code>f</code> exits via an exception, then <code>terminate</code> will be called, consistent
          with all other potentially-throwing operations invoked with <code>vector_policy</code> execution.

          <cxx-example>
    
    <span class="nowrap">[ <em>Example:</em></span>
    
            <pre>extern int* p;
for_loop(vec, 0, n[&amp;](int i) {
  y[i] +=y[i+1];
  if(y[i] &lt; 0) {
    no_vec([]{
      *p++ = i;
    });
  }
});</pre>

            The updates <code>*p++ = i</code> will occur in the same order as if the policy were <code>seq</code>.
          
    <span class="nowrap">— <em>end example</em> ]</span>
  </cxx-example>
        </dd>
  </cxx-notes>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

    <cxx-section id="parallel.alg.ordupdate.class">
    

    <section>
      <header><span class="section-number">7.2.6</span> <h1 data-bookmark-label="7.2.6 Ordered update class">Ordered update class</h1> <span style="float:right"><a href="#parallel.alg.ordupdate.class">[parallel.alg.ordupdate.class]</a></span></header>
      
      

<pre>class ordered_update_t {
  T&amp; ref_; // exposition only
public:
  ordered_update_t(T&amp; loc) noexcept
    : ref_(loc) {}
  ordered_update_t(const ordered_update_t&amp;) = delete;
  ordered_update_t&amp; operator=(const ordered_update_t&amp;) = delete;

  template &lt;class U&gt;
    auto operator=(U rhs) const noexcept
      { return no_vec([&amp;]{ return ref_ = std::move(rhs); }); }
  template &lt;class U&gt;
    auto operator+=(U rhs) const noexcept
      { return no_vec([&amp;]{ return ref_ += std::move(rhs); }); }
  template &lt;class U&gt;
    auto operator-=(U rhs) const noexcept
      { return no_vec([&amp;]{ return ref_ -= std::move(rhs); }); }
  template &lt;class U&gt;
    auto operator*=(U rhs) const noexcept
      { return no_vec([&amp;]{ return ref_ *= std::move(rhs); }); }
  template &lt;class U&gt;
    auto operator/=(U rhs) const noexcept
      { return no_vec([&amp;]{ return ref_ /= std::move(rhs); }); }
  template &lt;class U&gt;
    auto operator%=(U rhs) const noexcept
      { return no_vec([&amp;]{ return ref_ %= std::move(rhs); }); }
  template &lt;class U&gt;
    auto operator&gt;&gt;=(U rhs) const noexcept
      { return no_vec([&amp;]{ return ref_ &gt;&gt;= std::move(rhs); }); }
  template &lt;class U&gt;
    auto operator&lt;&lt;=(U rhs) const noexcept
      { return no_vec([&amp;]{ return ref_ &lt;&lt;= std::move(rhs); }); }
  template &lt;class U&gt;
    auto operator&amp;=(U rhs) const noexcept
      { return no_vec([&amp;]{ return ref_ &amp;= std::move(rhs); }); }
  template &lt;class U&gt;
    auto operator^=(U rhs) const noexcept
      { return no_vec([&amp;]{ return ref_ ^= std::move(rhs); }); }
  template &lt;class U&gt;
    auto operator|=(U rhs) const noexcept
      { return no_vec([&amp;]{ return ref_ |= std::move(rhs); }); }

  auto operator++() const noexcept
    { return no_vec([&amp;]{ return ++ref_; }); }
  auto operator++(int) const noexcept
    { return no_vec([&amp;]{ return ref_++; }); }
  auto operator--() const noexcept
    { return no_vec([&amp;]{ return --ref_; }); }
  auto operator--(int) const noexcept
    { return no_vec([&amp;]{ return ref_--; }); }
};
</pre>

      <p id="parallel.alg.ordupdate.class.1" para_num="1">
      An object of type <code>ordered_update_t&lt;T&gt;</code> is a proxy for an object of type T
        intended to be used within a parallel application of an element access function using a
        policy object of type <code>vector_policy</code>. Simple increments, assignments, and compound
        assignments to the object are forwarded to the proxied object, but are sequenced as though
        executed within a <code>no_vec</code> invocation.

        <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    
          The return-value deduction of the forwarded operations results in these operations returning by
          value, not reference. This formulation prevents accidental collisions on accesses to the return
          value.
        
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
      </p>
    
    </section>
  </cxx-section>

    <cxx-section id="parallel.alg.ordupdate.func">
    

    <section>
      <header><span class="section-number">7.2.7</span> <h1 data-bookmark-label="7.2.7 Ordered update function template">Ordered update function template</h1> <span style="float:right"><a href="#parallel.alg.ordupdate.func">[parallel.alg.ordupdate.func]</a></span></header>
      
      

      <cxx-function id="parallel.alg.ordupdate.func.1" para_num="1">
    
    <pre><code><cxx-signature>template&lt;T&gt;
ordered_update_t&lt;T&gt; ordered_update(T&amp; loc) noexcept;</cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.alg.ordupdate.func.2" para_num="2">
    
    <dt>Returns:</dt><dd>
          <code>{ loc }</code>.
        </dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

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

    </section>
  </cxx-clause>

<cxx-clause id="parallel.task_block">
    

    <section>
      <header><span class="section-number">8</span> <h1 data-bookmark-label="8 Task Block">Task Block</h1> <span style="float:right"><a href="#parallel.task_block">[parallel.task_block]</a></span></header>
      
  

   <cxx-section id="parallel.task_block.synopsis">
    

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

     <pre>namespace std::experimental {
inline namespace parallelism_v2 {
  class task_cancelled_exception;

  class task_block;

  template&lt;class F&gt;
    void define_task_block(F&amp;&amp; f);

  template&lt;class f&gt;
    void define_task_block_restore_thread(F&amp;&amp; f);
}
}
     </pre>
   
    </section>
  </cxx-section>

   <cxx-section id="parallel.task_block.task_cancelled_exception">
    

    <section>
      <header><span class="section-number">8.2</span> <h1 data-bookmark-label="8.2 Class task_cancelled_exception">Class <code>task_cancelled_exception</code></h1> <span style="float:right"><a href="#parallel.task_block.task_cancelled_exception">[parallel.task_block.task_cancelled_exception]</a></span></header>
      
     
     <pre>namespace std::experimental {
inline namespace parallelism_v2 {

  class task_cancelled_exception : public exception
  {
    public:
      task_cancelled_exception() noexcept;
      virtual const char* what() const noexcept override;
  };
}
}
     </pre>

     <p id="parallel.task_block.task_cancelled_exception.1" para_num="1">
       The class <code>task_cancelled_exception</code> defines the type of objects thrown by
       <code>task_block::run</code> or <code>task_block::wait</code> if they detect than an
       exception is pending within the current parallel block. See <cxx-ref to="parallel.task_block.exceptions"><a title="parallel.task_block.exceptions" href="#parallel.task_block.exceptions">8.5</a></cxx-ref>, below.
     </p>

     <cxx-section id="parallel.task_block.task_cancelled_exception.what">
    

    <section>
      <header><span class="section-number">8.2.1</span> <h1 data-bookmark-label="8.2.1 task_cancelled_exception member function what"><code>task_cancelled_exception</code> member function <code>what</code></h1> <span style="float:right"><a href="#parallel.task_block.task_cancelled_exception.what">[parallel.task_block.task_cancelled_exception.what]</a></span></header>
      
       

       <cxx-function id="parallel.task_block.task_cancelled_exception.what.1" para_num="1">
    
    <pre><code><cxx-signature>virtual const char* what() const noexcept</cxx-signature></code></pre>

    <dl>
      
         

         <cxx-returns id="parallel.task_block.task_cancelled_exception.what.2" para_num="2">
    
    <dt>Returns:</dt><dd>
           An implementation-defined NTBS.
         </dd>
  </cxx-returns>
       
    </dl>
  </cxx-function>
     
    </section>
  </cxx-section>
   
    </section>
  </cxx-section>

   <cxx-section id="parallel.task_block.class">
    

    <section>
      <header><span class="section-number">8.3</span> <h1 data-bookmark-label="8.3 Class task_block">Class <code>task_block</code></h1> <span style="float:right"><a href="#parallel.task_block.class">[parallel.task_block.class]</a></span></header>
      
     
     <pre>namespace std::experimental {
inline namespace parallelism_v2 {

  class task_block
  {
    private:
      ~task_block();

    public:
      task_block(const task_block&amp;) = delete;
      task_block&amp; operator=(const task_block&amp;) = delete;
      void operator&amp;() const = delete;

      template&lt;class F&gt;
        void run(F&amp;&amp; f);

      void wait();
  };
}
}
     </pre>

     <p id="parallel.task_block.class.1" para_num="1">
       The class <code>task_block</code> defines an interface for forking and joining parallel tasks. The <code>define_task_block</code> and <code>define_task_block_restore_thread</code> function templates create an object of type <code>task_block</code> and pass a reference to that object to a user-provided function object.
     </p>

     <p id="parallel.task_block.class.2" para_num="2">
       An object of class <code>task_block</code> cannot be constructed,
 destroyed, copied, or moved except by the implementation of the task 
block library. Taking the address of a <code>task_block</code> object via <code>operator&amp;</code> is ill-formed. Obtaining its address by any other means (including <code>addressof</code>) results in a pointer with an unspecified value; dereferencing such a pointer results in undefined behavior.
     </p>

     <p id="parallel.task_block.class.3" para_num="3">
       A <code>task_block</code> is <em>active</em> if it was created by the nearest enclosing task block, where “task block” refers to an
       invocation of <code>define_task_block</code> or <code>define_task_block_restore_thread</code> and “nearest enclosing” means the most
       recent invocation that has not yet completed. Code designated for execution in another thread by means other
       than the facilities in this section (e.g., using <code>thread</code> or <code>async</code>) are not enclosed in the task block and a
       <code>task_block</code> passed to (or captured by) such code is not active within that code. Performing any operation on a
       <code>task_block</code> that is not active results in undefined behavior.
     </p>

     <p id="parallel.task_block.class.4" para_num="4">
       When the argument to <code>task_block::run</code> is called, no <code>task_block</code> is active, not even the <code>task_block</code> on which <code>run</code> was called.
       (The function object should not, therefore, capture a <code>task_block</code> from the surrounding block.)
     </p>

     <cxx-example>
    
    <span class="nowrap">[ <em>Example:</em></span>
    
     <pre>define_task_block([&amp;](auto&amp; tb) {
  tb.run([&amp;]{
    tb.run([] { f(); });               // Error: tb is not active within run
    define_task_block([&amp;](auto&amp; tb2) { // Define new task block
      tb2.run(f);
      ...
    });
  });
  ...
});
     </pre>
     
    <span class="nowrap">— <em>end example</em> ]</span>
  </cxx-example><pre></pre>

     <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    
       Implementations are encouraged to diagnose the above error at translation time.
     
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>

     <cxx-section id="parallel.task_block.class.run">
    

    <section>
      <header><span class="section-number">8.3.1</span> <h1 data-bookmark-label="8.3.1 task_block member function template run"><code>task_block</code> member function template <code>run</code></h1> <span style="float:right"><a href="#parallel.task_block.class.run">[parallel.task_block.class.run]</a></span></header>
      
     
       
  
       <cxx-function id="parallel.task_block.class.run.1" para_num="1">
    
    <pre><code><cxx-signature>template&lt;class F&gt; void run(F&amp;&amp; f);</cxx-signature></code></pre>

    <dl>
      
         

         <cxx-requires id="parallel.task_block.class.run.2" para_num="2">
    
    <dt>Requires:</dt><dd>
           <code>F</code> shall be <code>MoveConstructible</code>. <code><em>DECAY_COPY</em>(std::forward&lt;F&gt;(f))()</code> shall be a valid expression.
         </dd>
  </cxx-requires>
  
         <cxx-preconditions id="parallel.task_block.class.run.3" para_num="3">
    
    <dt>Preconditions:</dt><dd>
           <code>*this</code> shall be the active <code>task_block</code>.
         </dd>
  </cxx-preconditions>
  
         <cxx-effects id="parallel.task_block.class.run.4" para_num="4">
    
    <dt>Effects:</dt><dd>
           Evaluates <code><em>DECAY_COPY</em>(std::forward&lt;F&gt;(f))()</code>, where <code><em>DECAY_COPY</em>(std::forward&lt;F&gt;(f))</code>
           is evaluated synchronously within the current thread. The call to the resulting copy of the function object is
           permitted to run on an unspecified thread created by the implementation in an unordered fashion relative to
           the sequence of operations following the call to <code>run(f)</code> (the continuation), or indeterminately sequenced
           within the same thread as the continuation. The call to <code>run</code> synchronizes with the call to the function
           object. The completion of the call to the function object synchronizes with the next invocation of <code>wait</code> on
           the same <code>task_block</code> or completion of the nearest enclosing task block (i.e., the <code>define_task_block</code> or
           <code>define_task_block_restore_thread</code> that created this <code>task_block</code>).
         </dd>
  </cxx-effects>
  
         <cxx-throws id="parallel.task_block.class.run.5" para_num="5">
    
    <dt>Throws:</dt><dd>
           <code>task_cancelled_exception</code>, as described in <cxx-ref to="parallel.task_block.exceptions"><a title="parallel.task_block.exceptions" href="#parallel.task_block.exceptions">8.5</a></cxx-ref>.
         </dd>
  </cxx-throws>
  
         <cxx-remarks id="parallel.task_block.class.run.6" para_num="6">
    
    <dt>Remarks:</dt><dd>
           The <code>run</code> function may return on a thread other than the one on which it was called; in such cases,
           completion of the call to <code>run</code> synchronizes with the continuation.
           
           <cxx-note><span class="nowrap">[ <em>Note:</em></span>
     The return from <code>run</code> is ordered similarly to an ordinary function call in a single thread.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
         </dd>
  </cxx-remarks>
  
         <cxx-remarks id="parallel.task_block.class.run.7" para_num="7">
    
    <dt>Remarks:</dt><dd>
           The invocation of the user-supplied function object <code>f</code> may be immediate or may be delayed until
           compute resources are available. <code>run</code> might or might not return before the invocation of <code>f</code> completes.
         </dd>
  </cxx-remarks>
  
       
    </dl>
  </cxx-function>
     
    </section>
  </cxx-section>

     <cxx-section id="parallel.task_block.class.wait">
    

    <section>
      <header><span class="section-number">8.3.2</span> <h1 data-bookmark-label="8.3.2 task_block member function wait"><code>task_block</code> member function <code>wait</code></h1> <span style="float:right"><a href="#parallel.task_block.class.wait">[parallel.task_block.class.wait]</a></span></header>
      

       

       <cxx-function id="parallel.task_block.class.wait.1" para_num="1">
    
    <pre><code><cxx-signature>void wait();</cxx-signature></code></pre>

    <dl>
      
         

         <cxx-preconditions id="parallel.task_block.class.wait.2" para_num="2">
    
    <dt>Preconditions:</dt><dd><code>*this</code> shall be the active <code>task_block</code>.</dd>
  </cxx-preconditions>

         <cxx-effects id="parallel.task_block.class.wait.3" para_num="3">
    
    <dt>Effects:</dt><dd>
           Blocks until the tasks spawned using this <code>task_block</code> have completed.
         </dd>
  </cxx-effects>

         <cxx-throws id="parallel.task_block.class.wait.4" para_num="4">
    
    <dt>Throws:</dt><dd>
           <code>task_cancelled_exception</code>, as described in <cxx-ref to="parallel.task_block.exceptions"><a title="parallel.task_block.exceptions" href="#parallel.task_block.exceptions">8.5</a></cxx-ref>.
         </dd>
  </cxx-throws>

         <cxx-postconditions id="parallel.task_block.class.wait.5" para_num="5">
    
    <dt>Postconditions:</dt><dd>
           All tasks spawned by the nearest enclosing task block have completed.
         </dd>
  </cxx-postconditions>

         <cxx-remarks id="parallel.task_block.class.wait.6" para_num="6">
    
    <dt>Remarks:</dt><dd>
           The <code>wait</code> function may return on a thread other than the one on which it was called; in such cases, completion of the call to <code>wait</code> synchronizes with subsequent operations.
           
           <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    The return from wait is ordered similarly to an ordinary function call in a single thread.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>

           <cxx-example>
    
    <span class="nowrap">[ <em>Example:</em></span>
    <pre>define_task_block([&amp;](auto&amp; tb) {
  tb.run([&amp;]{ process(a, w, x); }); // Process a[w] through a[x]
  if (y &lt; x) tb.wait();             // Wait if overlap between [w,x) and [y,z)
  process(a, y, z);                 // Process a[y] through a[z]
});
</pre>
           
    <span class="nowrap">— <em>end example</em> ]</span>
  </cxx-example>
         </dd>
  </cxx-remarks>
       
    </dl>
  </cxx-function>
     
    </section>
  </cxx-section>
   
    </section>
  </cxx-section>

   <cxx-section id="parallel.task_block.define_task_block">
    

    <section>
      <header><span class="section-number">8.4</span> <h1 data-bookmark-label="8.4 Function template define_task_block">Function template <code>define_task_block</code></h1> <span style="float:right"><a href="#parallel.task_block.define_task_block">[parallel.task_block.define_task_block]</a></span></header>
      
     

     <cxx-function id="parallel.task_block.define_task_block.1" para_num="1">
    
    <pre><code><cxx-signature>template&lt;class F&gt;
void define_task_block(F&amp;&amp; f);
       </cxx-signature><cxx-signature>template&lt;class F&gt;
void define_task_block_restore_thread(F&amp;&amp; f);
       </cxx-signature></code></pre>

    <dl>
      
       

       

       <cxx-requires id="parallel.task_block.define_task_block.2" para_num="2">
    
    <dt>Requires:</dt><dd>
         Given an lvalue <code>tb</code> of type <code>task_block</code>, the expression <code>f(tb)</code> shall be well-formed
       </dd>
  </cxx-requires>

       <cxx-effects id="parallel.task_block.define_task_block.3" para_num="3">
    
    <dt>Effects:</dt><dd>
         Constructs a <code>task_block</code> <code>tb</code> and calls <code>f(tb)</code>.
       </dd>
  </cxx-effects>

       <cxx-throws id="parallel.task_block.define_task_block.4" para_num="4">
    
    <dt>Throws:</dt><dd>
         <code>exception_list</code>, as specified in <cxx-ref to="parallel.task_block.exceptions"><a title="parallel.task_block.exceptions" href="#parallel.task_block.exceptions">8.5</a></cxx-ref>.
       </dd>
  </cxx-throws>

       <cxx-postconditions id="parallel.task_block.define_task_block.5" para_num="5">
    
    <dt>Postconditions:</dt><dd>
         All tasks spawned from <code>f</code> have finished execution.
       </dd>
  </cxx-postconditions>

       <cxx-remarks id="parallel.task_block.define_task_block.6" para_num="6">
    
    <dt>Remarks:</dt><dd>
         The <code>define_task_block</code> function may return on a thread other than the one on which it was called
         unless there are no task blocks active on entry to <code>define_task_block</code> (see <cxx-ref to="parallel.task_block.class"><a title="parallel.task_block.class" href="#parallel.task_block.class">8.3</a></cxx-ref>), in which
         case the function returns on the original thread. When <code>define_task_block</code> returns on a different thread,
         it synchronizes with operations following the call. <cxx-note><span class="nowrap">[ <em>Note:</em></span>
     The return from define_task_block is ordered
         similarly to an ordinary function call in a single thread.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note> The <code>define_task_block_restore_thread</code>
         function always returns on the same thread as the one on which it was called.
       </dd>
  </cxx-remarks>

       <cxx-notes id="parallel.task_block.define_task_block.7" para_num="7">
    
    <dt>Notes:</dt><dd>
         It is expected (but not mandated) that <code>f</code> will (directly or indirectly) call <code>tb.run(<em>function-object</em>)</code>.
       </dd>
  </cxx-notes>
     
    </dl>
  </cxx-function>
   
    </section>
  </cxx-section>

   <cxx-section id="parallel.task_block.exceptions">
    

    <section>
      <header><span class="section-number">8.5</span> <h1 data-bookmark-label="8.5 Exception Handling">Exception Handling</h1> <span style="float:right"><a href="#parallel.task_block.exceptions">[parallel.task_block.exceptions]</a></span></header>
      
     

     <p id="parallel.task_block.exceptions.1" para_num="1">
       Every <code>task_block</code> has an associated exception list. When the task block starts, its associated exception list is empty.
     </p>

     <p id="parallel.task_block.exceptions.2" para_num="2">
       When an exception is thrown from the user-provided function object passed to <code>define_task_block</code> or
       <code>define_task_block_restore_thread</code>, it is added to the exception list for that task block. Similarly, when
       an exception is thrown from the user-provided function object passed into <code>task_block::run</code>, the exception
       object is added to the exception list associated with the nearest enclosing task block. In both cases, an
       implementation may discard any pending tasks that have not yet been invoked. Tasks that are already in
       progress are not interrupted except at a call to <code>task_block::run</code> or <code>task_block::wait</code> as described below.
     </p>

     <p id="parallel.task_block.exceptions.3" para_num="3">
       If the implementation is able to detect that an exception has been thrown by another task within
       the same nearest enclosing task block, then <code>task_block::run</code> or <code>task_block::wait</code> may throw
       <code>task_canceled_exception</code>; these instances of <code>task_canceled_exception</code> are not added to the exception
       list of the corresponding task block.
     </p>

     <p id="parallel.task_block.exceptions.4" para_num="4">
       When a task block finishes with a non-empty exception list, the exceptions are aggregated into an <code>exception_list</code> object, which is then thrown from the task block.
     </p>

     <p id="parallel.task_block.exceptions.5" para_num="5">
       The order of the exceptions in the <code>exception_list</code> object is unspecified.
     </p>
   
    </section>
  </cxx-section>

    </section>
  </cxx-clause>






</body></html>