<!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>p0798R2: Monadic operations for std::optional</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 calc(-0.5em - 1px);
	}
	[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: medium;
	}
	dfn var {
		font-style: normal;
	}

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

	del { color: red;  text-decoration: line-through; }
	ins { color: #080; text-decoration: underline;    }

/** 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;
		border-bottom-width: 3px !important;
		margin-bottom: 0px !important;
	}
	.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 .secno { font-size: 85%; }
	.toc > li li li li li { font-size:   85%;    }
	.toc > li li li li li .secno { font-size: 100%; }

	/* @supports not (display:grid) { */
		.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 {
			clear: both;
		}

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

	@supports (display:grid) {
		/* Use #toc over .toc to override non-@supports rules. */
		#toc {
			display: grid;
			align-content: start;
			grid-template-columns: auto 1fr;
			grid-column-gap: 1rem;
			column-gap: 1rem;
			grid-row-gap: .6rem;
			row-gap: .6rem;
		}
		#toc h2 {
			grid-column: 1 / -1;
			margin-bottom: 0;
		}
		#toc ol,
		#toc li,
		#toc a {
			display: contents;
			/* Switch <a> to subgrid when supported */
		}
		#toc span {
			margin: 0;
		}
		#toc > .toc > li > a > span {
			/* The spans of the top-level list,
			   comprising the first items of each top-level section. */
			margin-top: 1.1rem;
		}
		#toc#toc .secno { /* Ugh, need more specificity to override base.css */
			grid-column: 1;
			width: auto;
			margin-left: 0;
		}
		#toc .content {
			grid-column: 2;
			width: auto;
			margin-right: 1rem;
		}
		#toc .content:hover {
			background: rgba(75%, 75%, 75%, .25);
			border-bottom: 3px solid #054572;
			margin-bottom: -3px;
		}
		#toc li li li .content {
			margin-left: 1rem;
		}
		#toc li li li li .content {
			margin-left: 2rem;
		}
	}


/** 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>
<style type="text/css">
    table, th, td {
      border: 1px solid black;
      border-collapse: collapse;
      vertical-align: top;
    }
    th, td {
      border-left: none;
      border-right: none;
      padding: 0px 10px;
    }
    th {
      text-align: center;
    }
  </style>
  <meta content="Bikeshed version 47cb5324cd11789aef12f220cf86d1780f94ab9c" name="generator">
  <link href="wg21.tartanllama.xyz/monadic-optional" rel="canonical">
  <link href="https://isocpp.org/favicon.ico" rel="icon">
<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-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-line-numbers */

.line-numbered {
    display: grid !important;
    grid-template-columns: min-content 1fr;
    grid-auto-flow: row;
}
.line-numbered > *,
.line-numbered::before,
.line-numbered::after {
    grid-column: 1/-1;
}
.line-no {
    grid-column: 1;
    color: gray;
}
.line {
    grid-column: 2;
}
.line:hover {
    background: rgba(0,0,0,.05);
}
.line-no[data-line]::before {
    padding: 0 .5em 0 .1em;
    content: attr(data-line);
}
.line-no[data-line-end]::after {
    padding: 0 .5em 0 .1em;
    content: attr(data-line-end);
}
</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; }
c-[a] { color: #990055 } /* Keyword.Declaration */
c-[b] { color: #990055 } /* Keyword.Type */
c-[c] { color: #708090 } /* Comment */
c-[d] { color: #708090 } /* Comment.Multiline */
c-[e] { color: #0077aa } /* Name.Attribute */
c-[f] { color: #669900 } /* Name.Tag */
c-[g] { color: #222222 } /* Name.Variable */
c-[k] { color: #990055 } /* Keyword */
c-[l] { color: #000000 } /* Literal */
c-[m] { color: #000000 } /* Literal.Number */
c-[n] { color: #0077aa } /* Name */
c-[o] { color: #999999 } /* Operator */
c-[p] { color: #999999 } /* Punctuation */
c-[s] { color: #a67f59 } /* Literal.String */
c-[t] { color: #a67f59 } /* Literal.String.Single */
c-[u] { color: #a67f59 } /* Literal.String.Double */
c-[cp] { color: #708090 } /* Comment.Preproc */
c-[c1] { color: #708090 } /* Comment.Single */
c-[cs] { color: #708090 } /* Comment.Special */
c-[kc] { color: #990055 } /* Keyword.Constant */
c-[kn] { color: #990055 } /* Keyword.Namespace */
c-[kp] { color: #990055 } /* Keyword.Pseudo */
c-[kr] { color: #990055 } /* Keyword.Reserved */
c-[ld] { color: #000000 } /* Literal.Date */
c-[nc] { color: #0077aa } /* Name.Class */
c-[no] { color: #0077aa } /* Name.Constant */
c-[nd] { color: #0077aa } /* Name.Decorator */
c-[ni] { color: #0077aa } /* Name.Entity */
c-[ne] { color: #0077aa } /* Name.Exception */
c-[nf] { color: #0077aa } /* Name.Function */
c-[nl] { color: #0077aa } /* Name.Label */
c-[nn] { color: #0077aa } /* Name.Namespace */
c-[py] { color: #0077aa } /* Name.Property */
c-[ow] { color: #999999 } /* Operator.Word */
c-[mb] { color: #000000 } /* Literal.Number.Bin */
c-[mf] { color: #000000 } /* Literal.Number.Float */
c-[mh] { color: #000000 } /* Literal.Number.Hex */
c-[mi] { color: #000000 } /* Literal.Number.Integer */
c-[mo] { color: #000000 } /* Literal.Number.Oct */
c-[sb] { color: #a67f59 } /* Literal.String.Backtick */
c-[sc] { color: #a67f59 } /* Literal.String.Char */
c-[sd] { color: #a67f59 } /* Literal.String.Doc */
c-[se] { color: #a67f59 } /* Literal.String.Escape */
c-[sh] { color: #a67f59 } /* Literal.String.Heredoc */
c-[si] { color: #a67f59 } /* Literal.String.Interpol */
c-[sx] { color: #a67f59 } /* Literal.String.Other */
c-[sr] { color: #a67f59 } /* Literal.String.Regex */
c-[ss] { color: #a67f59 } /* Literal.String.Symbol */
c-[vc] { color: #0077aa } /* Name.Variable.Class */
c-[vg] { color: #0077aa } /* Name.Variable.Global */
c-[vi] { color: #0077aa } /* Name.Variable.Instance */
c-[il] { color: #000000 } /* Literal.Number.Integer.Long */
</style>
 </head><body class="h-entry toc-inline"><p id="toc-nav"><a id="toc-jump" href="#toc"><span aria-hidden="true">↑</span> <span>Jump to Table of Contents</span></a><a id="toc-toggle" href="#toc"><span aria-hidden="true">→</span> <span>Pop Out Sidebar</span></a></p>
  <div class="head">
   <p data-fill-with="logo"></p>
   <h1 class="p-name no-ref" id="title">p0798R2<br>Monadic operations for std::optional</h1>
   <h2 class="no-num no-toc no-ref heading settled" id="subtitle"><span class="content">Published Proposal, <time class="dt-updated" datetime="2018-10-08">2018-10-08</time></span></h2>
   <div data-fill-with="spec-metadata">
    <dl>
     <dt>This version:
     </dt><dd><a class="u-url" href="wg21.tartanllama.xyz/monadic-optional">wg21.tartanllama.xyz/monadic-optional</a>
     </dd><dt>Author:
     </dt><dd>
      </dd><dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:simon.brand@microsoft.com">Simon Brand</a>
     </dd><dt>Audience:
     </dt><dd>LEWG, SG14
     </dd><dt>Project:
     </dt><dd>ISO/IEC JTC1/SC22/WG21 14882: Programming Language — C++
    </dd></dl>
   </div>
   <div data-fill-with="warning"></div>
   <hr title="Separator for header">
  </div>
  <div class="p-summary" data-fill-with="abstract">
   <h2 class="no-num no-toc no-ref heading settled" id="abstract"><span class="content">Abstract</span></h2>
   <p>std::optional will be a very important vocabulary type in C++17 
and up. Some uses of it can be very verbose and would benefit from 
operations which allow functional composition. I propose adding map, 
and_then, and or_else member functions to std::optional to support this 
monadic style of programming.</p>
  </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="#changes-from-r1"><span class="secno">1</span> <span class="content">Changes from r1</span></a>
    </li><li><a href="#changes-from-r0"><span class="secno">2</span> <span class="content">Changes from r0</span></a>
    </li><li><a href="#motivation"><span class="secno">3</span> <span class="content">Motivation</span></a>
    </li><li>
     <a href="#proposed-solution"><span class="secno">4</span> <span class="content">Proposed solution</span></a>
     <ol class="toc">
      <li><a href="#map"><span class="secno">4.1</span> <span class="content"><code class="highlight"><c- n="">map</c-></code></span></a>
      </li><li><a href="#and_then"><span class="secno">4.2</span> <span class="content"><code class="highlight"><c- n="">and_then</c-></code></span></a>
      </li><li><a href="#or_else"><span class="secno">4.3</span> <span class="content"><code class="highlight"><c- n="">or_else</c-></code></span></a>
      </li><li><a href="#chaining"><span class="secno">4.4</span> <span class="content">Chaining</span></a>
     </li></ol>
    </li><li><a href="#how-other-languages-handle-this"><span class="secno">5</span> <span class="content">How other languages handle this</span></a>
    </li><li>
     <a href="#considerations"><span class="secno">6</span> <span class="content">Considerations</span></a>
     <ol class="toc">
      <li><a href="#mapping-functions-returning-void"><span class="secno">6.1</span> <span class="content">Mapping functions returning <code class="highlight"><c- b="">void</c-></code></span></a>
      </li><li><a href="#more-functions"><span class="secno">6.2</span> <span class="content">More functions</span></a>
      </li><li><a href="#map-only"><span class="secno">6.3</span> <span class="content"><code class="highlight"><c- n="">map</c-></code> only</span></a>
      </li><li><a href="#operator-overloading"><span class="secno">6.4</span> <span class="content">Operator overloading</span></a>
      </li><li><a href="#applicative-functors"><span class="secno">6.5</span> <span class="content">Applicative Functors</span></a>
      </li><li><a href="#alternative-names"><span class="secno">6.6</span> <span class="content">Alternative names</span></a>
      </li><li><a href="#overloaded-and_then"><span class="secno">6.7</span> <span class="content">Overloaded <code class="highlight"><c- n="">and_then</c-></code></span></a>
     </li></ol>
    </li><li>
     <a href="#pitfalls"><span class="secno">7</span> <span class="content">Pitfalls</span></a>
     <ol class="toc">
      <li><a href="#other-solutions"><span class="secno">7.1</span> <span class="content">Other solutions</span></a>
      </li><li><a href="#interaction-with-other-proposals"><span class="secno">7.2</span> <span class="content">Interaction with other proposals</span></a>
     </li></ol>
    </li><li><a href="#implementation-experience"><span class="secno">8</span> <span class="content">Implementation experience</span></a>
    </li><li>
     <a href="#proposed-wording"><span class="secno">9</span> <span class="content">Proposed Wording</span></a>
     <ol class="toc">
      <li><a href="#new-synopsis-entry-optionalmonadic-monadic-operations"><span class="secno">9.1</span> <span class="content">New synopsis entry: <code class="highlight"><c- p="">[</c-><c- n="">optional</c-><c- p="">.</c-><c- n="">monadic</c-><c- p="">]</c-></code>, monadic operations</span></a>
      </li><li><a href="#new-section-monadic-operations-optionalmonadic"><span class="secno">9.2</span> <span class="content">New section: Monadic operations <code class="highlight"><c- p="">[</c-><c- n="">optional</c-><c- p="">.</c-><c- n="">monadic</c-></code>]</span></a>
      </li><li><a href="#acknowledgements"><span class="secno">9.3</span> <span class="content">Acknowledgements</span></a>
     </li></ol>
   </li></ol>
  </nav>
  <main>
   <h2 class="heading settled" data-level="1" id="changes-from-r1"><span class="secno">1. </span><span class="content">Changes from r1</span><a class="self-link" href="#changes-from-r1"></a></h2>
   <ul>
    <li data-md="">
     <p>Add list of programming languages to proposed solution section</p>
    </li><li data-md="">
     <p>Change <code class="highlight"><c- n="">map</c-></code> example code to not take address of stdlib function</p>
    </li><li data-md="">
     <p>Update wording to use <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">monostate</c-></code> on <code class="highlight"><c- b="">void</c-></code> returning callables</p>
   </li></ul>
   <h2 class="heading settled" data-level="2" id="changes-from-r0"><span class="secno">2. </span><span class="content">Changes from r0</span><a class="self-link" href="#changes-from-r0"></a></h2>
   <ul>
    <li data-md="">
     <p>More notes on P0650</p>
    </li><li data-md="">
     <p>Discussion about mapping of functions returning <code class="highlight"><c- b="">void</c-></code></p>
   </li></ul>
   <h2 class="heading settled" data-level="3" id="motivation"><span class="secno">3. </span><span class="content">Motivation</span><a class="self-link" href="#motivation"></a></h2>
   <p><code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-></code> aims to be a "vocabulary type", i.e. the canonical type to represent some programming concept. As such, <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-></code>
 will become widely used to represent an object which may or may not 
contain a value. Unfortunately, chaining together many computations 
which may or may not produce a value can be verbose, as empty-checking 
code will be mixed in with the actual programming logic. As an example, 
the following code automatically extracts cats from images and makes 
them more cute:</p>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- n="">image</c-> <c- nf="">get_cute_cat</c-> <c- p="">(</c-><c- k="">const</c-> <c- n="">image</c-><c- o="">&amp;</c-> <c- n="">img</c-><c- p="">)</c-> <c- p="">{</c-></span><span class="line-no" data-line="2"></span><span class="line">    <c- k="">return</c-> <c- n="">add_rainbow</c-><c- p="">(</c-></span><span class="line-no" data-line="3"></span><span class="line">             <c- n="">make_smaller</c-><c- p="">(</c-></span><span class="line-no" data-line="4"></span><span class="line">               <c- n="">make_eyes_sparkle</c-><c- p="">(</c-></span><span class="line-no" data-line="5"></span><span class="line">                 <c- n="">add_bow_tie</c-><c- p="">(</c-></span><span class="line-no" data-line="6"></span><span class="line">                   <c- n="">crop_to_cat</c-><c- p="">(</c-><c- n="">img</c-><c- p="">))));</c-></span><span class="line-no" data-line="7"></span><span class="line"><c- p="">}</c-></span></pre>
   <p>But there’s a problem. What if there’s not a cat in the picture? 
What if there’s no good place to add a bow tie? What if it has its back 
turned and we can’t make its eyes sparkle? Some of these operations 
could fail.</p>
   <p>One option would be to throw exceptions on failure. However, there
 are many code bases which do not use exceptions for a variety of 
reasons. There’s also the possibility that we’re going to get <em>lots</em>
 of pictures without cats in them, in which case we’d be using 
exceptions for control flow. This is commonly seen as bad practice, and 
has an item warning against it in the <a href="https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#e3-use-exceptions-for-error-handling-only">C++ Core Guidelines</a>.</p>
   <p>Another option would be to make those operations which could fail return a <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-></code>:</p>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- n="">image</c-><c- o="">&gt;</c-> <c- n="">get_cute_cat</c-> <c- p="">(</c-><c- k="">const</c-> <c- n="">image</c-><c- o="">&amp;</c-> <c- n="">img</c-><c- p="">)</c-> <c- p="">{</c-></span><span class="line-no" data-line="2"></span><span class="line">    <c- k="">auto</c-> <c- n="">cropped</c-> <c- o="">=</c-> <c- n="">crop_to_cat</c-><c- p="">(</c-><c- n="">img</c-><c- p="">);</c-></span><span class="line-no" data-line="3"></span><span class="line">    <c- k="">if</c-> <c- p="">(</c-><c- o="">!</c-><c- n="">cropped</c-><c- p="">)</c-> <c- p="">{</c-></span><span class="line-no" data-line="4"></span><span class="line">      <c- k="">return</c-> <c- n="">std</c-><c- o="">::</c-><c- n="">nullopt</c-><c- p="">;</c-></span><span class="line-no" data-line="5"></span><span class="line">    <c- p="">}</c-></span><span class="line-no" data-line="6"></span><span class="line"></span><span class="line-no" data-line="7"></span><span class="line">    <c- k="">auto</c-> <c- n="">with_tie</c-> <c- o="">=</c-> <c- n="">add_bow_tie</c-><c- p="">(</c-><c- o="">*</c-><c- n="">cropped</c-><c- p="">);</c-></span><span class="line-no" data-line="8"></span><span class="line">    <c- k="">if</c-> <c- p="">(</c-><c- o="">!</c-><c- n="">with_tie</c-><c- p="">)</c-> <c- p="">{</c-></span><span class="line-no" data-line="9"></span><span class="line">      <c- k="">return</c-> <c- n="">std</c-><c- o="">::</c-><c- n="">nullopt</c-><c- p="">;</c-></span><span class="line-no" data-line="10"></span><span class="line">    <c- p="">}</c-></span><span class="line-no" data-line="11"></span><span class="line"></span><span class="line-no" data-line="12"></span><span class="line">    <c- k="">auto</c-> <c- n="">with_sparkles</c-> <c- o="">=</c-> <c- n="">make_eyes_sparkle</c-><c- p="">(</c-><c- o="">*</c-><c- n="">with_tie</c-><c- p="">);</c-></span><span class="line-no" data-line="13"></span><span class="line">    <c- k="">if</c-> <c- p="">(</c-><c- o="">!</c-><c- n="">with_sparkles</c-><c- p="">)</c-> <c- p="">{</c-></span><span class="line-no" data-line="14"></span><span class="line">      <c- k="">return</c-> <c- n="">std</c-><c- o="">::</c-><c- n="">nullopt</c-><c- p="">;</c-></span><span class="line-no" data-line="15"></span><span class="line">    <c- p="">}</c-></span><span class="line-no" data-line="16"></span><span class="line"></span><span class="line-no" data-line="17"></span><span class="line">    <c- k="">return</c-> <c- n="">add_rainbow</c-><c- p="">(</c-><c- n="">make_smaller</c-><c- p="">(</c-><c- o="">*</c-><c- n="">with_sparkles</c-><c- p="">));</c-></span><span class="line-no" data-line="18"></span><span class="line"><c- p="">}</c-></span></pre>
   <p>Our code now has a lot of boilerplate to deal with the case where a
 step fails. Not only does this increase the noise and cognitive load of
 the function, but if we forget to put in a check, then suddenly we’re 
down the hole of undefined behaviour if we <code class="highlight"><c- o="">*</c-><c- n="">empty_optional</c-></code>.</p>
   <p>Another possibility would be to call <code class="highlight"><c- p="">.</c-><c- n="">value</c-><c- p="">()</c-></code> on the optionals and let the exception be thrown and caught like so:</p>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- n="">image</c-><c- o="">&gt;</c-> <c- n="">get_cute_cat</c-> <c- p="">(</c-><c- k="">const</c-> <c- n="">image</c-><c- o="">&amp;</c-> <c- n="">img</c-><c- p="">)</c-> <c- p="">{</c-></span><span class="line-no" data-line="2"></span><span class="line">    <c- k="">try</c-> <c- p="">{</c-></span><span class="line-no" data-line="3"></span><span class="line">        <c- k="">auto</c-> <c- n="">cropped</c-> <c- o="">=</c-> <c- n="">crop_to_cat</c-><c- p="">(</c-><c- n="">img</c-><c- p="">);</c-></span><span class="line-no" data-line="4"></span><span class="line">        <c- k="">auto</c-> <c- n="">with_tie</c-> <c- o="">=</c-> <c- n="">add_bow_tie</c-><c- p="">(</c-><c- n="">cropped</c-><c- p="">.</c-><c- n="">value</c-><c- p="">());</c-></span><span class="line-no" data-line="5"></span><span class="line">        <c- k="">auto</c-> <c- n="">with_sparkles</c-> <c- o="">=</c-> <c- n="">make_eyes_sparkle</c-><c- p="">(</c-><c- n="">with_tie</c-><c- p="">.</c-><c- n="">value</c-><c- p="">());</c-></span><span class="line-no" data-line="6"></span><span class="line">        <c- k="">return</c-> <c- nf="">add_rainbow</c-><c- p="">(</c-><c- n="">make_smaller</c-><c- p="">(</c-><c- n="">with_sparkles</c-><c- p="">.</c-><c- n="">value</c-><c- p="">()));</c-></span><span class="line-no" data-line="7"></span><span class="line">    <c- k="">catch</c-> <c- p="">(</c-><c- n="">std</c-><c- o="">::</c-><c- n="">bad_optional_access</c-><c- o="">&amp;</c-> <c- n="">e</c-><c- p="">)</c-> <c- p="">{</c-></span><span class="line-no" data-line="8"></span><span class="line">        <c- k="">return</c-> <c- n="">std</c-><c- o="">::</c-><c- n="">nullopt</c-><c- p="">;</c-></span><span class="line-no" data-line="9"></span><span class="line">    <c- p="">}</c-></span><span class="line-no" data-line="10"></span><span class="line"><c- p="">}</c-></span></pre>
   <p>Again, this is using exceptions for control flow. There must be a better way.</p>
   <h2 class="heading settled" data-level="4" id="proposed-solution"><span class="secno">4. </span><span class="content">Proposed solution</span><a class="self-link" href="#proposed-solution"></a></h2>
   <p>This paper proposes adding additional member functions to <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-></code> in order to push the handling of empty states off to the side. The proposed additions are <code class="highlight"><c- n="">map</c-></code>, <code class="highlight"><c- n="">and_then</c-></code> and <code class="highlight"><c- n="">or_else</c-></code>. Using these new functions, the code above becomes this:</p>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- n="">image</c-><c- o="">&gt;</c-> <c- n="">get_cute_cat</c-> <c- p="">(</c-><c- k="">const</c-> <c- n="">image</c-><c- o="">&amp;</c-> <c- n="">img</c-><c- p="">)</c-> <c- p="">{</c-></span><span class="line-no" data-line="2"></span><span class="line">    <c- k="">return</c-> <c- n="">crop_to_cat</c-><c- p="">(</c-><c- n="">img</c-><c- p="">)</c-></span><span class="line-no" data-line="3"></span><span class="line">           <c- p="">.</c-><c- n="">and_then</c-><c- p="">(</c-><c- n="">add_bow_tie</c-><c- p="">)</c-></span><span class="line-no" data-line="4"></span><span class="line">           <c- p="">.</c-><c- n="">and_then</c-><c- p="">(</c-><c- n="">make_eyes_sparkle</c-><c- p="">)</c-></span><span class="line-no" data-line="5"></span><span class="line">           <c- p="">.</c-><c- n="">map</c-><c- p="">(</c-><c- n="">make_smaller</c-><c- p="">)</c-></span><span class="line-no" data-line="6"></span><span class="line">           <c- p="">.</c-><c- n="">map</c-><c- p="">(</c-><c- n="">add_rainbow</c-><c- p="">);</c-></span><span class="line-no" data-line="7"></span><span class="line"><c- p="">}</c-></span></pre>
   <p>We’ve successfully got rid of all the manual checking. We’ve even 
improved on the clarity of the non-optional example, which needed to 
either be read inside-out or split into multiple declarations.</p>
   <p>This is common in other programming languages. Here is a list of programming languages which have a <code class="highlight"><c- n="">optional</c-></code>-like type with a monadic interface or some similar syntactic sugar:</p>
   <ul>
    <li data-md="">
     <p>Java: <code class="highlight"><c- n="">Optional</c-></code></p>
    </li><li data-md="">
     <p>Swift: <code class="highlight"><c- n="">Optional</c-></code></p>
    </li><li data-md="">
     <p>Haskell: <code class="highlight"><c- n="">Maybe</c-></code></p>
    </li><li data-md="">
     <p>Rust: <code class="highlight"><c- n="">Option</c-></code></p>
    </li><li data-md="">
     <p>OCaml: <code class="highlight"><c- n="">option</c-></code></p>
    </li><li data-md="">
     <p>Scala: <code class="highlight"><c- n="">Option</c-></code></p>
    </li><li data-md="">
     <p>Agda: <code class="highlight"><c- n="">Maybe</c-></code></p>
    </li><li data-md="">
     <p>Idris: <code class="highlight"><c- n="">Maybe</c-></code></p>
    </li><li data-md="">
     <p>Kotlin: <code class="highlight"><c- n="">T</c-><c- o="">?</c-></code></p>
    </li><li data-md="">
     <p>StandardML: <code class="highlight"><c- n="">option</c-></code></p>
    </li><li data-md="">
     <p>C#: <code class="highlight"><c- n="">Nullable</c-></code></p>
   </li></ul>
   <p>Here is a list of programming languages which have a <code class="highlight"><c- n="">optional</c-></code>-like type <em>without</em> a monadic interface or syntactic sugar:</p>
   <ul>
    <li data-md="">
     <p>C++</p>
    </li><li data-md="">
     <p>I couldn’t find any others</p>
   </li></ul>
   <p>All that we need now is an understanding of what <code class="highlight"><c- n="">map</c-></code> and <code class="highlight"><c- n="">and_then</c-></code> do and how to use them.</p>
   <h3 class="heading settled" data-level="4.1" id="map"><span class="secno">4.1. </span><span class="content"><code class="highlight"><c- n="">map</c-></code></span><a class="self-link" href="#map"></a></h3>
   <p><code class="highlight"><c- n="">map</c-></code> applies a 
function to the value stored in the optional and returns the result 
wrapped in an optional. If there is no stored value, then it returns an 
empty optional.</p>
   <p>For example, if you have a <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- n="">std</c-><c- o="">::</c-><c- n="">string</c-><c- o="">&gt;</c-></code> and you want to get a <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- n="">std</c-><c- o="">::</c-><c- b="">size_t</c-><c- o="">&gt;</c-></code> giving the size of the string if one is available, you could write this:</p>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- k="">auto</c-> <c- n="">s</c-> <c- o="">=</c-> <c- n="">opt_string</c-><c- p="">.</c-><c- n="">map</c-><c- p="">([](</c-><c- k="">auto</c-><c- o="">&amp;&amp;</c-> <c- n="">s</c-><c- p="">)</c-> <c- p="">{</c-> <c- k="">return</c-> <c- n="">s</c-><c- p="">.</c-><c- n="">size</c-><c- p="">();</c-> <c- p="">});</c-></span></pre>
   <p>which is somewhat equivalent to:</p>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- k="">if</c-> <c- p="">(</c-><c- n="">opt_string</c-><c- p="">)</c-> <c- p="">{</c-></span><span class="line-no" data-line="2"></span><span class="line">    <c- n="">std</c-><c- o="">::</c-><c- b="">size_t</c-> <c- n="">s</c-> <c- o="">=</c-> <c- n="">opt_string</c-><c- o="">-&gt;</c-><c- n="">size</c-><c- p="">();</c-></span><span class="line-no" data-line="3"></span><span class="line"><c- p="">}</c-></span></pre>
   <p><code class="highlight"><c- n="">map</c-></code> has one overload (expositional):</p>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">T</c-><c- o="">&gt;</c-></span><span class="line-no" data-line="2"></span><span class="line"><c- k="">class</c-> <c- nc="">optional</c-> <c- p="">{</c-></span><span class="line-no" data-line="3"></span><span class="line">    <c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">Return</c-><c- o="">&gt;</c-></span><span class="line-no" data-line="4"></span><span class="line">    <c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- n="">Return</c-><c- o="">&gt;</c-> <c- n="">map</c-> <c- p="">(</c-><c- n="">function</c-><c- o="">&lt;</c-><c- n="">Return</c-><c- p="">(</c-><c- n="">T</c-><c- p="">)</c-><c- o="">&gt;</c-> <c- n="">func</c-><c- p="">);</c-></span><span class="line-no" data-line="5"></span><span class="line"><c- p="">};</c-></span></pre>
   <p>It takes any callable object (like a function). If the <code class="highlight"><c- n="">optional</c-></code>
 does not have a value stored, then an empty optional is returned. 
Otherwise, the given function is called with the stored value as an 
argument, and the return value is returned inside an <code class="highlight"><c- n="">optional</c-></code>.</p>
   <p>If you come from a functional programming or category theory background, you may recognise this as a functor map.</p>
   <h3 class="heading settled" data-level="4.2" id="and_then"><span class="secno">4.2. </span><span class="content"><code class="highlight"><c- n="">and_then</c-></code></span><a class="self-link" href="#and_then"></a></h3>
   <p><code class="highlight"><c- n="">and_then</c-></code> is like <code class="highlight"><c- n="">map</c-></code>, but it is used on functions which may not return a value.</p>
   <p>For example, say you have <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- n="">std</c-><c- o="">::</c-><c- n="">string</c-><c- o="">&gt;</c-></code> and a function like <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">stoi</c-></code> which returns a <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- b="">int</c-><c- o="">&gt;</c-></code> instead of throwing on failure. Rather than manually checking the optional string before calling, you could do this:</p>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- b="">int</c-><c- o="">&gt;</c-> <c- n="">i</c-> <c- o="">=</c-> <c- n="">opt_string</c-><c- p="">.</c-><c- n="">and_then</c-><c- p="">(</c-><c- n="">stoi</c-><c- p="">);</c-></span></pre>
   <p>Which is roughly equivalent to:</p>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- k="">if</c-> <c- p="">(</c-><c- n="">opt_string</c-><c- p="">)</c-> <c- p="">{</c-></span><span class="line-no" data-line="2"></span><span class="line">   <c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- b="">int</c-><c- o="">&gt;</c-> <c- n="">i</c-> <c- o="">=</c-> <c- n="">stoi</c-><c- p="">(</c-><c- o="">*</c-><c- n="">opt_string</c-><c- p="">);</c-></span><span class="line-no" data-line="3"></span><span class="line"><c- p="">}</c-></span></pre>
   <p><code class="highlight"><c- n="">and_then</c-></code> has one overload which looks like this (again, expositional):</p>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">T</c-><c- o="">&gt;</c-></span><span class="line-no" data-line="2"></span><span class="line"><c- k="">class</c-> <c- nc="">optional</c-> <c- p="">{</c-></span><span class="line-no" data-line="3"></span><span class="line">    <c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">Return</c-><c- o="">&gt;</c-></span><span class="line-no" data-line="4"></span><span class="line">    <c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- n="">Return</c-><c- o="">&gt;</c-> <c- n="">and_then</c-> <c- p="">(</c-><c- n="">function</c-><c- o="">&lt;</c-><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- n="">Return</c-><c- o="">&gt;</c-><c- p="">(</c-><c- n="">T</c-><c- p="">)</c-><c- o="">&gt;</c-> <c- n="">func</c-><c- p="">);</c-></span><span class="line-no" data-line="5"></span><span class="line"><c- p="">};</c-></span></pre>
   <p>It takes any callable object which returns a <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-></code>.
 If the optional does not have a value stored, then an empty optional is
 returned. Otherwise, the given function is called with the stored value
 as an argument, and the return value is returned.</p>
   <p>Again, those from an FP background will recognise this as a monadic bind.</p>
   <h3 class="heading settled" data-level="4.3" id="or_else"><span class="secno">4.3. </span><span class="content"><code class="highlight"><c- n="">or_else</c-></code></span><a class="self-link" href="#or_else"></a></h3>
   <p><code class="highlight"><c- n="">or_else</c-></code> returns the 
optional if it has a value, otherwise it calls a given function. This 
allows you do things like logging or throwing exceptions in monadic 
contexts:</p>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- n="">get_opt</c-><c- p="">().</c-><c- n="">or_else</c-><c- p="">([]{</c-><c- n="">std</c-><c- o="">::</c-><c- n="">cout</c-> <c- o="">&lt;&lt;</c-> <c- s="">"get_opt failed"</c-><c- p="">;});</c-></span><span class="line-no" data-line="2"></span><span class="line"><c- n="">get_opt</c-><c- p="">().</c-><c- n="">or_else</c-><c- p="">([]{</c-><c- k="">throw</c-> <c- n="">std</c-><c- o="">::</c-><c- n="">runtime_error</c-><c- p="">(</c-><c- s="">"get_opt_failed"</c-><c- p="">)});</c-></span></pre>
   <p>Users can easily abstract these patterns if they are common:</p>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- b="">void</c-> <c- nf="">opt_log</c-><c- p="">(</c-><c- n="">std</c-><c- o="">::</c-><c- n="">string_view</c-> <c- n="">msg</c-><c- p="">)</c-> <c- p="">{</c-></span><span class="line-no" data-line="2"></span><span class="line">     <c- k="">return</c-> <c- p="">[</c-><c- o="">=</c-><c- p="">]</c-> <c- p="">{</c-> <c- n="">std</c-><c- o="">::</c-><c- n="">cout</c-> <c- o="">&lt;&lt;</c-> <c- n="">msg</c-><c- p="">;</c-> <c- p="">};</c-></span><span class="line-no" data-line="3"></span><span class="line"><c- p="">}</c-></span><span class="line-no" data-line="4"></span><span class="line"></span><span class="line-no" data-line="5"></span><span class="line"><c- b="">void</c-> <c- nf="">opt_throw</c-><c- p="">(</c-><c- n="">std</c-><c- o="">::</c-><c- n="">string_view</c-> <c- n="">msg</c-><c- p="">)</c-> <c- p="">{</c-></span><span class="line-no" data-line="6"></span><span class="line">     <c- k="">return</c-> <c- p="">[</c-><c- o="">=</c-><c- p="">]</c-> <c- p="">{</c-> <c- k="">throw</c-> <c- n="">std</c-><c- o="">::</c-><c- n="">runtime_error</c-><c- p="">(</c-><c- n="">msg</c-><c- p="">);</c-> <c- p="">};</c-></span><span class="line-no" data-line="7"></span><span class="line"><c- p="">}</c-></span><span class="line-no" data-line="8"></span><span class="line"></span><span class="line-no" data-line="9"></span><span class="line"><c- n="">get_opt</c-><c- p="">().</c-><c- n="">or_else</c-><c- p="">(</c-><c- n="">opt_log</c-><c- p="">(</c-><c- s="">"get_opt failed"</c-><c- p="">));</c-></span><span class="line-no" data-line="10"></span><span class="line"><c- n="">get_opt</c-><c- p="">().</c-><c- n="">or_else</c-><c- p="">(</c-><c- n="">opt_throw</c-><c- p="">(</c-><c- s="">"get_opt failed"</c-><c- p="">));</c-></span></pre>
   <p>It has one overload (expositional):</p>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">T</c-><c- o="">&gt;</c-></span><span class="line-no" data-line="2"></span><span class="line"><c- k="">class</c-> <c- nc="">optional</c-> <c- p="">{</c-></span><span class="line-no" data-line="3"></span><span class="line">    <c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">Return</c-><c- o="">&gt;</c-></span><span class="line-no" data-line="4"></span><span class="line">    <c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- n="">T</c-><c- o="">&gt;</c-> <c- n="">or_else</c-> <c- p="">(</c-><c- n="">function</c-><c- o="">&lt;</c-><c- n="">Return</c-><c- p="">()</c-><c- o="">&gt;</c-> <c- n="">func</c-><c- p="">);</c-></span><span class="line-no" data-line="5"></span><span class="line"><c- p="">};</c-></span></pre>
   <p><code class="highlight"><c- n="">func</c-></code> will be called if <code class="highlight"><c- o="">*</c-><c- k="">this</c-></code> is empty. <code class="highlight"><c- n="">Return</c-></code> will either be convertible to <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- n="">T</c-><c- o="">&gt;</c-></code>, or <code class="highlight"><c- b="">void</c-></code>. In the former case, the return of <code class="highlight"><c- n="">func</c-></code> will be returned from <code class="highlight"><c- n="">or_else</c-></code>; in the second case <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">nullopt</c-></code> will be returned.</p>
   <h3 class="heading settled" data-level="4.4" id="chaining"><span class="secno">4.4. </span><span class="content">Chaining</span><a class="self-link" href="#chaining"></a></h3>
   <p>With these two functions, doing a lot of chaining of functions which could fail becomes very clean:</p>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- b="">int</c-><c- o="">&gt;</c-> <c- n="">foo</c-><c- p="">()</c-> <c- p="">{</c-></span><span class="line-no" data-line="2"></span><span class="line">    <c- k="">return</c-></span><span class="line-no" data-line="3"></span><span class="line">      <c- n="">a</c-><c- p="">().</c-><c- n="">and_then</c-><c- p="">(</c-><c- n="">b</c-><c- p="">)</c-></span><span class="line-no" data-line="4"></span><span class="line">         <c- p="">.</c-><c- n="">and_then</c-><c- p="">(</c-><c- n="">c</c-><c- p="">)</c-></span><span class="line-no" data-line="5"></span><span class="line">         <c- p="">.</c-><c- n="">and_then</c-><c- p="">(</c-><c- n="">d</c-><c- p="">)</c-></span><span class="line-no" data-line="6"></span><span class="line">         <c- p="">.</c-><c- n="">and_then</c-><c- p="">(</c-><c- n="">e</c-><c- p="">);</c-></span><span class="line-no" data-line="7"></span><span class="line"><c- p="">}</c-></span></pre>
   <p>Taking the example of <code class="highlight"><c- n="">stoi</c-></code> from earlier, we could carry out mathematical operations on the result by just adding <code class="highlight"><c- n="">map</c-></code> calls:</p>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- b="">int</c-><c- o="">&gt;</c-> <c- n="">i</c-> <c- o="">=</c-> <c- n="">opt_string</c-></span><span class="line-no" data-line="2"></span><span class="line">                       <c- p="">.</c-><c- n="">and_then</c-><c- p="">(</c-><c- n="">stoi</c-><c- p="">)</c-></span><span class="line-no" data-line="3"></span><span class="line">                       <c- p="">.</c-><c- n="">map</c-><c- p="">([](</c-><c- k="">auto</c-> <c- n="">i</c-><c- p="">)</c-> <c- p="">{</c-> <c- k="">return</c-> <c- n="">i</c-> <c- o="">*</c-> <c- mi="">2</c-><c- p="">;</c-> <c- p="">});</c-></span></pre>
   <p>We can also intersperse our chain with error checking code:</p>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- b="">int</c-><c- o="">&gt;</c-> <c- n="">i</c-> <c- o="">=</c-> <c- n="">opt_string</c-></span><span class="line-no" data-line="2"></span><span class="line">                       <c- p="">.</c-><c- n="">and_then</c-><c- p="">(</c-><c- n="">stoi</c-><c- p="">)</c-></span><span class="line-no" data-line="3"></span><span class="line">                       <c- p="">.</c-><c- n="">or_else</c-><c- p="">(</c-><c- n="">opt_throw</c-><c- p="">(</c-><c- s="">"stoi failed"</c-><c- p="">))</c-></span><span class="line-no" data-line="4"></span><span class="line">                       <c- p="">.</c-><c- n="">map</c-><c- p="">([](</c-><c- k="">auto</c-> <c- n="">i</c-><c- p="">)</c-> <c- p="">{</c-> <c- k="">return</c-> <c- n="">i</c-> <c- o="">*</c-> <c- mi="">2</c-><c- p="">;</c-> <c- p="">});</c-></span></pre>
   <h2 class="heading settled" data-level="5" id="how-other-languages-handle-this"><span class="secno">5. </span><span class="content">How other languages handle this</span><a class="self-link" href="#how-other-languages-handle-this"></a></h2>
   <p><code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-></code> is known as <code class="highlight"><c- n="">Maybe</c-></code> in Haskell and it provides much the same functionality. <code class="highlight"><c- n="">map</c-></code> is in <code class="highlight"><c- n="">Functor</c-></code> and named <code class="highlight"><c- n="">fmap</c-></code>, and <code class="highlight"><c- n="">and_then</c-></code> is in <code class="highlight"><c- n="">Monad</c-></code> and named <code class="highlight"><c- o="">&gt;&gt;=</c-></code> (bind).</p>
   <p>Rust has an <code class="highlight"><c- n="">Option</c-></code> class, and uses the same names as are proposed in this paper. It also provides many additional member functions like <code class="highlight"><c- n="">or</c-></code>, <code class="highlight"><c- n="">and</c-></code>, <code class="highlight"><c- n="">map_or_else</c-></code>.</p>
   <h2 class="heading settled" data-level="6" id="considerations"><span class="secno">6. </span><span class="content">Considerations</span><a class="self-link" href="#considerations"></a></h2>
   <h3 class="heading settled" data-level="6.1" id="mapping-functions-returning-void"><span class="secno">6.1. </span><span class="content">Mapping functions returning <code class="highlight"><c- b="">void</c-></code></span><a class="self-link" href="#mapping-functions-returning-void"></a></h3>
   <p>There are three main options for handling <code class="highlight"><c- b="">void</c-></code> returning functions for <code class="highlight"><c- n="">map</c-></code>. The simplest is to disallow it (this is what <code class="highlight"><c- n="">boost</c-><c- o="">::</c-><c- n="">optional</c-></code> does). One is to return <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- n="">std</c-><c- o="">::</c-><c- n="">monostate</c-><c- o="">&gt;</c-></code> (or some other unit type) instead of <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- b="">void</c-><c- o="">&gt;</c-></code> (this is what <code class="highlight"><c- n="">tl</c-><c- o="">::</c-><c- n="">optional</c-></code> does). Another option is to add a <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- b="">void</c-><c- o="">&gt;</c-></code>
 specialization. This proposal uses the second approach. This 
functionality can be desirable since it allows chaining functions which 
are used purely for side effects.</p>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- n="">get_optional</c-><c- p="">()</c->          <c- c1="">// returns std::optional&lt;T&gt;</c-></span><span class="line-no" data-line="2"></span><span class="line">  <c- p="">.</c-><c- n="">map</c-><c- p="">(</c-><c- n="">print_value</c-><c- p="">)</c->     <c- c1="">// returns std::optional&lt;std::monostate&gt;</c-></span><span class="line-no" data-line="3"></span><span class="line">  <c- p="">.</c-><c- n="">map</c-><c- p="">(</c-><c- n="">notify_success</c-><c- p="">);</c-> <c- c1="">// Is only called when get_optional returned a value</c-></span></pre>
   <h3 class="heading settled" data-level="6.2" id="more-functions"><span class="secno">6.2. </span><span class="content">More functions</span><a class="self-link" href="#more-functions"></a></h3>
   <p>Rust’s <a href="https://doc.rust-lang.org/std/option/enum.Option.html">Option</a> class provides a lot more than <code class="highlight"><c- n="">map</c-></code>, <code class="highlight"><c- n="">and_then</c-></code> and <code class="highlight"><c- n="">or_else</c-></code>. If the idea to add these is received favourably, then we can think about what other additions we may want to make.</p>
   <h3 class="heading settled" data-level="6.3" id="map-only"><span class="secno">6.3. </span><span class="content"><code class="highlight"><c- n="">map</c-></code> only</span><a class="self-link" href="#map-only"></a></h3>
   <p>It would be possible to merge all of these into a single function 
which handles all use cases. However, I think this would make the 
function more difficult to teach and understand.</p>
   <h3 class="heading settled" data-level="6.4" id="operator-overloading"><span class="secno">6.4. </span><span class="content">Operator overloading</span><a class="self-link" href="#operator-overloading"></a></h3>
   <p>We could provide operator overloads with the same semantics as the functions. For example, <code class="highlight"><c- o="">|</c-></code> could mean <code class="highlight"><c- n="">map</c-></code>, <code class="highlight"><c- o="">&gt;=</c-></code> <code class="highlight"><c- n="">and_then</c-></code>, and <code class="highlight"><c- o="">&amp;</c-></code> <code class="highlight"><c- n="">or_else</c-></code>. Rewriting the original example gives this:</p>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- c1="">// original</c-></span><span class="line-no" data-line="2"></span><span class="line"><c- n="">crop_to_cat</c-><c- p="">(</c-><c- n="">img</c-><c- p="">)</c-></span><span class="line-no" data-line="3"></span><span class="line">  <c- p="">.</c-><c- n="">and_then</c-><c- p="">(</c-><c- n="">add_bow_tie</c-><c- p="">)</c-></span><span class="line-no" data-line="4"></span><span class="line">  <c- p="">.</c-><c- n="">and_then</c-><c- p="">(</c-><c- n="">make_eyes_sparkle</c-><c- p="">)</c-></span><span class="line-no" data-line="5"></span><span class="line">  <c- p="">.</c-><c- n="">map</c-><c- p="">(</c-><c- n="">make_smaller</c-><c- p="">)</c-></span><span class="line-no" data-line="6"></span><span class="line">  <c- p="">.</c-><c- n="">map</c-><c- p="">(</c-><c- n="">add_rainbow</c-><c- p="">);</c-></span><span class="line-no" data-line="7"></span><span class="line"></span><span class="line-no" data-line="8"></span><span class="line"><c- c1="">// rewritten</c-></span><span class="line-no" data-line="9"></span><span class="line"><c- n="">crop_to_cat</c-><c- p="">(</c-><c- n="">img</c-><c- p="">)</c-></span><span class="line-no" data-line="10"></span><span class="line">   <c- o="">&gt;=</c-> <c- n="">add_bow_tie</c-></span><span class="line-no" data-line="11"></span><span class="line">   <c- o="">&gt;=</c-> <c- n="">make_eyes_sparkle</c-></span><span class="line-no" data-line="12"></span><span class="line">    <c- o="">|</c-> <c- n="">make_smaller</c-></span><span class="line-no" data-line="13"></span><span class="line">    <c- o="">|</c-> <c- n="">add_rainbow</c-><c- p="">;</c-></span></pre>
   <p>Another option would be <code class="highlight"><c- o="">&gt;&gt;</c-></code> for <code class="highlight"><c- n="">and_then</c-></code>.</p>
   <h3 class="heading settled" data-level="6.5" id="applicative-functors"><span class="secno">6.5. </span><span class="content">Applicative Functors</span><a class="self-link" href="#applicative-functors"></a></h3>
   <p><code class="highlight"><c- n="">map</c-></code> could be overloaded to accept callables wrapped in <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">optionals</c-></code>. This fits the <em>applicative functor</em> concept. It would look like this:</p>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">Return</c-><c- o="">&gt;</c-></span><span class="line-no" data-line="2"></span><span class="line"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- n="">Return</c-><c- o="">&gt;</c-> <c- n="">map</c-> <c- p="">(</c-><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- n="">function</c-><c- o="">&lt;</c-><c- n="">Return</c-><c- p="">(</c-><c- n="">T</c-><c- p="">)</c-><c- o="">&gt;&gt;</c-> <c- n="">func</c-><c- p="">);</c-></span></pre>
   <p>This would give functional programmers the set of operations which
 they may expect from a monadic-style interface. However, I couldn’t 
think of many use-cases of this in C++. If some are found then we could 
add the extra overload.</p>
   <h3 class="heading settled" data-level="6.6" id="alternative-names"><span class="secno">6.6. </span><span class="content">Alternative names</span><a class="self-link" href="#alternative-names"></a></h3>
   <p><code class="highlight"><c- n="">map</c-></code> may confuse users
 who are more familiar with its use as a data structure, or consider the
 common array map from other languages to be different from this 
application. Some other possible names are <code class="highlight"><c- n="">then</c-></code>, <code class="highlight"><c- n="">when_value</c-></code>, <code class="highlight"><c- n="">fmap</c-></code>, <code class="highlight"><c- n="">transform</c-></code>.</p>
   <p>Alternative names for <code class="highlight"><c- n="">and_then</c-></code> are <code class="highlight"><c- n="">bind</c-></code>, <code class="highlight"><c- n="">compose</c-></code>, <code class="highlight"><c- n="">chain</c-></code>.</p>
   <p><code class="highlight"><c- n="">or_else</c-></code> could be named <code class="highlight"><c- n="">catch_error</c-></code>, in line with <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0650r0.pdf">P0650r0</a></p>
   <h3 class="heading settled" data-level="6.7" id="overloaded-and_then"><span class="secno">6.7. </span><span class="content">Overloaded <code class="highlight"><c- n="">and_then</c-></code></span><a class="self-link" href="#overloaded-and_then"></a></h3>
   <p>Instead of an additional <code class="highlight"><c- n="">or_else</c-></code> function, <code class="highlight"><c- n="">and_then</c-></code> could be overloaded to take an additional error function:</p>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- n="">o</c-><c- p="">.</c-><c- n="">and_then</c-><c- p="">(</c-><c- n="">a</c-><c- p="">,</c-> <c- p="">[]{</c-><c- k="">throw</c-> <c- n="">std</c-><c- o="">::</c-><c- n="">runtime_error</c-><c- p="">(</c-><c- s="">"oh no"</c-><c- p="">);});</c-></span></pre>
   <p>The above will throw if <code class="highlight"><c- n="">a</c-></code> returns an empty optional.</p>
   <h2 class="heading settled" data-level="7" id="pitfalls"><span class="secno">7. </span><span class="content">Pitfalls</span><a class="self-link" href="#pitfalls"></a></h2>
   <p>Users may want to write code like this:</p>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- b="">int</c-><c- o="">&gt;</c-> <c- n="">foo</c-><c- p="">(</c-><c- b="">int</c-> <c- n="">i</c-><c- p="">)</c-> <c- p="">{</c-></span><span class="line-no" data-line="2"></span><span class="line">    <c- k="">return</c-></span><span class="line-no" data-line="3"></span><span class="line">      <c- n="">a</c-><c- p="">().</c-><c- n="">and_then</c-><c- p="">(</c-><c- n="">b</c-><c- p="">)</c-></span><span class="line-no" data-line="4"></span><span class="line">         <c- p="">.</c-><c- n="">and_then</c-><c- p="">(</c-><c- n="">get_func</c-><c- p="">(</c-><c- n="">i</c-><c- p="">));</c-></span><span class="line-no" data-line="5"></span><span class="line"><c- p="">}</c-></span></pre>
   <p>The problem with this is <code class="highlight"><c- n="">get_func</c-></code> will be called regardless of whether <code class="highlight"><c- n="">b</c-></code> returns an empty <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-></code> or not. If it has side effects, then this may not be what the user wants.</p>
   <p>One possible solution to this would be to add an additional function, <code class="highlight"><c- n="">bind_with</c-></code> which will take a callable which provides what you want to bind to:</p>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- b="">int</c-><c- o="">&gt;</c-> <c- n="">foo</c-><c- p="">(</c-><c- b="">int</c-> <c- n="">i</c-><c- p="">)</c-> <c- p="">{</c-></span><span class="line-no" data-line="2"></span><span class="line">    <c- k="">return</c-></span><span class="line-no" data-line="3"></span><span class="line">      <c- n="">a</c-><c- p="">().</c-><c- n="">and_then</c-><c- p="">(</c-><c- n="">b</c-><c- p="">)</c-></span><span class="line-no" data-line="4"></span><span class="line">         <c- p="">.</c-><c- n="">bind_with</c-><c- p="">([</c-><c- n="">i</c-><c- p="">](){</c-><c- k="">return</c-> <c- n="">get_func</c-><c- p="">(</c-><c- n="">i</c-><c- p="">)});</c-></span><span class="line-no" data-line="5"></span><span class="line"><c- p="">}</c-></span></pre>
   <h3 class="heading settled" data-level="7.1" id="other-solutions"><span class="secno">7.1. </span><span class="content">Other solutions</span><a class="self-link" href="#other-solutions"></a></h3>
   <p>There is a proposal for adding a <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0650r0.pdf">general monadic interface</a>
 to C++. Unfortunately doing the kind of composition described above 
would be very verbose with the current proposal without some kind of 
Haskell-style <code class="highlight"><c- k="">do</c-></code> notation. The code for my first solution above would look like this:</p>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- b="">int</c-><c- o="">&gt;</c-> <c- n="">get_cute_cat</c-><c- p="">(</c-><c- k="">const</c-> <c- n="">image</c-><c- o="">&amp;</c-> <c- n="">img</c-><c- p="">)</c-> <c- p="">{</c-></span><span class="line-no" data-line="2"></span><span class="line">    <c- k="">return</c-></span><span class="line-no" data-line="3"></span><span class="line">      <c- n="">functor</c-><c- o="">::</c-><c- n="">map</c-><c- p="">(</c-></span><span class="line-no" data-line="4"></span><span class="line">        <c- n="">functor</c-><c- o="">::</c-><c- n="">map</c-><c- p="">(</c-></span><span class="line-no" data-line="5"></span><span class="line">          <c- n="">monad</c-><c- o="">::</c-><c- n="">bind</c-><c- p="">(</c-></span><span class="line-no" data-line="6"></span><span class="line">            <c- n="">monad</c-><c- o="">::</c-><c- n="">bind</c-><c- p="">(</c-><c- n="">crop_to_cat</c-><c- p="">(</c-><c- n="">img</c-><c- p="">),</c-></span><span class="line-no" data-line="7"></span><span class="line">              <c- n="">add_bow_tie</c-><c- p="">),</c-></span><span class="line-no" data-line="8"></span><span class="line">            <c- n="">make_eyes_sparkle</c-><c- p="">),</c-></span><span class="line-no" data-line="9"></span><span class="line">         <c- n="">make_smaller</c-><c- p="">),</c-></span><span class="line-no" data-line="10"></span><span class="line">      <c- n="">add_rainbow</c-><c- p="">);</c-></span><span class="line-no" data-line="11"></span><span class="line"><c- p="">}</c-></span></pre>
   <p>My proposal is not necessarily an alternative to this proposal; 
compatibility between the two could be ensured and the generic proposal 
could use my proposal as part of its implementation. This would allow 
users to use both the generic syntax for flexibility and extensibility, 
and the member-function syntax for brevity and clarity.</p>
   <p>If <code class="highlight"><c- k="">do</c-></code> notation or <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0301r1.html">unified call syntax</a>
 is accepted, then my proposal may not be necessary, as use of the 
generic monadic functionality would allow the same or similarly concise 
syntax.</p>
   <p>Another option would be to use a ranges-style interface for the general monadic interface:</p>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- b="">int</c-><c- o="">&gt;</c-> <c- n="">get_cute_cat</c-><c- p="">(</c-><c- k="">const</c-> <c- n="">image</c-><c- o="">&amp;</c-> <c- n="">img</c-><c- p="">)</c-> <c- p="">{</c-></span><span class="line-no" data-line="2"></span><span class="line">    <c- k="">return</c-> <c- n="">crop_to_cat</c-><c- p="">(</c-><c- n="">img</c-><c- p="">)</c-></span><span class="line-no" data-line="3"></span><span class="line">         <c- o="">|</c-> <c- n="">monad</c-><c- o="">::</c-><c- n="">bind</c-><c- p="">(</c-><c- n="">add_bow_tie</c-><c- p="">)</c-></span><span class="line-no" data-line="4"></span><span class="line">         <c- o="">|</c-> <c- n="">monad</c-><c- o="">::</c-><c- n="">bind</c-><c- p="">(</c-><c- n="">make_eyes_sparkle</c-><c- p="">)</c-></span><span class="line-no" data-line="5"></span><span class="line">         <c- o="">|</c-> <c- n="">functor</c-><c- o="">::</c-><c- n="">map</c-><c- p="">(</c-><c- n="">make_smaller</c-><c- p="">)</c-></span><span class="line-no" data-line="6"></span><span class="line">         <c- o="">|</c-> <c- n="">functor</c-><c- o="">::</c-><c- n="">map</c-><c- p="">(</c-><c- n="">add_rainbow</c-><c- p="">);</c-></span><span class="line-no" data-line="7"></span><span class="line"><c- p="">}</c-></span></pre>
   <h3 class="heading settled" data-level="7.2" id="interaction-with-other-proposals"><span class="secno">7.2. </span><span class="content">Interaction with other proposals</span><a class="self-link" href="#interaction-with-other-proposals"></a></h3>
   <p>There is a proposal for <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0323r2.pdf">std::expected</a>
 which would benefit from many of these same ideas. If the idea to add 
monadic interfaces to standard library classes on a case-by-case basis 
is chosen rather than a unified non-member function interface, then 
compatibility between this proposal and the <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">expected</c-></code> one should be maintained.</p>
   <p>Mapping functions which return <code class="highlight"><c- b="">void</c-></code> can be supported, but is a pain to implement since <code class="highlight"><c- b="">void</c-></code> is not a regular type. If the <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0146r1.html">Regular Void</a>
 proposal was accepted, implementation would be simpler and the results 
of the operation would conform to users' expectations better.</p>
   <p>Any proposals which make lambdas or overload sets easier to write 
and pass around will greatly improve this proposal. In particular, 
proposals for <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3617.htm">lift operators</a> and <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0573r0.html">abbreviated lambdas</a> would ensure that the clean style is preserved in the face of many anonymous functions and overloads.</p>
   <p>If an operator overloading approach is taken and the <a href="https://wg21.link/p1282">workflow operator</a> (<code class="highlight"><c- k="">operator</c-><c- o="">|&gt;</c-></code>) is accepted, then that could be used instead of <code class="highlight"><c- k="">operator</c-><c- o="">|</c-></code>.</p>
   <h2 class="heading settled" data-level="8" id="implementation-experience"><span class="secno">8. </span><span class="content">Implementation experience</span><a class="self-link" href="#implementation-experience"></a></h2>
   <p>This proposal has been implemented <a href="https://github.com/TartanLlama/monadic-optional">here</a>.</p>
   <hr>
   <h2 class="heading settled" data-level="9" id="proposed-wording"><span class="secno">9. </span><span class="content">Proposed Wording</span><a class="self-link" href="#proposed-wording"></a></h2>
   <h3 class="heading settled" data-level="9.1" id="new-synopsis-entry-optionalmonadic-monadic-operations"><span class="secno">9.1. </span><span class="content">New synopsis entry: <code class="highlight"><c- p="">[</c-><c- n="">optional</c-><c- p="">.</c-><c- n="">monadic</c-><c- p="">]</c-></code>, monadic operations</span><a class="self-link" href="#new-synopsis-entry-optionalmonadic-monadic-operations"></a></h3>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">F</c-><c- o="">&gt;</c-> <c- k="">constexpr</c-> <c- o="">*</c-><c- n="">see</c-> <c- n="">below</c-><c- o="">*</c-> <c- n="">and_then</c-><c- p="">(</c-><c- n="">F</c-><c- o="">&amp;&amp;</c-> <c- n="">f</c-><c- p="">)</c-> <c- o="">&amp;</c-><c- p="">;</c-></span><span class="line-no" data-line="2"></span><span class="line"><c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">F</c-><c- o="">&gt;</c-> <c- k="">constexpr</c-> <c- o="">*</c-><c- n="">see</c-> <c- n="">below</c-><c- o="">*</c-> <c- n="">and_then</c-><c- p="">(</c-><c- n="">F</c-><c- o="">&amp;&amp;</c-> <c- n="">f</c-><c- p="">)</c-> <c- o="">&amp;&amp;</c-><c- p="">;</c-></span><span class="line-no" data-line="3"></span><span class="line"><c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">F</c-><c- o="">&gt;</c-> <c- k="">constexpr</c-> <c- o="">*</c-><c- n="">see</c-> <c- n="">below</c-><c- o="">*</c-> <c- n="">and_then</c-><c- p="">(</c-><c- n="">F</c-><c- o="">&amp;&amp;</c-> <c- n="">f</c-><c- p="">)</c-> <c- k="">const</c-><c- o="">&amp;</c-><c- p="">;</c-></span><span class="line-no" data-line="4"></span><span class="line"><c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">F</c-><c- o="">&gt;</c-> <c- k="">constexpr</c-> <c- o="">*</c-><c- n="">see</c-> <c- n="">below</c-><c- o="">*</c-> <c- n="">and_then</c-><c- p="">(</c-><c- n="">F</c-><c- o="">&amp;&amp;</c-> <c- n="">f</c-><c- p="">)</c-> <c- k="">const</c-><c- o="">&amp;&amp;</c-><c- p="">;</c-></span><span class="line-no" data-line="5"></span><span class="line"><c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">F</c-><c- o="">&gt;</c-> <c- k="">constexpr</c-> <c- o="">*</c-><c- n="">see</c-> <c- n="">below</c-><c- o="">*</c-> <c- n="">map</c-><c- p="">(</c-><c- n="">F</c-><c- o="">&amp;&amp;</c-> <c- n="">f</c-><c- p="">)</c-> <c- o="">&amp;</c-><c- p="">;</c-></span><span class="line-no" data-line="6"></span><span class="line"><c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">F</c-><c- o="">&gt;</c-> <c- k="">constexpr</c-> <c- o="">*</c-><c- n="">see</c-> <c- n="">below</c-><c- o="">*</c-> <c- n="">map</c-><c- p="">(</c-><c- n="">F</c-><c- o="">&amp;&amp;</c-> <c- n="">f</c-><c- p="">)</c-> <c- o="">&amp;&amp;</c-><c- p="">;</c-></span><span class="line-no" data-line="7"></span><span class="line"><c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">F</c-><c- o="">&gt;</c-> <c- k="">constexpr</c-> <c- o="">*</c-><c- n="">see</c-> <c- n="">below</c-><c- o="">*</c-> <c- n="">map</c-><c- p="">(</c-><c- n="">F</c-><c- o="">&amp;&amp;</c-> <c- n="">f</c-><c- p="">)</c-> <c- k="">const</c-><c- o="">&amp;</c-><c- p="">;</c-></span><span class="line-no" data-line="8"></span><span class="line"><c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">F</c-><c- o="">&gt;</c-> <c- k="">constexpr</c-> <c- o="">*</c-><c- n="">see</c-> <c- n="">below</c-><c- o="">*</c-> <c- n="">map</c-><c- p="">(</c-><c- n="">F</c-><c- o="">&amp;&amp;</c-> <c- n="">f</c-><c- p="">)</c-> <c- k="">const</c-><c- o="">&amp;&amp;</c-><c- p="">;</c-></span><span class="line-no" data-line="9"></span><span class="line"><c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">F</c-><c- o="">&gt;</c-> <c- k="">constexpr</c-> <c- n="">optional</c-><c- o="">&lt;</c-><c- n="">T</c-><c- o="">&gt;</c-> <c- n="">or_else</c-><c- p="">(</c-><c- n="">F</c-> <c- o="">&amp;&amp;</c-><c- n="">f</c-><c- p="">)</c-> <c- o="">&amp;</c-><c- p="">;</c-></span><span class="line-no" data-line="10"></span><span class="line"><c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">F</c-><c- o="">&gt;</c-> <c- k="">constexpr</c-> <c- n="">optional</c-><c- o="">&lt;</c-><c- n="">T</c-><c- o="">&gt;</c-> <c- n="">or_else</c-><c- p="">(</c-><c- n="">F</c-> <c- o="">&amp;&amp;</c-><c- n="">f</c-><c- p="">)</c-> <c- o="">&amp;&amp;</c-><c- p="">;</c-></span><span class="line-no" data-line="11"></span><span class="line"><c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">F</c-><c- o="">&gt;</c-> <c- k="">constexpr</c-> <c- n="">optional</c-><c- o="">&lt;</c-><c- n="">T</c-><c- o="">&gt;</c-> <c- n="">or_else</c-><c- p="">(</c-><c- n="">F</c-> <c- o="">&amp;&amp;</c-><c- n="">f</c-><c- p="">)</c-> <c- k="">const</c-><c- o="">&amp;</c-><c- p="">;</c-></span><span class="line-no" data-line="12"></span><span class="line"><c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">F</c-><c- o="">&gt;</c-> <c- k="">constexpr</c-> <c- n="">optional</c-><c- o="">&lt;</c-><c- n="">T</c-><c- o="">&gt;</c-> <c- n="">or_else</c-><c- p="">(</c-><c- n="">F</c-> <c- o="">&amp;&amp;</c-><c- n="">f</c-><c- p="">)</c-> <c- k="">const</c-><c- o="">&amp;&amp;</c-><c- p="">;</c-></span></pre>
   <h3 class="heading settled" data-level="9.2" id="new-section-monadic-operations-optionalmonadic"><span class="secno">9.2. </span><span class="content">New section: Monadic operations <code class="highlight"><c- p="">[</c-><c- n="">optional</c-><c- p="">.</c-><c- n="">monadic</c-></code>]</span><a class="self-link" href="#new-section-monadic-operations-optionalmonadic"></a></h3>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">F</c-><c- o="">&gt;</c-> <c- k="">constexpr</c-> <c- o="">*</c-><c- n="">see</c-> <c- n="">below</c-><c- o="">*</c-> <c- n="">and_then</c-><c- p="">(</c-><c- n="">F</c-><c- o="">&amp;&amp;</c-> <c- n="">f</c-><c- p="">)</c-> <c- o="">&amp;</c-><c- p="">;</c-></span><span class="line-no" data-line="2"></span><span class="line"><c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">F</c-><c- o="">&gt;</c-> <c- k="">constexpr</c-> <c- o="">*</c-><c- n="">see</c-> <c- n="">below</c-><c- o="">*</c-> <c- n="">and_then</c-><c- p="">(</c-><c- n="">F</c-><c- o="">&amp;&amp;</c-> <c- n="">f</c-><c- p="">)</c-> <c- k="">const</c-><c- o="">&amp;</c-><c- p="">;</c-></span></pre>
   <p><em>Requires</em>: <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">invoke</c-><c- p="">(</c-><c- n="">std</c-><c- o="">::</c-><c- n="">forward</c-><c- o="">&lt;</c-><c- n="">F</c-><c- o="">&gt;</c-><c- p="">(</c-><c- n="">f</c-><c- p="">),</c-> <c- n="">value</c-><c- p="">())</c-></code> returns a <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- n="">U</c-><c- o="">&gt;</c-></code> for some <code class="highlight"><c- n="">U</c-></code>.</p>
   <p><em>Returns</em>: Let <code class="highlight"><c- n="">U</c-></code> be the result of <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">invoke</c-><c- p="">(</c-><c- n="">std</c-><c- o="">::</c-><c- n="">forward</c-><c- o="">&lt;</c-><c- n="">F</c-><c- o="">&gt;</c-><c- p="">(</c-><c- n="">f</c-><c- p="">),</c-> <c- n="">value</c-><c- p="">())</c-></code>. Returns a <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- n="">U</c-><c- o="">&gt;</c-></code>. If <code class="highlight"><c- o="">*</c-><c- k="">this</c-></code> contains a value then <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">invoke</c-><c- p="">(</c-><c- n="">std</c-><c- o="">::</c-><c- n="">forward</c-><c- o="">&lt;</c-><c- n="">F</c-><c- o="">&gt;</c-><c- p="">(</c-><c- n="">f</c-><c- p="">),</c-> <c- n="">value</c-><c- p="">())</c-></code> is returned, otherwise the returned <code class="highlight"><c- n="">optional</c-></code> does not contain a value.</p>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">F</c-><c- o="">&gt;</c-> <c- k="">constexpr</c-> <c- o="">*</c-><c- n="">see</c-> <c- n="">below</c-><c- o="">*</c-> <c- n="">and_then</c-><c- p="">(</c-><c- n="">F</c-><c- o="">&amp;&amp;</c-> <c- n="">f</c-><c- p="">)</c-> <c- o="">&amp;&amp;</c-><c- p="">;</c-></span><span class="line-no" data-line="2"></span><span class="line"><c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">F</c-><c- o="">&gt;</c-> <c- k="">constexpr</c-> <c- o="">*</c-><c- n="">see</c-> <c- n="">below</c-><c- o="">*</c-> <c- n="">and_then</c-><c- p="">(</c-><c- n="">F</c-><c- o="">&amp;&amp;</c-> <c- n="">f</c-><c- p="">)</c-> <c- k="">const</c-><c- o="">&amp;&amp;</c-><c- p="">;</c-></span></pre>
   <p><em>Requires</em>: <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">invoke</c-><c- p="">(</c-><c- n="">std</c-><c- o="">::</c-><c- n="">forward</c-><c- o="">&lt;</c-><c- n="">F</c-><c- o="">&gt;</c-><c- p="">(</c-><c- n="">f</c-><c- p="">),</c-> <c- n="">std</c-><c- o="">::</c-><c- n="">move</c-><c- p="">(</c-><c- n="">value</c-><c- p="">()))</c-></code> returns a <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- n="">U</c-><c- o="">&gt;</c-></code> for some <code class="highlight"><c- n="">U</c-></code>.</p>
   <p><em>Returns</em>: Let <code class="highlight"><c- n="">U</c-></code> be the result of <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">invoke</c-><c- p="">(</c-><c- n="">std</c-><c- o="">::</c-><c- n="">forward</c-><c- o="">&lt;</c-><c- n="">F</c-><c- o="">&gt;</c-><c- p="">(</c-><c- n="">f</c-><c- p="">),</c-> <c- n="">std</c-><c- o="">::</c-><c- n="">move</c-><c- p="">(</c-><c- n="">value</c-><c- p="">()))</c-></code>. Returns a <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- n="">U</c-><c- o="">&gt;</c-></code>. If <code class="highlight"><c- o="">*</c-><c- k="">this</c-></code> contains a value then <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">invoke</c-><c- p="">(</c-><c- n="">std</c-><c- o="">::</c-><c- n="">forward</c-><c- o="">&lt;</c-><c- n="">F</c-><c- o="">&gt;</c-><c- p="">(</c-><c- n="">f</c-><c- p="">),</c-> <c- n="">std</c-><c- o="">::</c-><c- n="">move</c-><c- p="">(</c-><c- n="">value</c-><c- p="">())</c-></code> is returned, otherwise the returned <code class="highlight"><c- n="">optional</c-></code> does not contain a value.</p>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">F</c-><c- o="">&gt;</c-> <c- k="">constexpr</c-> <c- o="">*</c-><c- n="">see</c-> <c- n="">below</c-><c- o="">*</c-> <c- n="">map</c-><c- p="">(</c-><c- n="">F</c-><c- o="">&amp;&amp;</c-> <c- n="">f</c-><c- p="">)</c-> <c- o="">&amp;</c-><c- p="">;</c-></span><span class="line-no" data-line="2"></span><span class="line"><c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">F</c-><c- o="">&gt;</c-> <c- k="">constexpr</c-> <c- o="">*</c-><c- n="">see</c-> <c- n="">below</c-><c- o="">*</c-> <c- n="">map</c-><c- p="">(</c-><c- n="">F</c-><c- o="">&amp;&amp;</c-> <c- n="">f</c-><c- p="">)</c-> <c- k="">const</c-><c- o="">&amp;</c-><c- p="">;</c-></span></pre>
   <p><em>Returns</em>: Let <code class="highlight"><c- n="">U</c-></code> be the result of <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">invoke</c-><c- p="">(</c-><c- n="">std</c-><c- o="">::</c-><c- n="">forward</c-><c- o="">&lt;</c-><c- n="">F</c-><c- o="">&gt;</c-><c- p="">(</c-><c- n="">f</c-><c- p="">),</c-> <c- n="">value</c-><c- p="">())</c-></code>.</p>
   <ul>
    <li data-md="">
     <p>If <code class="highlight"><c- n="">U</c-></code> is <code class="highlight"><c- b="">void</c-></code>, returns a <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- n="">std</c-><c- o="">::</c-><c- n="">monostate</c-><c- o="">&gt;</c-></code>. If <code class="highlight"><c- o="">*</c-><c- k="">this</c-></code> contains a value then <code class="highlight"><c- n="">f</c-></code> is invoked as if by <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">invoke</c-><c- p="">(</c-><c- n="">std</c-><c- o="">::</c-><c- n="">forward</c-><c- o="">&lt;</c-><c- n="">F</c-><c- o="">&gt;</c-><c- p="">(</c-><c- n="">f</c-><c- p="">),</c-> <c- n="">value</c-><c- p="">())</c-></code> and the returned <code class="highlight"><c- n="">optional</c-></code> will contain a default-constructed <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">monostate</c-></code> value; otherwise the returned <code class="highlight"><c- n="">optional</c-></code> will not contain a value.</p>
    </li><li data-md="">
     <p>If <code class="highlight"><c- n="">U</c-></code> is not <code class="highlight"><c- b="">void</c-></code>, returns a <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- n="">U</c-><c- o="">&gt;</c-></code>. If <code class="highlight"><c- o="">*</c-><c- k="">this</c-></code> contains a value then an <code class="highlight"><c- n="">optional</c-><c- o="">&lt;</c-><c- n="">U</c-><c- o="">&gt;</c-></code> is constructed from <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">invoke</c-><c- p="">(</c-><c- n="">std</c-><c- o="">::</c-><c- n="">forward</c-><c- o="">&lt;</c-><c- n="">F</c-><c- o="">&gt;</c-><c- p="">(</c-><c- n="">f</c-><c- p="">),</c-> <c- n="">value</c-><c- p="">())</c-></code> and returned, otherwise the returned <code class="highlight"><c- n="">optional</c-></code> does not contain a value.</p>
   </li></ul>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">F</c-><c- o="">&gt;</c-> <c- k="">constexpr</c-> <c- o="">*</c-><c- n="">see</c-> <c- n="">below</c-><c- o="">*</c-> <c- n="">map</c-><c- p="">(</c-><c- n="">F</c-><c- o="">&amp;&amp;</c-> <c- n="">f</c-><c- p="">)</c-> <c- o="">&amp;&amp;</c-><c- p="">;</c-></span><span class="line-no" data-line="2"></span><span class="line"><c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">F</c-><c- o="">&gt;</c-> <c- k="">constexpr</c-> <c- o="">*</c-><c- n="">see</c-> <c- n="">below</c-><c- o="">*</c-> <c- n="">map</c-><c- p="">(</c-><c- n="">F</c-><c- o="">&amp;&amp;</c-> <c- n="">f</c-><c- p="">)</c-> <c- k="">const</c-><c- o="">&amp;&amp;</c-><c- p="">;</c-></span></pre>
   <p><em>Returns</em>: Let <code class="highlight"><c- n="">U</c-></code> be the result of <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">invoke</c-><c- p="">(</c-><c- n="">std</c-><c- o="">::</c-><c- n="">forward</c-><c- o="">&lt;</c-><c- n="">F</c-><c- o="">&gt;</c-><c- p="">(</c-><c- n="">f</c-><c- p="">),</c-> <c- n="">std</c-><c- o="">::</c-><c- n="">move</c-><c- p="">(</c-><c- n="">value</c-><c- p="">()))</c-></code>.</p>
   <ul>
    <li data-md="">
     <p>If <code class="highlight"><c- n="">U</c-></code> is <code class="highlight"><c- b="">void</c-></code>, returns a <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- n="">std</c-><c- o="">::</c-><c- n="">monostate</c-><c- o="">&gt;</c-></code>. If <code class="highlight"><c- o="">*</c-><c- k="">this</c-></code> contains a value then <code class="highlight"><c- n="">f</c-></code> is invoked as if by <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">invoke</c-><c- p="">(</c-><c- n="">std</c-><c- o="">::</c-><c- n="">forward</c-><c- o="">&lt;</c-><c- n="">F</c-><c- o="">&gt;</c-><c- p="">(</c-><c- n="">f</c-><c- p="">),</c-> <c- n="">std</c-><c- o="">::</c-><c- n="">move</c-><c- p="">(</c-><c- n="">value</c-><c- p="">()))</c-></code> and the returned <code class="highlight"><c- n="">optional</c-></code> will contain a default-constructed <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">monostate</c-></code> value; otherwise the returned <code class="highlight"><c- n="">optional</c-></code> will not contain a value.</p>
    </li><li data-md="">
     <p>If <code class="highlight"><c- n="">U</c-></code> is not <code class="highlight"><c- b="">void</c-></code>, returns a <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">optional</c-><c- o="">&lt;</c-><c- n="">U</c-><c- o="">&gt;</c-></code>. If <code class="highlight"><c- o="">*</c-><c- k="">this</c-></code> contains a value then an <code class="highlight"><c- n="">optional</c-><c- o="">&lt;</c-><c- n="">U</c-><c- o="">&gt;</c-></code> is constructed from <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">invoke</c-><c- p="">(</c-><c- n="">std</c-><c- o="">::</c-><c- n="">forward</c-><c- o="">&lt;</c-><c- n="">F</c-><c- o="">&gt;</c-><c- p="">(</c-><c- n="">f</c-><c- p="">),</c-> <c- n="">std</c-><c- o="">::</c-><c- n="">move</c-><c- p="">(</c-><c- n="">value</c-><c- p="">())</c-></code> and returned, otherwise the returned <code class="highlight"><c- n="">optional</c-></code> does not contain a value.</p>
   </li></ul>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">F</c-><c- o="">&gt;</c-> <c- k="">constexpr</c-> <c- n="">optional</c-><c- o="">&lt;</c-><c- n="">T</c-><c- o="">&gt;</c-> <c- n="">or_else</c-><c- p="">(</c-><c- n="">F</c-> <c- o="">&amp;&amp;</c-><c- n="">f</c-><c- p="">)</c-> <c- o="">&amp;</c-><c- p="">;</c-></span><span class="line-no" data-line="2"></span><span class="line"><c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">F</c-><c- o="">&gt;</c-> <c- k="">constexpr</c-> <c- n="">optional</c-><c- o="">&lt;</c-><c- n="">T</c-><c- o="">&gt;</c-> <c- n="">or_else</c-><c- p="">(</c-><c- n="">F</c-> <c- o="">&amp;&amp;</c-><c- n="">f</c-><c- p="">)</c-> <c- k="">const</c-><c- o="">&amp;</c-><c- p="">;</c-></span></pre>
   <p><em>Requires</em>: <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">invoke_result_t</c-><c- o="">&lt;</c-><c- n="">F</c-><c- o="">&gt;</c-></code> must be <code class="highlight"><c- b="">void</c-></code> or convertible to <code class="highlight"><c- n="">optional</c-><c- o="">&lt;</c-><c- n="">T</c-><c- o="">&gt;</c-></code>.</p>
   <p><em>Effects</em>: If <code class="highlight"><c- o="">*</c-><c- k="">this</c-></code> has a value, returns <code class="highlight"><c- o="">*</c-><c- k="">this</c-></code>. Otherwise, if <code class="highlight"><c- n="">f</c-></code> returns void, calls <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">forward</c-><c- o="">&lt;</c-><c- n="">F</c-><c- o="">&gt;</c-><c- p="">(</c-><c- n="">f</c-><c- p="">)</c-></code> and returns <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">nullopt</c-></code>. Otherwise, returns <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">forward</c-><c- o="">&lt;</c-><c- n="">F</c-><c- o="">&gt;</c-><c- p="">(</c-><c- n="">f</c-><c- p="">)()</c-></code>;</p>
<pre class="highlight line-numbered"><span class="line-no" data-line="1"></span><span class="line"><c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">F</c-><c- o="">&gt;</c-> <c- k="">constexpr</c-> <c- n="">optional</c-><c- o="">&lt;</c-><c- n="">T</c-><c- o="">&gt;</c-> <c- n="">or_else</c-><c- p="">(</c-><c- n="">F</c-> <c- o="">&amp;&amp;</c-><c- n="">f</c-><c- p="">)</c-> <c- o="">&amp;&amp;</c-><c- p="">;</c-></span><span class="line-no" data-line="2"></span><span class="line"><c- k="">template</c-> <c- o="">&lt;</c-><c- k="">class</c-> <c- nc="">F</c-><c- o="">&gt;</c-> <c- k="">constexpr</c-> <c- n="">optional</c-><c- o="">&lt;</c-><c- n="">T</c-><c- o="">&gt;</c-> <c- n="">or_else</c-><c- p="">(</c-><c- n="">F</c-> <c- o="">&amp;&amp;</c-><c- n="">f</c-><c- p="">)</c-> <c- k="">const</c-><c- o="">&amp;&amp;</c-><c- p="">;</c-></span></pre>
   <p><em>Requires</em>: <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">invoke_result_t</c-><c- o="">&lt;</c-><c- n="">F</c-><c- o="">&gt;</c-></code> must be <code class="highlight"><c- b="">void</c-></code> or convertible to <code class="highlight"><c- n="">optional</c-><c- o="">&lt;</c-><c- n="">T</c-><c- o="">&gt;</c-></code>.</p>
   <p><em>Effects</em>: If <code class="highlight"><c- o="">*</c-><c- k="">this</c-></code> has a value, returns <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">move</c-><c- p="">(</c-><c- o="">*</c-><c- k="">this</c-><c- p="">)</c-></code>. Otherwise, if <code class="highlight"><c- n="">f</c-></code> returns void, calls <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">forward</c-><c- o="">&lt;</c-><c- n="">F</c-><c- o="">&gt;</c-><c- p="">(</c-><c- n="">f</c-><c- p="">)</c-></code> and returns <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">nullopt</c-></code>. Otherwise, returns <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">forward</c-><c- o="">&lt;</c-><c- n="">F</c-><c- o="">&gt;</c-><c- p="">(</c-><c- n="">f</c-><c- p="">)()</c-></code>;</p>
   <hr>
   <h3 class="heading settled" data-level="9.3" id="acknowledgements"><span class="secno">9.3. </span><span class="content">Acknowledgements</span><a class="self-link" href="#acknowledgements"></a></h3>
   <p>Thank you to Michael Wong for representing this paper to the 
committee. Thanks to Kenneth Benzie, Vittorio Romeo, Jonathan Müller, 
Adi Shavit, Nicol Bolas, Vicente Escribá and Barry Revzin for review and
 suggestions.</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></body></html>