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

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

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

code.sourceCode > span { display: inline; }
</style>
  <link href="data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAVoJEAN6CRADegkQAWIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wCCRAAAgkQAAIJEAACCRAAsgkQAvoJEAP+CRAD/gkQA/4JEAP+CRADAgkQALoJEAACCRAAAgkQAAP///wD///8AgkQAAIJEABSCRACSgkQA/IJEAP99PQD/dzMA/3czAP99PQD/gkQA/4JEAPyCRACUgkQAFIJEAAD///8A////AHw+AFiBQwDqgkQA/4BBAP9/PxP/uZd6/9rJtf/bybX/upd7/39AFP+AQQD/gkQA/4FDAOqAQgBc////AP///wDKklv4jlEa/3o7AP+PWC//8+3o///////////////////////z7un/kFox/35AAP+GRwD/mVYA+v///wD///8A0Zpk+NmibP+0d0T/8evj///////+/fv/1sKz/9bCs//9/fr//////+/m2/+NRwL/nloA/5xYAPj///8A////ANKaZPjRmGH/5cKh////////////k149/3UwAP91MQD/lmQ//86rhv+USg3/m1YA/5hSAP+bVgD4////AP///wDSmmT4zpJY/+/bx///////8+TV/8mLT/+TVx//gkIA/5lVAP+VTAD/x6B//7aEVv/JpH7/s39J+P///wD///8A0ppk+M6SWP/u2sf///////Pj1f/Nj1T/2KFs/8mOUv+eWhD/lEsA/8aee/+0glT/x6F7/7J8Rvj///8A////ANKaZPjRmGH/48Cf///////+/v7/2qt//82PVP/OkFX/37KJ/86siv+USg7/mVQA/5hRAP+bVgD4////AP///wDSmmT40ppk/9CVXP/69O////////7+/v/x4M//8d/P//7+/f//////9u7n/6tnJf+XUgD/nFgA+P///wD///8A0ppk+NKaZP/RmWL/1qNy//r07///////////////////////+vXw/9akdP/Wnmn/y5FY/6JfFvj///8A////ANKaZFTSmmTo0ppk/9GYYv/Ql1//5cWm//Hg0P/x4ND/5cWm/9GXYP/RmGH/0ppk/9KaZOjVnmpY////AP///wDSmmQA0ppkEtKaZI7SmmT60ppk/9CWX//OkVb/zpFW/9CWX//SmmT/0ppk/NKaZJDSmmQS0ppkAP///wD///8A0ppkANKaZADSmmQA0ppkKtKaZLrSmmT/0ppk/9KaZP/SmmT/0ppkvNKaZCrSmmQA0ppkANKaZAD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkUtKaZNzSmmTc0ppkVNKaZADSmmQA0ppkANKaZADSmmQA////AP5/AAD4HwAA4AcAAMADAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAMADAADgBwAA+B8AAP5/AAAoAAAAIAAAAEAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAyCRACMgkQA6oJEAOqCRACQgkQAEIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRABigkQA5oJEAP+CRAD/gkQA/4JEAP+CRADqgkQAZoJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAA4gkQAwoJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQAxIJEADyCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAP///wD///8A////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAWgkQAmIJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAJyCRAAYgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAdIJEAPCCRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAPSCRAB4gkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQASoJEANKCRAD/gkQA/4JEAP+CRAD/g0YA/39AAP9zLgD/bSQA/2shAP9rIQD/bSQA/3MuAP9/PwD/g0YA/4JEAP+CRAD/gkQA/4JEAP+CRADUgkQAToJEAACCRAAAgkQAAP///wD///8A////AP///wB+PwAAgkUAIoJEAKiCRAD/gkQA/4JEAP+CRAD/hEcA/4BBAP9sIwD/dTAA/5RfKv+viF7/vp56/76ee/+wiF7/lWAr/3YxAP9sIwD/f0AA/4RHAP+CRAD/gkQA/4JEAP+CRAD/gkQArIJEACaBQwAA////AP///wD///8A////AIBCAEBzNAD6f0EA/4NFAP+CRAD/gkQA/4VIAP92MwD/bSUA/6N1Tv/ezsL/////////////////////////////////38/D/6V3Uv9uJgD/dTEA/4VJAP+CRAD/gkQA/4JEAP+BQwD/fUAA/4FDAEj///8A////AP///wD///8AzJRd5qBlKf91NgD/dDUA/4JEAP+FSQD/cy4A/3YyAP/PuKP//////////////////////////////////////////////////////9K7qP94NQD/ciwA/4VJAP+CRAD/fkEA/35BAP+LSwD/mlYA6v///wD///8A////AP///wDdpnL/4qx3/8KJUv+PUhf/cTMA/3AsAP90LgD/4dK+/////////////////////////////////////////////////////////////////+TYxf91MAD/dTIA/31CAP+GRwD/llQA/6FcAP+gWwD8////AP///wD///8A////ANGZY/LSm2X/4ap3/92mcP+wdT3/byQA/8mwj////////////////////////////////////////////////////////////////////////////+LYxv9zLgP/jUoA/59bAP+hXAD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/RmWL/1p9q/9ubXv/XqXj////////////////////////////7+fD/vZyG/6BxS/+gcUr/vJuE//r37f//////////////////////3MOr/5dQBf+dVQD/nVkA/5xYAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmWP/yohJ//jo2P//////////////////////4NTG/4JDFf9lGAD/bSQA/20kAP9kGAD/fz8S/+Xb0f//////5NG9/6txN/+LOgD/m1QA/51aAP+cWAD/m1cA/5xYAP+cWADy////AP///wD///8A////ANKaZPLSmmT/0ppk/8+TWf/Unmv//v37//////////////////////+TWRr/VwsA/35AAP+ERgD/g0UA/4JGAP9lHgD/kFga/8KXX/+TRwD/jT4A/49CAP+VTQD/n10A/5xYAP+OQQD/lk4A/55cAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/y4tO/92yiP//////////////////////8NnE/8eCQP+rcTT/ez0A/3IyAP98PgD/gEMA/5FSAP+USwD/jj8A/5lUAP+JNwD/yqV2/694Mf+HNQD/jkAA/82rf/+laBj/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/LiUr/4byY///////////////////////gupX/0I5P/+Wuev/Lklz/l1sj/308AP+QSwD/ol0A/59aAP+aVQD/k0oA/8yoh///////+fXv/6pwO//Lp3v///////Pr4f+oay7y////AP///wD///8A////ANKaZPLSmmT/0ppk/8uJSv/hvJj//////////////////////+G7l//Jhkb/0ppk/96nc//fqXX/x4xO/6dkFP+QSQD/llEA/5xXAP+USgD/yaOA///////38uv/qG05/8ijdv//////8efb/6ZpLPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/zIxO/9yxh///////////////////////7dbA/8iEQf/Sm2X/0Zlj/9ScZv/eqHf/2KJv/7yAQf+XTgD/iToA/5lSAP+JNgD/yKFv/611LP+HNQD/jT8A/8qmeP+kZRT/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/Pk1n/1J5q//78+//////////////////+/fv/1aFv/8iEQv/Tm2b/0ppl/9GZY//Wn2z/1pZc/9eldf/Bl2b/kUcA/4w9AP+OQAD/lUwA/59eAP+cWQD/jT8A/5ZOAP+eXADy////AP///wD///8A////ANKaZPLSmmT/0ppk/9KZY//KiEn/8d/P///////////////////////47+f/05tm/8iCP//KiEj/yohJ/8eCP//RmGH//vfy///////n1sP/rXQ7/4k4AP+TTAD/nVoA/5xYAP+cVwD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/0ptl/8uLTf/aq37////////////////////////////+/fz/6c2y/961jv/etY7/6Myx//78+v//////////////////////3MWv/5xXD/+ORAD/mFQA/51ZAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmmT/0ppk/8mFRP/s1b//////////////////////////////////////////////////////////////////////////////+PD/0JFU/7NzMv+WUQD/kUsA/5tXAP+dWQDy////AP///wD///8A////ANKaZP/SmmT/0ppk/9KaZP/Sm2X/z5NZ/8yMT//z5NX/////////////////////////////////////////////////////////////////9Ofa/8yNUP/UmGH/36p5/8yTWv+qaSD/kksA/5ROAPz///8A////AP///wD///8A0ppk5NKaZP/SmmT/0ppk/9KaZP/TnGf/zY9T/82OUv/t1sD//////////////////////////////////////////////////////+7Yw//OkFX/zI5R/9OcZ//SmmP/26V0/9ymdf/BhUf/ol8R6P///wD///8A////AP///wDSmmQ80ppk9tKaZP/SmmT/0ppk/9KaZP/TnGj/zpFW/8qJSv/dson/8uHS//////////////////////////////////Lj0//etIv/y4lL/86QVf/TnGj/0ppk/9KaZP/RmWP/05xn/9ymdfjUnWdC////AP///wD///8A////ANKaZADSmmQc0ppkotKaZP/SmmT/0ppk/9KaZP/Tm2b/0Zli/8qJSf/NjlH/16Z3/+G8mP/myKr/5siq/+G8mP/Xp3f/zY5S/8qISf/RmGH/05tm/9KaZP/SmmT/0ppk/9KaZP/SmmSm0pljINWdaQD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkQtKaZMrSmmT/0ppk/9KaZP/SmmT/0ptl/9GYYf/Nj1P/y4lL/8qISP/KiEj/y4lK/82PU//RmGH/0ptl/9KaZP/SmmT/0ppk/9KaZP/SmmTO0ppkRtKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZGzSmmTu0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmTw0ppkcNKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZBLSmmSQ0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppklNKaZBTSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQy0ppkutKaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppkvtKaZDbSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkXNKaZODSmmT/0ppk/9KaZP/SmmT/0ppk5NKaZGDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkBtKaZIbSmmTo0ppk6tKaZIrSmmQK0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP/8P///+B///+AH//+AAf//AAD//AAAP/AAAA/gAAAHwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA+AAAAfwAAAP/AAAP/8AAP//gAH//+AH///4H////D//" rel="icon" />
  
  <!--[if lt IE 9]>
    <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
  <![endif]-->
</head>
<body>
<div class="wrapper">
<header id="title-block-header">
<h1 class="title" style="text-align:center"><code class="sourceCode default">std::basic_fixed_string</code></h1>
<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P3094R0</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2024-01-18</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>
      SG16 Unicode<br>
      SG18 Library Evolution Working Group Incubator (LEWGI)<br>
      Library Evolution Working Group<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to:</td>
    <td>
      Mateusz Pusz (<a href="http://www.epam.com">Epam
Systems</a>)<br>&lt;<a href="mailto:mateusz.pusz@gmail.com" class="email">mateusz.pusz@gmail.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="#introduction" id="toc-introduction"><span class="toc-section-number">1</span> Introduction<span></span></a></li>
<li><a href="#fixed_string-is-an-established-practice" id="toc-fixed_string-is-an-established-practice"><span class="toc-section-number">2</span>
<code class="sourceCode default">fixed_string</code> is an established
practice<span></span></a></li>
<li><a href="#minimal-interface-requirements" id="toc-minimal-interface-requirements"><span class="toc-section-number">3</span> Minimal interface
requirements<span></span></a></li>
<li><a href="#interface" id="toc-interface"><span class="toc-section-number">4</span> Interface<span></span></a></li>
<li><a href="#implementation-experience" id="toc-implementation-experience"><span class="toc-section-number">5</span> Implementation
experience<span></span></a></li>
<li><a href="#fixed_string-design-alternatives" id="toc-fixed_string-design-alternatives"><span class="toc-section-number">6</span>
<code class="sourceCode default">fixed_string</code> design
alternatives<span></span></a>
<ul>
<li><a href="#full-string_view-like-interface" id="toc-full-string_view-like-interface"><span class="toc-section-number">6.1</span> Full
<code class="sourceCode default">string_view</code>-like
interface<span></span></a></li>
<li><a href="#mutation-interface" id="toc-mutation-interface"><span class="toc-section-number">6.2</span> Mutation
interface<span></span></a></li>
<li><a href="#inplace_string" id="toc-inplace_string"><span class="toc-section-number">6.3</span>
<code class="sourceCode default">inplace_string</code><span></span></a></li>
<li><a href="#stdstring-with-a-static-storage-allocator" id="toc-stdstring-with-a-static-storage-allocator"><span class="toc-section-number">6.4</span>
<code class="sourceCode default">std::string</code> with a static
storage allocator<span></span></a></li>
<li><a href="#just-wait-for-the-c-language-to-solve-it" id="toc-just-wait-for-the-c-language-to-solve-it"><span class="toc-section-number">6.5</span> Just wait for the C++ language to
solve it<span></span></a></li>
</ul></li>
<li><a href="#acknowledgements" id="toc-acknowledgements"><span class="toc-section-number">7</span>
Acknowledgements<span></span></a></li>
<li><a href="#bibliography" id="toc-bibliography"><span class="toc-section-number">8</span> References<span></span></a></li>
</ul>
</div>
<h1 data-number="1" id="introduction"><span class="header-section-number">1</span> Introduction<a href="#introduction" class="self-link"></a></h1>
<p>This paper proposes standardizing a string type that could be used at
compile-time as a non-type template parameter (NTTP). This means that
such string type has to satisfy the structural type requirements of the
C++ language. One of such requirements is to expose all the data members
publicly. So far, none of the existing string types in the C++ standard
library satisfies such requirements.</p>
<p>This type is intended to serve as an essential building block and be
exposes as a part of the public interface of quantities and units
library proposed in <span class="citation" data-cites="P2980R1">[<a href="#ref-P2980R1" role="doc-biblioref">P2980R1</a>]</span>. All
dimensions, units, prefixes, and constants definitions will use it to
provide their textual representation.</p>
<h1 data-number="2" id="fixed_string-is-an-established-practice"><span class="header-section-number">2</span>
<code class="sourceCode default">fixed_string</code> is an established
practice<a href="#fixed_string-is-an-established-practice" class="self-link"></a></h1>
<p>There are plenty of home-grown
<code class="sourceCode default">fixed_string</code> types. Every
project that wants to pass text as NTTP already provides its own version
of it. There are also some that predate C++20 and do not satisfy
structural type requirements.</p>
<p>A <a href="https://github.com/search?q=fixed_string+language%3AC%2B%2B&amp;type=repositories&amp;ref=advsearch">quick
search in GitHub</a> returns plenty of results. Let’s mention a few of
those:</p>
<ul>
<li><a href="https://github.com/mpusz/mp-units/blob/master/src/core/include/mp-units/bits/external/fixed_string.h">mpusz/mp-units</a></li>
<li><a href="https://github.com/fmtlib/fmt/blob/5cfd28d476c6859617878f951931b8ce7d36b9df/include/fmt/format.h#L1065-L1071">fmtlib/fmt</a></li>
<li><a href="https://github.com/hanickadot/compile-time-regular-expressions/blob/029f1f13646cf65ec09780013418cb8f1c5d3a59/include/ctll/fixed_string.hpp#L44-L220">hanickadot/compile-time-regular-expressions</a></li>
<li><a href="https://github.com/tomazos/fixed_string">tomazos/fixed_string</a>
- a reference implementation of <span class="citation" data-cites="P0259R0">[<a href="#ref-P0259R0" role="doc-biblioref">P0259R0</a>]</span> (not a structural type as it is
8 years old)</li>
<li><a href="https://github.com/unterumarmung/fixed_string">unterumarmung/fixed_string</a></li>
<li><a href="https://github.com/mu001999/fixed_string">mu001999/fixed_string</a></li>
<li><a href="https://github.com/calebxyz/Fixed_Strings">calebxyz/Fixed_Strings</a></li>
<li><a href="https://github.com/astral-shining/FixedString">astral-shining/FixedString</a></li>
<li><a href="https://github.com/ynsn/fixed_string">ynsn/fixed_string</a></li>
</ul>
<p>Having such a type in the C++ standard library will prevent
reinventing the wheel by the community and reimplementing it in every
project that handles text at compile-time.</p>
<h1 data-number="3" id="minimal-interface-requirements"><span class="header-section-number">3</span> Minimal interface requirements<a href="#minimal-interface-requirements" class="self-link"></a></h1>
<p>Such type should at least:</p>
<ul>
<li>satisfy structural type requirements,</li>
<li>be equality comparable and potentially totally ordered,</li>
<li>store and provide concatenation support for zero-ended strings,</li>
<li>provide storage that, if set at compile time, would also be
available for read-only access at runtime,</li>
<li>provide at least read-only access to the contained storage.</li>
</ul>
<p>It does not need to expose a string-like interface. In case its
interface is immutable, as it is proposed by the author, we can easily
wrap it with <code class="sourceCode default">std::string_view</code> to
get such an interface for free.</p>
<h1 data-number="4" id="interface"><span class="header-section-number">4</span> Interface<a href="#interface" class="self-link"></a></h1>
<p><code class="sourceCode default">fixed_string</code> is a read-only
text container. It satisfies structural type requirements, its size is
fixed as one of the class template parameters, and it has a minimalistic
range/view-like interface:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">typename</span> CharT, std<span class="op">::</span><span class="dt">size_t</span> N<span class="op">&gt;</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> basic_fixed_string <span class="op">{</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>  CharT data_<span class="op">[</span>N <span class="op">+</span> <span class="dv">1</span><span class="op">]</span> <span class="op">=</span> <span class="op">{}</span>;  <span class="co">// exposition only</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> value_type <span class="op">=</span> CharT;</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> pointer <span class="op">=</span> CharT<span class="op">*</span>;</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> const_pointer <span class="op">=</span> <span class="kw">const</span> CharT<span class="op">*</span>;</span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> reference <span class="op">=</span> CharT<span class="op">&amp;</span>;</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> const_reference <span class="op">=</span> <span class="kw">const</span> CharT<span class="op">&amp;</span>;</span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> const_iterator <span class="op">=</span> <span class="kw">const</span> CharT<span class="op">*</span>;</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> iterator <span class="op">=</span> const_iterator;</span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> size_type <span class="op">=</span> std<span class="op">::</span><span class="dt">size_t</span>;</span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> difference_type <span class="op">=</span> std<span class="op">::</span><span class="dt">ptrdiff_t</span>;</span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> <span class="kw">explicit</span><span class="op">(</span><span class="kw">false</span><span class="op">)</span> basic_fixed_string<span class="op">(</span><span class="kw">const</span> CharT <span class="op">(&amp;</span>txt<span class="op">)[</span>N <span class="op">+</span> <span class="dv">1</span><span class="op">])</span> <span class="kw">noexcept</span>;</span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> basic_fixed_string<span class="op">(</span><span class="kw">const</span> CharT<span class="op">*</span> ptr, std<span class="op">::</span>integral_constant<span class="op">&lt;</span>std<span class="op">::</span><span class="dt">size_t</span>, N<span class="op">&gt;)</span> <span class="kw">noexcept</span>;</span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span>std<span class="op">::</span>convertible_to<span class="op">&lt;</span>CharT<span class="op">&gt;...</span> Rest<span class="op">&gt;</span></span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a>    <span class="kw">requires</span><span class="op">(</span><span class="dv">1</span> <span class="op">+</span> <span class="kw">sizeof</span><span class="op">...(</span>Rest<span class="op">)</span> <span class="op">==</span> N<span class="op">)</span></span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> <span class="kw">explicit</span> basic_fixed_string<span class="op">(</span>CharT first, Rest<span class="op">...</span> rest<span class="op">)</span> <span class="kw">noexcept</span>;</span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a>  <span class="op">[[</span><span class="at">nodiscard</span><span class="op">]]</span> <span class="kw">constexpr</span> <span class="dt">bool</span> empty<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a>  <span class="op">[[</span><span class="at">nodiscard</span><span class="op">]]</span> <span class="kw">constexpr</span> size_type size<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a>  <span class="op">[[</span><span class="at">nodiscard</span><span class="op">]]</span> <span class="kw">constexpr</span> const_pointer data<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb1-25"><a href="#cb1-25" aria-hidden="true" tabindex="-1"></a>  <span class="op">[[</span><span class="at">nodiscard</span><span class="op">]]</span> <span class="kw">constexpr</span> <span class="kw">const</span> CharT<span class="op">*</span> c_str<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb1-26"><a href="#cb1-26" aria-hidden="true" tabindex="-1"></a>  <span class="op">[[</span><span class="at">nodiscard</span><span class="op">]]</span> <span class="kw">constexpr</span> value_type <span class="kw">operator</span><span class="op">[](</span>size_type index<span class="op">)</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb1-27"><a href="#cb1-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-28"><a href="#cb1-28" aria-hidden="true" tabindex="-1"></a>  <span class="op">[[</span><span class="at">nodiscard</span><span class="op">]]</span> <span class="kw">constexpr</span> const_iterator begin<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb1-29"><a href="#cb1-29" aria-hidden="true" tabindex="-1"></a>  <span class="op">[[</span><span class="at">nodiscard</span><span class="op">]]</span> <span class="kw">constexpr</span> const_iterator cbegin<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb1-30"><a href="#cb1-30" aria-hidden="true" tabindex="-1"></a>  <span class="op">[[</span><span class="at">nodiscard</span><span class="op">]]</span> <span class="kw">constexpr</span> const_iterator end<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb1-31"><a href="#cb1-31" aria-hidden="true" tabindex="-1"></a>  <span class="op">[[</span><span class="at">nodiscard</span><span class="op">]]</span> <span class="kw">constexpr</span> const_iterator cend<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb1-32"><a href="#cb1-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-33"><a href="#cb1-33" aria-hidden="true" tabindex="-1"></a>  <span class="op">[[</span><span class="at">nodiscard</span><span class="op">]]</span> <span class="kw">constexpr</span> std<span class="op">::</span>basic_string_view<span class="op">&lt;</span>CharT<span class="op">&gt;</span> view<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb1-34"><a href="#cb1-34" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-35"><a href="#cb1-35" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span>std<span class="op">::</span><span class="dt">size_t</span> N2<span class="op">&gt;</span></span>
<span id="cb1-36"><a href="#cb1-36" aria-hidden="true" tabindex="-1"></a>  <span class="op">[[</span><span class="at">nodiscard</span><span class="op">]]</span> <span class="kw">constexpr</span> <span class="kw">friend</span> basic_fixed_string<span class="op">&lt;</span>CharT, N <span class="op">+</span> N2<span class="op">&gt;</span> <span class="kw">operator</span><span class="op">+(</span><span class="kw">const</span> basic_fixed_string<span class="op">&amp;</span> lhs,</span>
<span id="cb1-37"><a href="#cb1-37" aria-hidden="true" tabindex="-1"></a>                                                                             <span class="kw">const</span> basic_fixed_string<span class="op">&lt;</span>CharT, N2<span class="op">&gt;&amp;</span> rhs<span class="op">)</span> <span class="kw">noexcept</span>;</span>
<span id="cb1-38"><a href="#cb1-38" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-39"><a href="#cb1-39" aria-hidden="true" tabindex="-1"></a>  <span class="op">[[</span><span class="at">nodiscard</span><span class="op">]]</span> <span class="kw">constexpr</span> <span class="dt">bool</span> <span class="kw">operator</span><span class="op">==(</span><span class="kw">const</span> basic_fixed_string<span class="op">&amp;</span> other<span class="op">)</span> <span class="kw">const</span>;</span>
<span id="cb1-40"><a href="#cb1-40" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span>std<span class="op">::</span><span class="dt">size_t</span> N2<span class="op">&gt;</span></span>
<span id="cb1-41"><a href="#cb1-41" aria-hidden="true" tabindex="-1"></a>  <span class="op">[[</span><span class="at">nodiscard</span><span class="op">]]</span> <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="dt">bool</span> <span class="kw">operator</span><span class="op">==(</span><span class="kw">const</span> basic_fixed_string<span class="op">&amp;</span>, <span class="kw">const</span> basic_fixed_string<span class="op">&lt;</span>CharT, N2<span class="op">&gt;&amp;)</span>;</span>
<span id="cb1-42"><a href="#cb1-42" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-43"><a href="#cb1-43" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span>std<span class="op">::</span><span class="dt">size_t</span> N2<span class="op">&gt;</span></span>
<span id="cb1-44"><a href="#cb1-44" aria-hidden="true" tabindex="-1"></a>  <span class="op">[[</span><span class="at">nodiscard</span><span class="op">]]</span> <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span><span class="op">&lt;=&gt;(</span><span class="kw">const</span> basic_fixed_string<span class="op">&amp;</span> lhs,</span>
<span id="cb1-45"><a href="#cb1-45" aria-hidden="true" tabindex="-1"></a>                                                  <span class="kw">const</span> basic_fixed_string<span class="op">&lt;</span>CharT, N2<span class="op">&gt;&amp;</span> rhs<span class="op">)</span>;</span>
<span id="cb1-46"><a href="#cb1-46" aria-hidden="true" tabindex="-1"></a>  </span>
<span id="cb1-47"><a href="#cb1-47" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">typename</span> Traits<span class="op">&gt;</span></span>
<span id="cb1-48"><a href="#cb1-48" aria-hidden="true" tabindex="-1"></a>  <span class="kw">friend</span> std<span class="op">::</span>basic_ostream<span class="op">&lt;</span>CharT, Traits<span class="op">&gt;&amp;</span> <span class="kw">operator</span><span class="op">&lt;&lt;(</span>std<span class="op">::</span>basic_ostream<span class="op">&lt;</span>CharT, Traits<span class="op">&gt;&amp;</span> os,</span>
<span id="cb1-49"><a href="#cb1-49" aria-hidden="true" tabindex="-1"></a>                                                       <span class="kw">const</span> basic_fixed_string<span class="op">&lt;</span>CharT, N<span class="op">&gt;&amp;</span> str<span class="op">)</span>;</span>
<span id="cb1-50"><a href="#cb1-50" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb1-51"><a href="#cb1-51" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-52"><a href="#cb1-52" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">typename</span> CharT, std<span class="op">::</span><span class="dt">size_t</span> N<span class="op">&gt;</span></span>
<span id="cb1-53"><a href="#cb1-53" aria-hidden="true" tabindex="-1"></a>basic_fixed_string<span class="op">(</span><span class="kw">const</span> CharT <span class="op">(&amp;</span>str<span class="op">)[</span>N<span class="op">])</span> <span class="op">-&gt;</span> basic_fixed_string<span class="op">&lt;</span>CharT, N <span class="op">-</span> <span class="dv">1</span><span class="op">&gt;</span>;</span>
<span id="cb1-54"><a href="#cb1-54" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-55"><a href="#cb1-55" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">typename</span> CharT, std<span class="op">::</span><span class="dt">size_t</span> N<span class="op">&gt;</span></span>
<span id="cb1-56"><a href="#cb1-56" aria-hidden="true" tabindex="-1"></a>basic_fixed_string<span class="op">(</span><span class="kw">const</span> CharT<span class="op">*</span> ptr, std<span class="op">::</span>integral_constant<span class="op">&lt;</span>std<span class="op">::</span><span class="dt">size_t</span>, N<span class="op">&gt;)</span> <span class="op">-&gt;</span> basic_fixed_string<span class="op">&lt;</span>CharT, N<span class="op">&gt;</span>;</span>
<span id="cb1-57"><a href="#cb1-57" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-58"><a href="#cb1-58" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">typename</span> CharT, std<span class="op">::</span>convertible_to<span class="op">&lt;</span>CharT<span class="op">&gt;...</span> Rest<span class="op">&gt;</span></span>
<span id="cb1-59"><a href="#cb1-59" aria-hidden="true" tabindex="-1"></a>basic_fixed_string<span class="op">(</span>CharT, Rest<span class="op">...)</span> <span class="op">-&gt;</span> basic_fixed_string<span class="op">&lt;</span>CharT, <span class="dv">1</span> <span class="op">+</span> <span class="kw">sizeof</span><span class="op">...(</span>Rest<span class="op">)&gt;</span>;</span>
<span id="cb1-60"><a href="#cb1-60" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-61"><a href="#cb1-61" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span>std<span class="op">::</span><span class="dt">size_t</span> N<span class="op">&gt;</span></span>
<span id="cb1-62"><a href="#cb1-62" aria-hidden="true" tabindex="-1"></a><span class="kw">using</span> fixed_string <span class="op">=</span> basic_fixed_string<span class="op">&lt;</span><span class="dt">char</span>, N<span class="op">&gt;</span>;</span>
<span id="cb1-63"><a href="#cb1-63" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-64"><a href="#cb1-64" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">typename</span> CharT, std<span class="op">::</span><span class="dt">size_t</span> N<span class="op">&gt;</span></span>
<span id="cb1-65"><a href="#cb1-65" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> std<span class="op">::</span>formatter<span class="op">&lt;</span>basic_fixed_string<span class="op">&lt;</span>CharT, N<span class="op">&gt;&gt;</span> <span class="op">:</span> formatter<span class="op">&lt;</span>std<span class="op">::</span>basic_string_view<span class="op">&lt;</span>CharT<span class="op">&gt;&gt;</span> <span class="op">{</span></span>
<span id="cb1-66"><a href="#cb1-66" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">typename</span> FormatContext<span class="op">&gt;</span></span>
<span id="cb1-67"><a href="#cb1-67" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> format<span class="op">(</span><span class="kw">const</span> basic_fixed_string<span class="op">&lt;</span>CharT, N<span class="op">&gt;&amp;</span> str, FormatContext<span class="op">&amp;</span> ctx<span class="op">)</span></span>
<span id="cb1-68"><a href="#cb1-68" aria-hidden="true" tabindex="-1"></a>  <span class="op">{</span></span>
<span id="cb1-69"><a href="#cb1-69" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> formatter<span class="op">&lt;</span>std<span class="op">::</span>basic_string_view<span class="op">&lt;</span>CharT<span class="op">&gt;&gt;::</span>format<span class="op">(</span>str<span class="op">.</span>view<span class="op">()</span>, ctx<span class="op">)</span>;</span>
<span id="cb1-70"><a href="#cb1-70" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb1-71"><a href="#cb1-71" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<p>Please note that there are nearly no text-specific member functions
inside (besides <code class="sourceCode default">.c_str()</code> that
could be easily omitted and replaced with
<code class="sourceCode default">.data()</code> in the user’s code).</p>
<p>This type could probably even serve as a generic storage structural
type if it didn’t have an invariant requiring its internal contiguous
data storage to be of <code class="sourceCode default">size + 1</code>
and ending with <code class="sourceCode default">\0</code>.</p>
<h1 data-number="5" id="implementation-experience"><span class="header-section-number">5</span> Implementation experience<a href="#implementation-experience" class="self-link"></a></h1>
<p>This particular interface is implemented and successfully used in the
<a href="https://github.com/mpusz/mp-units/blob/master/src/core/include/mp-units/bits/external/fixed_string.h">mp-units</a>
project.</p>
<h1 data-number="6" id="fixed_string-design-alternatives"><span class="header-section-number">6</span>
<code class="sourceCode default">fixed_string</code> design
alternatives<a href="#fixed_string-design-alternatives" class="self-link"></a></h1>
<h2 data-number="6.1" id="full-string_view-like-interface"><span class="header-section-number">6.1</span> Full
<code class="sourceCode default">string_view</code>-like interface<a href="#full-string_view-like-interface" class="self-link"></a></h2>
<p>We could add a whole
<code class="sourceCode default">string_view</code>-like interface to
this class, but the author decided not to do it. This will add plenty of
overloads that will probably not be used too often by the users of this
particular type anyway. Doing that will add a maintenance burden to keep
it consistent with all other string-like types in the library.</p>
<p>If the user needs to obtain a
<code class="sourceCode default">string_view</code>-like interface to
work with this type, then
<code class="sourceCode default">std::string_view</code> itself can
easily be used to achieve that:</p>
<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>basic_fixed_string txt <span class="op">=</span> <span class="st">&quot;abc&quot;</span>;</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> pos <span class="op">=</span> txt<span class="op">.</span>view<span class="op">().</span>find_first_of<span class="op">(</span><span class="ch">&#39;b&#39;</span><span class="op">)</span>;</span></code></pre></div>
<h2 data-number="6.2" id="mutation-interface"><span class="header-section-number">6.2</span> Mutation interface<a href="#mutation-interface" class="self-link"></a></h2>
<p>As stated above, this type is read-only. As we can’t resize the
string, it could be considered controversial to allow mutation of the
contents. The only thing we could provide would be support for
overwriting specific characters in the internal storage. This, however,
does not seem to be a common use case for such a type.</p>
<p>If passed as an NTTP, such type would be
<code class="sourceCode default">const</code> at runtime, which would
disable all the mutation interface anyway.</p>
<p>On the other hand, such an interface would allow running every
<code class="sourceCode default">constexpr</code> algorithm from the C++
standard library on such a range at compile time.</p>
<p>If we decide to add such an interface, it is worth pointing out that
wrapping the type in the
<code class="sourceCode default">std::string_view</code> would not be
enough to obtain a proper string-like mutating interface. As we do not
have another string-like reference type that provides mutating
capabilities we can end up with the need to implement the entire string
interface in this class as well.</p>
<p>This is why the author does not propose to add it in the first
iteration. We can always easily add such an interface later if a need
for it arises.</p>
<h2 data-number="6.3" id="inplace_string"><span class="header-section-number">6.3</span>
<code class="sourceCode default">inplace_string</code><a href="#inplace_string" class="self-link"></a></h2>
<p>We could also consider providing a full-blown fixed-capacity string
class similar to the
<code class="sourceCode default">inplace_vector</code> <span class="citation" data-cites="P0843R9">[<a href="#ref-P0843R9" role="doc-biblioref">P0843R9</a>]</span>. It would provide not only full
read-write capability but also be really beneficial for embedded and
low-latency domains.</p>
<p>Despite being welcomed and valuable in the C++ community, the author
believes that such a type should not satisfy the current requirements
for a structural type, which is a hard requirement of this use case. If
<code class="sourceCode default">inplace_string</code> was used instead,
we would end up with separate template instantiations for objects with
the same value but a different capacity. We prefer to prevent such a
behavior.</p>
<h2 data-number="6.4" id="stdstring-with-a-static-storage-allocator"><span class="header-section-number">6.4</span>
<code class="sourceCode default">std::string</code> with a static
storage allocator<a href="#stdstring-with-a-static-storage-allocator" class="self-link"></a></h2>
<p>We could also try to use
<code class="sourceCode default">std::string</code> with a static
storage allocator, but this solution does not meet structural type
requirements and could be an overkill for this use case, resulting with
significantly decreased compile times.</p>
<p>Also, it would be hard or impossible to make the storage created at
compile-time to be accessible at runtime in such cases.</p>
<h2 data-number="6.5" id="just-wait-for-the-c-language-to-solve-it"><span class="header-section-number">6.5</span> Just wait for the C++ language
to solve it<a href="#just-wait-for-the-c-language-to-solve-it" class="self-link"></a></h2>
<p><span class="citation" data-cites="P2484R0">[<a href="#ref-P2484R0" role="doc-biblioref">P2484R0</a>]</span> proposed extending support for
class types as non-type template parameters in the C++ language.
However, this proposal’s primary author is no longer active in C++
standardization, and there have been no updates to the paper in the last
two years.</p>
<p>We can’t wait for the C++ language to change forever. This library
will be impossible to standardize without such a feature. This is why
the author recommends progressing with the
<code class="sourceCode default">fixed_string</code> approach.</p>
<h1 data-number="7" id="acknowledgements"><span class="header-section-number">7</span> Acknowledgements<a href="#acknowledgements" class="self-link"></a></h1>
<p>Special thanks and recognition goes to <a href="http://www.epam.com">Epam Systems</a> for supporting Mateusz’s
membership in the ISO C++ Committee and the production of this
proposal.</p>
<p>The author would also like to thank Hana Dusíková for providing
valuable feedback that helped him shape the final version of this
document.</p>
<h1 data-number="8" id="bibliography"><span class="header-section-number">8</span> References<a href="#bibliography" class="self-link"></a></h1>
<div id="refs" class="references csl-bib-body hanging-indent" role="doc-bibliography">
<div id="ref-P0259R0" class="csl-entry" role="doc-biblioentry">
[P0259R0] Michael Price, Andrew Tomazos. 2016-02-12. fixed_string: a
compile-time string. <a href="https://wg21.link/p0259r0"><div class="csl-block">https://wg21.link/p0259r0</div></a>
</div>
<div id="ref-P0843R9" class="csl-entry" role="doc-biblioentry">
[P0843R9] Gonzalo Brito Gadeschi, Timur Doumler, Nevin Liber, David
Sankel. 2023-09-14. inplace_vector. <a href="https://wg21.link/p0843r9"><div class="csl-block">https://wg21.link/p0843r9</div></a>
</div>
<div id="ref-P2484R0" class="csl-entry" role="doc-biblioentry">
[P2484R0] Richard Smith. 2021-11-17. Extending class types as non-type
template parameters. <a href="https://wg21.link/p2484r0"><div class="csl-block">https://wg21.link/p2484r0</div></a>
</div>
<div id="ref-P2980R1" class="csl-entry" role="doc-biblioentry">
[P2980R1] Mateusz Pusz, Dominik Berner, Johel Ernesto Guerrero Peña,
Charles Hogg, Nicolas Holthaus, Roth Michaels, Vincent Reverdy.
2023-11-28. A motivation, scope, and plan for a quantities and units
library. <a href="https://wg21.link/p2980r1"><div class="csl-block">https://wg21.link/p2980r1</div></a>
</div>
</div>
</div>
</div>
</body>
</html>
