%!TEX root = std.tex \rSec0[strings]{Strings library} \rSec1[strings.general]{General} \pnum This Clause describes components for manipulating sequences of any non-array trivially copyable standard-layout\iref{term.standard.layout.type} type \tcode{T} where \tcode{is_trivially_default_constructible_v} is \tcode{true}. Such types are called \defnx{char-like types}{char-like type}, and objects of char-like types are called \defnx{char-like objects}{char-like object} or simply \term{characters}. \pnum The following subclauses describe a character traits class, string classes, and null-terminated sequence utilities, as summarized in \tref{strings.summary}. \begin{libsumtab}[x{2.1in}]{Strings library summary}{strings.summary} \ref{char.traits} & Character traits & \tcode{} \\ \ref{string.view} & String view classes & \tcode{} \\ \rowsep \ref{string.classes} & String classes & \tcode{} \\ \rowsep \ref{c.strings} & Null-terminated sequence utilities & \tcode{} \\ \end{libsumtab} \rSec1[char.traits]{Character traits} \rSec2[char.traits.general]{General} \pnum Subclause \ref{char.traits} defines requirements on classes representing \term{character traits}, and defines a class template \tcode{char_traits}, along with five specializations, \tcode{char_traits}, \tcode{char_traits}, \tcode{char_traits}, \tcode{char_traits}, and \tcode{char_traits}, that meet those requirements. \pnum Most classes specified in \ref{string.classes}, \ref{string.view}, and \ref{input.output} need a set of related types and functions to complete the definition of their semantics. These types and functions are provided as a set of member \grammarterm{typedef-name}{s} and functions in the template parameter \tcode{traits} used by each such template. Subclause \ref{char.traits} defines the semantics of these members. \pnum To specialize those templates to generate a string, string view, or iostream class to handle a particular character container type\iref{defns.character.container} \tcode{C}, that and its related character traits class \tcode{X} are passed as a pair of parameters to the string, string view, or iostream template as parameters \tcode{charT} and \tcode{traits}. If \tcode{X::char_type} is not the same type as \tcode{C}, the program is ill-formed. \rSec2[char.traits.require]{Character traits requirements} \pnum In \tref{char.traits.req}, \tcode{X} denotes a traits class defining types and functions for the character container type \tcode{C}; \tcode{c} and \tcode{d} denote values of type \tcode{C}; \tcode{p} and \tcode{q} denote values of type \tcode{const C*}; \tcode{s} denotes a value of type \tcode{C*}; \tcode{n}, \tcode{i} and \tcode{j} denote values of type \tcode{size_t}; \tcode{e} and \tcode{f} denote values of type \tcode{X::int_type}; \tcode{pos} denotes a value of type \tcode{X::pos_type}; and \tcode{r} denotes an lvalue of type \tcode{C}. No expression which is part of the character traits requirements specified in \ref{char.traits.require} shall exit via an exception. \begin{libreqtab4d} {Character traits requirements} {char.traits.req} \\ \topline \lhdr{Expression} & \chdr{Return type} & \chdr{Assertion/note} & \rhdr{Complexity}\\ & & \chdr{pre-/post-condition} & \\ \capsep \endfirsthead \continuedcaption\\ \topline \lhdr{Expression} & \chdr{Return type} & \chdr{Assertion/note} & \rhdr{Complexity}\\ & & \chdr{pre-/post-condition} & \\ \capsep \endhead \tcode{X::char_type} & \tcode{C} & & \\ \rowsep \tcode{X::int_type} & & (described in~\ref{char.traits.typedefs}) & \\ \rowsep \tcode{X::off_type} & & (described in~\ref{iostreams.limits.pos} and \ref{iostream.forward}) & \\ \rowsep \tcode{X::pos_type} & & (described in~\ref{iostreams.limits.pos} and \ref{iostream.forward}) & \\ \rowsep \tcode{X::state_type} & & (described in~\ref{char.traits.typedefs}) & \\ \rowsep \tcode{X::eq(c,d)} & \tcode{bool} & \returns whether \tcode{c} is to be treated as equal to \tcode{d}. & constant \\ \rowsep \tcode{X::lt(c,d)} & \tcode{bool} & \returns whether \tcode{c} is to be treated as less than \tcode{d}. & constant \\ \rowsep \tcode{X::compare(p,q,n)} & \tcode{int} & \returns \tcode{0} if for each \tcode{i} in \range{0}{n}, \tcode{X::eq(p[i],q[i])} is \tcode{true}; else, a negative value if, for some \tcode{j} in \range{0}{n}, \tcode{X::lt(p[j],q[j])} is \tcode{true} and for each \tcode{i} in \range{0}{j} \tcode{X::eq(p[i],q[i])} is \tcode{true}; else a positive value. & linear \\ \rowsep \tcode{X::length(p)} & \tcode{size_t} & \returns the smallest \tcode{i} such that \tcode{X::eq(p[i],charT())} is \tcode{true}. & linear \\ \rowsep \tcode{X::find(p,n,c)} & \tcode{const X::char_type*} & \returns the smallest \tcode{q} in \range{p}{p+n} such that \tcode{X::eq(*q,c)} is \tcode{true}, \tcode{nullptr} otherwise. & linear \\ \rowsep \tcode{X::move(s,p,n)} & \tcode{X::char_type*} & for each \tcode{i} in \range{0}{n}, performs \tcode{X::assign(s[i],p[i])}. Copies correctly even where the ranges \range{p}{p+n} and \range{s}{s+n} overlap.\br \returns \tcode{s}. & linear \\ \rowsep \tcode{X::copy(s,p,n)} & \tcode{X::char_type*} & \expects The ranges \range{p}{p+n} and \range{s}{s+n} do not overlap.\par \returns \tcode{s}.\br for each \tcode{i} in \range{0}{n}, performs \tcode{X::assign(s[i],p[i])}. & linear \\ \rowsep \tcode{X::assign(r,d)} & (not used) & assigns \tcode{r=d}. & constant \\ \rowsep \tcode{X::assign\-(s,n,c)} & \tcode{X::char_type*} & for each \tcode{i} in \range{0}{n}, performs \tcode{X::assign(s[i],c)}.\br \returns \tcode{s}. & linear \\ \rowsep \tcode{X::not_eof(e)} & \tcode{int_type} & \returns \tcode{e} if \tcode{X::eq_int_type(e,X::eof())} is \tcode{false}, otherwise a value \tcode{f} such that \tcode{X::eq_int_type(f,X::eof())} is \tcode{false}. & constant \\ \rowsep \tcode{X::to_char_type\-(e)} & \tcode{X::char_type} & \returns if for some \tcode{c}, \tcode{X::eq_int_type(e,X::to_int_type(c))} is \tcode{true}, \tcode{c}; else some unspecified value. & constant \\ \rowsep \tcode{X::to_int_type\-(c)} & \tcode{X::int_type} & \returns some value \tcode{e}, constrained by the definitions of \tcode{to_char_type} and \tcode{eq_int_type}. & constant \\ \rowsep \tcode{X::eq_int_type\-(e,f)} & \tcode{bool} & \returns for all \tcode{c} and \tcode{d}, \tcode{X::eq(c,d)} is equal to \tcode{X::eq_int_type(X::to_int_type(c), X::to_int_type(d))}; otherwise, yields \tcode{true} if \tcode{e} and \tcode{f} are both copies of \tcode{X::eof()}; otherwise, yields \tcode{false} if one of \tcode{e} and \tcode{f} is a copy of \tcode{X::eof()} and the other is not; otherwise the value is unspecified. & constant \\ \rowsep \tcode{X::eof()} & \tcode{X::int_type} & \returns a value \tcode{e} such that \tcode{X::eq_int_type(e,X::to_int_type(c))} is \tcode{false} for all values \tcode{c}. & constant \\ \end{libreqtab4d} \pnum The class template \indexlibraryglobal{char_traits}% \begin{codeblock} template struct char_traits; \end{codeblock} is provided in the header \libheaderref{string} as a basis for explicit specializations. \rSec2[char.traits.typedefs]{Traits typedefs} \indexlibrarymember{char_type}{char_traits}% \indexlibrarymember{int_type}{char_traits}% \begin{itemdecl} using int_type = @\seebelow@; \end{itemdecl} \begin{itemdescr} \pnum \expects \tcode{int_type} shall be able to represent all of the valid characters converted from the corresponding \tcode{char_type} values, as well as an end-of-file value, \tcode{eof()}. \begin{footnote} If \tcode{eof()} can be held in \tcode{char_type} then some iostreams operations can give surprising results. \end{footnote} \end{itemdescr} \indexlibrarymember{state_type}{char_traits}% \begin{itemdecl} using state_type = @\seebelow@; \end{itemdecl} \begin{itemdescr} \pnum \expects \tcode{state_type} meets the \oldconcept{Destructible} (\tref{cpp17.destructible}), \oldconcept{CopyAssignable} (\tref{cpp17.copyassignable}), \oldconcept{CopyConstructible} (\tref{cpp17.copyconstructible}), and \oldconcept{DefaultConstructible} (\tref{cpp17.defaultconstructible}) requirements. \end{itemdescr} \rSec2[char.traits.specializations]{\tcode{char_traits} specializations} \rSec3[char.traits.specializations.general]{General} \indexlibraryglobal{char_traits}% \begin{codeblock} namespace std { template<> struct char_traits; template<> struct char_traits; template<> struct char_traits; template<> struct char_traits; template<> struct char_traits; } \end{codeblock} \pnum The header \libheader{string} defines five specializations of the class template \tcode{char_traits}: \tcode{char_traits<\brk{}char>}, \tcode{char_traits}, \tcode{char_traits}, \tcode{char_traits}, and \tcode{char_traits}. \rSec3[char.traits.specializations.char]{\tcode{struct char_traits}} \indexlibraryglobal{char_traits}% \begin{codeblock} namespace std { template<> struct char_traits { using char_type = char; using int_type = int; using off_type = streamoff; using pos_type = streampos; using state_type = mbstate_t; using comparison_category = strong_ordering; static constexpr void assign(char_type& c1, const char_type& c2) noexcept; static constexpr bool eq(char_type c1, char_type c2) noexcept; static constexpr bool lt(char_type c1, char_type c2) noexcept; static constexpr int compare(const char_type* s1, const char_type* s2, size_t n); static constexpr size_t length(const char_type* s); static constexpr const char_type* find(const char_type* s, size_t n, const char_type& a); static constexpr char_type* move(char_type* s1, const char_type* s2, size_t n); static constexpr char_type* copy(char_type* s1, const char_type* s2, size_t n); static constexpr char_type* assign(char_type* s, size_t n, char_type a); static constexpr int_type not_eof(int_type c) noexcept; static constexpr char_type to_char_type(int_type c) noexcept; static constexpr int_type to_int_type(char_type c) noexcept; static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept; static constexpr int_type eof() noexcept; }; } \end{codeblock} \pnum The type \tcode{mbstate_t} is defined in \libheaderref{cwchar} and can represent any of the conversion states that can occur in an \impldef{supported multibyte character encoding rules} set of supported multibyte character encoding rules. \pnum The two-argument member \tcode{assign} is defined identically to the built-in operator \tcode{=}. The two-argument members \tcode{eq} and \tcode{lt} are defined identically to the built-in operators \tcode{==} and \tcode{<} for type \tcode{unsigned char}. \pnum The member \tcode{eof()} returns \tcode{EOF}. \rSec3[char.traits.specializations.char8.t]{\tcode{struct char_traits}} \indexlibraryglobal{char_traits}% \begin{codeblock} namespace std { template<> struct char_traits { using char_type = char8_t; using int_type = unsigned int; using off_type = streamoff; using pos_type = u8streampos; using state_type = mbstate_t; using comparison_category = strong_ordering; static constexpr void assign(char_type& c1, const char_type& c2) noexcept; static constexpr bool eq(char_type c1, char_type c2) noexcept; static constexpr bool lt(char_type c1, char_type c2) noexcept; static constexpr int compare(const char_type* s1, const char_type* s2, size_t n); static constexpr size_t length(const char_type* s); static constexpr const char_type* find(const char_type* s, size_t n, const char_type& a); static constexpr char_type* move(char_type* s1, const char_type* s2, size_t n); static constexpr char_type* copy(char_type* s1, const char_type* s2, size_t n); static constexpr char_type* assign(char_type* s, size_t n, char_type a); static constexpr int_type not_eof(int_type c) noexcept; static constexpr char_type to_char_type(int_type c) noexcept; static constexpr int_type to_int_type(char_type c) noexcept; static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept; static constexpr int_type eof() noexcept; }; } \end{codeblock} \pnum The two-argument members \tcode{assign}, \tcode{eq}, and \tcode{lt} are defined identically to the built-in operators \tcode{=}, \tcode{==}, and \tcode{<} respectively. \pnum \indextext{UTF-8}% The member \tcode{eof()} returns an \impldef{return value of \tcode{char_traits::eof}} constant that cannot appear as a valid UTF-8 code unit. \rSec3[char.traits.specializations.char16.t]{\tcode{struct char_traits}} \indexlibraryglobal{char_traits}% \begin{codeblock} namespace std { template<> struct char_traits { using char_type = char16_t; using int_type = uint_least16_t; using off_type = streamoff; using pos_type = u16streampos; using state_type = mbstate_t; using comparison_category = strong_ordering; static constexpr void assign(char_type& c1, const char_type& c2) noexcept; static constexpr bool eq(char_type c1, char_type c2) noexcept; static constexpr bool lt(char_type c1, char_type c2) noexcept; static constexpr int compare(const char_type* s1, const char_type* s2, size_t n); static constexpr size_t length(const char_type* s); static constexpr const char_type* find(const char_type* s, size_t n, const char_type& a); static constexpr char_type* move(char_type* s1, const char_type* s2, size_t n); static constexpr char_type* copy(char_type* s1, const char_type* s2, size_t n); static constexpr char_type* assign(char_type* s, size_t n, char_type a); static constexpr int_type not_eof(int_type c) noexcept; static constexpr char_type to_char_type(int_type c) noexcept; static constexpr int_type to_int_type(char_type c) noexcept; static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept; static constexpr int_type eof() noexcept; }; } \end{codeblock} \pnum The two-argument members \tcode{assign}, \tcode{eq}, and \tcode{lt} are defined identically to the built-in operators \tcode{=}, \tcode{==}, and \tcode{<}, respectively. \pnum The member \tcode{eof()} returns an \impldef{return value of \tcode{char_traits::eof}} constant that cannot appear as a valid UTF-16 code unit. \rSec3[char.traits.specializations.char32.t]{\tcode{struct char_traits}} \indexlibraryglobal{char_traits}% \begin{codeblock} namespace std { template<> struct char_traits { using char_type = char32_t; using int_type = uint_least32_t; using off_type = streamoff; using pos_type = u32streampos; using state_type = mbstate_t; using comparison_category = strong_ordering; static constexpr void assign(char_type& c1, const char_type& c2) noexcept; static constexpr bool eq(char_type c1, char_type c2) noexcept; static constexpr bool lt(char_type c1, char_type c2) noexcept; static constexpr int compare(const char_type* s1, const char_type* s2, size_t n); static constexpr size_t length(const char_type* s); static constexpr const char_type* find(const char_type* s, size_t n, const char_type& a); static constexpr char_type* move(char_type* s1, const char_type* s2, size_t n); static constexpr char_type* copy(char_type* s1, const char_type* s2, size_t n); static constexpr char_type* assign(char_type* s, size_t n, char_type a); static constexpr int_type not_eof(int_type c) noexcept; static constexpr char_type to_char_type(int_type c) noexcept; static constexpr int_type to_int_type(char_type c) noexcept; static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept; static constexpr int_type eof() noexcept; }; } \end{codeblock} \pnum The two-argument members \tcode{assign}, \tcode{eq}, and \tcode{lt} are defined identically to the built-in operators \tcode{=}, \tcode{==}, and \tcode{<}, respectively. \pnum The member \tcode{eof()} returns an \impldef{return value of \tcode{char_traits::eof}} constant that cannot appear as a Unicode code point. \rSec3[char.traits.specializations.wchar.t]{\tcode{struct char_traits}} \indexlibraryglobal{char_traits}% \begin{codeblock} namespace std { template<> struct char_traits { using char_type = wchar_t; using int_type = wint_t; using off_type = streamoff; using pos_type = wstreampos; using state_type = mbstate_t; using comparison_category = strong_ordering; static constexpr void assign(char_type& c1, const char_type& c2) noexcept; static constexpr bool eq(char_type c1, char_type c2) noexcept; static constexpr bool lt(char_type c1, char_type c2) noexcept; static constexpr int compare(const char_type* s1, const char_type* s2, size_t n); static constexpr size_t length(const char_type* s); static constexpr const char_type* find(const char_type* s, size_t n, const char_type& a); static constexpr char_type* move(char_type* s1, const char_type* s2, size_t n); static constexpr char_type* copy(char_type* s1, const char_type* s2, size_t n); static constexpr char_type* assign(char_type* s, size_t n, char_type a); static constexpr int_type not_eof(int_type c) noexcept; static constexpr char_type to_char_type(int_type c) noexcept; static constexpr int_type to_int_type(char_type c) noexcept; static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept; static constexpr int_type eof() noexcept; }; } \end{codeblock} \pnum The two-argument members \tcode{assign}, \tcode{eq}, and \tcode{lt} are defined identically to the built-in operators \tcode{=}, \tcode{==}, and \tcode{<}, respectively. \pnum The member \tcode{eof()} returns \tcode{WEOF}. \rSec1[string.view]{String view classes} \rSec2[string.view.general]{General} \pnum The class template \tcode{basic_string_view} describes an object that can refer to a constant contiguous sequence of char-like\iref{strings.general} objects with the first element of the sequence at position zero. In the rest of \ref{string.view}, the type of the char-like objects held in a \tcode{basic_string_view} object is designated by \tcode{charT}. \pnum \begin{note} The library provides implicit conversions from \tcode{const charT*} and \tcode{std::basic_string} to \tcode{std::basic_string_view} so that user code can accept just \tcode{std::basic_string_view} as a non-templated parameter wherever a sequence of characters is expected. User-defined types can define their own implicit conversions to \tcode{std::basic_string_view} in order to interoperate with these functions. \end{note} \rSec2[string.view.synop]{Header \tcode{} synopsis} \indexheader{string_view}% \begin{codeblock} // mostly freestanding #include // see \ref{compare.syn} namespace std { // \ref{string.view.template}, class template \tcode{basic_string_view} template> class basic_string_view; // partially freestanding template constexpr bool ranges::@\libspec{enable_view}{basic_string_view}@> = true; template constexpr bool ranges::@\libspec{enable_borrowed_range}{basic_string_view}@> = true; // \ref{string.view.comparison}, non-member comparison functions template constexpr bool operator==(basic_string_view x, type_identity_t> y) noexcept; template constexpr @\seebelow@ operator<=>(basic_string_view x, @\itcorr@ type_identity_t> y) noexcept; // \ref{string.view.io}, inserters and extractors template basic_ostream& operator<<(basic_ostream& os, basic_string_view str); // hosted // \tcode{basic_string_view} \grammarterm{typedef-name}s using string_view = basic_string_view; using u8string_view = basic_string_view; using u16string_view = basic_string_view; using u32string_view = basic_string_view; using wstring_view = basic_string_view; // \ref{string.view.hash}, hash support template struct hash; template<> struct hash; template<> struct hash; template<> struct hash; template<> struct hash; template<> struct hash; inline namespace literals { inline namespace string_view_literals { // \ref{string.view.literals}, suffix for \tcode{basic_string_view} literals constexpr string_view operator""sv(const char* str, size_t len) noexcept; constexpr u8string_view operator""sv(const char8_t* str, size_t len) noexcept; constexpr u16string_view operator""sv(const char16_t* str, size_t len) noexcept; constexpr u32string_view operator""sv(const char32_t* str, size_t len) noexcept; constexpr wstring_view operator""sv(const wchar_t* str, size_t len) noexcept; } } } \end{codeblock} \pnum The function templates defined in \ref{utility.swap} and \ref{iterator.range} are available when \tcode{} is included. \rSec2[string.view.template]{Class template \tcode{basic_string_view}} \rSec3[string.view.template.general]{General} \indexlibraryglobal{basic_string_view}% \indexlibrarymember{traits_type}{basic_string_view}% \indexlibrarymember{value_type}{basic_string_view}% \indexlibrarymember{pointer}{basic_string_view}% \indexlibrarymember{const_pointer}{basic_string_view}% \indexlibrarymember{reference}{basic_string_view}% \indexlibrarymember{const_reference}{basic_string_view}% \indexlibrarymember{const_iterator}{basic_string_view}% \indexlibrarymember{iterator}{basic_string_view}% \indexlibrarymember{const_reverse_iterator}{basic_string_view}% \indexlibrarymember{reverse_iterator}{basic_string_view}% \indexlibrarymember{size_type}{basic_string_view}% \indexlibrarymember{difference_type}{basic_string_view}% \begin{codeblock} namespace std { template> class basic_string_view { public: // types using traits_type = traits; using value_type = charT; using pointer = value_type*; using const_pointer = const value_type*; using reference = value_type&; using const_reference = const value_type&; using const_iterator = @\impdefx{type of \tcode{basic_string_view::const_iterator}}@; // see \ref{string.view.iterators} using iterator = const_iterator;@ \begin{footnote} Because \tcode{basic_string_view} refers to a constant sequence, \tcode{iterator} and \tcode{const_iterator} are the same type. \end{footnote}@ using const_reverse_iterator = reverse_iterator; using reverse_iterator = const_reverse_iterator; using size_type = size_t; using difference_type = ptrdiff_t; static constexpr size_type npos = size_type(-1); // \ref{string.view.cons}, construction and assignment constexpr basic_string_view() noexcept; constexpr basic_string_view(const basic_string_view&) noexcept = default; constexpr basic_string_view& operator=(const basic_string_view&) noexcept = default; constexpr basic_string_view(const charT* str); basic_string_view(nullptr_t) = delete; constexpr basic_string_view(const charT* str, size_type len); template constexpr basic_string_view(It begin, End end); template constexpr explicit basic_string_view(R&& r); // \ref{string.view.iterators}, iterator support constexpr const_iterator begin() const noexcept; constexpr const_iterator end() const noexcept; constexpr const_iterator cbegin() const noexcept; constexpr const_iterator cend() const noexcept; constexpr const_reverse_iterator rbegin() const noexcept; constexpr const_reverse_iterator rend() const noexcept; constexpr const_reverse_iterator crbegin() const noexcept; constexpr const_reverse_iterator crend() const noexcept; // \ref{string.view.capacity}, capacity constexpr size_type size() const noexcept; constexpr size_type length() const noexcept; constexpr size_type max_size() const noexcept; constexpr bool empty() const noexcept; // \ref{string.view.access}, element access constexpr const_reference operator[](size_type pos) const; constexpr const_reference at(size_type pos) const; // freestanding-deleted constexpr const_reference front() const; constexpr const_reference back() const; constexpr const_pointer data() const noexcept; // \ref{string.view.modifiers}, modifiers constexpr void remove_prefix(size_type n); constexpr void remove_suffix(size_type n); constexpr void swap(basic_string_view& s) noexcept; // \ref{string.view.ops}, string operations constexpr size_type copy(charT* s, size_type n, size_type pos = 0) const; // freestanding-deleted constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const; // freestanding-deleted constexpr basic_string_view subview(size_type pos = 0, size_type n = npos) const; // freestanding-deleted constexpr int compare(basic_string_view s) const noexcept; constexpr int compare(size_type pos1, size_type n1, basic_string_view s) const; // freestanding-deleted constexpr int compare(size_type pos1, size_type n1, basic_string_view s, size_type pos2, size_type n2) const; // freestanding-deleted constexpr int compare(const charT* s) const; constexpr int compare(size_type pos1, size_type n1, const charT* s) const; // freestanding-deleted constexpr int compare(size_type pos1, size_type n1, const charT* s, size_type n2) const; // freestanding-deleted constexpr bool starts_with(basic_string_view x) const noexcept; constexpr bool starts_with(charT x) const noexcept; constexpr bool starts_with(const charT* x) const; constexpr bool ends_with(basic_string_view x) const noexcept; constexpr bool ends_with(charT x) const noexcept; constexpr bool ends_with(const charT* x) const; constexpr bool contains(basic_string_view x) const noexcept; constexpr bool contains(charT x) const noexcept; constexpr bool contains(const charT* x) const; // \ref{string.view.find}, searching constexpr size_type find(basic_string_view s, size_type pos = 0) const noexcept; constexpr size_type find(charT c, size_type pos = 0) const noexcept; constexpr size_type find(const charT* s, size_type pos, size_type n) const; constexpr size_type find(const charT* s, size_type pos = 0) const; constexpr size_type rfind(basic_string_view s, size_type pos = npos) const noexcept; constexpr size_type rfind(charT c, size_type pos = npos) const noexcept; constexpr size_type rfind(const charT* s, size_type pos, size_type n) const; constexpr size_type rfind(const charT* s, size_type pos = npos) const; constexpr size_type find_first_of(basic_string_view s, size_type pos = 0) const noexcept; constexpr size_type find_first_of(charT c, size_type pos = 0) const noexcept; constexpr size_type find_first_of(const charT* s, size_type pos, size_type n) const; constexpr size_type find_first_of(const charT* s, size_type pos = 0) const; constexpr size_type find_last_of(basic_string_view s, size_type pos = npos) const noexcept; constexpr size_type find_last_of(charT c, size_type pos = npos) const noexcept; constexpr size_type find_last_of(const charT* s, size_type pos, size_type n) const; constexpr size_type find_last_of(const charT* s, size_type pos = npos) const; constexpr size_type find_first_not_of(basic_string_view s, size_type pos = 0) const noexcept; constexpr size_type find_first_not_of(charT c, size_type pos = 0) const noexcept; constexpr size_type find_first_not_of(const charT* s, size_type pos, size_type n) const; constexpr size_type find_first_not_of(const charT* s, size_type pos = 0) const; constexpr size_type find_last_not_of(basic_string_view s, size_type pos = npos) const noexcept; constexpr size_type find_last_not_of(charT c, size_type pos = npos) const noexcept; constexpr size_type find_last_not_of(const charT* s, size_type pos, size_type n) const; constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const; private: const_pointer @\exposid{data_}@; // \expos size_type @\exposid{size_}@; // \expos }; // \ref{string.view.deduct}, deduction guides template basic_string_view(It, End) -> basic_string_view>; template basic_string_view(R&&) -> basic_string_view>; } \end{codeblock} \pnum In every specialization \tcode{basic_string_view}, the type \tcode{traits} shall meet the character traits requirements\iref{char.traits}. \begin{note} The program is ill-formed if \tcode{traits::char_type} is not the same type as \tcode{charT}. \end{note} \pnum For a \tcode{basic_string_view str}, any operation that invalidates a pointer in the range \begin{codeblock} @\range{str.data()}{str.data() + str.size()}@ \end{codeblock} invalidates pointers, iterators, and references to elements of \tcode{str}. \pnum The complexity of \tcode{basic_string_view} member functions is \bigoh{1} unless otherwise specified. \pnum \tcode{basic_string_view} is a trivially copyable type\iref{term.trivially.copyable.type}. \rSec3[string.view.cons]{Construction and assignment} \indexlibraryctor{basic_string_view}% \begin{itemdecl} constexpr basic_string_view() noexcept; \end{itemdecl} \begin{itemdescr} \pnum \ensures \tcode{\exposid{size_} == 0} and \tcode{\exposid{data_} == nullptr}. \end{itemdescr} \indexlibraryctor{basic_string_view}% \begin{itemdecl} constexpr basic_string_view(const charT* str); \end{itemdecl} \begin{itemdescr} \pnum \expects \range{str}{str + traits::length(str)} is a valid range. \pnum \effects Constructs a \tcode{basic_string_view}, initializing \exposid{data_} with \tcode{str} and initializing \exposid{size_} with \tcode{traits::length(str)}. \pnum \complexity \bigoh{\tcode{traits::length(str)}}. \end{itemdescr} \indexlibraryctor{basic_string_view}% \begin{itemdecl} constexpr basic_string_view(const charT* str, size_type len); \end{itemdecl} \begin{itemdescr} \pnum \expects \range{str}{str + len} is a valid range. \pnum \effects Constructs a \tcode{basic_string_view}, initializing \exposid{data_} with \tcode{str} and initializing \exposid{size_} with \tcode{len}. \end{itemdescr} \indexlibraryctor{basic_string_view}% \begin{itemdecl} template constexpr basic_string_view(It begin, End end); \end{itemdecl} \begin{itemdescr} \pnum \constraints \begin{itemize} \item \tcode{It} satisfies \libconcept{contiguous_iterator}. \item \tcode{End} satisfies \tcode{\libconcept{sized_sentinel_for}}. \item \tcode{is_same_v, charT>} is \tcode{true}. \item \tcode{is_convertible_v} is \tcode{false}. \end{itemize} \pnum \expects \begin{itemize} \item \range{begin}{end} is a valid range. \item \tcode{It} models \libconcept{contiguous_iterator}. \item \tcode{End} models \tcode{\libconcept{sized_sentinel_for}}. \end{itemize} \pnum \effects Initializes \exposid{data_} with \tcode{to_address(begin)} and initializes \exposid{size_} with \tcode{end - begin}. \pnum \throws When and what \tcode{end - begin} throws. \end{itemdescr} \indexlibraryctor{basic_string_view}% \begin{itemdecl} template constexpr explicit basic_string_view(R&& r); \end{itemdecl} \begin{itemdescr} \pnum Let \tcode{d} be an lvalue of type \tcode{remove_cvref_t}. \pnum \constraints \begin{itemize} \item \tcode{remove_cvref_t} is not the same type as \tcode{basic_string_view}, \item \tcode{R} models \tcode{ranges::\libconcept{contiguous_range}} and \tcode{ranges::\libconcept{sized_range}}, \item \tcode{is_same_v, charT>} is \tcode{true}, \item \tcode{is_convertible_v} is \tcode{false}, and \item \tcode{d.operator ::std::basic_string_view()} is not a valid expression. \end{itemize} \pnum \effects Initializes \exposid{data_} with \tcode{ranges::data(r)} and \exposid{size_} with \tcode{ranges::size(r)}. \pnum \throws Any exception thrown by \tcode{ranges::data(r)} and \tcode{ranges::size(r)}. \end{itemdescr} \rSec3[string.view.deduct]{Deduction guides} \begin{itemdecl} template basic_string_view(It, End) -> basic_string_view>; \end{itemdecl} \begin{itemdescr} \pnum \constraints \begin{itemize} \item \tcode{It} satisfies \libconcept{contiguous_iterator}. \item \tcode{End} satisfies \tcode{\libconcept{sized_sentinel_for}}. \end{itemize} \end{itemdescr} \begin{itemdecl} template basic_string_view(R&&) -> basic_string_view>; \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{R} satisfies \tcode{ranges::\libconcept{contiguous_range}}. \end{itemdescr} \rSec3[string.view.iterators]{Iterator support} \indexlibrarymember{const_iterator}{basic_string_view}% \begin{itemdecl} using const_iterator = @\impdefx{type of \tcode{basic_string_view::const_iterator}}@; \end{itemdecl} \begin{itemdescr} \pnum A type that meets the requirements of a constant \oldconcept{RandomAccessIterator}\iref{random.access.iterators}, models \libconcept{contiguous_iterator}\iref{iterator.concept.contiguous}, and meets the constexpr iterator requirements\iref{iterator.requirements.general}, whose \tcode{value_type} is the template parameter \tcode{charT}. \pnum All requirements on container iterators\iref{container.requirements} apply to \tcode{basic_string_view::const_iterator} as well. \end{itemdescr} \indexlibrarymember{begin}{basic_string_view}% \indexlibrarymember{cbegin}{basic_string_view}% \begin{itemdecl} constexpr const_iterator begin() const noexcept; constexpr const_iterator cbegin() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns An iterator such that \begin{itemize} \item if \tcode{!empty()}, \tcode{addressof(*begin()) == \exposid{data_}}, \item otherwise, an unspecified value such that \range{begin()}{end()} is a valid range. \end{itemize} \end{itemdescr} \indexlibrarymember{end}{basic_string_view}% \indexlibrarymember{cend}{basic_string_view}% \begin{itemdecl} constexpr const_iterator end() const noexcept; constexpr const_iterator cend() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{begin() + size()}. \end{itemdescr} \indexlibrarymember{rbegin}{basic_string_view}% \indexlibrarymember{crbegin}{basic_string_view}% \begin{itemdecl} constexpr const_reverse_iterator rbegin() const noexcept; constexpr const_reverse_iterator crbegin() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{const_reverse_iterator(end())}. \end{itemdescr} \indexlibrarymember{rend}{basic_string_view}% \indexlibrarymember{crend}{basic_string_view}% \begin{itemdecl} constexpr const_reverse_iterator rend() const noexcept; constexpr const_reverse_iterator crend() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{const_reverse_iterator(begin())}. \end{itemdescr} \rSec3[string.view.capacity]{Capacity} \indexlibrarymember{size}{basic_string_view}% \indexlibrarymember{length}{basic_string_view}% \begin{itemdecl} constexpr size_type size() const noexcept; constexpr size_type length() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \exposid{size_}. \end{itemdescr} \indexlibrarymember{max_size}{basic_string_view}% \begin{itemdecl} constexpr size_type max_size() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns The largest possible number of char-like objects that can be referred to by a \tcode{basic_string_view}. \end{itemdescr} \indexlibrarymember{empty}{basic_string_view}% \begin{itemdecl} constexpr bool empty() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{\exposid{size_} == 0}. \end{itemdescr} \rSec3[string.view.access]{Element access} \indexlibrarymember{operator[]}{basic_string_view}% \begin{itemdecl} constexpr const_reference operator[](size_type pos) const; \end{itemdecl} \begin{itemdescr} \pnum \hardexpects \tcode{pos < size()} is \tcode{true}. \begin{note} This precondition is stronger than the one on \tcode{basic_string::operator[]}. \end{note} \pnum \returns \tcode{\exposid{data_}[pos]}. \pnum \throws Nothing. \end{itemdescr} \indexlibrarymember{at}{basic_string_view}% \begin{itemdecl} constexpr const_reference at(size_type pos) const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{\exposid{data_}[pos]}. \pnum \throws \tcode{out_of_range} if \tcode{pos >= size()}. \end{itemdescr} \indexlibrarymember{front}{basic_string_view}% \begin{itemdecl} constexpr const_reference front() const; \end{itemdecl} \begin{itemdescr} \pnum \hardexpects \tcode{empty()} is \tcode{false}. \pnum \returns \tcode{\exposid{data_}[0]}. \pnum \throws Nothing. \end{itemdescr} \indexlibrarymember{back}{basic_string_view}% \begin{itemdecl} constexpr const_reference back() const; \end{itemdecl} \begin{itemdescr} \pnum \hardexpects \tcode{empty()} is \tcode{false}. \pnum \returns \tcode{\exposid{data_}[size() - 1]}. \pnum \throws Nothing. \end{itemdescr} \indexlibrarymember{data}{basic_string_view}% \begin{itemdecl} constexpr const_pointer data() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \exposid{data_}. \pnum \begin{note} Unlike \tcode{basic_string::data()} and \grammarterm{string-literal}s, \tcode{data()} can return a pointer to a buffer that is not null-terminated. Therefore it is typically a mistake to pass \tcode{data()} to a function that takes just a \tcode{const charT*} and expects a null-terminated string. \end{note} \end{itemdescr} \rSec3[string.view.modifiers]{Modifiers} \indexlibrarymember{remove_prefix}{basic_string_view}% \begin{itemdecl} constexpr void remove_prefix(size_type n); \end{itemdecl} \begin{itemdescr} \pnum \hardexpects \tcode{n <= size()} is \tcode{true}. \pnum \effects Equivalent to: \tcode{\exposid{data_} += n; \exposid{size_} -= n;} \end{itemdescr} \indexlibrarymember{remove_suffix}{basic_string_view}% \begin{itemdecl} constexpr void remove_suffix(size_type n); \end{itemdecl} \begin{itemdescr} \pnum \hardexpects \tcode{n <= size()} is \tcode{true}. \pnum \effects Equivalent to: \tcode{\exposid{size_} -= n;} \end{itemdescr} \indexlibrarymember{swap}{basic_string_view}% \begin{itemdecl} constexpr void swap(basic_string_view& s) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Exchanges the values of \tcode{*this} and \tcode{s}. \end{itemdescr} \rSec3[string.view.ops]{String operations} \indexlibrarymember{copy}{basic_string_view}% \begin{itemdecl} constexpr size_type copy(charT* s, size_type n, size_type pos = 0) const; \end{itemdecl} \begin{itemdescr} \pnum Let \tcode{rlen} be the smaller of \tcode{n} and \tcode{size() - pos}. \pnum \expects \range{s}{s + rlen} is a valid range. \pnum \effects Equivalent to \tcode{traits::copy(s, data() + pos, rlen)}. \pnum \returns \tcode{rlen}. \pnum \throws \tcode{out_of_range} if \tcode{pos > size()}. \pnum \complexity \bigoh{\tcode{rlen}}. \end{itemdescr} \indexlibrarymember{substr}{basic_string_view}% \indexlibrarymember{subview}{basic_string_view}% \begin{itemdecl} constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const; constexpr basic_string_view subview(size_type pos = 0, size_type n = npos) const; \end{itemdecl} \begin{itemdescr} \pnum Let \tcode{rlen} be the smaller of \tcode{n} and \tcode{size() - pos}. \pnum \effects Determines \tcode{rlen}, the effective length of the string to reference. \pnum \returns \tcode{basic_string_view(data() + pos, rlen)}. \pnum \throws \tcode{out_of_range} if \tcode{pos > size()}. \end{itemdescr} \indexlibrarymember{compare}{basic_string_view}% \begin{itemdecl} constexpr int compare(basic_string_view str) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum Let \tcode{rlen} be the smaller of \tcode{size()} and \tcode{str.size()}. \pnum \effects Determines \tcode{rlen}, the effective length of the strings to compare. The function then compares the two strings by calling \tcode{traits::compare(data(), str.data(), rlen)}. \pnum \returns The nonzero result if the result of the comparison is nonzero. Otherwise, returns a value as indicated in \tref{string.view.compare}. \begin{libtab2}{\tcode{compare()} results}{string.view.compare}{cc}{Condition}{Return Value} \tcode{size() < str.size()} & \tcode{< 0}\\ \tcode{size() == str.size()} & \tcode{ \ 0}\\ \tcode{size() > str.size()} & \tcode{> 0}\\ \end{libtab2} \pnum \complexity \bigoh{\tcode{rlen}}. \end{itemdescr} \indexlibrarymember{compare}{basic_string_view}% \begin{itemdecl} constexpr int compare(size_type pos1, size_type n1, basic_string_view str) const; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return substr(pos1, n1).compare(str);} \end{itemdescr} \indexlibrarymember{compare}{basic_string_view}% \begin{itemdecl} constexpr int compare(size_type pos1, size_type n1, basic_string_view str, size_type pos2, size_type n2) const; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return substr(pos1, n1).compare(str.substr(pos2, n2));} \end{itemdescr} \indexlibrarymember{compare}{basic_string_view}% \begin{itemdecl} constexpr int compare(const charT* s) const; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return compare(basic_string_view(s));} \end{itemdescr} \indexlibrarymember{compare}{basic_string_view}% \begin{itemdecl} constexpr int compare(size_type pos1, size_type n1, const charT* s) const; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return substr(pos1, n1).compare(basic_string_view(s));} \end{itemdescr} \indexlibrarymember{compare}{basic_string_view}% \begin{itemdecl} constexpr int compare(size_type pos1, size_type n1, const charT* s, size_type n2) const; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return substr(pos1, n1).compare(basic_string_view(s, n2));} \end{itemdescr} \indexlibrarymember{starts_with}{basic_string_view}% \begin{itemdecl} constexpr bool starts_with(basic_string_view x) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum Let \tcode{rlen} be the smaller of \tcode{size()} and \tcode{x.size()}. \pnum \effects Equivalent to: \tcode{return basic_string_view(data(), rlen) == x;} \end{itemdescr} \indexlibrarymember{starts_with}{basic_string_view}% \begin{itemdecl} constexpr bool starts_with(charT x) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return !empty() \&\& traits::eq(front(), x);} \end{itemdescr} \indexlibrarymember{starts_with}{basic_string_view}% \begin{itemdecl} constexpr bool starts_with(const charT* x) const; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return starts_with(basic_string_view(x));} \end{itemdescr} \indexlibrarymember{ends_with}{basic_string_view}% \begin{itemdecl} constexpr bool ends_with(basic_string_view x) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum Let \tcode{rlen} be the smaller of \tcode{size()} and \tcode{x.size()}. \pnum \effects Equivalent to: \begin{codeblock} return basic_string_view(data() + (size() - rlen), rlen) == x; \end{codeblock} \end{itemdescr} \indexlibrarymember{ends_with}{basic_string_view}% \begin{itemdecl} constexpr bool ends_with(charT x) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return !empty() \&\& traits::eq(back(), x);} \end{itemdescr} \indexlibrarymember{ends_with}{basic_string_view}% \begin{itemdecl} constexpr bool ends_with(const charT* x) const; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return ends_with(basic_string_view(x));} \end{itemdescr} \indexlibrarymember{contains}{basic_string_view}% \begin{itemdecl} constexpr bool contains(basic_string_view x) const noexcept; constexpr bool contains(charT x) const noexcept; constexpr bool contains(const charT* x) const; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return find(x) != npos;} \end{itemdescr} \rSec3[string.view.find]{Searching} \pnum Member functions in this subclause have complexity \bigoh{\tcode{size() * str.size()}} at worst, although implementations should do better. \pnum Let \placeholder{F} be one of \tcode{find}, \tcode{rfind}, \tcode{find_first_of}, \tcode{find_last_of}, \tcode{find_first_not_of}, and \tcode{find_last_not_of}. \begin{itemize} \item Each member function of the form \begin{codeblock} constexpr @\placeholder{return-type}@ @\placeholder{F}@(const charT* s, size_type pos) const; \end{codeblock} has effects equivalent to: \tcode{return \placeholder{F}(basic_string_view(s), pos);} \item Each member function of the form \begin{codeblock} constexpr @\placeholder{return-type}@ @\placeholder{F}@(const charT* s, size_type pos, size_type n) const; \end{codeblock} has effects equivalent to: \tcode{return \placeholder{F}(basic_string_view(s, n), pos);} \item Each member function of the form \begin{codeblock} constexpr @\placeholder{return-type}@ @\placeholder{F}@(charT c, size_type pos) const noexcept; \end{codeblock} has effects equivalent to: \tcode{return \placeholder{F}(basic_string_view(addressof(c), 1), pos);} \end{itemize} \indexlibrarymember{find}{basic_string_view}% \begin{itemdecl} constexpr size_type find(basic_string_view str, size_type pos = 0) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum Let \tcode{xpos} be the lowest position, if possible, such that the following conditions hold: \begin{itemize} \item \tcode{pos <= xpos} \item \tcode{xpos + str.size() <= size()} \item \tcode{traits::eq(\exposid{data_}[xpos + I], str[I])} for all elements \tcode{I} of the string referenced by \tcode{str}. \end{itemize} \pnum \effects Determines \tcode{xpos}. \pnum \returns \tcode{xpos} if the function can determine such a value for \tcode{xpos}. Otherwise, returns \tcode{npos}. \end{itemdescr} \indexlibrarymember{rfind}{basic_string_view}% \begin{itemdecl} constexpr size_type rfind(basic_string_view str, size_type pos = npos) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum Let \tcode{xpos} be the highest position, if possible, such that the following conditions hold: \begin{itemize} \item \tcode{xpos <= pos} \item \tcode{xpos + str.size() <= size()} \item \tcode{traits::eq(\exposid{data_}[xpos + I], str[I])} for all elements \tcode{I} of the string referenced by \tcode{str}. \end{itemize} \pnum \effects Determines \tcode{xpos}. \pnum \returns \tcode{xpos} if the function can determine such a value for \tcode{xpos}. Otherwise, returns \tcode{npos}. \end{itemdescr} \indexlibrarymember{find_first_of}{basic_string_view}% \begin{itemdecl} constexpr size_type find_first_of(basic_string_view str, size_type pos = 0) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum Let \tcode{xpos} be the lowest position, if possible, such that the following conditions hold: \begin{itemize} \item \tcode{pos <= xpos} \item \tcode{xpos < size()} \item \tcode{traits::eq(\exposid{data_}[xpos], str[I])} for some element \tcode{I} of the string referenced by \tcode{str}. \end{itemize} \pnum \effects Determines \tcode{xpos}. \pnum \returns \tcode{xpos} if the function can determine such a value for \tcode{xpos}. Otherwise, returns \tcode{npos}. \end{itemdescr} \indexlibrarymember{find_last_of}{basic_string_view}% \begin{itemdecl} constexpr size_type find_last_of(basic_string_view str, size_type pos = npos) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum Let \tcode{xpos} be the highest position, if possible, such that the following conditions hold: \begin{itemize} \item \tcode{xpos <= pos} \item \tcode{xpos < size()} \item \tcode{traits::eq(\exposid{data_}[xpos], str[I])} for some element \tcode{I} of the string referenced by \tcode{str}. \end{itemize} \pnum \effects Determines \tcode{xpos}. \pnum \returns \tcode{xpos} if the function can determine such a value for \tcode{xpos}. Otherwise, returns \tcode{npos}. \end{itemdescr} \indexlibrarymember{find_first_not_of}{basic_string_view}% \begin{itemdecl} constexpr size_type find_first_not_of(basic_string_view str, size_type pos = 0) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum Let \tcode{xpos} be the lowest position, if possible, such that the following conditions hold: \begin{itemize} \item \tcode{pos <= xpos} \item \tcode{xpos < size()} \item \tcode{traits::eq(\exposid{data_}[xpos], str[I])} for no element \tcode{I} of the string referenced by \tcode{str}. \end{itemize} \pnum \effects Determines \tcode{xpos}. \pnum \returns \tcode{xpos} if the function can determine such a value for \tcode{xpos}. Otherwise, returns \tcode{npos}. \end{itemdescr} \indexlibrarymember{find_last_not_of}{basic_string_view}% \begin{itemdecl} constexpr size_type find_last_not_of(basic_string_view str, size_type pos = npos) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum Let \tcode{xpos} be the highest position, if possible, such that the following conditions hold: \begin{itemize} \item \tcode{xpos <= pos} \item \tcode{xpos < size()} \item \tcode{traits::eq(\exposid{data_}[xpos], str[I])} for no element \tcode{I} of the string referenced by \tcode{str}. \end{itemize} \pnum \effects Determines \tcode{xpos}. \pnum \returns \tcode{xpos} if the function can determine such a value for \tcode{xpos}. Otherwise, returns \tcode{npos}. \end{itemdescr} \rSec2[string.view.comparison]{Non-member comparison functions} \indexlibrarymember{operator==}{basic_string_view}% \begin{itemdecl} template constexpr bool operator==(basic_string_view lhs, type_identity_t> rhs) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{lhs.compare(rhs) == 0}. \end{itemdescr} \indexlibrarymember{operator<=>}{basic_string_view}% \begin{itemdecl} template constexpr @\seebelow@ operator<=>(basic_string_view lhs, @\itcorr@ type_identity_t> rhs) noexcept; \end{itemdecl} \begin{itemdescr} \pnum Let \tcode{R} denote the type \tcode{traits::comparison_category} if that \grammarterm{qualified-id} is valid and denotes a type\iref{temp.deduct}, otherwise \tcode{R} is \tcode{weak_ordering}. \pnum \mandates \tcode{R} denotes a comparison category type\iref{cmp.categories}. \pnum \returns \tcode{static_cast(lhs.compare(rhs) <=> 0)}. \pnum \begin{note} The usage of \tcode{type_identity_t} as parameter ensures that an object of type \tcode{basic_string_view} can always be compared with an object of a type \tcode{T} with an implicit conversion to \tcode{basic_string_view}, and vice versa, as per \ref{over.match.oper}. \end{note} \end{itemdescr} \rSec2[string.view.io]{Inserters and extractors} \indexlibrarymember{operator<<}{basic_string_view}% \begin{itemdecl} template basic_ostream& operator<<(basic_ostream& os, basic_string_view str); \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves as a formatted output function\iref{ostream.formatted.reqmts} of \tcode{os}. Forms a character sequence \tcode{seq}, initially consisting of the elements defined by the range \range{str.begin()}{str.end()}. Determines padding for \tcode{seq} as described in~\ref{ostream.formatted.reqmts}. Then inserts \tcode{seq} as if by calling \tcode{os.rdbuf()->sputn(\brk{}seq, n)}, where \tcode{n} is the larger of \tcode{os.width()} and \tcode{str.size()}; then calls \tcode{os.\brk{}width(0)}. \pnum \returns \tcode{os}. \end{itemdescr} \rSec2[string.view.hash]{Hash support} \indexlibrarymember{hash}{string_view}% \indexlibrarymember{hash}{u8string_view}% \indexlibrarymember{hash}{u16string_view}% \indexlibrarymember{hash}{u32string_view}% \indexlibrarymember{hash}{wstring_view}% \begin{itemdecl} template<> struct hash; template<> struct hash; template<> struct hash; template<> struct hash; template<> struct hash; \end{itemdecl} \begin{itemdescr} \pnum The specialization is enabled\iref{unord.hash}. \begin{note} The hash value of a string view object is equal to the hash value of the corresponding string object\iref{basic.string.hash}. \end{note} \end{itemdescr} \rSec2[string.view.literals]{Suffix for \tcode{basic_string_view} literals} \indexlibrarymember{operator""""sv}{string_view}% \begin{itemdecl} constexpr string_view operator""sv(const char* str, size_t len) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{string_view\{str, len\}}. \end{itemdescr} \indexlibrarymember{operator""""sv}{u8string_view}% \begin{itemdecl} constexpr u8string_view operator""sv(const char8_t* str, size_t len) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{u8string_view\{str, len\}}. \end{itemdescr} \indexlibrarymember{operator""""sv}{u16string_view}% \begin{itemdecl} constexpr u16string_view operator""sv(const char16_t* str, size_t len) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{u16string_view\{str, len\}}. \end{itemdescr} \indexlibrarymember{operator""""sv}{u32string_view}% \begin{itemdecl} constexpr u32string_view operator""sv(const char32_t* str, size_t len) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{u32string_view\{str, len\}}. \end{itemdescr} \indexlibrarymember{operator""""sv}{wstring_view}% \begin{itemdecl} constexpr wstring_view operator""sv(const wchar_t* str, size_t len) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{wstring_view\{str, len\}}. \end{itemdescr} \rSec1[string.classes]{String classes} \rSec2[string.classes.general]{General} \pnum The header \tcode{} defines the \tcode{basic_string} class template for manipulating varying-length sequences of char-like objects and five \grammarterm{typedef-name}{s}, \tcode{string}, \tcode{u8string}, \tcode{u16string}, \tcode{u32string}, and \tcode{wstring}, that name the specializations \tcode{basic_string}, \tcode{basic_string}, \tcode{basic_string}, \tcode{basic_string}, and \tcode{basic_string<\brk{}wchar_t>}, respectively. \rSec2[string.syn]{Header \tcode{} synopsis} \indexheader{string}% \begin{codeblock} #include // see \ref{compare.syn} #include // see \ref{initializer.list.syn} namespace std { // \ref{char.traits}, character traits template struct char_traits; // freestanding template<> struct char_traits; // freestanding template<> struct char_traits; // freestanding template<> struct char_traits; // freestanding template<> struct char_traits; // freestanding template<> struct char_traits; // freestanding // \ref{basic.string}, \tcode{basic_string} template, class Allocator = allocator> class basic_string; template constexpr basic_string operator+(const basic_string& lhs, const basic_string& rhs); template constexpr basic_string operator+(basic_string&& lhs, const basic_string& rhs); template constexpr basic_string operator+(const basic_string& lhs, basic_string&& rhs); template constexpr basic_string operator+(basic_string&& lhs, basic_string&& rhs); template constexpr basic_string operator+(const charT* lhs, const basic_string& rhs); template constexpr basic_string operator+(const charT* lhs, basic_string&& rhs); template constexpr basic_string operator+(charT lhs, const basic_string& rhs); template constexpr basic_string operator+(charT lhs, basic_string&& rhs); template constexpr basic_string operator+(const basic_string& lhs, const charT* rhs); template constexpr basic_string operator+(basic_string&& lhs, const charT* rhs); template constexpr basic_string operator+(const basic_string& lhs, charT rhs); template constexpr basic_string operator+(basic_string&& lhs, charT rhs); template constexpr basic_string operator+(const basic_string& lhs, type_identity_t> rhs); template constexpr basic_string operator+(basic_string&& lhs, type_identity_t> rhs); template constexpr basic_string operator+(type_identity_t> lhs, const basic_string& rhs); template constexpr basic_string operator+(type_identity_t> lhs, basic_string&& rhs); template constexpr bool operator==(const basic_string& lhs, const basic_string& rhs) noexcept; template constexpr bool operator==(const basic_string& lhs, const charT* rhs); template constexpr @\seebelow@ operator<=>(const basic_string& lhs, @\itcorr@ const basic_string& rhs) noexcept; template constexpr @\seebelow@ operator<=>(const basic_string& lhs, @\itcorr@ const charT* rhs); // \ref{string.special}, swap template constexpr void swap(basic_string& lhs, basic_string& rhs) noexcept(noexcept(lhs.swap(rhs))); // \ref{string.io}, inserters and extractors template basic_istream& operator>>(basic_istream& is, basic_string& str); template basic_ostream& operator<<(basic_ostream& os, const basic_string& str); template basic_istream& getline(basic_istream& is, basic_string& str, charT delim); template basic_istream& getline(basic_istream&& is, basic_string& str, charT delim); template basic_istream& getline(basic_istream& is, basic_string& str); template basic_istream& getline(basic_istream&& is, basic_string& str); // \ref{string.erasure}, erasure template constexpr typename basic_string::size_type erase(basic_string& c, const U& value); template constexpr typename basic_string::size_type erase_if(basic_string& c, Predicate pred); // \tcode{basic_string} \grammarterm{typedef-name}s using @\libglobal{string}@ = basic_string; using @\libglobal{u8string}@ = basic_string; using @\libglobal{u16string}@ = basic_string; using @\libglobal{u32string}@ = basic_string; using @\libglobal{wstring}@ = basic_string; // \ref{string.conversions}, numeric conversions int stoi(const string& str, size_t* idx = nullptr, int base = 10); long stol(const string& str, size_t* idx = nullptr, int base = 10); unsigned long stoul(const string& str, size_t* idx = nullptr, int base = 10); long long stoll(const string& str, size_t* idx = nullptr, int base = 10); unsigned long long stoull(const string& str, size_t* idx = nullptr, int base = 10); float stof(const string& str, size_t* idx = nullptr); double stod(const string& str, size_t* idx = nullptr); long double stold(const string& str, size_t* idx = nullptr); string to_string(int val); string to_string(unsigned val); string to_string(long val); string to_string(unsigned long val); string to_string(long long val); string to_string(unsigned long long val); string to_string(float val); string to_string(double val); string to_string(long double val); int stoi(const wstring& str, size_t* idx = nullptr, int base = 10); long stol(const wstring& str, size_t* idx = nullptr, int base = 10); unsigned long stoul(const wstring& str, size_t* idx = nullptr, int base = 10); long long stoll(const wstring& str, size_t* idx = nullptr, int base = 10); unsigned long long stoull(const wstring& str, size_t* idx = nullptr, int base = 10); float stof(const wstring& str, size_t* idx = nullptr); double stod(const wstring& str, size_t* idx = nullptr); long double stold(const wstring& str, size_t* idx = nullptr); wstring to_wstring(int val); wstring to_wstring(unsigned val); wstring to_wstring(long val); wstring to_wstring(unsigned long val); wstring to_wstring(long long val); wstring to_wstring(unsigned long long val); wstring to_wstring(float val); wstring to_wstring(double val); wstring to_wstring(long double val); namespace pmr { template> using basic_string = std::basic_string>; using string = basic_string; using u8string = basic_string; using u16string = basic_string; using u32string = basic_string; using wstring = basic_string; } // \ref{basic.string.hash}, hash support template struct hash; template struct hash, A>>; template struct hash, A>>; template struct hash, A>>; template struct hash, A>>; template struct hash, A>>; inline namespace literals { inline namespace string_literals { // \ref{basic.string.literals}, suffix for \tcode{basic_string} literals constexpr string operator""s(const char* str, size_t len); constexpr u8string operator""s(const char8_t* str, size_t len); constexpr u16string operator""s(const char16_t* str, size_t len); constexpr u32string operator""s(const char32_t* str, size_t len); constexpr wstring operator""s(const wchar_t* str, size_t len); } } } \end{codeblock} \rSec2[basic.string]{Class template \tcode{basic_string}} \rSec3[basic.string.general]{General} \pnum \indexlibraryglobal{basic_string}% The class template \tcode{basic_string} describes objects that can store a sequence consisting of a varying number of arbitrary char-like objects with the first element of the sequence at position zero. Such a sequence is also called a ``string'' if the type of the char-like objects that it holds is clear from context. In the rest of \ref{basic.string}, the type of the char-like objects held in a \tcode{basic_string} object is designated by \tcode{charT}. \pnum A specialization of \tcode{basic_string} is a contiguous container\iref{container.reqmts}. \pnum In all cases, \crange{data()}{data() + size()} is a valid range, \tcode{data() + size()} points at an object with value \tcode{charT()} (a ``null terminator''\indextext{string!null terminator}), and \tcode{size() <= capacity()} is \tcode{true}. \indexlibraryglobal{basic_string}% \indexlibrarymember{traits_type}{basic_string}% \indexlibrarymember{value_type}{basic_string}% \indexlibrarymember{allocator_type}{basic_string}% \indexlibrarymember{size_type}{basic_string}% \indexlibrarymember{difference_type}{basic_string}% \indexlibrarymember{pointer}{basic_string}% \indexlibrarymember{const_pointer}{basic_string}% \indexlibrarymember{reference}{basic_string}% \indexlibrarymember{const_reference}{basic_string}% \indexlibrarymember{iterator}{basic_string}% \indexlibrarymember{const_iterator}{basic_string}% \indexlibrarymember{reverse_iterator}{basic_string}% \indexlibrarymember{const_reverse_iterator}{basic_string}% \begin{codeblock} namespace std { template, class Allocator = allocator> class basic_string { public: // types using traits_type = traits; using value_type = charT; using allocator_type = Allocator; using size_type = typename allocator_traits::size_type; using difference_type = typename allocator_traits::difference_type; using pointer = typename allocator_traits::pointer; using const_pointer = typename allocator_traits::const_pointer; using reference = value_type&; using const_reference = const value_type&; using iterator = @\impdefx{type of \tcode{basic_string::iterator}}@; // see \ref{container.requirements} using const_iterator = @\impdefx{type of \tcode{basic_string::const_iterator}}@; // see \ref{container.requirements} using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; static constexpr size_type npos = size_type(-1); // \ref{string.cons}, construct/copy/destroy constexpr basic_string() noexcept(noexcept(Allocator())) : basic_string(Allocator()) { } constexpr explicit basic_string(const Allocator& a) noexcept; constexpr basic_string(const basic_string& str); constexpr basic_string(basic_string&& str) noexcept; constexpr basic_string(const basic_string& str, size_type pos, const Allocator& a = Allocator()); constexpr basic_string(const basic_string& str, size_type pos, size_type n, const Allocator& a = Allocator()); constexpr basic_string(basic_string&& str, size_type pos, const Allocator& a = Allocator()); constexpr basic_string(basic_string&& str, size_type pos, size_type n, const Allocator& a = Allocator()); template constexpr basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator()); template constexpr explicit basic_string(const T& t, const Allocator& a = Allocator()); constexpr basic_string(const charT* s, size_type n, const Allocator& a = Allocator()); constexpr basic_string(const charT* s, const Allocator& a = Allocator()); basic_string(nullptr_t) = delete; constexpr basic_string(size_type n, charT c, const Allocator& a = Allocator()); template constexpr basic_string(InputIterator begin, InputIterator end, const Allocator& a = Allocator()); template<@\exposconcept{container-compatible-range}@ R> constexpr basic_string(from_range_t, R&& rg, const Allocator& a = Allocator()); constexpr basic_string(initializer_list, const Allocator& = Allocator()); constexpr basic_string(const basic_string&, const Allocator&); constexpr basic_string(basic_string&&, const Allocator&); constexpr ~basic_string(); constexpr basic_string& operator=(const basic_string& str); constexpr basic_string& operator=(basic_string&& str) noexcept(allocator_traits::propagate_on_container_move_assignment::value || allocator_traits::is_always_equal::value); template constexpr basic_string& operator=(const T& t); constexpr basic_string& operator=(const charT* s); basic_string& operator=(nullptr_t) = delete; constexpr basic_string& operator=(charT c); constexpr basic_string& operator=(initializer_list); // \ref{string.iterators}, iterators constexpr iterator begin() noexcept; constexpr const_iterator begin() const noexcept; constexpr iterator end() noexcept; constexpr const_iterator end() const noexcept; constexpr reverse_iterator rbegin() noexcept; constexpr const_reverse_iterator rbegin() const noexcept; constexpr reverse_iterator rend() noexcept; constexpr const_reverse_iterator rend() const noexcept; constexpr const_iterator cbegin() const noexcept; constexpr const_iterator cend() const noexcept; constexpr const_reverse_iterator crbegin() const noexcept; constexpr const_reverse_iterator crend() const noexcept; // \ref{string.capacity}, capacity constexpr size_type size() const noexcept; constexpr size_type length() const noexcept; constexpr size_type max_size() const noexcept; constexpr void resize(size_type n, charT c); constexpr void resize(size_type n); template constexpr void resize_and_overwrite(size_type n, Operation op); constexpr size_type capacity() const noexcept; constexpr void reserve(size_type res_arg); constexpr void shrink_to_fit(); constexpr void clear() noexcept; constexpr bool empty() const noexcept; // \ref{string.access}, element access constexpr const_reference operator[](size_type pos) const; constexpr reference operator[](size_type pos); constexpr const_reference at(size_type n) const; constexpr reference at(size_type n); constexpr const charT& front() const; constexpr charT& front(); constexpr const charT& back() const; constexpr charT& back(); // \ref{string.modifiers}, modifiers constexpr basic_string& operator+=(const basic_string& str); template constexpr basic_string& operator+=(const T& t); constexpr basic_string& operator+=(const charT* s); constexpr basic_string& operator+=(charT c); constexpr basic_string& operator+=(initializer_list); constexpr basic_string& append(const basic_string& str); constexpr basic_string& append(const basic_string& str, size_type pos, size_type n = npos); template constexpr basic_string& append(const T& t); template constexpr basic_string& append(const T& t, size_type pos, size_type n = npos); constexpr basic_string& append(const charT* s, size_type n); constexpr basic_string& append(const charT* s); constexpr basic_string& append(size_type n, charT c); template constexpr basic_string& append(InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@ R> constexpr basic_string& append_range(R&& rg); constexpr basic_string& append(initializer_list); constexpr void push_back(charT c); constexpr basic_string& assign(const basic_string& str); constexpr basic_string& assign(basic_string&& str) noexcept(allocator_traits::propagate_on_container_move_assignment::value || allocator_traits::is_always_equal::value); constexpr basic_string& assign(const basic_string& str, size_type pos, size_type n = npos); template constexpr basic_string& assign(const T& t); template constexpr basic_string& assign(const T& t, size_type pos, size_type n = npos); constexpr basic_string& assign(const charT* s, size_type n); constexpr basic_string& assign(const charT* s); constexpr basic_string& assign(size_type n, charT c); template constexpr basic_string& assign(InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@ R> constexpr basic_string& assign_range(R&& rg); constexpr basic_string& assign(initializer_list); constexpr basic_string& insert(size_type pos, const basic_string& str); constexpr basic_string& insert(size_type pos1, const basic_string& str, size_type pos2, size_type n = npos); template constexpr basic_string& insert(size_type pos, const T& t); template constexpr basic_string& insert(size_type pos1, const T& t, size_type pos2, size_type n = npos); constexpr basic_string& insert(size_type pos, const charT* s, size_type n); constexpr basic_string& insert(size_type pos, const charT* s); constexpr basic_string& insert(size_type pos, size_type n, charT c); constexpr iterator insert(const_iterator p, charT c); constexpr iterator insert(const_iterator p, size_type n, charT c); template constexpr iterator insert(const_iterator p, InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@ R> constexpr iterator insert_range(const_iterator p, R&& rg); constexpr iterator insert(const_iterator p, initializer_list); constexpr basic_string& erase(size_type pos = 0, size_type n = npos); constexpr iterator erase(const_iterator p); constexpr iterator erase(const_iterator first, const_iterator last); constexpr void pop_back(); constexpr basic_string& replace(size_type pos1, size_type n1, const basic_string& str); constexpr basic_string& replace(size_type pos1, size_type n1, const basic_string& str, size_type pos2, size_type n2 = npos); template constexpr basic_string& replace(size_type pos1, size_type n1, const T& t); template constexpr basic_string& replace(size_type pos1, size_type n1, const T& t, size_type pos2, size_type n2 = npos); constexpr basic_string& replace(size_type pos, size_type n1, const charT* s, size_type n2); constexpr basic_string& replace(size_type pos, size_type n1, const charT* s); constexpr basic_string& replace(size_type pos, size_type n1, size_type n2, charT c); constexpr basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str); template constexpr basic_string& replace(const_iterator i1, const_iterator i2, const T& t); constexpr basic_string& replace(const_iterator i1, const_iterator i2, const charT* s, size_type n); constexpr basic_string& replace(const_iterator i1, const_iterator i2, const charT* s); constexpr basic_string& replace(const_iterator i1, const_iterator i2, size_type n, charT c); template constexpr basic_string& replace(const_iterator i1, const_iterator i2, InputIterator j1, InputIterator j2); template<@\exposconcept{container-compatible-range}@ R> constexpr basic_string& replace_with_range(const_iterator i1, const_iterator i2, R&& rg); constexpr basic_string& replace(const_iterator, const_iterator, initializer_list); constexpr size_type copy(charT* s, size_type n, size_type pos = 0) const; constexpr void swap(basic_string& str) noexcept(allocator_traits::propagate_on_container_swap::value || allocator_traits::is_always_equal::value); // \ref{string.ops}, string operations constexpr const charT* c_str() const noexcept; constexpr const charT* data() const noexcept; constexpr charT* data() noexcept; constexpr operator basic_string_view() const noexcept; constexpr allocator_type get_allocator() const noexcept; template constexpr size_type find(const T& t, size_type pos = 0) const noexcept(@\seebelow@); constexpr size_type find(const basic_string& str, size_type pos = 0) const noexcept; constexpr size_type find(const charT* s, size_type pos, size_type n) const; constexpr size_type find(const charT* s, size_type pos = 0) const; constexpr size_type find(charT c, size_type pos = 0) const noexcept; template constexpr size_type rfind(const T& t, size_type pos = npos) const noexcept(@\seebelow@); constexpr size_type rfind(const basic_string& str, size_type pos = npos) const noexcept; constexpr size_type rfind(const charT* s, size_type pos, size_type n) const; constexpr size_type rfind(const charT* s, size_type pos = npos) const; constexpr size_type rfind(charT c, size_type pos = npos) const noexcept; template constexpr size_type find_first_of(const T& t, size_type pos = 0) const noexcept(@\seebelow@); constexpr size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept; constexpr size_type find_first_of(const charT* s, size_type pos, size_type n) const; constexpr size_type find_first_of(const charT* s, size_type pos = 0) const; constexpr size_type find_first_of(charT c, size_type pos = 0) const noexcept; template constexpr size_type find_last_of(const T& t, size_type pos = npos) const noexcept(@\seebelow@); constexpr size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept; constexpr size_type find_last_of(const charT* s, size_type pos, size_type n) const; constexpr size_type find_last_of(const charT* s, size_type pos = npos) const; constexpr size_type find_last_of(charT c, size_type pos = npos) const noexcept; template constexpr size_type find_first_not_of(const T& t, size_type pos = 0) const noexcept(@\seebelow@); constexpr size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept; constexpr size_type find_first_not_of(const charT* s, size_type pos, size_type n) const; constexpr size_type find_first_not_of(const charT* s, size_type pos = 0) const; constexpr size_type find_first_not_of(charT c, size_type pos = 0) const noexcept; template constexpr size_type find_last_not_of(const T& t, size_type pos = npos) const noexcept(@\seebelow@); constexpr size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept; constexpr size_type find_last_not_of(const charT* s, size_type pos, size_type n) const; constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const; constexpr size_type find_last_not_of(charT c, size_type pos = npos) const noexcept; constexpr basic_string substr(size_type pos = 0, size_type n = npos) const &; constexpr basic_string substr(size_type pos = 0, size_type n = npos) &&; constexpr basic_string_view subview(size_type pos = 0, size_type n = npos) const; template constexpr int compare(const T& t) const noexcept(@\seebelow@); template constexpr int compare(size_type pos1, size_type n1, const T& t) const; template constexpr int compare(size_type pos1, size_type n1, const T& t, size_type pos2, size_type n2 = npos) const; constexpr int compare(const basic_string& str) const noexcept; constexpr int compare(size_type pos1, size_type n1, const basic_string& str) const; constexpr int compare(size_type pos1, size_type n1, const basic_string& str, size_type pos2, size_type n2 = npos) const; constexpr int compare(const charT* s) const; constexpr int compare(size_type pos1, size_type n1, const charT* s) const; constexpr int compare(size_type pos1, size_type n1, const charT* s, size_type n2) const; constexpr bool starts_with(basic_string_view x) const noexcept; constexpr bool starts_with(charT x) const noexcept; constexpr bool starts_with(const charT* x) const; constexpr bool ends_with(basic_string_view x) const noexcept; constexpr bool ends_with(charT x) const noexcept; constexpr bool ends_with(const charT* x) const; constexpr bool contains(basic_string_view x) const noexcept; constexpr bool contains(charT x) const noexcept; constexpr bool contains(const charT* x) const; }; template::value_type>> basic_string(InputIterator, InputIterator, Allocator = Allocator()) -> basic_string::value_type, char_traits::value_type>, Allocator>; template>> basic_string(from_range_t, R&&, Allocator = Allocator()) -> basic_string, char_traits>, Allocator>; template> explicit basic_string(basic_string_view, const Allocator& = Allocator()) -> basic_string; template> basic_string(basic_string_view, typename @\seebelow@::size_type, typename @\seebelow@::size_type, const Allocator& = Allocator()) -> basic_string; } \end{codeblock} \pnum A \tcode{size_type} parameter type in a \tcode{basic_string} deduction guide refers to the \tcode{size_type} member type of the type deduced by the deduction guide. \pnum The types \tcode{iterator} and \tcode{const_iterator} meet the constexpr iterator requirements\iref{iterator.requirements.general}. \rSec3[string.require]{General requirements} \pnum If any operation would cause \tcode{size()} to exceed \tcode{max_size()}, that operation throws an exception object of type \tcode{length_error}. \pnum If any member function or operator of \tcode{basic_string} throws an exception, that function or operator has no other effect on the \tcode{basic_string} object. \pnum Every object of type \tcode{basic_string} uses an object of type \tcode{Allocator} to allocate and free storage for the contained \tcode{charT} objects as needed. The \tcode{Allocator} object used is obtained as described in \ref{container.reqmts}. In every specialization \tcode{basic_string}, the type \tcode{traits} shall meet the character traits requirements\iref{char.traits}. \begin{note} Every specialization \tcode{basic_string} is an allocator-aware container\iref{container.alloc.reqmts}, but does not use the allocator's \tcode{construct} and \tcode{destroy} member functions\iref{container.requirements.pre}. The program is ill-formed if \tcode{Allocator::value_type} is not the same type as \tcode{charT}. \end{note} \begin{note} The program is ill-formed if \tcode{traits::char_type} is not the same type as \tcode{charT}. \end{note} \pnum References, pointers, and iterators referring to the elements of a \tcode{basic_string} sequence may be invalidated by the following uses of that \tcode{basic_string} object: \begin{itemize} \item Passing as an argument to any standard library function taking a reference to non-const \tcode{basic_string} as an argument. \begin{footnote} For example, as an argument to non-member functions \tcode{swap()}\iref{string.special}, \tcode{operator>{}>()}\iref{string.io}, and \tcode{getline()}\iref{string.io}, or as an argument to \tcode{basic_string::swap()}. \end{footnote} \item Calling non-const member functions, except \tcode{operator[]}, \tcode{at}, \tcode{data}, \tcode{front}, \tcode{back}, \tcode{begin}, \tcode{rbegin}, \tcode{end}, and \tcode{rend}. \end{itemize} \rSec3[string.cons]{Constructors and assignment operators} \indexlibraryctor{basic_string}% \begin{itemdecl} constexpr explicit basic_string(const Allocator& a) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \ensures \tcode{size()} is equal to \tcode{0}. \end{itemdescr} \indexlibraryctor{basic_string}% \begin{itemdecl} constexpr basic_string(const basic_string& str); constexpr basic_string(basic_string&& str) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Constructs an object whose value is that of \tcode{str} prior to this call. \pnum \remarks In the second form, \tcode{str} is left in a valid but unspecified state. \end{itemdescr} \indexlibraryctor{basic_string}% \begin{itemdecl} constexpr basic_string(const basic_string& str, size_type pos, const Allocator& a = Allocator()); constexpr basic_string(const basic_string& str, size_type pos, size_type n, const Allocator& a = Allocator()); constexpr basic_string(basic_string&& str, size_type pos, const Allocator& a = Allocator()); constexpr basic_string(basic_string&& str, size_type pos, size_type n, const Allocator& a = Allocator()); \end{itemdecl} \begin{itemdescr} \pnum Let \begin{itemize} \item \tcode{s} be the value of \tcode{str} prior to this call and \item \tcode{rlen} be \tcode{pos + min(n, s.size() - pos)} for the overloads with parameter \tcode{n}, and \tcode{s.size()} otherwise. \end{itemize} \pnum \effects Constructs an object whose initial value is the range \range{s.data() + pos}{s.data() + rlen}. \pnum \throws \tcode{out_of_range} if \tcode{pos > s.size()}. \pnum \remarks For the overloads with a \tcode{basic_string\&\&} parameter, \tcode{str} is left in a valid but unspecified state. \pnum \recommended For the overloads with a \tcode{basic_string\&\&} parameter, implementations should avoid allocation if \tcode{s.get_allocator() == a} is \tcode{true}. \end{itemdescr} \indexlibraryctor{basic_string}% \begin{itemdecl} template constexpr basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator()); \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{is_convertible_v>} is \tcode{true}. \pnum \effects Creates a variable, \tcode{sv}, as if by \tcode{basic_string_view sv = t;} and then behaves the same as: \begin{codeblock} basic_string(sv.substr(pos, n), a); \end{codeblock} \end{itemdescr} \indexlibraryctor{basic_string}% \begin{itemdecl} template constexpr explicit basic_string(const T& t, const Allocator& a = Allocator()); \end{itemdecl} \begin{itemdescr} \pnum \constraints \begin{itemize} \item \tcode{is_convertible_v>} is \tcode{true} and \item \tcode{is_convertible_v} is \tcode{false}. \end{itemize} \pnum \effects Creates a variable, \tcode{sv}, as if by \tcode{basic_string_view sv = t;} and then behaves the same as \tcode{basic_string(sv.data(), sv.size(), a)}. \end{itemdescr} \indexlibraryctor{basic_string}% \begin{itemdecl} constexpr basic_string(const charT* s, size_type n, const Allocator& a = Allocator()); \end{itemdecl} \begin{itemdescr} \pnum \expects \range{s}{s + n} is a valid range. \pnum \effects Constructs an object whose initial value is the range \range{s}{s + n}. \pnum \ensures \tcode{size()} is equal to \tcode{n}, and \tcode{traits::compare(data(), s, n)} is equal to \tcode{0}. \end{itemdescr} \indexlibraryctor{basic_string}% \begin{itemdecl} constexpr basic_string(const charT* s, const Allocator& a = Allocator()); \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{Allocator} is a type that qualifies as an allocator\iref{container.reqmts}. \begin{note} This affects class template argument deduction. \end{note} \pnum \effects Equivalent to: \tcode{basic_string(s, traits::length(s), a)}. \end{itemdescr} \indexlibraryctor{basic_string}% \begin{itemdecl} constexpr basic_string(size_type n, charT c, const Allocator& a = Allocator()); \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{Allocator} is a type that qualifies as an allocator\iref{container.reqmts}. \begin{note} This affects class template argument deduction. \end{note} \pnum \effects Constructs an object whose value consists of \tcode{n} copies of \tcode{c}. \end{itemdescr} \indexlibraryctor{basic_string}% \begin{itemdecl} template constexpr basic_string(InputIterator begin, InputIterator end, const Allocator& a = Allocator()); \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{InputIterator} is a type that qualifies as an input iterator\iref{container.reqmts}. \pnum \effects Constructs a string from the values in the range \range{begin}{end}, as specified in \ref{sequence.reqmts}. \end{itemdescr} \indexlibraryctor{basic_string}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@ R> constexpr basic_string(from_range_t, R&& rg, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} \pnum \effects Constructs a string from the values in the range \tcode{rg}, as specified in \ref{sequence.reqmts}. \end{itemdescr} \indexlibraryctor{basic_string}% \begin{itemdecl} constexpr basic_string(initializer_list il, const Allocator& a = Allocator()); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{basic_string(il.begin(), il.end(), a)}. \end{itemdescr} \indexlibraryctor{basic_string}% \begin{itemdecl} constexpr basic_string(const basic_string& str, const Allocator& alloc); constexpr basic_string(basic_string&& str, const Allocator& alloc); \end{itemdecl} \begin{itemdescr} \pnum \effects Constructs an object whose value is that of \tcode{str} prior to this call. The stored allocator is constructed from \tcode{alloc}. In the second form, \tcode{str} is left in a valid but unspecified state. \pnum \throws The second form throws nothing if \tcode{alloc == str.get_allocator()}. \end{itemdescr} \begin{itemdecl} template::value_type>> basic_string(InputIterator, InputIterator, Allocator = Allocator()) -> basic_string::value_type, char_traits::value_type>, Allocator>; \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{InputIterator} is a type that qualifies as an input iterator, and \tcode{Allocator} is a type that qualifies as an allocator\iref{container.reqmts}. \end{itemdescr} \begin{itemdecl} template> explicit basic_string(basic_string_view, const Allocator& = Allocator()) -> basic_string; template> basic_string(basic_string_view, typename @\seebelow@::size_type, typename @\seebelow@::size_type, const Allocator& = Allocator()) -> basic_string; \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{Allocator} is a type that qualifies as an allocator\iref{container.reqmts}. \end{itemdescr} \indexlibrarymember{operator=}{basic_string}% \begin{itemdecl} constexpr basic_string& operator=(const basic_string& str); \end{itemdecl} \begin{itemdescr} \pnum \effects If \tcode{*this} and \tcode{str} are the same object, has no effect. Otherwise, replaces the value of \tcode{*this} with a copy of \tcode{str}. \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{operator=}{basic_string}% \begin{itemdecl} constexpr basic_string& operator=(basic_string&& str) noexcept(allocator_traits::propagate_on_container_move_assignment::value || allocator_traits::is_always_equal::value); \end{itemdecl} \begin{itemdescr} \pnum \effects Move assigns as a sequence container\iref{sequence.reqmts}, except that iterators, pointers and references may be invalidated. \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{operator=}{basic_string}% \begin{itemdecl} template constexpr basic_string& operator=(const T& t); \end{itemdecl} \begin{itemdescr} \pnum \constraints \begin{itemize} \item \tcode{is_convertible_v>} is \tcode{true} and \item \tcode{is_convertible_v} is \tcode{false}. \end{itemize} \pnum \effects Equivalent to: \begin{codeblock} basic_string_view sv = t; return assign(sv); \end{codeblock} \end{itemdescr} \indexlibrarymember{operator=}{basic_string}% \begin{itemdecl} constexpr basic_string& operator=(const charT* s); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return *this = basic_string_view(s);} \end{itemdescr} \indexlibrarymember{operator=}{basic_string}% \begin{itemdecl} constexpr basic_string& operator=(charT c); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} return *this = basic_string_view(addressof(c), 1); \end{codeblock} \end{itemdescr} \indexlibrarymember{operator=}{basic_string}% \begin{itemdecl} constexpr basic_string& operator=(initializer_list il); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} return *this = basic_string_view(il.begin(), il.size()); \end{codeblock} \end{itemdescr} \rSec3[string.iterators]{Iterator support} \indexlibrarymember{begin}{basic_string}% \indexlibrarymember{cbegin}{basic_string}% \begin{itemdecl} constexpr iterator begin() noexcept; constexpr const_iterator begin() const noexcept; constexpr const_iterator cbegin() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns An iterator referring to the first character in the string. \end{itemdescr} \indexlibrarymember{end}{basic_string}% \indexlibrarymember{cend}{basic_string}% \begin{itemdecl} constexpr iterator end() noexcept; constexpr const_iterator end() const noexcept; constexpr const_iterator cend() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns An iterator which is the past-the-end value. \end{itemdescr} \indexlibrarymember{rbegin}{basic_string}% \indexlibrarymember{crbegin}{basic_string}% \begin{itemdecl} constexpr reverse_iterator rbegin() noexcept; constexpr const_reverse_iterator rbegin() const noexcept; constexpr const_reverse_iterator crbegin() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns An iterator which is semantically equivalent to \tcode{reverse_iterator(end())}. \end{itemdescr} \indexlibrarymember{rend}{basic_string}% \indexlibrarymember{crend}{basic_string}% \begin{itemdecl} constexpr reverse_iterator rend() noexcept; constexpr const_reverse_iterator rend() const noexcept; constexpr const_reverse_iterator crend() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns An iterator which is semantically equivalent to \tcode{reverse_iterator(begin())}. \end{itemdescr} \rSec3[string.capacity]{Capacity} \indexlibrarymember{size}{basic_string}% \indexlibrarymember{length}{basic_string}% \begin{itemdecl} constexpr size_type size() const noexcept; constexpr size_type length() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns A count of the number of char-like objects currently in the string. \pnum \complexity Constant time. \end{itemdescr} \indexlibrarymember{max_size}{basic_string}% \begin{itemdecl} constexpr size_type max_size() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns The largest possible number of char-like objects that can be stored in a \tcode{basic_string}. \pnum \complexity Constant time. \end{itemdescr} \indexlibrarymember{resize}{basic_string}% \begin{itemdecl} constexpr void resize(size_type n, charT c); \end{itemdecl} \begin{itemdescr} \pnum \effects Alters the value of \tcode{*this} as follows: \begin{itemize} \item If \tcode{n <= size()}, erases the last \tcode{size() - n} elements. \item If \tcode{n > size()}, appends \tcode{n - size()} copies of \tcode{c}. \end{itemize} \end{itemdescr} \indexlibrarymember{resize}{basic_string}% \begin{itemdecl} constexpr void resize(size_type n); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{resize(n, charT())}. \end{itemdescr} \indexlibrarymember{resize_and_overwrite}{basic_string}% \begin{itemdecl} template constexpr void resize_and_overwrite(size_type n, Operation op); \end{itemdecl} \begin{itemdescr} \pnum Let \begin{itemize} \item \tcode{o = size()} before the call to \tcode{resize_and_overwrite}. \item \tcode{k} be \tcode{min(o, n)}. \item \tcode{p} be a value of type \tcode{charT*} or \tcode{charT* const}, such that the range \crange{p}{p + n} is valid and \tcode{this->compare(0, k, p, k) == 0} is \tcode{true} before the call. The values in the range \crange{p + k}{p + n} may be indeterminate\iref{basic.indet}. \item \tcode{m} be a value of type \tcode{size_type} or \tcode{const size_type} equal to \tcode{n}. \item \tcode{\placeholder{OP}} be the expression \tcode{std::move(op)(p, m)}. \item \tcode{r} = \tcode{\placeholder{OP}}. \end{itemize} \pnum \mandates \tcode{\placeholder{OP}} has an integer-like type\iref{iterator.concept.winc}. \pnum \expects \begin{itemize} \item \tcode{\placeholder{OP}} does not throw an exception or modify \tcode{p} or \tcode{m}. \item $\tcode{r} \geq 0$. \item $\tcode{r} \leq \tcode{m}$. \item After evaluating \tcode{\placeholder{OP}} there are no indeterminate values in the range \range{p}{p + r}. \end{itemize} \pnum \effects Evaluates \tcode{\placeholder{OP}}, replaces the contents of \tcode{*this} with \range{p}{p + r}, and invalidates all pointers and references to the range \crange{p}{p + n}. \pnum \recommended Implementations should avoid unnecessary copies and allocations by, for example, making \tcode{p} a pointer into internal storage and by restoring \tcode{*(p + r)} to \tcode{charT()} after evaluating \tcode{\placeholder{OP}}. \end{itemdescr} \indexlibrarymember{capacity}{basic_string}% \begin{itemdecl} constexpr size_type capacity() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns The size of the allocated storage in the string. \pnum \complexity Constant time. \end{itemdescr} \indexlibrarymember{reserve}{basic_string}% \begin{itemdecl} constexpr void reserve(size_type res_arg); \end{itemdecl} \begin{itemdescr} \pnum \effects A directive that informs a \tcode{basic_string} of a planned change in size, so that the storage allocation can be managed accordingly. Following a call to \tcode{reserve}, \tcode{capacity()} is greater or equal to the argument of \tcode{reserve} if reallocation happens; and equal to the previous value of \tcode{capacity()} otherwise. Reallocation happens at this point if and only if the current capacity is less than the argument of \tcode{reserve}. \pnum \throws \tcode{length_error} if \tcode{res_arg > max_size()} or any exceptions thrown by \tcode{allocator_traits} \tcode{::allocate}. \end{itemdescr} \indexlibrarymember{shrink_to_fit}{basic_string}% \begin{itemdecl} constexpr void shrink_to_fit(); \end{itemdecl} \begin{itemdescr} \pnum \effects \tcode{shrink_to_fit} is a non-binding request to reduce \tcode{capacity()} to \tcode{size()}. \begin{note} The request is non-binding to allow latitude for implementation-specific optimizations. \end{note} It does not increase \tcode{capacity()}, but may reduce \tcode{capacity()} by causing reallocation. \pnum \complexity If the size is not equal to the old capacity, linear in the size of the sequence; otherwise constant. \pnum \remarks Reallocation invalidates all the references, pointers, and iterators referring to the elements in the sequence, as well as the past-the-end iterator. \begin{note} If no reallocation happens, they remain valid. \end{note} \end{itemdescr} \indexlibrarymember{clear}{basic_string}% \begin{itemdecl} constexpr void clear() noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{erase(begin(), end());} \end{itemdescr} \indexlibrarymember{empty}{basic_string}% \begin{itemdecl} constexpr bool empty() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return size() == 0;} \end{itemdescr} \rSec3[string.access]{Element access} \indexlibrarymember{operator[]}{basic_string}% \begin{itemdecl} constexpr const_reference operator[](size_type pos) const; constexpr reference operator[](size_type pos); \end{itemdecl} \begin{itemdescr} \pnum \hardexpects \tcode{pos <= size()} is \tcode{true}. \pnum \returns \tcode{*(begin() + pos)} if \tcode{pos < size()}. Otherwise, returns a reference to an object of type \tcode{charT} with value \tcode{charT()}, where modifying the object to any value other than \tcode{charT()} leads to undefined behavior. \pnum \throws Nothing. \pnum \complexity Constant time. \end{itemdescr} \indexlibrarymember{at}{basic_string}% \begin{itemdecl} constexpr const_reference at(size_type pos) const; constexpr reference at(size_type pos); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{operator[](pos)}. \pnum \throws \tcode{out_of_range} if \tcode{pos >= size()}. \end{itemdescr} \indexlibrarymember{front}{basic_string}% \begin{itemdecl} constexpr const charT& front() const; constexpr charT& front(); \end{itemdecl} \begin{itemdescr} \pnum \hardexpects \tcode{empty()} is \tcode{false}. \pnum \effects Equivalent to: \tcode{return operator[](0);} \end{itemdescr} \indexlibrarymember{back}{basic_string}% \begin{itemdecl} constexpr const charT& back() const; constexpr charT& back(); \end{itemdecl} \begin{itemdescr} \pnum \hardexpects \tcode{empty()} is \tcode{false}. \pnum \effects Equivalent to: \tcode{return operator[](size() - 1);} \end{itemdescr} \rSec3[string.modifiers]{Modifiers} \rSec4[string.op.append]{\tcode{basic_string::operator+=}} \indexlibrarymember{operator+=}{basic_string}% \begin{itemdecl} constexpr basic_string& operator+=(const basic_string& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return append(str);} \end{itemdescr} \indexlibrarymember{operator+=}{basic_string}% \begin{itemdecl} template constexpr basic_string& operator+=(const T& t); \end{itemdecl} \begin{itemdescr} \pnum \constraints \begin{itemize} \item \tcode{is_convertible_v>} is \tcode{true} and \item \tcode{is_convertible_v} is \tcode{false}. \end{itemize} \pnum \effects Equivalent to: \begin{codeblock} basic_string_view sv = t; return append(sv); \end{codeblock} \end{itemdescr} \indexlibrarymember{operator+=}{basic_string}% \begin{itemdecl} constexpr basic_string& operator+=(const charT* s); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return append(s);} \end{itemdescr} \indexlibrarymember{operator+=}{basic_string}% \begin{itemdecl} constexpr basic_string& operator+=(charT c); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return append(size_type\{1\}, c);} \end{itemdescr} \indexlibrarymember{operator+=}{basic_string}% \begin{itemdecl} constexpr basic_string& operator+=(initializer_list il); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return append(il);} \end{itemdescr} \rSec4[string.append]{\tcode{basic_string::append}} \indexlibrarymember{append}{basic_string}% \begin{itemdecl} constexpr basic_string& append(const basic_string& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return append(str.data(), str.size());} \end{itemdescr} \indexlibrarymember{append}{basic_string}% \begin{itemdecl} constexpr basic_string& append(const basic_string& str, size_type pos, size_type n = npos); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} return append(basic_string_view(str).substr(pos, n)); \end{codeblock} \end{itemdescr} \indexlibrarymember{append}{basic_string}% \begin{itemdecl} template constexpr basic_string& append(const T& t); \end{itemdecl} \begin{itemdescr} \pnum \constraints \begin{itemize} \item \tcode{is_convertible_v>} is \tcode{true} and \item \tcode{is_convertible_v} is \tcode{false}. \end{itemize} \pnum \effects Equivalent to: \begin{codeblock} basic_string_view sv = t; return append(sv.data(), sv.size()); \end{codeblock} \end{itemdescr} \indexlibrarymember{append}{basic_string}% \begin{itemdecl} template constexpr basic_string& append(const T& t, size_type pos, size_type n = npos); \end{itemdecl} \begin{itemdescr} \pnum \constraints \begin{itemize} \item \tcode{is_convertible_v>} is \tcode{true} and \item \tcode{is_convertible_v} is \tcode{false}. \end{itemize} \pnum \effects Equivalent to: \begin{codeblock} basic_string_view sv = t; return append(sv.substr(pos, n)); \end{codeblock} \end{itemdescr} \indexlibrarymember{append}{basic_string}% \begin{itemdecl} constexpr basic_string& append(const charT* s, size_type n); \end{itemdecl} \begin{itemdescr} \pnum \expects \range{s}{s + n} is a valid range. \pnum \effects Appends a copy of the range \range{s}{s + n} to the string. \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{append}{basic_string}% \begin{itemdecl} constexpr basic_string& append(const charT* s); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return append(s, traits::length(s));} \end{itemdescr} \indexlibrarymember{append}{basic_string}% \begin{itemdecl} constexpr basic_string& append(size_type n, charT c); \end{itemdecl} \begin{itemdescr} \pnum \effects Appends \tcode{n} copies of \tcode{c} to the string. \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{append}{basic_string}% \begin{itemdecl} template constexpr basic_string& append(InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{InputIterator} is a type that qualifies as an input iterator\iref{container.reqmts}. \pnum \effects Equivalent to: \tcode{return append(basic_string(first, last, get_allocator()));} \end{itemdescr} \indexlibrarymember{append_range}{basic_string}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@ R> constexpr basic_string& append_range(R&& rg); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return append(basic_string(from_range, std::forward(rg), get_allocator()));} \end{itemdescr} \indexlibrarymember{append}{basic_string}% \begin{itemdecl} constexpr basic_string& append(initializer_list il); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return append(il.begin(), il.size());} \end{itemdescr} \indexlibrarymember{push_back}{basic_string}% \begin{itemdecl} constexpr void push_back(charT c); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{append(size_type\{1\}, c)}. \end{itemdescr} \rSec4[string.assign]{\tcode{basic_string::assign}} \indexlibrarymember{assign}{basic_string}% \begin{itemdecl} constexpr basic_string& assign(const basic_string& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return *this = str;} \end{itemdescr} \indexlibrarymember{assign}{basic_string}% \begin{itemdecl} constexpr basic_string& assign(basic_string&& str) noexcept(allocator_traits::propagate_on_container_move_assignment::value || allocator_traits::is_always_equal::value); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return *this = std::move(str);} \end{itemdescr} \indexlibrarymember{assign}{basic_string}% \begin{itemdecl} constexpr basic_string& assign(const basic_string& str, size_type pos, size_type n = npos); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} return assign(basic_string_view(str).substr(pos, n)); \end{codeblock} \end{itemdescr} \indexlibrarymember{assign}{basic_string}% \begin{itemdecl} template constexpr basic_string& assign(const T& t); \end{itemdecl} \begin{itemdescr} \pnum \constraints \begin{itemize} \item \tcode{is_convertible_v>} is \tcode{true} and \item \tcode{is_convertible_v} is \tcode{false}. \end{itemize} \pnum \effects Equivalent to: \begin{codeblock} basic_string_view sv = t; return assign(sv.data(), sv.size()); \end{codeblock} \end{itemdescr} \indexlibrarymember{assign}{basic_string}% \begin{itemdecl} template constexpr basic_string& assign(const T& t, size_type pos, size_type n = npos); \end{itemdecl} \begin{itemdescr} \pnum \constraints \begin{itemize} \item \tcode{is_convertible_v>} is \tcode{true} and \item \tcode{is_convertible_v} is \tcode{false}. \end{itemize} \pnum \effects Equivalent to: \begin{codeblock} basic_string_view sv = t; return assign(sv.substr(pos, n)); \end{codeblock} \end{itemdescr} \indexlibrarymember{assign}{basic_string}% \begin{itemdecl} constexpr basic_string& assign(const charT* s, size_type n); \end{itemdecl} \begin{itemdescr} \pnum \expects \range{s}{s + n} is a valid range. \pnum \effects Replaces the string controlled by \tcode{*this} with a copy of the range \range{s}{s + n}. \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{assign}{basic_string}% \begin{itemdecl} constexpr basic_string& assign(const charT* s); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return assign(s, traits::length(s));} \end{itemdescr} \indexlibrarymember{assign}{basic_string}% \begin{itemdecl} constexpr basic_string& assign(initializer_list il); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return assign(il.begin(), il.size());} \end{itemdescr} \indexlibrarymember{assign}{basic_string}% \begin{itemdecl} constexpr basic_string& assign(size_type n, charT c); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} clear(); resize(n, c); return *this; \end{codeblock} \end{itemdescr} \indexlibrarymember{assign}{basic_string}% \begin{itemdecl} template constexpr basic_string& assign(InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{InputIterator} is a type that qualifies as an input iterator\iref{container.reqmts}. \pnum \effects Equivalent to: \tcode{return assign(basic_string(first, last, get_allocator()));} \end{itemdescr} \indexlibrarymember{assign_range}{basic_string}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@ R> constexpr basic_string& assign_range(R&& rg); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return assign(basic_string(from_range, std::forward(rg), get_allocator()));} \end{itemdescr} \rSec4[string.insert]{\tcode{basic_string::insert}} \indexlibrarymember{insert}{basic_string}% \begin{itemdecl} constexpr basic_string& insert(size_type pos, const basic_string& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return insert(pos, str.data(), str.size());} \end{itemdescr} \indexlibrarymember{insert}{basic_string}% \begin{itemdecl} constexpr basic_string& insert(size_type pos1, const basic_string& str, size_type pos2, size_type n = npos); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} return insert(pos1, basic_string_view(str), pos2, n); \end{codeblock} \end{itemdescr} \indexlibrarymember{insert}{basic_string}% \begin{itemdecl} template constexpr basic_string& insert(size_type pos, const T& t); \end{itemdecl} \begin{itemdescr} \pnum \constraints \begin{itemize} \item \tcode{is_convertible_v>} is \tcode{true} and \item \tcode{is_convertible_v} is \tcode{false}. \end{itemize} \pnum \effects Equivalent to: \begin{codeblock} basic_string_view sv = t; return insert(pos, sv.data(), sv.size()); \end{codeblock} \end{itemdescr} \indexlibrarymember{insert}{basic_string}% \begin{itemdecl} template constexpr basic_string& insert(size_type pos1, const T& t, size_type pos2, size_type n = npos); \end{itemdecl} \begin{itemdescr} \pnum \constraints \begin{itemize} \item \tcode{is_convertible_v>} is \tcode{true} and \item \tcode{is_convertible_v} is \tcode{false}. \end{itemize} \pnum \effects Equivalent to: \begin{codeblock} basic_string_view sv = t; return insert(pos1, sv.substr(pos2, n)); \end{codeblock} \end{itemdescr} \indexlibrarymember{insert}{basic_string}% \begin{itemdecl} constexpr basic_string& insert(size_type pos, const charT* s, size_type n); \end{itemdecl} \begin{itemdescr} \pnum \expects \range{s}{s + n} is a valid range. \pnum \effects Inserts a copy of the range \range{s}{s + n} immediately before the character at position \tcode{pos} if \tcode{pos < size()}, or otherwise at the end of the string. \pnum \returns \tcode{*this}. \pnum \throws \begin{itemize} \item \tcode{out_of_range} if \tcode{pos > size()}, \item \tcode{length_error} if \tcode{n > max_size() - size()}, or \item any exceptions thrown by \tcode{allocator_traits::allocate}. \end{itemize} \end{itemdescr} \indexlibrarymember{insert}{basic_string}% \begin{itemdecl} constexpr basic_string& insert(size_type pos, const charT* s); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return insert(pos, s, traits::length(s));} \end{itemdescr} \indexlibrarymember{insert}{basic_string}% \begin{itemdecl} constexpr basic_string& insert(size_type pos, size_type n, charT c); \end{itemdecl} \begin{itemdescr} \pnum \effects Inserts \tcode{n} copies of \tcode{c} before the character at position \tcode{pos} if \tcode{pos < size()}, or otherwise at the end of the string. \pnum \returns \tcode{*this}. \pnum \throws \begin{itemize} \item \tcode{out_of_range} if \tcode{pos > size()}, \item \tcode{length_error} if \tcode{n > max_size() - size()}, or \item any exceptions thrown by \tcode{allocator_traits::allocate}. \end{itemize} \end{itemdescr} \indexlibrarymember{insert}{basic_string}% \begin{itemdecl} constexpr iterator insert(const_iterator p, charT c); \end{itemdecl} \begin{itemdescr} \pnum \expects \tcode{p} is a valid iterator on \tcode{*this}. \pnum \effects Inserts a copy of \tcode{c} at the position \tcode{p}. \pnum \returns An iterator which refers to the inserted character. \end{itemdescr} \indexlibrarymember{insert}{basic_string}% \begin{itemdecl} constexpr iterator insert(const_iterator p, size_type n, charT c); \end{itemdecl} \begin{itemdescr} \pnum \expects \tcode{p} is a valid iterator on \tcode{*this}. \pnum \effects Inserts \tcode{n} copies of \tcode{c} at the position \tcode{p}. \pnum \returns An iterator which refers to the first inserted character, or \tcode{p} if \tcode{n == 0}. \end{itemdescr} \indexlibrarymember{insert}{basic_string}% \begin{itemdecl} template constexpr iterator insert(const_iterator p, InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{InputIterator} is a type that qualifies as an input iterator\iref{container.reqmts}. \pnum \expects \tcode{p} is a valid iterator on \tcode{*this}. \pnum \effects Equivalent to \tcode{insert(p - begin(), basic_string(first, last, get_allocator()))}. \pnum \returns An iterator which refers to the first inserted character, or \tcode{p} if \tcode{first == last}. \end{itemdescr} \indexlibrarymember{insert_range}{basic_string}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@ R> constexpr iterator insert_range(const_iterator p, R&& rg); \end{itemdecl} \begin{itemdescr} \pnum \expects \tcode{p} is a valid iterator on \tcode{*this}. \pnum \effects Equivalent to \tcode{insert(p - begin(), basic_string(from_range, std::forward(rg), get_allocator()))}. \pnum \returns An iterator which refers to the first inserted character, or \tcode{p} if \tcode{rg} is empty. \end{itemdescr} \indexlibrarymember{insert}{basic_string}% \begin{itemdecl} constexpr iterator insert(const_iterator p, initializer_list il); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return insert(p, il.begin(), il.end());} \end{itemdescr} \rSec4[string.erase]{\tcode{basic_string::erase}} \indexlibrarymember{erase}{basic_string}% \begin{itemdecl} constexpr basic_string& erase(size_type pos = 0, size_type n = npos); \end{itemdecl} \begin{itemdescr} \pnum \effects Determines the effective length \tcode{xlen} of the string to be removed as the smaller of \tcode{n} and \tcode{size() - pos}. Removes the characters in the range \range{begin() + pos}{begin() + pos + xlen}. \pnum \returns \tcode{*this}. \pnum \throws \tcode{out_of_range} if \tcode{pos} \tcode{> size()}. \end{itemdescr} \indexlibrarymember{erase}{basic_string}% \begin{itemdecl} constexpr iterator erase(const_iterator p); \end{itemdecl} \begin{itemdescr} \pnum \expects \tcode{p} is a valid dereferenceable iterator on \tcode{*this}. \pnum \effects Removes the character referred to by \tcode{p}. \pnum \returns An iterator which points to the element immediately following \tcode{p} prior to the element being erased. If no such element exists, \tcode{end()} is returned. \pnum \throws Nothing. \end{itemdescr} \indexlibrarymember{erase}{basic_string}% \begin{itemdecl} constexpr iterator erase(const_iterator first, const_iterator last); \end{itemdecl} \begin{itemdescr} \pnum \expects \tcode{first} and \tcode{last} are valid iterators on \tcode{*this}. \range{first}{last} is a valid range. \pnum \effects Removes the characters in the range \range{first}{last}. \pnum \returns An iterator which points to the element pointed to by \tcode{last} prior to the other elements being erased. If no such element exists, \tcode{end()} is returned. \pnum \throws Nothing. \end{itemdescr} \indexlibrarymember{pop_back}{basic_string}% \begin{itemdecl} constexpr void pop_back(); \end{itemdecl} \begin{itemdescr} \pnum \hardexpects \tcode{empty()} is \tcode{false}. \pnum \effects Equivalent to \tcode{erase(end() - 1)}. \pnum \throws Nothing. \end{itemdescr} \rSec4[string.replace]{\tcode{basic_string::replace}} \indexlibrarymember{replace}{basic_string}% \begin{itemdecl} constexpr basic_string& replace(size_type pos1, size_type n1, const basic_string& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return replace(pos1, n1, str.data(), str.size());} \end{itemdescr} \indexlibrarymember{replace}{basic_string}% \begin{itemdecl} constexpr basic_string& replace(size_type pos1, size_type n1, const basic_string& str, size_type pos2, size_type n2 = npos); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} return replace(pos1, n1, basic_string_view(str).substr(pos2, n2)); \end{codeblock} \end{itemdescr} \indexlibrarymember{replace}{basic_string}% \begin{itemdecl} template constexpr basic_string& replace(size_type pos1, size_type n1, const T& t); \end{itemdecl} \begin{itemdescr} \pnum \constraints \begin{itemize} \item \tcode{is_convertible_v>} is \tcode{true} and \item \tcode{is_convertible_v} is \tcode{false}. \end{itemize} \pnum \effects Equivalent to: \begin{codeblock} basic_string_view sv = t; return replace(pos1, n1, sv.data(), sv.size()); \end{codeblock} \end{itemdescr} \indexlibrarymember{replace}{basic_string}% \begin{itemdecl} template constexpr basic_string& replace(size_type pos1, size_type n1, const T& t, size_type pos2, size_type n2 = npos); \end{itemdecl} \begin{itemdescr} \pnum \constraints \begin{itemize} \item \tcode{is_convertible_v>} is \tcode{true} and \item \tcode{is_convertible_v} is \tcode{false}. \end{itemize} \pnum \effects Equivalent to: \begin{codeblock} basic_string_view sv = t; return replace(pos1, n1, sv.substr(pos2, n2)); \end{codeblock} \end{itemdescr} \indexlibrarymember{replace}{basic_string}% \begin{itemdecl} constexpr basic_string& replace(size_type pos1, size_type n1, const charT* s, size_type n2); \end{itemdecl} \begin{itemdescr} \pnum \expects \range{s}{s + n2} is a valid range. \pnum \effects Determines the effective length \tcode{xlen} of the string to be removed as the smaller of \tcode{n1} and \tcode{size() - pos1}. If \tcode{size() - xlen >= max_size() - n2} throws \tcode{length_error}. Otherwise, the function replaces the characters in the range \range{begin() + pos1}{begin() + pos1 + xlen} with a copy of the range \range{s}{s + n2}. \pnum \returns \tcode{*this}. \pnum \throws \begin{itemize} \item \tcode{out_of_range} if \tcode{pos1 > size()}, \item \tcode{length_error} if the length of the resulting string would exceed \tcode{max_size()}, or \item any exceptions thrown by \tcode{allocator_traits::allocate}. \end{itemize} \end{itemdescr} \indexlibrarymember{replace}{basic_string}% \begin{itemdecl} constexpr basic_string& replace(size_type pos, size_type n, const charT* s); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return replace(pos, n, s, traits::length(s));} \end{itemdescr} \indexlibrarymember{replace}{basic_string}% \begin{itemdecl} constexpr basic_string& replace(size_type pos1, size_type n1, size_type n2, charT c); \end{itemdecl} \begin{itemdescr} \pnum \effects Determines the effective length \tcode{xlen} of the string to be removed as the smaller of \tcode{n1} and \tcode{size() - pos1}. If \tcode{size() - xlen >=} \tcode{max_size() - n2} throws \tcode{length_error}. Otherwise, the function replaces the characters in the range \range{begin() + pos1}{begin() + pos1 + xlen} with \tcode{n2} copies of \tcode{c}. \pnum \returns \tcode{*this}. \pnum \throws \begin{itemize} \item \tcode{out_of_range} if \tcode{pos1 > size()}, \item \tcode{length_error} if the length of the resulting string would exceed\tcode{max_size()}, or \item any exceptions thrown by \tcode{allocator_traits::allocate.} \end{itemize} \end{itemdescr} \indexlibrarymember{replace}{basic_string}% \begin{itemdecl} constexpr basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return replace(i1, i2, basic_string_view(str));} \end{itemdescr} \indexlibrarymember{replace}{basic_string}% \begin{itemdecl} template constexpr basic_string& replace(const_iterator i1, const_iterator i2, const T& t); \end{itemdecl} \begin{itemdescr} \pnum \constraints \begin{itemize} \item \tcode{is_convertible_v>} is \tcode{true} and \item \tcode{is_convertible_v} is \tcode{false}. \end{itemize} \pnum \expects \range{begin()}{i1} and \range{i1}{i2} are valid ranges. \pnum \effects Equivalent to: \begin{codeblock} basic_string_view sv = t; return replace(i1 - begin(), i2 - i1, sv.data(), sv.size()); \end{codeblock} \end{itemdescr} \indexlibrarymember{replace}{basic_string}% \begin{itemdecl} constexpr basic_string& replace(const_iterator i1, const_iterator i2, const charT* s, size_type n); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return replace(i1, i2, basic_string_view(s, n));} \end{itemdescr} \indexlibrarymember{replace}{basic_string}% \begin{itemdecl} constexpr basic_string& replace(const_iterator i1, const_iterator i2, const charT* s); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return replace(i1, i2, basic_string_view(s));} \end{itemdescr} \indexlibrarymember{replace}{basic_string}% \begin{itemdecl} constexpr basic_string& replace(const_iterator i1, const_iterator i2, size_type n, charT c); \end{itemdecl} \begin{itemdescr} \pnum \expects \range{begin()}{i1} and \range{i1}{i2} are valid ranges. \pnum \effects Equivalent to: \tcode{return replace(i1 - begin(), i2 - i1, n, c);} \end{itemdescr} \indexlibrarymember{replace}{basic_string}% \begin{itemdecl} template constexpr basic_string& replace(const_iterator i1, const_iterator i2, InputIterator j1, InputIterator j2); \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{InputIterator} is a type that qualifies as an input iterator\iref{container.reqmts}. \pnum \effects Equivalent to: \tcode{return replace(i1, i2, basic_string(j1, j2, get_allocator()));} \end{itemdescr} \indexlibrarymember{replace_with_range}{basic_string}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@ R> constexpr basic_string& replace_with_range(const_iterator i1, const_iterator i2, R&& rg); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} return replace(i1, i2, basic_string(from_range, std::forward(rg), get_allocator())); \end{codeblock} \end{itemdescr} \indexlibrarymember{replace}{basic_string}% \begin{itemdecl} constexpr basic_string& replace(const_iterator i1, const_iterator i2, initializer_list il); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return replace(i1, i2, il.begin(), il.size());} \end{itemdescr} \rSec4[string.copy]{\tcode{basic_string::copy}} \indexlibrarymember{copy}{basic_string}% \begin{itemdecl} constexpr size_type copy(charT* s, size_type n, size_type pos = 0) const; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return basic_string_view(*this).copy(s, n, pos);} \begin{note} This does not terminate \tcode{s} with a null object. \end{note} \end{itemdescr} \rSec4[string.swap]{\tcode{basic_string::swap}} \indexlibrarymember{swap}{basic_string}% \begin{itemdecl} constexpr void swap(basic_string& s) noexcept(allocator_traits::propagate_on_container_swap::value || allocator_traits::is_always_equal::value); \end{itemdecl} \begin{itemdescr} \pnum \expects \tcode{allocator_traits::propagate_on_container_swap::value} is \tcode{true} or \tcode{get_allocator() == s.get_allocator()}. \pnum \ensures \tcode{*this} contains the same sequence of characters that was in \tcode{s}, \tcode{s} contains the same sequence of characters that was in \tcode{*this}. \pnum \throws Nothing. \pnum \complexity Constant time. \end{itemdescr} \rSec3[string.ops]{String operations} \rSec4[string.accessors]{Accessors} \indexlibrarymember{c_str}{basic_string}% \indexlibrarymember{data}{basic_string}% \begin{itemdecl} constexpr const charT* c_str() const noexcept; constexpr const charT* data() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns A pointer \tcode{p} such that \tcode{p + i == addressof(operator[](i))} for each \tcode{i} in \crange{0}{size()}. \pnum \complexity Constant time. \pnum \remarks The program shall not modify any of the values stored in the character array; otherwise, the behavior is undefined. \end{itemdescr} \indexlibrarymember{data}{basic_string}% \begin{itemdecl} constexpr charT* data() noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns A pointer \tcode{p} such that \tcode{p + i == addressof(operator[](i))} for each \tcode{i} in \crange{0}{size()}. \pnum \complexity Constant time. \pnum \remarks The program shall not modify the value stored at \tcode{p + size()} to any value other than \tcode{charT()}; otherwise, the behavior is undefined. \end{itemdescr} \indexlibrarymember{operator basic_string_view}{basic_string}% \begin{itemdecl} constexpr operator basic_string_view() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return basic_string_view(data(), size());} \end{itemdescr} \indexlibrarymember{get_allocator}{basic_string}% \begin{itemdecl} constexpr allocator_type get_allocator() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns A copy of the \tcode{Allocator} object used to construct the string or, if that allocator has been replaced, a copy of the most recent replacement. \end{itemdescr} \rSec4[string.find]{Searching} \pnum \indexlibrarymember{find}{basic_string}% \indexlibrarymember{rfind}{basic_string}% \indexlibrarymember{find_first_of}{basic_string}% \indexlibrarymember{find_last_of}{basic_string}% \indexlibrarymember{find_first_not_of}{basic_string}% \indexlibrarymember{find_last_not_of}{basic_string}% Let \placeholder{F} be one of \tcode{find}, \tcode{rfind}, \tcode{find_first_of}, \tcode{find_last_of}, \tcode{find_first_not_of}, and \tcode{find_last_not_of}. \begin{itemize} \item Each member function of the form \begin{codeblock} constexpr size_type @\placeholder{F}@(const basic_string& str, size_type pos) const noexcept; \end{codeblock} has effects equivalent to: \tcode{return \placeholder{F}(basic_string_view(str), pos);} \item Each member function of the form \begin{codeblock} constexpr size_type @\placeholder{F}@(const charT* s, size_type pos) const; \end{codeblock} has effects equivalent to: \tcode{return \placeholder{F}(basic_string_view(s), pos);} \item Each member function of the form \begin{codeblock} constexpr size_type @\placeholder{F}@(const charT* s, size_type pos, size_type n) const; \end{codeblock} has effects equivalent to: \tcode{return \placeholder{F}(basic_string_view(s, n), pos);} \item Each member function of the form \begin{codeblock} constexpr size_type @\placeholder{F}@(charT c, size_type pos) const noexcept; \end{codeblock} has effects equivalent to: \begin{codeblock} return @\placeholder{F}@(basic_string_view(addressof(c), 1), pos); \end{codeblock} \end{itemize} \indexlibrarymember{find}{basic_string}% \indexlibrarymember{rfind}{basic_string}% \indexlibrarymember{find_first_of}{basic_string}% \indexlibrarymember{find_last_of}{basic_string}% \indexlibrarymember{find_first_not_of}{basic_string}% \indexlibrarymember{find_last_not_of}{basic_string}% \begin{itemdecl} template constexpr size_type find(const T& t, size_type pos = 0) const noexcept(@\seebelow@); template constexpr size_type rfind(const T& t, size_type pos = npos) const noexcept(@\seebelow@); template constexpr size_type find_first_of(const T& t, size_type pos = 0) const noexcept(@\seebelow@); template constexpr size_type find_last_of(const T& t, size_type pos = npos) const noexcept(@\seebelow@); template constexpr size_type find_first_not_of(const T& t, size_type pos = 0) const noexcept(@\seebelow@); template constexpr size_type find_last_not_of(const T& t, size_type pos = npos) const noexcept(@\seebelow@); \end{itemdecl} \begin{itemdescr} \pnum \constraints \begin{itemize} \item \tcode{is_convertible_v>} is \tcode{true} and \item \tcode{is_convertible_v} is \tcode{false}. \end{itemize} \pnum \effects Let \placeholder{G} be the name of the function. Equivalent to: \begin{codeblock} basic_string_view s = *this, sv = t; return s.@\placeholder{G}@(sv, pos); \end{codeblock} \pnum \remarks The exception specification is equivalent to \tcode{is_nothrow_convertible_v>}. \end{itemdescr} \rSec4[string.substr]{\tcode{basic_string::substr}} \indexlibrarymember{substr}{basic_string}% \begin{itemdecl} constexpr basic_string substr(size_type pos = 0, size_type n = npos) const &; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return basic_string(*this, pos, n);} \end{itemdescr} \indexlibrarymember{substr}{basic_string}% \begin{itemdecl} constexpr basic_string substr(size_type pos = 0, size_type n = npos) &&; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return basic_string(std::move(*this), pos, n);} \end{itemdescr} \indexlibrarymember{subview}{basic_string}% \begin{itemdecl} constexpr basic_string_view subview(size_type pos = 0, size_type n = npos) const; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return basic_string_view(*this).subview(pos, n);} \end{itemdescr} \rSec4[string.compare]{\tcode{basic_string::compare}} \indexlibrarymember{compare}{basic_string}% \begin{itemdecl} template constexpr int compare(const T& t) const noexcept(@\seebelow@); \end{itemdecl} \begin{itemdescr} \pnum \constraints \begin{itemize} \item \tcode{is_convertible_v>} is \tcode{true} and \item \tcode{is_convertible_v} is \tcode{false}. \end{itemize} \pnum \effects Equivalent to: \tcode{return basic_string_view(*this).compare(t);} \pnum \remarks The exception specification is equivalent to \tcode{is_nothrow_convertible_v>}. \end{itemdescr} \indexlibrarymember{compare}{basic_string}% \begin{itemdecl} template constexpr int compare(size_type pos1, size_type n1, const T& t) const; \end{itemdecl} \begin{itemdescr} \pnum \constraints \begin{itemize} \item \tcode{is_convertible_v>} is \tcode{true} and \item \tcode{is_convertible_v} is \tcode{false}. \end{itemize} \pnum \effects Equivalent to: \begin{codeblock} return basic_string_view(*this).substr(pos1, n1).compare(t); \end{codeblock} \end{itemdescr} \indexlibrarymember{compare}{basic_string}% \begin{itemdecl} template constexpr int compare(size_type pos1, size_type n1, const T& t, size_type pos2, size_type n2 = npos) const; \end{itemdecl} \begin{itemdescr} \pnum \constraints \begin{itemize} \item \tcode{is_convertible_v>} is \tcode{true} and \item \tcode{is_convertible_v} is \tcode{false}. \end{itemize} \pnum \effects Equivalent to: \begin{codeblock} basic_string_view s = *this, sv = t; return s.substr(pos1, n1).compare(sv.substr(pos2, n2)); \end{codeblock} \end{itemdescr} \indexlibrarymember{compare}{basic_string}% \begin{itemdecl} constexpr int compare(const basic_string& str) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return compare(basic_string_view(str));} \end{itemdescr} \indexlibrarymember{compare}{basic_string}% \begin{itemdecl} constexpr int compare(size_type pos1, size_type n1, const basic_string& str) const; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return compare(pos1, n1, basic_string_view(str));} \end{itemdescr} \indexlibrarymember{compare}{basic_string}% \begin{itemdecl} constexpr int compare(size_type pos1, size_type n1, const basic_string& str, size_type pos2, size_type n2 = npos) const; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} return compare(pos1, n1, basic_string_view(str), pos2, n2); \end{codeblock} \end{itemdescr} \indexlibrarymember{compare}{basic_string}% \begin{itemdecl} constexpr int compare(const charT* s) const; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return compare(basic_string_view(s));} \end{itemdescr} \indexlibrarymember{compare}{basic_string}% \begin{itemdecl} constexpr int compare(size_type pos, size_type n1, const charT* s) const; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return compare(pos, n1, basic_string_view(s));} \end{itemdescr} \indexlibrarymember{compare}{basic_string}% \begin{itemdecl} constexpr int compare(size_type pos, size_type n1, const charT* s, size_type n2) const; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return compare(pos, n1, basic_string_view(s, n2));} \end{itemdescr} \rSec4[string.starts.with]{\tcode{basic_string::starts_with}} \indexlibrarymember{starts_with}{basic_string}% \begin{itemdecl} constexpr bool starts_with(basic_string_view x) const noexcept; constexpr bool starts_with(charT x) const noexcept; constexpr bool starts_with(const charT* x) const; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} return basic_string_view(data(), size()).starts_with(x); \end{codeblock} \end{itemdescr} \rSec4[string.ends.with]{\tcode{basic_string::ends_with}} \indexlibrarymember{ends_with}{basic_string}% \begin{itemdecl} constexpr bool ends_with(basic_string_view x) const noexcept; constexpr bool ends_with(charT x) const noexcept; constexpr bool ends_with(const charT* x) const; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} return basic_string_view(data(), size()).ends_with(x); \end{codeblock} \end{itemdescr} \rSec4[string.contains]{\tcode{basic_string::contains}} \indexlibrarymember{contains}{basic_string}% \begin{itemdecl} constexpr bool contains(basic_string_view x) const noexcept; constexpr bool contains(charT x) const noexcept; constexpr bool contains(const charT* x) const; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} return basic_string_view(data(), size()).contains(x); \end{codeblock} \end{itemdescr} \rSec2[string.nonmembers]{Non-member functions} \indexlibraryglobal{basic_string} \rSec3[string.op.plus]{\tcode{operator+}} \indexlibrarymember{operator+}{basic_string}% \begin{itemdecl} template constexpr basic_string operator+(const basic_string& lhs, const basic_string& rhs); template constexpr basic_string operator+(const basic_string& lhs, const charT* rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} basic_string r = lhs; r.append(rhs); return r; \end{codeblock} \end{itemdescr} \indexlibrarymember{operator+}{basic_string}% \begin{itemdecl} template constexpr basic_string operator+(basic_string&& lhs, const basic_string& rhs); template constexpr basic_string operator+(basic_string&& lhs, const charT* rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} lhs.append(rhs); return std::move(lhs); \end{codeblock} \end{itemdescr} \indexlibrarymember{operator+}{basic_string}% \begin{itemdecl} template constexpr basic_string operator+(basic_string&& lhs, basic_string&& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} lhs.append(rhs); return std::move(lhs); \end{codeblock} except that both \tcode{lhs} and \tcode{rhs} are left in valid but unspecified states. \begin{note} If \tcode{lhs} and \tcode{rhs} have equal allocators, the implementation can move from either. \end{note} \end{itemdescr} \indexlibrarymember{operator+}{basic_string}% \begin{itemdecl} template constexpr basic_string operator+(const basic_string& lhs, basic_string&& rhs); template constexpr basic_string operator+(const charT* lhs, basic_string&& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} rhs.insert(0, lhs); return std::move(rhs); \end{codeblock} \end{itemdescr} \indexlibrarymember{operator+}{basic_string}% \begin{itemdecl} template constexpr basic_string operator+(const charT* lhs, const basic_string& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} basic_string r = rhs; r.insert(0, lhs); return r; \end{codeblock} \end{itemdescr} \indexlibrarymember{operator+}{basic_string}% \begin{itemdecl} template constexpr basic_string operator+(charT lhs, const basic_string& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} basic_string r = rhs; r.insert(r.begin(), lhs); return r; \end{codeblock} \end{itemdescr} \indexlibrarymember{operator+}{basic_string}% \begin{itemdecl} template constexpr basic_string operator+(charT lhs, basic_string&& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} rhs.insert(rhs.begin(), lhs); return std::move(rhs); \end{codeblock} \end{itemdescr} \indexlibrarymember{operator+}{basic_string}% \begin{itemdecl} template constexpr basic_string operator+(const basic_string& lhs, charT rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} basic_string r = lhs; r.push_back(rhs); return r; \end{codeblock} \end{itemdescr} \indexlibrarymember{operator+}{basic_string}% \begin{itemdecl} template constexpr basic_string operator+(basic_string&& lhs, charT rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} lhs.push_back(rhs); return std::move(lhs); \end{codeblock} \end{itemdescr} \indexlibrarymember{operator+}{basic_string}% \begin{itemdecl} template constexpr basic_string operator+(const basic_string& lhs, type_identity_t> rhs); \end{itemdecl} \begin{itemdescr} \pnum Equivalent to: \begin{codeblock} basic_string r = lhs; r.append(rhs); return r; \end{codeblock} \end{itemdescr} \indexlibrarymember{operator+}{basic_string}% \begin{itemdecl} template constexpr basic_string operator+(basic_string&& lhs, type_identity_t> rhs); \end{itemdecl} \begin{itemdescr} \pnum Equivalent to: \begin{codeblock} lhs.append(rhs); return std::move(lhs); \end{codeblock} \end{itemdescr} \indexlibrarymember{operator+}{basic_string}% \begin{itemdecl} template constexpr basic_string operator+(type_identity_t> lhs, const basic_string& rhs); \end{itemdecl} \begin{itemdescr} \pnum Equivalent to: \begin{codeblock} basic_string r = rhs; r.insert(0, lhs); return r; \end{codeblock} \end{itemdescr} \indexlibrarymember{operator+}{basic_string}% \begin{itemdecl} template constexpr basic_string operator+(type_identity_t> lhs, basic_string&& rhs); \end{itemdecl} \begin{itemdescr} \pnum Equivalent to: \begin{codeblock} rhs.insert(0, lhs); return std::move(rhs); \end{codeblock} \end{itemdescr} \pnum \begin{note} Using a specialization of \tcode{type_identity_t} as a parameter type ensures that an object of type \tcode{basic_string} can be concatenated with an object of a type \tcode{T} having an implicit conversion to \tcode{basic_string_view}\iref{over.match.oper}. \end{note} \rSec3[string.cmp]{Non-member comparison operator functions} \begin{itemdecl} template constexpr bool operator==(const basic_string& lhs, const basic_string& rhs) noexcept; template constexpr bool operator==(const basic_string& lhs, const charT* rhs); template constexpr @\seebelow@ operator<=>(const basic_string& lhs, @\itcorr@ const basic_string& rhs) noexcept; template constexpr @\seebelow@ operator<=>(const basic_string& lhs, @\itcorr@ const charT* rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Let \tcode{\placeholder{op}} be the operator. Equivalent to: \begin{codeblock} return basic_string_view(lhs) @\placeholder{op}@ basic_string_view(rhs); \end{codeblock} \end{itemdescr} \rSec3[string.special]{\tcode{swap}} \indexlibrarymember{swap}{basic_string}% \begin{itemdecl} template constexpr void swap(basic_string& lhs, basic_string& rhs) noexcept(noexcept(lhs.swap(rhs))); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{lhs.swap(rhs)}. \end{itemdescr} \rSec3[string.io]{Inserters and extractors} \indexlibrarymember{operator>>}{basic_string}% \begin{itemdecl} template basic_istream& operator>>(basic_istream& is, basic_string& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves as a formatted input function\iref{istream.formatted.reqmts}. After constructing a \tcode{sentry} object, if the \tcode{sentry} object returns \tcode{true} when converted to a value of type \tcode{bool}, calls \tcode{str.erase()} and then extracts characters from \tcode{is} and appends them to \tcode{str} as if by calling \tcode{str.append(1, c)}. If \tcode{is.width()} is greater than zero, the maximum number \tcode{n} of characters appended is \tcode{is.width()}; otherwise \tcode{n} is \tcode{str.max_size()}. Characters are extracted and appended until any of the following occurs: \begin{itemize} \item \textit{n} characters are stored; \item end-of-file occurs on the input sequence; \item \tcode{isspace(c, is.getloc())} is \tcode{true} for the next available input character \textit{c}. \end{itemize} \pnum After the last character (if any) is extracted, \tcode{is.width(0)} is called and the \tcode{sentry} object is destroyed. \pnum If the function extracts no characters, \tcode{ios_base::failbit} is set in the input function's local error state before \tcode{setstate} is called. \pnum \returns \tcode{is}. \end{itemdescr} \indexlibrarymember{operator<<}{basic_string}% \begin{itemdecl} template basic_ostream& operator<<(basic_ostream& os, const basic_string& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return os << basic_string_view(str);} \end{itemdescr} \indexlibrarymember{getline}{basic_string}% \begin{itemdecl} template basic_istream& getline(basic_istream& is, basic_string& str, charT delim); template basic_istream& getline(basic_istream&& is, basic_string& str, charT delim); \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves as an unformatted input function\iref{istream.unformatted}, except that it does not affect the value returned by subsequent calls to \tcode{basic_istream<>::gcount()}. After constructing a \tcode{sentry} object, if the \tcode{sentry} object returns \tcode{true} when converted to a value of type \tcode{bool}, calls \tcode{str.erase()} and then extracts characters from \tcode{is} and appends them to \tcode{str} as if by calling \tcode{str.append(1, c)} until any of the following occurs: \begin{itemize} \item end-of-file occurs on the input sequence; \item \tcode{traits::eq(c, delim)} for the next available input character \textit{c} (in which case, \textit{c} is extracted but not appended); \item \tcode{str.max_size()} characters are stored (in which case, \tcode{ios_base::failbit} is set in the input function's local error state). \end{itemize} \pnum The conditions are tested in the order shown. In any case, after the last character is extracted, the \tcode{sentry} object is destroyed. \pnum If the function extracts no characters, \tcode{ios_base::failbit} is set in the input function's local error state before \tcode{setstate} is called. \pnum \returns \tcode{is}. \end{itemdescr} \indexlibrarymember{getline}{basic_string}% \begin{itemdecl} template basic_istream& getline(basic_istream& is, basic_string& str); template basic_istream& getline(basic_istream&& is, basic_string& str); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{getline(is, str, is.widen('\textbackslash n'))}. \end{itemdescr} \rSec3[string.erasure]{Erasure} \indexlibrarymember{erase}{basic_string}% \begin{itemdecl} template constexpr typename basic_string::size_type erase(basic_string& c, const U& value); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} auto it = remove(c.begin(), c.end(), value); auto r = distance(it, c.end()); c.erase(it, c.end()); return r; \end{codeblock} \end{itemdescr} \indexlibrarymember{erase_if}{basic_string}% \begin{itemdecl} template constexpr typename basic_string::size_type erase_if(basic_string& c, Predicate pred); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} auto it = remove_if(c.begin(), c.end(), pred); auto r = distance(it, c.end()); c.erase(it, c.end()); return r; \end{codeblock} \end{itemdescr} \rSec2[string.conversions]{Numeric conversions} \indexlibraryglobal{stoi}% \indexlibraryglobal{stol}% \indexlibraryglobal{stoul}% \indexlibraryglobal{stoll}% \indexlibraryglobal{stoull}% \begin{itemdecl} int stoi(const string& str, size_t* idx = nullptr, int base = 10); long stol(const string& str, size_t* idx = nullptr, int base = 10); unsigned long stoul(const string& str, size_t* idx = nullptr, int base = 10); long long stoll(const string& str, size_t* idx = nullptr, int base = 10); unsigned long long stoull(const string& str, size_t* idx = nullptr, int base = 10); \end{itemdecl} \begin{itemdescr} \pnum \effects The first two functions call \tcode{strtol(str.c_str(), ptr, base)}, and the last three functions call \tcode{strtoul(str.c_str(), ptr, base)}, \tcode{strtoll(str.c_str(), ptr, base)}, and \tcode{strtoull(\brk{}str.c_str(), ptr, base)}, respectively. Each function returns the converted result, if any. The argument \tcode{ptr} designates a pointer to an object internal to the function that is used to determine what to store at \tcode{*idx}. If the function does not throw an exception and \tcode{idx != nullptr}, the function stores in \tcode{*idx} the index of the first unconverted element of \tcode{str}. \pnum \returns The converted result. \pnum \throws \tcode{invalid_argument} if \tcode{strtol}, \tcode{strtoul}, \tcode{strtoll}, or \tcode{strtoull} reports that no conversion can be performed. Throws \tcode{out_of_range} if \tcode{strtol}, \tcode{strtoul}, \tcode{strtoll} or \tcode{strtoull} sets \tcode{errno} to \tcode{ERANGE}, or if the converted value is outside the range of representable values for the return type. \end{itemdescr} \indexlibraryglobal{stof}% \indexlibraryglobal{stod}% \indexlibraryglobal{stold}% \begin{itemdecl} float stof(const string& str, size_t* idx = nullptr); double stod(const string& str, size_t* idx = nullptr); long double stold(const string& str, size_t* idx = nullptr); \end{itemdecl} \begin{itemdescr} \pnum \effects These functions call \tcode{strtof(str.c_str(), ptr)}, \tcode{strtod(str.c_str(), ptr)}, and \tcode{strtold(\brk{}str.c_str(), ptr)}, respectively. Each function returns the converted result, if any. The argument \tcode{ptr} designates a pointer to an object internal to the function that is used to determine what to store at \tcode{*idx}. If the function does not throw an exception and \tcode{idx != nullptr}, the function stores in \tcode{*idx} the index of the first unconverted element of \tcode{str}. \pnum \returns The converted result. \pnum \throws \tcode{invalid_argument} if \tcode{strtof}, \tcode{strtod}, or \tcode{strtold} reports that no conversion can be performed. Throws \tcode{out_of_range} if \tcode{strtof}, \tcode{strtod}, or \tcode{strtold} sets \tcode{errno} to \tcode{ERANGE} or if the converted value is outside the range of representable values for the return type. \end{itemdescr} \indexlibraryglobal{to_string}% \begin{itemdecl} string to_string(int val); string to_string(unsigned val); string to_string(long val); string to_string(unsigned long val); string to_string(long long val); string to_string(unsigned long long val); string to_string(float val); string to_string(double val); string to_string(long double val); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{format("\{\}", val)}. \end{itemdescr} \indexlibraryglobal{stoi}% \indexlibraryglobal{stol}% \indexlibraryglobal{stoul}% \indexlibraryglobal{stoll}% \indexlibraryglobal{stoull}% \begin{itemdecl} int stoi(const wstring& str, size_t* idx = nullptr, int base = 10); long stol(const wstring& str, size_t* idx = nullptr, int base = 10); unsigned long stoul(const wstring& str, size_t* idx = nullptr, int base = 10); long long stoll(const wstring& str, size_t* idx = nullptr, int base = 10); unsigned long long stoull(const wstring& str, size_t* idx = nullptr, int base = 10); \end{itemdecl} \begin{itemdescr} \pnum \effects The first two functions call \tcode{wcstol(str.c_str(), ptr, base)}, and the last three functions call \tcode{wcstoul(str.c_str(), ptr, base)}, \tcode{wcstoll(str.c_str(), ptr, base)}, and \tcode{wcstoull(\brk{}str.c_str(), ptr, base)}, respectively. Each function returns the converted result, if any. The argument \tcode{ptr} designates a pointer to an object internal to the function that is used to determine what to store at \tcode{*idx}. If the function does not throw an exception and \tcode{idx != nullptr}, the function stores in \tcode{*idx} the index of the first unconverted element of \tcode{str}. \pnum \returns The converted result. \pnum \throws \tcode{invalid_argument} if \tcode{wcstol}, \tcode{wcstoul}, \tcode{wcstoll}, or \tcode{wcstoull} reports that no conversion can be performed. Throws \tcode{out_of_range} if the converted value is outside the range of representable values for the return type. \end{itemdescr} \indexlibraryglobal{stof}% \indexlibraryglobal{stod}% \indexlibraryglobal{stold}% \begin{itemdecl} float stof(const wstring& str, size_t* idx = nullptr); double stod(const wstring& str, size_t* idx = nullptr); long double stold(const wstring& str, size_t* idx = nullptr); \end{itemdecl} \begin{itemdescr} \pnum \effects These functions call \tcode{wcstof(str.c_str(), ptr)}, \tcode{wcstod(str.c_str(), ptr)}, and \tcode{wcstold(\brk{}str.c_str(), ptr)}, respectively. Each function returns the converted result, if any. The argument \tcode{ptr} designates a pointer to an object internal to the function that is used to determine what to store at \tcode{*idx}. If the function does not throw an exception and \tcode{idx != nullptr}, the function stores in \tcode{*idx} the index of the first unconverted element of \tcode{str}. \pnum \returns The converted result. \pnum \throws \tcode{invalid_argument} if \tcode{wcstof}, \tcode{wcstod}, or \tcode{wcstold} reports that no conversion can be performed. Throws \tcode{out_of_range} if \tcode{wcstof}, \tcode{wcstod}, or \tcode{wcstold} sets \tcode{errno} to \tcode{ERANGE}. \end{itemdescr} \indexlibraryglobal{to_wstring}% \begin{itemdecl} wstring to_wstring(int val); wstring to_wstring(unsigned val); wstring to_wstring(long val); wstring to_wstring(unsigned long val); wstring to_wstring(long long val); wstring to_wstring(unsigned long long val); wstring to_wstring(float val); wstring to_wstring(double val); wstring to_wstring(long double val); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{format(L"\{\}", val)}. \end{itemdescr} \rSec2[basic.string.hash]{Hash support} \indexlibrarymember{hash}{basic_string}% \begin{itemdecl} template struct hash, A>>; template struct hash, A>>; template struct hash, A>>; template struct hash, A>>; template struct hash, A>>; \end{itemdecl} \begin{itemdescr} \pnum If \tcode{S} is one of these string types, \tcode{SV} is the corresponding string view type, and \tcode{s} is an object of type \tcode{S}, then \tcode{hash()(s) == hash()(SV(s))}. \end{itemdescr} \rSec2[basic.string.literals]{Suffix for \tcode{basic_string} literals} \indexlibrarymember{operator""""s}{string}% \begin{itemdecl} constexpr string operator""s(const char* str, size_t len); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{string\{str, len\}}. \end{itemdescr} \indexlibrarymember{operator""""s}{u8string}% \begin{itemdecl} constexpr u8string operator""s(const char8_t* str, size_t len); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{u8string\{str, len\}}. \end{itemdescr} \indexlibrarymember{operator""""s}{u16string}% \begin{itemdecl} constexpr u16string operator""s(const char16_t* str, size_t len); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{u16string\{str, len\}}. \end{itemdescr} \indexlibrarymember{operator""""s}{u32string}% \begin{itemdecl} constexpr u32string operator""s(const char32_t* str, size_t len); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{u32string\{str, len\}}. \end{itemdescr} \indexlibrarymember{operator""""s}{wstring}% \begin{itemdecl} constexpr wstring operator""s(const wchar_t* str, size_t len); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{wstring\{str, len\}}. \end{itemdescr} \pnum \begin{note} The same suffix \tcode{s} is used for \tcode{chrono::duration} literals denoting seconds but there is no conflict, since duration suffixes apply to numbers and string literal suffixes apply to character array literals. \end{note} \rSec1[c.strings]{Null-terminated sequence utilities} \rSec2[cstring.syn]{Header \tcode{} synopsis} \indexlibraryglobal{memchr}% \indexlibraryglobal{memcmp}% \indexlibraryglobal{memcpy}% \indexlibraryglobal{memmove}% \indexlibraryglobal{memset}% \indexlibraryglobal{size_t}% \indexlibraryglobal{strcat}% \indexlibraryglobal{strchr}% \indexlibraryglobal{strcmp}% \indexlibraryglobal{strcoll}% \indexlibraryglobal{strcpy}% \indexlibraryglobal{strcspn}% \indexlibraryglobal{strerror}% \indexlibraryglobal{strlen}% \indexlibraryglobal{strncat}% \indexlibraryglobal{strncmp}% \indexlibraryglobal{strncpy}% \indexlibraryglobal{strpbrk}% \indexlibraryglobal{strrchr}% \indexlibraryglobal{strspn}% \indexlibraryglobal{strstr}% \indexlibraryglobal{strtok}% \indexlibraryglobal{strxfrm}% \begin{codeblock} #define __STDC_VERSION_STRING_H__ 202311L namespace std { using size_t = @\textit{see \ref{support.types.layout}}@; // freestanding void* memcpy(void* s1, const void* s2, size_t n); // freestanding void* memccpy(void* s1, const void* s2, int c, size_t n); // freestanding void* memmove(void* s1, const void* s2, size_t n); // freestanding char* strcpy(char* s1, const char* s2); // freestanding char* strncpy(char* s1, const char* s2, size_t n); // freestanding char* strdup(const char* s); char* strndup(const char* s, size_t size); char* strcat(char* s1, const char* s2); // freestanding char* strncat(char* s1, const char* s2, size_t n); // freestanding int memcmp(const void* s1, const void* s2, size_t n); // freestanding int strcmp(const char* s1, const char* s2); // freestanding int strcoll(const char* s1, const char* s2); int strncmp(const char* s1, const char* s2, size_t n); // freestanding size_t strxfrm(char* s1, const char* s2, size_t n); const void* memchr(const void* s, int c, size_t n); // freestanding; see \ref{library.c} void* memchr(void* s, int c, size_t n); // freestanding; see \ref{library.c} const char* strchr(const char* s, int c); // freestanding; see \ref{library.c} char* strchr(char* s, int c); // freestanding; see \ref{library.c} size_t strcspn(const char* s1, const char* s2); // freestanding const char* strpbrk(const char* s1, const char* s2); // freestanding; see \ref{library.c} char* strpbrk(char* s1, const char* s2); // freestanding; see \ref{library.c} const char* strrchr(const char* s, int c); // freestanding; see \ref{library.c} char* strrchr(char* s, int c); // freestanding; see \ref{library.c} size_t strspn(const char* s1, const char* s2); // freestanding const char* strstr(const char* s1, const char* s2); // freestanding; see \ref{library.c} char* strstr(char* s1, const char* s2); // freestanding; see \ref{library.c} char* strtok(char* s1, const char* s2); void* memset(void* s, int c, size_t n); // freestanding void* memset_explicit(void* s, int c, size_t n); // freestanding char* strerror(int errnum); size_t strlen(const char* s); // freestanding } #define NULL @\textit{see \ref{support.types.nullptr}}@ // freestanding \end{codeblock} \pnum The contents and meaning of the header \libheaderdef{cstring} are the same as the C standard library header \libheader{string.h}. \pnum The functions \tcode{strerror} and \tcode{strtok} are not required to avoid data races\iref{res.on.data.races}. \pnum \indextext{signal-safe!\idxcode{memcpy}}% \indextext{signal-safe!\idxcode{memmove}}% The functions \tcode{memcpy} and \tcode{memmove} are signal-safe\iref{support.signal}. Each of these functions implicitly creates objects\iref{intro.object} in the destination region of storage immediately prior to copying the sequence of characters to the destination. Each of these functions returns a pointer to a suitable created object, if any, otherwise the value of the first parameter. \pnum \begin{note} The functions \tcode{strchr}, \tcode{strpbrk}, \tcode{strrchr}, \tcode{strstr}, and \tcode{memchr}, have different signatures in this document, but they have the same behavior as in the C standard library\iref{library.c}. \end{note} \xrefc{7.26}