2 //===----------------------------------------------------------------------===//
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP_STRING
11 #define _LIBCPP_STRING
17 #include <initializer_list>
22 template <class stateT>
28 fpos(streamoff = streamoff());
30 operator streamoff() const;
35 fpos& operator+=(streamoff);
36 fpos operator+ (streamoff) const;
37 fpos& operator-=(streamoff);
38 fpos operator- (streamoff) const;
41 template <class stateT> streamoff operator-(const fpos<stateT>& x, const fpos<stateT>& y);
43 template <class stateT> bool operator==(const fpos<stateT>& x, const fpos<stateT>& y);
44 template <class stateT> bool operator!=(const fpos<stateT>& x, const fpos<stateT>& y);
46 template <class charT>
49 using char_type = charT;
51 using off_type = streamoff;
52 using pos_type = streampos;
53 using state_type = mbstate_t;
54 using comparison_category = strong_ordering; // Since C++20 only for the specializations
55 // char, wchar_t, char8_t, char16_t, and char32_t.
57 static void assign(char_type& c1, const char_type& c2) noexcept;
58 static constexpr bool eq(char_type c1, char_type c2) noexcept;
59 static constexpr bool lt(char_type c1, char_type c2) noexcept;
61 static int compare(const char_type* s1, const char_type* s2, size_t n);
62 static size_t length(const char_type* s);
63 static const char_type* find(const char_type* s, size_t n, const char_type& a);
64 static char_type* move(char_type* s1, const char_type* s2, size_t n);
65 static char_type* copy(char_type* s1, const char_type* s2, size_t n);
66 static char_type* assign(char_type* s, size_t n, char_type a);
68 static constexpr int_type not_eof(int_type c) noexcept;
69 static constexpr char_type to_char_type(int_type c) noexcept;
70 static constexpr int_type to_int_type(char_type c) noexcept;
71 static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept;
72 static constexpr int_type eof() noexcept;
75 template <> struct char_traits<char>;
76 template <> struct char_traits<wchar_t>;
77 template <> struct char_traits<char8_t>; // C++20
78 template <> struct char_traits<char16_t>;
79 template <> struct char_traits<char32_t>;
81 template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
86 typedef traits traits_type;
87 typedef typename traits_type::char_type value_type;
88 typedef Allocator allocator_type;
89 typedef typename allocator_type::size_type size_type;
90 typedef typename allocator_type::difference_type difference_type;
91 typedef typename allocator_type::reference reference;
92 typedef typename allocator_type::const_reference const_reference;
93 typedef typename allocator_type::pointer pointer;
94 typedef typename allocator_type::const_pointer const_pointer;
95 typedef implementation-defined iterator;
96 typedef implementation-defined const_iterator;
97 typedef std::reverse_iterator<iterator> reverse_iterator;
98 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
100 static const size_type npos = -1;
103 noexcept(is_nothrow_default_constructible<allocator_type>::value); // constexpr since C++20
104 explicit basic_string(const allocator_type& a); // constexpr since C++20
105 basic_string(const basic_string& str); // constexpr since C++20
106 basic_string(basic_string&& str)
107 noexcept(is_nothrow_move_constructible<allocator_type>::value); // constexpr since C++20
108 basic_string(const basic_string& str, size_type pos,
109 const allocator_type& a = allocator_type()); // constexpr since C++20
110 basic_string(const basic_string& str, size_type pos, size_type n,
111 const Allocator& a = Allocator()); // constexpr since C++20
112 constexpr basic_string(
113 basic_string&& str, size_type pos, const Allocator& a = Allocator()); // since C++23
114 constexpr basic_string(
115 basic_string&& str, size_type pos, size_type n, const Allocator& a = Allocator()); // since C++23
117 basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator()); // C++17, constexpr since C++20
119 explicit basic_string(const T& t, const Allocator& a = Allocator()); // C++17, constexpr since C++20
120 basic_string(const value_type* s, const allocator_type& a = allocator_type()); // constexpr since C++20
121 basic_string(const value_type* s, size_type n, const allocator_type& a = allocator_type()); // constexpr since C++20
122 basic_string(nullptr_t) = delete; // C++23
123 basic_string(size_type n, value_type c, const allocator_type& a = allocator_type()); // constexpr since C++20
124 template<class InputIterator>
125 basic_string(InputIterator begin, InputIterator end,
126 const allocator_type& a = allocator_type()); // constexpr since C++20
127 template<container-compatible-range<charT> R>
128 constexpr basic_string(from_range_t, R&& rg, const Allocator& a = Allocator()); // since C++23
129 basic_string(initializer_list<value_type>, const Allocator& = Allocator()); // constexpr since C++20
130 basic_string(const basic_string&, const Allocator&); // constexpr since C++20
131 basic_string(basic_string&&, const Allocator&); // constexpr since C++20
133 ~basic_string(); // constexpr since C++20
135 operator basic_string_view<charT, traits>() const noexcept; // constexpr since C++20
137 basic_string& operator=(const basic_string& str); // constexpr since C++20
139 basic_string& operator=(const T& t); // C++17, constexpr since C++20
140 basic_string& operator=(basic_string&& str)
142 allocator_type::propagate_on_container_move_assignment::value ||
143 allocator_type::is_always_equal::value ); // C++17, constexpr since C++20
144 basic_string& operator=(const value_type* s); // constexpr since C++20
145 basic_string& operator=(nullptr_t) = delete; // C++23
146 basic_string& operator=(value_type c); // constexpr since C++20
147 basic_string& operator=(initializer_list<value_type>); // constexpr since C++20
149 iterator begin() noexcept; // constexpr since C++20
150 const_iterator begin() const noexcept; // constexpr since C++20
151 iterator end() noexcept; // constexpr since C++20
152 const_iterator end() const noexcept; // constexpr since C++20
154 reverse_iterator rbegin() noexcept; // constexpr since C++20
155 const_reverse_iterator rbegin() const noexcept; // constexpr since C++20
156 reverse_iterator rend() noexcept; // constexpr since C++20
157 const_reverse_iterator rend() const noexcept; // constexpr since C++20
159 const_iterator cbegin() const noexcept; // constexpr since C++20
160 const_iterator cend() const noexcept; // constexpr since C++20
161 const_reverse_iterator crbegin() const noexcept; // constexpr since C++20
162 const_reverse_iterator crend() const noexcept; // constexpr since C++20
164 size_type size() const noexcept; // constexpr since C++20
165 size_type length() const noexcept; // constexpr since C++20
166 size_type max_size() const noexcept; // constexpr since C++20
167 size_type capacity() const noexcept; // constexpr since C++20
169 void resize(size_type n, value_type c); // constexpr since C++20
170 void resize(size_type n); // constexpr since C++20
172 template<class Operation>
173 constexpr void resize_and_overwrite(size_type n, Operation op); // since C++23
175 void reserve(size_type res_arg); // constexpr since C++20
176 void reserve(); // deprecated in C++20
177 void shrink_to_fit(); // constexpr since C++20
178 void clear() noexcept; // constexpr since C++20
179 bool empty() const noexcept; // constexpr since C++20
181 const_reference operator[](size_type pos) const; // constexpr since C++20
182 reference operator[](size_type pos); // constexpr since C++20
184 const_reference at(size_type n) const; // constexpr since C++20
185 reference at(size_type n); // constexpr since C++20
187 basic_string& operator+=(const basic_string& str); // constexpr since C++20
189 basic_string& operator+=(const T& t); // C++17, constexpr since C++20
190 basic_string& operator+=(const value_type* s); // constexpr since C++20
191 basic_string& operator+=(value_type c); // constexpr since C++20
192 basic_string& operator+=(initializer_list<value_type>); // constexpr since C++20
194 basic_string& append(const basic_string& str); // constexpr since C++20
196 basic_string& append(const T& t); // C++17, constexpr since C++20
197 basic_string& append(const basic_string& str, size_type pos, size_type n=npos); // C++14, constexpr since C++20
199 basic_string& append(const T& t, size_type pos, size_type n=npos); // C++17, constexpr since C++20
200 basic_string& append(const value_type* s, size_type n); // constexpr since C++20
201 basic_string& append(const value_type* s); // constexpr since C++20
202 basic_string& append(size_type n, value_type c); // constexpr since C++20
203 template<class InputIterator>
204 basic_string& append(InputIterator first, InputIterator last); // constexpr since C++20
205 template<container-compatible-range<charT> R>
206 constexpr basic_string& append_range(R&& rg); // C++23
207 basic_string& append(initializer_list<value_type>); // constexpr since C++20
209 void push_back(value_type c); // constexpr since C++20
210 void pop_back(); // constexpr since C++20
211 reference front(); // constexpr since C++20
212 const_reference front() const; // constexpr since C++20
213 reference back(); // constexpr since C++20
214 const_reference back() const; // constexpr since C++20
216 basic_string& assign(const basic_string& str); // constexpr since C++20
218 basic_string& assign(const T& t); // C++17, constexpr since C++20
219 basic_string& assign(basic_string&& str); // constexpr since C++20
220 basic_string& assign(const basic_string& str, size_type pos, size_type n=npos); // C++14, constexpr since C++20
222 basic_string& assign(const T& t, size_type pos, size_type n=npos); // C++17, constexpr since C++20
223 basic_string& assign(const value_type* s, size_type n); // constexpr since C++20
224 basic_string& assign(const value_type* s); // constexpr since C++20
225 basic_string& assign(size_type n, value_type c); // constexpr since C++20
226 template<class InputIterator>
227 basic_string& assign(InputIterator first, InputIterator last); // constexpr since C++20
228 template<container-compatible-range<charT> R>
229 constexpr basic_string& assign_range(R&& rg); // C++23
230 basic_string& assign(initializer_list<value_type>); // constexpr since C++20
232 basic_string& insert(size_type pos1, const basic_string& str); // constexpr since C++20
234 basic_string& insert(size_type pos1, const T& t); // constexpr since C++20
235 basic_string& insert(size_type pos1, const basic_string& str,
236 size_type pos2, size_type n); // constexpr since C++20
238 basic_string& insert(size_type pos1, const T& t, size_type pos2, size_type n); // C++17, constexpr since C++20
239 basic_string& insert(size_type pos, const value_type* s, size_type n=npos); // C++14, constexpr since C++20
240 basic_string& insert(size_type pos, const value_type* s); // constexpr since C++20
241 basic_string& insert(size_type pos, size_type n, value_type c); // constexpr since C++20
242 iterator insert(const_iterator p, value_type c); // constexpr since C++20
243 iterator insert(const_iterator p, size_type n, value_type c); // constexpr since C++20
244 template<class InputIterator>
245 iterator insert(const_iterator p, InputIterator first, InputIterator last); // constexpr since C++20
246 template<container-compatible-range<charT> R>
247 constexpr iterator insert_range(const_iterator p, R&& rg); // C++23
248 iterator insert(const_iterator p, initializer_list<value_type>); // constexpr since C++20
250 basic_string& erase(size_type pos = 0, size_type n = npos); // constexpr since C++20
251 iterator erase(const_iterator position); // constexpr since C++20
252 iterator erase(const_iterator first, const_iterator last); // constexpr since C++20
254 basic_string& replace(size_type pos1, size_type n1, const basic_string& str); // constexpr since C++20
256 basic_string& replace(size_type pos1, size_type n1, const T& t); // C++17, constexpr since C++20
257 basic_string& replace(size_type pos1, size_type n1, const basic_string& str,
258 size_type pos2, size_type n2=npos); // C++14, constexpr since C++20
260 basic_string& replace(size_type pos1, size_type n1, const T& t,
261 size_type pos2, size_type n); // C++17, constexpr since C++20
262 basic_string& replace(size_type pos, size_type n1, const value_type* s, size_type n2); // constexpr since C++20
263 basic_string& replace(size_type pos, size_type n1, const value_type* s); // constexpr since C++20
264 basic_string& replace(size_type pos, size_type n1, size_type n2, value_type c); // constexpr since C++20
265 basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str); // constexpr since C++20
267 basic_string& replace(const_iterator i1, const_iterator i2, const T& t); // C++17, constexpr since C++20
268 basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s, size_type n); // constexpr since C++20
269 basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s); // constexpr since C++20
270 basic_string& replace(const_iterator i1, const_iterator i2, size_type n, value_type c); // constexpr since C++20
271 template<class InputIterator>
272 basic_string& replace(const_iterator i1, const_iterator i2, InputIterator j1, InputIterator j2); // constexpr since C++20
273 template<container-compatible-range<charT> R>
274 constexpr basic_string& replace_with_range(const_iterator i1, const_iterator i2, R&& rg); // C++23
275 basic_string& replace(const_iterator i1, const_iterator i2, initializer_list<value_type>); // constexpr since C++20
277 size_type copy(value_type* s, size_type n, size_type pos = 0) const; // constexpr since C++20
278 basic_string substr(size_type pos = 0, size_type n = npos) const; // constexpr in C++20, removed in C++23
279 basic_string substr(size_type pos = 0, size_type n = npos) const&; // since C++23
280 constexpr basic_string substr(size_type pos = 0, size_type n = npos) &&; // since C++23
281 void swap(basic_string& str)
282 noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
283 allocator_traits<allocator_type>::is_always_equal::value); // C++17, constexpr since C++20
285 const value_type* c_str() const noexcept; // constexpr since C++20
286 const value_type* data() const noexcept; // constexpr since C++20
287 value_type* data() noexcept; // C++17, constexpr since C++20
289 allocator_type get_allocator() const noexcept; // constexpr since C++20
291 size_type find(const basic_string& str, size_type pos = 0) const noexcept; // constexpr since C++20
293 size_type find(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension, constexpr since C++20
294 size_type find(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20
295 size_type find(const value_type* s, size_type pos = 0) const noexcept; // constexpr since C++20
296 size_type find(value_type c, size_type pos = 0) const noexcept; // constexpr since C++20
298 size_type rfind(const basic_string& str, size_type pos = npos) const noexcept; // constexpr since C++20
300 size_type rfind(const T& t, size_type pos = npos) const noexcept; // C++17, noexcept as an extension, constexpr since C++20
301 size_type rfind(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20
302 size_type rfind(const value_type* s, size_type pos = npos) const noexcept; // constexpr since C++20
303 size_type rfind(value_type c, size_type pos = npos) const noexcept; // constexpr since C++20
305 size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept; // constexpr since C++20
307 size_type find_first_of(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension, constexpr since C++20
308 size_type find_first_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20
309 size_type find_first_of(const value_type* s, size_type pos = 0) const noexcept; // constexpr since C++20
310 size_type find_first_of(value_type c, size_type pos = 0) const noexcept; // constexpr since C++20
312 size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept; // constexpr since C++20
314 size_type find_last_of(const T& t, size_type pos = npos) const noexcept noexcept; // C++17, noexcept as an extension, constexpr since C++20
315 size_type find_last_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20
316 size_type find_last_of(const value_type* s, size_type pos = npos) const noexcept; // constexpr since C++20
317 size_type find_last_of(value_type c, size_type pos = npos) const noexcept; // constexpr since C++20
319 size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept; // constexpr since C++20
321 size_type find_first_not_of(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension, constexpr since C++20
322 size_type find_first_not_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20
323 size_type find_first_not_of(const value_type* s, size_type pos = 0) const noexcept; // constexpr since C++20
324 size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept; // constexpr since C++20
326 size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept; // constexpr since C++20
328 size_type find_last_not_of(const T& t, size_type pos = npos) const noexcept; // C++17, noexcept as an extension, constexpr since C++20
329 size_type find_last_not_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20
330 size_type find_last_not_of(const value_type* s, size_type pos = npos) const noexcept; // constexpr since C++20
331 size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept; // constexpr since C++20
333 int compare(const basic_string& str) const noexcept; // constexpr since C++20
335 int compare(const T& t) const noexcept; // C++17, noexcept as an extension, constexpr since C++20
336 int compare(size_type pos1, size_type n1, const basic_string& str) const; // constexpr since C++20
338 int compare(size_type pos1, size_type n1, const T& t) const; // C++17, constexpr since C++20
339 int compare(size_type pos1, size_type n1, const basic_string& str,
340 size_type pos2, size_type n2=npos) const; // C++14, constexpr since C++20
342 int compare(size_type pos1, size_type n1, const T& t,
343 size_type pos2, size_type n2=npos) const; // C++17, constexpr since C++20
344 int compare(const value_type* s) const noexcept; // constexpr since C++20
345 int compare(size_type pos1, size_type n1, const value_type* s) const; // constexpr since C++20
346 int compare(size_type pos1, size_type n1, const value_type* s, size_type n2) const; // constexpr since C++20
348 constexpr bool starts_with(basic_string_view<charT, traits> sv) const noexcept; // C++20
349 constexpr bool starts_with(charT c) const noexcept; // C++20
350 constexpr bool starts_with(const charT* s) const; // C++20
351 constexpr bool ends_with(basic_string_view<charT, traits> sv) const noexcept; // C++20
352 constexpr bool ends_with(charT c) const noexcept; // C++20
353 constexpr bool ends_with(const charT* s) const; // C++20
355 constexpr bool contains(basic_string_view<charT, traits> sv) const noexcept; // C++23
356 constexpr bool contains(charT c) const noexcept; // C++23
357 constexpr bool contains(const charT* s) const; // C++23
360 template<class InputIterator,
361 class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
362 basic_string(InputIterator, InputIterator, Allocator = Allocator())
363 -> basic_string<typename iterator_traits<InputIterator>::value_type,
364 char_traits<typename iterator_traits<InputIterator>::value_type>,
367 template<ranges::input_range R,
368 class Allocator = allocator<ranges::range_value_t<R>>>
369 basic_string(from_range_t, R&&, Allocator = Allocator())
370 -> basic_string<ranges::range_value_t<R>, char_traits<ranges::range_value_t<R>>,
373 template<class charT,
375 class Allocator = allocator<charT>>
376 explicit basic_string(basic_string_view<charT, traits>, const Allocator& = Allocator())
377 -> basic_string<charT, traits, Allocator>; // C++17
379 template<class charT,
381 class Allocator = allocator<charT>>
382 basic_string(basic_string_view<charT, traits>,
383 typename see below::size_type, typename see below::size_type,
384 const Allocator& = Allocator())
385 -> basic_string<charT, traits, Allocator>; // C++17
387 template<class charT, class traits, class Allocator>
388 basic_string<charT, traits, Allocator>
389 operator+(const basic_string<charT, traits, Allocator>& lhs,
390 const basic_string<charT, traits, Allocator>& rhs); // constexpr since C++20
392 template<class charT, class traits, class Allocator>
393 basic_string<charT, traits, Allocator>
394 operator+(const charT* lhs , const basic_string<charT,traits,Allocator>&rhs); // constexpr since C++20
396 template<class charT, class traits, class Allocator>
397 basic_string<charT, traits, Allocator>
398 operator+(charT lhs, const basic_string<charT,traits,Allocator>& rhs); // constexpr since C++20
400 template<class charT, class traits, class Allocator>
401 basic_string<charT, traits, Allocator>
402 operator+(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs); // constexpr since C++20
404 template<class charT, class traits, class Allocator>
405 basic_string<charT, traits, Allocator>
406 operator+(const basic_string<charT, traits, Allocator>& lhs, charT rhs); // constexpr since C++20
408 template<class charT, class traits, class Allocator>
409 bool operator==(const basic_string<charT, traits, Allocator>& lhs,
410 const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20
412 template<class charT, class traits, class Allocator>
413 bool operator==(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20
415 template<class charT, class traits, class Allocator>
416 bool operator==(const basic_string<charT,traits,Allocator>& lhs, const charT* rhs) noexcept; // constexpr since C++20
418 template<class charT, class traits, class Allocator>
419 bool operator!=(const basic_string<charT,traits,Allocator>& lhs,
420 const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20
422 template<class charT, class traits, class Allocator>
423 bool operator!=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20
425 template<class charT, class traits, class Allocator>
426 bool operator!=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // removed in C++20
428 template<class charT, class traits, class Allocator>
429 bool operator< (const basic_string<charT, traits, Allocator>& lhs,
430 const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20
432 template<class charT, class traits, class Allocator>
433 bool operator< (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // removed in C++20
435 template<class charT, class traits, class Allocator>
436 bool operator< (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20
438 template<class charT, class traits, class Allocator>
439 bool operator> (const basic_string<charT, traits, Allocator>& lhs,
440 const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20
442 template<class charT, class traits, class Allocator>
443 bool operator> (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // removed in C++20
445 template<class charT, class traits, class Allocator>
446 bool operator> (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20
448 template<class charT, class traits, class Allocator>
449 bool operator<=(const basic_string<charT, traits, Allocator>& lhs,
450 const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20
452 template<class charT, class traits, class Allocator>
453 bool operator<=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // removed in C++20
455 template<class charT, class traits, class Allocator>
456 bool operator<=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20
458 template<class charT, class traits, class Allocator>
459 bool operator>=(const basic_string<charT, traits, Allocator>& lhs,
460 const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20
462 template<class charT, class traits, class Allocator>
463 bool operator>=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // removed in C++20
465 template<class charT, class traits, class Allocator>
466 bool operator>=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20
468 template<class charT, class traits, class Allocator> // since C++20
469 constexpr see below operator<=>(const basic_string<charT, traits, Allocator>& lhs,
470 const basic_string<charT, traits, Allocator>& rhs) noexcept;
472 template<class charT, class traits, class Allocator> // since C++20
473 constexpr see below operator<=>(const basic_string<charT, traits, Allocator>& lhs,
474 const charT* rhs) noexcept;
476 template<class charT, class traits, class Allocator>
477 void swap(basic_string<charT, traits, Allocator>& lhs,
478 basic_string<charT, traits, Allocator>& rhs)
479 noexcept(noexcept(lhs.swap(rhs))); // constexpr since C++20
481 template<class charT, class traits, class Allocator>
482 basic_istream<charT, traits>&
483 operator>>(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str);
485 template<class charT, class traits, class Allocator>
486 basic_ostream<charT, traits>&
487 operator<<(basic_ostream<charT, traits>& os, const basic_string<charT, traits, Allocator>& str);
489 template<class charT, class traits, class Allocator>
490 basic_istream<charT, traits>&
491 getline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str,
494 template<class charT, class traits, class Allocator>
495 basic_istream<charT, traits>&
496 getline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str);
498 template<class charT, class traits, class Allocator, class U>
499 typename basic_string<charT, traits, Allocator>::size_type
500 erase(basic_string<charT, traits, Allocator>& c, const U& value); // C++20
501 template<class charT, class traits, class Allocator, class Predicate>
502 typename basic_string<charT, traits, Allocator>::size_type
503 erase_if(basic_string<charT, traits, Allocator>& c, Predicate pred); // C++20
505 typedef basic_string<char> string;
506 typedef basic_string<wchar_t> wstring;
507 typedef basic_string<char8_t> u8string; // C++20
508 typedef basic_string<char16_t> u16string;
509 typedef basic_string<char32_t> u32string;
511 int stoi (const string& str, size_t* idx = nullptr, int base = 10);
512 long stol (const string& str, size_t* idx = nullptr, int base = 10);
513 unsigned long stoul (const string& str, size_t* idx = nullptr, int base = 10);
514 long long stoll (const string& str, size_t* idx = nullptr, int base = 10);
515 unsigned long long stoull(const string& str, size_t* idx = nullptr, int base = 10);
517 float stof (const string& str, size_t* idx = nullptr);
518 double stod (const string& str, size_t* idx = nullptr);
519 long double stold(const string& str, size_t* idx = nullptr);
521 string to_string(int val);
522 string to_string(unsigned val);
523 string to_string(long val);
524 string to_string(unsigned long val);
525 string to_string(long long val);
526 string to_string(unsigned long long val);
527 string to_string(float val);
528 string to_string(double val);
529 string to_string(long double val);
531 int stoi (const wstring& str, size_t* idx = nullptr, int base = 10);
532 long stol (const wstring& str, size_t* idx = nullptr, int base = 10);
533 unsigned long stoul (const wstring& str, size_t* idx = nullptr, int base = 10);
534 long long stoll (const wstring& str, size_t* idx = nullptr, int base = 10);
535 unsigned long long stoull(const wstring& str, size_t* idx = nullptr, int base = 10);
537 float stof (const wstring& str, size_t* idx = nullptr);
538 double stod (const wstring& str, size_t* idx = nullptr);
539 long double stold(const wstring& str, size_t* idx = nullptr);
541 wstring to_wstring(int val);
542 wstring to_wstring(unsigned val);
543 wstring to_wstring(long val);
544 wstring to_wstring(unsigned long val);
545 wstring to_wstring(long long val);
546 wstring to_wstring(unsigned long long val);
547 wstring to_wstring(float val);
548 wstring to_wstring(double val);
549 wstring to_wstring(long double val);
551 template <> struct hash<string>;
552 template <> struct hash<u8string>; // C++20
553 template <> struct hash<u16string>;
554 template <> struct hash<u32string>;
555 template <> struct hash<wstring>;
557 basic_string<char> operator""s( const char *str, size_t len ); // C++14, constexpr since C++20
558 basic_string<wchar_t> operator""s( const wchar_t *str, size_t len ); // C++14, constexpr since C++20
559 constexpr basic_string<char8_t> operator""s( const char8_t *str, size_t len ); // C++20
560 basic_string<char16_t> operator""s( const char16_t *str, size_t len ); // C++14, constexpr since C++20
561 basic_string<char32_t> operator""s( const char32_t *str, size_t len ); // C++14, constexpr since C++20
567 #include <__algorithm/max.h>
568 #include <__algorithm/min.h>
569 #include <__algorithm/remove.h>
570 #include <__algorithm/remove_if.h>
571 #include <__assert> // all public C++ headers provide the assertion handler
573 #include <__format/enable_insertable.h>
574 #include <__functional/hash.h>
575 #include <__functional/unary_function.h>
576 #include <__fwd/string.h>
577 #include <__ios/fpos.h>
578 #include <__iterator/distance.h>
579 #include <__iterator/iterator_traits.h>
580 #include <__iterator/reverse_iterator.h>
581 #include <__iterator/wrap_iter.h>
582 #include <__memory/addressof.h>
583 #include <__memory/allocate_at_least.h>
584 #include <__memory/allocator.h>
585 #include <__memory/allocator_traits.h>
586 #include <__memory/compressed_pair.h>
587 #include <__memory/construct_at.h>
588 #include <__memory/pointer_traits.h>
589 #include <__memory/swap_allocator.h>
590 #include <__memory_resource/polymorphic_allocator.h>
591 #include <__ranges/access.h>
592 #include <__ranges/concepts.h>
593 #include <__ranges/container_compatible_range.h>
594 #include <__ranges/from_range.h>
595 #include <__ranges/size.h>
596 #include <__string/char_traits.h>
597 #include <__string/extern_template_lists.h>
598 #include <__type_traits/is_allocator.h>
599 #include <__type_traits/is_array.h>
600 #include <__type_traits/is_convertible.h>
601 #include <__type_traits/is_nothrow_default_constructible.h>
602 #include <__type_traits/is_nothrow_move_assignable.h>
603 #include <__type_traits/is_same.h>
604 #include <__type_traits/is_standard_layout.h>
605 #include <__type_traits/is_trivial.h>
606 #include <__type_traits/noexcept_move_assign_container.h>
607 #include <__type_traits/remove_cvref.h>
608 #include <__type_traits/void_t.h>
609 #include <__utility/auto_cast.h>
610 #include <__utility/declval.h>
611 #include <__utility/forward.h>
612 #include <__utility/is_pointer_in_range.h>
613 #include <__utility/move.h>
614 #include <__utility/swap.h>
615 #include <__utility/unreachable.h>
617 #include <cstdio> // EOF
621 #include <string_view>
624 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
628 // standard-mandated includes
631 #include <__iterator/access.h>
632 #include <__iterator/data.h>
633 #include <__iterator/empty.h>
634 #include <__iterator/reverse_access.h>
635 #include <__iterator/size.h>
639 #include <initializer_list>
641 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
642 # pragma GCC system_header
646 #include <__undef_macros>
649 _LIBCPP_BEGIN_NAMESPACE_STD
653 template<class _CharT, class _Traits, class _Allocator>
654 basic_string<_CharT, _Traits, _Allocator>
655 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
656 operator+(const basic_string<_CharT, _Traits, _Allocator>& __x,
657 const basic_string<_CharT, _Traits, _Allocator>& __y);
659 template<class _CharT, class _Traits, class _Allocator>
660 _LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX20
661 basic_string<_CharT, _Traits, _Allocator>
662 operator+(const _CharT* __x, const basic_string<_CharT,_Traits,_Allocator>& __y);
664 template<class _CharT, class _Traits, class _Allocator>
665 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
666 basic_string<_CharT, _Traits, _Allocator>
667 operator+(_CharT __x, const basic_string<_CharT,_Traits,_Allocator>& __y);
669 template<class _CharT, class _Traits, class _Allocator>
670 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
671 basic_string<_CharT, _Traits, _Allocator>
672 operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const _CharT* __y);
674 template<class _CharT, class _Traits, class _Allocator>
675 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
676 basic_string<_CharT, _Traits, _Allocator>
677 operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y);
679 extern template _LIBCPP_EXPORTED_FROM_ABI string operator+
680 <char, char_traits<char>, allocator<char> >(char const*, string const&);
682 template <class _Iter>
683 struct __string_is_trivial_iterator : public false_type {};
686 struct __string_is_trivial_iterator<_Tp*>
687 : public is_arithmetic<_Tp> {};
689 template <class _Iter>
690 struct __string_is_trivial_iterator<__wrap_iter<_Iter> >
691 : public __string_is_trivial_iterator<_Iter> {};
693 template <class _CharT, class _Traits, class _Tp>
694 struct __can_be_converted_to_string_view : public _BoolConstant<
695 is_convertible<const _Tp&, basic_string_view<_CharT, _Traits> >::value &&
696 !is_convertible<const _Tp&, const _CharT*>::value
699 struct __uninitialized_size_tag {};
700 struct __init_with_sentinel_tag {};
702 template<class _CharT, class _Traits, class _Allocator>
706 typedef basic_string __self;
707 typedef basic_string_view<_CharT, _Traits> __self_view;
708 typedef _Traits traits_type;
709 typedef _CharT value_type;
710 typedef _Allocator allocator_type;
711 typedef allocator_traits<allocator_type> __alloc_traits;
712 typedef typename __alloc_traits::size_type size_type;
713 typedef typename __alloc_traits::difference_type difference_type;
714 typedef value_type& reference;
715 typedef const value_type& const_reference;
716 typedef typename __alloc_traits::pointer pointer;
717 typedef typename __alloc_traits::const_pointer const_pointer;
719 static_assert((!is_array<value_type>::value), "Character type of basic_string must not be an array");
720 static_assert(( is_standard_layout<value_type>::value), "Character type of basic_string must be standard-layout");
721 static_assert(( is_trivial<value_type>::value), "Character type of basic_string must be trivial");
722 static_assert(( is_same<_CharT, typename traits_type::char_type>::value),
723 "traits_type::char_type must be the same type as CharT");
724 static_assert(( is_same<typename allocator_type::value_type, value_type>::value),
725 "Allocator::value_type must be same type as value_type");
727 static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value,
728 "[allocator.requirements] states that rebinding an allocator to the same type should result in the "
729 "original allocator");
731 // TODO: Implement iterator bounds checking without requiring the global database.
732 typedef __wrap_iter<pointer> iterator;
733 typedef __wrap_iter<const_pointer> const_iterator;
734 typedef std::reverse_iterator<iterator> reverse_iterator;
735 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
738 static_assert(CHAR_BIT == 8, "This implementation assumes that one byte contains 8 bits");
740 #ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
746 size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1;
747 size_type __is_long_ : 1;
750 enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ?
751 (sizeof(__long) - 1)/sizeof(value_type) : 2};
755 value_type __data_[__min_cap];
756 unsigned char __padding_[sizeof(value_type) - 1];
757 unsigned char __size_ : 7;
758 unsigned char __is_long_ : 1;
761 // The __endian_factor is required because the field we use to store the size
762 // has one fewer bit than it would if it were not a bitfield.
764 // If the LSB is used to store the short-flag in the short string representation,
765 // we have to multiply the size by two when it is stored and divide it by two when
766 // it is loaded to make sure that we always store an even number. In the long string
767 // representation, we can ignore this because we can assume that we always allocate
768 // an even amount of value_types.
770 // If the MSB is used for the short-flag, the max_size() is numeric_limits<size_type>::max() / 2.
771 // This does not impact the short string representation, since we never need the MSB
772 // for representing the size of a short string anyway.
774 #ifdef _LIBCPP_BIG_ENDIAN
775 static const size_type __endian_factor = 2;
777 static const size_type __endian_factor = 1;
780 #else // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
782 #ifdef _LIBCPP_BIG_ENDIAN
783 static const size_type __endian_factor = 1;
785 static const size_type __endian_factor = 2;
788 // Attribute 'packed' is used to keep the layout compatible with the
789 // previous definition that did not use bit fields. This is because on
790 // some platforms bit fields have a default size rather than the actual
791 // size used, e.g., it is 4 bytes on AIX. See D128285 for details.
794 struct _LIBCPP_PACKED {
795 size_type __is_long_ : 1;
796 size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1;
802 enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ?
803 (sizeof(__long) - 1)/sizeof(value_type) : 2};
807 struct _LIBCPP_PACKED {
808 unsigned char __is_long_ : 1;
809 unsigned char __size_ : 7;
811 char __padding_[sizeof(value_type) - 1];
812 value_type __data_[__min_cap];
815 #endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
817 static_assert(sizeof(__short) == (sizeof(value_type) * (__min_cap + 1)), "__short has an unexpected size.");
819 union __ulx{__long __lx; __short __lxx;};
821 enum {__n_words = sizeof(__ulx) / sizeof(size_type)};
825 size_type __words[__n_words];
838 __compressed_pair<__rep, allocator_type> __r_;
840 // Construct a string with the given allocator and enough storage to hold `__size` characters, but
841 // don't initialize the characters. The contents of the string, including the null terminator, must be
842 // initialized separately.
843 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
844 explicit basic_string(__uninitialized_size_tag, size_type __size, const allocator_type& __a)
845 : __r_(__default_init_tag(), __a) {
846 if (__size > max_size())
847 __throw_length_error();
848 if (__fits_in_sso(__size)) {
849 __r_.first() = __rep();
850 __set_short_size(__size);
852 auto __capacity = __recommend(__size) + 1;
853 auto __allocation = __alloc_traits::allocate(__alloc(), __capacity);
854 __begin_lifetime(__allocation, __capacity);
855 __set_long_cap(__capacity);
856 __set_long_pointer(__allocation);
857 __set_long_size(__size);
861 template <class _Iter, class _Sent>
862 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
863 basic_string(__init_with_sentinel_tag, _Iter __first, _Sent __last, const allocator_type& __a)
864 : __r_(__default_init_tag(), __a) {
865 __init_with_sentinel(std::move(__first), std::move(__last));
868 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator __make_iterator(pointer __p) {
869 return iterator(__p);
872 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator __make_const_iterator(const_pointer __p) const {
873 return const_iterator(__p);
877 _LIBCPP_TEMPLATE_DATA_VIS static const size_type npos = -1;
879 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string()
880 _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
881 : __r_(__value_init_tag(), __default_init_tag()) {}
883 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(const allocator_type& __a)
884 #if _LIBCPP_STD_VER <= 14
885 _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
889 : __r_(__value_init_tag(), __a) {}
891 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const basic_string& __str)
892 : __r_(__default_init_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc())) {
893 if (!__str.__is_long())
894 __r_.first() = __str.__r_.first();
896 __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size());
899 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const basic_string& __str, const allocator_type& __a)
900 : __r_(__default_init_tag(), __a) {
901 if (!__str.__is_long())
902 __r_.first() = __str.__r_.first();
904 __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size());
907 #ifndef _LIBCPP_CXX03_LANG
908 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(basic_string&& __str)
909 # if _LIBCPP_STD_VER <= 14
910 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
914 : __r_(std::move(__str.__r_)) {
915 __str.__r_.first() = __rep();
918 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(basic_string&& __str, const allocator_type& __a)
919 : __r_(__default_init_tag(), __a) {
920 if (__str.__is_long() && __a != __str.__alloc()) // copy, not move
921 __init(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size());
923 if (__libcpp_is_constant_evaluated())
924 __r_.first() = __rep();
925 __r_.first() = __str.__r_.first();
926 __str.__r_.first() = __rep();
929 #endif // _LIBCPP_CXX03_LANG
931 template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0>
932 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s)
933 : __r_(__default_init_tag(), __default_init_tag()) {
934 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "basic_string(const char*) detected nullptr");
935 __init(__s, traits_type::length(__s));
938 template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0>
939 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s, const _Allocator& __a)
940 : __r_(__default_init_tag(), __a) {
941 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "basic_string(const char*, allocator) detected nullptr");
942 __init(__s, traits_type::length(__s));
945 #if _LIBCPP_STD_VER >= 23
946 basic_string(nullptr_t) = delete;
949 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s, size_type __n)
950 : __r_(__default_init_tag(), __default_init_tag()) {
951 _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr");
955 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
956 basic_string(const _CharT* __s, size_type __n, const _Allocator& __a)
957 : __r_(__default_init_tag(), __a) {
958 _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr,
959 "basic_string(const char*, n, allocator) detected nullptr");
963 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(size_type __n, _CharT __c)
964 : __r_(__default_init_tag(), __default_init_tag()) {
968 #if _LIBCPP_STD_VER >= 23
969 _LIBCPP_HIDE_FROM_ABI constexpr
970 basic_string(basic_string&& __str, size_type __pos, const _Allocator& __alloc = _Allocator())
971 : basic_string(std::move(__str), __pos, npos, __alloc) {}
973 _LIBCPP_HIDE_FROM_ABI constexpr
974 basic_string(basic_string&& __str, size_type __pos, size_type __n, const _Allocator& __alloc = _Allocator())
975 : __r_(__default_init_tag(), __alloc) {
976 if (__pos > __str.size())
977 __throw_out_of_range();
979 auto __len = std::min<size_type>(__n, __str.size() - __pos);
980 if (__alloc_traits::is_always_equal::value || __alloc == __str.__alloc()) {
981 __move_assign(std::move(__str), __pos, __len);
983 // Perform a copy because the allocators are not compatible.
984 __init(__str.data() + __pos, __len);
989 template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0>
990 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(size_type __n, _CharT __c, const _Allocator& __a)
991 : __r_(__default_init_tag(), __a) {
995 _LIBCPP_CONSTEXPR_SINCE_CXX20
996 basic_string(const basic_string& __str, size_type __pos, size_type __n, const _Allocator& __a = _Allocator())
997 : __r_(__default_init_tag(), __a) {
998 size_type __str_sz = __str.size();
999 if (__pos > __str_sz)
1000 __throw_out_of_range();
1001 __init(__str.data() + __pos, std::min(__n, __str_sz - __pos));
1004 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1005 basic_string(const basic_string& __str, size_type __pos, const _Allocator& __a = _Allocator())
1006 : __r_(__default_init_tag(), __a) {
1007 size_type __str_sz = __str.size();
1008 if (__pos > __str_sz)
1009 __throw_out_of_range();
1010 __init(__str.data() + __pos, __str_sz - __pos);
1013 template <class _Tp,
1014 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1015 !__is_same_uncvref<_Tp, basic_string>::value,
1017 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1018 basic_string(const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a = allocator_type())
1019 : __r_(__default_init_tag(), __a) {
1020 __self_view __sv0 = __t;
1021 __self_view __sv = __sv0.substr(__pos, __n);
1022 __init(__sv.data(), __sv.size());
1025 template <class _Tp,
1026 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1027 !__is_same_uncvref<_Tp, basic_string>::value,
1029 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(const _Tp& __t)
1030 : __r_(__default_init_tag(), __default_init_tag()) {
1031 __self_view __sv = __t;
1032 __init(__sv.data(), __sv.size());
1035 template <class _Tp,
1036 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1037 !__is_same_uncvref<_Tp, basic_string>::value,
1039 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(
1040 const _Tp& __t, const allocator_type& __a)
1041 : __r_(__default_init_tag(), __a) {
1042 __self_view __sv = __t;
1043 __init(__sv.data(), __sv.size());
1046 template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0>
1047 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(_InputIterator __first, _InputIterator __last)
1048 : __r_(__default_init_tag(), __default_init_tag()) {
1049 __init(__first, __last);
1052 template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0>
1053 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1054 basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a)
1055 : __r_(__default_init_tag(), __a) {
1056 __init(__first, __last);
1059 #if _LIBCPP_STD_VER >= 23
1060 template <_ContainerCompatibleRange<_CharT> _Range>
1061 _LIBCPP_HIDE_FROM_ABI constexpr
1062 basic_string(from_range_t, _Range&& __range, const allocator_type& __a = allocator_type())
1063 : __r_(__default_init_tag(), __a) {
1064 if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
1065 __init_with_size(ranges::begin(__range), ranges::end(__range), ranges::distance(__range));
1067 __init_with_sentinel(ranges::begin(__range), ranges::end(__range));
1072 #ifndef _LIBCPP_CXX03_LANG
1073 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(initializer_list<_CharT> __il)
1074 : __r_(__default_init_tag(), __default_init_tag()) {
1075 __init(__il.begin(), __il.end());
1078 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(initializer_list<_CharT> __il, const _Allocator& __a)
1079 : __r_(__default_init_tag(), __a) {
1080 __init(__il.begin(), __il.end());
1082 #endif // _LIBCPP_CXX03_LANG
1084 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 ~basic_string() {
1086 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
1089 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1090 operator __self_view() const _NOEXCEPT { return __self_view(data(), size()); }
1092 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(const basic_string& __str);
1094 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1095 !__is_same_uncvref<_Tp, basic_string>::value, int> = 0>
1096 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(const _Tp& __t) {
1097 __self_view __sv = __t;
1098 return assign(__sv);
1101 #ifndef _LIBCPP_CXX03_LANG
1102 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(basic_string&& __str)
1103 _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value)) {
1104 __move_assign(__str, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>());
1108 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1109 basic_string& operator=(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}
1111 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1112 basic_string& operator=(const value_type* __s) {return assign(__s);}
1113 #if _LIBCPP_STD_VER >= 23
1114 basic_string& operator=(nullptr_t) = delete;
1116 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(value_type __c);
1118 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1119 iterator begin() _NOEXCEPT
1120 {return __make_iterator(__get_pointer());}
1121 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1122 const_iterator begin() const _NOEXCEPT
1123 {return __make_const_iterator(__get_pointer());}
1124 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1125 iterator end() _NOEXCEPT
1126 {return __make_iterator(__get_pointer() + size());}
1127 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1128 const_iterator end() const _NOEXCEPT
1129 {return __make_const_iterator(__get_pointer() + size());}
1131 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1132 reverse_iterator rbegin() _NOEXCEPT
1133 {return reverse_iterator(end());}
1134 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1135 const_reverse_iterator rbegin() const _NOEXCEPT
1136 {return const_reverse_iterator(end());}
1137 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1138 reverse_iterator rend() _NOEXCEPT
1139 {return reverse_iterator(begin());}
1140 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1141 const_reverse_iterator rend() const _NOEXCEPT
1142 {return const_reverse_iterator(begin());}
1144 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1145 const_iterator cbegin() const _NOEXCEPT
1147 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1148 const_iterator cend() const _NOEXCEPT
1150 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1151 const_reverse_iterator crbegin() const _NOEXCEPT
1153 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1154 const_reverse_iterator crend() const _NOEXCEPT
1157 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type size() const _NOEXCEPT
1158 {return __is_long() ? __get_long_size() : __get_short_size();}
1159 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type length() const _NOEXCEPT {return size();}
1161 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type max_size() const _NOEXCEPT {
1162 size_type __m = __alloc_traits::max_size(__alloc());
1163 if (__m <= std::numeric_limits<size_type>::max() / 2) {
1164 return __m - __alignment;
1166 bool __uses_lsb = __endian_factor == 2;
1167 return __uses_lsb ? __m - __alignment : (__m / 2) - __alignment;
1171 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type capacity() const _NOEXCEPT {
1172 return (__is_long() ? __get_long_cap() : static_cast<size_type>(__min_cap)) - 1;
1175 _LIBCPP_CONSTEXPR_SINCE_CXX20 void resize(size_type __n, value_type __c);
1176 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void resize(size_type __n) { resize(__n, value_type()); }
1178 _LIBCPP_CONSTEXPR_SINCE_CXX20 void reserve(size_type __requested_capacity);
1180 #if _LIBCPP_STD_VER >= 23
1181 template <class _Op>
1182 _LIBCPP_HIDE_FROM_ABI constexpr
1183 void resize_and_overwrite(size_type __n, _Op __op) {
1184 __resize_default_init(__n);
1185 __erase_to_end(std::move(__op)(data(), _LIBCPP_AUTO_CAST(__n)));
1189 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __resize_default_init(size_type __n);
1191 _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI void reserve() _NOEXCEPT { shrink_to_fit(); }
1192 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void shrink_to_fit() _NOEXCEPT;
1193 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void clear() _NOEXCEPT;
1195 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1196 bool empty() const _NOEXCEPT {return size() == 0;}
1198 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference operator[](size_type __pos) const _NOEXCEPT {
1199 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos <= size(), "string index out of bounds");
1200 if (__builtin_constant_p(__pos) && !__fits_in_sso(__pos)) {
1201 return *(__get_long_pointer() + __pos);
1203 return *(data() + __pos);
1206 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](size_type __pos) _NOEXCEPT {
1207 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos <= size(), "string index out of bounds");
1208 if (__builtin_constant_p(__pos) && !__fits_in_sso(__pos)) {
1209 return *(__get_long_pointer() + __pos);
1211 return *(__get_pointer() + __pos);
1214 _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference at(size_type __n) const;
1215 _LIBCPP_CONSTEXPR_SINCE_CXX20 reference at(size_type __n);
1217 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator+=(const basic_string& __str) {
1218 return append(__str);
1221 template <class _Tp,
1222 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1223 !__is_same_uncvref<_Tp, basic_string >::value,
1225 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1226 operator+=(const _Tp& __t) {
1227 __self_view __sv = __t; return append(__sv);
1230 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator+=(const value_type* __s) {
1234 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator+=(value_type __c) {
1239 #ifndef _LIBCPP_CXX03_LANG
1240 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1241 basic_string& operator+=(initializer_list<value_type> __il) { return append(__il); }
1242 #endif // _LIBCPP_CXX03_LANG
1244 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const basic_string& __str) {
1245 return append(__str.data(), __str.size());
1248 template <class _Tp,
1249 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1250 !__is_same_uncvref<_Tp, basic_string>::value,
1252 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1253 append(const _Tp& __t) {
1254 __self_view __sv = __t;
1255 return append(__sv.data(), __sv.size());
1258 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos);
1260 template <class _Tp,
1261 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1262 !__is_same_uncvref<_Tp, basic_string>::value,
1264 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1267 append(const _Tp& __t, size_type __pos, size_type __n = npos);
1269 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const value_type* __s, size_type __n);
1270 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const value_type* __s);
1271 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(size_type __n, value_type __c);
1273 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1274 void __append_default_init(size_type __n);
1276 template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
1277 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1278 append(_InputIterator __first, _InputIterator __last) {
1279 const basic_string __temp(__first, __last, __alloc());
1280 append(__temp.data(), __temp.size());
1284 template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>
1285 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1286 append(_ForwardIterator __first, _ForwardIterator __last);
1288 #if _LIBCPP_STD_VER >= 23
1289 template <_ContainerCompatibleRange<_CharT> _Range>
1290 _LIBCPP_HIDE_FROM_ABI
1291 constexpr basic_string& append_range(_Range&& __range) {
1292 insert_range(end(), std::forward<_Range>(__range));
1297 #ifndef _LIBCPP_CXX03_LANG
1298 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1299 basic_string& append(initializer_list<value_type> __il) {return append(__il.begin(), __il.size());}
1300 #endif // _LIBCPP_CXX03_LANG
1302 _LIBCPP_CONSTEXPR_SINCE_CXX20 void push_back(value_type __c);
1303 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void pop_back();
1305 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference front() _NOEXCEPT {
1306 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::front(): string is empty");
1307 return *__get_pointer();
1310 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference front() const _NOEXCEPT {
1311 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::front(): string is empty");
1315 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference back() _NOEXCEPT {
1316 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::back(): string is empty");
1317 return *(__get_pointer() + size() - 1);
1320 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference back() const _NOEXCEPT {
1321 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::back(): string is empty");
1322 return *(data() + size() - 1);
1325 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1326 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1327 assign(const _Tp& __t) {
1328 __self_view __sv = __t;
1329 return assign(__sv.data(), __sv.size());
1332 #if _LIBCPP_STD_VER >= 20
1333 _LIBCPP_HIDE_FROM_ABI constexpr
1334 void __move_assign(basic_string&& __str, size_type __pos, size_type __len) {
1335 // Pilfer the allocation from __str.
1336 _LIBCPP_ASSERT_INTERNAL(__alloc() == __str.__alloc(), "__move_assign called with wrong allocator");
1337 __r_.first() = __str.__r_.first();
1338 __str.__r_.first() = __rep();
1340 _Traits::move(data(), data() + __pos, __len);
1342 _Traits::assign(data()[__len], value_type());
1346 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1347 basic_string& assign(const basic_string& __str) { return *this = __str; }
1348 #ifndef _LIBCPP_CXX03_LANG
1349 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1350 basic_string& assign(basic_string&& __str)
1351 _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value))
1352 {*this = std::move(__str); return *this;}
1354 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos);
1356 template <class _Tp,
1357 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1358 !__is_same_uncvref<_Tp, basic_string>::value,
1360 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1361 assign(const _Tp& __t, size_type __pos, size_type __n = npos);
1363 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const value_type* __s, size_type __n);
1364 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const value_type* __s);
1365 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(size_type __n, value_type __c);
1366 template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
1367 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1368 assign(_InputIterator __first, _InputIterator __last);
1370 template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>
1371 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1372 assign(_ForwardIterator __first, _ForwardIterator __last);
1374 #if _LIBCPP_STD_VER >= 23
1375 template <_ContainerCompatibleRange<_CharT> _Range>
1376 _LIBCPP_HIDE_FROM_ABI
1377 constexpr basic_string& assign_range(_Range&& __range) {
1378 if constexpr (__string_is_trivial_iterator<ranges::iterator_t<_Range>>::value &&
1379 (ranges::forward_range<_Range> || ranges::sized_range<_Range>)) {
1380 size_type __n = static_cast<size_type>(ranges::distance(__range));
1381 __assign_trivial(ranges::begin(__range), ranges::end(__range), __n);
1384 __assign_with_sentinel(ranges::begin(__range), ranges::end(__range));
1391 #ifndef _LIBCPP_CXX03_LANG
1392 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1393 basic_string& assign(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}
1394 #endif // _LIBCPP_CXX03_LANG
1396 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1397 insert(size_type __pos1, const basic_string& __str) {
1398 return insert(__pos1, __str.data(), __str.size());
1401 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1402 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1403 insert(size_type __pos1, const _Tp& __t) {
1404 __self_view __sv = __t;
1405 return insert(__pos1, __sv.data(), __sv.size());
1408 template <class _Tp,
1409 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1410 !__is_same_uncvref<_Tp, basic_string>::value,
1412 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1413 insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n = npos);
1415 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1416 insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n = npos);
1417 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* __s, size_type __n);
1418 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* __s);
1419 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, size_type __n, value_type __c);
1420 _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator insert(const_iterator __pos, value_type __c);
1422 #if _LIBCPP_STD_VER >= 23
1423 template <_ContainerCompatibleRange<_CharT> _Range>
1424 _LIBCPP_HIDE_FROM_ABI
1425 constexpr iterator insert_range(const_iterator __position, _Range&& __range) {
1426 if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
1427 auto __n = static_cast<size_type>(ranges::distance(__range));
1428 return __insert_with_size(__position, ranges::begin(__range), ranges::end(__range), __n);
1431 basic_string __temp(from_range, std::forward<_Range>(__range), __alloc());
1432 return insert(__position, __temp.data(), __temp.data() + __temp.size());
1437 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator
1438 insert(const_iterator __pos, size_type __n, value_type __c) {
1439 difference_type __p = __pos - begin();
1440 insert(static_cast<size_type>(__p), __n, __c);
1441 return begin() + __p;
1444 template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
1445 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator
1446 insert(const_iterator __pos, _InputIterator __first, _InputIterator __last);
1448 template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>
1449 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator
1450 insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last);
1452 #ifndef _LIBCPP_CXX03_LANG
1453 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1454 iterator insert(const_iterator __pos, initializer_list<value_type> __il)
1455 {return insert(__pos, __il.begin(), __il.end());}
1456 #endif // _LIBCPP_CXX03_LANG
1458 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& erase(size_type __pos = 0, size_type __n = npos);
1459 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1460 iterator erase(const_iterator __pos);
1461 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1462 iterator erase(const_iterator __first, const_iterator __last);
1464 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1465 replace(size_type __pos1, size_type __n1, const basic_string& __str) {
1466 return replace(__pos1, __n1, __str.data(), __str.size());
1469 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1470 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1471 replace(size_type __pos1, size_type __n1, const _Tp& __t) {
1472 __self_view __sv = __t;
1473 return replace(__pos1, __n1, __sv.data(), __sv.size());
1476 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1477 replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2 = npos);
1479 template <class _Tp,
1480 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1481 !__is_same_uncvref<_Tp, basic_string>::value,
1483 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1484 replace(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2 = npos);
1486 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1487 replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2);
1488 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& replace(size_type __pos, size_type __n1, const value_type* __s);
1489 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c);
1491 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1492 replace(const_iterator __i1, const_iterator __i2, const basic_string& __str) {
1494 static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __str.data(), __str.size());
1497 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1498 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1499 replace(const_iterator __i1, const_iterator __i2, const _Tp& __t) {
1500 __self_view __sv = __t;
1501 return replace(__i1 - begin(), __i2 - __i1, __sv);
1504 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1505 replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n) {
1506 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s, __n);
1509 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1510 replace(const_iterator __i1, const_iterator __i2, const value_type* __s) {
1511 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s);
1514 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1515 replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c) {
1516 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __n, __c);
1519 template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0>
1520 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1521 replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2);
1523 #if _LIBCPP_STD_VER >= 23
1524 template <_ContainerCompatibleRange<_CharT> _Range>
1525 _LIBCPP_HIDE_FROM_ABI
1526 constexpr basic_string& replace_with_range(const_iterator __i1, const_iterator __i2, _Range&& __range) {
1527 basic_string __temp(from_range, std::forward<_Range>(__range), __alloc());
1528 return replace(__i1, __i2, __temp);
1532 #ifndef _LIBCPP_CXX03_LANG
1533 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1534 basic_string& replace(const_iterator __i1, const_iterator __i2, initializer_list<value_type> __il)
1535 {return replace(__i1, __i2, __il.begin(), __il.end());}
1536 #endif // _LIBCPP_CXX03_LANG
1538 _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type copy(value_type* __s, size_type __n, size_type __pos = 0) const;
1540 #if _LIBCPP_STD_VER <= 20
1541 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1542 basic_string substr(size_type __pos = 0, size_type __n = npos) const {
1543 return basic_string(*this, __pos, __n);
1546 _LIBCPP_HIDE_FROM_ABI constexpr
1547 basic_string substr(size_type __pos = 0, size_type __n = npos) const& {
1548 return basic_string(*this, __pos, __n);
1551 _LIBCPP_HIDE_FROM_ABI constexpr
1552 basic_string substr(size_type __pos = 0, size_type __n = npos) && {
1553 return basic_string(std::move(*this), __pos, __n);
1557 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1558 void swap(basic_string& __str)
1559 #if _LIBCPP_STD_VER >= 14
1562 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
1563 __is_nothrow_swappable<allocator_type>::value);
1566 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1567 const value_type* c_str() const _NOEXCEPT {return data();}
1568 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1569 const value_type* data() const _NOEXCEPT {return std::__to_address(__get_pointer());}
1570 #if _LIBCPP_STD_VER >= 17
1571 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1572 value_type* data() _NOEXCEPT {return std::__to_address(__get_pointer());}
1575 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1576 allocator_type get_allocator() const _NOEXCEPT {return __alloc();}
1578 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1579 size_type find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
1581 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1582 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1583 find(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
1585 _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1586 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1587 size_type find(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
1588 _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT;
1590 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1591 size_type rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
1593 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1594 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1595 rfind(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
1597 _LIBCPP_CONSTEXPR_SINCE_CXX20
1598 size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1599 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1600 size_type rfind(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
1601 _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type rfind(value_type __c, size_type __pos = npos) const _NOEXCEPT;
1603 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1604 size_type find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
1606 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1607 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1608 find_first_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
1610 _LIBCPP_CONSTEXPR_SINCE_CXX20
1611 size_type find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1612 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1613 size_type find_first_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
1614 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1615 size_type find_first_of(value_type __c, size_type __pos = 0) const _NOEXCEPT;
1617 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1618 size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
1620 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1621 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1622 find_last_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
1624 _LIBCPP_CONSTEXPR_SINCE_CXX20
1625 size_type find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1626 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1627 size_type find_last_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
1628 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1629 size_type find_last_of(value_type __c, size_type __pos = npos) const _NOEXCEPT;
1631 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1632 size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
1634 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1635 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1636 find_first_not_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
1638 _LIBCPP_CONSTEXPR_SINCE_CXX20
1639 size_type find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1640 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1641 size_type find_first_not_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
1642 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1643 size_type find_first_not_of(value_type __c, size_type __pos = 0) const _NOEXCEPT;
1645 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1646 size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
1648 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1649 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1650 find_last_not_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
1652 _LIBCPP_CONSTEXPR_SINCE_CXX20
1653 size_type find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1654 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1655 size_type find_last_not_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
1656 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1657 size_type find_last_not_of(value_type __c, size_type __pos = npos) const _NOEXCEPT;
1659 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1660 int compare(const basic_string& __str) const _NOEXCEPT;
1662 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1663 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 int
1664 compare(const _Tp& __t) const _NOEXCEPT;
1666 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1667 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 int
1668 compare(size_type __pos1, size_type __n1, const _Tp& __t) const;
1670 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1671 int compare(size_type __pos1, size_type __n1, const basic_string& __str) const;
1672 _LIBCPP_CONSTEXPR_SINCE_CXX20
1673 int compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2,
1674 size_type __n2 = npos) const;
1676 template <class _Tp,
1677 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1678 !__is_same_uncvref<_Tp, basic_string>::value,
1680 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int
1681 compare(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2 = npos) const;
1683 _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(const value_type* __s) const _NOEXCEPT;
1684 _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(size_type __pos1, size_type __n1, const value_type* __s) const;
1685 _LIBCPP_CONSTEXPR_SINCE_CXX20
1686 int compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const;
1688 #if _LIBCPP_STD_VER >= 20
1689 constexpr _LIBCPP_HIDE_FROM_ABI
1690 bool starts_with(__self_view __sv) const noexcept
1691 { return __self_view(data(), size()).starts_with(__sv); }
1693 constexpr _LIBCPP_HIDE_FROM_ABI
1694 bool starts_with(value_type __c) const noexcept
1695 { return !empty() && _Traits::eq(front(), __c); }
1697 constexpr _LIBCPP_HIDE_FROM_ABI
1698 bool starts_with(const value_type* __s) const noexcept
1699 { return starts_with(__self_view(__s)); }
1701 constexpr _LIBCPP_HIDE_FROM_ABI
1702 bool ends_with(__self_view __sv) const noexcept
1703 { return __self_view(data(), size()).ends_with( __sv); }
1705 constexpr _LIBCPP_HIDE_FROM_ABI
1706 bool ends_with(value_type __c) const noexcept
1707 { return !empty() && _Traits::eq(back(), __c); }
1709 constexpr _LIBCPP_HIDE_FROM_ABI
1710 bool ends_with(const value_type* __s) const noexcept
1711 { return ends_with(__self_view(__s)); }
1714 #if _LIBCPP_STD_VER >= 23
1715 constexpr _LIBCPP_HIDE_FROM_ABI
1716 bool contains(__self_view __sv) const noexcept
1717 { return __self_view(data(), size()).contains(__sv); }
1719 constexpr _LIBCPP_HIDE_FROM_ABI
1720 bool contains(value_type __c) const noexcept
1721 { return __self_view(data(), size()).contains(__c); }
1723 constexpr _LIBCPP_HIDE_FROM_ABI
1724 bool contains(const value_type* __s) const
1725 { return __self_view(data(), size()).contains(__s); }
1728 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __invariants() const;
1730 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __clear_and_shrink() _NOEXCEPT;
1733 template<class _Alloc>
1734 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1735 bool friend operator==(const basic_string<char, char_traits<char>, _Alloc>& __lhs,
1736 const basic_string<char, char_traits<char>, _Alloc>& __rhs) _NOEXCEPT;
1738 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __shrink_or_extend(size_type __target_capacity);
1740 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1741 bool __is_long() const _NOEXCEPT {
1742 if (__libcpp_is_constant_evaluated() && __builtin_constant_p(__r_.first().__l.__is_long_)) {
1743 return __r_.first().__l.__is_long_;
1745 return __r_.first().__s.__is_long_;
1748 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __begin_lifetime(pointer __begin, size_type __n) {
1749 #if _LIBCPP_STD_VER >= 20
1750 if (__libcpp_is_constant_evaluated()) {
1751 for (size_type __i = 0; __i != __n; ++__i)
1752 std::construct_at(std::addressof(__begin[__i]));
1757 #endif // _LIBCPP_STD_VER >= 20
1760 _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI static bool __fits_in_sso(size_type __sz) {
1761 return __sz < __min_cap;
1764 template <class _Iterator, class _Sentinel>
1765 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
1766 void __assign_trivial(_Iterator __first, _Sentinel __last, size_type __n);
1768 template <class _Iterator, class _Sentinel>
1769 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
1770 void __assign_with_sentinel(_Iterator __first, _Sentinel __last);
1772 template <class _ForwardIterator, class _Sentinel>
1773 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
1774 iterator __insert_from_safe_copy(size_type __n, size_type __ip, _ForwardIterator __first, _Sentinel __last) {
1775 size_type __sz = size();
1776 size_type __cap = capacity();
1778 if (__cap - __sz >= __n)
1780 __p = std::__to_address(__get_pointer());
1781 size_type __n_move = __sz - __ip;
1783 traits_type::move(__p + __ip + __n, __p + __ip, __n_move);
1787 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __ip, 0, __n);
1788 __p = std::__to_address(__get_long_pointer());
1792 traits_type::assign(__p[__sz], value_type());
1793 for (__p += __ip; __first != __last; ++__p, ++__first)
1794 traits_type::assign(*__p, *__first);
1796 return begin() + __ip;
1799 template<class _Iterator, class _Sentinel>
1800 _LIBCPP_CONSTEXPR_SINCE_CXX20
1801 iterator __insert_with_size(const_iterator __pos, _Iterator __first, _Sentinel __last, size_type __n);
1803 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 allocator_type& __alloc() _NOEXCEPT { return __r_.second(); }
1804 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const allocator_type& __alloc() const _NOEXCEPT { return __r_.second(); }
1806 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1807 void __set_short_size(size_type __s) _NOEXCEPT {
1808 _LIBCPP_ASSERT_INTERNAL(
1809 __s < __min_cap, "__s should never be greater than or equal to the short string capacity");
1810 __r_.first().__s.__size_ = __s;
1811 __r_.first().__s.__is_long_ = false;
1814 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1815 size_type __get_short_size() const _NOEXCEPT {
1816 _LIBCPP_ASSERT_INTERNAL(
1817 !__r_.first().__s.__is_long_, "String has to be short when trying to get the short size");
1818 return __r_.first().__s.__size_;
1821 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1822 void __set_long_size(size_type __s) _NOEXCEPT
1823 {__r_.first().__l.__size_ = __s;}
1824 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1825 size_type __get_long_size() const _NOEXCEPT
1826 {return __r_.first().__l.__size_;}
1827 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1828 void __set_size(size_type __s) _NOEXCEPT
1829 {if (__is_long()) __set_long_size(__s); else __set_short_size(__s);}
1831 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1832 void __set_long_cap(size_type __s) _NOEXCEPT {
1833 __r_.first().__l.__cap_ = __s / __endian_factor;
1834 __r_.first().__l.__is_long_ = true;
1837 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1838 size_type __get_long_cap() const _NOEXCEPT {
1839 return __r_.first().__l.__cap_ * __endian_factor;
1842 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1843 void __set_long_pointer(pointer __p) _NOEXCEPT
1844 {__r_.first().__l.__data_ = __p;}
1845 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1846 pointer __get_long_pointer() _NOEXCEPT
1847 {return __r_.first().__l.__data_;}
1848 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1849 const_pointer __get_long_pointer() const _NOEXCEPT
1850 {return __r_.first().__l.__data_;}
1851 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1852 pointer __get_short_pointer() _NOEXCEPT
1853 {return pointer_traits<pointer>::pointer_to(__r_.first().__s.__data_[0]);}
1854 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1855 const_pointer __get_short_pointer() const _NOEXCEPT
1856 {return pointer_traits<const_pointer>::pointer_to(__r_.first().__s.__data_[0]);}
1857 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1858 pointer __get_pointer() _NOEXCEPT
1859 {return __is_long() ? __get_long_pointer() : __get_short_pointer();}
1860 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1861 const_pointer __get_pointer() const _NOEXCEPT
1862 {return __is_long() ? __get_long_pointer() : __get_short_pointer();}
1864 template <size_type __a> static
1865 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1866 size_type __align_it(size_type __s) _NOEXCEPT
1867 {return (__s + (__a-1)) & ~(__a-1);}
1870 #ifdef _LIBCPP_ABI_STRING_8_BYTE_ALIGNMENT
1876 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1877 size_type __recommend(size_type __s) _NOEXCEPT
1879 if (__s < __min_cap) {
1880 return static_cast<size_type>(__min_cap) - 1;
1882 size_type __guess = __align_it<sizeof(value_type) < __alignment ?
1883 __alignment/sizeof(value_type) : 1 > (__s+1) - 1;
1884 if (__guess == __min_cap) ++__guess;
1888 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
1889 void __init(const value_type* __s, size_type __sz, size_type __reserve);
1890 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
1891 void __init(const value_type* __s, size_type __sz);
1892 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
1893 void __init(size_type __n, value_type __c);
1895 // Slow path for the (inlined) copy constructor for 'long' strings.
1896 // Always externally instantiated and not inlined.
1897 // Requires that __s is zero terminated.
1898 // The main reason for this function to exist is because for unstable, we
1899 // want to allow inlining of the copy constructor. However, we don't want
1900 // to call the __init() functions as those are marked as inline which may
1901 // result in over-aggressive inlining by the compiler, where our aim is
1902 // to only inline the fast path code directly in the ctor.
1903 _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init_copy_ctor_external(const value_type* __s, size_type __sz);
1905 template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
1906 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init(_InputIterator __first, _InputIterator __last);
1908 template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>
1909 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init(_ForwardIterator __first, _ForwardIterator __last);
1911 template <class _InputIterator, class _Sentinel>
1912 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1913 void __init_with_sentinel(_InputIterator __first, _Sentinel __last);
1914 template <class _InputIterator, class _Sentinel>
1915 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1916 void __init_with_size(_InputIterator __first, _Sentinel __last, size_type __sz);
1918 _LIBCPP_CONSTEXPR_SINCE_CXX20
1919 #if _LIBCPP_ABI_VERSION >= 2 // We want to use the function in the dylib in ABIv1
1920 _LIBCPP_HIDE_FROM_ABI
1922 _LIBCPP_DEPRECATED_("use __grow_by_without_replace")
1923 void __grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
1924 size_type __n_copy, size_type __n_del, size_type __n_add = 0);
1925 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
1926 void __grow_by_without_replace(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
1927 size_type __n_copy, size_type __n_del, size_type __n_add = 0);
1928 _LIBCPP_CONSTEXPR_SINCE_CXX20
1929 void __grow_by_and_replace(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
1930 size_type __n_copy, size_type __n_del,
1931 size_type __n_add, const value_type* __p_new_stuff);
1933 // __assign_no_alias is invoked for assignment operations where we
1934 // have proof that the input does not alias the current instance.
1935 // For example, operator=(basic_string) performs a 'self' check.
1936 template <bool __is_short>
1937 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& __assign_no_alias(const value_type* __s, size_type __n);
1939 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __erase_to_end(size_type __pos) {
1940 __null_terminate_at(std::__to_address(__get_pointer()), __pos);
1943 // __erase_external_with_move is invoked for erase() invocations where
1944 // `n ~= npos`, likely requiring memory moves on the string data.
1945 _LIBCPP_CONSTEXPR_SINCE_CXX20 void __erase_external_with_move(size_type __pos, size_type __n);
1947 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1948 void __copy_assign_alloc(const basic_string& __str)
1949 {__copy_assign_alloc(__str, integral_constant<bool,
1950 __alloc_traits::propagate_on_container_copy_assignment::value>());}
1952 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1953 void __copy_assign_alloc(const basic_string& __str, true_type)
1955 if (__alloc() == __str.__alloc())
1956 __alloc() = __str.__alloc();
1959 if (!__str.__is_long())
1961 __clear_and_shrink();
1962 __alloc() = __str.__alloc();
1966 allocator_type __a = __str.__alloc();
1967 auto __allocation = std::__allocate_at_least(__a, __str.__get_long_cap());
1968 __begin_lifetime(__allocation.ptr, __allocation.count);
1970 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
1971 __alloc() = std::move(__a);
1972 __set_long_pointer(__allocation.ptr);
1973 __set_long_cap(__allocation.count);
1974 __set_long_size(__str.size());
1979 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1980 void __copy_assign_alloc(const basic_string&, false_type) _NOEXCEPT
1983 #ifndef _LIBCPP_CXX03_LANG
1984 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1985 void __move_assign(basic_string& __str, false_type)
1986 _NOEXCEPT_(__alloc_traits::is_always_equal::value);
1987 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1988 void __move_assign(basic_string& __str, true_type)
1989 #if _LIBCPP_STD_VER >= 17
1992 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
1996 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1998 __move_assign_alloc(basic_string& __str)
2000 !__alloc_traits::propagate_on_container_move_assignment::value ||
2001 is_nothrow_move_assignable<allocator_type>::value)
2002 {__move_assign_alloc(__str, integral_constant<bool,
2003 __alloc_traits::propagate_on_container_move_assignment::value>());}
2005 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
2006 void __move_assign_alloc(basic_string& __c, true_type)
2007 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
2009 __alloc() = std::move(__c.__alloc());
2012 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
2013 void __move_assign_alloc(basic_string&, false_type)
2017 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& __assign_external(const value_type* __s);
2018 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& __assign_external(const value_type* __s, size_type __n);
2020 // Assigns the value in __s, guaranteed to be __n < __min_cap in length.
2021 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& __assign_short(const value_type* __s, size_type __n) {
2022 pointer __p = __is_long()
2023 ? (__set_long_size(__n), __get_long_pointer())
2024 : (__set_short_size(__n), __get_short_pointer());
2025 traits_type::move(std::__to_address(__p), __s, __n);
2026 traits_type::assign(__p[__n], value_type());
2030 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
2031 basic_string& __null_terminate_at(value_type* __p, size_type __newsz) {
2032 __set_size(__newsz);
2033 traits_type::assign(__p[__newsz], value_type());
2037 template <class _Tp>
2038 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __addr_in_range(const _Tp& __v) const {
2039 return std::__is_pointer_in_range(data(), data() + size() + 1, std::addressof(__v));
2042 _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI
2043 void __throw_length_error() const {
2044 std::__throw_length_error("basic_string");
2047 _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI
2048 void __throw_out_of_range() const {
2049 std::__throw_out_of_range("basic_string");
2052 friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+<>(const basic_string&, const basic_string&);
2053 friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+<>(const value_type*, const basic_string&);
2054 friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+<>(value_type, const basic_string&);
2055 friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+<>(const basic_string&, const value_type*);
2056 friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+<>(const basic_string&, value_type);
2059 // These declarations must appear before any functions are implicitly used
2060 // so that they have the correct visibility specifier.
2061 #define _LIBCPP_DECLARE(...) extern template __VA_ARGS__;
2062 #ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
2063 _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, char)
2064 # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
2065 _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, wchar_t)
2068 _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, char)
2069 # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
2070 _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, wchar_t)
2073 #undef _LIBCPP_DECLARE
2076 #if _LIBCPP_STD_VER >= 17
2077 template<class _InputIterator,
2078 class _CharT = __iter_value_type<_InputIterator>,
2079 class _Allocator = allocator<_CharT>,
2080 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
2081 class = enable_if_t<__is_allocator<_Allocator>::value>
2083 basic_string(_InputIterator, _InputIterator, _Allocator = _Allocator())
2084 -> basic_string<_CharT, char_traits<_CharT>, _Allocator>;
2086 template<class _CharT,
2088 class _Allocator = allocator<_CharT>,
2089 class = enable_if_t<__is_allocator<_Allocator>::value>
2091 explicit basic_string(basic_string_view<_CharT, _Traits>, const _Allocator& = _Allocator())
2092 -> basic_string<_CharT, _Traits, _Allocator>;
2094 template<class _CharT,
2096 class _Allocator = allocator<_CharT>,
2097 class = enable_if_t<__is_allocator<_Allocator>::value>,
2098 class _Sz = typename allocator_traits<_Allocator>::size_type
2100 basic_string(basic_string_view<_CharT, _Traits>, _Sz, _Sz, const _Allocator& = _Allocator())
2101 -> basic_string<_CharT, _Traits, _Allocator>;
2104 #if _LIBCPP_STD_VER >= 23
2105 template <ranges::input_range _Range,
2106 class _Allocator = allocator<ranges::range_value_t<_Range>>,
2107 class = enable_if_t<__is_allocator<_Allocator>::value>
2109 basic_string(from_range_t, _Range&&, _Allocator = _Allocator())
2110 -> basic_string<ranges::range_value_t<_Range>, char_traits<ranges::range_value_t<_Range>>, _Allocator>;
2113 template <class _CharT, class _Traits, class _Allocator>
2114 _LIBCPP_CONSTEXPR_SINCE_CXX20
2115 void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s,
2117 size_type __reserve)
2119 if (__libcpp_is_constant_evaluated())
2120 __r_.first() = __rep();
2121 if (__reserve > max_size())
2122 __throw_length_error();
2124 if (__fits_in_sso(__reserve))
2126 __set_short_size(__sz);
2127 __p = __get_short_pointer();
2131 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__reserve) + 1);
2132 __p = __allocation.ptr;
2133 __begin_lifetime(__p, __allocation.count);
2134 __set_long_pointer(__p);
2135 __set_long_cap(__allocation.count);
2136 __set_long_size(__sz);
2138 traits_type::copy(std::__to_address(__p), __s, __sz);
2139 traits_type::assign(__p[__sz], value_type());
2142 template <class _CharT, class _Traits, class _Allocator>
2143 _LIBCPP_CONSTEXPR_SINCE_CXX20
2145 basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz)
2147 if (__libcpp_is_constant_evaluated())
2148 __r_.first() = __rep();
2149 if (__sz > max_size())
2150 __throw_length_error();
2152 if (__fits_in_sso(__sz))
2154 __set_short_size(__sz);
2155 __p = __get_short_pointer();
2159 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1);
2160 __p = __allocation.ptr;
2161 __begin_lifetime(__p, __allocation.count);
2162 __set_long_pointer(__p);
2163 __set_long_cap(__allocation.count);
2164 __set_long_size(__sz);
2166 traits_type::copy(std::__to_address(__p), __s, __sz);
2167 traits_type::assign(__p[__sz], value_type());
2170 template <class _CharT, class _Traits, class _Allocator>
2171 _LIBCPP_CONSTEXPR_SINCE_CXX20
2172 void basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external(
2173 const value_type* __s, size_type __sz) {
2174 if (__libcpp_is_constant_evaluated())
2175 __r_.first() = __rep();
2178 if (__fits_in_sso(__sz)) {
2179 __p = __get_short_pointer();
2180 __set_short_size(__sz);
2182 if (__sz > max_size())
2183 __throw_length_error();
2184 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1);
2185 __p = __allocation.ptr;
2186 __begin_lifetime(__p, __allocation.count);
2187 __set_long_pointer(__p);
2188 __set_long_cap(__allocation.count);
2189 __set_long_size(__sz);
2191 traits_type::copy(std::__to_address(__p), __s, __sz + 1);
2194 template <class _CharT, class _Traits, class _Allocator>
2195 _LIBCPP_CONSTEXPR_SINCE_CXX20
2197 basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c)
2199 if (__libcpp_is_constant_evaluated())
2200 __r_.first() = __rep();
2202 if (__n > max_size())
2203 __throw_length_error();
2205 if (__fits_in_sso(__n))
2207 __set_short_size(__n);
2208 __p = __get_short_pointer();
2212 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__n) + 1);
2213 __p = __allocation.ptr;
2214 __begin_lifetime(__p, __allocation.count);
2215 __set_long_pointer(__p);
2216 __set_long_cap(__allocation.count);
2217 __set_long_size(__n);
2219 traits_type::assign(std::__to_address(__p), __n, __c);
2220 traits_type::assign(__p[__n], value_type());
2223 template <class _CharT, class _Traits, class _Allocator>
2224 template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> >
2225 _LIBCPP_CONSTEXPR_SINCE_CXX20
2226 void basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last)
2228 __init_with_sentinel(std::move(__first), std::move(__last));
2231 template <class _CharT, class _Traits, class _Allocator>
2232 template <class _InputIterator, class _Sentinel>
2233 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
2234 void basic_string<_CharT, _Traits, _Allocator>::__init_with_sentinel(_InputIterator __first, _Sentinel __last) {
2235 __r_.first() = __rep();
2237 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
2240 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
2241 for (; __first != __last; ++__first)
2242 push_back(*__first);
2243 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
2248 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
2251 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
2254 template <class _CharT, class _Traits, class _Allocator>
2255 template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> >
2256 _LIBCPP_CONSTEXPR_SINCE_CXX20 void
2257 basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last)
2259 size_type __sz = static_cast<size_type>(std::distance(__first, __last));
2260 __init_with_size(__first, __last, __sz);
2263 template <class _CharT, class _Traits, class _Allocator>
2264 template <class _InputIterator, class _Sentinel>
2265 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
2266 void basic_string<_CharT, _Traits, _Allocator>::__init_with_size(
2267 _InputIterator __first, _Sentinel __last, size_type __sz) {
2268 if (__libcpp_is_constant_evaluated())
2269 __r_.first() = __rep();
2271 if (__sz > max_size())
2272 __throw_length_error();
2275 if (__fits_in_sso(__sz))
2277 __set_short_size(__sz);
2278 __p = __get_short_pointer();
2283 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1);
2284 __p = __allocation.ptr;
2285 __begin_lifetime(__p, __allocation.count);
2286 __set_long_pointer(__p);
2287 __set_long_cap(__allocation.count);
2288 __set_long_size(__sz);
2291 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
2294 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
2295 for (; __first != __last; ++__first, (void) ++__p)
2296 traits_type::assign(*__p, *__first);
2297 traits_type::assign(*__p, value_type());
2298 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
2303 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
2306 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
2309 template <class _CharT, class _Traits, class _Allocator>
2310 _LIBCPP_CONSTEXPR_SINCE_CXX20
2312 basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace
2313 (size_type __old_cap, size_type __delta_cap, size_type __old_sz,
2314 size_type __n_copy, size_type __n_del, size_type __n_add, const value_type* __p_new_stuff)
2316 size_type __ms = max_size();
2317 if (__delta_cap > __ms - __old_cap - 1)
2318 __throw_length_error();
2319 pointer __old_p = __get_pointer();
2320 size_type __cap = __old_cap < __ms / 2 - __alignment ?
2321 __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) :
2323 auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1);
2324 pointer __p = __allocation.ptr;
2325 __begin_lifetime(__p, __allocation.count);
2327 traits_type::copy(std::__to_address(__p),
2328 std::__to_address(__old_p), __n_copy);
2330 traits_type::copy(std::__to_address(__p) + __n_copy, __p_new_stuff, __n_add);
2331 size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
2332 if (__sec_cp_sz != 0)
2333 traits_type::copy(std::__to_address(__p) + __n_copy + __n_add,
2334 std::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz);
2335 if (__old_cap+1 != __min_cap)
2336 __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1);
2337 __set_long_pointer(__p);
2338 __set_long_cap(__allocation.count);
2339 __old_sz = __n_copy + __n_add + __sec_cp_sz;
2340 __set_long_size(__old_sz);
2341 traits_type::assign(__p[__old_sz], value_type());
2344 // __grow_by is deprecated because it does not set the size. It may not update the size when the size is changed, and it
2345 // may also not set the size at all when the string was short initially. This leads to unpredictable size value. It is
2346 // not removed or changed to avoid breaking the ABI.
2347 template <class _CharT, class _Traits, class _Allocator>
2349 _LIBCPP_CONSTEXPR_SINCE_CXX20
2350 #if _LIBCPP_ABI_VERSION >= 2 // We want to use the function in the dylib in ABIv1
2351 _LIBCPP_HIDE_FROM_ABI
2353 _LIBCPP_DEPRECATED_("use __grow_by_without_replace")
2354 basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
2355 size_type __n_copy, size_type __n_del, size_type __n_add)
2357 size_type __ms = max_size();
2358 if (__delta_cap > __ms - __old_cap)
2359 __throw_length_error();
2360 pointer __old_p = __get_pointer();
2361 size_type __cap = __old_cap < __ms / 2 - __alignment ?
2362 __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) :
2364 auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1);
2365 pointer __p = __allocation.ptr;
2366 __begin_lifetime(__p, __allocation.count);
2368 traits_type::copy(std::__to_address(__p),
2369 std::__to_address(__old_p), __n_copy);
2370 size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
2371 if (__sec_cp_sz != 0)
2372 traits_type::copy(std::__to_address(__p) + __n_copy + __n_add,
2373 std::__to_address(__old_p) + __n_copy + __n_del,
2375 if (__old_cap + 1 != __min_cap)
2376 __alloc_traits::deallocate(__alloc(), __old_p, __old_cap + 1);
2377 __set_long_pointer(__p);
2378 __set_long_cap(__allocation.count);
2381 template <class _CharT, class _Traits, class _Allocator>
2382 void _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
2383 basic_string<_CharT, _Traits, _Allocator>::__grow_by_without_replace(
2384 size_type __old_cap,
2385 size_type __delta_cap,
2389 size_type __n_add) {
2390 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
2391 __grow_by(__old_cap, __delta_cap, __old_sz, __n_copy, __n_del, __n_add);
2392 _LIBCPP_SUPPRESS_DEPRECATED_POP
2393 __set_long_size(__old_sz - __n_del + __n_add);
2398 template <class _CharT, class _Traits, class _Allocator>
2399 template <bool __is_short>
2400 _LIBCPP_CONSTEXPR_SINCE_CXX20
2401 basic_string<_CharT, _Traits, _Allocator>&
2402 basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias(
2403 const value_type* __s, size_type __n) {
2404 size_type __cap = __is_short ? static_cast<size_type>(__min_cap) : __get_long_cap();
2406 pointer __p = __is_short ? __get_short_pointer() : __get_long_pointer();
2407 __is_short ? __set_short_size(__n) : __set_long_size(__n);
2408 traits_type::copy(std::__to_address(__p), __s, __n);
2409 traits_type::assign(__p[__n], value_type());
2411 size_type __sz = __is_short ? __get_short_size() : __get_long_size();
2412 __grow_by_and_replace(__cap - 1, __n - __cap + 1, __sz, 0, __sz, __n, __s);
2417 template <class _CharT, class _Traits, class _Allocator>
2418 _LIBCPP_CONSTEXPR_SINCE_CXX20
2419 basic_string<_CharT, _Traits, _Allocator>&
2420 basic_string<_CharT, _Traits, _Allocator>::__assign_external(
2421 const value_type* __s, size_type __n) {
2422 size_type __cap = capacity();
2424 value_type* __p = std::__to_address(__get_pointer());
2425 traits_type::move(__p, __s, __n);
2426 return __null_terminate_at(__p, __n);
2428 size_type __sz = size();
2429 __grow_by_and_replace(__cap, __n - __cap, __sz, 0, __sz, __n, __s);
2434 template <class _CharT, class _Traits, class _Allocator>
2435 _LIBCPP_CONSTEXPR_SINCE_CXX20
2436 basic_string<_CharT, _Traits, _Allocator>&
2437 basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n)
2439 _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::assign received nullptr");
2440 return (__builtin_constant_p(__n) && __fits_in_sso(__n))
2441 ? __assign_short(__s, __n)
2442 : __assign_external(__s, __n);
2445 template <class _CharT, class _Traits, class _Allocator>
2446 _LIBCPP_CONSTEXPR_SINCE_CXX20
2447 basic_string<_CharT, _Traits, _Allocator>&
2448 basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c)
2450 size_type __cap = capacity();
2453 size_type __sz = size();
2454 __grow_by_without_replace(__cap, __n - __cap, __sz, 0, __sz);
2456 value_type* __p = std::__to_address(__get_pointer());
2457 traits_type::assign(__p, __n, __c);
2458 return __null_terminate_at(__p, __n);
2461 template <class _CharT, class _Traits, class _Allocator>
2462 _LIBCPP_CONSTEXPR_SINCE_CXX20
2463 basic_string<_CharT, _Traits, _Allocator>&
2464 basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c)
2469 __p = __get_long_pointer();
2474 __p = __get_short_pointer();
2475 __set_short_size(1);
2477 traits_type::assign(*__p, __c);
2478 traits_type::assign(*++__p, value_type());
2482 template <class _CharT, class _Traits, class _Allocator>
2483 _LIBCPP_CONSTEXPR_SINCE_CXX20
2484 basic_string<_CharT, _Traits, _Allocator>&
2485 basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str)
2487 if (this != std::addressof(__str)) {
2488 __copy_assign_alloc(__str);
2490 if (!__str.__is_long()) {
2491 __r_.first() = __str.__r_.first();
2493 return __assign_no_alias<true>(__str.data(), __str.size());
2496 return __assign_no_alias<false>(__str.data(), __str.size());
2502 #ifndef _LIBCPP_CXX03_LANG
2504 template <class _CharT, class _Traits, class _Allocator>
2505 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
2507 basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, false_type)
2508 _NOEXCEPT_(__alloc_traits::is_always_equal::value)
2510 if (__alloc() != __str.__alloc())
2513 __move_assign(__str, true_type());
2516 template <class _CharT, class _Traits, class _Allocator>
2517 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
2519 basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type)
2520 #if _LIBCPP_STD_VER >= 17
2523 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
2527 __alloc_traits::deallocate(__alloc(), __get_long_pointer(),
2529 #if _LIBCPP_STD_VER <= 14
2530 if (!is_nothrow_move_assignable<allocator_type>::value) {
2531 __set_short_size(0);
2532 traits_type::assign(__get_short_pointer()[0], value_type());
2536 __move_assign_alloc(__str);
2537 __r_.first() = __str.__r_.first();
2538 __str.__set_short_size(0);
2539 traits_type::assign(__str.__get_short_pointer()[0], value_type());
2544 template <class _CharT, class _Traits, class _Allocator>
2545 template<class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> >
2546 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
2547 basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
2549 __assign_with_sentinel(__first, __last);
2553 template <class _CharT, class _Traits, class _Allocator>
2554 template <class _InputIterator, class _Sentinel>
2555 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
2557 basic_string<_CharT, _Traits, _Allocator>::__assign_with_sentinel(_InputIterator __first, _Sentinel __last) {
2558 const basic_string __temp(__init_with_sentinel_tag(), std::move(__first), std::move(__last), __alloc());
2559 assign(__temp.data(), __temp.size());
2562 template <class _CharT, class _Traits, class _Allocator>
2563 template<class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> >
2564 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
2565 basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)
2567 if (__string_is_trivial_iterator<_ForwardIterator>::value) {
2568 size_type __n = static_cast<size_type>(std::distance(__first, __last));
2569 __assign_trivial(__first, __last, __n);
2571 __assign_with_sentinel(__first, __last);
2577 template <class _CharT, class _Traits, class _Allocator>
2578 template <class _Iterator, class _Sentinel>
2579 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
2581 basic_string<_CharT, _Traits, _Allocator>::__assign_trivial(_Iterator __first, _Sentinel __last, size_type __n) {
2582 _LIBCPP_ASSERT_INTERNAL(
2583 __string_is_trivial_iterator<_Iterator>::value, "The iterator type given to `__assign_trivial` must be trivial");
2585 size_type __cap = capacity();
2587 // Unlike `append` functions, if the input range points into the string itself, there is no case that the input
2588 // range could get invalidated by reallocation:
2589 // 1. If the input range is a subset of the string itself, its size cannot exceed the capacity of the string,
2590 // thus no reallocation would happen.
2591 // 2. In the exotic case where the input range is the byte representation of the string itself, the string
2592 // object itself stays valid even if reallocation happens.
2593 size_type __sz = size();
2594 __grow_by_without_replace(__cap, __n - __cap, __sz, 0, __sz);
2596 pointer __p = __get_pointer();
2597 for (; __first != __last; ++__p, (void) ++__first)
2598 traits_type::assign(*__p, *__first);
2599 traits_type::assign(*__p, value_type());
2603 template <class _CharT, class _Traits, class _Allocator>
2604 _LIBCPP_CONSTEXPR_SINCE_CXX20
2605 basic_string<_CharT, _Traits, _Allocator>&
2606 basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, size_type __pos, size_type __n)
2608 size_type __sz = __str.size();
2610 __throw_out_of_range();
2611 return assign(__str.data() + __pos, std::min(__n, __sz - __pos));
2614 template <class _CharT, class _Traits, class _Allocator>
2615 template <class _Tp,
2616 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
2617 !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
2619 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
2620 basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp& __t, size_type __pos, size_type __n) {
2621 __self_view __sv = __t;
2622 size_type __sz = __sv.size();
2624 __throw_out_of_range();
2625 return assign(__sv.data() + __pos, std::min(__n, __sz - __pos));
2628 template <class _CharT, class _Traits, class _Allocator>
2629 _LIBCPP_CONSTEXPR_SINCE_CXX20
2630 basic_string<_CharT, _Traits, _Allocator>&
2631 basic_string<_CharT, _Traits, _Allocator>::__assign_external(const value_type* __s) {
2632 return __assign_external(__s, traits_type::length(__s));
2635 template <class _CharT, class _Traits, class _Allocator>
2636 _LIBCPP_CONSTEXPR_SINCE_CXX20
2637 basic_string<_CharT, _Traits, _Allocator>&
2638 basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s)
2640 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::assign received nullptr");
2641 return __builtin_constant_p(*__s)
2642 ? (__fits_in_sso(traits_type::length(__s))
2643 ? __assign_short(__s, traits_type::length(__s))
2644 : __assign_external(__s, traits_type::length(__s)))
2645 : __assign_external(__s);
2649 template <class _CharT, class _Traits, class _Allocator>
2650 _LIBCPP_CONSTEXPR_SINCE_CXX20
2651 basic_string<_CharT, _Traits, _Allocator>&
2652 basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n)
2654 _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::append received nullptr");
2655 size_type __cap = capacity();
2656 size_type __sz = size();
2657 if (__cap - __sz >= __n)
2661 value_type* __p = std::__to_address(__get_pointer());
2662 traits_type::copy(__p + __sz, __s, __n);
2665 traits_type::assign(__p[__sz], value_type());
2669 __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __sz, 0, __n, __s);
2673 template <class _CharT, class _Traits, class _Allocator>
2674 _LIBCPP_CONSTEXPR_SINCE_CXX20
2675 basic_string<_CharT, _Traits, _Allocator>&
2676 basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c)
2680 size_type __cap = capacity();
2681 size_type __sz = size();
2682 if (__cap - __sz < __n)
2683 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
2684 pointer __p = __get_pointer();
2685 traits_type::assign(std::__to_address(__p) + __sz, __n, __c);
2688 traits_type::assign(__p[__sz], value_type());
2693 template <class _CharT, class _Traits, class _Allocator>
2694 _LIBCPP_CONSTEXPR_SINCE_CXX20 inline void
2695 basic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n)
2699 size_type __cap = capacity();
2700 size_type __sz = size();
2701 if (__cap - __sz < __n)
2702 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
2703 pointer __p = __get_pointer();
2706 traits_type::assign(__p[__sz], value_type());
2710 template <class _CharT, class _Traits, class _Allocator>
2711 _LIBCPP_CONSTEXPR_SINCE_CXX20
2713 basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c)
2715 bool __is_short = !__is_long();
2720 __cap = __min_cap - 1;
2721 __sz = __get_short_size();
2725 __cap = __get_long_cap() - 1;
2726 __sz = __get_long_size();
2730 __grow_by_without_replace(__cap, 1, __sz, __sz, 0);
2731 __is_short = false; // the string is always long after __grow_by
2733 pointer __p = __get_pointer();
2736 __p = __get_short_pointer() + __sz;
2737 __set_short_size(__sz+1);
2741 __p = __get_long_pointer() + __sz;
2742 __set_long_size(__sz+1);
2744 traits_type::assign(*__p, __c);
2745 traits_type::assign(*++__p, value_type());
2748 template <class _CharT, class _Traits, class _Allocator>
2749 template<class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> >
2750 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
2751 basic_string<_CharT, _Traits, _Allocator>::append(
2752 _ForwardIterator __first, _ForwardIterator __last)
2754 size_type __sz = size();
2755 size_type __cap = capacity();
2756 size_type __n = static_cast<size_type>(std::distance(__first, __last));
2759 if (__string_is_trivial_iterator<_ForwardIterator>::value &&
2760 !__addr_in_range(*__first))
2762 if (__cap - __sz < __n)
2763 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
2764 pointer __p = __get_pointer() + __sz;
2765 for (; __first != __last; ++__p, (void) ++__first)
2766 traits_type::assign(*__p, *__first);
2767 traits_type::assign(*__p, value_type());
2768 __set_size(__sz + __n);
2772 const basic_string __temp(__first, __last, __alloc());
2773 append(__temp.data(), __temp.size());
2779 template <class _CharT, class _Traits, class _Allocator>
2780 _LIBCPP_CONSTEXPR_SINCE_CXX20
2781 basic_string<_CharT, _Traits, _Allocator>&
2782 basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, size_type __pos, size_type __n)
2784 size_type __sz = __str.size();
2786 __throw_out_of_range();
2787 return append(__str.data() + __pos, std::min(__n, __sz - __pos));
2790 template <class _CharT, class _Traits, class _Allocator>
2791 template <class _Tp,
2792 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
2793 !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
2795 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
2796 basic_string<_CharT, _Traits, _Allocator>::append(const _Tp& __t, size_type __pos, size_type __n) {
2797 __self_view __sv = __t;
2798 size_type __sz = __sv.size();
2800 __throw_out_of_range();
2801 return append(__sv.data() + __pos, std::min(__n, __sz - __pos));
2804 template <class _CharT, class _Traits, class _Allocator>
2805 _LIBCPP_CONSTEXPR_SINCE_CXX20
2806 basic_string<_CharT, _Traits, _Allocator>&
2807 basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s)
2809 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::append received nullptr");
2810 return append(__s, traits_type::length(__s));
2815 template <class _CharT, class _Traits, class _Allocator>
2816 _LIBCPP_CONSTEXPR_SINCE_CXX20
2817 basic_string<_CharT, _Traits, _Allocator>&
2818 basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n)
2820 _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::insert received nullptr");
2821 size_type __sz = size();
2823 __throw_out_of_range();
2824 size_type __cap = capacity();
2825 if (__cap - __sz >= __n)
2829 value_type* __p = std::__to_address(__get_pointer());
2830 size_type __n_move = __sz - __pos;
2833 if (std::__is_pointer_in_range(__p + __pos, __p + __sz, __s))
2835 traits_type::move(__p + __pos + __n, __p + __pos, __n_move);
2837 traits_type::move(__p + __pos, __s, __n);
2840 traits_type::assign(__p[__sz], value_type());
2844 __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s);
2848 template <class _CharT, class _Traits, class _Allocator>
2849 _LIBCPP_CONSTEXPR_SINCE_CXX20
2850 basic_string<_CharT, _Traits, _Allocator>&
2851 basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n, value_type __c)
2853 size_type __sz = size();
2855 __throw_out_of_range();
2858 size_type __cap = capacity();
2860 if (__cap - __sz >= __n)
2862 __p = std::__to_address(__get_pointer());
2863 size_type __n_move = __sz - __pos;
2865 traits_type::move(__p + __pos + __n, __p + __pos, __n_move);
2869 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n);
2870 __p = std::__to_address(__get_long_pointer());
2872 traits_type::assign(__p + __pos, __n, __c);
2875 traits_type::assign(__p[__sz], value_type());
2880 template <class _CharT, class _Traits, class _Allocator>
2881 template<class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> >
2882 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator
2883 basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last)
2885 const basic_string __temp(__first, __last, __alloc());
2886 return insert(__pos, __temp.data(), __temp.data() + __temp.size());
2889 template <class _CharT, class _Traits, class _Allocator>
2890 template<class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> >
2891 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator
2892 basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last)
2894 auto __n = static_cast<size_type>(std::distance(__first, __last));
2895 return __insert_with_size(__pos, __first, __last, __n);
2898 template <class _CharT, class _Traits, class _Allocator>
2899 template<class _Iterator, class _Sentinel>
2900 _LIBCPP_CONSTEXPR_SINCE_CXX20
2901 typename basic_string<_CharT, _Traits, _Allocator>::iterator
2902 basic_string<_CharT, _Traits, _Allocator>::__insert_with_size(
2903 const_iterator __pos, _Iterator __first, _Sentinel __last, size_type __n) {
2904 size_type __ip = static_cast<size_type>(__pos - begin());
2906 return begin() + __ip;
2908 if (__string_is_trivial_iterator<_Iterator>::value && !__addr_in_range(*__first))
2910 return __insert_from_safe_copy(__n, __ip, __first, __last);
2914 const basic_string __temp(__init_with_sentinel_tag(), __first, __last, __alloc());
2915 return __insert_from_safe_copy(__n, __ip, __temp.begin(), __temp.end());
2919 template <class _CharT, class _Traits, class _Allocator>
2920 _LIBCPP_CONSTEXPR_SINCE_CXX20
2921 basic_string<_CharT, _Traits, _Allocator>&
2922 basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str,
2923 size_type __pos2, size_type __n)
2925 size_type __str_sz = __str.size();
2926 if (__pos2 > __str_sz)
2927 __throw_out_of_range();
2928 return insert(__pos1, __str.data() + __pos2, std::min(__n, __str_sz - __pos2));
2931 template <class _CharT, class _Traits, class _Allocator>
2932 template <class _Tp,
2933 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
2934 !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
2936 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
2937 basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n) {
2938 __self_view __sv = __t;
2939 size_type __str_sz = __sv.size();
2940 if (__pos2 > __str_sz)
2941 __throw_out_of_range();
2942 return insert(__pos1, __sv.data() + __pos2, std::min(__n, __str_sz - __pos2));
2945 template <class _CharT, class _Traits, class _Allocator>
2946 _LIBCPP_CONSTEXPR_SINCE_CXX20
2947 basic_string<_CharT, _Traits, _Allocator>&
2948 basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s)
2950 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::insert received nullptr");
2951 return insert(__pos, __s, traits_type::length(__s));
2954 template <class _CharT, class _Traits, class _Allocator>
2955 _LIBCPP_CONSTEXPR_SINCE_CXX20
2956 typename basic_string<_CharT, _Traits, _Allocator>::iterator
2957 basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c)
2959 size_type __ip = static_cast<size_type>(__pos - begin());
2960 size_type __sz = size();
2961 size_type __cap = capacity();
2965 __grow_by_without_replace(__cap, 1, __sz, __ip, 0, 1);
2966 __p = std::__to_address(__get_long_pointer());
2970 __p = std::__to_address(__get_pointer());
2971 size_type __n_move = __sz - __ip;
2973 traits_type::move(__p + __ip + 1, __p + __ip, __n_move);
2975 traits_type::assign(__p[__ip], __c);
2976 traits_type::assign(__p[++__sz], value_type());
2978 return begin() + static_cast<difference_type>(__ip);
2983 template <class _CharT, class _Traits, class _Allocator>
2984 _LIBCPP_CONSTEXPR_SINCE_CXX20
2985 basic_string<_CharT, _Traits, _Allocator>&
2986 basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2)
2987 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
2989 _LIBCPP_ASSERT_UNCATEGORIZED(__n2 == 0 || __s != nullptr, "string::replace received nullptr");
2990 size_type __sz = size();
2992 __throw_out_of_range();
2993 __n1 = std::min(__n1, __sz - __pos);
2994 size_type __cap = capacity();
2995 if (__cap - __sz + __n1 >= __n2)
2997 value_type* __p = std::__to_address(__get_pointer());
3000 size_type __n_move = __sz - __pos - __n1;
3005 traits_type::move(__p + __pos, __s, __n2);
3006 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
3007 return __null_terminate_at(__p, __sz + (__n2 - __n1));
3009 if (std::__is_pointer_in_range(__p + __pos + 1, __p + __sz, __s))
3011 if (__p + __pos + __n1 <= __s)
3013 else // __p + __pos < __s < __p + __pos + __n1
3015 traits_type::move(__p + __pos, __s, __n1);
3022 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
3025 traits_type::move(__p + __pos, __s, __n2);
3026 return __null_terminate_at(__p, __sz + (__n2 - __n1));
3029 __grow_by_and_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2, __s);
3033 template <class _CharT, class _Traits, class _Allocator>
3034 _LIBCPP_CONSTEXPR_SINCE_CXX20
3035 basic_string<_CharT, _Traits, _Allocator>&
3036 basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, size_type __n2, value_type __c)
3038 size_type __sz = size();
3040 __throw_out_of_range();
3041 __n1 = std::min(__n1, __sz - __pos);
3042 size_type __cap = capacity();
3044 if (__cap - __sz + __n1 >= __n2)
3046 __p = std::__to_address(__get_pointer());
3049 size_type __n_move = __sz - __pos - __n1;
3051 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
3056 __grow_by_without_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2);
3057 __p = std::__to_address(__get_long_pointer());
3059 traits_type::assign(__p + __pos, __n2, __c);
3060 return __null_terminate_at(__p, __sz - (__n1 - __n2));
3063 template <class _CharT, class _Traits, class _Allocator>
3064 template<class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> >
3065 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
3066 basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2,
3067 _InputIterator __j1, _InputIterator __j2)
3069 const basic_string __temp(__j1, __j2, __alloc());
3070 return replace(__i1, __i2, __temp);
3073 template <class _CharT, class _Traits, class _Allocator>
3074 _LIBCPP_CONSTEXPR_SINCE_CXX20
3075 basic_string<_CharT, _Traits, _Allocator>&
3076 basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str,
3077 size_type __pos2, size_type __n2)
3079 size_type __str_sz = __str.size();
3080 if (__pos2 > __str_sz)
3081 __throw_out_of_range();
3082 return replace(__pos1, __n1, __str.data() + __pos2, std::min(__n2, __str_sz - __pos2));
3085 template <class _CharT, class _Traits, class _Allocator>
3086 template <class _Tp,
3087 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
3088 !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
3090 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
3091 basic_string<_CharT, _Traits, _Allocator>::replace(
3092 size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2) {
3093 __self_view __sv = __t;
3094 size_type __str_sz = __sv.size();
3095 if (__pos2 > __str_sz)
3096 __throw_out_of_range();
3097 return replace(__pos1, __n1, __sv.data() + __pos2, std::min(__n2, __str_sz - __pos2));
3100 template <class _CharT, class _Traits, class _Allocator>
3101 _LIBCPP_CONSTEXPR_SINCE_CXX20
3102 basic_string<_CharT, _Traits, _Allocator>&
3103 basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s)
3105 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::replace received nullptr");
3106 return replace(__pos, __n1, __s, traits_type::length(__s));
3111 // 'externally instantiated' erase() implementation, called when __n != npos.
3112 // Does not check __pos against size()
3113 template <class _CharT, class _Traits, class _Allocator>
3114 _LIBCPP_CONSTEXPR_SINCE_CXX20
3116 basic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move(
3117 size_type __pos, size_type __n)
3121 size_type __sz = size();
3122 value_type* __p = std::__to_address(__get_pointer());
3123 __n = std::min(__n, __sz - __pos);
3124 size_type __n_move = __sz - __pos - __n;
3126 traits_type::move(__p + __pos, __p + __pos + __n, __n_move);
3127 __null_terminate_at(__p, __sz - __n);
3131 template <class _CharT, class _Traits, class _Allocator>
3132 _LIBCPP_CONSTEXPR_SINCE_CXX20
3133 basic_string<_CharT, _Traits, _Allocator>&
3134 basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos,
3137 __throw_out_of_range();
3139 __erase_to_end(__pos);
3141 __erase_external_with_move(__pos, __n);
3146 template <class _CharT, class _Traits, class _Allocator>
3147 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
3148 typename basic_string<_CharT, _Traits, _Allocator>::iterator
3149 basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos)
3151 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
3152 __pos != end(), "string::erase(iterator) called with a non-dereferenceable iterator");
3153 iterator __b = begin();
3154 size_type __r = static_cast<size_type>(__pos - __b);
3156 return __b + static_cast<difference_type>(__r);
3159 template <class _CharT, class _Traits, class _Allocator>
3160 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
3161 typename basic_string<_CharT, _Traits, _Allocator>::iterator
3162 basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last)
3164 _LIBCPP_ASSERT_VALID_INPUT_RANGE(__first <= __last, "string::erase(first, last) called with invalid range");
3165 iterator __b = begin();
3166 size_type __r = static_cast<size_type>(__first - __b);
3167 erase(__r, static_cast<size_type>(__last - __first));
3168 return __b + static_cast<difference_type>(__r);
3171 template <class _CharT, class _Traits, class _Allocator>
3172 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
3174 basic_string<_CharT, _Traits, _Allocator>::pop_back()
3176 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::pop_back(): string is already empty");
3177 __erase_to_end(size() - 1);
3180 template <class _CharT, class _Traits, class _Allocator>
3181 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
3183 basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT
3187 traits_type::assign(*__get_long_pointer(), value_type());
3192 traits_type::assign(*__get_short_pointer(), value_type());
3193 __set_short_size(0);
3197 template <class _CharT, class _Traits, class _Allocator>
3198 _LIBCPP_CONSTEXPR_SINCE_CXX20
3200 basic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c)
3202 size_type __sz = size();
3204 append(__n - __sz, __c);
3206 __erase_to_end(__n);
3209 template <class _CharT, class _Traits, class _Allocator>
3210 _LIBCPP_CONSTEXPR_SINCE_CXX20 inline void
3211 basic_string<_CharT, _Traits, _Allocator>::__resize_default_init(size_type __n)
3213 size_type __sz = size();
3215 __append_default_init(__n - __sz);
3217 __erase_to_end(__n);
3220 template <class _CharT, class _Traits, class _Allocator>
3221 _LIBCPP_CONSTEXPR_SINCE_CXX20
3223 basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacity)
3225 if (__requested_capacity > max_size())
3226 __throw_length_error();
3228 // Make sure reserve(n) never shrinks. This is technically only required in C++20
3229 // and later (since P0966R1), however we provide consistent behavior in all Standard
3230 // modes because this function is instantiated in the shared library.
3231 if (__requested_capacity <= capacity())
3234 size_type __target_capacity = std::max(__requested_capacity, size());
3235 __target_capacity = __recommend(__target_capacity);
3236 if (__target_capacity == capacity()) return;
3238 __shrink_or_extend(__target_capacity);
3241 template <class _CharT, class _Traits, class _Allocator>
3242 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
3244 basic_string<_CharT, _Traits, _Allocator>::shrink_to_fit() _NOEXCEPT
3246 size_type __target_capacity = __recommend(size());
3247 if (__target_capacity == capacity()) return;
3249 __shrink_or_extend(__target_capacity);
3252 template <class _CharT, class _Traits, class _Allocator>
3253 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
3255 basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target_capacity)
3257 size_type __cap = capacity();
3258 size_type __sz = size();
3260 pointer __new_data, __p;
3261 bool __was_long, __now_long;
3262 if (__fits_in_sso(__target_capacity))
3266 __new_data = __get_short_pointer();
3267 __p = __get_long_pointer();
3271 if (__target_capacity > __cap) {
3272 auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1);
3273 __new_data = __allocation.ptr;
3274 __target_capacity = __allocation.count - 1;
3278 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
3281 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
3282 auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1);
3283 __new_data = __allocation.ptr;
3284 __target_capacity = __allocation.count - 1;
3285 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
3291 #else // _LIBCPP_HAS_NO_EXCEPTIONS
3292 if (__new_data == nullptr)
3294 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
3296 __begin_lifetime(__new_data, __target_capacity + 1);
3298 __was_long = __is_long();
3299 __p = __get_pointer();
3301 traits_type::copy(std::__to_address(__new_data),
3302 std::__to_address(__p), size()+1);
3304 __alloc_traits::deallocate(__alloc(), __p, __cap+1);
3307 __set_long_cap(__target_capacity+1);
3308 __set_long_size(__sz);
3309 __set_long_pointer(__new_data);
3312 __set_short_size(__sz);
3315 template <class _CharT, class _Traits, class _Allocator>
3316 _LIBCPP_CONSTEXPR_SINCE_CXX20
3317 typename basic_string<_CharT, _Traits, _Allocator>::const_reference
3318 basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const
3321 __throw_out_of_range();
3322 return (*this)[__n];
3325 template <class _CharT, class _Traits, class _Allocator>
3326 _LIBCPP_CONSTEXPR_SINCE_CXX20
3327 typename basic_string<_CharT, _Traits, _Allocator>::reference
3328 basic_string<_CharT, _Traits, _Allocator>::at(size_type __n)
3331 __throw_out_of_range();
3332 return (*this)[__n];
3335 template <class _CharT, class _Traits, class _Allocator>
3336 _LIBCPP_CONSTEXPR_SINCE_CXX20
3337 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3338 basic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n, size_type __pos) const
3340 size_type __sz = size();
3342 __throw_out_of_range();
3343 size_type __rlen = std::min(__n, __sz - __pos);
3344 traits_type::copy(__s, data() + __pos, __rlen);
3348 template <class _CharT, class _Traits, class _Allocator>
3349 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
3351 basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str)
3352 #if _LIBCPP_STD_VER >= 14
3355 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
3356 __is_nothrow_swappable<allocator_type>::value)
3359 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
3360 __alloc_traits::propagate_on_container_swap::value ||
3361 __alloc_traits::is_always_equal::value ||
3362 __alloc() == __str.__alloc(), "swapping non-equal allocators");
3363 std::swap(__r_.first(), __str.__r_.first());
3364 std::__swap_allocator(__alloc(), __str.__alloc());
3369 template <class _Traits>
3370 struct _LIBCPP_HIDDEN __traits_eq
3372 typedef typename _Traits::char_type char_type;
3373 _LIBCPP_HIDE_FROM_ABI
3374 bool operator()(const char_type& __x, const char_type& __y) _NOEXCEPT
3375 {return _Traits::eq(__x, __y);}
3378 template<class _CharT, class _Traits, class _Allocator>
3379 _LIBCPP_CONSTEXPR_SINCE_CXX20
3380 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3381 basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
3383 size_type __n) const _NOEXCEPT
3385 _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::find(): received nullptr");
3386 return std::__str_find<value_type, size_type, traits_type, npos>
3387 (data(), size(), __s, __pos, __n);
3390 template<class _CharT, class _Traits, class _Allocator>
3391 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
3392 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3393 basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str,
3394 size_type __pos) const _NOEXCEPT
3396 return std::__str_find<value_type, size_type, traits_type, npos>
3397 (data(), size(), __str.data(), __pos, __str.size());
3400 template<class _CharT, class _Traits, class _Allocator>
3401 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
3402 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3403 basic_string<_CharT, _Traits, _Allocator>::find(const _Tp &__t,
3404 size_type __pos) const _NOEXCEPT
3406 __self_view __sv = __t;
3407 return std::__str_find<value_type, size_type, traits_type, npos>
3408 (data(), size(), __sv.data(), __pos, __sv.size());
3411 template<class _CharT, class _Traits, class _Allocator>
3412 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
3413 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3414 basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
3415 size_type __pos) const _NOEXCEPT
3417 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::find(): received nullptr");
3418 return std::__str_find<value_type, size_type, traits_type, npos>
3419 (data(), size(), __s, __pos, traits_type::length(__s));
3422 template<class _CharT, class _Traits, class _Allocator>
3423 _LIBCPP_CONSTEXPR_SINCE_CXX20
3424 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3425 basic_string<_CharT, _Traits, _Allocator>::find(value_type __c,
3426 size_type __pos) const _NOEXCEPT
3428 return std::__str_find<value_type, size_type, traits_type, npos>
3429 (data(), size(), __c, __pos);
3434 template<class _CharT, class _Traits, class _Allocator>
3435 _LIBCPP_CONSTEXPR_SINCE_CXX20
3436 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3437 basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
3439 size_type __n) const _NOEXCEPT
3441 _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::rfind(): received nullptr");
3442 return std::__str_rfind<value_type, size_type, traits_type, npos>
3443 (data(), size(), __s, __pos, __n);
3446 template<class _CharT, class _Traits, class _Allocator>
3447 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
3448 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3449 basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str,
3450 size_type __pos) const _NOEXCEPT
3452 return std::__str_rfind<value_type, size_type, traits_type, npos>
3453 (data(), size(), __str.data(), __pos, __str.size());
3456 template<class _CharT, class _Traits, class _Allocator>
3457 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
3458 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3459 basic_string<_CharT, _Traits, _Allocator>::rfind(const _Tp& __t,
3460 size_type __pos) const _NOEXCEPT
3462 __self_view __sv = __t;
3463 return std::__str_rfind<value_type, size_type, traits_type, npos>
3464 (data(), size(), __sv.data(), __pos, __sv.size());
3467 template<class _CharT, class _Traits, class _Allocator>
3468 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
3469 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3470 basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
3471 size_type __pos) const _NOEXCEPT
3473 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::rfind(): received nullptr");
3474 return std::__str_rfind<value_type, size_type, traits_type, npos>
3475 (data(), size(), __s, __pos, traits_type::length(__s));
3478 template<class _CharT, class _Traits, class _Allocator>
3479 _LIBCPP_CONSTEXPR_SINCE_CXX20
3480 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3481 basic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c,
3482 size_type __pos) const _NOEXCEPT
3484 return std::__str_rfind<value_type, size_type, traits_type, npos>
3485 (data(), size(), __c, __pos);
3490 template<class _CharT, class _Traits, class _Allocator>
3491 _LIBCPP_CONSTEXPR_SINCE_CXX20
3492 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3493 basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
3495 size_type __n) const _NOEXCEPT
3497 _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr");
3498 return std::__str_find_first_of<value_type, size_type, traits_type, npos>
3499 (data(), size(), __s, __pos, __n);
3502 template<class _CharT, class _Traits, class _Allocator>
3503 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
3504 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3505 basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str,
3506 size_type __pos) const _NOEXCEPT
3508 return std::__str_find_first_of<value_type, size_type, traits_type, npos>
3509 (data(), size(), __str.data(), __pos, __str.size());
3512 template<class _CharT, class _Traits, class _Allocator>
3513 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
3514 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3515 basic_string<_CharT, _Traits, _Allocator>::find_first_of(const _Tp& __t,
3516 size_type __pos) const _NOEXCEPT
3518 __self_view __sv = __t;
3519 return std::__str_find_first_of<value_type, size_type, traits_type, npos>
3520 (data(), size(), __sv.data(), __pos, __sv.size());
3523 template<class _CharT, class _Traits, class _Allocator>
3524 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
3525 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3526 basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
3527 size_type __pos) const _NOEXCEPT
3529 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::find_first_of(): received nullptr");
3530 return std::__str_find_first_of<value_type, size_type, traits_type, npos>
3531 (data(), size(), __s, __pos, traits_type::length(__s));
3534 template<class _CharT, class _Traits, class _Allocator>
3535 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
3536 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3537 basic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c,
3538 size_type __pos) const _NOEXCEPT
3540 return find(__c, __pos);
3545 template<class _CharT, class _Traits, class _Allocator>
3546 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
3547 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3548 basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
3550 size_type __n) const _NOEXCEPT
3552 _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr");
3553 return std::__str_find_last_of<value_type, size_type, traits_type, npos>
3554 (data(), size(), __s, __pos, __n);
3557 template<class _CharT, class _Traits, class _Allocator>
3558 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
3559 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3560 basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str,
3561 size_type __pos) const _NOEXCEPT
3563 return std::__str_find_last_of<value_type, size_type, traits_type, npos>
3564 (data(), size(), __str.data(), __pos, __str.size());
3567 template<class _CharT, class _Traits, class _Allocator>
3568 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
3569 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3570 basic_string<_CharT, _Traits, _Allocator>::find_last_of(const _Tp& __t,
3571 size_type __pos) const _NOEXCEPT
3573 __self_view __sv = __t;
3574 return std::__str_find_last_of<value_type, size_type, traits_type, npos>
3575 (data(), size(), __sv.data(), __pos, __sv.size());
3578 template<class _CharT, class _Traits, class _Allocator>
3579 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
3580 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3581 basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
3582 size_type __pos) const _NOEXCEPT
3584 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::find_last_of(): received nullptr");
3585 return std::__str_find_last_of<value_type, size_type, traits_type, npos>
3586 (data(), size(), __s, __pos, traits_type::length(__s));
3589 template<class _CharT, class _Traits, class _Allocator>
3590 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
3591 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3592 basic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c,
3593 size_type __pos) const _NOEXCEPT
3595 return rfind(__c, __pos);
3598 // find_first_not_of
3600 template<class _CharT, class _Traits, class _Allocator>
3601 _LIBCPP_CONSTEXPR_SINCE_CXX20
3602 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3603 basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s,
3605 size_type __n) const _NOEXCEPT
3607 _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr");
3608 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
3609 (data(), size(), __s, __pos, __n);
3612 template<class _CharT, class _Traits, class _Allocator>
3613 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
3614 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3615 basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string& __str,
3616 size_type __pos) const _NOEXCEPT
3618 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
3619 (data(), size(), __str.data(), __pos, __str.size());
3622 template<class _CharT, class _Traits, class _Allocator>
3623 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
3624 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3625 basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const _Tp& __t,
3626 size_type __pos) const _NOEXCEPT
3628 __self_view __sv = __t;
3629 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
3630 (data(), size(), __sv.data(), __pos, __sv.size());
3633 template<class _CharT, class _Traits, class _Allocator>
3634 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
3635 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3636 basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s,
3637 size_type __pos) const _NOEXCEPT
3639 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::find_first_not_of(): received nullptr");
3640 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
3641 (data(), size(), __s, __pos, traits_type::length(__s));
3644 template<class _CharT, class _Traits, class _Allocator>
3645 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
3646 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3647 basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c,
3648 size_type __pos) const _NOEXCEPT
3650 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
3651 (data(), size(), __c, __pos);
3656 template<class _CharT, class _Traits, class _Allocator>
3657 _LIBCPP_CONSTEXPR_SINCE_CXX20
3658 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3659 basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s,
3661 size_type __n) const _NOEXCEPT
3663 _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr");
3664 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
3665 (data(), size(), __s, __pos, __n);
3668 template<class _CharT, class _Traits, class _Allocator>
3669 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
3670 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3671 basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string& __str,
3672 size_type __pos) const _NOEXCEPT
3674 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
3675 (data(), size(), __str.data(), __pos, __str.size());
3678 template<class _CharT, class _Traits, class _Allocator>
3679 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
3680 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3681 basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const _Tp& __t,
3682 size_type __pos) const _NOEXCEPT
3684 __self_view __sv = __t;
3685 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
3686 (data(), size(), __sv.data(), __pos, __sv.size());
3689 template<class _CharT, class _Traits, class _Allocator>
3690 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
3691 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3692 basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s,
3693 size_type __pos) const _NOEXCEPT
3695 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::find_last_not_of(): received nullptr");
3696 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
3697 (data(), size(), __s, __pos, traits_type::length(__s));
3700 template<class _CharT, class _Traits, class _Allocator>
3701 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
3702 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3703 basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c,
3704 size_type __pos) const _NOEXCEPT
3706 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
3707 (data(), size(), __c, __pos);
3712 template <class _CharT, class _Traits, class _Allocator>
3713 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
3714 _LIBCPP_CONSTEXPR_SINCE_CXX20 int
3715 basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const _NOEXCEPT
3717 __self_view __sv = __t;
3718 size_t __lhs_sz = size();
3719 size_t __rhs_sz = __sv.size();
3720 int __result = traits_type::compare(data(), __sv.data(),
3721 std::min(__lhs_sz, __rhs_sz));
3724 if (__lhs_sz < __rhs_sz)
3726 if (__lhs_sz > __rhs_sz)
3731 template <class _CharT, class _Traits, class _Allocator>
3732 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
3734 basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT
3736 return compare(__self_view(__str));
3739 template <class _CharT, class _Traits, class _Allocator>
3740 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
3742 basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
3744 const value_type* __s,
3745 size_type __n2) const
3747 _LIBCPP_ASSERT_UNCATEGORIZED(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr");
3748 size_type __sz = size();
3749 if (__pos1 > __sz || __n2 == npos)
3750 __throw_out_of_range();
3751 size_type __rlen = std::min(__n1, __sz - __pos1);
3752 int __r = traits_type::compare(data() + __pos1, __s, std::min(__rlen, __n2));
3757 else if (__rlen > __n2)
3763 template <class _CharT, class _Traits, class _Allocator>
3764 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
3765 _LIBCPP_CONSTEXPR_SINCE_CXX20 int
3766 basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
3768 const _Tp& __t) const
3770 __self_view __sv = __t;
3771 return compare(__pos1, __n1, __sv.data(), __sv.size());
3774 template <class _CharT, class _Traits, class _Allocator>
3775 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
3777 basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
3779 const basic_string& __str) const
3781 return compare(__pos1, __n1, __str.data(), __str.size());
3784 template <class _CharT, class _Traits, class _Allocator>
3785 template <class _Tp,
3786 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
3787 !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
3789 _LIBCPP_CONSTEXPR_SINCE_CXX20 int basic_string<_CharT, _Traits, _Allocator>::compare(
3790 size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2) const {
3791 __self_view __sv = __t;
3792 return __self_view(*this).substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
3795 template <class _CharT, class _Traits, class _Allocator>
3796 _LIBCPP_CONSTEXPR_SINCE_CXX20
3798 basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
3800 const basic_string& __str,
3802 size_type __n2) const
3804 return compare(__pos1, __n1, __self_view(__str), __pos2, __n2);
3807 template <class _CharT, class _Traits, class _Allocator>
3808 _LIBCPP_CONSTEXPR_SINCE_CXX20
3810 basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT
3812 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::compare(): received nullptr");
3813 return compare(0, npos, __s, traits_type::length(__s));
3816 template <class _CharT, class _Traits, class _Allocator>
3817 _LIBCPP_CONSTEXPR_SINCE_CXX20
3819 basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
3821 const value_type* __s) const
3823 _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::compare(): received nullptr");
3824 return compare(__pos1, __n1, __s, traits_type::length(__s));
3829 template<class _CharT, class _Traits, class _Allocator>
3830 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
3832 basic_string<_CharT, _Traits, _Allocator>::__invariants() const
3834 if (size() > capacity())
3836 if (capacity() < __min_cap - 1)
3838 if (data() == nullptr)
3840 if (!_Traits::eq(data()[size()], value_type()))
3845 // __clear_and_shrink
3847 template<class _CharT, class _Traits, class _Allocator>
3848 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
3850 basic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT
3855 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), capacity() + 1);
3856 __r_.first() = __rep();
3862 template<class _CharT, class _Traits, class _Allocator>
3863 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
3865 operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3866 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
3868 #if _LIBCPP_STD_VER >= 20
3869 return basic_string_view<_CharT, _Traits>(__lhs) == basic_string_view<_CharT, _Traits>(__rhs);
3871 size_t __lhs_sz = __lhs.size();
3872 return __lhs_sz == __rhs.size() && _Traits::compare(__lhs.data(),
3878 template<class _Allocator>
3879 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
3881 operator==(const basic_string<char, char_traits<char>, _Allocator>& __lhs,
3882 const basic_string<char, char_traits<char>, _Allocator>& __rhs) _NOEXCEPT
3884 size_t __lhs_sz = __lhs.size();
3885 if (__lhs_sz != __rhs.size())
3887 const char* __lp = __lhs.data();
3888 const char* __rp = __rhs.data();
3889 if (__lhs.__is_long())
3890 return char_traits<char>::compare(__lp, __rp, __lhs_sz) == 0;
3891 for (; __lhs_sz != 0; --__lhs_sz, ++__lp, ++__rp)
3897 #if _LIBCPP_STD_VER <= 17
3898 template<class _CharT, class _Traits, class _Allocator>
3899 inline _LIBCPP_HIDE_FROM_ABI
3901 operator==(const _CharT* __lhs,
3902 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
3904 typedef basic_string<_CharT, _Traits, _Allocator> _String;
3905 _LIBCPP_ASSERT_UNCATEGORIZED(__lhs != nullptr, "operator==(char*, basic_string): received nullptr");
3906 size_t __lhs_len = _Traits::length(__lhs);
3907 if (__lhs_len != __rhs.size()) return false;
3908 return __rhs.compare(0, _String::npos, __lhs, __lhs_len) == 0;
3910 #endif // _LIBCPP_STD_VER <= 17
3912 template<class _CharT, class _Traits, class _Allocator>
3913 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
3915 operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
3916 const _CharT* __rhs) _NOEXCEPT
3918 #if _LIBCPP_STD_VER >= 20
3919 return basic_string_view<_CharT, _Traits>(__lhs) == basic_string_view<_CharT, _Traits>(__rhs);
3921 typedef basic_string<_CharT, _Traits, _Allocator> _String;
3922 _LIBCPP_ASSERT_UNCATEGORIZED(__rhs != nullptr, "operator==(basic_string, char*): received nullptr");
3923 size_t __rhs_len = _Traits::length(__rhs);
3924 if (__rhs_len != __lhs.size()) return false;
3925 return __lhs.compare(0, _String::npos, __rhs, __rhs_len) == 0;
3929 #if _LIBCPP_STD_VER >= 20
3931 template <class _CharT, class _Traits, class _Allocator>
3932 _LIBCPP_HIDE_FROM_ABI constexpr auto operator<=>(
3933 const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3934 const basic_string<_CharT, _Traits, _Allocator>& __rhs) noexcept {
3935 return basic_string_view<_CharT, _Traits>(__lhs) <=> basic_string_view<_CharT, _Traits>(__rhs);
3938 template <class _CharT, class _Traits, class _Allocator>
3939 _LIBCPP_HIDE_FROM_ABI constexpr auto
3940 operator<=>(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) {
3941 return basic_string_view<_CharT, _Traits>(__lhs) <=> basic_string_view<_CharT, _Traits>(__rhs);
3944 #else // _LIBCPP_STD_VER >= 20
3946 template<class _CharT, class _Traits, class _Allocator>
3947 inline _LIBCPP_HIDE_FROM_ABI
3949 operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
3950 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
3952 return !(__lhs == __rhs);
3955 template<class _CharT, class _Traits, class _Allocator>
3956 inline _LIBCPP_HIDE_FROM_ABI
3958 operator!=(const _CharT* __lhs,
3959 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
3961 return !(__lhs == __rhs);
3964 template<class _CharT, class _Traits, class _Allocator>
3965 inline _LIBCPP_HIDE_FROM_ABI
3967 operator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3968 const _CharT* __rhs) _NOEXCEPT
3970 return !(__lhs == __rhs);
3975 template<class _CharT, class _Traits, class _Allocator>
3976 inline _LIBCPP_HIDE_FROM_ABI
3978 operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3979 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
3981 return __lhs.compare(__rhs) < 0;
3984 template<class _CharT, class _Traits, class _Allocator>
3985 inline _LIBCPP_HIDE_FROM_ABI
3987 operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3988 const _CharT* __rhs) _NOEXCEPT
3990 return __lhs.compare(__rhs) < 0;
3993 template<class _CharT, class _Traits, class _Allocator>
3994 inline _LIBCPP_HIDE_FROM_ABI
3996 operator< (const _CharT* __lhs,
3997 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
3999 return __rhs.compare(__lhs) > 0;
4004 template<class _CharT, class _Traits, class _Allocator>
4005 inline _LIBCPP_HIDE_FROM_ABI
4007 operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
4008 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
4010 return __rhs < __lhs;
4013 template<class _CharT, class _Traits, class _Allocator>
4014 inline _LIBCPP_HIDE_FROM_ABI
4016 operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
4017 const _CharT* __rhs) _NOEXCEPT
4019 return __rhs < __lhs;
4022 template<class _CharT, class _Traits, class _Allocator>
4023 inline _LIBCPP_HIDE_FROM_ABI
4025 operator> (const _CharT* __lhs,
4026 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
4028 return __rhs < __lhs;
4033 template<class _CharT, class _Traits, class _Allocator>
4034 inline _LIBCPP_HIDE_FROM_ABI
4036 operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
4037 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
4039 return !(__rhs < __lhs);
4042 template<class _CharT, class _Traits, class _Allocator>
4043 inline _LIBCPP_HIDE_FROM_ABI
4045 operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
4046 const _CharT* __rhs) _NOEXCEPT
4048 return !(__rhs < __lhs);
4051 template<class _CharT, class _Traits, class _Allocator>
4052 inline _LIBCPP_HIDE_FROM_ABI
4054 operator<=(const _CharT* __lhs,
4055 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
4057 return !(__rhs < __lhs);
4062 template<class _CharT, class _Traits, class _Allocator>
4063 inline _LIBCPP_HIDE_FROM_ABI
4065 operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
4066 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
4068 return !(__lhs < __rhs);
4071 template<class _CharT, class _Traits, class _Allocator>
4072 inline _LIBCPP_HIDE_FROM_ABI
4074 operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
4075 const _CharT* __rhs) _NOEXCEPT
4077 return !(__lhs < __rhs);
4080 template<class _CharT, class _Traits, class _Allocator>
4081 inline _LIBCPP_HIDE_FROM_ABI
4083 operator>=(const _CharT* __lhs,
4084 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
4086 return !(__lhs < __rhs);
4088 #endif // _LIBCPP_STD_VER >= 20
4092 template<class _CharT, class _Traits, class _Allocator>
4093 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
4094 basic_string<_CharT, _Traits, _Allocator>
4095 operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
4096 const basic_string<_CharT, _Traits, _Allocator>& __rhs)
4098 using _String = basic_string<_CharT, _Traits, _Allocator>;
4099 auto __lhs_sz = __lhs.size();
4100 auto __rhs_sz = __rhs.size();
4101 _String __r(__uninitialized_size_tag(),
4102 __lhs_sz + __rhs_sz,
4103 _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator()));
4104 auto __ptr = std::__to_address(__r.__get_pointer());
4105 _Traits::copy(__ptr, __lhs.data(), __lhs_sz);
4106 _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz);
4107 _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());
4111 template<class _CharT, class _Traits, class _Allocator>
4112 _LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX20
4113 basic_string<_CharT, _Traits, _Allocator>
4114 operator+(const _CharT* __lhs , const basic_string<_CharT,_Traits,_Allocator>& __rhs)
4116 using _String = basic_string<_CharT, _Traits, _Allocator>;
4117 auto __lhs_sz = _Traits::length(__lhs);
4118 auto __rhs_sz = __rhs.size();
4119 _String __r(__uninitialized_size_tag(),
4120 __lhs_sz + __rhs_sz,
4121 _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator()));
4122 auto __ptr = std::__to_address(__r.__get_pointer());
4123 _Traits::copy(__ptr, __lhs, __lhs_sz);
4124 _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz);
4125 _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());
4129 template<class _CharT, class _Traits, class _Allocator>
4130 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
4131 basic_string<_CharT, _Traits, _Allocator>
4132 operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Allocator>& __rhs)
4134 using _String = basic_string<_CharT, _Traits, _Allocator>;
4135 typename _String::size_type __rhs_sz = __rhs.size();
4136 _String __r(__uninitialized_size_tag(),
4138 _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator()));
4139 auto __ptr = std::__to_address(__r.__get_pointer());
4140 _Traits::assign(__ptr, 1, __lhs);
4141 _Traits::copy(__ptr + 1, __rhs.data(), __rhs_sz);
4142 _Traits::assign(__ptr + 1 + __rhs_sz, 1, _CharT());
4146 template<class _CharT, class _Traits, class _Allocator>
4147 inline _LIBCPP_CONSTEXPR_SINCE_CXX20
4148 basic_string<_CharT, _Traits, _Allocator>
4149 operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs)
4151 using _String = basic_string<_CharT, _Traits, _Allocator>;
4152 typename _String::size_type __lhs_sz = __lhs.size();
4153 typename _String::size_type __rhs_sz = _Traits::length(__rhs);
4154 _String __r(__uninitialized_size_tag(),
4155 __lhs_sz + __rhs_sz,
4156 _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator()));
4157 auto __ptr = std::__to_address(__r.__get_pointer());
4158 _Traits::copy(__ptr, __lhs.data(), __lhs_sz);
4159 _Traits::copy(__ptr + __lhs_sz, __rhs, __rhs_sz);
4160 _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());
4164 template<class _CharT, class _Traits, class _Allocator>
4165 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
4166 basic_string<_CharT, _Traits, _Allocator>
4167 operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs)
4169 using _String = basic_string<_CharT, _Traits, _Allocator>;
4170 typename _String::size_type __lhs_sz = __lhs.size();
4171 _String __r(__uninitialized_size_tag(),
4173 _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator()));
4174 auto __ptr = std::__to_address(__r.__get_pointer());
4175 _Traits::copy(__ptr, __lhs.data(), __lhs_sz);
4176 _Traits::assign(__ptr + __lhs_sz, 1, __rhs);
4177 _Traits::assign(__ptr + 1 + __lhs_sz, 1, _CharT());
4181 #ifndef _LIBCPP_CXX03_LANG
4183 template<class _CharT, class _Traits, class _Allocator>
4184 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
4185 basic_string<_CharT, _Traits, _Allocator>
4186 operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs)
4188 return std::move(__lhs.append(__rhs));
4191 template<class _CharT, class _Traits, class _Allocator>
4192 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
4193 basic_string<_CharT, _Traits, _Allocator>
4194 operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs)
4196 return std::move(__rhs.insert(0, __lhs));
4199 template<class _CharT, class _Traits, class _Allocator>
4200 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
4201 basic_string<_CharT, _Traits, _Allocator>
4202 operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs)
4204 return std::move(__lhs.append(__rhs));
4207 template<class _CharT, class _Traits, class _Allocator>
4208 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
4209 basic_string<_CharT, _Traits, _Allocator>
4210 operator+(const _CharT* __lhs , basic_string<_CharT,_Traits,_Allocator>&& __rhs)
4212 return std::move(__rhs.insert(0, __lhs));
4215 template<class _CharT, class _Traits, class _Allocator>
4216 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
4217 basic_string<_CharT, _Traits, _Allocator>
4218 operator+(_CharT __lhs, basic_string<_CharT,_Traits,_Allocator>&& __rhs)
4220 __rhs.insert(__rhs.begin(), __lhs);
4221 return std::move(__rhs);
4224 template<class _CharT, class _Traits, class _Allocator>
4225 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
4226 basic_string<_CharT, _Traits, _Allocator>
4227 operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const _CharT* __rhs)
4229 return std::move(__lhs.append(__rhs));
4232 template<class _CharT, class _Traits, class _Allocator>
4233 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
4234 basic_string<_CharT, _Traits, _Allocator>
4235 operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT __rhs)
4237 __lhs.push_back(__rhs);
4238 return std::move(__lhs);
4241 #endif // _LIBCPP_CXX03_LANG
4245 template<class _CharT, class _Traits, class _Allocator>
4246 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
4248 swap(basic_string<_CharT, _Traits, _Allocator>& __lhs,
4249 basic_string<_CharT, _Traits, _Allocator>& __rhs)
4250 _NOEXCEPT_(_NOEXCEPT_(__lhs.swap(__rhs)))
4255 _LIBCPP_EXPORTED_FROM_ABI int stoi (const string& __str, size_t* __idx = nullptr, int __base = 10);
4256 _LIBCPP_EXPORTED_FROM_ABI long stol (const string& __str, size_t* __idx = nullptr, int __base = 10);
4257 _LIBCPP_EXPORTED_FROM_ABI unsigned long stoul (const string& __str, size_t* __idx = nullptr, int __base = 10);
4258 _LIBCPP_EXPORTED_FROM_ABI long long stoll (const string& __str, size_t* __idx = nullptr, int __base = 10);
4259 _LIBCPP_EXPORTED_FROM_ABI unsigned long long stoull(const string& __str, size_t* __idx = nullptr, int __base = 10);
4261 _LIBCPP_EXPORTED_FROM_ABI float stof (const string& __str, size_t* __idx = nullptr);
4262 _LIBCPP_EXPORTED_FROM_ABI double stod (const string& __str, size_t* __idx = nullptr);
4263 _LIBCPP_EXPORTED_FROM_ABI long double stold(const string& __str, size_t* __idx = nullptr);
4265 _LIBCPP_EXPORTED_FROM_ABI string to_string(int __val);
4266 _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned __val);
4267 _LIBCPP_EXPORTED_FROM_ABI string to_string(long __val);
4268 _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long __val);
4269 _LIBCPP_EXPORTED_FROM_ABI string to_string(long long __val);
4270 _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long long __val);
4271 _LIBCPP_EXPORTED_FROM_ABI string to_string(float __val);
4272 _LIBCPP_EXPORTED_FROM_ABI string to_string(double __val);
4273 _LIBCPP_EXPORTED_FROM_ABI string to_string(long double __val);
4275 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4276 _LIBCPP_EXPORTED_FROM_ABI int stoi (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
4277 _LIBCPP_EXPORTED_FROM_ABI long stol (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
4278 _LIBCPP_EXPORTED_FROM_ABI unsigned long stoul (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
4279 _LIBCPP_EXPORTED_FROM_ABI long long stoll (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
4280 _LIBCPP_EXPORTED_FROM_ABI unsigned long long stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
4282 _LIBCPP_EXPORTED_FROM_ABI float stof (const wstring& __str, size_t* __idx = nullptr);
4283 _LIBCPP_EXPORTED_FROM_ABI double stod (const wstring& __str, size_t* __idx = nullptr);
4284 _LIBCPP_EXPORTED_FROM_ABI long double stold(const wstring& __str, size_t* __idx = nullptr);
4286 _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(int __val);
4287 _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned __val);
4288 _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long __val);
4289 _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long __val);
4290 _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long long __val);
4291 _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long long __val);
4292 _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(float __val);
4293 _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(double __val);
4294 _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long double __val);
4295 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4297 template<class _CharT, class _Traits, class _Allocator>
4298 _LIBCPP_TEMPLATE_DATA_VIS
4299 const typename basic_string<_CharT, _Traits, _Allocator>::size_type
4300 basic_string<_CharT, _Traits, _Allocator>::npos;
4302 template <class _CharT, class _Allocator>
4303 struct __string_hash : public __unary_function<basic_string<_CharT, char_traits<_CharT>, _Allocator>, size_t> {
4304 _LIBCPP_HIDE_FROM_ABI size_t
4305 operator()(const basic_string<_CharT, char_traits<_CharT>, _Allocator>& __val) const _NOEXCEPT {
4306 return std::__do_string_hash(__val.data(), __val.data() + __val.size());
4310 template <class _Allocator>
4311 struct hash<basic_string<char, char_traits<char>, _Allocator> > : __string_hash<char, _Allocator> {};
4313 #ifndef _LIBCPP_HAS_NO_CHAR8_T
4314 template <class _Allocator>
4315 struct hash<basic_string<char8_t, char_traits<char8_t>, _Allocator> > : __string_hash<char8_t, _Allocator> {};
4318 template <class _Allocator>
4319 struct hash<basic_string<char16_t, char_traits<char16_t>, _Allocator> > : __string_hash<char16_t, _Allocator> {};
4321 template <class _Allocator>
4322 struct hash<basic_string<char32_t, char_traits<char32_t>, _Allocator> > : __string_hash<char32_t, _Allocator> {};
4324 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4325 template <class _Allocator>
4326 struct hash<basic_string<wchar_t, char_traits<wchar_t>, _Allocator> > : __string_hash<wchar_t, _Allocator> {};
4329 template<class _CharT, class _Traits, class _Allocator>
4330 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
4331 operator<<(basic_ostream<_CharT, _Traits>& __os,
4332 const basic_string<_CharT, _Traits, _Allocator>& __str);
4334 template<class _CharT, class _Traits, class _Allocator>
4335 _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
4336 operator>>(basic_istream<_CharT, _Traits>& __is,
4337 basic_string<_CharT, _Traits, _Allocator>& __str);
4339 template<class _CharT, class _Traits, class _Allocator>
4340 _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
4341 getline(basic_istream<_CharT, _Traits>& __is,
4342 basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm);
4344 template<class _CharT, class _Traits, class _Allocator>
4345 inline _LIBCPP_HIDE_FROM_ABI
4346 basic_istream<_CharT, _Traits>&
4347 getline(basic_istream<_CharT, _Traits>& __is,
4348 basic_string<_CharT, _Traits, _Allocator>& __str);
4350 template<class _CharT, class _Traits, class _Allocator>
4351 inline _LIBCPP_HIDE_FROM_ABI
4352 basic_istream<_CharT, _Traits>&
4353 getline(basic_istream<_CharT, _Traits>&& __is,
4354 basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm);
4356 template<class _CharT, class _Traits, class _Allocator>
4357 inline _LIBCPP_HIDE_FROM_ABI
4358 basic_istream<_CharT, _Traits>&
4359 getline(basic_istream<_CharT, _Traits>&& __is,
4360 basic_string<_CharT, _Traits, _Allocator>& __str);
4362 #if _LIBCPP_STD_VER >= 20
4363 template <class _CharT, class _Traits, class _Allocator, class _Up>
4364 inline _LIBCPP_HIDE_FROM_ABI
4365 typename basic_string<_CharT, _Traits, _Allocator>::size_type
4366 erase(basic_string<_CharT, _Traits, _Allocator>& __str, const _Up& __v) {
4367 auto __old_size = __str.size();
4368 __str.erase(std::remove(__str.begin(), __str.end(), __v), __str.end());
4369 return __old_size - __str.size();
4372 template <class _CharT, class _Traits, class _Allocator, class _Predicate>
4373 inline _LIBCPP_HIDE_FROM_ABI
4374 typename basic_string<_CharT, _Traits, _Allocator>::size_type
4375 erase_if(basic_string<_CharT, _Traits, _Allocator>& __str,
4376 _Predicate __pred) {
4377 auto __old_size = __str.size();
4378 __str.erase(std::remove_if(__str.begin(), __str.end(), __pred),
4380 return __old_size - __str.size();
4384 #if _LIBCPP_STD_VER >= 14
4385 // Literal suffixes for basic_string [basic.string.literals]
4386 inline namespace literals
4388 inline namespace string_literals
4390 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
4391 basic_string<char> operator""s( const char *__str, size_t __len )
4393 return basic_string<char> (__str, __len);
4396 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4397 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
4398 basic_string<wchar_t> operator""s( const wchar_t *__str, size_t __len )
4400 return basic_string<wchar_t> (__str, __len);
4404 #ifndef _LIBCPP_HAS_NO_CHAR8_T
4405 inline _LIBCPP_HIDE_FROM_ABI constexpr
4406 basic_string<char8_t> operator""s(const char8_t *__str, size_t __len)
4408 return basic_string<char8_t> (__str, __len);
4412 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
4413 basic_string<char16_t> operator""s( const char16_t *__str, size_t __len )
4415 return basic_string<char16_t> (__str, __len);
4418 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
4419 basic_string<char32_t> operator""s( const char32_t *__str, size_t __len )
4421 return basic_string<char32_t> (__str, __len);
4423 } // namespace string_literals
4424 } // namespace literals
4426 #if _LIBCPP_STD_VER >= 20
4428 inline constexpr bool __format::__enable_insertable<std::basic_string<char>> = true;
4429 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4431 inline constexpr bool __format::__enable_insertable<std::basic_string<wchar_t>> = true;
4437 _LIBCPP_END_NAMESPACE_STD
4441 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
4442 # include <algorithm>
4443 # include <concepts>
4445 # include <iterator>
4447 # include <type_traits>
4448 # include <typeinfo>
4452 #endif // _LIBCPP_STRING