<!doctype html><html lang="en">
 <head>
  <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  <meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
  <title>P0452r1: Unifying &lt;numeric> Parallel Algorithms</title>
<style data-fill-with="stylesheet">/******************************************************************************
 *                   Style sheet for the W3C specifications                   *
 *
 * Special classes handled by this style sheet include:
 *
 * Indices
 *   - .toc for the Table of Contents (<ol class="toc">)
 *     + <span class="secno"> for the section numbers
 *   - #toc for the Table of Contents (<nav id="toc">)
 *   - ul.index for Indices (<a href="#ref">term</a><span>, in §N.M</span>)
 *   - table.index for Index Tables (e.g. for properties or elements)
 *
 * Structural Markup
 *   - table.data for general data tables
 *     -> use 'scope' attribute, <colgroup>, <thead>, and <tbody> for best results !
 *     -> use <table class='complex data'> for extra-complex tables
 *     -> use <td class='long'> for paragraph-length cell content
 *     -> use <td class='pre'> when manual line breaks/indentation would help readability
 *   - dl.switch for switch statements
 *   - ol.algorithm for algorithms (helps to visualize nesting)
 *   - .figure and .caption (HTML4) and figure and figcaption (HTML5)
 *     -> .sidefigure for right-floated figures
 *   - ins/del
 *
 * Code
 *   - pre and code
 *
 * Special Sections
 *   - .note       for informative notes             (div, p, span, aside, details)
 *   - .example    for informative examples          (div, p, pre, span)
 *   - .issue      for issues                        (div, p, span)
 *   - .assertion  for assertions                    (div, p, span)
 *   - .advisement for loud normative statements     (div, p, strong)
 *   - .annoying-warning for spec obsoletion notices (div, aside, details)
 *
 * Definition Boxes
 *   - pre.def   for WebIDL definitions
 *   - table.def for tables that define other entities (e.g. CSS properties)
 *   - dl.def    for definition lists that define other entitles (e.g. HTML elements)
 *
 * Numbering
 *   - .secno for section numbers in .toc and headings (<span class='secno'>3.2</span>)
 *   - .marker for source-inserted example/figure/issue numbers (<span class='marker'>Issue 4</span>)
 *   - ::before styled for CSS-generated issue/example/figure numbers:
 *     -> Documents wishing to use this only need to add
 *        figcaption::before,
 *        .caption::before { content: "Figure "  counter(figure) " ";  }
 *        .example::before { content: "Example " counter(example) " "; }
 *        .issue::before   { content: "Issue "   counter(issue) " ";   }
 *
 * Header Stuff (ignore, just don't conflict with these classes)
 *   - .head for the header
 *   - .copyright for the copyright
 *
 * Miscellaneous
 *   - .overlarge for things that should be as wide as possible, even if
 *     that overflows the body text area. This can be used on an item or
 *     on its container, depending on the effect desired.
 *     Note that this styling basically doesn't help at all when printing,
 *     since A4 paper isn't much wider than the max-width here.
 *     It's better to design things to fit into a narrower measure if possible.
 *   - js-added ToC jump links (see fixup.js)
 *
 ******************************************************************************/

/******************************************************************************/
/*                                   Body                                     */
/******************************************************************************/

	body {
		counter-reset: example figure issue;

		/* Layout */
		max-width: 50em;               /* limit line length to 50em for readability   */
		margin: 0 auto;                /* center text within page                     */
		padding: 1.6em 1.5em 2em 50px; /* assume 16px font size for downlevel clients */
		padding: 1.6em 1.5em 2em calc(26px + 1.5em); /* leave space for status flag     */

		/* Typography */
		line-height: 1.5;
		font-family: sans-serif;
		widows: 2;
		orphans: 2;
		word-wrap: break-word;
		overflow-wrap: break-word;
		hyphens: auto;

		/* Colors */
		color: black;
		background: white top left fixed no-repeat;
		background-size: 25px auto;
	}


/******************************************************************************/
/*                         Front Matter & Navigation                          */
/******************************************************************************/

/** Header ********************************************************************/

	div.head { margin-bottom: 1em }
	div.head hr { border-style: solid; }

	div.head h1 {
		font-weight: bold;
		margin: 0 0 .1em;
		font-size: 220%;
	}

	div.head h2 { margin-bottom: 1.5em;}

/** W3C Logo ******************************************************************/

	.head .logo {
		float: right;
		margin: 0.4rem 0 0.2rem .4rem;
	}

	.head img[src*="logos/W3C"] {
		display: block;
		border: solid #1a5e9a;
		border-width: .65rem .7rem .6rem;
		border-radius: .4rem;
		background: #1a5e9a;
		color: white;
		font-weight: bold;
	}

	.head a:hover > img[src*="logos/W3C"],
	.head a:focus > img[src*="logos/W3C"] {
		opacity: .8;
	}

	.head a:active > img[src*="logos/W3C"] {
		background: #c00;
		border-color: #c00;
	}

	/* see also additional rules in Link Styling section */

/** Copyright *****************************************************************/

	p.copyright,
	p.copyright small { font-size: small }

/** Back to Top / ToC Toggle **************************************************/

	@media print {
		#toc-nav {
			display: none;
		}
	}
	@media not print {
		#toc-nav {
			position: fixed;
			z-index: 2;
			bottom: 0; left: 0;
			margin: 0;
			min-width: 1.33em;
			border-top-right-radius: 2rem;
			box-shadow: 0 0 2px;
			font-size: 1.5em;
			color: black;
		}
		#toc-nav > a {
			display: block;
			white-space: nowrap;

			height: 1.33em;
			padding: .1em 0.3em;
			margin: 0;

			background: white;
			box-shadow: 0 0 2px;
			border: none;
			border-top-right-radius: 1.33em;
			background: white;
		}
		#toc-nav > #toc-jump {
			padding-bottom: 2em;
			margin-bottom: -1.9em;
		}

		#toc-nav > a:hover,
		#toc-nav > a:focus {
			background: #f8f8f8;
		}
		#toc-nav > a:not(:hover):not(:focus) {
			color: #707070;
		}

		/* statusbar gets in the way on keyboard focus; remove once browsers fix */
		#toc-nav > a[href="#toc"]:not(:hover):focus:last-child {
			padding-bottom: 1.5rem;
		}

		#toc-nav:not(:hover) > a:not(:focus) > span + span {
			/* Ideally this uses :focus-within on #toc-nav */
			display: none;
		}
		#toc-nav > a > span + span {
			padding-right: 0.2em;
		}

		#toc-toggle-inline {
			vertical-align: 0.05em;
			font-size: 80%;
			color: gray;
			color: hsla(203,20%,40%,.7);
			border-style: none;
			background: transparent;
			position: relative;
		}
		#toc-toggle-inline:hover:not(:active),
		#toc-toggle-inline:focus:not(:active) {
			text-shadow: 1px 1px silver;
			top: -1px;
			left: -1px;
		}

		#toc-nav :active {
			color: #C00;
		}
	}

/** ToC Sidebar ***************************************************************/

	/* Floating sidebar */
	@media screen {
		body.toc-sidebar #toc {
			position: fixed;
			top: 0; bottom: 0;
			left: 0;
			width: 23.5em;
			max-width: 80%;
			max-width: calc(100% - 2em - 26px);
			overflow: auto;
			padding: 0 1em;
			padding-left: 42px;
			padding-left: calc(1em + 26px);
			background: inherit;
			background-color: #f7f8f9;
			z-index: 1;
			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) inset;
		}
		body.toc-sidebar #toc h2 {
			margin-top: .8rem;
			font-variant: small-caps;
			font-variant: all-small-caps;
			text-transform: lowercase;
			font-weight: bold;
			color: gray;
			color: hsla(203,20%,40%,.7);
		}
		body.toc-sidebar #toc-jump:not(:focus) {
			width: 0;
			height: 0;
			padding: 0;
			position: absolute;
			overflow: hidden;
		}
	}
	/* Hide main scroller when only the ToC is visible anyway */
	@media screen and (max-width: 28em) {
		body.toc-sidebar {
			overflow: hidden;
		}
	}

	/* Sidebar with its own space */
	@media screen and (min-width: 78em) {
		body:not(.toc-inline) #toc {
			position: fixed;
			top: 0; bottom: 0;
			left: 0;
			width: 23.5em;
			overflow: auto;
			padding: 0 1em;
			padding-left: 42px;
			padding-left: calc(1em + 26px);
			background: inherit;
			background-color: #f7f8f9;
			z-index: 1;
			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) inset;
		}
		body:not(.toc-inline) #toc h2 {
			margin-top: .8rem;
			font-variant: small-caps;
			font-variant: all-small-caps;
			text-transform: lowercase;
			font-weight: bold;
			color: gray;
			color: hsla(203,20%,40%,.7);
		}

		body:not(.toc-inline) {
			padding-left: 29em;
		}
		/* See also Overflow section at the bottom */

		body:not(.toc-inline) #toc-jump:not(:focus) {
			width: 0;
			height: 0;
			padding: 0;
			position: absolute;
			overflow: hidden;
		}
	}
	@media screen and (min-width: 90em) {
		body:not(.toc-inline) {
			margin: 0 4em;
		}
	}

/******************************************************************************/
/*                                Sectioning                                  */
/******************************************************************************/

/** Headings ******************************************************************/

	h1, h2, h3, h4, h5, h6, dt {
		page-break-after: avoid;
		page-break-inside: avoid;
		font: 100% sans-serif;   /* Reset all font styling to clear out UA styles */
		font-family: inherit;    /* Inherit the font family. */
		line-height: 1.2;        /* Keep wrapped headings compact */
		hyphens: manual;         /* Hyphenated headings look weird */
	}

	h2, h3, h4, h5, h6 {
		margin-top: 3rem;
	}

	h1, h2, h3 {
		color: #005A9C;
		background: transparent;
	}

	h1 { font-size: 170%; }
	h2 { font-size: 140%; }
	h3 { font-size: 120%; }
	h4 { font-weight: bold; }
	h5 { font-style: italic; }
	h6 { font-variant: small-caps; }
	dt { font-weight: bold; }

/** Subheadings ***************************************************************/

	h1 + h2,
	#subtitle {
		/* #subtitle is a subtitle in an H2 under the H1 */
		margin-top: 0;
	}
	h2 + h3,
	h3 + h4,
	h4 + h5,
	h5 + h6 {
		margin-top: 1.2em; /* = 1 x line-height */
	}

/** Section divider ***********************************************************/

	:not(.head) > hr {
		font-size: 1.5em;
		text-align: center;
		margin: 1em auto;
		height: auto;
		border: transparent solid 0;
		background: transparent;
	}
	:not(.head) > hr::before {
		content: "\2727\2003\2003\2727\2003\2003\2727";
	}

/******************************************************************************/
/*                            Paragraphs and Lists                            */
/******************************************************************************/

	p {
		margin: 1em 0;
	}

	dd > p:first-child,
	li > p:first-child {
		margin-top: 0;
	}

	ul, ol {
		margin-left: 0;
		padding-left: 2em;
	}

	li {
		margin: 0.25em 0 0.5em;
		padding: 0;
	}

	dl dd {
		margin: 0 0 .5em 2em;
	}

	.head dd + dd { /* compact for header */
		margin-top: -.5em;
	}

	/* Style for algorithms */
	ol.algorithm ol:not(.algorithm),
	.algorithm > ol ol:not(.algorithm) {
	 border-left: 0.5em solid #DEF;
	}

	/* Put nice boxes around each algorithm. */
	[data-algorithm]:not(.heading) {
	  padding: .5em;
	  border: thin solid #ddd; border-radius: .5em;
	  margin: .5em 0;
	}
	[data-algorithm]:not(.heading) > :first-child {
	  margin-top: 0;
	}
	[data-algorithm]:not(.heading) > :last-child {
	  margin-bottom: 0;
	}

	/* Style for switch/case <dl>s */
	dl.switch > dd > ol.only,
	dl.switch > dd > .only > ol {
	 margin-left: 0;
	}
	dl.switch > dd > ol.algorithm,
	dl.switch > dd > .algorithm > ol {
	 margin-left: -2em;
	}
	dl.switch {
	 padding-left: 2em;
	}
	dl.switch > dt {
	 text-indent: -1.5em;
	 margin-top: 1em;
	}
	dl.switch > dt + dt {
	 margin-top: 0;
	}
	dl.switch > dt::before {
	 content: '\21AA';
	 padding: 0 0.5em 0 0;
	 display: inline-block;
	 width: 1em;
	 text-align: right;
	 line-height: 0.5em;
	}

/** Terminology Markup ********************************************************/


/******************************************************************************/
/*                                 Inline Markup                              */
/******************************************************************************/

/** Terminology Markup ********************************************************/
	dfn   { /* Defining instance */
		font-weight: bolder;
	}
	a > i { /* Instance of term */
		font-style: normal;
	}
	dt dfn code, code.idl {
		font-size: normal;
	}
	dfn var {
		font-style: normal;
	}

/** Change Marking ************************************************************/

	del { color: red !important;  background-color: #FFB0B0; text-decoration: line-through; }
	ins { color: #080 !important; background-color: #B0FFB0; text-decoration: none;         }

	del code, del pre, .del code, .del pre, code del, pre del, code .del, pre .del { background-color: #FFB0B0 !important; text-decoration: line-through; }
	ins code, ins pre, .ins code, .ins pre, code ins, pre ins, code .ins, pre .ins { background-color: #B0FFB0 !important; text-decoration: none;         }

/** Miscellaneous improvements to inline formatting ***************************/

	sup {
		vertical-align: super;
		font-size: 80%
	}

/******************************************************************************/
/*                                    Code                                    */
/******************************************************************************/

/** General monospace/pre rules ***********************************************/

	pre, code, samp {
		font-family: Menlo, Consolas, "DejaVu Sans Mono", Monaco, monospace;
		font-size: .9em;
		page-break-inside: avoid;
		hyphens: none;
		text-transform: none;
	}
	pre code,
	code code {
		font-size: 100%;
	}

	pre {
		margin-top: 1em;
		margin-bottom: 1em;
		overflow: auto;
	}

/** Inline Code fragments *****************************************************/

  /* Do something nice. */

/******************************************************************************/
/*                                    Links                                   */
/******************************************************************************/

/** General Hyperlinks ********************************************************/

	/* We hyperlink a lot, so make it less intrusive */
	a[href] {
		color: #034575;
		text-decoration: none;
		border-bottom: 1px solid #707070;
		/* Need a bit of extending for it to look okay */
		padding: 0 1px 0;
		margin: 0 -1px 0;
	}
	a:visited {
		border-bottom-color: #BBB;
	}

	/* Use distinguishing colors when user is interacting with the link */
	a[href]:focus,
	a[href]:hover {
		background: #f8f8f8;
		background: rgba(75%, 75%, 75%, .25);
		border-bottom-width: 3px;
		margin-bottom: -2px;
	}
	a[href]:active {
		color: #C00;
		border-color: #C00;
	}

	/* Backout above styling for W3C logo */
	.head .logo,
	.head .logo a {
		border: none;
		text-decoration: none;
		background: transparent;
	}

/******************************************************************************/
/*                                    Images                                  */
/******************************************************************************/

	img {
		border-style: none;
	}

	/* For autogen numbers, add
	   .caption::before, figcaption::before { content: "Figure " counter(figure) ". "; }
	*/

	figure, .figure, .sidefigure {
		page-break-inside: avoid;
		text-align: center;
		margin: 2.5em 0;
	}
	.figure img,    .sidefigure img,    figure img,
	.figure object, .sidefigure object, figure object {
		max-width: 100%;
		margin: auto;
	}
	.figure pre, .sidefigure pre, figure pre {
		text-align: left;
		display: table;
		margin: 1em auto;
	}
	.figure table, figure table {
		margin: auto;
	}
	@media screen and (min-width: 20em) {
		.sidefigure {
			float: right;
			width: 50%;
			margin: 0 0 0.5em 0.5em
		}
	}
	.caption, figcaption, caption {
		font-style: italic;
		font-size: 90%;
	}
	.caption::before, figcaption::before, figcaption > .marker {
		font-weight: bold;
	}
	.caption, figcaption {
		counter-increment: figure;
	}

	/* DL list is indented 2em, but figure inside it is not */
	dd > .figure, dd > figure { margin-left: -2em }

/******************************************************************************/
/*                             Colored Boxes                                  */
/******************************************************************************/

	.issue, .note, .example, .assertion, .advisement, blockquote {
		padding: .5em;
		border: .5em;
		border-left-style: solid;
		page-break-inside: avoid;
	}
	span.issue, span.note {
		padding: .1em .5em .15em;
		border-right-style: solid;
	}

	.issue,
	.note,
	.example,
	.advisement,
	.assertion,
	blockquote {
		margin: 1em auto;
	}
	.note  > p:first-child,
	.issue > p:first-child,
	blockquote > :first-child {
		margin-top: 0;
	}
	blockquote > :last-child {
		margin-bottom: 0;
	}

/** Blockquotes ***************************************************************/

	blockquote {
		border-color: silver;
	}

/** Open issue ****************************************************************/

	.issue {
		border-color: #E05252;
		background: #FBE9E9;
		counter-increment: issue;
		overflow: auto;
	}
	.issue::before, .issue > .marker {
		text-transform: uppercase;
		color: #AE1E1E;
		padding-right: 1em;
		text-transform: uppercase;
	}
	/* Add .issue::before { content: "Issue " counter(issue) " "; } for autogen numbers,
	   or use class="marker" to mark up the issue number in source. */

/** Example *******************************************************************/

	.example {
		border-color: #E0CB52;
		background: #FCFAEE;
		counter-increment: example;
		overflow: auto;
		clear: both;
	}
	.example::before, .example > .marker {
		text-transform: uppercase;
		color: #827017;
		min-width: 7.5em;
		display: block;
	}
	/* Add .example::before { content: "Example " counter(example) " "; } for autogen numbers,
	   or use class="marker" to mark up the example number in source. */

/** Non-normative Note ********************************************************/

	.note {
		border-color: #52E052;
		background: #E9FBE9;
		overflow: auto;
	}

	.note::before, .note > .marker,
	details.note > summary::before,
	details.note > summary > .marker {
		text-transform: uppercase;
		display: block;
		color: hsl(120, 70%, 30%);
	}
	/* Add .note::before { content: "Note"; } for autogen label,
	   or use class="marker" to mark up the label in source. */

	details.note > summary {
		display: block;
		color: hsl(120, 70%, 30%);
	}
	details.note[open] > summary {
		border-bottom: 1px silver solid;
	}

/** Assertion Box *************************************************************/
	/*  for assertions in algorithms */

	.assertion {
		border-color: #AAA;
		background: #EEE;
	}

/** Advisement Box ************************************************************/
	/*  for attention-grabbing normative statements */

	.advisement {
		border-color: orange;
		border-style: none solid;
		background: #FFEECC;
	}
	strong.advisement {
		display: block;
		text-align: center;
	}
	.advisement > .marker {
		color: #B35F00;
	}

/** Spec Obsoletion Notice ****************************************************/
	/* obnoxious obsoletion notice for older/abandoned specs. */

	details {
		display: block;
	}
	summary {
		font-weight: bolder;
	}

	.annoying-warning:not(details),
	details.annoying-warning:not([open]) > summary,
	details.annoying-warning[open] {
		background: #fdd;
		color: red;
		font-weight: bold;
		padding: .75em 1em;
		border: thick red;
		border-style: solid;
		border-radius: 1em;
	}
	.annoying-warning :last-child {
		margin-bottom: 0;
	}

@media not print {
	details.annoying-warning[open] {
		position: fixed;
		left: 1em;
		right: 1em;
		bottom: 1em;
		z-index: 1000;
	}
}

	details.annoying-warning:not([open]) > summary {
		text-align: center;
	}

/** Entity Definition Boxes ***************************************************/

	.def {
		padding: .5em 1em;
		background: #DEF;
		margin: 1.2em 0;
		border-left: 0.5em solid #8CCBF2;
	}

/******************************************************************************/
/*                                    Tables                                  */
/******************************************************************************/

	th, td {
		text-align: left;
		text-align: start;
	}

/** Property/Descriptor Definition Tables *************************************/

	table.def {
		/* inherits .def box styling, see above */
		width: 100%;
		border-spacing: 0;
	}

	table.def td,
	table.def th {
		padding: 0.5em;
		vertical-align: baseline;
		border-bottom: 1px solid #bbd7e9;
	}

	table.def > tbody > tr:last-child th,
	table.def > tbody > tr:last-child td {
		border-bottom: 0;
	}

	table.def th {
		font-style: italic;
		font-weight: normal;
		padding-left: 1em;
		width: 3em;
	}

	/* For when values are extra-complex and need formatting for readability */
	table td.pre {
		white-space: pre-wrap;
	}

	/* A footnote at the bottom of a def table */
	table.def           td.footnote {
		padding-top: 0.6em;
	}
	table.def           td.footnote::before {
		content: " ";
		display: block;
		height: 0.6em;
		width: 4em;
		border-top: thin solid;
	}

/** Data tables (and properly marked-up index tables) *************************/
	/*
		 <table class="data"> highlights structural relationships in a table
		 when correct markup is used (e.g. thead/tbody, th vs. td, scope attribute)

		 Use class="complex data" for particularly complicated tables --
		 (This will draw more lines: busier, but clearer.)

		 Use class="long" on table cells with paragraph-like contents
		 (This will adjust text alignment accordingly.)
		 Alternately use class="longlastcol" on tables, to have the last column assume "long".
	*/

	table {
		word-wrap: normal;
		overflow-wrap: normal;
		hyphens: manual;
	}

	table.data,
	table.index {
		margin: 1em auto;
		border-collapse: collapse;
		border: hidden;
		width: 100%;
	}
	table.data caption,
	table.index caption {
		max-width: 50em;
		margin: 0 auto 1em;
	}

	table.data td,  table.data th,
	table.index td, table.index th {
		padding: 0.5em 1em;
		border-width: 1px;
		border-color: silver;
		border-top-style: solid;
	}

	table.data thead td:empty {
		padding: 0;
		border: 0;
	}

	table.data  thead,
	table.index thead,
	table.data  tbody,
	table.index tbody {
		border-bottom: 2px solid;
	}

	table.data colgroup,
	table.index colgroup {
		border-left: 2px solid;
	}

	table.data  tbody th:first-child,
	table.index tbody th:first-child  {
		border-right: 2px solid;
		border-top: 1px solid silver;
		padding-right: 1em;
	}

	table.data th[colspan],
	table.data td[colspan] {
		text-align: center;
	}

	table.complex.data th,
	table.complex.data td {
		border: 1px solid silver;
		text-align: center;
	}

	table.data.longlastcol td:last-child,
	table.data td.long {
	 vertical-align: baseline;
	 text-align: left;
	}

	table.data img {
		vertical-align: middle;
	}


/*
Alternate table alignment rules

	table.data,
	table.index {
		text-align: center;
	}

	table.data  thead th[scope="row"],
	table.index thead th[scope="row"] {
		text-align: right;
	}

	table.data  tbody th:first-child,
	table.index tbody th:first-child  {
		text-align: right;
	}

Possible extra rowspan handling

	table.data  tbody th[rowspan]:not([rowspan='1']),
	table.index tbody th[rowspan]:not([rowspan='1']),
	table.data  tbody td[rowspan]:not([rowspan='1']),
	table.index tbody td[rowspan]:not([rowspan='1']) {
		border-left: 1px solid silver;
	}

	table.data  tbody th[rowspan]:first-child,
	table.index tbody th[rowspan]:first-child,
	table.data  tbody td[rowspan]:first-child,
	table.index tbody td[rowspan]:first-child{
		border-left: 0;
		border-right: 1px solid silver;
	}
*/

/******************************************************************************/
/*                                  Indices                                   */
/******************************************************************************/


/** Table of Contents *********************************************************/

	.toc a {
		/* More spacing; use padding to make it part of the click target. */
		padding-top: 0.1rem;
		/* Larger, more consistently-sized click target */
		display: block;
		/* Reverse color scheme */
		color: black;
		border-color: #3980B5;
	}
	.toc a:visited {
		border-color: #054572;
	}
	.toc a:not(:focus):not(:hover) {
		/* Allow colors to cascade through from link styling */
		border-bottom-color: transparent;
	}

	.toc, .toc ol, .toc ul, .toc li {
		list-style: none; /* Numbers must be inlined into source */
		/* because generated content isn't search/selectable and markers can't do multilevel yet */
		margin:  0;
		padding: 0;
		line-height: 1.1rem; /* consistent spacing */
	}

	/* ToC not indented until third level, but font style & margins show hierarchy */
	.toc > li             { font-weight: bold;   }
	.toc > li li          { font-weight: normal; }
	.toc > li li li       { font-size:   95%;    }
	.toc > li li li li    { font-size:   90%;    }
	.toc > li li li li li { font-size:   85%;    }

	.toc > li             { margin: 1.5rem 0;    }
	.toc > li li          { margin: 0.3rem 0;    }
	.toc > li li li       { margin-left: 2rem;   }

	/* Section numbers in a column of their own */
	.toc .secno {
		float: left;
		width: 4rem;
		white-space: nowrap;
	}
	.toc > li li li li .secno {
		font-size: 85%;
	}
	.toc > li li li li li .secno {
		font-size: 100%;
	}

	:not(li) > .toc              { margin-left:  5rem; }
	.toc .secno                  { margin-left: -5rem; }
	.toc > li li li .secno       { margin-left: -7rem; }
	.toc > li li li li .secno    { margin-left: -9rem; }
	.toc > li li li li li .secno { margin-left: -11rem; }

	/* Tighten up indentation in narrow ToCs */
	@media (max-width: 30em) {
		:not(li) > .toc              { margin-left:  4rem; }
		.toc .secno                  { margin-left: -4rem; }
		.toc > li li li              { margin-left:  1rem; }
		.toc > li li li .secno       { margin-left: -5rem; }
		.toc > li li li li .secno    { margin-left: -6rem; }
		.toc > li li li li li .secno { margin-left: -7rem; }
	}
	@media screen and (min-width: 78em) {
		body:not(.toc-inline) :not(li) > .toc              { margin-left:  4rem; }
		body:not(.toc-inline) .toc .secno                  { margin-left: -4rem; }
		body:not(.toc-inline) .toc > li li li              { margin-left:  1rem; }
		body:not(.toc-inline) .toc > li li li .secno       { margin-left: -5rem; }
		body:not(.toc-inline) .toc > li li li li .secno    { margin-left: -6rem; }
		body:not(.toc-inline) .toc > li li li li li .secno { margin-left: -7rem; }
	}
	body.toc-sidebar #toc :not(li) > .toc              { margin-left:  4rem; }
	body.toc-sidebar #toc .toc .secno                  { margin-left: -4rem; }
	body.toc-sidebar #toc .toc > li li li              { margin-left:  1rem; }
	body.toc-sidebar #toc .toc > li li li .secno       { margin-left: -5rem; }
	body.toc-sidebar #toc .toc > li li li li .secno    { margin-left: -6rem; }
	body.toc-sidebar #toc .toc > li li li li li .secno { margin-left: -7rem; }

	.toc li {
		clear: both;
	}


/** Index *********************************************************************/

	/* Index Lists: Layout */
	ul.index       { margin-left: 0; columns: 15em; text-indent: 1em hanging; }
	ul.index li    { margin-left: 0; list-style: none; break-inside: avoid; }
	ul.index li li { margin-left: 1em }
	ul.index dl    { margin-top: 0; }
	ul.index dt    { margin: .2em 0 .2em 20px;}
	ul.index dd    { margin: .2em 0 .2em 40px;}
	/* Index Lists: Typography */
	ul.index ul,
	ul.index dl { font-size: smaller; }
	@media not print {
		ul.index li span {
			white-space: nowrap;
			color: transparent; }
		ul.index li a:hover + span,
		ul.index li a:focus + span {
			color: #707070;
		}
	}

/** Index Tables *****************************************************/
	/* See also the data table styling section, which this effectively subclasses */

	table.index {
		font-size: small;
		border-collapse: collapse;
		border-spacing: 0;
		text-align: left;
		margin: 1em 0;
	}

	table.index td,
	table.index th {
		padding: 0.4em;
	}

	table.index tr:hover td:not([rowspan]),
	table.index tr:hover th:not([rowspan]) {
		background: #f7f8f9;
	}

	/* The link in the first column in the property table (formerly a TD) */
	table.index th:first-child a {
		font-weight: bold;
	}

/******************************************************************************/
/*                                    Print                                   */
/******************************************************************************/

	@media print {
		/* Pages have their own margins. */
		html {
			margin: 0;
		}
		/* Serif for print. */
		body {
			font-family: serif;
		}
	}
	@page {
		margin: 1.5cm 1.1cm;
	}

/******************************************************************************/
/*                                    Legacy                                  */
/******************************************************************************/

	/* This rule is inherited from past style sheets. No idea what it's for. */
	.hide { display: none }



/******************************************************************************/
/*                             Overflow Control                               */
/******************************************************************************/

	.figure .caption, .sidefigure .caption, figcaption {
		/* in case figure is overlarge, limit caption to 50em */
		max-width: 50rem;
		margin-left: auto;
		margin-right: auto;
	}
	.overlarge > table {
		/* limit preferred width of table */
		max-width: 50em;
		margin-left: auto;
		margin-right: auto;
	}

	@media (min-width: 55em) {
		.overlarge {
			margin-left: calc(13px + 26.5rem - 50vw);
			margin-right: calc(13px + 26.5rem - 50vw);
			max-width: none;
		}
	}
	@media screen and (min-width: 78em) {
		body:not(.toc-inline) .overlarge {
			/* 30.5em body padding 50em content area */
			margin-left: calc(40em - 50vw) !important;
			margin-right: calc(40em - 50vw) !important;
		}
	}
	@media screen and (min-width: 90em) {
		body:not(.toc-inline) .overlarge {
			/* 4em html margin 30.5em body padding 50em content area */
			margin-left: 0 !important;
			margin-right: calc(84.5em - 100vw) !important;
		}
	}

	@media not print {
		.overlarge {
			overflow-x: auto;
			/* See Lea Verou's explanation background-attachment:
			 * http://lea.verou.me/2012/04/background-attachment-local/
			 *
			background: top left  / 4em 100% linear-gradient(to right,  #ffffff, rgba(255, 255, 255, 0)) local,
			            top right / 4em 100% linear-gradient(to left, #ffffff, rgba(255, 255, 255, 0)) local,
			            top left  / 1em 100% linear-gradient(to right,  #c3c3c5, rgba(195, 195, 197, 0)) scroll,
			            top right / 1em 100% linear-gradient(to left, #c3c3c5, rgba(195, 195, 197, 0)) scroll,
			            white;
			background-repeat: no-repeat;
			*/
		}
	}
</style>
  <meta content="Bikeshed 1.0.0" name="generator">
<style>/* style-md-lists */

            /* This is a weird hack for me not yet following the commonmark spec
               regarding paragraph and lists. */
            [data-md] > :first-child {
                margin-top: 0;
            }
            [data-md] > :last-child {
                margin-bottom: 0;
            }</style>
<style>/* style-hidedel */

            #hidedel:checked ~ del, #hidedel:checked ~ * del { display:none; }
            #hidedel ~ #hidedel-label::before, #hidedel ~ * #hidedel-label::before { content: "☐ "; }
            #hidedel:checked ~ #hidedel-label::before, #hidedel:checked ~ * #hidedel-label::before { content: "☑ "; }
        </style>
<style>/* style-selflinks */

            .heading, .issue, .note, .example, li, dt {
                position: relative;
            }
            a.self-link {
                position: absolute;
                top: 0;
                left: calc(-1 * (3.5rem - 26px));
                width: calc(3.5rem - 26px);
                height: 2em;
                text-align: center;
                border: none;
                transition: opacity .2s;
                opacity: .5;
            }
            a.self-link:hover {
                opacity: 1;
            }
            .heading > a.self-link {
                font-size: 83%;
            }
            li > a.self-link {
                left: calc(-1 * (3.5rem - 26px) - 2em);
            }
            dfn > a.self-link {
                top: auto;
                left: auto;
                opacity: 0;
                width: 1.5em;
                height: 1.5em;
                background: gray;
                color: white;
                font-style: normal;
                transition: opacity .2s, background-color .2s, color .2s;
            }
            dfn:hover > a.self-link {
                opacity: 1;
            }
            dfn > a.self-link:hover {
                color: black;
            }

            a.self-link::before            { content: "¶"; }
            .heading > a.self-link::before { content: "§"; }
            dfn > a.self-link::before      { content: "#"; }</style>
<style>/* style-counters */

            body {
                counter-reset: example figure issue;
            }
            .issue {
                counter-increment: issue;
            }
            .issue:not(.no-marker)::before {
                content: "Issue " counter(issue);
            }

            .example {
                counter-increment: example;
            }
            .example:not(.no-marker)::before {
                content: "Example " counter(example);
            }
            .invalid.example:not(.no-marker)::before,
            .illegal.example:not(.no-marker)::before {
                content: "Invalid Example" counter(example);
            }

            figcaption {
                counter-increment: figure;
            }
            figcaption:not(.no-marker)::before {
                content: "Figure " counter(figure) " ";
            }</style>
<style>/* style-autolinks */

            .css.css, .property.property, .descriptor.descriptor {
                color: #005a9c;
                font-size: inherit;
                font-family: inherit;
            }
            .css::before, .property::before, .descriptor::before {
                content: "‘";
            }
            .css::after, .property::after, .descriptor::after {
                content: "’";
            }
            .property, .descriptor {
                /* Don't wrap property and descriptor names */
                white-space: nowrap;
            }
            .type { /* CSS value <type> */
                font-style: italic;
            }
            pre .property::before, pre .property::after {
                content: "";
            }
            [data-link-type="property"]::before,
            [data-link-type="propdesc"]::before,
            [data-link-type="descriptor"]::before,
            [data-link-type="value"]::before,
            [data-link-type="function"]::before,
            [data-link-type="at-rule"]::before,
            [data-link-type="selector"]::before,
            [data-link-type="maybe"]::before {
                content: "‘";
            }
            [data-link-type="property"]::after,
            [data-link-type="propdesc"]::after,
            [data-link-type="descriptor"]::after,
            [data-link-type="value"]::after,
            [data-link-type="function"]::after,
            [data-link-type="at-rule"]::after,
            [data-link-type="selector"]::after,
            [data-link-type="maybe"]::after {
                content: "’";
            }

            [data-link-type].production::before,
            [data-link-type].production::after,
            .prod [data-link-type]::before,
            .prod [data-link-type]::after {
                content: "";
            }

            [data-link-type=element],
            [data-link-type=element-attr] {
                font-family: Menlo, Consolas, "DejaVu Sans Mono", monospace;
                font-size: .9em;
            }
            [data-link-type=element]::before { content: "<" }
            [data-link-type=element]::after  { content: ">" }

            [data-link-type=biblio] {
                white-space: pre;
            }</style>
<style>/* style-syntax-highlighting */

        .highlight:not(.idl) { background: hsl(24, 20%, 95%); }
        code.highlight { padding: .1em; border-radius: .3em; }
        pre.highlight, pre > code.highlight { display: block; padding: 1em; margin: .5em 0; overflow: auto; border-radius: 0; }
        .highlight .c { color: #708090 } /* Comment */
        .highlight .k { color: #990055 } /* Keyword */
        .highlight .l { color: #000000 } /* Literal */
        .highlight .n { color: #0077aa } /* Name */
        .highlight .o { color: #999999 } /* Operator */
        .highlight .p { color: #999999 } /* Punctuation */
        .highlight .cm { color: #708090 } /* Comment.Multiline */
        .highlight .cp { color: #708090 } /* Comment.Preproc */
        .highlight .c1 { color: #708090 } /* Comment.Single */
        .highlight .cs { color: #708090 } /* Comment.Special */
        .highlight .kc { color: #990055 } /* Keyword.Constant */
        .highlight .kd { color: #990055 } /* Keyword.Declaration */
        .highlight .kn { color: #990055 } /* Keyword.Namespace */
        .highlight .kp { color: #990055 } /* Keyword.Pseudo */
        .highlight .kr { color: #990055 } /* Keyword.Reserved */
        .highlight .kt { color: #990055 } /* Keyword.Type */
        .highlight .ld { color: #000000 } /* Literal.Date */
        .highlight .m { color: #000000 } /* Literal.Number */
        .highlight .s { color: #a67f59 } /* Literal.String */
        .highlight .na { color: #0077aa } /* Name.Attribute */
        .highlight .nc { color: #0077aa } /* Name.Class */
        .highlight .no { color: #0077aa } /* Name.Constant */
        .highlight .nd { color: #0077aa } /* Name.Decorator */
        .highlight .ni { color: #0077aa } /* Name.Entity */
        .highlight .ne { color: #0077aa } /* Name.Exception */
        .highlight .nf { color: #0077aa } /* Name.Function */
        .highlight .nl { color: #0077aa } /* Name.Label */
        .highlight .nn { color: #0077aa } /* Name.Namespace */
        .highlight .py { color: #0077aa } /* Name.Property */
        .highlight .nt { color: #669900 } /* Name.Tag */
        .highlight .nv { color: #222222 } /* Name.Variable */
        .highlight .ow { color: #999999 } /* Operator.Word */
        .highlight .mb { color: #000000 } /* Literal.Number.Bin */
        .highlight .mf { color: #000000 } /* Literal.Number.Float */
        .highlight .mh { color: #000000 } /* Literal.Number.Hex */
        .highlight .mi { color: #000000 } /* Literal.Number.Integer */
        .highlight .mo { color: #000000 } /* Literal.Number.Oct */
        .highlight .sb { color: #a67f59 } /* Literal.String.Backtick */
        .highlight .sc { color: #a67f59 } /* Literal.String.Char */
        .highlight .sd { color: #a67f59 } /* Literal.String.Doc */
        .highlight .s2 { color: #a67f59 } /* Literal.String.Double */
        .highlight .se { color: #a67f59 } /* Literal.String.Escape */
        .highlight .sh { color: #a67f59 } /* Literal.String.Heredoc */
        .highlight .si { color: #a67f59 } /* Literal.String.Interpol */
        .highlight .sx { color: #a67f59 } /* Literal.String.Other */
        .highlight .sr { color: #a67f59 } /* Literal.String.Regex */
        .highlight .s1 { color: #a67f59 } /* Literal.String.Single */
        .highlight .ss { color: #a67f59 } /* Literal.String.Symbol */
        .highlight .vc { color: #0077aa } /* Name.Variable.Class */
        .highlight .vg { color: #0077aa } /* Name.Variable.Global */
        .highlight .vi { color: #0077aa } /* Name.Variable.Instance */
        .highlight .il { color: #000000 } /* Literal.Number.Integer.Long */
        </style>
 <body class="h-entry">
  <input id="hidedel" style="display:none" type="checkbox">
  <div class="head">
   <p data-fill-with="logo"></p>
   <h1 class="p-name no-ref" id="title">P0452r1<br>Unifying &lt;numeric> Parallel Algorithms</h1>
   <h2 class="no-num no-toc no-ref heading settled" id="subtitle"><span class="content">Published Proposal, <time class="dt-updated" datetime="2017-03-01">1 March 2017</time></span></h2>
   <div data-fill-with="spec-metadata">
    <dl>
     <dt>This version:
     <dd><a class="u-url" href="http://wg21.link/P0452r1">http://wg21.link/P0452r1</a>
     <dt>Author:
     <dd>
      <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:balelbach@lbl.gov">Bryce Adelstein Lelbach</a> (<span class="p-org org">Lawrence Berkeley National Laboratory</span>)
     <dt>Audience:
     <dd>SG1, LEWG, LWG
     <dt>Toggle Diffs:
     <dd>
      <label for="hidedel" id="hidedel-label">Hide deleted text</label>
     <dt>Project:
     <dd><span>ISO JTC1/SC22/WG21: Programming Language C++</span>
    </dl>
   </div>
   <div data-fill-with="warning"></div>
   <hr title="Separator for header">
  </div>
  <div class="p-summary" data-fill-with="abstract"></div>
  <nav data-fill-with="table-of-contents" id="toc">
   <h2 class="no-num no-toc no-ref" id="contents">Table of Contents</h2>
   <ol class="toc" role="directory">
    <li>
     <a href="#overview"><span class="secno">1</span> <span class="content">Overview</span></a>
     <ol class="toc">
      <li><a href="#ipnopar"><span class="secno">1.1</span> <span class="content"><code class="highlight"><span class="n">inner_product</span></code> Cannot Be Parallelized</span></a>
      <li><a href="#ipistr"><span class="secno">1.2</span> <span class="content"><code class="highlight"><span class="n">inner_product</span></code> is a Form of <code class="highlight"><span class="n">transform_reduce</span></code></span></a>
      <li><a href="#trmiss"><span class="secno">1.3</span> <span class="content"><code class="highlight"><span class="n">transform_reduce</span></code> is Missing an Overload</span></a>
      <li><a href="#trparam"><span class="secno">1.4</span> <span class="content"><code class="highlight"><span class="n">transform_reduce</span></code> Parameter Order is Odd</span></a>
      <li><a href="#scanparam"><span class="secno">1.5</span> <span class="content"><code class="highlight"><span class="n">transform_inclusive_scan</span></code> and <code class="highlight"><span class="n">transform_exclusive_scan</span></code> Parameter Order is Odd</span></a>
     </ol>
    <li><a href="#reso"><span class="secno">2</span> <span class="content">Proposed Resolution</span></a>
    <li><a href="#faq"><span class="secno">3</span> <span class="content">FAQ</span></a>
    <li>
     <a href="#wording"><span class="secno">4</span> <span class="content">Wording</span></a>
     <ol class="toc">
      <li><a href="#tripwording"><span class="secno">4.1</span> <span class="content">Wording for <code class="highlight"><span class="n">transform_reduce</span></code>/<code class="highlight"><span class="n">inner_product</span></code></span></a>
      <li><a href="#teswording"><span class="secno">4.2</span> <span class="content">Wording for <code class="highlight"><span class="n">transform_exclusive_scan</span></code></span></a>
      <li><a href="#tiswording"><span class="secno">4.3</span> <span class="content">Wording for <code class="highlight"><span class="n">transform_inclusive_scan</span></code></span></a>
     </ol>
    <li><a href="#ack"><span class="secno">5</span> <span class="content">Acknowledgement</span></a>
    <li>
     <a href="#references"><span class="secno"></span> <span class="content">References</span></a>
     <ol class="toc">
      <li><a href="#informative"><span class="secno"></span> <span class="content">Informative References</span></a>
     </ol>
   </ol>
  </nav>
  <main>
   <h2 class="heading settled" data-level="1" id="overview"><span class="secno">1. </span><span class="content">Overview</span><a class="self-link" href="#overview"></a></h2>
   <p>US 161 and US 184 identify issues relating to the <code class="highlight"><span class="n">ExecutionPolicy</span></code> (e.g.
parallel) signatures of the four pre-C++17 sequence algorithms (<code class="highlight"><span class="n">accumulate</span></code>, <code class="highlight"><span class="n">inner_product</span></code>, <code class="highlight"><span class="n">partial_sum</span></code> and <code class="highlight"><span class="n">adjacent_difference</span></code>) found in <code class="highlight"><span class="o">&lt;</span><span class="n">numeric</span><span class="o">></span></code>.</p>
   <p>All of these issues revolve around the strength of the ordering requirements of
these algorithms and the new <code class="highlight"><span class="o">&lt;</span><span class="n">numeric</span><span class="o">></span></code> algorithms with
weaker ordering guarantees that were introduced in the Parallelism TS v1 and
C++17 (<code class="highlight"><span class="n">reduce</span></code>, <code class="highlight"><span class="n">transform_reduce</span></code>, <code class="highlight"><span class="n">inclusive_scan</span></code>, <code class="highlight"><span class="n">exclusive_scan</span></code>, <code class="highlight"><span class="n">transform_inclusive_scan</span></code> and <code class="highlight"><span class="n">transform_exclusive_scan</span></code>).</p>
   <p>This paper proposes two types of changes:</p>
   <ul>
    <li data-md="">
     <p>Addition/removal of <code class="highlight"><span class="o">&lt;</span><span class="n">numeric</span><span class="o">></span></code> sequence algorithm signatures.</p>
    <li data-md="">
     <p>Changes to the order of parameters of <code class="highlight"><span class="o">&lt;</span><span class="n">numeric</span><span class="o">></span></code> sequence
algorithm signatures.</p>
   </ul>
   <h3 class="heading settled" data-level="1.1" id="ipnopar"><span class="secno">1.1. </span><span class="content"><code class="highlight"><span class="n">inner_product</span></code> Cannot Be Parallelized</span><a class="self-link" href="#ipnopar"></a></h3>
   <p>Currently, <code class="highlight"><span class="n">accumulate</span></code>, <code class="highlight"><span class="n">inner_product</span></code> and <code class="highlight"><span class="n">partial_sum</span></code> use
"accumulator-style" wording:</p>
   <blockquote>
     <strong>26.8.2 Accumulate</strong> [<strong>accumulate</strong>]: 
<pre class="highlight"><span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIterator</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">T</span><span class="o">></span>
  <span class="n">T</span> <span class="n">accumulate</span><span class="p">(</span><span class="n">InputIterator</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIterator</span> <span class="n">last</span><span class="p">,</span>
               <span class="n">T</span> <span class="n">init</span><span class="p">)</span><span class="p">;</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIterator</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">T</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">BinaryOperation</span><span class="o">></span>
  <span class="n">T</span> <span class="n">accumulate</span><span class="p">(</span><span class="n">InputIterator</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIterator</span> <span class="n">last</span><span class="p">,</span>
               <span class="n">T</span> <span class="n">init</span><span class="p">,</span>
               <span class="n">BinaryOperation</span> <span class="n">binary_op</span><span class="p">)</span><span class="p">;</span>
</pre>
    <p>1 <em>Effects:</em> Computes its result by initializing the accumulator <code class="highlight"><span class="n">acc</span></code> with the initial value <code class="highlight"><span class="n">init</span></code> and then modifies it with <code class="highlight"><span class="n">acc</span> <span class="o">=</span> <span class="n">acc</span> <span class="o">+</span> <span class="o">*</span><span class="n">i</span></code> or <code class="highlight"><span class="n">acc</span> <span class="o">=</span> <span class="n">binary_op</span><span class="p">(</span><span class="n">acc</span><span class="p">,</span> <span class="o">*</span><span class="n">i</span><span class="p">)</span></code> for every iterator <code class="highlight"><span class="n">i</span></code> in the range <code class="highlight"><span class="p">[</span><span class="n">first</span><span class="p">,</span> <span class="n">last</span><span class="p">)</span></code> in order.</p>
    <p>2 <em>Requires:</em> <code class="highlight"><span class="n">T</span></code> shall meet the requirements of <code class="highlight"><span class="n">CopyConstructible</span></code> (Table 22) and <code class="highlight"><span class="n">CopyAssignable</span></code> (Table 24) types. In the range <code class="highlight"><span class="p">[</span><span class="n">first</span><span class="p">,</span> <span class="n">last</span><span class="p">]</span></code>, <code class="highlight"><span class="n">binary_op</span></code> shall neither modify elements nor invalidate iterators or subranges.</p>
   </blockquote>
   <blockquote>
     <strong>26.8.5 Inner product</strong> [<strong>inner.product</strong>]: 
<pre class="highlight"><span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIterator1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">InputIterator2</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">T</span><span class="o">></span>
  <span class="n">T</span> <span class="n">inner_product</span><span class="p">(</span><span class="n">InputIterator1</span> <span class="n">first1</span><span class="p">,</span> <span class="n">InputIterator1</span> <span class="n">last1</span><span class="p">,</span>
                  <span class="n">InputIterator2</span> <span class="n">first2</span><span class="p">,</span>
                  <span class="n">T</span> <span class="n">init</span><span class="p">)</span><span class="p">;</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIterator1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">InputIterator2</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">T</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">BinaryOperation1</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">BinaryOperation2</span><span class="o">></span>
  <span class="n">T</span> <span class="n">inner_product</span><span class="p">(</span><span class="n">InputIterator1</span> <span class="n">first1</span><span class="p">,</span> <span class="n">InputIterator1</span> <span class="n">last1</span><span class="p">,</span>
                  <span class="n">InputIterator2</span> <span class="n">first2</span><span class="p">,</span>
                  <span class="n">T</span> <span class="n">init</span><span class="p">,</span>
                  <span class="n">BinaryOperation1</span> <span class="n">binary_op1</span><span class="p">,</span>
                  <span class="n">BinaryOperation2</span> <span class="n">binary_op2</span><span class="p">)</span><span class="p">;</span>
</pre>
    <p>1 <em>Effects:</em> Computes its result by initializing the accumulator <code class="highlight"><span class="n">acc</span></code> with the initial value <code class="highlight"><span class="n">init</span></code> and then modifying it with <code class="highlight"><span class="n">acc</span> <span class="o">=</span> <span class="n">acc</span> <span class="o">+</span> <span class="p">(</span><span class="o">*</span><span class="n">i1</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="o">*</span><span class="n">i2</span><span class="p">)</span></code> or <code class="highlight"><span class="n">acc</span> <span class="o">=</span> <span class="n">binary_op1</span><span class="p">(</span><span class="n">acc</span><span class="p">,</span> <span class="n">binary_op2</span><span class="p">(</span><span class="o">*</span><span class="n">i1</span><span class="p">,</span> <span class="o">*</span><span class="n">i2</span><span class="p">)</span><span class="p">)</span></code> for every iterator <code class="highlight"><span class="n">i1</span></code> in the range <code class="highlight"><span class="p">[</span><span class="n">first1</span><span class="p">,</span> <span class="n">last1</span><span class="p">)</span></code> and iterator <code class="highlight"><span class="n">i2</span></code> in the range <code class="highlight"><span class="p">[</span><span class="n">first2</span><span class="p">,</span> <span class="n">first2</span> <span class="o">+</span> <span class="p">(</span><span class="n">last1</span> <span class="o">-</span> <span class="n">first1</span><span class="p">)</span><span class="p">)</span></code> in order.</p>
    <p>2 <em>Requires:</em> <code class="highlight"><span class="n">T</span></code> shall meet the requirements of <code class="highlight"><span class="n">CopyConstructible</span></code> (Table 22) and <code class="highlight"><span class="n">CopyAssignable</span></code> (Table 24) types. In the ranges <code class="highlight"><span class="p">[</span><span class="n">first1</span><span class="p">,</span> <span class="n">last1</span><span class="p">]</span></code> and <code class="highlight"><span class="p">[</span><span class="n">first2</span><span class="p">,</span> <span class="n">first2</span> <span class="o">+</span> <span class="p">(</span><span class="n">last1</span> <span class="o">-</span> <span class="n">first1</span><span class="p">)</span><span class="p">]</span></code> <code class="highlight"><span class="n">binary_op1</span></code> and <code class="highlight"><span class="n">binary_op2</span></code> shall neither modify elements nor invalidate iterators or subranges.</p>
   </blockquote>
   <blockquote>
     <strong>26.8.6 Partial sum</strong> [<strong>partial.sum</strong>] 
<pre class="highlight"><span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIterator</span><span class="p">,</span> <span class="k">class</span> <span class="nc">OutputIterator</span><span class="o">></span>
  <span class="n">OutputIterator</span> <span class="n">partial_sum</span><span class="p">(</span><span class="n">InputIterator</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIterator</span> <span class="n">last</span><span class="p">,</span>
                             <span class="n">OutputIterator</span> <span class="n">result</span><span class="p">)</span><span class="p">;</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIterator</span><span class="p">,</span> <span class="k">class</span> <span class="nc">OutputIterator</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">BinaryOperation</span><span class="o">></span>
  <span class="n">OutputIterator</span> <span class="n">partial_sum</span><span class="p">(</span><span class="n">InputIterator</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIterator</span> <span class="n">last</span><span class="p">,</span>
                             <span class="n">OutputIterator</span> <span class="n">result</span><span class="p">,</span>
                             <span class="n">BinaryOperation</span> <span class="n">binary_op</span><span class="p">)</span><span class="p">;</span>
</pre>
    <p>1 <em>Effects:</em> For a non-empty range, the function creates an accumulator <code class="highlight"><span class="n">acc</span></code> whose type is <code class="highlight"><span class="n">InputIterator</span></code>'s value type, initializes it with <code class="highlight"><span class="o">*</span><span class="n">first</span></code>, and assigns the result to <code class="highlight"><span class="o">*</span><span class="n">result</span></code>. For every iterator <code class="highlight"><span class="n">i</span></code> in <code class="highlight"><span class="p">[</span><span class="n">first</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">last</span><span class="p">)</span></code> in order, <code class="highlight"><span class="n">acc</span></code> is then modified by <code class="highlight"><span class="n">acc</span> <span class="o">=</span> <span class="n">acc</span> <span class="o">+</span> <span class="o">*</span><span class="n">i</span></code> or <code class="highlight"><span class="n">acc</span> <span class="o">=</span> <span class="n">binary_op</span><span class="p">(</span><span class="n">acc</span><span class="p">,</span> <span class="o">*</span><span class="n">i</span><span class="p">)</span></code> and the result is assigned to <code class="highlight"><span class="o">*</span><span class="p">(</span><span class="n">result</span> <span class="o">+</span> <span class="p">(</span><span class="n">i</span> <span class="o">-</span> <span class="n">first</span><span class="p">)</span><span class="p">)</span></code>.</p>
    <p>2 <em>Returns:</em> <code class="highlight"><span class="n">result</span> <span class="o">+</span> <span class="p">(</span><span class="n">last</span> <span class="o">-</span> <span class="n">first</span><span class="p">)</span></code>.</p>
    <p>3 <em>Complexity:</em> Exactly <code class="highlight"><span class="p">(</span><span class="n">last</span> <span class="o">-</span> <span class="n">first</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span></code> applications of the binary operation.</p>
    <p>4 <em>Requires:</em> <code class="highlight"><span class="n">InputIterator</span></code>'s value type shall be constructible from the type of <code class="highlight"><span class="o">*</span><span class="n">first</span></code>. The result of the expression <code class="highlight"><span class="n">acc</span> <span class="o">+</span> <span class="o">*</span><span class="n">i</span></code> or <code class="highlight"><span class="n">binary_op</span><span class="p">(</span><span class="n">acc</span><span class="p">,</span> <span class="o">*</span><span class="n">i</span><span class="p">)</span></code> shall be implicitly convertible to <code class="highlight"><span class="n">InputIterator</span></code>'s value type. <code class="highlight"><span class="n">acc</span></code> shall be writable (24.2.1) to the <code class="highlight"><span class="n">result</span></code> output iterator. In the ranges <code class="highlight"><span class="p">[</span><span class="n">first</span><span class="p">,</span> <span class="n">last</span><span class="p">]</span></code> and <code class="highlight"><span class="p">[</span><span class="n">result</span><span class="p">,</span> <span class="n">result</span> <span class="o">+</span> <span class="p">(</span><span class="n">last</span> <span class="o">-</span> <span class="n">first</span><span class="p">)</span><span class="p">]</span></code> <code class="highlight"><span class="n">binary_op</span></code> shall neither modify elements nor invalidate iterators or subranges.</p>
    <p>5 <em>Remarks:</em> <code class="highlight"><span class="n">result</span></code> may be equal to <code class="highlight"><span class="n">first</span></code>.</p>
   </blockquote>
   <p>This wording specifies that these algorithms perform the following operations:</p>
   <ul>
    <li data-md="">
     <p>Create an accumulator <code class="highlight"><span class="n">acc</span></code> which is initialized with <code class="highlight"><span class="n">init</span></code>.</p>
    <li data-md="">
     <p>For (the) iterator(s) in the range(s) <strong>in order</strong>, modify <code class="highlight"><span class="n">acc</span></code> by applying
an update operation which takes <code class="highlight"><span class="n">acc</span></code> and the dereferenced value(s) of the
iterator(s) as arguments.</p>
   </ul>
   <p>The ordering requirement is necessary to ensure that these algorithms are
well-defined for <strong>non-associative</strong> and/or <strong>non-commutative</strong> operations, such as
floating-point addition and multiplication (non-associative and commutative),
and subtraction (non-associative and non-commutative).</p>
   <p>Currently, the wording forces each iteration to depend on the prior iteration
to ensure the correct ordering of accumulation. This introduces a loop-carried
dependency that makes it impossible to parallelize.</p>
   <p>To parallelize <code class="highlight"><span class="n">accumulate</span></code> and <code class="highlight"><span class="n">inner_product</span></code> we need to be able to
re-order applications of the operations, partition the workload into sub-tasks
and then combine the results of the sub-tasks together using the operator.
This, however, would give a non-deterministic result for non-associative or
non-commutative operations.</p>
   <p>For <code class="highlight"><span class="n">partial_sum</span></code>, re-ordering is not possible due to the nature of the
algorithm. However, partitioning is possible. Thus, you get a non-deterministic
result for non-associative operations but it is fine for non-commutative
operations.</p>
   <p>To allow parallelization of <code class="highlight"><span class="n">accumulate</span></code> and <code class="highlight"><span class="n">partial_sum</span></code> without relaxing
the existing ordering, new algorithms with weaker ordering were introduced
instead of adding <code class="highlight"><span class="n">ExecutionPolicy</span></code> signatures of the existing ones: <code class="highlight"><span class="n">reduce</span></code> (a weaker <code class="highlight"><span class="n">accumulate</span></code>) and <code class="highlight"><span class="n">inclusive_scan</span></code> (a weaker <code class="highlight"><span class="n">partial_sum</span></code>).</p>
   <p>However, for <code class="highlight"><span class="n">inner_product</span></code>, no new algorithm with weaker ordering was
introduced and an <code class="highlight"><span class="n">ExecutionPolicy</span></code> signature <strong>was</strong> added instead. US 184
points out that this signature is not useful as it cannot be parallelized due
to the ordering constraints.</p>
   <h3 class="heading settled" data-level="1.2" id="ipistr"><span class="secno">1.2. </span><span class="content"><code class="highlight"><span class="n">inner_product</span></code> is a Form of <code class="highlight"><span class="n">transform_reduce</span></code></span><a class="self-link" href="#ipistr"></a></h3>
   <p>Just as <code class="highlight"><span class="n">reduce</span></code> is the parallelizable counterpart of <code class="highlight"><span class="n">accumulate</span></code> (same basic
operation but without a specific ordering), <code class="highlight"><span class="n">inner_product</span></code> has a natural
counter-part. Consider this possible implementation of <code class="highlight"><span class="n">inner_product</span></code>:</p>
<pre class="highlight"><span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIt1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">InputIt2</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">T</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">ReductionOperation</span><span class="p">,</span> <span class="k">class</span> <span class="nc">BinaryTransformOperation</span><span class="o">></span>
<span class="n">T</span> <span class="n">inner_product</span><span class="p">(</span><span class="n">InputIt1</span> <span class="n">first1</span><span class="p">,</span> <span class="n">InputIt1</span> <span class="n">last1</span><span class="p">,</span>
                <span class="n">InputIt2</span> <span class="n">first2</span><span class="p">,</span> <span class="n">T</span> <span class="n">init</span><span class="p">,</span>
                <span class="n">ReductionOperation</span> <span class="n">reduce_op</span><span class="p">,</span>
                <span class="n">BinaryTransformOperation</span> <span class="n">transform_op</span><span class="p">)</span>
<span class="p">{</span>
    <span class="k">while</span> <span class="p">(</span><span class="n">first1</span> <span class="o">!</span><span class="o">=</span> <span class="n">last1</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">init</span> <span class="o">=</span> <span class="n">reduce_op</span><span class="p">(</span><span class="n">init</span><span class="p">,</span> <span class="n">transform_op</span><span class="p">(</span><span class="o">*</span><span class="n">first1</span><span class="p">,</span> <span class="o">*</span><span class="n">first2</span><span class="p">)</span><span class="p">)</span><span class="p">;</span>
        <span class="o">+</span><span class="o">+</span><span class="n">first1</span><span class="p">;</span>
        <span class="o">+</span><span class="o">+</span><span class="n">first2</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="n">value</span><span class="p">;</span>
<span class="p">}</span>
</pre>
   <p>The application of <code class="highlight"><span class="n">transform_op</span></code> to the sequence is a binary <code class="highlight"><span class="n">transform</span></code>:</p>
<pre class="highlight"><span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIt1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">InputIt2</span><span class="p">,</span> 
          <span class="k">class</span> <span class="nc">OutputIt</span><span class="p">,</span> <span class="k">class</span> <span class="nc">BinaryTransformOperation</span><span class="o">></span>
<span class="n">OutputIt</span> <span class="n">transform</span><span class="p">(</span><span class="n">InputIt1</span> <span class="n">first1</span><span class="p">,</span> <span class="n">InputIt1</span> <span class="n">last1</span><span class="p">,</span> <span class="n">InputIt2</span> <span class="n">first2</span><span class="p">,</span> 
                   <span class="n">OutputIt</span> <span class="n">o_first</span><span class="p">,</span> <span class="n">BinaryTransformOperation</span> <span class="n">transform_op</span><span class="p">)</span>
<span class="p">{</span>
    <span class="k">while</span> <span class="p">(</span><span class="n">first1</span> <span class="o">!</span><span class="o">=</span> <span class="n">last1</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="o">*</span><span class="n">o_first</span><span class="o">+</span><span class="o">+</span> <span class="o">=</span> <span class="n">transform_op</span><span class="p">(</span><span class="o">*</span><span class="n">first1</span><span class="o">+</span><span class="o">+</span><span class="p">,</span> <span class="o">*</span><span class="n">first2</span><span class="o">+</span><span class="o">+</span><span class="p">)</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="n">o_first</span><span class="p">;</span>
<span class="p">}</span>
</pre>
   <p>And the application of <code class="highlight"><span class="n">reduce_op</span></code> accumulates the transformed values:</p>
<pre class="highlight"><span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIt</span><span class="p">,</span> <span class="k">class</span> <span class="nc">T</span><span class="p">,</span> <span class="k">class</span> <span class="nc">ReductionOperation</span><span class="o">></span>
<span class="n">T</span> <span class="n">accumulate</span><span class="p">(</span><span class="n">InputIt</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIt</span> <span class="n">last</span><span class="p">,</span> <span class="n">T</span> <span class="n">init</span><span class="p">,</span> 
             <span class="n">ReductionOperation</span> <span class="n">reduce_op</span><span class="p">)</span>
<span class="p">{</span>
    <span class="k">for</span> <span class="p">(</span><span class="p">;</span> <span class="n">first</span> <span class="o">!</span><span class="o">=</span> <span class="n">last</span><span class="p">;</span> <span class="o">+</span><span class="o">+</span><span class="n">first</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">init</span> <span class="o">=</span> <span class="n">reduce_op</span><span class="p">(</span><span class="n">init</span><span class="p">,</span> <span class="o">*</span><span class="n">first</span><span class="p">)</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="n">init</span><span class="p">;</span>
<span class="p">}</span>
</pre>
   <p>
    So, <code class="highlight"><span class="n">inner_product</span></code> is an 
    <strike><code class="highlight"><span class="n">accumulate</span></code>s</strike>
    <code class="highlight"><span class="n">reduce</span></code>s
of a <code class="highlight"><span class="n">transform</span></code>ed sequence. It’s a <code class="highlight"><span class="n">transform_reduce</span></code>!.
   </p>
   <h3 class="heading settled" data-level="1.3" id="trmiss"><span class="secno">1.3. </span><span class="content"><code class="highlight"><span class="n">transform_reduce</span></code> is Missing an Overload</span><a class="self-link" href="#trmiss"></a></h3>
   <p>However, <code class="highlight"><span class="n">transform_reduce</span></code> is missing an signature for a binary transform;
only signatures with unary transform operations are currently specified by the
C++17 CD. I call this missing signature <b>binary-binary <code class="highlight"><span class="n">transform_reduce</span></code></b>, since both the reduction and transformation
operation are binary operations.</p>
   <p>This signature, which is equivalent to parallel <code class="highlight"><span class="n">inner_product</span></code> with weaker
ordering, is very useful. Many of the typical examples of <code class="highlight"><span class="n">transform_reduce</span></code> usage that I’ve seen use tricks to perform a binary-binary <code class="highlight"><span class="n">transform_reduce</span></code> using the unary-binary <code class="highlight"><span class="n">transform_reduce</span></code> that is in the C++17 CD.</p>
   <p>The typical <code class="highlight"><span class="n">transform_reduce</span></code> dot product example (similar to what is
found in the original <code class="highlight"><span class="n">transform_reduce</span></code> proposal <a data-link-type="biblio" href="#biblio-n3960">[N3960]</a>) looks like this:</p>
<pre class="highlight"><span class="n">std</span><span class="o">:</span><span class="o">:</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">:</span><span class="o">:</span><span class="n">tuple</span><span class="o">&lt;</span><span class="kt">double</span><span class="p">,</span> <span class="kt">double</span><span class="o">></span> <span class="o">></span> <span class="n">XY</span> <span class="o">=</span> <span class="c1">// ...
</span>
<span class="kt">double</span> <span class="n">dot_product</span> <span class="o">=</span> <span class="n">std</span><span class="o">:</span><span class="o">:</span><span class="n">transform_reduce</span><span class="p">(</span>
    <span class="n">std</span><span class="o">:</span><span class="o">:</span><span class="n">par_unseq</span><span class="p">,</span>

    <span class="c1">// Input sequence.
</span>    <span class="n">XY</span><span class="p">.</span><span class="n">begin</span><span class="p">(</span><span class="p">)</span><span class="p">,</span> <span class="n">XY</span><span class="p">.</span><span class="n">end</span><span class="p">(</span><span class="p">)</span><span class="p">,</span>

    <span class="c1">// Unary transformation operation. 
</span>    <span class="p">[</span><span class="p">]</span><span class="p">(</span><span class="n">std</span><span class="o">:</span><span class="o">:</span><span class="n">tuple</span><span class="o">&lt;</span><span class="kt">double</span><span class="p">,</span> <span class="kt">double</span><span class="o">></span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">xy</span><span class="p">)</span>
    <span class="p">{</span>
      <span class="c1">// Array of struct means this is tricky to execute on vector hardware:
</span>      <span class="c1">//
</span>      <span class="c1">// memory layout: X[0] Y[0] X[1] Y[1] X[2] Y[2] X[3] Y[3] ...
</span>      <span class="c1">//
</span>      <span class="c1">// op #0: load a pack of Xs (they aren’t contiguous; the load will be
</span>      <span class="c1">//                           strided, may need to access multiple
</span>      <span class="c1">//                           cache lines and may be harder for the
</span>      <span class="c1">//                           hardware prefetcher to handle)
</span>      <span class="c1">// op #1: load a pack of Ys (same as above)
</span>      <span class="c1">// op #2: multiply the pack of Xs by vector of Ys
</span>      <span class="k">return</span> <span class="n">std</span><span class="o">:</span><span class="o">:</span><span class="n">get</span><span class="o">&lt;</span><span class="mi">0</span><span class="o">></span><span class="p">(</span><span class="n">xy</span><span class="p">)</span> <span class="o">*</span> <span class="n">std</span><span class="o">:</span><span class="o">:</span><span class="n">get</span><span class="p">(</span><span class="n">xy</span><span class="p">)</span><span class="p">;</span>
    <span class="p">}</span><span class="p">,</span>

    <span class="kt">double</span><span class="p">(</span><span class="mf">0.0</span><span class="p">)</span><span class="p">,</span> <span class="c1">// Initial value for reduction.
</span>
    <span class="c1">// Binary reduction operation.
</span>    <span class="n">std</span><span class="o">:</span><span class="o">:</span><span class="n">plus</span><span class="o">&lt;</span><span class="kt">double</span><span class="o">></span><span class="p">(</span><span class="p">)</span>
  <span class="p">)</span><span class="p">;</span>
</pre>
   <p>Note that this is array-of-structs NOT struct-of-arrays. The HPX and THRUST dot
product examples use iterator tricks (zip iterators or counting iterators) to
switch to a struct-of-arrays scheme. The zip iterator trick is shown below,
using Boost:</p>
<pre class="highlight"><span class="n">std</span><span class="o">:</span><span class="o">:</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">double</span><span class="o">></span> <span class="n">X</span> <span class="o">=</span> <span class="c1">// ...
</span><span class="n">std</span><span class="o">:</span><span class="o">:</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">double</span><span class="o">></span> <span class="n">Y</span> <span class="o">=</span> <span class="c1">// ...
</span>
<span class="kt">double</span> <span class="n">dot_product</span> <span class="o">=</span> <span class="n">std</span><span class="o">:</span><span class="o">:</span><span class="n">transform_reduce</span><span class="p">(</span>
    <span class="n">std</span><span class="o">:</span><span class="o">:</span><span class="n">par_unseq</span><span class="p">,</span>

    <span class="c1">// Input sequence.
</span>    <span class="n">boost</span><span class="o">:</span><span class="o">:</span><span class="n">make_zip_iterator</span><span class="p">(</span><span class="n">X</span><span class="p">.</span><span class="n">begin</span><span class="p">(</span><span class="p">)</span><span class="p">,</span> <span class="n">Y</span><span class="p">.</span><span class="n">begin</span><span class="p">(</span><span class="p">)</span><span class="p">)</span><span class="p">,</span>
    <span class="n">boost</span><span class="o">:</span><span class="o">:</span><span class="n">make_zip_iterator</span><span class="p">(</span><span class="n">X</span><span class="p">.</span><span class="n">end</span><span class="p">(</span><span class="p">)</span><span class="p">,</span> <span class="n">Y</span><span class="p">.</span><span class="n">end</span><span class="p">(</span><span class="p">)</span><span class="p">)</span><span class="p">,</span>

    <span class="c1">// Unary transformation operation.
</span>    <span class="p">[</span><span class="p">]</span><span class="p">(</span><span class="k">auto</span><span class="o">&amp;</span><span class="o">&amp;</span> <span class="n">xy</span><span class="p">)</span> <span class="c1">// std::tuple&lt;double, double>-esque
</span>    <span class="p">{</span>
        <span class="c1">// Struct of arrays means this is easier to execute on vector hardware:
</span>        <span class="c1">//
</span>        <span class="c1">// memory layout: X[0] X[1] X[2] X[3] ... Y[0] Y[1] Y[2] Y[3] ...
</span>        <span class="c1">//
</span>        <span class="c1">// op #0: load a pack of Xs (elements are contiguous, load will access
</span>        <span class="c1">//                           only one cache line and the hardware
</span>        <span class="c1">//                           prefetcher will easily track the memory
</span>        <span class="c1">//                           stream)
</span>        <span class="c1">// op #1: load a pack of Ys (same as above)
</span>        <span class="c1">// op #2: multiply the pack of Xs by the pack of Ys
</span>        <span class="k">return</span> <span class="n">std</span><span class="o">:</span><span class="o">:</span><span class="n">get</span><span class="o">&lt;</span><span class="mi">0</span><span class="o">></span><span class="p">(</span><span class="n">xy</span><span class="p">)</span> <span class="o">*</span> <span class="n">std</span><span class="o">:</span><span class="o">:</span><span class="n">get</span><span class="o">&lt;</span><span class="mi">1</span><span class="o">></span><span class="p">(</span><span class="n">xy</span><span class="p">)</span><span class="p">;</span>
    <span class="p">}</span><span class="p">,</span>

    <span class="kt">double</span><span class="p">(</span><span class="mf">0.0</span><span class="p">)</span><span class="p">,</span> <span class="c1">// Initial value for reduction.
</span>
    <span class="c1">// Binary reduction operation.
</span>    <span class="n">std</span><span class="o">:</span><span class="o">:</span><span class="n">plus</span><span class="o">&lt;</span><span class="kt">double</span><span class="o">></span><span class="p">(</span><span class="p">)</span>
<span class="p">)</span><span class="p">;</span>
</pre>
   <p>More examples of this pattern can be found in HPX
(<a href="https://github.com/STEllAR-GROUP/hpx/blob/master/examples/quickstart/vector_zip_dotproduct.cpp">zip iterator example</a> and <a href="https://github.com/STEllAR-GROUP/hpx/blob/master/examples/quickstart/vector_counting_dotproduct.cpp">counting iterator example</a>)
and THRUST
(<a href="https://github.com/thrust/thrust/blob/master/examples/dot_products_with_zip.cu">zip iterator example</a>).</p>
   <h3 class="heading settled" data-level="1.4" id="trparam"><span class="secno">1.4. </span><span class="content"><code class="highlight"><span class="n">transform_reduce</span></code> Parameter Order is Odd</span><a class="self-link" href="#trparam"></a></h3>
   <p>The missing binary-binary <code class="highlight"><span class="n">transform_reduce</span></code> would look like this:</p>
<pre class="highlight"><span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIt1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">InputIt2</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">BinaryTransformOperation</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">T</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">ReductionOperation</span><span class="o">></span> <span class="c1">// Always binary.
</span><span class="n">T</span> <span class="n">transform_reduce</span><span class="p">(</span><span class="n">InputIt1</span> <span class="n">first1</span><span class="p">,</span> <span class="n">InputIt1</span> <span class="n">last1</span><span class="p">,</span>
                   <span class="n">InputIt2</span> <span class="n">first2</span><span class="p">,</span>
                   <span class="n">BinaryTransformOperation</span> <span class="n">transform_op</span><span class="p">,</span>
                   <span class="n">T</span> <span class="n">init</span><span class="p">,</span>
                   <span class="n">ReductionOperation</span> <span class="n">reduce_op</span><span class="p">)</span><span class="p">;</span>
</pre>
   <p>Note that the order of parameters, which is consistent with the other <code class="highlight"><span class="n">transform_reduce</span></code> signatures, is inconsistent with <code class="highlight"><span class="n">inner_product</span></code>, <code class="highlight"><span class="n">transform</span></code> and <code class="highlight"><span class="n">accumulate</span></code>:</p>
<pre class="highlight"><span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIt1</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">UnaryTransformOperation</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">T</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">ReductionOperation</span><span class="o">></span> <span class="c1">// Always binary.
</span><span class="n">T</span> <span class="n">transform_reduce</span><span class="p">(</span><span class="n">InputIt1</span> <span class="n">first1</span><span class="p">,</span> <span class="n">InputIt1</span> <span class="n">last1</span><span class="p">,</span>
                   <span class="n">UnaryTransformOperation</span> <span class="n">transform_op</span><span class="p">,</span>
                   <span class="n">T</span> <span class="n">init</span><span class="p">,</span>
                   <span class="n">ReductionOperation</span> <span class="n">reduce_op</span><span class="p">)</span><span class="p">;</span>

<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIt1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">InputIt2</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">T</span><span class="o">></span>
<span class="n">T</span> <span class="n">inner_product</span><span class="p">(</span><span class="n">InputIt1</span> <span class="n">first1</span><span class="p">,</span> <span class="n">InputIt1</span> <span class="n">last1</span><span class="p">,</span> <span class="n">InputIt2</span> <span class="n">first2</span><span class="p">,</span>
                <span class="n">T</span> <span class="n">init</span><span class="p">)</span><span class="p">;</span>

<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIt1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">InputIt2</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">T</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">ReductionOperation</span><span class="p">,</span> <span class="c1">// Always binary.
</span>          <span class="k">class</span> <span class="nc">BinaryTransformOperation</span><span class="o">></span> 
<span class="n">T</span> <span class="n">inner_product</span><span class="p">(</span><span class="n">InputIt1</span> <span class="n">first1</span><span class="p">,</span> <span class="n">InputIt1</span> <span class="n">last1</span><span class="p">,</span> <span class="n">InputIt2</span> <span class="n">first2</span><span class="p">,</span>
                <span class="n">T</span> <span class="n">init</span><span class="p">,</span>
                <span class="n">ReductionOperation</span> <span class="n">reduce_op</span><span class="p">,</span>
                <span class="n">BinaryTransformOperation</span> <span class="n">transform_op</span><span class="p">)</span><span class="p">;</span>


<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIt1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">InputIt2</span><span class="p">,</span> <span class="k">class</span> <span class="nc">OutputIt</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">BinaryTransformOperation</span><span class="o">></span>
<span class="n">OutputIt</span> <span class="n">transform</span><span class="p">(</span><span class="n">InputIt1</span> <span class="n">first1</span><span class="p">,</span> <span class="n">InputIt1</span> <span class="n">last1</span><span class="p">,</span> <span class="n">InputIt2</span> <span class="n">first2</span><span class="p">,</span>
                   <span class="n">OutputIt</span> <span class="n">o_first</span><span class="p">,</span>
                   <span class="n">BinaryTransformOperation</span> <span class="n">transform_op</span><span class="p">)</span><span class="p">;</span>

<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIt1</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">T</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">ReductionOperation</span><span class="o">></span>
<span class="n">T</span> <span class="n">accumulate</span><span class="p">(</span><span class="n">InputIt1</span> <span class="n">first1</span><span class="p">,</span> <span class="n">InputIt1</span> <span class="n">last1</span><span class="p">,</span>
             <span class="n">T</span> <span class="n">init</span><span class="p">,</span>
             <span class="n">ReductionOperation</span> <span class="n">reduce_op</span><span class="p">)</span><span class="p">;</span>
</pre>
   <p>The inconsistencies are:</p>
   <ul>
    <li data-md="">
     <p>In <code class="highlight"><span class="n">inner_product</span></code>, <code class="highlight"><span class="n">accumulate</span></code> and <code class="highlight"><span class="n">reduce</span></code> (which is not
shown but has the same interface as <code class="highlight"><span class="n">accumulate</span></code>), the <code class="highlight"><span class="n">init</span></code> parameter comes after the iterator parameters and before the
operation parameters. In <code class="highlight"><span class="n">transform_reduce</span></code>, it is in between the
transformation operation parameter and the reduction operation parameter.</p>
    <li data-md="">
     <p>In <code class="highlight"><span class="n">inner_product</span></code>, the reduction operation parameter comes before the
transformation operation parameter. In <code class="highlight"><span class="n">transform_reduce</span></code>, the reduction
operation parameter comes before the transformation operation parameter.</p>
   </ul>
   <h3 class="heading settled" data-level="1.5" id="scanparam"><span class="secno">1.5. </span><span class="content"><code class="highlight"><span class="n">transform_inclusive_scan</span></code> and <code class="highlight"><span class="n">transform_exclusive_scan</span></code> Parameter Order is Odd</span><a class="self-link" href="#scanparam"></a></h3>
   <p>Like <code class="highlight"><span class="n">transform_reduce</span></code>, the new <code class="highlight"><span class="n">transform_inclusive_scan</span></code> and <code class="highlight"><span class="n">transform_exclusive_scan</span></code> algorithms have parameter orders that are
inconsistent with existing algorithms that they are closely related to, like <code class="highlight"><span class="n">accumulate</span></code>, <code class="highlight"><span class="n">partial_sum</span></code> and <code class="highlight"><span class="n">inner_product</span></code>. The specific issues:</p>
   <ul>
    <li data-md="">
     <p>In <code class="highlight"><span class="n">exclusive_scan</span></code>, the <code class="highlight"><span class="n">init</span></code> parameter comes after the
iterator parameters and before the operation parameters. In <code class="highlight"><span class="n">transform_exclusive_scan</span></code>, the <code class="highlight"><span class="n">init</span></code> parameter is after the
transformation operation parameter and the reduction operation parameter.</p>
    <li data-md="">
     <p>In <code class="highlight"><span class="n">inclusive_scan</span></code>, the reduction operation parameter comes before the
transformation operation parameter. In <code class="highlight"><span class="n">transform_inclusive_scan</span></code> and <code class="highlight"><span class="n">transform_exclusive_scan</span></code>, the reduction operation parameter comes before
the transformation operation parameter.</p>
   </ul>
   <h2 class="heading settled" data-level="2" id="reso"><span class="secno">2. </span><span class="content">Proposed Resolution</span><a class="self-link" href="#reso"></a></h2>
   <p>The following changes would resolve the issues with the <code class="highlight"><span class="o">&lt;</span><span class="n">numeric</span><span class="o">></span></code> raised by US 161 and US 184:</p>
   <ul>
    <li data-md="">
     <p>Remove the <code class="highlight"><span class="n">ExecutionPolicy</span></code> signature for <code class="highlight"><span class="n">inner_product</span></code>.</p>
    <li data-md="">
     <p>Add binary-binary <code class="highlight"><span class="n">transform_reduce</span></code> signatures (four signatures: with and
without <code class="highlight"><span class="n">ExecutionPolicy</span></code> parameters, and with and without defaulted
operations).</p>
    <li data-md="">
     <p>Change the parameter order for all <code class="highlight"><span class="n">transform_reduce</span></code> signatures so that:</p>
     <ul>
      <li data-md="">
       <p>The initial value parameter comes after the iterator parameters and before
the operation parameters.</p>
      <li data-md="">
       <p>The reduction operation parameter comes before the transformation
operation parameters.</p>
     </ul>
    <li data-md="">
     <p>Change the parameter order for <code class="highlight"><span class="n">transform_</span><span class="o">*</span><span class="n">_scan</span></code> signatures so
that:</p>
     <ul>
      <li data-md="">
       <p>For <code class="highlight"><span class="n">transform_exclusive_scan</span></code>, the initial value parameter comes after
the iterator parameters and before the operation parameters.</p>
      <li data-md="">
       <p>For <code class="highlight"><span class="n">transform_inclusive_scan</span></code> and <code class="highlight"><span class="n">transform_exclusive_scan</span></code>, the
reduction operation parameter comes before the transformation
operation parameters.</p>
     </ul>
   </ul>
   <p>With these changes, a parallel dot product over struct-of-arrays data can be
written as:</p>
<pre class="highlight"><span class="n">std</span><span class="o">:</span><span class="o">:</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">double</span><span class="o">></span> <span class="n">X</span> <span class="o">=</span> <span class="c1">// ...
</span><span class="n">std</span><span class="o">:</span><span class="o">:</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">double</span><span class="o">></span> <span class="n">Y</span> <span class="o">=</span> <span class="c1">// ...
</span>
<span class="kt">double</span> <span class="n">dot_product</span> <span class="o">=</span>
    <span class="n">std</span><span class="o">:</span><span class="o">:</span><span class="n">transform_reduce</span><span class="p">(</span><span class="n">std</span><span class="o">:</span><span class="o">:</span><span class="n">par_unseq</span><span class="p">,</span> <span class="n">x</span><span class="p">.</span><span class="n">begin</span><span class="p">(</span><span class="p">)</span><span class="p">,</span> <span class="n">x</span><span class="p">.</span><span class="n">end</span><span class="p">(</span><span class="p">)</span><span class="p">,</span> <span class="n">y</span><span class="p">.</span><span class="n">begin</span><span class="p">(</span><span class="p">)</span><span class="p">,</span> <span class="kt">double</span><span class="p">(</span><span class="mf">0.0</span><span class="p">)</span><span class="p">)</span><span class="p">;</span>
</pre>
   <p>A parallel word count could be written with binary-binary <code class="highlight"><span class="n">transform_reduce</span></code> as:</p>
<pre class="highlight"><span class="kt">bool</span> <span class="nf">is_word_beginning</span><span class="p">(</span><span class="kt">char</span> <span class="n">left</span><span class="p">,</span> <span class="kt">char</span> <span class="n">right</span><span class="p">)</span>
<span class="p">{</span>
    <span class="k">return</span> <span class="n">std</span><span class="o">:</span><span class="o">:</span><span class="n">isspace</span><span class="p">(</span><span class="n">left</span><span class="p">)</span> <span class="o">&amp;</span><span class="o">&amp;</span> <span class="o">!</span><span class="n">std</span><span class="o">:</span><span class="o">:</span><span class="n">isspace</span><span class="p">(</span><span class="n">right</span><span class="p">)</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">std</span><span class="o">:</span><span class="o">:</span><span class="kt">size_t</span> <span class="n">word_count</span><span class="p">(</span><span class="n">std</span><span class="o">:</span><span class="o">:</span><span class="n">string_view</span> <span class="n">s</span><span class="p">)</span>
<span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">s</span><span class="p">.</span><span class="n">empty</span><span class="p">(</span><span class="p">)</span><span class="p">)</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>

    <span class="c1">// Count the number of characters that start a new word.
</span>    <span class="k">return</span> <span class="n">std</span><span class="o">:</span><span class="o">:</span><span class="n">transform_reduce</span><span class="p">(</span>
        <span class="n">std</span><span class="o">:</span><span class="o">:</span><span class="n">par_unseq</span><span class="p">,</span>
    
        <span class="c1">// "Left" input sequence:  s[0], s[1], ..., s[s.size() - 2]
</span>        <span class="n">s</span><span class="p">.</span><span class="n">begin</span><span class="p">(</span><span class="p">)</span><span class="p">,</span> <span class="n">s</span><span class="p">.</span><span class="n">end</span><span class="p">(</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span>
        <span class="c1">// "Right" input sequence: s[1], s[2], ..., s[s.size() - 1]
</span>        <span class="n">s</span><span class="p">.</span><span class="n">begin</span><span class="p">(</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span>

        <span class="c1">// Initial value for reduction: if the first character
</span>        <span class="c1">// is not a space, then it’s the beginning of a word.
</span>        <span class="n">std</span><span class="o">:</span><span class="o">:</span><span class="kt">size_t</span><span class="p">(</span><span class="o">!</span><span class="n">std</span><span class="o">:</span><span class="o">:</span><span class="n">isspace</span><span class="p">(</span><span class="n">s</span><span class="p">.</span><span class="n">front</span><span class="p">(</span><span class="p">)</span><span class="p">)</span> <span class="o">?</span> <span class="mi">1</span> <span class="o">:</span> <span class="mi">0</span><span class="p">)</span><span class="p">,</span>

        <span class="c1">// Binary transformation operation.
</span>        <span class="n">std</span><span class="o">:</span><span class="o">:</span><span class="n">plus</span><span class="o">&lt;</span><span class="n">std</span><span class="o">:</span><span class="o">:</span><span class="kt">size_t</span><span class="o">></span><span class="p">(</span><span class="p">)</span><span class="p">,</span>

        <span class="c1">// Binary transformation operation: Return 1 when we hit
</span>        <span class="c1">// a new word.
</span>        <span class="n">is_word_beginning</span>
    <span class="p">)</span><span class="p">;</span>
<span class="p">}</span>
</pre>
   <h2 class="heading settled" data-level="3" id="faq"><span class="secno">3. </span><span class="content">FAQ</span><a class="self-link" href="#faq"></a></h2>
   <p><b>Q: Why does this need to be fixed now?</b></p>
   <ul>
    <li data-md="">
     <p><code class="highlight"><span class="n">inner_product</span></code> currently has ordering guarantees which prevent
parallelization. If we fix them in the future, it will have to be a
breaking change.</p>
    <li data-md="">
     <p>The order of parameters in some of the new algorithms from the Parallelism TS
v1 is inconsistent. If we fix them in the future, it will have to be a
breaking change.</p>
   </ul>
   <p><b>Q: The initial value parameter comes before the operation parameters in <code class="highlight"><span class="n">exclusive_scan</span></code>, but after the operation parameters in <code class="highlight"><span class="n">inclusive_scan</span></code>. Isn’t this also inconsistent?</b></p>
   <p>Initially, I thought this was inconsistent. However, I’ve since learned from
LWG that this was done intentionally. The goal is to keep parameters fixed
relative to the other signatures for that algorithm. For example, since <code class="highlight"><span class="n">inclusive_scan</span></code> does not require an initial value parameter, it would be odd
to change from:</p>
<pre class="highlight"><span class="n">OutputIt</span> <span class="nf">inclusive_scan</span><span class="p">(</span><span class="n">InputIt</span><span class="p">,</span> <span class="n">InputIt</span><span class="p">,</span> <span class="n">OutputIt</span><span class="p">)</span><span class="p">;</span>
<span class="n">OutputIt</span> <span class="nf">inclusive_scan</span><span class="p">(</span><span class="n">InputIt</span><span class="p">,</span> <span class="n">InputIt</span><span class="p">,</span> <span class="n">OutputIt</span><span class="p">,</span> <span class="n">BinaryOperation</span><span class="p">)</span><span class="p">;</span>
<span class="n">OutputIt</span> <span class="nf">inclusive_scan</span><span class="p">(</span><span class="n">InputIt</span><span class="p">,</span> <span class="n">InputIt</span><span class="p">,</span> <span class="n">OutputIt</span><span class="p">,</span> <span class="n">BinaryOperation</span><span class="p">,</span> <span class="n">T</span> <span class="n">init</span><span class="p">)</span><span class="p">;</span>
</pre>
   <p>to this:</p>
<pre class="highlight"><span class="n">OutputIt</span> <span class="nf">inclusive_scan</span><span class="p">(</span><span class="n">InputIt</span><span class="p">,</span> <span class="n">InputIt</span><span class="p">,</span> <span class="n">OutputIt</span><span class="p">)</span><span class="p">;</span>
<span class="n">OutputIt</span> <span class="nf">inclusive_scan</span><span class="p">(</span><span class="n">InputIt</span><span class="p">,</span> <span class="n">InputIt</span><span class="p">,</span> <span class="n">OutputIt</span><span class="p">,</span> <span class="n">BinaryOperation</span><span class="p">)</span><span class="p">;</span>
<span class="n">OutputIt</span> <span class="nf">inclusive_scan</span><span class="p">(</span><span class="n">InputIt</span><span class="p">,</span> <span class="n">InputIt</span><span class="p">,</span> <span class="n">OutputIt</span><span class="p">,</span> <span class="n">T</span> <span class="n">init</span><span class="p">,</span> <span class="n">BinaryOperation</span><span class="p">)</span><span class="p">;</span>
</pre>
   <p>because it makes the order of <code class="highlight"><span class="n">BinaryOperation</span></code> inconsistent.</p>
   <p><b>Q: Why does this paper not address the parallel signature of <code class="highlight"><span class="n">adjacent_difference</span></code>?</b></p>
   <p><code class="highlight"><span class="n">adjacent_difference</span></code> uses accumulator style wording and lives in
&lt;numeric>, but it is not truly an accumulation, and has none of the
associativity and commutativity concerns of the other &lt;numeric>
algorithms. SG1 preferred to follow the approach taken with <code class="highlight"><span class="n">for_each</span></code> and
relax the ordering requirement for the parallel signature of <code class="highlight"><span class="n">adjacent_difference</span></code> instead of adding a new algorithm with weaker guarantees. <a data-link-type="biblio" href="#biblio-p0574r1">[P0574r1]</a> contains the necessary changes for <code class="highlight"><span class="n">adjacent_difference</span></code>.</p>
   <h2 class="heading settled" data-level="4" id="wording"><span class="secno">4. </span><span class="content">Wording</span><a class="self-link" href="#wording"></a></h2>
   <p>The following changes are relative to the latest working paper as of 03-02-2017
(<a data-link-type="biblio" href="#biblio-n4640">[N4640]</a>) with the changes from <a data-link-type="biblio" href="#biblio-p0467r2">[P0467r2]</a> applied.</p>
   <p>The � character is used to denote a placeholder section number which the editor
shall choose.</p>
   <h3 class="heading settled" data-level="4.1" id="tripwording"><span class="secno">4.1. </span><span class="content">Wording for <code class="highlight"><span class="n">transform_reduce</span></code>/<code class="highlight"><span class="n">inner_product</span></code></span><a class="self-link" href="#tripwording"></a></h3>
   <p>Apply the following changes to the declarations of <code class="highlight"><span class="n">transform_reduce</span></code> in the <code class="highlight"><span class="o">&lt;</span><span class="n">numeric</span><span class="o">></span></code> header synopsis in 26.8.1 [<strong>numerics.ops.overview</strong>]:</p>
   <blockquote>
<pre class="highlight"><ins><span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIterator1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">InputIterator2</span><span class="p">,</span></ins>
<ins>          <span class="k">class</span> <span class="nc">T</span><span class="o">></span></ins>
<ins>  <span class="n">T</span> <span class="n">transform_reduce</span><span class="p">(</span><span class="n">InputIterator1</span> <span class="n">first1</span><span class="p">,</span> <span class="n">InputIterator1</span> <span class="n">last1</span><span class="p">,</span></ins>
<ins>                     <span class="n">InputIterator2</span> <span class="n">first2</span><span class="p">,</span></ins>
<ins>                     <span class="n">T</span> <span class="n">init</span><span class="p">)</span><span class="p">;</span></ins>
<ins><span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIterator1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">InputIterator2</span><span class="p">,</span></ins>
<ins>          <span class="k">class</span> <span class="nc">T</span><span class="p">,</span></ins>
<ins>          <span class="k">class</span> <span class="nc">BinaryOperation1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">BinaryOperation2</span><span class="o">></span></ins>
<ins>  <span class="n">T</span> <span class="n">transform_reduce</span><span class="p">(</span><span class="n">InputIterator1</span> <span class="n">first1</span><span class="p">,</span> <span class="n">InputIterator1</span> <span class="n">last1</span><span class="p">,</span></ins>
<ins>                     <span class="n">InputIterator2</span> <span class="n">first2</span><span class="p">,</span></ins>
<ins>                     <span class="n">T</span> <span class="n">init</span><span class="p">,</span></ins>
<ins>                     <span class="n">BinaryOperation1</span> <span class="n">binary_op1</span><span class="p">,</span></ins>
<ins>                     <span class="n">BinaryOperation2</span> <span class="n">binary_op2</span><span class="p">)</span><span class="p">;</span></ins>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIterator</span><span class="p">,</span>
          <del><span class="k">class</span> <span class="nc">UnaryOperation</span><span class="p">,</span></del>
          <span class="k">class</span> <span class="nc">T</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">BinaryOperation</span><ins><span class="p">,</span> <span class="k">class</span> <span class="nc">UnaryOperation</span></ins><span class="o">></span>
  <span class="n">T</span> <span class="n">transform_reduce</span><span class="p">(</span><span class="n">InputIterator</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIterator</span> <span class="n">last</span><span class="p">,</span>
                     <del><span class="n">UnaryOperation</span> <span class="n">unary_op</span><span class="p">,</span></del>
                     <span class="n">T</span> <span class="n">init</span><span class="p">,</span>
                     <span class="n">BinaryOperation</span> <span class="n">binary_op</span><ins><span class="p">,</span> <span class="n">UnaryOperation</span> <span class="n">unary_op</span></ins><span class="p">)</span><span class="p">;</span>
<ins><span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">ExecutionPolicy</span><span class="p">,</span> <span class="k">class</span> <span class="nc">ForwardIterator1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">ForwardIterator2</span><span class="p">,</span></ins>
<ins>          <span class="k">class</span> <span class="nc">T</span><span class="o">></span></ins>
<ins>  <span class="n">T</span> <span class="n">transform_reduce</span><span class="p">(</span><span class="n">ExecutionPolicy</span><span class="o">&amp;</span><span class="o">&amp;</span> <span class="n">exec</span><span class="p">,</span> <span class="c1">// see 25.2.5</span></ins><span class="c1">
</span><ins>                     <span class="n">ForwardIterator1</span> <span class="n">first1</span><span class="p">,</span> <span class="n">ForwardIterator1</span> <span class="n">last1</span><span class="p">,</span></ins>
<ins>                     <span class="n">ForwardIterator2</span> <span class="n">first2</span><span class="p">,</span></ins>
<ins>                     <span class="n">T</span> <span class="n">init</span><span class="p">)</span><span class="p">;</span></ins>
<ins><span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">ExecutionPolicy</span><span class="p">,</span> <span class="k">class</span> <span class="nc">ForwardIterator1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">ForwardIterator2</span><span class="p">,</span></ins>
<ins>          <span class="k">class</span> <span class="nc">T</span><span class="p">,</span></ins>
<ins>          <span class="k">class</span> <span class="nc">BinaryOperation1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">BinaryOperation2</span><span class="o">></span></ins>
<ins>  <span class="n">T</span> <span class="n">transform_reduce</span><span class="p">(</span><span class="n">ExecutionPolicy</span><span class="o">&amp;</span><span class="o">&amp;</span> <span class="n">exec</span><span class="p">,</span> <span class="c1">// see 25.2.5</span></ins><span class="c1">
</span><ins>                     <span class="n">ForwardIterator1</span> <span class="n">first1</span><span class="p">,</span> <span class="n">ForwardIterator1</span> <span class="n">last1</span><span class="p">,</span></ins>
<ins>                     <span class="n">ForwardIterator2</span> <span class="n">first2</span><span class="p">,</span></ins>
<ins>                     <span class="n">T</span> <span class="n">init</span><span class="p">,</span></ins>
<ins>                     <span class="n">BinaryOperation1</span> <span class="n">binary_op1</span><span class="p">,</span></ins>
<ins>                     <span class="n">BinaryOperation2</span> <span class="n">binary_op2</span><span class="p">)</span><span class="p">;</span></ins>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">ExecutionPolicy</span><span class="p">,</span> <span class="k">class</span> <span class="nc">ForwardIterator</span><span class="p">,</span>
          <del><span class="k">class</span> <span class="nc">UnaryOperation</span><span class="p">,</span></del>
          <span class="k">class</span> <span class="nc">T</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">BinaryOperation</span><ins><span class="p">,</span> <span class="k">class</span> <span class="nc">UnaryOperation</span></ins><span class="o">></span>
  <span class="n">T</span> <span class="n">transform_reduce</span><span class="p">(</span><span class="n">ExecutionPolicy</span><span class="o">&amp;</span><span class="o">&amp;</span> <span class="n">exec</span><span class="p">,</span> <span class="c1">// see 25.2.5
</span>                     <span class="n">ForwardIterator</span> <span class="n">first</span><span class="p">,</span> <span class="n">ForwardIterator</span> <span class="n">last</span><span class="p">,</span>
                     <del><span class="n">UnaryOperation</span> <span class="n">unary_op</span><span class="p">,</span></del>
                     <span class="n">T</span> <span class="n">init</span><span class="p">,</span>
                     <span class="n">BinaryOperation</span> <span class="n">binary_op</span><ins><span class="p">,</span> <span class="n">UnaryOperation</span> <span class="n">unary_op</span></ins><span class="p">)</span><span class="p">;</span>

<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIterator1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">InputIterator2</span><span class="p">,</span> <span class="k">class</span> <span class="nc">T</span><span class="o">></span>
  <span class="n">T</span> <span class="n">inner_product</span><span class="p">(</span><span class="n">InputIterator1</span> <span class="n">first1</span><span class="p">,</span> <span class="n">InputIterator1</span> <span class="n">last1</span><span class="p">,</span>
                  <span class="n">InputIterator2</span> <span class="n">first2</span><span class="p">,</span> <span class="n">T</span> <span class="n">init</span><span class="p">)</span><span class="p">;</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIterator1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">InputIterator2</span><span class="p">,</span> <span class="k">class</span> <span class="nc">T</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">BinaryOperation1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">BinaryOperation2</span><span class="o">></span>
  <span class="n">T</span> <span class="n">inner_product</span><span class="p">(</span><span class="n">InputIterator1</span> <span class="n">first1</span><span class="p">,</span> <span class="n">InputIterator1</span> <span class="n">last1</span><span class="p">,</span>
                  <span class="n">InputIterator2</span> <span class="n">first2</span><span class="p">,</span> <span class="n">T</span> <span class="n">init</span><span class="p">,</span>
                  <span class="n">BinaryOperation1</span> <span class="n">binary_op1</span><span class="p">,</span>
                  <span class="n">BinaryOperation2</span> <span class="n">binary_op2</span><span class="p">)</span><span class="p">;</span>
<del><span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">ExecutionPolicy</span><span class="p">,</span> <span class="k">class</span> <span class="nc">ForwardIterator1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">ForwardIterator2</span><span class="p">,</span></del>
<del>          <span class="k">class</span> <span class="nc">T</span><span class="o">></span></del>
<del>  <span class="n">T</span> <span class="n">inner_product</span><span class="p">(</span><span class="n">ExecutionPolicy</span><span class="o">&amp;</span><span class="o">&amp;</span> <span class="n">exec</span><span class="p">,</span> <span class="c1">// see 25.2.5</span></del><span class="c1">
</span><del>                  <span class="n">ForwardIterator1</span> <span class="n">first1</span><span class="p">,</span> <span class="n">ForwardIterator1</span> <span class="n">last1</span><span class="p">,</span></del>
<del>                  <span class="n">ForwardIterator2</span> <span class="n">first2</span><span class="p">,</span> <span class="n">T</span> <span class="n">init</span><span class="p">)</span><span class="p">;</span></del>
<del><span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">ExecutionPolicy</span><span class="p">,</span> <span class="k">class</span> <span class="nc">ForwardIterator1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">ForwardIterator2</span><span class="p">,</span></del>
<del>          <span class="k">class</span> <span class="nc">T</span><span class="p">,</span> <span class="k">class</span> <span class="nc">BinaryOperation1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">BinaryOperation2</span><span class="o">></span></del>
<del>  <span class="n">T</span> <span class="n">inner_product</span><span class="p">(</span><span class="n">ExecutionPolicy</span><span class="o">&amp;</span><span class="o">&amp;</span> <span class="n">exec</span><span class="p">,</span> <span class="c1">// see 25.2.5</span></del><span class="c1">
</span><del>                  <span class="n">ForwardIterator1</span> <span class="n">first1</span><span class="p">,</span> <span class="n">ForwardIterator1</span> <span class="n">last1</span><span class="p">,</span></del>
<del>                  <span class="n">ForwardIterator2</span> <span class="n">first2</span><span class="p">,</span> <span class="n">T</span> <span class="n">init</span><span class="p">,</span></del>
<del>                  <span class="n">BinaryOperation1</span> <span class="n">binary_op1</span><span class="p">,</span></del>
<del>                  <span class="n">BinaryOperation2</span> <span class="n">binary_op2</span><span class="p">)</span><span class="p">;</span></del>
</pre>
   </blockquote>
   <p>Apply the following changes to the definitions of <code class="highlight"><span class="n">transform_reduce</span></code> in 26.8.4 [<strong>transform.reduce</strong>]:</p>
   <blockquote>
     <strong>26.8.4 Transform reduce</strong> [<strong>transform.reduce</strong>]: 
<pre class="highlight"><ins style="display: block;"><span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIterator1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">InputIterator2</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">T</span><span class="o">></span>
  <span class="n">T</span> <span class="n">transform_reduce</span><span class="p">(</span><span class="n">InputIterator1</span> <span class="n">first1</span><span class="p">,</span> <span class="n">InputIterator1</span> <span class="n">last1</span><span class="p">,</span>
                     <span class="n">InputIterator2</span> <span class="n">first2</span><span class="p">,</span>
                     <span class="n">T</span> <span class="n">init</span><span class="p">)</span><span class="p">;</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">ExecutionPolicy</span><span class="p">,</span> <span class="k">class</span> <span class="nc">ForwardIterator1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">ForwardIterator2</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">T</span><span class="o">></span>
  <span class="n">T</span> <span class="n">transform_reduce</span><span class="p">(</span><span class="n">ExecutionPolicy</span><span class="o">&amp;</span><span class="o">&amp;</span> <span class="n">exec</span><span class="p">,</span>
                     <span class="n">ForwardIterator1</span> <span class="n">first1</span><span class="p">,</span> <span class="n">ForwardIterator1</span> <span class="n">last1</span><span class="p">,</span>
                     <span class="n">ForwardIterator2</span> <span class="n">first2</span><span class="p">,</span>
                     <span class="n">T</span> <span class="n">init</span><span class="p">)</span><span class="p">;</span>
</ins></pre>
    <ins style="display: block;"> � <em>Effects:</em> Equivalent to: <code class="highlight"><span class="k">return</span> <span class="nf">transform_reduce</span><span class="p">(</span><span class="n">first1</span><span class="p">,</span> <span class="n">last1</span><span class="p">,</span> <span class="n">first2</span><span class="p">,</span> <span class="n">init</span><span class="p">,</span> <span class="n">plus</span><span class="o">&lt;</span><span class="o">></span><span class="p">(</span><span class="p">)</span><span class="p">,</span> <span class="n">multiplies</span><span class="o">&lt;</span><span class="o">></span><span class="p">(</span><span class="p">)</span><span class="p">)</span><span class="p">;</span></code> </ins>
<pre class="highlight"><ins style="display: block;"><span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIterator1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">InputIterator2</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">T</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">BinaryOperation1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">BinaryOperation2</span><span class="o">></span>
  <span class="n">T</span> <span class="n">transform_reduce</span><span class="p">(</span><span class="n">InputIterator1</span> <span class="n">first1</span><span class="p">,</span> <span class="n">InputIterator1</span> <span class="n">last1</span><span class="p">,</span>
                     <span class="n">InputIterator2</span> <span class="n">first2</span><span class="p">,</span>
                     <span class="n">T</span> <span class="n">init</span><span class="p">,</span>
                     <span class="n">BinaryOperation1</span> <span class="n">binary_op1</span><span class="p">,</span>
                     <span class="n">BinaryOperation2</span> <span class="n">binary_op2</span><span class="p">)</span><span class="p">;</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">ExecutionPolicy</span><span class="p">,</span> <span class="k">class</span> <span class="nc">ForwardIterator1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">ForwardIterator2</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">T</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">BinaryOperation1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">BinaryOperation2</span><span class="o">></span>
  <span class="n">T</span> <span class="n">transform_reduce</span><span class="p">(</span><span class="n">ExecutionPolicy</span><span class="o">&amp;</span><span class="o">&amp;</span> <span class="n">exec</span><span class="p">,</span> 
                     <span class="n">ForwardIterator1</span> <span class="n">first1</span><span class="p">,</span> <span class="n">ForwardIterator1</span> <span class="n">last1</span><span class="p">,</span>
                     <span class="n">ForwardIterator2</span> <span class="n">first2</span><span class="p">,</span>
                     <span class="n">T</span> <span class="n">init</span><span class="p">,</span>
                     <span class="n">BinaryOperation1</span> <span class="n">binary_op1</span><span class="p">,</span>
                     <span class="n">BinaryOperation2</span> <span class="n">binary_op2</span><span class="p">)</span><span class="p">;</span>
</ins></pre>
    <ins style="display: block;">
      � <em>Returns:</em> <code class="highlight"><span class="n">GENERALIZED_SUM</span><span class="p">(</span><span class="n">binary_op1</span><span class="p">,</span> <span class="n">init</span><span class="p">,</span> <span class="n">binary_op2</span><span class="p">(</span><span class="o">*</span><span class="n">i</span><span class="p">,</span> <span class="o">*</span><span class="p">(</span><span class="n">first2</span> <span class="o">+</span> <span class="p">(</span><span class="n">i</span> <span class="o">-</span> <span class="n">first1</span><span class="p">)</span><span class="p">)</span><span class="p">)</span><span class="p">,</span> <span class="p">.</span><span class="p">.</span><span class="p">.</span><span class="p">)</span></code> for every iterator <code class="highlight"><span class="n">i</span></code> in <code class="highlight"><span class="p">[</span><span class="n">first1</span><span class="p">,</span> <span class="n">last1</span><span class="p">)</span></code>. 
     <p>� <em>Requires:</em> Neither <code class="highlight"><span class="n">binary_op1</span></code> nor <code class="highlight"><span class="n">binary_op2</span></code> shall invalidate subranges, or modify elements in the ranges <code class="highlight"><span class="p">[</span><span class="n">first1</span><span class="p">,</span> <span class="n">last1</span><span class="p">)</span></code> and <code class="highlight"><span class="p">[</span><span class="n">first2</span><span class="p">,</span> <span class="n">first2</span> <span class="o">+</span> <span class="p">(</span><span class="n">last1</span> <span class="o">-</span> <span class="n">first1</span><span class="p">)</span><span class="p">)</span></code>.</p>
     <p>� <em>Complexity:</em> <code class="highlight"><span class="n">O</span><span class="p">(</span><span class="n">last1</span> <span class="o">-</span> <span class="n">first1</span><span class="p">)</span></code> applications each of <code class="highlight"><span class="n">binary_op1</span></code> and <code class="highlight"><span class="n">binary_op2</span></code>.</p>
    </ins>
<pre class="highlight"><span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIterator</span><span class="p">,</span>
          <del><span class="k">class</span> <span class="nc">UnaryOperation</span><span class="p">,</span></del>
          <span class="k">class</span> <span class="nc">T</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">BinaryOperation</span><ins><span class="p">,</span> <span class="k">class</span> <span class="nc">UnaryOperation</span></ins><span class="o">></span>
  <span class="n">T</span> <span class="n">transform_reduce</span><span class="p">(</span><span class="n">InputIterator</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIterator</span> <span class="n">last</span><span class="p">,</span>
                     <del><span class="n">UnaryOperation</span> <span class="n">unary_op</span><span class="p">,</span></del>
                     <span class="n">T</span> <span class="n">init</span><span class="p">,</span>
                     <span class="n">BinaryOperation</span> <span class="n">binary_op</span><ins><span class="p">,</span> <span class="n">UnaryOperation</span> <span class="n">unary_op</span></ins><span class="p">)</span><span class="p">;</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">ExecutionPolicy</span><span class="p">,</span> <span class="k">class</span> <span class="nc">ForwardIterator</span><span class="p">,</span>
          <del><span class="k">class</span> <span class="nc">UnaryOperation</span><span class="p">,</span></del>
          <span class="k">class</span> <span class="nc">T</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">BinaryOperation</span><ins><span class="p">,</span> <span class="k">class</span> <span class="nc">UnaryOperation</span></ins><span class="o">></span>
  <span class="n">T</span> <span class="n">transform_reduce</span><span class="p">(</span><span class="n">ExecutionPolicy</span><span class="o">&amp;</span><span class="o">&amp;</span> <span class="n">exec</span><span class="p">,</span>
                     <span class="n">ForwardIterator</span> <span class="n">first</span><span class="p">,</span> <span class="n">ForwardIterator</span> <span class="n">last</span><span class="p">,</span>
                     <del><span class="n">UnaryOperation</span> <span class="n">unary_op</span><span class="p">,</span></del>
                     <span class="n">T</span> <span class="n">init</span><span class="p">,</span>
                     <span class="n">BinaryOperation</span> <span class="n">binary_op</span><ins><span class="p">,</span> <span class="n">UnaryOperation</span> <span class="n">unary_op</span></ins><span class="p">)</span><span class="p">;</span></pre>
    <p>
     1 <em>Returns:</em> <code class="highlight"><span class="n">GENERALIZED_SUM</span><span class="p">(</span><span class="n">binary_op</span><span class="p">,</span> <span class="n">init</span><span class="p">,</span> <span class="n">unary_op</span><span class="p">(</span><span class="o">*</span><span class="n">i</span><span class="p">)</span><span class="p">,</span> <span class="p">.</span><span class="p">.</span><span class="p">.</span><span class="p">)</span></code> for every 
     <ins>iterator</ins>
      <code class="highlight"><span class="n">i</span></code> in <code class="highlight"><span class="p">[</span><span class="n">first</span><span class="p">,</span> <span class="n">last</span><span class="p">)</span></code>.
    </p>
    <p>2 <em>Requires:</em> Neither <code class="highlight"><span class="n">unary_op</span></code> nor <code class="highlight"><span class="n">binary_op</span></code> shall invalidate subranges, or modify elements in the range <code class="highlight"><span class="p">[</span><span class="n">first</span><span class="p">,</span> <span class="n">last</span><span class="p">)</span></code>.</p>
    <p>3 <em>Complexity:</em> <code class="highlight"><span class="n">O</span><span class="p">(</span><span class="n">last</span> <span class="o">-</span> <span class="n">first</span><span class="p">)</span></code> applications each of <code class="highlight"><span class="n">unary_op</span></code> and <code class="highlight"><span class="n">binary_op</span></code>.</p>
    <p>4 <em>Notes:</em> <code class="highlight"><span class="n">transform_reduce</span></code> does not apply <code class="highlight"><span class="n">unary_op</span></code> to <code class="highlight"><span class="n">init</span></code>.</p>
   </blockquote>
   <p><strong>Direction to the Editor:</strong> Reorder the declarations and definitions of <code class="highlight"><span class="n">inner_product</span></code> to come before the declarations of <code class="highlight"><span class="n">transform_reduce</span><span class="p">(</span><span class="p">)</span></code> in the <code class="highlight"><span class="o">&lt;</span><span class="n">numeric</span><span class="o">></span></code> header synopsis and class definitions in 26.8 to
maintain consistency with <code class="highlight"><span class="n">accumulate</span></code>/<code class="highlight"><span class="n">reduce</span></code> and <code class="highlight"><span class="n">partial_sum</span></code>/<code class="highlight"><span class="n">inclusive_scan</span></code>.</p>
   <h3 class="heading settled" data-level="4.2" id="teswording"><span class="secno">4.2. </span><span class="content">Wording for <code class="highlight"><span class="n">transform_exclusive_scan</span></code></span><a class="self-link" href="#teswording"></a></h3>
   <p>Apply the following changes to the declarations of <code class="highlight"><span class="n">transform_exclusive_scan</span></code> in the <code class="highlight"><span class="o">&lt;</span><span class="n">numeric</span><span class="o">></span></code> header synopsis in 26.8.1
[<strong>numerics.ops.overview</strong>]:</p>
   <blockquote>
<pre class="highlight"><span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIterator</span><span class="p">,</span> <span class="k">class</span> <span class="nc">OutputIterator</span><span class="p">,</span>
          <del><span class="k">class</span> <span class="nc">UnaryOperation</span><span class="p">,</span></del>
          <span class="k">class</span> <span class="nc">T</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">BinaryOperation</span><ins><span class="p">,</span></ins>
          <ins><span class="k">class</span> <span class="nc">UnaryOperation</span></ins><span class="o">></span>
<span class="n">OutputIterator</span> <span class="n">transform_exclusive_scan</span><span class="p">(</span><span class="n">InputIterator</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIterator</span> <span class="n">last</span><span class="p">,</span>
                                        <span class="n">OutputIterator</span> <span class="n">result</span><span class="p">,</span>
                                        <del><span class="n">UnaryOperation</span> <span class="n">unary_op</span><span class="p">,</span></del>
                                        <span class="n">T</span> <span class="n">init</span><span class="p">,</span>
                                        <span class="n">BinaryOperation</span> <span class="n">binary_op</span><ins><span class="p">,</span></ins>
                                        <ins><span class="n">UnaryOperation</span> <span class="n">unary_op</span></ins><span class="p">)</span><span class="p">;</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">ExecutionPolicy</span><span class="p">,</span> <span class="k">class</span> <span class="nc">ForwardIterator1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">ForwardIterator2</span><span class="p">,</span>
          <del><span class="k">class</span> <span class="nc">UnaryOperation</span><span class="p">,</span></del>
          <span class="k">class</span> <span class="nc">T</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">BinaryOperation</span><ins><span class="p">,</span></ins>
          <ins><span class="k">class</span> <span class="nc">UnaryOperation</span></ins><span class="o">></span>
<span class="n">ForwardIterator2</span> <span class="n">transform_exclusive_scan</span><span class="p">(</span><span class="n">ExecutionPolicy</span><span class="o">&amp;</span><span class="o">&amp;</span> <span class="n">exec</span><span class="p">,</span> <span class="c1">// see 25.2.5
</span>                                          <span class="n">ForwardIterator1</span> <span class="n">first</span><span class="p">,</span> <span class="n">ForwardIterator1</span> <span class="n">last</span><span class="p">,</span>
                                          <span class="n">ForwardIterator2</span> <span class="n">result</span><span class="p">,</span>
                                          <del><span class="n">UnaryOperation</span> <span class="n">unary_op</span><span class="p">,</span></del>
                                          <span class="n">T</span> <span class="n">init</span><span class="p">,</span>
                                          <span class="n">BinaryOperation</span> <span class="n">binary_op</span><ins><span class="p">,</span></ins>
                                          <ins><span class="n">UnaryOperation</span> <span class="n">unary_op</span></ins><span class="p">)</span><span class="p">;</span>
</pre>
   </blockquote>
   <p>Apply the following changes to the definitions of <code class="highlight"><span class="n">transform_exclusive_scan</span></code> in 26.8.9 [<strong>transform.exclusive.scan</strong>]:</p>
   <blockquote>
<pre class="highlight"><span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIterator</span><span class="p">,</span> <span class="k">class</span> <span class="nc">OutputIterator</span><span class="p">,</span>
          <del><span class="k">class</span> <span class="nc">UnaryOperation</span><span class="p">,</span></del>
          <span class="k">class</span> <span class="nc">T</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">BinaryOperation</span><ins><span class="p">,</span></ins>
          <ins><span class="k">class</span> <span class="nc">UnaryOperation</span></ins><span class="o">></span>
<span class="n">OutputIterator</span> <span class="n">transform_exclusive_scan</span><span class="p">(</span><span class="n">InputIterator</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIterator</span> <span class="n">last</span><span class="p">,</span>
                                        <span class="n">OutputIterator</span> <span class="n">result</span><span class="p">,</span>
                                        <del><span class="n">UnaryOperation</span> <span class="n">unary_op</span><span class="p">,</span></del>
                                        <span class="n">T</span> <span class="n">init</span><span class="p">,</span>
                                        <span class="n">BinaryOperation</span> <span class="n">binary_op</span><ins><span class="p">,</span></ins>
                                        <ins><span class="n">UnaryOperation</span> <span class="n">unary_op</span></ins><span class="p">)</span><span class="p">;</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">ExecutionPolicy</span><span class="p">,</span> <span class="k">class</span> <span class="nc">ForwardIterator1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">ForwardIterator2</span><span class="p">,</span>
          <del><span class="k">class</span> <span class="nc">UnaryOperation</span><span class="p">,</span></del>
          <span class="k">class</span> <span class="nc">T</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">BinaryOperation</span><ins><span class="p">,</span></ins>
          <ins><span class="k">class</span> <span class="nc">UnaryOperation</span></ins><span class="o">></span>
<span class="n">ForwardIterator2</span> <span class="n">transform_exclusive_scan</span><span class="p">(</span><span class="n">ExecutionPolicy</span><span class="o">&amp;</span><span class="o">&amp;</span> <span class="n">exec</span><span class="p">,</span>
                                          <span class="n">ForwardIterator1</span> <span class="n">first</span><span class="p">,</span> <span class="n">ForwardIterator1</span> <span class="n">last</span><span class="p">,</span>
                                          <span class="n">ForwardIterator2</span> <span class="n">result</span><span class="p">,</span>
                                          <del><span class="n">UnaryOperation</span> <span class="n">unary_op</span><span class="p">,</span></del>
                                          <span class="n">T</span> <span class="n">init</span><span class="p">,</span>
                                          <span class="n">BinaryOperation</span> <span class="n">binary_op</span><ins><span class="p">,</span></ins>
                                          <ins><span class="n">UnaryOperation</span> <span class="n">unary_op</span></ins><span class="p">)</span><span class="p">;</span></pre>
   </blockquote>
   <h3 class="heading settled" data-level="4.3" id="tiswording"><span class="secno">4.3. </span><span class="content">Wording for <code class="highlight"><span class="n">transform_inclusive_scan</span></code></span><a class="self-link" href="#tiswording"></a></h3>
   <p>Apply the following changes to the declarations of <code class="highlight"><span class="n">transform_inclusive_scan</span></code> in the <code class="highlight"><span class="o">&lt;</span><span class="n">numeric</span><span class="o">></span></code> header synopsis in 26.8.1
[<strong>numerics.ops.overview</strong>]:</p>
   <blockquote>
<pre class="highlight"><span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIterator</span><span class="p">,</span> <span class="k">class</span> <span class="nc">OutputIterator</span><span class="p">,</span>
          <del><span class="k">class</span> <span class="nc">UnaryOperation</span><span class="p">,</span></del>
          <span class="k">class</span> <span class="nc">BinaryOperation</span><ins><span class="p">,</span></ins>
          <ins><span class="k">class</span> <span class="nc">UnaryOperation</span></ins><span class="o">></span>
<span class="n">OutputIterator</span> <span class="n">transform_inclusive_scan</span><span class="p">(</span><span class="n">InputIterator</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIterator</span> <span class="n">last</span><span class="p">,</span>
                                        <span class="n">OutputIterator</span> <span class="n">result</span><span class="p">,</span>
                                        <del><span class="n">UnaryOperation</span> <span class="n">unary_op</span><span class="p">,</span></del>
                                        <span class="n">BinaryOperation</span> <span class="n">binary_op</span><ins><span class="p">,</span></ins>
                                        <ins><span class="n">UnaryOperation</span> <span class="n">unary_op</span></ins><span class="p">)</span><span class="p">;</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIterator</span><span class="p">,</span> <span class="k">class</span> <span class="nc">OutputIterator</span><span class="p">,</span>
          <del><span class="k">class</span> <span class="nc">UnaryOperation</span><span class="p">,</span></del>
          <span class="k">class</span> <span class="nc">BinaryOperation</span><span class="p">,</span>
          <ins><span class="k">class</span> <span class="nc">UnaryOperation</span><span class="p">,</span></ins>
          <span class="k">class</span> <span class="nc">T</span><span class="o">></span>
<span class="n">OutputIterator</span> <span class="n">transform_inclusive_scan</span><span class="p">(</span><span class="n">InputIterator</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIterator</span> <span class="n">last</span><span class="p">,</span>
                                        <span class="n">OutputIterator</span> <span class="n">result</span><span class="p">,</span>
                                        <del><span class="n">UnaryOperation</span> <span class="n">unary_op</span><span class="p">,</span></del>
                                        <span class="n">BinaryOperation</span> <span class="n">binary_op</span><span class="p">,</span>
                                        <ins><span class="n">UnaryOperation</span> <span class="n">unary_op</span><span class="p">,</span></ins>
                                        <span class="n">T</span> <span class="n">init</span><span class="p">)</span><span class="p">;</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">ExecutionPolicy</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">ForwardIterator1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">ForwardIterator2</span><span class="p">,</span>
          <del><span class="k">class</span> <span class="nc">UnaryOperation</span><span class="p">,</span></del>
          <span class="k">class</span> <span class="nc">BinaryOperation</span><ins><span class="p">,</span></ins>
          <ins><span class="k">class</span> <span class="nc">UnaryOperation</span></ins><span class="o">></span>
<span class="n">ForwardIterator2</span> <span class="n">transform_inclusive_scan</span><span class="p">(</span><span class="n">ExecutionPolicy</span><span class="o">&amp;</span><span class="o">&amp;</span> <span class="n">exec</span><span class="p">,</span> <span class="c1">// see 25.2.5
</span>                                          <span class="n">ForwardIterator1</span> <span class="n">first</span><span class="p">,</span> <span class="n">ForwardIterator1</span> <span class="n">last</span><span class="p">,</span>
                                          <span class="n">ForwardIterator2</span> <span class="n">result</span><span class="p">,</span>
                                          <del><span class="n">UnaryOperation</span> <span class="n">unary_op</span><span class="p">,</span></del>
                                          <span class="n">BinaryOperation</span> <span class="n">binary_op</span><ins><span class="p">,</span></ins>
                                          <ins><span class="n">UnaryOperation</span> <span class="n">unary_op</span></ins><span class="p">)</span><span class="p">;</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">ExecutionPolicy</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">ForwardIterator1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">ForwardIterator2</span><span class="p">,</span>
          <del><span class="k">class</span> <span class="nc">UnaryOperation</span><span class="p">,</span></del>
          <span class="k">class</span> <span class="nc">BinaryOperation</span><span class="p">,</span>
          <ins><span class="k">class</span> <span class="nc">UnaryOperation</span><span class="p">,</span></ins>
          <span class="k">class</span> <span class="nc">T</span><span class="o">></span>
<span class="n">ForwardIterator2</span> <span class="n">transform_inclusive_scan</span><span class="p">(</span><span class="n">ExecutionPolicy</span><span class="o">&amp;</span><span class="o">&amp;</span> <span class="n">exec</span><span class="p">,</span> <span class="c1">// see 25.2.5
</span>                                          <span class="n">ForwardIterator1</span> <span class="n">first</span><span class="p">,</span> <span class="n">ForwardIterator1</span> <span class="n">last</span><span class="p">,</span>
                                          <span class="n">ForwardIterator2</span> <span class="n">result</span><span class="p">,</span>
                                          <del><span class="n">UnaryOperation</span> <span class="n">unary_op</span><span class="p">,</span></del>
                                          <span class="n">BinaryOperation</span> <span class="n">binary_op</span><span class="p">,</span>
                                          <ins><span class="n">UnaryOperation</span> <span class="n">unary_op</span><span class="p">,</span></ins>
                                          <span class="n">T</span> <span class="n">init</span><span class="p">)</span><span class="p">;</span></pre>
   </blockquote>
   <p>Apply the following changes to the definitions of <code class="highlight"><span class="n">transform_inclusive_scan</span></code> in 26.8.10 [<strong>transform.inclusive.scan</strong>]:</p>
   <blockquote>
<pre class="highlight"><span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIterator</span><span class="p">,</span> <span class="k">class</span> <span class="nc">OutputIterator</span><span class="p">,</span>
          <del><span class="k">class</span> <span class="nc">UnaryOperation</span><span class="p">,</span></del>
          <span class="k">class</span> <span class="nc">BinaryOperation</span><ins><span class="p">,</span></ins>
          <ins><span class="k">class</span> <span class="nc">UnaryOperation</span></ins><span class="o">></span>
<span class="n">OutputIterator</span> <span class="n">transform_inclusive_scan</span><span class="p">(</span><span class="n">InputIterator</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIterator</span> <span class="n">last</span><span class="p">,</span>
                                        <span class="n">OutputIterator</span> <span class="n">result</span><span class="p">,</span>
                                        <del><span class="n">UnaryOperation</span> <span class="n">unary_op</span><span class="p">,</span></del>
                                        <span class="n">BinaryOperation</span> <span class="n">binary_op</span><ins><span class="p">,</span></ins>
                                        <ins><span class="n">UnaryOperation</span> <span class="n">unary_op</span></ins><span class="p">)</span><span class="p">;</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIterator</span><span class="p">,</span> <span class="k">class</span> <span class="nc">OutputIterator</span><span class="p">,</span>
          <del><span class="k">class</span> <span class="nc">UnaryOperation</span><span class="p">,</span></del>
          <span class="k">class</span> <span class="nc">BinaryOperation</span><span class="p">,</span>
          <ins><span class="k">class</span> <span class="nc">UnaryOperation</span><span class="p">,</span></ins>
          <span class="k">class</span> <span class="nc">T</span><span class="o">></span>
<span class="n">OutputIterator</span> <span class="n">transform_inclusive_scan</span><span class="p">(</span><span class="n">InputIterator</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIterator</span> <span class="n">last</span><span class="p">,</span>
                                        <span class="n">OutputIterator</span> <span class="n">result</span><span class="p">,</span>
                                        <del><span class="n">UnaryOperation</span> <span class="n">unary_op</span><span class="p">,</span></del>
                                        <span class="n">BinaryOperation</span> <span class="n">binary_op</span><span class="p">,</span>
                                        <ins><span class="n">UnaryOperation</span> <span class="n">unary_op</span><span class="p">,</span></ins>
                                        <span class="n">T</span> <span class="n">init</span><span class="p">)</span><span class="p">;</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">ExecutionPolicy</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">ForwardIterator1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">ForwardIterator2</span><span class="p">,</span>
          <del><span class="k">class</span> <span class="nc">UnaryOperation</span><span class="p">,</span></del>
          <span class="k">class</span> <span class="nc">BinaryOperation</span><ins><span class="p">,</span></ins>
          <ins><span class="k">class</span> <span class="nc">UnaryOperation</span></ins><span class="o">></span>
<span class="n">ForwardIterator2</span> <span class="n">transform_inclusive_scan</span><span class="p">(</span><span class="n">ExecutionPolicy</span><span class="o">&amp;</span><span class="o">&amp;</span> <span class="n">exec</span><span class="p">,</span>
                                          <span class="n">ForwardIterator1</span> <span class="n">first</span><span class="p">,</span> <span class="n">ForwardIterator1</span> <span class="n">last</span><span class="p">,</span>
                                          <span class="n">ForwardIterator2</span> <span class="n">result</span><span class="p">,</span>
                                          <del><span class="n">UnaryOperation</span> <span class="n">unary_op</span><span class="p">,</span></del>
                                          <span class="n">BinaryOperation</span> <span class="n">binary_op</span><ins><span class="p">,</span></ins>
                                          <ins><span class="n">UnaryOperation</span> <span class="n">unary_op</span></ins><span class="p">)</span><span class="p">;</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">ExecutionPolicy</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">ForwardIterator1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">ForwardIterator2</span><span class="p">,</span>
          <del><span class="k">class</span> <span class="nc">UnaryOperation</span><span class="p">,</span></del>
          <span class="k">class</span> <span class="nc">BinaryOperation</span><span class="p">,</span>
          <ins><span class="k">class</span> <span class="nc">UnaryOperation</span><span class="p">,</span></ins>
          <span class="k">class</span> <span class="nc">T</span><span class="o">></span>
<span class="n">ForwardIterator2</span> <span class="n">transform_inclusive_scan</span><span class="p">(</span><span class="n">ExecutionPolicy</span><span class="o">&amp;</span><span class="o">&amp;</span> <span class="n">exec</span><span class="p">,</span>
                                          <span class="n">ForwardIterator1</span> <span class="n">first</span><span class="p">,</span> <span class="n">ForwardIterator1</span> <span class="n">last</span><span class="p">,</span>
                                          <span class="n">ForwardIterator2</span> <span class="n">result</span><span class="p">,</span>
                                          <del><span class="n">UnaryOperation</span> <span class="n">unary_op</span><span class="p">,</span></del>
                                          <span class="n">BinaryOperation</span> <span class="n">binary_op</span><span class="p">,</span>
                                          <ins><span class="n">UnaryOperation</span> <span class="n">unary_op</span><span class="p">,</span></ins>
                                          <span class="n">T</span> <span class="n">init</span><span class="p">)</span><span class="p">;</span></pre>
   </blockquote>
   <h2 class="heading settled" data-level="5" id="ack"><span class="secno">5. </span><span class="content">Acknowledgement</span><a class="self-link" href="#ack"></a></h2>
   <p>Thanks to:</p>
   <ul>
    <li data-md="">
     <p>Agustín Bergé for helping identify this issue.</p>
    <li data-md="">
     <p>Alisdair Meredith for assisting with wording and tackling the related problem with <code class="highlight"><span class="n">adjacent_difference</span></code>.</p>
    <li data-md="">
     <p>Hartmut Kaiser, JF Bastien, Michael Garland and Jared Hoberock for providing feedback.</p>
   </ul>
  </main>
<script>
(function() {
  "use strict";
  var collapseSidebarText = '<span aria-hidden="true">←</span> '
                          + '<span>Collapse Sidebar</span>';
  var expandSidebarText   = '<span aria-hidden="true">→</span> '
                          + '<span>Pop Out Sidebar</span>';
  var tocJumpText         = '<span aria-hidden="true">↑</span> '
                          + '<span>Jump to Table of Contents</span>';

  var sidebarMedia = window.matchMedia('screen and (min-width: 78em)');
  var autoToggle   = function(e){ toggleSidebar(e.matches) };
  if(sidebarMedia.addListener) {
    sidebarMedia.addListener(autoToggle);
  }

  function toggleSidebar(on) {
    if (on == undefined) {
      on = !document.body.classList.contains('toc-sidebar');
    }

    /* Don’t scroll to compensate for the ToC if we’re above it already. */
    var headY = 0;
    var head = document.querySelector('.head');
    if (head) {
      // terrible approx of "top of ToC"
      headY += head.offsetTop + head.offsetHeight;
    }
    var skipScroll = window.scrollY < headY;

    var toggle = document.getElementById('toc-toggle');
    var tocNav = document.getElementById('toc');
    if (on) {
      var tocHeight = tocNav.offsetHeight;
      document.body.classList.add('toc-sidebar');
      document.body.classList.remove('toc-inline');
      toggle.innerHTML = collapseSidebarText;
      if (!skipScroll) {
        window.scrollBy(0, 0 - tocHeight);
      }
      tocNav.focus();
      sidebarMedia.addListener(autoToggle); // auto-collapse when out of room
    }
    else {
      document.body.classList.add('toc-inline');
      document.body.classList.remove('toc-sidebar');
      toggle.innerHTML = expandSidebarText;
      if (!skipScroll) {
        window.scrollBy(0, tocNav.offsetHeight);
      }
      if (toggle.matches(':hover')) {
        /* Unfocus button when not using keyboard navigation,
           because I don’t know where else to send the focus. */
        toggle.blur();
      }
    }
  }

  function createSidebarToggle() {
    /* Create the sidebar toggle in JS; it shouldn’t exist when JS is off. */
    var toggle = document.createElement('a');
      /* This should probably be a button, but appearance isn’t standards-track.*/
    toggle.id = 'toc-toggle';
    toggle.class = 'toc-toggle';
    toggle.href = '#toc';
    toggle.innerHTML = collapseSidebarText;

    sidebarMedia.addListener(autoToggle);
    var toggler = function(e) {
      e.preventDefault();
      sidebarMedia.removeListener(autoToggle); // persist explicit off states
      toggleSidebar();
      return false;
    }
    toggle.addEventListener('click', toggler, false);


    /* Get <nav id=toc-nav>, or make it if we don’t have one. */
    var tocNav = document.getElementById('toc-nav');
    if (!tocNav) {
      tocNav = document.createElement('p');
      tocNav.id = 'toc-nav';
      /* Prepend for better keyboard navigation */
      document.body.insertBefore(tocNav, document.body.firstChild);
    }
    /* While we’re at it, make sure we have a Jump to Toc link. */
    var tocJump = document.getElementById('toc-jump');
    if (!tocJump) {
      tocJump = document.createElement('a');
      tocJump.id = 'toc-jump';
      tocJump.href = '#toc';
      tocJump.innerHTML = tocJumpText;
      tocNav.appendChild(tocJump);
    }

    tocNav.appendChild(toggle);
  }

  var toc = document.getElementById('toc');
  if (toc) {
    createSidebarToggle();
    toggleSidebar(sidebarMedia.matches);

    /* If the sidebar has been manually opened and is currently overlaying the text
       (window too small for the MQ to add the margin to body),
       then auto-close the sidebar once you click on something in there. */
    toc.addEventListener('click', function(e) {
      if(e.target.tagName.toLowerCase() == "a" && document.body.classList.contains('toc-sidebar') && !sidebarMedia.matches) {
        toggleSidebar(false);
      }
    }, false);
  }
  else {
    console.warn("Can’t find Table of Contents. Please use <nav id='toc'> around the ToC.");
  }

  /* Wrap tables in case they overflow */
  var tables = document.querySelectorAll(':not(.overlarge) > table.data, :not(.overlarge) > table.index');
  var numTables = tables.length;
  for (var i = 0; i < numTables; i++) {
    var table = tables[i];
    var wrapper = document.createElement('div');
    wrapper.className = 'overlarge';
    table.parentNode.insertBefore(wrapper, table);
    wrapper.appendChild(table);
  }

})();
</script>
  <h2 class="no-num no-ref heading settled" id="references"><span class="content">References</span><a class="self-link" href="#references"></a></h2>
  <h3 class="no-num no-ref heading settled" id="informative"><span class="content">Informative References</span><a class="self-link" href="#informative"></a></h3>
  <dl>
   <dt id="biblio-p0467r2">[P0467r2]
   <dd><a href="https://wg21.link/p0467r2">Iterator Concerns for Parallel Algorithms</a>. URL: <a href="https://wg21.link/p0467r2">https://wg21.link/p0467r2</a>
   <dt id="biblio-p0574r1">[P0574r1]
   <dd><a href="https://wg21.link/p0574r1">Algorithm Complexity Constraints and Parallel Overloads</a>. URL: <a href="https://wg21.link/p0574r1">https://wg21.link/p0574r1</a>
   <dt id="biblio-n3960">[N3960]
   <dd>Jared Hoberock. <a href="https://wg21.link/n3960">Working Draft, Technical Specification for C++ Extensions for Parallelism</a>. 28 February 2014. URL: <a href="https://wg21.link/n3960">https://wg21.link/n3960</a>
   <dt id="biblio-n4640">[N4640]
   <dd>Richard Smith. <a href="https://wg21.link/n4640">Working Draft, Standard for Programming Language C++</a>. 6 February 2017. URL: <a href="https://wg21.link/n4640">https://wg21.link/n4640</a>
  </dl>
