<!doctype html><html lang="en">
 <head>
  <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  <title>Hotel Parallelifornia: terminate() for Parallel Algorithms Exception Handling</title>
  <meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
<style data-fill-with="stylesheet">/******************************************************************************
 *                   Style sheet for ISO/IEC JTC1/SC22 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)
 *   - .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;}

    .metadata-key {
        font-weight: bold; 
    }

/** 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) {
	 border-left: 0.5em solid #DEF;
	}

	/* Style for switch/case <dl>s */
	dl.switch > dd > ol.only {
	 margin-left: 0;
	}
	dl.switch > dd > ol.algorithm {
	 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: inherit;
	}
	dfn var {
		font-style: normal;
	}

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

    ins { text-decoration:none; font-weight:bold; background-color:#A0FFA0 }
    del { text-decoration:line-through; background-color:#FFA0A0 }  

/** 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, .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,
	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;
	}

/** 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-style:  italic; }
	.toc > li li li li    { font-style:  normal; }
	.toc > li li li li li { font-style:  italic;
	                        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-counters */

            .issue:not(.no-marker)::before {
                content: "Issue " counter(issue);
            }

            .example:not(.no-marker)::before {
                content: "Example";
                content: "Example " counter(example);
            }
            .invalid.example:not(.no-marker)::before,
            .illegal.example:not(.no-marker)::before {
                content: "Invalid Example";
                content: "Invalid Example" counter(example);
            }</style>
<style>/* style-syntax-highlighting */
.highlight .hll { background-color: #ffffcc }
.highlight  { background: #ffffff; }
.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 .ch { color: #708090 } /* Comment.Hashbang */
.highlight .cm { color: #708090 } /* Comment.Multiline */
.highlight .cp { color: #708090 } /* Comment.Preproc */
.highlight .cpf { color: #708090 } /* Comment.PreprocFile */
.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: #0077aa } /* 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 */
        .highlight { 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; }
        </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-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>
 <body class="h-entry">
  <div class="head">
   <h1 class="p-name no-ref" id="title">P0394-r4: Hotel Parallelifornia: terminate() for Parallel Algorithms Exception Handling</h1>
   <div data-fill-with="spec-metadata">
    <dl>
     <dd><span class="metadata-key">Project: </span><span>ISO/IEC JTC1/SC22/WG21</span>
     <dd><span class="metadata-key">Audience: </span><span>SG1</span>
     <dd><span class="metadata-key">Repository: </span><a href="https://github.com/brycelelbach/wg21_p0333_improving_parallel_algorithms_exception_handling" rel="repository">brycelelbach/wg21_p0333_improving_parallel_algorithms_exception_handling</a>
     <dd><span class="metadata-key">Author: </span><span class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:jfb@google.com">JF Bastien</a> (<span class="p-org org">Google</span>)</span>
     <dd><span class="metadata-key">Author: </span><span 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">Berkeley Lab</span>)</span>
    </dl>
   </div>
   <hr title="Separator for header">
  </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="#bg"><span class="secno">1</span> <span class="content">Background</span></a>
    <li><a href="#sg1fb333"><span class="secno">2</span> <span class="content">SG1 Feedback on P0333</span></a>
    <li><a href="#sg1fb394"><span class="secno">3</span> <span class="content">SG1 Feedback on D0394</span></a>
    <li><a href="#lewgfb394"><span class="secno">4</span> <span class="content">LEWG Feedback on D0394</span></a>
    <li><a href="#lwgfb394"><span class="secno">5</span> <span class="content">LWG Feedback on D0394</span></a>
    <li><a href="#prop"><span class="secno">6</span> <span class="content">Proposed Wording Change</span></a>
    <li><a href="#exam"><span class="secno">7</span> <span class="content">Examples</span></a>
    <li><a href="#acko"><span class="secno">8</span> <span class="content">Acknowledgments</span></a>
   </ol>
  </nav>
  <main>
   <center>
    <big><i>You can throw any time you like, but the exceptions can never leave.</i></big>
   </center>
   <h2 class="heading settled" data-level="1" id="bg"><span class="secno">1. </span><span class="content">Background</span><a class="self-link" href="#bg"></a></h2>
   <p><a href="http://wg21.link/P0333r0">P0333r0 Improving Parallel Algorithm Exception Handling</a> states:</p>
   <blockquote>
     The exception handling behavior of parallel algorithms invoked with <code class="highlight"><span></span><span class="n">par_unseq</span></code> (the <code class="highlight"><span></span><span class="n">parallel_unsequenced_execution_policy</span></code>) is inconsistent with the exception handling behavior of the other two execution policies specified in the IS (<code class="highlight"><span></span><span class="n">seq</span></code> AKA <code class="highlight"><span></span><span class="n">sequential_execution_policy</span></code> and <code class="highlight"><span></span><span class="n">par</span></code> AKA <code class="highlight"><span></span><span class="n">parallel_execution_policy</span></code>). 
    <p>25.2.4 [algorithms.parallel.exception] states that if an element access function exits via an uncaught exception in a parallel algorithm invoked under the <code class="highlight"><span></span><span class="n">par_unseq</span></code> execution policy, <code class="highlight"><span></span><span class="n">terminate</span><span class="p">()</span></code> will be called. This is inconsistent with the other two policies, which would exit by throwing either the uncaught exception or an <code class="highlight"><span></span><span class="n">exception_list</span></code> containing (at least) the uncaught exception.</p>
   </blockquote>
   <h2 class="heading settled" data-level="2" id="sg1fb333"><span class="secno">2. </span><span class="content">SG1 Feedback on P0333</span><a class="self-link" href="#sg1fb333"></a></h2>
   <p>P0333r0 proposed addressing this problem by allowing <code class="highlight"><span></span><span class="n">par_unseq</span></code> element access functions to throw exceptions. SG1’s discussion in Oulu concludes that throwing exceptions pessimizes code which cannot be proven to not throw, e.g. when invoking opaque functions which aren’t marked as <code class="highlight"><span></span><span class="k">noexcept</span></code> (see <a href="#exam2">Example #2</a>). Invoking <code class="highlight"><span></span><span class="n">terminate</span><span class="p">()</span></code> greatly simplifies code generation in these cases.</p>
   <p>We therefore propose to fix the inconsistency by making all parallel algorithms invoke <code class="highlight"><span></span><span class="n">terminate</span><span class="p">()</span></code> if element access functions exit via an uncaught exception. This has the added benefit of removing the need for <code class="highlight"><span></span><span class="n">exception_list</span></code>. A parallel algorithm is still allowed to throw <code class="highlight"><span></span><span class="n">bad_alloc</span></code> (if it fails to acquire temporary memory resources for parallel execution), but nothing else may be thrown. There is existing precedent for calling <code class="highlight"><span></span><span class="n">terminate</span><span class="p">()</span></code> when an exception escapes from <code class="highlight"><span></span><span class="kr">thread</span></code>, <code class="highlight"><span></span><span class="n">main</span><span class="p">()</span></code> or a transaction in the <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4514.pdf">Transaction TS</a>.</p>
   <p>Removing the need for <code class="highlight"><span></span><span class="n">exception_list</span></code> solves outstanding design concerns with <code class="highlight"><span></span><span class="n">exception_list</span></code> which were raised at Jacksonville during the <a href="http://wiki.edg.com/bin/view/Wg21jacksonville/P0024">discussion of P0024 The Parallelism TS Should be Standardized</a>. Specifically, there was concern about having an <code class="highlight"><span></span><span class="n">exception_list</span></code> which was not constructible by users. The consensus in LEWG at Jacksonville was to give <code class="highlight"><span></span><span class="n">exception_list</span></code> user-accessible constructors and mutators for C++17.</p>
   <p><a href="http://wg21.link/D0322r1">D0322r1 exception_list</a> proposed a possible design for a user-constructible <code class="highlight"><span></span><span class="n">exception_list</span></code>. Designing this <code class="highlight"><span></span><span class="n">exception_list</span></code>, is a difficult task. <code class="highlight"><span></span><span class="n">exception_list</span></code> derives from <code class="highlight"><span></span><span class="n">exception</span></code>, and in a parallel context it could potentially be caught in multiple threads concurrently. Thus, any <code class="highlight"><span></span><span class="n">exception_list</span></code> design would need to be thread-safe. To ensure thread-safety and to maintain consistency with all other standard exceptions, the authors of D0322r1 felt it was necessary for <code class="highlight"><span></span><span class="n">exception_list</span></code> to be immutable. The standard library does not currently have immutable containers; <code class="highlight"><span></span><span class="n">exception_list</span></code> would be the first, and thus would be exploring an entirely new design space. At Oulu, the authors of D0322r1 and LEWG felt that there was not sufficient time before C++17 to decide on a design for immutable containers in the standard library. By removing the need for <code class="highlight"><span></span><span class="n">exception_list</span></code>, it is not necessary for it to be fixed in time for C++17.</p>
   <p>Further issues with <code class="highlight"><span></span><span class="n">exception_list</span></code> include:</p>
   <ul>
    <li data-md="">
     <p>The order in which <code class="highlight"><span></span><span class="n">exception_list</span></code> is populated is unspecified, since the algorithms are concurrent and/or parallel.</p>
    <li data-md="">
     <p>Whether implementations forge ahead or abort early is implementation-defined.</p>
    <li data-md="">
     <p>Which NTBS content is expected in <code class="highlight"><span></span><span class="p">.</span><span class="n">what</span><span class="p">()</span></code> considering that <code class="highlight"><span></span><span class="n">exception_list</span></code> is generated at runtime, <code class="highlight"><span></span><span class="p">.</span><span class="n">what</span><span class="p">()</span></code> cannot allocate, and an <code class="highlight"><span></span><span class="n">exception_list</span></code> may be very larger. If the NTBS is constructed optimistically based on the contents, it may well run out of memory while enumerating the members. Otherwise, the NTBS is unlikely to provide useful information.</p>
    <li data-md="">
     <p>Whether and when nested <code class="highlight"><span></span><span class="n">exception_list</span></code>s are allowed is unclear.</p>
    <li data-md="">
     <p>As discussed in <a href="http://wg21.link/N4157">N4157 Relaxing Packaging Rules for Exceptions Thrown by Parallel Algorithms</a>, walking an <code class="highlight"><span></span><span class="n">exception_list</span></code> is not easy. You must recursively walk the list to deal with nested <code class="highlight"><span></span><span class="n">exception_list</span></code>s and unpackage the underlying <code class="highlight"><span></span><span class="n">exception_ptr</span></code>s (see <a href="#exam1">Example 1</a>).</p>
   </ul>
   <h2 class="heading settled" data-level="3" id="sg1fb394"><span class="secno">3. </span><span class="content">SG1 Feedback on D0394</span><a class="self-link" href="#sg1fb394"></a></h2>
   <p>SG1 reviewed D0394 on Wednesday morning at Oulu. A straw poll was taken about forwarding this to LEWG for C++17:</p>
   <table class="def">
    <tbody>
     <tr>
      <th><b>SF</b>
      <th><b>F</b>
      <th><b>N</b>
      <th><b>A</b>
      <th><b>SA</b>
     <tr>
      <th>12
      <th>5
      <th>1
      <th>0
      <th>0
   </table>
   <h2 class="heading settled" data-level="4" id="lewgfb394"><span class="secno">4. </span><span class="content">LEWG Feedback on D0394</span><a class="self-link" href="#lewgfb394"></a></h2>
   <p>LEWG reviewed D0394 on Thursday morning at Oulu. A straw poll was taken about forwarding this to LWG for C++17:</p>
   <table class="def">
    <tbody>
     <tr>
      <th><b>SF</b>
      <th><b>F</b>
      <th><b>N</b>
      <th><b>A</b>
      <th><b>SA</b>
     <tr>
      <th>13
      <th>1
      <th>2
      <th>0
      <th>0
   </table>
   <h2 class="heading settled" data-level="5" id="lwgfb394"><span class="secno">5. </span><span class="content">LWG Feedback on D0394</span><a class="self-link" href="#lwgfb394"></a></h2>
   <p>LEWG reviewed D0394 on Thursday evening at Oulu. A straw poll was taken about sending this to plenary for C++17:</p>
   <table class="def">
    <tbody>
     <tr>
      <th><b>SF</b>
      <th><b>F</b>
      <th><b>N</b>
      <th><b>A</b>
      <th><b>SA</b>
     <tr>
      <th>7
      <th>6
      <th>0
      <th>0
      <th>0
   </table>
   <h2 class="heading settled" data-level="6" id="prop"><span class="secno">6. </span><span class="content">Proposed Wording Change</span><a class="self-link" href="#prop"></a></h2>
   <p>Add the following clause after 15.5.1.1 (1.12) [except.terminate]:</p>
   <blockquote>
     — when execution of the initial function of a thread exits via an exception (30.3.1.2), or <br> 
    <ins> — when execution of an <em>element access function</em> (25.2.1) of a parallel algorithm
exits via an exception (25.2.4), or </ins>
   </blockquote>
   <p>Apply the following changes to 17.6.1.2 [headers] paragraph 2:</p>
   <blockquote>
     The C++ standard library provides 
    <ins>60</ins>
    <del>61</del>
     C++ library headers, as shown in Table 14. 
   </blockquote>
   <p>In 17.6.1.2 [headers], delete <code>&lt;exception_list></code> from Table 14.</p>
   <p>In 18.1 [support.general], delete the row for exception lists from Table 29.</p>
   <p>Delete 18.8.8 [support.exception.list].</p>
   <p>Apply the following changes to 25.2.4 [algorithms.parallel.exceptions]
paragraph 2:</p>
   <blockquote>
     During the execution of a parallel algorithm, if the invocation of an element
access function exits via an uncaught exception, 
    <ins><code>terminate()</code> is called.</ins>
    <del>the behavior of the program
is determined by the type of execution policy used to invoke the algorithm:</del>
    <ul>
     <li>
      <del> If the execution policy object is of type <code>parallel_vector_execution_policy</code>, <code>terminate()</code> is called. </del>
     <li>
      <del> If the execution policy object is of type <code>sequential_execution_policy</code> or <code>parallel_ execution_policy</code>, the execution
        of the algorithm exits via an exception. The exception will be an <code>exception_list</code> containing all uncaught exceptions
        thrown during the invocations of element access functions, or optionally
        the uncaught exception if there was only one.
        [<em>Note:</em> For example, when <code>for_each</code> is executed
        sequentially, if an invocation of the user-provided function object
        throws an exception, <code>for_each</code> can exit via the
        uncaught exception, or throw an <code>exception_list</code> containing the original exception exception. - <em>end note</em>]
        [<em>Note:</em> These guarantees imply that, unless the algorithm
        has failed to allocate memory and exits via <code>bad_alloc</code>,
        all exceptions thrown during the execution of the algorithm are
        communicated to the caller. It is unspecified whether an algorithm
        implementation will "forge ahead" after encountering and capturing
        a user exception. - <em>end note</em>]
        [<em>Note:</em> The algorithm may exit via the <code>bad_alloc</code> exception even if one or more user-provided
        function objects have exited via an exception. For example, this 
        can happen when an algorithm fails to allocate memory while
        creating or adding elements to the <code>exception_list</code> object. - <em>end note</em>] </del>
     <li>
      <del> If the execution policy object is of any other type, the behavior
        is implementation-defined. </del>
    </ul>
   </blockquote>
   <h2 class="heading settled" data-level="7" id="exam"><span class="secno">7. </span><span class="content">Examples</span><a class="self-link" href="#exam"></a></h2>
   <p><span id="exam1">1.) Example of recursively walking an <code class="highlight"><span></span><span class="n">exception_list</span></code>. The ordering of the list is unspecified. Currently there is no standard library facility to help unpack an <code class="highlight"><span></span><span class="n">exception_list</span></code>.</span></p>
<pre class="highlight"><span></span><span class="kt">void</span> <span class="nf">walk</span><span class="p">(</span><span class="k">const</span> <span class="n">exception_ptr</span><span class="o">&amp;</span> <span class="n">e</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">try</span> <span class="p">{</span>
        <span class="n">rethrow_exception</span><span class="p">(</span><span class="n">e</span><span class="p">);</span>
    <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="k">const</span> <span class="n">range_error</span><span class="o">&amp;</span> <span class="n">r</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"found a range error</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
    <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="k">const</span> <span class="n">exception_list</span><span class="o">&amp;</span> <span class="n">y</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="nl">d</span> <span class="p">:</span> <span class="n">y</span><span class="p">)</span>
            <span class="n">walk</span><span class="p">(</span><span class="n">d</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kt">void</span> <span class="nf">example</span><span class="p">(</span><span class="n">Iter</span> <span class="n">first</span><span class="p">,</span> <span class="n">Iter</span> <span class="n">last</span><span class="p">,</span> <span class="kt">bool</span> <span class="p">(</span><span class="o">*</span><span class="n">p</span><span class="p">)(</span><span class="k">const</span> <span class="n">Foo</span><span class="o">&amp;</span><span class="p">))</span> <span class="p">{</span>
    <span class="k">try</span> <span class="p">{</span>
        <span class="k">return</span> <span class="n">none_of</span><span class="p">(</span><span class="n">par</span><span class="p">,</span> <span class="n">first</span><span class="p">,</span> <span class="n">last</span><span class="p">,</span> <span class="n">p</span><span class="p">);</span>
    <span class="p">}</span> <span class="k">catch</span> <span class="p">(...)</span> <span class="p">{</span>
        <span class="n">walk</span><span class="p">(</span><span class="n">current_exception</span><span class="p">());</span>
    <span class="p">}</span>
<span class="p">}</span></pre>
   <p><span id="exam2">2.) Example of how opaque calls can force a vectorizing SIMD compiler to pessimize a function by forcing it to prepare for divergence of control flow.</span></p>
<pre class="highlight"><span></span><span class="k">struct</span> <span class="n">foo</span>
<span class="p">{</span>
    <span class="n">foo</span><span class="p">();</span> 
    <span class="o">~</span><span class="n">foo</span><span class="p">();</span>
    <span class="kt">void</span> <span class="nf">bar</span><span class="p">();</span> <span class="c1">// Won’t throw, but not noexcept</span>
    <span class="kt">void</span> <span class="nf">bar_noexcept</span><span class="p">()</span> <span class="k">noexcept</span><span class="p">;</span>
<span class="p">};</span>

<span class="kt">void</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">foo</span><span class="o">>&amp;</span> <span class="n">v</span><span class="p">)</span>
<span class="p">{</span>
    <span class="cp">#pragma omp simd</span>
    <span class="k">for</span> <span class="p">(</span><span class="k">auto</span><span class="o">&amp;</span> <span class="nl">e</span> <span class="p">:</span> <span class="n">v</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">foo</span> <span class="n">f</span><span class="p">;</span>

        <span class="c1">// .bar() might exit via exception. If it does, the exception boils</span>
        <span class="c1">// up into this context and we have to do stack unwinding before </span>
        <span class="c1">// initialize exits via an uncaught exception.</span>
        <span class="c1">//</span>
        <span class="c1">// This can lead to a divergence of control flow. Multiple SIMD lanes</span>
        <span class="c1">// will be executing .bar() concurrently, but only one of them may</span>
        <span class="c1">// throw. This requires masking all the way up the call chain within</span>
        <span class="c1">// the SIMD region. This is blisteringly expensive, especially on SIMD</span>
        <span class="c1">// architectures without full masking support.</span>
        <span class="n">f</span><span class="p">.</span><span class="n">bar</span><span class="p">();</span>

        <span class="n">e</span> <span class="o">=</span> <span class="n">f</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kt">void</span> <span class="nf">initialize_faster</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">foo</span><span class="o">>&amp;</span> <span class="n">v</span><span class="p">)</span>
<span class="p">{</span>
    <span class="cp">#pragma omp simd</span>
    <span class="k">for</span> <span class="p">(</span><span class="k">auto</span><span class="o">&amp;</span> <span class="nl">e</span> <span class="p">:</span> <span class="n">v</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">foo</span> <span class="n">f</span><span class="p">;</span>

        <span class="c1">// We do not need to worry about .bar() exiting by uncaught exception,</span>
        <span class="c1">// so we do not need to prepare for any divergence of control flow.</span>

        <span class="n">f</span><span class="p">.</span><span class="n">bar_noexcept</span><span class="p">();</span>

        <span class="n">e</span> <span class="o">=</span> <span class="n">f</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span></pre>
   <h2 class="heading settled" data-level="8" id="acko"><span class="secno">8. </span><span class="content">Acknowledgments</span><a class="self-link" href="#acko"></a></h2>
   <p>Our thanks to Pablo Halpern, Alisdair Meredith and various members of both SG1 and LEWG for their contributions to this proposal.</p>
  </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>