<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang xml:lang>
<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" />
  <title>`allocator_traits::is_internally_relocatable`</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}
  </style>
  <style type="text/css">
body {
margin: 5em;
font-family: serif;

hyphens: auto;
line-height: 1.35;
text-align: left;
}
@media screen and (max-width: 30em) {
body {
margin: 1.5em;
}
}
div.wrapper {
max-width: 60em;
margin: auto;
}

ul {
list-style-type: none;
padding-left: 2.5em;
margin-top: -0.2em;
margin-bottom: -0.2em;
}
ol {
padding-left: 2.5em;
}
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;
}

#TOC ul > li:before {
content: none;
}
#TOC > ul {
padding-left: 0;
}

.toc-section-number {
margin-right: 0.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: left; }
div.section { text-align: left; }
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"><code class="sourceCode cpp">allocator_traits<span class="op">::</span>is_internally_relocatable</code></h1>
<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P3585R0</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td><!-- $TimeStamp$ -->
2025-01-13 11:44 EST<!-- $ --></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>
      LEWGI, LEWG<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to:</td>
    <td>
      Pablo Halpern<br>&lt;<a href="mailto:phalpern@halpernwightsoftware.com" class="email">phalpern@halpernwightsoftware.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="#abstract" id="toc-abstract"><span class="toc-section-number">1</span> Abstract<span></span></a></li>
<li><a href="#change-log" id="toc-change-log"><span class="toc-section-number">2</span> Change Log<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="#proposed-feature" id="toc-proposed-feature"><span class="toc-section-number">4</span> Proposed
feature<span></span></a></li>
<li><a href="#beforeafter-comparisons" id="toc-beforeafter-comparisons"><span class="toc-section-number">5</span> Before/After
Comparisons<span></span></a></li>
<li><a href="#alternatives-considered" id="toc-alternatives-considered"><span class="toc-section-number">6</span> Alternatives
considered<span></span></a>
<ul>
<li><a href="#replace-is_internally_relocatable-metafunction-with-a-fixed-value" id="toc-replace-is_internally_relocatable-metafunction-with-a-fixed-value"><span class="toc-section-number">6.1</span> Replace
<code class="sourceCode cpp">is_internally_relocatable</code>
metafunction with a fixed value<span></span></a></li>
<li><a href="#do-not-provide-the-internally_relocate-member" id="toc-do-not-provide-the-internally_relocate-member"><span class="toc-section-number">6.2</span> Do not provide the
<code class="sourceCode cpp">internally_relocate</code>
member<span></span></a></li>
</ul></li>
<li><a href="#implementation-experience" id="toc-implementation-experience"><span class="toc-section-number">7</span> Implementation
Experience<span></span></a></li>
<li><a href="#wording" id="toc-wording"><span class="toc-section-number">8</span> Wording<span></span></a></li>
<li><a href="#bibliography" id="toc-bibliography"><span class="toc-section-number">9</span> References<span></span></a></li>
</ul>
</div>
<h1 data-number="1" id="abstract"><span class="header-section-number">1</span> Abstract<a href="#abstract" class="self-link"></a></h1>
<p>We propose a mechanism whereby a container implementation can bypass
calls to <code class="sourceCode cpp">allocator_traits<span class="op">&lt;</span>Alloc<span class="op">&gt;::</span>construct</code>
and <code class="sourceCode cpp">allocator_traits<span class="op">&lt;</span>Alloc<span class="op">&gt;::</span>destroy</code>
for relocating elements internally when the allocator permits such
elision. This bypass permission is already implicitly granted for
allocators that do not declare their own
<code class="sourceCode cpp">construct</code> and
<code class="sourceCode cpp">destroy</code> members but should be a
valid allowance for <code class="sourceCode cpp">pmr<span class="op">::</span>polymorphic_allocator</code>
and most other allocators. Granting this permission would allow
containers such as <code class="sourceCode cpp">vector</code> to take
advantage of optimizations provided by relocation, especially
<em>trivial relocation</em> as defined in <span class="citation" data-cites="P2786R11">[<a href="https://wg21.link/p2786r11" role="doc-biblioref">P2786R11</a>]</span>, even for allocators that
would otherwise require a less-efficient
<code class="sourceCode cpp">construct</code>/<code class="sourceCode cpp">destroy</code>
sequence to effect relocation. We further propose a mechanism by which
an allocator can augment the relocation operation itself, e.g., to
insert bookkeeping logic before or after relocating elements. This paper
builds on <span class="citation" data-cites="P2786R11">[<a href="https://wg21.link/p2786r11" role="doc-biblioref">P2786R11</a>]</span>, <em>Trivial Relocation for
C++26</em>.</p>
<h1 data-number="2" id="change-log"><span class="header-section-number">2</span> Change Log<a href="#change-log" class="self-link"></a></h1>
<p><strong>R0 Pre-February 2024 Hagenberg meeting</strong></p>
<ul>
<li>Initial concept introduced. Mostly-complete wording.</li>
</ul>
<h1 data-number="3" id="motivation"><span class="header-section-number">3</span> Motivation<a href="#motivation" class="self-link"></a></h1>
<p>The container requirements preamble (<span>23.2.1
<a href="https://wg21.link/N4993#container.requirements.pre">[container.requirements.pre]</a><a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a></span>) says that objects in a
container must be constructed using <code class="sourceCode cpp">allocator_traits<span class="op">&lt;</span>Alloc<span class="op">&gt;::</span>construct</code>
and destroyed using <code class="sourceCode cpp">allocator_traits<span class="op">&lt;</span>Alloc<span class="op">&gt;::</span>destroy</code>.
Unfortunately, this requirement prevents operations such as
<code class="sourceCode cpp">emplace</code>,
<code class="sourceCode cpp">insert</code>,
<code class="sourceCode cpp">erase</code>, and reallocation on
<code class="sourceCode cpp">vector</code>-like containers from taking
advantage of performance benefits from <em>trivial relocation</em>, as
defined in <span class="citation" data-cites="P2786R11">[<a href="https://wg21.link/p2786r11" role="doc-biblioref">P2786R11</a>]</span>, because trivial relocation
bypasses constructors and destructors and therefore provides no hooks
for calling the <code class="sourceCode cpp">construct</code> and
<code class="sourceCode cpp">destroy</code> allocator members.</p>
<p>Most allocators, however, even those that provide
<code class="sourceCode cpp">construct</code> and
<code class="sourceCode cpp">destroy</code> members, do not require that
<code class="sourceCode cpp">construct</code> and
<code class="sourceCode cpp">destroy</code> be called for internal
relocation of elements within a same container. We are proposing a
mechanism by which allocators can inform containers that they have
permission to bypass <code class="sourceCode cpp">construct</code> and
<code class="sourceCode cpp">destroy</code> for such internal
relocations.</p>
<p>Because some allocators might need to perform bookkeeping, e.g., for
debugging or to track individual objects, this proposal also proposes a
hook whereby the allocator can take provide a replacement relocation
algorithm that would typically invoke <code class="sourceCode cpp">std<span class="op">::</span>relocate</code>, but
would add additional logic before and/or after that invocation.</p>
<h1 data-number="4" id="proposed-feature"><span class="header-section-number">4</span> Proposed feature<a href="#proposed-feature" class="self-link"></a></h1>
<p>We propose adding two members to <code class="sourceCode cpp">std<span class="op">::</span>allocator_traits<span class="op">&lt;</span>Allocator<span class="op">&gt;</span></code>:</p>
<ul>
<li><p>A function template, <code class="sourceCode cpp">allocator_traits<span class="op">&lt;</span>Alloc<span class="op">&gt;::</span>internally_relocate</code>,
having an interface and semantic similar to the <code class="sourceCode cpp">std<span class="op">::</span>relocate</code>
function proposed in <span class="citation" data-cites="P2786R11">[<a href="https://wg21.link/p2786r11" role="doc-biblioref">P2786R11</a>]</span>. If
<code class="sourceCode cpp">Alloc</code> declares its own
<code class="sourceCode cpp">internally_relocate</code> member, then
<code class="sourceCode cpp">allocator_traits</code> delegates to it;
otherwise it delegates to <code class="sourceCode cpp">std<span class="op">::</span>relocate</code>.</p></li>
<li><p>A nested type trait metafunction, <code class="sourceCode cpp">allocator_traits<span class="op">&lt;</span>Alloc<span class="op">&gt;::</span>is_internally_relocatable<span class="op">&lt;</span>T<span class="op">&gt;</span></code>,
and its corresponding inline variable, <code class="sourceCode cpp">allocator_traits<span class="op">&lt;</span>Alloc<span class="op">&gt;::</span>is_internally_relocatable_v<span class="op">&lt;</span>T<span class="op">&gt;</span></code>,
that evaluate to <code class="sourceCode cpp">true_type</code> and
<code class="sourceCode cpp"><span class="kw">true</span></code>,
respectively, if the container has permission to relocate elements of
type <code class="sourceCode cpp">T</code> without calling
<code class="sourceCode cpp">construct</code> and
<code class="sourceCode cpp">destroy</code>. For a relocatable
<code class="sourceCode cpp">T</code> (i.e, when <code class="sourceCode cpp">is_nothrow_relocatable_v<span class="op">&lt;</span>T<span class="op">&gt;</span></code>
is <code class="sourceCode cpp"><span class="kw">true</span></code>),
this trait’s value is automatically
<code class="sourceCode cpp"><span class="kw">true</span></code> if
<code class="sourceCode cpp">Alloc</code> has neither a
<code class="sourceCode cpp">construct</code> nor
<code class="sourceCode cpp">destroy</code> member function or if it has
an <code class="sourceCode cpp">internally_relocate</code> member;
otherwise, this trait’s value is automatically
<code class="sourceCode cpp"><span class="kw">false</span></code>. If a
specific allocator defines its own
<code class="sourceCode cpp">is_internally_relocatable</code>
metafunction, however, then
<code class="sourceCode cpp">allocator_traits</code> delegates to the
allocator’s version, just as it does for propagation traits and most
other type members.</p></li>
</ul>
<p>A container would be expected to invoke <code class="sourceCode cpp">allocator_traits<span class="op">&lt;</span>Allocator<span class="op">&gt;::</span>internally_relocate</code>
instead of <code class="sourceCode cpp">std<span class="op">::</span>relocate</code> for
relocating elements within a container and would be expected to use
<code class="sourceCode cpp">allocator_traits<span class="op">&lt;</span>Alloc<span class="op">&gt;::</span>is_internally_relocatable_v<span class="op">&lt;</span>T<span class="op">&gt;</span></code>
instead of <code class="sourceCode cpp">std<span class="op">::</span>is_nothrow_relocatable_v<span class="op">&lt;</span>T<span class="op">&gt;</span></code>
to determine whether to use relocation for
<code class="sourceCode cpp">T</code>.</p>
<p>The complexity requirements for <code class="sourceCode cpp">vector<span class="op">::</span>erase</code> are
overconstrained in a way that can be intercepted as preventing the use
of relocation, regardless of the allocator. We propose a small wording
change for that, too.</p>
<h1 data-number="5" id="beforeafter-comparisons"><span class="header-section-number">5</span> Before/After Comparisons<a href="#beforeafter-comparisons" class="self-link"></a></h1>
<p>Below is a snippit from an implementation of <code class="sourceCode cpp">vector<span class="op">&lt;</span>T, A<span class="op">&gt;::</span>erase</code>,
where <code class="sourceCode cpp">first</code> and
<code class="sourceCode cpp">last</code> define the range of addresses
for the elements being erased. The <em>Before</em> code restricts
relocation to cases where the allocator has neither a
<code class="sourceCode cpp">construct</code> nor
<code class="sourceCode cpp">destroy</code> function. The <em>After</em>
code expands the use of relocation to include allocators that give
explicit permission to do so. Although the <em>After</em> code is
shorter, the goal is not concision, but the functionality of extending
relocation to a broader set of allocators.</p>
<table>
<thead>
<tr class="header">
<th><div style="text-align:center">
<strong>Before</strong>
</div></th>
<th><div style="text-align:center">
<strong>After</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">using</span> AT <span class="op">=</span> allocator_traits<span class="op">&lt;</span>A<span class="op">&gt;</span>;</span>
<span id="cb1-2"><a href="#cb1-2" 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">&amp;&amp;</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>              <span class="op">!</span> <span class="kw">requires</span><span class="op">(</span>A<span class="op">&amp;</span> a, T<span class="op">*</span> p<span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>                  a<span class="op">.</span>construct<span class="op">(</span>p, std<span class="op">::</span>move<span class="op">(*</span>p<span class="op">))</span>; <span class="op">}</span> <span class="op">&amp;&amp;</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>              <span class="op">!</span> <span class="kw">requires</span><span class="op">(</span>A <span class="op">&amp;</span>a, T<span class="op">*</span> p<span class="op">)</span> <span class="op">{</span> a<span class="op">.</span>destroy<span class="op">(</span>p<span class="op">)</span>; <span class="op">})</span> <span class="op">{</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>  AT<span class="op">::</span>destroy<span class="op">(</span>m_alloc, first<span class="op">)</span>;</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>  m_end <span class="op">=</span> relocate<span class="op">(</span>last, m_end, first<span class="op">)</span>;</span>
<span id="cb1-8"><a href="#cb1-8" 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">using</span> AT <span class="op">=</span> allocator_traits<span class="op">&lt;</span>A<span class="op">&gt;</span>;</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="kw">constexpr</span> <span class="op">(</span>AT<span class="op">::</span><span class="kw">template</span> is_internally_relocatable_v<span class="op">&lt;</span>T<span class="op">&gt;)</span> <span class="op">{</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>  AT<span class="op">::</span>destroy<span class="op">(</span>m_alloc, first<span class="op">)</span>;</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>  m_end <span class="op">=</span> AT<span class="op">::</span>internally_relocate<span class="op">(</span>m_alloc,</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>                                  last, m_end, first<span class="op">)</span>;</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>

</div></td>
</tr>
</tbody>
</table>
<h1 data-number="6" id="alternatives-considered"><span class="header-section-number">6</span> Alternatives considered<a href="#alternatives-considered" class="self-link"></a></h1>
<p>The proposal in this paper provides maximum flexibility at the cost
of some complexity. There are two orthogonal ways we can consider for
reducing flexibility to gain simplicity and concision.</p>
<h2 data-number="6.1" id="replace-is_internally_relocatable-metafunction-with-a-fixed-value"><span class="header-section-number">6.1</span> Replace
<code class="sourceCode cpp">is_internally_relocatable</code>
metafunction with a fixed value<a href="#replace-is_internally_relocatable-metafunction-with-a-fixed-value" class="self-link"></a></h2>
<p><code class="sourceCode cpp">allocator_traits<span class="op">&lt;</span>A<span class="op">&gt;::</span>is_internally_relocatable<span class="op">&lt;</span>T<span class="op">&gt;</span></code>
is a metafunction whose value is dependent both on the allocator,
<code class="sourceCode cpp">A</code>, and the element type,
<code class="sourceCode cpp">T</code>. The evaluation of this
metafunction is made especially verbose by the necessary use of the
<code class="sourceCode cpp"><span class="kw">template</span></code>
keyword:</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="cf">if</span> <span class="kw">constexpr</span> <span class="op">(</span>allocator_traits<span class="op">&lt;</span>A<span class="op">&gt;::</span><strong>template</strong> is_internally_relocatable<span class="op">&lt;</span>T<span class="op">&gt;)</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>  <span class="op">{</span> <span class="co">/* use relocation */</span> <span class="op">}</span></span></code></pre></div>
<p>When overriding this trait for a specific allocator we have yet to
see an example where this trait is other than an alias for <code class="sourceCode cpp">std<span class="op">::</span>is_nothrow_relocatable</code>;
i.e., we have never seen an allocator that needs to make a per-type
decision on relocatability that is different from the default.</p>
<p>One simplification, then, would be to replace the
<code class="sourceCode cpp">is_internally_relocatable</code>
metafunction with a simple
<code class="sourceCode cpp">true_type</code>/<code class="sourceCode cpp">false_type</code>
metavalue that would be independent of
<code class="sourceCode cpp">T</code>, and thus easier to override for a
specific allocator. This metavalue would be
<code class="sourceCode cpp">true_type</code> if the allocator is
granting permission to perform relocation without invoking
<code class="sourceCode cpp">construct</code> and
<code class="sourceCode cpp">destroy</code>, but would not convey any
information about whether <code class="sourceCode cpp">T</code> itself
is relocatable:</p>
<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="cf">if</span> <span class="kw">constexpr</span> <span class="op">(</span>std<span class="op">::</span>allocator_traits<span class="op">&lt;</span>A<span class="op">&gt;::</span>allow_internal_relocation <span class="op">&amp;&amp;</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>              std<span class="op">::</span>is_nothrow_relocatable<span class="op">&lt;</span>T<span class="op">&gt;)</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">{</span> <span class="co">/* use relocation */</span> <span class="op">}</span></span></code></pre></div>
<p>The <code class="sourceCode cpp">allow_internal_relocation</code>
metavalue is syntactically cleaner and easier to override, but is not
really simpler to use because
<code class="sourceCode cpp">is_nothrow_relocatable</code> must now be
evaluated separately, so this alternative was considered slightly
inferior to the current proposal.</p>
<h2 data-number="6.2" id="do-not-provide-the-internally_relocate-member"><span class="header-section-number">6.2</span> Do not provide the
<code class="sourceCode cpp">internally_relocate</code> member<a href="#do-not-provide-the-internally_relocate-member" class="self-link"></a></h2>
<p>It is probably rare that a specific allocator type would mandate that
internal relocation be performed using anything other than a call to
<code class="sourceCode cpp">std<span class="op">::</span>relocate</code>.
This proposal could be simplified, therefore, by removing the
<code class="sourceCode cpp">internally_relocate</code> function
template.</p>
<p>We have found in testing, however, that being able to instrument
calls to <code class="sourceCode cpp">internally_relocate</code> is
useful for verifying that relocation is occurring when expected.
Furthermore, allocators have been described that keep track of
individual elements, and it seems unwise to close off the benefits of
relocation for such allocators. So, while,
<code class="sourceCode cpp">internally_relocate</code> slightly
increases the specification size and implementation burden, we concluded
that the increased flexibility warrants its inclusion.</p>
<h1 data-number="7" id="implementation-experience"><span class="header-section-number">7</span> Implementation Experience<a href="#implementation-experience" class="self-link"></a></h1>
<p>A working implementation of the modified
<code class="sourceCode cpp">allocator_traits</code> and a
<code class="sourceCode cpp">vector</code> that takes advantage of the
new feature can be found at <a href="https://github.com/MungoG/relocatability/tree/master/code">https://github.com/MungoG/relocatability/tree/master/code</a>.</p>
<p>There is extensive experience bypassing
<code class="sourceCode cpp">construct</code> and
<code class="sourceCode cpp">destroy</code> for relocation when using a
pmr-like allocators in the <a href="https://github.com/bloomberg/bde">BDE library</a>.</p>
<h1 data-number="8" id="wording"><span class="header-section-number">8</span> Wording<a href="#wording" class="self-link"></a></h1>
<p>The wording below is lacking changes to header synopsis and class
definitions, but should provide sufficient detail for evaluating this
proposal.</p>
<p>To <strong>Allocator Traits Member Types</strong>, <span>20.2.9.2
<a href="https://wg21.link/N4993#allocator.traits.types">[allocator.traits.types]</a></span>,
add</p>
<div class="add" style="color: #006e28">
<p><code class="sourceCode default">template &lt;class T&gt; struct is_internally_relocatable;</code></p>
<blockquote>
<p><em>Class Template</em>: <code class="sourceCode default">is_internally_relocatable&lt;T&gt;::value</code>
is a <code class="sourceCode default">constexpr bool</code> whose value
is:</p>
</blockquote>
<blockquote>
<ul>
<li><code class="sourceCode default">Alloc::is_internally_relocatable&lt;T&gt;::value</code>,
if such a value exists; otherwise</li>
</ul>
</blockquote>
<blockquote>
<ul>
<li><code class="sourceCode default">is_nothrow_relocatable_v&lt;T&gt;</code> if
<code class="sourceCode default">Alloc::internally_relocate(T*, T*, T*)</code>
is an invocable member; otherwise</li>
</ul>
</blockquote>
<blockquote>
<ul>
<li><code class="sourceCode default">false</code> if either or both of
<code class="sourceCode default">Alloc::construct</code> or
<code class="sourceCode default">Alloc::destroy</code> are invocable
members; otherwise</li>
</ul>
</blockquote>
<blockquote>
<ul>
<li><code class="sourceCode default">std::is_nothrow_relocatable_v&lt;T&gt;</code>.</li>
</ul>
</blockquote>
<blockquote>
<p><code class="sourceCode default">constexpr bool is_internally_relocatable_v&lt;T&gt;</code>
is an alias for <code class="sourceCode default">is_internally_relocatable&lt;T&gt;::value</code>.</p>
</blockquote>

</div>
<p>To <strong>Allocator Traits Static member functions</strong>,
<span>20.2.9.3
<a href="https://wg21.link/N4993#allocator.traits.members">[allocator.traits.members]</a></span>,
add</p>
<div class="add" style="color: #006e28">

<div class="line-block"><code class="sourceCode default">template &lt;class T&gt;</code><br />
    <code class="sourceCode default">T* internally_relocate(Alloc&amp; a, T* first, T* last, T* result);</code></div>
<blockquote>
<p><em>Mandates</em>: <code class="sourceCode default">is_internally_relocatable_v&lt;T&gt;</code>
is <code class="sourceCode default">true</code>.</p>
</blockquote>
<blockquote>
<p><em>Preconditions</em>:
<code class="sourceCode default">(last - first) != 1</code>, or
<code class="sourceCode default">*first</code> points to a complete
object (<span>6.7.2
<a href="https://wg21.link/N4993#intro.object">[intro.object]</a></span>).</p>
</blockquote>
<blockquote>
<p><em>Effects</em>: Calls <code class="sourceCode default">a.internally_relocate(first, last, result)</code>
if such an expression is valid, otherwise, calls <code class="sourceCode default">std::relocate(first, last, result)</code>.</p>
</blockquote>
<blockquote>
<p><em>Returns</em>:
<code class="sourceCode default">result + (last-first)</code>.</p>
</blockquote>
<blockquote>
<p><em>Throws</em>: <code class="sourceCode default">nothing</code></p>
</blockquote>

</div>
<p>In <strong>Class
<code class="sourceCode cpp">polymorphic_allocator</code>
General</strong>, <span>20.4.3.1
<a href="https://wg21.link/N4993#mem.poly.allocator.class.general">[mem.poly.allocator.class.general]</a></span>,
add a <code class="sourceCode cpp">is_internally_relocatable</code>
member metafunction:</p>
<div class="line-block"><code class="sourceCode cpp"><span class="kw">public</span><span class="op">:</span></code><br />
    <code class="sourceCode cpp"><span class="kw">using</span> value_type <span class="op">=</span> Tp</code>;</div>
<div class="add" style="color: #006e28">

<div class="line-block">    <code class="sourceCode default">template &lt;class U&gt;</code><br />
        <code class="sourceCode default">using is_internally_relocatable = is_nothrow_relocatable&lt;U&gt;;</code></div>

</div>
<p>Change <strong>Vector modifiers</strong> <span>23.3.11.5
<a href="https://wg21.link/N4993#vector.modifiers">[vector.modifiers]</a></span>
as follows:</p>
<div class="line-block"><code class="sourceCode cpp"><span class="kw">constexpr</span> iterator erase<span class="op">(</span>const_iterator position<span class="op">)</span>;</code><br />
<code class="sourceCode cpp"><span class="kw">constexpr</span> iterator erase<span class="op">(</span>const_iterator first, const_iterator last<span class="op">)</span>;</code><br />
<code class="sourceCode cpp"><span class="kw">constexpr</span> <span class="dt">void</span> pop_back<span class="op">()</span>;</code></div>
<blockquote>
<p><em>Effects</em>: Invalidates iterators and references at or after
the point of the erase.</p>
</blockquote>
<blockquote>
<p><em>Throws</em>: Nothing unless an exception is thrown by the
assignment operator or move assignment operator of T.</p>
</blockquote>
<blockquote>
<p><em>Complexity</em>: <span class="rm" style="color: #bf0303"><del>The
destructor of T is called the number of times equal to the number of the
elements erased, but the assignment operator of T is called the number
of times equal to the number of elements in the vector after the erased
elements.</del></span> <span class="add" style="color: #006e28"><ins>Linear in the distance from the first
element to be erased to the end of the original vector.</ins></span></p>
</blockquote>
<h1 data-number="9" id="bibliography"><span class="header-section-number">9</span> References<a href="#bibliography" class="self-link"></a></h1>
<div id="refs" class="references csl-bib-body hanging-indent" data-entry-spacing="1" role="doc-bibliography">
<div id="ref-P2786R11" class="csl-entry" role="doc-biblioentry">
[P2786R11] Pablo Halpern, Joshua Berne, Corentin Jabot, Pablo Halpern,
Lori Hughes. 2024-12-17. Trivial Relocatability For C++26. <a href="https://wg21.link/p2786r11"><div class="csl-block">https://wg21.link/p2786r11</div></a>
</div>
</div>
<section class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1" role="doc-endnote"><p>All citations to the Standard are to
working draft N4993 unless otherwise specified.<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
</div>
</div>
</body>
</html>
