<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 2.0.12">
<title>std::string::substr() &amp;&amp;</title>
<style>
/* Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */
/* Uncomment @import statement to use as custom stylesheet */
/*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/
article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}
audio,video{display:inline-block}
audio:not([controls]){display:none;height:0}
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}
a{background:none}
a:focus{outline:thin dotted}
a:active,a:hover{outline:0}
h1{font-size:2em;margin:.67em 0}
abbr[title]{border-bottom:1px dotted}
b,strong{font-weight:bold}
dfn{font-style:italic}
hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}
mark{background:#ff0;color:#000}
code,kbd,pre,samp{font-family:monospace;font-size:1em}
pre{white-space:pre-wrap}
q{quotes:"\201C" "\201D" "\2018" "\2019"}
small{font-size:80%}
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
sup{top:-.5em}
sub{bottom:-.25em}
img{border:0}
svg:not(:root){overflow:hidden}
figure{margin:0}
fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
legend{border:0;padding:0}
button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
button,input{line-height:normal}
button,select{text-transform:none}
button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}
button[disabled],html input[disabled]{cursor:default}
input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
textarea{overflow:auto;vertical-align:top}
table{border-collapse:collapse;border-spacing:0}
*,*::before,*::after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
html,body{font-size:100%}
body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto;tab-size:4;word-wrap:anywhere;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
a:hover{cursor:pointer}
img,object,embed{max-width:100%;height:auto}
object,embed{height:100%}
img{-ms-interpolation-mode:bicubic}
.left{float:left!important}
.right{float:right!important}
.text-left{text-align:left!important}
.text-right{text-align:right!important}
.text-center{text-align:center!important}
.text-justify{text-align:justify!important}
.hide{display:none}
img,object,svg{display:inline-block;vertical-align:middle}
textarea{height:auto;min-height:50px}
select{width:100%}
.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0}
a{color:#2156a5;text-decoration:underline;line-height:inherit}
a:hover,a:focus{color:#1d4b8f}
a img{border:0}
p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
p aside{font-size:.875em;line-height:1.35;font-style:italic}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
h1{font-size:2.125em}
h2{font-size:1.6875em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
h4,h5{font-size:1.125em}
h6{font-size:1em}
hr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}
em,i{font-style:italic;line-height:inherit}
strong,b{font-weight:bold;line-height:inherit}
small{font-size:60%;line-height:inherit}
code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
ul,ol{margin-left:1.5em}
ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}
ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
ul.square{list-style-type:square}
ul.circle{list-style-type:circle}
ul.disc{list-style-type:disc}
ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
dl dt{margin-bottom:.3125em;font-weight:bold}
dl dd{margin-bottom:1.25em}
abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}
abbr{text-transform:none}
blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}
blockquote cite::before{content:"\2014 \0020"}
blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}
blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
@media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
h1{font-size:2.75em}
h2{font-size:2.3125em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
h4{font-size:1.4375em}}
table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede;word-wrap:normal}
table thead,table tfoot{background:#f7f8f7}
table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
table tr.even,table tr.alt{background:#f8f8f7}
table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{line-height:1.6}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
.center{margin-left:auto;margin-right:auto}
.stretch{width:100%}
.clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table}
.clearfix::after,.float-group::after{clear:both}
:not(pre).nobreak{word-wrap:normal}
:not(pre).nowrap{white-space:nowrap}
:not(pre).pre-wrap{white-space:pre-wrap}
:not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}
pre{color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;line-height:1.45;text-rendering:optimizeSpeed}
pre code,pre pre{color:inherit;font-size:inherit;line-height:inherit}
pre>code{display:block}
pre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal}
em em{font-style:normal}
strong strong{font-weight:400}
.keyseq{color:rgba(51,51,51,.8)}
kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
.keyseq kbd:first-child{margin-left:0}
.keyseq kbd:last-child{margin-right:0}
.menuseq,.menuref{color:#000}
.menuseq b:not(.caret),.menuref{font-weight:inherit}
.menuseq{word-spacing:-.02em}
.menuseq b.caret{font-size:1.25em;line-height:.8}
.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}
b.button::before,b.button::after{position:relative;top:-1px;font-weight:400}
b.button::before{content:"[";padding:0 3px 0 2px}
b.button::after{content:"]";padding:0 2px 0 3px}
p a>code:hover{color:rgba(0,0,0,.9)}
#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
#header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table}
#header::after,#content::after,#footnotes::after,#footer::after{clear:both}
#content{margin-top:1.25em}
#content::before{content:none}
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
#header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}
#header .details span:first-child{margin-left:-.125em}
#header .details span.email a{color:rgba(0,0,0,.85)}
#header .details br{display:none}
#header .details br+span::before{content:"\00a0\2013\00a0"}
#header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
#header .details br+span#revremark::before{content:"\00a0|\00a0"}
#header #revnumber{text-transform:capitalize}
#header #revnumber::after{content:"\00a0"}
#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
#toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em}
#toc>ul{margin-left:.125em}
#toc ul.sectlevel0>li>a{font-style:italic}
#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
#toc li{line-height:1.3334;margin-top:.3334em}
#toc a{text-decoration:none}
#toc a:active{text-decoration:underline}
#toctitle{color:#7a2518;font-size:1.2em}
@media screen and (min-width:768px){#toctitle{font-size:1.375em}
body.toc2{padding-left:15em;padding-right:0}
#toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
#toc.toc2 ul ul{margin-left:0;padding-left:1em}
#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
body.toc2.toc-right{padding-left:0;padding-right:15em}
body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}}
@media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
#toc.toc2{width:20em}
#toc.toc2 #toctitle{font-size:1.375em}
#toc.toc2>ul{font-size:.95em}
#toc.toc2 ul ul{padding-left:1.25em}
body.toc2.toc-right{padding-left:0;padding-right:20em}}
#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
#content #toc>:first-child{margin-top:0}
#content #toc>:last-child{margin-bottom:0}
#footer{max-width:none;background:rgba(0,0,0,.8);padding:1.25em}
#footer-text{color:rgba(255,255,255,.8);line-height:1.44}
#content{margin-bottom:.625em}
.sect1{padding-bottom:.625em}
@media screen and (min-width:768px){#content{margin-bottom:1.25em}
.sect1{padding-bottom:1.25em}}
.sect1:last-child{padding-bottom:0}
.sect1+.sect1{border-top:1px solid #e7e7e9}
#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
#content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
details,.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
details>summary:first-of-type{cursor:pointer;display:list-item;outline:none;margin-bottom:.75em}
.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
table.tableblock.fit-content>caption.title{white-space:nowrap;width:0}
.paragraph.lead>p,#preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)}
table.tableblock #preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:inherit}
.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
.admonitionblock>table td.icon{text-align:center;width:80px}
.admonitionblock>table td.icon img{max-width:none}
.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6);word-wrap:anywhere}
.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}
.exampleblock>.content>:first-child{margin-top:0}
.exampleblock>.content>:last-child{margin-bottom:0}
.sidebarblock{border-style:solid;border-width:1px;border-color:#dbdbd6;margin-bottom:1.25em;padding:1.25em;background:#f3f3f2;-webkit-border-radius:4px;border-radius:4px}
.sidebarblock>:first-child{margin-top:0}
.sidebarblock>:last-child{margin-bottom:0}
.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
.literalblock pre,.listingblock>.content>pre{-webkit-border-radius:4px;border-radius:4px;overflow-x:auto;padding:1em;font-size:.8125em}
@media screen and (min-width:768px){.literalblock pre,.listingblock>.content>pre{font-size:.90625em}}
@media screen and (min-width:1280px){.literalblock pre,.listingblock>.content>pre{font-size:1em}}
.literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class="highlight"],.listingblock>.content>pre[class^="highlight "]{background:#f7f7f8}
.literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)}
.listingblock>.content{position:relative}
.listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:inherit;opacity:.5}
.listingblock:hover code[data-lang]::before{display:block}
.listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5}
.listingblock.terminal pre .command:not([data-prompt])::before{content:"$"}
.listingblock pre.highlightjs{padding:0}
.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}
.listingblock pre.prettyprint{border-width:0}
.prettyprint{background:#f7f7f8}
pre.prettyprint .linenums{line-height:1.45;margin-left:2em}
pre.prettyprint li{background:none;list-style-type:inherit;padding-left:0}
pre.prettyprint li code[data-lang]::before{opacity:1}
pre.prettyprint li:not(:first-child) code[data-lang]::before{display:none}
table.linenotable{border-collapse:separate;border:0;margin-bottom:0;background:none}
table.linenotable td[class]{color:inherit;vertical-align:top;padding:0;line-height:inherit;white-space:normal}
table.linenotable td.code{padding-left:.75em}
table.linenotable td.linenos{border-right:1px solid currentColor;opacity:.35;padding-right:.5em}
pre.pygments .lineno{border-right:1px solid currentColor;opacity:.35;display:inline-block;margin-right:.75em}
pre.pygments .lineno::before{content:"";margin-right:-.125em}
.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
.quoteblock:not(.excerpt)>.title{margin-left:-1.5em;margin-bottom:.75em}
.quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
.quoteblock blockquote{margin:0;padding:0;border:0}
.quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
.quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right}
.verseblock{margin:0 1em 1.25em}
.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
.verseblock pre strong{font-weight:400}
.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
.quoteblock .attribution br,.verseblock .attribution br{display:none}
.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
.quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none}
.quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0}
.quoteblock.abstract{margin:0 1em 1.25em;display:block}
.quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center}
.quoteblock.excerpt>blockquote,.quoteblock .quoteblock{padding:0 0 .25em 1em;border-left:.25em solid #dddddf}
.quoteblock.excerpt,.quoteblock .quoteblock{margin-left:0}
.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem}
.quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;text-align:left;margin-right:0}
p.tableblock:last-child{margin-bottom:0}
td.tableblock>.content{margin-bottom:1.25em;word-wrap:anywhere}
td.tableblock>.content>:last-child{margin-bottom:-1.25em}
table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
table.grid-all>*>tr>*{border-width:1px}
table.grid-cols>*>tr>*{border-width:0 1px}
table.grid-rows>*>tr>*{border-width:1px 0}
table.frame-all{border-width:1px}
table.frame-ends{border-width:1px 0}
table.frame-sides{border-width:0 1px}
table.frame-none>colgroup+*>:first-child>*,table.frame-sides>colgroup+*>:first-child>*{border-top-width:0}
table.frame-none>:last-child>:last-child>*,table.frame-sides>:last-child>:last-child>*{border-bottom-width:0}
table.frame-none>*>tr>:first-child,table.frame-ends>*>tr>:first-child{border-left-width:0}
table.frame-none>*>tr>:last-child,table.frame-ends>*>tr>:last-child{border-right-width:0}
table.stripes-all tr,table.stripes-odd tr:nth-of-type(odd),table.stripes-even tr:nth-of-type(even),table.stripes-hover tr:hover{background:#f8f8f7}
th.halign-left,td.halign-left{text-align:left}
th.halign-right,td.halign-right{text-align:right}
th.halign-center,td.halign-center{text-align:center}
th.valign-top,td.valign-top{vertical-align:top}
th.valign-bottom,td.valign-bottom{vertical-align:bottom}
th.valign-middle,td.valign-middle{vertical-align:middle}
table thead th,table tfoot th{font-weight:bold}
tbody tr th{background:#f7f8f7}
tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
p.tableblock>code:only-child{background:none;padding:0}
p.tableblock{font-size:1em}
ol{margin-left:1.75em}
ul li ol{margin-left:1.5em}
dl dd{margin-left:1.125em}
dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}
ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}
ul.unstyled,ol.unstyled{margin-left:0}
ul.checklist{margin-left:.625em}
ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}
ul.checklist li>p:first-child>input[type="checkbox"]:first-child{margin-right:.25em}
ul.inline{display:-ms-flexbox;display:-webkit-box;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em}
ul.inline>li{margin-left:1.25em}
.unstyled dl dt{font-weight:400;font-style:normal}
ol.arabic{list-style-type:decimal}
ol.decimal{list-style-type:decimal-leading-zero}
ol.loweralpha{list-style-type:lower-alpha}
ol.upperalpha{list-style-type:upper-alpha}
ol.lowerroman{list-style-type:lower-roman}
ol.upperroman{list-style-type:upper-roman}
ol.lowergreek{list-style-type:lower-greek}
.hdlist>table,.colist>table{border:0;background:none}
.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
td.hdlist1{font-weight:bold;padding-bottom:1.25em}
td.hdlist2{word-wrap:anywhere}
.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
.colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top}
.colist td:not([class]):first-child img{max-width:none}
.colist td:not([class]):last-child{padding:.25em 0}
.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}
.imageblock.left{margin:.25em .625em 1.25em 0}
.imageblock.right{margin:.25em 0 1.25em .625em}
.imageblock>.title{margin-bottom:0}
.imageblock.thumb,.imageblock.th{border-width:6px}
.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
.image.left{margin-right:.625em}
.image.right{margin-left:.625em}
a.image{text-decoration:none;display:inline-block}
a.image object{pointer-events:none}
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
sup.footnote a,sup.footnoteref a{text-decoration:none}
sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em}
#footnotes .footnote:last-of-type{margin-bottom:0}
#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}
.gist .file-data>table td.line-data{width:99%}
div.unbreakable{page-break-inside:avoid}
.big{font-size:larger}
.small{font-size:smaller}
.underline{text-decoration:underline}
.overline{text-decoration:overline}
.line-through{text-decoration:line-through}
.aqua{color:#00bfbf}
.aqua-background{background:#00fafa}
.black{color:#000}
.black-background{background:#000}
.blue{color:#0000bf}
.blue-background{background:#0000fa}
.fuchsia{color:#bf00bf}
.fuchsia-background{background:#fa00fa}
.gray{color:#606060}
.gray-background{background:#7d7d7d}
.green{color:#006000}
.green-background{background:#007d00}
.lime{color:#00bf00}
.lime-background{background:#00fa00}
.maroon{color:#600000}
.maroon-background{background:#7d0000}
.navy{color:#000060}
.navy-background{background:#00007d}
.olive{color:#606000}
.olive-background{background:#7d7d00}
.purple{color:#600060}
.purple-background{background:#7d007d}
.red{color:#bf0000}
.red-background{background:#fa0000}
.silver{color:#909090}
.silver-background{background:#bcbcbc}
.teal{color:#006060}
.teal-background{background:#007d7d}
.white{color:#bfbfbf}
.white-background{background:#fafafa}
.yellow{color:#bfbf00}
.yellow-background{background:#fafa00}
span.icon>.fa{cursor:default}
a span.icon>.fa{cursor:inherit}
.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
.admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c}
.admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
.admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900}
.admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400}
.admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000}
.conum[data-value]{display:inline-block;color:#fff!important;background:rgba(0,0,0,.8);-webkit-border-radius:50%;border-radius:50%;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
.conum[data-value] *{color:#fff!important}
.conum[data-value]+b{display:none}
.conum[data-value]::after{content:attr(data-value)}
pre .conum[data-value]{position:relative;top:-.125em}
b.conum *{color:inherit!important}
.conum:not([data-value]):empty{display:none}
dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
h1,h2,p,td.content,span.alt{letter-spacing:-.01em}
p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}
p{margin-bottom:1.25rem}
.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
.exampleblock>.content{background:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}
.print-only{display:none!important}
@page{margin:1.25cm .75cm}
@media print{*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}
html{font-size:80%}
a{color:inherit!important;text-decoration:underline!important}
a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
abbr[title]::after{content:" (" attr(title) ")"}
pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
thead{display:table-header-group}
svg{max-width:100%}
p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
#header,#content,#footnotes,#footer{max-width:none}
#toc,.sidebarblock,.exampleblock>.content{background:none!important}
#toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important}
body.book #header{text-align:center}
body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em}
body.book #header .details{border:0!important;display:block;padding:0!important}
body.book #header .details span:first-child{margin-left:0!important}
body.book #header .details br{display:block}
body.book #header .details br+span::before{content:none!important}
body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
.listingblock code[data-lang]::before{display:block}
#footer{padding:0 .9375em}
.hide-on-print{display:none!important}
.print-only{display:block!important}
.hide-for-print{display:none!important}
.show-for-print{display:inherit!important}}
@media print,amzn-kf8{#header>h1:first-child{margin-top:1.25rem}
.sect1{padding:0!important}
.sect1+.sect1{border:0}
#footer{background:none}
#footer-text{color:rgba(0,0,0,.6);font-size:.9em}}
@media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}}
</style>
<style>
pre { line-height: 125%; margin: 0; }
td.linenos pre { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }
span.linenos { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }
td.linenos pre.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }
pre.pygments .hll { background-color: #ffffcc }
pre.pygments { background: #f8f8f8; }
pre.pygments .tok-c { color: #408080; font-style: italic } /* Comment */
pre.pygments .tok-err { border: 1px solid #FF0000 } /* Error */
pre.pygments .tok-k { color: #008000; font-weight: bold } /* Keyword */
pre.pygments .tok-o { color: #666666 } /* Operator */
pre.pygments .tok-ch { color: #408080; font-style: italic } /* Comment.Hashbang */
pre.pygments .tok-cm { color: #408080; font-style: italic } /* Comment.Multiline */
pre.pygments .tok-cp { color: #BC7A00 } /* Comment.Preproc */
pre.pygments .tok-cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */
pre.pygments .tok-c1 { color: #408080; font-style: italic } /* Comment.Single */
pre.pygments .tok-cs { color: #408080; font-style: italic } /* Comment.Special */
pre.pygments .tok-gd { color: #A00000 } /* Generic.Deleted */
pre.pygments .tok-ge { font-style: italic } /* Generic.Emph */
pre.pygments .tok-gr { color: #FF0000 } /* Generic.Error */
pre.pygments .tok-gh { color: #000080; font-weight: bold } /* Generic.Heading */
pre.pygments .tok-gi { color: #00A000 } /* Generic.Inserted */
pre.pygments .tok-go { color: #888888 } /* Generic.Output */
pre.pygments .tok-gp { color: #000080; font-weight: bold } /* Generic.Prompt */
pre.pygments .tok-gs { font-weight: bold } /* Generic.Strong */
pre.pygments .tok-gu { color: #800080; font-weight: bold } /* Generic.Subheading */
pre.pygments .tok-gt { color: #0044DD } /* Generic.Traceback */
pre.pygments .tok-kc { color: #008000; font-weight: bold } /* Keyword.Constant */
pre.pygments .tok-kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
pre.pygments .tok-kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
pre.pygments .tok-kp { color: #008000 } /* Keyword.Pseudo */
pre.pygments .tok-kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
pre.pygments .tok-kt { color: #B00040 } /* Keyword.Type */
pre.pygments .tok-m { color: #666666 } /* Literal.Number */
pre.pygments .tok-s { color: #BA2121 } /* Literal.String */
pre.pygments .tok-na { color: #7D9029 } /* Name.Attribute */
pre.pygments .tok-nb { color: #008000 } /* Name.Builtin */
pre.pygments .tok-nc { color: #0000FF; font-weight: bold } /* Name.Class */
pre.pygments .tok-no { color: #880000 } /* Name.Constant */
pre.pygments .tok-nd { color: #AA22FF } /* Name.Decorator */
pre.pygments .tok-ni { color: #999999; font-weight: bold } /* Name.Entity */
pre.pygments .tok-ne { color: #D2413A; font-weight: bold } /* Name.Exception */
pre.pygments .tok-nf { color: #0000FF } /* Name.Function */
pre.pygments .tok-nl { color: #A0A000 } /* Name.Label */
pre.pygments .tok-nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
pre.pygments .tok-nt { color: #008000; font-weight: bold } /* Name.Tag */
pre.pygments .tok-nv { color: #19177C } /* Name.Variable */
pre.pygments .tok-ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
pre.pygments .tok-w { color: #bbbbbb } /* Text.Whitespace */
pre.pygments .tok-mb { color: #666666 } /* Literal.Number.Bin */
pre.pygments .tok-mf { color: #666666 } /* Literal.Number.Float */
pre.pygments .tok-mh { color: #666666 } /* Literal.Number.Hex */
pre.pygments .tok-mi { color: #666666 } /* Literal.Number.Integer */
pre.pygments .tok-mo { color: #666666 } /* Literal.Number.Oct */
pre.pygments .tok-sa { color: #BA2121 } /* Literal.String.Affix */
pre.pygments .tok-sb { color: #BA2121 } /* Literal.String.Backtick */
pre.pygments .tok-sc { color: #BA2121 } /* Literal.String.Char */
pre.pygments .tok-dl { color: #BA2121 } /* Literal.String.Delimiter */
pre.pygments .tok-sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
pre.pygments .tok-s2 { color: #BA2121 } /* Literal.String.Double */
pre.pygments .tok-se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
pre.pygments .tok-sh { color: #BA2121 } /* Literal.String.Heredoc */
pre.pygments .tok-si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
pre.pygments .tok-sx { color: #008000 } /* Literal.String.Other */
pre.pygments .tok-sr { color: #BB6688 } /* Literal.String.Regex */
pre.pygments .tok-s1 { color: #BA2121 } /* Literal.String.Single */
pre.pygments .tok-ss { color: #19177C } /* Literal.String.Symbol */
pre.pygments .tok-bp { color: #008000 } /* Name.Builtin.Pseudo */
pre.pygments .tok-fm { color: #0000FF } /* Name.Function.Magic */
pre.pygments .tok-vc { color: #19177C } /* Name.Variable.Class */
pre.pygments .tok-vg { color: #19177C } /* Name.Variable.Global */
pre.pygments .tok-vi { color: #19177C } /* Name.Variable.Instance */
pre.pygments .tok-vm { color: #19177C } /* Name.Variable.Magic */
pre.pygments .tok-il { color: #666666 } /* Literal.Number.Integer.Long */
</style>
</head>
<body class="article">
<div id="header">
<h1><code>std::string::substr() &amp;&amp;</code></h1>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Document number:</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">P2438R0</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Date:</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2021-09-14</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Project:</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Programming Language C++, Library Working Group</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Reply-to:</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="mailto:federico.kircheis@gmail.com">federico.kircheis@gmail.com</a>, <a href="mailto:tomaszkam@gmail.com">tomaszkam@gmail.com</a></p></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect1">
<h2 id="_beforeafter_table">1. Before/After table</h2>
<div class="sectionbody">
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 33.3333%;">
<col style="width: 33.3333%;">
<col style="width: 33.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">without this proposal</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">with this proposal</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-k">auto</span> <span class="tok-n">a</span> <span class="tok-o">=</span> <span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">string</span><span class="tok-p">(</span><span class="tok-cm">/* */</span><span class="tok-p">);</span>
<span class="tok-k">auto</span> <span class="tok-n">b</span> <span class="tok-o">=</span> <span class="tok-n">a</span><span class="tok-p">.</span><span class="tok-n">substr</span><span class="tok-p">(</span><span class="tok-cm">/*  */</span><span class="tok-p">);</span></code></pre>
</div>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of <code>a</code> does not change</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of <code>a</code> does not change</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-k">auto</span> <span class="tok-nf">foo</span><span class="tok-p">()</span> <span class="tok-o">-&gt;</span> <span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">string</span><span class="tok-p">;</span>

<span class="tok-k">auto</span> <span class="tok-n">b</span> <span class="tok-o">=</span> <span class="tok-n">foo</span><span class="tok-p">().</span><span class="tok-n">substr</span><span class="tok-p">(</span><span class="tok-cm">/* */</span><span class="tok-p">);</span></code></pre>
</div>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>foo()</code> returns a temporary <code>std::string</code>. <code>.substr</code> creates a new string and copies the relevant content. At last the temporary string returned by foo is released.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>foo()</code> returns a <code>std::string</code>. <code>.substr</code> implementation can reuse the storage of the string returned by foo and leave it in a valid but unspecified state. At last the temporary string returned by <code>foo()</code> is released.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-k">auto</span> <span class="tok-n">a</span> <span class="tok-o">=</span> <span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">string</span><span class="tok-p">(</span><span class="tok-cm">/* */</span><span class="tok-p">).</span><span class="tok-n">substr</span><span class="tok-p">(</span><span class="tok-cm">/* */</span><span class="tok-p">);</span></code></pre>
</div>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A temporary <code>std::string</code> is created, on that instance <code>.substr</code> creates a new string and copies the relevant content. At last the temporary string is released.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A temporary <code>std::string</code> is created, on that instance <code>.substr</code> implementation can reuse the storage and leave the temporary string in a valid but unspecified state. At last the temporary string is released.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-k">auto</span> <span class="tok-n">a</span> <span class="tok-o">=</span> <span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">string</span><span class="tok-p">(</span><span class="tok-cm">/* */</span><span class="tok-p">);</span>
<span class="tok-k">auto</span> <span class="tok-n">b</span> <span class="tok-o">=</span> <span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">move</span><span class="tok-p">(</span><span class="tok-n">a</span><span class="tok-p">).</span><span class="tok-n">substr</span><span class="tok-p">(</span><span class="tok-cm">/* */</span><span class="tok-p">);</span></code></pre>
</div>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of <code>a</code> does not change</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">As <code>a</code> is casted to an xvalue, the implementation of <code>.substr</code> can reuse the storage and leave <code>this</code> string in a valid but unspecified state.</p></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect1">
<h2 id="_motivation">2. Motivation</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Since C&#43;&#43;11 the C&#43;&#43; language supports move semantic.
All classes where it made sense where updated with move constructors and move assignment operators.
This made it possible to take advantage of rvalues and "steal" resources, thus avoiding, for example, unnecessary costly copies.</p>
</div>
<div class="paragraph">
<p>Some classes that came in later revisions of the language also take advantage of move semantic for member functions, like <code>std::optional::value</code> and <code>std::optional::value_or</code>.</p>
</div>
<div class="paragraph">
<p>In the case of <code>std::string::substr()</code>, it is possible to take advantage of move semantic to.</p>
</div>
<div class="paragraph">
<p>Consider following two code snippets:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-c1">// example 1</span>
<span class="tok-n">benchmark</span> <span class="tok-o">=</span> <span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">string</span><span class="tok-p">(</span><span class="tok-n">argv</span><span class="tok-p">[</span><span class="tok-n">i</span><span class="tok-p">]).</span><span class="tok-n">substr</span><span class="tok-p">(</span><span class="tok-mi">12</span><span class="tok-p">);</span>

<span class="tok-c1">// example 2</span>
<span class="tok-n">name_</span> <span class="tok-o">=</span> <span class="tok-n">obs</span><span class="tok-p">.</span><span class="tok-n">stringValue</span><span class="tok-p">().</span><span class="tok-n">substr</span><span class="tok-p">(</span><span class="tok-mi">0</span><span class="tok-p">,</span><span class="tok-mi">32</span><span class="tok-p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>In the first example, <code>argv[1]</code> is copied in a temporary string, then <code>substr</code> creates a new object.
In this case one could use <code>string_view</code> to avoid the unnecessary copy, but changing already working code has a cost too.</p>
</div>
<div class="paragraph">
<p>In the second example, if <code>stringValue()</code> returns an <code>std::string</code> by value, the user of that API cannot use a <code>string_view</code> to avoid an unnecessary copy, like in the first case.</p>
</div>
<div class="paragraph">
<p>If <code>std::string</code> would have an overload for <code>substr() &amp;&amp;</code>, in both cases the standard library could avoid unnecessary work, and instead of copying the data "steal" it.</p>
</div>
<div class="paragraph">
<p>It is true that adding a new overload increases the already extremely high number of member functions of <code>std::string</code>.</p>
</div>
<div class="paragraph">
<p>On the other hand most users do not need to know it&#8217;s existence to take advantage of the provided optimization.</p>
</div>
<div class="paragraph">
<p>Thus this paper is not extending API surface, there is no names or behavior to be learned by user, and we just get extension that follows established language convection.</p>
</div>
<div class="paragraph">
<p>For users aware of the overload, they can move a string in order to "steal" it&#8217;s storage in a natural way:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">string</span> <span class="tok-n">foo</span> <span class="tok-o">=</span> <span class="tok-p">...;</span>
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">string</span> <span class="tok-n">bar</span> <span class="tok-o">=</span> <span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">move</span><span class="tok-p">(</span><span class="tok-n">foo</span><span class="tok-p">).</span><span class="tok-n">substr</span><span class="tok-p">(...);</span></code></pre>
</div>
</div>
<div class="sect2">
<h3 id="_couldnt_a_library_vendor_provide_such_overload_as_qoi">2.1. Couldn&#8217;t a library vendor provide such overload as QOI?</h3>
<div class="paragraph">
<p>No, because it is a breaking change.
Fur such library, following code would misbehave</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">string</span> <span class="tok-n">foo</span> <span class="tok-o">=</span> <span class="tok-p">...;</span>
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">string</span> <span class="tok-n">bar</span> <span class="tok-o">=</span> <span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">move</span><span class="tok-p">(</span><span class="tok-n">foo</span><span class="tok-p">).</span><span class="tok-n">substr</span><span class="tok-p">(...);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p><code>[res.on.arguments]</code> says that a programmer can&#8217;t expect an object referred to by an rvalue reference to remain untouched.
But there is currently no rvalue reference in <code>substr()</code>.
This paper is proposing to add it.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_design_decisions">3. Design Decisions</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This is purely a library extension.</p>
</div>
<div class="paragraph">
<p>Currently <code>substr</code> is defined as</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-k">constexpr</span> <span class="tok-n">basic_string</span> <span class="tok-n">substr</span><span class="tok-p">(</span><span class="tok-n">size_type</span> <span class="tok-n">pos</span> <span class="tok-o">=</span> <span class="tok-mi">0</span><span class="tok-p">,</span> <span class="tok-n">size_type</span> <span class="tok-n">n</span> <span class="tok-o">=</span> <span class="tok-n">npos</span><span class="tok-p">)</span> <span class="tok-k">const</span><span class="tok-p">;</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>This paper proposes to define following overloads</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-k">constexpr</span> <span class="tok-n">basic_string</span> <span class="tok-n">substr</span><span class="tok-p">(</span><span class="tok-n">size_type</span> <span class="tok-n">pos</span> <span class="tok-o">=</span> <span class="tok-mi">0</span><span class="tok-p">,</span> <span class="tok-n">size_type</span> <span class="tok-n">n</span> <span class="tok-o">=</span> <span class="tok-n">npos</span><span class="tok-p">)</span> <span class="tok-k">const</span> <span class="tok-o">&amp;</span><span class="tok-p">;</span>
<span class="tok-k">constexpr</span> <span class="tok-n">basic_string</span> <span class="tok-n">substr</span><span class="tok-p">(</span><span class="tok-n">size_type</span> <span class="tok-n">pos</span> <span class="tok-o">=</span> <span class="tok-mi">0</span><span class="tok-p">,</span> <span class="tok-n">size_type</span> <span class="tok-n">n</span> <span class="tok-o">=</span> <span class="tok-n">npos</span><span class="tok-p">)</span> <span class="tok-o">&amp;&amp;</span><span class="tok-p">;</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Other overloads (<code>constexpr basic_string substr(size_type pos = 0, size_type n = npos) const &amp;&amp;;</code> and <code>constexpr basic_string substr(size_type pos = 0, size_type n = npos) &amp;;</code>) are not necessary.</p>
</div>
<div class="paragraph">
<p>Notice that the current proposal is a breaking change, as following snippet of code might work differently if this paper gets accepted:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">string</span> <span class="tok-n">foo</span> <span class="tok-o">=</span> <span class="tok-p">...;</span>
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">string</span> <span class="tok-n">bar</span> <span class="tok-o">=</span> <span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">move</span><span class="tok-p">(</span><span class="tok-n">foo</span><span class="tok-p">).</span><span class="tok-n">substr</span><span class="tok-p">(...);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Until C&#43;&#43;20, <code>foo</code> wont change it&#8217;s value, after this paper, the state of <code>foo</code> would be in a "valid but unspecified state".</p>
</div>
<div class="paragraph">
<p>While a breaking change is generally bad:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>I do not think there exists code like <code>std::move(foo).substr(&#8230;&#8203;)</code> in the wild</p>
</li>
<li>
<p>Even if such code exists, the intention of the author was very probably to tell the compiler that he is not interested in the value of <code>foo</code> anymore, as it is normally the case when using <code>std::move</code> on a variable. In other words, with this proposal the user is getting what he asked for.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The standard library proposes two way for creating a "substring" instance, either by calling "substr" method or via constructor that accepts (str, pos, len). We see both of them as different spelling of same functionality, and believe they behavior should remaining consistent. Thus we propose to add rvalue overload constructors.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-k">constexpr</span> <span class="tok-nf">basic_string</span><span class="tok-p">(</span> <span class="tok-n">basic_string</span><span class="tok-o">&amp;&amp;</span> <span class="tok-n">other</span><span class="tok-p">,</span> <span class="tok-n">size_type</span> <span class="tok-n">pos</span><span class="tok-p">,</span> <span class="tok-k">const</span> <span class="tok-n">Allocator</span><span class="tok-o">&amp;</span> <span class="tok-n">alloc</span> <span class="tok-o">=</span> <span class="tok-n">Allocator</span><span class="tok-p">()</span> <span class="tok-p">);</span>
<span class="tok-k">constexpr</span> <span class="tok-nf">basic_string</span><span class="tok-p">(</span> <span class="tok-n">basic_string</span><span class="tok-o">&amp;&amp;</span> <span class="tok-n">other</span><span class="tok-p">,</span> <span class="tok-n">size_type</span> <span class="tok-n">pos</span><span class="tok-p">,</span> <span class="tok-n">size_type</span> <span class="tok-n">count</span><span class="tok-p">,</span> <span class="tok-k">const</span> <span class="tok-n">Allocator</span><span class="tok-o">&amp;</span> <span class="tok-n">alloc</span> <span class="tok-o">=</span> <span class="tok-n">Allocator</span><span class="tok-p">()</span> <span class="tok-p">);</span></code></pre>
</div>
</div>
<div class="sect2">
<h3 id="_note_on_the_propagation_of_the_allocator">3.1. Note on the propagation of the allocator</h3>
<div class="paragraph">
<p><code>basic_string</code> is one of the allocator-container, which means that any memory resource used by this class need to be acquired and released to from the associated allocator instance.
This imposes some limitation on the behavior of the proposed overload.
For example in:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">pmr</span><span class="tok-o">::</span><span class="tok-n">string</span> <span class="tok-n">s1</span> <span class="tok-o">=</span> <span class="tok-p">....;</span>
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">pmr</span><span class="tok-o">::</span><span class="tok-n">string</span> <span class="tok-n">s2</span> <span class="tok-o">=</span> <span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">move</span><span class="tok-p">(</span><span class="tok-n">s1</span><span class="tok-p">).</span><span class="tok-n">substr</span><span class="tok-p">();</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>For <code>s2</code> to be able to steal memory from <code>s1</code>, we need to be sure that the allocators used by both objects are equal (<code>s1.get_allocator() == s2.get_allocator()</code>).
This is trivially achievable for the case of the for the allocators that are always equal (<code>std::allocator_traits&lt;A&gt;::is_always_equal::value</code> is true), including most common case of the stateless <code>std::allocator</code> and implementation can unconditionally steal any allocated memory in such situation.</p>
</div>
<div class="paragraph">
<p>Moreover, the proposed overload can still provide some optimization in case of the stateful allocators, where <code>s2.get_allocator()</code> (which is required to be default constructed) happens to be the same as allocator of the source <code>s1</code>.
In any remaining cases, behavior of this overload should follow existing const version, and as such it does not add any overhead.</p>
</div>
<div class="paragraph">
<p>This paper, recommends implementation to avoid additional memory allocation when possible (note if no-allocation would be performed, there is nothing to avoid), however it does not require so.
This leave it free for implementation to decide, if the optimization should be guarded by:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>compile time check of <code>std::allocator_traits&lt;A&gt;::is_always_equal</code></p>
</li>
<li>
<p>runtime comparison of allocators instance (addition comparison cost).</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_overload_with_user_supplied_allocator">3.2. Overload with user supplied-allocator:</h3>
<div class="paragraph">
<p>While writing the paper, we have noticed that specification of the <code>substr()</code> requires returned object to use default constructed allocator.
This means that invocation of this function is ill-formed for the <code>basic_string</code> instance with non-default constructing allocator, for example for invited <code>memory_pool_allocator&lt;char&gt;</code> that can be only constructed from reference to the pool, the following are ill-formed:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-n">memory_pool</span> <span class="tok-n">pool</span> <span class="tok-o">=</span> <span class="tok-p">...;</span>
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">basic_string</span><span class="tok-o">&lt;</span><span class="tok-kt">char</span><span class="tok-p">,</span> <span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">char_traits</span><span class="tok-o">&lt;</span><span class="tok-kt">char</span><span class="tok-o">&gt;</span><span class="tok-p">,</span> <span class="tok-n">memory_pool_allocator</span><span class="tok-o">&lt;</span><span class="tok-kt">char</span><span class="tok-o">&gt;&gt;</span> <span class="tok-n">s1</span><span class="tok-p">(</span><span class="tok-n">memory_pool_allocator</span><span class="tok-o">&lt;</span><span class="tok-kt">char</span><span class="tok-o">&gt;</span><span class="tok-p">(</span><span class="tok-n">pool</span><span class="tok-p">));</span>
<span class="tok-k">auto</span> <span class="tok-n">s2</span> <span class="tok-o">=</span> <span class="tok-n">s1</span><span class="tok-p">.</span><span class="tok-n">substr</span><span class="tok-p">();</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>This could be address by adding Allocator parameters to <code>substr()</code> overload that accepts allocator to be used as parameter:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-k">constexpr</span> <span class="tok-n">basic_string</span> <span class="tok-n">substr</span><span class="tok-p">(</span><span class="tok-n">size_type</span> <span class="tok-n">pos</span><span class="tok-p">,</span> <span class="tok-k">const</span> <span class="tok-n">Allocator</span><span class="tok-o">&amp;</span> <span class="tok-n">alloc</span><span class="tok-p">)</span> <span class="tok-k">const</span><span class="tok-p">;</span>
<span class="tok-k">constexpr</span> <span class="tok-n">basic_string</span> <span class="tok-n">substr</span><span class="tok-p">(</span><span class="tok-n">size_type</span> <span class="tok-n">pos</span><span class="tok-p">,</span> <span class="tok-n">size_type</span> <span class="tok-n">n</span><span class="tok-p">,</span> <span class="tok-k">const</span> <span class="tok-n">Allocator</span><span class="tok-o">&amp;</span> <span class="tok-n">alloc</span><span class="tok-p">)</span> <span class="tok-k">const</span><span class="tok-p">;</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>While the authors think that this additional feature is related to proposed changes, it is orthogonal to them and could be handled as separate paper.
We seek LEWG guidance if that functionality should be included in the paper.</p>
</div>
</div>
<div class="sect2">
<h3 id="_are_they_any_other_function_of_stdstring_that_would_benefit_from_a_overload">3.3. Are they any other function of <code>std::string</code> that would benefit from a <code>&amp;&amp;</code> overload</h3>
<div class="paragraph">
<p>The member function <code>append</code> and <code>operator+=</code> take <code>std::string</code> as const-ref parameter</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-k">constexpr</span> <span class="tok-n">basic_string</span><span class="tok-o">&amp;</span> <span class="tok-k">operator</span><span class="tok-o">+=</span><span class="tok-p">(</span> <span class="tok-k">const</span> <span class="tok-n">basic_string</span><span class="tok-o">&amp;</span> <span class="tok-n">str</span> <span class="tok-p">);</span>

<span class="tok-k">constexpr</span> <span class="tok-n">basic_string</span><span class="tok-o">&amp;</span> <span class="tok-n">append</span><span class="tok-p">(</span><span class="tok-k">const</span> <span class="tok-n">basic_string</span><span class="tok-o">&amp;</span> <span class="tok-n">str</span><span class="tok-p">);</span>
<span class="tok-k">constexpr</span> <span class="tok-n">basic_string</span><span class="tok-o">&amp;</span> <span class="tok-n">append</span><span class="tok-p">(</span><span class="tok-k">const</span> <span class="tok-n">basic_string</span><span class="tok-o">&amp;</span> <span class="tok-n">str</span><span class="tok-p">,</span> <span class="tok-n">size_type</span> <span class="tok-n">pos</span><span class="tok-p">,</span> <span class="tok-n">size_type</span> <span class="tok-n">n</span> <span class="tok-o">=</span> <span class="tok-n">npos</span><span class="tok-p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>But in this case, because of the interaction of two string instances, the benefits from stealing the resource of <code>str</code> are less clear.
Supposing both string instances use the same allocator, an implementation should compare the capacity of <code>str</code> and <code>this</code>, and evaluate if moving <code>str.size()</code> elements is less costly than copying them.
This would make the implementation of <code>append</code> less obvious, and the performance implications are difficult to predict.</p>
</div>
<div class="paragraph">
<p>For those reasons, the authors does not propose to add new overloads for <code>append</code> and <code>operator+</code>.</p>
</div>
<div class="paragraph">
<p>The authors are not aware of other functions that could benefit from a <code>&amp;&amp;</code> overload.</p>
</div>
</div>
<div class="sect2">
<h3 id="_concerns_on_abi_stability">3.4. Concerns on ABI stability</h3>
<div class="paragraph">
<p>Changing <code>basic_string substr(std::size_t pos, std::size_t len) const;</code> into <code>basic_string substr(std::size_t pos, std::size_t len) const&amp;;</code> and <code>basic_string substr(std::size_t pos, std::size_t len) &amp;&amp;;</code> (the first change is required by the core language rules), can affect the
mangling of the name, thus causing ABI break.</p>
</div>
<div class="paragraph">
<p>For a library it is possible to continue to define the old symbol, so that already existing code will continue to links and work without errors.
For example, it is possible to use asm to define the old mangled name as an alias for the new <code>const&amp;</code> symbol.</p>
</div>
<div class="paragraph">
<p>This is not a novel technique, as it has been explained by the ARG (ABI Review group), and similar breaks have already taken place for other papers, like <a href="https://wg21.link/p0408">P0408</a>.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_technical_specifications">4. Technical Specifications</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Suggested wording (against <a href="http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/n4892.pdf">N4892</a>):</p>
</div>
<div class="paragraph">
<p>Apply following modifications to definition of <code>basic_string class template in [basic.string.general] General</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre>constexpr basic_string(const basic_string&amp; str, size_type pos, const Allocator&amp; a = Allocator());
constexpr basic_string(const basic_string&amp; str, size_type pos, size_type n, const Allocator&amp; a = Allocator());
<span class="underline">constexpr basic_string( basic_string&amp;&amp; str, size_type pos, const Allocator&amp; alloc = Allocator() );</span>
<span class="underline">constexpr basic_string( basic_string&amp;&amp; str, size_type pos, size_type n, const Allocator&amp; alloc = Allocator() );</span></pre>
</div>
</div>
<div class="paragraph">
<p>and</p>
</div>
<div class="listingblock">
<div class="content">
<pre>constexpr basic_string substr(size_type pos = 0, size_type n = npos) const <span class="underline">&amp;</span>;
<span class="underline">constexpr basic_string substr(size_type pos = 0, size_type n = npos) &amp;&amp;;</span></pre>
</div>
</div>
<div class="paragraph">
<p>Replace the definition of the corresponding constructor <code>[string.cons] Constructors and assignment operators</code></p>
</div>
<div class="paragraph">
<p>Wording note:
We no longer define this constructors in terms of being equivalent to corresponding construction from <code>basic_string_view</code>, as that would prevent reuse of the memory, that we want to allow.
The use of "prior the call", are not necessary for <code>const&amp;</code>, but allow us to merge the wording.</p>
</div>
<div class="listingblock">
<div class="content">
<pre>constexpr basic_string(const basic_string&amp; str, size_type pos, const Allocator&amp; a = Allocator());
constexpr basic_string(const basic_string&amp; str, size_type pos, size_type n, const Allocator&amp; a = Allocator());
<span class="underline">constexpr basic_string( basic_string&amp;&amp; str, size_type pos, const Allocator&amp; alloc = Allocator() );</span>
<span class="underline">constexpr basic_string( basic_string&amp;&amp; str, size_type pos, size_type n, const Allocator&amp; alloc = Allocator() );</span></pre>
</div>
</div>
<div class="paragraph">
<p><span class="line-through"><em>Effects</em>: Let <code>n</code> be <code>npos</code> for the first overload. Equivalent to: <code>basic_string(basic_string_view&lt;charT, traits&gt;(str).substr(pos, n), a)</code>.</span><br>
<span class="underline">Let:</span></p>
</div>
<div class="ulist">
<ul>
<li>
<p><span class="underline"><code>s</code> be the value of <code>str</code> prior this call,</span></p>
</li>
<li>
<p><span class="underline"><code>rlen</code> be smaller of <code>n</code> and <code>s.size() - pos</code>, for overloads that define parameter <code>n</code>, and <code>s.size() - pos</code> otherwise.</span></p>
</li>
</ul>
</div>
<div class="paragraph">
<p><span class="underline"><em>Effects</em>: Constructs an object whose initial value is the range <code>[s.data() + pos, rlen)</code><br>
<em>Throws</em>: <code>out_­of_­range</code> if <code>pos &gt; s.size()</code><br>
<em>Remarks</em>: The <code>str</code> is in valid but unspecified state, after invocation of either third or fourth overload.<br>
<em>Recommended practice</em>: For third and fourth overload implementations should avoid unnecessary copies and allocations, if <code>s.get_allocator() == a</code> is <code>true</code>.</span></p>
</div>
<div class="paragraph">
<p>Apply following changes to <code>[string.substr] basic_­string​::​substr</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre>constexpr basic_string substr(size_type pos = 0, size_type n = npos) const <span class="underline">&amp;</span>;</pre>
</div>
</div>
<div class="paragraph">
<p><span class="line-through"><em>Effects</em>: Determines the effective length <code>rlen</code> of the string to copy as the smaller of n and <code>size() - pos</code>.</span><br>
<span class="line-through"><em>Returns</em>: <code>basic_­string(data()+pos, rlen)</code>.</span><br>
<span class="line-through"><em>Throws</em>: <code>out_­of_­range</code> if <code>pos &gt; size()</code>.</span><br>
<span class="underline"><em>Effects</em>: Equivalent to: <code>return basic_string(*this, pos, n);</code></span></p>
</div>
<div class="listingblock">
<div class="content">
<pre><span class="underline">constexpr basic_string substr(size_type pos = 0, size_type n = npos) &amp;&amp;;</span></pre>
</div>
</div>
<div class="paragraph">
<p><span class="underline"><em>Effects</em>: Equivalent to: <code>return basic_string(std::move(*this), pos, n);</code>.</span></p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_acknowledgements">5. Acknowledgements</h2>
<div class="sectionbody">
<div class="paragraph">
<p>A big thank you to all those giving feedback for this paper.</p>
</div>
</div>
</div>
</div>
</body>
</html>