<!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>P2785R3: Relocating prvalues</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
 *     -> ins/del.c### for candidate and proposed changes (amendments)
 *
 * Code
 *   - pre and code
 *
 * Special Sections
 *   - .note       for informative notes             (div, p, span, aside, details)
 *   - .example    for informative examples          (div, p, pre, span)
 *   - .issue      for issues                        (div, p, span)
 *   - .advisement for loud normative statements     (div, p, strong)
 *   - .annoying-warning for spec obsoletion notices (div, aside, details)
 *   - .correction for "candidate corrections"       (div, aside, details, section)
 *   - .addition   for "candidate additions"         (div, aside, details, section)
 *   - .correction.proposed for "proposed corrections" (div, aside, details, section)
 *   - .addition.proposed   for "proposed additions"   (div, aside, details, section)
 *
 * 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
 *
 * Outdated warning for old specs
 *
 * 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 {
	}

	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;

		color: black;
		color: var(--text);
		background: white top left fixed no-repeat;
		background: var(--bg) 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: 3;
			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,
	#profile-and-date {
		/* #profile-and-date 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: inherit;
	}
	dfn var {
		font-style: normal;
	}

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

	del {
		color: #aa0000;
		color: var(--del-text);
		background: transparent;
		background: var(--del-bg);
		text-decoration: line-through;
	}
	ins {
		color: #006100;
		color: var(--ins-text);
		background: transparent;
		background: var(--ins-bg);
		text-decoration: underline;
	}

	/* for amendments (candidate/proposed changes) */

	.amendment ins, .correction ins, .addition ins,
	ins[class^=c] {
		text-decoration-style: dotted;
	}
	.amendment del, .correction del, .addition del,
	del[class^=c] {
		text-decoration-style: dotted;
	}
	.amendment.proposed ins, .correction.proposed ins, .addition.proposed ins,
	ins[class^=c].proposed {
		text-decoration-style: double;
	}
	.amendment.proposed del, .correction.proposed del, .addition.proposed del,
	del[class^=c].proposed {
		text-decoration-style: double;
	}

/** 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: underline #707070;
		text-decoration: underline var(--a-normal-underline);
		text-decoration-skip-ink: none;
	}
	a:visited {
		color: #034575;
		color: var(--a-visited-text);
		text-decoration-color: #bbb;
		text-decoration-color: var(--a-visited-underline);
	}

	/* Indicate interaction with the link */
	a[href]:focus,
	a[href]:hover {
		text-decoration-thickness: 2px;
	}
	a[href]:active {
		color: #c00;
		color: var(--a-active-text);
		text-decoration-color: #c00;
		text-decoration-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,
	.amendment, .correction, .addition {
		margin: 1em auto;
		padding: .5em;
		border: .5em;
		border-left-style: solid;
		page-break-inside: avoid;
	}
	span.issue, span.note {
		padding: .1em .5em .15em;
		border-right-style: solid;
	}

	blockquote > :first-child,
	.note  > p:first-child,
	.issue > p:first-child,
	.amendment > p:first-child,
	.correction > p:first-child,
	.addition > p:first-child {
		margin-top: 0;
	}
	blockquote > :last-child,
	.note  > p:last-child,
	.issue > p:last-child,
	.amendment > p:last-child,
	.correction > p:last-child,
	.addition > p:last-child {
		margin-bottom: 0;
	}


	.issue::before, .issue > .marker,
	.example::before, .example > .marker,
	.note::before, .note > .marker,
	details.note > summary > .marker,
	.amendment::before, .amendment > .marker,
	details.amendment > summary > .marker,
	.addition::before, .addition > .marker,
	addition.amendment > summary > .marker,
	.correction::before, .correction > .marker,
	correction.amendment > 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);
	}

/** Amendment Box *************************************************************/

	.amendment, .correction, .addition {
		border-color: #330099;
		border-color: var(--amendment-border);
		background: #F5F0FF;
		background: var(--amendment-bg);
		color: black;
		color: var(--amendment-text);
	}
	.amendment.proposed, .correction.proposed, .addition.proposed {
		border-style: solid;
		border-block-width: 0.25em;
	}
	.amendment::before, .amendment > .marker,
	details.amendment > summary::before, details.amendment > summary > .marker,
	.correction::before, .correction > .marker,
	details.correction > summary::before, details.correction > summary > .marker,
	.addition::before, .addition > .marker,
	details.addition > summary::before, details.addition > summary > .marker {
		color: #220066;
		color: var(--amendmentheading-text);
	}
	.amendment.proposed::before, .amendment.proposed > .marker,
	details.amendment.proposed > summary::before, details.amendment.proposed > summary > .marker,
	.correction.proposed::before, .correction.proposed > .marker,
	details.correction.proposed > summary::before, details.correction.proposed > summary > .marker,
	.addition.proposed::before, .addition.proposed > .marker,
	details.addition.proposed > summary::before, details.addition.proposed > summary > .marker {
		font-weight: bold;
	}

/** 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: 0.1rem 1px 0;
		/* Larger, more consistently-sized click target */
		display: block;
		/* Switch to using border-bottom for underlines */
		text-decoration: none;
		border-bottom: 1px solid;
		/* 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:focus,
	.toc a:hover {
		background: rgba(75%, 75%, 75%, .25);
		background: var(--a-hover-bg);
		border-bottom-width: 3px;
		margin-bottom: -2px;
	}
	.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;
	}
	.toc {
		line-height: 1.1em;
	}

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

	/* @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 li li li .secno { font-size: 85%; }
		.toc > li li li li li .secno { font-size: 100%; }

		.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;
			border-bottom: 3px solid transparent;
			margin-bottom: -3px;
		}
		#toc .content:hover,
		#toc .content:focus {
			background: rgba(75%, 75%, 75%, .25);
			background: var(--a-hover-bg);
			border-bottom-color: #054572;
			border-bottom-color: var(--toclink-underline);
		}
		#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 a + span {
			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;
	}

/** Outdated warning **********************************************************/

.outdated-spec {
	color: black;
	color: var(--outdatedspec-text);
	background-color: rgba(0,0,0,0.5);
	background-color: var(--outdatedspec-bg);
}

.outdated-warning {
	position: fixed;
	bottom: 50%;
	left: 0;
	right: 0;
	margin: 0 auto;
	width: 50%;
	background: maroon;
	background: var(--outdated-bg);
	color: white;
	color: var(--outdated-text);
	border-radius: 1em;
	box-shadow: 0 0 1em red;
	box-shadow: 0 0 1em var(--outdated-shadow);
	padding: 2em;
	text-align: center;
	z-index: 2;
}

.outdated-warning a {
	color: currentcolor;
	background: transparent;
}

.edited-rec-warning {
	background: darkorange;
	background: var(--editedrec-bg);
	box-shadow: 0 0 1em;
}

.outdated-warning button {
	color: var(--outdated-text);
	border-radius: 1em;
	box-shadow: 0 0 1em red;
	box-shadow: 0 0 1em var(--outdated-shadow);
	padding: 2em;
	text-align: center;
	z-index: 2;
}

.outdated-warning a {
	color: currentcolor;
	background: transparent;
}

.edited-rec-warning {
	background: darkorange;
	background: var(--editedrec-bg);
	box-shadow: 0 0 1em;
}

.outdated-warning button {
	position: absolute;
	top: 0;
	right:0;
	margin: 0;
	border: 0;
	padding: 0.25em 0.5em;
	background: transparent;
	color: white;
	color: var(--outdated-text);
	font:1em sans-serif;
	text-align:center;
}

.outdated-warning span {
	display: block;
}

.outdated-collapsed {
	bottom: 0;
	border-radius: 0;
	width: 100%;
	padding: 0;
}

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

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

		.outdated-warning {
			position: absolute;
			border-style: solid;
			border-color: red;
		}

		.outdated-warning input {
			display: none;
		}
	}
	@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 item positioning:
		  "content column" is 50ems wide at max; less on smaller screens.
		  Extra space (after ToC + content) is empty on the right.

		  1. When item < content column, centers item in column.
		  2. When content < item < available, left-aligns.
		  3. When item > 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>
    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 5fcd28d6d, updated Tue May 30 13:12:11 2023 -0700" name="generator">
  <link href="https://htmlpreview.github.io/?https://github.com/SebastienBini/cpp-relocation-proposal/blob/main/relocation.html" rel="canonical">
  <link href="https://isocpp.org/favicon.ico" rel="icon">
  <meta content="b28d6d3e7ece4f80589cf96de0558804470df26f" name="document-revision">
<style>/* Boilerplate: 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;
}

@media (prefers-color-scheme: dark) {
    :root {
        --selflink-text: black;
        --selflink-bg: silver;
        --selflink-hover-text: white;
    }
}
</style>
<style>/* Boilerplate: style-colors */

/* Any --*-text not paired with a --*-bg is assumed to have a transparent bg */
:root {
    color-scheme: light dark;

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

    --unofficial-watermark: url(https://www.w3.org/StyleSheets/TR/2016/logos/UD-watermark);

    --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: #bbb;
    --a-visited-text: var(--a-normal-text);
    --a-visited-underline: #707070;
    --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);

    --amendment-border: #330099;
    --amendment-bg: #F5F0FF;
    --amendment-text: var(--text);
    --amendmentheading-text: #220066;

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

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

        --unofficial-watermark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='400'%3E%3Cg fill='%23100808' transform='translate(200 200) rotate(-45) translate(-200 -200)' stroke='%23100808' stroke-width='3'%3E%3Ctext x='50%25' y='220' style='font: bold 70px sans-serif; text-anchor: middle; letter-spacing: 6px;'%3EUNOFFICIAL%3C/text%3E%3Ctext x='50%25' y='305' style='font: bold 70px sans-serif; text-anchor: middle; letter-spacing: 6px;'%3EDRAFT%3C/text%3E%3C/g%3E%3C/svg%3E");

        --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);

        --amendment-border: #330099;
        --amendment-bg: #080010;
        --amendment-text: var(--text);
        --amendmentheading-text: #cc00ff;

        --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; }
}
</style>
<style>/* Boilerplate: 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>/* Boilerplate: style-issues */
a[href].issue-return {
    float: right;
    float: inline-end;
    color: var(--issueheading-text);
    font-weight: bold;
    text-decoration: none;
}
</style>
<style>/* Boilerplate: 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>/* Boilerplate: 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%;
}
.example > a.self-link,
.note > a.self-link,
.issue > a.self-link {
    /* These blocks are overflow:auto, so positioning outside
       doesn't work. */
    left: auto;
    right: 0;
}
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>/* Boilerplate: 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: rgba(0, 0, 0, .03); }
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 */


@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 */
}
</style>
 <body class="h-entry">
  <div class="head">
   <p data-fill-with="logo"></p>
   <h1 class="p-name no-ref" id="title">P2785R3<br>Relocating prvalues</h1>
   <h2 class="no-num no-toc no-ref heading settled" id="profile-and-date"><span class="content">Published Proposal, <time class="dt-updated" datetime="2023-06-14">2023-06-14</time></span></h2>
   <div data-fill-with="spec-metadata">
    <dl>
     <dt>This version:
     <dd><a class="u-url" href="https://htmlpreview.github.io/?https://github.com/SebastienBini/cpp-relocation-proposal/blob/main/relocation.html">https://htmlpreview.github.io/?https://github.com/SebastienBini/cpp-relocation-proposal/blob/main/relocation.html</a>
     <dt class="editor">Authors:
     <dd class="editor p-author h-card vcard"><span class="p-name fn"></span>
     <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:sebastien.bini@gmail.com">Sébastien Bini</a> (<span class="p-org org">Stormshield</span>)
     <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:ed@catmur.uk">Ed Catmur</a>
     <dt>Audience:
     <dd>LEWG, EWG
     <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 several mechanisms to enable real relocation in C++.

  We cover several topics, such as trivial relocatibility, container optimizations,
  supports for relocate-only types, library changes and the impact of the existing code base.</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="#intro"><span class="secno">1</span> <span class="content">Overview</span></a>
    <li>
     <a href="#motivation"><span class="secno">2</span> <span class="content">Motivation</span></a>
     <ol class="toc">
      <li><a href="#motivation-never-empty"><span class="secno">2.1</span> <span class="content">Never-empty types</span></a>
      <li><a href="#motivation-constant-objects"><span class="secno">2.2</span> <span class="content">Constant objects</span></a>
      <li><a href="#motivation-teachability"><span class="secno">2.3</span> <span class="content">Teachability</span></a>
      <li><a href="#motivation-vs-trivial-relocation"><span class="secno">2.4</span> <span class="content">Versus trivial relocation</span></a>
      <li><a href="#motivation-helper-types"><span class="secno">2.5</span> <span class="content">Helper types</span></a>
      <li><a href="#motivation-performance"><span class="secno">2.6</span> <span class="content">Library performance</span></a>
     </ol>
    <li>
     <a href="#nomenclature"><span class="secno">3</span> <span class="content">Nomenclature</span></a>
     <ol class="toc">
      <li><a href="#src-and-target"><span class="secno">3.1</span> <span class="content">Source and target objects</span></a>
      <li><a href="#dtor-state"><span class="secno">3.2</span> <span class="content">Destructed state</span></a>
      <li><a href="#unowned-parameter"><span class="secno">3.3</span> <span class="content">Unowned parameter</span></a>
     </ol>
    <li>
     <a href="#compare"><span class="secno">4</span> <span class="content">Comparison with existing proposals</span></a>
     <ol class="toc">
      <li><a href="#compare-P1144R8"><span class="secno">4.1</span> <span class="content">P1144R8: Object relocation in terms of move plus destroy by Arthur O’Dwyer</span></a>
      <li><a href="#compare-P0023R0"><span class="secno">4.2</span> <span class="content">P0023R0: Relocator: Efficiently moving objects by Denis Bider</span></a>
      <li><a href="#compare-N4158"><span class="secno">4.3</span> <span class="content">N4158: Destructive Move by Pablo Halpern</span></a>
      <li><a href="#compare-P1029R3"><span class="secno">4.4</span> <span class="content">P1029R3: move = bitcopies by Niall Douglas</span></a>
      <li><a href="#compare-P0308R0"><span class="secno">4.5</span> <span class="content">P0308R0: Valueless Variants Considered Harmful by Peter Dimov</span></a>
      <li><a href="#compare-D2839"><span class="secno">4.6</span> <span class="content">D2839R1: Nontrivial Relocation via a New <em>owning reference</em> Type by Brian Bi and Joshua Berne</span></a>
     </ol>
    <li>
     <a href="#lg-changes"><span class="secno">5</span> <span class="content">Proposed language changes</span></a>
     <ol class="toc">
      <li>
       <a href="#reloc-operator"><span class="secno">5.1</span> <span class="content">reloc operator</span></a>
       <ol class="toc">
        <li><a href="#reloc-perfect-fwd"><span class="secno">5.1.1</span> <span class="content">reloc to perfectly forward all value categories</span></a>
        <li><a href="#reloc-value-change"><span class="secno">5.1.2</span> <span class="content">reloc returns a temporary</span></a>
        <li><a href="#reloc-illegal-uses"><span class="secno">5.1.3</span> <span class="content">Illegal uses of reloc</span></a>
        <li><a href="#reloc-early-end-of-scope"><span class="secno">5.1.4</span> <span class="content">Early end-of-scope</span></a>
        <li><a href="#conditional-reloc"><span class="secno">5.1.5</span> <span class="content">Conditional relocation</span></a>
        <li><a href="#reloc-elision"><span class="secno">5.1.6</span> <span class="content">Relocation elision</span></a>
        <li><a href="#discarded-reloc-expr"><span class="secno">5.1.7</span> <span class="content">Discarded reloc expressions</span></a>
       </ol>
      <li>
       <a href="#reloc-ctor"><span class="secno">5.2</span> <span class="content">Relocation constructor</span></a>
       <ol class="toc">
        <li>
         <a href="#reloc-ctor-declaration"><span class="secno">5.2.1</span> <span class="content">Declaration</span></a>
         <ol class="toc">
          <li><a href="#reloc-ctor-declaration-implicit"><span class="secno">5.2.1.1</span> <span class="content">Implicit declaration</span></a>
          <li><a href="#reloc-ctor-declaration-deleted"><span class="secno">5.2.1.2</span> <span class="content">Deleted implicitly-declared or defaulted relocation constructor</span></a>
          <li><a href="#trivial-relocation"><span class="secno">5.2.1.3</span> <span class="content">Trivial relocation</span></a>
         </ol>
        <li>
         <a href="#reloc-ctor-definition"><span class="secno">5.2.2</span> <span class="content">Definition</span></a>
         <ol class="toc">
          <li><a href="#reloc-ctor-default-definition"><span class="secno">5.2.2.1</span> <span class="content">Default definition</span></a>
          <li><a href="#reloc-ctor-user-definition"><span class="secno">5.2.2.2</span> <span class="content">User-provided definition</span></a>
          <li><a href="#reloc-ctor-exceptions"><span class="secno">5.2.2.3</span> <span class="content">Exception handling</span></a>
          <li><a href="#reloc-ctor-additional-params"><span class="secno">5.2.2.4</span> <span class="content">Additional parameters</span></a>
         </ol>
        <li><a href="#reloc-ctor-invoke"><span class="secno">5.2.3</span> <span class="content">Invocation</span></a>
       </ol>
      <li>
       <a href="#reloc-assign-operator"><span class="secno">5.3</span> <span class="content">Relocation assignment operator</span></a>
       <ol class="toc">
        <li>
         <a href="#reloc-assign-declaration"><span class="secno">5.3.1</span> <span class="content">Declaration</span></a>
         <ol class="toc">
          <li><a href="#reloc-assign-operator-implicit"><span class="secno">5.3.1.1</span> <span class="content">Implicit declaration</span></a>
          <li><a href="#reloc-assign-declaration-deleted"><span class="secno">5.3.1.2</span> <span class="content">Deleted implicitly-declared or defaulted relocation assignment operator</span></a>
         </ol>
        <li>
         <a href="#aliased-reloc-assign"><span class="secno">5.3.2</span> <span class="content">Relocation assignment operator parameter relocation elision</span></a>
         <ol class="toc">
          <li><a href="#aliased-reloc-assign-declaration"><span class="secno">5.3.2.1</span> <span class="content">Elision at declaration level</span></a>
          <li><a href="#aliased-reloc-assign-definition"><span class="secno">5.3.2.2</span> <span class="content">Elision at definition level</span></a>
         </ol>
        <li>
         <a href="#reloc-assign-definition"><span class="secno">5.3.3</span> <span class="content">Definition</span></a>
         <ol class="toc">
          <li><a href="#reloc-assign-default-definition"><span class="secno">5.3.3.1</span> <span class="content">Default definition</span></a>
          <li><a href="#reloc-assign-user-definition"><span class="secno">5.3.3.2</span> <span class="content">Possible user definitions</span></a>
         </ol>
        <li><a href="#reloc-assign-invoke"><span class="secno">5.3.4</span> <span class="content">Invocation</span></a>
       </ol>
      <li><a href="#overload-resolution"><span class="secno">5.4</span> <span class="content">Overload resolution</span></a>
      <li>
       <a href="#structured-reloc"><span class="secno">5.5</span> <span class="content">Structured relocation</span></a>
       <ol class="toc">
        <li><a href="#structured-reloc-discussion"><span class="secno">5.5.1</span> <span class="content">Discussion</span></a>
        <li><a href="#structured-reloc-declaration"><span class="secno">5.5.2</span> <span class="content">Structured relocation declaration</span></a>
        <li>
         <a href="#structured-reloc-obj-decomposition"><span class="secno">5.5.3</span> <span class="content">Object decomposition</span></a>
         <ol class="toc">
          <li><a href="#structured-reloc-dm"><span class="secno">5.5.3.1</span> <span class="content">data members protocol</span></a>
          <li>
           <a href="#structured-reloc-get_all"><span class="secno">5.5.3.2</span> <span class="content">get_all protocol</span></a>
           <ol class="toc">
            <li><a href="#structured-reloc-tuple"><span class="secno">5.5.3.2.1</span> <span class="content">std::tuple and std::array are implementation-defined</span></a>
            <li><a href="#structured-reloc-implem"><span class="secno">5.5.3.2.2</span> <span class="content">Possible get_all implementations</span></a>
           </ol>
         </ol>
       </ol>
      <li>
       <a href="#decomposing-func"><span class="secno">5.6</span> <span class="content">Decomposing functions</span></a>
       <ol class="toc">
        <li><a href="#decomposing-func-declare"><span class="secno">5.6.1</span> <span class="content">Declaration</span></a>
        <li>
         <a href="#decomposing-func-definition"><span class="secno">5.6.2</span> <span class="content">Definition</span></a>
         <ol class="toc">
          <li><a href="#decomposing-func-examples"><span class="secno">5.6.2.1</span> <span class="content">Examples</span></a>
         </ol>
        <li>
         <a href="#ill-formed-decomposing-func"><span class="secno">5.6.3</span> <span class="content">Ill-formed definition</span></a>
         <ol class="toc">
          <li><a href="#decomposing-func-aberrations"><span class="secno">5.6.3.1</span> <span class="content">Aberrations</span></a>
          <li><a href="#decomposing-func-accessibility"><span class="secno">5.6.3.2</span> <span class="content">Accessibility</span></a>
          <li><a href="#decomposing-func-immovable"><span class="secno">5.6.3.3</span> <span class="content">ABI requirements</span></a>
          <li><a href="#decomposing-func-ill-formedness-criteria"><span class="secno">5.6.3.4</span> <span class="content">Ill-formedness criteria</span></a>
         </ol>
        <li><a href="#decomposing-lambda"><span class="secno">5.6.4</span> <span class="content">Decomposing lambda</span></a>
       </ol>
      <li>
       <a href="#abi"><span class="secno">5.7</span> <span class="content">ABI changes</span></a>
       <ol class="toc">
        <li><a href="#callee-destroy-abi"><span class="secno">5.7.1</span> <span class="content">relocate-only function parameters</span></a>
        <li><a href="#prvalue-assign-op-abi"><span class="secno">5.7.2</span> <span class="content">prvalue assignment operator</span></a>
        <li><a href="#decomposing-func-abi"><span class="secno">5.7.3</span> <span class="content">Decomposing functions</span></a>
       </ol>
     </ol>
    <li>
     <a href="#proposed-lib-changes"><span class="secno">6</span> <span class="content">Proposed library changes</span></a>
     <ol class="toc">
      <li>
       <a href="#std-mem-header"><span class="secno">6.1</span> <span class="content">Memory header</span></a>
       <ol class="toc">
        <li><a href="#std-construct_at"><span class="secno">6.1.1</span> <span class="content">std::construct_at</span></a>
        <li><a href="#std-destroy_relocate"><span class="secno">6.1.2</span> <span class="content">std::destroy_relocate</span></a>
        <li><a href="#std-uninitialized_relocate"><span class="secno">6.1.3</span> <span class="content">std::uninitialized_relocate</span></a>
       </ol>
      <li>
       <a href="#std-utility-header"><span class="secno">6.2</span> <span class="content">Utility header</span></a>
       <ol class="toc">
        <li><a href="#std-relocate"><span class="secno">6.2.1</span> <span class="content">std::relocate</span></a>
       </ol>
      <li>
       <a href="#stl-relocate-only"><span class="secno">6.3</span> <span class="content">Bring relocate-only type support to the STL</span></a>
       <ol class="toc">
        <li><a href="#std-pair-tuple"><span class="secno">6.3.1</span> <span class="content">std::pair and std::tuple</span></a>
        <li><a href="#std-optional"><span class="secno">6.3.2</span> <span class="content">std::optional</span></a>
        <li><a href="#std-variant"><span class="secno">6.3.3</span> <span class="content">std::variant</span></a>
        <li><a href="#std-any"><span class="secno">6.3.4</span> <span class="content">std::any</span></a>
       </ol>
      <li>
       <a href="#lib-change-containers"><span class="secno">6.4</span> <span class="content">Containers</span></a>
       <ol class="toc">
        <li><a href="#lib-insertion-overloads"><span class="secno">6.4.1</span> <span class="content">Insertion overloads</span></a>
        <li><a href="#lib-extract-functions"><span class="secno">6.4.2</span> <span class="content">Extracting functions</span></a>
        <li><a href="#lib-relocate_out"><span class="secno">6.4.3</span> <span class="content">relocate_out</span></a>
        <li><a href="#std-vector"><span class="secno">6.4.4</span> <span class="content">std::vector</span></a>
        <li><a href="#std-deque"><span class="secno">6.4.5</span> <span class="content">std::deque</span></a>
        <li><a href="#std-list"><span class="secno">6.4.6</span> <span class="content">std::list</span></a>
        <li><a href="#std-forward_list"><span class="secno">6.4.7</span> <span class="content">std::forward_list</span></a>
        <li><a href="#std-set-and-map"><span class="secno">6.4.8</span> <span class="content">set and map containers</span></a>
        <li><a href="#std-queues"><span class="secno">6.4.9</span> <span class="content">queues</span></a>
        <li><a href="#std-iterator"><span class="secno">6.4.10</span> <span class="content">Iterator library</span></a>
        <li><a href="#std-misc-classes"><span class="secno">6.4.11</span> <span class="content">Other STL classes</span></a>
       </ol>
     </ol>
    <li>
     <a href="#discuss"><span class="secno">7</span> <span class="content">Discussions</span></a>
     <ol class="toc">
      <li><a href="#reloc-new-keyword"><span class="secno">7.1</span> <span class="content">Why a new keyword?</span></a>
      <li>
       <a href="#stl-api-changes"><span class="secno">7.2</span> <span class="content">STL API changes</span></a>
       <ol class="toc">
        <li><a href="#value-extract-api-choice"><span class="secno">7.2.1</span> <span class="content">Why add overload to the value-extracting functions in STL containers?</span></a>
        <li><a href="#optional-extract-api-choice"><span class="secno">7.2.2</span> <span class="content">Why name the value-extracting function of optional extract?</span></a>
       </ol>
      <li>
       <a href="#future-directions"><span class="secno">7.3</span> <span class="content">Future directions</span></a>
       <ol class="toc">
        <li><a href="#future-capture-value"><span class="secno">7.3.1</span> <span class="content">More perfect forwarding</span></a>
        <li><a href="#solve-discarded-reloc-expr"><span class="secno">7.3.2</span> <span class="content">discarded reloc expression</span></a>
       </ol>
      <li><a href="#easier-cpp"><span class="secno">7.4</span> <span class="content">Will it make C++ easier?</span></a>
     </ol>
    <li>
     <a href="#references"><span class="secno"></span> <span class="content">References</span></a>
     <ol class="toc">
      <li><a href="#informative"><span class="secno"></span> <span class="content">Informative References</span></a>
     </ol>
   </ol>
  </nav>
  <main>
   <h2 class="heading settled" data-level="1" id="intro"><span class="secno">1. </span><span class="content">Overview</span><a class="self-link" href="#intro"></a></h2>
   <p>C++11 introduced rvalue references, move constructor and move-assignment operators.
While these have improved C++ in many ways, there is still one operation that is 
unsupported: relocation. By "relocation", we mean the operation to construct a 
new object while simultaneously destructing the source object. Some other proposals
look at this as "move + destruct", while we see this as a unique, different, 
and optionally better optimized operation.</p>
   <p>This new operation brings several benefits, principally in terms of performance and
code correctness. This proposal has its own take on trivial relocatibility 
(which allows to optimize the relocation operation into a simple <code class="highlight"><c- n>memcpy</c-></code>). 
It also supports relocate-only types (such as <code class="highlight"><c- n>gsl</c-><c- o>::</c-><c- n>not_null</c-><c- o>&lt;</c-><c- n>std</c-><c- o>::</c-><c- n>unique_ptr</c-><c- o>&lt;</c-><c- b>int</c-><c- o>>></c-></code>)
and enables to relocate constant objects.</p>
   <p>The proposal introduces:</p>
   <ul>
    <li data-md>
     <p>two new special member functions: a relocation constructor <code class="highlight"><c- n>T</c-><c- p>(</c-><c- n>T</c-><c- p>)</c-></code> and a relocation
assignment operator <code class="highlight"><c- n>T</c-><c- o>&amp;</c-> <c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- n>T</c-><c- p>)</c-></code> ;</p>
    <li data-md>
     <p>a new keyword: <code class="highlight"><c- n>reloc</c-></code> ;</p>
    <li data-md>
     <p>slight changes to overload resolution rules ;</p>
    <li data-md>
     <p>might introduce ABI breaks of some functions ;</p>
    <li data-md>
     <p>library evolution to support relocation.</p>
   </ul>
   <p>The proposal does not introduce a new value type; instead relocation will happen from prvalues.</p>
   <h2 class="heading settled" data-level="2" id="motivation"><span class="secno">2. </span><span class="content">Motivation</span><a class="self-link" href="#motivation"></a></h2>
   <h3 class="heading settled" data-level="2.1" id="motivation-never-empty"><span class="secno">2.1. </span><span class="content">Never-empty types</span><a class="self-link" href="#motivation-never-empty"></a></h3>
   <p>C++ lacks support for relocate-only types. Let’s us consider the <code class="highlight"><c- n>gsl</c-><c- o>::</c-><c- n>not_null</c-><c- o>&lt;</c-><c- n>std</c-><c- o>::</c-><c- n>unique_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>></c-></code> case for a moment. <code class="highlight"><c- n>gsl</c-><c- o>::</c-><c- n>not_null</c-></code> inhibits
the move constructor, as a moved-from pointer would be null and break the class invariant.
In turn <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>unique_ptr</c-></code> inhibits the copy constructor because of its ownership policy. 
Hence this type is non-copyable and non-movable. Those objects are legitimate since
they improve code correctness (the user need not check whether they are empty) and performance
(the compiler need not check whether they are empty).</p>
   <p>Unfortunately those objects are quite impractical to handle in C++: they cannot be moved around
in program memory (passed down to function, stored and removed from containers, etc...), 
while in principle there is no good reason to prevent that. With the relocation
semantics in mind this would be allowed: each time the <code class="highlight"><c- n>gsl</c-><c- o>::</c-><c- n>not_null</c-><c- o>&lt;</c-><c- n>std</c-><c- o>::</c-><c- n>unique_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>></c-></code> is moved in memory, it simultaneously destroys the previous instance (in practice, 
this simply means the memory occupied by the source object just becomes uninitialized, 
and in particular, the source object’s destructor is not called).</p>
   <h3 class="heading settled" data-level="2.2" id="motivation-constant-objects"><span class="secno">2.2. </span><span class="content">Constant objects</span><a class="self-link" href="#motivation-constant-objects"></a></h3>
   <p>Another place where C++ falls short is with constant objects. As of today, constant
objects cannot be moved in C++ as the move constructor cannot steal the resources
of a constant object. As such, never-modified objects that
end their life by being moved (e.g. via <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>move</c-></code>, or implicitly by return-value optimization
where complete elision is not viable) cannot be marked as <code class="highlight"><c- k>const</c-></code>. 
This is a missed opportunity and it leads to poorer code. The
proposed relocation semantics solves this problem: constant objects can be relocated,
they are just destroyed when done so.</p>
   <p>Automatic objects are recommended by various guidelines to be constant, since a constant object
will not change throughout its lifetime, simplifying reasoning about program state both for
humans (coders, reviewers, maintainers) and for machines (compilers, tooling). Allowing an object
to be <code class="highlight"><c- k>const</c-></code> throughout its lifetime but give up its resources at the end of its lifetime allows
for better, safer code.</p>
   <p>As we will see other proposals about relocation provide little support for
relocate-only types, and even less for constant objects.
They only partly improve their support in a limited way.</p>
   <h3 class="heading settled" data-level="2.3" id="motivation-teachability"><span class="secno">2.3. </span><span class="content">Teachability</span><a class="self-link" href="#motivation-teachability"></a></h3>
   <p>It is a matter of some confusion for learners that a "moved-from" object still exists and is
accessible, but has an unspecified state. This leads to so-called "use-after-move" bugs, and
requires static analysis passes and coding guidelines to prevent. "What does <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>move</c-></code> do?"
is, regrettably, a common "gotcha" question in a certain style of coding interview. In this
matter C++ compares unfavorably to other languages where the "move" operation is destructive
(if trivial) and bars further access to the source object.</p>
   <h3 class="heading settled" data-level="2.4" id="motivation-vs-trivial-relocation"><span class="secno">2.4. </span><span class="content">Versus trivial relocation</span><a class="self-link" href="#motivation-vs-trivial-relocation"></a></h3>
   <p>As will be seen below, trivial relocation provides an incomplete solution to the issues
presented in this section. The primary concern is that of composability; an aggregate of
a self-referential type that cannot be trivially relocated (e.g. <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>string</c-></code> in some
implementations) and a relocate-only type (e.g. a non-null <code class="highlight"><c- n>unique_ptr</c-></code>) can neither be
relocated by move-and-destroy nor trivially relocated. Thus non-trivial relocation
emerges as a requirement.</p>
   <h3 class="heading settled" data-level="2.5" id="motivation-helper-types"><span class="secno">2.5. </span><span class="content">Helper types</span><a class="self-link" href="#motivation-helper-types"></a></h3>
   <p>In framework code it is a relatively everyday task to write helper classes that are
constructed to own some resource, passed around from place to place, and then destroyed,
cleaning up the resource in the destructor. Move semantics for such classes requires
identifying or adding an appropriate empty state, writing a move constructor, and
adding checks to the destructor; all of these inhibit performance and are opportunities
to introduce bugs. Relocation would replace all of this with a single defaulted special
member function declaration.</p>
   <h3 class="heading settled" data-level="2.6" id="motivation-performance"><span class="secno">2.6. </span><span class="content">Library performance</span><a class="self-link" href="#motivation-performance"></a></h3>
   <p>Finally, relocation and especially trivial relocation will bring performance boosts
in many situations. Other proposals make fine work at enumerating all the gains to be had
from trivial relocation (see in particular <a data-link-type="biblio" href="#biblio-p1144r8" title="std::is_trivially_relocatable">[P1144R8]</a>). To summarize, the performance gains
are mainly in containers (std::vector::resize and the likes)
and code size gains from functions that use <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>swap</c-></code>.</p>
   <h2 class="heading settled" data-level="3" id="nomenclature"><span class="secno">3. </span><span class="content">Nomenclature</span><a class="self-link" href="#nomenclature"></a></h2>
   <p>We refer to the <a href="https://wg21.link/intro.defs">Terms and definitions</a> of the C++ Standard,
and to nomenclature introduced therein,
in particular the <a href="https://wg21.link/intro.object">object model</a>.
In addition, we define:</p>
   <h3 class="heading settled" data-level="3.1" id="src-and-target"><span class="secno">3.1. </span><span class="content">Source and target objects</span><a class="self-link" href="#src-and-target"></a></h3>
   <p>Relocation is the act of constructing a new instance while ending the lifetime of an existing one.
This allows destructively stealing its resources, if any.</p>
   <p>The new instance is called the <em>target object</em>.
The existing instance whose lifetime is ended and whose resources
are stolen is called the <em>source object</em>.</p>
   <h3 class="heading settled" data-level="3.2" id="dtor-state"><span class="secno">3.2. </span><span class="content">Destructed state</span><a class="self-link" href="#dtor-state"></a></h3>
   <p>An object is to be in a <em>destructed state</em> if its lifetime has ended because:</p>
   <ul>
    <li data-md>
     <p>its destructor was called, or ;</p>
    <li data-md>
     <p>it was passed to as source object to its relocation constructor.</p>
   </ul>
   <p>It is a
programming error to call the destructor of an object if it is already in a <em>destructed state</em>.
As described in <a href="https://eel.is/c++draft/basic.life#9">[basic.life]</a>,
this has undefined behavior unless the object type is trivial, in which case its destructor
or pseudo-destructor is a no-op.</p>
   <h3 class="heading settled" data-level="3.3" id="unowned-parameter"><span class="secno">3.3. </span><span class="content">Unowned parameter</span><a class="self-link" href="#unowned-parameter"></a></h3>
   <p>An object is said to be an <em>unowned parameter</em> with regards to a function <code class="highlight"><c- n>f</c-></code> if the object is a parameter of the function, passed by value, but the
function <code class="highlight"><c- n>f</c-></code> does not have control over its lifetime.</p>
   <p>The lifetime of function parameters is implementation-defined in C++, but it
is of most importance with relocation. Depending on the function call convention
or ABI, the function may or may not be in charge of the lifetime of its parameters.</p>
   <p>We denote two main parameter passing conventions:</p>
   <ul>
    <li data-md>
     <p><em>caller-destroy</em>: the call site is in charge of the lifetime of the parameter passed in the function call ;</p>
    <li data-md>
     <p><em>callee-destroy</em>: the function itself is in charge of the lifetime of its parameters ;</p>
   </ul>
   <p>Depending on the ABI choice, the convention can be per parameter, or apply
to all the function parameters. Other conventions may exist, and they are
still compatible with this proposal.</p>
   <p>For instance, in a function with caller-destroy convention, all its value
parameters are <em>unowned parameters</em>.
Likewise, with callee-destroy, none of its parameters are <em>unowned parameters</em>.</p>
   <h2 class="heading settled" data-level="4" id="compare"><span class="secno">4. </span><span class="content">Comparison with existing proposals</span><a class="self-link" href="#compare"></a></h2>
   <p>This proposal introduces the <code class="highlight"><c- n>reloc</c-></code> keyword, which allows users to explicitly
and safely relocate local variables in their code base.</p>
   <p>This proposal is also one of the few (with <a data-link-type="biblio" href="#biblio-p0308r0" title="Valueless Variants Considered Harmful">[P0308R0]</a>), to tackle the case of
relocate-only types. The <code class="highlight"><c- n>reloc</c-></code> keyword thus becomes necessary to safely pass 
around such objects in user code.</p>
   <p>Also, all these proposals (but <a data-link-type="biblio" href="#biblio-p0308r0" title="Valueless Variants Considered Harmful">[P0308R0]</a>) aim to optimize the move and destruct
operations into a single memcpy. But there are places where this optimization 
could not happen, and we are left with a suboptimized move and destruct. 
The relocation constructor that we propose offers a customization point, and
especially allow for a more optimized relocation technique than move and destruct.</p>
   <h3 class="heading settled" data-level="4.1" id="compare-P1144R8"><span class="secno">4.1. </span><span class="content">P1144R8: Object relocation in terms of move plus destroy by Arthur O’Dwyer</span><a class="self-link" href="#compare-P1144R8"></a></h3>
   <p><a data-link-type="biblio" href="#biblio-p1144r8" title="std::is_trivially_relocatable">[P1144R8]</a> puts the focus on trivially relocatable types, and offers ways to
mark a type as trivially relocatable.</p>
   <p>The current proposal has its own take on trivial relocatability that does not
rely on a class attribute. Instead the trivial relocatability
trait flows naturally from the new relocation constructor that we introduce. In short:
if a class type has a relocation constructor that is (explicitly) declared as defaulted or
is implicitly defined and not defaulted as deleted, and all of 
its subobjects are trivially relocatable (or fully trivial), then the type
is trivially relocatable.</p>
   <p>This approach is not prone to errors when compared to a class attribute,
which could be mistakenly overriden by some users on classes that are not 
trivially relocatable.</p>
   <p>Also, <a data-link-type="biblio" href="#biblio-p1144r8" title="std::is_trivially_relocatable">[P1144R8]</a> does not account for relocate-only types. To some extend, trivially
relocatable types have minimal support as they could be trivially relocated in the
places where "move plus destroy" can be optimized. However:</p>
   <ul>
    <li data-md>
     <p>this only concerns trivially relocatable types ;</p>
    <li data-md>
     <p>there are places where the optimization cannot happen, and as such the object cannot be "relocated" ;</p>
    <li data-md>
     <p>this poses a composability issue. If a relocate-only (non-movable and non-copyable), trivially-relocatable type
is a data member of a class that also has other non-trivially-relocatable data members, then the
enclosing class becomes non trivially relocatable, while remaining relocate-only. 
This renders the enclosing class impractical to use without proper support
for relocate-only types.</p>
   </ul>
   <p>In this proposal we reuse <a data-link-type="biblio" href="#biblio-p1144r8" title="std::is_trivially_relocatable">[P1144R8]</a>'s <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>relocate</c-></code> function, except that we
name it <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>destroy_relocate</c-></code>.</p>
   <h3 class="heading settled" data-level="4.2" id="compare-P0023R0"><span class="secno">4.2. </span><span class="content">P0023R0: Relocator: Efficiently moving objects by Denis Bider</span><a class="self-link" href="#compare-P0023R0"></a></h3>
   <p>The Relocator introduced in <a data-link-type="biblio" href="#biblio-p0023r0" title="Relocator: Efficiently moving objects">[P0023R0]</a> is similar to the proposed relocation constructor.
However P0023R0’s Relocator is not viewed as a constructor. Instead, it is a special
function that can be invoked in lieu of move plus destroy where possible.</p>
   <p>However this brings again suboptimal support for relocate-only types. Indeed <a data-link-type="biblio" href="#biblio-p0023r0" title="Relocator: Efficiently moving objects">[P0023R0]</a> does not force relocation to happen in all cases, and falls back to move+destroy paradigm
when relocation cannot happen.</p>
   <p>A typical example is when relocating a function parameter:</p>
<pre class="language-c++ highlight"><c- b>void</c-> <c- nf>sink</c-><c- p>(</c-><c- n>T</c-><c- p>);</c->
<c- b>void</c-> <c- nf>foo</c-><c- p>(</c-><c- n>T</c-> <c- n>x</c-><c- p>)</c-> <c- p>{</c-> <c- n>sink</c-><c- p>(</c-><c- n>x</c-><c- p>);</c-> <c- p>}</c->
</pre>
   <p>Here, under the terms of <a data-link-type="biblio" href="#biblio-p0023r0" title="Relocator: Efficiently moving objects">[P0023R0]</a>, relocation may not happen because of ABI
constraints (if <code class="highlight"><c- n>x</c-></code> is an unowned parameter).
This will cause <code class="highlight"><c- n>foo</c-></code> to fallback to a move+deferred detroy paradigm.</p>
   <p>This proposal has another take on this issue: if <code class="highlight"><c- n>T</c-></code> is relocate-only, then any
function
that takes a <code class="highlight"><c- n>T</c-></code> parameter by value is required to have an ABI that allows it to 
relocate 
its input parameter (e.g. callee-destroy ABI).</p>
   <p>This proposal also introduces the <code class="highlight"><c- n>reloc</c-></code> keyword that is here to trigger
the relocation, and protect against the reuse of the relocated object. 
The solution then becomes:</p>
<pre class="language-c++ highlight"><c- b>void</c-> <c- nf>sink</c-><c- p>(</c-><c- n>T</c-><c- p>);</c->
<c- b>void</c-> <c- nf>foo</c-><c- p>(</c-><c- n>T</c-> <c- n>x</c-><c- p>)</c-> <c- p>{</c-> <c- n>sink</c-><c- p>(</c-><c- n>reloc</c-> <c- n>x</c-><c- p>);</c-> <c- d>/* x can no longer be used. */</c-> <c- p>}</c->
</pre>
   <p>Moreover, the proposed syntax for invoking <a data-link-type="biblio" href="#biblio-p0023r0" title="Relocator: Efficiently moving objects">[P0023R0]</a>'s relocator is low-level and
prone to error:</p>
<pre class="language-c++ highlight"><c- n>T</c-> <c- n>x</c-><c- p>;</c->
<c- k>alignas</c-><c- p>(</c-><c- n>T</c-><c- p>)</c-> <c- b>char</c-> <c- n>buf</c-><c- p>[</c-><c- k>sizeof</c-><c- p>(</c-><c- n>T</c-><c- p>)];</c->
<c- n>T</c-><c- o>*</c-> <c- n>y</c-> <c- o>=</c-> <c- n>new</c-> <c- p>(</c-><c- n>buf</c-><c- p>)</c-> <c- o>>></c-><c- n>T</c-><c- p>(</c-><c- n>x</c-><c- p>);</c->
</pre>
   <p>Here the lifetime of <code class="highlight"><c- n>x</c-></code> has been ended as if by a destructor call, but the language
is not aware of this,
so firstly the user may erreoneously refer to <code class="highlight"><c- n>x</c-></code> as if it was within its lifetime,
and secondly if an object is not recreated in <code class="highlight"><c- n>x</c-></code> by the time the block
exits, the behavior is undefined by <a href="https://eel.is/c++draft/basic.life#9">[basic.life]/9</a>.
Likewise, the language is not aware of the existence of <code class="highlight"><c- o>*</c-><c- n>y</c-></code> so will not call its
destructor; the behavior is then possibly undefined under <a href="https://eel.is/c++draft/basic.life#5">[basic.life]/5</a>.
In contrast, the present proposal would write the above as:</p>
<pre class="language-c++ highlight"><c- n>T</c-> <c- n>x</c-><c- p>;</c->
<c- n>T</c-> <c- n>y</c-> <c- o>=</c-> <c- n>reloc</c-> <c- n>x</c-><c- p>;</c->
</pre>
   <p>Here the use of the <code class="highlight"><c- n>reloc</c-></code> keyword ensures that the language is aware that the lifetime
of <code class="highlight"><c- n>x</c-></code> has finished, so the destructor only of <code class="highlight"><c- n>y</c-></code> is called at scope exit.</p>
   <h3 class="heading settled" data-level="4.3" id="compare-N4158"><span class="secno">4.3. </span><span class="content">N4158: Destructive Move by Pablo Halpern</span><a class="self-link" href="#compare-N4158"></a></h3>
   <p><a data-link-type="biblio" href="#biblio-n4158" title="Destructive Move">[N4158]</a> proposes a customizable function <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>uninitialized_destructive_move</c-></code>,
that is somewhat similar to the relocation constructor, but is a pure library solution.</p>
   <p>It has several drawbacks :</p>
   <ul>
    <li data-md>
     <p>relocation can only happen if this function is called explicitly. Typically this function
would be called in container implementation. But then we cannot relocate 
local variables with this.</p>
    <li data-md>
     <p>users can write their own <code class="highlight"><c- n>uninitialized_destructive_move</c-></code> overload, but this
is terrible for composability. Classes that have a subobject with a 
custom <code class="highlight"><c- n>uninitialized_destructive_move</c-></code> overload do not get a <code class="highlight"><c- n>uninitialized_destructive_move</c-></code> overload generated for free.</p>
    <li data-md>
     <p><code class="highlight"><c- n>uninitialized_destructive_move</c-></code> cannot be default-generated with memberwise
relocation.</p>
   </ul>
   <h3 class="heading settled" data-level="4.4" id="compare-P1029R3"><span class="secno">4.4. </span><span class="content">P1029R3: move = bitcopies by Niall Douglas</span><a class="self-link" href="#compare-P1029R3"></a></h3>
   <p><a data-link-type="biblio" href="#biblio-p1029r3" title="move = bitcopies">[P1029R3]</a> enables a special bitcopies move constructor for types that are trivially relocatable.</p>
   <p>Like the other proposals <a data-link-type="biblio" href="#biblio-p1029r3" title="move = bitcopies">[P1029R3]</a> does not provide support for relocate-only types
(it suffers from the same drawbacks as <a data-link-type="biblio" href="#biblio-p1144r8" title="std::is_trivially_relocatable">[P1144R8]</a> in that regard).</p>
   <h3 class="heading settled" data-level="4.5" id="compare-P0308R0"><span class="secno">4.5. </span><span class="content">P0308R0: Valueless Variants Considered Harmful by Peter Dimov</span><a class="self-link" href="#compare-P0308R0"></a></h3>
   <p>We only consider the "pilfering" proposition from <a data-link-type="biblio" href="#biblio-p0308r0" title="Valueless Variants Considered Harmful">[P0308R0]</a>.
P0308R0’s pilfering shares some similarities with the current proposal, 
as it is an attempt to support relocate-only types as a pure library solution.</p>
   <p>We believe a language solution is best suited here:</p>
   <ul>
    <li data-md>
     <p>the source object is effectively destroyed by the relocation: its destructor
is not called. This can hardly be achieved by a library solution ;</p>
    <li data-md>
     <p>the <code class="highlight"><c- n>reloc</c-></code> keyword makes sure the relocated object is not reused,
while <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>pilfer</c-></code> does not ;</p>
    <li data-md>
     <p>the pilfering constructor is inconvenient to write as we need to unwrap from <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>pilfered</c-></code> and rewrap to propagate to base classes and data-members ;</p>
    <li data-md>
     <p>as a library solution, the pilfering constructor cannot be defaulted ;</p>
    <li data-md>
     <p>trivial relocation is not possible with pilfering, which makes <a data-link-type="biblio" href="#biblio-p0308r0" title="Valueless Variants Considered Harmful">[P0308R0]</a> miss
the performance boost that is so longed for.</p>
   </ul>
   <h3 class="heading settled" data-level="4.6" id="compare-D2839"><span class="secno">4.6. </span><span class="content">D2839R1: Nontrivial Relocation via a New <em>owning reference</em> Type by Brian Bi and Joshua Berne</span><a class="self-link" href="#compare-D2839"></a></h3>
   <p><a data-link-type="biblio" href="#biblio-d2839r1" title="Nontrivial Relocation via a New owning reference Type">[D2839R1]</a> is very close in spirit and mechanism to this paper. We consider the
addition of an "owning reference" to be an unnecessary complication to the type
system that would impose a burden throughout library code. We refute the claim
that a prvalue occupying storage constitutes a fourth value category; in our
model, the lvalue that previously occupied that storage ceases to exist and a
new prvalue is formed, which may come to occupy that storage (if relocation is
elided) or distinct storage (in the general case).</p>
   <p>We are intrigued by the claim that an owning reference can provided superior
performance when passing a variable up the stack, compared to repeatedly relocating
it from caller to callee, but believe that in practice such gains would be minimal
and liable to be eliminated via optimization, while our model offers the possibility
of improved locality, since the relocated object will reside directly in the leafmost
function’s stack as opposed to being accessible only via indirection.</p>
   <p>Otherwise, the paper has some minor differences in naming (e.g. <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>force_relocate</c-></code> for what we call <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>destroy_relocate</c-></code>) that could easily be reconciled in either
direction.</p>
   <h2 class="heading settled" data-level="5" id="lg-changes"><span class="secno">5. </span><span class="content">Proposed language changes</span><a class="self-link" href="#lg-changes"></a></h2>
   <h3 class="heading settled" data-level="5.1" id="reloc-operator"><span class="secno">5.1. </span><span class="content">reloc operator</span><a class="self-link" href="#reloc-operator"></a></h3>
   <p>This paper suggests to introduce a new keyword, named <code class="highlight"><c- n>reloc</c-></code>. <code class="highlight"><c- n>reloc</c-></code> acts as a
unary operator that can be applied to named, local, complete objects (in other
words: function-local non-static variables and, with some restrictions,
function parameters and
identifiers introduced through the syntax of structured binding declarations).</p>
   <p><code class="highlight"><c- n>reloc</c-> <c- n>obj</c-></code> does the following:</p>
   <ul>
    <li data-md>
     <p>if <code class="highlight"><c- n>obj</c-></code> is ref-qualified, then performs perfect-forwarding
(as if by <code class="highlight"><c- k>static_cast</c-><c- o>&lt;</c-><c- k>decltype</c-><c- p>(</c-><c- n>obj</c-><c- p>)</c-><c- o>></c-><c- p>(</c-><c- n>obj</c-><c- p>)</c-></code>);</p>
    <li data-md>
     <p>otherwise returns a temporary obtained from the source object, leaving
it in a <em>destructed state</em> or a "<em>pending-destruction</em>" state ;</p>
    <li data-md>
     <p>in all cases, marks the "early" end-of-scope of the variable <code class="highlight"><c- n>obj</c-></code>, preventing
from use-after-relocation errors.</p>
   </ul>
   <h4 class="heading settled" data-level="5.1.1" id="reloc-perfect-fwd"><span class="secno">5.1.1. </span><span class="content">reloc to perfectly forward all value categories</span><a class="self-link" href="#reloc-perfect-fwd"></a></h4>
   <p><code class="highlight"><c- n>reloc</c-></code> can be used on ref-qualified objects to enable perfect forwarding.
If the source object is ref-qualified, then it performs the following cast: <code class="highlight"><c- k>static_cast</c-><c- o>&lt;</c-><c- k>decltype</c-><c- p>(</c-><c- n>obj</c-><c- p>)</c-><c- o>></c-><c- p>(</c-><c- n>obj</c-><c- p>)</c-></code>.</p>
   <p>This makes <code class="highlight"><c- n>reloc</c-></code> the one operator to use to perfectly forward lvalues, xvalues
and prvalues. It also prevents from use-after-move and use-after-relocation errors.</p>
   <h4 class="heading settled" data-level="5.1.2" id="reloc-value-change"><span class="secno">5.1.2. </span><span class="content">reloc returns a temporary</span><a class="self-link" href="#reloc-value-change"></a></h4>
   <p>The main use case of <code class="highlight"><c- n>reloc</c-></code> is to change the value category of an object to a
prvalue. This happens by creating a temporary from the given source object, 
when the source object is not ref-qualified.</p>
   <p>This temporary may or may not be materialized, depending on the context of the
expression.</p>
   <p>If materialized, then the temporary is initialized as follows:</p>
   <ul>
    <li data-md>
     <p>if the source object is not an <em>unowned parameter</em>, then the temporary is
initialized using its relocation, move or copy constructor:</p>
     <ul>
      <li data-md>
       <p>the relocation constructor is called if accessible. This is a destructive
operation for the source object: when the constructor returns, the 
source object is considered to be in a <em>destructed state</em>.</p>
      <li data-md>
       <p>otherwise, either the move or copy constructor is called, ignoring the
cv-qualifiers on the source object. The destructor of the source object 
is then called at the end of the full-expression evaluation.</p>
      <li data-md>
       <p>In all cases, the destructor of the source object is no longer called when
its end of scope is reached.</p>
     </ul>
    <li data-md>
     <p>otherwise (the source object is an <em>unowned parameter</em>), then the temporary is
initialized using its move or copy constructor, ignoring the 
cv-qualifiers on the source object. The destructor of the 
source object is deferred until the function returns. Typically we expect 
the source object to be in a "moved-from" state, waiting to be destructed.</p>
   </ul>
   <p>If the temporary is not materialized and that the source object is not an <em>unowned parameter</em>, then the destructor of the source object is called at the 
end of the full-expression evaluation, at the same time as temporary objects are destroyed.
See <a href="#discarded-reloc-expr">Discarded reloc expressions</a> for more details on 
unmaterialized temporaries from <code class="highlight"><c- n>reloc</c-></code> statements.</p>
   <p>Note that an object passed to <code class="highlight"><c- n>reloc</c-></code> is guaranteed to be either in a <em>destructed state</em> at the end of the expression evaluation if it is not an <em>unowned parameter</em>, 
or else in a "<em>pending-destruction</em>" state.</p>
   <h4 class="heading settled" data-level="5.1.3" id="reloc-illegal-uses"><span class="secno">5.1.3. </span><span class="content">Illegal uses of reloc</span><a class="self-link" href="#reloc-illegal-uses"></a></h4>
   <p>A <code class="highlight"><c- n>reloc</c-></code> statement is ill-formed if any of the following conditions is met:</p>
   <ul>
    <li data-md>
     <p>its parameter is not the name of a variable ;</p>
    <li data-md>
     <p>the source object is not a <em>complete object</em> ;</p>
    <li data-md>
     <p>the source object is not ref-qualified and does not have local storage
(i.e. not a local function variable and not a function parameter passed by
value) ;</p>
    <li data-md>
     <p>the source object is not ref-qualified and does not have an accessible relocation,
move, or copy constructor ;</p>
    <li data-md>
     <p>the source object is a structured binding (and not an identifier introduced in a <a href="#structured-reloc">structured relocation declaration</a>) ;</p>
    <li data-md>
     <p>the source object is a lambda capture from a <a href="#decomposing-lambda">non-decomposing lambda</a> ;</p>
   </ul>
   <p>In particular, the <code class="highlight"><c- n>reloc</c-></code> statement is well-formed if the source object is a
member of a function-local anonymous union.</p>
   <p>For instance:</p>
<pre class="language-cpp highlight"><c- b>void</c-> <c- nf>foo</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>string</c-> <c- n>str</c-><c- p>);</c->
<c- n>std</c-><c- o>::</c-><c- n>string</c-> <c- nf>get_string</c-><c- p>();</c->
<c- n>std</c-><c- o>::</c-><c- n>pair</c-><c- o>&lt;</c-><c- n>std</c-><c- o>::</c-><c- n>string</c-><c- p>,</c-> <c- n>std</c-><c- o>::</c-><c- n>string</c-><c- o>></c-> <c- n>get_strings</c-><c- p>();</c->

<c- n>std</c-><c- o>::</c-><c- n>string</c-> <c- n>gStr</c-> <c- o>=</c-> <c- s>"static string"</c-><c- p>;</c->

<c- b>void</c-> <c- nf>bar</c-><c- p>(</c-><c- b>void</c-><c- p>)</c->
<c- p>{</c->
	<c- n>std</c-><c- o>::</c-><c- n>string</c-> <c- n>str</c-> <c- o>=</c-> <c- s>"test string"</c-><c- p>;</c->
	<c- n>foo</c-><c- p>(</c-><c- n>reloc</c-> <c- n>str</c-><c- p>);</c-> <c- c1>// OK: relocation will happen given that std::string has a reloc ctor</c->
	<c- n>foo</c-><c- p>(</c-><c- n>reloc</c-> <c- n>gStr</c-><c- p>);</c-> <c- c1>// ill-formed: gStr does not have local storage</c->

	<c- n>std</c-><c- o>::</c-><c- n>pair</c-> <c- n>p</c-><c- p>{</c-><c- n>std</c-><c- o>::</c-><c- n>string</c-><c- p>{},</c-> <c- n>std</c-><c- o>::</c-><c- n>string</c-><c- p>{}};</c->
	<c- n>foo</c-><c- p>(</c-><c- n>reloc</c-> <c- n>p</c-><c- p>.</c-><c- n>first</c-><c- p>);</c-> <c- c1>// ill-formed: p.first is not a complete object, and not the name of variable</c->

	<c- n>foo</c-><c- p>(</c-><c- n>reloc</c-> <c- n>get_string</c-><c- p>());</c-> <c- c1>// ill-formed: not the name of variable</c->
	<c- n>foo</c-><c- p>(</c-><c- n>reloc</c-> <c- n>get_strings</c-><c- p>().</c-><c- n>first</c-><c- p>);</c-> <c- c1>// ill-formed: not a complete object, and not the name of variable</c->
<c- p>}</c->

<c- b>void</c-> <c- nf>foobar</c-><c- p>(</c-><c- k>const</c-> <c- n>std</c-><c- o>::</c-><c- n>string</c-><c- o>&amp;</c-> <c- n>str</c-><c- p>)</c->
<c- p>{</c->
	<c- n>foo</c-><c- p>(</c-><c- n>reloc</c-> <c- n>str</c-><c- p>);</c-> <c- c1>// OK: str is passed by reference.</c->
	<c- c1>// Note that the lifetime of the referent of str is unaffected.</c->
<c- p>}</c->
<c- b>void</c-> <c- nf>foobar</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>string</c-><c- o>*</c-> <c- n>str</c-><c- p>)</c->
<c- p>{</c->
	<c- n>foo</c-><c- p>(</c-><c- n>reloc</c-> <c- o>*</c-><c- n>str</c-><c- p>);</c-> <c- c1>// ill-formed: *str is not the name of variable</c->
<c- p>}</c->
<c- b>void</c-> <c- nf>foobar2</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>string</c-><c- o>*</c-> <c- n>str</c-><c- p>)</c->
<c- p>{</c->
	<c- n>foobar</c-><c- p>(</c-><c- n>reloc</c-> <c- n>str</c-><c- p>);</c-> <c- c1>// OK, the pointer itself is relocated (not the pointed value)</c->
<c- p>}</c-> 

<c- k>class</c-> <c- nc>A</c->
<c- p>{</c->
	<c- n>std</c-><c- o>::</c-><c- n>string</c-> <c- n>_str</c-><c- p>;</c->
<c- k>public</c-><c- o>:</c->
	<c- b>void</c-> <c- n>bar</c-><c- p>()</c->
	<c- p>{</c->
		<c- n>foo</c-><c- p>(</c-><c- n>reloc</c-> <c- n>_str</c-><c- p>);</c-> <c- c1>// ill-formed: _str is not a complete object and does not have local storage</c->
	<c- p>}</c->
<c- p>};</c->
</pre>
   <h4 class="heading settled" data-level="5.1.4" id="reloc-early-end-of-scope"><span class="secno">5.1.4. </span><span class="content">Early end-of-scope</span><a class="self-link" href="#reloc-early-end-of-scope"></a></h4>
   <p><code class="highlight"><c- n>reloc</c-> <c- n>obj</c-></code> simulates an early end-of-scope of <code class="highlight"><c- n>obj</c-></code>. It does so by forbidding
any further mention of the name <code class="highlight"><c- n>obj</c-></code> which would resolve into the relocated object.</p>
   <p>If <code class="highlight"><c- n>obj</c-></code> is a member of an anonymous union, then <code class="highlight"><c- n>reloc</c-></code> does not prevent
name reuse; all members of that union, including the one that was relocated,
can be reused normally.</p>
   <p>Pointers and references that pointed to <code class="highlight"><c- n>obj</c-></code> become dangling,
and we don’t try to offer any protection against that. We only protect against
reusing the variable that was passed to <code class="highlight"><c- n>reloc</c-></code>.</p>
   <p>The program is ill-formed if <code class="highlight"><c- n>reloc</c-> <c- n>obj</c-></code> is used in an instruction and any of
the following is true:</p>
   <ul>
    <li data-md>
     <p>in at least one code path from after the instruction that contained <code class="highlight"><c- n>reloc</c-> <c- n>obj</c-></code> up
to the natural end-of-scope of said <code class="highlight"><c- n>obj</c-></code>, the name <code class="highlight"><c- n>obj</c-></code> is reused and it 
resolves to the object that was passed to <code class="highlight"><c- n>reloc</c-></code> ;</p>
    <li data-md>
     <p>within the instruction where <code class="highlight"><c- n>reloc</c-> <c- n>obj</c-></code> is used, the name <code class="highlight"><c- n>obj</c-></code> is reused in
the same conditional branch.</p>
   </ul>
   <p>The code path evaluation performed to detect such ill-formed programs is
based only on compile-time evaluations, disregarding run-time values:</p>
   <ul>
    <li data-md>
     <p>For any non-constexpr <code class="highlight"><c- k>if</c-></code> block encountered in the code path, the true branch
must be considered as well as the else branch (if it exists).</p>
    <li data-md>
     <p>If an <code class="highlight"><c- k>if</c-> <c- k>constexpr</c-></code> block is encountered, only the branch that evaluates to true
is considered.</p>
    <li data-md>
     <p>Any <code class="highlight"><c- k>for</c-></code> or <code class="highlight"><c- k>while</c-></code> loop body is considered to be entered once if <code class="highlight"><c- n>reloc</c-></code> is used before the <code class="highlight"><c- k>for</c-></code>/<code class="highlight"><c- k>while</c-></code> block or in the init-statement of the <code class="highlight"><c- k>for</c-></code> loop.</p>
    <li data-md>
     <p>If <code class="highlight"><c- n>reloc</c-></code> is used within a loop body, a loop condition, or a for-loop
iteration expression, and that there exists a code path from the <code class="highlight"><c- n>reloc</c-></code> instruction up to the next iteration of the loop (i.e. no <code class="highlight"><c- k>return</c-></code> statement, 
no <code class="highlight"><c- k>break</c-></code> statement that applies to that loop, or no <code class="highlight"><c- k>goto</c-></code> statement that 
jumps after that loop) then the loop is considered to happen one
more time for code-path evaluation.</p>
   </ul>
   <p>Consider the following examples:</p>
<pre class="language-cpp highlight"><c- b>void</c-> <c- nf>relocate_case_01</c-><c- p>()</c->
<c- p>{</c->
	<c- k>const</c-> <c- n>T</c-> <c- n>var</c-> <c- o>=</c-> <c- n>getT</c-><c- p>();</c->
	<c- n>bar</c-><c- p>(</c-><c- n>reloc</c-> <c- n>var</c-><c- p>);</c->
	<c- k>if</c-> <c- p>(</c-><c- n>sometest</c-><c- p>(</c-><c- n>var</c-><c- p>))</c-> <c- c1>// ERROR</c->
		<c- n>do_smth</c-><c- p>(</c-><c- n>var</c-><c- p>);</c-> <c- c1>// ERROR</c->
<c- p>}</c->
</pre>
   <code class="highlight"><c- n>var</c-></code> cannot be reused after the <code class="highlight"><c- n>reloc</c-></code> call. 
<pre class="language-cpp highlight"><c- b>void</c-> <c- nf>relocate_case_02</c-><c- p>()</c->
<c- p>{</c->
	<c- k>const</c-> <c- n>T</c-> <c- n>var</c-><c- p>;</c->
	<c- p>{</c->
		<c- k>const</c-> <c- n>T</c-> <c- n>var</c-><c- p>;</c->
		<c- n>bar</c-><c- p>(</c-><c- n>reloc</c-> <c- n>var</c-><c- p>);</c->
		<c- n>do_smth</c-><c- p>(</c-><c- n>var</c-><c- p>);</c-> <c- c1>// ERROR, var cannot be reused after the &lt;code data-opaque bs-autolink-syntax='`reloc`'>reloc&lt;/code> call</c->
		<c- p>{</c->
			<c- k>const</c-> <c- n>T</c-> <c- n>var</c-><c- p>;</c->
			<c- n>do_smth</c-><c- p>(</c-><c- n>var</c-><c- p>);</c-> <c- c1>// OK</c->
		<c- p>}</c->
		<c- n>do_smth</c-><c- p>(</c-><c- n>var</c-><c- p>);</c-> <c- c1>// ERROR, var cannot be reused after the &lt;code data-opaque bs-autolink-syntax='`reloc`'>reloc&lt;/code> call</c->
	<c- p>}</c->
	<c- n>do_smth</c-><c- p>(</c-><c- n>var</c-><c- p>);</c-> <c- c1>// OK</c->
<c- p>}</c->
</pre>
   The second and forth calls to <code class="highlight"><c- n>do_smth</c-><c- p>(</c-><c- n>var</c-><c- p>)</c-></code> are allowed because the name <code class="highlight"><c- n>var</c-></code> does not resolve to the relocated object. 
<pre class="language-cpp highlight"><c- b>void</c-> <c- nf>relocate_case_03</c-><c- p>()</c->
<c- p>{</c->
	<c- k>const</c-> <c- n>T</c-> <c- n>var</c-> <c- o>=</c-> <c- n>getT</c-><c- p>();</c->
	<c- k>if</c-> <c- p>(</c-><c- n>sometest</c-><c- p>(</c-><c- n>var</c-><c- p>))</c->
		<c- n>bar</c-><c- p>(</c-><c- n>reloc</c-> <c- n>var</c-><c- p>);</c->
	<c- k>else</c->
		<c- n>do_smth</c-><c- p>(</c-><c- n>var</c-><c- p>);</c-> <c- c1>// OK</c->
<c- p>}</c->
</pre>
   <code class="highlight"><c- n>do_smth</c-><c- p>(</c-><c- n>var</c-><c- p>)</c-></code> is allowed because the <code class="highlight"><c- k>else</c-></code> branch is not affected by the <code class="highlight"><c- n>reloc</c-></code> call of the <code class="highlight"><c- k>if</c-></code> branch. 
<pre class="language-cpp highlight"><c- b>void</c-> <c- nf>relocate_case_04</c-><c- p>()</c->
<c- p>{</c->
	<c- k>const</c-> <c- n>T</c-> <c- n>var</c-> <c- o>=</c-> <c- n>getT</c-><c- p>();</c->
	<c- k>if</c-> <c- p>(</c-><c- n>sometest</c-><c- p>(</c-><c- n>var</c-><c- p>))</c->
		<c- n>bar</c-><c- p>(</c-><c- n>reloc</c-> <c- n>var</c-><c- p>);</c->
	<c- k>else</c->
		<c- n>do_smth</c-><c- p>(</c-><c- n>var</c-><c- p>);</c-> <c- c1>// OK</c->
	<c- c1>// [...]</c->
	<c- n>do_smth_else</c-><c- p>(</c-><c- n>var</c-><c- p>);</c-> <c- c1>// ERROR</c->
<c- p>}</c->
</pre>
   <code class="highlight"><c- n>do_smth_else</c-><c- p>(</c-><c- n>var</c-><c- p>)</c-></code> is an error because <code class="highlight"><c- n>var</c-></code> is mentioned after the <code class="highlight"><c- n>reloc</c-></code> call. 
<pre class="language-cpp highlight"><c- b>void</c-> <c- nf>relocate_case_05</c-><c- p>()</c->
<c- p>{</c->
	<c- k>const</c-> <c- n>T</c-> <c- n>var</c-> <c- o>=</c-> <c- n>getT</c-><c- p>();</c->
	<c- k>if</c-> <c- p>(</c-><c- n>sometest</c-><c- p>(</c-><c- n>var</c-><c- p>))</c->
		<c- n>bar</c-><c- p>(</c-><c- n>reloc</c-> <c- n>var</c-><c- p>);</c->
	<c- k>else</c->
		<c- n>do_smth</c-><c- p>(</c-><c- n>reloc</c-> <c- n>var</c-><c- p>);</c-> <c- c1>// OK</c->
<c- p>}</c->
</pre>
   Both <code class="highlight"><c- n>reloc</c-></code> are okay as they happen on different code paths. 
<pre class="language-cpp highlight"><c- b>void</c-> <c- nf>relocate_case_06</c-><c- p>()</c->
<c- p>{</c->
	<c- k>const</c-> <c- n>T</c-> <c- n>var</c-> <c- o>=</c-> <c- n>getT</c-><c- p>();</c->
	<c- b>bool</c-> <c- n>relocated</c-> <c- o>=</c-> false<c- p>;</c->
	<c- k>if</c-> <c- p>(</c-><c- n>sometest</c-><c- p>(</c-><c- n>var</c-><c- p>))</c->
	<c- p>{</c->
		<c- n>bar</c-><c- p>(</c-><c- n>reloc</c-> <c- n>var</c-><c- p>);</c->
		<c- n>relocated</c-> <c- o>=</c-> true<c- p>;</c->
	<c- p>}</c->
	<c- k>else</c->
		<c- n>do_smth</c-><c- p>(</c-><c- n>var</c-><c- p>);</c-> <c- c1>// OK</c->
	<c- c1>// [...]</c->
	<c- k>if</c-> <c- p>(</c-><c- o>!</c-><c- n>relocated</c-><c- p>)</c->
		<c- n>do_smth_else</c-><c- p>(</c-><c- n>var</c-><c- p>);</c-> <c- c1>// ERROR</c->
<c- p>}</c->
</pre>
   It does not matter that the developer attempted to do the safe thing with the <code class="highlight"><c- n>relocated</c-></code> variable. The code-path analysis disregards run-time values and 
explores all branches of an <code class="highlight"><c- k>if</c-></code> block (unless in the case of <code class="highlight"><c- k>if</c-> <c- k>constexpr</c-></code>). 
<pre class="language-cpp highlight"><c- b>void</c-> <c- nf>relocate_case_07</c-><c- p>()</c->
<c- p>{</c->
	<c- k>constexpr</c-> <c- b>bool</c-> <c- n>relocated</c-> <c- o>=</c-> <c- n>my_can_relocate</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-><c- p>{}();</c->
	<c- k>const</c-> <c- n>T</c-> <c- n>var</c-> <c- o>=</c-> <c- n>getT</c-><c- p>();</c->
	<c- k>if</c-> <c- k>constexpr</c-><c- p>(</c-><c- n>relocated</c-><c- p>)</c->
	<c- p>{</c->
		<c- n>bar</c-><c- p>(</c-><c- n>reloc</c-> <c- n>var</c-><c- p>);</c->
	<c- p>}</c->
	<c- k>else</c->
		<c- n>do_smth</c-><c- p>(</c-><c- n>var</c-><c- p>);</c-> <c- c1>// OK</c->
	<c- c1>// [...]</c->
	<c- k>if</c-> <c- k>constexpr</c-><c- p>(</c-><c- o>!</c-><c- n>relocated</c-><c- p>)</c->
		<c- n>do_smth_else</c-><c- p>(</c-><c- n>var</c-><c- p>);</c-> <c- c1>// OK</c->
<c- p>}</c->
</pre>
   The above example is safe because of the use of <code class="highlight"><c- k>if</c-> <c- k>constexpr</c-></code>. 
<pre class="language-cpp highlight"><c- b>void</c-> <c- nf>relocate_case_08</c-><c- p>()</c->
<c- p>{</c->
	<c- k>const</c-> <c- n>T</c-> <c- n>var</c-> <c- o>=</c-> <c- n>getT</c-><c- p>();</c->
	<c- k>if</c-> <c- p>(</c-><c- n>sometest</c-><c- p>(</c-><c- n>var</c-><c- p>))</c->
	<c- p>{</c->
		<c- n>bar</c-><c- p>(</c-><c- n>reloc</c-> <c- n>var</c-><c- p>);</c->
		<c- k>return</c-><c- p>;</c->
	<c- p>}</c->
	<c- n>do_smth</c-><c- p>(</c-><c- n>var</c-><c- p>);</c-> <c- c1>// OK</c->
<c- p>}</c->
</pre>
   This example is also safe thanks to the <code class="highlight"><c- k>return</c-></code> statement right after the <code class="highlight"><c- n>reloc</c-></code> instruction, which prevents from running <code class="highlight"><c- n>do_smth</c-><c- p>(</c-><c- n>var</c-><c- p>);</c-></code>. 
<pre class="language-cpp highlight"><c- b>void</c-> <c- nf>relocate_case_09</c-><c- p>()</c->
<c- p>{</c->
	<c- k>const</c-> <c- n>T</c-> <c- n>var</c-> <c- o>=</c-> <c- n>getT</c-><c- p>();</c->
	<c- k>for</c-> <c- p>(</c-><c- b>int</c-> <c- n>i</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>i</c-> <c- o>!=</c-> <c- mi>10</c-><c- p>;</c-> <c- o>++</c-><c- n>i</c-><c- p>)</c->
		<c- n>do_smth</c-><c- p>(</c-><c- n>reloc</c-> <c- n>var</c-><c- p>);</c-> <c- c1>// ERROR</c->
<c- p>}</c->
</pre>
   This is ill-formed as each iteration reuses <code class="highlight"><c- n>var</c-></code> which is declared before the loop body. 
Even if <code class="highlight"><c- n>i</c-></code> were compared against <code class="highlight"><c- mi>1</c-></code> or even <code class="highlight"><c- mi>0</c-></code> (for respectively one iteration, 
or no iteration) then the program would still be ill-formed.
Run-time values (like <code class="highlight"><c- n>i</c-></code>) are disregarded in the code-path analysis that comes 
with <code class="highlight"><c- n>reloc</c-></code>. The analysis will report that there is an optional code jump, 
after the <code class="highlight"><c- n>do_smth</c-></code> call (and <code class="highlight"><c- n>reloc</c-> <c- n>var</c-></code>), which jumps to before the <code class="highlight"><c- n>reloc</c-> <c- n>var</c-></code> call and after the initialization of <code class="highlight"><c- n>var</c-></code>. Although the jump is optional 
(depends on <code class="highlight"><c- n>i</c-></code>, whose value is disregarded for this analysis) it may still 
happen and thus such code is ill-formed. 
<pre class="language-cpp highlight"><c- b>void</c-> <c- nf>relocate_case_10</c-><c- p>()</c->
<c- p>{</c->
	<c- k>const</c-> <c- n>T</c-> <c- n>var</c-> <c- o>=</c-> <c- n>getT</c-><c- p>();</c->
	<c- k>for</c-> <c- p>(</c-><c- b>int</c-> <c- n>i</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>i</c-> <c- o>!=</c-> <c- mi>10</c-><c- p>;</c-> <c- o>++</c-><c- n>i</c-><c- p>)</c->
	<c- p>{</c->
		<c- k>if</c-> <c- p>(</c-><c- n>i</c-> <c- o>==</c-> <c- mi>9</c-><c- p>)</c->
			<c- n>do_smth</c-><c- p>(</c-><c- n>reloc</c-> <c- n>var</c-><c- p>);</c-> <c- c1>// ERROR</c->
		<c- k>else</c->
			<c- n>do_smth</c-><c- p>(</c-><c- n>var</c-><c- p>);</c-> <c- c1>// ERROR</c->
	<c- p>}</c->
<c- p>}</c->
</pre>
   This is ill-formed for the same reason as above. The code-path analysis will 
report that any iteration of the for-loop may take any branch of the if statement 
and potentially reuse a relocated variable. 
<pre class="language-cpp highlight"><c- b>void</c-> <c- nf>relocate_case_11</c-><c- p>()</c->
<c- p>{</c->
	<c- k>const</c-> <c- n>T</c-> <c- n>var</c-> <c- o>=</c-> <c- n>getT</c-><c- p>();</c->
	<c- k>for</c-> <c- p>(</c-><c- b>int</c-> <c- n>i</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>i</c-> <c- o>!=</c-> <c- mi>10</c-><c- p>;</c-> <c- o>++</c-><c- n>i</c-><c- p>)</c->
	<c- p>{</c->
		<c- k>if</c-> <c- p>(</c-><c- n>i</c-> <c- o>==</c-> <c- mi>9</c-><c- p>)</c-> <c- p>{</c->
			<c- n>do_smth</c-><c- p>(</c-><c- n>reloc</c-> <c- n>var</c-><c- p>);</c-> <c- c1>// OK</c->
			<c- k>break</c-><c- p>;</c->
		<c- p>}</c->
		<c- k>else</c->
			<c- n>do_smth</c-><c- p>(</c-><c- n>var</c-><c- p>);</c-> <c- c1>// OK</c->
	<c- p>}</c->
<c- p>}</c->
</pre>
   Adding the break statement right after the <code class="highlight"><c- n>reloc</c-></code> call makes the code snippet well-formed. 
Indeed the <code class="highlight"><c- k>break</c-></code> statement forces the loop exit, which implies that the 
conditional jump at the end of loop (that may start the next iteration) is no 
longer part of the code path that follows the <code class="highlight"><c- n>reloc</c-></code> instruction. 
<pre class="language-cpp highlight"><c- b>void</c-> <c- nf>relocate_case_12</c-><c- p>()</c->
<c- p>{</c->
	<c- k>for</c-> <c- p>(</c-><c- b>int</c-> <c- n>i</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>i</c-> <c- o>!=</c-> <c- mi>10</c-><c- p>;</c-> <c- o>++</c-><c- n>i</c-><c- p>)</c->
	<c- p>{</c->
		<c- k>const</c-> <c- n>T</c-> <c- n>var</c-> <c- o>=</c-> <c- n>getT</c-><c- p>();</c->
		<c- n>do_smth</c-><c- p>(</c-><c- n>reloc</c-> <c- n>var</c-><c- p>);</c-> <c- c1>// OK</c->
	<c- p>}</c->
<c- p>}</c->
</pre>
   <code class="highlight"><c- n>var</c-></code> is local to the for-loop body, so <code class="highlight"><c- n>reloc</c-></code> is well-formed here. The next loop 
iteration inspected by the code path analysis will see that <code class="highlight"><c- n>var</c-></code> is a new object
that shadows that of the previous iteration. 
<pre class="language-cpp highlight"><c- b>void</c-> <c- nf>relocate_case_13</c-><c- p>()</c->
<c- p>{</c->
	<c- k>const</c-> <c- n>T</c-> <c- n>var</c-> <c- o>=</c-> <c- n>getT</c-><c- p>();</c->
<c- nl>from</c-><c- p>:</c->
	<c- k>if</c-> <c- p>(</c-><c- n>sometest</c-><c- p>(</c-><c- n>var</c-><c- p>))</c-> <c- c1>// ERROR</c->
	<c- p>{</c->
		<c- n>do_smth</c-><c- p>(</c-><c- n>var</c-><c- p>);</c-> <c- c1>// ERROR</c->
	<c- p>}</c->
	<c- k>else</c->
	<c- p>{</c->
		<c- n>do_smth</c-><c- p>(</c-><c- n>reloc</c-> <c- n>var</c-><c- p>);</c->
	<c- p>}</c->
	<c- k>goto</c-> <c- n>from</c-><c- p>;</c->
<c- p>}</c->
</pre>
   Because of the <code class="highlight"><c- k>goto</c-></code> instruction, <code class="highlight"><c- n>var</c-></code> may be reused after <code class="highlight"><c- n>reloc</c-> <c- n>var</c-></code>. 
<pre class="language-cpp highlight"><c- b>void</c-> <c- nf>relocate_case_14</c-><c- p>()</c->
<c- p>{</c->
	<c- k>const</c-> <c- n>T</c-> <c- n>var</c-> <c- o>=</c-> <c- n>getT</c-><c- p>();</c->
<c- nl>from</c-><c- p>:</c->
	<c- k>if</c-> <c- p>(</c-><c- n>sometest</c-><c- p>(</c-><c- n>var</c-><c- p>))</c-> <c- c1>// OK</c->
	<c- p>{</c->
		<c- n>do_smth</c-><c- p>(</c-><c- n>var</c-><c- p>);</c-> <c- c1>// OK</c->
		<c- k>goto</c-> <c- n>from</c-><c- p>;</c->
	<c- p>}</c->
	<c- k>else</c->
	<c- p>{</c->
		<c- n>do_smth</c-><c- p>(</c-><c- n>reloc</c-> <c- n>var</c-><c- p>);</c->
	<c- p>}</c->
<c- p>}</c->
</pre>
   In this scenario <code class="highlight"><c- k>goto</c-></code> is placed in a way that does not trigger the reuse of relocated <code class="highlight"><c- n>var</c-></code>. 
<pre class="language-cpp highlight"><c- b>void</c-> <c- nf>relocate_case_15</c-><c- p>()</c->
<c- p>{</c->
	<c- k>union</c-> <c- p>{</c-> <c- n>T</c-> <c- n>x</c-><c- p>;</c-> <c- n>U</c-> <c- n>y</c-><c- p>;</c-> <c- p>};</c->
	<c- n>x</c-> <c- o>=</c-> <c- n>getT</c-><c- p>();</c->
	<c- k>if</c-> <c- p>(</c-><c- n>sometest</c-><c- p>(</c-><c- n>x</c-><c- p>))</c->
	<c- p>{</c->
		<c- n>do_smth</c-><c- p>(</c-><c- n>reloc</c-> <c- n>x</c-><c- p>);</c->
		<c- n>x</c-> <c- o>=</c-> <c- n>getT</c-><c- p>();</c-> <c- c1>// well-formed</c->
	<c- p>}</c->
	<c- k>else</c->
	<c- p>{</c->
		<c- n>reloc</c-> <c- n>x</c-><c- p>;</c-> <c- c1>// destroy x</c->
		<c- n>y</c-> <c- o>=</c-> <c- n>getU</c-><c- p>();</c->
		<c- n>do_smth_else</c-><c- p>(</c-><c- n>reloc</c-> <c- n>y</c-><c- p>);</c-> <c- c1>// well-formed</c->
		<c- n>x</c-> <c- o>=</c-> <c- n>getT</c-><c- p>();</c-> <c- c1>// well-formed</c->
	<c- p>}</c->
	<c- n>do_smth_else</c-><c- p>(</c-><c- n>reloc</c-> <c- n>y</c-><c- p>);</c-> <c- c1>// well-formed</c->
<c- p>}</c->
</pre>
   <code class="highlight"><c- n>reloc</c-></code> does not prevent reusing the names of anonymous union members. 
   <h4 class="heading settled" data-level="5.1.5" id="conditional-reloc"><span class="secno">5.1.5. </span><span class="content">Conditional relocation</span><a class="self-link" href="#conditional-reloc"></a></h4>
   <p>It may happen that the <code class="highlight"><c- n>reloc</c-></code> is invoked in the some code branches and not in
others:</p>
<pre class="language-c++ highlight"><c- b>void</c-> <c- nf>foo</c-><c- p>()</c->
<c- p>{</c->
    <c- n>T</c-> <c- n>obj</c-> <c- o>=</c-> <c- d>/* ... */</c-><c- p>;</c->
    <c- k>if</c-> <c- p>(</c-><c- n>some_test</c-><c- p>())</c->
        <c- n>bar</c-><c- p>(</c-><c- n>reloc</c-> <c- n>obj</c-><c- p>);</c->
    <c- k>else</c->
        <c- n>handle_error</c-><c- p>();</c->
    <c- n>live_on</c-><c- p>();</c->
<c- p>}</c->
</pre>
   <p>This code is well-formed. <code class="highlight"><c- n>obj</c-></code> is relocated in the <code class="highlight"><c- k>if</c-></code> branch (left in a <em>destructed state</em>), and not in the <code class="highlight"><c- k>else</c-></code> branch. When <code class="highlight"><c- n>obj</c-></code> reaches its end of scope, the function needs to know
whether <code class="highlight"><c- n>obj</c-></code> is in a <em>destructed state</em> in order to elide its destructor call.</p>
   <p>This requires extra tracking, which will probably take the form of extra flags
in the function stack. Given a source object, this tracking is only necessary 
if all the following conditions are met:</p>
   <ul>
    <li data-md>
     <p>the source object is not an <em>unowned parameter</em> ;</p>
    <li data-md>
     <p>the source object is not trivial (its destructor is not a no-op) ;</p>
    <li data-md>
     <p>in conditional branches, <code class="highlight"><c- n>reloc</c-></code> is used in at least one branch and not used
in at least one branch as well (taking into account the potentially empty <code class="highlight"><c- k>else</c-></code> branch).</p>
   </ul>
   <p>We prefer to leave the details of this tracking implementation-defined.</p>
   <p>Concerns have been expressed that extra flags would violate the "don’t pay for
what you don’t use" principle. We acknowledge this concern, but feel that the
user is getting at least something out of this. Alternatives would be for the source
object to be destroyed implicitly at the opening or closing brace of the <code class="highlight"><c- k>else</c-></code>,
for the code to be ill-formed unless the source object is relocated within the <code class="highlight"><c- k>else</c-></code>, or for the code to be ill-formed unconditionally. Note that in each of these
cases, the user can recover our preferred behavior in library, using <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>optional</c-></code> to add the tracking flags that in our proposal would be provided by the language.</p>
   <h4 class="heading settled" data-level="5.1.6" id="reloc-elision"><span class="secno">5.1.6. </span><span class="content">Relocation elision</span><a class="self-link" href="#reloc-elision"></a></h4>
   <p>Whether performed by relocation, move or copy constructor, relocation
may be elided if the compiler can ensure that the source object is created at
the address to be occuped by the target object.
This is intended to work in much the same way as the named return value optimization;
for example:</p>
<pre class="language-c+ highlight"><c- b>void</c-> <c- nf>f</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>string</c-> <c- n>s</c-><c- p>);</c->
<c- b>void</c-> <c- nf>g</c-><c- p>()</c-> <c- p>{</c->
    <c- n>std</c-><c- o>::</c-><c- n>string</c-> <c- n>s</c-><c- p>;</c->  <c- c1>// may be created in f’s argument slot</c->
    <c- n>f</c-><c- p>(</c-><c- n>reloc</c-> <c- n>s</c-><c- p>);</c->  <c- c1>// relocation may be elided</c->
<c- p>}</c->
</pre>
   <h4 class="heading settled" data-level="5.1.7" id="discarded-reloc-expr"><span class="secno">5.1.7. </span><span class="content">Discarded reloc expressions</span><a class="self-link" href="#discarded-reloc-expr"></a></h4>
   <p>Under some conditions the following expression is well-formed: <code class="highlight"><c- n>reloc</c-> <c- n>obj</c-><c- p>;</c-></code> (note the semi-colon).</p>
   <p>Given the rules we established for <code class="highlight"><c- n>reloc</c-></code>, this statement returns a temporary
constructed from the source object. The temporary is then destructed at the end
of the expression evaluation.</p>
   <p>However, materializing a temporary whose only goal is to be destroyed is
suboptimal. Hence, it is authorized for implementations to (as above)
elide the creation
of the temporary object, 
effectively only calling the destructor of the source
object at the end of the expression evaluation. If this optimization is done, 
the temporary returned by <code class="highlight"><c- n>reloc</c-></code> is not materialized.</p>
   <p>This means that <code class="highlight"><c- n>reloc</c-> <c- n>obj</c-><c- p>;</c-></code> has the following behavior:</p>
   <ul>
    <li data-md>
     <p>if <code class="highlight"><c- n>obj</c-></code> is not an <em>unowned parameter</em> then:</p>
     <ul>
      <li data-md>
       <p>The temporary is likely elided, effectively only calling the
destructor of <code class="highlight"><c- n>obj</c-></code>.</p>
      <li data-md>
       <p>Otherwise a temporary is initialized from the
source object, and then destructed.</p>
     </ul>
    <li data-md>
     <p>otherwise (<code class="highlight"><c- n>obj</c-></code> is an <em>unowned parameter</em>):</p>
     <ul>
      <li data-md>
       <p>A temporary is created from the move or copy constructor, and then destructed.</p>
      <li data-md>
       <p>The source object destruction is deferred until the function returns.</p>
     </ul>
   </ul>
   <p>In particular, <code class="highlight"><c- n>reloc</c-> <c- n>obj</c-><c- p>;</c-></code> is ill-formed if the source object has no accessible
relocation, move or copy constructor.</p>
   <p>For instance this gives:</p>
<pre class="language-c++ highlight"><c- b>void</c-> <c- nf>do_something_01</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>mutex</c-><c- o>&amp;</c-> <c- n>m</c-><c- p>)</c->
<c- p>{</c->
    <c- n>std</c-><c- o>::</c-><c- n>lock_guard</c-> <c- n>guard</c-><c- p>{</c-><c- n>m</c-><c- p>};</c->
    <c- k>if</c-> <c- p>(</c-><c- o>!</c-><c- n>some_test</c-><c- p>())</c->
    <c- p>{</c->
        <c- n>reloc</c-> <c- n>guard</c-><c- p>;</c-> <c- c1>// ill-formed: no relocation or move constructor</c->
        <c- n>log</c-><c- p>(</c-><c- s>"thread "</c-><c- p>,</c-> <c- n>std</c-><c- o>::</c-><c- n>this_thread</c-><c- o>::</c-><c- n>get_id</c-><c- p>(),</c-> <c- s>" failed"</c-><c- p>);</c->
        <c- k>return</c-><c- p>;</c->
    <c- p>}</c->
    <c- n>bar</c-><c- p>();</c->
<c- p>}</c->
<c- b>void</c-> <c- nf>do_something_02</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>unique_lock</c-><c- o>&lt;</c-><c- n>std</c-><c- o>::</c-><c- n>mutex</c-><c- o>></c-> <c- n>guard</c-><c- p>)</c->
<c- p>{</c->
    <c- k>if</c-> <c- p>(</c-><c- o>!</c-><c- n>some_test</c-><c- p>())</c->
    <c- p>{</c->
        <c- n>reloc</c-> <c- n>guard</c-><c- p>;</c-> <c- d>/* well-formed: lock is released, either by calling the </c->
<c- d>            destructor directly, or by constructing a temporary from </c->
<c- d>            guard (by relocation or move) and destructing it. */</c->
        <c- n>log</c-><c- p>(</c-><c- s>"thread "</c-><c- p>,</c-> <c- n>std</c-><c- o>::</c-><c- n>this_thread</c-><c- o>::</c-><c- n>get_id</c-><c- p>(),</c-> <c- s>" failed"</c-><c- p>);</c->
        <c- k>return</c-><c- p>;</c->
    <c- p>}</c->
    <c- n>bar</c-><c- p>();</c->
<c- p>}</c->
<c- b>void</c-> <c- nf>do_something_03</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>mutex</c-><c- o>&amp;</c-> <c- n>m</c-><c- p>)</c->
<c- p>{</c->
    <c- n>std</c-><c- o>::</c-><c- n>unique_lock</c-> <c- n>guard</c-><c- p>{</c-><c- n>m</c-><c- p>};</c->
    <c- k>if</c-> <c- p>(</c-><c- o>!</c-><c- n>some_test</c-><c- p>())</c->
    <c- p>{</c->
        <c- n>reloc</c-> <c- n>guard</c-><c- p>;</c-> <c- d>/* well-formed: temporary is likely elided regardless of </c->
<c- d>            do_something_03’s ABI, only calling the destructor of guard. */</c->
        <c- n>log</c-><c- p>(</c-><c- s>"thread "</c-><c- p>,</c-> <c- n>std</c-><c- o>::</c-><c- n>this_thread</c-><c- o>::</c-><c- n>get_id</c-><c- p>(),</c-> <c- s>" failed"</c-><c- p>);</c->
        <c- k>return</c-><c- p>;</c->
    <c- p>}</c->
    <c- n>bar</c-><c- p>();</c->
    <c- d>/* guard destructor is called only if it wasn’t passed to reloc. */</c->
<c- p>}</c->
</pre>
   <h3 class="heading settled" data-level="5.2" id="reloc-ctor"><span class="secno">5.2. </span><span class="content">Relocation constructor</span><a class="self-link" href="#reloc-ctor"></a></h3>
   <p>We introduce the relocation constructor. As relocation happens from prvalues,
the constructor takes a prvalue as parameter: <code class="highlight"><c- n>T</c-><c- p>(</c-><c- n>T</c-><c- p>)</c-></code>.</p>
   <p>This signature was picked as it completes the C++ tripartite value system.
The copy constructor creates a new instance from an lvalue, the move constructor 
from an xvalue, and then the relocation constructor from a prvalue.</p>
   <p class="note" role="note"><span class="marker">Note:</span> a further benefit of this syntax is that it is currently ill-formed <a href="http://wg21.link/class.copy.ctor#5">[class.copy.ctor]/5</a>, and
thus available for extension.</p>
   <p>A point of confusion may be that the syntax implies an infinite regress: the
parameter must be constructed, which requires a prior call to the relocation
constructor, and so on. This is not the case; if the source object was previously
a glvalue the operand of the <code class="highlight"><c- n>reloc</c-></code> operator, it was transformed into a prvalue
immediately before entering the relocation constructor, and the parameter of the
relocation constructor is that same prvalue. (If the source object was already a
prvalue, there is no issue; the parameter is that prvalue.)</p>
   <p>An attractive intuition is that the parameter aliases the source object in the
same way as a reference or a structured binding declaration.
However, this is misleading; the lifetime of a source object glvalue has already
ended and so use of a pointer or reference referring to the source object has
undefined behavior, except as provided by [basic.life] and [class.cdtor].</p>
   <p class="note" role="note"><span class="marker">Note:</span> this behavior matches that for the destructor of a class type; see <a href="https://wg21.link/basic.life#1.4">[basic.life]</a> paragraph 1.</p>
   <p>This intuition is only useful in so far as the ABI for a relocation
constructor prvalue parameter is likely to be the same as that for a copy or move
constructor parameter, since the prvalue parameter may have the same storage
location as a previously existing glvalue.</p>
   <p class="note" role="note"><span class="marker">Note:</span> it does not matter that the ABI for the relocation constructor parameter
differs from that for a prvalue parameter in normal functions, since it is not
possible to take the address of a constructor.</p>
   <p>The role of the relocation constructor is to construct a new instance by destructively
stealing the resources from the source object. Unlike the move
constructor, the relocation constructor needs not to leave the source object in
valid state. In fact the lifetime of the source object was ended immediately prior
to entering the relocation constructor, and thus the source object must simply be
considered as uninitialized memory after
the relocation constructor terminates. We also say that the source object
is left in a <em>destructed state</em>. This means that the destructor of the source
object must no longer be called (and will not be called, assuming the <code class="highlight"><c- n>reloc</c-></code> operator was used).</p>
   <h4 class="heading settled" data-level="5.2.1" id="reloc-ctor-declaration"><span class="secno">5.2.1. </span><span class="content">Declaration</span><a class="self-link" href="#reloc-ctor-declaration"></a></h4>
   <p>The relocation constructor can be declared (implicitly or explicitly), defaulted
and deleted like any other constructor.</p>
   <p>The relocation constructor of a class-type <code class="highlight"><c- n>T</c-></code> implicitly gets a <code class="highlight"><c- k>noexcept</c-><c- p>(</c->true<c- p>)</c-></code> exception specification unless:</p>
   <ul>
    <li data-md>
     <p>it is explicitly declared with <code class="highlight"><c- k>noexcept</c-><c- p>(</c->false<c- p>)</c-></code> ;</p>
    <li data-md>
     <p>or one <code class="highlight"><c- n>T</c-></code>'s subobjects has a <code class="highlight"><c- k>noexcept</c-><c- p>(</c->false<c- p>)</c-></code> relocation constructor ;</p>
    <li data-md>
     <p>or one <code class="highlight"><c- n>T</c-></code>'s subobjects does not declare a relocation constructor and has
a <code class="highlight"><c- k>noexcept</c-><c- p>(</c->false<c- p>)</c-></code> move constructor.</p>
   </ul>
   <p>These rules are similar to that of the destructor’s implicit exception specification.</p>
   <p>A class-type that provides a relocation constructor has some impact on the program
ABI. See the <a href="#abi">ABI section</a>.</p>
   <h5 class="heading settled" data-level="5.2.1.1" id="reloc-ctor-declaration-implicit"><span class="secno">5.2.1.1. </span><span class="content">Implicit declaration</span><a class="self-link" href="#reloc-ctor-declaration-implicit"></a></h5>
   <p>If a class-type follows the Rule of Zero (updated to account for the relocation
constructor and relocation assignment operator), then the compiler will declare
a non-explicit inline public relocation constructor,
i.e. if none of the following are user-declared:</p>
   <ul>
    <li data-md>
     <p>copy constructor</p>
    <li data-md>
     <p>copy assignment operator</p>
    <li data-md>
     <p>move constructor</p>
    <li data-md>
     <p>move assignment operator</p>
    <li data-md>
     <p>destructor</p>
    <li data-md>
     <p>relocating assignment operator</p>
   </ul>
   <h5 class="heading settled" data-level="5.2.1.2" id="reloc-ctor-declaration-deleted"><span class="secno">5.2.1.2. </span><span class="content">Deleted implicitly-declared or defaulted relocation constructor</span><a class="self-link" href="#reloc-ctor-declaration-deleted"></a></h5>
   <p>The implicitly-declared or defaulted relocation constructor for class <code class="highlight"><c- n>T</c-></code> is defined as deleted:</p>
   <ul>
    <li data-md>
     <p>if <code class="highlight"><c- n>T</c-></code> has subobjects that explicitly declare a deleted relocation constructor ;</p>
    <li data-md>
     <p>or <code class="highlight"><c- n>T</c-></code> has subobjects with missing relocation and move constructors (i.e.
that are deleted, inaccessible, or ambiguous).</p>
    <li data-md>
     <p>or <code class="highlight"><c- n>T</c-></code> has subobjects with deleted or unaccessible destructor.</p>
   </ul>
   <p>As for move constructors, a defaulted relocation constructor that is deleted is
ignored by overload resolution.</p>
   <p class="note" role="note"><span class="marker">Note:</span> this means that a class with an explictly deleted relocation constructor
will still be relocated if necessary, but through the move (or copy) constructor
and destructor.</p>
   <h5 class="heading settled" data-level="5.2.1.3" id="trivial-relocation"><span class="secno">5.2.1.3. </span><span class="content">Trivial relocation</span><a class="self-link" href="#trivial-relocation"></a></h5>
   <p>A relocation constructor of a class type <code class="highlight"><c- n>X</c-></code> is <em>trivial</em> if it is not user-provided and
if:</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>X</c-></code> has no virtual functions and no virtual base classes, and</p>
    <li data-md>
     <p>for each direct base class and direct non-static data member of class type or array thereof,
the relocation operation (which may be a relocation constructor or
synthesized from copy/move constructor plus destructor) selected
to relocate that base or member is trivial.</p>
   </ul>
   <p>A <em>trivially relocatable class</em> is one which:</p>
   <ul>
    <li data-md>
     <p>has a trivial, eligible relocation constructor, or</p>
    <li data-md>
     <p>does not have a relocation constructor (including one that is deleted),
and is trivially copyable.</p>
   </ul>
   <p class="note" role="note"><span class="marker">Note:</span> <em>eligible</em> is defined in <a href="http://wg21.link/special#def:special_member_function,eligible">[special]</a>.</p>
   <p>Scalar types, trivially relocatable class types, and arrays and cv-qualified versions
thereof are <em>trivially relocatable</em>.</p>
   <p><strong class="advisement"> we also tighten the definition of "trivial class" (and thus "trivial") to
require that the class in question be trivially relocatable as well as trivially
copyable. This is to ensure that if the user wants code to be called on relocation,
the library does not bypass said code by, say, using <code class="highlight"><c- n>memmove</c-></code>.</strong></p>
   <h4 class="heading settled" data-level="5.2.2" id="reloc-ctor-definition"><span class="secno">5.2.2. </span><span class="content">Definition</span><a class="self-link" href="#reloc-ctor-definition"></a></h4>
   <h5 class="heading settled" data-level="5.2.2.1" id="reloc-ctor-default-definition"><span class="secno">5.2.2.1. </span><span class="content">Default definition</span><a class="self-link" href="#reloc-ctor-default-definition"></a></h5>
   <p>The default relocation constructor implementation for a class-type <code class="highlight"><c- n>T</c-></code> depends
on <code class="highlight"><c- n>T</c-></code>'s type traits.</p>
   <p>If <code class="highlight"><c- n>T</c-></code> is trivially relocatable then the relocation constructor
effectively (ignoring padding) performs
a memcpy over its entire memory layout.</p>
   <p>Otherwise in the nominal case, the constructor implementation performs
memberwise relocations.</p>
   <p>In the relocation constructor <code class="highlight"><c- n>T</c-><c- p>(</c-><c- n>T</c-> <c- n>src</c-><c- p>)</c-></code>, for each subobject <code class="highlight"><c- n>s</c-></code> (of type <code class="highlight"><c- n>S</c-></code>)
of <code class="highlight"><c- n>T</c-></code>, in declaration order:</p>
   <ul>
    <li data-md>
     <p>if <code class="highlight"><c- n>S</c-></code> has an accessible relocation constructor, then <code class="highlight"><c- k>this</c-><c- o>-></c-><c- n>s</c-></code> is constructed
by calling the relocation constructor, passing <code class="highlight"><c- n>src</c-><c- p>.</c-><c- n>s</c-></code> as source object. <code class="highlight"><c- n>src</c-><c- p>.</c-><c- n>s</c-></code> is then left in a <em>destructed state</em>. Note that if <code class="highlight"><c- n>S</c-></code> is trivially 
relocatable then the relocation constructor call may be optiomized into a 
memcpy: <code class="highlight"><c- n>memcpy</c-><c- p>(</c-><c- o>&amp;</c-><c- k>this</c-><c- o>-></c-><c- n>s</c-><c- p>,</c-> <c- o>&amp;</c-><c- n>src</c-><c- p>.</c-><c- n>s</c-><c- p>,</c-> <c- k>sizeof</c-><c- p>(</c-><c- n>S</c-><c- p>))</c-></code> ;</p>
    <li data-md>
     <p>otherwise if <code class="highlight"><c- n>S</c-></code> has an accessible move constructor and destructor, then <code class="highlight"><c- k>this</c-><c- o>-></c-><c- n>s</c-></code> is constructed by calling the move constructor, ignoring <code class="highlight"><c- n>src</c-><c- p>.</c-><c- n>s</c-></code>'s
cv-qualifiers. This operation is called <em>synthesized 
relocation</em>. <code class="highlight"><c- n>src</c-><c- p>.</c-><c- n>s</c-></code> is <strong>not</strong> in a <em>destructed state</em> ;</p>
   </ul>
   <p>When all target subobjects have been constructed, the destructors all of
source subobjects are called, in reversed declaration order, omitting those 
that are already in a <em>destructed state</em>.</p>
   <h5 class="heading settled" data-level="5.2.2.2" id="reloc-ctor-user-definition"><span class="secno">5.2.2.2. </span><span class="content">User-provided definition</span><a class="self-link" href="#reloc-ctor-user-definition"></a></h5>
   <p>Users can provide their own definition of the relocation constructor.
Special rules apply to the relocation constructor’s member initialization list:
subobjects that have no user-provided initialization will be constructed by
relocation or synthesized relocation, instead of being default-constructed.</p>
   <p>In other terms, subobjects that are omitted in the member initializer list are
not constructed using their default constructor, but instead are constructed 
using relocation from the matching source subobject. That relocation is performed
either by the relocation constructor or by synthesized relocation, using the rules
described in the default relocation constructor implementation. If synthesized 
relocation happened for a subobject, then the source subobject is not in a <em>destructed state</em> yet.</p>
   <p>Before the relocation constructor body is entered, the destructors of all the
source subobjects are called in reversed declaration order, omitting those 
that are in a <em>destructed state</em>.
In particular a source subobject 
is not in a <em>destructed state</em> if the target subobject has a user-provided 
initialization in the member initialization list, hence the destructor of such 
subobject is always called before the constructor body is entered.</p>
   <p>At the end of the member initialization list, the whole source object is left
in a <em>destructed state</em>. Using the source object in the constructor body leads
to an undefined behavior.</p>
   <p>Consider the following examples:</p>
<pre class="language-c++ highlight"><c- k>struct</c-> <c- nc>T</c->
<c- p>{</c->
    <c- n>std</c-><c- o>::</c-><c- n>string</c-> <c- n>_a</c-><c- p>,</c-> <c- n>_b</c-><c- p>,</c-> <c- n>_c</c-><c- p>;</c->

    <c- n>T</c-><c- p>(</c-><c- n>T</c-> <c- n>src</c-><c- p>)</c-> <c- o>:</c->
        <c- n>_a</c-><c- p>{</c-><c- n>std</c-><c- o>::</c-><c- n>move</c-><c- p>(</c-><c- n>src</c-><c- p>.</c-><c- n>_a</c-><c- p>)},</c-> <c- n>_b</c-><c- p>{}</c-> <c- p>{}</c-> <c- d>/*</c->
<c- d>        1. T::_a is constructed using the move constructor.</c->
<c- d>        2. T::_b is default constructed.</c->
<c- d>        3. T::_c is constructed using std::string’s relocation constructor, from src._c.</c->
<c- d>        4. src._b and src._a are destructed (in that order) before the constructor body is entered.</c->
<c- d>    */</c->
<c- p>};</c->

<c- k>struct</c-> <c- nc>U</c->
<c- p>{</c->
    <c- n>std</c-><c- o>::</c-><c- n>string</c-> <c- n>_a</c-><c- p>,</c-> <c- n>_b</c-><c- p>;</c->
    <c- n>U</c-><c- p>(</c-><c- n>U</c-> <c- n>src</c-><c- p>)</c-> <c- p>{}</c-> <c- d>/*</c->
<c- d>        U relocation constructor behaves like the default definition, although it </c->
<c- d>        counts as user-provided.</c->
<c- d>    */</c->
<c- p>};</c->

<c- n>class</c-> <c- n>List</c->
<c- p>{</c->
<c- n>public</c-><c- o>:</c->
    <c- n>List</c-><c- p>(</c-><c- n>List</c-> <c- n>src</c-><c- p>)</c-> <c- d>/* _sentinel is memcpied from src._sentinel */</c->
    <c- p>{</c->
        <c- d>/* fixup references */</c->
        <c- n>_sentinel</c-><c- p>.</c-><c- n>_prev</c-><c- o>-></c-><c- n>_next</c-> <c- o>=</c-> <c- o>&amp;</c-><c- n>_sentinel</c-><c- p>;</c->
        <c- n>_sentinel</c-><c- p>.</c-><c- n>_next</c-><c- o>-></c-><c- n>_prev</c-> <c- o>=</c-> <c- o>&amp;</c-><c- n>_sentinel</c-><c- p>;</c->
    <c- p>}</c->
<c- n>private</c-><c- o>:</c->
    <c- k>struct</c-> <c- nc>Node</c-> <c- p>{</c-> <c- n>Node</c-><c- o>*</c-> <c- n>_prev</c-><c- p>;</c-> <c- n>Node</c-><c- o>*</c-> <c- n>_next</c-><c- p>;</c-> <c- b>int</c-> <c- n>_value</c-><c- p>;</c-> <c- p>};</c->
    <c- n>Node</c-> <c- n>_sentinel</c-><c- p>;</c->
<c- p>};</c->
</pre>
   <p>Alternatively, if the user calls a delegating constructor in place of a member
initializer list, then the destructor of the source object is called right after 
the delegating constructor call completes.</p>
   <p>This further means that the source object is fully destructed by the time the
relocation constructor body is entered. Any operation on it may result in
undefined behavior. However the source object name can still be accessed for 
debugging purposes (like printing its address somewhere).
Compilers can still emit warnings when undefined uses of the source object
are done in the constructor body.</p>
   <p>It is not possible for users to explicitly call the relocation constructor on subobjects.
This is because there is no existing syntax to do so:</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>T</c-><c- p>(</c-><c- n>T</c-> <c- n>src</c-><c- p>)</c-> <c- o>:</c-> <c- n>_a</c-><c- p>{</c-><c- n>src</c-><c- p>.</c-><c- n>_a</c-><c- p>}</c-></code> calls the copy constructor.</p>
    <li data-md>
     <p><code class="highlight"><c- n>T</c-><c- p>(</c-><c- n>T</c-> <c- n>src</c-><c- p>)</c-> <c- o>:</c-> <c- n>_a</c-><c- p>{</c-><c- k>auto</c-><c- p>{</c-><c- n>src</c-><c- p>.</c-><c- n>_a</c-><c- p>}}</c-></code> calls the copy constructor to make a temporary,
which then gets passed to the relocation constructor.</p>
    <li data-md>
     <p><code class="highlight"><c- n>T</c-><c- p>(</c-><c- n>T</c-> <c- n>src</c-><c- p>)</c-> <c- o>:</c-> <c- n>_a</c-><c- p>{</c-><c- n>reloc</c-> <c- n>src</c-><c- p>.</c-><c- n>_a</c-><c- p>}</c-></code> is not permitted as we cannot call <code class="highlight"><c- n>reloc</c-></code> on a subobject.</p>
    <li data-md>
     <p><code class="highlight"><c- n>T</c-><c- p>(</c-><c- n>T</c-> <c- n>src</c-><c- p>)</c-> <c- o>:</c-> <c- n>_a</c-><c- p>{</c-><c- n>std</c-><c- o>::</c-><c- n>destroy_relocate</c-><c- p>(</c-><c- o>&amp;</c-><c- n>src</c-><c- p>.</c-><c- n>_a</c-><c- p>)}</c-></code> is erroneous as well, as <code class="highlight"><c- n>src</c-><c- p>.</c-><c- n>_a</c-></code> will be destructed at the end of the member initializer list.</p>
   </ul>
   <p>This is the reason why omitted subobjects are automatically constructed by relocation,
and not using their default constructor. If users want to default-construct some subobject,
then they can write it explicitly: <code class="highlight"><c- n>T</c-><c- p>(</c-><c- n>T</c-> <c- n>src</c-><c- p>)</c-> <c- o>:</c-> <c- n>_a</c-><c- p>{}</c-> <c- p>{}</c-></code> (in which case the source subobject 
is destroyed at the end of the initializer list).</p>
   <p>It is for safety reasons that the relocation constructor ensures that
the source object is entirely destroyed by the time the constructor’s body is reached.
Had it been otherwise, then it would have been the responsibility of the users to destroy
the subobjects that did not get relocated. This would likely lead to programming errors, 
especially when we consider synthesized relocation.</p>
   <h5 class="heading settled" data-level="5.2.2.3" id="reloc-ctor-exceptions"><span class="secno">5.2.2.3. </span><span class="content">Exception handling</span><a class="self-link" href="#reloc-ctor-exceptions"></a></h5>
   <p>The relocation constructor is able to handle exceptions. If an exception leaks
through the relocation constructor then it guarantees that the <em>target</em> is not 
constructed and the <em>source</em> object is destroyed.</p>
   <p>**This is in general undesirable, which is why the relocation constructor is <code class="highlight"><c- k>noexcept</c-></code> if at all possible.**</p>
   <p>As we have seen above, the relocation constructor acts in three stages:
(a) target subobjects construction, 
(b) destruction in reversed declaration order on any source subobject 
that is not in a <em>destructed state</em> (because of synthesized relocation or 
user-provided initialization), (c) the function body.</p>
   <p><strong>Stage A: target subobjects construction</strong></p>
   <p>If an exception leaks through in stage (a) then:</p>
   <ol>
    <li data-md>
     <p>in reversed declaration order, call the destructor of all initialized subobjects.</p>
    <li data-md>
     <p>in reversed declaration order, call the destructor of the source subobjects
that are not in a <em>destructed state</em>:</p>
     <ul>
      <li data-md>
       <p>all subobjects whose corresponding target subobject <em>didn’t</em> get initialized ;</p>
      <li data-md>
       <p>all subobjects whose corresponding target subobject <em>did</em> get initialized,
but through synthesized relocation or user-provided initialization ;</p>
      <li data-md>
       <p>if the initialization that threw did not happen through a relocation
constructor call, 
then the matching subobject. (If the initialization happened by 
relocation then we know that the source subobject is in a <em>destructed state</em>.)</p>
     </ul>
   </ol>
   <p>We call the destructor on the target subobjects first as they were
constructed more recently.</p>
   <p><strong>Stage B: source subobjects destruction</strong></p>
   <p>If an exception leaks through in stage (b) then:</p>
   <ul>
    <li data-md>
     <p>All target subobjects are destroyed in reversed declaration order.</p>
    <li data-md>
     <p>All the remaining destructors of the source subobjects are called in reversed
declaration order.</p>
   </ul>
   <p><strong>Stage C: constructor body</strong></p>
   <p>If an exception leaks through in stage (c) then all target subobjects are
destroyed in reversed declaration order, like it is the case for any constructor.</p>
   <p><strong>Delegating constructor case</strong></p>
   <p>If an exception leaks through the delegating constructor then the source object
is destructor is called and the exception is propagated.</p>
   <p>Note that the target object needs not to be destroyed as the delegating
constructor already took care of that.</p>
   <h5 class="heading settled" data-level="5.2.2.4" id="reloc-ctor-additional-params"><span class="secno">5.2.2.4. </span><span class="content">Additional parameters</span><a class="self-link" href="#reloc-ctor-additional-params"></a></h5>
   <p>As with copy and move constructors, it is permissible to add additional parameters
to a relocation constructor, on condition they have a default initializer.</p>
   <p>One case where this can be of use is if the user needs space to store information
and/or resources
for the duration of the relocation constructor, for a contrived example:</p>
<pre class="language-c++ highlight"><c- n>class</c-> <c- n>T</c->
<c- p>{</c->
<c- n>public</c-><c- o>:</c->
    <c- n>class</c-> <c- n>Helper</c-> <c- p>{</c->
    <c- n>public</c-><c- o>:</c->
        <c- n>Helper</c-><c- p>()</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
        <c- o>~</c-><c- n>Helper</c-><c- p>()</c-> <c- p>{</c-> <c- n>delete</c-> <c- n>p</c-><c- p>;</c-> <c- p>}</c->
    <c- n>private</c-><c- o>:</c->
        <c- n>friend</c-> <c- n>T</c-><c- p>;</c->
        <c- b>int</c-><c- o>*</c-> <c- n>p</c-><c- p>;</c->
    <c- p>};</c->

    <c- n>T</c-><c- p>(</c-><c- n>T</c-> <c- n>src</c-><c- p>,</c-> <c- n>Helper</c-> <c- n>storage</c-> <c- o>=</c-> <c- p>{})</c-> <c- n>noexcept</c-><c- p>(</c->false<c- p>)</c->
        <c- o>:</c-> <c- n>_p</c-><c- p>(</c-><c- n>storage</c-><c- p>.</c-><c- n>p</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>exchange</c-><c- p>(</c-><c- n>src</c-><c- p>.</c-><c- n>_p</c-><c- p>,</c-> <c- n>nullptr</c-><c- p>))</c->
    <c- p>{</c->
        <c- n>storage</c-><c- p>.</c-><c- n>p</c-> <c- o>=</c-> <c- n>nullptr</c-><c- p>;</c->
    <c- p>}</c->

    <c- o>~</c-><c- n>T</c-><c- p>()</c-> <c- p>{</c->
        <c- n>delete</c-> <c- n>_p</c-><c- p>;</c->
    <c- p>}</c->

<c- n>private</c-><c- o>:</c->
    <c- b>int</c-><c- o>*</c-> <c- n>_p</c-><c- p>;</c->
    <c- n>RelocateOnly</c-> <c- n>_q</c-><c- p>;</c->
    <c- n>ThrowingRelocate</c-> <c- n>_r</c-><c- p>;</c->
<c- p>};</c->
</pre>
   <p>In the above, <code class="highlight"><c- n>T</c-><c- o>::</c-><c- n>_p</c-></code> does not manage its own lifetime,
but the presence of <code class="highlight"><c- n>T</c-><c- o>::</c-><c- n>_r</c-></code> means that <code class="highlight"><c- n>T</c-><c- o>::</c-><c- n>T</c-><c- p>(</c-><c- n>T</c-><c- p>)</c-></code> is not noexcept so we need to
release its resources if an exception is thrown during relocation.
The presence of <code class="highlight"><c- n>T</c-><c- o>::</c-><c- n>_q</c-></code> demonstrates that relocation cannot be synthesized.</p>
   <h4 class="heading settled" data-level="5.2.3" id="reloc-ctor-invoke"><span class="secno">5.2.3. </span><span class="content">Invocation</span><a class="self-link" href="#reloc-ctor-invoke"></a></h4>
   <p>The relocation constructor is invoked <em>as necessary</em> to relocate a prvalue
from one storage location to another. Use of the <code class="highlight"><c- n>reloc</c-></code> operator does not
guarantee that a relocation constructor (if present) will be called,
since it may be elided
if the compiler can arrange that the source glvalue was constructed at the
appropriate address.</p>
   <p>In particular, code of the form <code class="highlight"><c- n>T</c-> <c- n>x</c-> <c- o>=</c-> <c- n>reloc</c-> <c- n>y</c-><c- p>;</c-></code> is <em>highly</em> likely to be a
no-op, simply renaming an existing object. This is however likely to find use
for "sealing" objects with complex initialization, replacing the idiom of
immediately-invoked function expressions (IIFEs, <a data-link-type="biblio" href="#biblio-iife" title="IIFE for Complex Initialization - C++ Stories">[IIFE]</a>):</p>
   <table>
    <tbody>
     <tr>
      <th>Before
      <th>After
     <tr>
      <td valign="top">
<pre class="highlight" lang="cpp"><c- n>T</c-> <c- k>const</c-> <c- n>x</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>invoke</c-><c- p>([</c-><c- o>&amp;</c-><c- p>]</c->
<c- p>{</c->
    <c- n>T</c-> <c- n>x</c-><c- p>;</c->
    <c- n>x</c-><c- p>.</c-><c- n>modify</c-><c- p>(</c-><c- n>y</c-><c- p>,</c-> <c- n>z</c-><c- p>);</c->
    <c- k>return</c-> <c- n>x</c-><c- p>;</c->
<c- p>});</c->
</pre>
      <td valign="top">
<pre class="highlight" lang="cpp"><c- n>T</c-> <c- n>x_mut</c-><c- p>;</c->
<c- n>x_mut</c-><c- p>.</c-><c- n>modify</c-><c- p>(</c-><c- n>y</c-><c- p>,</c-> <c- n>z</c-><c- p>);</c->
<c- n>T</c-> <c- k>const</c-> <c- n>x</c-> <c- o>=</c-> <c- n>reloc</c-> <c- n>x_mut</c-><c- p>;</c->
</pre>
   </table>
   <p>Or, consider:</p>
<pre class="language-c++ highlight"><c- n>C</c-> <c- nf>f</c-><c- p>(</c-><c- b>int</c-> <c- n>i</c-><c- p>)</c-> <c- p>{</c->
    <c- n>C</c-> <c- n>c1</c-><c- p>,</c-> <c- n>c2</c-><c- p>;</c->
    <c- k>if</c-> <c- p>(</c-><c- n>i</c-> <c- o>==</c-> <c- mi>0</c-><c- p>)</c->
        <c- p>[[</c-><c- n>likely</c-><c- p>]]</c-> <c- k>return</c-> <c- n>reloc</c-> <c- n>c1</c-><c- p>;</c->  <c- c1>// #1</c->
    <c- k>else</c-> <c- k>if</c-> <c- p>(</c-><c- n>i</c-> <c- o>==</c-> <c- mi>1</c-><c- p>)</c->
        <c- p>[[</c-><c- n>likely</c-><c- p>]]</c-> <c- k>return</c-> <c- n>c1</c-><c- p>;</c->  <c- c1>// #2</c->
    <c- k>else</c->
        <c- p>[[</c-><c- n>unlikely</c-><c- p>]]</c-> <c- k>return</c-> <c- n>c2</c-><c- p>;</c->  <c- c1>// #3</c->
<c- p>}</c->
</pre>
   <p>At <code class="highlight"><c- cp>#1</c-></code> the <code class="highlight"><c- n>reloc</c-></code> is largely redundant; the end-of-life optimization means
the compiler is entitled to treat <code class="highlight"><c- n>c1</c-></code> as a prvalue anyway, as in <code class="highlight"><c- cp>#2</c-></code>. Indeed,
the likelihood annotation encourages the compiler to construct <code class="highlight"><c- n>c1</c-></code> in the
return slot, such that both <code class="highlight"><c- cp>#1</c-></code> and <code class="highlight"><c- cp>#2</c-></code> are a no-op. It is only <code class="highlight"><c- cp>#3</c-></code> that is
likely to invoke the relocation constructor.</p>
   <p>The relocation constructor may also be invoked by library functions, for example <a href="#std-destroy_relocate">§ 6.1.2 std::destroy_relocate</a>.</p>
   <h3 class="heading settled" data-level="5.3" id="reloc-assign-operator"><span class="secno">5.3. </span><span class="content">Relocation assignment operator</span><a class="self-link" href="#reloc-assign-operator"></a></h3>
   <p>We further introduce the relocation assignment operator. Its signature shall be: <code class="highlight"><c- n>T</c-><c- o>&amp;</c-> <c- n>T</c-><c- o>::</c-><c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- n>T</c-><c- p>)</c-></code>. Such operators may already be defined in existing codebases, 
but the proposed changes will not interfere with them.</p>
   <p>Sometimes we also make mentions to the <em>prvalue-assignment operator</em>.
It refers to the same function, 
but further indicates that this function existed prior to the proposal.</p>
   <h4 class="heading settled" data-level="5.3.1" id="reloc-assign-declaration"><span class="secno">5.3.1. </span><span class="content">Declaration</span><a class="self-link" href="#reloc-assign-declaration"></a></h4>
   <p>The relocation assignment operator becomes a special member function. As such,
declaring one breaks the Rule of Zero, which was not the case previously.</p>
   <p>The relocation assignment operator may be implicitly declared, and may be
defaulted or deleted.</p>
   <h5 class="heading settled" data-level="5.3.1.1" id="reloc-assign-operator-implicit"><span class="secno">5.3.1.1. </span><span class="content">Implicit declaration</span><a class="self-link" href="#reloc-assign-operator-implicit"></a></h5>
   <p>If a class-type follows the Rule of Zero, then the compiler will declare
an inline public relocation assignment operator.</p>
   <h5 class="heading settled" data-level="5.3.1.2" id="reloc-assign-declaration-deleted"><span class="secno">5.3.1.2. </span><span class="content">Deleted implicitly-declared or defaulted relocation assignment operator</span><a class="self-link" href="#reloc-assign-declaration-deleted"></a></h5>
   <p>The implicitly-declared or defaulted relocation assignment operator for class <code class="highlight"><c- n>T</c-></code> is defined as deleted:</p>
   <ul>
    <li data-md>
     <p>if <code class="highlight"><c- n>T</c-></code> has subobjects that have an implicitly or explicitly deleted relocation assignment operator ;</p>
    <li data-md>
     <p>or <code class="highlight"><c- n>T</c-></code> has no relocation, move, or copy constructor ;</p>
    <li data-md>
     <p>or <code class="highlight"><c- n>T</c-></code> has subobjects that have inaccessible relocation or move assignment operators ;</p>
    <li data-md>
     <p>or <code class="highlight"><c- n>T</c-></code> has subobjects with deleted or unaccessible destructor.</p>
   </ul>
   <p>A defaulted relocation assignment operator that is deleted is ignored by overload
resolution.</p>
   <h4 class="heading settled" data-level="5.3.2" id="aliased-reloc-assign"><span class="secno">5.3.2. </span><span class="content">Relocation assignment operator parameter relocation elision</span><a class="self-link" href="#aliased-reloc-assign"></a></h4>
   <p>As with the relocation constructor, it is desirable that the parameter should be
the source object <em>converted to</em> a prvalue, and not a temporary prvalue relocated <em>from</em> the source object. This is particularly critical for
the default definition of the operator, which
(as you might suspect) performs memberwise calls to other relocation assignment operators.
Without elision, that would imply recursive relocation of each subobject, down to
their smallest unbreakable parts.</p>
   <p>This, however, poses a problem, since it is possible to take the address of a
relocation assignment operator, yielding a pointer (or reference) with (typical)
signature <code class="highlight"><c- n>T</c-><c- o>&amp;</c-> <c- p>(</c-><c- n>T</c-><c- o>::</c-><c- p>)(</c-><c- n>T</c-><c- p>)</c-></code>, implying that the source object must occupy a parameter slot,
which may not find it possible to have the same storage address as the source object,
and/or which the caller may expect to destroy (see <a href="#abi">§ 5.7 ABI changes</a>).</p>
   <p>Nevertheless, we mandate elision where possible:</p>
   <ul>
    <li data-md>
     <p>If the class-type (possibly implicitly) declares a non-deleted relocation constructor,
or declares a defaulted relocation assignment operator, then elision is 
mandated at declaration level ;</p>
    <li data-md>
     <p>Otherwise, if the class-type defines a relocation assignment operator as
defaulted, then elision is mandated at definition level ;</p>
    <li data-md>
     <p>Otherwise elision is not mandated.</p>
   </ul>
   <p>Elision is performed in such a way as to avoid ABI break (more on that on the <a href="#prvalue-assign-op-abi">ABI
section</a>).</p>
   <h5 class="heading settled" data-level="5.3.2.1" id="aliased-reloc-assign-declaration"><span class="secno">5.3.2.1. </span><span class="content">Elision at declaration level</span><a class="self-link" href="#aliased-reloc-assign-declaration"></a></h5>
   <p>If elision is mandated at declaration level, then the assignment operator
declaration actually declares two member functions:</p>
   <ul>
    <li data-md>
     <p>the non-eliding one, which takes its input parameter by value.
This is the function that will get called when user-code calls the 
assignment operator. It is the prvalue-assignment operator as we know it 
today ;</p>
    <li data-md>
     <p>the eliding one, which takes its input parameter as if by reference, and has the
same return type as the non-eliding one. The eliding 
function has no identifier and does not participate in overload resolution.
Users cannot take its address and this function cannot be called directly in
user-code.
The eliding operator is in charge of destructing its source object, by 
relocation or destructor call.</p>
   </ul>
   <p>The definition of the assignment operator (which is user-provided or
defaulted) will serve as the definition of the eliding operator.</p>
   <p>The non-eliding operator definition is generated by the compiler, and merely wraps
the call to the eliding one:</p>
   <ul>
    <li data-md>
     <p>If the source object passed to the non-eliding operator is not an <em>unowned parameter</em>,
then the operator:</p>
     <ol>
      <li data-md>
       <p>Calls the eliding operator, passing the source object as if by reference.</p>
      <li data-md>
       <p>It forwards as return value whatever the eliding operator returns.</p>
      <li data-md>
       <p>Upon function exit, it does not destroy the source object as it is
already in a <em>destructed state</em>.</p>
     </ol>
    <li data-md>
     <p>Otherwise (the source object is an <em>unowned parameter</em>), then the operator:</p>
     <ol>
      <li data-md>
       <p>Creates a copy of the source object, using move or copy constructor.</p>
      <li data-md>
       <p>Calls the eliding operator, passing that copy by reference.</p>
      <li data-md>
       <p>It forwards as return value whatever the eliding operator returns.</p>
      <li data-md>
       <p>Upon function exit, it does not destroy the copy as it is
already in a <em>destructed state</em>.</p>
     </ol>
   </ul>
   <p>If the address of the assignment operator is queried, then the address of the
non-eliding version is returned. If the assignment operator is virtual, then only
the non-eliding version is considered to be <code class="highlight"><c- k>virtual</c-></code> and is added to the vtable entry.</p>
   <h5 class="heading settled" data-level="5.3.2.2" id="aliased-reloc-assign-definition"><span class="secno">5.3.2.2. </span><span class="content">Elision at definition level</span><a class="self-link" href="#aliased-reloc-assign-definition"></a></h5>
   <p>If elision is mandated at definition level, then the two versions of the operator
are generated (eliding and non-eliding) in the translation unit where the operator
is defined. The visibility of the eliding operator symbol to other translation
units is implementation-defined.</p>
   <p>The definition of the two functions are the same as if elision was mandated at
declaration level.</p>
   <h4 class="heading settled" data-level="5.3.3" id="reloc-assign-definition"><span class="secno">5.3.3. </span><span class="content">Definition</span><a class="self-link" href="#reloc-assign-definition"></a></h4>
   <h5 class="heading settled" data-level="5.3.3.1" id="reloc-assign-default-definition"><span class="secno">5.3.3.1. </span><span class="content">Default definition</span><a class="self-link" href="#reloc-assign-default-definition"></a></h5>
   <p>The default definition of the operator, given the rules above, benefits from elision. In
particular, the default definition is responsible for the destruction of its
source object.</p>
   <p>As you would expect, the default definition merely delegates to the relocation
assignment operator of all its subobjects.</p>
   <p>In <code class="highlight"><c- n>T</c-></code>'s default assignment operator, for all subobjects <code class="highlight"><c- n>s</c-></code> of <code class="highlight"><c- n>T</c-></code> of type <code class="highlight"><c- n>S</c-></code>:</p>
   <ul>
    <li data-md>
     <p>If <code class="highlight"><c- n>S</c-></code>'s relocation assignment operator mandates relocation elision at declaration level,
then call it with <code class="highlight"><c- n>src</c-><c- p>.</c-><c- n>s</c-></code> as parameter (passed as if by reference thanks to elision). 
The source subobject is then left in a <em>destructed state</em>.</p>
    <li data-md>
     <p>Otherwise if <code class="highlight"><c- n>S</c-></code> provides an non-eliding relocation assignment operator but
has an accessible relocation constructor,
then call the operator, if necessary relocating <code class="highlight"><c- n>src</c-><c- p>.</c-><c- n>s</c-></code> into the parameter slot.
The source subobject is then left in a <em>destructed state</em>.</p>
    <li data-md>
     <p>Otherwise if <code class="highlight"><c- n>S</c-></code> provides an non-eliding relocation assignment operator
and no accessible relocation constructor, then 
call the operator by passing a temporary copy of <code class="highlight"><c- n>src</c-><c- p>.</c-><c- n>s</c-></code>. This temporary is 
move-or-copy-constructed, ignoring the potential cv-qualifiers on <code class="highlight"><c- n>s</c-></code>.
The source subobject is <em>not</em> destructed.</p>
    <li data-md>
     <p>Otherwise if <code class="highlight"><c- n>S</c-></code> provides a move assignment or copy assignment operator, then
call the operator: <code class="highlight"><c- k>this</c-><c- o>-></c-><c- n>s</c-><c- p>.</c-><c- k>operator</c-><c- o>=</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>move</c-><c- p>(</c-><c- n>src</c-><c- p>.</c-><c- n>s</c-><c- p>));</c-></code>.
The source subobject is <em>not</em> destructed.</p>
   </ul>
   <p>After all the assignment operator calls have been made,
the destructors of all source subobjects that are not in a <em>destructed state</em> are called in reversed declaration order.</p>
   <p>This subobject destruction phase also happens as-is during stack-unwinding if one
of the assignment operators throws, effectively ensuring that the source object
will be left in a <em>destructed state</em>.</p>
   <h5 class="heading settled" data-level="5.3.3.2" id="reloc-assign-user-definition"><span class="secno">5.3.3.2. </span><span class="content">Possible user definitions</span><a class="self-link" href="#reloc-assign-user-definition"></a></h5>
   <p>Unlike the relocation constructor, the relocation assignment operator does not
rely on some special member initialization list. Instead, the assignment
operator relies on existing mechanisms.</p>
   <p>The two patterns commonly used to implement the assignment operator still work
as expected.</p>
   <p><strong>relocate-and-swap</strong></p>
<pre class="language-c++ highlight"><c- n>T</c-><c- o>&amp;</c-> <c- n>operator</c-><c- o>=</c-><c- p>(</c-><c- n>T</c-> <c- n>src</c-><c- p>)</c->
<c- p>{</c->
    <c- n>swap</c-><c- p>(</c-><c- o>*</c-><c- n>this</c-><c- p>,</c-> <c- n>src</c-><c- p>);</c->
    <c- k>return</c-> <c- o>*</c-><c- n>this</c-><c- p>;</c->
    <c- d>/* src destructor will still be called using normal rules */</c->
<c- p>}</c->
</pre>
   <p><strong>destroy-and-construct</strong></p>
<pre class="language-c++ highlight"><c- n>constexpr</c-> <c- n>T</c-><c- o>&amp;</c-> <c- n>operator</c-><c- o>=</c-><c- p>(</c-><c- n>T</c-> <c- n>src</c-><c- p>)</c-> <c- n>noexcept</c->
<c- p>{</c->
    <c- k>static_assert</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>is_nothrow_destructible_v</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-> <c- o>&amp;&amp;</c-> 
        <c- n>std</c-><c- o>::</c-><c- n>is_nothrow_relocatable_v</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-><c- p>);</c->

    <c- n>std</c-><c- o>::</c-><c- n>destroy_at</c-><c- p>(</c-><c- n>this</c-><c- p>);</c->
    <c- k>return</c-> <c- o>*</c-><c- n>std</c-><c- o>::</c-><c- n>construct_at</c-><c- p>(</c-><c- n>this</c-><c- p>,</c-> <c- n>reloc</c-> <c- n>src</c-><c- p>);</c->
<c- p>}</c->
</pre>
   <p>Let’s have a look at what happens in this function:</p>
   <ul>
    <li data-md>
     <p>The static assertion makes sure we have a relocation constructor. Hence,
the relocation assignment operator comes with an eliding and a non-eliding
version ;</p>
    <li data-md>
     <p>The provided definition will be used for the eliding version of the operator ;</p>
    <li data-md>
     <p>As its relocation is elided, <code class="highlight"><c- n>src</c-></code> is not an unowned parameter. As a consequence, <code class="highlight"><c- n>reloc</c-> <c- n>src</c-></code> will effectively call the relocation constructor, as it is able to elide 
the destructor call of <code class="highlight"><c- n>src</c-></code> ;</p>
    <li data-md>
     <p>The <code class="highlight"><c- n>src</c-></code> parameter may be provided by the non-eliding version. This <code class="highlight"><c- n>src</c-></code> may be a copy of the actual source object that was originally passed to the
assignment operator in user code. Whether a copy is made depends on whether
the non-eliding version is in charge of destroying its parameter. If not 
(<code class="highlight"><c- n>src</c-></code> is an <em>unowned parameter</em> with regards to the non-eliding operator) then
a copy is made, and the destructor of the source object is called at 
call-site, after the assignment operator returns.</p>
   </ul>
   <p>This approach is likely the most efficient one, although it is not exception-safe.
We recommend either the <code class="highlight"><c- k>noexcept</c-></code> specification or the static assertions to be 
part of the implementation to make sure of that.</p>
   <p>If <code class="highlight"><c- n>T</c-></code> is trivially
relocatable, then the operator is as optimal as we would like, as it merely 
translates into a destructor call and a memcpy call.</p>
   <p><strong>Union trick</strong></p>
   <p>If for some reason, the implementation needs to prevent the destructor call
on the source object, it is still possible to perform the "union trick":</p>
<pre class="language-c++ highlight"><c- n>T</c-><c- o>&amp;</c-> <c- n>operator</c-><c- o>=</c-><c- p>(</c-><c- n>T</c-> <c- n>src</c-><c- p>)</c->
<c- p>{</c->
    <c- k>union</c-> <c- p>{</c-> <c- n>T</c-> <c- n>tmp</c-> <c- p>}</c-> <c- o>=</c-> <c- p>{</c-> <c- p>.</c-><c- n>tmp</c-> <c- o>=</c-> <c- n>reloc</c-> <c- n>src</c-><c- p>;</c-> <c- p>};</c->
    <c- d>/* do some stuff with tmp (like calling std::destroy_relocate), </c->
<c- d>     * knowing its destructor will not be called by the language */</c->
    <c- k>return</c-> <c- o>*</c-><c- n>this</c-><c- p>;</c->
<c- p>}</c->
</pre>
   <h4 class="heading settled" data-level="5.3.4" id="reloc-assign-invoke"><span class="secno">5.3.4. </span><span class="content">Invocation</span><a class="self-link" href="#reloc-assign-invoke"></a></h4>
<pre class="language-c++ highlight"><c- n>T</c-> <c- n>x</c-><c- p>,</c-> <c- n>y</c-><c- p>;</c->
<c- n>x</c-> <c- o>=</c-> <c- n>reloc</c-> <c- n>y</c-><c- p>;</c->
</pre>
   <p>Every call to the relocation assignment operator follows normal rules.</p>
   <p>If the call site detects that an eliding version of the operator is available
(either because the eliding happened at declaration level, or because it
happened at definition level and the call site is in the same 
translation unit as the definition, or through link-time optimization),
then which version of the operator
is called is implementation-defined.</p>
   <p>The nominal case is to call the non-eliding version. The implementation is allowed
to call the eliding version instead, as long as it can elide the call to the 
destructor on the source object.</p>
   <h3 class="heading settled" data-level="5.4" id="overload-resolution"><span class="secno">5.4. </span><span class="content">Overload resolution</span><a class="self-link" href="#overload-resolution"></a></h3>
   <p class="note" role="note"><span class="marker">Note:</span> Compare <a data-link-type="biblio" href="#biblio-p2665r0" title="Allow calling overload sets containing T, const T&amp;">[P2665R0]</a> "Allow calling overload sets containing T,
const T&amp;".</p>
   <p>The current overload resolution rules are not suitable for relocation by prvalue.</p>
   <p>Indeed, consider the following scenario:</p>
<pre class="language-c++ highlight"><c- b>void</c-> <c- nf>bar</c-><c- p>(</c-><c- n>T</c-><c- o>&amp;&amp;</c-><c- p>);</c->
<c- b>void</c-> <c- nf>bar</c-><c- p>(</c-><c- n>T</c-><c- p>);</c->

<c- b>void</c-> <c- nf>foo</c-><c- p>(</c-><c- n>T</c-> <c- n>val</c-><c- p>)</c->
<c- p>{</c->
    <c- n>bar</c-><c- p>(</c-><c- n>reloc</c-> <c- n>val</c-><c- p>);</c-> <c- d>/* ambiguous call using today’s rules */</c->
<c- p>}</c->
</pre>
   <p>Hence we propose a change in the overload resolution rules to prefer passing by
value for prvalue arguments.</p>
   <p>Specifically, we would amend [over.ics.rank]/3.2.3 to read:</p>
   <ul>
    <li data-md>
     <p>neither of S1 and S2 bind a reference to an implicit object parameter of a
non-static member function declared without a ref-qualifier, and either:</p>
     <ul>
      <li data-md>
       <p>S1 binds an lvalue reference to an lvalue, and S2 does not, or:</p>
      <li data-md>
       <p>S1 binds an rvalue reference to an xvalue, and S2 does not, or:</p>
      <li data-md>
       <p>S1 does not bind a reference, and S2 binds a reference to a prvalue, or:</p>
      <li data-md>
       <p>S1 binds an rvalue reference to a prvalue, and S2 binds an lvalue reference [Example:</p>
<pre class="language-c++ highlight"><c- b>int</c-> <c- n>i</c-><c- p>;</c->
<c- b>int</c-> <c- nf>f1</c-><c- p>();</c->
<c- b>int</c-><c- o>&amp;&amp;</c-> <c- nf>f2</c-><c- p>();</c->
<c- p>...</c->
<c- b>int</c-> <c- n>g2</c-><c- p>(</c-><c- k>const</c-> <c- b>int</c-><c- o>&amp;</c-><c- p>);</c->
<c- b>int</c-> <c- nf>g2</c-><c- p>(</c-><c- b>int</c-><c- p>);</c->
<c- b>int</c-> <c- nf>g2</c-><c- p>(</c-><c- b>int</c-><c- o>&amp;&amp;</c-><c- p>);</c->
<c- b>int</c-> <c- n>j2</c-> <c- o>=</c-> <c- n>g2</c-><c- p>(</c-><c- n>i</c-><c- p>);</c-> <c- c1>// calls g2(const int&amp;)</c->
<c- b>int</c-> <c- n>k2</c-> <c- o>=</c-> <c- n>g2</c-><c- p>(</c-><c- n>f1</c-><c- p>());</c-> <c- c1>// calls g2(int)</c->
<c- b>int</c-> <c- n>l2</c-> <c- o>=</c-> <c- n>g2</c-><c- p>(</c-><c- n>f2</c-><c- p>());</c-> <c- c1>// calls g2(int&amp;&amp;)</c->
<c- p>...</c->
</pre>
       - end example] 
     </ul>
   </ul>
   <h3 class="heading settled" data-level="5.5" id="structured-reloc"><span class="secno">5.5. </span><span class="content">Structured relocation</span><a class="self-link" href="#structured-reloc"></a></h3>
   <h4 class="heading settled" data-level="5.5.1" id="structured-reloc-discussion"><span class="secno">5.5.1. </span><span class="content">Discussion</span><a class="self-link" href="#structured-reloc-discussion"></a></h4>
   <p><code class="highlight"><c- k>auto</c-> <c- p>[</c-><c- n>x</c-><c- p>,</c-> <c- n>y</c-><c- p>]</c-> <c- o>=</c-> <c- n>foo</c-><c- p>();</c-> <c- n>sink</c-><c- p>(</c-><c- n>reloc</c-> <c- n>y</c-><c- p>);</c-></code>, if ill-formed given the rules we
established for <code class="highlight"><c- n>reloc</c-></code>. <code class="highlight"><c- n>x</c-></code> and <code class="highlight"><c- n>y</c-></code> are not complete objects but aliases to some anonymous
object the language creates behind the scene.</p>
   <p>The proposal aims to provide support for relocate-only types. This support
would be partial, if not impractical, without allowing some form of 
relocation from a structured binding. This is motivated by:</p>
   <ul>
    <li data-md>
     <p>The need to make APIs that support relocate-only types. How would we write an
API to extract an item at an arbitrary position from a vector? We propose the 
following API: <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>pair</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>iterator</c-><c- o>></c-> <c- n>vector</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>::</c-><c- n>erase</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>relocate_t</c-><c- p>,</c-> <c- n>const_iterator</c-><c- p>);</c-></code> (returns relocated vector element and next valid iterator) as it is consistent
with other vector APIs and complies with the <a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rf-out">core guidelines</a>. 
Then, what can users do with the returned object as it lies in a pair, and 
that it is forbidden to relocate a subobject? The return value 
is unusable for relocate-only types, unless we provide some support for it.</p>
    <li data-md>
     <p>In our experience, most C++ developers believe that a structured binding is
a complete, separate object, and not a name alias to some subobject. As such
it would feel unnatural for them if they cannot relocate from a structured binding.</p>
   </ul>
   <h4 class="heading settled" data-level="5.5.2" id="structured-reloc-declaration"><span class="secno">5.5.2. </span><span class="content">Structured relocation declaration</span><a class="self-link" href="#structured-reloc-declaration"></a></h4>
   <p>A structured relocation declaration is syntactically identical to a structured
binding, with the exception that no ref-qualifiers are allowed after the <code class="highlight"><c- k>auto</c-></code> type specifier.</p>
<pre class="language-c++ highlight"><c- n>T</c-> <c- nf>foo</c-><c- p>();</c->
<c- n>T</c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>bar</c-><c- p>();</c->
<c- n>T</c-> <c- nf>foobar</c-><c- p>();</c->

<c- c1>// [...]</c->

<c- k>auto</c-> <c- p>[</c-><c- n>x</c-><c- p>,</c-> <c- n>y</c-><c- p>]</c-> <c- o>=</c-> <c- n>foo</c-><c- p>();</c-> <c- c1>// matches structured relocation declaration</c->
<c- k>auto</c-> <c- k>const</c-> <c- p>[</c-><c- n>w</c-><c- p>,</c-> <c- n>z</c-><c- p>]</c-> <c- o>=</c-> <c- n>bar</c-><c- p>();</c-> <c- c1>// matches structured relocation declaration</c->
<c- k>auto</c-><c- o>&amp;&amp;</c-> <c- p>[</c-><c- n>a</c-><c- p>,</c-> <c- n>b</c-><c- p>]</c-> <c- o>=</c-> <c- n>foobar</c-><c- p>();</c-> <c- c1>// structured bindings will be used</c->
</pre>
   <p>The structured relocation declaration further requires that the type of the
expression that is used to initialize it 
supports <a href="#structured-reloc-obj-decomposition">object decomposition</a>.
If not, then the declaration is simply a structured bindings declaration and will
follow structured bindings rules.</p>
   <p>A structured relocation introduces a new complete object for each identifier
declared in the brackets <code class="highlight"><c- p>[]</c-></code>. In other words, the new identifiers are not
aliases like in structured bindings, but actual complete objects. As such, they 
can then be relocated like any other.</p>
   <h4 class="heading settled" data-level="5.5.3" id="structured-reloc-obj-decomposition"><span class="secno">5.5.3. </span><span class="content">Object decomposition</span><a class="self-link" href="#structured-reloc-obj-decomposition"></a></h4>
   <p>As there are three binding protocols for structured bindings, there are two
"object decomposition" protocols for structured relocation. If none 
of those two protocols matches, then the declaration is not a
structured relocation declaration.</p>
   <p>First, <em>get_all</em> protocol is tested, and then the <em>data members</em> protocol.</p>
   <p>In what follows, let <code class="highlight"><c- n>E</c-></code> be the type of the initializer expression (the type
of the expression used to initialize the structured relocation).</p>
   <ul>
    <li data-md>
     <p>If <code class="highlight"><c- n>E</c-></code> is ref-qualified, then let <code class="highlight"><c- n>S</c-></code> be the same as <code class="highlight"><c- n>E</c-></code>, but deprived of its
ref-qualifiers.
If one of the two protocols applies, then an anonymous object of type <code class="highlight"><c- n>S</c-></code> is 
constructed from the initializer, using the appropriate constructor. 
This anonymous object will be considered as source object ;</p>
    <li data-md>
     <p>Otherwise (<code class="highlight"><c- n>E</c-></code> is a prvalue), then let <code class="highlight"><c- n>S</c-></code> be the same as <code class="highlight"><c- n>E</c-></code>. The initializer
expression will be used as source object.</p>
   </ul>
   <h5 class="heading settled" data-level="5.5.3.1" id="structured-reloc-dm"><span class="secno">5.5.3.1. </span><span class="content">data members protocol</span><a class="self-link" href="#structured-reloc-dm"></a></h5>
   <p>The <em>data members</em> protocol is quite similar to that of structured bindings.
For this protocol to apply, all the following conditions must be satisfied:</p>
   <ul>
    <li data-md>
     <p>every non-static data member of <code class="highlight"><c- n>S</c-></code> must be a direct member of <code class="highlight"><c- n>S</c-></code> or of the same
base class of <code class="highlight"><c- n>S</c-></code> ;</p>
    <li data-md>
     <p>the number of identifiers must equal the number of non-static data members ;</p>
    <li data-md>
     <p><code class="highlight"><c- n>S</c-></code> may not have an anonymous union member ;</p>
    <li data-md>
     <p><em>specific to structured relocation:</em> every base class, between <code class="highlight"><c- n>S</c-></code> and the base
class the data members are found in, does not have a user-defined destructor.</p>
   </ul>
   <p>If this protocol applies, then the <em>i</em>-th identifier is constructed by
relocation or synthesized relocation (move constructor ignoring cv-qualifiers, 
followed by destructor call) using the <em>i</em>-th data member of the source 
object.</p>
   <h5 class="heading settled" data-level="5.5.3.2" id="structured-reloc-get_all"><span class="secno">5.5.3.2. </span><span class="content">get_all protocol</span><a class="self-link" href="#structured-reloc-get_all"></a></h5>
   <p>The function <code class="highlight"><c- n>get_all</c-><c- p>(</c-><c- n>S</c-><c- p>)</c-></code> is looked-up using ADL-lookup. If there is
no match, then this protocol does not apply.</p>
   <p>If there is a match, then this function is called. The returned type is again
tested against the two protocols. If <em>get_all</em> matches for the
returned type, then we reapply it again, so on and so forth, until <em>get_all</em> doesn’t match and only <em>data members</em> does.</p>
   <p>This follows the same recursive logic as <code class="highlight"><c- k>operator</c-><c- o>-></c-><c- p>()</c-></code>.
We recursively call <code class="highlight"><c- n>get_all</c-></code> as long as the <em>get_all</em> protocol 
applies. When the recursion ends, we end up with a type which 
matches the <em>data member</em> protocol.</p>
   <p>The program is ill-formed if <code class="highlight"><c- n>T</c-></code> matches the <em>get_all</em> protocol but
the return type of <code class="highlight"><c- n>get_all</c-><c- p>(</c-><c- n>T</c-><c- p>)</c-></code> matches none of the two protocols.</p>
   <h6 class="heading settled" data-level="5.5.3.2.1" id="structured-reloc-tuple"><span class="secno">5.5.3.2.1. </span><span class="content">std::tuple and std::array are implementation-defined</span><a class="self-link" href="#structured-reloc-tuple"></a></h6>
   <p><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>pair</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>tuple</c-></code>, and <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>array</c-></code> shall provide their own implementation
of <code class="highlight"><c- n>get_all</c-></code>. The return type is implementation-defined (may rely on compiler magic).</p>
   <p>This allows us to write things like:</p>
<pre class="language-c++ highlight"><c- b>void</c-> <c- nf>bar</c-><c- p>(</c-><c- n>T</c-><c- p>);</c->
<c- b>void</c-> <c- nf>foo</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>vector</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>&amp;</c-> <c- n>v</c-><c- p>)</c->
<c- p>{</c->
    <c- d>/* erase(std::relocate_t) removes a vector element at given iterator,</c->
<c- d>     * returns a pair with next valid iterator and relocated vector element. */</c->
    <c- k>auto</c-> <c- p>[</c-><c- n>val</c-><c- p>,</c-> <c- n>it</c-><c- p>]</c-> <c- o>=</c-> <c- n>v</c-><c- p>.</c-><c- n>erase</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>relocate</c-><c- p>,</c-> <c- n>v</c-><c- p>.</c-><c- n>begin</c-><c- p>()</c-> <c- o>+</c-> <c- mi>1</c-><c- p>);</c-> <c- d>/* calls get_all behind</c->
<c- d>        the scene. */</c->
    <c- n>bar</c-><c- p>(</c-><c- n>reloc</c-> <c- n>val</c-><c- p>);</c-> <c- d>/* can call reloc on val as it is not a structured binding */</c->
<c- p>}</c->
</pre>
   <p>This code works even if <code class="highlight"><c- n>T</c-></code> is relocate-only.</p>
   <h6 class="heading settled" data-level="5.5.3.2.2" id="structured-reloc-implem"><span class="secno">5.5.3.2.2. </span><span class="content">Possible get_all implementations</span><a class="self-link" href="#structured-reloc-implem"></a></h6>
   <p>Most of the time, <code class="highlight"><c- n>get_all</c-></code> functions will want to be <a href="#decomposing-func">§ 5.6 Decomposing functions</a>.
A <code class="highlight"><c- n>get_all</c-></code> implementation as a decomposing function is provided in the mentioned
section.</p>
   <p>Thanks to <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>tuple</c-></code>'s <code class="highlight"><c- n>get_all</c-></code> we can easily write
a <code class="highlight"><c- n>get_all</c-></code> implementation for a custom class:</p>
<pre class="language-c++ highlight"><c- n>class</c-> <c- n>MyType</c->
<c- p>{</c->
<c- n>public</c-><c- o>:</c->
    <c- n>MyType</c-><c- p>();</c->
    <c- n>MyType</c-><c- p>(</c-><c- n>MyType</c-><c- p>);</c->

    <c- c1>// Possible implementation:</c->
    <c- k>auto</c-> <c- n>get_all</c-><c- p>(</c-><c- n>this</c-> <c- n>MyType</c-> <c- n>self</c-><c- p>)</c->
    <c- p>{</c->
        <c- k>return</c-> <c- n>std</c-><c- o>::</c-><c- n>tuple</c-><c- p>{</c-><c- n>std</c-><c- o>::</c-><c- n>relocate</c-><c- p>,</c-> <c- n>std</c-><c- o>::</c-><c- n>move</c-><c- p>(</c-><c- n>self</c-><c- p>.</c-><c- n>_name</c-><c- p>),</c-> <c- n>self</c-><c- p>.</c-><c- n>_flag</c-><c- p>,</c->
            <c- o>!</c-><c- n>self</c-><c- p>.</c-><c- n>_nodes</c-><c- p>.</c-><c- n>empty</c-><c- p>()};</c->
    <c- p>}</c->

<c- n>private</c-><c- o>:</c->
    <c- n>std</c-><c- o>::</c-><c- n>string</c-> <c- n>_name</c-><c- p>;</c->
    <c- b>bool</c-> <c- n>_flag</c-><c- p>;</c->
    <c- n>std</c-><c- o>::</c-><c- n>vector</c-><c- o>&lt;</c-><c- n>Node</c-><c- o>*></c-> <c- n>_nodes</c-><c- p>;</c->

<c- p>};</c->
</pre>
   <p>The implementation relies on the proposed new constructor for <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>tuple</c-></code>:</p>
<pre class="language-c+++ highlight"><c- n>template</c-> <c- o>&lt;</c-><c- n>class</c-><c- p>...</c-> <c- n>Tp</c-><c- o>></c->
<c- n>tuple</c-><c- o>::</c-><c- n>tuple</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>relocate_t</c-><c- p>,</c-> <c- n>Tp</c-><c- p>);</c->
</pre>
   which captures the tuple elements by value and relocates them inside the tuple. <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>relocate_t</c-></code> is just a tag type used for overload disambiguation. 
   <p>Then, in following snippet:</p>
<pre class="language-c++ highlight"><c- n>MyType</c-> <c- n>tp</c-><c- p>;</c->
<c- k>auto</c-> <c- p>[</c-><c- n>name</c-><c- p>,</c-> <c- n>flag</c-><c- p>,</c-> <c- n>nodes</c-><c- p>]</c-> <c- o>=</c-> <c- n>reloc</c-> <c- n>tp</c-><c- p>;</c->
<c- c1>// equivalent to: auto [name, flag, nodes] = get_all(get_all(reloc tp));</c->
</pre>
   <p><code class="highlight"><c- n>MyType</c-></code>'s <code class="highlight"><c- n>get_all</c-></code> returns a tuple. <code class="highlight"><c- n>get_all</c-></code> is defined for tuples as well, so
it is called again. The second return type won’t have a <code class="highlight"><c- n>get_all</c-></code> defined, hence
the recursion stops and the <em>data member</em> protocol is used.</p>
   <h3 class="heading settled" data-level="5.6" id="decomposing-func"><span class="secno">5.6. </span><span class="content">Decomposing functions</span><a class="self-link" href="#decomposing-func"></a></h3>
   <p>We established that <code class="highlight"><c- n>reloc</c-></code> can only be used to relocate function-local variables.
Thus it follows that <code class="highlight"><c- n>reloc</c-></code> cannot be used on data-members, which is impractical
when we consider <a href="#structured-reloc">§ 5.5 Structured relocation</a> and user-defined <code class="highlight"><c- n>get_all</c-></code> functions:</p>
<pre class="language-c++ highlight"><c- k>struct</c-> <c- nc>MyClass</c->
<c- p>{</c->
    <c- n>gsl</c-><c- o>::</c-><c- n>non_null</c-><c- o>&lt;</c-><c- n>std</c-><c- o>::</c-><c- n>unique_ptr</c-><c- o>&lt;</c-><c- b>int</c-><c- o>>></c-> <c- n>_reloc_only</c-><c- p>;</c->

    <c- k>auto</c-> <c- n>get_all</c-><c- p>(</c-><c- n>this</c-> <c- n>MyClass</c-> <c- n>self</c-><c- p>)</c->
    <c- p>{</c->
        <c- k>return</c-> <c- n>reloc</c-> <c- n>self</c-><c- p>.</c-><c- n>_reloc_only</c-><c- p>;</c-> <c- c1>// ill-formed, cannot relocate data members</c->
    <c- p>}</c->
<c- p>}</c->
</pre>
   <p>We introduce a special kind of member functions, called <em>decomposing functions</em>,
to enable relocation of data-members. A decomposing function is a member
function that takes an explicit <code class="highlight"><c- k>this</c-></code> parameter by value and whose name is <code class="highlight"><c- n>reloc</c-></code>:</p>
<pre class="language-c++ highlight"><c- k>auto</c-> <c- n>get_all</c-><c- p>(</c-><c- n>this</c-> <c- n>T</c-> <c- n>reloc</c-><c- p>)</c->
</pre>
   <h4 class="heading settled" data-level="5.6.1" id="decomposing-func-declare"><span class="secno">5.6.1. </span><span class="content">Declaration</span><a class="self-link" href="#decomposing-func-declare"></a></h4>
   <p>The decomposing trait of a function may not appear in the declaration if the
parameter name is omitted or different than <code class="highlight"><c- n>reloc</c-></code>. The decomposing trait
is an implementation detail and it does not need to appear in the declaration.</p>
   <p>A decomposing function does not bear any constraints on the number and types of
parameters, except for its first parameter. The first parameter must be an
explicit object parameter passed by value, possibly cv-qualified.</p>
   <p>Further constraints apply to the type of the first parameter. For instance
the type must be same as, or derive from the class-type the function is a
member of. However those constraints are only checked in the context of the definition,
not the declaration. See also <a href="#decomposing-func-ill-formedness-criteria">here</a>).</p>
   <h4 class="heading settled" data-level="5.6.2" id="decomposing-func-definition"><span class="secno">5.6.2. </span><span class="content">Definition</span><a class="self-link" href="#decomposing-func-definition"></a></h4>
   <p>A decomposing function decomposes its <code class="highlight"><c- k>this</c-></code> parameter into subobjects before
the function body is entered. It is subject to the following rules:</p>
   <ul>
    <li data-md>
     <p>The explicit <code class="highlight"><c- k>this</c-></code> object is inaccessible in the function body ;</p>
    <li data-md>
     <p>Upon calling the function, before the function body is entered, <code class="highlight"><c- o>*</c-><c- k>this</c-></code> is decomposed into individual objects for each direct base and
non-static data member. This decomposition is a no-op: all subobjects of <code class="highlight"><c- o>*</c-><c- k>this</c-></code> merely get considered as distinct complete objects. In particular the
decomposition does not odr-use any of the copy, move or relocation constructor
of the subobjects.</p>
    <li data-md>
     <p>Although the lifetime of <code class="highlight"><c- o>*</c-><c- k>this</c-></code> ends once decomposed, its destructor is never
called ;</p>
    <li data-md>
     <p>The direct base objects have no identifiers, and can only be accessed once
through the <code class="highlight"><c- n>reloc</c-> <c- n>Base</c-></code> expression (<code class="highlight"><c- n>Base</c-></code> being a direct base of the
class-type). In particular, base data members are inaccessible in the
function body ;</p>
    <li data-md>
     <p>The non-static data member objects are identified by their name in the class
declaration and can be accessed normally. If disambiguation is necessary then
the data members can be accessed with the syntax <code class="highlight"><c- n>T</c-><c- o>::</c-><c- n>datamember</c-></code>, <code class="highlight"><c- n>T</c-></code> being
the type of the <code class="highlight"><c- k>this</c-></code> parameter, and <code class="highlight"><c- n>datamember</c-></code> being the name of the
data member.</p>
   </ul>
   <p>Special considerations are taken for overlapping subobjects:</p>
   <ul>
    <li data-md>
     <p><strong>EBO bases and</strong> <code class="highlight"><c- p>[[</c-><c- n>no_unique_address</c-><c- p>]]</c-></code> <strong>members:</strong> Obey the above rules.</p>
    <li data-md>
     <p><strong>Anonymous unions:</strong> Obey the above rules. <code class="highlight"><c- n>reloc</c-></code> rules pertaining to function-local
anonymous union members apply.</p>
    <li data-md>
     <p><strong>Virtual bases (and bases with virtual bases):</strong> are unrelocatable. They cannot
be accessed by the <code class="highlight"><c- n>reloc</c-> <c- n>Base</c-></code> expression (ill-formed).</p>
   </ul>
   <p>Since subobjects have become complete objects, they can be relocated like any
function-local variable; otherwise, their destructor is called on exit from function scope.</p>
   <h5 class="heading settled" data-level="5.6.2.1" id="decomposing-func-examples"><span class="secno">5.6.2.1. </span><span class="content">Examples</span><a class="self-link" href="#decomposing-func-examples"></a></h5>
   <p><strong>A possible get_all implementation with a relocate-only type</strong></p>
<pre class="language-c++ highlight"><c- k>struct</c-> <c- nc>Addr</c->
<c- p>{</c->
    <c- n>gsl</c-><c- o>::</c-><c- n>non_null</c-><c- o>&lt;</c-><c- n>std</c-><c- o>::</c-><c- n>unique_ptr</c-><c- o>&lt;</c-><c- b>int</c-><c- o>>></c-> <c- n>_addr</c-><c- p>;</c->

    <c- k>auto</c-> <c- n>get_all</c-><c- p>(</c-><c- n>this</c-> <c- n>Addr</c-> <c- n>reloc</c-><c- p>)</c-> <c- p>{</c-> <c- k>return</c-> <c- n>_addr</c-><c- p>;</c-> <c- p>}</c->
<c- p>};</c->
<c- k>struct</c-> <c- nc>T</c-> <c- o>:</c-> <c- n>Addr</c->
<c- p>{</c->
    <c- n>std</c-><c- o>::</c-><c- n>vector</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>_data</c-><c- p>;</c->

    <c- k>auto</c-> <c- n>get_all</c-><c- p>(</c-><c- n>this</c-> <c- n>T</c-> <c- n>reloc</c-><c- p>)</c->
    <c- p>{</c->
        <c- k>auto</c-> <c- k>const</c-> <c- p>[</c-><c- n>addr</c-><c- p>]</c-> <c- o>=</c-> <c- n>reloc</c-> <c- n>Addr</c-><c- p>;</c->
        <c- k>return</c-> <c- n>std</c-><c- o>::</c-><c- n>pair</c-><c- p>{</c-><c- n>reloc</c-> <c- n>addr</c-><c- p>,</c-> <c- n>reloc</c-> <c- n>_data</c-><c- p>};</c->
    <c- p>}</c->
<c- p>};</c->
</pre>
   <p><strong>Curiously Recurring Template Pattern</strong></p>
<pre class="language-c++ highlight"><c- n>template</c-> <c- o>&lt;</c-><c- n>class</c-> <c- n>Derived</c-><c- o>></c->
<c- k>struct</c-> <c- nc>ExtractAddr</c->
<c- p>{</c->
    <c- k>auto</c-> <c- n>get_addr</c-><c- p>(</c-><c- n>this</c-> <c- n>Derived</c-> <c- n>reloc</c-><c- p>)</c-> <c- p>{</c-> <c- k>return</c-> <c- n>Derived</c-><c- o>::</c-><c- n>_addr</c-><c- p>;</c-> <c- p>}</c->
<c- p>};</c->
<c- k>struct</c-> <c- nc>ExtractAddr2</c->
<c- p>{</c->
    <c- n>template</c-> <c- o>&lt;</c-><c- n>class</c-> <c- n>Derived</c-><c- o>></c->
    <c- k>auto</c-> <c- n>get_addr</c-><c- p>(</c-><c- n>this</c-> <c- n>Derived</c-> <c- n>reloc</c-><c- p>)</c-> <c- p>{</c-> <c- k>return</c-> <c- n>Derived</c-><c- o>::</c-><c- n>_addr</c-><c- p>;</c-> <c- p>}</c->
<c- p>};</c->
<c- k>struct</c-> <c- nc>A</c-> <c- o>:</c-> <c- n>ExtractAddr</c-><c- o>&lt;</c-><c- n>A</c-><c- o>></c->
<c- p>{</c->
    <c- n>gsl</c-><c- o>::</c-><c- n>non_null</c-><c- o>&lt;</c-><c- n>std</c-><c- o>::</c-><c- n>unique_ptr</c-><c- o>&lt;</c-><c- b>int</c-><c- o>>></c-> <c- n>_addr</c-><c- p>;</c->
    <c- c1>// [...]</c->
<c- p>};</c->
<c- k>struct</c-> <c- nc>B</c-> <c- o>:</c-> <c- n>ExtractAddr2</c->
<c- p>{</c->
    <c- n>gsl</c-><c- o>::</c-><c- n>non_null</c-><c- o>&lt;</c-><c- n>std</c-><c- o>::</c-><c- n>unique_ptr</c-><c- o>&lt;</c-><c- b>int</c-><c- o>>></c-> <c- n>_addr</c-><c- p>;</c->
    <c- c1>// [...]</c->
<c- p>};</c->
</pre>
   <p>Note that, in the above example, if we have a <code class="highlight"><c- n>DA</c-></code> structure that inherits
from <code class="highlight"><c- n>A</c-></code> and a <code class="highlight"><c- n>DB</c-></code> structure that inherits from <code class="highlight"><c- n>B</c-></code>,
then <code class="highlight"><c- n>DA</c-><c- p>{}.</c-><c- n>get_addr</c-><c- p>()</c-></code> is well-formed while <code class="highlight"><c- n>DB</c-><c- p>{}.</c-><c- n>get_addr</c-><c- p>()</c-></code> is not.
Indeed <code class="highlight"><c- n>_addr</c-></code> is not a direct member of <code class="highlight"><c- n>DB</c-></code> (type deduced in <code class="highlight"><c- n>ExtractAddr2</c-><c- o>::</c-><c- n>get_addr</c-></code>)
and hence is not directly accessible this way.</p>
   <p><strong>A possible implementation of a putative unique_ptr::release (not proposed)</strong></p>
<pre class="language-c++ highlight"><c- n>T</c-><c- o>*</c-> <c- n>unique_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-><c- n>D</c-><c- o>>::</c-><c- n>release</c-><c- p>(</c-><c- n>this</c-> <c- n>unique_ptr</c-> <c- n>reloc</c-><c- p>)</c->
<c- p>{</c->
    <c- d>/* the "owned" pointer is loose at this point because of the decomposition */</c->
    <c- k>return</c-> <c- n>_ptr</c-><c- p>;</c->
<c- p>}</c->
</pre>
   <h4 class="heading settled" data-level="5.6.3" id="ill-formed-decomposing-func"><span class="secno">5.6.3. </span><span class="content">Ill-formed definition</span><a class="self-link" href="#ill-formed-decomposing-func"></a></h4>
   <p>If not forbidden, there are several ways where decomposition functions can be
misused and lead to problems. In this section we will see those cases and 
they will serve as motivation to the ill-formedness criteria.</p>
   <h5 class="heading settled" data-level="5.6.3.1" id="decomposing-func-aberrations"><span class="secno">5.6.3.1. </span><span class="content">Aberrations</span><a class="self-link" href="#decomposing-func-aberrations"></a></h5>
   <p>As mentioned in <a data-link-type="biblio" href="#biblio-p0847r6" title="Deducing this">[P0847R6]</a>, in the <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0847r6.html#pathological-cases">pathological cases section</a>,
code like this is possible:</p>
<pre class="language-c++ highlight"><c- k>struct</c-> <c- nc>A</c->
<c- p>{</c->
    <c- n>template</c-> <c- o>&lt;</c-><c- n>class</c-> <c- n>T</c-><c- o>></c->
    <c- k>auto</c-> <c- n>foo</c-><c- p>(</c-><c- n>this</c-> <c- n>T</c-> <c- n>self</c-><c- p>);</c->
<c- p>};</c->

<c- k>auto</c-> <c- n>func</c-> <c- o>=</c-> <c- o>&amp;</c-><c- n>A</c-><c- o>::</c-><c- n>foo</c-><c- o>&lt;</c-><c- n>std</c-><c- o>::</c-><c- n>unique_ptr</c-><c- o>&lt;</c-><c- b>int</c-><c- o>>></c-><c- p>;</c->
<c- n>func</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>make_unique</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-><c- p>(</c-><c- mi>0</c-><c- p>));</c->
</pre>
   <p>This remains acceptable in the context of P0847R6, but may lead to dangerous code
with decomposing functions. We don’t want the following code to be valid:</p>
<pre class="language-c++ highlight"><c- k>struct</c-> <c- nc>Sink</c->
<c- p>{</c->
    <c- n>template</c-> <c- o>&lt;</c-><c- n>class</c-> <c- n>T</c-><c- o>></c->
    <c- b>void</c-> <c- n>sink</c-><c- p>(</c-><c- n>this</c-> <c- n>T</c-> <c- n>reloc</c-><c- p>)</c-> <c- p>{}</c-> <c- d>/* prevent dtor call, </c->
<c- d>        although each subobject is destroyed individually */</c->
<c- p>};</c->

<c- k>auto</c-> <c- n>func</c-> <c- o>=</c-> <c- o>&amp;</c-><c- n>Sink</c-><c- o>::</c-><c- n>sink</c-><c- o>&lt;</c-><c- n>std</c-><c- o>::</c-><c- n>unique_ptr</c-><c- o>&lt;</c-><c- b>int</c-><c- o>>></c-><c- p>;</c->
<c- n>func</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>make_unique</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-><c- p>(</c-><c- mi>0</c-><c- p>));</c-> <c- c1>// leak</c->
</pre>
   <p>We don’t want users to decompose types that were never designed to support
decomposition. Ideally, a decomposing function should be defined for the same
source object type it is declared in (i.e. the explicit <code class="highlight"><c- k>this</c-></code> parameter type should
match the class-type which the function is a member of).
However we feel this is too
restrictive, especially when considering template code and the CRTP pattern.</p>
   <p>Hence we require the source object type to be the same as or to inherit from
the class-type the decomposing function is a member of,
or else the definition of the decomposing function is ill-formed.</p>
   <h5 class="heading settled" data-level="5.6.3.2" id="decomposing-func-accessibility"><span class="secno">5.6.3.2. </span><span class="content">Accessibility</span><a class="self-link" href="#decomposing-func-accessibility"></a></h5>
   <p>Let’s imagine for a moment that the source object has inaccessible subobjects
from the context of the decomposing function.</p>
   <p>Upon entering the function, all subobjects are promoted to complete objects.
As we don’t want to break accessibility rules, we may forbid access to the objects
that previously were inaccessible subobjects.</p>
   <p>However this is not necessary. If they are never accessed, then it means that
their destructor will be called when the function exits. Calling the destructor
requires them to be accessible in the first place.</p>
   <p>Hence, we further mandate that all subobjects of the source object be accessible
from the context of the decomposing function.</p>
   <p>Note that this condition is fulfilled in the nominal case, where the decomposing
function is merely a member function of the source object, and hence is granted
access to all of its subobjects.</p>
   <h5 class="heading settled" data-level="5.6.3.3" id="decomposing-func-immovable"><span class="secno">5.6.3.3. </span><span class="content">ABI requirements</span><a class="self-link" href="#decomposing-func-immovable"></a></h5>
   <p>The decomposing trait does not appear in the function declaration, and as such
a decomposing function does not have any specific ABI. In particular it shares
the same ABI as any explicit <code class="highlight"><c- k>this</c-></code> member function where the <code class="highlight"><c- k>this</c-></code> paramater is
passed by value.</p>
   <p>Some ABIs may not natively be compatible with decomposing functions, especially
if the ABI specifies that the destruction of the source object happens at the
call site and not in the decomposing function.</p>
   <p>To support such cases, we need to allow implementors to silently and transparently
make a temporary copy of the source object, and pass that temporary copy
to the decomposing function (see <a href="#decomposing-func-abi">§ 5.7.3 Decomposing functions</a>).</p>
   <p>This requires the source object to have at least one of the copy, move or
relocation constructor.</p>
   <p>Note that, for regular functions, function parameters passed by value can only
be passed to <code class="highlight"><c- n>reloc</c-></code> if they provide at least one of the three constructors.
This requirement follows the same spirit.</p>
   <h5 class="heading settled" data-level="5.6.3.4" id="decomposing-func-ill-formedness-criteria"><span class="secno">5.6.3.4. </span><span class="content">Ill-formedness criteria</span><a class="self-link" href="#decomposing-func-ill-formedness-criteria"></a></h5>
   <p>Now that we have seen motivating cases, let us summarize the ill-formedness
criteria for a decomposing function.
Let a decomposing function be defined in a class-type <code class="highlight"><c- n>T</c-></code>, which takes
an explicit <code class="highlight"><c- k>this</c-></code> parameter (the source object) of type <code class="highlight"><c- n>S</c-></code>.
The definition is ill-formed if:</p>
   <ul>
    <li data-md>
     <p>the explicit <code class="highlight"><c- k>this</c-></code> parameter is not passed by value and is named <code class="highlight"><c- n>reloc</c-></code> ;</p>
    <li data-md>
     <p>or the decomposing function is not a member function ;</p>
    <li data-md>
     <p>or <code class="highlight"><c- n>S</c-></code> has any inaccessible subobjects with regards to the decomposing
function ;</p>
    <li data-md>
     <p>or <code class="highlight"><c- n>S</c-></code> is not the same as <code class="highlight"><c- n>T</c-></code>, and does not derive from <code class="highlight"><c- n>T</c-></code> ;</p>
    <li data-md>
     <p>or <code class="highlight"><c- n>S</c-></code> has no accessible relocation constructor, no accessible move
constructor and no accessible copy constructor (none of the three).</p>
   </ul>
   <h4 class="heading settled" data-level="5.6.4" id="decomposing-lambda"><span class="secno">5.6.4. </span><span class="content">Decomposing lambda</span><a class="self-link" href="#decomposing-lambda"></a></h4>
   <p>A decomposing lambda is a lambda function that takes an explicit <code class="highlight"><c- k>this</c-></code> parameter by value and whose name is <code class="highlight"><c- n>reloc</c-></code>.</p>
   <p>As for decomposing functions, a decomposing lambda is ill-formed if:</p>
   <ul>
    <li data-md>
     <p>the type of the <code class="highlight"><c- k>this</c-></code> parameter is not passed by value ;</p>
    <li data-md>
     <p>or the parameter type is not the same as, or does not derive from
the type of the lambda (see <a href="#decomposing-func-aberrations">§ 5.6.3.1 Aberrations</a>) ;</p>
    <li data-md>
     <p>or the parameter type has no relocation, move and copy constructors
(none of the three).</p>
   </ul>
   <p>A decomposing lambda acts as a decomposing function: when called, before the
lambda body is entered, all the lambda captures are considered as distinct
complete objects. As such, the lambda captures can be relocated.</p>
<pre class="language-c++ highlight"><c- b>void</c-> <c- nf>foo</c-><c- p>(</c-><c- n>reloc_only_t</c-><c- p>);</c->

<c- n>reloc_only_t</c-> <c- n>var</c-><c- p>;</c->
<c- k>auto</c-> <c- n>func</c-> <c- o>=</c-> <c- p>[</c-><c- n>v</c-> <c- o>=</c-> <c- n>reloc</c-> <c- n>var</c-><c- p>](</c-><c- n>this</c-> <c- k>auto</c-> <c- n>reloc</c-><c- p>)</c->
<c- p>{</c->
    <c- n>foo</c-><c- p>(</c-><c- n>reloc</c-> <c- n>v</c-><c- p>);</c->
<c- p>};</c->
<c- p>(</c-><c- n>reloc</c-> <c- n>func</c-><c- p>)();</c-> <c- c1>// well-formed</c->
</pre>
   <h3 class="heading settled" data-level="5.7" id="abi"><span class="secno">5.7. </span><span class="content">ABI changes</span><a class="self-link" href="#abi"></a></h3>
   <p>As noted above (<a href="#unowned-parameter">§ 3.3 Unowned parameter</a>), some platforms have a <em>caller-destroy</em> ABI
where the <em>calling</em> function expects to destroy nontrivial parameters passed by
value. This poses a problem for functions that wish to relocate from such
parameters, and a potential ABI break.</p>
   <h4 class="heading settled" data-level="5.7.1" id="callee-destroy-abi"><span class="secno">5.7.1. </span><span class="content">relocate-only function parameters</span><a class="self-link" href="#callee-destroy-abi"></a></h4>
   <p>We propose the following requirement on functions:
if a function takes a parameter by value, whose type is relocate-only, then
the function is responsible for the destruction of that parameter.</p>
   <p>A relocate-only type is a type that declares a non-deleted relocation constructor,
the move and copy constructors being not declared, or declared as deleted.
This requirement is essential to fully support relocate-only types in the language.</p>
   <p>This requirement <em>might</em> introduce an ABI break. As of today, there are no relocate-only
types, so no ABI should break. In the proposed library changes, we do not 
make any existing type relocate-only, especially for that concern.
However we do add a relocation constructor on many classes, alongside their 
existing copy and move constructors. In doing so, 
some of them may become relocate-only, should their copy and move constructors
be deleted (for instance <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>optional</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code> with <code class="highlight"><c- n>T</c-></code> being relocate-only).</p>
   <p>One example is a function with signature: <code class="highlight"><c- b>void</c-> <c- nf>foo</c-><c- p>(</c-><c- n>gsl</c-><c- o>::</c-><c- n>non_null</c-><c- o>&lt;</c-><c- n>std</c-><c- o>::</c-><c- n>unique_ptr</c-><c- o>&lt;</c-><c- b>int</c-><c- o>>></c-><c- p>);</c-></code>.
We propose to add a relocation constructor to <code class="highlight"><c- n>unique_ptr</c-></code>, and GSL developers will
likely add a relocation constructor too. That makes <code class="highlight"><c- n>gsl</c-><c- o>::</c-><c- n>non_null</c-><c- o>&lt;</c-><c- n>std</c-><c- o>::</c-><c- n>unique_ptr</c-><c- o>&lt;</c-><c- b>int</c-><c- o>>></c-></code> relocate-only, while it wasn’t before, and may cause a potential ABI break.</p>
   <p>There is zero value of passing a <code class="highlight"><c- n>gsl</c-><c- o>::</c-><c- n>non_null</c-><c- o>&lt;</c-><c- n>std</c-><c- o>::</c-><c- n>unique_ptr</c-><c- o>></c-></code> by value
to a function today, so we doubt anyone would write such a function.
However those functions might theoritically exist, and might have an ABI change.</p>
   <p>Also, library vendors are encouraged to migrate to an ABI where any function that
takes non-trivial parameters by value are responsible for their destruction.
Then, the function definition can make the most of <code class="highlight"><c- n>reloc</c-></code>.
This is not required by the proposal.</p>
   <p>We believe it’s up to the implementation to choose what they want to do with their ABI:</p>
   <ul>
    <li data-md>
     <p><em>full break</em>, use callee-destroy or equivalent for all non-trivial relocatable types
passed by value (for those who don’t care about ABI) ;</p>
    <li data-md>
     <p><em>break with opt-out</em>: a relocation constructor attribute to opt-out of the ABI
break on functions where it is passed be value. 
This solution should also provide propagation mechanisms suitable for composition 
(these could be standardized at a later date) ;</p>
    <li data-md>
     <p><em>likely no break, but opt-in</em>: an improved <code class="highlight"><c- p>[[</c-><c- n>trivial_abi</c-><c- p>]]</c-></code> that actually checks that
the type is trivially relocatable ;</p>
    <li data-md>
     <p><em>likely no break</em>: use callee-destroy only for relocate-only types ;</p>
    <li data-md>
     <p>and those that are callee-destroy already don’t need to do anything!</p>
   </ul>
   <p>In all cases the following mitigation and migration techniques could be employed:</p>
   <ul>
    <li data-md>
     <p>functions that have an ABI change could be mangled differently. This makes
ABI breakage detectable ;</p>
    <li data-md>
     <p>for such functions, up to two symbols are emitted, where the old
symbol is emitted only if the function does not in actual fact relocate from 
its parameters, in which case the new symbol is emitted, and its implementation 
forwards to the old and then destructs its relocatable parameters on exit ;</p>
   </ul>
   <h4 class="heading settled" data-level="5.7.2" id="prvalue-assign-op-abi"><span class="secno">5.7.2. </span><span class="content">prvalue assignment operator</span><a class="self-link" href="#prvalue-assign-op-abi"></a></h4>
   <p>As mentioned above, if the class-type is relocate-only, then it may have an
impact on existing prvalue-assignment operators (like it does to any function).
However this change is purely opt-in. If there is an existing prvalue-assignment 
operator in a class, then it will prevent the implicit declaration of the 
relocation constructor, which will in turn prevent from the potential ABI break.</p>
   <p>Also, the relocation assignment operator may be aliased.
If aliasing occurs, then the ABI does not break as aliasing happens only on a 
new hidden function.</p>
   <p>The only scenario where the ABI might break is where:</p>
   <ul>
    <li data-md>
     <p>aliasing happened on declaration level ;</p>
    <li data-md>
     <p>code was compiled against it, and especially generated code that makes direct
calls to the aliased version ;</p>
    <li data-md>
     <p>the class changes, the aliasing only happens at definition level, or does not happen at all.</p>
   </ul>
   <p>This may introduce an ABI break, detectable at link-time (aliased symbols missing):</p>
   <ul>
    <li data-md>
     <p>if the aliasing now happens at definition level, but the aliased operator symbol
remains visible nonetheless, then no ABI breaks are introduced ;</p>
    <li data-md>
     <p>otherwise the ABI break happens, but remains detectable at link-time.</p>
   </ul>
   <h4 class="heading settled" data-level="5.7.3" id="decomposing-func-abi"><span class="secno">5.7.3. </span><span class="content">Decomposing functions</span><a class="self-link" href="#decomposing-func-abi"></a></h4>
   <p>A decomposing function has an extra ABI requirement: the function must be in
charge of the lifetime of its explicit <code class="highlight"><c- k>this</c-></code> parameter. How this requirement is
satisfied is up to compiler vendors.</p>
   <p>Some tricks are possible for ABIs that do not natively meet this requirement.
An attractive solution is to proceed as with the relocation assignment operator;
when a decomposing function is defined, two functions are emitted:</p>
   <ul>
    <li data-md>
     <p>an eliding one: this function takes the explicit <code class="highlight"><c- k>this</c-></code> parameter as if by reference
and is in charge of its lifetime. Its body is the body of the decomposing
function provided by the user.</p>
    <li data-md>
     <p>a non-eliding one:</p>
     <ul>
      <li data-md>
       <p>If the explicit <code class="highlight"><c- k>this</c-></code> parameter is not an <em>unowned parameter</em>, then it simply calls
the eliding one, passing the <code class="highlight"><c- k>this</c-></code> parameter object as if by reference.</p>
      <li data-md>
       <p>Otherwise it makes a temporary copy of the source object, and calls the
eliding one, passing the copy as if by reference. Upon function exit,
the destructor of the copy is not called as its lifetime already ended
when it was passed the eliding function.</p>
      <li data-md>
       <p>In all cases, it forwards as return value whatever the decomposing function
returns.</p>
     </ul>
   </ul>
   <p>The attentive reader will have noticed that a program with a decomposing function
is ill-formed if the class-type does not provide a relocation, move or copy
constructor. Hence, the non-eliding function is able to perform a copy if necessary
without adding extra requirements on the class-type.</p>
   <h2 class="heading settled" data-level="6" id="proposed-lib-changes"><span class="secno">6. </span><span class="content">Proposed library changes</span><a class="self-link" href="#proposed-lib-changes"></a></h2>
   <h3 class="heading settled" data-level="6.1" id="std-mem-header"><span class="secno">6.1. </span><span class="content">Memory header</span><a class="self-link" href="#std-mem-header"></a></h3>
   <h4 class="heading settled" data-level="6.1.1" id="std-construct_at"><span class="secno">6.1.1. </span><span class="content">std::construct_at</span><a class="self-link" href="#std-construct_at"></a></h4>
   <p>We propose to add the following overload to <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>construct_at</c-></code>:</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>constexpr</c-> <c- n>T</c-><c- o>*</c-> <c- n>construct_at</c-><c- p>(</c-> <c- n>T</c-><c- o>*</c-> <c- n>p</c-><c- p>,</c-> <c- n>T</c-> <c- n>src</c-> <c- p>);</c->
</pre>
   <p>Which would be equivalent to <code class="highlight"><c- o>::</c-><c- k>new</c-> <c- p>(</c-><c- n>p</c-><c- p>)</c-> <c- n>T</c-><c- p>{</c-><c- n>reloc</c-> <c- n>src</c-><c- p>}</c-></code>, except that it may be
used in constant expression evaluations.</p>
   <p class="note" role="note"><span class="marker">Note:</span> this overload would be unnecessary if the <a href="#future-capture-value">§ 7.3.1 More perfect forwarding</a> direction were to be adopted; instead the existing signature should be
altered to use the <code class="highlight"><c- k>decltype</c-><c- p>(</c-><c- k>auto</c-><c- p>)</c-></code> placeholder.</p>
   <h4 class="heading settled" data-level="6.1.2" id="std-destroy_relocate"><span class="secno">6.1.2. </span><span class="content">std::destroy_relocate</span><a class="self-link" href="#std-destroy_relocate"></a></h4>
   <p>We propose to add the following function in the <code class="highlight"><c- n>std</c-></code> namespace in the <code class="highlight"><c- n>memory</c-></code> header to perform relocation through a pointer:</p>
<pre class="language-c++ highlight"><c- n>template</c-> <c- o>&lt;</c-><c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>destroy_relocate</c-><c- p>(</c-><c- n>T</c-><c- o>*</c-> <c- n>src</c-><c- p>);</c->
</pre>
   <p>The function constructs a new object by calling either the relocation constructor,
the move constructor, 
or the copy constructor (in that order of preference), 
using <code class="highlight"><c- o>*</c-><c- n>src</c-></code> as parameter while ignoring its cv-qualifiers:</p>
   <ul>
    <li data-md>
     <p>If the move or copy constructor is called then the destructor of <code class="highlight"><c- o>*</c-><c- n>src</c-></code> is called
afterwards ;</p>
    <li data-md>
     <p>Likewise, if the move or copy constructor throws, then the destructor of <code class="highlight"><c- o>*</c-><c- n>src</c-></code> is called as well.</p>
   </ul>
   <p>The function returns the constructed value. Its definition is implementation-defined.</p>
   <p>This function is intended to be used by library authors, to enable relocation
from a memory address. For instance, extracting a value out of an optional just 
becomes:</p>
<pre class="language-c++ highlight"><c- n>T</c-> <c- n>optional</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>::</c-><c- n>extract</c-><c- p>()</c->
<c- p>{</c->
    <c- n>_has_value</c-> <c- o>=</c-> false<c- p>;</c->
    <c- k>return</c-> <c- n>std</c-><c- o>::</c-><c- n>destroy_relocate</c-><c- p>(</c-><c- n>_value_addr</c-><c- p>());</c-> 
    <c- c1>// _value_addr() being a private function returning the address of the owned value</c->
<c- p>}</c->
</pre>
   <p>This function is not intended to be used on local objects:</p>
<pre class="language-c++ highlight"><c- b>void</c-> <c- nf>foo</c-><c- p>()</c->
<c- p>{</c->
    <c- k>const</c-> <c- n>T</c-> <c- n>val</c-><c- p>;</c->
    <c- n>bar</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>destroy_relocate</c-><c- p>(</c-><c- o>&amp;</c-><c- n>val</c-><c- p>));</c-> <c- d>/* BAD, val destructor is called at the </c->
<c- d>        end of its scope while it is already destructed!*/</c->
<c- p>}</c->
</pre>
   <p>This what motivates the name of the function. Although relocation is always a
destructive operation, the name serves as a reminder to the developers.</p>
   <h4 class="heading settled" data-level="6.1.3" id="std-uninitialized_relocate"><span class="secno">6.1.3. </span><span class="content">std::uninitialized_relocate</span><a class="self-link" href="#std-uninitialized_relocate"></a></h4>
   <p>We propose to introduce the following new functions in the <code class="highlight"><c- n>std</c-></code> namespace in
the <code class="highlight"><c- n>memory</c-></code> header:</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>InputIt</c-><c- p>,</c-> <c- n>class</c-> <c- n>ForwardIt</c-><c- o>></c->
<c- n>ForwardIt</c-> <c- n>uninitialized_relocate</c-><c- p>(</c-><c- n>InputIt</c-> <c- n>first</c-><c- p>,</c-> <c- n>InputIt</c-> <c- n>last</c-><c- p>,</c-> <c- n>ForwardIt</c-> <c- n>d_first</c-><c- p>);</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c-> <c- n>class</c-> <c- n>InputIt</c-><c- p>,</c-> <c- n>class</c-> <c- n>ForwardIt</c-><c- o>></c->
<c- n>ForwardIt</c-> <c- n>uninitialized_relocate</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>policy</c-><c- p>,</c-> <c- n>InputIt</c-> <c- n>first</c-><c- p>,</c-> <c- n>InputIt</c-> <c- n>last</c-><c- p>,</c->
	<c- n>ForwardIt</c-> <c- n>d_first</c-><c- p>)</c-> <c- p>;</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>InputIt</c-><c- p>,</c-> <c- n>class</c-> <c- n>Size</c-><c- p>,</c-> <c- n>class</c-> <c- n>ForwardIt</c-><c- o>></c->
<c- n>pair</c-><c- o>&lt;</c-><c- n>InputIt</c-><c- p>,</c-> <c- n>ForwardIt</c-><c- o>></c-> <c- n>uninitialized_relocate_n</c-><c- p>(</c-><c- n>InputIt</c-> <c- n>first</c-><c- p>,</c-> <c- n>Size</c-> <c- n>count</c-><c- p>,</c->
	<c- n>ForwardIt</c-> <c- n>d_first</c-><c- p>)</c-> <c- p>;</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c-> <c- n>class</c-> <c- n>InputIt</c-><c- p>,</c-> <c- n>class</c-> <c- n>Size</c-><c- p>,</c-> <c- n>class</c-> <c- n>ForwardIt</c-><c- o>></c->
<c- n>pair</c-><c- o>&lt;</c-><c- n>InputIt</c-><c- p>,</c-> <c- n>ForwardIt</c-><c- o>></c-> <c- n>uninitialized_relocate_n</c-><c- p>(</c->
	<c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>policy</c-><c- p>,</c-> <c- n>InputIt</c-> <c- n>first</c-><c- p>,</c-> <c- n>Size</c-> <c- n>count</c-><c- p>,</c-> <c- n>ForwardIt</c-> <c- n>d_first</c-><c- p>);</c->
</pre>
   <p>Those relocate elements from the range <code class="highlight"><c- p>[</c-><c- n>first</c-><c- p>,</c-> <c- n>last</c-><c- p>)</c-></code> (or the first <code class="highlight"><c- n>count</c-></code> elements from <code class="highlight"><c- n>first</c-></code>) to an uninitialized memory area beginning at <code class="highlight"><c- n>d_first</c-></code>. 
Elements in the source range will be destructed at the end of the function 
(even if an exception is thrown).</p>
   <p>Returns:</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>uninitialized_relocate</c-></code>: an iterator to the element past the last element relocated;</p>
    <li data-md>
     <p><code class="highlight"><c- n>uninitialized_relocate_n</c-></code>: a pair whose first element is an iterator to the
element past the last element relocated in the source range, and whose second 
element is an iterator to the element past the last element relocated in the 
destination range.</p>
   </ul>
   <p>If the type to relocate is trivially relocatable and both iterator types are
contiguous, then both functions can be implemented as single <code class="highlight"><c- n>memcpy</c-></code> call over 
the entire source range.
Otherwise relocation happens element-wise, as if by calling <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>destroy_relocate</c-></code> on each element.</p>
   <p>If an exception is thrown by <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>destroy_relocate</c-></code>, then the destructor of all
remaining elements in the source range is called, as well as the destructor of
all constructed objects in the output iterator.</p>
   <h3 class="heading settled" data-level="6.2" id="std-utility-header"><span class="secno">6.2. </span><span class="content">Utility header</span><a class="self-link" href="#std-utility-header"></a></h3>
   <h4 class="heading settled" data-level="6.2.1" id="std-relocate"><span class="secno">6.2.1. </span><span class="content">std::relocate</span><a class="self-link" href="#std-relocate"></a></h4>
   <p>We propose to add the following tag type in the <code class="highlight"><c- n>std</c-></code> namespace in the <code class="highlight"><c- n>utility</c-></code> header (mainly useful with templates):</p>
<pre class="language-cpp highlight"><c- k>namespace</c-> <c- nn>std</c->
<c- p>{</c->
<c- c1>// tag type to indicate that the parameters are passed by value</c->
<c- k>struct</c-> <c- nc>relocate_t</c-> <c- p>{};</c->
<c- kr>inline</c-> <c- k>constexpr</c-> <c- n>relocate_t</c-> <c- n>relocate</c-> <c- o>=</c-> <c- p>{};</c->
<c- p>}</c->
</pre>
   <p class="note" role="note"><span class="marker">Note:</span> this facility would be unnecessary if the <a href="#future-capture-value">§ 7.3.1 More perfect forwarding</a> direction were to be adopted; instead the existing signatures should be
altered to use the <code class="highlight"><c- k>decltype</c-><c- p>(</c-><c- k>auto</c-><c- p>)</c-></code> placeholder.</p>
   <h3 class="heading settled" data-level="6.3" id="stl-relocate-only"><span class="secno">6.3. </span><span class="content">Bring relocate-only type support to the STL</span><a class="self-link" href="#stl-relocate-only"></a></h3>
   <h4 class="heading settled" data-level="6.3.1" id="std-pair-tuple"><span class="secno">6.3.1. </span><span class="content">std::pair and std::tuple</span><a class="self-link" href="#std-pair-tuple"></a></h4>
   <p>We propose to add a default relocation constructor and a default relocation
assignment operator to <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>pair</c-></code> and <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>tuple</c-></code>.</p>
   <p>We also porpose to add the following functions:</p>
<pre class="language-c++ highlight"><c- n>template</c-> <c- o>&lt;</c-><c- n>class</c-> <c- n>T1</c-><c- p>,</c-> <c- n>class</c-> <c- n>T2</c-><c- o>></c->
<c- n>pair</c-><c- o>&lt;</c-><c- n>T1</c-><c- p>,</c-> <c- n>T2</c-><c- o>>::</c-><c- n>pair</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>relocate_t</c-><c- p>,</c-> <c- n>T1</c-><c- p>,</c-> <c- n>T2</c-><c- p>);</c-> <c- c1>// constructs by relocation</c->

<c- n>template</c-> <c- o>&lt;</c-><c- n>class</c-><c- p>...</c-> <c- n>Types</c-><c- o>></c->
<c- n>tuple</c-><c- o>&lt;</c-><c- n>Types</c-><c- p>...</c-><c- o>>::</c-><c- n>tuple</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>relocate_t</c-><c- p>,</c-> <c- n>Types</c-><c- p>...);</c-> <c- c1>// constructs by relocation</c->

<c- n>template</c-> <c- o>&lt;</c-><c- n>class</c-><c- p>...</c-> <c- n>Types</c-><c- o>></c->
<c- n>template</c-> <c- o>&lt;</c-><c- n>class</c-> <c- n>U1</c-><c- p>,</c-> <c- n>class</c-> <c- n>U2</c-><c- o>></c->
<c- n>tuple</c-><c- o>&lt;</c-><c- n>Types</c-><c- p>...</c-><c- o>>::</c-><c- n>tuple</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>pair</c-><c- o>&lt;</c-><c- n>U1</c-><c- p>,</c-> <c- n>U2</c-><c- o>></c-><c- p>);</c-> <c- c1>// constructs by relocation</c->
</pre>
   <p>Note that we do not introduce extra template parameters for type arguments, as
relocation can only happen from matching types.</p>
   <h4 class="heading settled" data-level="6.3.2" id="std-optional"><span class="secno">6.3.2. </span><span class="content">std::optional</span><a class="self-link" href="#std-optional"></a></h4>
   <p>We propose to add the following functions to <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>optional</c-></code>:</p>
<pre class="language-c++ highlight"><c- c1>// relocation constructor</c->
<c- n>template</c-> <c- o>&lt;</c-><c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>optional</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>::</c-><c- n>optional</c-><c- p>(</c-><c- n>optional</c-><c- p>);</c->

<c- c1>// relocation assignment operator</c->
<c- n>template</c-> <c- o>&lt;</c-><c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>optional</c-><c- o>&amp;</c-> <c- n>optional</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>::</c-><c- n>operator</c-><c- o>=</c-><c- p>(</c-><c- n>optional</c-><c- p>);</c->

<c- c1>// Converting constructor</c->
<c- n>template</c-> <c- o>&lt;</c-><c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>optional</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>::</c-><c- n>optional</c-><c- p>(</c-><c- n>T</c-> <c- n>val</c-><c- p>);</c->

<c- c1>// Converting assignment</c->
<c- n>template</c-> <c- o>&lt;</c-><c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>optional</c-><c- o>&amp;</c-> <c- n>optional</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>::</c-><c- n>operator</c-><c- o>=</c-><c- p>(</c-><c- n>T</c-> <c- n>val</c-><c- p>);</c->

<c- d>/**</c->
<c- d> * \brief Extracts the contained value from the optional</c->
<c- d> *</c->
<c- d> * The returned value is relocated from the contained value.</c->
<c- d> *</c->
<c- d> * After this call the optional no longer contains any value.</c->
<c- d> *</c->
<c- d> * \throws std::bad_optional_access if the optional did not contain any value.</c->
<c- d> */</c->
<c- n>template</c-> <c- o>&lt;</c-><c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>optional</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>::</c-><c- n>extract</c-><c- p>();</c->
</pre>
   <h4 class="heading settled" data-level="6.3.3" id="std-variant"><span class="secno">6.3.3. </span><span class="content">std::variant</span><a class="self-link" href="#std-variant"></a></h4>
<pre class="language-c++ highlight"><c- c1>// relocation constructor</c->
<c- n>template</c-> <c- o>&lt;</c-><c- n>class</c-><c- p>...</c-> <c- n>Types</c-><c- o>></c->
<c- n>variant</c-><c- o>&lt;</c-><c- n>Types</c-><c- p>...</c-><c- o>>::</c-><c- n>variant</c-><c- p>(</c-><c- n>variant</c-><c- p>);</c->

<c- c1>// relocation assignment operator</c->
<c- n>template</c-> <c- o>&lt;</c-><c- n>class</c-><c- p>...</c-> <c- n>Types</c-><c- o>></c->
<c- n>variant</c-><c- o>&amp;</c-> <c- n>variant</c-><c- o>&lt;</c-><c- n>Types</c-><c- p>...</c-><c- o>>::</c-><c- n>operator</c-><c- o>=</c-><c- p>(</c-><c- n>variant</c-><c- p>);</c->

<c- c1>// Converting constructor</c->
<c- n>template</c-> <c- o>&lt;</c-><c- n>class</c-><c- p>...</c-> <c- n>Types</c-><c- o>></c->
<c- n>template</c-> <c- o>&lt;</c-><c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>constexpr</c-> <c- n>variant</c-><c- o>&lt;</c-><c- n>Types</c-><c- p>...</c-><c- o>>::</c-><c- n>variant</c-><c- p>(</c-><c- n>T</c-> <c- n>val</c-><c- p>);</c->

<c- c1>// Converting assignment</c->
<c- n>template</c-> <c- o>&lt;</c-><c- n>class</c-><c- p>...</c-> <c- n>Types</c-><c- o>></c->
<c- n>template</c-> <c- o>&lt;</c-><c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>variant</c-><c- o>&amp;</c-> <c- n>variant</c-><c- o>&lt;</c-><c- n>Types</c-><c- p>...</c-><c- o>>::</c-><c- n>operator</c-><c- o>=</c-><c- p>(</c-><c- n>T</c-><c- p>);</c->
</pre>
   <h4 class="heading settled" data-level="6.3.4" id="std-any"><span class="secno">6.3.4. </span><span class="content">std::any</span><a class="self-link" href="#std-any"></a></h4>
<pre class="language-c++ highlight"><c- c1>// relocation constructor</c->
<c- n>any</c-><c- o>::</c-><c- n>any</c-><c- p>(</c-><c- n>any</c-><c- p>);</c->

<c- c1>// relocation assignment operator</c->
<c- n>any</c-><c- o>&amp;</c-> <c- n>any</c-><c- o>::</c-><c- n>operator</c-><c- o>=</c-><c- p>(</c-><c- n>any</c-><c- p>);</c->

<c- c1>// Converting constructor</c->
<c- n>template</c-> <c- o>&lt;</c-><c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>any</c-><c- o>::</c-><c- n>any</c-><c- p>(</c-><c- n>T</c-><c- p>);</c->

<c- c1>// Converting assignment</c->
<c- n>template</c-> <c- o>&lt;</c-><c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>any</c-><c- o>&amp;</c-> <c- n>any</c-><c- o>::</c-><c- n>operator</c-><c- o>=</c-><c- p>(</c-><c- n>T</c-><c- p>);</c->
</pre>
   <h3 class="heading settled" data-level="6.4" id="lib-change-containers"><span class="secno">6.4. </span><span class="content">Containers</span><a class="self-link" href="#lib-change-containers"></a></h3>
   <p>All containers must provide a relocation constructor and a
relocation assignment operator.</p>
   <p>Also, in order to fully support relocate-only types, containers should provide
a way to insert and remove elements by relocation.</p>
   <h4 class="heading settled" data-level="6.4.1" id="lib-insertion-overloads"><span class="secno">6.4.1. </span><span class="content">Insertion overloads</span><a class="self-link" href="#lib-insertion-overloads"></a></h4>
   <p>Existing APIs cannot fulfill this need. They all take the element
to insert as a reference parameter, while relocation requires to pass elements
by value.</p>
   <p>As such we suggest adding overloads to all insertion functions, where the
element to insert is passed by value.</p>
   <h4 class="heading settled" data-level="6.4.2" id="lib-extract-functions"><span class="secno">6.4.2. </span><span class="content">Extracting functions</span><a class="self-link" href="#lib-extract-functions"></a></h4>
   <p>The STL does not provide any function to erase an element
from a container and return it as return value.</p>
   <p>Consider a container of relocate-only types. If an element of that container is to be
"moved out" of it, it could only happen through relocation as it is
the only operation supported by the type. Hence the relocated element must
necessarily be simultaneously erased from the container as its lifetime ended.</p>
   <p>This is why we propose to add various "value-extracting" functions to existing
containers, which erase an element and return it. Those functions are overloads
over existing <code class="highlight"><c- n>pop</c-><c- o>*</c-><c- p>()</c-></code> and <code class="highlight"><c- n>erase</c-><c- p>()</c-></code> functions, but they take the <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>relocate_t</c-></code> <a href="#std-relocate">tag type</a> as first parameter. The return value will be constructed by
relocation (likely thanks to <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>destroy_relocate</c-></code>).</p>
   <p>All extracting functions will operate the same way. First, the return value is constructed
as if by <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>destroy_relocate</c-></code> from the container element. Second, the container
adjusts its size and memory to effectively erase the contained element from
its internal data structures.</p>
   <p>If an exception is emitted during the first step, then the container proceeds
to erase its element nonetheless (as if in the second step) and then propagates
the exception.
If an exception is emitted during the second step
(regardless of whether the second step was triggered normally of by an exception
caught during the first step), then <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>terminate</c-></code> is called.</p>
   <h4 class="heading settled" data-level="6.4.3" id="lib-relocate_out"><span class="secno">6.4.3. </span><span class="content">relocate_out</span><a class="self-link" href="#lib-relocate_out"></a></h4>
   <p>We further propose to add a <code class="highlight"><c- n>relocate_out</c-></code> function to some containers. <code class="highlight"><c- n>relocate_out</c-></code> takes three iterators as parameters. The first two iterators
belong to the container and define the range to relocate. The last parameter
is an output iterator where the relocated elements will be constructed.
This is similar the <code class="highlight"><c- n>erase</c-></code> functions that take a range of elements, except that
an extra output iterator is provided.
It returns a pair of iterators, whose first iterator is the next valid iterator
in the container (similar to what <code class="highlight"><c- n>erase</c-></code> returns), and whose second iterator
is the output iterator, past the last element copied (similar to what <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>copy</c-></code> returns).</p>
   <p><code class="highlight"><c- n>relocate_out</c-></code> is proposed to improve support of relocate-only types. Without this,
it would not be possible to move a range of relocate-only elements from one container to
another, without writing complex and inefficient loops calling some value-extracting
function at each iteration.</p>
   <p>Note that there is less need for a <code class="highlight"><c- n>relocate_in</c-></code> function as the <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>insert_iterator</c-></code> family will have an overload to enable relocation.</p>
   <p><code class="highlight"><c- n>relocate_out</c-></code> proceeds as follows:</p>
   <ol>
    <li data-md>
     <p>relocates the elements within range to the output iterator.
The elements within range inside the container are then in a <em>destructed state</em>.</p>
    <li data-md>
     <p>The destructed elements are removed from the container. How this is achieved
depends on the container. For instance <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>vector</c-></code> may call <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>uninitialized_relocate</c-></code> to move the trailing part of the container
in the destructed range, and simply reduce its size.</p>
   </ol>
   <p>If an exception leaks through the first step, then the second step is run
to erase from the container all the elements that are in a <em>destructed state</em> (i.e. those which got succesfully relocated plus the one responsible for the exception)
, and the exception is propagated.
If an exception is emitted during the second step
(regardless of whether the second step was triggered normally of by an exception
caught in the first step), then <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>terminate</c-></code> is called.</p>
   <h4 class="heading settled" data-level="6.4.4" id="std-vector"><span class="secno">6.4.4. </span><span class="content">std::vector</span><a class="self-link" href="#std-vector"></a></h4>
<pre class="language-cpp highlight"><c- c1>// pushes a value by relocation</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Alloc</c-><c- o>></c->
<c- k>constexpr</c-> <c- b>void</c-> <c- n>vector</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Alloc</c-><c- o>>::</c-><c- n>push_back</c-><c- p>(</c-><c- n>T</c-> <c- n>value</c-><c- p>);</c->

<c- c1>// inserts a value by relocation</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Alloc</c-><c- o>></c->
<c- n>iterator</c-> <c- n>vector</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Alloc</c-><c- o>>::</c-><c- n>insert</c-><c- p>(</c-><c- n>const_iterator</c-> <c- n>pos</c-><c- p>,</c-> <c- n>T</c-> <c- n>value</c-><c- p>);</c->

<c- c1>// removes the last item from the vector and returns it</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Alloc</c-><c- o>></c->
<c- n>T</c-> <c- n>vector</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Alloc</c-><c- o>>::</c-><c- n>pop_back</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>relocate_t</c-><c- p>);</c->

<c- c1>// removes the item from the vector and returns it with the next valid iterator</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Alloc</c-><c- o>></c->
<c- n>std</c-><c- o>::</c-><c- n>pair</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>iterator</c-><c- o>></c-> <c- n>vector</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Alloc</c-><c- o>>::</c-><c- n>erase</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>relocate_t</c-><c- p>,</c-> <c- n>const_iterator</c-> <c- n>pos</c-><c- p>);</c->

<c- c1>// relocates items in [from, to[ into out, </c->
<c- c1>// as if by doing iteratively: *out++ = std::destroy_relocate(&amp;*src++);</c->
<c- c1>// items within range are removed from *this.</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Alloc</c-><c- o>></c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>OutputIterator</c-><c- o>></c->
<c- n>std</c-><c- o>::</c-><c- n>pair</c-><c- o>&lt;</c-><c- n>iterator</c-><c- p>,</c-> <c- n>OutputIterator</c-><c- o>></c-> <c- n>vector</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Alloc</c-><c- o>>::</c-><c- n>relocate_out</c-><c- p>(</c->
	<c- n>const_iterator</c-> <c- n>from</c-><c- p>,</c-> <c- n>const_iterator</c-> <c- n>to</c-><c- p>,</c-> <c- n>OutputIterator</c-> <c- n>out</c-><c- p>);</c->
</pre>
   <h4 class="heading settled" data-level="6.4.5" id="std-deque"><span class="secno">6.4.5. </span><span class="content">std::deque</span><a class="self-link" href="#std-deque"></a></h4>
<pre class="language-cpp highlight"><c- c1>// pushes a value by relocation</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Alloc</c-><c- o>></c->
<c- k>constexpr</c-> <c- b>void</c-> <c- n>deque</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Alloc</c-><c- o>>::</c-><c- n>push_front</c-><c- p>(</c-><c- n>T</c-> <c- n>value</c-><c- p>);</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Alloc</c-><c- o>></c->
<c- k>constexpr</c-> <c- b>void</c-> <c- n>deque</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Alloc</c-><c- o>>::</c-><c- n>push_back</c-><c- p>(</c-><c- n>T</c-> <c- n>value</c-><c- p>);</c->

<c- c1>// inserts a value by relocation</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Alloc</c-><c- o>></c->
<c- n>iterator</c-> <c- n>deque</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Alloc</c-><c- o>>::</c-><c- n>insert</c-><c- p>(</c-><c- n>const_iterator</c-> <c- n>pos</c-><c- p>,</c-> <c- n>T</c-> <c- n>value</c-><c- p>);</c->

<c- c1>// removes the last item from the queue and returns it</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Alloc</c-><c- o>></c->
<c- n>T</c-> <c- n>deque</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Alloc</c-><c- o>>::</c-><c- n>pop_back</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>relocate_t</c-><c- p>);</c->
<c- c1>// removes the first item from the queue and returns it</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Alloc</c-><c- o>></c->
<c- n>T</c-> <c- n>deque</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Alloc</c-><c- o>>::</c-><c- n>pop_front</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>relocate_t</c-><c- p>);</c->
<c- c1>// removes the item from the queue and returns it with the next valid iterator</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Alloc</c-><c- o>></c->
<c- n>std</c-><c- o>::</c-><c- n>pair</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>iterator</c-><c- o>></c-> <c- n>deque</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Alloc</c-><c- o>>::</c-><c- n>erase</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>relocate_t</c-><c- p>,</c-> <c- n>const_iterator</c-> <c- n>pos</c-><c- p>);</c->

<c- c1>// relocates items in [from, to[ into out. </c->
<c- c1>// items within range are removed from *this.</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Alloc</c-><c- o>></c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>OutputIterator</c-><c- o>></c->
<c- n>std</c-><c- o>::</c-><c- n>pair</c-><c- o>&lt;</c-><c- n>iterator</c-><c- p>,</c-> <c- n>OutputIterator</c-><c- o>></c-> <c- n>deque</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Alloc</c-><c- o>>::</c-><c- n>relocate_out</c-><c- p>(</c->
	<c- n>const_iterator</c-> <c- n>from</c-><c- p>,</c-> <c- n>const_iterator</c-> <c- n>to</c-><c- p>,</c-> <c- n>OutputIterator</c-> <c- n>out</c-><c- p>);</c->
</pre>
   <h4 class="heading settled" data-level="6.4.6" id="std-list"><span class="secno">6.4.6. </span><span class="content">std::list</span><a class="self-link" href="#std-list"></a></h4>
<pre class="language-cpp highlight"><c- c1>// pushes a value by relocation</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Alloc</c-><c- o>></c->
<c- b>void</c-> <c- n>list</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Alloc</c-><c- o>>::</c-><c- n>push_front</c-><c- p>(</c-><c- n>T</c-> <c- n>value</c-><c- p>);</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Alloc</c-><c- o>></c->
<c- b>void</c-> <c- n>list</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Alloc</c-><c- o>>::</c-><c- n>push_back</c-><c- p>(</c-><c- n>T</c-> <c- n>value</c-><c- p>);</c->

<c- c1>// inserts a value by relocation</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Alloc</c-><c- o>></c->
<c- n>iterator</c-> <c- n>list</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Alloc</c-><c- o>>::</c-><c- n>insert</c-><c- p>(</c-><c- n>const_iterator</c-> <c- n>pos</c-><c- p>,</c-> <c- n>T</c-> <c- n>value</c-><c- p>);</c->

<c- c1>// removes the last item from the list and returns it</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Alloc</c-><c- o>></c->
<c- n>T</c-> <c- n>list</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Alloc</c-><c- o>>::</c-><c- n>pop_back</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>relocate_t</c-><c- p>);</c->
<c- c1>// removes the first item from the list and returns it</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Alloc</c-><c- o>></c->
<c- n>T</c-> <c- n>list</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Alloc</c-><c- o>>::</c-><c- n>pop_front</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>relocate_t</c-><c- p>);</c->
<c- c1>// removes the item from the list and returns it with the next valid iterator</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Alloc</c-><c- o>></c->
<c- n>std</c-><c- o>::</c-><c- n>pair</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>iterator</c-><c- o>></c-> <c- n>list</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Alloc</c-><c- o>>::</c-><c- n>erase</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>relocate_t</c-><c- p>,</c-> <c- n>const_iterator</c-> <c- n>pos</c-><c- p>);</c->

<c- c1>// relocates items in [from, to[ into out. </c->
<c- c1>// items within range are removed from *this.</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Alloc</c-><c- o>></c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>OutputIterator</c-><c- o>></c->
<c- n>std</c-><c- o>::</c-><c- n>pair</c-><c- o>&lt;</c-><c- n>iterator</c-><c- p>,</c-> <c- n>OutputIterator</c-><c- o>></c-> <c- n>list</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Alloc</c-><c- o>>::</c-><c- n>relocate_out</c-><c- p>(</c->
	<c- n>const_iterator</c-> <c- n>from</c-><c- p>,</c-> <c- n>const_iterator</c-> <c- n>to</c-><c- p>,</c-> <c- n>OutputIterator</c-> <c- n>out</c-><c- p>);</c->
</pre>
   <h4 class="heading settled" data-level="6.4.7" id="std-forward_list"><span class="secno">6.4.7. </span><span class="content">std::forward_list</span><a class="self-link" href="#std-forward_list"></a></h4>
<pre class="language-cpp highlight"><c- c1>// inserts a value by relocation</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Alloc</c-><c- o>></c->
<c- n>iterator</c-> <c- n>forward_list</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Alloc</c-><c- o>>::</c-><c- n>insert_after</c-><c- p>(</c-><c- n>const_iterator</c-> <c- n>pos</c-><c- p>,</c->
	<c- n>T</c-> <c- n>value</c-><c- p>);</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Alloc</c-><c- o>></c->
<c- b>void</c-> <c- n>forward_list</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Alloc</c-><c- o>>::</c-><c- n>push_front</c-><c- p>(</c-><c- n>T</c-> <c- n>value</c-><c- p>);</c->

<c- c1>// removes the first item from the list and returns it</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Alloc</c-><c- o>></c->
<c- n>T</c-> <c- n>forward_list</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Alloc</c-><c- o>>::</c-><c- n>pop_front</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>relocate_t</c-><c- p>);</c->
<c- c1>// removes the item after pos from the list and returns it with the iterator following pos</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Alloc</c-><c- o>></c->
<c- n>std</c-><c- o>::</c-><c- n>pair</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>iterator</c-><c- o>></c-> <c- n>forward_list</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Alloc</c-><c- o>>::</c-><c- n>erase_after</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>relocate_t</c-><c- p>,</c-> <c- n>const_iterator</c-> <c- n>pos</c-><c- p>);</c->

<c- c1>// relocates items in ]from, to[ into out. </c->
<c- c1>// items within range are removed from *this.</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Alloc</c-><c- o>></c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>OutputIterator</c-><c- o>></c->
<c- n>OutputIterator</c-> <c- n>forward_list</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Alloc</c-><c- o>>::</c-><c- n>relocate_after</c-><c- p>(</c->
	<c- n>const_iterator</c-> <c- n>from</c-><c- p>,</c-> <c- n>const_iterator</c-> <c- n>to</c-><c- p>,</c-> <c- n>OutputIterator</c-> <c- n>out</c-><c- p>);</c->
</pre>
   <h4 class="heading settled" data-level="6.4.8" id="std-set-and-map"><span class="secno">6.4.8. </span><span class="content">set and map containers</span><a class="self-link" href="#std-set-and-map"></a></h4>
<pre class="language-cpp highlight"><c- c1>// std::set, std::multiset, std::map, std::multimap,</c->
<c- c1>// std::flat_set, std::flat_multiset, std::flat_map, std::flat_multimap,</c->
<c- c1>// std::unordered_set, std::unordered_multiset, std::unordered_map</c->
<c- c1>// and std::unordered_multimap, all aliased as 'map':</c->
<c- n>std</c-><c- o>::</c-><c- n>pair</c-><c- o>&lt;</c-><c- n>iterator</c-><c- p>,</c-> <c- b>bool</c-><c- o>></c-> <c- n>map</c-><c- o>::</c-><c- n>insert</c-><c- p>(</c-><c- n>value_type</c-> <c- n>value</c-><c- p>);</c->
<c- n>iterator</c-> <c- nf>map::insert</c-><c- p>(</c-><c- n>const_iterator</c-> <c- n>hint</c-><c- p>,</c-> <c- n>value_type</c-> <c- n>value</c-><c- p>);</c->

<c- c1>// extract the stored value from the container</c->
<c- n>std</c-><c- o>::</c-><c- n>pair</c-><c- o>&lt;</c-><c- n>value_type</c-><c- p>,</c-> <c- n>iterator</c-><c- o>></c-> <c- n>map</c-><c- o>::</c-><c- n>erase</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>relocate_t</c-><c- p>,</c-> <c- n>const_iterator</c-> <c- n>position</c-><c- p>);</c->
</pre>
   <h4 class="heading settled" data-level="6.4.9" id="std-queues"><span class="secno">6.4.9. </span><span class="content">queues</span><a class="self-link" href="#std-queues"></a></h4>
<pre class="language-cpp highlight"><c- c1>// for std::stack, std::queue, std::priority_queue, aliased queue below:</c->
<c- b>void</c-> <c- nf>queue::push</c-><c- p>(</c-><c- n>T</c-> <c- n>value</c-><c- p>);</c->

<c- c1>// removes the next element from the queue, calling the appropriate pop function</c->
<c- c1>// on the underlying container with std::relocate as parameter</c->
<c- n>T</c-> <c- nf>queue::pop</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>relocate_t</c-><c- p>);</c->
</pre>
   <h4 class="heading settled" data-level="6.4.10" id="std-iterator"><span class="secno">6.4.10. </span><span class="content">Iterator library</span><a class="self-link" href="#std-iterator"></a></h4>
   <p>We propose to add the following overloads:</p>
<pre class="language-c++ highlight"><c- n>template</c-> <c- o>&lt;</c-><c- n>class</c-> <c- n>Container</c-><c- o>></c->
<c- n>back_insert_iterator</c-><c- o>&lt;</c-><c- n>Container</c-><c- o>>&amp;</c-> <c- n>operator</c-><c- o>=</c-><c- p>(</c-> <c- n>typename</c-> <c- n>Container</c-><c- o>::</c-><c- n>value_type</c-> <c- n>value</c-> <c- p>);</c->

<c- n>template</c-> <c- o>&lt;</c-><c- n>class</c-> <c- n>Container</c-><c- o>></c->
<c- n>front_insert_iterator</c-><c- o>&lt;</c-><c- n>Container</c-><c- o>>&amp;</c-> <c- n>operator</c-><c- o>=</c-><c- p>(</c-> <c- n>typename</c-> <c- n>Container</c-><c- o>::</c-><c- n>value_type</c-> <c- n>value</c-> <c- p>);</c->

<c- n>template</c-> <c- o>&lt;</c-><c- n>class</c-> <c- n>Container</c-><c- o>></c->
<c- n>insert_iterator</c-><c- o>&lt;</c-><c- n>Container</c-><c- o>>&amp;</c-> <c- n>operator</c-><c- o>=</c-><c- p>(</c-> <c- n>typename</c-> <c- n>Container</c-><c- o>::</c-><c- n>value_type</c-> <c- n>value</c-> <c- p>);</c->
</pre>
   <h4 class="heading settled" data-level="6.4.11" id="std-misc-classes"><span class="secno">6.4.11. </span><span class="content">Other STL classes</span><a class="self-link" href="#std-misc-classes"></a></h4>
   <p>We propose to add a relocation constructor and a relocation assignment operator
to all the following classes:</p>
   <ul>
    <li data-md>
     <p><strong>String library</strong>: <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>basic_string</c-></code> ;</p>
    <li data-md>
     <p><strong>Utility</strong>: <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>function</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>reference_wrapper</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>shared_ptr</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>weak_ptr</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>unique_ptr</c-></code> ;</p>
    <li data-md>
     <p><strong>Regular expression</strong>: <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>basic_regex</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>match_results</c-></code> ;</p>
    <li data-md>
     <p><strong>Thread support</strong>: <code class="highlight"><c- n>std</c-><c- o>::</c-><c- kr>thread</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>jthread</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>unique_lock</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>promise</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>future</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>shared_future</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>packaged_task</c-></code> ;</p>
    <li data-md>
     <p><strong>Filesystem</strong>: <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>filesystem</c-><c- o>::</c-><c- n>path</c-></code>.</p>
   </ul>
   <h2 class="heading settled" data-level="7" id="discuss"><span class="secno">7. </span><span class="content">Discussions</span><a class="self-link" href="#discuss"></a></h2>
   <h3 class="heading settled" data-level="7.1" id="reloc-new-keyword"><span class="secno">7.1. </span><span class="content">Why a new keyword?</span><a class="self-link" href="#reloc-new-keyword"></a></h3>
   <p>Alternatively, a new series of symbols could be used instead of introducing
a new keyword, like: <code class="highlight"><c- o>&lt;~&lt;</c-> <c- n>obj</c-></code> or <code class="highlight"><c- o>&amp;&lt;</c-> <c- n>obj</c-></code> in place of <code class="highlight"><c- n>reloc</c-> <c- n>obj</c-></code>.
However, we feel like <code class="highlight"><c- n>reloc</c-> <c- n>obj</c-></code> better conveys the intent, and has better 
readibility.</p>
   <p>The introduction of a new keyword may always break existing codebases. We had a
look at several well-known open source C++ projects to analyse what volume of code
would break if <code class="highlight"><c- n>reloc</c-></code> were a keyword.</p>
   <p>For each of the following repositories, we searched for the <code class="highlight"><c- n>reloc</c-></code> string,
at word boundaries, with case-sensitivity, in all C++ source files and headers
(<code class="highlight"><c- o>*</c-><c- p>.</c-><c- n>cc</c-></code>, <code class="highlight"><c- o>*</c-><c- p>.</c-><c- n>cpp</c-></code>, <code class="highlight"><c- o>*</c-><c- p>.</c-><c- n>cxx</c-></code>, <code class="highlight"><c- o>*</c-><c- p>.</c-><c- n>h</c-></code>, <code class="highlight"><c- o>*</c-><c- p>.</c-><c- n>hpp</c-></code>, <code class="highlight"><c- o>*</c-><c- p>.</c-><c- n>hh</c-></code>).
We manually discarded matches that
were not code (comments or strings). And we put that in perspective with the
total number of files, lines and words of the repository.</p>
   <ul>
    <li data-md>
     <p><a href="https://github.com/qt/qtbase">Qt</a>: 0 hits; files:  7,586 ; lines:  2,794,607 ;
words:  98,635,622; commit: 040b4a4b21b3</p>
    <li data-md>
     <p><a href="https://github.com/boostorg/boost">boost</a> (with all submodules): 0 hits;
files:  23,726 ; lines:  4,133,844 ; 
words:  180,808,943; commit: 86733163a3c6</p>
    <li data-md>
     <p><a href="https://github.com/godotengine/godot">godot</a>: 0 hits; files:  5,068 ;
lines:  2,545,299 ; 
words:  99,389,743; commit: b6e06038f8a3</p>
    <li data-md>
     <p><a href="https://github.com/abseil/abseil-cpp">abseil-cpp</a>: 0 hits; files:  766 ;
lines:  247,441 ; 
words:  9,028,820; commit: de6fca2110e7</p>
    <li data-md>
     <p><a href="https://github.com/facebook/folly">folly</a>: 0 hits; files:  1,861 ;
lines:  532,918 ; 
words:  16,669,085; commit: cde9d22e8614</p>
    <li data-md>
     <p><a href="https://github.com/llvm/llvm-project">llvm-project</a>: <strong>124 hits in 11 files</strong> (<code class="highlight"><c- n>reloc</c-></code> only used as local variable or 
data-member, counting all uses); files:  39,048 ; lines:  9,760,587 ; 
words:  385,429,611; commit: 9816c1912d56</p>
    <li data-md>
     <p><a href="https://github.com/gcc-mirror/gcc">gcc</a>: <strong>244 hits in 31 files</strong> (<code class="highlight"><c- n>reloc</c-></code> only used as local variable or 
data-member, counting all uses); files:  15,337 ; lines:  4,616,875 ; 
words:  146,146,684; commit: ee6f262b87fe</p>
    <li data-md>
     <p><a href="https://github.com/Tencent/rapidjson">rapidjson</a>: 0 hits; files:  96 ;
lines:  39,828 ; words:  1,492,060; 
commit: a98e99992bd6</p>
    <li data-md>
     <p><a href="https://github.com/google/googletest">googletest</a>: 0 hits; files:  155 ;
lines:  85,703 ; words:  3,104,817; 
commit: 71140c3ca7a8</p>
    <li data-md>
     <p><a href="https://github.com/jbeder/yaml-cpp">yaml-cpp</a>: 0 hits; files:  259 ;
lines:  112,513 ; words:  3,784,676; 
commit: 1b50109f7bea</p>
    <li data-md>
     <p><a href="https://github.com/google/flatbuffers">flatbuffers</a>: 0 hits; files:  175 ;
lines:  98,163 ; words:  3,851,726; 
commit: e0d68bdda2f6</p>
    <li data-md>
     <p><a href="https://github.com/mongodb/mongo">MongoDB</a>: <strong>22 hits in 6 files</strong> (<code class="highlight"><c- n>reloc</c-></code> only used as local variable, 
counting all uses); files:  20,054 ; lines:  6,439,465 ; words:  265,329,429; 
commit: 73b7a22328c7</p>
    <li data-md>
     <p><a href="https://github.com/opencv/opencv">OpenCV</a>: 0 hits; files:  3,315 ;
lines:  1,556,606 ; words:  58,339,686; 
commit: 9627ab9462a4</p>
    <li data-md>
     <p><a href="https://github.com/electron/electron">electron</a>: 0 hits; files:  698 ;
lines:  99,717 ; words:  3,431,787; 
commit: 644243efd61b</p>
    <li data-md>
     <p><a href="https://github.com/rui314/mold">mold</a>: 0 hits; files:  813 ; lines:  262,560 ;
words:  9,992,769; commit: a45f97b47430</p>
    <li data-md>
     <p><a href="https://github.com/ClickHouse/ClickHouse">ClickHouse</a>: 0 hits; files:  5,566 ;
lines:  1,128,735 ; words:  68,112,047; commit: d42d9f70c812;</p>
    <li data-md>
     <p><a href="https://github.com/davisking/dlib">Dlib</a>: 0 hits; files:  1,421 ;
lines:  533,513 ; words:  19,080,728; commit: a12824d42584</p>
    <li data-md>
     <p><a href="https://github.com/SFML/SFML">SFML</a>: 0 hits; files:  532 ; lines:  168,787 ;
words:  7,272,946; commit: 9bdf20781819</p>
    <li data-md>
     <p><a href="https://github.com/xbmc/xbmc">Kodi</a>: 0 hits; files:  4,360 ; lines:  1,008,255 ;
words:  34,114,229; commit: b228c778668f</p>
    <li data-md>
     <p><a href="https://github.com/boostorg/beast">Beast</a>: 0 hits; files:  473 ;
lines:  145,193 ; words:  4,768,152; commit: 334b9871bed6</p>
    <li data-md>
     <p><a href="https://github.com/nlohmann/json">JSON for modern C++</a>: 0 hits; files:  450 ;
lines:  137,679 ; words:  5,210,982; commit: 4c6cde72e533</p>
    <li data-md>
     <p><a href="https://github.com/includeos/IncludeOS">IncludeOS</a>: 0 hits; files:  841 ;
lines:  107,582 ; words:  2,903,698; commit: 99b60c782161</p>
    <li data-md>
     <p><a href="https://github.com/SerenityOS/serenity">SerenityOS</a>: <strong>15 hits in 2 files</strong> (<code class="highlight"><c- n>reloc</c-></code> only used as local variable, counting all uses); files:  5,538 ; 
lines:  887,768 ; words:  31,766,641; commit: 97dde51a9b3f</p>
   </ul>
   <p>Repository statistics are computed with the following command:</p>
<pre class="language-bash highlight">find -type f <c- se>\(</c-> -name <c- t>'*.h'</c-> -or -name <c- t>'*.hh'</c-> -or -name <c- t>'*.hpp'</c-> -or -name <c- t>'*.cc'</c-> <c- se>\</c->
    -or -name <c- t>'*.cpp'</c-> -or -name <c- t>'*.cxx'</c-> <c- se>\)</c-> -exec wc -l -c <c- o>{}</c-> <c- se>\;</c-> <c- se>\</c->
    <c- p>|</c-> awk <c- t>'{ f+=1 } { l += $1 } { w += $2 } END { print "files: ", f, "; lines: ", l, "; words: ", w }'</c->
</pre>
   <p>As you can see, in the vast majority of cases, <code class="highlight"><c- n>reloc</c-></code> is not used at all.
The impact seems to be minimal, where only a few files might need to be fixed 
here and there. To smooth the transition, compilers may also warn that existing 
code will break as <code class="highlight"><c- n>reloc</c-></code> will become a keyword in a next C++ version.</p>
   <h3 class="heading settled" data-level="7.2" id="stl-api-changes"><span class="secno">7.2. </span><span class="content">STL API changes</span><a class="self-link" href="#stl-api-changes"></a></h3>
   <h4 class="heading settled" data-level="7.2.1" id="value-extract-api-choice"><span class="secno">7.2.1. </span><span class="content">Why add overload to the value-extracting functions in STL containers?</span><a class="self-link" href="#value-extract-api-choice"></a></h4>
   <p>In the original draft, all value-extracting functions were named <code class="highlight"><c- n>pilfer</c-></code> (or <code class="highlight"><c- n>pilfer_back</c-></code> and so on). However we felt it was better to reuse the function names that already
exist.</p>
   <p>We thought of simply changing the return value of existing functions: <code class="highlight"><c- n>vector</c-><c- o>::</c-><c- n>pop_back</c-><c- p>()</c-></code> would return the erased value. C++17 already changed the return value of <code class="highlight"><c- n>vector</c-><c- o>::</c-><c- n>emplace_back</c-></code>.
It caused no ABI issue (the return type of template member function is part of the mangling),
and no performance hit (as template functions are inlined,
when the reference returned from <code class="highlight"><c- n>vector</c-><c- o>::</c-><c- n>emplace_back</c-></code> is not used, then the
instructions that return the reference are not emitted).</p>
   <p>We could have done the same with <code class="highlight"><c- n>vector</c-><c- o>::</c-><c- n>pop_back</c-><c- p>()</c-></code>. However, doing so would require
that the type stored in the container to have one of the three constructors
(relocation, move or copy). This is a requirement that doesn’t exist today
for node-based containers (<code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>list</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>set</c-></code> etc...).
To state it otherwise, making an <code class="highlight"><c- n>T</c-> <c- n>list</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>::</c-><c- n>pop_back</c-><c- p>()</c-></code> will add unwanted
constraints on what can be stored in a list.</p>
   <p>In order to preserve a consistent API across all STL containers, we opted in favor
of <code class="highlight"><c- n>pop</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>relocate_t</c-><c- p>)</c-></code> overloads.</p>
   <h4 class="heading settled" data-level="7.2.2" id="optional-extract-api-choice"><span class="secno">7.2.2. </span><span class="content">Why name the value-extracting function of optional extract?</span><a class="self-link" href="#optional-extract-api-choice"></a></h4>
   <p>As mentioned we introduce <code class="highlight"><c- n>T</c-> <c- n>optional</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>::</c-><c- n>extract</c-><c- p>()</c-></code> to relocate a value out of
the optional.</p>
   <p>Alternatively, this function could have been named <code class="highlight"><c- n>pop</c-></code> if
we want to stay consistent with what’s done with containers.</p>
   <p>However a container <code class="highlight"><c- n>pop</c-><c- p>()</c-></code> function doesn’t return anything, only the <code class="highlight"><c- n>pop</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>relocate_t</c-><c- p>)</c-></code> overload does.</p>
   <p>We prefer <code class="highlight"><c- n>extract</c-><c- p>()</c-></code> over <code class="highlight"><c- n>pop</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>relocate_t</c-><c- p>)</c-></code> for <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>optional</c-></code>, as it
better conveys the intent, is easier to write, and <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>optional</c-></code> is not after
all a container.</p>
   <p>Another alternative would be to name all value-extracting functions with a new
name, and have it in common with <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>optional</c-></code> (like <code class="highlight"><c- n>pilfer</c-><c- p>()</c-></code>), however we
prefer to stick with existing API for containers.</p>
   <h3 class="heading settled" data-level="7.3" id="future-directions"><span class="secno">7.3. </span><span class="content">Future directions</span><a class="self-link" href="#future-directions"></a></h3>
   <p>We removed some of the changes we initilialy had in mind, to keep for future
extensions. This proposal aims to be the bare minimum to bring support for 
relocate-only types.</p>
   <h4 class="heading settled" data-level="7.3.1" id="future-capture-value"><span class="secno">7.3.1. </span><span class="content">More perfect forwarding</span><a class="self-link" href="#future-capture-value"></a></h4>
   <p>Currently, "perfect forwarding" is built on top of <em>universal references</em>, requiring
an understanding of reference-collapsing and the use of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>forward</c-></code>. The present
proposal improves on this by incidentally replacing <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>forward</c-></code> with <code class="highlight"><c- n>reloc</c-></code>, but
at the same time the situation is worsened by making relocate-only types viable;
such types cannot be relocated when passed by universal reference.</p>
   <table>
    <tbody>
     <tr>
      <th>Before
      <th>After
      <th>Future
     <tr>
      <td>
<pre class="highlight" lang="c++"><c- k>template</c-> 
<class... args><c- b>void</c-> <c- nf>fwd</c-><c- p>(</c-><c- n>Args</c-><c- o>&amp;&amp;</c-><c- p>...</c-> <c- n>args</c-><c- p>)</c->
<c- p>{</c->
    <c- n>do_stuff</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>forward</c-><c- p>(</c-><args><c- n>args</c-><c- p>)...);</c->
<c- p>}</c->
</args></class...></pre>
      <td>
<pre class="highlight" lang="c++"><c- k>template</c-> 
<class... args><c- b>void</c-> <c- nf>fwd</c-><c- p>(</c-><c- n>Args</c-><c- o>&amp;&amp;</c-><c- p>...</c-> <c- n>args</c-><c- p>)</c->
<c- p>{</c->
    <c- n>do_stuff</c-><c- p>(</c-><c- n>reloc</c-> <c- n>args</c-><c- p>...);</c->
<c- p>}</c->
</class...></pre>
      <td>
<pre class="highlight" lang="c++"><c- b>void</c-> <c- nf>fwd</c-><c- p>(</c-><c- k>decltype</c-><c- p>(</c-><c- k>auto</c-><c- p>)...</c-> <c- n>args</c-><c- p>)</c->
<c- p>{</c->
    <c- n>do_stuff</c-><c- p>(</c-><c- n>reloc</c-> <c- n>args</c-><c- p>...);</c->
<c- p>}</c->
</pre>
   </table>
   <p>By allowing <code class="highlight"><c- k>decltype</c-><c- p>(</c-><c- k>auto</c-><c- p>)</c-></code> as a <em>placeholder-type-specifier</em> in a <em>parameter-declaration</em> (i.e. relaxing <a href="http://wg21.link/dcl.fct#22.sentence-6">[dcl.fct] paragraph 22</a>)
it would become possible to deduce each parameter to value, lvalue
reference or rvalue reference according to whether the argument is of
value category prvalue, lvalue or xvalue, and forward by relocation.</p>
   <h4 class="heading settled" data-level="7.3.2" id="solve-discarded-reloc-expr"><span class="secno">7.3.2. </span><span class="content">discarded reloc expression</span><a class="self-link" href="#solve-discarded-reloc-expr"></a></h4>
   <p>Initilialy, discarded reloc expressions such as <code class="highlight"><c- n>reloc</c-> <c- n>obj</c-><c- p>;</c-></code> would simply
translate to a call to the destructor of <code class="highlight"><c- n>obj</c-></code>, while ensuring that the 
destructor won’t be called again at the end of its scope.</p>
   <p>However this is hardly possible at the moment because of all the different ABIs
that exist. If <code class="highlight"><c- n>obj</c-></code> is an <em>unowned parameter</em>, then the function cannot elide
the destructor call of <code class="highlight"><c- n>obj</c-></code> that will happen on the caller-side.</p>
   <p>We wanted the well-formedness of the code above all else (i.e. <code class="highlight"><c- n>reloc</c-> <c- n>obj</c-><c- p>;</c-></code> could
not be well-formed on some implementations and not in others). As such, 
in this proposal, <code class="highlight"><c- n>reloc</c-> <c- n>obj</c-><c- p>;</c-></code> is only well-formed if <code class="highlight"><c- n>obj</c-></code> is 
relocatable, movable or copyable.</p>
   <p>Hence, the best we can do if <code class="highlight"><c- n>obj</c-></code> is an <em>unowned parameter</em>,
is to move-construct a temporary, and destruct
it right after, which will trigger the desired side-effects of the destructor 
(e.g. release a lock if <code class="highlight"><c- n>obj</c-></code> is a <code class="highlight"><c- n>unique_lock</c-></code>).
The destructor of <code class="highlight"><c- n>obj</c-></code> will still be called when the function
returns, but will likely do nothing as the object will be in a moved-from state.</p>
   <p>A future proposal could make <code class="highlight"><c- n>reloc</c-> <c- n>obj</c-><c- p>;</c-></code> to just call the destructor,
regardless of whether <code class="highlight"><c- n>obj</c-></code> is an <em>unowned parameter</em> and of its constructors, 
solving those ABI issues.</p>
   <h3 class="heading settled" data-level="7.4" id="easier-cpp"><span class="secno">7.4. </span><span class="content">Will it make C++ easier?</span><a class="self-link" href="#easier-cpp"></a></h3>
   <p>Even though it does come with new rules, we argue that it mostly removes the
moved-from state understanding problem, as well as used-after-move errors 
(if <code class="highlight"><c- n>reloc</c-></code> is used instead of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>move</c-></code>).</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-d2839r1">[D2839R1]
   <dd>Brian Bi; Joshua Berne. <a href="https://isocpp.org/files/papers/D2839R1.html"><cite>Nontrivial Relocation via a New owning reference Type</cite></a>. June 2023. URL: <a href="https://isocpp.org/files/papers/D2839R1.html">https://isocpp.org/files/papers/D2839R1.html</a>
   <dt id="biblio-iife">[IIFE]
   <dd>Bartlomiej Filipek. <a href="https://www.cppstories.com/2016/11/iife-for-complex-initialization/"><cite>IIFE for Complex Initialization - C++ Stories</cite></a>. October 2016. URL: <a href="https://www.cppstories.com/2016/11/iife-for-complex-initialization/">https://www.cppstories.com/2016/11/iife-for-complex-initialization/</a>
   <dt id="biblio-n4158">[N4158]
   <dd>Pablo Halpern. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4158.pdf"><cite>Destructive Move</cite></a>. October 2014. URL: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4158.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4158.pdf</a>
   <dt id="biblio-p0023r0">[P0023R0]
   <dd>Denis Bider. <a href="http://open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0023r0.pdf"><cite>Relocator: Efficiently moving objects</cite></a>. April 2016. URL: <a href="http://open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0023r0.pdf">http://open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0023r0.pdf</a>
   <dt id="biblio-p0308r0">[P0308R0]
   <dd>Peter Dimov. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html"><cite>Valueless Variants Considered Harmful</cite></a>. March 2016. URL: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html</a>
   <dt id="biblio-p0847r6">[P0847R6]
   <dd>Gašper Ažman; et al. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0847r6.html"><cite>Deducing this</cite></a>. January 2021. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0847r6.html">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0847r6.html</a>
   <dt id="biblio-p1029r3">[P1029R3]
   <dd>Niall Douglas. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1029r3.pdf"><cite>move = bitcopies</cite></a>. January 2020. URL: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1029r3.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1029r3.pdf</a>
   <dt id="biblio-p1144r8">[P1144R8]
   <dd>Arthur O'Dwyer. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p1144r8.html"><cite>std::is_trivially_relocatable</cite></a>. May 2023. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p1144r8.html">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p1144r8.html</a>
   <dt id="biblio-p2665r0">[P2665R0]
   <dd>Bengt Gustafsson. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2665r0.pdf"><cite>Allow calling overload sets containing T, const T&amp;</cite></a>. October 2022. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2665r0.pdf">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2665r0.pdf</a>
  </dl>