<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta name="generator" content="dascandy/fiets">
<title>
std::zstring_view</title>
  <style type="text/css">
body {
  margin: 5em;
  font-family: sans-serif;
  hyphens: auto;
  line-height: 1.35;
}
ul {
  padding-left: 2em;
}
h1, h2, h3, h4 {
  position: relative;
  line-height: 1;
}
h1.title {
}
h2.subtitle {
}
h1.toc a, h2.toc a, h3.toc a, h4.toc a {
  text-decoration: none;
  color: #000000;
}
h1.toc a:hover, h2.toc a:hover, h3.toc a:hover, h4.toc a:hover {
  text-decoration: underline;
}
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: "§"; }
span.identifier {
  font-style: italic;
}
span.special {
  color: #bf003f;
}
span.keyword {
  color: #0030cf;
}
span.comment {
  color: #00c000;
}
span.new {
  text-decoration: underline;
  background-color: #006e28;
}
div.code, span.code {
  font-family: Courier New, monospace;
  background-color: #e8e8e8;
  white-space: pre;
}
span.delete {
  text-decoration: line-through;
  background-color: #bf0303;
}
p.indent {
  margin-left: 50px;
}
p.quote {
  margin-left: 50px;
  border: 2px solid black;
  background-color: #f0f0e0;
}
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;
}
th {
  border-bottom: 2px solid black;
  background-color: #f0f0f0;
}
</style>
</head>
<body>
<h1 class="title" style="text-align:center">std::zstring_view</h1><table><tbody><tr><td> Document # </td><td> P3655R0 </td></tr><tr><td> Date </td><td> 2025-02-19 </td></tr><tr><td> Targeted subgroups </td><td> LEWG </td></tr><tr><td> Ship vehicle </td><td> C++29 </td></tr><tr><td> Reply-to </td><td> Peter Bindels &lt;dascandy@gmail.com&gt; </td></tr><tr><td> </td><td> Hana Dusíková &lt;hanicka@hanicka.net&gt; </td></tr><tr><td> </td><td> Jeremy Rifkin &lt;jeremy@rifkin.dev&gt; </td></tr></tbody></table><h1 data-number="1" id="Abstract"><span class="header-section-number">1</span> Abstract<a href="#Abstract" class="self-link"></a></h1><p>We propose a standard string view type that guarantees null-termination.</p><h1 data-number="2" id="Introduction"><span class="header-section-number">2</span> Introduction<a href="#Introduction" class="self-link"></a></h1><p>C++17 introduced <span class="code">std<span class="special">::</span>string_view</span>, a non-owning view of a continuous sequence of characters. It is cheap to use, offers fast operations, and replaced most uses of <span class="code"><span class="keyword">const</span> std<span class="special">::</span>string<span class="special">&amp;</span></span> or <span class="code"><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span></span> as function parameters.  The utility and interface of string views as well as the benefits of not having to do unnecessary <span class="code">strlen</span> calculations on C-style strings makes string view types highly desirable for working with strings in C++.</p><p>Unlike <span class="code"><span class="keyword">const</span> std<span class="special">::</span>string<span class="special">&amp;</span></span> and <span class="code"><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span></span>, <span class="code">std<span class="special">::</span>string_view</span> is not null-terminated which is important for fast and cheap substring operations. However, this means <span class="code">std<span class="special">::</span>string_view</span> is not a suitable replacement for either of the two aforementioned types whenever a null-terminated C-style string is needed. While most C++ code mostly interfaces with C++ code, it is not uncommon to need to use operating system calls, C interfaces, third-party library APIs, or even C++ standard library APIs which require null-terminated strings. Because of a lack of a desirable option for passing non-owned null-terminated strings, <span class="code">std<span class="special">::</span>string_view</span> parameters are none the less sometimes used today in cases where null-terminated strings are needed, calling <span class="code">std<span class="special">::</span>string_view<span class="special">::</span>data</span> to get a <span class="code"><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span></span>. This is, needless to say, very bug-prone.</p><p>For this reason, many C++ developers use custom <span class="code">zstring_view</span> or <span class="code">cstring_view</span> types which are guaranteed to be null-terminated. We propose standardizing this utility.</p><h1 data-number="3" id="Previous-Papers"><span class="header-section-number">3</span> Previous Papers<a href="#Previous-Papers" class="self-link"></a></h1><p>The idea of <span class="code">zstring_view</span> was present even in the original paper for <span class="code">string_view</span> (Sept 2012 - Feb 2014) <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3921.html#null-termination">N3921</a>:</p><p class="quote">Another option would be to define a separate zstring_view class to represent null-terminated strings and let it decay to string_view when necessary. That's plausible but not part of this proposal.</p><p>An attempt was made in Feb 2019 to concretely propose the type (renamed to <span class="code">cstring_view</span>) with <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1402r0.pdf">P1402</a>, but it failed to gain consensus at <a href="https://wiki.edg.com/bin/view/Wg21kona2019/P1402">Kona</a>. In fact, the discussion there concluded with "CONSENSUS: We will not pursue P1402R0 or this problem space." It should be noted that this discussion was in LEWGI, and was not taken by full LEWG. It is also worth noting that contracts were briefly contemplated in the minutes as a way of addressing the problem, however, contracts can't check for a null character safely as it wouldn't be part of the view. Similarly, other runtime checks for <span class="code">string_view</span> null-termination are off the table.</p><p>However, in 2024 <a href="https://wg21.link/p3081">P3081 Core safety profiles for C++26</a> was published which contains an aside regarding a null-terminated <span class="code">zstring_view</span> in section 8, noting:</p><p class="quote">This is one of the commonly-requested features from the <a href="https://github.com/microsoft/GSL">GSL</a> library that does not yet have a std:: equivalent. It was specifically requested by several reviewers of this work.</p><p>During the discussion, it was made clear that <span class="code">zstring_view</span> deserves attention on its own and it should be happenstance introduced as part of an entirely different topic. While P3081 did not end up passing for reasons other than <span class="code">zstring_view</span>, it is another example of the utility being seen as desirable.</p><p>We also have <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2996r9.html">P2996 Reflection for C++26</a>, which in its specification of functions returning a <span class="code">string_view</span> or <span class="code">u8string_view</span> tries its best to say it's actually supposed to be a <span class="code">zstring_view</span>, except without naming the type for existential reasons:</p><p class="quote">Any function in namespace std::meta that whose return type is string_view or u8string_view returns an object V such that <span class="code">V<span class="special">.</span>data<span class="special">()[</span>V<span class="special">.</span>size<span class="special">()]</span> <span class="special">==</span> <span class="special">'\</span>0<span class="special">'</span></span>.</p><p>As such, we do believe that there is both space for such a type, and a desire from multiple angles to have it defined in the standard library.</p><h1 data-number="4" id="Reasons-to-have-the-type"><span class="header-section-number">4</span> Reasons to have the type<a href="#Reasons-to-have-the-type" class="self-link"></a></h1><p>Many functions right now whether C++ standard library calls, operating system calls, or third-party library calls require null-terminated C-style strings. Absent an efficient type that can represent a non-owning view of a null-terminated string, these functions must take either a <span class="code"><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span></span> and incur potential <span class="code">strlen</span> overhead, take a <span class="code"><span class="keyword">const</span> std<span class="special">::</span>string<span class="special">&amp;</span></span> and possibly superfluously copy and allocate, take a <span class="code">string_view</span> and make a copy, or haphazardly take a <span class="code">std<span class="special">::</span>string_view</span> with a fragile unenforceable contract that it is a view of a null-terminated string. Such a contract would be unenforceable because <span class="code"><span class="keyword">pre</span><span class="special">(</span>sv<span class="special">[</span>sv<span class="special">.</span>size<span class="special">()]</span> <span class="special">==</span> 0<span class="special">)</span></span> is potentially undefined behavior.</p><p>String views tend to start their life coming from a string literal or from a type that owns its internal buffer, often <span class="code">std<span class="special">::</span>string</span>. Both of these are places that can always create a <span class="code">zstring_view</span> instead, as they both know their data is inherently null terminated.</p><p>Strings are very often just passed along with a non-owning string type all the way to where they are used as data. Some of these potential uses, such as calling <span class="code">std<span class="special">::</span>ofstream<span class="special">::</span>write</span>, do not rely on the null terminator, but others, like <span class="code">std<span class="special">::</span>ofstream<span class="special">::</span>ofstream</span>, do. Using <span class="code">string_view</span> as the intermediate type loses the knowledge that a null terminator is already guaranteed to be present, requiring the developer to either make assumptions or make a copy. Another common use might be creating a stringstream from a string <a href="https://stackoverflow.com/questions/58524805/is-there-a-way-to-create-a-stringstream-from-a-string-view-without-copying-data">StackOverflow question</a>.</p><p>We do not have to look far for examples of <span class="code">std<span class="special">::</span>string_view</span> being used in bug-prone ways with APIs expecting null-terminators. Searching <span class="code"><span class="special">/\.</span>data<span class="special">\(\)/</span> string_view language<span class="special">:</span>c<span class="special">++</span> <span class="special">-</span>is<span class="special">:</span>fork</span> on GitHub code search turns up two examples on the first page:</p><p>From <a href="https://github.com/surge-synthesizer/shortcircuit-xt/blob/ba6ea3a2e703e4fa0ed069427aa42b668699b624/libs/md5sum/demo.cc#L37">surge-synthesizer/shortcircuit-xt</a></p><code><div class="code">std<span class="special">::</span>optional<span class="special">&lt;</span>std<span class="special">::</span>string<span class="special">&gt;</span> hash_file<span class="special">(</span><span class="keyword">const</span> std<span class="special">::</span>string_view <span class="special">&amp;</span>file_name<span class="special">)</span> <span class="special">{</span>
    <span class="keyword">auto</span> fd <span class="special">=</span> open<span class="special">(</span>file_name<span class="special">.</span>data<span class="special">(),</span> O_RDONLY<span class="special">);</span>
    <span class="special">...</span></div></code><p>From <a href="https://github.com/VisualGMQ/gmq_header/blob/cbc2853f391acc51ddd25a50d567cac404776413/log.hpp#L66">VisualGMQ/gmq_header</a></p><code><div class="code"><span class="keyword">void</span> log<span class="special">(</span>Level level<span class="special">,</span> std<span class="special">::</span>string_view funcName<span class="special">,</span> std<span class="special">::</span>string_view filename<span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> line<span class="special">,</span> Args<span class="special">&amp;&amp;</span><span class="special">...</span> args<span class="special">)</span> <span class="special">{</span>
    <span class="keyword">if</span> <span class="special">(</span>level <span class="special">&lt;</span><span class="special">=</span> level_<span class="special">)</span> <span class="special">{</span>
        printf<span class="special">("[%</span>s<span class="special">][%</span>s<span class="special">][%</span>s<span class="special">][%</span>u<span class="special">]",</span> Level2Str<span class="special">(</span>level<span class="special">).</span>data<span class="special">(),</span> filename<span class="special">.</span>data<span class="special">(),</span> funcName<span class="special">.</span>data<span class="special">(),</span> line<span class="special">);</span>
        <span class="special">...</span></div></code><p>These two examples could be argued to be bad code or misuses of <span class="code">std<span class="special">::</span>string_view</span>, however, the fact that they are written reflects the desire for the ability to use string view types in such cases.</p><p>These problems are visible enough that we have targeted patches for specific instances of this problem in the standard - <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2495r0.pdf">P2495</a> attempts to directly patch this specific example. The solution bypasses that the problem is that we're missing an unbroken type-safe chain of knowledge that the value being passed is or is not null-terminated.</p><p>The type effectively fills out the design space that exists around strings within C++. We started off with <span class="code">std<span class="special">::</span>string</span> as an owning string type, ambiguously being specified as having a null terminator or not, clarified in C++11 to definitely *have* a null terminator. C++14 added <span class="code">std<span class="special">::</span>string_view</span> to that set, offering a non-null-terminated non-owning string type. The type itself raises the question, should we add a non-null-terminated owning string type, and/or a null-terminated non-owning string type? We're proposing the last of these, leaving only the non-null-terminated owning string type as not present. We believe there is no situation to be written where a non-null-terminated owning string type would have a measurable benefit over the null-terminated owning string type that we have, and as such it is not worth the added complexity.</p><p>Without them we retain the question we had before - <span class="code"><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span></span>, <span class="code"><span class="keyword">const</span> std<span class="special">::</span>string<span class="special">&amp;</span></span> or <span class="code">string_view</span>? The first loses lots of type safety and potentially requires redundant <span class="code">strlen</span> computation elsewhere in the software, the second requires it to be a <span class="code">std<span class="special">::</span>string</span> but retains null-termination knowledge, the last offers the ability to send any string type constructible to a string_view, but loses any knowledge of null termination. For the common case of passing along "some string input" to a function that ends up requiring null termination, the proposed <span class="code">zstring_view</span> is the only type that properly captures it.</p><h1 data-number="5" id="Reasons-not-to-have-the-type"><span class="header-section-number">5</span> Reasons not to have the type<a href="#Reasons-not-to-have-the-type" class="self-link"></a></h1><p>In an ideal world, we could actually fix the operating systems and third-party libraries to accept pointer-and-size strings in all places, removing the need for null termination to exist, and for null termination propagation to be relevant. Sometimes, in particular from environments where this may not be unrealistic in a subset, the argument is voiced that <span class="code">zstring_view</span> does not offer any benefits.</p><p>Adding the type complicates the type system around strings by having more options for string types. This is not as much of an argument as it seems, since for each site a single type is the most appropriate, and the only places that would differ are those where the difference can make a meaningful performance impact - ie, the exact kind of tight loop where the type is useful for being able to make the difference.</p><h1 data-number="6" id="Subtle-details"><span class="header-section-number">6</span> Subtle details<a href="#Subtle-details" class="self-link"></a></h1><h2 data-number="6.1" id="zstring_view-and-string_view-relation"><span class="header-section-number">6.1</span> zstring_view and string_view relation<a href="#zstring_view-and-string_view-relation" class="self-link"></a></h2><p>Initially we expected that <span class="code">zstring_view</span> may be implementable in terms of <span class="code">string_view</span>. This is not actually true; in particular it is not well-formed to use <span class="code">string_view</span>'s <span class="code"><span class="keyword">operator</span><span class="special">=</span></span> to assign a non-null-terminated <span class="code">string_view</span> to a <span class="code">zstring_view</span>. As such, there can not be an inheritance relation between the two.</p><p><span class="code">zstring_view</span> is transparently convertible to a <span class="code">string_view</span>. For the conversion operator, there is no <span class="code"><span class="keyword">operator</span><span class="special">=</span></span> that could affect the original <span class="code">zstring_view</span>, and as such it is a correct change to do. It in particular makes it so that any use of <span class="code">zstring_view</span> in places where string_view is expected or desired will work without additional work.</p><p>This brings into reality an overload ambiguity:</p><code><div class="code">  <span class="keyword">void</span> handle<span class="special">(</span>string_view v<span class="special">);</span>
  <span class="keyword">void</span> handle<span class="special">(</span>zstring_view v<span class="special">);</span>
  handle<span class="special">("</span>Hello World<span class="special">!");</span></div></code><p>This is now an ambiguous function call. It is not a new problem; <a href="https://godbolt.org/z/c31e31fKW">Example on Godbolt</a> shows that the exact same problem already happens with regular <span class="code">std<span class="special">::</span>string</span> and <span class="code">std<span class="special">::</span>string_view</span>. The reason is somewhat fundamental; all three types model the concept "string" and *are* ambiguous. The user should be clear about which properties of string it's expecting. Adding this new type only adds to the vocabulary the option to say "non-owning null-terminated", giving the user better choices rather than complicating it.</p><h2 data-number="6.2" id="Construction"><span class="header-section-number">6.2</span> Construction<a href="#Construction" class="self-link"></a></h2><p><span class="code">std<span class="special">::</span>basic_string_view</span> offers a handfull of constructors:</p><code><div class="code"><span class="keyword">constexpr</span> basic_string_view<span class="special">(</span><span class="keyword">const</span> charT<span class="special">*</span> str<span class="special">);</span>
<span class="keyword">constexpr</span> basic_string_view<span class="special">(</span><span class="keyword">const</span> charT<span class="special">*</span> str<span class="special">,</span> size_type len<span class="special">);</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> It<span class="special">,</span> <span class="keyword">class</span> End<span class="special">&gt;</span>
<span class="keyword">constexpr</span> basic_string_view<span class="special">(</span>It begin<span class="special">,</span> End end<span class="special">);</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> R<span class="special">&gt;</span>
<span class="keyword">constexpr</span> <span class="keyword">explicit</span> basic_string_view<span class="special">(</span>R<span class="special">&amp;&amp;</span> r<span class="special">);</span>
basic_string_view<span class="special">(</span> std<span class="special">::</span>nullptr_t <span class="special">)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span></div></code><p>All of these could be supported for <span class="code">zstring_view</span>, however, all but <span class="code">basic_string_view<span class="special">(</span><span class="keyword">const</span> charT<span class="special">*</span> str<span class="special">)</span></span> could be inadvertently misused. We propose offering <span class="code"><span class="keyword">constexpr</span> basic_string_view<span class="special">(</span><span class="keyword">const</span> charT<span class="special">*</span> str<span class="special">,</span> size_type len<span class="special">);</span></span> as an O(1) constructor but omitting the iterator and range constructors. The range constructor would be particularly easy to inadvertently misuse, especially if not <span class="code"><span class="keyword">explicit</span></span>.</p><h2 data-number="6.3" id="Member-functions-on--string_view--that-return-a--string_view-"><span class="header-section-number">6.3</span> Member functions on `string_view` that return a `string_view`<a href="#Member-functions-on--string_view--that-return-a--string_view-" class="self-link"></a></h2><p>In some cases the functions can be replicated on <span class="code">zstring_view</span> with the return type being a <span class="code">zstring_view</span>, while in some cases the return type loses the ability to guarantee null termination, and should still return a <span class="code">string_view</span>. The types are somewhat entangled.</p><h3 data-number="6.3.1" id="-substr-"><span class="header-section-number">6.3.1</span> `substr`<a href="#-substr-" class="self-link"></a></h3><p>The <span class="code">substr</span> function is changed from a single function with a default argument, to two functions, one with one and one with two arguments. The one-argument <span class="code">substr</span> always retains the end (identical to <span class="code">string_view</span>'s <span class="code">substr</span>) and returns a <span class="code">zstring_view</span>; the two-argument <span class="code">substr</span> at least in a conceptual sense chops off at least the null terminator from the end, and should always return a <span class="code">string_view</span>.</p><h3 data-number="6.3.2" id="-remove_prefix-"><span class="header-section-number">6.3.2</span> `remove_prefix`<a href="#-remove_prefix-" class="self-link"></a></h3><p><span class="code">remove_prefix</span> drops characters from the front of the string it's called on. Behavior fits.</p><h3 data-number="6.3.3" id="-remove_suffix-"><span class="header-section-number">6.3.3</span> `remove_suffix`<a href="#-remove_suffix-" class="self-link"></a></h3><p><span class="code">remove_suffix</span> changes the string in-situ, and as such is unimplementable on zstring_view. It should be a function marked as =delete with a reason pointing users to use the two-argument <span class="code">substr</span> function instead, which returns a <span class="code">string_view</span>.</p><h1 data-number="7" id="Bikeshedding"><span class="header-section-number">7</span> Bikeshedding<a href="#Bikeshedding" class="self-link"></a></h1><p>Null-terminated string view types are typically named <span class="code">zstring_view</span> (N3921, P3081, GSL) or <span class="code">cstring_view</span> (P1402). <span class="code">cstring_view</span> follows the <span class="code">std<span class="special">::</span>string<span class="special">::</span>c_str<span class="special">()</span></span> nomenclature while <span class="code">zstring_view</span> has some establishment and recognizability.</p><p>Github code search shows similar popularity between <a href="https://github.com/search?q=%2F%5Cbcstring_view%5Cb%2F%20language%3Ac%2B%2B%20-is%3Afork&type=code">`cstring_view`</a> (1.2k results as of the time of writing) and <a href="https://github.com/search?q=%2F%5Cbzstring_view%5Cb%2F+language%3Ac%2B%2B+-is%3Afork&type=code">`zstring_view`</a> (680 results as of the time of writing).</p><h1 data-number="8" id="Reference-Implementation"><span class="header-section-number">8</span> Reference Implementation<a href="#Reference-Implementation" class="self-link"></a></h1><p>A reference implementation is at <a href="https://github.com/jeremy-rifkin/zstring_view">Jeremy's Github</a>.</p><h1 data-number="9" id="Standard-Library-Changes"><span class="header-section-number">9</span> Standard Library Changes<a href="#Standard-Library-Changes" class="self-link"></a></h1><p>There are a handful of interfaces in the standard library which take <span class="code"><span class="keyword">const</span> string<span class="special">&amp;</span></span> and really want a <span class="code">zstring_view</span></p><p>or possibly a <span class="code">string_view</span>. These include:</p><ul><li>Constructors for stdexcept types, <span class="code">system_error</span>, <span class="code">format_error</span>, <span class="code">ios_base<span class="special">::</span>failure</span>, and <span class="code">std<span class="special">::</span>filesystem<span class="special">::</span>filesystem_error</span></li><li>The <span class="code">stoi</span> family of functions</li><li><span class="code">random_device<span class="special">::</span>random_device</span></li><li>Lots of locale interfaces</li><li><span class="code">basic_filebuf<span class="special">::</span>open</span>, <span class="code">basic_ifstream<span class="special">::</span>basic_ifstream</span>, <span class="code">basic_ifstream<span class="special">::</span>open</span>, <span class="code">basic_ofstream<span class="special">::</span>basic_ofstream</span>, <span class="code">basic_ofstream<span class="special">::</span>open</span>, <span class="code">basic_fstream<span class="special">::</span>basic_fstream</span>,  and <span class="code">basic_fstream<span class="special">::</span>open</span></li></ul><p>There are further interfaces which take <span class="code"><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span></span> and could have overloads taking a <span class="code">zstring_view</span> or <span class="code">string_view</span>.</p><p>We do not propose any such changes in this paper but would like to in a follow-up paper.</p><h1 data-number="10" id="Polls"><span class="header-section-number">10</span> Polls<a href="#Polls" class="self-link"></a></h1><p>The first question to LEWG is, do we want to have the zstring_view type in the standard library? So far it looks like voting against the type leads to people implementing their own, including C++ committee members "implementing" their own zstring_view in wording. We also have a few direction questions with regards to either "fixing" string interface, or keeping the interfaces synchronized.</p><h2 data-number="10.1" id="We-encourage-further-work-on-the-zstring_view-proposal-for-the-Cpp29-timeframe-"><span class="header-section-number">10.1</span> We encourage further work on the zstring_view proposal for the C++29 timeframe.<a href="#We-encourage-further-work-on-the-zstring_view-proposal-for-the-Cpp29-timeframe-" class="self-link"></a></h2><p>If so, we will return at the next meeting (Kona 2025) with the wording worked out and checked with a Core representative, with the intent of merging zstring_view early in the C++29 cycle. If not, we will retire this paper.</p><h2 data-number="10.2" id="We-prefer-the-name--cstring_view-"><span class="header-section-number">10.2</span> We prefer the name `cstring_view`<a href="#We-prefer-the-name--cstring_view-" class="self-link"></a></h2><p>The bikeshedding mentioned above. At this point we can still choose which name to use. The authors have no preference.</p><ul><li><span class="code">cstring_view</span> is slightly more common on Github at the time of writing</li><li><span class="code">cstring_view</span> matches existing <span class="code">std<span class="special">::</span>string</span> interface nomenclature (<span class="code">c_str<span class="special">()</span></span>).</li><li><span class="code">zstring_view</span> is the most recently proposed name in <a href="https://wg21.link/p3081">P3081 Core safety profiles for C++26</a></li></ul><h2 data-number="10.3" id="We-prefer-the-zstring_view-interface-to--fix--the-known-problems-in-string_view-s-interface"><span class="header-section-number">10.3</span> We prefer the zstring_view interface to "fix" the known problems in string_view's interface<a href="#We-prefer-the-zstring_view-interface-to--fix--the-known-problems-in-string_view-s-interface" class="self-link"></a></h2><p>The poll is worded as a difference from the current proposal, which tries to match the existing <span class="code">string</span> and <span class="code">string_view</span> where possible. The "fixes" would entail the following. We can choose to take any subset of them including the full set.</p><h3 data-number="10.3.1" id="Array-constructor"><span class="header-section-number">10.3.1</span> Array constructor<a href="#Array-constructor" class="self-link"></a></h3><code><div class="code"><span class="keyword">template</span> <span class="special">&lt;</span>size_t N<span class="special">&gt;</span>
<span class="keyword">explicit</span> <span class="keyword">constexpr</span> basic_zstring_view<span class="special">(</span><span class="keyword">const</span> charT <span class="special">(</span><span class="special">&amp;</span>str<span class="special">)[</span>N<span class="special">]);</span></div></code><h3 data-number="10.3.2" id="-trim-n---functions"><span class="header-section-number">10.3.2</span> `trim(n)` functions<a href="#-trim-n---functions" class="self-link"></a></h3><p>We don't include <span class="code">remove_suffix</span> in the <span class="code">zstring_view</span> interface for reasons mentioned earlier, but, it could be desirable to introduce a <span class="code">trim_suffix</span> member function which does the same operation but returns a <span class="code">string_view</span> instead of mutating the <span class="code">zstring_view</span>. For completeness:</p><code><div class="code"><span class="keyword">constexpr</span> basic_zstring_view trim_prefix<span class="special">(</span>size_type n<span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">constexpr</span> basic_string_view<span class="special">&lt;</span>charT<span class="special">,</span> traits<span class="special">&gt;</span> trim_suffix<span class="special">(</span>size_type n<span class="special">)</span> <span class="keyword">const</span><span class="special">;</span></div></code><h1 data-number="11" id="Wording"><span class="header-section-number">11</span> Wording<a href="#Wording" class="self-link"></a></h1><p>This wording section is currently mostly high-level and synopsis changes. We defer full wording until feedback from LEWG.</p><p>Borrowing extensively from existing <span class="code">string_view</span> wording.</p><p>Add to <span class="code"><span class="special">[</span>format<span class="special">.</span>formatter<span class="special">.</span>spec<span class="special">]</span></span> 2.2:</p><code><div class="code"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> traits<span class="special">&gt;</span>
  <span class="keyword">struct</span> formatter<span class="special">&lt;</span>basic_zstring_view<span class="special">&lt;</span>charT<span class="special">,</span> traits<span class="special">&gt;</span><span class="special">,</span> charT<span class="special">&gt;</span><span class="special">;</span></div></code><p>Add to <span class="code"><span class="special">[</span>format<span class="special">.</span>formatter<span class="special">.</span>spec<span class="special">]</span></span> 4.1:</p><code><div class="code"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> traits<span class="special">&gt;</span>
  <span class="keyword">struct</span> formatter<span class="special">&lt;</span>basic_zstring_view<span class="special">&lt;</span><span class="keyword">char</span><span class="special">,</span> traits<span class="special">&gt;</span><span class="special">,</span> <span class="keyword">wchar_t</span><span class="special">&gt;</span><span class="special">;</span></div></code><p>Update <a href="string.view.general">string.view.general</a> note 1 to mention conversion from <span class="code">basic_zstring_view</span> to <span class="code">basic_string_view</span>.</p><p>Add to <a href="basic.string.general">basic.string.general</a>:</p><code><div class="code">    <span class="keyword">constexpr</span> <span class="keyword">operator</span> basic_zstring_view<span class="special">&lt;</span>charT<span class="special">,</span> traits<span class="special">&gt;</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span></div></code><p>Wording on additions deferred until a later revision.</p><h2 data-number="11.1" id="Zstring-View-Classes--zstring-view-"><span class="header-section-number">11.1</span> Zstring View Classes [zstring.view]<a href="#Zstring-View-Classes--zstring-view-" class="self-link"></a></h2><h3 data-number="11.1.1" id="General--zstring-view-general-"><span class="header-section-number">11.1.1</span> General [zstring.view.general]<a href="#General--zstring-view-general-" class="self-link"></a></h3><p>The class template basic_zstring_view describes an object that can refer to a constant contiguous sequence of char-like (<a href="strings.general">strings.general</a>) objects with the first element of the sequence at position zero. In the rest of <a href="string.view">string.view</a>, the type of the char-like objects held in a <span class="code">basic_string_view</span> object is designated by <span class="code">charT</span>.</p><p>In all cases, <span class="code"><span class="special">[</span>data<span class="special">(),</span> data<span class="special">()</span> <span class="special">+</span> size<span class="special">()]</span></span> is a valid range and <span class="code">data<span class="special">()</span> <span class="special">+</span> size<span class="special">()</span></span> points at an object with value <span class="code">charT<span class="special">()</span></span> (a "null terminator").</p><p>[Note 1: <span class="code">basic_zstring_view<span class="special">&lt;</span>charT<span class="special">,</span> <span class="special">...</span><span class="special">&gt;</span></span> is primarily useful when working with C APIs which expect null terminated strings. - end note]</p><h4 data-number="11.1.1.1" id="Header---zstring_view---synopsis--zstring-view-synop-"><span class="header-section-number">11.1.1.1</span> Header `<zstring_view>` synopsis [zstring.view.synop]<a href="#Header---zstring_view---synopsis--zstring-view-synop-" class="self-link"></a></h4><code><div class="code"><span class="comment">// mostly freestanding</span><br><span class="special">#</span>include <span class="special">&lt;</span>compare<span class="special">&gt;</span>              <span class="comment">// see [compare.syn]</span><br>
<span class="keyword">namespace</span> std <span class="special">{</span>
  <span class="comment">// [zstring.view.template], class template basic_zstring_view</span><br>  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> charT<span class="special">,</span> <span class="keyword">class</span> traits <span class="special">=</span> char_traits<span class="special">&lt;</span>charT<span class="special">&gt;&gt;</span>
  <span class="keyword">class</span> basic_zstring_view<span class="special">;</span>                                              <span class="comment">// partially freestanding</span><br>
  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> charT<span class="special">,</span> <span class="keyword">class</span> traits<span class="special">&gt;</span>
    <span class="keyword">constexpr</span> <span class="keyword">bool</span> ranges<span class="special">::</span>enable_view<span class="special">&lt;</span>basic_zstring_view<span class="special">&lt;</span>charT<span class="special">,</span> traits<span class="special">&gt;&gt;</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span>
  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> charT<span class="special">,</span> <span class="keyword">class</span> traits<span class="special">&gt;</span>
    <span class="keyword">constexpr</span> <span class="keyword">bool</span> ranges<span class="special">::</span>enable_borrowed_range<span class="special">&lt;</span>basic_zstring_view<span class="special">&lt;</span>charT<span class="special">,</span> traits<span class="special">&gt;&gt;</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span>

  <span class="comment">// [zstring.view.comparison], non-member comparison functions</span><br>  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> charT<span class="special">,</span> <span class="keyword">class</span> traits<span class="special">&gt;</span>
    <span class="keyword">constexpr</span> <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span>basic_zstring_view<span class="special">&lt;</span>charT<span class="special">,</span> traits<span class="special">&gt;</span> x<span class="special">,</span>
                              type_identity_t<span class="special">&lt;</span>basic_zstring_view<span class="special">&lt;</span>charT<span class="special">,</span> traits<span class="special">&gt;&gt;</span> y<span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> charT<span class="special">,</span> <span class="keyword">class</span> traits<span class="special">&gt;</span>
    <span class="keyword">constexpr</span> <span class="comment">/* see below */</span><br> <span class="keyword">operator</span><span class="special">&lt;</span><span class="special">=</span><span class="special">&gt;</span><span class="special">(</span>basic_zstring_view<span class="special">&lt;</span>charT<span class="special">,</span> traits<span class="special">&gt;</span> x<span class="special">,</span>
                              type_identity_t<span class="special">&lt;</span>basic_zstring_view<span class="special">&lt;</span>charT<span class="special">,</span> traits<span class="special">&gt;&gt;</span> y<span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>

  <span class="comment">// [zstring.view.io], inserters and extractors</span><br>  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> charT<span class="special">,</span> <span class="keyword">class</span> traits<span class="special">&gt;</span>
    basic_ostream<span class="special">&lt;</span>charT<span class="special">,</span> traits<span class="special">&gt;&amp;</span>
      <span class="keyword">operator</span><span class="special">&lt;&lt;</span><span class="special">(</span>basic_ostream<span class="special">&lt;</span>charT<span class="special">,</span> traits<span class="special">&gt;&amp;</span> os<span class="special">,</span>
                 basic_zstring_view<span class="special">&lt;</span>charT<span class="special">,</span> traits<span class="special">&gt;</span> str<span class="special">);</span>                 <span class="comment">// hosted</span><br>
  <span class="comment">// basic_zstring_view typedef-names</span><br>  <span class="keyword">using</span> zstring_view    <span class="special">=</span> basic_zstring_view<span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;</span><span class="special">;</span>
  <span class="keyword">using</span> u8zstring_view  <span class="special">=</span> basic_zstring_view<span class="special">&lt;</span><span class="keyword">char8_t</span><span class="special">&gt;</span><span class="special">;</span>
  <span class="keyword">using</span> u16zstring_view <span class="special">=</span> basic_zstring_view<span class="special">&lt;</span><span class="keyword">char16_t</span><span class="special">&gt;</span><span class="special">;</span>
  <span class="keyword">using</span> u32zstring_view <span class="special">=</span> basic_zstring_view<span class="special">&lt;</span><span class="keyword">char32_t</span><span class="special">&gt;</span><span class="special">;</span>
  <span class="keyword">using</span> wzstring_view   <span class="special">=</span> basic_zstring_view<span class="special">&lt;</span><span class="keyword">wchar_t</span><span class="special">&gt;</span><span class="special">;</span>

  <span class="comment">// [zstring.view.hash], hash support</span><br>  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> T<span class="special">&gt;</span> <span class="keyword">struct</span> hash<span class="special">;</span>
  <span class="keyword">template</span><span class="special">&lt;&gt;</span> <span class="keyword">struct</span> hash<span class="special">&lt;</span>zstring_view<span class="special">&gt;</span><span class="special">;</span>
  <span class="keyword">template</span><span class="special">&lt;&gt;</span> <span class="keyword">struct</span> hash<span class="special">&lt;</span>u8zstring_view<span class="special">&gt;</span><span class="special">;</span>
  <span class="keyword">template</span><span class="special">&lt;&gt;</span> <span class="keyword">struct</span> hash<span class="special">&lt;</span>u16zstring_view<span class="special">&gt;</span><span class="special">;</span>
  <span class="keyword">template</span><span class="special">&lt;&gt;</span> <span class="keyword">struct</span> hash<span class="special">&lt;</span>u32zstring_view<span class="special">&gt;</span><span class="special">;</span>
  <span class="keyword">template</span><span class="special">&lt;&gt;</span> <span class="keyword">struct</span> hash<span class="special">&lt;</span>wzstring_view<span class="special">&gt;</span><span class="special">;</span>

  <span class="keyword">inline</span> <span class="keyword">namespace</span> literals <span class="special">{</span>
    <span class="keyword">inline</span> <span class="keyword">namespace</span> zstring_view_literals <span class="special">{</span>
      <span class="comment">// [zstring.view.literals], suffix for basic_zstring_view literals</span><br>      <span class="keyword">constexpr</span> zstring_view    <span class="keyword">operator</span><span class="special">""</span>zsv<span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> str<span class="special">,</span> size_t len<span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
      <span class="keyword">constexpr</span> u8zstring_view  <span class="keyword">operator</span><span class="special">""</span>zsv<span class="special">(</span><span class="keyword">const</span> <span class="keyword">char8_t</span><span class="special">*</span> str<span class="special">,</span> size_t len<span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
      <span class="keyword">constexpr</span> u16zstring_view <span class="keyword">operator</span><span class="special">""</span>zsv<span class="special">(</span><span class="keyword">const</span> <span class="keyword">char16_t</span><span class="special">*</span> str<span class="special">,</span> size_t len<span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
      <span class="keyword">constexpr</span> u32zstring_view <span class="keyword">operator</span><span class="special">""</span>zsv<span class="special">(</span><span class="keyword">const</span> <span class="keyword">char32_t</span><span class="special">*</span> str<span class="special">,</span> size_t len<span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
      <span class="keyword">constexpr</span> wzstring_view   <span class="keyword">operator</span><span class="special">""</span>zsv<span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> str<span class="special">,</span> size_t len<span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="special">}</span>
  <span class="special">}</span>
<span class="special">}</span></div></code><h3 data-number="11.1.2" id="Class-template-basic_zstring_view--zstring-view-template-"><span class="header-section-number">11.1.2</span> Class template basic_zstring_view [zstring.view.template]<a href="#Class-template-basic_zstring_view--zstring-view-template-" class="self-link"></a></h3><h4 data-number="11.1.2.1" id="General--zstring-view-template-general-"><span class="header-section-number">11.1.2.1</span> General [zstring.view.template.general]<a href="#General--zstring-view-template-general-" class="self-link"></a></h4><code><div class="code"><span class="keyword">namespace</span> std <span class="special">{</span>
  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> charT<span class="special">,</span> <span class="keyword">class</span> traits <span class="special">=</span> char_traits<span class="special">&lt;</span>charT<span class="special">&gt;&gt;</span>
  <span class="keyword">class</span> basic_zstring_view <span class="special">{</span>
  <span class="keyword">public</span><span class="special">:</span>
    <span class="comment">// types</span><br>    <span class="keyword">using</span> traits_type            <span class="special">=</span> traits<span class="special">;</span>
    <span class="keyword">using</span> value_type             <span class="special">=</span> charT<span class="special">;</span>
    <span class="keyword">using</span> pointer                <span class="special">=</span> value_type<span class="special">*;</span>
    <span class="keyword">using</span> const_pointer          <span class="special">=</span> <span class="keyword">const</span> value_type<span class="special">*;</span>
    <span class="keyword">using</span> reference              <span class="special">=</span> value_type<span class="special">&amp;</span><span class="special">;</span>
    <span class="keyword">using</span> const_reference        <span class="special">=</span> <span class="keyword">const</span> value_type<span class="special">&amp;</span><span class="special">;</span>
    <span class="keyword">using</span> const_iterator         <span class="special">=</span> implementation<span class="special">-</span>defined<span class="special">;</span> <span class="comment">// see [zstring.view.iterators]</span><br>    <span class="keyword">using</span> iterator               <span class="special">=</span> const_iterator<span class="special">;</span>
    <span class="keyword">using</span> const_reverse_iterator <span class="special">=</span> reverse_iterator<span class="special">&lt;</span>const_iterator<span class="special">&gt;</span><span class="special">;</span>
    <span class="keyword">using</span> reverse_iterator       <span class="special">=</span> const_reverse_iterator<span class="special">;</span>
    <span class="keyword">using</span> size_type              <span class="special">=</span> size_t<span class="special">;</span>
    <span class="keyword">using</span> difference_type        <span class="special">=</span> ptrdiff_t<span class="special">;</span>
    <span class="keyword">static</span> <span class="keyword">constexpr</span> size_type npos <span class="special">=</span> size_type<span class="special">(-</span>1<span class="special">);</span>

    <span class="comment">// [zstring.view.cons], construction and assignment</span><br>    <span class="keyword">constexpr</span> basic_zstring_view<span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">constexpr</span> basic_zstring_view<span class="special">(</span><span class="keyword">const</span> basic_zstring_view<span class="special">&amp;</span><span class="special">)</span> <span class="keyword">noexcept</span> <span class="special">=</span> <span class="keyword">default</span><span class="special">;</span>
    <span class="keyword">constexpr</span> basic_zstring_view<span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> basic_zstring_view<span class="special">&amp;</span><span class="special">)</span> <span class="keyword">noexcept</span> <span class="special">=</span> <span class="keyword">default</span><span class="special">;</span>
    <span class="keyword">constexpr</span> basic_zstring_view<span class="special">(</span><span class="keyword">const</span> charT<span class="special">*</span> str<span class="special">);</span>
    <span class="keyword">constexpr</span> basic_string_view<span class="special">(</span><span class="keyword">const</span> charT<span class="special">*</span> str<span class="special">,</span> size_type len<span class="special">);</span>
    basic_zstring_view<span class="special">(</span>nullptr_t<span class="special">)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>

    <span class="comment">// [zstring.view.iterators], iterator support</span><br>    <span class="keyword">constexpr</span> const_iterator begin<span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">constexpr</span> const_iterator end<span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">constexpr</span> const_iterator cbegin<span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">constexpr</span> const_iterator cend<span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">constexpr</span> const_reverse_iterator rbegin<span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">constexpr</span> const_reverse_iterator rend<span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">constexpr</span> const_reverse_iterator crbegin<span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">constexpr</span> const_reverse_iterator crend<span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>

    <span class="comment">// [zstring.view.capacity], capacity</span><br>    <span class="keyword">constexpr</span> size_type size<span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">constexpr</span> size_type length<span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">constexpr</span> size_type max_size<span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="special">[[</span>nodiscard<span class="special">]]</span> <span class="keyword">constexpr</span> <span class="keyword">bool</span> empty<span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>

    <span class="comment">// [zstring.view.access], element access</span><br>    <span class="keyword">constexpr</span> const_reference <span class="keyword">operator</span><span class="special">[](</span>size_type pos<span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
    <span class="keyword">constexpr</span> const_reference at<span class="special">(</span>size_type pos<span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
    <span class="keyword">constexpr</span> const_reference front<span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
    <span class="keyword">constexpr</span> const_reference back<span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
    <span class="keyword">constexpr</span> const_pointer data<span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">constexpr</span> const_pointer c_str<span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>

    <span class="keyword">operator</span> basic_string_view<span class="special">&lt;</span>charT<span class="special">,</span> traits<span class="special">&gt;</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>

    <span class="comment">// [zstring.view.modifiers], modifiers</span><br>    <span class="keyword">constexpr</span> <span class="keyword">void</span> remove_prefix<span class="special">(</span>size_type n<span class="special">);</span>
    <span class="keyword">constexpr</span> <span class="keyword">void</span> remove_suffix<span class="special">(</span>size_type n<span class="special">)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">("</span>cannot remove_suffix in<span class="special">-</span>place on zstring_view <span class="keyword">while</span> retaining null terminator<span class="special">.</span> Use substr instead<span class="special">.");</span>
    <span class="keyword">constexpr</span> <span class="keyword">void</span> swap<span class="special">(</span>basic_zstring_view<span class="special">&amp;</span> s<span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>

    <span class="comment">// [zstring.view.ops], zstring operations</span><br>    <span class="keyword">constexpr</span> size_type copy<span class="special">(</span>charT<span class="special">*</span> s<span class="special">,</span> size_type n<span class="special">,</span> size_type pos <span class="special">=</span> 0<span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>

    <span class="keyword">constexpr</span> basic_string_view<span class="special">&lt;</span>charT<span class="special">,</span> traits<span class="special">&gt;</span> substr<span class="special">(</span>size_type pos <span class="special">=</span> 0<span class="special">,</span> size_type n <span class="special">=</span> npos<span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>

    <span class="keyword">constexpr</span> <span class="keyword">int</span> compare<span class="special">(</span>basic_string_view<span class="special">&lt;</span>charT<span class="special">,</span> traits<span class="special">&gt;</span> s<span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">constexpr</span> <span class="keyword">int</span> compare<span class="special">(</span>size_type pos1<span class="special">,</span> size_type n1<span class="special">,</span> basic_zstring_view s<span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
    <span class="keyword">constexpr</span> <span class="keyword">int</span> compare<span class="special">(</span>size_type pos1<span class="special">,</span> size_type n1<span class="special">,</span> basic_zstring_view s<span class="special">,</span>
                          size_type pos2<span class="special">,</span> size_type n2<span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
    <span class="keyword">constexpr</span> <span class="keyword">int</span> compare<span class="special">(</span><span class="keyword">const</span> charT<span class="special">*</span> s<span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
    <span class="keyword">constexpr</span> <span class="keyword">int</span> compare<span class="special">(</span>size_type pos1<span class="special">,</span> size_type n1<span class="special">,</span> <span class="keyword">const</span> charT<span class="special">*</span> s<span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
    <span class="keyword">constexpr</span> <span class="keyword">int</span> compare<span class="special">(</span>size_type pos1<span class="special">,</span> size_type n1<span class="special">,</span> <span class="keyword">const</span> charT<span class="special">*</span> s<span class="special">,</span> size_type n2<span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>

    <span class="keyword">constexpr</span> <span class="keyword">bool</span> starts_with<span class="special">(</span>basic_string_view<span class="special">&lt;</span>charT<span class="special">,</span> traits<span class="special">&gt;</span> x<span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">constexpr</span> <span class="keyword">bool</span> starts_with<span class="special">(</span>charT x<span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">constexpr</span> <span class="keyword">bool</span> starts_with<span class="special">(</span><span class="keyword">const</span> charT<span class="special">*</span> x<span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
    <span class="keyword">constexpr</span> <span class="keyword">bool</span> ends_with<span class="special">(</span>basic_string_view<span class="special">&lt;</span>charT<span class="special">,</span> traits<span class="special">&gt;</span> x<span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">constexpr</span> <span class="keyword">bool</span> ends_with<span class="special">(</span>charT x<span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">constexpr</span> <span class="keyword">bool</span> ends_with<span class="special">(</span><span class="keyword">const</span> charT<span class="special">*</span> x<span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>

    <span class="keyword">constexpr</span> <span class="keyword">bool</span> contains<span class="special">(</span>basic_string_view<span class="special">&lt;</span>charT<span class="special">,</span> traits<span class="special">&gt;</span> x<span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">constexpr</span> <span class="keyword">bool</span> contains<span class="special">(</span>charT x<span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">constexpr</span> <span class="keyword">bool</span> contains<span class="special">(</span><span class="keyword">const</span> charT<span class="special">*</span> x<span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>

    <span class="comment">// [zstring.view.find], searching</span><br>    <span class="keyword">constexpr</span> size_type find<span class="special">(</span>basic_string_view<span class="special">&lt;</span>charT<span class="special">,</span> traits<span class="special">&gt;</span> s<span class="special">,</span> size_type pos <span class="special">=</span> 0<span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">constexpr</span> size_type find<span class="special">(</span>charT c<span class="special">,</span> size_type pos <span class="special">=</span> 0<span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">constexpr</span> size_type find<span class="special">(</span><span class="keyword">const</span> charT<span class="special">*</span> s<span class="special">,</span> size_type pos<span class="special">,</span> size_type n<span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
    <span class="keyword">constexpr</span> size_type find<span class="special">(</span><span class="keyword">const</span> charT<span class="special">*</span> s<span class="special">,</span> size_type pos <span class="special">=</span> 0<span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
    <span class="keyword">constexpr</span> size_type rfind<span class="special">(</span>basic_string_view<span class="special">&lt;</span>charT<span class="special">,</span> traits<span class="special">&gt;</span> s<span class="special">,</span> size_type pos <span class="special">=</span> npos<span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">constexpr</span> size_type rfind<span class="special">(</span>charT c<span class="special">,</span> size_type pos <span class="special">=</span> npos<span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">constexpr</span> size_type rfind<span class="special">(</span><span class="keyword">const</span> charT<span class="special">*</span> s<span class="special">,</span> size_type pos<span class="special">,</span> size_type n<span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
    <span class="keyword">constexpr</span> size_type rfind<span class="special">(</span><span class="keyword">const</span> charT<span class="special">*</span> s<span class="special">,</span> size_type pos <span class="special">=</span> npos<span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>

    <span class="keyword">constexpr</span> size_type find_first_of<span class="special">(</span>basic_string_view<span class="special">&lt;</span>charT<span class="special">,</span> traits<span class="special">&gt;</span> s<span class="special">,</span> size_type pos <span class="special">=</span> 0<span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">constexpr</span> size_type find_first_of<span class="special">(</span>charT c<span class="special">,</span> size_type pos <span class="special">=</span> 0<span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">constexpr</span> size_type find_first_of<span class="special">(</span><span class="keyword">const</span> charT<span class="special">*</span> s<span class="special">,</span> size_type pos<span class="special">,</span> size_type n<span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
    <span class="keyword">constexpr</span> size_type find_first_of<span class="special">(</span><span class="keyword">const</span> charT<span class="special">*</span> s<span class="special">,</span> size_type pos <span class="special">=</span> 0<span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
    <span class="keyword">constexpr</span> size_type find_last_of<span class="special">(</span>basic_string_view<span class="special">&lt;</span>charT<span class="special">,</span> traits<span class="special">&gt;</span> s<span class="special">,</span> size_type pos <span class="special">=</span> npos<span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">constexpr</span> size_type find_last_of<span class="special">(</span>charT c<span class="special">,</span> size_type pos <span class="special">=</span> npos<span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">constexpr</span> size_type find_last_of<span class="special">(</span><span class="keyword">const</span> charT<span class="special">*</span> s<span class="special">,</span> size_type pos<span class="special">,</span> size_type n<span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
    <span class="keyword">constexpr</span> size_type find_last_of<span class="special">(</span><span class="keyword">const</span> charT<span class="special">*</span> s<span class="special">,</span> size_type pos <span class="special">=</span> npos<span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
    <span class="keyword">constexpr</span> size_type find_first_not_of<span class="special">(</span>basic_string_view<span class="special">&lt;</span>charT<span class="special">,</span> traits<span class="special">&gt;</span> s<span class="special">,</span> size_type pos <span class="special">=</span> 0<span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">constexpr</span> size_type find_first_not_of<span class="special">(</span>charT c<span class="special">,</span> size_type pos <span class="special">=</span> 0<span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">constexpr</span> size_type find_first_not_of<span class="special">(</span><span class="keyword">const</span> charT<span class="special">*</span> s<span class="special">,</span> size_type pos<span class="special">,</span>
                                          size_type n<span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
    <span class="keyword">constexpr</span> size_type find_first_not_of<span class="special">(</span><span class="keyword">const</span> charT<span class="special">*</span> s<span class="special">,</span> size_type pos <span class="special">=</span> 0<span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
    <span class="keyword">constexpr</span> size_type find_last_not_of<span class="special">(</span>basic_string_view<span class="special">&lt;</span>charT<span class="special">,</span> traits<span class="special">&gt;</span> s<span class="special">,</span>
                                         size_type pos <span class="special">=</span> npos<span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">constexpr</span> size_type find_last_not_of<span class="special">(</span>charT c<span class="special">,</span> size_type pos <span class="special">=</span> npos<span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">constexpr</span> size_type find_last_not_of<span class="special">(</span><span class="keyword">const</span> charT<span class="special">*</span> s<span class="special">,</span> size_type pos<span class="special">,</span>
                                         size_type n<span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
    <span class="keyword">constexpr</span> size_type find_last_not_of<span class="special">(</span><span class="keyword">const</span> charT<span class="special">*</span> s<span class="special">,</span> size_type pos <span class="special">=</span> npos<span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>

  <span class="keyword">private</span><span class="special">:</span>
    const_pointer data_<span class="special">;</span>        <span class="comment">// exposition only</span><br>    size_type size_<span class="special">;</span>            <span class="comment">// exposition only</span><br>  <span class="special">};</span>
<span class="special">}</span></div></code><p>Wording on members deferred until a later revision.</p></body></html>
