<!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>P2226R0: A proposal for an idiom to move from an object and reset it to its default constructed state</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)
 *
 ******************************************************************************/

/* color variables included separately for reliability */

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

	html {
		color: black;
		color: var(--text);
		background-color: white;
		background-color: var(--bg);
	}

	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;

		background: transparent 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: solid var(--logo-bg);
		border-width: .65rem .7rem .6rem;
		border-radius: .4rem;
		background: #1a5e9a;
		background: var(--logo-bg);
		color: white;
		color: var(--logo-text);
		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;
		background: var(--logo-active-bg);
		border-color: #c00;
		border-color: var(--logo-active-bg);
	}

	/* 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;
		}
		#toc-nav > a {
			display: block;
			white-space: nowrap;

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

			box-shadow: 0 0 2px;
			border: none;
			border-top-right-radius: 1.33em;

			color: #707070;
			color: var(--tocnav-normal-text);
			background: white;
			background: var(--tocnav-normal-bg);
		}
		#toc-nav > a:hover,
		#toc-nav > a:focus {
			color: black;
			color: var(--tocnav-hover-text);
			background: #f8f8f8;
			background: var(--tocnav-hover-bg);
		}
		#toc-nav > a:active {
			color: #c00;
			color: var(--tocnav-active-text);
			background: white;
			background: var(--tocnav-active-bg);
		}

		#toc-nav > #toc-jump {
			padding-bottom: 2em;
			margin-bottom: -1.9em;
		}

		/* 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 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);
			color: black;
			color: var(--tocsidebar-text);
			background: inherit;
			background-color: #f7f8f9;
			background-color: var(--tocsidebar-bg);
			z-index: 1;
			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) inset;
			box-shadow: -.1em 0 .25em var(--tocsidebar-shadow) 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);
			color: var(--tocsidebar-heading-text);
		}
		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);
			color: black;
			color: var(--tocsidebar-text);
			background: inherit;
			background-color: #f7f8f9;
			background-color: var(--tocsidebar-bg);
			z-index: 1;
			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) inset;
			box-shadow: -.1em 0 .25em var(--tocsidebar-shadow) 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);
			color: var(--tocsidebar-heading-text);
		}

		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;
		color: var(--heading-text);
	}

	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) > :not(.head) + hr {
		font-size: 1.5em;
		text-align: center;
		margin: 1em auto;
		height: auto;
		color: black;
		color: var(--hr-text);
		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;
	 border-left: 0.5em solid var(--algo-border);
	}

	/* Put nice boxes around each algorithm. */
	[data-algorithm]:not(.heading) {
	  padding: .5em;
	  border: thin solid #ddd;
	  border: thin solid var(--algo-border);
	  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;
		color: var(--del-text);
		background: transparent;
		background: var(--del-bg);
		text-decoration: line-through;
	}
	ins {
		color: #080;
		color: var(--ins-text);
		background: transparent;
		background: var(--ins-bg);
		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;
		hyphens: none;
		text-transform: none;
		text-align: left;
		text-align: start;
		font-variant: normal;
		orphans: 3;
		widows: 3;
		page-break-before: avoid;
	}
	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;
		color: var(--a-normal-text);
		text-decoration: none;
		border-bottom: 1px solid #707070;
		border-bottom: 1px solid var(--a-normal-underline);
		/* Need a bit of extending for it to look okay */
		padding: 0 1px 0;
		margin: 0 -1px 0;
	}
	a:visited {
		color: #034575;
		color: var(--a-visited-text);
		border-bottom-color: #bbb;
		border-bottom-color: var(--a-visited-underline);
	}

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

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

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

	img {
		border-style: none;
	}

	img, svg {
		/* Intentionally not color-scheme aware. */
		background: white;
	}

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


	.issue::before, .issue > .marker,
	.example::before, .example > .marker,
	.note::before, .note > .marker,
	details.note > summary > .marker {
		text-transform: uppercase;
		padding-right: 1em;
	}

	.example::before, .example > .marker {
		display: block;
		padding-right: 0em;
	}

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

	blockquote {
		border-color: silver;
		border-color: var(--blockquote-border);
		background: transparent;
		background: var(--blockquote-bg);
		color: currentcolor;
		color: var(--blockquote-text);
	}

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

	.issue {
		border-color: #e05252;
		border-color: var(--issue-border);
		background: #fbe9e9;
		background: var(--issue-bg);
		color: black;
		color: var(--issue-text);
		counter-increment: issue;
		overflow: auto;
	}
	.issue::before, .issue > .marker {
		color: #831616;
		color: var(--issueheading-text);
	}
	/* 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;
		border-color: var(--example-border);
		background: #fcfaee;
		background: var(--example-bg);
		color: black;
		color: var(--example-text);
		counter-increment: example;
		overflow: auto;
		clear: both;
	}
	.example::before, .example > .marker {
		color: #574b0f;
		color: var(--exampleheading-text);
	}
	/* 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;
		border-color: var(--note-border);
		background: #e9fbe9;
		background: var(--note-bg);
		color: black;
		color: var(--note-text);
		overflow: auto;
	}

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

	details.note[open] > summary {
		border-bottom: 1px silver solid;
		border-bottom: 1px var(--notesummary-underline) solid;
	}

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

	.assertion {
		border-color: #AAA;
		border-color: var(--assertion-border);
		background: #EEE;
		background: var(--assertion-bg);
		color: black;
		color: var(--assertion-text);
	}

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

	.advisement {
		border-color: orange;
		border-color: var(--advisement-border);
		border-style: none solid;
		background: #fec;
		background: var(--advisement-bg);
		color: black;
		color: var(--advisement-text);
	}
	strong.advisement {
		display: block;
		text-align: center;
	}
	.advisement::before, .advisement > .marker {
		color: #b35f00;
		color: var(--advisementheading-text);
	}

/** 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: hsla(40,100%,50%,0.95);
		background: var(--warning-bg);
		color: black;
		color: var(--warning-text);
		padding: .75em 1em;
		border: red;
		border: var(--warning-border);
		border-style: solid none;
		box-shadow: 0 2px 8px black;
		text-align: center;
	}
	.annoying-warning :last-child {
		margin-bottom: 0;
	}

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

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

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

	.def {
		padding: .5em 1em;
		background: #def;
		background: var(--def-bg);
		margin: 1.2em 0;
		border-left: 0.5em solid #8ccbf2;
		border-left: 0.5em solid var(--def-border);
		color: black;
		color: var(--def-text);
	}

/******************************************************************************/
/*                                    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;
		border-bottom: 1px solid var(--defrow-border);
	}

	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-color: var(--datacell-border);
		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;
		border-top: 1px solid var(--datacell-border);
		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;
		border: 1px solid var(--datacell-border);
		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;
		color: var(--toclink-text);
		border-color: #3980b5;
		border-color: var(--toclink-underline);
	}
	.toc a:visited {
		color: black;
		color: var(--toclink-visited-text);
		border-color: #054572;
		border-color: var(--toclink-visited-underline);
	}
	.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; }
		}
		/* Loosen it on wide screens */
		@media screen and (min-width: 78em) {
			body:not(.toc-inline) :not(li) > .toc              { margin-left:  4rem; }
			body:not(.toc-inline) .toc .secno                  { margin-left: -4rem; }
			body:not(.toc-inline) .toc > li li li              { margin-left:  1rem; }
			body:not(.toc-inline) .toc > li li li .secno       { margin-left: -5rem; }
			body:not(.toc-inline) .toc > li li li li .secno    { margin-left: -6rem; }
			body:not(.toc-inline) .toc > li li li li li .secno { margin-left: -7rem; }
	}
	/* } */

	@supports (display:grid) and (display:contents) {
		/* 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,
		#toc .content:focus {
			background: rgba(75%, 75%, 75%, .25);
			background: var(--a-hover-bg);
			border-bottom: 3px solid #054572;
			border-bottom: 3px solid var(--toclink-underline);
			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:not(.dfn-paneled) {
			white-space: nowrap;
			color: transparent; }
		ul.index li a:hover + span,
		ul.index li a:focus + span {
			color: #707070;
			color: var(--indexinfo-text);
		}
	}

/** 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]) {
		color: black;
		color: var(--indextable-hover-text);
		background: #f7f8f9;
		background: var(--indextable-hover-bg);
	}

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



/******************************************************************************/
/*                             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 {
		/* Magic to create good table positioning:
		   "content column" is 50ems wide at max; less on smaller screens.
		   Extra space (after ToC + content) is empty on the right.

		   1. When table < content column, centers table in column.
		   2. When content < table < available, left-aligns.
		   3. When table > available, fills available + scroll bar.
		*/
		display: grid;
		grid-template-columns: minmax(0, 50em);
	}
	.overlarge > table {
		/* limit preferred width of table */
		max-width: 50em;
		margin-left: auto;
		margin-right: auto;
	}

	@media (min-width: 55em) {
		.overlarge {
			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-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-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;
    }

    del { background: #fcc; color: #000; text-decoration: line-through; }
    ins { background: #cfc; color: #000; }
    blockquote .highlight:not(.idl) { background: initial; margin: initial; padding: 0.5em }
    blockquote ul { background: inherit; }
    blockquote code.highlight:not(.idl) { padding: initial; }
    blockquote c-[a] { color: inherit; } /* Keyword.Declaration */
    blockquote c-[b] { color: inherit; } /* Keyword.Type */
    blockquote c-[c] { color: inherit; } /* Comment */
    blockquote c-[d] { color: inherit; } /* Comment.Multiline */
    blockquote c-[e] { color: inherit; } /* Name.Attribute */
    blockquote c-[f] { color: inherit; } /* Name.Tag */
    blockquote c-[g] { color: inherit; } /* Name.Variable */
    blockquote c-[k] { color: inherit; } /* Keyword */
    blockquote c-[l] { color: inherit; } /* Literal */
    blockquote c-[m] { color: inherit; } /* Literal.Number */
    blockquote c-[n] { color: inherit; } /* Name */
    blockquote c-[o] { color: inherit; } /* Operator */
    blockquote c-[p] { color: inherit; } /* Punctuation */
    blockquote c-[s] { color: inherit; } /* Literal.String */
    blockquote c-[t] { color: inherit; } /* Literal.String.Single */
    blockquote c-[u] { color: inherit; } /* Literal.String.Double */
    blockquote c-[cp] { color: inherit; } /* Comment.Preproc */
    blockquote c-[c1] { color: inherit; } /* Comment.Single */
    blockquote c-[cs] { color: inherit; } /* Comment.Special */
    blockquote c-[kc] { color: inherit; } /* Keyword.Constant */
    blockquote c-[kn] { color: inherit; } /* Keyword.Namespace */
    blockquote c-[kp] { color: inherit; } /* Keyword.Pseudo */
    blockquote c-[kr] { color: inherit; } /* Keyword.Reserved */
    blockquote c-[ld] { color: inherit; } /* Literal.Date */
    blockquote c-[nc] { color: inherit; } /* Name.Class */
    blockquote c-[no] { color: inherit; } /* Name.Constant */
    blockquote c-[nd] { color: inherit; } /* Name.Decorator */
    blockquote c-[ni] { color: inherit; } /* Name.Entity */
    blockquote c-[ne] { color: inherit; } /* Name.Exception */
    blockquote c-[nf] { color: inherit; } /* Name.Function */
    blockquote c-[nl] { color: inherit; } /* Name.Label */
    blockquote c-[nn] { color: inherit; } /* Name.Namespace */
    blockquote c-[py] { color: inherit; } /* Name.Property */
    blockquote c-[ow] { color: inherit; } /* Operator.Word */
    blockquote c-[mb] { color: inherit; } /* Literal.Number.Bin */
    blockquote c-[mf] { color: inherit; } /* Literal.Number.Float */
    blockquote c-[mh] { color: inherit; } /* Literal.Number.Hex */
    blockquote c-[mi] { color: inherit; } /* Literal.Number.Integer */
    blockquote c-[mo] { color: inherit; } /* Literal.Number.Oct */
    blockquote c-[sb] { color: inherit; } /* Literal.String.Backtick */
    blockquote c-[sc] { color: inherit; } /* Literal.String.Char */
    blockquote c-[sd] { color: inherit; } /* Literal.String.Doc */
    blockquote c-[se] { color: inherit; } /* Literal.String.Escape */
    blockquote c-[sh] { color: inherit; } /* Literal.String.Heredoc */
    blockquote c-[si] { color: inherit; } /* Literal.String.Interpol */
    blockquote c-[sx] { color: inherit; } /* Literal.String.Other */
    blockquote c-[sr] { color: inherit; } /* Literal.String.Regex */
    blockquote c-[ss] { color: inherit; } /* Literal.String.Symbol */
    blockquote c-[vc] { color: inherit; } /* Name.Variable.Class */
    blockquote c-[vg] { color: inherit; } /* Name.Variable.Global */
    blockquote c-[vi] { color: inherit; } /* Name.Variable.Instance */
    blockquote c-[il] { color: inherit; } /* Literal.Number.Integer.Long */
  </style>
  <meta content="Bikeshed version 89ebb6ab, updated Fri Oct 9 15:32:07 2020 -0700" name="generator">
  <link href="https://isocpp.org/favicon.ico" rel="icon">
<style>
ins  {background-color: #CCFFCC; text-decoration: underline;}
del  {background-color: #FFCACA; text-decoration: line-through;}
</style>
<style>/* style-autolinks */

.css.css, .property.property, .descriptor.descriptor {
    color: var(--a-normal-text);
    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-colors */

/* Any --*-text not paired with a --*-bg is assumed to have a transparent bg */
html {
    color: black;
    color: var(--text);
    background-color: white;
    background-color: var(--bg);
}
:root {
    color-scheme: light dark;

    --text: black;
    --bg: white;

    --logo-bg: #1a5e9a;
    --logo-active-bg: #c00;
    --logo-text: white;

    --tocnav-normal-text: #707070;
    --tocnav-normal-bg: var(--bg);
    --tocnav-hover-text: var(--tocnav-normal-text);
    --tocnav-hover-bg: #f8f8f8;
    --tocnav-active-text: #c00;
    --tocnav-active-bg: var(--tocnav-normal-bg);

    --tocsidebar-text: var(--text);
    --tocsidebar-bg: #f7f8f9;
    --tocsidebar-shadow: rgba(0,0,0,.1);
    --tocsidebar-heading-text: hsla(203,20%,40%,.7);

    --toclink-text: var(--text);
    --toclink-underline: #3980b5;
    --toclink-visited-text: var(--toclink-text);
    --toclink-visited-underline: #054572;

    --heading-text: #005a9c;

    --hr-text: var(--text);

    --algo-border: #def;

    --del-text: red;
    --del-bg: transparent;
    --ins-text: #080;
    --ins-bg: transparent;

    --a-normal-text: #034575;
    --a-normal-underline: #707070;
    --a-visited-text: var(--a-normal-text);
    --a-visited-underline: #bbb;
    --a-hover-bg: rgba(75%, 75%, 75%, .25);
    --a-active-text: #c00;
    --a-active-underline: #c00;

    --blockquote-border: silver;
    --blockquote-bg: transparent;
    --blockquote-text: currentcolor;

    --issue-border: #e05252;
    --issue-bg: #fbe9e9;
    --issue-text: var(--text);
    --issueheading-text: #831616;

    --example-border: #e0cb52;
    --example-bg: #fcfaee;
    --example-text: var(--text);
    --exampleheading-text: #574b0f;

    --note-border: #52e052;
    --note-bg: #e9fbe9;
    --note-text: var(--text);
    --noteheading-text: hsl(120, 70%, 30%);
    --notesummary-underline: silver;

    --assertion-border: #aaa;
    --assertion-bg: #eee;
    --assertion-text: black;

    --advisement-border: orange;
    --advisement-bg: #fec;
    --advisement-text: var(--text);
    --advisementheading-text: #b35f00;

    --warning-border: red;
    --warning-bg: hsla(40,100%,50%,0.95);
    --warning-text: var(--text);

    --def-border: #8ccbf2;
    --def-bg: #def;
    --def-text: var(--text);
    --defrow-border: #bbd7e9;

    --datacell-border: silver;

    --indexinfo-text: #707070;

    --indextable-hover-text: black;
    --indextable-hover-bg: #f7f8f9;

    --outdatedspec-bg: rgba(0, 0, 0, .5);
    --outdatedspec-text: black;
    --outdated-bg: maroon;
    --outdated-text: white;
    --outdated-shadow: red;

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

:root {
    --highlight-hover-bg: rgba(0, 0, 0, .05);
}
.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: var(--highlight-hover-bg);
}
.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-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 */

:root {
    --selflink-text: white;
    --selflink-bg: gray;
    --selflink-hover-text: black;
}
.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: var(--selflink-bg);
    color: var(--selflink-text);
    font-style: normal;
    transition: opacity .2s, background-color .2s, color .2s;
}
dfn:hover > a.self-link {
    opacity: 1;
}
dfn > a.self-link:hover {
    color: var(--selflink-hover-text);
}

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

code.highlight { padding: .1em; border-radius: .3em; }
pre.highlight, pre > code.highlight { display: block; padding: 1em; margin: .5em 0; overflow: auto; border-radius: 0; }

.highlight:not(.idl) { background: #fdf6e3; }
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>
<style>/* style-darkmode */

@media (prefers-color-scheme: dark) {
    :root {
        --text: #ddd;
        --bg: black;

        --logo-bg: #1a5e9a;
        --logo-active-bg: #c00;
        --logo-text: white;

        --tocnav-normal-text: #999;
        --tocnav-normal-bg: var(--bg);
        --tocnav-hover-text: var(--tocnav-normal-text);
        --tocnav-hover-bg: #080808;
        --tocnav-active-text: #f44;
        --tocnav-active-bg: var(--tocnav-normal-bg);

        --tocsidebar-text: var(--text);
        --tocsidebar-bg: #080808;
        --tocsidebar-shadow: rgba(255,255,255,.1);
        --tocsidebar-heading-text: hsla(203,20%,40%,.7);

        --toclink-text: var(--text);
        --toclink-underline: #6af;
        --toclink-visited-text: var(--toclink-text);
        --toclink-visited-underline: #054572;

        --heading-text: #8af;

        --hr-text: var(--text);

        --algo-border: #456;

        --del-text: #f44;
        --del-bg: transparent;
        --ins-text: #4a4;
        --ins-bg: transparent;

        --a-normal-text: #6af;
        --a-normal-underline: #555;
        --a-visited-text: var(--a-normal-text);
        --a-visited-underline: var(--a-normal-underline);
        --a-hover-bg: rgba(25%, 25%, 25%, .2);
        --a-active-text: #f44;
        --a-active-underline: var(--a-active-text);

        --borderedblock-bg: rgba(255, 255, 255, .05);

        --blockquote-border: silver;
        --blockquote-bg: var(--borderedblock-bg);
        --blockquote-text: currentcolor;

        --issue-border: #e05252;
        --issue-bg: var(--borderedblock-bg);
        --issue-text: var(--text);
        --issueheading-text: hsl(0deg, 70%, 70%);

        --example-border: hsl(50deg, 90%, 60%);
        --example-bg: var(--borderedblock-bg);
        --example-text: var(--text);
        --exampleheading-text: hsl(50deg, 70%, 70%);

        --note-border: hsl(120deg, 100%, 35%);
        --note-bg: var(--borderedblock-bg);
        --note-text: var(--text);
        --noteheading-text: hsl(120, 70%, 70%);
        --notesummary-underline: silver;

        --assertion-border: #444;
        --assertion-bg: var(--borderedblock-bg);
        --assertion-text: var(--text);

        --advisement-border: orange;
        --advisement-bg: #222218;
        --advisement-text: var(--text);
        --advisementheading-text: #f84;

        --warning-border: red;
        --warning-bg: hsla(40,100%,20%,0.95);
        --warning-text: var(--text);

        --def-border: #8ccbf2;
        --def-bg: #080818;
        --def-text: var(--text);
        --defrow-border: #136;

        --datacell-border: silver;

        --indexinfo-text: #aaa;

        --indextable-hover-text: var(--text);
        --indextable-hover-bg: #181818;

        --outdatedspec-bg: rgba(255, 255, 255, .5);
        --outdatedspec-text: black;
        --outdated-bg: maroon;
        --outdated-text: white;
        --outdated-shadow: red;

        --editedrec-bg: darkorange;
    }
    /* In case a transparent-bg image doesn't expect to be on a dark bg,
       which is quite common in practice... */
    img { background: white; }
}
@media (prefers-color-scheme: dark) {
    :root {
        --selflink-text: black;
        --selflink-bg: silver;
        --selflink-hover-text: white;
    }
}

@media (prefers-color-scheme: dark) {
    .highlight:not(.idl) { background: rgba(255, 255, 255, .05); }

    c-[a] { color: #d33682 } /* Keyword.Declaration */
    c-[b] { color: #d33682 } /* Keyword.Type */
    c-[c] { color: #2aa198 } /* Comment */
    c-[d] { color: #2aa198 } /* Comment.Multiline */
    c-[e] { color: #268bd2 } /* Name.Attribute */
    c-[f] { color: #b58900 } /* Name.Tag */
    c-[g] { color: #cb4b16 } /* Name.Variable */
    c-[k] { color: #d33682 } /* Keyword */
    c-[l] { color: #657b83 } /* Literal */
    c-[m] { color: #657b83 } /* Literal.Number */
    c-[n] { color: #268bd2 } /* Name */
    c-[o] { color: #657b83 } /* Operator */
    c-[p] { color: #657b83 } /* Punctuation */
    c-[s] { color: #6c71c4 } /* Literal.String */
    c-[t] { color: #6c71c4 } /* Literal.String.Single */
    c-[u] { color: #6c71c4 } /* Literal.String.Double */
    c-[ch] { color: #2aa198 } /* Comment.Hashbang */
    c-[cp] { color: #2aa198 } /* Comment.Preproc */
    c-[cpf] { color: #2aa198 } /* Comment.PreprocFile */
    c-[c1] { color: #2aa198 } /* Comment.Single */
    c-[cs] { color: #2aa198 } /* Comment.Special */
    c-[kc] { color: #d33682 } /* Keyword.Constant */
    c-[kn] { color: #d33682 } /* Keyword.Namespace */
    c-[kp] { color: #d33682 } /* Keyword.Pseudo */
    c-[kr] { color: #d33682 } /* Keyword.Reserved */
    c-[ld] { color: #657b83 } /* Literal.Date */
    c-[nc] { color: #268bd2 } /* Name.Class */
    c-[no] { color: #268bd2 } /* Name.Constant */
    c-[nd] { color: #268bd2 } /* Name.Decorator */
    c-[ni] { color: #268bd2 } /* Name.Entity */
    c-[ne] { color: #268bd2 } /* Name.Exception */
    c-[nf] { color: #268bd2 } /* Name.Function */
    c-[nl] { color: #268bd2 } /* Name.Label */
    c-[nn] { color: #268bd2 } /* Name.Namespace */
    c-[py] { color: #268bd2 } /* Name.Property */
    c-[ow] { color: #657b83 } /* Operator.Word */
    c-[mb] { color: #657b83 } /* Literal.Number.Bin */
    c-[mf] { color: #657b83 } /* Literal.Number.Float */
    c-[mh] { color: #657b83 } /* Literal.Number.Hex */
    c-[mi] { color: #657b83 } /* Literal.Number.Integer */
    c-[mo] { color: #657b83 } /* Literal.Number.Oct */
    c-[sa] { color: #6c71c4 } /* Literal.String.Affix */
    c-[sb] { color: #6c71c4 } /* Literal.String.Backtick */
    c-[sc] { color: #6c71c4 } /* Literal.String.Char */
    c-[dl] { color: #6c71c4 } /* Literal.String.Delimiter */
    c-[sd] { color: #6c71c4 } /* Literal.String.Doc */
    c-[se] { color: #6c71c4 } /* Literal.String.Escape */
    c-[sh] { color: #6c71c4 } /* Literal.String.Heredoc */
    c-[si] { color: #6c71c4 } /* Literal.String.Interpol */
    c-[sx] { color: #6c71c4 } /* Literal.String.Other */
    c-[sr] { color: #6c71c4 } /* Literal.String.Regex */
    c-[ss] { color: #6c71c4 } /* Literal.String.Symbol */
    c-[fm] { color: #268bd2 } /* Name.Function.Magic */
    c-[vc] { color: #cb4b16 } /* Name.Variable.Class */
    c-[vg] { color: #cb4b16 } /* Name.Variable.Global */
    c-[vi] { color: #cb4b16 } /* Name.Variable.Instance */
    c-[vm] { color: #cb4b16 } /* Name.Variable.Magic */
    c-[il] { color: #657b83 } /* Literal.Number.Integer.Long */
}

@media (prefers-color-scheme: dark) {
    :root {
        --highlight-hover-bg: rgba(255, 255, 255, .05);
    }
}
</style>
 <body class="h-entry">
  <div class="head">
   <p data-fill-with="logo"></p>
   <h1 class="p-name no-ref" id="title">P2226R0<br>A proposal for an idiom to move from an object and reset it to its default constructed state</h1>
   <h2 class="no-num no-toc no-ref heading settled" id="subtitle"><span class="content">Published Proposal, <time class="dt-updated" datetime="2020-10-02">2020-10-02</time></span></h2>
   <div data-fill-with="spec-metadata">
    <dl>
     <dt>Issue Tracking:
     <dd><a href="#issues-index">Inline In Spec</a>
     <dt class="editor">Author:
     <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:giuseppe.dangelo@kdab.com">Giuseppe D'Angelo</a>
     <dt>Audience:
     <dd>SG18, SG1, SG20
     <dt>Project:
     <dd>ISO/IEC JTC1/SC22/WG21 14882: Programming Language — C++
    </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>This paper proposes two new CPOs called <code class="highlight"><c- n>take</c-></code> and <code class="highlight"><c- n>take_assign</c-></code>;

  they reset an object to its default constructed state,
  and return the old value of that object or assign the old value to another object.
  Effectively, <code class="highlight"><c- n>T</c-> <c- n>t</c-> <c- o>=</c-> <c- n>take</c-><c- p>(</c-><c- n>obj</c-><c- p>)</c-></code> should become the idiomatic form
  for C++14’s <code class="highlight"><c- n>T</c-> <c- n>t</c-> <c- o>=</c-> <c- n>exchange</c-><c- p>(</c-><c- n>obj</c-><c- p>,</c-> <c- p>{})</c-></code>; and <code class="highlight"><c- n>take_assign</c-><c- p>(</c-><c- n>new_obj</c-><c- p>,</c-> <c- n>old_obj</c-><c- p>)</c-></code> the idiomatic form for <code class="highlight"><c- n>new_obj</c-> <c- o>=</c-> <c- n>exchange</c-><c- p>(</c-><c- n>old_obj</c-><c- p>,</c-> <c- p>{})</c-></code>.
  Formally, the new value of <code class="highlight"><c- n>obj</c-></code> is equal to the one achieved
  through value initialization, not default initialization (e.g. <code class="highlight"><c- n>take</c-></code> called on an object of pointer type will reset it to <code class="highlight"><c- k>nullptr</c-></code>; cf. [dcl.init.general]).
  In the paper we are however going to liberally talk about
  "default constructed" state or value, implying the state (resp. value)
  reached through value initialization.</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="#changelog"><span class="secno">1</span> <span class="content">Changelog</span></a>
    <li><a href="#tonytables"><span class="secno">2</span> <span class="content">Tony Tables</span></a>
    <li>
     <a href="#motivation"><span class="secno">3</span> <span class="content">Motivation and Scope</span></a>
     <ol class="toc">
      <li><a href="#streamliningexchange"><span class="secno">3.1</span> <span class="content">Streamlining <code class="highlight"><c- n>exchange</c-></code></span></a>
      <li><a href="#movesemantics"><span class="secno">3.2</span> <span class="content"><i>Safe</i> move semantics</span></a>
      <li><a href="#customizationpoint"><span class="secno">3.3</span> <span class="content">Customizing <code class="highlight"><c- n>take</c-></code></span></a>
      <li><a href="#takeassign"><span class="secno">3.4</span> <span class="content">The need for <code class="highlight"><c- n>take_assign</c-></code></span></a>
     </ol>
    <li><a href="#impact"><span class="secno">4</span> <span class="content">Impact On The Standard</span></a>
    <li>
     <a href="#designdecisions"><span class="secno">5</span> <span class="content">Design Decisions</span></a>
     <ol class="toc">
      <li><a href="#naming"><span class="secno">5.1</span> <span class="content">Bikeshedding: naming</span></a>
      <li><a href="#defaultingparameter"><span class="secno">5.2</span> <span class="content">Why not simply defaulting the second parameter of <code class="highlight"><c- n>exchange</c-></code> to <code class="highlight"><c- n>T</c-><c- p>()</c-></code>?</span></a>
      <li><a href="#exceptionsafety"><span class="secno">5.3</span> <span class="content">What kind of exception safety should <code class="highlight"><c- n>take</c-></code> offer?</span></a>
      <li><a href="#algorithms"><span class="secno">5.4</span> <span class="content">Should there be <code class="highlight"><c- n>take</c-></code>-based algorithms, iterators, etc.?</span></a>
      <li><a href="#membertake"><span class="secno">5.5</span> <span class="content">Do we need member <code class="highlight"><c- n>take</c-></code> / <code class="highlight"><c- n>take_assign</c-></code> for some Standard Library classes, like the member <code class="highlight"><c- n>swap</c-></code>?</span></a>
      <li><a href="#takepostconditions"><span class="secno">5.6</span> <span class="content">What are the post-conditions that an overload of <code class="highlight"><c- n>take</c-></code> / <code class="highlight"><c- n>take_assign</c-></code> for a user-defined type must respect w.r.t. the taken-from object?</span></a>
      <li><a href="#atomic_take"><span class="secno">5.7</span> <span class="content">Should there be an <code class="highlight"><c- n>atomic_take</c-></code>?</span></a>
      <li><a href="#takeormove"><span class="secno">5.8</span> <span class="content">Should we promote the usage of <code class="highlight"><c- n>take</c-></code> over <code class="highlight"><c- n>move</c-></code> (in education materials, coding guidelines, etc.)?</span></a>
      <li><a href="#force_move"><span class="secno">5.9</span> <span class="content"><code class="highlight"><c- n>take</c-></code> guarantees a move <em>and</em> resets the source object; on the other hand, <code class="highlight"><c- n>move</c-></code> does not even guarantee a move. Should there be another function that guarantees a move, but does not reset?</span></a>
     </ol>
    <li>
     <a href="#technicalspecifications"><span class="secno">6</span> <span class="content">Technical Specifications</span></a>
     <ol class="toc">
      <li>
       <a href="#implementation"><span class="secno">6.1</span> <span class="content">Implementation</span></a>
       <ol class="toc">
        <li><a href="#implementationtake"><span class="secno">6.1.1</span> <span class="content"><code class="highlight"><c- n>take</c-></code> and <code class="highlight"><c- n>take_assign</c-></code></span></a>
        <li><a href="#implementationalgorithms"><span class="secno">6.1.2</span> <span class="content">Algorithms</span></a>
       </ol>
      <li><a href="#featuretestmacro"><span class="secno">6.2</span> <span class="content">Feature testing macro</span></a>
      <li><a href="#proposedwording"><span class="secno">6.3</span> <span class="content">Proposed wording</span></a>
     </ol>
    <li><a href="#acknowledgements"><span class="secno">7</span> <span class="content">Acknowledgements</span></a>
    <li>
     <a href="#references"><span class="secno"></span> <span class="content">References</span></a>
     <ol class="toc">
      <li><a href="#informative"><span class="secno"></span> <span class="content">Informative References</span></a>
     </ol>
    <li><a href="#issues-index"><span class="secno"></span> <span class="content">Issues Index</span></a>
   </ol>
  </nav>
  <main>
   <h2 class="heading settled" data-level="1" id="changelog"><span class="secno">1. </span><span class="content">Changelog</span><a class="self-link" href="#changelog"></a></h2>
   <ul>
    <li data-md>
     <p>R0</p>
     <ul>
      <li data-md>
       <p>First submission</p>
     </ul>
   </ul>
   <h2 class="heading settled" data-level="2" id="tonytables"><span class="secno">2. </span><span class="content">Tony Tables</span><a class="self-link" href="#tonytables"></a></h2>
   <table>
    <thead>
     <tr>
      <th>Before
      <th>After
    <tbody>
     <tr>
      <td>
<pre class="highlight"><c- k>class</c-> <c- nc>C</c-> <c- p>{</c->
    <c- n>Data</c-> <c- o>*</c-><c- n>data</c-><c- p>;</c->
<c- k>public</c-><c- o>:</c->
    <c- c1>// idiomatic, C++14</c->
    <c- n>C</c-><c- p>(</c-><c- n>C</c-><c- o>&amp;&amp;</c-> <c- n>other</c-><c- p>)</c-> <c- k>noexcept</c-> <c- o>:</c-> <c- n>data</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>exchange</c-><c- p>(</c-><c- n>other</c-><c- p>.</c-><c- n>data</c-><c- p>,</c-> <c- p>{}))</c-> <c- p>{}</c->
<c- p>};</c->
</pre>
      <td>
<pre class="highlight"><c- k>class</c-> <c- nc>C</c-> <c- p>{</c->
    <c- n>Data</c-> <c- o>*</c-><c- n>data</c-><c- p>;</c->
<c- k>public</c-><c- o>:</c->
    <c- c1>// idiomatic, C++2?</c->
    <c- n>C</c-><c- p>(</c-><c- n>C</c-><c- o>&amp;&amp;</c-> <c- n>other</c-><c- p>)</c-> <c- k>noexcept</c-> <c- o>:</c-> <c- n>data</c-><c- p>(</c-><ins><c- n>std</c-><c- o>::</c-><c- n>take</c-><c- p>(</c-><c- n>other</c-><c- p>.</c-><c- n>data</c-><c- p>)</c-></ins><c- p>)</c-> <c- p>{}</c->
<c- p>};</c->
</pre>
     <tr>
      <td>
<pre class="highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>K</c-><c- p>,</c->
          <c- k>typename</c-> <c- n>V</c-><c- p>,</c->
          <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-><c- p>...</c-><c- o>></c-> <c- k>typename</c-> <c- n>C</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>vector</c-><c- o>></c->
<c- k>class</c-> <c- nc>flat_map</c-> <c- p>{</c->
    <c- n>C</c-><c- o>&lt;</c-><c- n>K</c-><c- o>></c-> <c- n>m_keys</c-><c- p>;</c->
    <c- n>C</c-><c- o>&lt;</c-><c- n>V</c-><c- o>></c-> <c- n>m_values</c-><c- p>;</c->

<c- k>public</c-><c- o>:</c->
    <c- d>/*</c->
<c- d>      If flat_map wants to ensure a "valid but not specified"</c->
<c- d>      state after a move, then it cannot default its move</c->
<c- d>      operations: C’s own move operations may leave flat_map</c->
<c- d>      in an invalid state, e.g. with m_keys.size() != m_values.size()</c->
<c- d>      (breaking a more than reasonable class invariant for flat_map).</c->
<c- d>      In other words, "valid but not specified" states do not compose;</c->
<c- d>      we need to reset them to a fully specified state to restore</c->
<c- d>      this class' invariants.</c->
<c- d>    */</c->
    <c- n>flat_map</c-><c- p>(</c-><c- n>flat_map</c-><c- o>&amp;&amp;</c-> <c- n>other</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>(</c-><c- o>~~~</c-><c- p>)</c->
        <c- o>:</c-> <c- n>m_keys</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>exchange</c-><c- p>(</c-><c- n>other</c-><c- p>.</c-><c- n>m_keys</c-><c- p>,</c-> <c- p>{})),</c->
          <c- n>m_values</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>exchange</c-><c- p>(</c-><c- n>other</c-><c- p>.</c-><c- n>m_values</c-><c- p>,</c-> <c- p>{}))</c->
    <c- p>{}</c->

    <c- n>flat_map</c-> <c- o>&amp;</c-><c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- n>flat_map</c-><c- o>&amp;&amp;</c-> <c- n>other</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>(</c-><c- o>~~~</c-><c- p>)</c->
    <c- p>{</c->
        <c- n>m_keys</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>exchange</c-><c- p>(</c-><c- n>other</c-><c- p>.</c-><c- n>m_keys</c-><c- p>,</c-> <c- p>{});</c->
        <c- n>m_values</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>exchange</c-><c- p>(</c-><c- n>other</c-><c- p>.</c-><c- n>m_values</c-><c- p>,</c-> <c- p>{});</c->
        <c- k>return</c-> <c- o>*</c-><c- k>this</c-><c- p>;</c->
    <c- p>}</c->
<c- p>};</c->
</pre>
      <td>
<pre class="highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- n>K</c-><c- p>,</c->
          <c- k>typename</c-> <c- n>V</c-><c- p>,</c->
          <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-><c- p>...</c-><c- o>></c-> <c- k>typename</c-> <c- n>C</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>vector</c-><c- o>></c->
<c- k>class</c-> <c- nc>flat_map</c-> <c- p>{</c->
    <c- n>C</c-><c- o>&lt;</c-><c- n>K</c-><c- o>></c-> <c- n>m_keys</c-><c- p>;</c->
    <c- n>C</c-><c- o>&lt;</c-><c- n>V</c-><c- o>></c-> <c- n>m_values</c-><c- p>;</c->

<c- k>public</c-><c- o>:</c->









    <c- c1>// same, idiomatic</c->
    <c- n>flat_map</c-><c- p>(</c-><c- n>flat_map</c-><c- o>&amp;&amp;</c-> <c- n>other</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>(</c-><c- o>~~~</c-><c- p>)</c->
        <c- o>:</c-> <c- n>m_keys</c-><c- p>(</c-><ins><c- n>std</c-><c- o>::</c-><c- n>take</c-><c- p>(</c-><c- n>other</c-><c- p>.</c-><c- n>m_keys</c-><c- p>)</c-></ins><c- p>),</c->
          <c- n>m_values</c-><c- p>(</c-><ins><c- n>std</c-><c- o>::</c-><c- n>take</c-><c- p>(</c-><c- n>other</c-><c- p>.</c-><c- n>m_values</c-><c- p>)</c-></ins><c- p>)</c->
    <c- p>{}</c->

    <c- n>flat_map</c-> <c- o>&amp;</c-><c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- n>flat_map</c-><c- o>&amp;&amp;</c-> <c- n>other</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>(</c-><c- o>~~~</c-><c- p>)</c->
    <c- p>{</c->
        <ins><c- n>std</c-><c- o>::</c-><c- n>take_assign</c-><c- p>(</c-><c- n>m_keys</c-><c- p>,</c-> <c- n>other</c-><c- p>.</c-><c- n>m_keys</c-><c- p>);</c-></ins>
        <ins><c- n>std</c-><c- o>::</c-><c- n>take_assign</c-><c- p>(</c-><c- n>m_values</c-><c- p>,</c-> <c- n>other</c-><c- p>.</c-><c- n>m_values</c-><c- p>);</c-></ins>
        <c- k>return</c-> <c- o>*</c-><c- k>this</c-><c- p>;</c->
    <c- p>}</c->
<c- p>};</c->
</pre>
     <tr>
      <td>
<pre class="highlight"><c- b>void</c-> <c- n>Engine</c-><c- o>::</c-><c- n>processAll</c-><c- p>()</c->
<c- p>{</c->
    <c- c1>// process only the data available at this point</c->
    <c- k>for</c-> <c- p>(</c-><c- k>auto</c-><c- o>&amp;</c-> <c- nl>value</c-> <c- p>:</c-> <c- n>std</c-><c- o>::</c-><c- n>exchange</c-><c- p>(</c-><c- n>m_data</c-><c- p>,</c-> <c- p>{}))</c-> <c- p>{</c->
        <c- c1>// may end up writing into m_data; we will not process it,</c->
        <c- c1>// and it will not invalidate our iterators</c->
        <c- n>processOne</c-><c- p>(</c-><c- n>value</c-><c- p>);</c->
    <c- p>}</c->
<c- p>}</c->
</pre>
      <td>
<pre class="highlight"><c- b>void</c-> <c- n>Engine</c-><c- o>::</c-><c- n>processAll</c-><c- p>()</c->
<c- p>{</c->
    <c- c1>// same, idiomatic</c->
    <c- k>for</c-> <c- p>(</c-><c- k>auto</c-><c- o>&amp;</c-> <c- nl>value</c-> <c- p>:</c-> <ins><c- n>std</c-><c- o>::</c-><c- n>take</c-><c- p>(</c-><c- n>m_data</c-><c- p>)</c-></ins><c- p>)</c-> <c- p>{</c->


        <c- n>processOne</c-><c- p>(</c-><c- n>value</c-><c- p>);</c->
    <c- p>}</c->
<c- p>}</c->
</pre>
     <tr>
      <td>
<pre class="highlight"><c- b>void</c-> <c- n>ConsumerThread</c-><c- o>::</c-><c- n>process</c-><c- p>()</c->
<c- p>{</c->
    <c- c1>// grab the pending data under mutex protection,</c->
    <c- c1>// so this thread can then process it</c->
    <c- n>Data</c-> <c- n>pendingData</c-> <c- o>=</c-> <c- p>[</c-><c- o>&amp;</c-><c- p>]()</c-> <c- p>{</c->
        <c- n>std</c-><c- o>::</c-><c- n>scoped_lock</c-> <c- n>lock</c-><c- p>(</c-><c- n>m_mutex</c-><c- p>);</c->
        <c- k>return</c-> <c- n>std</c-><c- o>::</c-><c- n>exchange</c-><c- p>(</c-><c- n>m_data</c-><c- p>,</c-> <c- p>{});</c->
    <c- p>}();</c->

    <c- k>for</c-> <c- p>(</c-><c- k>auto</c-><c- o>&amp;</c-> <c- nl>value</c-> <c- p>:</c-> <c- n>pendingData</c-><c- p>)</c->
        <c- n>process</c-><c- p>(</c-><c- n>value</c-><c- p>);</c->
<c- p>}</c->
</pre>
      <td>
<pre class="highlight"><c- b>void</c-> <c- n>ConsumerThread</c-><c- o>::</c-><c- n>process</c-><c- p>()</c->
<c- p>{</c->


    <c- n>Data</c-> <c- n>pendingData</c-> <c- o>=</c-> <c- p>[</c-><c- o>&amp;</c-><c- p>]()</c-> <c- p>{</c->
        <c- n>std</c-><c- o>::</c-><c- n>scoped_lock</c-> <c- n>lock</c-><c- p>(</c-><c- n>m_mutex</c-><c- p>);</c->
        <c- k>return</c-> <ins><c- n>std</c-><c- o>::</c-><c- n>take</c-><c- p>(</c-><c- n>m_data</c-><c- p>)</c-></ins><c- p>;</c->
    <c- p>}();</c->

    <c- k>for</c-> <c- p>(</c-><c- k>auto</c-><c- o>&amp;</c-> <c- nl>value</c-> <c- p>:</c-> <c- n>pendingData</c-><c- p>)</c->
        <c- n>process</c-><c- p>(</c-><c- n>value</c-><c- p>);</c->
<c- p>}</c->
</pre>
     <tr>
      <td>
<pre class="highlight"><c- b>void</c-> <c- n>Engine</c-><c- o>::</c-><c- n>maybeRunOnce</c-><c- p>()</c->
<c- p>{</c->
    <c- k>if</c-> <c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>exchange</c-><c- p>(</c-><c- n>m_shouldRun</c-><c- p>,</c-> false<c- p>))</c->
        <c- n>run</c-><c- p>();</c->
<c- p>}</c->
</pre>
      <td>
<pre class="highlight"><c- b>void</c-> <c- n>Engine</c-><c- o>::</c-><c- n>maybeRunOnce</c-><c- p>()</c->
<c- p>{</c->
    <c- k>if</c-> <c- p>(</c-><ins><c- n>std</c-><c- o>::</c-><c- n>take</c-><c- p>(</c-><c- n>m_shouldRun</c-><c- p>)</c-></ins><c- p>)</c->
        <c- n>run</c-><c- p>();</c->
<c- p>}</c->
</pre>
     <tr>
      <td>
<pre class="highlight"><c- k>struct</c-> <c- n>S</c-> <c- p>{</c->
    <c- c1>// unconditional sinks</c->
    <c- c1>// overloaded for efficiency following F.15</c->
    <c- b>void</c-> <c- n>set_data</c-><c- p>(</c-><c- k>const</c-> <c- n>Data</c-><c- o>&amp;</c-> <c- n>d</c-><c- p>);</c->
    <c- b>void</c-> <c- nf>set_data</c-><c- p>(</c-><c- n>Data</c-><c- o>&amp;&amp;</c-> <c- n>d</c-><c- p>);</c->
<c- p>}</c-> <c- n>s</c-><c- p>;</c->

<c- n>Data</c-> <c- n>d</c-> <c- o>=</c-> <c- o>~~~</c-><c- p>;</c->

<c- c1>// sink "d", but leave it in a *specified* valid state</c->
<c- n>s</c-><c- p>.</c-><c- n>set_data</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>exchange</c-><c- p>(</c-><c- n>d</c-><c- p>,</c-> <c- p>{}));</c->

<c- n>assert</c-><c- p>(</c-><c- n>d</c-> <c- o>==</c-> <c- n>Data</c-><c- p>());</c->
</pre>
      <td>
<pre class="highlight"><c- k>struct</c-> <c- n>S</c-> <c- p>{</c->


    <c- b>void</c-> <c- n>set_data</c-><c- p>(</c-><c- k>const</c-> <c- n>Data</c-><c- o>&amp;</c-> <c- n>d</c-><c- p>);</c->
    <c- b>void</c-> <c- nf>set_data</c-><c- p>(</c-><c- n>Data</c-><c- o>&amp;&amp;</c-> <c- n>d</c-><c- p>);</c->
<c- p>}</c-> <c- n>s</c-><c- p>;</c->

<c- n>Data</c-> <c- n>d</c-> <c- o>=</c-> <c- o>~~~</c-><c- p>;</c->

<c- c1>// same, but idiomatic</c->
<c- n>s</c-><c- p>.</c-><c- n>set_data</c-><c- p>(</c-><ins><c- n>std</c-><c- o>::</c-><c- n>take</c-><c- p>(</c-><c- n>d</c-><c- p>)</c-></ins><c- p>);</c->

<c- n>assert</c-><c- p>(</c-><c- n>d</c-> <c- o>==</c-> <c- n>Data</c-><c- p>());</c->
</pre>
   </table>
   <p>In the example we are referring to the <a data-link-type="biblio" href="#biblio-f15">C++ Core Guideline F.15</a>.</p>
   <h2 class="heading settled" data-level="3" id="motivation"><span class="secno">3. </span><span class="content">Motivation and Scope</span><a class="self-link" href="#motivation"></a></h2>
   <h3 class="heading settled" data-level="3.1" id="streamliningexchange"><span class="secno">3.1. </span><span class="content">Streamlining <code class="highlight"><c- n>exchange</c-></code></span><a class="self-link" href="#streamliningexchange"></a></h3>
   <p>C++14, with the adoption of <a data-link-type="biblio" href="#biblio-n3668">[N3668]</a>, introduced the <code class="highlight"><c- n>exchange</c-></code> utility function template. <code class="highlight"><c- n>exchange</c-></code> is commonly found in the implementation of move operations, in algorithms,
and in other similar scenarios. Its intent is to streamline multiple operations
in one function call, making them less error prone, and ultimately creating an
idiom:</p>
<pre class="highlight"><c- k>struct</c-> <c- n>MyPtr</c-> <c- p>{</c->
    <c- n>Data</c-> <c- o>*</c-><c- n>d</c-><c- p>;</c->

    <c- c1>// BAD, the split makes it possible to forget to reset other.d to nullptr</c->
    <c- n>MyPtr</c-><c- p>(</c-><c- n>MyPtr</c-><c- o>&amp;&amp;</c-> <c- n>other</c-><c- p>)</c-> <c- o>:</c-> <c- n>d</c-><c- p>(</c-><c- n>other</c-><c- p>.</c-><c- n>d</c-><c- p>)</c-> <c- p>{</c-> <c- n>other</c-><c- p>.</c-><c- n>d</c-> <c- o>=</c-> <c- k>nullptr</c-><c- p>;</c-> <c- p>}</c->

    <c- c1>// BETTER, use std::exchange</c->
    <c- n>MyPtr</c-><c- p>(</c-><c- n>MyPtr</c-><c- o>&amp;&amp;</c-> <c- n>other</c-><c- p>)</c-> <c- o>:</c-> <c- n>d</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>exchange</c-><c- p>(</c-><c- n>other</c-><c- p>.</c-><c- n>d</c-><c- p>,</c-> <c- k>nullptr</c-><c- p>))</c-> <c- p>{}</c->

    <c- c1>// GOOD, idiomatic: use std::exchange, generalizing</c->
    <c- n>MyPtr</c-><c- p>(</c-><c- n>MyPtr</c-><c- o>&amp;&amp;</c-> <c- n>other</c-><c- p>)</c-> <c- o>:</c-> <c- n>d</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>exchange</c-><c- p>(</c-><c- n>other</c-><c- p>.</c-><c- n>d</c-><c- p>,</c-> <c- p>{}))</c-> <c- p>{}</c->


    <c- b>void</c-> <c- n>reset</c-><c- p>(</c-><c- n>Data</c-> <c- o>*</c-><c- n>newData</c-> <c- o>=</c-> <c- k>nullptr</c-><c- p>)</c->
    <c- p>{</c->
        <c- c1>// BAD, poor readability</c->
        <c- n>swap</c-><c- p>(</c-><c- n>d</c-><c- p>,</c-> <c- n>newData</c-><c- p>);</c->
        <c- k>if</c-> <c- p>(</c-><c- n>newData</c-><c- p>)</c->
            <c- n>dispose</c-><c- p>(</c-><c- n>newData</c-><c- p>);</c->

        <c- c1>// BETTER, readable</c->
        <c- n>Data</c-> <c- o>*</c-><c- n>old</c-> <c- o>=</c-> <c- n>d</c-><c- p>;</c->
        <c- n>d</c-> <c- o>=</c-> <c- n>newData</c-><c- p>;</c->
        <c- k>if</c-> <c- p>(</c-><c- n>old</c-><c- p>)</c->
            <c- n>dispose</c-><c- p>(</c-><c- n>old</c-><c- p>);</c->

        <c- c1>// GOOD, streamlined</c->
        <c- k>if</c-> <c- p>(</c-><c- n>Data</c-> <c- o>*</c-><c- n>old</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>exchange</c-><c- p>(</c-><c- n>d</c-><c- p>,</c-> <c- n>newData</c-><c- p>))</c->
            <c- n>dispose</c-><c- p>(</c-><c- n>old</c-><c- p>);</c->
    <c- p>}</c->
<c- p>};</c->
</pre>
   <p>By surveying various code bases, we noticed a common pattern: <b>a
significant amount (50%-90%) of calls to <code class="highlight"><c- n>exchange</c-></code> uses a default
constructed value as the second parameter</b>. The typical call has the idiomatic
form <code class="highlight"><c- n>exchange</c-><c- p>(</c-><c- n>obj</c-><c- p>,</c-> <c- p>{})</c-></code>, or it has some other form that could still
be rewritten into that one (like <code class="highlight"><c- n>exchange</c-><c- p>(</c-><c- n>pointer</c-><c- p>,</c-> <c- k>nullptr</c-><c- p>)</c-></code> or <code class="highlight"><c- n>exchange</c-><c- p>(</c-><c- n>boolean_flag</c-><c- p>,</c-> false<c- p>)</c-></code>).</p>
   <p>For instance, here’s some results form very popular C++ projects:</p>
   <table>
    <thead>
     <tr>
      <th>Project
      <th>Number of calls to <code class="highlight"><c- n>exchange</c-></code>
      <th>Number of calls to <code class="highlight"><c- n>exchange</c-><c- p>(</c-><c- n>obj</c-><c- p>,</c-> <c- p>{})</c-></code> or equivalent
(i.e. calls that could be replaced by <code class="highlight"><c- n>take</c-></code>)
      <th>Percentage
      <th>Notes
    <tbody>
     <tr>
      <td>Boost 1.74.0
      <td>121
      <td>97
      <td>80%
      <td>Incl. calls to <code class="highlight"><c- n>boost</c-><c- o>::</c-><c- n>exchange</c-></code>, as well as <code class="highlight"><c- n>boost</c-><c- o>::</c-><c- n>exchange</c-></code>'s own autotests.
     <tr>
      <td>Qt (qtbase and qtdeclarative repositories, dev branch)
      <td>37
      <td>33
      <td>89%
      <td>Incl. calls to <code class="highlight"><c- n>qExchange</c-></code>.
Of the 4 calls that do not use a default constructed second argument, 2 are
actually workaround for broken/legacy APIs and may get removed in the future.
     <tr>
      <td>Absl (master branch)
      <td>10
      <td>9
      <td>90%
      <td>Incl. calls to <code class="highlight"><c- n>absl</c-><c- o>::</c-><c- n>exchange</c-></code>; the 1 call that
cannot be replaced comes from <code class="highlight"><c- n>absl</c-><c- o>::</c-><c- n>exchange</c-></code>'s own autotests.
     <tr>
      <td>Firefox (mozilla-central repository)
      <td>14
      <td>10
      <td>71%
      <td>Incl. calls to <code class="highlight"><c- n>skstd</c-><c- o>::</c-><c- n>exchange</c-></code>.
     <tr>
      <td>Chromium (master branch)
      <td>38
      <td>30
      <td>79%
      <td>
   </table>
   <p class="note" role="note"><span>Note:</span> it is interesting that, one way or another,
several projects introduced their own version of <code class="highlight"><c- n>exchange</c-></code> in order to be able to use it without a C++14 toolchain.</p>
   <p>The observation of such a widespread pattern led to the present proposal.
Obviously, the figures above do not include any code path where the semantic
equivalent of <code class="highlight"><c- n>exchange</c-></code> is "unrolled" in those codebases; nonetheless, <strong>we claim that there is positive value for the C++ community if the pattern
of "move out the old value, set a new default constructed one"
could be given a name, and become an idiom on its own.</strong> If the chosen name for such a pattern is clear and sufficiently concise,
it would improve the usage of <code class="highlight"><c- n>exchange</c-><c- p>(</c-><c- n>obj</c-><c- p>,</c-> <c- p>{})</c-></code> (which is heavy on the eyes and somehow distracts from the actual intentions).</p>
   <p>We propose to call this idiom the <strong>take</strong> idiom.
This paper introduces two function objects, <code class="highlight"><c- n>take</c-></code> and <code class="highlight"><c- n>take_assign</c-></code>, that
can be used to streamline the calls to <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>exchange</c-></code> (depending on whether
we are constructing a new object or assigning onto an existing one).</p>
   <h3 class="heading settled" data-level="3.2" id="movesemantics"><span class="secno">3.2. </span><span class="content"><i>Safe</i> move semantics</span><a class="self-link" href="#movesemantics"></a></h3>
   <p>We also believe that such an idiom would become an useful tool in understanding
and using move semantics. <code class="highlight"><c- n>take</c-></code>, as presented, can be used as a drop-in
replacement for <code class="highlight"><c- n>move</c-></code> (under the reasonable assumption that movable types are
also, typically, default constructible). Unlike <code class="highlight"><c- n>move</c-></code>, it would leave the
source object in a well-defined state -- its default constructed state:</p>
<pre class="highlight"><c- n>f</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>move</c-><c- p>(</c-><c- n>obj</c-><c- p>));</c-> <c- c1>// obj’s state is unknown</c->
                   <c- c1>// - could be valid but unspecified</c->
                   <c- c1>// - could be not valid / moved from</c->
                   <c- c1>// - potentially, could be not moved-from at all...</c->

<c- c1>// VERSUS</c->

<c- n>f</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>take</c-><c- p>(</c-><c- n>obj</c-><c- p>));</c-> <c- c1>// obj has specified state</c->
</pre>
   <p>Using <a data-link-type="biblio" href="#biblio-seanparent">Sean Parent</a>'s definitions, <code class="highlight"><c- n>take</c-></code> would constitute a <em>safe</em> operation, and be the counterpart of <code class="highlight"><c- n>move</c-></code> (an <em>unsafe</em> operation).</p>
   <p>As for some other differences between the two:</p>
   <table>
    <thead>
     <tr>
      <th>
      <th><code class="highlight"><c- n>move</c-></code>
      <th><code class="highlight"><c- n>take</c-></code>
    <tbody>
     <tr>
      <th>Does <code class="highlight"><c- k>auto</c-> <c- n>new_obj</c-> <c- o>=</c-> <c- n>xxxx</c-><c- p>(</c-><c- n>old_obj</c-><c- p>);</c-></code> throw exceptions?
      <td>Usually no: move constructors are commonly <code class="highlight"><c- k>noexcept</c-></code>
      <td>Depends: generally no assumptions can be made regarding the default constructor
     <tr>
      <th>What is the state of <code class="highlight"><c- n>old_obj</c-></code> after the call above?
      <td>Usually <em>unspecified</em>;
depending on the class, it’s valid or not valid/partially formed 
      <td><em>Specified</em>: default constructed state
     <tr>
      <th>If a type is cheap to move, is the above call cheap?
      <td>Yes (tautological) 
      <td>Depends: generally no assumptions can be made regarding the default constructor
     <tr>
      <th>What does <code class="highlight"><c- n>obj</c-> <c- o>=</c-> <c- n>xxxx</c-><c- p>(</c-><c- n>obj</c-><c- p>);</c-></code> do?
      <td>Leaves <code class="highlight"><c- n>obj</c-></code> in its moved-from state,
or leaves <code class="highlight"><c- n>obj</c-></code> in its original state,
depending on the implementation
      <td>Leaves <code class="highlight"><c- n>obj</c-></code> in its original state,
assuming no exceptions occur;
it’s, however, expensive and not a no-op!
     <tr>
      <th>If I no longer need <code class="highlight"><c- n>old_obj</c-></code>, is <code class="highlight"><c- n>new_obj</c-> <c- o>=</c-> <c- n>xxxx</c-><c- p>(</c-><c- n>old_obj</c-><c- p>);</c-></code> a good idea?
      <td>Yes
      <td>No
   </table>
   <p>In conclusion: <b>we believe the Standard Library should offer both <code class="highlight"><c- n>move</c-></code> and <code class="highlight"><c- n>take</c-></code> to users; each one has its merits and valid use cases.</b></p>
   <h3 class="heading settled" data-level="3.3" id="customizationpoint"><span class="secno">3.3. </span><span class="content">Customizing <code class="highlight"><c- n>take</c-></code></span><a class="self-link" href="#customizationpoint"></a></h3>
   <p><code class="highlight"><c- n>take</c-><c- p>(</c-><c- n>obj</c-><c- p>)</c-></code> can be implemented just as <code class="highlight"><c- n>exchange</c-><c- p>(</c-><c- n>obj</c-><c- p>,</c-> <c- p>{})</c-></code>, that is:</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>></c-></span><span class="line-no" data-line="2"></span><span class="line"><c- k>constexpr</c-> <c- n>T</c-> <c- n>take</c-><c- p>(</c-><c- n>T</c-><c- o>&amp;</c-> <c- n>obj</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">    <c- n>T</c-> <c- n>old_val</c-> <c- o>=</c-> <c- n>move</c-><c- p>(</c-><c- n>obj</c-><c- p>);</c-></span><span class="line-no" data-line="5"></span><span class="line">    <c- n>obj</c-> <c- o>=</c-> <c- n>T</c-><c- p>();</c-></span><span class="line-no" data-line="6"></span><span class="line">    <c- k>return</c-> <c- n>old_val</c-><c- p>;</c-></span><span class="line-no" data-line="7"></span><span class="line"><c- p>}</c-></span></pre>
   <p>While this is a valid general-purpose implementation, it’s not necessarily the
most efficient for all <code class="highlight"><c- n>T</c-></code>s. For instance, what if the move constructor of a
given type leaves the moved-from object already in the default constructed state?
The reset on line 5 would be not necessary.</p>
   <p>One can build other similar examples where the generic code would be suboptimal:</p>
   <ul>
    <li data-md>
     <p>in case of types implemented out-of-line the generic code places N out-of-line
calls (move constructor, default constructor, move assignment, destructor, plus
the return mechanism), but it could be replaced by just one out-of-line call;</p>
    <li data-md>
     <p>for wrapper types like <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>array</c-></code> one doesn’t need a temporary,
default-constructed one; instead, <code class="highlight"><c- n>take</c-></code> could be applied to the individual
components.</p>
   </ul>
   <p>There is a strong analogy with <code class="highlight"><c- n>swap</c-></code> here. <code class="highlight"><c- n>swap</c-></code> is offered as a
customization point because a type’s author could implement it better than what
the Standard Library can do in its general-purpose implementation. It’s very
likely that a type that features a custom <code class="highlight"><c- n>swap</c-></code> could also benefit from a better
version of <code class="highlight"><c- n>take</c-></code> than the one above.</p>
   <p><b>Therefore, we claim that <code class="highlight"><c- n>take</c-></code> should also be a customization point.</b> The implementation above can be the default provided by the Standard Library;
but type authors can provide their own version if it makes sense for their own
types. For this to work, we propose making <code class="highlight"><c- n>take</c-></code> a CPO, so that it would
automatically find suitable overloads of <code class="highlight"><c- n>take</c-></code> for user-defined datatypes.</p>
   <h3 class="heading settled" data-level="3.4" id="takeassign"><span class="secno">3.4. </span><span class="content">The need for <code class="highlight"><c- n>take_assign</c-></code></span><a class="self-link" href="#takeassign"></a></h3>
   <p>Using <code class="highlight"><c- n>take</c-></code> to assign over an existing object may result in suboptimal code
which cannot be improved even with a customized overload for <code class="highlight"><c- n>take</c-></code>.</p>
   <p>Let’s consider an expression like:</p>
<pre class="highlight"><c- n>another_obj</c-> <c- o>=</c-> <c- n>take</c-><c- p>(</c-><c- n>obj</c-><c- p>);</c->
</pre>
   <p>This expression requires the construction and destruction of a temporary object
(the return value from <code class="highlight"><c- n>take</c-></code>) that cannot be elided or removed. This prevents
this code to be optimal -- the same considerations regarding the customization
of <code class="highlight"><c- n>take</c-></code> apply here.</p>
   <p>For instance, for a type whose move operations leave the moved-from object in
the default constructed state, then the above could be rewritten in a plain
move assignment (ignoring the issue of self-moves):</p>
<pre class="highlight"><c- c1>// this could be equivalent to take for some types</c->
<c- n>another_obj</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>move</c-><c- p>(</c-><c- n>old_obj</c-><c- p>);</c->
</pre>
   <p>This will have the same effects, but <em>without</em> the intermediate temporary
object. As a consequence, we cannot propose <code class="highlight"><c- n>take</c-></code> for this use-case (or it
won’t get used in practice, playing the "poor performance" card).</p>
   <p>The fundamental advantage of <code class="highlight"><c- n>move</c-></code> over <code class="highlight"><c- n>take</c-></code> in the above example is that the
move assignment operator has access to <em>both</em> the assigned-to and the
assigned-from objects. Such advantage is unachievable by a function like <code class="highlight"><c- n>take</c-></code>, which knows nothing about the assigned-to object (it doesn’t even know
that it is being used in an assignment). <strong>The conclusion is that in order to be
able to offer the same level of performance we need a function that implements
take-assignment</strong>.</p>
   <p>We propose <code class="highlight"><c- n>take_assign</c-></code> as the name of that function; just like <code class="highlight"><c- n>take</c-></code>,
it should be a customization point.</p>
   <h2 class="heading settled" data-level="4" id="impact"><span class="secno">4. </span><span class="content">Impact On The Standard</span><a class="self-link" href="#impact"></a></h2>
   <p>This proposal is a pure library extension.</p>
   <p>It proposes changes to existing headers,
but it does not require changes to any standard classes or functions and
it does not require changes to any of the standard requirement tables.</p>
   <p>This proposal does not require any changes in the core language.</p>
   <p>This proposal does not depend on any other library extensions.</p>
   <h2 class="heading settled" data-level="5" id="designdecisions"><span class="secno">5. </span><span class="content">Design Decisions</span><a class="self-link" href="#designdecisions"></a></h2>
   <p>The most natural place to add the <code class="highlight"><c- n>take</c-></code> and <code class="highlight"><c- n>take_assign</c-></code> CPOs presented by
this proposal is the already existing <code class="highlight"><c- o>&lt;</c-><c- n>utility</c-><c- o>></c-></code> header, following the
precedent of <code class="highlight"><c- n>move</c-></code> and <code class="highlight"><c- n>exchange</c-></code>.</p>
   <h3 class="heading settled" data-level="5.1" id="naming"><span class="secno">5.1. </span><span class="content">Bikeshedding: naming</span><a class="self-link" href="#naming"></a></h3>
   <p>We foresee that finding the right name for the proposed idiom / function objects
is going to be a huge contention point. Therefore, we want to kickstart
a possible discussion right away. In R0, we are proposing <code class="highlight"><c- n>take</c-></code>,
inspired by Rust’s own <a data-link-type="biblio" href="#biblio-stdmemtake">std::mem::take</a> function, which has
comparable semantics to the ones defined here.</p>
   <p>Other possible alternatives include:</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>reset</c-></code></p>
    <li data-md>
     <p><code class="highlight"><c- n>move_and_reset</c-></code></p>
    <li data-md>
     <p><code class="highlight"><c- n>safe_move</c-></code> (modelled after <a data-link-type="biblio" href="#biblio-seanparent">Sean Parent</a>'s terminology)</p>
    <li data-md>
     <p><code class="highlight"><c- n>transfer</c-></code></p>
    <li data-md>
     <p><code class="highlight"><c- n>collect</c-></code></p>
    <li data-md>
     <p><code class="highlight"><c- n>grab</c-></code></p>
   </ul>
   <p>We strongly believe that this idiom needs a concise name in order to be useful;
therefore we are not proposing something like <code class="highlight"><c- n>exchange_with_default_constructed</c-></code>.</p>
   <p class="issue" id="issue-ff4607c7"><a class="self-link" href="#issue-ff4607c7"></a> Submit a poll to LEWG(I), seeking ideas and consensus for a name.</p>
   <h3 class="heading settled" data-level="5.2" id="defaultingparameter"><span class="secno">5.2. </span><span class="content">Why not simply defaulting the second parameter of <code class="highlight"><c- n>exchange</c-></code> to <code class="highlight"><c- n>T</c-><c- p>()</c-></code>?</span><a class="self-link" href="#defaultingparameter"></a></h3>
   <p><a data-link-type="biblio" href="#biblio-n3668">[N3668]</a> mentions this idea, but indeed rejects it
because it makes the name <code class="highlight"><c- n>exchange</c-></code> much less clear:</p>
<pre class="highlight"><c- n>another_obj</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>exchange</c-><c- p>(</c-><c- n>obj</c-><c- p>);</c-> <c- c1>// exchange obj... with what? with another_obj? wait, is this a swap?</c->
</pre>
   We agree with that reasoning, so we are not proposing to change <code class="highlight"><c- n>exchange</c-></code>.
Moreover, this would also mean making <code class="highlight"><c- n>exchange</c-></code> a customization point
to reap the same benefits of a custom <code class="highlight"><c- n>take</c-></code>, which is a breaking change
at this point. 
   <h3 class="heading settled" data-level="5.3" id="exceptionsafety"><span class="secno">5.3. </span><span class="content">What kind of exception safety should <code class="highlight"><c- n>take</c-></code> offer?</span><a class="self-link" href="#exceptionsafety"></a></h3>
   <p>The same of <code class="highlight"><c- n>exchange</c-></code>, namely, the basic exception safety. Obtaining
a higher level is out of scope and not achievable without pessimizing the
common use case.</p>
   <h3 class="heading settled" data-level="5.4" id="algorithms"><span class="secno">5.4. </span><span class="content">Should there be <code class="highlight"><c- n>take</c-></code>-based algorithms, iterators, etc.?</span><a class="self-link" href="#algorithms"></a></h3>
   <p>Yes, and we are proposing them.</p>
   <h3 class="heading settled" data-level="5.5" id="membertake"><span class="secno">5.5. </span><span class="content">Do we need member <code class="highlight"><c- n>take</c-></code> / <code class="highlight"><c- n>take_assign</c-></code> for some Standard Library classes, like the member <code class="highlight"><c- n>swap</c-></code>?</span><a class="self-link" href="#membertake"></a></h3>
   <p>We are unable at this moment at giving a definitive answer; the motivations
behind making <code class="highlight"><c- n>swap</c-></code> a member are unclear to the author -- is it convenience or
part of the customization design of <code class="highlight"><c- n>swap</c-></code>, which maybe is not necessary when
using CPOs?</p>
   <p class="issue" id="issue-241e9d6e"><a class="self-link" href="#issue-241e9d6e"></a> We need to seek LEWG(I) guidance here.</p>
   <h3 class="heading settled" data-level="5.6" id="takepostconditions"><span class="secno">5.6. </span><span class="content">What are the post-conditions that an overload of <code class="highlight"><c- n>take</c-></code> / <code class="highlight"><c- n>take_assign</c-></code> for a user-defined type must respect w.r.t. the taken-from object?</span><a class="self-link" href="#takepostconditions"></a></h3>
   <p>By making <code class="highlight"><c- n>take</c-></code> a customization point, it becomes essential to clearly document
what user-provided overloads are supposed to do. In particular it might not
be what "reset to the default constructed" state really entails.</p>
   <p>Let’s consider <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>string</c-></code>, used like this:</p>
<pre class="highlight"><c- n>std</c-><c- o>::</c-><c- n>string</c-> <c- n>s</c-><c- p>,</c-> <c- n>t</c-> <c- o>=</c-> <c- o>~~~</c-><c- p>;</c->

<c- c1>// hand-rolled take_assign</c->
<c- n>t</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>move</c-><c- p>(</c-><c- n>s</c-><c- p>);</c->
<c- n>s</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>string</c-><c- p>();</c->
</pre>
   <p>It’s clear that, after this code, <code class="highlight"><c- n>s</c-></code> is in a valid state, and it’s
empty -- matching the default-constructed state of a <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>string</c-></code> object.
But <code class="highlight"><c- n>s</c-></code> may not be <em>fully</em> in its default-constructed state:
for instance, it may be carrying extra capacity (which actually happens on <a data-link-type="biblio" href="#biblio-stdstringcapacityaftermoveassignment">libstdc++</a>).</p>
<pre class="highlight"><c- n>assert</c-><c- p>(</c-><c- n>s</c-><c- p>.</c-><c- n>empty</c-><c- p>());</c->          <c- c1>// OK</c->
<c- n>assert</c-><c- p>(</c-><c- n>s</c-> <c- o>==</c-> <c- n>std</c-><c- o>::</c-><c- n>string</c-><c- p>());</c-> <c- c1>// OK</c->
<c- n>assert</c-><c- p>(</c-><c- n>s</c-><c- p>.</c-><c- n>capacity</c-><c- p>()</c-> <c- o>==</c-> <c- n>std</c-><c- o>::</c-><c- n>string</c-><c- p>().</c-><c- n>capacity</c-><c- p>());</c-> <c- c1>// ERROR</c->
</pre>
   <p>This is fine: the capacity of a default constructed <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>string</c-></code> is
unspecified, so one cannot assume anything about it.</p>
   <p>The same line of reasoning should be applied to <code class="highlight"><c- n>take</c-></code>. Summarizing,
a taken-from object:</p>
   <ol>
    <li data-md>
     <p>must have the same <em>documented</em> state and invariants of a default
constructed object of its type;</p>
    <li data-md>
     <p>has any state which is unspecified on default construction reset to
unspecified (even if it was specified before the call to <code class="highlight"><c- n>take</c-></code>);</p>
    <li data-md>
     <p>if its type models <code class="highlight"><c- n>equality_comparable</c-></code>, it must compare equal to a
default constructed object.</p>
   </ol>
   <p>In case of <code class="highlight"><c- n>take_assign</c-></code>, the above must be guaranteed even in case of a
"self-take".</p>
   <h3 class="heading settled" data-level="5.7" id="atomic_take"><span class="secno">5.7. </span><span class="content">Should there be an <code class="highlight"><c- n>atomic_take</c-></code>?</span><a class="self-link" href="#atomic_take"></a></h3>
   <p>The rationale of adding <code class="highlight"><c- n>exchange</c-></code> (with that specific name)
in the Standard Library was generalizing the already existing semantics
of <code class="highlight"><c- n>atomic_exchange</c-></code>, extending them to non-atomic, movable types.
By having <code class="highlight"><c- n>take</c-><c- p>(</c-><c- n>obj</c-><c- p>)</c-></code> as a "shortcut" for <code class="highlight"><c- n>exchange</c-><c- p>(</c-><c- n>obj</c-><c- p>,</c-> <c- p>{})</c-></code>,
one may indeed wonder if also <code class="highlight"><c- n>atomic_take</c-><c- p>(</c-><c- n>obj</c-><c- p>)</c-></code> should be added,
as a shortcut for <code class="highlight"><c- n>atomic_exchange</c-><c- p>(</c-><c- n>obj</c-><c- p>,</c-> <c- p>{})</c-></code> (mut. mut. for <code class="highlight"><c- n>atomic</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>::</c-><c- n>take</c-></code>).</p>
   <p>We are not fully convinced by the usefulness of <code class="highlight"><c- n>atomic_take</c-></code> and therefore we are not proposing it here.
First and foremost, unlike <code class="highlight"><c- n>exchange</c-></code>, <code class="highlight"><c- n>atomic_exchange</c-></code> has many more uses where the second argument is <em>not</em> a default constructed value.
Second, the overwhelming majority of usage of atomic types consist of atomic
integral types and atomic pointer types. We do not believe that substituting <code class="highlight"><c- n>atomic_exchange</c-><c- p>(</c-><c- n>val</c-><c- p>,</c-> <c- mi>0</c-><c- p>)</c-></code> or <code class="highlight"><c- n>atomic_exchange</c-><c- p>(</c-><c- n>val</c-><c- p>,</c-> <c- k>nullptr</c-><c- p>)</c-></code> with <code class="highlight"><c- n>atomic_take</c-><c- p>(</c-><c- n>val</c-><c- p>)</c-></code> would convey the same "meaning" when used
in the context of atomic programming.</p>
   <p>We would be happy to be convinced otherwise.</p>
   <p class="issue" id="issue-f443a90a"><a class="self-link" href="#issue-f443a90a"></a> Ask SG1 for their opinion regarding <code class="highlight"><c- n>atomic_take</c-></code>.</p>
   <h3 class="heading settled" data-level="5.8" id="takeormove"><span class="secno">5.8. </span><span class="content">Should we promote the usage of <code class="highlight"><c- n>take</c-></code> over <code class="highlight"><c- n>move</c-></code> (in education materials, coding guidelines, etc.)?</span><a class="self-link" href="#takeormove"></a></h3>
   <p>No. We believe we need instead to educate users about the availability of
both options in the Standard Library, make them understand the implications
of each one, and let the users choose the right tool for the job at hand.
To give an example: it sounds extremely unlikely that one should be using <code class="highlight"><c- n>take</c-></code> inside a shuffle-based algorithm (the impact in performance
and correctness would be disastrous when compared to using <code class="highlight"><c- n>move</c-></code> instead).</p>
   <p>There is however an important point to be made:
the state of a moved-from object has being actively disputed in the C++
community pretty much since the very introduction of move semantics.
The usual position is one between these two:</p>
   <ol>
    <li data-md>
     <p>object is valid but unspecified (e.g. [lib.types.movedfrom], <a data-link-type="biblio" href="#biblio-sutter">[Sutter]</a>, <a data-link-type="biblio" href="#biblio-c64">[C.64]</a>), and therefore it can be used in any way that
does not have preconditions (or similarly it would still be possible
to check such preconditions before usage); or</p>
    <li data-md>
     <p>object is partially formed / not valid,
(e.g. <a data-link-type="biblio" href="#biblio-p2027r0">[P2027R0]</a>), and therefore the only operations
allowed on such an object are assignment and destruction.</p>
   </ol>
   <p>This debate has not yet reached a conclusion. In the meanwhile, <em>what should
a user handling a generic object of type <code class="highlight"><c- n>T</c-></code> do, if they want to keep using it
after it has been moved?</em> The simplest solution would be to reset the
object to a well known state. If there is already such a well known state
readily available for the user, then the combination of <code class="highlight"><c- n>move</c-></code> + "reset to
state X" (however that would be expressed in code) makes perfect sense and it’s
certainly the way to go. Otherwise, the easiest state to reason about objects
of type <code class="highlight"><c- n>T</c-></code> is their default constructed state; therefore one may want to reset
their moved-from object to such default constructed state, and then keep using
the object. Moving plus resetting to default constructed state is precisely
what <code class="highlight"><c- n>take</c-></code> does.</p>
   <p>We would like to clarify that we do not have any sort of "hidden agenda"
that wants to settle the state of a moved-from object (in the Standard Library,
or in general). And, we absolutely do not claim that moved-from objects should
always be reset to their default constructed state (in their move operations,
or by always using <code class="highlight"><c- n>take</c-></code> instead of <code class="highlight"><c- n>move</c-></code> in one’s codebase). <b>The availability of <code class="highlight"><c- n>take</c-></code> for users should simply constitute
another tool in their toolbox, allowing them to choose which kind of operation
(safe/unsafe) makes most sense for their programs at any given point.</b></p>
   <h3 class="heading settled" data-level="5.9" id="force_move"><span class="secno">5.9. </span><span class="content"><code class="highlight"><c- n>take</c-></code> guarantees a move <em>and</em> resets the source object; on the other hand, <code class="highlight"><c- n>move</c-></code> does not even guarantee a move. Should there be another function that guarantees a move, but does not reset?</span><a class="self-link" href="#force_move"></a></h3>
   <p>In other words, should there be some sort of "intermediate" function between <code class="highlight"><c- n>move</c-></code> and <code class="highlight"><c- n>take</c-></code>, that simply guarantees that the input object will be moved from?
For instance:</p>
<pre class="highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- o>></c->
<c- k>constexpr</c-> <c- n>T</c-> <c- n>really_move</c-><c- p>(</c-><c- n>T</c-><c- o>&amp;</c-> <c- n>obj</c-><c- p>)</c-> <c- k>requires</c-> <c- p>(</c-><c- o>!</c-><c- n>is_const_v</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-><c- p>)</c-> <c- d>/* or equivalent */</c->
<c- p>{</c->
    <c- n>T</c-> <c- n>moved</c-> <c- o>=</c-> <c- n>move</c-><c- p>(</c-><c- n>obj</c-><c- p>);</c->
    <c- k>return</c-> <c- n>moved</c-><c- p>;</c->
<c- p>}</c->
</pre>
   <p>A possible use case would be to "sink" an object, therefore
deterministically releasing its resources from the caller, even if the
called function does not actually move from it:</p>
<pre class="highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>Fun</c-><c- o>></c->
<c- b>void</c-> <c- n>really_sink</c-><c- p>(</c-><c- n>Fun</c-> <c- n>f</c-><c- p>)</c->
<c- p>{</c->
    <c- n>Object</c-> <c- n>obj</c-> <c- o>=</c-> <c- o>~~~</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>obj</c-><c- p>));</c-> <c- c1>// if f doesn’t actually move,</c->
                       <c- c1>// we still have obj’s resources here in the caller</c->

    <c- c1>// VERSUS</c->

    <c- n>f</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>really_move</c-><c- p>(</c-><c- n>obj</c-><c- p>));</c-> <c- c1>// obj is moved from, always.</c->
                              <c- c1>// using take would be an overkill</c->
                              <c- c1>// (for instance, obj is not used afterwards,</c->
                              <c- c1>// so why resetting it?)</c->
<c- p>}</c->
</pre>
   <p>Now, having functions which have parameters of type rvalue reference (or
forwarding reference), and then do not <code class="highlight"><c- n>move</c-></code> / <code class="highlight"><c- n>forward</c-></code> them unconditionally
in all code paths, is generally frowned upon (cf. <a data-link-type="biblio" href="#biblio-f18">[F.18]</a> and <a data-link-type="biblio" href="#biblio-f19">[F.19]</a>,
and especially the "Enforcement" sections). The possibility for <code class="highlight"><c- n>move</c-></code> to
actually <em>not</em> move seems more a theoretical exercise than an issue commonly
found in practice.</p>
   <p>In any case, we do not have enough data to claim that there is a "widespread
need" for such a function in the Standard Library; surveying the same projects
listed in <a href="#motivation">§ 3 Motivation and Scope</a> gives inconcludent results (it seems that such a
function is not defined in any of them, for their own internal purposes).</p>
   <p>Therefore, we are not going to propose such a <code class="highlight"><c- n>really_move</c-></code> function here.</p>
   <p>We do not think that <code class="highlight"><c- n>take</c-></code> does impede in any way the addition of
such a function anyhow, via a separate proposal. One might even argue that the
addition of such a <code class="highlight"><c- n>really_move</c-></code> function should be not tied to the addition
of <code class="highlight"><c- n>take</c-></code>, as it solves a different problem: ensuring that an object
gets always moved from.</p>
   <p class="issue" id="issue-ed71fd42"><a class="self-link" href="#issue-ed71fd42"></a> Poll LEWG(I) for more opinions.</p>
   <h2 class="heading settled" data-level="6" id="technicalspecifications"><span class="secno">6. </span><span class="content">Technical Specifications</span><a class="self-link" href="#technicalspecifications"></a></h2>
   <h3 class="heading settled" data-level="6.1" id="implementation"><span class="secno">6.1. </span><span class="content">Implementation</span><a class="self-link" href="#implementation"></a></h3>
   <h4 class="heading settled" data-level="6.1.1" id="implementationtake"><span class="secno">6.1.1. </span><span class="content"><code class="highlight"><c- n>take</c-></code> and <code class="highlight"><c- n>take_assign</c-></code></span><a class="self-link" href="#implementationtake"></a></h4>
   <p><code class="highlight"><c- n>take</c-></code> and <code class="highlight"><c- n>take_assign</c-></code> are CPOs that needs to dispatch to ADL-found <code class="highlight"><c- n>take</c-></code> (resp. <code class="highlight"><c- n>take_assign</c-></code>), if found, or fall back to a default implementation
provided by the Standard Library.</p>
   <p>The actual design (finding members, finding non-members, etc.) needs some
feedback depending on the answers for the issue raised at <a href="#membertake">§ 5.5 Do we need member take / take_assign for some Standard Library classes, like the member swap?</a>.</p>
   <p>The default implementation should be straightforward, for instance like this:</p>
<pre class="highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- o>></c->
<c- k>constexpr</c-> <c- n>T</c-> <c- n>take</c-><c- p>(</c-><c- n>T</c-><c- o>&amp;</c-> <c- n>obj</c-><c- p>)</c->
<c- p>{</c->
    <c- n>T</c-> <c- n>old_val</c-> <c- o>=</c-> <c- n>move</c-><c- p>(</c-><c- n>obj</c-><c- p>);</c->
    <c- n>obj</c-> <c- o>=</c-> <c- n>T</c-><c- p>();</c->
    <c- k>return</c-> <c- n>old_val</c-><c- p>;</c->
<c- p>}</c->

<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- o>></c->
<c- k>constexpr</c-> <c- b>void</c-> <c- n>take_assign</c-><c- p>(</c-><c- n>T</c-><c- o>&amp;</c-> <c- n>target</c-><c- p>,</c-> <c- n>T</c-><c- o>&amp;</c-> <c- n>source</c-><c- p>)</c->
<c- p>{</c->
    <c- n>target</c-> <c- o>=</c-> <c- n>move</c-><c- p>(</c-><c- n>source</c-><c- p>);</c->
    <c- n>source</c-> <c- o>=</c-> <c- n>T</c-><c- p>();</c->
<c- p>}</c->
</pre>
   <h4 class="heading settled" data-level="6.1.2" id="implementationalgorithms"><span class="secno">6.1.2. </span><span class="content">Algorithms</span><a class="self-link" href="#implementationalgorithms"></a></h4>
   <p>Add:</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>take</c-></code>, <code class="highlight"><c- n>take_backward</c-></code> (in <code class="highlight"><c- o>&lt;</c-><c- n>algorithm</c-><c- o>></c-></code> and <code class="highlight"><c- o>&lt;</c-><c- n>ranges</c-><c- o>></c-></code>)</p>
    <li data-md>
     <p><code class="highlight"><c- n>uninitialized_take</c-></code>, <code class="highlight"><c- n>uninitialized_take_n</c-></code> (in <code class="highlight"><c- o>&lt;</c-><c- n>memory</c-><c- o>></c-></code>)</p>
    <li data-md>
     <p><code class="highlight"><c- n>take_iterator</c-></code>, <code class="highlight"><c- n>make_take_iterator</c-></code>, <code class="highlight"><c- n>take_sentinel</c-></code> (in <code class="highlight"><c- o>&lt;</c-><c- n>iterator</c-><c- o>></c-></code>)</p>
   </ul>
   <h3 class="heading settled" data-level="6.2" id="featuretestmacro"><span class="secno">6.2. </span><span class="content">Feature testing macro</span><a class="self-link" href="#featuretestmacro"></a></h3>
   <p>We propose <code class="highlight"><c- n>__cpp_lib_take</c-></code>.</p>
   <h3 class="heading settled" data-level="6.3" id="proposedwording"><span class="secno">6.3. </span><span class="content">Proposed wording</span><a class="self-link" href="#proposedwording"></a></h3>
   <p>All changes are relative to <a data-link-type="biblio" href="#biblio-n4861">[N4861]</a>.</p>
   <p>TBD.</p>
   <h2 class="heading settled" data-level="7" id="acknowledgements"><span class="secno">7. </span><span class="content">Acknowledgements</span><a class="self-link" href="#acknowledgements"></a></h2>
   <p>Thanks to KDAB for supporting this work.</p>
   <p>Thanks to Marc Mutz for reviewing this proposal,
and pointing me to <a data-link-type="biblio" href="#biblio-seanparent">Sean Parent</a>'s blog post.
His educational work regarding move semantics has been inspirational.
He originally proposed the idea of an idiomatic form for <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>exchange</c-><c- p>(</c-><c- n>obj</c-><c- p>,</c-> <c- p>{})</c-></code> on the <a data-link-type="biblio" href="#biblio-marcmutz">std-proposals mailing list</a>.</p>
   <p>Thanks to Arthur O’Dwyer for the early feedback.</p>
   <p>All remaining errors are ours and ours only.</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>
  <h2 class="no-num no-ref heading settled" id="references"><span class="content">References</span><a class="self-link" href="#references"></a></h2>
  <h3 class="no-num no-ref heading settled" id="informative"><span class="content">Informative References</span><a class="self-link" href="#informative"></a></h3>
  <dl>
   <dt id="biblio-c64">[C.64]
   <dd>Bjarne Stroustrup; Herb Sutter. <a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rc-move-semantic">C++ Core Guidelines, C.64: A move operation should move and leave its source in a valid state</a>. URL: <a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rc-move-semantic">https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rc-move-semantic</a>
   <dt id="biblio-f15">[F.15]
   <dd>Bjarne Stroustrup; Herb Sutter. <a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rf-conventional">C++ Core Guidelines, F.15: Prefer simple and conventional ways of passing information</a>. URL: <a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rf-conventional">https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rf-conventional</a>
   <dt id="biblio-f18">[F.18]
   <dd>Bjarne Stroustrup; Herb Sutter. <a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#f18-for-will-move-from-parameters-pass-by-x-and-stdmove-the-parameter">C++ Core Guidelines, F.18: For “will-move-from” parameters, pass by X&amp;&amp; and std::move the parameter</a>. URL: <a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#f18-for-will-move-from-parameters-pass-by-x-and-stdmove-the-parameter">https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#f18-for-will-move-from-parameters-pass-by-x-and-stdmove-the-parameter</a>
   <dt id="biblio-f19">[F.19]
   <dd>Bjarne Stroustrup; Herb Sutter. <a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#f19-for-forward-parameters-pass-by-tp-and-only-stdforward-the-parameter">C++ Core Guidelines, F.19: For “forward” parameters, pass by TP&amp;&amp; and only std::forward the parameter</a>. URL: <a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#f19-for-forward-parameters-pass-by-tp-and-only-stdforward-the-parameter">https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#f19-for-forward-parameters-pass-by-tp-and-only-stdforward-the-parameter</a>
   <dt id="biblio-marcmutz">[MarcMutz]
   <dd>Marc Mutz. <a href="https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/qDB0BG-GQqQ/discussion">Is `std::exchange(obj, {})` common enough to be spelled `std::move_and_reset(obj)`?</a>. URL: <a href="https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/qDB0BG-GQqQ/discussion">https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/qDB0BG-GQqQ/discussion</a>
   <dt id="biblio-n3668">[N3668]
   <dd>Jeffrey Yasskin. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3668.html">exchange() utility function, revision 3</a>. URL: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3668.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3668.html</a>
   <dt id="biblio-n4861">[N4861]
   <dd>Richard Smith, Thomas Koeppe, Jens Maurer, Dawn Perchik. <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2020/n4861.pdf">Working Draft, Standard for Programming Language C++</a>. URL: <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2020/n4861.pdf">http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2020/n4861.pdf</a>
   <dt id="biblio-p2027r0">[P2027R0]
   <dd>Geoff Romer. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2027r0.pdf">Moved-from objects need not be valid</a>. URL: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2027r0.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2027r0.pdf</a>
   <dt id="biblio-seanparent">[SeanParent]
   <dd>Sean Parent. <a href="https://sean-parent.stlab.cc/2014/05/30/about-move.html">About Move</a>. URL: <a href="https://sean-parent.stlab.cc/2014/05/30/about-move.html">https://sean-parent.stlab.cc/2014/05/30/about-move.html</a>
   <dt id="biblio-stdmemtake">[StdMemTake]
   <dd>Rust. <a href="https://doc.rust-lang.org/std/mem/fn.take.html">Function std::mem::take</a>. URL: <a href="https://doc.rust-lang.org/std/mem/fn.take.html">https://doc.rust-lang.org/std/mem/fn.take.html</a>
   <dt id="biblio-stdstringcapacityaftermoveassignment">[StdStringCapacityAfterMoveAssignment]
   <dd><a href="https://godbolt.org/z/6rfPYv">`std::string` retains capacity after move assignment</a>. URL: <a href="https://godbolt.org/z/6rfPYv">https://godbolt.org/z/6rfPYv</a>
   <dt id="biblio-sutter">[Sutter]
   <dd>Herb Sutter. <a href="https://herbsutter.com/2020/02/17/move-simply/">Move, simply</a>. URL: <a href="https://herbsutter.com/2020/02/17/move-simply/">https://herbsutter.com/2020/02/17/move-simply/</a>
  </dl>
  <h2 class="no-num no-ref heading settled" id="issues-index"><span class="content">Issues Index</span><a class="self-link" href="#issues-index"></a></h2>
  <div style="counter-reset:issue">
   <div class="issue"> Submit a poll to LEWG(I), seeking ideas and consensus for a name.<a href="#issue-ff4607c7"> ↵ </a></div>
   <div class="issue"> We need to seek LEWG(I) guidance here.<a href="#issue-241e9d6e"> ↵ </a></div>
   <div class="issue"> Ask SG1 for their opinion regarding <code class="highlight"><c- n>atomic_take</c-></code>.<a href="#issue-f443a90a"> ↵ </a></div>
   <div class="issue"> Poll LEWG(I) for more opinions.<a href="#issue-ed71fd42"> ↵ </a></div>
  </div>