[string.classes]

# 27 Strings library [[strings]](./#strings)

## 27.4 String classes [string.classes]

### [27.4.1](#general) General [[string.classes.general]](string.classes.general)

[1](#general-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L1754)

The header <string> defines thebasic_string class template for manipulating
varying-length sequences of char-like objects and five[*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]")*s*, string,u8string,u16string,u32string,
and wstring, that name
the specializationsbasic_string<char>,basic_string<char8_t>,basic_string<char16_t>,basic_string<char32_t>,
andbasic_string<​wchar_t>, respectively[.](#general-1.sentence-1)

### [27.4.2](#string.syn) Header <string> synopsis [[string.syn]](string.syn)

#include <compare> // see [[compare.syn]](compare.syn "17.12.1 Header <compare> synopsis")#include <initializer_list> // see [[initializer.list.syn]](initializer.list.syn "17.11.2 Header <initializer_­list> synopsis")namespace std {// [[char.traits]](char.traits "27.2 Character traits"), character traitstemplate<class charT> struct char_traits; // freestandingtemplate<> struct char_traits<char>; // freestandingtemplate<> struct char_traits<char8_t>; // freestandingtemplate<> struct char_traits<char16_t>; // freestandingtemplate<> struct char_traits<char32_t>; // freestandingtemplate<> struct char_traits<wchar_t>; // freestanding// [[basic.string]](#basic.string "27.4.3 Class template basic_­string"), basic_stringtemplate<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>class basic_string; template<class charT, class traits, class Allocator>constexpr basic_string<charT, traits, Allocator>operator+(const basic_string<charT, traits, Allocator>& lhs, const basic_string<charT, traits, Allocator>& rhs); template<class charT, class traits, class Allocator>constexpr basic_string<charT, traits, Allocator>operator+(basic_string<charT, traits, Allocator>&& lhs, const basic_string<charT, traits, Allocator>& rhs); template<class charT, class traits, class Allocator>constexpr basic_string<charT, traits, Allocator>operator+(const basic_string<charT, traits, Allocator>& lhs,
 basic_string<charT, traits, Allocator>&& rhs); template<class charT, class traits, class Allocator>constexpr basic_string<charT, traits, Allocator>operator+(basic_string<charT, traits, Allocator>&& lhs,
 basic_string<charT, traits, Allocator>&& rhs); template<class charT, class traits, class Allocator>constexpr basic_string<charT, traits, Allocator>operator+(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs); template<class charT, class traits, class Allocator>constexpr basic_string<charT, traits, Allocator>operator+(const charT* lhs,
 basic_string<charT, traits, Allocator>&& rhs); template<class charT, class traits, class Allocator>constexpr basic_string<charT, traits, Allocator>operator+(charT lhs, const basic_string<charT, traits, Allocator>& rhs); template<class charT, class traits, class Allocator>constexpr basic_string<charT, traits, Allocator>operator+(charT lhs,
 basic_string<charT, traits, Allocator>&& rhs); template<class charT, class traits, class Allocator>constexpr basic_string<charT, traits, Allocator>operator+(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs); template<class charT, class traits, class Allocator>constexpr basic_string<charT, traits, Allocator>operator+(basic_string<charT, traits, Allocator>&& lhs, const charT* rhs); template<class charT, class traits, class Allocator>constexpr basic_string<charT, traits, Allocator>operator+(const basic_string<charT, traits, Allocator>& lhs,
 charT rhs); template<class charT, class traits, class Allocator>constexpr basic_string<charT, traits, Allocator>operator+(basic_string<charT, traits, Allocator>&& lhs,
 charT rhs); template<class charT, class traits, class Allocator>constexpr basic_string<charT, traits, Allocator>operator+(const basic_string<charT, traits, Allocator>& lhs,
 type_identity_t<basic_string_view<charT, traits>> rhs); template<class charT, class traits, class Allocator>constexpr basic_string<charT, traits, Allocator>operator+(basic_string<charT, traits, Allocator>&& lhs,
 type_identity_t<basic_string_view<charT, traits>> rhs); template<class charT, class traits, class Allocator>constexpr basic_string<charT, traits, Allocator>operator+(type_identity_t<basic_string_view<charT, traits>> lhs, const basic_string<charT, traits, Allocator>& rhs); template<class charT, class traits, class Allocator>constexpr basic_string<charT, traits, Allocator>operator+(type_identity_t<basic_string_view<charT, traits>> lhs,
 basic_string<charT, traits, Allocator>&& rhs); template<class charT, class traits, class Allocator>constexpr booloperator==(const basic_string<charT, traits, Allocator>& lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; template<class charT, class traits, class Allocator>constexpr bool operator==(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs); template<class charT, class traits, class Allocator>constexpr *see below* operator<=>(const basic_string<charT, traits, Allocator>& lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; template<class charT, class traits, class Allocator>constexpr *see below* operator<=>(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs); // [[string.special]](#string.special "27.4.4.3 swap"), swaptemplate<class charT, class traits, class Allocator>constexpr void swap(basic_string<charT, traits, Allocator>& lhs,
 basic_string<charT, traits, Allocator>& rhs)noexcept(noexcept(lhs.swap(rhs))); // [[string.io]](#string.io "27.4.4.4 Inserters and extractors"), inserters and extractorstemplate<class charT, class traits, class Allocator> basic_istream<charT, traits>&operator>>(basic_istream<charT, traits>& is,
 basic_string<charT, traits, Allocator>& str); template<class charT, class traits, class Allocator> basic_ostream<charT, traits>&operator<<(basic_ostream<charT, traits>& os, const basic_string<charT, traits, Allocator>& str); template<class charT, class traits, class Allocator> basic_istream<charT, traits>& getline(basic_istream<charT, traits>& is,
 basic_string<charT, traits, Allocator>& str,
 charT delim); template<class charT, class traits, class Allocator> basic_istream<charT, traits>& getline(basic_istream<charT, traits>&& is,
 basic_string<charT, traits, Allocator>& str,
 charT delim); template<class charT, class traits, class Allocator> basic_istream<charT, traits>& getline(basic_istream<charT, traits>& is,
 basic_string<charT, traits, Allocator>& str); template<class charT, class traits, class Allocator> basic_istream<charT, traits>& getline(basic_istream<charT, traits>&& is,
 basic_string<charT, traits, Allocator>& str); // [[string.erasure]](#string.erasure "27.4.4.5 Erasure"), erasuretemplate<class charT, class traits, class Allocator, class U = charT>constexpr typename basic_string<charT, traits, Allocator>::size_type
 erase(basic_string<charT, traits, Allocator>& c, const U& value); template<class charT, class traits, class Allocator, class Predicate>constexpr typename basic_string<charT, traits, Allocator>::size_type
 erase_if(basic_string<charT, traits, Allocator>& c, Predicate pred); // basic_string [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]")*s*using [string](#lib:string "27.4.2 Header <string> synopsis [string.syn]") = basic_string<char>; using [u8string](#lib:u8string "27.4.2 Header <string> synopsis [string.syn]") = basic_string<char8_t>; using [u16string](#lib:u16string "27.4.2 Header <string> synopsis [string.syn]") = basic_string<char16_t>; using [u32string](#lib:u32string "27.4.2 Header <string> synopsis [string.syn]") = basic_string<char32_t>; using [wstring](#lib:wstring "27.4.2 Header <string> synopsis [string.syn]") = basic_string<wchar_t>; // [[string.conversions]](#string.conversions "27.4.5 Numeric conversions"), numeric conversionsint 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<class charT, class traits = char_traits<charT>>using basic_string = std::basic_string<charT, traits, polymorphic_allocator<charT>>; using string = basic_string<char>; using u8string = basic_string<char8_t>; using u16string = basic_string<char16_t>; using u32string = basic_string<char32_t>; using wstring = basic_string<wchar_t>; }// [[basic.string.hash]](#basic.string.hash "27.4.6 Hash support"), hash supporttemplate<class T> struct hash; template<class A> struct hash<basic_string<char, char_traits<char>, A>>; template<class A> struct hash<basic_string<char8_t, char_traits<char8_t>, A>>; template<class A> struct hash<basic_string<char16_t, char_traits<char16_t>, A>>; template<class A> struct hash<basic_string<char32_t, char_traits<char32_t>, A>>; template<class A> struct hash<basic_string<wchar_t, char_traits<wchar_t>, A>>; inline namespace literals {inline namespace string_literals {// [[basic.string.literals]](#basic.string.literals "27.4.7 Suffix for basic_­string literals"), suffix for basic_string literalsconstexpr 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); }}}

### [27.4.3](#basic.string) Class template basic_string [[basic.string]](basic.string)

#### [27.4.3.1](#basic.string.general) General [[basic.string.general]](basic.string.general)

[1](#basic.string.general-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L1994)

The
class templatebasic_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[.](#basic.string.general-1.sentence-1)

Such a sequence is also called a âstringâ if the type of the
char-like objects that it holds
is clear from context[.](#basic.string.general-1.sentence-2)

In the rest of [[basic.string]](#basic.string "27.4.3 Class template basic_­string"),
the type of the char-like objects held in a basic_string object
is designated by charT[.](#basic.string.general-1.sentence-3)

[2](#basic.string.general-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2008)

A specialization of basic_string is a contiguous container ([[container.reqmts]](container.reqmts "23.2.2.2 Container requirements"))[.](#basic.string.general-2.sentence-1)

[3](#basic.string.general-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2011)

In all cases,
[data(), data() + size()] is a valid range,data() + size() points at an object with value charT() (a ânull terminatorâ),
and size() <= capacity() is true[.](#basic.string.general-3.sentence-1)

[ð](#lib:basic_string_)

namespace std {template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>class basic_string {public:// typesusing traits_type = traits; using value_type = charT; using allocator_type = Allocator; using size_type = typename allocator_traits<Allocator>::size_type; using difference_type = typename allocator_traits<Allocator>::difference_type; using pointer = typename allocator_traits<Allocator>::pointer; using const_pointer = typename allocator_traits<Allocator>::const_pointer; using reference = value_type&; using const_reference = const value_type&; using iterator = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2 Requirements")using const_iterator = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2 Requirements")using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>; static constexpr size_type npos = size_type(-1); // [[string.cons]](#string.cons "27.4.3.3 Constructors and assignment operators"), construct/copy/destroyconstexpr 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<class T>constexpr basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator()); template<class T>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<class InputIterator>constexpr basic_string(InputIterator begin, InputIterator end, const Allocator& a = Allocator()); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<charT> R>constexpr basic_string(from_range_t, R&& rg, const Allocator& a = Allocator()); constexpr basic_string(initializer_list<charT>, 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<Allocator>::propagate_on_container_move_assignment::value || allocator_traits<Allocator>::is_always_equal::value); template<class T>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<charT>); // [[string.iterators]](#string.iterators "27.4.3.4 Iterator support"), iteratorsconstexpr 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; // [[string.capacity]](#string.capacity "27.4.3.5 Capacity"), capacityconstexpr 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<class Operation> 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; // [[string.access]](#string.access "27.4.3.6 Element access"), element accessconstexpr 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(); // [[string.modifiers]](#string.modifiers "27.4.3.7 Modifiers"), modifiersconstexpr basic_string& operator+=(const basic_string& str); template<class T>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<charT>); constexpr basic_string& append(const basic_string& str); constexpr basic_string& append(const basic_string& str, size_type pos, size_type n = npos); template<class T>constexpr basic_string& append(const T& t); template<class T>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<class InputIterator>constexpr basic_string& append(InputIterator first, InputIterator last); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<charT> R>constexpr basic_string& append_range(R&& rg); constexpr basic_string& append(initializer_list<charT>); constexpr void push_back(charT c); constexpr basic_string& assign(const basic_string& str); constexpr basic_string& assign(basic_string&& str)noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value || allocator_traits<Allocator>::is_always_equal::value); constexpr basic_string& assign(const basic_string& str, size_type pos, size_type n = npos); template<class T>constexpr basic_string& assign(const T& t); template<class T>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<class InputIterator>constexpr basic_string& assign(InputIterator first, InputIterator last); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<charT> R>constexpr basic_string& assign_range(R&& rg); constexpr basic_string& assign(initializer_list<charT>); 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<class T>constexpr basic_string& insert(size_type pos, const T& t); template<class T>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<class InputIterator>constexpr iterator insert(const_iterator p, InputIterator first, InputIterator last); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<charT> R>constexpr iterator insert_range(const_iterator p, R&& rg); constexpr iterator insert(const_iterator p, initializer_list<charT>); 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<class T>constexpr basic_string& replace(size_type pos1, size_type n1, const T& t); template<class T>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<class T>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<class InputIterator>constexpr basic_string& replace(const_iterator i1, const_iterator i2,
 InputIterator j1, InputIterator j2); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<charT> 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<charT>); constexpr size_type copy(charT* s, size_type n, size_type pos = 0) const; constexpr void swap(basic_string& str)noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value || allocator_traits<Allocator>::is_always_equal::value); // [[string.ops]](#string.ops "27.4.3.8 String operations"), string operationsconstexpr const charT* c_str() const noexcept; constexpr const charT* data() const noexcept; constexpr charT* data() noexcept; constexpr operator basic_string_view<charT, traits>() const noexcept; constexpr allocator_type get_allocator() const noexcept; template<class T>constexpr size_type find(const T& t, size_type pos = 0) const noexcept(*see below*); 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<class T>constexpr size_type rfind(const T& t, size_type pos = npos) const noexcept(*see below*); 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<class T>constexpr size_type find_first_of(const T& t, size_type pos = 0) const noexcept(*see below*); 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<class T>constexpr size_type find_last_of(const T& t,
 size_type pos = npos) const noexcept(*see below*); 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<class T>constexpr size_type find_first_not_of(const T& t,
 size_type pos = 0) const noexcept(*see below*); 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<class T>constexpr size_type find_last_not_of(const T& t,
 size_type pos = npos) const noexcept(*see below*); 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<charT, traits> subview(size_type pos = 0,
 size_type n = npos) const; template<class T>constexpr int compare(const T& t) const noexcept(*see below*); template<class T>constexpr int compare(size_type pos1, size_type n1, const T& t) const; template<class T>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<charT, traits> 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<charT, traits> 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<charT, traits> x) const noexcept; constexpr bool contains(charT x) const noexcept; constexpr bool contains(const charT* x) const; }; template<class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>> basic_string(InputIterator, InputIterator, Allocator = Allocator())-> basic_string<typename iterator_traits<InputIterator>::value_type,
 char_traits<typename iterator_traits<InputIterator>::value_type>,
 Allocator>; template<ranges::[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R, class Allocator = allocator<ranges::range_value_t<R>>> basic_string(from_range_t, R&&, Allocator = Allocator())-> basic_string<ranges::range_value_t<R>, char_traits<ranges::range_value_t<R>>,
 Allocator>; template<class charT, class traits, class Allocator = allocator<charT>>explicit basic_string(basic_string_view<charT, traits>, const Allocator& = Allocator())-> basic_string<charT, traits, Allocator>; template<class charT, class traits, class Allocator = allocator<charT>> basic_string(basic_string_view<charT, traits>, typename *see below*::size_type, typename *see below*::size_type, const Allocator& = Allocator())-> basic_string<charT, traits, Allocator>;}

[4](#basic.string.general-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2351)

A size_type parameter type in
a basic_string deduction guide
refers to the size_type member type of
the type deduced by the deduction guide[.](#basic.string.general-4.sentence-1)

[5](#basic.string.general-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2357)

The types iterator and const_iterator meet
the constexpr iterator requirements ([[iterator.requirements.general]](iterator.requirements.general "24.3.1 General"))[.](#basic.string.general-5.sentence-1)

#### [27.4.3.2](#string.require) General requirements [[string.require]](string.require)

[1](#string.require-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2363)

If any operation would cause size() to
exceed max_size(), that operation throws an
exception object of type length_error[.](#string.require-1.sentence-1)

[2](#string.require-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2368)

If any member function or operator of basic_string throws an exception, that
function or operator has no other effect on the basic_string object[.](#string.require-2.sentence-1)

[3](#string.require-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2372)

Every object of typebasic_string<charT, traits, Allocator> uses an object of typeAllocator to allocate and free storage for the contained charT objects as needed[.](#string.require-3.sentence-1)

The Allocator object used is
obtained as described in [[container.reqmts]](container.reqmts "23.2.2.2 Container requirements")[.](#string.require-3.sentence-2)

In every specialization basic_string<charT, traits, Allocator>,
the type traits shall meet
the character traits requirements ([[char.traits]](char.traits "27.2 Character traits"))[.](#string.require-3.sentence-3)

[*Note [1](#string.require-note-1)*:

Every specialization basic_string<charT, traits, Allocator> is
an allocator-aware container ([[container.alloc.reqmts]](container.alloc.reqmts "23.2.2.5 Allocator-aware containers")),
but does not use the allocator's construct and destroy member functions ([[container.requirements.pre]](container.requirements.pre "23.2.1 Preamble"))[.](#string.require-3.sentence-4)

The program is ill-formed ifAllocator​::​value_type is not the same type as charT[.](#string.require-3.sentence-5)

â *end note*]

[*Note [2](#string.require-note-2)*:

The program is ill-formed if traits​::​char_type is not the same type as charT[.](#string.require-3.sentence-6)

â *end note*]

[4](#string.require-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2394)

References, pointers, and iterators referring to the elements of abasic_string sequence may be
invalidated by the following uses of that basic_string object:

- [(4.1)](#string.require-4.1)

  Passing as an argument to any standard library function taking a reference to non-constbasic_string as an argument[.](#string.require-4.1.sentence-1)[212](#footnote-212 "For example, as an argument to non-member functions swap() ([string.special]), operator>>() ([string.io]), and getline() ([string.io]), or as an argument to basic_­string​::​swap().")

- [(4.2)](#string.require-4.2)

  Calling non-const member functions, exceptoperator[],at,data,front,back,begin,rbegin,end,
andrend[.](#string.require-4.2.sentence-1)

[212)](#footnote-212)[212)](#footnoteref-212)

For example, as an argument to non-member
functions swap() ([[string.special]](#string.special "27.4.4.3 swap")),operator>>() ([[string.io]](#string.io "27.4.4.4 Inserters and extractors")), and getline() ([[string.io]](#string.io "27.4.4.4 Inserters and extractors")), or as
an argument to basic_string​::​swap()[.](#footnote-212.sentence-1)

#### [27.4.3.3](#string.cons) Constructors and assignment operators [[string.cons]](string.cons)

[ð](#lib:basic_string,constructor)

`constexpr explicit basic_string(const Allocator& a) noexcept;
`

[1](#string.cons-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2431)

*Postconditions*: size() is equal to 0[.](#string.cons-1.sentence-1)

[ð](#lib:basic_string,constructor_)

`constexpr basic_string(const basic_string& str);
constexpr basic_string(basic_string&& str) noexcept;
`

[2](#string.cons-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2443)

*Effects*: Constructs an object whose
value is that of str prior to this call[.](#string.cons-2.sentence-1)

[3](#string.cons-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2448)

*Remarks*: In the second form, str is left in a valid but unspecified state[.](#string.cons-3.sentence-1)

[ð](#lib:basic_string,constructor__)

`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());
`

[4](#string.cons-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2466)

Let

- [(4.1)](#string.cons-4.1)

s be the value of str prior to this call and

- [(4.2)](#string.cons-4.2)

rlen be pos + min(n, s.size() - pos) for the overloads with parameter n, ands.size() otherwise[.](#string.cons-4.sentence-1)

[5](#string.cons-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2477)

*Effects*: Constructs an object
whose initial value is the range [s.data() + pos, s.data() + rlen)[.](#string.cons-5.sentence-1)

[6](#string.cons-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2482)

*Throws*: out_of_range if pos > s.size()[.](#string.cons-6.sentence-1)

[7](#string.cons-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2486)

*Remarks*: For the overloads with a basic_string&& parameter,str is left in a valid but unspecified state[.](#string.cons-7.sentence-1)

[8](#string.cons-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2491)

*Recommended practice*: For the overloads with a basic_string&& parameter,
implementations should avoid allocation
if s.get_allocator() == a is true[.](#string.cons-8.sentence-1)

[ð](#lib:basic_string,constructor___)

`template<class T>
  constexpr basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator());
`

[9](#string.cons-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2505)

*Constraints*: is_convertible_v<const T&, basic_string_view<charT, traits>> is true[.](#string.cons-9.sentence-1)

[10](#string.cons-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2510)

*Effects*: Creates a variable, sv,
as if by basic_string_view<charT, traits> sv = t; and then behaves the same as:basic_string(sv.substr(pos, n), a);

[ð](#lib:basic_string,constructor____)

`template<class T>
  constexpr explicit basic_string(const T& t, const Allocator& a = Allocator());
`

[11](#string.cons-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2527)

*Constraints*: 

- [(11.1)](#string.cons-11.1)

is_convertible_v<const T&, basic_string_view<charT, traits>> istrue and

- [(11.2)](#string.cons-11.2)

is_convertible_v<const T&, const charT*> isfalse[.](#string.cons-11.sentence-1)

[12](#string.cons-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2538)

*Effects*: Creates a variable, sv, as if bybasic_string_view<charT, traits> sv = t; and
then behaves the same as basic_string(sv.data(), sv.size(), a)[.](#string.cons-12.sentence-1)

[ð](#lib:basic_string,constructor_____)

`constexpr basic_string(const charT* s, size_type n, const Allocator& a = Allocator());
`

[13](#string.cons-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2551)

*Preconditions*: [s, s + n) is a valid range[.](#string.cons-13.sentence-1)

[14](#string.cons-14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2555)

*Effects*: Constructs an object whose initial value is the range [s, s + n)[.](#string.cons-14.sentence-1)

[15](#string.cons-15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2559)

*Postconditions*: size() is equal to n, andtraits​::​compare(data(), s, n) is equal to 0[.](#string.cons-15.sentence-1)

[ð](#lib:basic_string,constructor______)

`constexpr basic_string(const charT* s, const Allocator& a = Allocator());
`

[16](#string.cons-16)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2571)

*Constraints*: Allocator is a type
that qualifies as an allocator ([[container.reqmts]](container.reqmts "23.2.2.2 Container requirements"))[.](#string.cons-16.sentence-1)

[*Note [1](#string.cons-note-1)*:

This affects class template argument deduction[.](#string.cons-16.sentence-2)

â *end note*]

[17](#string.cons-17)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2579)

*Effects*: Equivalent to: basic_string(s, traits​::​length(s), a)[.](#string.cons-17.sentence-1)

[ð](#lib:basic_string,constructor_______)

`constexpr basic_string(size_type n, charT c, const Allocator& a = Allocator());
`

[18](#string.cons-18)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2590)

*Constraints*: Allocator is a type
that qualifies as an allocator ([[container.reqmts]](container.reqmts "23.2.2.2 Container requirements"))[.](#string.cons-18.sentence-1)

[*Note [2](#string.cons-note-2)*:

This affects class template argument deduction[.](#string.cons-18.sentence-2)

â *end note*]

[19](#string.cons-19)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2598)

*Effects*: Constructs an object whose value consists of n copies of c[.](#string.cons-19.sentence-1)

[ð](#lib:basic_string,constructor________)

`template<class InputIterator>
  constexpr basic_string(InputIterator begin, InputIterator end, const Allocator& a = Allocator());
`

[20](#string.cons-20)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2610)

*Constraints*: InputIterator is a type that qualifies as an input
iterator ([[container.reqmts]](container.reqmts "23.2.2.2 Container requirements"))[.](#string.cons-20.sentence-1)

[21](#string.cons-21)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2615)

*Effects*: Constructs a string from the values in the range [begin, end),
as specified in [[sequence.reqmts]](sequence.reqmts "23.2.4 Sequence containers")[.](#string.cons-21.sentence-1)

[ð](#lib:basic_string,constructor_________)

`template<[container-compatible-range](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<charT> R>
  constexpr basic_string(from_range_t, R&& rg, const Allocator& = Allocator());
`

[22](#string.cons-22)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2628)

*Effects*: Constructs a string from the values in the range rg,
as specified in [[sequence.reqmts]](sequence.reqmts "23.2.4 Sequence containers")[.](#string.cons-22.sentence-1)

[ð](#lib:basic_string,constructor__________)

`constexpr basic_string(initializer_list<charT> il, const Allocator& a = Allocator());
`

[23](#string.cons-23)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2640)

*Effects*: Equivalent to basic_string(il.begin(), il.end(), a)[.](#string.cons-23.sentence-1)

[ð](#lib:basic_string,constructor___________)

`constexpr basic_string(const basic_string& str, const Allocator& alloc);
constexpr basic_string(basic_string&& str, const Allocator& alloc);
`

[24](#string.cons-24)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2652)

*Effects*: Constructs an object whose value is
that of str prior to this call[.](#string.cons-24.sentence-1)

The stored allocator is constructed from alloc[.](#string.cons-24.sentence-2)

In the second form, str is left in a valid but unspecified state[.](#string.cons-24.sentence-3)

[25](#string.cons-25)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2659)

*Throws*: The second form throws nothing if alloc == str.get_allocator()[.](#string.cons-25.sentence-1)

[ð](#string.cons-itemdecl:13)

`template<class InputIterator,
         class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
  basic_string(InputIterator, InputIterator, Allocator = Allocator())
    -> basic_string<typename iterator_traits<InputIterator>::value_type,
                    char_traits<typename iterator_traits<InputIterator>::value_type>,
                    Allocator>;
`

[26](#string.cons-26)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2674)

*Constraints*: InputIterator is a type that qualifies as an input iterator,
and Allocator is a type that qualifies as an allocator ([[container.reqmts]](container.reqmts "23.2.2.2 Container requirements"))[.](#string.cons-26.sentence-1)

[ð](#string.cons-itemdecl:14)

`template<class charT,
         class traits,
         class Allocator = allocator<charT>>
  explicit basic_string(basic_string_view<charT, traits>, const Allocator& = Allocator())
    -> basic_string<charT, traits, Allocator>;

template<class charT,
         class traits,
         class Allocator = allocator<charT>>
  basic_string(basic_string_view<charT, traits>,
               typename see below::size_type, typename see below::size_type,
               const Allocator& = Allocator())
    -> basic_string<charT, traits, Allocator>;
`

[27](#string.cons-27)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2697)

*Constraints*: Allocator is a type that qualifies as
an allocator ([[container.reqmts]](container.reqmts "23.2.2.2 Container requirements"))[.](#string.cons-27.sentence-1)

[ð](#lib:operator=,basic_string)

`constexpr basic_string& operator=(const basic_string& str);
`

[28](#string.cons-28)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2709)

*Effects*: If *this and str are the same object, has no effect[.](#string.cons-28.sentence-1)

Otherwise, replaces the value of *this with a copy of str[.](#string.cons-28.sentence-2)

[29](#string.cons-29)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2714)

*Returns*: *this[.](#string.cons-29.sentence-1)

[ð](#lib:operator=,basic_string_)

`constexpr basic_string& operator=(basic_string&& str)
  noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
           allocator_traits<Allocator>::is_always_equal::value);
`

[30](#string.cons-30)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2727)

*Effects*: Move assigns as a sequence container ([[sequence.reqmts]](sequence.reqmts "23.2.4 Sequence containers")),
except that iterators, pointers and references may be invalidated[.](#string.cons-30.sentence-1)

[31](#string.cons-31)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2732)

*Returns*: *this[.](#string.cons-31.sentence-1)

[ð](#lib:operator=,basic_string__)

`template<class T>
  constexpr basic_string& operator=(const T& t);
`

[32](#string.cons-32)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2744)

*Constraints*: 

- [(32.1)](#string.cons-32.1)

is_convertible_v<const T&, basic_string_view<charT, traits>> is true and

- [(32.2)](#string.cons-32.2)

is_convertible_v<const T&, const charT*> is false[.](#string.cons-32.sentence-1)

[33](#string.cons-33)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2753)

*Effects*: Equivalent to:basic_string_view<charT, traits> sv = t;return assign(sv);

[ð](#lib:operator=,basic_string___)

`constexpr basic_string& operator=(const charT* s);
`

[34](#string.cons-34)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2768)

*Effects*: Equivalent to:return *this = basic_string_view<charT, traits>(s);

[ð](#lib:operator=,basic_string____)

`constexpr basic_string& operator=(charT c);
`

[35](#string.cons-35)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2780)

*Effects*: Equivalent to:return *this = basic_string_view<charT, traits>(addressof(c), 1);

[ð](#lib:operator=,basic_string_____)

`constexpr basic_string& operator=(initializer_list<charT> il);
`

[36](#string.cons-36)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2794)

*Effects*: Equivalent to:return *this = basic_string_view<charT, traits>(il.begin(), il.size());

#### [27.4.3.4](#string.iterators) Iterator support [[string.iterators]](string.iterators)

[ð](#lib:begin,basic_string)

`constexpr iterator       begin() noexcept;
constexpr const_iterator begin() const noexcept;
constexpr const_iterator cbegin() const noexcept;
`

[1](#string.iterators-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2813)

*Returns*: An iterator referring to the first character in the string[.](#string.iterators-1.sentence-1)

[ð](#lib:end,basic_string)

`constexpr iterator       end() noexcept;
constexpr const_iterator end() const noexcept;
constexpr const_iterator cend() const noexcept;
`

[2](#string.iterators-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2827)

*Returns*: An iterator which is the past-the-end value[.](#string.iterators-2.sentence-1)

[ð](#lib:rbegin,basic_string)

`constexpr reverse_iterator       rbegin() noexcept;
constexpr const_reverse_iterator rbegin() const noexcept;
constexpr const_reverse_iterator crbegin() const noexcept;
`

[3](#string.iterators-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2841)

*Returns*: An iterator which is semantically equivalent toreverse_iterator(end())[.](#string.iterators-3.sentence-1)

[ð](#lib:rend,basic_string)

`constexpr reverse_iterator       rend() noexcept;
constexpr const_reverse_iterator rend() const noexcept;
constexpr const_reverse_iterator crend() const noexcept;
`

[4](#string.iterators-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2856)

*Returns*: An iterator which is semantically equivalent toreverse_iterator(begin())[.](#string.iterators-4.sentence-1)

#### [27.4.3.5](#string.capacity) Capacity [[string.capacity]](string.capacity)

[ð](#lib:size,basic_string)

`constexpr size_type size() const noexcept;
constexpr size_type length() const noexcept;
`

[1](#string.capacity-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2872)

*Returns*: A count of the number of char-like objects currently in the string[.](#string.capacity-1.sentence-1)

[2](#string.capacity-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2876)

*Complexity*: Constant time[.](#string.capacity-2.sentence-1)

[ð](#lib:max_size,basic_string)

`constexpr size_type max_size() const noexcept;
`

[3](#string.capacity-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2887)

*Returns*: The largest possible number of char-like objects that can be stored in abasic_string[.](#string.capacity-3.sentence-1)

[4](#string.capacity-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2892)

*Complexity*: Constant time[.](#string.capacity-4.sentence-1)

[ð](#lib:resize,basic_string)

`constexpr void resize(size_type n, charT c);
`

[5](#string.capacity-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2903)

*Effects*: Alters the value of*this as follows:

- [(5.1)](#string.capacity-5.1)

  Ifn <= size(),
erases the last size() - n elements[.](#string.capacity-5.1.sentence-1)

- [(5.2)](#string.capacity-5.2)

  Ifn > size(),
appends n - size() copies of c[.](#string.capacity-5.2.sentence-1)

[ð](#lib:resize,basic_string_)

`constexpr void resize(size_type n);
`

[6](#string.capacity-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2926)

*Effects*: Equivalent to resize(n, charT())[.](#string.capacity-6.sentence-1)

[ð](#lib:resize_and_overwrite,basic_string)

`template<class Operation> constexpr void resize_and_overwrite(size_type n, Operation op);
`

[7](#string.capacity-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2937)

Let

- [(7.1)](#string.capacity-7.1)

  o = size() before the call to resize_and_overwrite[.](#string.capacity-7.1.sentence-1)

- [(7.2)](#string.capacity-7.2)

  k be min(o, n)[.](#string.capacity-7.2.sentence-1)

- [(7.3)](#string.capacity-7.3)

  p be a value of type charT* or charT* const,
such that the range [p, p + n] is valid andthis->compare(0, k, p, k) == 0 is true before the call[.](#string.capacity-7.3.sentence-1)
  The values in the range [p + k, p + n] may be indeterminate ([[basic.indet]](basic.indet "6.8.5 Indeterminate and erroneous values"))[.](#string.capacity-7.3.sentence-2)

- [(7.4)](#string.capacity-7.4)

  m be a value of type size_type or const size_type equal to n[.](#string.capacity-7.4.sentence-1)

- [(7.5)](#string.capacity-7.5)

  *OP* be the expression std​::​move(op)(p, m)[.](#string.capacity-7.5.sentence-1)

- [(7.6)](#string.capacity-7.6)

  r = *OP*[.](#string.capacity-7.6.sentence-1)

[8](#string.capacity-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2958)

*Mandates*: *OP* has an integer-like type ([[iterator.concept.winc]](iterator.concept.winc "24.3.4.4 Concept weakly_­incrementable"))[.](#string.capacity-8.sentence-1)

[9](#string.capacity-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2962)

*Preconditions*: 

- [(9.1)](#string.capacity-9.1)

  *OP* does not throw an exception or modify p or m[.](#string.capacity-9.1.sentence-1)

- [(9.2)](#string.capacity-9.2)

  r â¥ 0[.](#string.capacity-9.2.sentence-1)

- [(9.3)](#string.capacity-9.3)

  r â¤ m[.](#string.capacity-9.3.sentence-1)

- [(9.4)](#string.capacity-9.4)

  After evaluating *OP* there are no indeterminate values in the range [p, p + r)[.](#string.capacity-9.4.sentence-1)

[10](#string.capacity-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2976)

*Effects*: Evaluates *OP*,
replaces the contents of *this with [p, p + r), and
invalidates all pointers and references to the range [p, p + n][.](#string.capacity-10.sentence-1)

[11](#string.capacity-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2982)

*Recommended practice*: Implementations should avoid unnecessary copies and allocations
by, for example, making p a pointer into internal storage and
by restoring *(p + r) to charT() after evaluating *OP*[.](#string.capacity-11.sentence-1)

[ð](#lib:capacity,basic_string)

`constexpr size_type capacity() const noexcept;
`

[12](#string.capacity-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2995)

*Returns*: The size of the allocated storage in the string[.](#string.capacity-12.sentence-1)

[13](#string.capacity-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2999)

*Complexity*: Constant time[.](#string.capacity-13.sentence-1)

[ð](#lib:reserve,basic_string)

`constexpr void reserve(size_type res_arg);
`

[14](#string.capacity-14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3010)

*Effects*: A directive that informs a basic_string of a planned change in size,
so that the storage allocation can be managed accordingly[.](#string.capacity-14.sentence-1)

Following a call toreserve,capacity() is greater or equal to the argument ofreserve if reallocation happens; and
equal to the previous value ofcapacity() otherwise[.](#string.capacity-14.sentence-2)

Reallocation happens at this point if and only if
the current capacity is less than the argument of reserve[.](#string.capacity-14.sentence-3)

[15](#string.capacity-15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3026)

*Throws*: length_error ifres_arg > max_size() or any exceptions thrown byallocator_traits <Allocator>​::​allocate[.](#string.capacity-15.sentence-1)

[ð](#lib:shrink_to_fit,basic_string)

`constexpr void shrink_to_fit();
`

[16](#string.capacity-16)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3040)

*Effects*: shrink_to_fit is a non-binding request to reducecapacity() to size()[.](#string.capacity-16.sentence-1)

[*Note [1](#string.capacity-note-1)*:

The request is non-binding to
allow latitude for implementation-specific optimizations[.](#string.capacity-16.sentence-2)

â *end note*]

It does not increase capacity(), but may reduce capacity() by causing reallocation[.](#string.capacity-16.sentence-3)

[17](#string.capacity-17)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3051)

*Complexity*: If the size is not equal to the old capacity,
linear in the size of the sequence;
otherwise constant[.](#string.capacity-17.sentence-1)

[18](#string.capacity-18)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3057)

*Remarks*: Reallocation invalidates all the references, pointers, and iterators
referring to the elements in the sequence, as well as the past-the-end iterator[.](#string.capacity-18.sentence-1)

[*Note [2](#string.capacity-note-2)*:

If no reallocation happens, they remain valid[.](#string.capacity-18.sentence-2)

â *end note*]

[ð](#lib:clear,basic_string)

`constexpr void clear() noexcept;
`

[19](#string.capacity-19)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3072)

*Effects*: Equivalent to: erase(begin(), end());

[ð](#lib:empty,basic_string)

`constexpr bool empty() const noexcept;
`

[20](#string.capacity-20)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3083)

*Effects*: Equivalent to:return size() == 0;

#### [27.4.3.6](#string.access) Element access [[string.access]](string.access)

[ð](#lib:operator%5b%5d,basic_string)

`constexpr const_reference operator[](size_type pos) const;
constexpr reference       operator[](size_type pos);
`

[1](#string.access-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3098)

*Hardened preconditions*: pos <= size() is true[.](#string.access-1.sentence-1)

[2](#string.access-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3102)

*Returns*: *(begin() + pos) if pos < size()[.](#string.access-2.sentence-1)

Otherwise,
returns a reference to an object of type charT with valuecharT(), where modifying the object to any value other thancharT() leads to undefined behavior[.](#string.access-2.sentence-2)

[3](#string.access-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3109)

*Throws*: Nothing[.](#string.access-3.sentence-1)

[4](#string.access-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3113)

*Complexity*: Constant time[.](#string.access-4.sentence-1)

[ð](#lib:at,basic_string)

`constexpr const_reference at(size_type pos) const;
constexpr reference       at(size_type pos);
`

[5](#string.access-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3125)

*Returns*: operator[](pos)[.](#string.access-5.sentence-1)

[6](#string.access-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3129)

*Throws*: out_of_range ifpos >= size()[.](#string.access-6.sentence-1)

[ð](#lib:front,basic_string)

`constexpr const charT& front() const;
constexpr charT& front();
`

[7](#string.access-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3143)

*Hardened preconditions*: empty() is false[.](#string.access-7.sentence-1)

[8](#string.access-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3147)

*Effects*: Equivalent to: return operator[](0);

[ð](#lib:back,basic_string)

`constexpr const charT& back() const;
constexpr charT& back();
`

[9](#string.access-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3159)

*Hardened preconditions*: empty() is false[.](#string.access-9.sentence-1)

[10](#string.access-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3163)

*Effects*: Equivalent to: return operator[](size() - 1);

#### [27.4.3.7](#string.modifiers) Modifiers [[string.modifiers]](string.modifiers)

#### [27.4.3.7.1](#string.op.append) basic_string​::​operator+= [[string.op.append]](string.op.append)

[ð](#lib:operator+=,basic_string)

`constexpr basic_string& operator+=(const basic_string& str);
`

[1](#string.op.append-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3178)

*Effects*: Equivalent to: return append(str);

[ð](#lib:operator+=,basic_string_)

`template<class T>
  constexpr basic_string& operator+=(const T& t);
`

[2](#string.op.append-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3192)

*Constraints*: 

- [(2.1)](#string.op.append-2.1)

is_convertible_v<const T&, basic_string_view<charT, traits>> istrue and

- [(2.2)](#string.op.append-2.2)

is_convertible_v<const T&, const charT*> isfalse[.](#string.op.append-2.sentence-1)

[3](#string.op.append-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3203)

*Effects*: Equivalent to:basic_string_view<charT, traits> sv = t;return append(sv);

[ð](#lib:operator+=,basic_string__)

`constexpr basic_string& operator+=(const charT* s);
`

[4](#string.op.append-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3218)

*Effects*: Equivalent to: return append(s);

[ð](#lib:operator+=,basic_string___)

`constexpr basic_string& operator+=(charT c);
`

[5](#string.op.append-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3229)

*Effects*: Equivalent to: return append(size_type{1}, c);

[ð](#lib:operator+=,basic_string____)

`constexpr basic_string& operator+=(initializer_list<charT> il);
`

[6](#string.op.append-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3240)

*Effects*: Equivalent to: return append(il);

#### [27.4.3.7.2](#string.append) basic_string​::​append [[string.append]](string.append)

[ð](#lib:append,basic_string)

`constexpr basic_string& append(const basic_string& str);
`

[1](#string.append-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3254)

*Effects*: Equivalent to: return append(str.data(), str.size());

[ð](#lib:append,basic_string_)

`constexpr basic_string& append(const basic_string& str, size_type pos, size_type n = npos);
`

[2](#string.append-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3265)

*Effects*: Equivalent to:return append(basic_string_view<charT, traits>(str).substr(pos, n));

[ð](#lib:append,basic_string__)

`template<class T>
  constexpr basic_string& append(const T& t);
`

[3](#string.append-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3280)

*Constraints*: 

- [(3.1)](#string.append-3.1)

is_convertible_v<const T&, basic_string_view<charT, traits>> istrue and

- [(3.2)](#string.append-3.2)

is_convertible_v<const T&, const charT*> isfalse[.](#string.append-3.sentence-1)

[4](#string.append-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3291)

*Effects*: Equivalent to:basic_string_view<charT, traits> sv = t;return append(sv.data(), sv.size());

[ð](#lib:append,basic_string___)

`template<class T>
  constexpr basic_string& append(const T& t, size_type pos, size_type n = npos);
`

[5](#string.append-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3307)

*Constraints*: 

- [(5.1)](#string.append-5.1)

is_convertible_v<const T&, basic_string_view<charT, traits>> istrue and

- [(5.2)](#string.append-5.2)

is_convertible_v<const T&, const charT*> isfalse[.](#string.append-5.sentence-1)

[6](#string.append-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3318)

*Effects*: Equivalent to:basic_string_view<charT, traits> sv = t;return append(sv.substr(pos, n));

[ð](#lib:append,basic_string____)

`constexpr basic_string& append(const charT* s, size_type n);
`

[7](#string.append-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3333)

*Preconditions*: [s, s + n) is a valid range[.](#string.append-7.sentence-1)

[8](#string.append-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3337)

*Effects*: Appends a copy of the range [s, s + n) to the string[.](#string.append-8.sentence-1)

[9](#string.append-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3341)

*Returns*: *this[.](#string.append-9.sentence-1)

[ð](#lib:append,basic_string_____)

`constexpr basic_string& append(const charT* s);
`

[10](#string.append-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3352)

*Effects*: Equivalent to: return append(s, traits​::​length(s));

[ð](#lib:append,basic_string______)

`constexpr basic_string& append(size_type n, charT c);
`

[11](#string.append-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3363)

*Effects*: Appends n copies of c to the string[.](#string.append-11.sentence-1)

[12](#string.append-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3367)

*Returns*: *this[.](#string.append-12.sentence-1)

[ð](#lib:append,basic_string_______)

`template<class InputIterator>
  constexpr basic_string& append(InputIterator first, InputIterator last);
`

[13](#string.append-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3379)

*Constraints*: InputIterator is a type that qualifies as an input
iterator ([[container.reqmts]](container.reqmts "23.2.2.2 Container requirements"))[.](#string.append-13.sentence-1)

[14](#string.append-14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3384)

*Effects*: Equivalent to: return append(basic_string(first, last, get_allocator()));

[ð](#lib:append_range,basic_string)

`template<[container-compatible-range](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<charT> R>
  constexpr basic_string& append_range(R&& rg);
`

[15](#string.append-15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3396)

*Effects*: Equivalent to: return append(basic_string(from_range, std​::​forward<R>(rg), get_allocator()));

[ð](#lib:append,basic_string________)

`constexpr basic_string& append(initializer_list<charT> il);
`

[16](#string.append-16)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3407)

*Effects*: Equivalent to: return append(il.begin(), il.size());

[ð](#lib:push_back,basic_string)

`constexpr void push_back(charT c);
`

[17](#string.append-17)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3418)

*Effects*: Equivalent toappend(size_type{1}, c)[.](#string.append-17.sentence-1)

#### [27.4.3.7.3](#string.assign) basic_string​::​assign [[string.assign]](string.assign)

[ð](#lib:assign,basic_string)

`constexpr basic_string& assign(const basic_string& str);
`

[1](#string.assign-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3432)

*Effects*: Equivalent to: return *this = str;

[ð](#lib:assign,basic_string_)

`constexpr basic_string& assign(basic_string&& str)
  noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
           allocator_traits<Allocator>::is_always_equal::value);
`

[2](#string.assign-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3445)

*Effects*: Equivalent to: return *this = std​::​move(str);

[ð](#lib:assign,basic_string__)

`constexpr basic_string& assign(const basic_string& str, size_type pos, size_type n = npos);
`

[3](#string.assign-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3457)

*Effects*: Equivalent to:return assign(basic_string_view<charT, traits>(str).substr(pos, n));

[ð](#lib:assign,basic_string___)

`template<class T>
  constexpr basic_string& assign(const T& t);
`

[4](#string.assign-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3472)

*Constraints*: 

- [(4.1)](#string.assign-4.1)

is_convertible_v<const T&, basic_string_view<charT, traits>> istrue and

- [(4.2)](#string.assign-4.2)

is_convertible_v<const T&, const charT*> isfalse[.](#string.assign-4.sentence-1)

[5](#string.assign-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3483)

*Effects*: Equivalent to:basic_string_view<charT, traits> sv = t;return assign(sv.data(), sv.size());

[ð](#lib:assign,basic_string____)

`template<class T>
  constexpr basic_string& assign(const T& t, size_type pos, size_type n = npos);
`

[6](#string.assign-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3499)

*Constraints*: 

- [(6.1)](#string.assign-6.1)

is_convertible_v<const T&, basic_string_view<charT, traits>> istrue and

- [(6.2)](#string.assign-6.2)

is_convertible_v<const T&, const charT*> isfalse[.](#string.assign-6.sentence-1)

[7](#string.assign-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3510)

*Effects*: Equivalent to:basic_string_view<charT, traits> sv = t;return assign(sv.substr(pos, n));

[ð](#lib:assign,basic_string_____)

`constexpr basic_string& assign(const charT* s, size_type n);
`

[8](#string.assign-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3525)

*Preconditions*: [s, s + n) is a valid range[.](#string.assign-8.sentence-1)

[9](#string.assign-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3529)

*Effects*: Replaces the string controlled by *this with
a copy of the range [s, s + n)[.](#string.assign-9.sentence-1)

[10](#string.assign-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3534)

*Returns*: *this[.](#string.assign-10.sentence-1)

[ð](#lib:assign,basic_string______)

`constexpr basic_string& assign(const charT* s);
`

[11](#string.assign-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3545)

*Effects*: Equivalent to: return assign(s, traits​::​length(s));

[ð](#lib:assign,basic_string_______)

`constexpr basic_string& assign(initializer_list<charT> il);
`

[12](#string.assign-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3556)

*Effects*: Equivalent to: return assign(il.begin(), il.size());

[ð](#lib:assign,basic_string________)

`constexpr basic_string& assign(size_type n, charT c);
`

[13](#string.assign-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3567)

*Effects*: Equivalent to:clear();
resize(n, c);return *this;

[ð](#lib:assign,basic_string_________)

`template<class InputIterator>
  constexpr basic_string& assign(InputIterator first, InputIterator last);
`

[14](#string.assign-14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3584)

*Constraints*: InputIterator is a type that qualifies as an input
iterator ([[container.reqmts]](container.reqmts "23.2.2.2 Container requirements"))[.](#string.assign-14.sentence-1)

[15](#string.assign-15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3589)

*Effects*: Equivalent to: return assign(basic_string(first, last, get_allocator()));

[ð](#lib:assign_range,basic_string)

`template<[container-compatible-range](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<charT> R>
  constexpr basic_string& assign_range(R&& rg);
`

[16](#string.assign-16)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3601)

*Effects*: Equivalent to: return assign(basic_string(from_range, std​::​forward<R>(rg), get_allocator()));

#### [27.4.3.7.4](#string.insert) basic_string​::​insert [[string.insert]](string.insert)

[ð](#lib:insert,basic_string)

`constexpr basic_string& insert(size_type pos, const basic_string& str);
`

[1](#string.insert-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3614)

*Effects*: Equivalent to: return insert(pos, str.data(), str.size());

[ð](#lib:insert,basic_string_)

`constexpr basic_string& insert(size_type pos1, const basic_string& str,
                               size_type pos2, size_type n = npos);
`

[2](#string.insert-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3626)

*Effects*: Equivalent to:return insert(pos1, basic_string_view<charT, traits>(str), pos2, n);

[ð](#lib:insert,basic_string__)

`template<class T>
  constexpr basic_string& insert(size_type pos, const T& t);
`

[3](#string.insert-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3641)

*Constraints*: 

- [(3.1)](#string.insert-3.1)

is_convertible_v<const T&, basic_string_view<charT, traits>> istrue and

- [(3.2)](#string.insert-3.2)

is_convertible_v<const T&, const charT*> isfalse[.](#string.insert-3.sentence-1)

[4](#string.insert-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3652)

*Effects*: Equivalent to:basic_string_view<charT, traits> sv = t;return insert(pos, sv.data(), sv.size());

[ð](#lib:insert,basic_string___)

`template<class T>
  constexpr basic_string& insert(size_type pos1, const T& t,
                                 size_type pos2, size_type n = npos);
`

[5](#string.insert-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3669)

*Constraints*: 

- [(5.1)](#string.insert-5.1)

is_convertible_v<const T&, basic_string_view<charT, traits>> istrue and

- [(5.2)](#string.insert-5.2)

is_convertible_v<const T&, const charT*> isfalse[.](#string.insert-5.sentence-1)

[6](#string.insert-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3680)

*Effects*: Equivalent to:basic_string_view<charT, traits> sv = t;return insert(pos1, sv.substr(pos2, n));

[ð](#lib:insert,basic_string____)

`constexpr basic_string& insert(size_type pos, const charT* s, size_type n);
`

[7](#string.insert-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3695)

*Preconditions*: [s, s + n) is a valid range[.](#string.insert-7.sentence-1)

[8](#string.insert-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3699)

*Effects*: Inserts a copy of the range [s, s + n)
immediately before the character at position pos if pos < size(),
or otherwise at the end of the string[.](#string.insert-8.sentence-1)

[9](#string.insert-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3705)

*Returns*: *this[.](#string.insert-9.sentence-1)

[10](#string.insert-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3709)

*Throws*: 

- [(10.1)](#string.insert-10.1)

out_of_range if pos > size(),

- [(10.2)](#string.insert-10.2)

length_error if n > max_size() - size(), or

- [(10.3)](#string.insert-10.3)

any exceptions thrown by allocator_traits<Allocator>​::​allocate[.](#string.insert-10.sentence-1)

[ð](#lib:insert,basic_string_____)

`constexpr basic_string& insert(size_type pos, const charT* s);
`

[11](#string.insert-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3724)

*Effects*: Equivalent to: return insert(pos, s, traits​::​length(s));

[ð](#lib:insert,basic_string______)

`constexpr basic_string& insert(size_type pos, size_type n, charT c);
`

[12](#string.insert-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3735)

*Effects*: Inserts n copies of c before the character at position pos if pos < size(),
or otherwise at the end of the string[.](#string.insert-12.sentence-1)

[13](#string.insert-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3741)

*Returns*: *this[.](#string.insert-13.sentence-1)

[14](#string.insert-14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3745)

*Throws*: 

- [(14.1)](#string.insert-14.1)

out_of_range if pos > size(),

- [(14.2)](#string.insert-14.2)

length_error if n > max_size() - size(), or

- [(14.3)](#string.insert-14.3)

any exceptions thrown by allocator_traits<Allocator>​::​allocate[.](#string.insert-14.sentence-1)

[ð](#lib:insert,basic_string_______)

`constexpr iterator insert(const_iterator p, charT c);
`

[15](#string.insert-15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3760)

*Preconditions*: p is a valid iterator on*this[.](#string.insert-15.sentence-1)

[16](#string.insert-16)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3765)

*Effects*: Inserts a copy of c at the position p[.](#string.insert-16.sentence-1)

[17](#string.insert-17)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3769)

*Returns*: An iterator which refers to the inserted character[.](#string.insert-17.sentence-1)

[ð](#lib:insert,basic_string________)

`constexpr iterator insert(const_iterator p, size_type n, charT c);
`

[18](#string.insert-18)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3780)

*Preconditions*: p is a valid iterator on*this[.](#string.insert-18.sentence-1)

[19](#string.insert-19)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3785)

*Effects*: Inserts n copies of c at the position p[.](#string.insert-19.sentence-1)

[20](#string.insert-20)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3789)

*Returns*: An iterator which refers to the first inserted character, orp if n == 0[.](#string.insert-20.sentence-1)

[ð](#lib:insert,basic_string_________)

`template<class InputIterator>
  constexpr iterator insert(const_iterator p, InputIterator first, InputIterator last);
`

[21](#string.insert-21)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3802)

*Constraints*: InputIterator is a type that qualifies as an input
iterator ([[container.reqmts]](container.reqmts "23.2.2.2 Container requirements"))[.](#string.insert-21.sentence-1)

[22](#string.insert-22)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3807)

*Preconditions*: p is a valid iterator on*this[.](#string.insert-22.sentence-1)

[23](#string.insert-23)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3812)

*Effects*: Equivalent toinsert(p - begin(), basic_string(first, last, get_allocator()))[.](#string.insert-23.sentence-1)

[24](#string.insert-24)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3817)

*Returns*: An iterator which refers to the first inserted character, orp if first == last[.](#string.insert-24.sentence-1)

[ð](#lib:insert_range,basic_string)

`template<[container-compatible-range](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<charT> R>
  constexpr iterator insert_range(const_iterator p, R&& rg);
`

[25](#string.insert-25)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3830)

*Preconditions*: p is a valid iterator on *this[.](#string.insert-25.sentence-1)

[26](#string.insert-26)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3834)

*Effects*: Equivalent toinsert(p - begin(), basic_string(from_range, std​::​forward<R>(rg), get_allocator()))[.](#string.insert-26.sentence-1)

[27](#string.insert-27)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3839)

*Returns*: An iterator which refers to the first inserted character, orp if rg is empty[.](#string.insert-27.sentence-1)

[ð](#lib:insert,basic_string__________)

`constexpr iterator insert(const_iterator p, initializer_list<charT> il);
`

[28](#string.insert-28)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3851)

*Effects*: Equivalent to: return insert(p, il.begin(), il.end());

#### [27.4.3.7.5](#string.erase) basic_string​::​erase [[string.erase]](string.erase)

[ð](#lib:erase,basic_string)

`constexpr basic_string& erase(size_type pos = 0, size_type n = npos);
`

[1](#string.erase-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3864)

*Effects*: Determines the effective length xlen of the string to be removed as the smaller of n andsize() - pos[.](#string.erase-1.sentence-1)

Removes the characters in the range [begin() + pos, begin() + pos + xlen)[.](#string.erase-1.sentence-2)

[2](#string.erase-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3871)

*Returns*: *this[.](#string.erase-2.sentence-1)

[3](#string.erase-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3875)

*Throws*: out_of_range if pos> size()[.](#string.erase-3.sentence-1)

[ð](#lib:erase,basic_string_)

`constexpr iterator erase(const_iterator p);
`

[4](#string.erase-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3888)

*Preconditions*: p is a valid dereferenceable iterator on *this[.](#string.erase-4.sentence-1)

[5](#string.erase-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3892)

*Effects*: Removes the character referred to by p[.](#string.erase-5.sentence-1)

[6](#string.erase-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3896)

*Returns*: An iterator which points to the element immediately following p prior to
the element being erased[.](#string.erase-6.sentence-1)

If no such element exists,end() is returned[.](#string.erase-6.sentence-2)

[7](#string.erase-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3904)

*Throws*: Nothing[.](#string.erase-7.sentence-1)

[ð](#lib:erase,basic_string__)

`constexpr iterator erase(const_iterator first, const_iterator last);
`

[8](#string.erase-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3915)

*Preconditions*: first and last are valid iterators on*this[.](#string.erase-8.sentence-1)

[first, last) is a valid range[.](#string.erase-8.sentence-2)

[9](#string.erase-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3920)

*Effects*: Removes the characters in the range
[first, last)[.](#string.erase-9.sentence-1)

[10](#string.erase-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3925)

*Returns*: An iterator which points to the element pointed to by last prior to
the other elements being erased[.](#string.erase-10.sentence-1)

If no such element exists,end() is returned[.](#string.erase-10.sentence-2)

[11](#string.erase-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3933)

*Throws*: Nothing[.](#string.erase-11.sentence-1)

[ð](#lib:pop_back,basic_string)

`constexpr void pop_back();
`

[12](#string.erase-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3944)

*Hardened preconditions*: empty() is false[.](#string.erase-12.sentence-1)

[13](#string.erase-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3948)

*Effects*: Equivalent to erase(end() - 1)[.](#string.erase-13.sentence-1)

[14](#string.erase-14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3952)

*Throws*: Nothing[.](#string.erase-14.sentence-1)

#### [27.4.3.7.6](#string.replace) basic_string​::​replace [[string.replace]](string.replace)

[ð](#lib:replace,basic_string)

`constexpr basic_string& replace(size_type pos1, size_type n1, const basic_string& str);
`

[1](#string.replace-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3965)

*Effects*: Equivalent to: return replace(pos1, n1, str.data(), str.size());

[ð](#lib:replace,basic_string_)

`constexpr basic_string& replace(size_type pos1, size_type n1, const basic_string& str,
                                size_type pos2, size_type n2 = npos);
`

[2](#string.replace-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3977)

*Effects*: Equivalent to:return replace(pos1, n1, basic_string_view<charT, traits>(str).substr(pos2, n2));

[ð](#lib:replace,basic_string__)

`template<class T>
  constexpr basic_string& replace(size_type pos1, size_type n1, const T& t);
`

[3](#string.replace-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L3992)

*Constraints*: 

- [(3.1)](#string.replace-3.1)

is_convertible_v<const T&, basic_string_view<charT, traits>> istrue and

- [(3.2)](#string.replace-3.2)

is_convertible_v<const T&, const charT*> isfalse[.](#string.replace-3.sentence-1)

[4](#string.replace-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4003)

*Effects*: Equivalent to:basic_string_view<charT, traits> sv = t;return replace(pos1, n1, sv.data(), sv.size());

[ð](#lib:replace,basic_string___)

`template<class T>
  constexpr basic_string& replace(size_type pos1, size_type n1, const T& t,
                                  size_type pos2, size_type n2 = npos);
`

[5](#string.replace-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4020)

*Constraints*: 

- [(5.1)](#string.replace-5.1)

is_convertible_v<const T&, basic_string_view<charT, traits>> istrue and

- [(5.2)](#string.replace-5.2)

is_convertible_v<const T&, const charT*> isfalse[.](#string.replace-5.sentence-1)

[6](#string.replace-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4031)

*Effects*: Equivalent to:basic_string_view<charT, traits> sv = t;return replace(pos1, n1, sv.substr(pos2, n2));

[ð](#lib:replace,basic_string____)

`constexpr basic_string& replace(size_type pos1, size_type n1, const charT* s, size_type n2);
`

[7](#string.replace-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4046)

*Preconditions*: [s, s + n2) is a valid range[.](#string.replace-7.sentence-1)

[8](#string.replace-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4050)

*Effects*: Determines the effective length xlen of the string to be
removed as the smaller of n1 and size() - pos1[.](#string.replace-8.sentence-1)

Ifsize() - xlen >= max_size() - n2 throws length_error[.](#string.replace-8.sentence-2)

Otherwise,
the function replaces the characters in the range
[begin() + pos1, begin() + pos1 + xlen)
with a copy of the range [s, s + n2)[.](#string.replace-8.sentence-3)

[9](#string.replace-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4059)

*Returns*: *this[.](#string.replace-9.sentence-1)

[10](#string.replace-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4063)

*Throws*: 

- [(10.1)](#string.replace-10.1)

out_of_range if pos1 > size(),

- [(10.2)](#string.replace-10.2)

length_error if the length of the resulting string
would exceed max_size(), or

- [(10.3)](#string.replace-10.3)

any exceptions thrown by allocator_traits<Allocator>​::​allocate[.](#string.replace-10.sentence-1)

[ð](#lib:replace,basic_string_____)

`constexpr basic_string& replace(size_type pos, size_type n, const charT* s);
`

[11](#string.replace-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4079)

*Effects*: Equivalent to: return replace(pos, n, s, traits​::​length(s));

[ð](#lib:replace,basic_string______)

`constexpr basic_string& replace(size_type pos1, size_type n1, size_type n2, charT c);
`

[12](#string.replace-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4090)

*Effects*: Determines the effective length xlen of the string to be
removed as the smaller of n1 and size() - pos1[.](#string.replace-12.sentence-1)

Ifsize() - xlen >= max_size() - n2 throws length_error[.](#string.replace-12.sentence-2)

Otherwise,
the function replaces the characters in the range
[begin() + pos1, begin() + pos1 + xlen)
with n2 copies of c[.](#string.replace-12.sentence-3)

[13](#string.replace-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4099)

*Returns*: *this[.](#string.replace-13.sentence-1)

[14](#string.replace-14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4103)

*Throws*: 

- [(14.1)](#string.replace-14.1)

out_of_range if pos1 > size(),

- [(14.2)](#string.replace-14.2)

length_error if the length of the resulting string
would exceed max_size(), or

- [(14.3)](#string.replace-14.3)

any exceptions thrown by allocator_traits<Allocator>​::​allocate.

[ð](#lib:replace,basic_string_______)

`constexpr basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str);
`

[15](#string.replace-15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4119)

*Effects*: Equivalent to: return replace(i1, i2, basic_string_view<charT, traits>(str));

[ð](#lib:replace,basic_string________)

`template<class T>
  constexpr basic_string& replace(const_iterator i1, const_iterator i2, const T& t);
`

[16](#string.replace-16)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4131)

*Constraints*: 

- [(16.1)](#string.replace-16.1)

is_convertible_v<const T&, basic_string_view<charT, traits>> istrue and

- [(16.2)](#string.replace-16.2)

is_convertible_v<const T&, const charT*> isfalse[.](#string.replace-16.sentence-1)

[17](#string.replace-17)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4142)

*Preconditions*: [begin(), i1) and [i1, i2) are valid ranges[.](#string.replace-17.sentence-1)

[18](#string.replace-18)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4146)

*Effects*: Equivalent to:basic_string_view<charT, traits> sv = t;return replace(i1 - begin(), i2 - i1, sv.data(), sv.size());

[ð](#lib:replace,basic_string_________)

`constexpr basic_string& replace(const_iterator i1, const_iterator i2, const charT* s, size_type n);
`

[19](#string.replace-19)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4161)

*Effects*: Equivalent to: return replace(i1, i2, basic_string_view<charT, traits>(s, n));

[ð](#lib:replace,basic_string__________)

`constexpr basic_string& replace(const_iterator i1, const_iterator i2, const charT* s);
`

[20](#string.replace-20)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4172)

*Effects*: Equivalent to: return replace(i1, i2, basic_string_view<charT, traits>(s));

[ð](#lib:replace,basic_string___________)

`constexpr basic_string& replace(const_iterator i1, const_iterator i2, size_type n, charT c);
`

[21](#string.replace-21)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4183)

*Preconditions*: [begin(), i1) and [i1, i2) are valid ranges[.](#string.replace-21.sentence-1)

[22](#string.replace-22)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4187)

*Effects*: Equivalent to: return replace(i1 - begin(), i2 - i1, n, c);

[ð](#lib:replace,basic_string____________)

`template<class InputIterator>
  constexpr basic_string& replace(const_iterator i1, const_iterator i2,
                                  InputIterator j1, InputIterator j2);
`

[23](#string.replace-23)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4200)

*Constraints*: InputIterator is a type that qualifies as an input
iterator ([[container.reqmts]](container.reqmts "23.2.2.2 Container requirements"))[.](#string.replace-23.sentence-1)

[24](#string.replace-24)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4205)

*Effects*: Equivalent to: return replace(i1, i2, basic_string(j1, j2, get_allocator()));

[ð](#lib:replace_with_range,basic_string)

`template<[container-compatible-range](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<charT> R>
  constexpr basic_string& replace_with_range(const_iterator i1, const_iterator i2, R&& rg);
`

[25](#string.replace-25)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4217)

*Effects*: Equivalent to:return replace(i1, i2, basic_string(from_range, std::forward<R>(rg), get_allocator()));

[ð](#lib:replace,basic_string_____________)

`constexpr basic_string& replace(const_iterator i1, const_iterator i2, initializer_list<charT> il);
`

[26](#string.replace-26)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4231)

*Effects*: Equivalent to: return replace(i1, i2, il.begin(), il.size());

#### [27.4.3.7.7](#string.copy) basic_string​::​copy [[string.copy]](string.copy)

[ð](#lib:copy,basic_string)

`constexpr size_type copy(charT* s, size_type n, size_type pos = 0) const;
`

[1](#string.copy-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4244)

*Effects*: Equivalent to:return basic_string_view<charT, traits>(*this).copy(s, n, pos);

[*Note [1](#string.copy-note-1)*:

This does not terminate s with a null object[.](#string.copy-1.sentence-1)

â *end note*]

#### [27.4.3.7.8](#string.swap) basic_string​::​swap [[string.swap]](string.swap)

[ð](#lib:swap,basic_string)

`constexpr void swap(basic_string& s)
  noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value ||
           allocator_traits<Allocator>::is_always_equal::value);
`

[1](#string.swap-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4263)

*Preconditions*: allocator_traits<Allocator>​::​propagate_on_container_swap​::​value is true orget_allocator() == s.get_allocator()[.](#string.swap-1.sentence-1)

[2](#string.swap-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4269)

*Postconditions*: *this contains the same sequence of characters that was in s,s contains the same sequence of characters that was in*this[.](#string.swap-2.sentence-1)

[3](#string.swap-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4276)

*Throws*: Nothing[.](#string.swap-3.sentence-1)

[4](#string.swap-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4280)

*Complexity*: Constant time[.](#string.swap-4.sentence-1)

#### [27.4.3.8](#string.ops) String operations [[string.ops]](string.ops)

#### [27.4.3.8.1](#string.accessors) Accessors [[string.accessors]](string.accessors)

[ð](#lib:c_str,basic_string)

`constexpr const charT* c_str() const noexcept;
constexpr const charT* data() const noexcept;
`

[1](#string.accessors-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4297)

*Returns*: A pointer p such that p + i == addressof(operator[](i)) for eachi in [0, size()][.](#string.accessors-1.sentence-1)

[2](#string.accessors-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4302)

*Complexity*: Constant time[.](#string.accessors-2.sentence-1)

[3](#string.accessors-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4306)

*Remarks*: The program shall not modify any of the values stored in the character array; otherwise, the behavior is undefined[.](#string.accessors-3.sentence-1)

[ð](#lib:data,basic_string_)

`constexpr charT* data() noexcept;
`

[4](#string.accessors-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4317)

*Returns*: A pointer p such that p + i == addressof(operator[](i)) for eachi in [0, size()][.](#string.accessors-4.sentence-1)

[5](#string.accessors-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4322)

*Complexity*: Constant time[.](#string.accessors-5.sentence-1)

[6](#string.accessors-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4326)

*Remarks*: The program shall not modify the value stored at p + size() to any value other than charT(); otherwise, the behavior is undefined[.](#string.accessors-6.sentence-1)

[ð](#lib:operator_basic_string_view,basic_string)

`constexpr operator basic_string_view<charT, traits>() const noexcept;
`

[7](#string.accessors-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4338)

*Effects*: Equivalent to:return basic_string_view<charT, traits>(data(), size());

[ð](#lib:get_allocator,basic_string)

`constexpr allocator_type get_allocator() const noexcept;
`

[8](#string.accessors-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4350)

*Returns*: A copy of theAllocator object used to construct the string or, if that allocator has been replaced, a
copy of the most recent replacement[.](#string.accessors-8.sentence-1)

#### [27.4.3.8.2](#string.find) Searching [[string.find]](string.find)

[1](#string.find-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4360)

Let *F* be one offind, rfind, find_first_of, find_last_of,find_first_not_of, and find_last_not_of[.](#string.find-1.sentence-1)

- [(1.1)](#string.find-1.1)

Each member function of the formconstexpr size_type *F*(const basic_string& str, size_type pos) const noexcept; has effects equivalent to:return *F*(basic_string_view<charT, traits>(str), pos);

- [(1.2)](#string.find-1.2)

Each member function of the formconstexpr size_type *F*(const charT* s, size_type pos) const; has effects equivalent to:return *F*(basic_string_view<charT, traits>(s), pos);

- [(1.3)](#string.find-1.3)

Each member function of the formconstexpr size_type *F*(const charT* s, size_type pos, size_type n) const; has effects equivalent to:return *F*(basic_string_view<charT, traits>(s, n), pos);

- [(1.4)](#string.find-1.4)

Each member function of the formconstexpr size_type *F*(charT c, size_type pos) const noexcept; has effects equivalent to:return *F*(basic_string_view<charT, traits>(addressof(c), 1), pos);

[ð](#lib:find,basic_string_)

`template<class T>
  constexpr size_type find(const T& t, size_type pos = 0) const noexcept(see below);
template<class T>
  constexpr size_type rfind(const T& t, size_type pos = npos) const noexcept(see below);
template<class T>
  constexpr size_type find_first_of(const T& t, size_type pos = 0) const noexcept(see below);
template<class T>
  constexpr size_type find_last_of(const T& t, size_type pos = npos) const noexcept(see below);
template<class T>
  constexpr size_type find_first_not_of(const T& t, size_type pos = 0) const noexcept(see below);
template<class T>
  constexpr size_type find_last_not_of(const T& t, size_type pos = npos) const noexcept(see below);
`

[2](#string.find-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4429)

*Constraints*: 

- [(2.1)](#string.find-2.1)

is_convertible_v<const T&, basic_string_view<charT, traits>> istrue and

- [(2.2)](#string.find-2.2)

is_convertible_v<const T&, const charT*> isfalse[.](#string.find-2.sentence-1)

[3](#string.find-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4440)

*Effects*: Let *G* be the name of the function[.](#string.find-3.sentence-1)

Equivalent to:basic_string_view<charT, traits> s = *this, sv = t;return s.*G*(sv, pos);

[4](#string.find-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4449)

*Remarks*: The exception specification is equivalent tois_nothrow_convertible_v<const T&, basic_string_view<charT, traits>>[.](#string.find-4.sentence-1)

#### [27.4.3.8.3](#string.substr) basic_string​::​substr [[string.substr]](string.substr)

[ð](#lib:substr,basic_string)

`constexpr basic_string substr(size_type pos = 0, size_type n = npos) const &;
`

[1](#string.substr-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4463)

*Effects*: Equivalent to: return basic_string(*this, pos, n);

[ð](#lib:substr,basic_string_)

`constexpr basic_string substr(size_type pos = 0, size_type n = npos) &&;
`

[2](#string.substr-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4474)

*Effects*: Equivalent to: return basic_string(std​::​move(*this), pos, n);

[ð](#lib:subview,basic_string)

`constexpr basic_string_view<charT, traits> subview(size_type pos = 0, size_type n = npos) const;
`

[3](#string.substr-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4485)

*Effects*: Equivalent to: return basic_string_view<charT, traits>(*this).subview(pos, n);

#### [27.4.3.8.4](#string.compare) basic_string​::​compare [[string.compare]](string.compare)

[ð](#lib:compare,basic_string)

`template<class T>
  constexpr int compare(const T& t) const noexcept(see below);
`

[1](#string.compare-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4499)

*Constraints*: 

- [(1.1)](#string.compare-1.1)

is_convertible_v<const T&, basic_string_view<charT, traits>> istrue and

- [(1.2)](#string.compare-1.2)

is_convertible_v<const T&, const charT*> isfalse[.](#string.compare-1.sentence-1)

[2](#string.compare-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4510)

*Effects*: Equivalent to: return basic_string_view<charT, traits>(*this).compare(t);

[3](#string.compare-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4514)

*Remarks*: The exception specification is equivalent tois_nothrow_convertible_v<const T&, basic_string_view<charT, traits>>[.](#string.compare-3.sentence-1)

[ð](#lib:compare,basic_string_)

`template<class T>
  constexpr int compare(size_type pos1, size_type n1, const T& t) const;
`

[4](#string.compare-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4527)

*Constraints*: 

- [(4.1)](#string.compare-4.1)

is_convertible_v<const T&, basic_string_view<charT, traits>> istrue and

- [(4.2)](#string.compare-4.2)

is_convertible_v<const T&, const charT*> isfalse[.](#string.compare-4.sentence-1)

[5](#string.compare-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4538)

*Effects*: Equivalent to:return basic_string_view<charT, traits>(*this).substr(pos1, n1).compare(t);

[ð](#lib:compare,basic_string__)

`template<class T>
  constexpr int compare(size_type pos1, size_type n1, const T& t,
                        size_type pos2, size_type n2 = npos) const;
`

[6](#string.compare-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4554)

*Constraints*: 

- [(6.1)](#string.compare-6.1)

is_convertible_v<const T&, basic_string_view<charT, traits>> istrue and

- [(6.2)](#string.compare-6.2)

is_convertible_v<const T&, const charT*> isfalse[.](#string.compare-6.sentence-1)

[7](#string.compare-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4565)

*Effects*: Equivalent to:basic_string_view<charT, traits> s = *this, sv = t;return s.substr(pos1, n1).compare(sv.substr(pos2, n2));

[ð](#lib:compare,basic_string___)

`constexpr int compare(const basic_string& str) const noexcept;
`

[8](#string.compare-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4580)

*Effects*: Equivalent to:return compare(basic_string_view<charT, traits>(str));

[ð](#lib:compare,basic_string____)

`constexpr int compare(size_type pos1, size_type n1, const basic_string& str) const;
`

[9](#string.compare-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4592)

*Effects*: Equivalent to:return compare(pos1, n1, basic_string_view<charT, traits>(str));

[ð](#lib:compare,basic_string_____)

`constexpr int compare(size_type pos1, size_type n1, const basic_string& str,
                      size_type pos2, size_type n2 = npos) const;
`

[10](#string.compare-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4605)

*Effects*: Equivalent to:return compare(pos1, n1, basic_string_view<charT, traits>(str), pos2, n2);

[ð](#lib:compare,basic_string______)

`constexpr int compare(const charT* s) const;
`

[11](#string.compare-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4619)

*Effects*: Equivalent to:return compare(basic_string_view<charT, traits>(s));

[ð](#lib:compare,basic_string_______)

`constexpr int compare(size_type pos, size_type n1, const charT* s) const;
`

[12](#string.compare-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4631)

*Effects*: Equivalent to: return compare(pos, n1, basic_string_view<charT, traits>(s));

[ð](#lib:compare,basic_string________)

`constexpr int compare(size_type pos, size_type n1, const charT* s, size_type n2) const;
`

[13](#string.compare-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4642)

*Effects*: Equivalent to: return compare(pos, n1, basic_string_view<charT, traits>(s, n2));

#### [27.4.3.8.5](#string.starts.with) basic_string​::​starts_with [[string.starts.with]](string.starts.with)

[ð](#lib:starts_with,basic_string)

`constexpr bool starts_with(basic_string_view<charT, traits> x) const noexcept;
constexpr bool starts_with(charT x) const noexcept;
constexpr bool starts_with(const charT* x) const;
`

[1](#string.starts.with-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4657)

*Effects*: Equivalent to:return basic_string_view<charT, traits>(data(), size()).starts_with(x);

#### [27.4.3.8.6](#string.ends.with) basic_string​::​ends_with [[string.ends.with]](string.ends.with)

[ð](#lib:ends_with,basic_string)

`constexpr bool ends_with(basic_string_view<charT, traits> x) const noexcept;
constexpr bool ends_with(charT x) const noexcept;
constexpr bool ends_with(const charT* x) const;
`

[1](#string.ends.with-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4675)

*Effects*: Equivalent to:return basic_string_view<charT, traits>(data(), size()).ends_with(x);

#### [27.4.3.8.7](#string.contains) basic_string​::​contains [[string.contains]](string.contains)

[ð](#lib:contains,basic_string)

`constexpr bool contains(basic_string_view<charT, traits> x) const noexcept;
constexpr bool contains(charT x) const noexcept;
constexpr bool contains(const charT* x) const;
`

[1](#string.contains-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4693)

*Effects*: Equivalent to:return basic_string_view<charT, traits>(data(), size()).contains(x);

### [27.4.4](#string.nonmembers) Non-member functions [[string.nonmembers]](string.nonmembers)

#### [27.4.4.1](#string.op.plus) operator+ [[string.op.plus]](string.op.plus)

[ð](#lib:operator+,basic_string)

`template<class charT, class traits, class Allocator>
  constexpr basic_string<charT, traits, Allocator>
    operator+(const basic_string<charT, traits, Allocator>& lhs,
              const basic_string<charT, traits, Allocator>& rhs);
template<class charT, class traits, class Allocator>
  constexpr basic_string<charT, traits, Allocator>
    operator+(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs);
`

[1](#string.op.plus-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4719)

*Effects*: Equivalent to:basic_string<charT, traits, Allocator> r = lhs;
r.append(rhs);return r;

[ð](#lib:operator+,basic_string_)

`template<class charT, class traits, class Allocator>
  constexpr basic_string<charT, traits, Allocator>
    operator+(basic_string<charT, traits, Allocator>&& lhs,
              const basic_string<charT, traits, Allocator>& rhs);
template<class charT, class traits, class Allocator>
  constexpr basic_string<charT, traits, Allocator>
    operator+(basic_string<charT, traits, Allocator>&& lhs, const charT* rhs);
`

[2](#string.op.plus-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4741)

*Effects*: Equivalent to:lhs.append(rhs);return std::move(lhs);

[ð](#lib:operator+,basic_string__)

`template<class charT, class traits, class Allocator>
  constexpr basic_string<charT, traits, Allocator>
    operator+(basic_string<charT, traits, Allocator>&& lhs,
              basic_string<charT, traits, Allocator>&& rhs);
`

[3](#string.op.plus-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4759)

*Effects*: Equivalent to:lhs.append(rhs);return std::move(lhs); except that both lhs and rhs are left in valid but unspecified states[.](#string.op.plus-3.sentence-1)

[*Note [1](#string.op.plus-note-1)*:

If lhs and rhs have equal allocators,
the implementation can move from either[.](#string.op.plus-3.sentence-2)

â *end note*]

[ð](#lib:operator+,basic_string___)

`template<class charT, class traits, class Allocator>
  constexpr basic_string<charT, traits, Allocator>
    operator+(const basic_string<charT, traits, Allocator>& lhs,
              basic_string<charT, traits, Allocator>&& rhs);
template<class charT, class traits, class Allocator>
  constexpr basic_string<charT, traits, Allocator>
    operator+(const charT* lhs, basic_string<charT, traits, Allocator>&& rhs);
`

[4](#string.op.plus-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4786)

*Effects*: Equivalent to:rhs.insert(0, lhs);return std::move(rhs);

[ð](#lib:operator+,basic_string____)

`template<class charT, class traits, class Allocator>
  constexpr basic_string<charT, traits, Allocator>
    operator+(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs);
`

[5](#string.op.plus-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4803)

*Effects*: Equivalent to:basic_string<charT, traits, Allocator> r = rhs;
r.insert(0, lhs);return r;

[ð](#lib:operator+,basic_string_____)

`template<class charT, class traits, class Allocator>
  constexpr basic_string<charT, traits, Allocator>
    operator+(charT lhs, const basic_string<charT, traits, Allocator>& rhs);
`

[6](#string.op.plus-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4821)

*Effects*: Equivalent to:basic_string<charT, traits, Allocator> r = rhs;
r.insert(r.begin(), lhs);return r;

[ð](#lib:operator+,basic_string______)

`template<class charT, class traits, class Allocator>
  constexpr basic_string<charT, traits, Allocator>
    operator+(charT lhs, basic_string<charT, traits, Allocator>&& rhs);
`

[7](#string.op.plus-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4839)

*Effects*: Equivalent to:rhs.insert(rhs.begin(), lhs);return std::move(rhs);

[ð](#lib:operator+,basic_string_______)

`template<class charT, class traits, class Allocator>
  constexpr basic_string<charT, traits, Allocator>
    operator+(const basic_string<charT, traits, Allocator>& lhs, charT rhs);
`

[8](#string.op.plus-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4856)

*Effects*: Equivalent to:basic_string<charT, traits, Allocator> r = lhs;
r.push_back(rhs);return r;

[ð](#lib:operator+,basic_string________)

`template<class charT, class traits, class Allocator>
  constexpr basic_string<charT, traits, Allocator>
    operator+(basic_string<charT, traits, Allocator>&& lhs, charT rhs);
`

[9](#string.op.plus-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4874)

*Effects*: Equivalent to:lhs.push_back(rhs);return std::move(lhs);

[ð](#lib:operator+,basic_string_________)

`template<class charT, class traits, class Allocator>
  constexpr basic_string<charT, traits, Allocator>
    operator+(const basic_string<charT, traits, Allocator>& lhs,
              type_identity_t<basic_string_view<charT, traits>> rhs);
`

[10](#string.op.plus-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4892)

Equivalent to:basic_string<charT, traits, Allocator> r = lhs;
r.append(rhs);return r;

[ð](#lib:operator+,basic_string__________)

`template<class charT, class traits, class Allocator>
  constexpr basic_string<charT, traits, Allocator>
    operator+(basic_string<charT, traits, Allocator>&& lhs,
              type_identity_t<basic_string_view<charT, traits>> rhs);
`

[11](#string.op.plus-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4910)

Equivalent to:lhs.append(rhs);return std::move(lhs);

[ð](#lib:operator+,basic_string___________)

`template<class charT, class traits, class Allocator>
  constexpr basic_string<charT, traits, Allocator>
    operator+(type_identity_t<basic_string_view<charT, traits>> lhs,
              const basic_string<charT, traits, Allocator>& rhs);
`

[12](#string.op.plus-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4927)

Equivalent to:basic_string<charT, traits, Allocator> r = rhs;
r.insert(0, lhs);return r;

[ð](#lib:operator+,basic_string____________)

`template<class charT, class traits, class Allocator>
  constexpr basic_string<charT, traits, Allocator>
    operator+(type_identity_t<basic_string_view<charT, traits>> lhs,
              basic_string<charT, traits, Allocator>&& rhs);
`

[13](#string.op.plus-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4945)

Equivalent to:rhs.insert(0, lhs);return std::move(rhs);

[14](#string.op.plus-14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4953)

[*Note [2](#string.op.plus-note-2)*:

Using a specialization of type_identity_t as a parameter type ensures
that an object of type basic_string<charT, traits, Allocator> can be concatenated with an object of a type T having an implicit conversion tobasic_string_view<charT, traits> ([[over.match.oper]](over.match.oper "12.2.2.3 Operators in expressions"))[.](#string.op.plus-14.sentence-1)

â *end note*]

#### [27.4.4.2](#string.cmp) Non-member comparison operator functions [[string.cmp]](string.cmp)

[ð](#string.cmp-itemdecl:1)

`template<class charT, class traits, class Allocator>
  constexpr bool
    operator==(const basic_string<charT, traits, Allocator>& lhs,
               const basic_string<charT, traits, Allocator>& rhs) noexcept;
template<class charT, class traits, class Allocator>
  constexpr bool operator==(const basic_string<charT, traits, Allocator>& lhs,
                            const charT* rhs);

template<class charT, class traits, class Allocator>
  constexpr see below operator<=>(const basic_string<charT, traits, Allocator>& lhs,
                                  const basic_string<charT, traits, Allocator>& rhs) noexcept;
template<class charT, class traits, class Allocator>
  constexpr see below operator<=>(const basic_string<charT, traits, Allocator>& lhs,
                                  const charT* rhs);
`

[1](#string.cmp-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4980)

*Effects*: Let *op* be the operator[.](#string.cmp-1.sentence-1)

Equivalent to:return basic_string_view<charT, traits>(lhs) *op* basic_string_view<charT, traits>(rhs);

#### [27.4.4.3](#string.special) swap [[string.special]](string.special)

[ð](#lib:swap,basic_string_)

`template<class charT, class traits, class Allocator>
  constexpr void
    swap(basic_string<charT, traits, Allocator>& lhs,
         basic_string<charT, traits, Allocator>& rhs)
      noexcept(noexcept(lhs.swap(rhs)));
`

[1](#string.special-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5001)

*Effects*: Equivalent to lhs.swap(rhs)[.](#string.special-1.sentence-1)

#### [27.4.4.4](#string.io) Inserters and extractors [[string.io]](string.io)

[ð](#lib:operator%3e%3e,basic_string)

`template<class charT, class traits, class Allocator>
  basic_istream<charT, traits>&
    operator>>(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str);
`

[1](#string.io-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5016)

*Effects*: Behaves as a formatted input function ([[istream.formatted.reqmts]](istream.formatted.reqmts "31.7.5.3.1 Common requirements"))[.](#string.io-1.sentence-1)

After constructing a sentry object,
if the sentry object returns true when converted to a value of type bool,
calls str.erase() and then extracts characters from is and appends them
to str as if by callingstr.append(1, c)[.](#string.io-1.sentence-2)

Ifis.width() is greater than zero, the maximum
number n of characters appended isis.width();
otherwise n isstr.max_size()[.](#string.io-1.sentence-3)

Characters are extracted and appended until any of the following
occurs:

- [(1.1)](#string.io-1.1)

*n* characters are stored;

- [(1.2)](#string.io-1.2)

end-of-file occurs on the input sequence;

- [(1.3)](#string.io-1.3)

isspace(c, is.getloc()) is true for the next available input character*c*[.](#string.io-1.sentence-4)

[2](#string.io-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5047)

After the last character (if any) is extracted,is.width(0) is called and thesentry object is destroyed[.](#string.io-2.sentence-1)

[3](#string.io-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5054)

If the function extracts no characters,ios_base​::​failbit is set in the input function's local error state
before setstate is called[.](#string.io-3.sentence-1)

[4](#string.io-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5059)

*Returns*: is[.](#string.io-4.sentence-1)

[ð](#lib:operator%3c%3c,basic_string)

`template<class charT, class traits, class Allocator>
  basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& os,
               const basic_string<charT, traits, Allocator>& str);
`

[5](#string.io-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5073)

*Effects*: Equivalent to: return os << basic_string_view<charT, traits>(str);

[ð](#lib:getline,basic_string)

`template<class charT, class traits, class Allocator>
  basic_istream<charT, traits>&
    getline(basic_istream<charT, traits>& is,
            basic_string<charT, traits, Allocator>& str,
            charT delim);
template<class charT, class traits, class Allocator>
  basic_istream<charT, traits>&
    getline(basic_istream<charT, traits>&& is,
            basic_string<charT, traits, Allocator>& str,
            charT delim);
`

[6](#string.io-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5093)

*Effects*: Behaves as an unformatted input function ([[istream.unformatted]](istream.unformatted "31.7.5.4 Unformatted input functions")),
except that it does not affect the value returned by subsequent calls tobasic_istream<>​::​gcount()[.](#string.io-6.sentence-1)

After constructing a sentry object,
if the sentry object returns true when converted to a value of type bool,
calls str.erase() and then extracts characters from is and appends them
to str as if by callingstr.append(1, c) until any of the following occurs:

- [(6.1)](#string.io-6.1)

end-of-file occurs on the input sequence;

- [(6.2)](#string.io-6.2)

traits​::​eq(c, delim) for the next available input character*c* (in which case,*c* is extracted but not appended);

- [(6.3)](#string.io-6.3)

str.max_size() characters are stored
(in which case,ios_base​::​failbit is set in the input function's local error state)[.](#string.io-6.sentence-2)

[7](#string.io-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5123)

The conditions are tested in the order shown[.](#string.io-7.sentence-1)

In any case,
after the last character is extracted, thesentry object is destroyed[.](#string.io-7.sentence-2)

[8](#string.io-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5130)

If the function extracts no characters,ios_base​::​failbit is set in the input function's local error state
before setstate is called[.](#string.io-8.sentence-1)

[9](#string.io-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5135)

*Returns*: is[.](#string.io-9.sentence-1)

[ð](#lib:getline,basic_string_)

`template<class charT, class traits, class Allocator>
  basic_istream<charT, traits>&
    getline(basic_istream<charT, traits>& is,
            basic_string<charT, traits, Allocator>& str);
template<class charT, class traits, class Allocator>
  basic_istream<charT, traits>&
    getline(basic_istream<charT, traits>&& is,
            basic_string<charT, traits, Allocator>& str);
`

[10](#string.io-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5153)

*Returns*: getline(is, str, is.widen('\n'))[.](#string.io-10.sentence-1)

#### [27.4.4.5](#string.erasure) Erasure [[string.erasure]](string.erasure)

[ð](#lib:erase,basic_string___)

`template<class charT, class traits, class Allocator, class U = charT>
  constexpr typename basic_string<charT, traits, Allocator>::size_type
    erase(basic_string<charT, traits, Allocator>& c, const U& value);
`

[1](#string.erasure-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5168)

*Effects*: Equivalent to:auto it = remove(c.begin(), c.end(), value);auto r = distance(it, c.end());
c.erase(it, c.end());return r;

[ð](#lib:erase_if,basic_string)

`template<class charT, class traits, class Allocator, class Predicate>
  constexpr typename basic_string<charT, traits, Allocator>::size_type
    erase_if(basic_string<charT, traits, Allocator>& c, Predicate pred);
`

[2](#string.erasure-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5187)

*Effects*: Equivalent to:auto it = remove_if(c.begin(), c.end(), pred);auto r = distance(it, c.end());
c.erase(it, c.end());return r;

### [27.4.5](#string.conversions) Numeric conversions [[string.conversions]](string.conversions)

[ð](#lib:stoi)

`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);
`

[1](#string.conversions-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5214)

*Effects*: The first two functions call strtol(str.c_str(), ptr, base),
and the last three functions call strtoul(str.c_str(), ptr, base),strtoll(str.c_str(), ptr, base), and strtoull(​str.c_str(), ptr,
base), respectively[.](#string.conversions-1.sentence-1)

Each function returns the converted result, if any[.](#string.conversions-1.sentence-2)

The
argument ptr designates a pointer to an object internal to the function
that is used to determine what to store at *idx[.](#string.conversions-1.sentence-3)

If the function does
not throw an exception and idx != nullptr, the function stores in *idx the index of the first unconverted element of str[.](#string.conversions-1.sentence-4)

[2](#string.conversions-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5225)

*Returns*: The converted result[.](#string.conversions-2.sentence-1)

[3](#string.conversions-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5229)

*Throws*: invalid_argument if strtol, strtoul,strtoll, or strtoull reports that no conversion can be
performed[.](#string.conversions-3.sentence-1)

Throws out_of_range if strtol, strtoul,strtoll or strtoull sets errno to ERANGE,
or if the converted value is outside the range of representable values
for the return type[.](#string.conversions-3.sentence-2)

[ð](#lib:stof)

`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);
`

[4](#string.conversions-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5249)

*Effects*: These functions callstrtof(str.c_str(), ptr), strtod(str.c_str(), ptr), andstrtold(​str.c_str(), ptr), respectively[.](#string.conversions-4.sentence-1)

Each function returns
the converted result, if any[.](#string.conversions-4.sentence-2)

The argument ptr designates a pointer to
an object internal to the function that is used to determine what to store at*idx[.](#string.conversions-4.sentence-3)

If the function does not throw an exception and idx != nullptr,
the function stores in *idx the index of the first unconverted element
of str[.](#string.conversions-4.sentence-4)

[5](#string.conversions-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5260)

*Returns*: The converted result[.](#string.conversions-5.sentence-1)

[6](#string.conversions-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5264)

*Throws*: invalid_argument if strtof, strtod, orstrtold reports that no conversion can be performed[.](#string.conversions-6.sentence-1)

Throwsout_of_range if strtof, strtod, orstrtold sets errno to ERANGE or if the converted value is outside the range of representable
values for the return type[.](#string.conversions-6.sentence-2)

[ð](#lib:to_string)

`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);
`

[7](#string.conversions-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5288)

*Returns*: format("{}", val)[.](#string.conversions-7.sentence-1)

[ð](#lib:stoi_)

`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);
`

[8](#string.conversions-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5307)

*Effects*: The first two functions call wcstol(str.c_str(), ptr, base),
and the last three functions call wcstoul(str.c_str(), ptr, base),wcstoll(str.c_str(), ptr, base), and wcstoull(​str.c_str(), ptr,
base), respectively[.](#string.conversions-8.sentence-1)

Each function returns the converted result, if any[.](#string.conversions-8.sentence-2)

The
argument ptr designates a pointer to an object internal to the function
that is used to determine what to store at *idx[.](#string.conversions-8.sentence-3)

If the function does
not throw an exception and idx != nullptr, the function stores in *idx the index of the first unconverted element of str[.](#string.conversions-8.sentence-4)

[9](#string.conversions-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5318)

*Returns*: The converted result[.](#string.conversions-9.sentence-1)

[10](#string.conversions-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5322)

*Throws*: invalid_argument if wcstol, wcstoul, wcstoll, orwcstoull reports that no conversion can be performed[.](#string.conversions-10.sentence-1)

Throwsout_of_range if the converted value is outside the range of representable values
for the return type[.](#string.conversions-10.sentence-2)

[ð](#lib:stof_)

`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);
`

[11](#string.conversions-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5340)

*Effects*: These functions call wcstof(str.c_str(), ptr),wcstod(str.c_str(), ptr), and wcstold(​str.c_str(), ptr),
respectively[.](#string.conversions-11.sentence-1)

Each function returns the converted
result, if any[.](#string.conversions-11.sentence-2)

The argument ptr designates a pointer to an object internal to
the function that is used to determine what to store at *idx[.](#string.conversions-11.sentence-3)

If the function
does not throw an exception and idx != nullptr, the function stores in *idx the index of the first unconverted element of str[.](#string.conversions-11.sentence-4)

[12](#string.conversions-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5350)

*Returns*: The converted result[.](#string.conversions-12.sentence-1)

[13](#string.conversions-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5354)

*Throws*: invalid_argument if wcstof, wcstod, or wcstold reports that no
conversion can be performed[.](#string.conversions-13.sentence-1)

Throws out_of_range if wcstof, wcstod, orwcstold sets errno to ERANGE[.](#string.conversions-13.sentence-2)

[ð](#lib:to_wstring)

`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);
`

[14](#string.conversions-14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5375)

*Returns*: format(L"{}", val)[.](#string.conversions-14.sentence-1)

### [27.4.6](#basic.string.hash) Hash support [[basic.string.hash]](basic.string.hash)

[ð](#lib:hash,basic_string)

`template<class A> struct hash<basic_string<char, char_traits<char>, A>>;
template<class A> struct hash<basic_string<char8_t, char_traits<char8_t>, A>>;
template<class A> struct hash<basic_string<char16_t, char_traits<char16_t>, A>>;
template<class A> struct hash<basic_string<char32_t, char_traits<char32_t>, A>>;
template<class A> struct hash<basic_string<wchar_t, char_traits<wchar_t>, A>>;
`

[1](#basic.string.hash-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5392)

If S is one of these string types,SV is the corresponding string view type, ands is an object of type S,
then hash<S>()(s) == hash<SV>()(SV(s))[.](#basic.string.hash-1.sentence-1)

### [27.4.7](#basic.string.literals) Suffix for basic_string literals [[basic.string.literals]](basic.string.literals)

[ð](#lib:operator%22%22s,string)

`constexpr string operator""s(const char* str, size_t len);
`

[1](#basic.string.literals-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5407)

*Returns*: string{str, len}[.](#basic.string.literals-1.sentence-1)

[ð](#lib:operator%22%22s,u8string)

`constexpr u8string operator""s(const char8_t* str, size_t len);
`

[2](#basic.string.literals-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5417)

*Returns*: u8string{str, len}[.](#basic.string.literals-2.sentence-1)

[ð](#lib:operator%22%22s,u16string)

`constexpr u16string operator""s(const char16_t* str, size_t len);
`

[3](#basic.string.literals-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5427)

*Returns*: u16string{str, len}[.](#basic.string.literals-3.sentence-1)

[ð](#lib:operator%22%22s,u32string)

`constexpr u32string operator""s(const char32_t* str, size_t len);
`

[4](#basic.string.literals-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5437)

*Returns*: u32string{str, len}[.](#basic.string.literals-4.sentence-1)

[ð](#lib:operator%22%22s,wstring)

`constexpr wstring operator""s(const wchar_t* str, size_t len);
`

[5](#basic.string.literals-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5447)

*Returns*: wstring{str, len}[.](#basic.string.literals-5.sentence-1)

[6](#basic.string.literals-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5452)

[*Note [1](#basic.string.literals-note-1)*:

The same suffix s is used for 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[.](#basic.string.literals-6.sentence-1)

â *end note*]
