<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="mpark/wg21" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  <meta name="dcterms.date" content="2025-02-11" />
  <title>Uninitialized algorithms for relocation</title>
  <style>
      code{white-space: pre-wrap;}
      span.smallcaps{font-variant: small-caps;}
      span.underline{text-decoration: underline;}
      div.column{display: inline-block; vertical-align: top; width: 50%;}
      div.csl-block{margin-left: 1.5em;}
      ul.task-list{list-style: none;}
      pre > code.sourceCode { white-space: pre; position: relative; }
      pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
      pre > code.sourceCode > span:empty { height: 1.2em; }
      .sourceCode { overflow: visible; }
      code.sourceCode > span { color: inherit; text-decoration: inherit; }
      div.sourceCode { margin: 1em 0; }
      pre.sourceCode { margin: 0; }
      @media screen {
      div.sourceCode { overflow: auto; }
      }
      @media print {
      pre > code.sourceCode { white-space: pre-wrap; }
      pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
      }
      pre.numberSource code
        { counter-reset: source-line 0; }
      pre.numberSource code > span
        { position: relative; left: -4em; counter-increment: source-line; }
      pre.numberSource code > span > a:first-child::before
        { content: counter(source-line);
          position: relative; left: -1em; text-align: right; vertical-align: baseline;
          border: none; display: inline-block;
          -webkit-touch-callout: none; -webkit-user-select: none;
          -khtml-user-select: none; -moz-user-select: none;
          -ms-user-select: none; user-select: none;
          padding: 0 4px; width: 4em;
          color: #aaaaaa;
        }
      pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
      div.sourceCode
        {  background-color: #f6f8fa; }
      @media screen {
      pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
      }
      code span { } /* Normal */
      code span.al { color: #ff0000; } /* Alert */
      code span.an { } /* Annotation */
      code span.at { } /* Attribute */
      code span.bn { color: #9f6807; } /* BaseN */
      code span.bu { color: #9f6807; } /* BuiltIn */
      code span.cf { color: #00607c; } /* ControlFlow */
      code span.ch { color: #9f6807; } /* Char */
      code span.cn { } /* Constant */
      code span.co { color: #008000; font-style: italic; } /* Comment */
      code span.cv { color: #008000; font-style: italic; } /* CommentVar */
      code span.do { color: #008000; } /* Documentation */
      code span.dt { color: #00607c; } /* DataType */
      code span.dv { color: #9f6807; } /* DecVal */
      code span.er { color: #ff0000; font-weight: bold; } /* Error */
      code span.ex { } /* Extension */
      code span.fl { color: #9f6807; } /* Float */
      code span.fu { } /* Function */
      code span.im { } /* Import */
      code span.in { color: #008000; } /* Information */
      code span.kw { color: #00607c; } /* Keyword */
      code span.op { color: #af1915; } /* Operator */
      code span.ot { } /* Other */
      code span.pp { color: #6f4e37; } /* Preprocessor */
      code span.re { } /* RegionMarker */
      code span.sc { color: #9f6807; } /* SpecialChar */
      code span.ss { color: #9f6807; } /* SpecialString */
      code span.st { color: #9f6807; } /* String */
      code span.va { } /* Variable */
      code span.vs { color: #9f6807; } /* VerbatimString */
      code span.wa { color: #008000; font-weight: bold; } /* Warning */
      code.diff {color: #898887}
      code.diff span.va {color: #006e28}
      code.diff span.st {color: #bf0303}

      .marginalized[data-old]::before {
        text-decoration-line: line-through;
        color: #bf0303;
        content: attr(data-old);
      }
      .marginalized[data-old] {
        color: #006e28;
      }
      .add .marginalized {
        color: #006e28;
      }

  </style>
  <style type="text/css">
body {
margin: 5em;
font-family: serif;

hyphens: auto;
line-height: 1.35;
text-align: justify;
}
@media screen and (max-width: 30em) {
body {
margin: 1.5em;
}
}
div.wrapper {
max-width: 60em;
margin: auto;
}
ul {
list-style-type: none;
padding-left: 2em;
margin-top: -0.2em;
margin-bottom: -0.2em;
}
a {
text-decoration: none;
color: #4183C4;
}
a.hidden_link {
text-decoration: none;
color: inherit;
}
li {
margin-top: 0.6em;
margin-bottom: 0.6em;
}
h1, h2, h3, h4 {
position: relative;
line-height: 1;
}
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;
font-family: sans-serif;
font-weight: normal;
font-size: 83%;
}
a.self-link:hover { opacity: 1; }
a.self-link::before { content: "§"; }
ul > li:before {
content: "\2014";
position: absolute;
margin-left: -1.5em;
}
:target { background-color: #C9FBC9; }
:target .codeblock { background-color: #C9FBC9; }
:target ul { background-color: #C9FBC9; }
.abbr_ref { float: right; }
.folded_abbr_ref { float: right; }
:target .folded_abbr_ref { display: none; }
:target .unfolded_abbr_ref { float: right; display: inherit; }
.unfolded_abbr_ref { display: none; }
.secnum { display: inline-block; min-width: 35pt; }
.header-section-number { display: inline-block; min-width: 35pt; }
.annexnum { display: block; }
div.sourceLinkParent {
float: right;
}
a.sourceLink {
position: absolute;
opacity: 0;
margin-left: 10pt;
}
a.sourceLink:hover {
opacity: 1;
}
a.itemDeclLink {
position: absolute;
font-size: 75%;
text-align: right;
width: 5em;
opacity: 0;
}
a.itemDeclLink:hover { opacity: 1; }
span.marginalizedparent {
position: relative;
left: -5em;
}
li span.marginalizedparent { left: -7em; }
li ul > li span.marginalizedparent { left: -9em; }
li ul > li ul > li span.marginalizedparent { left: -11em; }
li ul > li ul > li ul > li span.marginalizedparent { left: -13em; }
div.footnoteNumberParent {
position: relative;
left: -4.7em;
}
a.marginalized {
position: absolute;
font-size: 75%;
text-align: right;
width: 5em;
}
a.enumerated_item_num {
position: relative;
left: -3.5em;
display: inline-block;
margin-right: -3em;
text-align: right;
width: 3em;
}
div.para { margin-bottom: 0.6em; margin-top: 0.6em; text-align: justify; }
div.section { text-align: justify; }
div.sentence { display: inline; }
span.indexparent {
display: inline;
position: relative;
float: right;
right: -1em;
}
a.index {
position: absolute;
display: none;
}
a.index:before { content: "⟵"; }

a.index:target {
display: inline;
}
.indexitems {
margin-left: 2em;
text-indent: -2em;
}
div.itemdescr {
margin-left: 3em;
}
.bnf {
font-family: serif;
margin-left: 40pt;
margin-top: 0.5em;
margin-bottom: 0.5em;
}
.ncbnf {
font-family: serif;
margin-top: 0.5em;
margin-bottom: 0.5em;
margin-left: 40pt;
}
.ncsimplebnf {
font-family: serif;
font-style: italic;
margin-top: 0.5em;
margin-bottom: 0.5em;
margin-left: 40pt;
background: inherit; 
}
span.textnormal {
font-style: normal;
font-family: serif;
white-space: normal;
display: inline-block;
}
span.rlap {
display: inline-block;
width: 0px;
}
span.descr { font-style: normal; font-family: serif; }
span.grammarterm { font-style: italic; }
span.term { font-style: italic; }
span.terminal { font-family: monospace; font-style: normal; }
span.nonterminal { font-style: italic; }
span.tcode { font-family: monospace; font-style: normal; }
span.textbf { font-weight: bold; }
span.textsc { font-variant: small-caps; }
a.nontermdef { font-style: italic; font-family: serif; }
span.emph { font-style: italic; }
span.techterm { font-style: italic; }
span.mathit { font-style: italic; }
span.mathsf { font-family: sans-serif; }
span.mathrm { font-family: serif; font-style: normal; }
span.textrm { font-family: serif; }
span.textsl { font-style: italic; }
span.mathtt { font-family: monospace; font-style: normal; }
span.mbox { font-family: serif; font-style: normal; }
span.ungap { display: inline-block; width: 2pt; }
span.textit { font-style: italic; }
span.texttt { font-family: monospace; }
span.tcode_in_codeblock { font-family: monospace; font-style: normal; }
span.phantom { color: white; }

span.math { font-style: normal; }
span.mathblock {
display: block;
margin-left: auto;
margin-right: auto;
margin-top: 1.2em;
margin-bottom: 1.2em;
text-align: center;
}
span.mathalpha {
font-style: italic;
}
span.synopsis {
font-weight: bold;
margin-top: 0.5em;
display: block;
}
span.definition {
font-weight: bold;
display: block;
}
.codeblock {
margin-left: 1.2em;
line-height: 127%;
}
.outputblock {
margin-left: 1.2em;
line-height: 127%;
}
div.itemdecl {
margin-top: 2ex;
}
code.itemdeclcode {
white-space: pre;
display: block;
}
span.textsuperscript {
vertical-align: super;
font-size: smaller;
line-height: 0;
}
.footnotenum { vertical-align: super; font-size: smaller; line-height: 0; }
.footnote {
font-size: small;
margin-left: 2em;
margin-right: 2em;
margin-top: 0.6em;
margin-bottom: 0.6em;
}
div.minipage {
display: inline-block;
margin-right: 3em;
}
div.numberedTable {
text-align: center;
margin: 2em;
}
div.figure {
text-align: center;
margin: 2em;
}
table {
border: 1px solid black;
border-collapse: collapse;
margin-left: auto;
margin-right: auto;
margin-top: 0.8em;
text-align: left;
hyphens: none; 
}
td, th {
padding-left: 1em;
padding-right: 1em;
vertical-align: top;
}
td.empty {
padding: 0px;
padding-left: 1px;
}
td.left {
text-align: left;
}
td.right {
text-align: right;
}
td.center {
text-align: center;
}
td.justify {
text-align: justify;
}
td.border {
border-left: 1px solid black;
}
tr.rowsep, td.cline {
border-top: 1px solid black;
}
tr.even, tr.odd {
border-bottom: 1px solid black;
}
tr.capsep {
border-top: 3px solid black;
border-top-style: double;
}
tr.header {
border-bottom: 3px solid black;
border-bottom-style: double;
}
th {
border-bottom: 1px solid black;
}
span.centry {
font-weight: bold;
}
div.table {
display: block;
margin-left: auto;
margin-right: auto;
text-align: center;
width: 90%;
}
span.indented {
display: block;
margin-left: 2em;
margin-bottom: 1em;
margin-top: 1em;
}
ol.enumeratea { list-style-type: none; background: inherit; }
ol.enumerate { list-style-type: none; background: inherit; }

code.sourceCode > span { display: inline; }
</style>
  <link href="data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAVoJEAN6CRADegkQAWIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wCCRAAAgkQAAIJEAACCRAAsgkQAvoJEAP+CRAD/gkQA/4JEAP+CRADAgkQALoJEAACCRAAAgkQAAP///wD///8AgkQAAIJEABSCRACSgkQA/IJEAP99PQD/dzMA/3czAP99PQD/gkQA/4JEAPyCRACUgkQAFIJEAAD///8A////AHw+AFiBQwDqgkQA/4BBAP9/PxP/uZd6/9rJtf/bybX/upd7/39AFP+AQQD/gkQA/4FDAOqAQgBc////AP///wDKklv4jlEa/3o7AP+PWC//8+3o///////////////////////z7un/kFox/35AAP+GRwD/mVYA+v///wD///8A0Zpk+NmibP+0d0T/8evj///////+/fv/1sKz/9bCs//9/fr//////+/m2/+NRwL/nloA/5xYAPj///8A////ANKaZPjRmGH/5cKh////////////k149/3UwAP91MQD/lmQ//86rhv+USg3/m1YA/5hSAP+bVgD4////AP///wDSmmT4zpJY/+/bx///////8+TV/8mLT/+TVx//gkIA/5lVAP+VTAD/x6B//7aEVv/JpH7/s39J+P///wD///8A0ppk+M6SWP/u2sf///////Pj1f/Nj1T/2KFs/8mOUv+eWhD/lEsA/8aee/+0glT/x6F7/7J8Rvj///8A////ANKaZPjRmGH/48Cf///////+/v7/2qt//82PVP/OkFX/37KJ/86siv+USg7/mVQA/5hRAP+bVgD4////AP///wDSmmT40ppk/9CVXP/69O////////7+/v/x4M//8d/P//7+/f//////9u7n/6tnJf+XUgD/nFgA+P///wD///8A0ppk+NKaZP/RmWL/1qNy//r07///////////////////////+vXw/9akdP/Wnmn/y5FY/6JfFvj///8A////ANKaZFTSmmTo0ppk/9GYYv/Ql1//5cWm//Hg0P/x4ND/5cWm/9GXYP/RmGH/0ppk/9KaZOjVnmpY////AP///wDSmmQA0ppkEtKaZI7SmmT60ppk/9CWX//OkVb/zpFW/9CWX//SmmT/0ppk/NKaZJDSmmQS0ppkAP///wD///8A0ppkANKaZADSmmQA0ppkKtKaZLrSmmT/0ppk/9KaZP/SmmT/0ppkvNKaZCrSmmQA0ppkANKaZAD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkUtKaZNzSmmTc0ppkVNKaZADSmmQA0ppkANKaZADSmmQA////AP5/AAD4HwAA4AcAAMADAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAMADAADgBwAA+B8AAP5/AAAoAAAAIAAAAEAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAyCRACMgkQA6oJEAOqCRACQgkQAEIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRABigkQA5oJEAP+CRAD/gkQA/4JEAP+CRADqgkQAZoJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAA4gkQAwoJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQAxIJEADyCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAP///wD///8A////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAWgkQAmIJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAJyCRAAYgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAdIJEAPCCRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAPSCRAB4gkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQASoJEANKCRAD/gkQA/4JEAP+CRAD/g0YA/39AAP9zLgD/bSQA/2shAP9rIQD/bSQA/3MuAP9/PwD/g0YA/4JEAP+CRAD/gkQA/4JEAP+CRADUgkQAToJEAACCRAAAgkQAAP///wD///8A////AP///wB+PwAAgkUAIoJEAKiCRAD/gkQA/4JEAP+CRAD/hEcA/4BBAP9sIwD/dTAA/5RfKv+viF7/vp56/76ee/+wiF7/lWAr/3YxAP9sIwD/f0AA/4RHAP+CRAD/gkQA/4JEAP+CRAD/gkQArIJEACaBQwAA////AP///wD///8A////AIBCAEBzNAD6f0EA/4NFAP+CRAD/gkQA/4VIAP92MwD/bSUA/6N1Tv/ezsL/////////////////////////////////38/D/6V3Uv9uJgD/dTEA/4VJAP+CRAD/gkQA/4JEAP+BQwD/fUAA/4FDAEj///8A////AP///wD///8AzJRd5qBlKf91NgD/dDUA/4JEAP+FSQD/cy4A/3YyAP/PuKP//////////////////////////////////////////////////////9K7qP94NQD/ciwA/4VJAP+CRAD/fkEA/35BAP+LSwD/mlYA6v///wD///8A////AP///wDdpnL/4qx3/8KJUv+PUhf/cTMA/3AsAP90LgD/4dK+/////////////////////////////////////////////////////////////////+TYxf91MAD/dTIA/31CAP+GRwD/llQA/6FcAP+gWwD8////AP///wD///8A////ANGZY/LSm2X/4ap3/92mcP+wdT3/byQA/8mwj////////////////////////////////////////////////////////////////////////////+LYxv9zLgP/jUoA/59bAP+hXAD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/RmWL/1p9q/9ubXv/XqXj////////////////////////////7+fD/vZyG/6BxS/+gcUr/vJuE//r37f//////////////////////3MOr/5dQBf+dVQD/nVkA/5xYAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmWP/yohJ//jo2P//////////////////////4NTG/4JDFf9lGAD/bSQA/20kAP9kGAD/fz8S/+Xb0f//////5NG9/6txN/+LOgD/m1QA/51aAP+cWAD/m1cA/5xYAP+cWADy////AP///wD///8A////ANKaZPLSmmT/0ppk/8+TWf/Unmv//v37//////////////////////+TWRr/VwsA/35AAP+ERgD/g0UA/4JGAP9lHgD/kFga/8KXX/+TRwD/jT4A/49CAP+VTQD/n10A/5xYAP+OQQD/lk4A/55cAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/y4tO/92yiP//////////////////////8NnE/8eCQP+rcTT/ez0A/3IyAP98PgD/gEMA/5FSAP+USwD/jj8A/5lUAP+JNwD/yqV2/694Mf+HNQD/jkAA/82rf/+laBj/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/LiUr/4byY///////////////////////gupX/0I5P/+Wuev/Lklz/l1sj/308AP+QSwD/ol0A/59aAP+aVQD/k0oA/8yoh///////+fXv/6pwO//Lp3v///////Pr4f+oay7y////AP///wD///8A////ANKaZPLSmmT/0ppk/8uJSv/hvJj//////////////////////+G7l//Jhkb/0ppk/96nc//fqXX/x4xO/6dkFP+QSQD/llEA/5xXAP+USgD/yaOA///////38uv/qG05/8ijdv//////8efb/6ZpLPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/zIxO/9yxh///////////////////////7dbA/8iEQf/Sm2X/0Zlj/9ScZv/eqHf/2KJv/7yAQf+XTgD/iToA/5lSAP+JNgD/yKFv/611LP+HNQD/jT8A/8qmeP+kZRT/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/Pk1n/1J5q//78+//////////////////+/fv/1aFv/8iEQv/Tm2b/0ppl/9GZY//Wn2z/1pZc/9eldf/Bl2b/kUcA/4w9AP+OQAD/lUwA/59eAP+cWQD/jT8A/5ZOAP+eXADy////AP///wD///8A////ANKaZPLSmmT/0ppk/9KZY//KiEn/8d/P///////////////////////47+f/05tm/8iCP//KiEj/yohJ/8eCP//RmGH//vfy///////n1sP/rXQ7/4k4AP+TTAD/nVoA/5xYAP+cVwD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/0ptl/8uLTf/aq37////////////////////////////+/fz/6c2y/961jv/etY7/6Myx//78+v//////////////////////3MWv/5xXD/+ORAD/mFQA/51ZAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmmT/0ppk/8mFRP/s1b//////////////////////////////////////////////////////////////////////////////+PD/0JFU/7NzMv+WUQD/kUsA/5tXAP+dWQDy////AP///wD///8A////ANKaZP/SmmT/0ppk/9KaZP/Sm2X/z5NZ/8yMT//z5NX/////////////////////////////////////////////////////////////////9Ofa/8yNUP/UmGH/36p5/8yTWv+qaSD/kksA/5ROAPz///8A////AP///wD///8A0ppk5NKaZP/SmmT/0ppk/9KaZP/TnGf/zY9T/82OUv/t1sD//////////////////////////////////////////////////////+7Yw//OkFX/zI5R/9OcZ//SmmP/26V0/9ymdf/BhUf/ol8R6P///wD///8A////AP///wDSmmQ80ppk9tKaZP/SmmT/0ppk/9KaZP/TnGj/zpFW/8qJSv/dson/8uHS//////////////////////////////////Lj0//etIv/y4lL/86QVf/TnGj/0ppk/9KaZP/RmWP/05xn/9ymdfjUnWdC////AP///wD///8A////ANKaZADSmmQc0ppkotKaZP/SmmT/0ppk/9KaZP/Tm2b/0Zli/8qJSf/NjlH/16Z3/+G8mP/myKr/5siq/+G8mP/Xp3f/zY5S/8qISf/RmGH/05tm/9KaZP/SmmT/0ppk/9KaZP/SmmSm0pljINWdaQD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkQtKaZMrSmmT/0ppk/9KaZP/SmmT/0ptl/9GYYf/Nj1P/y4lL/8qISP/KiEj/y4lK/82PU//RmGH/0ptl/9KaZP/SmmT/0ppk/9KaZP/SmmTO0ppkRtKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZGzSmmTu0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmTw0ppkcNKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZBLSmmSQ0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppklNKaZBTSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQy0ppkutKaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppkvtKaZDbSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkXNKaZODSmmT/0ppk/9KaZP/SmmT/0ppk5NKaZGDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkBtKaZIbSmmTo0ppk6tKaZIrSmmQK0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP/8P///+B///+AH//+AAf//AAD//AAAP/AAAA/gAAAHwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA+AAAAfwAAAP/AAAP/8AAP//gAH//+AH///4H////D//" rel="icon" />
  
  <!--[if lt IE 9]>
    <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
  <![endif]-->
</head>
<body>
<div class="wrapper">
<header id="title-block-header">
<h1 class="title" style="text-align:center">Uninitialized algorithms for
relocation</h1>
<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>
      P3516R1
      [<a href="https://wg21.link/P3516">Latest</a>]
      [<a href="https://wg21.link/P3516/status">Status</a>]
    </td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2025-02-11</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Project:</td>
    <td>Programming Language C++</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Audience:</td>
    <td>
      LEWG<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to:</td>
    <td>
      Louis Dionne<br>&lt;<a href="mailto:ldionne.2@gmail.com" class="email">ldionne.2@gmail.com</a>&gt;<br>
      Giuseppe D’Angelo<br>&lt;<a href="mailto:giuseppe.dangelo@kdab.com" class="email">giuseppe.dangelo@kdab.com</a>&gt;<br>
    </td>
  </tr>
</table>
</header>
<div style="clear:both">
<div id="TOC" role="doc-toc">
<h1 id="toctitle">Contents</h1>
<ul>
<li><a href="#changelog" id="toc-changelog"><span class="toc-section-number">1</span> Changelog<span></span></a></li>
<li><a href="#introduction" id="toc-introduction"><span class="toc-section-number">2</span> Introduction<span></span></a></li>
<li><a href="#motivation" id="toc-motivation"><span class="toc-section-number">3</span> Motivation<span></span></a></li>
<li><a href="#proposal" id="toc-proposal"><span class="toc-section-number">4</span> Proposal<span></span></a></li>
<li><a href="#usage-examples" id="toc-usage-examples"><span class="toc-section-number">5</span> Usage examples<span></span></a>
<ul>
<li><a href="#vectoremplace-vectorinsert" id="toc-vectoremplace-vectorinsert"><span class="toc-section-number">5.1</span> <code class="sourceCode cpp">vector<span class="op">::</span>emplace</code> /
<code class="sourceCode cpp">vector<span class="op">::</span>insert</code><span></span></a></li>
<li><a href="#vectorerase" id="toc-vectorerase"><span class="toc-section-number">5.2</span> <code class="sourceCode cpp">vector<span class="op">::</span>erase</code><span></span></a></li>
<li><a href="#vectoremplace_back-vectorpush_back" id="toc-vectoremplace_back-vectorpush_back"><span class="toc-section-number">5.3</span> <code class="sourceCode cpp">vector<span class="op">::</span>emplace_back</code>
/ <code class="sourceCode cpp">vector<span class="op">::</span>push_back</code><span></span></a></li>
</ul></li>
<li><a href="#compatibility-with-relocation-proposals" id="toc-compatibility-with-relocation-proposals"><span class="toc-section-number">6</span> Compatibility with relocation
proposals<span></span></a></li>
<li><a href="#wording" id="toc-wording"><span class="toc-section-number">7</span> Wording<span></span></a>
<ul>
<li><a href="#version.syn" id="toc-version.syn"><span class="toc-section-number">7.1</span>
[version.syn]<span></span></a></li>
<li><a href="#algorithms.requirements" id="toc-algorithms.requirements"><span class="toc-section-number">7.2</span>
[algorithms.requirements]<span></span></a></li>
<li><a href="#specialized.algorithms.general" id="toc-specialized.algorithms.general"><span class="toc-section-number">7.3</span>
[specialized.algorithms.general]<span></span></a></li>
<li><a href="#special.mem.concepts" id="toc-special.mem.concepts"><span class="toc-section-number">7.4</span>
[special.mem.concepts]<span></span></a></li>
<li><a href="#memory.syn" id="toc-memory.syn"><span class="toc-section-number">7.5</span> [memory.syn]<span></span></a></li>
<li><a href="#specialized.algorithms" id="toc-specialized.algorithms"><span class="toc-section-number">7.6</span>
[specialized.algorithms]<span></span></a></li>
</ul></li>
<li><a href="#acknowledgements" id="toc-acknowledgements"><span class="toc-section-number">8</span>
Acknowledgements<span></span></a></li>
</ul>
</div>
<h1 data-number="1" id="changelog"><span class="header-section-number">1</span> Changelog<a href="#changelog" class="self-link"></a></h1>
<ul>
<li>R1 (LEWG in Hagenberg)
<ul>
<li>Rebased on top of P2786R11, after the modifications approved by LEWG
on 2025-01-14.</li>
<li>Wording fixes.</li>
</ul></li>
<li>R0 (Pre-Hagenberg)
<ul>
<li>First revision.</li>
</ul></li>
</ul>
<h1 data-number="2" id="introduction"><span class="header-section-number">2</span> Introduction<a href="#introduction" class="self-link"></a></h1>
<p><a href="https://wg21.link/P2786">P2786</a> is currently making
progress through EWG and LEWG. In Poland, LEWG expressed a strong desire
for that language feature to come with a proper user-facing library
interface. This paper proposes such an interface. That interface is
heavily influenced by the uninitialized algorithms that were originally
proposed in <a href="https://wg21.link/P1144">P1144</a> which, after
implementation experience in libc++, seem to be almost exactly what we
need.</p>
<p>This paper aims to provide the high-level algorithms that all
programmers will want to use, while purposefully not touching on some of
the more contentious design points of <a href="https://wg21.link/P2786">P2786</a>/<a href="https://wg21.link/P1144">P1144</a>. The high-level algorithms
proposed in this paper are compatible with essentially any definition of
“trivial relocation” we might introduce in the language in C++26 or
later.</p>
<h1 data-number="3" id="motivation"><span class="header-section-number">3</span> Motivation<a href="#motivation" class="self-link"></a></h1>
<p>Today, many algorithms and containers use some flavor of assignment,
either as an implementation detail or as part of their API promise. In
cases where the use of assignment is merely an implementation detail,
writing the code in terms of relocation can often result in cleaner code
and improved performance (since move-construction is often faster than
move-assignment).</p>
<p>Furthermore, in a future where the language itself provides a
definition of relocation (and in particular trivial relocation),
algorithms and containers written in terms of relocation today would
benefit from a massive speedup for trivially relocatable types without
requiring any change. Indeed, the algorithms introduced in this paper
boil down to <code class="sourceCode cpp">memmove</code> (or
<code class="sourceCode cpp">memcpy</code> if we can prove the absence
of overlap) in trivial cases, which are fairly common.</p>
<h1 data-number="4" id="proposal"><span class="header-section-number">4</span> Proposal<a href="#proposal" class="self-link"></a></h1>
<p>We propose adding algorithms <code class="sourceCode cpp">std<span class="op">::</span>uninitialized_relocate</code>,
<code class="sourceCode cpp">std<span class="op">::</span>uninitialized_relocate_n</code>,
and <code class="sourceCode cpp">std<span class="op">::</span>uninitialized_relocate_backward</code>.
We also add the equivalent
<code class="sourceCode cpp">ranges<span class="op">::</span></code>
functions and the parallel algorithm overloads. At a high level, these
algorithms relocate a range of objects from one memory location to
another, which is a very useful primitive when writing containers and
algorithms.</p>
<p>However, the library interface proposed here is intentionally
independent of the details of the underlying language feature.</p>
<p>Design points:</p>
<ul>
<li>These functions behave similarly to the other uninitialized
algorithms like <code class="sourceCode cpp">std<span class="op">::</span>uninitialized_copy</code>,
with the difference that the new proposed relocation algorithms support
overlapping input/output ranges like
<code class="sourceCode cpp">std<span class="op">::</span>move</code>
and <code class="sourceCode cpp">std<span class="op">::</span>move_backward</code>.
That is necessary in order to support most use cases where one is
relocating a range a bit “to the right” or a bit “to the left” of its
current location.</li>
<li>Unlike P2786 which talks of <em>trivial relocation</em>, these
algorithms talk of <em>relocation</em> in the general sense. This is
because it’s generally more useful (and easier!) to write an algorithm
or data structure operation in terms of general relocation, even if it
is not trivial (in which case it is move + destroy). Even non-trivial
relocation is usually faster than the equivalent assignment-based
algorithm. By encouraging users to write their code in terms of general
relocation today, we are preparing the terrain for when the language
gets a notion of trivial relocation, and in the meantime we let
implementations optimize under the as-if rule.</li>
<li>The algorithms provide an exception guarantee that in case of an
exception, the whole source range is destroyed and the whole destination
range as well. Otherwise, the ranges would contain an unknown number of
alive objects, making it impossible for the caller to perform a clean
up. This turns out to work well with what e.g. <code class="sourceCode cpp">std<span class="op">::</span>vector<span class="op">::</span>insert</code>
requires in order to provide the basic exception safety guarantee (see
the examples below).</li>
<li>The algorithms accept
<code class="sourceCode cpp">input_iterator</code>s (or
<code class="sourceCode cpp">bidirectional_iterator</code>s for the
backward variant) for the input range. This iterator category is
sufficient to implement these algorithms properly. However, it does mean
that the range overlap precondition cannot be checked at runtime for
some iterator categories. In practice, we would expect an implementation
that wishes to check this precondition to do so whenever the input range
is at least random access, which should be the vast majority of use
cases.</li>
<li>The algorithms accept
<code class="sourceCode cpp">forward_iterator</code>s for the output
range, which is necessary to perform cleanup if an exception is
thrown.</li>
<li>The proposed API facilities are intended to be as consistent as
possible with existing uninitialized algorithms, with the few
differences being a direct consequence of the fact that the source range
does not contain any elements after performing the operation.</li>
</ul>
<h1 data-number="5" id="usage-examples"><span class="header-section-number">5</span> Usage examples<a href="#usage-examples" class="self-link"></a></h1>
<p>In these examples, we ignore allocator support for simplicity, and we
use <code class="sourceCode cpp">iterator</code> instead of
<code class="sourceCode cpp">const_iterator</code> as the parameter
types to lighten the code. The “real” code for implementing these
functions does not look meaningfully different.</p>
<h2 data-number="5.1" id="vectoremplace-vectorinsert"><span class="header-section-number">5.1</span> <code class="sourceCode cpp">vector<span class="op">::</span>emplace</code> /
<code class="sourceCode cpp">vector<span class="op">::</span>insert</code><a href="#vectoremplace-vectorinsert" class="self-link"></a></h2>
<table>
<thead>
<tr class="header">
<th><div style="text-align:center">
<strong>Assignment based</strong>
</div></th>
<th><div style="text-align:center">
<strong>This paper</strong>
</div></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><div>

<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> <span class="op">...</span>Args<span class="op">&gt;</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> iterator</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>vector<span class="op">&lt;</span>T<span class="op">&gt;::</span>emplace<span class="op">(</span>iterator position, Args<span class="op">&amp;&amp;...</span> args<span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> <span class="op">[[</span><span class="at">unlikely</span><span class="op">]]</span> <span class="op">(</span>size<span class="op">()</span> <span class="op">==</span> capacity<span class="op">())</span> <span class="op">{</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>    <span class="co">// slow path where we grow the vector</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> <span class="op">(</span>position <span class="op">==</span> end<span class="op">())</span> <span class="op">{</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>construct_at<span class="op">(</span>std<span class="op">::</span>to_address<span class="op">(</span>position<span class="op">)</span>,</span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>                      std<span class="op">::</span>forward<span class="op">&lt;</span>Args<span class="op">&gt;(</span>args<span class="op">)...)</span>;</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span>end_;</span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>    T tmp<span class="op">(</span>std<span class="op">::</span>forward<span class="op">&lt;</span>Args<span class="op">&gt;(</span>args<span class="op">)...)</span>;</span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Create a gap at the end by moving the last</span></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a>    <span class="co">// element into the &quot;new last position&quot;.</span></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>construct_at<span class="op">(</span>std<span class="op">::</span>to_address<span class="op">(</span>end<span class="op">())</span>,</span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a>                      std<span class="op">::</span>move<span class="op">(</span>back<span class="op">()))</span>;</span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span>end_;</span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a>    <span class="co">// The element before the last one is moved-from:</span></span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a>    <span class="co">// shift everything else by one position to the</span></span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a>    <span class="co">// right to open a gap at the insert location.</span></span>
<span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>move_backward<span class="op">(</span>position, end<span class="op">()</span> <span class="op">-</span> <span class="dv">2</span>, end<span class="op">()</span> <span class="op">-</span> <span class="dv">1</span><span class="op">)</span>;</span>
<span id="cb1-25"><a href="#cb1-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-26"><a href="#cb1-26" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Now there&#39;s a gap at the insert location, move the</span></span>
<span id="cb1-27"><a href="#cb1-27" aria-hidden="true" tabindex="-1"></a>    <span class="co">// new element into it.</span></span>
<span id="cb1-28"><a href="#cb1-28" aria-hidden="true" tabindex="-1"></a>    <span class="op">*</span>position <span class="op">=</span> std<span class="op">::</span>move<span class="op">(</span>tmp<span class="op">)</span>;</span>
<span id="cb1-29"><a href="#cb1-29" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb1-30"><a href="#cb1-30" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> position;</span>
<span id="cb1-31"><a href="#cb1-31" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>

</div></td>
<td><div>

<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> <span class="op">...</span>Args<span class="op">&gt;</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> iterator</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>vector<span class="op">&lt;</span>T<span class="op">&gt;::</span>emplace<span class="op">(</span>iterator position, Args<span class="op">&amp;&amp;...</span> args<span class="op">)</span> <span class="op">{</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> <span class="op">[[</span><span class="at">unlikely</span><span class="op">]]</span> <span class="op">(</span>size<span class="op">()</span> <span class="op">==</span> capacity<span class="op">())</span> <span class="op">{</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>    <span class="co">// slow path where we grow the vector</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> <span class="op">(</span>position <span class="op">==</span> end<span class="op">())</span> <span class="op">{</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>construct_at<span class="op">(</span>std<span class="op">::</span>to_address<span class="op">(</span>position<span class="op">)</span>,</span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a>                      std<span class="op">::</span>forward<span class="op">&lt;</span>Args<span class="op">&gt;(</span>args<span class="op">)...)</span>;</span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span>end_;</span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a>    T tmp<span class="op">(</span>std<span class="op">::</span>forward<span class="op">&lt;</span>Args<span class="op">&gt;(</span>args<span class="op">)...)</span>;</span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Create a gap inside the vector by relocating</span></span>
<span id="cb2-16"><a href="#cb2-16" aria-hidden="true" tabindex="-1"></a>    <span class="co">// everything to the right.</span></span>
<span id="cb2-17"><a href="#cb2-17" aria-hidden="true" tabindex="-1"></a>    <span class="cf">try</span> <span class="op">{</span></span>
<span id="cb2-18"><a href="#cb2-18" aria-hidden="true" tabindex="-1"></a>      std<span class="op">::</span>uninitialized_relocate_backward<span class="op">(</span>position, end<span class="op">()</span>,</span>
<span id="cb2-19"><a href="#cb2-19" aria-hidden="true" tabindex="-1"></a>                                           end<span class="op">()</span> <span class="op">+</span> <span class="dv">1</span><span class="op">)</span>;</span>
<span id="cb2-20"><a href="#cb2-20" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span> <span class="cf">catch</span> <span class="op">(...)</span> <span class="op">{</span></span>
<span id="cb2-21"><a href="#cb2-21" aria-hidden="true" tabindex="-1"></a>      <span class="co">// basic guarantee: vector lost its tail</span></span>
<span id="cb2-22"><a href="#cb2-22" aria-hidden="true" tabindex="-1"></a>      end_ <span class="op">=</span> std<span class="op">::</span>to_address<span class="op">(</span>position<span class="op">)</span>;</span>
<span id="cb2-23"><a href="#cb2-23" aria-hidden="true" tabindex="-1"></a>      <span class="cf">throw</span>;</span>
<span id="cb2-24"><a href="#cb2-24" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb2-25"><a href="#cb2-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-26"><a href="#cb2-26" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Move-construct the new value into the gap created above.</span></span>
<span id="cb2-27"><a href="#cb2-27" aria-hidden="true" tabindex="-1"></a>    <span class="cf">try</span> <span class="op">{</span></span>
<span id="cb2-28"><a href="#cb2-28" aria-hidden="true" tabindex="-1"></a>      std<span class="op">::</span>construct_at<span class="op">(</span>std<span class="op">::</span>to_address<span class="op">(</span>position<span class="op">)</span>, std<span class="op">::</span>move<span class="op">(</span>tmp<span class="op">))</span>;</span>
<span id="cb2-29"><a href="#cb2-29" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span> <span class="cf">catch</span> <span class="op">(...)</span> <span class="op">{</span></span>
<span id="cb2-30"><a href="#cb2-30" aria-hidden="true" tabindex="-1"></a>      <span class="co">// basic guarantee: vector lost its tail</span></span>
<span id="cb2-31"><a href="#cb2-31" aria-hidden="true" tabindex="-1"></a>      std<span class="op">::</span>destroy<span class="op">(</span>position <span class="op">+</span> <span class="dv">1</span>, end<span class="op">()</span> <span class="op">+</span> <span class="dv">1</span><span class="op">)</span>;</span>
<span id="cb2-32"><a href="#cb2-32" aria-hidden="true" tabindex="-1"></a>      end_ <span class="op">=</span> std<span class="op">::</span>to_address<span class="op">(</span>position<span class="op">)</span>;</span>
<span id="cb2-33"><a href="#cb2-33" aria-hidden="true" tabindex="-1"></a>      <span class="cf">throw</span>;</span>
<span id="cb2-34"><a href="#cb2-34" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb2-35"><a href="#cb2-35" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-36"><a href="#cb2-36" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span>end_;</span>
<span id="cb2-37"><a href="#cb2-37" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb2-38"><a href="#cb2-38" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> position;</span>
<span id="cb2-39"><a href="#cb2-39" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>

</div></td>
</tr>
</tbody>
</table>
<p>A few things are worth noting:</p>
<ul>
<li>The relocation-based implementation looks more complicated than the
assignment-based one, but in reality the complexity only stems from
exception handling. The algorithm is conceptually simpler because we
just relocate things around instead of creating artificial gaps that
contain moved-from objects, like in the assignment-based one.</li>
<li>Both implementations provide the basic exception safety guarantee,
but they provide it differently. After an exception, the
assignment-based implementation may leave elements in the <code class="sourceCode cpp"><span class="op">[</span>position, end<span class="op">())</span></code>
range in a moved-from state, and the vector size may or may not have
been incremented by 1. Whether this is actually the case or not depends
on which operation exactly throws. Either way, the user has no direct
means to know which elements have been left in a moved-from state. The
relocation-based implementation instead ends up with the elements in
<code class="sourceCode cpp"><span class="op">[</span>position, end<span class="op">())</span></code>
being erased from the vector. It’s unclear whether one behavior is
really superior over the other, but both are conforming.</li>
<li>There is no mention of <em>trivial</em> relocation in the
implementation. We relocate elements even when that is not equivalent to
<code class="sourceCode cpp">std<span class="op">::</span>memcpy</code>
(or whatever the language definition would be).</li>
<li>An implementation that considers the usage of move-assignment to be
part of the function’s API may want to preserve that behavior, in which
case the relocating code path may be guarded by something like P2786’s
<code class="sourceCode cpp">is_replaceable_v<span class="op">&lt;</span>T<span class="op">&gt;</span></code>
(and otherwise fallback to move-assignment). In the absence of
<code class="sourceCode cpp">is_replaceable</code>, a conservative
implementation could use <code class="sourceCode cpp">std<span class="op">::</span>is_trivially_copyable</code>
as a guard.</li>
</ul>
<h3 data-number="5.1.1" id="this-code-with-p2786-only"><span class="header-section-number">5.1.1</span> This code with P2786 only<a href="#this-code-with-p2786-only" class="self-link"></a></h3>
<p>Implementing a similar relocation-based <code class="sourceCode cpp">vector<span class="op">::</span>emplace</code>
with P2786’s facilities only but without the facilities in this paper
would produce the following code:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> <span class="op">...</span>Args<span class="op">&gt;</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> iterator</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>vector<span class="op">&lt;</span>T<span class="op">&gt;::</span>emplace<span class="op">(</span>iterator position, Args<span class="op">&amp;&amp;...</span> args<span class="op">)</span> <span class="op">{</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> <span class="op">[[</span><span class="at">unlikely</span><span class="op">]]</span> <span class="op">(</span>size<span class="op">()</span> <span class="op">==</span> capacity<span class="op">())</span> <span class="op">{</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>    <span class="co">// slow path where we grow the vector</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> relocate_via_assignment <span class="op">=</span> <span class="op">[&amp;]</span> <span class="op">{</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>    T tmp<span class="op">(</span>std<span class="op">::</span>forward<span class="op">&lt;</span>Args<span class="op">&gt;(</span>args<span class="op">)...)</span>;</span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Create a gap at the end by moving the last</span></span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a>    <span class="co">// element into the &quot;new last position&quot;.</span></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>construct_at<span class="op">(</span>std<span class="op">::</span>to_address<span class="op">(</span>end<span class="op">())</span>,</span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a>                      std<span class="op">::</span>move<span class="op">(</span>back<span class="op">()))</span>;</span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span>end_;</span>
<span id="cb3-16"><a href="#cb3-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-17"><a href="#cb3-17" aria-hidden="true" tabindex="-1"></a>    <span class="co">// The element before the last one is moved-from:</span></span>
<span id="cb3-18"><a href="#cb3-18" aria-hidden="true" tabindex="-1"></a>    <span class="co">// shift everything else by one position to the</span></span>
<span id="cb3-19"><a href="#cb3-19" aria-hidden="true" tabindex="-1"></a>    <span class="co">// right to open a gap at the insert location.</span></span>
<span id="cb3-20"><a href="#cb3-20" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>move_backward<span class="op">(</span>position, end<span class="op">()</span> <span class="op">-</span> <span class="dv">2</span>, end<span class="op">()</span> <span class="op">-</span> <span class="dv">1</span><span class="op">)</span>;</span>
<span id="cb3-21"><a href="#cb3-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-22"><a href="#cb3-22" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Now there&#39;s a gap at the insert location, move the</span></span>
<span id="cb3-23"><a href="#cb3-23" aria-hidden="true" tabindex="-1"></a>    <span class="co">// new element into it.</span></span>
<span id="cb3-24"><a href="#cb3-24" aria-hidden="true" tabindex="-1"></a>    <span class="op">*</span>position <span class="op">=</span> std<span class="op">::</span>move<span class="op">(</span>tmp<span class="op">)</span>;</span>
<span id="cb3-25"><a href="#cb3-25" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span>;</span>
<span id="cb3-26"><a href="#cb3-26" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-27"><a href="#cb3-27" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> <span class="op">(</span>position <span class="op">==</span> end<span class="op">())</span> <span class="op">{</span></span>
<span id="cb3-28"><a href="#cb3-28" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>construct_at<span class="op">(</span>std<span class="op">::</span>to_address<span class="op">(</span>position<span class="op">)</span>,</span>
<span id="cb3-29"><a href="#cb3-29" aria-hidden="true" tabindex="-1"></a>                      std<span class="op">::</span>forward<span class="op">&lt;</span>Args<span class="op">&gt;(</span>args<span class="op">)...)</span>;</span>
<span id="cb3-30"><a href="#cb3-30" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span>end_;</span>
<span id="cb3-31"><a href="#cb3-31" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb3-32"><a href="#cb3-32" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Create a gap inside the vector by relocating</span></span>
<span id="cb3-33"><a href="#cb3-33" aria-hidden="true" tabindex="-1"></a>    <span class="co">// everything to the right.</span></span>
<span id="cb3-34"><a href="#cb3-34" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="kw">constexpr</span> <span class="op">(</span>std<span class="op">::</span>is_trivially_relocatable_v<span class="op">&lt;</span>T<span class="op">&gt;)</span> <span class="op">{</span></span>
<span id="cb3-35"><a href="#cb3-35" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="kw">consteval</span> <span class="op">{</span></span>
<span id="cb3-36"><a href="#cb3-36" aria-hidden="true" tabindex="-1"></a>        relocate_via_assignment<span class="op">()</span>;</span>
<span id="cb3-37"><a href="#cb3-37" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb3-38"><a href="#cb3-38" aria-hidden="true" tabindex="-1"></a>        <span class="kw">union</span> <span class="op">{</span> T tmp; <span class="op">}</span>;</span>
<span id="cb3-39"><a href="#cb3-39" aria-hidden="true" tabindex="-1"></a>        std<span class="op">::</span>construct_at<span class="op">(</span>std<span class="op">::</span>addressof<span class="op">(</span>tmp<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>Args<span class="op">&gt;(</span>args<span class="op">)...)</span>;</span>
<span id="cb3-40"><a href="#cb3-40" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-41"><a href="#cb3-41" aria-hidden="true" tabindex="-1"></a>        std<span class="op">::</span>trivially_relocate<span class="op">(</span>std<span class="op">::</span>to_address<span class="op">(</span>position<span class="op">)</span>, std<span class="op">::</span>to_address<span class="op">(</span>end<span class="op">())</span>,</span>
<span id="cb3-42"><a href="#cb3-42" aria-hidden="true" tabindex="-1"></a>                                std<span class="op">::</span>to_address<span class="op">(</span>end<span class="op">())</span> <span class="op">+</span> <span class="dv">1</span><span class="op">)</span>;</span>
<span id="cb3-43"><a href="#cb3-43" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-44"><a href="#cb3-44" aria-hidden="true" tabindex="-1"></a>        <span class="co">// Trivially relocate the new value into the gap created above.</span></span>
<span id="cb3-45"><a href="#cb3-45" aria-hidden="true" tabindex="-1"></a>        std<span class="op">::</span>trivially_relocate<span class="op">(</span>std<span class="op">::</span>addressof<span class="op">(</span>tmp<span class="op">)</span>, std<span class="op">::</span>addressof<span class="op">(</span>tmp<span class="op">)</span> <span class="op">+</span> <span class="dv">1</span>,</span>
<span id="cb3-46"><a href="#cb3-46" aria-hidden="true" tabindex="-1"></a>                                std<span class="op">::</span>to_address<span class="op">(</span>position<span class="op">))</span>;</span>
<span id="cb3-47"><a href="#cb3-47" aria-hidden="true" tabindex="-1"></a>        <span class="op">++</span>end_;</span>
<span id="cb3-48"><a href="#cb3-48" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
<span id="cb3-49"><a href="#cb3-49" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb3-50"><a href="#cb3-50" aria-hidden="true" tabindex="-1"></a>      relocate_via_assignment<span class="op">()</span>;</span>
<span id="cb3-51"><a href="#cb3-51" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb3-52"><a href="#cb3-52" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb3-53"><a href="#cb3-53" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> position;</span>
<span id="cb3-54"><a href="#cb3-54" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<!--
TODO
Inserting in the middle of a `std::vector<std::string>` is roughly X times faster with relocation
than with assignments.

Measure and provide a link to the benchmarks (can use the libc++ branch)
-->
<h2 data-number="5.2" id="vectorerase"><span class="header-section-number">5.2</span> <code class="sourceCode cpp">vector<span class="op">::</span>erase</code><a href="#vectorerase" class="self-link"></a></h2>
<table>
<thead>
<tr class="header">
<th><div style="text-align:center">
<strong>Assignment based</strong>
</div></th>
<th><div style="text-align:center">
<strong>This paper</strong>
</div></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><div>

<div class="sourceCode" id="cb4"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> iterator</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>vector<span class="op">&lt;</span>T<span class="op">&gt;::</span>erase<span class="op">(</span>iterator first, iterator last<span class="op">)</span> <span class="op">{</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> <span class="op">(</span>first <span class="op">==</span> last<span class="op">)</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> last;</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> new_end <span class="op">=</span> std<span class="op">::</span>move<span class="op">(</span>last, end<span class="op">()</span>, first<span class="op">)</span>;</span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>  std<span class="op">::</span>destroy<span class="op">(</span>new_end, end<span class="op">())</span>;</span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a>  end_ <span class="op">-=</span> <span class="op">(</span>last <span class="op">-</span> first<span class="op">)</span>;</span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> first;</span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>

</div></td>
<td><div>

<div class="sourceCode" id="cb5"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> iterator</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>vector<span class="op">&lt;</span>T<span class="op">&gt;::</span>erase<span class="op">(</span>iterator first, iterator last<span class="op">)</span> <span class="op">{</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> <span class="op">(</span>first <span class="op">==</span> last<span class="op">)</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> last;</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>  <span class="co">// Destroy the range being erased and relocate the</span></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>  <span class="co">// tail of the vector into the created gap.</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>  std<span class="op">::</span>destroy<span class="op">(</span>first, last<span class="op">)</span>;</span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a>  <span class="cf">try</span> <span class="op">{</span></span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>uninitialized_relocate<span class="op">(</span>last, end<span class="op">()</span>, first<span class="op">)</span>;</span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span> <span class="cf">catch</span> <span class="op">(...)</span> <span class="op">{</span></span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a>    end_ <span class="op">=</span> std<span class="op">::</span>to_address<span class="op">(</span>first<span class="op">)</span>; <span class="co">// vector lost its tail</span></span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a>    <span class="cf">throw</span>;</span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb5-15"><a href="#cb5-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-16"><a href="#cb5-16" aria-hidden="true" tabindex="-1"></a>  end_ <span class="op">-=</span> <span class="op">(</span>last <span class="op">-</span> first<span class="op">)</span>;</span>
<span id="cb5-17"><a href="#cb5-17" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> first;</span>
<span id="cb5-18"><a href="#cb5-18" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>

</div></td>
</tr>
</tbody>
</table>
<p>Things worth noting:</p>
<ul>
<li>Again, there is no mention of <em>trivial</em> relocation above,
since we write the algorithm in term of general relocation.</li>
<li>Like for <code class="sourceCode cpp">vector<span class="op">::</span>emplace</code>,
an implementation that considers the usage of move-assignment to be part
of the function’s API may want to preserve that behavior by further
constraining the usage of relocation.</li>
<li>Pedantically, the relocation-based implementation violates an
exception constraint on <code class="sourceCode cpp">std<span class="op">::</span>vector<span class="op">::</span>erase</code>.
The current specification requires <code class="sourceCode cpp">vector<span class="op">::</span>erase</code> not
to throw an exception unless <code class="sourceCode cpp">T</code>’s
<em>move-assignment operator</em> throws. The implementation above can
also throw if the <em>move-constructor</em> throws. We view this as an
overspecification in the Standard that could be relaxed – this is
probably an artifact of the fact that implementations were assumed to
use assignment. To make the definition above pedantically correct, we
should only use relocation when <code class="sourceCode cpp">is_nothrow_move_constructible<span class="op">&lt;</span>T<span class="op">&gt;</span></code>
is satisfied, and otherwise use assignment.</li>
</ul>
<!--
TODO:

Erasing in the middle of a `std::vector<std::string>` is roughly X times faster with relocation than with
assignments.
-->
<h2 data-number="5.3" id="vectoremplace_back-vectorpush_back"><span class="header-section-number">5.3</span> <code class="sourceCode cpp">vector<span class="op">::</span>emplace_back</code>
/ <code class="sourceCode cpp">vector<span class="op">::</span>push_back</code><a href="#vectoremplace_back-vectorpush_back" class="self-link"></a></h2>
<p>Note that the vector growth policy presented here is more naive than
what
<code class="sourceCode cpp">std<span class="op">::</span>vector</code>
typically does. Also keep in mind that we must provide the strong
exception safety guarantee here.</p>
<table>
<thead>
<tr class="header">
<th><div style="text-align:center">
<strong>Move-construction based</strong>
</div></th>
<th><div style="text-align:center">
<strong>This paper</strong>
</div></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><div>

<div class="sourceCode" id="cb6"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> <span class="op">...</span>Args<span class="op">&gt;</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> reference</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>vector<span class="op">&lt;</span>T<span class="op">&gt;::</span>emplace_back<span class="op">(</span>Args<span class="op">&amp;&amp;</span> <span class="op">...</span>args<span class="op">)</span> <span class="op">{</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> <span class="op">[[</span><span class="at">likely</span><span class="op">]]</span> <span class="op">(</span>size<span class="op">()</span> <span class="op">&lt;</span> capacity<span class="op">())</span> <span class="op">{</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>construct_at<span class="op">(</span>std<span class="op">::</span>to_address<span class="op">(</span>end<span class="op">())</span>,</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>                      std<span class="op">::</span>forward<span class="op">&lt;</span>Args<span class="op">&gt;(</span>args<span class="op">)...)</span>;</span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span>end_;</span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> back<span class="op">()</span>;</span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a>  <span class="co">// Move or copy all the elements into a large</span></span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true" tabindex="-1"></a>  <span class="co">// enough vector.</span></span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true" tabindex="-1"></a>  vector<span class="op">&lt;</span>T<span class="op">&gt;</span> tmp;</span>
<span id="cb6-14"><a href="#cb6-14" aria-hidden="true" tabindex="-1"></a>  tmp<span class="op">.</span>reserve<span class="op">((</span>size<span class="op">()</span> <span class="op">+</span> <span class="dv">1</span><span class="op">)</span> <span class="op">*</span> <span class="dv">2</span><span class="op">)</span>;</span>
<span id="cb6-15"><a href="#cb6-15" aria-hidden="true" tabindex="-1"></a>  std<span class="op">::</span>construct_at<span class="op">(</span>tmp<span class="op">.</span>begin_ <span class="op">+</span> size<span class="op">()</span>,</span>
<span id="cb6-16"><a href="#cb6-16" aria-hidden="true" tabindex="-1"></a>                    std<span class="op">::</span>forward<span class="op">&lt;</span>Args<span class="op">&gt;(</span>args<span class="op">)...)</span>;</span>
<span id="cb6-17"><a href="#cb6-17" aria-hidden="true" tabindex="-1"></a>  <span class="co">// guard destruction in case of exception</span></span>
<span id="cb6-18"><a href="#cb6-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-19"><a href="#cb6-19" aria-hidden="true" tabindex="-1"></a>  <span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span><span class="op">&amp;</span> element <span class="op">:</span> <span class="op">*</span><span class="kw">this</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb6-20"><a href="#cb6-20" aria-hidden="true" tabindex="-1"></a>    <span class="op">[[</span><span class="at">assume</span><span class="op">(</span><span class="at">tmp</span><span class="op">.</span><span class="at">size</span><span class="op">()</span><span class="at"> </span><span class="op">&lt;</span><span class="at"> tmp</span><span class="op">.</span><span class="at">capacity</span><span class="op">())]]</span>;</span>
<span id="cb6-21"><a href="#cb6-21" aria-hidden="true" tabindex="-1"></a>    tmp<span class="op">.</span>emplace_back<span class="op">(</span>std<span class="op">::</span>move_if_noexcept<span class="op">(</span>element<span class="op">))</span>;</span>
<span id="cb6-22"><a href="#cb6-22" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb6-23"><a href="#cb6-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-24"><a href="#cb6-24" aria-hidden="true" tabindex="-1"></a>  <span class="co">// disengage guard</span></span>
<span id="cb6-25"><a href="#cb6-25" aria-hidden="true" tabindex="-1"></a>  <span class="op">++</span>tmp<span class="op">.</span>end_;</span>
<span id="cb6-26"><a href="#cb6-26" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-27"><a href="#cb6-27" aria-hidden="true" tabindex="-1"></a>  swap<span class="op">(</span>tmp<span class="op">)</span>;</span>
<span id="cb6-28"><a href="#cb6-28" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> back<span class="op">()</span>;</span>
<span id="cb6-29"><a href="#cb6-29" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>

</div></td>
<td><div>

<div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> <span class="op">...</span>Args<span class="op">&gt;</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> reference</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>vector<span class="op">&lt;</span>T<span class="op">&gt;::</span>emplace_back<span class="op">(</span>Args<span class="op">&amp;&amp;</span> <span class="op">...</span>args<span class="op">)</span> <span class="op">{</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> <span class="op">[[</span><span class="at">likely</span><span class="op">]]</span> <span class="op">(</span>size<span class="op">()</span> <span class="op">&lt;</span> capacity<span class="op">())</span> <span class="op">{</span></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>construct_at<span class="op">(</span>std<span class="op">::</span>to_address<span class="op">(</span>end<span class="op">())</span>,</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>                      std<span class="op">::</span>forward<span class="op">&lt;</span>Args<span class="op">&gt;(</span>args<span class="op">)...)</span>;</span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span>end_;</span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> back<span class="op">()</span>;</span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a>  <span class="co">// Relocate all the elements into a large enough vector,</span></span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a>  <span class="co">// or copy if moving might throw.</span></span>
<span id="cb7-13"><a href="#cb7-13" aria-hidden="true" tabindex="-1"></a>  vector<span class="op">&lt;</span>T<span class="op">&gt;</span> tmp;</span>
<span id="cb7-14"><a href="#cb7-14" aria-hidden="true" tabindex="-1"></a>  tmp<span class="op">.</span>reserve<span class="op">((</span>size<span class="op">()</span> <span class="op">+</span> <span class="dv">1</span><span class="op">)</span> <span class="op">*</span> <span class="dv">2</span><span class="op">)</span>;</span>
<span id="cb7-15"><a href="#cb7-15" aria-hidden="true" tabindex="-1"></a>  std<span class="op">::</span>construct_at<span class="op">(</span>tmp<span class="op">.</span>begin_ <span class="op">+</span> size<span class="op">()</span>,</span>
<span id="cb7-16"><a href="#cb7-16" aria-hidden="true" tabindex="-1"></a>                    std<span class="op">::</span>forward<span class="op">&lt;</span>Args<span class="op">&gt;(</span>args<span class="op">)...)</span>;</span>
<span id="cb7-17"><a href="#cb7-17" aria-hidden="true" tabindex="-1"></a>  <span class="co">// guard destruction in case of exception</span></span>
<span id="cb7-18"><a href="#cb7-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-19"><a href="#cb7-19" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> <span class="kw">constexpr</span> <span class="op">(</span>is_nothrow_relocatable_v<span class="op">&lt;</span>T<span class="op">&gt;)</span> <span class="op">{</span> <span class="co">// from P2786</span></span>
<span id="cb7-20"><a href="#cb7-20" aria-hidden="true" tabindex="-1"></a>    tmp<span class="op">.</span>end_ <span class="op">=</span> std<span class="op">::</span>uninitialized_relocate<span class="op">(</span>begin<span class="op">()</span>, end<span class="op">()</span>,</span>
<span id="cb7-21"><a href="#cb7-21" aria-hidden="true" tabindex="-1"></a>                                           tmp<span class="op">.</span>begin_<span class="op">)</span>;</span>
<span id="cb7-22"><a href="#cb7-22" aria-hidden="true" tabindex="-1"></a>    end_ <span class="op">=</span> begin_;</span>
<span id="cb7-23"><a href="#cb7-23" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb7-24"><a href="#cb7-24" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span><span class="op">&amp;</span> element <span class="op">:</span> <span class="op">*</span><span class="kw">this</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb7-25"><a href="#cb7-25" aria-hidden="true" tabindex="-1"></a>      <span class="op">[[</span><span class="at">assume</span><span class="op">(</span><span class="at">tmp</span><span class="op">.</span><span class="at">size</span><span class="op">()</span><span class="at"> </span><span class="op">&lt;</span><span class="at"> tmp</span><span class="op">.</span><span class="at">capacity</span><span class="op">())]]</span>;</span>
<span id="cb7-26"><a href="#cb7-26" aria-hidden="true" tabindex="-1"></a>      tmp<span class="op">.</span>emplace_back<span class="op">(</span>std<span class="op">::</span>move_if_noexcept<span class="op">(</span>element<span class="op">))</span>;</span>
<span id="cb7-27"><a href="#cb7-27" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb7-28"><a href="#cb7-28" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb7-29"><a href="#cb7-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-30"><a href="#cb7-30" aria-hidden="true" tabindex="-1"></a>  <span class="co">// disengage guard</span></span>
<span id="cb7-31"><a href="#cb7-31" aria-hidden="true" tabindex="-1"></a>  <span class="op">++</span>tmp<span class="op">.</span>end_;</span>
<span id="cb7-32"><a href="#cb7-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-33"><a href="#cb7-33" aria-hidden="true" tabindex="-1"></a>  swap<span class="op">(</span>tmp<span class="op">)</span>;</span>
<span id="cb7-34"><a href="#cb7-34" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> back<span class="op">()</span>;</span>
<span id="cb7-35"><a href="#cb7-35" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>

</div></td>
</tr>
</tbody>
</table>
<p>Things worth noting:</p>
<ul>
<li>Again, there is no mention of <em>trivial</em> relocation: we write
the algorithm based on general relocation.</li>
<li>The above implementation omits to support the case where
<code class="sourceCode cpp">args<span class="op">...</span></code> is
in fact a single object located inside the vector we’re inserting in.
Supporting that essentially requires creating a temporary value or
constructing the new element before we start moving from the current
vector, but does not meaningfully change the code.</li>
<li>We use <code class="sourceCode cpp">std<span class="op">::</span>move_if_noexcept</code>
even in the case of a potentially throwing move constructor because we
must handle non-copyable types with a potentially throwing move
constructor (in which case the strong exception safety guarantee is
waived).</li>
</ul>
<!--
TODO
Performance comparison
-->
<h1 data-number="6" id="compatibility-with-relocation-proposals"><span class="header-section-number">6</span> Compatibility with relocation
proposals<a href="#compatibility-with-relocation-proposals" class="self-link"></a></h1>
<p>The current version of the proposal is based on <a href="https://wg21.link/P2786">P2786</a> trivial relocation library
APIs, as approved by LEWG during the 2025-01-14 meeting.</p>
<p>In general it’s worth noting that our specification can be easily
extended to a future notion of language relocation; the algorithms
themselves won’t need to change; only the proposed exposition-only
entities will need centralized fixes. We consider this a major feature
of the proposed design.</p>
<h1 data-number="7" id="wording"><span class="header-section-number">7</span> Wording<a href="#wording" class="self-link"></a></h1>
<p><strong>Note</strong>: the following wording assumes that P2786R11
(as approved by LEWG, see above) has already been merged.</p>
<h2 data-number="7.1" id="version.syn"><span class="header-section-number">7.1</span> [version.syn]<a href="#version.syn" class="self-link"></a></h2>
<p>Modify the feature-testing macro for
<code class="sourceCode cpp">__cpp_lib_raw_memory_algorithms</code> to
match the date of adoption of the present proposal:</p>
<div>
<div class="sourceCode" id="cb8"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="st">-#define __cpp_lib_raw_memory_algorithms             202411L // also in &lt;memory&gt;</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="va">+#define __cpp_lib_raw_memory_algorithms             ??????L // also in &lt;memory&gt;</span></span></code></pre></div>
</div>
<h2 data-number="7.2" id="algorithms.requirements"><span class="header-section-number">7.2</span> [algorithms.requirements]<a href="#algorithms.requirements" class="self-link"></a></h2>
<p>Modify <span>26.2
<a href="https://wg21.link/algorithms.requirements">[algorithms.requirements]</a></span>
as shown:</p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">(4.?)</a></span> If
an algorithm’s template parameter is named
<code class="sourceCode cpp">InputIterator</code>,
<code class="sourceCode cpp">InputIterator1</code>, or
<code class="sourceCode cpp">InputIterator2</code>, the template
argument shall meet the <em>Cpp17InputIterator</em> requirements
([input.iterators]).</li>
<li><span class="marginalizedparent"><a class="marginalized">(4.?)</a></span> If
an algorithm’s template parameter is named
<code class="sourceCode cpp">OutputIterator</code>,
<code class="sourceCode cpp">OutputIterator1</code>, or
<code class="sourceCode cpp">OutputIterator2</code>, the template
argument shall meet the <em>Cpp17OutputIterator</em> requirements
([output.iterators]).</li>
<li><span class="marginalizedparent"><a class="marginalized">(4.?)</a></span> If
an algorithm’s template parameter is named
<code class="sourceCode cpp">ForwardIterator</code>,
<code class="sourceCode cpp">ForwardIterator1</code>,
<code class="sourceCode cpp">ForwardIterator2</code>, <span class="rm" style="color: #bf0303"><del>or</del></span>
<code class="sourceCode cpp">NoThrowForwardIterator</code>, <span class="add" style="color: #006e28"><ins><span><code class="sourceCode default">NoThrowForwardIterator1</code></span>,
or
<span><code class="sourceCode default">NoThrowForwardIterator2</code></span>,</ins></span>
the template argument shall meet the <em>Cpp17ForwardIterator</em>
requirements ([forward.iterators]) if it is required to be a mutable
iterator, or model <code class="sourceCode cpp">forward_iterator</code>
([iterator.concept.forward]) otherwise.</li>
<li><span class="marginalizedparent"><a class="marginalized">(4.?)</a></span>
<span class="rm" style="color: #bf0303"><del>If an algorithm’s template
parameter is named
<span><code class="sourceCode default">NoThrowForwardIterator</code></span>,
the template argument is also required to have the property that no
exceptions are thrown from increment, assignment, or comparison of, or
indirection through, valid iterators.</del></span></li>
<li><span class="marginalizedparent"><a class="marginalized">(4.?)</a></span> If
an algorithm’s template parameter is named
<code class="sourceCode cpp">BidirectionalIterator</code>,
<code class="sourceCode cpp">BidirectionalIterator1</code>, <span class="rm" style="color: #bf0303"><del>or</del></span>
<code class="sourceCode cpp">BidirectionalIterator2</code>, <span class="add" style="color: #006e28"><ins><span><code class="sourceCode default">NoThrowBidirectionalIterator1</code></span>,
or
<span><code class="sourceCode default">NoThrowBidirectionalIterator2</code></span>,</ins></span>
the template argument shall meet the <em>Cpp17BidirectionalIterator</em>
requirements ([bidirectional.iterators]) if it is required to be a
mutable iterator, or model
<code class="sourceCode cpp">bidirectional_iterator</code>
([iterator.concept.bidir]) otherwise.</li>
<li><span class="marginalizedparent"><a class="marginalized">(4.?)</a></span> If
an algorithm’s template parameter is named
<code class="sourceCode cpp">RandomAccessIterator</code>,
<code class="sourceCode cpp">RandomAccessIterator1</code>, or
<code class="sourceCode cpp">RandomAccessIterator2</code>, the template
argument shall meet the <em>Cpp17RandomAccessIterator</em> requirements
([random.access.iterators]) if it is required to be a mutable iterator,
or model <code class="sourceCode cpp">random_access_iterator</code>
([iterator.concept.random.access]) otherwise.</li>
<li><span class="marginalizedparent"><a class="marginalized">(4.?)</a></span>
<span class="add" style="color: #006e28"><ins>If an algorithm’s template
parameter is named
<span><code class="sourceCode default">NoThrowForwardIterator</code></span>,
<span><code class="sourceCode default">NoThrowForwardIterator1</code></span>,
<span><code class="sourceCode default">NoThrowForwardIterator2</code></span>,
<span><code class="sourceCode default">NoThrowBidirectionalIterator1</code></span>,
or
<span><code class="sourceCode default">NoThrowBidirectionalIterator2</code></span>,
the template argument is also required to have the property that no
exceptions are thrown from increment, assignment, or comparison of, or
indirection through, valid iterators.</ins></span></li>
</ul>
<h2 data-number="7.3" id="specialized.algorithms.general"><span class="header-section-number">7.3</span>
[specialized.algorithms.general]<a href="#specialized.algorithms.general" class="self-link"></a></h2>
<p>Modify <span>26.11.1
<a href="https://wg21.link/specialized.algorithms.general">[specialized.algorithms.general]</a></span>
as shown:</p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">2</a></span> Unless
otherwise specified, if an exception is thrown in the following
algorithms, objects constructed by a placement <em>new-expression</em>
(<span>7.6.2.8
<a href="https://wg21.link/expr.new">[expr.new]</a></span>) <span class="add" style="color: #006e28"><ins>or whose lifetime has started
due to a call to
<span><code class="sourceCode default">trivially_relocate</code></span></ins></span>
are destroyed in an unspecified order before allowing the exception to
propagate.</li>
</ul>
<p>…</p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">4</a></span> Some
algorithms specified in [specialized.algorithms] make use of the <span class="rm" style="color: #bf0303"><del>exposition-only function template
<em><span><code class="sourceCode default">voidify</code></span></em></del></span>
<span class="add" style="color: #006e28"><ins>following exposition-only
entities</ins></span>:</li>
</ul>
<div>
<div class="sourceCode" id="cb9"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a>template&lt;class T&gt;</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>  constexpr void* <em>voidify</em>(T&amp; obj) noexcept {</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>    return addressof(obj);</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a><span class="va">+template&lt;class Source, class Dest&gt;</span></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a><span class="va">+ concept <em>relocatable-from</em> =</span></span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a><span class="va">+   same_as&lt;Source, Dest&gt; &amp;&amp;</span></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a><span class="va">+   (move_constructible&lt;Dest&gt; || is_trivially_relocatable_v&lt;Dest&gt;);</span></span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a><span class="va">+</span></span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a><span class="va">+template&lt;class T&gt;</span></span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true" tabindex="-1"></a><span class="va">+ requires move_constructible&lt;T&gt;</span></span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true" tabindex="-1"></a><span class="va">+  constexpr T* <em>relocate-via-move-and-destroy</em>(T* dest, T* source) {</span></span>
<span id="cb9-14"><a href="#cb9-14" aria-hidden="true" tabindex="-1"></a><span class="va">+    struct guard { T *t; ~guard() { destroy_at(t); } } g(source);</span></span>
<span id="cb9-15"><a href="#cb9-15" aria-hidden="true" tabindex="-1"></a><span class="va">+    return ::new (<em>voidify</em>(*dest)) T(std::move(*source));</span></span>
<span id="cb9-16"><a href="#cb9-16" aria-hidden="true" tabindex="-1"></a><span class="va">+  }</span></span>
<span id="cb9-17"><a href="#cb9-17" aria-hidden="true" tabindex="-1"></a><span class="va">+</span></span>
<span id="cb9-18"><a href="#cb9-18" aria-hidden="true" tabindex="-1"></a><span class="va">+template&lt;class T&gt;</span></span>
<span id="cb9-19"><a href="#cb9-19" aria-hidden="true" tabindex="-1"></a><span class="va">+ requires <em>relocatable-from</em>&lt;T, T&gt;</span></span>
<span id="cb9-20"><a href="#cb9-20" aria-hidden="true" tabindex="-1"></a><span class="va">+  constexpr T* <em>relocate-at</em>(T* dest, T* source)</span></span>
<span id="cb9-21"><a href="#cb9-21" aria-hidden="true" tabindex="-1"></a><span class="va">+    noexcept(is_nothrow_relocatable_v&lt;T&gt;)</span></span>
<span id="cb9-22"><a href="#cb9-22" aria-hidden="true" tabindex="-1"></a><span class="va">+  {</span></span>
<span id="cb9-23"><a href="#cb9-23" aria-hidden="true" tabindex="-1"></a><span class="va">+    if constexpr (is_trivially_relocatable_v&lt;T&gt; &amp;&amp; is_move_constructible_v&lt;T&gt;) {</span></span>
<span id="cb9-24"><a href="#cb9-24" aria-hidden="true" tabindex="-1"></a><span class="va">+      if consteval {</span></span>
<span id="cb9-25"><a href="#cb9-25" aria-hidden="true" tabindex="-1"></a><span class="va">+        return <em>relocate-via-move-and-destroy</em>(dest, source);</span></span>
<span id="cb9-26"><a href="#cb9-26" aria-hidden="true" tabindex="-1"></a><span class="va">+      } else {</span></span>
<span id="cb9-27"><a href="#cb9-27" aria-hidden="true" tabindex="-1"></a><span class="va">+        return trivially_relocate(source, source + 1, dest);</span></span>
<span id="cb9-28"><a href="#cb9-28" aria-hidden="true" tabindex="-1"></a><span class="va">+      }</span></span>
<span id="cb9-29"><a href="#cb9-29" aria-hidden="true" tabindex="-1"></a><span class="va">+    } else if constexpr (is_trivially_relocatable_v&lt;T&gt;) {</span></span>
<span id="cb9-30"><a href="#cb9-30" aria-hidden="true" tabindex="-1"></a><span class="va">+      return trivially_relocate(source, source + 1, dest);</span></span>
<span id="cb9-31"><a href="#cb9-31" aria-hidden="true" tabindex="-1"></a><span class="va">+    } else {</span></span>
<span id="cb9-32"><a href="#cb9-32" aria-hidden="true" tabindex="-1"></a><span class="va">+      return <em>relocate-via-move-and-destroy</em>(dest, source);</span></span>
<span id="cb9-33"><a href="#cb9-33" aria-hidden="true" tabindex="-1"></a><span class="va">+    }</span></span>
<span id="cb9-34"><a href="#cb9-34" aria-hidden="true" tabindex="-1"></a><span class="va">+  }</span></span></code></pre></div>
</div>
<!--
TODO

Design questions for relocatable-from:
- Should we spell out the prerequisites? 1. source != dest, 2. T is complete
- Should it unconditionally destroy the source? For the single element relocate, there's a recovery option.
-->
<hr />
<h2 data-number="7.4" id="special.mem.concepts"><span class="header-section-number">7.4</span> [special.mem.concepts]<a href="#special.mem.concepts" class="self-link"></a></h2>
<p>Add at the end of <span>26.11.2
<a href="https://wg21.link/special.mem.concepts">[special.mem.concepts]</a></span>:</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> I<span class="op">&gt;</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a><span class="kw">concept</span> <em>nothrow-bidirectional-iterator</em> <span class="op">=</span> <span class="co">// exposition only</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>  <em>nothrow-forward-iterator</em><span class="op">&lt;</span>I<span class="op">&gt;</span> <span class="op">&amp;&amp;</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>  bidirectional_iterator<span class="op">&lt;</span>I<span class="op">&gt;</span> <span class="op">&amp;&amp;</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>  <em>nothrow-sentinel-for</em><span class="op">&lt;</span>I, I<span class="op">&gt;</span>;</span></code></pre></div>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">?</a></span>
[<em>Note</em>: This concept allows some
<code class="sourceCode cpp">bidirectional_iterator</code>
([iterator.concept.bidir]) operations to throw exceptions. — <em>end
note</em>]</li>
</ul>
<div class="sourceCode" id="cb11"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> R<span class="op">&gt;</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a><span class="kw">concept</span> <em>nothrow-bidirectional-range</em> <span class="op">=</span> <span class="co">// exposition only</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>  <em>nothrow-forward-range</em><span class="op">&lt;</span>R<span class="op">&gt;</span> <span class="op">&amp;&amp;</span></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>  <em>nothrow-bidirectional-iterator</em><span class="op">&lt;</span>iterator_t<span class="op">&lt;</span>R<span class="op">&gt;&gt;</span>;</span></code></pre></div>
<h2 data-number="7.5" id="memory.syn"><span class="header-section-number">7.5</span> [memory.syn]<a href="#memory.syn" class="self-link"></a></h2>
<p>In <span>20.2.2
<a href="https://wg21.link/memory.syn">[memory.syn]</a></span>, add to
the <code class="sourceCode cpp"><span class="op">&lt;</span>memory<span class="op">&gt;</span></code>
header synopsis (before <code class="sourceCode cpp"><span class="op">[</span>unique<span class="op">.</span>ptr<span class="op">]</span></code>):</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> NoThrowForwardIterator1, <span class="kw">class</span> NoThrowForwardIterator2<span class="op">&gt;</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> NoThrowForwardIterator2</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>    uninitialized_relocate<span class="op">(</span>NoThrowForwardIterator1 first,    <span class="co">// freestanding</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>                           NoThrowForwardIterator1 last,</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>                           NoThrowForwardIterator2 result<span class="op">)</span>;</span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> ExecutionPolicy, <span class="kw">class</span> NoThrowForwardIterator1, <span class="kw">class</span> NoThrowForwardIterator2<span class="op">&gt;</span></span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> NoThrowForwardIterator2</span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a>    uninitialized_relocate<span class="op">(</span>ExecutionPolicy<span class="op">&amp;&amp;</span> exec,    <span class="co">// see [algorithms.parallel.overloads]</span></span>
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a>                           NoThrowForwardIterator1 first,</span>
<span id="cb12-11"><a href="#cb12-11" aria-hidden="true" tabindex="-1"></a>                           NoThrowForwardIterator1 last,</span>
<span id="cb12-12"><a href="#cb12-12" aria-hidden="true" tabindex="-1"></a>                           NoThrowForwardIterator2 result<span class="op">)</span>;</span>
<span id="cb12-13"><a href="#cb12-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-14"><a href="#cb12-14" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> NoThrowForwardIterator1, <span class="kw">class</span> Size, <span class="kw">class</span> NoThrowForwardIterator2<span class="op">&gt;</span></span>
<span id="cb12-15"><a href="#cb12-15" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> pair<span class="op">&lt;</span>NoThrowForwardIterator1, NoThrowForwardIterator2<span class="op">&gt;</span></span>
<span id="cb12-16"><a href="#cb12-16" aria-hidden="true" tabindex="-1"></a>    uninitialized_relocate_n<span class="op">(</span>NoThrowForwardIterator1 first,    <span class="co">// freestanding</span></span>
<span id="cb12-17"><a href="#cb12-17" aria-hidden="true" tabindex="-1"></a>                             Size n,</span>
<span id="cb12-18"><a href="#cb12-18" aria-hidden="true" tabindex="-1"></a>                             NoThrowForwardIterator2 result<span class="op">)</span>;</span>
<span id="cb12-19"><a href="#cb12-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-20"><a href="#cb12-20" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> ExecutionPolicy, <span class="kw">class</span> NoThrowForwardIterator1, <span class="kw">class</span> Size, <span class="kw">class</span> NoThrowForwardIterator2<span class="op">&gt;</span></span>
<span id="cb12-21"><a href="#cb12-21" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> pair<span class="op">&lt;</span>NoThrowForwardIterator1, NoThrowForwardIterator2<span class="op">&gt;</span></span>
<span id="cb12-22"><a href="#cb12-22" aria-hidden="true" tabindex="-1"></a>    uninitialized_relocate_n<span class="op">(</span>ExecutionPolicy<span class="op">&amp;&amp;</span> exec,    <span class="co">// see [algorithms.parallel.overloads]</span></span>
<span id="cb12-23"><a href="#cb12-23" aria-hidden="true" tabindex="-1"></a>                             NoThrowForwardIterator1 first,</span>
<span id="cb12-24"><a href="#cb12-24" aria-hidden="true" tabindex="-1"></a>                             Size n,</span>
<span id="cb12-25"><a href="#cb12-25" aria-hidden="true" tabindex="-1"></a>                             NoThrowForwardIterator2 result<span class="op">)</span>;</span>
<span id="cb12-26"><a href="#cb12-26" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-27"><a href="#cb12-27" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> NoThrowBidirectionalIterator1, <span class="kw">class</span> NoThrowBidirectionalIterator2<span class="op">&gt;</span></span>
<span id="cb12-28"><a href="#cb12-28" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> NoThrowBidirectionalIterator2</span>
<span id="cb12-29"><a href="#cb12-29" aria-hidden="true" tabindex="-1"></a>    uninitialized_relocate_backward<span class="op">(</span>NoThrowBidirectionalIterator1 first,    <span class="co">// freestanding</span></span>
<span id="cb12-30"><a href="#cb12-30" aria-hidden="true" tabindex="-1"></a>                                    NoThrowBidirectionalIterator1 last,</span>
<span id="cb12-31"><a href="#cb12-31" aria-hidden="true" tabindex="-1"></a>                                    NoThrowBidirectionalIterator2 result<span class="op">)</span>;</span>
<span id="cb12-32"><a href="#cb12-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-33"><a href="#cb12-33" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> ExecutionPolicy, <span class="kw">class</span> NoThrowBidirectionalIterator1, <span class="kw">class</span> NoThrowBidirectionalIterator2<span class="op">&gt;</span></span>
<span id="cb12-34"><a href="#cb12-34" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> NoThrowBidirectionalIterator2</span>
<span id="cb12-35"><a href="#cb12-35" aria-hidden="true" tabindex="-1"></a>    uninitialized_relocate_backward<span class="op">(</span>ExecutionPolicy<span class="op">&amp;&amp;</span> exec, <span class="co">// see [algorithms.parallel.overloads]</span></span>
<span id="cb12-36"><a href="#cb12-36" aria-hidden="true" tabindex="-1"></a>                                    NoThrowBidirectionalIterator1 first,</span>
<span id="cb12-37"><a href="#cb12-37" aria-hidden="true" tabindex="-1"></a>                                    NoThrowBidirectionalIterator1 last,</span>
<span id="cb12-38"><a href="#cb12-38" aria-hidden="true" tabindex="-1"></a>                                    NoThrowBidirectionalIterator2 result<span class="op">)</span>;</span>
<span id="cb12-39"><a href="#cb12-39" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-40"><a href="#cb12-40" aria-hidden="true" tabindex="-1"></a><span class="kw">namespace</span> ranges <span class="op">{</span></span>
<span id="cb12-41"><a href="#cb12-41" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> I, <span class="kw">class</span> O<span class="op">&gt;</span></span>
<span id="cb12-42"><a href="#cb12-42" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> uninitialized_relocate_result <span class="op">=</span> in_out_result<span class="op">&lt;</span>I, O<span class="op">&gt;</span>;    <span class="co">// freestanding</span></span>
<span id="cb12-43"><a href="#cb12-43" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-44"><a href="#cb12-44" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><em>nothrow-forward-iterator</em> I, <em>nothrow-sentinel-for</em><span class="op">&lt;</span>I<span class="op">&gt;</span> S1,</span>
<span id="cb12-45"><a href="#cb12-45" aria-hidden="true" tabindex="-1"></a>           <em>nothrow-forward-iterator</em> O, <em>nothrow-sentinel-for</em><span class="op">&lt;</span>O<span class="op">&gt;</span> S2<span class="op">&gt;</span></span>
<span id="cb12-46"><a href="#cb12-46" aria-hidden="true" tabindex="-1"></a>    <span class="kw">requires</span> <em>relocatable-from</em><span class="op">&lt;</span>iter_value_t<span class="op">&lt;</span>I<span class="op">&gt;</span>, iter_value_t<span class="op">&lt;</span>O<span class="op">&gt;&gt;</span></span>
<span id="cb12-47"><a href="#cb12-47" aria-hidden="true" tabindex="-1"></a>      <span class="kw">constexpr</span> uninitialized_relocate_result<span class="op">&lt;</span>I, O<span class="op">&gt;</span></span>
<span id="cb12-48"><a href="#cb12-48" aria-hidden="true" tabindex="-1"></a>        uninitialized_relocate<span class="op">(</span>I ifirst, S1 ilast, O ofirst, S2 olast<span class="op">)</span>;    <span class="co">// freestanding</span></span>
<span id="cb12-49"><a href="#cb12-49" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-50"><a href="#cb12-50" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><em>nothrow-forward-range</em> IR, <em>nothrow-forward_range</em><span class="op">&lt;</span>I<span class="op">&gt;</span> OR<span class="op">&gt;</span>,</span>
<span id="cb12-51"><a href="#cb12-51" aria-hidden="true" tabindex="-1"></a>    <span class="kw">requires</span> <em>relocatable-from</em><span class="op">&lt;</span>range_value_t<span class="op">&lt;</span>IR<span class="op">&gt;</span>, range_value_t<span class="op">&lt;</span>OR<span class="op">&gt;&gt;</span></span>
<span id="cb12-52"><a href="#cb12-52" aria-hidden="true" tabindex="-1"></a>      <span class="kw">constexpr</span> uninitialized_relocate_result<span class="op">&lt;</span>borrowed_iterator_t<span class="op">&lt;</span>IR<span class="op">&gt;</span>, borrowed_iterator_t<span class="op">&lt;</span>OR<span class="op">&gt;&gt;</span></span>
<span id="cb12-53"><a href="#cb12-53" aria-hidden="true" tabindex="-1"></a>        uninitialized_relocate<span class="op">(</span>IR<span class="op">&amp;&amp;</span> in_range, OR<span class="op">&amp;&amp;</span> out_range<span class="op">)</span>;    <span class="co">// freestanding</span></span>
<span id="cb12-54"><a href="#cb12-54" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-55"><a href="#cb12-55" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> I, <span class="kw">class</span> O<span class="op">&gt;</span></span>
<span id="cb12-56"><a href="#cb12-56" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> uninitialized_relocate_n_result <span class="op">=</span> in_out_result<span class="op">&lt;</span>I, O<span class="op">&gt;</span>;    <span class="co">// freestanding</span></span>
<span id="cb12-57"><a href="#cb12-57" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-58"><a href="#cb12-58" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><em>nothrow-forward-iterator</em> I,</span>
<span id="cb12-59"><a href="#cb12-59" aria-hidden="true" tabindex="-1"></a>           <em>nothrow-forward-iterator</em> O, <em>nothrow-sentinel-for</em><span class="op">&lt;</span>O<span class="op">&gt;</span> S<span class="op">&gt;</span></span>
<span id="cb12-60"><a href="#cb12-60" aria-hidden="true" tabindex="-1"></a>    <span class="kw">requires</span> <em>relocatable-from</em><span class="op">&lt;</span>iter_value_t<span class="op">&lt;</span>I<span class="op">&gt;</span>, iter_value_t<span class="op">&lt;</span>O<span class="op">&gt;&gt;</span></span>
<span id="cb12-61"><a href="#cb12-61" aria-hidden="true" tabindex="-1"></a>      <span class="kw">constexpr</span> uninitialized_relocate_n_result<span class="op">&lt;</span>I, O<span class="op">&gt;</span></span>
<span id="cb12-62"><a href="#cb12-62" aria-hidden="true" tabindex="-1"></a>        uninitialized_relocate_n<span class="op">(</span>I ifirst, iter_difference_t<span class="op">&lt;</span>I<span class="op">&gt;</span> n, O ofirst, S olast<span class="op">)</span>;    <span class="co">// freestanding</span></span>
<span id="cb12-63"><a href="#cb12-63" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-64"><a href="#cb12-64" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> I, <span class="kw">class</span> O<span class="op">&gt;</span></span>
<span id="cb12-65"><a href="#cb12-65" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> uninitialized_relocate_backward_result <span class="op">=</span> in_out_result<span class="op">&lt;</span>I, O<span class="op">&gt;</span>;    <span class="co">// freestanding</span></span>
<span id="cb12-66"><a href="#cb12-66" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-67"><a href="#cb12-67" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><em>nothrow-bidirectional-iterator</em> I, <em>nothrow-sentinel-for</em><span class="op">&lt;</span>I<span class="op">&gt;</span> S1,</span>
<span id="cb12-68"><a href="#cb12-68" aria-hidden="true" tabindex="-1"></a>           <em>nothrow-bidirectional-iterator</em> O, <em>nothrow-sentinel-for</em><span class="op">&lt;</span>O<span class="op">&gt;</span> S2<span class="op">&gt;</span></span>
<span id="cb12-69"><a href="#cb12-69" aria-hidden="true" tabindex="-1"></a>    <span class="kw">requires</span> <em>relocatable-from</em><span class="op">&lt;</span>iter_value_t<span class="op">&lt;</span>I<span class="op">&gt;</span>, iter_value_t<span class="op">&lt;</span>O<span class="op">&gt;&gt;</span></span>
<span id="cb12-70"><a href="#cb12-70" aria-hidden="true" tabindex="-1"></a>      <span class="kw">constexpr</span> uninitialized_relocate_backward_result<span class="op">&lt;</span>I, O<span class="op">&gt;</span></span>
<span id="cb12-71"><a href="#cb12-71" aria-hidden="true" tabindex="-1"></a>        uninitialized_relocate_backward<span class="op">(</span>I ifirst, S1 ilast, O ofirst, S2 olast<span class="op">)</span>;    <span class="co">// freestanding</span></span>
<span id="cb12-72"><a href="#cb12-72" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-73"><a href="#cb12-73" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><em>nothrow-bidirectional-range</em> IR, <em>nothrow-bidirectional-range</em> OR<span class="op">&gt;</span></span>
<span id="cb12-74"><a href="#cb12-74" aria-hidden="true" tabindex="-1"></a>    <span class="kw">requires</span> <em>relocatable-from</em><span class="op">&lt;</span>range_value_t<span class="op">&lt;</span>IR<span class="op">&gt;</span>, range_value_t<span class="op">&lt;</span>OR<span class="op">&gt;&gt;</span></span>
<span id="cb12-75"><a href="#cb12-75" aria-hidden="true" tabindex="-1"></a>      <span class="kw">constexpr</span> uninitialized_relocate_backward_result<span class="op">&lt;</span>borrowed_iterator_t<span class="op">&lt;</span>IR<span class="op">&gt;</span>, borrowed_iterator_t<span class="op">&lt;</span>OR<span class="op">&gt;&gt;</span></span>
<span id="cb12-76"><a href="#cb12-76" aria-hidden="true" tabindex="-1"></a>        uninitialized_relocate_backward<span class="op">(</span>IR<span class="op">&amp;&amp;</span> in_range, OR<span class="op">&amp;&amp;</span> out_range<span class="op">)</span>;    <span class="co">// freestanding</span></span>
<span id="cb12-77"><a href="#cb12-77" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h2 data-number="7.6" id="specialized.algorithms"><span class="header-section-number">7.6</span> [specialized.algorithms]<a href="#specialized.algorithms" class="self-link"></a></h2>
<h3 data-number="7.6.1" id="uninitialized.relocate"><span class="header-section-number">7.6.1</span> [uninitialized.relocate]<a href="#uninitialized.relocate" class="self-link"></a></h3>
<p>Append to <span>26.11
<a href="https://wg21.link/specialized.algorithms">[specialized.algorithms]</a></span>
a new subclause,
<code class="sourceCode cpp">uninitialized_relocate</code>
[uninitialized.relocate], with these contents:</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> NoThrowForwardIterator1, <span class="kw">class</span> NoThrowForwardIterator2<span class="op">&gt;</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> NoThrowForwardIterator2</span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>    uninitialized_relocate<span class="op">(</span>NoThrowForwardIterator1 first,</span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>                           NoThrowForwardIterator1 last,</span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>                           NoThrowForwardIterator2 result<span class="op">)</span>;</span></code></pre></div>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">?</a></span>
<em>Preconditions</em>: <code class="sourceCode cpp">result</code> is
not in the range <code class="sourceCode cpp"><span class="op">[</span>first, last<span class="op">)</span></code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">?</a></span>
<em>Effects</em>: Equivalent to:</p></li>
</ul>
<div class="sourceCode" id="cb14"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a>NoThrowForwardIterator2 first_result <span class="op">=</span> result;</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a><span class="cf">try</span> <span class="op">{</span></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>  <span class="cf">while</span> <span class="op">(</span>first <span class="op">!=</span> last<span class="op">)</span> <span class="op">{</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>    <em>relocate-at</em><span class="op">(</span>addressof<span class="op">(*</span>result<span class="op">)</span>, addressof<span class="op">(*</span>first<span class="op">))</span>;</span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span>first;</span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span>result;</span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span> <span class="cf">catch</span> <span class="op">(...)</span> <span class="op">{</span></span>
<span id="cb14-9"><a href="#cb14-9" aria-hidden="true" tabindex="-1"></a>  destroy<span class="op">(++</span>first, last<span class="op">)</span>;</span>
<span id="cb14-10"><a href="#cb14-10" aria-hidden="true" tabindex="-1"></a>  destroy<span class="op">(</span>first_result, result<span class="op">)</span>;</span>
<span id="cb14-11"><a href="#cb14-11" aria-hidden="true" tabindex="-1"></a>  <span class="cf">throw</span>;</span>
<span id="cb14-12"><a href="#cb14-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb14-13"><a href="#cb14-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-14"><a href="#cb14-14" aria-hidden="true" tabindex="-1"></a><span class="cf">return</span> result;</span></code></pre></div>
<div class="sourceCode" id="cb15"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">namespace</span> ranges <span class="op">{</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><em>nothrow-input-iterator</em> I, <em>nothrow-sentinel-for</em><span class="op">&lt;</span>I<span class="op">&gt;</span> S1,</span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>           <em>nothrow-forward-iterator</em> O, <em>nothrow-sentinel-for</em><span class="op">&lt;</span>O<span class="op">&gt;</span> S2<span class="op">&gt;</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">requires</span> <em>relocatable-from</em><span class="op">&lt;</span>iter_value_t<span class="op">&lt;</span>I<span class="op">&gt;</span>, iter_value_t<span class="op">&lt;</span>O<span class="op">&gt;&gt;</span></span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>      <span class="kw">constexpr</span> uninitialized_relocate_result<span class="op">&lt;</span>I, O<span class="op">&gt;</span></span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>        uninitialized_relocate<span class="op">(</span>I ifirst, S1 ilast, O ofirst, O2 olast<span class="op">)</span>;</span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><em>nothrow-input-range</em> IR, <em>nothrow-forward_range</em><span class="op">&lt;</span>I<span class="op">&gt;</span> OR<span class="op">&gt;</span>,</span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">requires</span> <em>relocatable-from</em><span class="op">&lt;</span>range_value_t<span class="op">&lt;</span>IR<span class="op">&gt;</span>, range_value_t<span class="op">&lt;</span>OR<span class="op">&gt;&gt;</span></span>
<span id="cb15-10"><a href="#cb15-10" aria-hidden="true" tabindex="-1"></a>      <span class="kw">constexpr</span> uninitialized_relocate_result<span class="op">&lt;</span>borrowed_iterator_t<span class="op">&lt;</span>IR<span class="op">&gt;</span>, borrowed_iterator_t<span class="op">&lt;</span>OR<span class="op">&gt;&gt;</span></span>
<span id="cb15-11"><a href="#cb15-11" aria-hidden="true" tabindex="-1"></a>        uninitialized_relocate<span class="op">(</span>IR<span class="op">&amp;&amp;</span> in_range, OR<span class="op">&amp;&amp;</span> out_range<span class="op">)</span>;</span>
<span id="cb15-12"><a href="#cb15-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">?</a></span>
<em>Preconditions</em>: <code class="sourceCode cpp">ofirst</code> is
not in the range <code class="sourceCode cpp"><span class="op">[</span>ifirst, ilast<span class="op">)</span></code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">?</a></span>
<em>Effects</em>: Equivalent to:</p></li>
</ul>
<div class="sourceCode" id="cb16"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a>O first_result <span class="op">=</span> ofirst;</span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a><span class="cf">try</span> <span class="op">{</span></span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a>  <span class="cf">while</span> <span class="op">(</span>ifirst <span class="op">!=</span> ilast <span class="op">&amp;&amp;</span> ofirst <span class="op">!=</span> olast<span class="op">)</span> <span class="op">{</span></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a>    <em>relocate-at</em><span class="op">(</span>addressof<span class="op">(*</span>ofirst<span class="op">)</span>, addressof<span class="op">(*</span>ifirst<span class="op">))</span>;</span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span>ifirst;</span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span>ofirst;</span>
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb16-8"><a href="#cb16-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span> <span class="cf">catch</span> <span class="op">(...)</span> <span class="op">{</span></span>
<span id="cb16-9"><a href="#cb16-9" aria-hidden="true" tabindex="-1"></a>  destroy<span class="op">(</span>first_result, ofirst<span class="op">)</span>;</span>
<span id="cb16-10"><a href="#cb16-10" aria-hidden="true" tabindex="-1"></a>  <span class="op">++</span>ifirst;</span>
<span id="cb16-11"><a href="#cb16-11" aria-hidden="true" tabindex="-1"></a>  <span class="cf">while</span> <span class="op">(</span>ifirst <span class="op">!=</span> ilast <span class="op">&amp;&amp;</span> ofirst <span class="op">!=</span> olast<span class="op">)</span> <span class="op">{</span></span>
<span id="cb16-12"><a href="#cb16-12" aria-hidden="true" tabindex="-1"></a>    destroy_at<span class="op">(</span>addressof<span class="op">(*</span>ifirst<span class="op">))</span>;</span>
<span id="cb16-13"><a href="#cb16-13" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span>ifirst;</span>
<span id="cb16-14"><a href="#cb16-14" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span>ofirst;</span>
<span id="cb16-15"><a href="#cb16-15" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb16-16"><a href="#cb16-16" aria-hidden="true" tabindex="-1"></a>  <span class="cf">throw</span>;</span>
<span id="cb16-17"><a href="#cb16-17" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb16-18"><a href="#cb16-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-19"><a href="#cb16-19" aria-hidden="true" tabindex="-1"></a><span class="cf">return</span> <span class="op">{</span>std<span class="op">::</span>move<span class="op">(</span>ifirst<span class="op">)</span>, ofirst<span class="op">}</span>;</span></code></pre></div>
<h3 data-number="7.6.2" id="uninitialized.relocate_n"><span class="header-section-number">7.6.2</span> [uninitialized.relocate_n]<a href="#uninitialized.relocate_n" class="self-link"></a></h3>
<p>Append to <span>26.11
<a href="https://wg21.link/specialized.algorithms">[specialized.algorithms]</a></span>
a new subclause,
<code class="sourceCode cpp">uninitialized_relocate_n</code>
[uninitialized.relocate_n], with these contents:</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> NoThrowForwardIterator1, <span class="kw">class</span> Size, <span class="kw">class</span> NoThrowForwardIterator2<span class="op">&gt;</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> pair<span class="op">&lt;</span>NoThrowForwardIterator1, NoThrowForwardIterator2<span class="op">&gt;</span></span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a>    uninitialized_relocate_n<span class="op">(</span>NoThrowForwardIterator1 first,</span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a>                             Size n,</span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a>                             NoThrowForwardIterator2 result<span class="op">)</span>;</span></code></pre></div>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">?</a></span>
<em>Preconditions</em>: <code class="sourceCode cpp">result</code> is
not in the range <code class="sourceCode cpp"><span class="op">[</span>first, first <span class="op">+</span> n<span class="op">)</span></code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">?</a></span>
<em>Effects</em>: Equivalent to:</p></li>
</ul>
<div class="sourceCode" id="cb18"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a>NoThrowForwardIterator2 first_result <span class="op">=</span> result;</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a><span class="cf">try</span> <span class="op">{</span></span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>  <span class="cf">while</span> <span class="op">(</span>n <span class="op">&gt;</span> <span class="dv">0</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a>    <em>relocate-at</em><span class="op">(</span>addressof<span class="op">(*</span>result<span class="op">)</span>, addressof<span class="op">(*</span>first<span class="op">))</span>;</span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span>first;</span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span>result;</span>
<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">--</span>n;</span>
<span id="cb18-8"><a href="#cb18-8" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb18-9"><a href="#cb18-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span> <span class="cf">catch</span> <span class="op">(...)</span> <span class="op">{</span></span>
<span id="cb18-10"><a href="#cb18-10" aria-hidden="true" tabindex="-1"></a>  destroy_n<span class="op">(++</span>first, <span class="op">--</span>n<span class="op">)</span>;</span>
<span id="cb18-11"><a href="#cb18-11" aria-hidden="true" tabindex="-1"></a>  destroy<span class="op">(</span>first_result, result<span class="op">)</span>;</span>
<span id="cb18-12"><a href="#cb18-12" aria-hidden="true" tabindex="-1"></a>  <span class="cf">throw</span>;</span>
<span id="cb18-13"><a href="#cb18-13" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb18-14"><a href="#cb18-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-15"><a href="#cb18-15" aria-hidden="true" tabindex="-1"></a><span class="cf">return</span> <span class="op">{</span>first, result<span class="op">}</span>;</span></code></pre></div>
<div class="sourceCode" id="cb19"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="kw">namespace</span> ranges <span class="op">{</span></span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><em>nothrow-forward-iterator</em> I,</span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a>           <em>nothrow-forward-iterator</em> O, <em>nothrow-sentinel-for</em><span class="op">&lt;</span>O<span class="op">&gt;</span> S<span class="op">&gt;</span></span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">requires</span> <em>relocatable-from</em><span class="op">&lt;</span>iter_value_t<span class="op">&lt;</span>I<span class="op">&gt;</span>, iter_value_t<span class="op">&lt;</span>O<span class="op">&gt;&gt;</span></span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a>      <span class="kw">constexpr</span> uninitialized_relocate_n_result<span class="op">&lt;</span>I, O<span class="op">&gt;</span></span>
<span id="cb19-6"><a href="#cb19-6" aria-hidden="true" tabindex="-1"></a>        uninitialized_relocate_n<span class="op">(</span>I ifirst, iter_difference_t<span class="op">&lt;</span>I<span class="op">&gt;</span> n, O ofirst, S olast<span class="op">)</span>;</span>
<span id="cb19-7"><a href="#cb19-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">?</a></span>
<em>Preconditions</em>: <code class="sourceCode cpp">ofirst</code> is
not in the range <code class="sourceCode cpp"><span class="op">[</span>ifirst, ifirst <span class="op">+</span> n<span class="op">)</span></code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">?</a></span>
<em>Effects</em>: Equivalent to:</p></li>
</ul>
<div class="sourceCode" id="cb20"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a>O first_result <span class="op">=</span> ofirst;</span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a><span class="cf">try</span> <span class="op">{</span></span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a>  <span class="cf">while</span> <span class="op">(</span>n <span class="op">&gt;</span> <span class="dv">0</span> <span class="op">&amp;&amp;</span> ofirst <span class="op">!=</span> olast<span class="op">)</span> <span class="op">{</span></span>
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a>    <em>relocate-at</em><span class="op">(</span>addressof<span class="op">(*</span>ofirst<span class="op">)</span>, addressof<span class="op">(*</span>ifirst<span class="op">))</span>;</span>
<span id="cb20-5"><a href="#cb20-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span>ifirst;</span>
<span id="cb20-6"><a href="#cb20-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span>ofirst;</span>
<span id="cb20-7"><a href="#cb20-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">--</span>n;</span>
<span id="cb20-8"><a href="#cb20-8" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb20-9"><a href="#cb20-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span> <span class="cf">catch</span> <span class="op">(...)</span> <span class="op">{</span></span>
<span id="cb20-10"><a href="#cb20-10" aria-hidden="true" tabindex="-1"></a>  destroy<span class="op">(</span>first_result, ofirst<span class="op">)</span>;</span>
<span id="cb20-11"><a href="#cb20-11" aria-hidden="true" tabindex="-1"></a>  <span class="op">++</span>ifirst;</span>
<span id="cb20-12"><a href="#cb20-12" aria-hidden="true" tabindex="-1"></a>  <span class="op">--</span>n;</span>
<span id="cb20-13"><a href="#cb20-13" aria-hidden="true" tabindex="-1"></a>  <span class="cf">while</span> <span class="op">(</span>n <span class="op">&gt;</span> <span class="dv">0</span> <span class="op">&amp;&amp;</span> ofirst <span class="op">!=</span> olast<span class="op">)</span> <span class="op">{</span></span>
<span id="cb20-14"><a href="#cb20-14" aria-hidden="true" tabindex="-1"></a>    destroy_at<span class="op">(</span>addressof<span class="op">(*</span>ifirst<span class="op">))</span>;</span>
<span id="cb20-15"><a href="#cb20-15" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span>ifirst;</span>
<span id="cb20-16"><a href="#cb20-16" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span>ofirst;</span>
<span id="cb20-17"><a href="#cb20-17" aria-hidden="true" tabindex="-1"></a>    <span class="op">--</span>n;</span>
<span id="cb20-18"><a href="#cb20-18" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb20-19"><a href="#cb20-19" aria-hidden="true" tabindex="-1"></a>  <span class="cf">throw</span>;</span>
<span id="cb20-20"><a href="#cb20-20" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb20-21"><a href="#cb20-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-22"><a href="#cb20-22" aria-hidden="true" tabindex="-1"></a><span class="cf">return</span> <span class="op">{</span>std<span class="op">::</span>move<span class="op">(</span>ifirst<span class="op">)</span>, ofirst<span class="op">}</span>;</span></code></pre></div>
<h3 data-number="7.6.3" id="uninitialized.relocate_backward"><span class="header-section-number">7.6.3</span>
[uninitialized.relocate_backward]<a href="#uninitialized.relocate_backward" class="self-link"></a></h3>
<p>Append to <span>26.11
<a href="https://wg21.link/specialized.algorithms">[specialized.algorithms]</a></span>
a new subclause,
<code class="sourceCode cpp">uninitialized_relocate_backward</code>
[uninitialized.relocate_backward], with these contents:</p>
<div class="sourceCode" id="cb21"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> NoThrowBidirectionalIterator1, <span class="kw">class</span> NoThrowBidirectionalIterator2<span class="op">&gt;</span></span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> NoThrowBidirectionalIterator2</span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a>    uninitialized_relocate_backward<span class="op">(</span>NoThrowBidirectionalIterator1 first,</span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a>                                    NoThrowBidirectionalIterator1 last,</span>
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a>                                    NoThrowBidirectionalIterator2 result<span class="op">)</span>;</span></code></pre></div>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">?</a></span>
<em>Preconditions</em>: <code class="sourceCode cpp">result</code> is
not in the range <code class="sourceCode cpp"><span class="op">(</span>first, last<span class="op">]</span></code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">?</a></span>
<em>Effects</em>: Equivalent to:</p></li>
</ul>
<div class="sourceCode" id="cb22"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a>NoThrowBidirectionalIterator2 result_last <span class="op">=</span> result;</span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a><span class="cf">try</span> <span class="op">{</span></span>
<span id="cb22-3"><a href="#cb22-3" aria-hidden="true" tabindex="-1"></a>  <span class="cf">while</span> <span class="op">(</span>last <span class="op">!=</span> first<span class="op">)</span> <span class="op">{</span></span>
<span id="cb22-4"><a href="#cb22-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">--</span>last;</span>
<span id="cb22-5"><a href="#cb22-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">--</span>result;</span>
<span id="cb22-6"><a href="#cb22-6" aria-hidden="true" tabindex="-1"></a>    <em>relocate-at</em><span class="op">(</span>addressof<span class="op">(*</span>result<span class="op">)</span>, addressof<span class="op">(*</span>last<span class="op">))</span>;</span>
<span id="cb22-7"><a href="#cb22-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb22-8"><a href="#cb22-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span> <span class="cf">catch</span> <span class="op">(...)</span> <span class="op">{</span></span>
<span id="cb22-9"><a href="#cb22-9" aria-hidden="true" tabindex="-1"></a>  destroy<span class="op">(</span>first, last<span class="op">)</span>;</span>
<span id="cb22-10"><a href="#cb22-10" aria-hidden="true" tabindex="-1"></a>  destroy<span class="op">(++</span>result, result_last<span class="op">)</span>;</span>
<span id="cb22-11"><a href="#cb22-11" aria-hidden="true" tabindex="-1"></a>  <span class="cf">throw</span>;</span>
<span id="cb22-12"><a href="#cb22-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb22-13"><a href="#cb22-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb22-14"><a href="#cb22-14" aria-hidden="true" tabindex="-1"></a><span class="cf">return</span> <span class="op">{</span>last, result<span class="op">}</span>;</span></code></pre></div>
<div class="sourceCode" id="cb23"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="kw">namespace</span> ranges <span class="op">{</span></span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><em>nothrow-bidirectional-iterator</em> I, <em>nothrow-sentinel-for</em><span class="op">&lt;</span>I<span class="op">&gt;</span> S1,</span>
<span id="cb23-3"><a href="#cb23-3" aria-hidden="true" tabindex="-1"></a>           <em>nothrow-bidirectional-iterator</em> O, <em>nothrow-sentinel-for</em><span class="op">&lt;</span>O<span class="op">&gt;</span> S2<span class="op">&gt;</span></span>
<span id="cb23-4"><a href="#cb23-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">requires</span> <em>relocatable-from</em><span class="op">&lt;</span>iter_value_t<span class="op">&lt;</span>I<span class="op">&gt;</span>, iter_value_t<span class="op">&lt;</span>O<span class="op">&gt;&gt;</span></span>
<span id="cb23-5"><a href="#cb23-5" aria-hidden="true" tabindex="-1"></a>      <span class="kw">constexpr</span> uninitialized_relocate_backward_result<span class="op">&lt;</span>I, O<span class="op">&gt;</span></span>
<span id="cb23-6"><a href="#cb23-6" aria-hidden="true" tabindex="-1"></a>        uninitialized_relocate_backward<span class="op">(</span>I ifirst, S1 ilast, O ofirst, S2 olast<span class="op">)</span>;</span>
<span id="cb23-7"><a href="#cb23-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb23-8"><a href="#cb23-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><em>nothrow-bidirectional-range</em> IR, <em>nothrow-bidirectional-range</em> OR<span class="op">&gt;</span></span>
<span id="cb23-9"><a href="#cb23-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">requires</span> <em>relocatable-from</em><span class="op">&lt;</span>range_value_t<span class="op">&lt;</span>IR<span class="op">&gt;</span>, range_value_t<span class="op">&lt;</span>OR<span class="op">&gt;&gt;</span></span>
<span id="cb23-10"><a href="#cb23-10" aria-hidden="true" tabindex="-1"></a>      <span class="kw">constexpr</span> uninitialized_relocate_backward_result<span class="op">&lt;</span>borrowed_iterator_t<span class="op">&lt;</span>IR<span class="op">&gt;</span>, borrowed_iterator_t<span class="op">&lt;</span>OR<span class="op">&gt;&gt;</span></span>
<span id="cb23-11"><a href="#cb23-11" aria-hidden="true" tabindex="-1"></a>        uninitialized_relocate_backward<span class="op">(</span>IR<span class="op">&amp;&amp;</span> in_range, OR<span class="op">&amp;&amp;</span> out_range<span class="op">)</span>;</span>
<span id="cb23-12"><a href="#cb23-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">?</a></span>
<em>Preconditions</em>: <code class="sourceCode cpp">olast</code> is not
in the range <code class="sourceCode cpp"><span class="op">(</span>ifirst, ilast<span class="op">]</span></code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">?</a></span>
<em>Effects</em>: Equivalent to:</p></li>
</ul>
<div class="sourceCode" id="cb24"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a>O result_last <span class="op">=</span> olast;</span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a><span class="cf">try</span> <span class="op">{</span></span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a>  <span class="cf">while</span> <span class="op">(</span>ilast <span class="op">!=</span> ifirst <span class="op">&amp;&amp;</span> olast <span class="op">!=</span> ofirst<span class="op">)</span> <span class="op">{</span></span>
<span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">--</span>ilast;</span>
<span id="cb24-5"><a href="#cb24-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">--</span>olast;</span>
<span id="cb24-6"><a href="#cb24-6" aria-hidden="true" tabindex="-1"></a>    <em>relocate-at</em><span class="op">(</span>addressof<span class="op">(*</span>olast<span class="op">)</span>, addressof<span class="op">(*</span>ilast<span class="op">))</span>;</span>
<span id="cb24-7"><a href="#cb24-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb24-8"><a href="#cb24-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span> <span class="cf">catch</span> <span class="op">(...)</span> <span class="op">{</span></span>
<span id="cb24-9"><a href="#cb24-9" aria-hidden="true" tabindex="-1"></a>  destroy<span class="op">(++</span>olast, result_last<span class="op">)</span>;</span>
<span id="cb24-10"><a href="#cb24-10" aria-hidden="true" tabindex="-1"></a>  <span class="op">--</span>ilast;</span>
<span id="cb24-11"><a href="#cb24-11" aria-hidden="true" tabindex="-1"></a>  <span class="cf">while</span> <span class="op">(</span>ilast <span class="op">!=</span> ifirst <span class="op">&amp;&amp;</span> olast <span class="op">!=</span> ofirst<span class="op">)</span> <span class="op">{</span></span>
<span id="cb24-12"><a href="#cb24-12" aria-hidden="true" tabindex="-1"></a>    <span class="op">--</span>ilast;</span>
<span id="cb24-13"><a href="#cb24-13" aria-hidden="true" tabindex="-1"></a>    <span class="op">--</span>olast;</span>
<span id="cb24-14"><a href="#cb24-14" aria-hidden="true" tabindex="-1"></a>    destroy_at<span class="op">(</span>addressof<span class="op">(*</span>ilast<span class="op">))</span>;</span>
<span id="cb24-15"><a href="#cb24-15" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb24-16"><a href="#cb24-16" aria-hidden="true" tabindex="-1"></a>  <span class="cf">throw</span>;</span>
<span id="cb24-17"><a href="#cb24-17" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb24-18"><a href="#cb24-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb24-19"><a href="#cb24-19" aria-hidden="true" tabindex="-1"></a><span class="cf">return</span> <span class="op">{</span>ilast, olast<span class="op">}</span>;</span></code></pre></div>
<h1 data-number="8" id="acknowledgements"><span class="header-section-number">8</span> Acknowledgements<a href="#acknowledgements" class="self-link"></a></h1>
<p>Thanks to the authors of <a href="https://wg21.link/P2786">P2786</a>
and <a href="https://wg21.link/P1144">P1144</a> for pushing for trivial
relocation, for the numerous discussions that resulted in this paper,
and for many bits of wording that we got inspiration from for this
paper.</p>
</div>
</div>
</body>
</html>
