<!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-REF");document.createElement("CXX-SECTION");document.createElement("CXX-NOTE");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">N4742</cxx-docnum></td></tr>
          
          
            <tr><th>Date:</th><td><time pubdate=""><span class="pubyear">2018</span>-04-02</time></td></tr>
          
          
            <tr><th>Revises:</th><td><cxx-revises><a href="http://wg21.link/N4725">N4725</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.exceptions">Parallel exceptions</a>
        
          <ol>
            
              <li><span class="marker">5.1</span><a href="#parallel.exceptions.synopsis">Header &lt;experimental/exception_list&gt; synopsis</a>
        
      </li>
            
          </ol>
        
      </li>
            
              <li><span class="marker">6</span><a href="#parallel.execpol">Execution policies</a>
        
          <ol>
            
              <li><span class="marker">6.1</span><a href="#parallel.execpol.synopsis">Header &lt;experimental/execution&gt; synopsis</a>
        
      </li>
            
              <li><span class="marker">6.2</span><a href="#parallel.execpol.unseq">Unsequenced execution policy</a>
        
      </li>
            
              <li><span class="marker">6.3</span><a href="#parallel.execpol.vec">Vector execution policy</a>
        
      </li>
            
              <li><span class="marker">6.4</span><a href="#parallel.execpol.objects">Execution policy objects</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>
            
              <li><span class="marker">9</span><a href="#parallel.simd">Data-Parallel Types</a>
        
          <ol>
            
              <li><span class="marker">9.1</span><a href="#parallel.simd.general">General</a>
        
      </li>
            
              <li><span class="marker">9.2</span><a href="#parallel.simd.synopsis">Header &lt;experimental/simd&gt; synopsis</a>
        
          <ol>
            
              <li><span class="marker">9.2.1</span><a href="#parallel.simd.abi">simd ABI tags</a>
        
      </li>
            
              <li><span class="marker">9.2.2</span><a href="#parallel.simd.traits">simd type traits</a>
        
      </li>
            
              <li><span class="marker">9.2.3</span><a href="#parallel.simd.whereexpr">Class templates const_where_expression and where_expression</a>
        
      </li>
            
          </ol>
        
      </li>
            
              <li><span class="marker">9.3</span><a href="#parallel.simd.class">Class template simd</a>
        
          <ol>
            
              <li><span class="marker">9.3.1</span><a href="#parallel.simd.overview">Class template simd overview</a>
        
      </li>
            
              <li><span class="marker">9.3.2</span><a href="#parallel.simd.reference">Element references</a>
        
      </li>
            
              <li><span class="marker">9.3.3</span><a href="#parallel.simd.ctor">Constructors</a>
        
      </li>
            
              <li><span class="marker">9.3.4</span><a href="#parallel.simd.copy">Copy functions</a>
        
      </li>
            
              <li><span class="marker">9.3.5</span><a href="#parallel.simd.subscr">Subscript operators</a>
        
      </li>
            
              <li><span class="marker">9.3.6</span><a href="#parallel.simd.unary">Unary operators</a>
        
      </li>
            
          </ol>
        
      </li>
            
              <li><span class="marker">9.4</span><a href="#parallel.simd.nonmembers">Non-member operations</a>
        
          <ol>
            
              <li><span class="marker">9.4.1</span><a href="#parallel.simd.binary">Binary operators</a>
        
      </li>
            
              <li><span class="marker">9.4.2</span><a href="#parallel.simd.cassign">Compound assignment</a>
        
      </li>
            
              <li><span class="marker">9.4.3</span><a href="#parallel.simd.comparison">Compare operators</a>
        
      </li>
            
              <li><span class="marker">9.4.4</span><a href="#parallel.simd.reductions">Reductions</a>
        
      </li>
            
              <li><span class="marker">9.4.5</span><a href="#parallel.simd.casts">Casts</a>
        
      </li>
            
              <li><span class="marker">9.4.6</span><a href="#parallel.simd.alg">Algorithms</a>
        
      </li>
            
              <li><span class="marker">9.4.7</span><a href="#parallel.simd.math">Math library</a>
        
      </li>
            
          </ol>
        
      </li>
            
              <li><span class="marker">9.5</span><a href="#parallel.simd.mask.class">Class template simd_mask</a>
        
          <ol>
            
              <li><span class="marker">9.5.1</span><a href="#parallel.simd.mask.overview">Class template simd_mask overview</a>
        
      </li>
            
              <li><span class="marker">9.5.2</span><a href="#parallel.simd.mask.ctor">Constructors</a>
        
      </li>
            
              <li><span class="marker">9.5.3</span><a href="#parallel.simd.mask.copy">Copy functions</a>
        
      </li>
            
              <li><span class="marker">9.5.4</span><a href="#parallel.simd.mask.subscr">Subscript operators</a>
        
      </li>
            
              <li><span class="marker">9.5.5</span><a href="#parallel.simd.mask.unary">Unary operators</a>
        
      </li>
            
          </ol>
        
      </li>
            
              <li><span class="marker">9.6</span><a href="#parallel.simd.mask.nonmembers">Non-member operations</a>
        
          <ol>
            
              <li><span class="marker">9.6.1</span><a href="#parallel.simd.mask.binary">Binary operators</a>
        
      </li>
            
              <li><span class="marker">9.6.2</span><a href="#parallel.simd.mask.cassign">Compound assignment</a>
        
      </li>
            
              <li><span class="marker">9.6.3</span><a href="#parallel.simd.mask.comparison">Comparisons</a>
        
      </li>
            
              <li><span class="marker">9.6.4</span><a href="#parallel.simd.mask.reductions">Reductions</a>
        
      </li>
            
              <li><span class="marker">9.6.5</span><a href="#parallel.simd.mask.where">Where functions</a>
        
      </li>
            
          </ol>
        
      </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 (<cxx-ref in="cxx" to="library">C++17 <span title="library">§20</span></cxx-ref>) 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_-</code><br><code>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">6.2</a></cxx-ref></td>
          <td><code>__cpp_lib_experimental_-</code><br><code>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_-</code><br><code>parallel_for_loop</code></td>
          <td>201711</td>
          <td><code>&lt;experimental/algorithm&gt;</code></td>
        </tr>
        <tr>
          <td><ins>P0214R9</ins></td>
          <td><ins>Data-Parallel Vector Types &amp; Operations</ins></td>
          <td><ins><cxx-ref to="parallel.simd" <="" cxx-ref=""><a title="parallel.simd" href="#parallel.simd">9</a></cxx-ref></ins></td>
          <td><ins><code>__cpp_lib_experimental_-</code><code>parallel_simd</code></ins>
          </td><td><ins>201803</ins></td>
          <td><ins><code>&lt;experimental/simd&gt;</code></ins></td>
        </tr>
      </thead>
    
  </table>
  
    </section>
  </cxx-section>

    </section>
  </cxx-clause>


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

    <section>
      <header><span class="section-number">5</span> <h1 data-bookmark-label="5 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">5.1</span> <h1 data-bookmark-label="5.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> fulfills 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.execpol">
    

    <section>
      <header><span class="section-number">6</span> <h1 data-bookmark-label="6 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">6.1</span> <h1 data-bookmark-label="6.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">6.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">6.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">6.4</a>, Execution policy objects</i></cxx-ref>
  inline constexpr unsequenced_policy unseq{ <i>unspecified</i> };
  inline constexpr vector_policy vec{ <i>unspecified</i> };
}
}
}
</pre>
  
    </section>
  </cxx-section>

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

    <section>
      <header><span class="section-number">6.2</span> <h1 data-bookmark-label="6.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> will be called.</p>

  
    </section>
  </cxx-section>

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

    <section>
      <header><span class="section-number">6.3</span> <h1 data-bookmark-label="6.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 (<a href="#parallel.alg.general.wavefront">[parallel.alg.general.wavefront]</a>). <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 (<a href="#parallel.alg.general.wavefront">[parallel.alg.general.wavefront]</a>) for the last argument to <code>for_loop</code>, <code>for_loop_n</code>, <code>for_loop_strided</code>, or <code>for_loop_strided_n</code>.</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> will be called.</p>

  
    </section>
  </cxx-section>

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

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

<pre>inline constexpr execution::unsequenced_policy unseq{ <ins><i>unspecified</i></ins> };
inline constexpr execution::vector_policy vec{ <ins><i>unspecified</i></ins> };
</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.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 --->

    <p id="parallel.alg.wavefront.3" para_num="3">
      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.4" para_num="4">
      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 --->

    <p id="parallel.alg.wavefront.5" para_num="5">
      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.6" para_num="6">
      <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.7" para_num="7">
      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>j</sub> if i &lt; j 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>
  
    </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; using no_deduce_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<ins>, class S</ins>&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><ins>A</ins><del>a</del> 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>.</dd>
  </cxx-requires>

        <cxx-returns id="parallel.alg.reductions.9" para_num="9">
    
    <dt>Returns:</dt><dd><ins>A</ins><del>a</del> 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> to 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>
          <ins>A</ins><del>a</del>n induction object with induction value type <code>remove_cv_t&lt;remove_reference_t&lt;T&gt;&gt;</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 <code>advance</code> and <code>distance</code>.
    <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 <code>rest</code> 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&lt;F&gt;(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>
          <ins>T</ins><del>t</del>he 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>template&lt;class T&gt;
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 <ins><em>nearest enclosing</em></ins><del>nearest enclosing</del> <ins><em>task block</em></ins><del>task block</del>, where <ins><em>task block</em></ins><del>“task block”</del> refers to an
       invocation of <code>define_task_block</code> or <code>define_task_block_restore_thread</code> and <ins><em>nearest enclosing</em></ins><del>“nearest enclosing”</del> 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 <ins><code>define_task_block</code></ins><del>define_task_block</del> 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>


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

    <section>
      <header><span class="section-number">9</span> <h1 data-bookmark-label="9 Data-Parallel Types"><ins>Data-Parallel Types</ins></h1> <span style="float:right"><a href="#parallel.simd">[parallel.simd]</a></span></header>
      
  

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

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

    <p id="parallel.simd.general.1" para_num="1">
    <ins>
      The data-parallel library consists of data-parallel types and 
operations on these types. A data-parallel type consists of elements of 
an underlying arithmetic type, called the <em>element type</em>. The number of elements is a constant for each data-parallel type and called the <em>width</em> of that type.
    </ins>
    </p>

    <p id="parallel.simd.general.2" para_num="2">
    <ins>
      Throughout this Clause, the term <em>data-parallel type</em> refers to all <em>supported</em> <cxx-ref to="parallel.simd.overview"><a title="parallel.simd.overview" href="#parallel.simd.overview">9.3.1</a></cxx-ref> specializations of the <code>simd</code> and <code>simd_mask</code> class templates. A <em>data-parallel object</em> is an object of <em>data-parallel type</em>.
    </ins>
    </p>

    <p id="parallel.simd.general.3" para_num="3">
    <ins>
      An <em>element-wise operation</em> applies a specified operation 
to the elements of one or more data-parallel objects. Each such 
application is unsequenced with respect to the others. A <em>unary element-wise operation</em> is an element-wise operation that applies a unary operation to each element of a data-parallel object. A <em>binary element-wise operation</em> is an element-wise operation that applies a binary operation to corresponding elements of two data-parallel objects.
    </ins>
    </p>

    <p id="parallel.simd.general.4" para_num="4">
    <ins>
      Throughout this Clause, the set of <em>vectorizable types</em> for a data-parallel type comprises all cv-unqualified arithmetic types other than <code>bool</code>.
    </ins>
    </p>

    <p id="parallel.simd.general.5" para_num="5">
    <ins>
      <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    The intent is to support acceleration through data-parallel 
execution resources, such as SIMD registers and instructions or 
execution units driven by a common instruction decoder. If such 
execution resources are unavailable, the interfaces support a 
transparent fallback to sequential execution.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
    </ins>
    </p>

  
    </section>
  </cxx-section>

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

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

    <ins>
    <pre>namespace std::experimental {
inline namespace parallelism_v2 {
  namespace simd_abi {
  
    struct scalar {};
    template&lt;int N&gt; struct fixed_size {};
    template&lt;class T&gt; inline constexpr int max_fixed_size = <em>implementation-defined</em>;
    template&lt;class T&gt; using compatible = <em>implementation-defined</em>;
    template&lt;class T&gt; using native = <em>implementation-defined</em>;
  
    template&lt;class T, size_t N&gt; struct deduce { using type = <em>see below</em>; };
    template&lt;class T, size_t N&gt; using deduce_t = typename deduce&lt;T, N&gt;::type;
  }

  struct element_aligned_tag {};
  struct vector_aligned_tag {};
  template&lt;size_t&gt; struct overaligned_tag {};
  inline constexpr element_aligned_tag element_aligned{};
  inline constexpr vector_aligned_tag vector_aligned{};
  template&lt;size_t N&gt; inline constexpr overaligned_tag&lt;N&gt; overaligned{};

  <cxx-ref insynopsis="" to="parallel.simd.traits">// <i><a title="parallel.simd.traits" href="#parallel.simd.traits">9.2.2</a>, simd type traits</i></cxx-ref>
  template&lt;class T&gt; struct is_abi_tag;
  template&lt;class T&gt; inline constexpr bool is_abi_tag_v = is_abi_tag&lt;T&gt;::value;

  template&lt;class T&gt; struct is_simd;
  template&lt;class T&gt; inline constexpr bool is_simd_v = is_simd&lt;T&gt;::value;

  template&lt;class T&gt; struct is_simd_mask;
  template&lt;class T&gt; inline constexpr bool is_simd_mask_v = is_simd_mask&lt;T&gt;::value;

  template&lt;class T&gt; struct is_simd_flag_type;
  template&lt;class T&gt; inline constexpr bool is_simd_flag_type_v =
    is_simd_flag_type&lt;T&gt;::value;

  template&lt;class T, class Abi = simd_abi::compatible&lt;T&gt;&gt; struct simd_size;
  template&lt;class T, class Abi = simd_abi::compatible&lt;T&gt;&gt;
  inline constexpr size_t simd_size_v = simd_size&lt;T,Abi&gt;::value;

  template&lt;class T, class U = typename T::value_type&gt; struct memory_alignment;
  template&lt;class T, class U = typename T::value_type&gt;
  inline constexpr size_t memory_alignment_v = memory_alignment&lt;T,U&gt;::value;

  <cxx-ref insynopsis="" to="parallel.simd.class">// <i><a title="parallel.simd.class" href="#parallel.simd.class">9.3</a>, Class template simd</i></cxx-ref>
  template&lt;class T, class Abi = simd_abi::compatible&lt;T&gt;&gt; class simd;
  template&lt;class T&gt; using native_simd = simd&lt;T, simd_abi::native&lt;T&gt;&gt;;
  template&lt;class T, int N&gt; using fixed_size_simd = simd&lt;T, simd_abi::fixed_size&lt;N&gt;&gt;;

  <cxx-ref insynopsis="" to="parallel.simd.mask.class">// <i><a title="parallel.simd.mask.class" href="#parallel.simd.mask.class">9.5</a>, Class template simd_mask</i></cxx-ref>
  template&lt;class T, class Abi = simd_abi::compatible&lt;T&gt;&gt; class simd_mask;
  template&lt;class T&gt; using native_simd_mask = simd_mask&lt;T, simd_abi::native&lt;T&gt;&gt;;
  template&lt;class T, int N&gt; using fixed_size_simd_mask =
    simd_mask&lt;T, simd_abi::fixed_size&lt;N&gt;&gt;;

  <cxx-ref insynopsis="" to="parallel.simd.casts">// <i><a title="parallel.simd.casts" href="#parallel.simd.casts">9.4.5</a>, Casts</i></cxx-ref>
  template&lt;class T, class U, class Abi&gt; <em>see below</em> simd_cast(const simd&lt;U, Abi&gt;&amp;);
  template&lt;class T, class U, class Abi&gt; <em>see below</em> static_simd_cast(const simd&lt;U, Abi&gt;&amp;);

  template&lt;class T, class Abi&gt;
    fixed_size_simd&lt;T, simd_size_v&lt;T, Abi&gt;&gt;
      to_fixed_size(const simd&lt;T, Abi&gt;&amp;) noexcept;
  template&lt;class T, class Abi&gt;
    fixed_size_simd_mask&lt;T, simd_size_v&lt;T, Abi&gt;&gt;
      to_fixed_size(const simd_mask&lt;T, Abi&gt;&amp;) noexcept;
  template&lt;class T, int N&gt;
    native_simd&lt;T&gt; to_native(const fixed_size_simd&lt;T, N&gt;&amp;) noexcept;
  template&lt;class T, int N&gt;
    native_simd_mask&lt;T&gt; to_native(const fixed_size_simd_mask&lt;T, N&gt;&amp;) noexcept;
  template&lt;class T, int N&gt;
    simd&lt;T&gt; to_compatible(const fixed_size_simd&lt;T, N&gt;&amp;) noexcept;
  template&lt;class T, int N&gt;
    simd_mask&lt;T&gt; to_compatible(const fixed_size_simd_mask&lt;T, N&gt;&amp;) noexcept;

  template&lt;size_t... Sizes, class T, class Abi&gt;
    tuple&lt;simd&lt;T, simd_abi::deduce_t&lt;T, Sizes&gt;&gt;...&gt;
      split(const simd&lt;T, Abi&gt;&amp;);
  template&lt;size_t... Sizes, class T, class Abi&gt;
    tuple&lt;simd_mask&lt;T, simd_mask_abi::deduce_t&lt;T, Sizes&gt;&gt;...&gt;
      split(const simd_mask&lt;T, Abi&gt;&amp;);
  template&lt;class V, class Abi&gt;
    array&lt;V, simd_size_v&lt;typename V::value_type, Abi&gt; / V::size()&gt;
      split(const simd&lt;typename V::value_type, Abi&gt;&amp;);
  template&lt;class V, class Abi&gt;
    array&lt;V, simd_size_v&lt;typename V::value_type, Abi&gt; / V::size()&gt;
      split(const simd_mask&lt;typename V::value_type, Abi&gt;&amp;);

  template&lt;class T, class... Abis&gt;
    simd&lt;T, simd_abi::deduce_t&lt;T, (simd_size_v&lt;T, Abis&gt; + ...)&gt;&gt;
      concat(const simd&lt;T, Abis&gt;&amp;...);
  template&lt;class T, class... Abis&gt;
    simd_mask&lt;T, simd_abi::deduce_t&lt;T, (simd_size_v&lt;T, Abis&gt; + ...)&gt;&gt;
      concat(const simd_mask&lt;T, Abis&gt;&amp;...);

  <cxx-ref insynopsis="" to="parallel.simd.mask.reductions">// <i><a title="parallel.simd.mask.reductions" href="#parallel.simd.mask.reductions">9.6.4</a>, Reductions</i></cxx-ref>
  template&lt;class T, class Abi&gt; bool all_of(const simd_mask&lt;T, Abi&gt;&amp;) noexcept;
  template&lt;class T, class Abi&gt; bool any_of(const simd_mask&lt;T, Abi&gt;&amp;) noexcept;
  template&lt;class T, class Abi&gt; bool none_of(const simd_mask&lt;T, Abi&gt;&amp;) noexcept;
  template&lt;class T, class Abi&gt; bool some_of(const simd_mask&lt;T, Abi&gt;&amp;) noexcept;
  template&lt;class T, class Abi&gt; int popcount(const simd_mask&lt;T, Abi&gt;&amp;) noexcept;
  template&lt;class T, class Abi&gt; int find_first_set(const simd_mask&lt;T, Abi&gt;&amp;);
  template&lt;class T, class Abi&gt; int find_last_set(const simd_mask&lt;T, Abi&gt;&amp;);

  bool all_of(<em>see below</em>) noexcept;
  bool any_of(<em>see below</em>) noexcept;
  bool none_of(<em>see below</em>) noexcept;
  bool some_of(<em>see below</em>) noexcept;
  int popcount(<em>see below</em>) noexcept;
  int find_first_set(<em>see below</em>) noexcept;
  int find_last_set(<em>see below</em>) noexcept;

  <cxx-ref insynopsis="" to="parallel.simd.whereexpr">// <i><a title="parallel.simd.whereexpr" href="#parallel.simd.whereexpr">9.2.3</a>, Class templates const_where_expression and where_expression</i></cxx-ref>
  template&lt;class M, class T&gt; class const_where_expression;
  template&lt;class M, class T&gt; class where_expression;

  <cxx-ref insynopsis="" to="parallel.simd.mask.where">// <i><a title="parallel.simd.mask.where" href="#parallel.simd.mask.where">9.6.5</a>, Where functions</i></cxx-ref>
  template&lt;class T&gt; struct nodeduce { using type = T; }; // exposition only
  template&lt;class T&gt; using nodeduce_t = typename nodeduce&lt;T&gt;::type; // exposition only

  template&lt;class T, class Abi&gt;
    where_expression&lt;simd_mask&lt;T, Abi&gt;, simd&lt;T, Abi&gt;&gt;
      where(const typename simd&lt;T, Abi&gt;::mask_type&amp;, simd&lt;T, Abi&gt;&amp;) noexcept;

  template&lt;class T, class Abi&gt;
    const_where_expression&lt;simd_mask&lt;T, Abi&gt;, simd&lt;T, Abi&gt;&gt;
      where(const typename simd&lt;T, Abi&gt;::mask_type&amp;, const simd&lt;T, Abi&gt;&amp;) noexcept;

  template&lt;class T, class Abi&gt;
    where_expression&lt;simd_mask&lt;T, Abi&gt;, simd_mask&lt;T, Abi&gt;&gt;
      where(const nodeduce_t&lt;simd_mask&lt;T, Abit&gt;&gt;&amp;, simd_mask&lt;T, Abi&gt;&amp;) noexcept;

  template&lt;class T, class Abi&gt;
    const_where_expression&lt;simd_mask&lt;T, Abi&gt;, simd_mask&lt;T, Abi&gt;&gt;
      where(const nodeduce_t&lt;simd_mask&lt;T, Abit&gt;&gt;&amp;, const simd_mask&lt;T, Abi&gt;&amp;) noexcept;

  template&lt;class T&gt;
    where_expression&lt;bool, T&gt;
      where(<em>see below</em> k, T&amp; d) noexcept;

  template&lt;class T&gt;
    const_where_expression&lt;bool, T&gt;
      where(<em>see below</em> k, const T&amp; d) noexcept;

  <cxx-ref insynopsis="" to="parallel.simd.reductions">// <i><a title="parallel.simd.reductions" href="#parallel.simd.reductions">9.4.4</a>, Reductions</i></cxx-ref>
  template&lt;class T, class Abi, class BinaryOperation = plus&lt;&gt;&gt;
    T reduce(const simd&lt;T, Abi&gt;&amp;,
             BinaryOperation = {});

  template&lt;class M, class V, class BinaryOperation&gt;
    typename V::value_type reduce(const const_where_expression&lt;M, V&gt;&amp; x,
                                  typename V::value_type identity_element,
                                  BinaryOperation binary_op);
  template&lt;class M, class V&gt;
    typename V::value_type reduce(const const_where_expression&lt;M, V&gt;&amp; x,
                                  plus&lt;&gt;
                                  binary_op = {});
  template&lt;class M, class V&gt;
    typename V::value_type reduce(const const_where_expression&lt;M, V&gt;&amp; x,
                                  multiplies&lt;&gt;
                                  binary_op);
  template&lt;class M, class V&gt;
    typename V::value_type reduce(const const_where_expression&lt;M, V&gt;&amp; x,
                                  bit_and&lt;&gt;
                                  binary_op);
  template&lt;class M, class V&gt;
    typename V::value_type reduce(const const_where_expression&lt;M, V&gt;&amp; x,
                                  bit_or&lt;&gt;
                                  binary_op);
  template&lt;class M, class V&gt;
    typename V::value_type reduce(const const_where_expression&lt;M, V&gt;&amp; x,
                                  bit_xor&lt;&gt;
                                  binary_op);

  template&lt;class T, class Abi&gt;
    T hmin(const simd&lt;T, abi&gt;&amp;);
  template&lt;class T, class Abi&gt;
    typename V::value_type hmin(const const_where_expression&lt;M, V&gt;&amp;);
  template&lt;class T, class Abi&gt;
    T hmax(const simd&lt;T, abi&gt;&amp;);
  template&lt;class T, class Abi&gt;
    typename V::value_type hmax(const const_where_expression&lt;M, V&gt;&amp;);

  <cxx-ref insynopsis="" to="parallel.simd.alg">// <i><a title="parallel.simd.alg" href="#parallel.simd.alg">9.4.6</a>, Algorithms</i></cxx-ref>
  template&lt;class T, class Abi&gt;
    simd&lt;T, Abi&gt;
      min(const simd&lt;T, Abi&gt;&amp; a, const simd&lt;T, Abi&gt;&amp; b) noexcept;
  template&lt;class T, class Abi&gt;
    simd&lt;T, Abi&gt;
      max(const simd&lt;T, Abi&gt;&amp; a, const simd&lt;T, Abi&gt;&amp; b) noexcept;
  template&lt;class T, class Abi&gt;
    pair&lt;simd&lt;T, Abi&gt;, simd&lt;T, Abi&gt;&gt;
      minmax(const simd&lt;T, Abi&gt;&amp; a, const simd&lt;T, Abi&gt;&amp; b) noexcept;
  template&lt;class T, class Abi&gt;
    simd&lt;T, Abi&gt;
      clamp(const simd&lt;T, Abi&gt;&amp; v,
            const simd&lt;T, Abi&gt;&amp; lo,
            const simd&lt;T, Abi&gt;&amp; hi) noexcept;
}
}
    </pre>
    </ins>

    <p id="parallel.simd.synopsis.1" para_num="1">
    <ins>
      The header <code>&lt;experimental/simd&gt;</code> defines class templates, tag types, trait types, and function templates for element-wise operations on data-parallel objects.
    </ins>
    </p>

    <cxx-section id="parallel.simd.abi">
    

    <section>
      <header><span class="section-number">9.2.1</span> <h1 data-bookmark-label="9.2.1 simd ABI tags"><ins><code>simd</code> ABI tags</ins></h1> <span style="float:right"><a href="#parallel.simd.abi">[parallel.simd.abi]</a></span></header>
      
      
      <ins>
      <pre>namespace simd_abi {
  struct scalar {};
  template&lt;int N&gt; struct fixed_size {};
  template&lt;class T&gt; inline constexpr in max_fixed_size = <em>implementation-defined</em>;
  template&lt;class T&gt; using compatible = <em>implementation-defined</em>;
  template&lt;class T&gt; using native = <em>implementation-defined</em>;
}
      </pre>
      </ins>

      <p id="parallel.simd.abi.1" para_num="1">
      <ins>
        An <em>ABI tag</em> is a type in the <code>std::experimental::parallelism_v2::simd_abi</code> namespace that indicates a choice of size and binary representation for objects of data-parallel type. <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    The intent is for the size and binary representation to depend on the target architecture.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note> The ABI tag, together with a given element type implies a 
number of elements. ABI tag types are used as the second template 
argument to <code>simd</code> and <code>simd_mask</code>.
      </ins>
      </p>

      <p id="parallel.simd.abi.2" para_num="2">
      <ins>
        <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    The ABI tag is orthogonal to selecting the machine instruction set. 
The selected machine instruction set limits the usable ABI tag types, 
though (see <cxx-ref to="parallel.simd.overview"><a title="parallel.simd.overview" href="#parallel.simd.overview">9.3.1</a></cxx-ref>).
 The ABI tags enable users to safely pass objects of data-parallel type 
between translation unit boundaries (e.g. function calls or I/O).
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
      </ins>
      </p>

      <p id="parallel.simd.abi.3" para_num="3">
      <ins>
        Use of the <code>scalar</code> tag type requires data-parallel types to store a single element (i.e., <code>simd&lt;T, simd_abi::scalar&gt;::size()</code> returns 1). <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    <code>scalar</code> is not an alias for <code>fixed_size&lt;1&gt;</code>.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
      </ins>
      </p>

      <p id="parallel.simd.abi.4" para_num="4">
      <ins>
        The value of <code>max_fixed_size&lt;T&gt;</code> is at least 32.
      </ins>
      </p>

      <p id="parallel.simd.abi.5" para_num="5">
      <ins>
        Use of the <code>simd_abi::fixed_size&lt;N&gt;</code> tag type requires data-parallel types to store <code>N</code> elements (i.e. <code>simd&lt;T, simd_abi::fixed_size&lt;N&gt;&gt;::size()</code> is <code>N</code>). <code>simd&lt;T, fixed_size&lt;N&gt;&gt;</code> and <code>simd_mask&lt;T, fixed_size&lt;N&gt;&gt;</code> with <code>N &gt; 0</code> and <code>N &lt;= max_fixed_size&lt;T&gt;</code> shall be supported. Additionally, for every supported <code>simd&lt;T, Abi&gt;</code> (see <cxx-ref to="parallel.simd.overview"><a title="parallel.simd.overview" href="#parallel.simd.overview">9.3.1</a></cxx-ref>), where <code>Abi</code> is an ABI tag that is not a specialization of <code>simd_abi::fixed_size</code>, <code>N == simd&lt;T, Abi&gt;::size()</code> shall be supported.
      </ins>
      </p>

      <p id="parallel.simd.abi.6" para_num="6">
      <ins>
        <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    It is unspecified whether <code>simd&lt;T, fixed_size&lt;T, fixed_size&lt;N&gt;&gt;</code> with <code>N &gt; max_fixed_size&lt;T&gt;</code> is supported. The value of <code>max_fixed_size&lt;T&gt;</code> can depend on compiler flags and can change between different compiler versions.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
      </ins>
      </p>

      <p id="parallel.simd.abi.7" para_num="7">
      <ins>
        <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    An implementation can forego ABI compatibility between differently compiled translation units for <code>simd</code> and <code>simd_mask</code> specializations using the same <code>simd_abi::fixed_size&lt;N&gt;</code> tag. Otherwise, the efficiency of <code>simd&lt;T, Abi&gt;</code> is likely to be better than for <code>simd&lt;T, fixed_size&lt;simd_size_v&lt;T, Abi&gt;&gt;&gt;</code> (with <code>Abi</code> not a specialization of <code>simd_abi::fixed_size</code>).
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
      </ins>
      </p>

      <p id="parallel.simd.abi.8" para_num="8">
      <ins>
        An implementation may define additional <em>extended ABI tag</em> types in the <code>std::experimental::parallelism_v2::simd_abi</code> namespace, to support other forms of data-parallel computation.
      </ins>
      </p>

      <p id="parallel.simd.abi.9" para_num="9">
      <ins>
        <code>compatible&lt;T&gt;</code> is an implementation-defined alias for an ABI tag. <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    The intent is to use the ABI tag producing the most efficient data-parallel execution for the element type <code>T</code> that ensures ABI compatibility between translation units on the target architecture.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>

        <br>
        <br>


        [ <em>Example:</em> Consider a target architecture supporting the extended ABI tags <code>__simd128</code> and <code>__simd256</code>, where the <code>__simd256</code> type requires an optional ISA extension on said architecture. Also, the target architecture does not support <code>long double</code> with either ABI tag. The implementation therefore defines

        </ins></p><ul> 
          <li>
          <ins>
            <code>compatible&lt;T&gt;</code> is an alias for <code>__simd128</code> for all vectorizable <code>T</code>, except <code>long double</code>, and
          </ins>
          </li>

          <li>
          <ins>
            <code>compatible&lt;long double&gt;</code> as an alias for <code>scalar</code>.
          </ins>
          </li>
        </ul>

        <ins>
        <em>— end example</em> ]
        </ins>
      
      <!--- /p --->

      <p id="parallel.simd.abi.10" para_num="10">
      <ins>
        <code>native&lt;T&gt;</code> is an implementation-defined alias for an ABI tag. <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    The intent is to use the ABI tag producing the most efficient data-parallel execution for the element type <code>T</code> that is supported on the currently targeted system. For target architectures without ISA extensions, the <code>native&lt;T&gt;</code> and <code>compatible&lt;T&gt;</code> aliases will likely be the same. For target architectures with ISA extensions, compiler flags may influence the <code>native&lt;T&gt;</code> alias while <code>compatible&lt;T&gt;</code> will be the same independent of such flags.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>

        <br>
        <br>

        [ <em>Example:</em> Consider a target architecture supporting the extended ABI tags <code>__simd128</code> and <code>__simd256</code>, where hardware support for <code>__simd256</code> only exists for floating-point types. The implementation therefore defines <code>native&lt;T&gt;</code> as an alias for

          </ins></p><ul>
            <li>
            <ins>
              <code>__simd256</code> if <code>T</code> is a floating-point type, and
            </ins>
            </li>

            <li>
            <ins>
              <code>__simd128</code> otherwise.
            </ins>
            </li>
          </ul>
        <ins>
        <em>— end example</em> ]
        </ins>
      
      <p id="parallel.simd.abi.11" para_num="11"></p>

      <ins>
      <pre>template&lt;T, size_t N&gt; struct deduce { using type = <em>see below</em>; };</pre>
      </ins>

      <p id="parallel.simd.abi.12" para_num="12">
      <ins>
        The member <code>type</code> shall be present if and only if

        </ins></p><ul>
          <li>
          <ins>
            <code>T</code> is a vectorizable type, and
          </ins>
          </li>

          <li>
          <ins>
            <code>simd_abi::fixed_size&lt;N&gt;</code> is supported (see <cxx-ref to="parallel.simd.abi"><a title="parallel.simd.abi" href="#parallel.simd.abi">9.2.1</a></cxx-ref>).
          </ins>
          </li>
        </ul>
      
      <!--- /p --->

      <p id="parallel.simd.abi.13" para_num="13">
      <ins>
        Where present, the member typedef <code>type</code> shall name an ABI tag type that satisfies
      </ins>

        </p><ul>
          <li>
          <ins>
            <code>simd_size&lt;T, type&gt; == N</code>, and
          </ins>
          </li>

          <li>
          <ins>
            <code>simd&lt;T, type&gt;</code> is default constructible (see <cxx-ref to="parallel.simd.overview"><a title="parallel.simd.overview" href="#parallel.simd.overview">9.3.1</a></cxx-ref>).
          </ins>
          </li>
        </ul>

      <ins>
        If <code>N</code> is <code>1</code>, the member typedef <code>type</code> is <code>simd_abi::scalar</code>. Otherwise, if there are multiple ABI tag types that satisfy the constraints, the member typedef <code>type</code> is implementation-defined. <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    It is expected that extended ABI tags can produce better optimizations and thus are preferred over <code>simd_abi::fixed_size&lt;N&gt;</code>.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
      </ins>
      <!--- /p --->

      <p id="parallel.simd.abi.14" para_num="14">
      <ins>
        The behavior of a program that adds specializations for <code>deduce</code> is undefined.
      </ins>
      </p>
    
    </section>
  </cxx-section>

    <cxx-section id="parallel.simd.traits">
    

    <section>
      <header><span class="section-number">9.2.2</span> <h1 data-bookmark-label="9.2.2 simd type traits"><ins><code>simd</code> type traits</ins></h1> <span style="float:right"><a href="#parallel.simd.traits">[parallel.simd.traits]</a></span></header>
      
      

      <ins>
      <code>template&lt;class T&gt; struct is_abi_tag { <em>see below</em> };</code>
      </ins>

      <p id="parallel.simd.traits.1" para_num="1">
      <ins>
        The type <code>is_abi_tag&lt;T&gt;</code> is a <code>UnaryTypeTrait</code> with a <code>BaseCharacteristic</code> of <code>true_type</code> if <code>T</code> is a standard or extended ABI tag, and <code>false_type</code> otherwise.
      </ins>
      </p>

      <p id="parallel.simd.traits.2" para_num="2">
      <ins>
        The behavior of a program that adds specializations for <code>is_abi_tag</code> is undefined.
      </ins>
      </p>

      <ins>
      <code>template&lt;class T&gt; struct is_simd { <em>see below</em> };</code>
      </ins>

      <p id="parallel.simd.traits.3" para_num="3">
      <ins>
        The type <code>is_simd&lt;T&gt;</code> is a <code>UnaryTypeTrait</code> with a <code>BaseCharacteristic</code> of <code>true_type</code> if <code>T</code> is a specialization of the <code>simd</code> class template, and <code>false_type</code> otherwise.
      </ins>
      </p>

      <p id="parallel.simd.traits.4" para_num="4">
      <ins>
        The behavior of a program that adds specializations for <code>is_simd</code> is undefined.
      </ins>
      </p>

      <ins><code>template&lt;class T&gt; struct is_simd_mask { <em>see below</em> };</code></ins>

      <p id="parallel.simd.traits.5" para_num="5">
      <ins>
        The type <code>is_simd_mask&lt;T&gt;</code> is a <code>UnaryTypeTrait</code> with a <code>BaseCharacteristic</code> of <code>true_type</code> if <code>T</code> is a specialization of the <code>simd_mask</code> class template, and <code>false_type</code> otherwise.
      </ins>
      </p>

      <p id="parallel.simd.traits.6" para_num="6">
      <ins>
        The behavior of a program that adds specializations for <code>is_simd_mask</code> is undefined.
      </ins>
      </p>

      <ins>
      <code>template&lt;class T&gt; struct is_simd_flag_type { <em>see below</em> };</code>
      </ins>

      <p id="parallel.simd.traits.7" para_num="7">
      <ins>
        The type <code>is_simd_flag_type&lt;class T&gt;</code> is a <code>UnaryTypeTrait</code> with a <code>BaseCharacteristic</code> of <code>true_type</code> if <code>T</code> is one of

        </ins></p><ul>
          <li>
          <ins>
            <code>element_aligned_tag</code>, or
          </ins>
          </li>

          <li>
          <ins>
            <code>vector_aligned_tag</code>, or
          </ins>
          </li>

          <li>
          <ins>
            <code>overaligned_tag&lt;N&gt;</code> with <code>N &gt; 0</code> and <code>N</code> an integral power of two,
          </ins>
          </li>
        </ul>

        <ins>
        and <code>false_type</code> otherwise.
        </ins>
      
      <!--- /p .-->

      <p id="parallel.simd.traits.8" para_num="8">
      <ins>
        The behavior of a program that adds specializations for <code>is_simd_flag_type</code> is undefined.
      </ins>
      </p>

      <ins>
      <code>template&lt;class T, class Abi = simd_abi::compatible&lt;T&gt;&gt; struct simd_size { <em>see below</em> };</code>
      </ins>

      <p id="parallel.simd.traits.9" para_num="9">
      <ins>
        <code>simd_size&lt;T, Abi&gt;</code> shall have a member <code>value</code> if and only if

        </ins></p><ul>
          <li>
          <ins>
            <code>T</code> is a vectorizable type, and
          </ins>
          </li>

          <li>
          <ins>
            <code>is_abi_tag_v&lt;Abi&gt;</code> is <code>true</code>.
          </ins>
          </li>
        </ul>

        <ins>
        <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    
          The rules are different from those in (<cxx-ref to="parallel.simd.overview"><a title="parallel.simd.overview" href="#parallel.simd.overview">9.3.1</a></cxx-ref>).
        
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
        </ins>
      
      <!--- /p --->

      <p id="parallel.simd.traits.10" para_num="10">
      <ins>
        If <code>value</code> is present, the type <code>simd_size&lt;T, Abi&gt;</code> is a <code>BinaryTypeTrait</code> with a <code>BaseCharacteristic</code> of <code>integral_constant&lt;size_t, N&gt;</code> with <code>N</code> equal to the number of elements in a <code>simd&lt;T, Abi&gt;</code> object. <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    If <code>simd&lt;T, Abi&gt;</code> is not supported for the currently targeted system, <code>simd_size&lt;T, Abi&gt;::value</code> produces the value <code>simd&lt;T, Abi&gt;::size()</code> would return if it were supported.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
      </ins>
      </p>

      <p id="parallel.simd.traits.11" para_num="11">
      <ins>
        The behavior of a program that adds specializations for <code>simd_size</code> is undefined.
      </ins>
      </p>

      <ins>
      <code>template&lt;class T, class U = typename T::value_type&gt; struct memory_alignment { <em>see below</em> };</code>
      </ins>

      <p id="parallel.simd.traits.12" para_num="12">
      <ins>
        <code>memory_alignment&lt;T, U&gt;</code> shall have a member <code>value</code> if and only if
      </ins>

        </p><ul>
          <li>
          <ins>
            <code>is_simd_mask_v&lt;T&gt;</code> is <code>true</code> and <code>U</code> is <code>bool</code>, or
          </ins>
          </li>

          <li>
          <ins>
            <code>is_simd_v&lt;T&gt;</code> is <code>true</code> and <code>U</code> is a vectorizable type.
          </ins>
          </li>
        </ul>
      <!--- /p --->

      <p id="parallel.simd.traits.13" para_num="13">
      <ins>
        If <code>value</code> is present, the type <code>memory_alignment&lt;T, U&gt;</code> is a <code>BinaryTypeTrait</code> with a <code>BaseCharacteristic</code> of <code>integral_constant&lt;size_t, N&gt;</code> for some implementation-defined <code>N</code> (see <cxx-ref to="parallel.simd.copy"><a title="parallel.simd.copy" href="#parallel.simd.copy">9.3.4</a></cxx-ref> and <cxx-ref to="parallel.simd.mask.copy"><a title="parallel.simd.mask.copy" href="#parallel.simd.mask.copy">9.5.3</a></cxx-ref>). <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    <code>value</code> identifies the alignment restrictions on pointers used for (converting) loads and stores for the give type <code>T</code> on arrays of type <code>U</code>.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
      </ins>
      </p>

      <p id="parallel.simd.traits.14" para_num="14">
      <ins>
        The behavior of a program that adds specializations for <code>memory_alignment</code> is undefined.
      </ins>
      </p>
    
    </section>
  </cxx-section>

    <cxx-section id="parallel.simd.whereexpr">
    

    <section>
      <header><span class="section-number">9.2.3</span> <h1 data-bookmark-label="9.2.3 Class templates const_where_expression and where_expression"><ins>Class templates <code>const_where_expression</code> and <code>where_expression</code></ins></h1> <span style="float:right"><a href="#parallel.simd.whereexpr">[parallel.simd.whereexpr]</a></span></header>
      
      
      <ins>
      <pre>template&lt;class M, class T&gt; class const_where_expression {
  const M mask; <em>// exposition only</em>
  T&amp; data; <em>// exposition only</em>

public:
  const_where_expression(const const_where_expression&amp;) = delete;
  const_where_expression&amp; operator=(const const_where_expression&amp;) = delete;

  T operator-() const &amp;&amp;;
  T operator+() const &amp;&amp;;
  T operator~() const &amp;&amp;;

  template&lt;class U, class Flags&gt; void copy_to(U* mem, Flags f) const &amp;&amp;;
};

template&lt;class M, class T&gt;
class where_expression : public const_where_expression&lt;M, T&gt; {
public:
  template&lt;class U&gt; void operator=(U&amp;&amp; x) &amp;&amp;;
  template&lt;class U&gt; void operator+=(U&amp;&amp; x) &amp;&amp;;
  template&lt;class U&gt; void operator-=(U&amp;&amp; x) &amp;&amp;;
  template&lt;class U&gt; void operator*=(U&amp;&amp; x) &amp;&amp;;
  template&lt;class U&gt; void operator/=(U&amp;&amp; x) &amp;&amp;;
  template&lt;class U&gt; void operator%=(U&amp;&amp; x) &amp;&amp;;
  template&lt;class U&gt; void operator&amp;=(U&amp;&amp; x) &amp;&amp;;
  template&lt;class U&gt; void operator|=(U&amp;&amp; x) &amp;&amp;;
  template&lt;class U&gt; void operator^=(U&amp;&amp; x) &amp;&amp;;
  template&lt;class U&gt; void operator&lt;&lt;=(U&amp;&amp; x) &amp;&amp;;
  template&lt;class U&gt; void operator&gt;&gt;=(U&amp;&amp; x) &amp;&amp;;

  void operator++() &amp;&amp;
  void operator++(int) &amp;&amp;
  void operator--() &amp;&amp;
  void operator--(int) &amp;&amp;

  template&lt;class U, class Flags&gt; void copy_from(const U* mem, Flags) &amp;&amp;;
};
      </pre>
      </ins>
  
      <p id="parallel.simd.whereexpr.1" para_num="1">
      <ins>
        The class templates <code>const_where_expression</code> and <code>where_expression</code> abstract the notion of selecting elements of a given object of arithmetic or data-parallel type.
      </ins>
      </p>
  
      <p id="parallel.simd.whereexpr.2" para_num="2">
      <ins>
        The first templates argument <code>M</code> shall be cv-unqualified <code>bool</code> or a cv-unqualified <code>simd_mask</code> specialization.
      </ins>
      </p>
  
      <p id="parallel.simd.whereexpr.3" para_num="3">
      <ins>
        If <code>M</code> is <code>bool</code>, <code>T</code> shall be a cv-unqualified arithmetic type. Otherwise, <code>T</code> shall either be <code>M</code> or <code>typename M::simd_type</code>.
      </ins>
      </p>
  
      <p id="parallel.simd.whereexpr.4" para_num="4">
      <ins>
        In this subclause, if <code>M</code> is <code>bool</code>, <code>data[0]</code> is used interchangably for <code>data</code>, <code>mask[0]</code> is used interchangably for <code>mask</code>, and <code>M::size()</code> is used interchangably for <code>1</code>.
      </ins>
      </p>
  
      <p id="parallel.simd.whereexpr.5" para_num="5">
      <ins>
        The <em>selected indices</em> signify the integers <code>i</code> ∊ {<em>j</em> ∊ ℕ<sub>0</sub> ∣ <em>j</em> &lt; <code>M::size()</code> ⋀ <code>mask[</code><em>j</em><code>]</code> }. The <em>selected elements</em> signify the elements <code>data[i]</code> for all selected indices <code>i</code>.
      </ins>
      </p>
  
      <p id="parallel.simd.whereexpr.6" para_num="6">
      <ins>
        In this subclause, the type <code>value_type</code> is an alias for <code>T</code> if <code>M</code> is <code>bool</code>, or an alias for <code>typename T::value_type</code> if <code>is_simd_mask_v&lt;M&gt;</code> is <code>true</code>.
      </ins>
      <!--- /p --->
  
      </p><p id="parallel.simd.whereexpr.7" para_num="7">
      <ins>
        <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    The <code>where</code> functions <cxx-ref to="parallel.simd.mask.where"><a title="parallel.simd.mask.where" href="#parallel.simd.mask.where">9.6.5</a></cxx-ref> initialize <code>mask</code> with the first argument to <code>where</code> and <code>data</code> with the second argument to <code>where</code>.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
      </ins>
      </p>
  
      <cxx-function id="parallel.simd.whereexpr.8" para_num="8">
    
    <pre><code><cxx-signature><ins>
  T operator-() const &amp;&amp;;
  T operator+() const &amp;&amp;;
  T operator~() const &amp;&amp;;
        </ins>
        </cxx-signature></code></pre>

    <dl>
      
        
  
        <cxx-returns id="parallel.simd.whereexpr.9" para_num="9">
    
    <dt>Returns:</dt><dd>
        <ins>
          A copy of <code>data</code> with the indicated unary operator applied to all selected elements.
        </ins>
        </dd>
  </cxx-returns>
  
        <cxx-throws id="parallel.simd.whereexpr.10" para_num="10">
    
    <dt>Throws:</dt><dd>
        <ins>
          Nothing.
        </ins>
        </dd>
  </cxx-throws>
      
    </dl>
  </cxx-function>
  
      <cxx-function id="parallel.simd.whereexpr.11" para_num="11">
    
    <pre><code><cxx-signature><ins>
template&lt;class U, class Flags&gt; void copy_to(U* mem, Flags) const &amp;&amp;;
        </ins>
        </cxx-signature></code></pre>

    <dl>
      
        
  
        <cxx-requires id="parallel.simd.whereexpr.12" para_num="12">
    
    <dt>Requires:</dt><dd>
        <ins>
          If the template parameter <code>Flags</code> is <code>vector_aligned_tag</code>, <code>mem</code> shall point to storage aligned by <code>memory_alignment_v&lt;T, U&gt;</code>. If the template parameter <code>Flags</code> is <code>overaligned_tag&lt;N&gt;</code>, <code>mem</code> shall point to storage aligned by <code>N</code>. If the template parameter <code>Flags</code> is <code>element_aligned_tag</code>, <code>mem</code> shall point to storage aligned by <code>alignof(U)</code>. If <code>M</code> is not <code>bool</code>, the largest <code>i</code> ∊ <code>[0, M::size())</code> where <code>mask[i]</code> is <code>true</code> is less than the number of values pointed to by <code>mem</code>.
        </ins>
        </dd>
  </cxx-requires>
  
        <cxx-effects id="parallel.simd.whereexpr.13" para_num="13">
    
    <dt>Effects:</dt><dd>
        <ins>
          Copies the selected elements as if <code>mem[i] = static_cast&lt;U&gt;(data[i])</code> for all selected indices <code>i</code>.
        </ins>
        </dd>
  </cxx-effects>
  
        <cxx-throws id="parallel.simd.whereexpr.14" para_num="14">
    
    <dt>Throws:</dt><dd>
        <ins>
          Nothing.
        </ins>
        </dd>
  </cxx-throws>
  
        <cxx-remarks id="parallel.simd.whereexpr.15" para_num="15">
    
    <dt>Remarks:</dt><dd>
        <ins>
          This function shall not participate in overload resolution unless
  
          <ul>
            <li>
              <code>is_simd_flag_type_v&lt;Flags&gt;</code> is <code>true</code>, and
            </li>
  
            <li>
              either
  
              <ul>
                <li>
                  <code>U</code> is <code>bool</code> and <code>value_type</code> is <code>bool</code>, or
                </li>
  
                <li>
                  <code>U</code> is a vectorizable type and <code>value_type</code> is not <code>bool</code>.
                </li>
              </ul>
            </li>
          </ul>
        </ins>
        </dd>
  </cxx-remarks>
      
    </dl>
  </cxx-function>
  
      <cxx-function id="parallel.simd.whereexpr.16" para_num="16">
    
    <pre><code><cxx-signature><ins>
template&lt;class U&gt; void operator=(U&amp;&amp; x) &amp;&amp;;
        </ins>
        </cxx-signature></code></pre>

    <dl>
      
        

        <cxx-effects id="parallel.simd.whereexpr.17" para_num="17">
    
    <dt>Effects:</dt><dd>
        <ins>
          Replaces <code>data[i]</code> with <code>static_cast&lt;T&gt;(std::forward&lt;U&gt;(x))[i]</code> for all selected indices <code>i</code>.
        </ins>
        </dd>
  </cxx-effects>

        <cxx-remarks id="parallel.simd.whereexpr.18" para_num="18">
    
    <dt>Remarks:</dt><dd>
        <ins>
          This operator shall not participate in overload resolution unless <code>U</code> is convertible to <code>T</code>.
        </ins>
        </dd>
  </cxx-remarks>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.whereexpr.19" para_num="19">
    
    <pre><code><cxx-signature><ins>
template&lt;class U&gt; void operator+=(U&amp;&amp; x) &amp;&amp;;
template&lt;class U&gt; void operator-=(U&amp;&amp; x) &amp;&amp;;
template&lt;class U&gt; void operator*=(U&amp;&amp; x) &amp;&amp;;
template&lt;class U&gt; void operator/=(U&amp;&amp; x) &amp;&amp;;
template&lt;class U&gt; void operator%=(U&amp;&amp; x) &amp;&amp;;
template&lt;class U&gt; void operator&amp;=(U&amp;&amp; x) &amp;&amp;;
template&lt;class U&gt; void operator|=(U&amp;&amp; x) &amp;&amp;;
template&lt;class U&gt; void operator^=(U&amp;&amp; x) &amp;&amp;;
template&lt;class U&gt; void operator&lt;&lt;=(U&amp;&amp; x) &amp;&amp;;
template&lt;class U&gt; void operator&gt;&gt;=(U&amp;&amp; x) &amp;&amp;;</ins>
        </cxx-signature></code></pre>

    <dl>
      
        

        <cxx-effects id="parallel.simd.whereexpr.20" para_num="20">
    
    <dt>Effects:</dt><dd>
        <ins>
          Replaces <code>data[i]</code> with <code>static_cast&lt;T&gt;(data @ std::forward&lt;U&gt;(x))[i]</code> (where <code>@</code> denotes the indicated operator) for all selected indices <code>i</code>.
        </ins>
        </dd>
  </cxx-effects>

        <cxx-remarks id="parallel.simd.whereexpr.21" para_num="21">
    
    <dt>Remarks:</dt><dd>
        <ins>
          Each of these operators shall not participate in overload resolution unless the return type of <code>data @ std::forward&lt;U&gt;(x)</code> is convertible to <code>T</code>.
 It is unspecified whether the binary operator, implied by the compound 
assignment operator, is executed on all elements or only on the selected
 elements.
        </ins>
        </dd>
  </cxx-remarks>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.whereexpr.22" para_num="22">
    
    <pre><code><cxx-signature><ins>
void operator++() &amp;&amp;;
void operator++(int) &amp;&amp;;
void operator--() &amp;&amp;;
void operator--(int) &amp;&amp;;
        </ins>
        </cxx-signature></code></pre>

    <dl>
      
        
  
        <cxx-effects id="parallel.simd.whereexpr.23" para_num="23">
    
    <dt>Effects:</dt><dd>
        <ins>
          Applies the indicated operator to the selected elements.
        </ins>
        </dd>
  </cxx-effects>
  
        <cxx-remarks id="parallel.simd.whereexpr.24" para_num="24">
    
    <dt>Remarks:</dt><dd>
        <ins>
          Each of these operators shall not participate in overload 
resolution unless the indicated operator can be applied to objects of 
type <code>T</code>.
        </ins>
        </dd>
  </cxx-remarks>
        
      
    </dl>
  </cxx-function>
  
      <cxx-function id="parallel.simd.whereexpr.25" para_num="25">
    
    <pre><code><cxx-signature><ins>
template&lt;class U, class Flags&gt; void copy_from(const U* mem, Flags) &amp;&amp;;</ins>
        </cxx-signature></code></pre>

    <dl>
      
        
  
        <cxx-requires id="parallel.simd.whereexpr.26" para_num="26">
    
    <dt>Requires:</dt><dd>
        <ins>
          If the template parameter <code>Flags</code> is <code>vector_aligned_tag</code>, <code>mem</code> shall point to storage aligned by <code>memory_alignment_v&lt;T, U&gt;</code>. If the template parameter <code>Flags</code> is <code>overaligned_tag&lt;N&gt;</code>, <code>mem</code> shall point to storage aligned by <code>N</code>. If the template parameter <code>Flags</code> is <code>element_aligned_tag</code>, <code>mem</code> shall point to storage aligned by <code>alignof(U)</code>. If <code>is_simd_flag_type_v&lt;U&gt;</code> is <code>true</code>, for all selected indices <code>i</code>, <code>i</code> shall be less than the number of values pointed to by <code>mem</code>.
        </ins>
        </dd>
  </cxx-requires>
  
        <cxx-effects id="parallel.simd.whereexpr.27" para_num="27">
    
    <dt>Effects:</dt><dd>
        <ins>
          Replaces the selected elements as if <code>data[i] = static_cast&lt;value_type&gt;(mem[i])</code> for all selected indices <code>i</code>.
        </ins>
        </dd>
  </cxx-effects>
  
        <cxx-remarks id="parallel.simd.whereexpr.28" para_num="28">
    
    <dt>Remarks:</dt><dd>
        <ins>
          This function shall not participate in overload resolution unless
  
          <ul>
            <li>
              <code>is_simd_flag_type_v&lt;Flags&gt;</code> is <code>true</code>, and
            </li>
  
            <li>
              either
  
              <ul>
                <li>
                  <code>U</code> is <code>bool</code> and <code>value_type</code> is <code>bool</code>, or
                </li>
  
                <li>
                  <code>U</code> is a vectorizable type and <code>value_type</code> is not <code>bool</code>. 
                </li>
              </ul>
            </li>
          </ul>
        </ins>
        </dd>
  </cxx-remarks>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>
  
    </section>
  </cxx-section>

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

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

    <cxx-section id="parallel.simd.overview">
    

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

      <ins>
      <pre>template&lt;class T, class Abi&gt; class simd {
public:
  using value_type = T;
  using reference = <em>see below</em>;
  using mask_type = simd_mask&lt;T, Abi&gt;
  using abi_type = Abi;

  static constexpr size_t size() noexcept;

  simd() = default;

  <em>// implicit conversion constructor</em>
  template&lt;class U&gt; simd(const simd&lt;U, simd_abi::fixed_size&lt;size()&gt;&gt;&amp;);

  <em>// implicit broadcast constructor (see below for constraints)</em>
  template&lt;class U&gt; simd(U&amp;&amp; value);

  <em>// generator constructor (see below for constraints)</em>
  template&lt;class G&gt; explicit simd(G&amp;&amp; gen);

  <em>// load constructor</em>
  template&lt;class U, class Flags&gt; simd(const U* mem, Flags f);

  <cxx-ref insynopsis="" to="parallel.simd.copy">// <i><a title="parallel.simd.copy" href="#parallel.simd.copy">9.3.4</a>, Copy functions</i></cxx-ref>
  template&lt;class U, class Flags&gt; copy_from(const U* mem, Flags f);
  template&lt;class U, class Flags&gt; copy_to(U* mem, Flags f);

  <cxx-ref insynopsis="" to="parallel.simd.subscr">// <i><a title="parallel.simd.subscr" href="#parallel.simd.subscr">9.3.5</a>, Subscript operators</i></cxx-ref>
  reference operator[](size_t);
  value_type operator[](size_t) const;

  <cxx-ref insynopsis="" to="parallel.simd.unary">// <i><a title="parallel.simd.unary" href="#parallel.simd.unary">9.3.6</a>, Unary operators</i></cxx-ref>
  simd&amp; operator++();
  simd operator++(int);
  simd&amp; operator--();
  simd operator--(int);
  mask_type operator!() const;
  simd operator~() const;
  simd operator+() const;
  simd operator-() const;

  <cxx-ref insynopsis="" to="parallel.simd.binary">// <i><a title="parallel.simd.binary" href="#parallel.simd.binary">9.4.1</a>, Binary operators</i></cxx-ref>
  friend simd operator+(const simd&amp;, const simd&amp;);
  friend simd operator-(const simd&amp;, const simd&amp;);
  friend simd operator*(const simd&amp;, const simd&amp;);
  friend simd operator/(const simd&amp;, const simd&amp;);
  friend simd operator%(const simd&amp;, const simd&amp;);
  friend simd operator&amp;(const simd&amp;, const simd&amp;);
  friend simd operator|(const simd&amp;, const simd&amp;);
  friend simd operator^(const simd&amp;, const simd&amp;);
  friend simd operator&lt;&lt;(const simd&amp;, const simd&amp;);
  friend simd operator&gt;&gt;(const simd&amp;, const simd&amp;);
  friend simd operator&lt;&lt;(const simd&amp;, int);
  friend simd operator&gt;&gt;(const simd&amp;, int);

  <cxx-ref insynopsis="" to="parallel.simd.cassign">// <i><a title="parallel.simd.cassign" href="#parallel.simd.cassign">9.4.2</a>, Compound assignment</i></cxx-ref>
  friend simd&amp; operator+=(simd&amp;, const simd&amp;);
  friend simd&amp; operator-=(simd&amp;, const simd&amp;);
  friend simd&amp; operator*=(simd&amp;, const simd&amp;);
  friend simd&amp; operator/=(simd&amp;, const simd&amp;);
  friend simd&amp; operator%=(simd&amp;, const simd&amp;);
  friend simd&amp; operator&amp;=(simd&amp;, const simd&amp;);
  friend simd&amp; operator|=(simd&amp;, const simd&amp;);
  friend simd&amp; operator^=(simd&amp;, const simd&amp;);
  friend simd&amp; operator&lt;&lt;=(simd&amp;, const simd&amp;);
  friend simd&amp; operator&gt;&gt;=(simd&amp;, const simd&amp;);
  friend simd&amp; operator&lt;&lt;=(simd&amp;, int);
  friend simd&amp; operator&gt;&gt;=(simd&amp;, int);

  <cxx-ref insynopsis="" to="parallel.simd.comparison">// <i><a title="parallel.simd.comparison" href="#parallel.simd.comparison">9.4.3</a>, Compare operators</i></cxx-ref>
  friend mask_type operator==(const simd&amp;, const simd&amp;);
  friend mask_type operator!=(const simd&amp;, const simd&amp;);
  friend mask_type operator&gt;=(const simd&amp;, const simd&amp;);
  friend mask_type operator&lt;=(const simd&amp;, const simd&amp;);
  friend mask_type operator&gt;(const simd&amp;, const simd&amp;);
  friend mask_type operator&lt;(const simd&amp;, const simd&amp;);
};
      </pre>
      </ins>

      <p id="parallel.simd.overview.1" para_num="1">
      <ins>
        The class template <code>simd</code> is a data-parallel type. The width of a given <code>simd</code> specialization is a constant expression, determined by the template parameters.
      </ins>
      </p>

      <p id="parallel.simd.overview.2" para_num="2">
      <ins>
        Every specialization of <code>simd</code> shall be a complete type. The specialization <code>simd&lt;T, Abi&gt;</code> is supported if <code>T</code> is a vectorizable type and

        </ins></p><ul>
          <li>
          <ins>
            <code>Abi</code> is <code>simd_abi::scalar</code>, or
          </ins>
          </li>

          <li>
          <ins>
            <code>Abi</code> is <code>simd_abi::fixed_size&lt;N&gt;</code>, with <code>N</code> is constrained as defined in <cxx-ref to="parallel.simd.abi"><a title="parallel.simd.abi" href="#parallel.simd.abi">9.2.1</a></cxx-ref>.
          </ins>
          </li>
        </ul>

        <ins>
          If <code>Abi</code> is an extended ABI tag, it is implementation-defined whether <code>simd&lt;T, Abi&gt;</code> is supported. <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    The intent is for implementations to decide on the basis of the currently targeted system.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
          
          <br><br>

          If <code>simd&lt;T, Abi&gt;</code> is not supported, the 
specialization shall have a deleted default constructor, deleted 
destructor, deleted copy constructor, and deleted copy assignment.

          <br><br>

          <cxx-example>
    
    <span class="nowrap">[ <em>Example:</em></span>
    
            Consider an implementation that defines the extended ABI tags <code>__simd_x</code> and <code>__gpu_y</code>. When the compiler is invoked to translate to a machine that has support for the <code>__simd_x</code> ABI tag for all arithmetic types other than <code>long double</code> and no support for the <code>__gpu_y</code> ABI tag, then:

            <ul>
              <li>
                <code>simd&lt;T, simd_abi::__gpu_y&gt;</code> is not supported for any <code>T</code> and has a deleted constructor.
              </li>

              <li>
                <code>simd&lt;long double, simd_abi::__simd_x&gt;</code> is not supported and has a deleted constructor.
              </li>

              <li>
                <code>simd&lt;double, simd_abi::__simd_x&gt;</code> is supported.
              </li>

              <li>
                <code>simd&lt;long double, simd_abi::scalar&gt;</code> is supported.
              </li>
            </ul>
          
    <span class="nowrap">— <em>end example</em> ]</span>
  </cxx-example>
        </ins>
      
      <!--- /p --->

      <p id="parallel.simd.overview.3" para_num="3">
      <ins>
        Default intialization performs no initialization of the elements; value-initialization initializes each element with <code>T()</code>. <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    Thus, default initialization leaves the elements in an indeterminate state.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
      </ins>
      </p>

      <cxx-function id="parallel.simd.overview.4" para_num="4">
    
    <pre><code><cxx-signature><ins>
static constexpr size_t size() noexcept;</ins>
        </cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.simd.overview.5" para_num="5">
    
    <dt>Returns:</dt><dd>
        <ins>
          The width of <code>simd&lt;T, Abi&gt;</code>.
        </ins>
        </dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

    <p id="parallel.simd.overview.6" para_num="6">
    <ins>
      Implementations should enable explicit conversion from and to 
implementation-defined types. This adds one or more of the following 
declarations to class <code>simd</code>:

      <br>
      <br>

      <code><ins>explicit operator <em>implementation-defined</em>() const;</ins></code>
      <code><ins>explicit simd(const <em>implementation-defined</em>&amp; init);</ins></code>

      <br>
      <br>

      [ <em>Example:</em>
        Consider an implementation that supports the type <code>__vec4f</code> and the function <code>__vec4f _vec4f_addsub(__vec4f, __vec4f)</code> for the currently targeted system.
        A user may require the use of <code>_vec4f_addsub</code> for maximum performance and thus writes:

        </ins></p><pre><ins>
using V = simd&lt;float, simd_abi::__simd128&gt;;
V addsub(V a, V b) {
  return static_cast&lt;V&gt;(_vec4f_addsub(static_cast&lt;__vec4f&gt;(a), static_cast&lt;__vec4f&gt;(b)));
}
        </ins>
        </pre>
      <ins>
      <em>— end example</em> ]
      </ins>
    
    <!--- /p --->
    
    </section>
  </cxx-section>

    <cxx-section id="parallel.simd.reference">
    

    <section>
      <header><span class="section-number">9.3.2</span> <h1 data-bookmark-label="9.3.2 Element references"><ins>Element references</ins></h1> <span style="float:right"><a href="#parallel.simd.reference">[parallel.simd.reference]</a></span></header>
      
      

      <p id="parallel.simd.reference.1" para_num="1">
      <ins>
        A <code>reference</code> is an object that refers to an element in a <code>simd</code> or <code>simd_mask</code> object. <code>reference::value_type</code> is the same type as <code>simd::value_type</code> or <code>simd_mask::value_type</code>, respectively.
      </ins>
      </p>

      <p id="parallel.simd.reference.2" para_num="2">
      <ins>
        Class <code>reference</code> is for exposition only. An 
implementation is permitted to provide equivalent functionality without 
providing a class with this name.
      </ins>

        </p><pre>        <ins>
class reference <em>// exposition only</em>
{
public:
  reference() = delete;
  reference(const reference&amp;) = delete;

  operator value_type() const noexcept;

  template&lt;class U&gt; reference operator=(U&amp;&amp; x) &amp;&amp;;

  template&lt;class U&gt; reference operator+=(U&amp;&amp; x) &amp;&amp;;
  template&lt;class U&gt; reference operator-=(U&amp;&amp; x) &amp;&amp;;
  template&lt;class U&gt; reference operator*=(U&amp;&amp; x) &amp;&amp;;
  template&lt;class U&gt; reference operator/=(U&amp;&amp; x) &amp;&amp;;
  template&lt;class U&gt; reference operator%=(U&amp;&amp; x) &amp;&amp;;
  template&lt;class U&gt; reference operator|=(U&amp;&amp; x) &amp;&amp;;
  template&lt;class U&gt; reference operator&amp;=(U&amp;&amp; x) &amp;&amp;;
  template&lt;class U&gt; reference operator^=(U&amp;&amp; x) &amp;&amp;;
  template&lt;class U&gt; reference operator&lt;&lt;=(U&amp;&amp; x) &amp;&amp;;
  template&lt;class U&gt; reference operator&gt;&gt;=(U&amp;&amp; x) &amp;&amp;;

  reference operator++() &amp;&amp;;
  value_type operator++(int) &amp;&amp;;
  reference operator--() &amp;&amp;;
  value_type operator--(int) &amp;&amp;;

  friend void swap(reference&amp;&amp; a, reference&amp;&amp; b) noexcept;
  friend void swap(value_type&amp;&amp; a, reference&amp;&amp; b) noexcept;
  friend void swap(reference&amp;&amp; a, value_type&amp;&amp; b) noexcept;
};</ins>
        </pre>
      <!--- /p --->

      <cxx-function id="parallel.simd.reference.3" para_num="3">
    
    <pre><code><cxx-signature><ins>operator value_type() const noexcept;</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.simd.reference.4" para_num="4">
    
    <dt>Returns:</dt><dd>
        <ins>
          The value of the element referred to by <code>*this</code>.
        </ins>
        </dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.reference.5" para_num="5">
    
    <pre><code><cxx-signature><ins>template&lt;class U&gt; reference operator=(U&amp;&amp; x) &amp;&amp;;</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-effects id="parallel.simd.reference.6" para_num="6">
    
    <dt>Effects:</dt><dd>
        <ins>
          Replaces the referred to element in <code>simd</code> or <code>simd_mask</code> with <code>static_cast&lt;value_type&gt;(std::forward&lt;U&gt;(x))</code>.
        </ins>
        </dd>
  </cxx-effects>

        <cxx-returns id="parallel.simd.reference.7" para_num="7">
    
    <dt>Returns:</dt><dd>
        <ins>
          A copy of <code>*this</code>.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-remarks id="parallel.simd.reference.8" para_num="8">
    
    <dt>Remarks:</dt><dd>
        <ins>
          This function shall not participate in overload resolution unless <code>declval&lt;value_type &amp;&gt;() = std::forward&gt;U&gt;(x)</code> is well-formed.
        </ins>
        </dd>
  </cxx-remarks>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.reference.9" para_num="9">
    
    <pre><code><cxx-signature><ins>
template&lt;class U&gt; reference operator+=(U&amp;&amp; x) &amp;&amp;;
template&lt;class U&gt; reference operator-=(U&amp;&amp; x) &amp;&amp;;
template&lt;class U&gt; reference operator*=(U&amp;&amp; x) &amp;&amp;;
template&lt;class U&gt; reference operator/=(U&amp;&amp; x) &amp;&amp;;
template&lt;class U&gt; reference operator%=(U&amp;&amp; x) &amp;&amp;;
template&lt;class U&gt; reference operator|=(U&amp;&amp; x) &amp;&amp;;
template&lt;class U&gt; reference operator&amp;=(U&amp;&amp; x) &amp;&amp;;
template&lt;class U&gt; reference operator^=(U&amp;&amp; x) &amp;&amp;;
template&lt;class U&gt; reference operator&lt;&lt;=(U&amp;&amp; x) &amp;&amp;;
template&lt;class U&gt; reference operator&gt;&gt;=(U&amp;&amp; x) &amp;&amp;;</ins>
        </cxx-signature></code></pre>

    <dl>
      
        

        <cxx-effects id="parallel.simd.reference.10" para_num="10">
    
    <dt>Effects:</dt><dd>
        <ins>
          Applies the indicated compound operator to the referred to element in <code>simd</code> or <code>simd_mask</code> and <code>std::forward&lt;U&gt;(x)</code>.
        </ins>
        </dd>
  </cxx-effects>

        <cxx-returns id="parallel.simd.reference.11" para_num="11">
    
    <dt>Returns:</dt><dd>
        <ins>
          A copy of <code>*this</code>.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-remarks id="parallel.simd.reference.12" para_num="12">
    
    <dt>Remarks:</dt><dd>
        <ins>
          This function shall not participate in overload resolution unless <code>declval&lt;value_type &amp;&gt;() @= std::forward&lt;U&gt;(x)</code> (where <code>@=</code> denotes the indicated compound assignment operator) is well-formed.
        </ins>
        </dd>
  </cxx-remarks>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.reference.13" para_num="13">
    
    <pre><code><cxx-signature><ins>
reference operator++() &amp;&amp;;
reference operator--() &amp;&amp;;
        </ins>
        </cxx-signature></code></pre>

    <dl>
      
        

        <cxx-effects id="parallel.simd.reference.14" para_num="14">
    
    <dt>Effects:</dt><dd>
        <ins>
          Applies the indicated operator to the referred to element in <code>simd</code> or <code>simd_mask</code>.
        </ins>
        </dd>
  </cxx-effects>

        <cxx-returns id="parallel.simd.reference.15" para_num="15">
    
    <dt>Returns:</dt><dd>
        <ins>
          A copy of <code>*this</code>.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-remarks id="parallel.simd.reference.16" para_num="16">
    
    <dt>Remarks:</dt><dd>
        <ins>
          This function shall not participate in overload resolution 
unless the indicated operator can be applied to objects of type <code>value_type</code>.
        </ins>
        </dd>
  </cxx-remarks>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.reference.17" para_num="17">
    
    <pre><code><cxx-signature><ins>
value_type operator++(int) &amp;&amp;;
value_type operator--(int) &amp;&amp;;
        </ins>
        </cxx-signature></code></pre>

    <dl>
      
        

        <cxx-effects id="parallel.simd.reference.18" para_num="18">
    
    <dt>Effects:</dt><dd>
        <ins>
          Applies the indicated operator to the referred to element in <code>simd</code> or <code>simd_mask</code>.
        </ins>
        </dd>
  </cxx-effects>

        <cxx-returns id="parallel.simd.reference.19" para_num="19">
    
    <dt>Returns:</dt><dd>
        <ins>
          A copy of the referred to element before applying the indicated operator.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-remarks id="parallel.simd.reference.20" para_num="20">
    
    <dt>Remarks:</dt><dd>
        <ins>
          This function shall not participate in overload resolution 
unless the indicated operator can be applied to objects of type <code>value_type</code>.
        </ins>
        </dd>
  </cxx-remarks>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.reference.21" para_num="21">
    
    <pre><code><cxx-signature><ins>
friend void swap(reference&amp;&amp; a, reference&amp;&amp; b) noexcept;
friend void swap(value_type&amp; a, reference&amp;&amp; b) noexcept;
friend void swap(reference&amp;&amp; a, value_type&amp; b) noexcept;</ins>
        </cxx-signature></code></pre>

    <dl>
      
        

        <cxx-effects id="parallel.simd.reference.22" para_num="22">
    
    <dt>Effects:</dt><dd>
        <ins>
          Exchanges the values <code>a</code> and <code>b</code> refer to.
        </ins>
        </dd>
  </cxx-effects>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>
    
    <cxx-section id="parallel.simd.ctor">
    

    <section>
      <header><span class="section-number">9.3.3</span> <h1 data-bookmark-label="9.3.3 Constructors"><ins>Constructors</ins></h1> <span style="float:right"><a href="#parallel.simd.ctor">[parallel.simd.ctor]</a></span></header>
      
      

      <cxx-function id="parallel.simd.ctor.1" para_num="1">
    
    <pre><code><cxx-signature><ins>template&lt;class U&gt; simd(U&amp;&amp;);</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-effects id="parallel.simd.ctor.2" para_num="2">
    
    <dt>Effects:</dt><dd>
        <ins>
          Constructs an object with each element initialized to the value of the argument after conversion to <code>value_type</code>.
        </ins>
        </dd>
  </cxx-effects>

        <cxx-throws id="parallel.simd.ctor.3" para_num="3">
    
    <dt>Throws:</dt><dd>
        <ins>
          Any exception thrown while converting the argument to <code>value_type</code>.
        </ins>
        </dd>
  </cxx-throws>

        <cxx-remarks id="parallel.simd.ctor.4" para_num="4">
    
    <dt>Remarks:</dt><dd>
        <ins>
          Let <code>From</code> identify the type <code>remove_cv_t&lt;remove_reference_t&lt;U&gt;&gt;</code>. This constructor shall not participate in overload resolution unless:

          <br>
          <br>

          <ul>
            <li>
              <code>From</code> is a vectorizable type and every possibly value of <code>From</code> can be represented with type <code>value_type</code>, or
            </li>

            <li>
              <code>From</code> is not an arithmetic type and is implicitly convertible to <code>value_type</code>, or
            </li>

            <li>
              <code>From</code> is <code>int</code>, or

            </li><li>
              <code>From</code> is <code>unsigned int</code> and <code>value_type</code> is an unsigned integral type.
            </li>
            
          </ul>
        </ins>
        </dd>
  </cxx-remarks>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.ctor.5" para_num="5">
    
    <pre><code><cxx-signature><ins>template&lt;class U&gt; simd(const simd&lt;U, simd_abi::fixed_size&lt;size()&gt;&gt;&amp; x);</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-effects id="parallel.simd.ctor.6" para_num="6">
    
    <dt>Effects:</dt><dd>
        <ins>
          Constructs an object where the <em>i</em>-th element equals <code>static_cast&lt;T&gt;(x[i])</code> for all <code>i</code> ∊ <code>[0, size())</code>.
        </ins>
        </dd>
  </cxx-effects>

        <cxx-remarks id="parallel.simd.ctor.7" para_num="7">
    
    <dt>Remarks:</dt><dd>
        <ins>
          This constructor shall not participate in overload resolution unless
        </ins>

          <ul>
            <li>
            <ins>
              <code>abi_type</code> is <code>simd_abi::fixed_size&lt;size()&gt;</code>, and
            </ins>
            </li>

            <li>
            <ins>
              every possible value of <code>U</code> can be represented with type <code>value_type</code>, and
            </ins>
            </li>

            <li>
            <ins>
              if both <code>U</code> and <code>value_type</code> are integral, the integer conversion rank [conv.rank] of <code>value_type</code> is greater than the integer conversion rank of <code>U</code>.
            </ins>
            </li>
          </ul>
        </dd>
  </cxx-remarks>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.ctor.8" para_num="8">
    
    <pre><code><cxx-signature><ins>template&lt;class G&gt; simd(G&amp;&amp; gen);</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-effects id="parallel.simd.ctor.9" para_num="9">
    
    <dt>Effects:</dt><dd>
        <ins>
          Constructs an object where the <em>i</em>-th element is initialized to <code>gen(integral_constant&lt;size_t, i&gt;())</code>.
        </ins>
        </dd>
  </cxx-effects>

        <cxx-remarks id="parallel.simd.ctor.10" para_num="10">
    
    <dt>Remarks:</dt><dd>
        <ins>
          This constructor shall not participate in overload resolution unless <code>simd(gen(integral_constant&lt;size_t, i&gt;()))</code> is well-formed for all <code>i</code> ∊ <code>[0, size())</code>.
        </ins>
        </dd>
  </cxx-remarks>

        <p id="parallel.simd.ctor.11" para_num="11">
        <ins>
          The calls to <code>gen</code> are unsequenced with respect to each other. Vectorization-unsafe standard library functions may not be invoked by <code>gen</code> ([algorithms.parallel.exec]).
        </ins>
        </p>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.ctor.12" para_num="12">
    
    <pre><code><cxx-signature><ins>template&lt;class U, class Flags&gt; simd(const U* mem, Flags);</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-requires id="parallel.simd.ctor.13" para_num="13">
    
    <dt>Requires:</dt><dd>
        <ins>
          If the template parameter <code>Flags</code> is <code>vector_aligned_tag</code>, <code>mem</code> shall point to storage aligend by <code>memory_alignment_v&lt;simd, U&gt;</code>. If the template parameter <code>Flags</code> is <code>overaligned_tag&lt;N&gt;</code>, <code>mem</code> shall point to storage aligned by <code>N</code>. If the template parameter <code>Flags</code> is <code>element_aligned_tag</code>, <code>mem</code> shall point to storage aligned by <code>alignof(U)</code>. <code>[mem, mem + size())</code> is a valid range.
        </ins>
        </dd>
  </cxx-requires>

        <cxx-effects id="parallel.simd.ctor.14" para_num="14">
    
    <dt>Effects:</dt><dd>
        <ins>
          Constructs an object where the <em>i</em>-th element is initialized to <code>static_cast&lt;T&gt;(mem[i])</code> for all <code>i</code> ∊ <code>[0, size())</code>. 
        </ins>
        </dd>
  </cxx-effects>

        <cxx-remarks id="parallel.simd.ctor.15" para_num="15">
    
    <dt>Remarks:</dt><dd>
        <ins>
          This constructor shall not participate in overload resolution unless

          <ul>
            <li>
            <ins>
              <code>is_simd_flag_type_v&lt;Flags&gt;</code> is <code>true</code>, and
            </ins>
            </li>

            <li>
            <ins>
              <code>U</code> is a vectorizable type.
            </ins>
            </li>
          </ul>
        </ins>
        </dd>
  </cxx-remarks>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

    <cxx-section id="parallel.simd.copy">
    

    <section>
      <header><span class="section-number">9.3.4</span> <h1 data-bookmark-label="9.3.4 Copy functions"><ins>Copy functions</ins></h1> <span style="float:right"><a href="#parallel.simd.copy">[parallel.simd.copy]</a></span></header>
      
      

      <cxx-function id="parallel.simd.copy.1" para_num="1">
    
    <pre><code><cxx-signature><ins>template&lt;class U, class Flags&gt; void copy_from(const U* mem, Flags);</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-requires id="parallel.simd.copy.2" para_num="2">
    
    <dt>Requires:</dt><dd>
        <ins>
          If the template parameter <code>Flags</code> is <code>vector_aligned_tag</code>, <code>mem</code> shall point to storage aligned by <code>memory_alignment_v&lt;simd, U&gt;</code>. If the template parameter <code>Flags</code> is <code>overaligned_tag&lt;N&gt;</code>, <code>mem</code> shall point to storage aligend by <code>N</code>. If the template parameter <code>Flags</code> is <code>element_aligned_tag</code>, <code>mem</code> shall point to storage aligned by <code>alignof(U)</code>. <code>[mem, mem + size())</code> is a valid range.
        </ins>
        </dd>
  </cxx-requires>

        <cxx-effects id="parallel.simd.copy.3" para_num="3">
    
    <dt>Effects:</dt><dd>
        <ins>
          Replaces the elements of the <code>simd</code> object such that the <em>i</em>-th element is assigned with <code>static_cast&lt;T&gt;(mem[i])</code> for all <code>i</code> ∊ <code>[0, size())</code>.
        </ins>
        </dd>
  </cxx-effects>

        <cxx-remarks id="parallel.simd.copy.4" para_num="4">
    
    <dt>Remarks:</dt><dd>
        <ins>
          This function shall not participate in overload resolution unless

          <ul>
            <li>
              <code>is_simd_flag_type_v&lt;Flags&gt;</code> is <code>true</code>, and
            </li>

            <li>
              <code>U</code> is a vectorizable type.
            </li>
          </ul>
        </ins>
        </dd>
  </cxx-remarks>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.copy.5" para_num="5">
    
    <pre><code><cxx-signature><ins>template&lt;class U, class Flags&gt; void copy_to(U* mem, Flags) const;</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-requires id="parallel.simd.copy.6" para_num="6">
    
    <dt>Requires:</dt><dd>
        <ins>
          If the template parameter <code>Flags</code> is <code>vector_aligned_tag</code>, <code>mem</code> shall point to storage aligned by <code>memory_alignment_v&lt;simd, U&gt;</code>. If the template parameter <code>Flags</code> is <code>overaligned_tag&lt;N&gt;</code>, <code>mem</code> shall point to storage aligned by <code>N</code>. If the template parameter <code>Flags</code> is <code>element_aligned_tag</code>, <code>mem</code> shall point to storage aligned by <code>alignof(U)</code>. <code>[mem, mem + size())</code> is a valid range.
        </ins>
        </dd>
  </cxx-requires>

        <cxx-effects id="parallel.simd.copy.7" para_num="7">
    
    <dt>Effects:</dt><dd>
        <ins>
          Copies all <code>simd</code> elements as if <code>mem[i] = static_cast&lt;U&gt;(operator[](i))</code> for all <code>i</code> ∊ <code>[0, size())</code>.
        </ins>
        </dd>
  </cxx-effects>

        <cxx-remarks id="parallel.simd.copy.8" para_num="8">
    
    <dt>Remarks:</dt><dd>
        <ins>
          This function shall not participate in overload resolution unless

          <ul>
            <li>
              <code>is_simd_flag_type_v&lt;Flags&gt;</code> is <code>true</code>, and
            </li>

            <li>
              <code>U</code> is a vectorizable type.
            </li>
          </ul>
        </ins>
        </dd>
  </cxx-remarks>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

    <cxx-section id="parallel.simd.subscr">
    

    <section>
      <header><span class="section-number">9.3.5</span> <h1 data-bookmark-label="9.3.5 Subscript operators"><ins>Subscript operators</ins></h1> <span style="float:right"><a href="#parallel.simd.subscr">[parallel.simd.subscr]</a></span></header>
      
      

      <cxx-function id="parallel.simd.subscr.1" para_num="1">
    
    <pre><code><cxx-signature><ins>reference operator[](size_t i);</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-requires id="parallel.simd.subscr.2" para_num="2">
    
    <dt>Requires:</dt><dd>
        <ins>
          <code>i &lt; size()</code>.
        </ins>
        </dd>
  </cxx-requires>

        <cxx-returns id="parallel.simd.subscr.3" para_num="3">
    
    <dt>Returns:</dt><dd>
        <ins>
          A <code>reference</code> (see <cxx-ref to="parallel.simd.reference"><a title="parallel.simd.reference" href="#parallel.simd.reference">9.3.2</a></cxx-ref>) referring to the <em>i</em>-th element.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-throws id="parallel.simd.subscr.4" para_num="4">
    
    <dt>Throws:</dt><dd>
        <ins>
          Nothing.
        </ins>
        </dd>
  </cxx-throws>
      
    </dl>
  </cxx-function>
      
      <cxx-function id="parallel.simd.subscr.5" para_num="5">
    
    <pre><code><cxx-signature><ins>value_type operator[](size_t i) const;</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-requires id="parallel.simd.subscr.6" para_num="6">
    
    <dt>Requires:</dt><dd>
        <ins>
          <code>i &lt; size()</code>.
        </ins>
        </dd>
  </cxx-requires>

        <cxx-returns id="parallel.simd.subscr.7" para_num="7">
    
    <dt>Returns:</dt><dd>
        <ins>
          The value of the <em>i</em>-th element.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-throws id="parallel.simd.subscr.8" para_num="8">
    
    <dt>Throws:</dt><dd>
        <ins>
          Nothing.
        </ins>
        </dd>
  </cxx-throws>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

    <cxx-section id="parallel.simd.unary">
    

    <section>
      <header><span class="section-number">9.3.6</span> <h1 data-bookmark-label="9.3.6 Unary operators"><ins>Unary operators</ins></h1> <span style="float:right"><a href="#parallel.simd.unary">[parallel.simd.unary]</a></span></header>
      
      

      <p id="parallel.simd.unary.1" para_num="1">
      <ins>
        Effects in this subclause are applied as unary element-wise operations.
      </ins>
      </p>

      <cxx-function id="parallel.simd.unary.2" para_num="2">
    
    <pre><code><cxx-signature><ins>simd&amp; operator++();</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-effects id="parallel.simd.unary.3" para_num="3">
    
    <dt>Effects:</dt><dd>
        <ins>
          Increments every element by one.
        </ins>
        </dd>
  </cxx-effects>

        <cxx-returns id="parallel.simd.unary.4" para_num="4">
    
    <dt>Returns:</dt><dd>
        <ins>
          <code>*this</code>.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-throws id="parallel.simd.unary.5" para_num="5">
    
    <dt>Throws:</dt><dd>
        <ins>
          Nothing.
        </ins>
        </dd>
  </cxx-throws>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.unary.6" para_num="6">
    
    <pre><code><cxx-signature><ins>simd operator++(int);</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-effects id="parallel.simd.unary.7" para_num="7">
    
    <dt>Effects:</dt><dd>
        <ins>
          Increments every element by one.
        </ins>
        </dd>
  </cxx-effects>

        <cxx-returns id="parallel.simd.unary.8" para_num="8">
    
    <dt>Returns:</dt><dd>
        <ins>
          A copy of <code>*this</code> before incrementing.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-throws id="parallel.simd.unary.9" para_num="9">
    
    <dt>Throws:</dt><dd>
        <ins>
          Nothing.
        </ins>
        </dd>
  </cxx-throws>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.unary.10" para_num="10">
    
    <pre><code><cxx-signature><ins>simd&amp; operator--();</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-effects id="parallel.simd.unary.11" para_num="11">
    
    <dt>Effects:</dt><dd>
        <ins>
          Decrements every element by one.
        </ins>
        </dd>
  </cxx-effects>

        <cxx-returns id="parallel.simd.unary.12" para_num="12">
    
    <dt>Returns:</dt><dd>
        <ins>
          <code>*this</code>.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-throws id="parallel.simd.unary.13" para_num="13">
    
    <dt>Throws:</dt><dd>
        <ins>
          Nothing.
        </ins>
        </dd>
  </cxx-throws>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.unary.14" para_num="14">
    
    <pre><code><cxx-signature><ins>simd operator--(int);</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-effects id="parallel.simd.unary.15" para_num="15">
    
    <dt>Effects:</dt><dd>
        <ins>
          Decrements every element by one.
        </ins>
        </dd>
  </cxx-effects>

        <cxx-returns id="parallel.simd.unary.16" para_num="16">
    
    <dt>Returns:</dt><dd>
        <ins>
          A copy of <code>*this</code> before decrementing.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-throws id="parallel.simd.unary.17" para_num="17">
    
    <dt>Throws:</dt><dd>
        <ins>
          Nothing.
        </ins>
        </dd>
  </cxx-throws>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.unary.18" para_num="18">
    
    <pre><code><cxx-signature><ins>mask_type operator!() const;</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.simd.unary.19" para_num="19">
    
    <dt>Returns:</dt><dd>
        <ins>
          A <code>simd_mask</code> object with the <em>i</em>-th element set to <code>!operator[](i)</code> for all <code>i</code> ∊ <code>[0, size())</code>. 
        </ins>
        </dd>
  </cxx-returns>

        <cxx-throws id="parallel.simd.unary.20" para_num="20">
    
    <dt>Throws:</dt><dd>
          <ins>
            Nothing.
          </ins>
        </dd>
  </cxx-throws>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.unary.21" para_num="21">
    
    <pre><code><cxx-signature><ins>simd operator~() const;</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.simd.unary.22" para_num="22">
    
    <dt>Returns:</dt><dd>
        <ins>
          A <code>simd</code> object where each bit is the inverse of the corresponding bit in <code>*this</code>.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-throws id="parallel.simd.unary.23" para_num="23">
    
    <dt>Throws:</dt><dd>
        <ins>
          Nothing.
        </ins>
        </dd>
  </cxx-throws>

        <cxx-remarks id="parallel.simd.unary.24" para_num="24">
    
    <dt>Remarks:</dt><dd>
        <ins>
          This operator shall not participate in overload resolution unless <code>T</code> is an integral type.
        </ins>
        </dd>
  </cxx-remarks>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.unary.25" para_num="25">
    
    <pre><code><cxx-signature><ins>simd operator+() const;</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.simd.unary.26" para_num="26">
    
    <dt>Returns:</dt><dd>
        <ins>
          <code>*this</code>.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-throws id="parallel.simd.unary.27" para_num="27">
    
    <dt>Throws:</dt><dd>
        <ins>
          Nothing.
        </ins>
        </dd>
  </cxx-throws>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.unary.28" para_num="28">
    
    <pre><code><cxx-signature><ins>simd operator-() const;</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.simd.unary.29" para_num="29">
    
    <dt>Returns:</dt><dd>
        <ins>
          A <code>simd</code> object where the <em>i</em>-th element is initialized to <code>-operator[](i)</code> for all <code>i</code> ∊ <code>[0, size())</code>.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-throws id="parallel.simd.unary.30" para_num="30">
    
    <dt>Throws:</dt><dd>
        <ins>
          Nothing.
        </ins>
        </dd>
  </cxx-throws>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>
  
    </section>
  </cxx-section>

  <cxx-section id="parallel.simd.nonmembers">
    

    <section>
      <header><span class="section-number">9.4</span> <h1 data-bookmark-label="9.4 Non-member operations"><ins>Non-member operations</ins></h1> <span style="float:right"><a href="#parallel.simd.nonmembers">[parallel.simd.nonmembers]</a></span></header>
      
    

    <cxx-section id="parallel.simd.binary">
    

    <section>
      <header><span class="section-number">9.4.1</span> <h1 data-bookmark-label="9.4.1 Binary operators"><ins>Binary operators</ins></h1> <span style="float:right"><a href="#parallel.simd.binary">[parallel.simd.binary]</a></span></header>
      
      
      <cxx-function id="parallel.simd.binary.1" para_num="1">
    
    <pre><code><cxx-signature><ins>
friend simd operator+(const simd&amp; lhs, const simd&amp; rhs);
friend simd operator-(const simd&amp; lhs, const simd&amp; rhs);
friend simd operator*(const simd&amp; lhs, const simd&amp; rhs);
friend simd operator/(const simd&amp; lhs, const simd&amp; rhs);
friend simd operator%(const simd&amp; lhs, const simd&amp; rhs);
friend simd operator&amp;(const simd&amp; lhs, const simd&amp; rhs);
friend simd operator|(const simd&amp; lhs, const simd&amp; rhs);
friend simd operator^(const simd&amp; lhs, const simd&amp; rhs);
friend simd operator&lt;&lt;(const simd&amp; lhs, const simd&amp; rhs);
friend simd operator&gt;&gt;(const simd&amp; lhs, const simd&amp; rhs);
</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.simd.binary.2" para_num="2">
    
    <dt>Returns:</dt><dd>
        <ins>
          A <code>simd</code> object initialized with the results of the element-wise application of the indicated operator.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-throws id="parallel.simd.binary.3" para_num="3">
    
    <dt>Throws:</dt><dd>
        <ins>
          Nothing.
        </ins>
        </dd>
  </cxx-throws>

        <cxx-remarks id="parallel.simd.binary.4" para_num="4">
    
    <dt>Remarks:</dt><dd>
        <ins>
          Each of these operators shall not participate in overload 
resolution unless the indicated operator can be applied to objects of 
type <code>value_type</code>.
        </ins>
        </dd>
  </cxx-remarks>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.binary.5" para_num="5">
    
    <pre><code><cxx-signature><ins>
friend simd operator&lt;&lt;(const simd&amp; v, int n);
friend simd operator&gt;&gt;(const simd&amp; v, int n);
</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.simd.binary.6" para_num="6">
    
    <dt>Returns:</dt><dd>
        <ins>
          A <code>simd</code> object where the <em>i</em>-th element is initialized to the result of applying the indicated operator to <code>v[i]</code> and <code>n</code> for all <code>i</code> ∊ <code>[0, size())</code>.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-throws id="parallel.simd.binary.7" para_num="7">
    
    <dt>Throws:</dt><dd>
        <ins>
          Nothing.
        </ins>
        </dd>
  </cxx-throws>

        <cxx-remarks id="parallel.simd.binary.8" para_num="8">
    
    <dt>Remarks:</dt><dd>
        <ins>
          These operators shall not participate in overload resolution 
unless the indicated operator can be applied to objects of type <code>value_type</code>.
        </ins>
        </dd>
  </cxx-remarks>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

    <cxx-section id="parallel.simd.cassign">
    

    <section>
      <header><span class="section-number">9.4.2</span> <h1 data-bookmark-label="9.4.2 Compound assignment"><ins>Compound assignment</ins></h1> <span style="float:right"><a href="#parallel.simd.cassign">[parallel.simd.cassign]</a></span></header>
      
      

      <cxx-function id="parallel.simd.cassign.1" para_num="1">
    
    <pre><code><cxx-signature><ins>
friend simd&amp; operator+=(simd&amp; lhs, const simd&amp; rhs);
friend simd&amp; operator-=(simd&amp; lhs, const simd&amp; rhs);
friend simd&amp; operator*=(simd&amp; lhs, const simd&amp; rhs);
friend simd&amp; operator/=(simd&amp; lhs, const simd&amp; rhs);
friend simd&amp; operator%=(simd&amp; lhs, const simd&amp; rhs);
friend simd&amp; operator&amp;=(simd&amp; lhs, const simd&amp; rhs);
friend simd&amp; operator|=(simd&amp; lhs, const simd&amp; rhs);
friend simd&amp; operator^=(simd&amp; lhs, const simd&amp; rhs);
friend simd&amp; operator&lt;&lt;=(simd&amp; lhs, const simd&amp; rhs);
friend simd&amp; operator&gt;&gt;=(simd&amp; lhs, const simd&amp; rhs);
friend simd&amp; operator&lt;&lt;=(simd&amp; lhs, int n);
friend simd&amp; operator&gt;&gt;=(simd&amp; lhs, int n);
</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-effects id="parallel.simd.cassign.2" para_num="2">
    
    <dt>Effects:</dt><dd>
        <ins>
          These operators perform the indicated binary element-wise operation.
        </ins>
        </dd>
  </cxx-effects>

        <cxx-returns id="parallel.simd.cassign.3" para_num="3">
    
    <dt>Returns:</dt><dd>
        <ins>
          <code>lhs</code>.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-throws id="parallel.simd.cassign.4" para_num="4">
    
    <dt>Throws:</dt><dd>
        <ins>
          Nothing.
        </ins>
        </dd>
  </cxx-throws>

        <cxx-remarks id="parallel.simd.cassign.5" para_num="5">
    
    <dt>Remarks:</dt><dd>
        <ins>
          These operators shall not participate in overload resolution 
unless the indicated operator can be applied to objects of type <code>value_type</code>.
        </ins>
        </dd>
  </cxx-remarks>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

    <cxx-section id="parallel.simd.comparison">
    

    <section>
      <header><span class="section-number">9.4.3</span> <h1 data-bookmark-label="9.4.3 Compare operators"><ins>Compare operators</ins></h1> <span style="float:right"><a href="#parallel.simd.comparison">[parallel.simd.comparison]</a></span></header>
      
      

      <cxx-function id="parallel.simd.comparison.1" para_num="1">
    
    <pre><code><cxx-signature><ins>
friend mask_type operator==(const simd&amp;, const simd&amp;);
friend mask_type operator!=(const simd&amp;, const simd&amp;);
friend mask_type operator&gt;=(const simd&amp;, const simd&amp;);
friend mask_type operator&lt;=(const simd&amp;, const simd&amp;);
friend mask_type operator&gt;(const simd&amp;, const simd&amp;);
friend mask_type operator&lt;(const simd&amp;, const simd&amp;);
</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.simd.comparison.2" para_num="2">
    
    <dt>Returns:</dt><dd>
        <ins>
          A <code>simd_mask</code> object initialized with the results of the element-wise application of the indicated operator.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-throws id="parallel.simd.comparison.3" para_num="3">
    
    <dt>Throws:</dt><dd>
        <ins>
          Nothing.
        </ins>
        </dd>
  </cxx-throws>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

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

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

      <p id="parallel.simd.reductions.1" para_num="1">
      <ins>
        In this subclause, <code>BinaryOperation</code> shall be a binary element-wise operation.
      </ins>
      </p>

      <cxx-function id="parallel.simd.reductions.2" para_num="2">
    
    <pre><code><cxx-signature><ins>
template&lt;class T, class Abi, class BinaryOperation = plus&lt;&gt;&gt;
T reduce(const simd&lt;T, Abi&gt;&amp; x, BinaryOperation binary_op = {});
</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-requires id="parallel.simd.reductions.3" para_num="3">
    
    <dt>Requires:</dt><dd>
        <ins>
          <code>binary_op</code> shall be callable with two arguments of type <code>T</code> returning <code>T</code>, or callable with two arguments of type <code>simd&lt;T, A1&gt;</code> returning <code>simd&lt;T, A1&gt;</code> for every <code>A1</code> that is an ABI tag type.
        </ins>
        </dd>
  </cxx-requires>

        <cxx-returns id="parallel.simd.reductions.4" para_num="4">
    
    <dt>Returns:</dt><dd>
        <ins>
          <code><em>GENERALIZED_SUM</em>(binary_op, x.data[i], ...)</code> for all <code>i</code> ∊ <code>[0, size())</code>.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-throws id="parallel.simd.reductions.5" para_num="5">
    
    <dt>Throws:</dt><dd>
        <ins>
          Any exception thrown from <code>binary_op</code>.
        </ins>
        </dd>
  </cxx-throws>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.reductions.6" para_num="6">
    
    <pre><code><cxx-signature><ins>
template&lt;class M, class V, class BinaryOperation&gt;
typename V::value_type reduce(const const_where_expression&lt;M, V&gt;&amp; x, typename V::value_type identity_element,
                              BinaryOperation binary_op = {});
</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-requires id="parallel.simd.reductions.7" para_num="7">
    
    <dt>Requires:</dt><dd>
        <ins>
          <code>binary_op</code> shall be callable with two arguments of type <code>T</code> returning <code>T</code>, or callable with two arguments of type <code>simd&lt;T, A1&gt;</code> returning <code>simd&lt;T, A1&gt;</code> for every <code>A1</code> that is an ABI tag type. The results of <code>binary_op(identity_element, x)</code> and <code>binary_op(x, identity_element)</code> shall be equal to <code>x</code> for all finite values <code>x</code> representable by <code>V::value_type</code>.
        </ins>
        </dd>
  </cxx-requires>

        <cxx-returns id="parallel.simd.reductions.8" para_num="8">
    
    <dt>Returns:</dt><dd>
        <ins>
          If <code>none_of(x.mask)</code>, returns <code>identity_element</code>. Otherwise, returns <code><em>GENERALIZED_SUM</em>(binary_op, x.data[i], ...)</code> for all <code>i</code> ∊ {<em>j</em> ∊ ℕ<sub>0</sub> ∣ <em>j</em> &lt; <code>M::size()</code> ⋀ <code>mask[</code><em>j</em><code>]</code> }.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-throws id="parallel.simd.reductions.9" para_num="9">
    
    <dt>Throws:</dt><dd>
        <ins>
          Any exception thrown from <code>binary_op</code>.
        </ins>
        </dd>
  </cxx-throws>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.reductions.10" para_num="10">
    
    <pre><code><cxx-signature><ins>
template&lt;class M, class V&gt;
typename V::value_type reduce(const const_where_expression&lt;M, V&gt;&amp; x, plus&lt;&gt; binary_op);
</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.simd.reductions.11" para_num="11">
    
    <dt>Returns:</dt><dd>
        <ins>
          If <code>none_of(x.mask)</code>, returns <code>0</code>. Otherwise, returns <code><em>GENERALIZED_SUM</em>(binary_op, x.data[i], ...)</code> for all <code>i</code> ∊ {<em>j</em> ∊ ℕ<sub>0</sub> ∣ <em>j</em> &lt; <code>M::size()</code> ⋀ <code>mask[</code><em>j</em><code>]</code> }.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-throws id="parallel.simd.reductions.12" para_num="12">
    
    <dt>Throws:</dt><dd>
        <ins>
          Nothing.
        </ins>
        </dd>
  </cxx-throws>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.reductions.13" para_num="13">
    
    <pre><code><cxx-signature><ins>
template&lt;class M, class V&gt;
typename V::value_type reduce(const const_where_expression&lt;M, V&gt;&amp; x, multiplies&lt;&gt; binary_op);
</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.simd.reductions.14" para_num="14">
    
    <dt>Returns:</dt><dd>
        <ins>
          If <code>none_of(x.mask)</code>, returns <code>1</code>. Otherwise, returns <code><em>GENERALIZED_SUM</em>(binary_op, x.data[i], ...)</code> for all <code>i</code> ∊ {<em>j</em> ∊ ℕ<sub>0</sub> ∣ <em>j</em> &lt; <code>M::size()</code> ⋀ <code>mask[</code><em>j</em><code>]</code> }.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-throws id="parallel.simd.reductions.15" para_num="15">
    
    <dt>Throws:</dt><dd>
        <ins>
          Nothing.
        </ins>
        </dd>
  </cxx-throws>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.reductions.16" para_num="16">
    
    <pre><code><cxx-signature><ins>
template&lt;class M, class V&gt;
typename V::value_type reduce(const const_where_expression&lt;M, V&gt;&amp; x, bit_and&lt;&gt; binary_op);
</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-requires id="parallel.simd.reductions.17" para_num="17">
    
    <dt>Requires:</dt><dd>
        <ins>
          <code>is_integral_v&lt;V::value_type&gt;</code> is <code>true</code>.
        </ins>
        </dd>
  </cxx-requires>

        <cxx-returns id="parallel.simd.reductions.18" para_num="18">
    
    <dt>Returns:</dt><dd>
        <ins>
          If <code>none_of(x.mask)</code>, returns <code>~V::value_type()</code>. Otherwise, returns <code><em>GENERALIZED_SUM</em>(binary_op, x.data[i], ...)</code> for all <code>i</code> ∊ {<em>j</em> ∊ ℕ<sub>0</sub> ∣ <em>j</em> &lt; <code>M::size()</code> ⋀ <code>mask[</code><em>j</em><code>]</code> }.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-throws id="parallel.simd.reductions.19" para_num="19">
    
    <dt>Throws:</dt><dd>
        <ins>
          Nothing.
        </ins>
        </dd>
  </cxx-throws>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.reductions.20" para_num="20">
    
    <pre><code><cxx-signature><ins>
template&lt;class M, class V&gt;
typename V::value_type reduce(const const_where_expression&lt;M, V&gt;&amp; x, bit_or&lt;&gt; binary_op);
template&lt;class M, class V&gt;
typename V::value_type reduce(const const_where_expression&lt;M, V&gt;&amp; x, bit_xor&lt;&gt; binary_op);
</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-requires id="parallel.simd.reductions.21" para_num="21">
    
    <dt>Requires:</dt><dd>
        <ins>
          <code>is_integral_v&lt;V::value_type&gt;</code> is <code>true</code>.
        </ins>
        </dd>
  </cxx-requires>

        <cxx-returns id="parallel.simd.reductions.22" para_num="22">
    
    <dt>Returns:</dt><dd>
        <ins>
          If <code>none_of(x.mask)</code>, returns <code>0</code>. Otherwise, returns <code><em>GENERALIZED_SUM</em>(binary_op, x.data[i], ...)</code> for all <code>i</code> ∊ {<em>j</em> ∊ ℕ<sub>0</sub> ∣ <em>j</em> &lt; <code>M::size()</code> ⋀ <code>mask[</code><em>j</em><code>]</code> }.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-throws id="parallel.simd.reductions.23" para_num="23">
    
    <dt>Throws:</dt><dd>
        <ins>
          Nothing.
        </ins>
        </dd>
  </cxx-throws>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.reductions.24" para_num="24">
    
    <pre><code><cxx-signature><ins>template&lt;class T, class Abi&gt; T hmin(const simd&lt;T, Abi&gt;&amp; x);</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.simd.reductions.25" para_num="25">
    
    <dt>Returns:</dt><dd>
        <ins>
          The value of an element <code>x[j]</code> for which <code>x[j] &lt;= x[i]</code> for all <code>i</code> ∊ <code>[0, size())</code>.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-throws id="parallel.simd.reductions.26" para_num="26">
    
    <dt>Throws:</dt><dd>
        <ins>
          Nothing.
        </ins>
        </dd>
  </cxx-throws>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.reductions.27" para_num="27">
    
    <pre><code><cxx-signature><ins>template&lt;class T, class V&gt; typename V::value_type hmin(const const_where_expression&lt;M, V&gt;&amp; x);</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.simd.reductions.28" para_num="28">
    
    <dt>Returns:</dt><dd>
        <ins>
          If <code>none_of(x.mask)</code>, the return value is <code>numeric_limits&lt;V::value_type&gt;::max()</code>. Otherwise, returns the value of an element <code>x.data[j]</code> for which <code>x.mask[j] == true</code> and <code>x.data[j] &lt;= x.data[i]</code> for all <code>i</code> ∊ {<em>j</em> ∊ ℕ<sub>0</sub> ∣ <em>j</em> &lt; <code>M::size()</code> ⋀ <code>mask[</code><em>j</em><code>]</code> }.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-throws id="parallel.simd.reductions.29" para_num="29">
    
    <dt>Throws:</dt><dd>
        <ins>
          Nothing.
        </ins>
        </dd>
  </cxx-throws>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.reductions.30" para_num="30">
    
    <pre><code><cxx-signature><ins>template&lt;class T, class Abi&gt; T hmax(const simd&lt;T, Abi&gt;&amp; x);</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.simd.reductions.31" para_num="31">
    
    <dt>Returns:</dt><dd>
        <ins>
          The value of an element <code>x[j]</code> for which <code>x[j] &gt;= x[i]</code> for all <code>i</code> ∊ <code>[0, size())</code>.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-throws id="parallel.simd.reductions.32" para_num="32">
    
    <dt>Throws:</dt><dd>
        <ins>
          Nothing.
        </ins>
        </dd>
  </cxx-throws>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.reductions.33" para_num="33">
    
    <pre><code><cxx-signature><ins>template&lt;class T, class V&gt; typename V::value_type hmax(const const_where_expression&lt;M, V&gt;&amp; x);</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.simd.reductions.34" para_num="34">
    
    <dt>Returns:</dt><dd>
        <ins>
          If <code>none_of(x.mask)</code>, the return value is <code>numeric_limits&lt;V::value_type&gt;::lowest()</code>. Otherwise, returns the value of an element <code>x.data[j]</code> for which <code>x.mask[j] == true</code> and <code>x.data[j] &gt;= x.data[i]</code> for all <code>i</code> ∊ {<em>j</em> ∊ ℕ<sub>0</sub> ∣ <em>j</em> &lt; <code>M::size()</code> ⋀ <code>mask[</code><em>j</em><code>]</code> }.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-throws id="parallel.simd.reductions.35" para_num="35">
    
    <dt>Throws:</dt><dd>
        <ins>
          Nothing.
        </ins>
        </dd>
  </cxx-throws>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

    <cxx-section id="parallel.simd.casts">
    

    <section>
      <header><span class="section-number">9.4.5</span> <h1 data-bookmark-label="9.4.5 Casts"><ins>Casts</ins></h1> <span style="float:right"><a href="#parallel.simd.casts">[parallel.simd.casts]</a></span></header>
      
      

      <cxx-function id="parallel.simd.casts.1" para_num="1">
    
    <pre><code><cxx-signature><ins>template&lt;class T, class U, class Abi&gt; <em>see below</em> simd_cast(const simd&lt;U, Abi&gt;&amp; x)</ins></cxx-signature></code></pre>

    <dl>
      
        

        <p id="parallel.simd.casts.2" para_num="2">
        <ins>
          Let <code>To</code> identify <code>T::value_type</code> if <code>is_simd_v&lt;T&gt;</code> is <code>true</code>, or <code>T</code> otherwise.
        </ins>
        </p>

        <cxx-returns id="parallel.simd.casts.3" para_num="3">
    
    <dt>Returns:</dt><dd>
        <ins>
          A <code>simd</code> object with the <em>i</em>-th element initialized to <code>static_cast&lt;To&gt;(x[i])</code> for all <code>i</code> ∊ <code>[0, size())</code>.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-throws id="parallel.simd.casts.4" para_num="4">
    
    <dt>Throws:</dt><dd>
        <ins>
          Nothing.
        </ins>
        </dd>
  </cxx-throws>

        <cxx-remarks id="parallel.simd.casts.5" para_num="5">
    
    <dt>Remarks:</dt><dd>
        <ins>
          The function shall not participate in overload resolution unless

          <ul>
            <li>
            <ins>
              every possible value of type <code>U</code> can be represented with type <code>To</code>, and
            </ins>
            </li>

            <li>
            <ins>
              either

              <ul>
                <li>
                <ins>
                  <code>is_simd_v&lt;T&gt;</code> is <code>false</code>, or
                </ins>
                </li>

                <li>
                <ins>
                  <code>T::size() == simd&lt;U, Abi&gt;::size()</code> is <code>true</code>.
                </ins>
                </li>
              </ul>
            </ins>
            </li>
          </ul>
        </ins>
        </dd>
  </cxx-remarks>

        <p id="parallel.simd.casts.6" para_num="6">
        <ins>
          The return type is
        </ins>

          </p><ul>
            <li>
            <ins>
              <code>T</code> if <code>is_simd_v&lt;T&gt;</code> is <code>true</code>, otherwise
            </ins>
            </li>

            <li>
            <ins>
              <code>simd&lt;T, Abi&gt;</code> is <code>U</code> is <code>T</code>, otherwise
            </ins>
            </li>

            <li>
            <ins>
              <code>simd&lt;T, simd_abi::fixed_size&lt;simd&lt;U, Abi&gt;::size()&gt;&gt;</code>
            </ins>
            </li>
          </ul>
        <br>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.casts.7" para_num="7">
    
    <pre><code><cxx-signature><ins>template&lt;class T, class U, class Abi&gt; <em>see below</em> static_simd_cast(const simd&lt;U, Abi&gt;&amp; x);</ins></cxx-signature></code></pre>

    <dl>
      
        

        <p id="parallel.simd.casts.8" para_num="8">
        <ins>
          Let <code>To</code> identify <code>T::value_type</code> if <code>is_simd_v&lt;T&gt;</code> is <code>true</code> or <code>T</code> otherwise.
        </ins>
        </p>

        <cxx-returns id="parallel.simd.casts.9" para_num="9">
    
    <dt>Returns:</dt><dd>
        <ins>
          A <code>simd</code> object with the <em>i</em>-th element initialized to <code>static_cast&lt;To&gt;(x[i])</code> for all <code>i</code> ∊ <code>[0, size())</code>.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-throws id="parallel.simd.casts.10" para_num="10">
    
    <dt>Throws:</dt><dd>
        <ins>
          Nothing.
        </ins>
        </dd>
  </cxx-throws>

        <cxx-remarks id="parallel.simd.casts.11" para_num="11">
    
    <dt>Remarks:</dt><dd>
        <ins>
          The function shall not participate in overload resolution unless either

          <ul>
            <li>
            <ins>
              <code>is_simd_v&lt;T&gt;</code> is <code>false</code>, or
            </ins>
            </li>

            <li>
            <ins>
              <code>T::size() == simd&lt;U, Abi&gt;::size()</code> is <code>true</code>.
            </ins>
            </li>
          </ul>
        </ins>
        </dd>
  </cxx-remarks>

        <p id="parallel.simd.casts.12" para_num="12">
        <ins>The return type is</ins>

          </p><ul>
            <li>
            <ins>
              <code>T</code> if <code>is_simd_v&lt;T&gt;</code> is <code>true</code>, otherwise
            </ins>
            </li>

            <li>
            <ins>
              <code>simd&lt;T, Abi&gt;</code> if either <code>U</code> is <code>T</code> or <code>U</code> and <code>T</code> are integral types that only differ in signedness, otherwise
            </ins>
            </li>

            <li>
            <ins>
              <code>simd&lt;T, simd_abi::fixed_size&lt;simd&lt;U, Abi&gt;::size()&gt;&gt;</code>.
            </ins>
            </li>
          </ul>
        <br>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.casts.13" para_num="13">
    
    <pre><code><cxx-signature><ins>
template&lt;class T, class Abi&gt;
fixed_size_simd&lt;T, simd_size_v&lt;T, Abi&gt;&gt; to_fixed_size(const simd&lt;T, Abi&gt;&amp; x) noexcept;
template&lt;class T, class Abi&gt;
fixed_size_simd_mask&lt;T, simd_size_v&lt;T, Abi&gt;&gt; to_fixed_size(const simd_mask&lt;T, Abi&gt;&amp; x) noexcept;
</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.simd.casts.14" para_num="14">
    
    <dt>Returns:</dt><dd>
        <ins>
          A data-parallel object with the <em>i</em>-th element initialized to <code>x[i]</code> for all <code>i</code> ∊ <code>[0, size())</code>.
        </ins>
        </dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.casts.15" para_num="15">
    
    <pre><code><cxx-signature><ins>
template&lt;class T, int N&gt; native_simd&lt;T&gt; to_native(const fixed_size_simd&lt;T, N&gt;&amp; x) noexcept;
template&lt;class T, int N&gt; native_simd_mask&lt;T&gt; to_native(const fixed_size_simd_mask&lt;T, N&gt;&amp; x) noexcept;
</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.simd.casts.16" para_num="16">
    
    <dt>Returns:</dt><dd>
        <ins>
          A data-parallel object with the <em>i</em>-th element initialized to <code>x[i]</code> for all <code>i</code> ∊ <code>[0, size())</code>. 
        </ins>
        </dd>
  </cxx-returns>

        <cxx-remarks id="parallel.simd.casts.17" para_num="17">
    
    <dt>Remarks:</dt><dd>
        <ins>
          These functions shall not participate in overload resolution unless <code>simd_size_v&lt;T, simd_abi::native&lt;T&gt;&gt; == N</code> is <code>true</code>.
        </ins>
        </dd>
  </cxx-remarks>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.casts.18" para_num="18">
    
    <pre><code><cxx-signature><ins>
template&lt;class T, int N&gt; simd&lt;T&gt; to_compatible(const fixed_size_simd&lt;T, N&gt;&amp; x) noexcept;
template&lt;class T, int N&gt; simd_mask&lt;T&gt; to_compatible(const fixed_size_simd_mask&lt;T, N&gt;&amp; x) noexcept;
</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.simd.casts.19" para_num="19">
    
    <dt>Returns:</dt><dd>
        <ins>
          A data-parallel object with the <em>i</em>-th element initialized to <code>x[i]</code> for all <code>i</code> ∊ <code>[0, size())</code>.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-remarks id="parallel.simd.casts.20" para_num="20">
    
    <dt>Remarks:</dt><dd>
        <ins>
          These functions shall not participate in overload resolution unless <code>simd_size_v&lt;T, simd_abi::compatible&lt;T&gt;&gt; == N</code> is <code>true</code>.
        </ins>
        </dd>
  </cxx-remarks>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.casts.21" para_num="21">
    
    <pre><code><cxx-signature><ins>
template&lt;size_t... Sizes, class T, class Abi&gt;
  tuple&lt;simd&lt;T, simd_abi::deduce_t&lt;T, Sizes&gt;&gt;...&gt;
    split(const simd&lt;T, Abi&gt;&amp; x);
template&lt;size_t... Sizes, class T, class Abi&gt;
  tuple&lt;simd_mask&lt;T, simd_abi::deduce_t&lt;T, Sizes&gt;&gt;...&gt;
    split(const simd_mask&lt;T, Abi&gt;&amp; x);
</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.simd.casts.22" para_num="22">
    
    <dt>Returns:</dt><dd>
        <ins>
          A <code>tuple</code> of data-parallel objects with the <em>i</em>-th <code>simd</code>/<code>simd_mask</code> element of the <em>j</em>-th <code>tuple</code> element initialized to the value of the element <code>x</code> with index <em>i</em> + sum of the first <em>j</em> values in the <code>Sizes</code> pack.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-remarks id="parallel.simd.casts.23" para_num="23">
    
    <dt>Remarks:</dt><dd>
        <ins>
          These functions shall not participate in overload resolution unless the sum of all values in the <code>Sizes</code> pack is equal to <code>simd_size_v&lt;T, Abi&gt;</code>.
        </ins>
        </dd>
  </cxx-remarks>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.casts.24" para_num="24">
    
    <pre><code><cxx-signature><ins>
template&lt;class V, class Abi&gt;
  array&lt;V, simd_size_v&lt;typename V::value_type, Abi&gt; / V::size()&gt;
    split(const simd&lt;typename V::value_type, Abi&gt;&amp; x);
template&lt;class V, class Abi&gt;
  array&lt;V, simd_size_v&lt;typename V::value_type, Abi&gt; / V::size()&gt;
    split(const simd_mask&lt;typename V::value_type, Abi&gt;&amp; x);
</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.simd.casts.25" para_num="25">
    
    <dt>Returns:</dt><dd>
        <ins>
          An <code>array</code> of data-parallel objects with the <em>i</em>-th <code>simd</code>/<code>simd_mask</code> element of the <em>j</em>-th <code>array</code> element initialized to the value of the element in <code>x</code> with index <code><em>i</em> + <em>j</em> * V::size()</code>.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-remarks id="parallel.simd.casts.26" para_num="26">
    
    <dt>Remarks:</dt><dd>
        <ins>
          These functions shall not participate in overload resolution unless

          <ul>
            <li>
            <ins>
              <code>simd_size_v&lt;typename V::value_type, Abi&gt;</code> is an integral multiple of <code>V::size()</code>, and
            </ins>
            </li>

            <li>
            <ins>
              for the overload with a <code>simd</code> parameter <code>is_simd_v&lt;V&gt;</code> is <code>true</code>, for the overload with a <code>simd_mask</code> parameter <code>is_simd_mask_v&lt;V&gt;</code> is <code>true</code>.
            </ins>
            </li>
          </ul>
        </ins>
        </dd>
  </cxx-remarks>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.casts.27" para_num="27">
    
    <pre><code><cxx-signature><ins>
template&lt;class T, class... Abis&gt;
simd&lt;T, simd_abi::deduce_t&lt;T, (simd_size_v&lt;T, Abis&gt; + ...)&gt;&gt; concat(const simd&lt;T, Abis&gt;&amp;... xs);
template&lt;class T, class... Abis&gt;
simd_mask&lt;T, simd_abi::deduce_t&lt;T, (simd_size_v&lt;T, Abis&gt; + ...)&gt;&gt; concat(const simd_mask&lt;T, Abis&gt;&amp;... xs);
</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.simd.casts.28" para_num="28">
    
    <dt>Returns:</dt><dd>
        <ins>
          A data-parallel object initialized with the concatenated values in the <code>xs</code> pack of data-parallel objects: The <em>i</em>-th <code>simd</code>/<code>simd_mask</code> element of the <em>j</em>-th parameter in the <code>xs</code> pack is copied to the return value's element with index <em>i</em> + the sum of the width of the first <em>j</em> parameters in the <code>xs</code> pack.
        </ins>
        </dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

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

    <section>
      <header><span class="section-number">9.4.6</span> <h1 data-bookmark-label="9.4.6 Algorithms"><ins>Algorithms</ins></h1> <span style="float:right"><a href="#parallel.simd.alg">[parallel.simd.alg]</a></span></header>
      
      

      <cxx-function id="parallel.simd.alg.1" para_num="1">
    
    <pre><code><cxx-signature><ins>template&lt;class T, class Abi&gt; simd&lt;T, Abi&gt; min(const simd&lt;T, Abi&gt;&amp; a, const simd&lt;T, Abi&gt;&amp; b) noexcept;</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.simd.alg.2" para_num="2">
    
    <dt>Returns:</dt><dd>
        <ins>
          The result of the element-wise application of <code>std::min(a[i], b[i])</code> for all <code>i</code> ∊ <code>[0, size())</code>.
        </ins>
        </dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.alg.3" para_num="3">
    
    <pre><code><cxx-signature><ins>template&lt;class T, class Abi&gt; simd&lt;T, Abi&gt; max(const simd&lt;T, Abi&gt;&amp; a, const simd&lt;T, Abi&gt;&amp; b) noexcept;</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.simd.alg.4" para_num="4">
    
    <dt>Returns:</dt><dd>
        <ins>
          The result of the element-wise application of <code>std::max(a[i], b[i])</code> for all <code>i</code> ∊ <code>[0, size())</code>.
        </ins>
        </dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.alg.5" para_num="5">
    
    <pre><code><cxx-signature><ins>
template&lt;class T, class Abi&gt;
pair&lt;simd&lt;T, Abi&gt;, simd&lt;T, Abi&gt;&gt; minmax(const simd&lt;T, Abi&gt;&amp; a, const simd&lt;T, Abi&gt;&amp; b) noexcept;</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.simd.alg.6" para_num="6">
    
    <dt>Returns:</dt><dd>
        <ins>
          A <code>pair</code> initialized with

          <ul>
            <li>
            <ins>
              the result of element-wise application of <code>std::min(a[i], b[i])</code> for all <code>i</code> ∊ <code>[0, size())</code> in the <code>first</code> member, and

            </ins>
            </li>

            <li>
            <ins>
              the result of element-wise application of <code>std::max(a[i], b[i])</code> for all <code>i</code> ∊ <code>[0, size())</code> in the <code>second</code> member.

            </ins>
            </li>
          </ul>
        </ins>
        </dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.alg.7" para_num="7">
    
    <pre><code><cxx-signature><ins>
template&lt;class T, class Abi&gt; simd&lt;T, Abi&gt;
clamp(const simd&lt;T, Abi&gt;&amp; v, const simd&lt;T, Abi&gt;&amp; lo, const simd&lt;T, Abi&gt;&amp; hi);</ins></cxx-signature></code></pre>

    <dl>
      
        

          <cxx-requires id="parallel.simd.alg.8" para_num="8">
    
    <dt>Requires:</dt><dd>
          <ins>
            No element in <code>lo</code> shall be greater than the corresponding element in <code>hi</code>.
          </ins>
          </dd>
  </cxx-requires>

          <cxx-returns id="parallel.simd.alg.9" para_num="9">
    
    <dt>Returns:</dt><dd>
          <ins>
            The result of element-wise application of <code>std::clamp(v[i], lo[i], hi[i])</code> for all <code>i</code> ∊ <code>[0, size())</code>.

          </ins>
          </dd>
  </cxx-returns>
        
    </dl>
  </cxx-function>
      
    </section>
  </cxx-section>

      <cxx-section id="parallel.simd.math">
    

    <section>
      <header><span class="section-number">9.4.7</span> <h1 data-bookmark-label="9.4.7 Math library"><ins>Math library</ins></h1> <span style="float:right"><a href="#parallel.simd.math">[parallel.simd.math]</a></span></header>
      
        

        <p id="parallel.simd.math.1" para_num="1">
        <ins>
          For each set of overloaded functions within <code>&lt;cmath&gt;</code>, there shall be additional overloads sufficient to ensure that if any argument corresponding to a <code>double</code> parameter has type <code>simd&lt;T, Abi&gt;</code>, where <code>is_floating_point_v&lt;T&gt;</code> is <code>true</code>, then:

          </ins></p><ul>
            <li>
            <ins>
              All arguments corresponding to <code>double</code> parameters shall be convertible to <code>simd&lt;T, Abi&gt;</code>.
            </ins>
            </li>

            <li>
            <ins>
              All arguments corresponding to <code>double*</code> parameters shall be of type <code>simd&lt;T, Abi&gt;*</code>.
            </ins>
            </li>

            <li>
            <ins>
              All arguments corresponding to parameters of integral type <code>U</code> shall be convertible to <code>fixed_size_simd&lt;U, simd_size_v&lt;T, Abi&gt;&gt;</code>.
            </ins>
            </li>

            <li>
            <ins>
              All arguments corresponding to <code>U*</code>, where <code>U</code> is integral, shall be of type <code>fixed_size_simd&lt;U, simd_size_v&lt;T, Abi&gt;&gt;*</code>.
            </ins>
            </li>

            <li>
            <ins>
              If the corresponding return type is <code>double</code>, the return type of the additional overloads is <code>simd&lt;T, Abi&gt;</code>. Otherwise, if the corresponding return type is <code>bool</code>, the return type of the additional overload is <code>simd_mask&lt;T, Abi&gt;</code>. Otherwise, the return type is <code>fixed_size_simd&lt;R, simd_size_v&lt;T, Abi&gt;&gt;</code>, with <code>R</code> denoting the corresponding return type.
            </ins>
            </li>
          </ul>

          <ins>
          It is unspecified whether a call to these overloads with arguments that are all convertible to <code>simd&lt;T, Abi&gt;</code> but are not of type <code>simd&lt;T, Abi&gt;</code> is well-formed.
          </ins>
        
        <!--- /p --->

        <p id="parallel.simd.math.2" para_num="2">
        <ins>
          Each function overload produced by the above rules applies the indicated <code>&lt;cmath&gt;</code>
 function element-wise. The results per element are not required to be 
bitwise equal to the application of the function which is overloaded for
 the element type. 
        </ins>
        </p>

        <p id="parallel.simd.math.3" para_num="3">
        <ins>
          The behavior is undefined if a domain, pole, or range error 
occurs when the input argument(s) are applied to the indicated <code>&lt;cmath&gt;</code> function.
        </ins>
        </p>

        <p id="parallel.simd.math.4" para_num="4">
        <ins>
          If <code>abs</code> is called with an argument of type <code>simd&lt;X, Abi&gt;</code> for which <code>is_unsigned_v&lt;X&gt;</code> is <code>true</code>, the program is ill-formed.
        </ins>
        </p>
      
    </section>
  </cxx-section>
    
    </section>
  </cxx-section>
  

  <cxx-section id="parallel.simd.mask.class">
    

    <section>
      <header><span class="section-number">9.5</span> <h1 data-bookmark-label="9.5 Class template simd_mask"><ins>Class template <code>simd_mask</code></ins></h1> <span style="float:right"><a href="#parallel.simd.mask.class">[parallel.simd.mask.class]</a></span></header>
      
    

    <cxx-section id="parallel.simd.mask.overview">
    

    <section>
      <header><span class="section-number">9.5.1</span> <h1 data-bookmark-label="9.5.1 Class template simd_mask overview"><ins>Class template <code>simd_mask</code> overview</ins></h1> <span style="float:right"><a href="#parallel.simd.mask.overview">[parallel.simd.mask.overview]</a></span></header>
      
      

      <pre>      <ins>
template&lt;class T, class Abi&gt; class simd_mask {
public:
  using value_type = bool;
  using reference = <em>see below</em>;
  using simd_type = simd&lt;T, Abi&gt;;
  using abi_type = Abi;

  static constexpr size_t size() noexcept;

  simd_mask() = default;

  <em>// broadcast constructor</em>
  explicit simd_mask(value_type) noexcept;

  <em>// implicit type conversion constructor</em>
  template&lt;class U&gt;
    simd_mask(const simd_mask&lt;U, simd_abi::fixed_size&lt;size()&gt;&gt;&amp;) noexcept;

  <em>// load constructor</em>
  template&lt;class Flags&gt; simd_mask(const value_Type* mem, Flags);

  <cxx-ref insynopsis="" to="parallel.simd.mask.copy">// <i><a title="parallel.simd.mask.copy" href="#parallel.simd.mask.copy">9.5.3</a>, Copy functions</i></cxx-ref>
  template&lt;class Flags&gt; void copy_from(const value_type* mem, Flags);
  template&lt;class Flags&gt; void copy_to(value_type* mem, Flags);

  <cxx-ref insynopsis="" to="parallel.simd.mask.subscr">// <i><a title="parallel.simd.mask.subscr" href="#parallel.simd.mask.subscr">9.5.4</a>, Subscript operators</i></cxx-ref>
  reference operator[](size_t);
  value_type operator[](size_t) const;

  <cxx-ref insynopsis="" to="parallel.simd.mask.unary">// <i><a title="parallel.simd.mask.unary" href="#parallel.simd.mask.unary">9.5.5</a>, Unary operators</i></cxx-ref>
  simd_mask operator!() const noexcept;
  
  <cxx-ref insynopsis="" to="parallel.simd.mask.binary">// <i><a title="parallel.simd.mask.binary" href="#parallel.simd.mask.binary">9.6.1</a>, Binary operators</i></cxx-ref>
  friend simd_mask operator&amp;&amp;(const simd_mask&amp;, const simd_mask&amp;) noexcept;
  friend simd_mask operator||(const simd_mask&amp;, const simd_mask&amp;) noexcept;
  friend simd_mask operator&amp;(const simd_mask&amp;, const simd_mask&amp;) noexcept;
  friend simd_mask operator|(const simd_mask&amp;, const simd_mask&amp;) noexcept;
  friend simd_mask operator^(const simd_mask&amp;, const simd_mask&amp;) noexcept;

  <cxx-ref insynopsis="" to="parallel.simd.mask.cassign">// <i><a title="parallel.simd.mask.cassign" href="#parallel.simd.mask.cassign">9.6.2</a>, Compound assignment</i></cxx-ref>
  friend simd_mask&amp; operator&amp;=(simd_mask&amp;, const simd_mask&amp;) noexcept;
  friend simd_mask&amp; operator|=(simd_mask&amp;, const simd_mask&amp;) noexcept;
  friend simd_mask&amp; operator^=(simd_mask&amp;, const simd_mask&amp;) noexcept;

  <cxx-ref insynopsis="" to="parallel.simd.mask.comparison">// <i><a title="parallel.simd.mask.comparison" href="#parallel.simd.mask.comparison">9.6.3</a>, Comparisons</i></cxx-ref>
  friend simd_mask operator==(const simd_mask&amp;, const simd_mask&amp;) noexcept;
  friend simd_mask operator!=(const simd_mask&amp;, const simd_mask&amp;) noexcept;
};</ins></pre>

      <p id="parallel.simd.mask.overview.1" para_num="1">
      <ins>
        The class template <code>simd_mask</code> is a data-parallel type with the element type <code>bool</code>. The width of a given <code>simd_mask</code> specialization is a constant expression, determined by the template parameters. Specifically, <code>simd_mask&lt;T, Abi&gt;::size() == simd&lt;T, Abi&gt;::size()</code>.
      </ins>
      </p>

      <p id="parallel.simd.mask.overview.2" para_num="2">
      <ins>
        Every specialization of <code>simd_mask</code> shall be a complete type. The specialization <code>simd_mask&lt;T, Abi&gt;</code> is supported if <code>T</code> is a vectorizable type and

        </ins></p><ul>
          <li>
          <ins>
            <code>Abi</code> is <code>simd_abi::scalar</code>, or
          </ins>
          </li>

          <li>
          <ins>
            <code>Abi</code> is <code>simd_abi::fixed_size&lt;N&gt;</code>, with <code>N</code> constrained as defined in (<cxx-ref to="parallel.simd.abi"><a title="parallel.simd.abi" href="#parallel.simd.abi">9.2.1</a></cxx-ref>).
          </ins>
          </li>
        </ul>

        <ins>
        If <code>Abi</code> is an extended ABI tag, it is implementation-defined whether <code>simd_mask&lt;T, Abi&gt;</code> is supported. <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    The intent is for implementations to decide on the basis of the currently targeted system.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
        If <code>simd_mask&lt;T, Abi&gt;</code> is not supported, the 
specialization shall have a deleted default constructor, deleted 
destructor, deleted copy constructor, and deleted copy assignment.
        </ins>
      
      <br>

      <p id="parallel.simd.mask.overview.3" para_num="3">
      <ins>
        Default initialization performs no intialization of the elements; value-initialization initializes each element with <code>false</code>. <cxx-note><span class="nowrap">[ <em>Note:</em></span>
    Thus, default initialization leaves the elements in an indeterminate state.
    <span class="nowrap">— <em>end note</em> ]</span>
  </cxx-note>
      </ins>
      </p>

      <cxx-function id="parallel.simd.mask.overview.4" para_num="4">
    
    <pre><code><cxx-signature><ins>static constexpr size_t size() noexcept;</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.simd.mask.overview.5" para_num="5">
    
    <dt>Returns:</dt><dd>
        <ins>
          The width of <code>simd&lt;T, Abi&gt;</code>.
        </ins>
        </dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>

      <p id="parallel.simd.mask.overview.6" para_num="6">
      <ins>
        Implementations should enable explicit conversion from and to 
implementation-defined types. This adds one or more of the following 
declarations to class <code>simd_mask</code>:

        </ins></p><pre>        <ins>
explicit operator <em>implementation-defined</em>() const;
explicit simd_mask(const <em>implementation-defined</em>&amp; init) const;</ins></pre>
        <br>

        <p id="parallel.simd.mask.overview.7" para_num="7">
        <ins>
          The member type <code>reference</code> has the same interface as <code>simd&lt;T, Abi&gt;::reference</code>, except its <code>value_type</code> is <code>bool</code>. (<cxx-ref to="parallel.simd.reference"><a title="parallel.simd.reference" href="#parallel.simd.reference">9.3.2</a></cxx-ref>)
        </ins>
        </p>
    
    </section>
  </cxx-section>
      
    <cxx-section id="parallel.simd.mask.ctor">
    

    <section>
      <header><span class="section-number">9.5.2</span> <h1 data-bookmark-label="9.5.2 Constructors"><ins>Constructors</ins></h1> <span style="float:right"><a href="#parallel.simd.mask.ctor">[parallel.simd.mask.ctor]</a></span></header>
      
      

      <cxx-function id="parallel.simd.mask.ctor.1" para_num="1">
    
    <pre><code><cxx-signature><ins>explicit simd_mask(value_type x) noexcept</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-effects id="parallel.simd.mask.ctor.2" para_num="2">
    
    <dt>Effects:</dt><dd>
        <ins>
          Constructs an object with each element initialized to <code>x</code>.
        </ins>
        </dd>
  </cxx-effects>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.mask.ctor.3" para_num="3">
    
    <pre><code><cxx-signature><ins>template&lt;class U&gt; simd_mask(const simd_mask&lt;U, simd_abi::fixed_size&lt;size()&gt;&gt;&amp; x) noexcept;</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-effects id="parallel.simd.mask.ctor.4" para_num="4">
    
    <dt>Effects:</dt><dd>
        <ins>
          Constructs an object of type <code>simd_mask</code> where the <em>i</em>-th element equals <code>x[i]</code> for all <code>i</code> ∊ <code>[0, size())</code>.
        </ins>
        </dd>
  </cxx-effects>

        <cxx-remarks id="parallel.simd.mask.ctor.5" para_num="5">
    
    <dt>Remarks:</dt><dd>
        <ins>
          This constructor shall not participate in overload resolution unless <code>abi_type</code> is <code>simd_abi::fixed_size&lt;size()&gt;</code>.
        </ins>
        </dd>
  </cxx-remarks>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.mask.ctor.6" para_num="6">
    
    <pre><code><cxx-signature><ins>template&lt;class Flags&gt; simd_mask(const value_type* mem, Flags);</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-requires id="parallel.simd.mask.ctor.7" para_num="7">
    
    <dt>Requires:</dt><dd>
        <ins>
          If the template parameter <code>Flags</code> is <code>vector_aligned_tag</code>, <code>mem</code> shall point to storage aligned by <code>memory_alignment_v&lt;simd_mask&gt;</code>. If the template parameter <code>Flags</code> is <code>overaligned_tag&lt;N&gt;</code>, <code>mem</code> shall point to storage aligned by <code>N</code>. If the template parameter <code>Flags</code> is <code>element_aligned_tag</code>, <code>mem</code> shall point to storage aligned by <code>alignof(U)</code>. <code>[mem, mem + size())</code> is a valid range.
        </ins>
        </dd>
  </cxx-requires>

        <cxx-effects id="parallel.simd.mask.ctor.8" para_num="8">
    
    <dt>Effects:</dt><dd>
        <ins>
          Constructs an object where the <em>i</em>-th element is initialized to <code>mem[i]</code> for all <code>i</code> ∊ <code>[0, size())</code>. 
        </ins>
        </dd>
  </cxx-effects>

        <cxx-remarks id="parallel.simd.mask.ctor.9" para_num="9">
    
    <dt>Remarks:</dt><dd>
        <ins>
          This constructor shall not participate in overload resolution unless <code>is_simd_flag_type_v&lt;Flags&gt;</code> is <code>true</code>.
        </ins>
        </dd>
  </cxx-remarks>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

    <cxx-section id="parallel.simd.mask.copy">
    

    <section>
      <header><span class="section-number">9.5.3</span> <h1 data-bookmark-label="9.5.3 Copy functions"><ins>Copy functions</ins></h1> <span style="float:right"><a href="#parallel.simd.mask.copy">[parallel.simd.mask.copy]</a></span></header>
      
      

      <cxx-function id="parallel.simd.mask.copy.1" para_num="1">
    
    <pre><code><cxx-signature><ins>template&lt;class Flags&gt; void copy_from(const value_type* mem, Flags);</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-requires id="parallel.simd.mask.copy.2" para_num="2">
    
    <dt>Requires:</dt><dd>
        <ins>
          If the template parameter <code>Flags</code> is <code>vector_aligned_tag</code>, <code>mem</code> shall point to storage aligned by <code>memory_alignment_v&lt;simd_mask&gt;</code>. If the template parameter <code>Flags</code> is <code>overaligned_tag&lt;N&gt;</code>, <code>mem</code> shall point to storage aligned by <code>N</code>. If the template parameter <code>Flags</code> is <code>element_aligned_tag</code>, <code>mem</code> shall point to storage aligned by <code>alignof(U)</code>. <code>[mem, mem + size())</code> is a valid range.
        </ins>
        </dd>
  </cxx-requires>

        <cxx-effects id="parallel.simd.mask.copy.3" para_num="3">
    
    <dt>Effects:</dt><dd>
        <ins>
          Replaces the elements of the <code>simd_mask</code> object such that the <em>i</em>-th element is replaced with <code>mem[i]</code> for all <code>i</code> ∊ <code>[0, size())</code>.

        </ins>
        </dd>
  </cxx-effects>

        <cxx-remarks id="parallel.simd.mask.copy.4" para_num="4">
    
    <dt>Remarks:</dt><dd>
        <ins>
          This function shall not participate in overload resolution unless <code>is_simd_flag_type_v&lt;Flags&gt;</code> is <code>true</code>.
        </ins>
        </dd>
  </cxx-remarks>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.mask.copy.5" para_num="5">
    
    <pre><code><cxx-signature><ins>template&lt;class Flags&gt; void copy_to(value_type* mem, Flags);</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-requires id="parallel.simd.mask.copy.6" para_num="6">
    
    <dt>Requires:</dt><dd>
        <ins>
          If the template parameter <code>Flags</code> is <code>vector_aligned_tag</code>, <code>mem</code> shall point to storage aligned by <code>memory_alignment_v&lt;simd_mask&gt;</code>. If the template parameter <code>Flags</code> is <code>overaligned_tag&lt;N&gt;</code>, <code>mem</code> shall point to storage aligned by <code>N</code>. If the template parameter <code>Flags</code> is <code>element_aligned_tag</code>, <code>mem</code> shall point to storage aligned by <code>alignof(U)</code>. <code>[mem, mem + size())</code> is a valid range.
        </ins>
        </dd>
  </cxx-requires>

        <cxx-effects id="parallel.simd.mask.copy.7" para_num="7">
    
    <dt>Effects:</dt><dd>
        <ins>
          Copies all <code>simd_mask</code> elements as if <code>mem[i] = operator[](i)</code> for all <code>i</code> ∊ <code>[0, size())</code>.
        </ins>
        </dd>
  </cxx-effects>

        <cxx-remarks id="parallel.simd.mask.copy.8" para_num="8">
    
    <dt>Remarks:</dt><dd>
        <ins>
          This function shall not participate in overload resolution unless <code>is_simd_flag_type_v&lt;Flags&gt;</code> is <code>true</code>.
        </ins>
        </dd>
  </cxx-remarks>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

    <cxx-section id="parallel.simd.mask.subscr">
    

    <section>
      <header><span class="section-number">9.5.4</span> <h1 data-bookmark-label="9.5.4 Subscript operators"><ins>Subscript operators</ins></h1> <span style="float:right"><a href="#parallel.simd.mask.subscr">[parallel.simd.mask.subscr]</a></span></header>
      
      

      <cxx-function id="parallel.simd.mask.subscr.1" para_num="1">
    
    <pre><code><cxx-signature><ins>reference operator[](size_t i);</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-requires id="parallel.simd.mask.subscr.2" para_num="2">
    
    <dt>Requires:</dt><dd>
        <ins>
          <code>i &lt; size()</code>.
        </ins>
        </dd>
  </cxx-requires>

        <cxx-returns id="parallel.simd.mask.subscr.3" para_num="3">
    
    <dt>Returns:</dt><dd>
        <ins>
          A <code>reference</code> (see <cxx-ref to="parallel.simd.reference"><a title="parallel.simd.reference" href="#parallel.simd.reference">9.3.2</a></cxx-ref>) referring to the <em>i</em>-th element.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-throws id="parallel.simd.mask.subscr.4" para_num="4">
    
    <dt>Throws:</dt><dd>
        <ins>
          Nothing.
        </ins>
        </dd>
  </cxx-throws>
      
    </dl>
  </cxx-function>

      <cxx-function id="parallel.simd.mask.subscr.5" para_num="5">
    
    <pre><code><cxx-signature><ins>value_type operator[](size_t i) const;</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-requires id="parallel.simd.mask.subscr.6" para_num="6">
    
    <dt>Requires:</dt><dd>
        <ins>
          <code>i &lt; size()</code>.
        </ins>
        </dd>
  </cxx-requires>

        <cxx-returns id="parallel.simd.mask.subscr.7" para_num="7">
    
    <dt>Returns:</dt><dd>
        <ins>
          The value of the <em>i</em>-th element.
        </ins>
        </dd>
  </cxx-returns>

        <cxx-throws id="parallel.simd.mask.subscr.8" para_num="8">
    
    <dt>Throws:</dt><dd>
        <ins>
          Nothing.
        </ins>
        </dd>
  </cxx-throws>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>

    <cxx-section id="parallel.simd.mask.unary">
    

    <section>
      <header><span class="section-number">9.5.5</span> <h1 data-bookmark-label="9.5.5 Unary operators"><ins>Unary operators</ins></h1> <span style="float:right"><a href="#parallel.simd.mask.unary">[parallel.simd.mask.unary]</a></span></header>
      
      

      <cxx-function id="parallel.simd.mask.unary.1" para_num="1">
    
    <pre><code><cxx-signature><ins>simd_mask operator!() const noexcept;</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.simd.mask.unary.2" para_num="2">
    
    <dt>Returns:</dt><dd>
        <ins>
          The result of the element-wise appliation of <code>operator!</code>.
        </ins>
        </dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>
  
    </section>
  </cxx-section>

  <cxx-section id="parallel.simd.mask.nonmembers">
    

    <section>
      <header><span class="section-number">9.6</span> <h1 data-bookmark-label="9.6 Non-member operations"><ins>Non-member operations</ins></h1> <span style="float:right"><a href="#parallel.simd.mask.nonmembers">[parallel.simd.mask.nonmembers]</a></span></header>
      
    

    <cxx-section id="parallel.simd.mask.binary">
    

    <section>
      <header><span class="section-number">9.6.1</span> <h1 data-bookmark-label="9.6.1 Binary operators"><ins>Binary operators</ins></h1> <span style="float:right"><a href="#parallel.simd.mask.binary">[parallel.simd.mask.binary]</a></span></header>
      
      

      <cxx-function id="parallel.simd.mask.binary.1" para_num="1">
    
    <pre><code><cxx-signature><ins>
friend simd_mask operator&amp;&amp;(const simd_mask&amp;, const simd_mask&amp;) noexcept;
friend simd_mask operator||(const simd_mask&amp;, const simd_mask&amp;) noexcept;
friend simd_mask operator&amp; (const simd_mask&amp;, const simd_mask&amp;) noexcept;
friend simd_mask operator| (const simd_mask&amp;, const simd_mask&amp;) noexcept;
friend simd_mask operator^ (const simd_mask&amp;, const simd_mask&amp;) noexcept;
</ins></cxx-signature></code></pre>

    <dl>
      
        

        <cxx-returns id="parallel.simd.mask.binary.2" para_num="2">
    
    <dt>Returns:</dt><dd>
        <ins>
          A <code>simd_mask</code> object initialized with the results of the element-wise appliation of the indicated operator.
        </ins>
        </dd>
  </cxx-returns>
      
    </dl>
  </cxx-function>
    
    </section>
  </cxx-section>
  

  <cxx-section id="parallel.simd.mask.cassign">
    

    <section>
      <header><span class="section-number">9.6.2</span> <h1 data-bookmark-label="9.6.2 Compound assignment"><ins>Compound assignment</ins></h1> <span style="float:right"><a href="#parallel.simd.mask.cassign">[parallel.simd.mask.cassign]</a></span></header>
      
    

    <cxx-function id="parallel.simd.mask.cassign.1" para_num="1">
    
    <pre><code><cxx-signature><ins>
friend simd_mask&amp; operator&amp;=(simd_mask&amp; lhs, const simd_mask&amp; rhs) noexcept;
friend simd_mask&amp; operator|=(simd_mask&amp; lhs, const simd_mask&amp; rhs) noexcept;
friend simd_mask&amp; operator^=(simd_mask&amp; lhs, const simd_mask&amp; rhs) noexcept;
</ins></cxx-signature></code></pre>

    <dl>
      
      

      <cxx-effects id="parallel.simd.mask.cassign.2" para_num="2">
    
    <dt>Effects:</dt><dd>
      <ins>
        These operators perform the indicated binary element-wise operation.
      </ins>
      </dd>
  </cxx-effects>

      <cxx-returns id="parallel.simd.mask.cassign.3" para_num="3">
    
    <dt>Returns:</dt><dd>
      <ins>
        <code>lhs</code>.
      </ins>
      </dd>
  </cxx-returns>
    
    </dl>
  </cxx-function>
  
    </section>
  </cxx-section>
    
  <cxx-section id="parallel.simd.mask.comparison">
    

    <section>
      <header><span class="section-number">9.6.3</span> <h1 data-bookmark-label="9.6.3 Comparisons"><ins>Comparisons</ins></h1> <span style="float:right"><a href="#parallel.simd.mask.comparison">[parallel.simd.mask.comparison]</a></span></header>
      
    

    <cxx-function id="parallel.simd.mask.comparison.1" para_num="1">
    
    <pre><code><cxx-signature><ins>
friend simd_mask operator==(const simd_mask&amp;, const simd_mask&amp;) noexcept;
friend simd_mask operator!=(const simd_mask&amp;, const simd_mask&amp;) noexcept;
</ins></cxx-signature></code></pre>

    <dl>
      
      

      <cxx-returns id="parallel.simd.mask.comparison.2" para_num="2">
    
    <dt>Returns:</dt><dd>
      <ins>
        An object initialized with the results of the element-wise application of the indicated operator.
      </ins>
      </dd>
  </cxx-returns>
    
    </dl>
  </cxx-function>
  
    </section>
  </cxx-section>

  <cxx-section id="parallel.simd.mask.reductions">
    

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

    <cxx-function id="parallel.simd.mask.reductions.1" para_num="1">
    
    <pre><code><cxx-signature><ins>template&lt;class T, class Abi&gt; bool all_of(const simd_mask&lt;T, Abi&gt;&amp; k) noexcept;</ins></cxx-signature></code></pre>

    <dl>
      
      

      <cxx-returns id="parallel.simd.mask.reductions.2" para_num="2">
    
    <dt>Returns:</dt><dd>
      <ins>
        <code>true</code> if all boolean elements in <code>k</code> are <code>true</code>, <code>false</code> otherwise.
      </ins>
      </dd>
  </cxx-returns>
    
    </dl>
  </cxx-function>

    <cxx-function id="parallel.simd.mask.reductions.3" para_num="3">
    
    <pre><code><cxx-signature><ins>template&lt;class T, class Abi&gt; bool any_of(const simd_mask&lt;T, Abi&gt;&amp; k) noexcept;</ins></cxx-signature></code></pre>

    <dl>
      
      

      <cxx-returns id="parallel.simd.mask.reductions.4" para_num="4">
    
    <dt>Returns:</dt><dd>
      <ins>
        <code>true</code> if at least one boolean element in <code>k</code> is <code>true</code>, <code>false</code> otherwise.
      </ins>
      </dd>
  </cxx-returns>
    
    </dl>
  </cxx-function>

    <cxx-function id="parallel.simd.mask.reductions.5" para_num="5">
    
    <pre><code><cxx-signature><ins>template&lt;class T, class Abi&gt; bool none_of(const simd_mask&lt;T, Abi&gt;&amp; k) noexcept;</ins></cxx-signature></code></pre>

    <dl>
      
      

      <cxx-returns id="parallel.simd.mask.reductions.6" para_num="6">
    
    <dt>Returns:</dt><dd>
      <ins>
        <code>true</code> if none of the one boolean elements in <code>k</code> is <code>true</code>, <code>false</code> otherwise.
      </ins>
      </dd>
  </cxx-returns>
    
    </dl>
  </cxx-function>

    <cxx-function id="parallel.simd.mask.reductions.7" para_num="7">
    
    <pre><code><cxx-signature><ins>template&lt;class T, class Abi&gt; bool some_of(const simd_mask&lt;T, Abi&gt;&amp; k) noexcept;</ins></cxx-signature></code></pre>

    <dl>
      
      

      <cxx-returns id="parallel.simd.mask.reductions.8" para_num="8">
    
    <dt>Returns:</dt><dd>
      <ins>
        <code>true</code> if at least one of the one boolean elements in <code>k</code> is <code>true</code> and at least one of the boolean elements in <code>k</code> is <code>false</code>, <code>false</code> otherwise.
      </ins>
      </dd>
  </cxx-returns>
    
    </dl>
  </cxx-function>

    <cxx-function id="parallel.simd.mask.reductions.9" para_num="9">
    
    <pre><code><cxx-signature><ins>template&lt;class T, class Abi&gt; int popcount(const simd_mask&lt;T, Abi&gt;&amp; k) noexcept;</ins></cxx-signature></code></pre>

    <dl>
      
      

      <cxx-returns id="parallel.simd.mask.reductions.10" para_num="10">
    
    <dt>Returns:</dt><dd>
      <ins>
        The number of boolean elements in <code>k</code> that are <code>true</code>.
      </ins>
      </dd>
  </cxx-returns>
    
    </dl>
  </cxx-function>

    <cxx-function id="parallel.simd.mask.reductions.11" para_num="11">
    
    <pre><code><cxx-signature><ins>template&lt;class T, class Abi&gt; int find_first_set(const simd_mask&lt;T, Abi&gt;&amp; k);</ins></cxx-signature></code></pre>

    <dl>
      
      

      <cxx-requires id="parallel.simd.mask.reductions.12" para_num="12">
    
    <dt>Requires:</dt><dd>
      <ins>
        <code>any_of(k)</code> returns <code>true</code>.
      </ins>
      </dd>
  </cxx-requires>

      <cxx-returns id="parallel.simd.mask.reductions.13" para_num="13">
    
    <dt>Returns:</dt><dd>
      <ins>
        The lowest element index <code>i</code> where <code>k[i]</code> is <code>true</code>.
      </ins>
      </dd>
  </cxx-returns>
    
    </dl>
  </cxx-function>

    <cxx-function id="parallel.simd.mask.reductions.14" para_num="14">
    
    <pre><code><cxx-signature><ins>template&lt;class T, class Abi&gt; int find_last_set(const simd_mask&lt;T, Abi&gt;&amp; k);</ins></cxx-signature></code></pre>

    <dl>
      
      

      <cxx-requires id="parallel.simd.mask.reductions.15" para_num="15">
    
    <dt>Requires:</dt><dd>
      <ins>
        <code>any_of(k)</code> returns <code>true</code>.
      </ins>
      </dd>
  </cxx-requires>

      <cxx-returns id="parallel.simd.mask.reductions.16" para_num="16">
    
    <dt>Returns:</dt><dd>
      <ins>
        The greatest element index <code>i</code> where <code>k[i]</code> is <code>true</code>.
      </ins>
      </dd>
  </cxx-returns>
    
    </dl>
  </cxx-function>

    <cxx-function id="parallel.simd.mask.reductions.17" para_num="17">
    
    <pre><code><cxx-signature><ins>
bool all_of(<em>see below</em>) noexcept;
bool any_of(<em>see below</em>) noexcept;
bool none_of(<em>see below</em>) noexcept;
bool some_of(<em>see below</em>) noexcept;
int popcount(<em>see below</em>) noexcept;
</ins></cxx-signature></code></pre>

    <dl>
      
      

      <cxx-returns id="parallel.simd.mask.reductions.18" para_num="18">
    
    <dt>Returns:</dt><dd>
      <ins>
        <code>all_of</code> and <code>any_of</code> return their arguments; <code>none_of</code> returns the negation of its argument; <code>some_of</code> returns <code>false</code>; <code>popcount</code> returns the integral representation of its argument.
      </ins>
      </dd>
  </cxx-returns>

      <cxx-remarks id="parallel.simd.mask.reductions.19" para_num="19">
    
    <dt>Remarks:</dt><dd>
      <ins>
        The functions shall not participate in overload resolution unless the argument is of type <code>bool</code>.
      </ins>
      </dd>
  </cxx-remarks>
    
    </dl>
  </cxx-function>

    <cxx-function id="parallel.simd.mask.reductions.20" para_num="20">
    
    <pre><code><cxx-signature><ins>
int find_first_set(<em>see below</em>) noexcept;
int find_last_set(<em>see below</em>) noexcept;
</ins></cxx-signature></code></pre>

    <dl>
      
      

      <cxx-requires id="parallel.simd.mask.reductions.21" para_num="21">
    
    <dt>Requires:</dt><dd>
      <ins>
        The value of the argument is <code>true</code>.
      </ins>
      </dd>
  </cxx-requires>
      
      <cxx-returns id="parallel.simd.mask.reductions.22" para_num="22">
    
    <dt>Returns:</dt><dd>
      <ins>
        <code>0</code>.
      </ins>
      </dd>
  </cxx-returns>

      <cxx-remarks id="parallel.simd.mask.reductions.23" para_num="23">
    
    <dt>Remarks:</dt><dd>
      <ins>
        The functions shall not participate in overload resolution unless the argument is of type <code>bool</code>.
      </ins>
      </dd>
  </cxx-remarks>
    
    </dl>
  </cxx-function>
  
    </section>
  </cxx-section>

  <cxx-section id="parallel.simd.mask.where">
    

    <section>
      <header><span class="section-number">9.6.5</span> <h1 data-bookmark-label="9.6.5 Where functions"><ins>Where functions</ins></h1> <span style="float:right"><a href="#parallel.simd.mask.where">[parallel.simd.mask.where]</a></span></header>
      
    

    <cxx-function id="parallel.simd.mask.where.1" para_num="1">
    
    <pre><code><cxx-signature><ins>
template&lt;class T, class Abi&gt;
where_expression&lt;simd_mask&lt;T, Abi&gt;, simd&lt;T, Abi&gt;&gt; where(const typename simd&lt;T, Abi&gt;::mask_type&amp; k,
                                                        simd&lt;T, Abi&gt;&amp; v) noexcept;
template&lt;class T, class Abi&gt;
const_where_expression&lt;simd_mask&lt;T, Abi&gt;, simd&lt;T, Abi&gt;&gt; where(const typename simd&lt;T, Abi&gt;::mask_type&amp; k,
                                                              const simd&lt;T, Abi&gt;&amp; v) noexcept;
template&lt;class T, class Abi&gt;
where_expression&lt;simd_mask&lt;T, Abi&gt;, simd_mask&lt;T, Abi&gt;&gt; where(const nodeduce_t&lt;simd_mask&lt;T, Abi&gt;&gt;&amp; k,
                                                             simd_mask&lt;T, Abi&gt;&amp; v) noexcept;
template&lt;class T, class Abi&gt;
const_where_expression&lt;simd_mask&lt;T, Abi&gt;, simd_mask&lt;T, Abi&gt;&gt; where(const nodeduce_t&lt;simd_mask&lt;T, Abi&gt;&gt;&amp; k,
                                                                   const simd_mask&lt;T, Abi&gt;&amp; v) noexcept;
</ins></cxx-signature></code></pre>

    <dl>
      
      

      <cxx-returns id="parallel.simd.mask.where.2" para_num="2">
    
    <dt>Returns:</dt><dd>
      <ins>
        An object (<cxx-ref to="parallel.simd.whereexpr"><a title="parallel.simd.whereexpr" href="#parallel.simd.whereexpr">9.2.3</a></cxx-ref>) with <code>mask</code> and <code>data</code> initialized with <code>k</code> and <code>v</code> respectively.
      </ins>
      </dd>
  </cxx-returns>
    
    </dl>
  </cxx-function>

    <cxx-function id="parallel.simd.mask.where.3" para_num="3">
    
    <pre><code><cxx-signature><ins>
template&lt;class T&gt; where_expression&lt;bool T&gt; where(<em>see below</em> k, T&amp; v) noexcept;
template&lt;class T&gt;
const_where_expression&lt;bool, T&gt; where(<em>see below</em> k, const T&amp; v) noexcept;
</ins></cxx-signature></code></pre>

    <dl>
      
      

      <cxx-remarks id="parallel.simd.mask.where.4" para_num="4">
    
    <dt>Remarks:</dt><dd>
      <ins>
        The functions shall not participate in overload resolution unless

        <ul>
          <li>
          <ins>
            <code>T</code> is neither a <code>simd</code> nor a <code>simd_mask</code> specialization, and
          </ins>
          </li>

          <li>
          <ins>
            the first argument is of type <code>bool</code>.
          </ins>
          </li>
        </ul>
      </ins>
      </dd>
  </cxx-remarks>

      <cxx-returns id="parallel.simd.mask.where.5" para_num="5">
    
    <dt>Returns:</dt><dd>
      <ins>
        An object (<cxx-ref to="parallel.simd.whereexpr"><a title="parallel.simd.whereexpr" href="#parallel.simd.whereexpr">9.2.3</a></cxx-ref>) with <code>mask</code> and <code>data</code> initialized with <code>k</code> and <code>v</code> respectively.
      </ins>
      </dd>
  </cxx-returns>
    
    </dl>
  </cxx-function>
  
    </section>
  </cxx-section>

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






</body></html>