1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
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
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_STRING
11#define _LIBCPP_STRING
12
13/*
14 string synopsis
15
16namespace std
17{
18
19template <class stateT>
20class fpos
21{
22private:
23 stateT st;
24public:
25 fpos(streamoff = streamoff());
26
27 operator streamoff() const;
28
29 stateT state() const;
30 void state(stateT);
31
32 fpos& operator+=(streamoff);
33 fpos operator+ (streamoff) const;
34 fpos& operator-=(streamoff);
35 fpos operator- (streamoff) const;
36};
37
38template <class stateT> streamoff operator-(const fpos<stateT>& x, const fpos<stateT>& y);
39
40template <class stateT> bool operator==(const fpos<stateT>& x, const fpos<stateT>& y);
41template <class stateT> bool operator!=(const fpos<stateT>& x, const fpos<stateT>& y);
42
43template <class charT>
44struct char_traits
45{
46 typedef charT char_type;
47 typedef ... int_type;
48 typedef streamoff off_type;
49 typedef streampos pos_type;
50 typedef mbstate_t state_type;
51
52 static void assign(char_type& c1, const char_type& c2) noexcept;
53 static constexpr bool eq(char_type c1, char_type c2) noexcept;
54 static constexpr bool lt(char_type c1, char_type c2) noexcept;
55
56 static int compare(const char_type* s1, const char_type* s2, size_t n);
57 static size_t length(const char_type* s);
58 static const char_type* find(const char_type* s, size_t n, const char_type& a);
59 static char_type* move(char_type* s1, const char_type* s2, size_t n);
60 static char_type* copy(char_type* s1, const char_type* s2, size_t n);
61 static char_type* assign(char_type* s, size_t n, char_type a);
62
63 static constexpr int_type not_eof(int_type c) noexcept;
64 static constexpr char_type to_char_type(int_type c) noexcept;
65 static constexpr int_type to_int_type(char_type c) noexcept;
66 static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept;
67 static constexpr int_type eof() noexcept;
68};
69
70template <> struct char_traits<char>;
71template <> struct char_traits<wchar_t>;
72template <> struct char_traits<char8_t>; // C++20
73template <> struct char_traits<char16_t>;
74template <> struct char_traits<char32_t>;
75
76template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
77class basic_string
78{
79public:
80// types:
81 typedef traits traits_type;
82 typedef typename traits_type::char_type value_type;
83 typedef Allocator allocator_type;
84 typedef typename allocator_type::size_type size_type;
85 typedef typename allocator_type::difference_type difference_type;
86 typedef typename allocator_type::reference reference;
87 typedef typename allocator_type::const_reference const_reference;
88 typedef typename allocator_type::pointer pointer;
89 typedef typename allocator_type::const_pointer const_pointer;
90 typedef implementation-defined iterator;
91 typedef implementation-defined const_iterator;
92 typedef std::reverse_iterator<iterator> reverse_iterator;
93 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
94
95 static const size_type npos = -1;
96
97 basic_string()
98 noexcept(is_nothrow_default_constructible<allocator_type>::value); // constexpr since C++20
99 explicit basic_string(const allocator_type& a); // constexpr since C++20
100 basic_string(const basic_string& str); // constexpr since C++20
101 basic_string(basic_string&& str)
102 noexcept(is_nothrow_move_constructible<allocator_type>::value); // constexpr since C++20
103 basic_string(const basic_string& str, size_type pos,
104 const allocator_type& a = allocator_type()); // constexpr since C++20
105 basic_string(const basic_string& str, size_type pos, size_type n,
106 const Allocator& a = Allocator()); // constexpr since C++20
107 template<class T>
108 basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator()); // C++17, constexpr since C++20
109 template <class T>
110 explicit basic_string(const T& t, const Allocator& a = Allocator()); // C++17, constexpr since C++20
111 basic_string(const value_type* s, const allocator_type& a = allocator_type()); // constexpr since C++20
112 basic_string(const value_type* s, size_type n, const allocator_type& a = allocator_type()); // constexpr since C++20
113 basic_string(nullptr_t) = delete; // C++2b
114 basic_string(size_type n, value_type c, const allocator_type& a = allocator_type()); // constexpr since C++20
115 template<class InputIterator>
116 basic_string(InputIterator begin, InputIterator end,
117 const allocator_type& a = allocator_type()); // constexpr since C++20
118 basic_string(initializer_list<value_type>, const Allocator& = Allocator()); // constexpr since C++20
119 basic_string(const basic_string&, const Allocator&); // constexpr since C++20
120 basic_string(basic_string&&, const Allocator&); // constexpr since C++20
121
122 ~basic_string(); // constexpr since C++20
123
124 operator basic_string_view<charT, traits>() const noexcept; // constexpr since C++20
125
126 basic_string& operator=(const basic_string& str); // constexpr since C++20
127 template <class T>
128 basic_string& operator=(const T& t); // C++17, constexpr since C++20
129 basic_string& operator=(basic_string&& str)
130 noexcept(
131 allocator_type::propagate_on_container_move_assignment::value ||
132 allocator_type::is_always_equal::value ); // C++17, constexpr since C++20
133 basic_string& operator=(const value_type* s); // constexpr since C++20
134 basic_string& operator=(nullptr_t) = delete; // C++2b
135 basic_string& operator=(value_type c); // constexpr since C++20
136 basic_string& operator=(initializer_list<value_type>); // constexpr since C++20
137
138 iterator begin() noexcept; // constexpr since C++20
139 const_iterator begin() const noexcept; // constexpr since C++20
140 iterator end() noexcept; // constexpr since C++20
141 const_iterator end() const noexcept; // constexpr since C++20
142
143 reverse_iterator rbegin() noexcept; // constexpr since C++20
144 const_reverse_iterator rbegin() const noexcept; // constexpr since C++20
145 reverse_iterator rend() noexcept; // constexpr since C++20
146 const_reverse_iterator rend() const noexcept; // constexpr since C++20
147
148 const_iterator cbegin() const noexcept; // constexpr since C++20
149 const_iterator cend() const noexcept; // constexpr since C++20
150 const_reverse_iterator crbegin() const noexcept; // constexpr since C++20
151 const_reverse_iterator crend() const noexcept; // constexpr since C++20
152
153 size_type size() const noexcept; // constexpr since C++20
154 size_type length() const noexcept; // constexpr since C++20
155 size_type max_size() const noexcept; // constexpr since C++20
156 size_type capacity() const noexcept; // constexpr since C++20
157
158 void resize(size_type n, value_type c); // constexpr since C++20
159 void resize(size_type n); // constexpr since C++20
160
161 template<class Operation>
162 constexpr void resize_and_overwrite(size_type n, Operation op); // since C++23
163
164 void reserve(size_type res_arg); // constexpr since C++20
165 void reserve(); // deprecated in C++20
166 void shrink_to_fit(); // constexpr since C++20
167 void clear() noexcept; // constexpr since C++20
168 bool empty() const noexcept; // constexpr since C++20
169
170 const_reference operator[](size_type pos) const; // constexpr since C++20
171 reference operator[](size_type pos); // constexpr since C++20
172
173 const_reference at(size_type n) const; // constexpr since C++20
174 reference at(size_type n); // constexpr since C++20
175
176 basic_string& operator+=(const basic_string& str); // constexpr since C++20
177 template <class T>
178 basic_string& operator+=(const T& t); // C++17, constexpr since C++20
179 basic_string& operator+=(const value_type* s); // constexpr since C++20
180 basic_string& operator+=(value_type c); // constexpr since C++20
181 basic_string& operator+=(initializer_list<value_type>); // constexpr since C++20
182
183 basic_string& append(const basic_string& str); // constexpr since C++20
184 template <class T>
185 basic_string& append(const T& t); // C++17, constexpr since C++20
186 basic_string& append(const basic_string& str, size_type pos, size_type n=npos); // C++14, constexpr since C++20
187 template <class T>
188 basic_string& append(const T& t, size_type pos, size_type n=npos); // C++17, constexpr since C++20
189 basic_string& append(const value_type* s, size_type n); // constexpr since C++20
190 basic_string& append(const value_type* s); // constexpr since C++20
191 basic_string& append(size_type n, value_type c); // constexpr since C++20
192 template<class InputIterator>
193 basic_string& append(InputIterator first, InputIterator last); // constexpr since C++20
194 basic_string& append(initializer_list<value_type>); // constexpr since C++20
195
196 void push_back(value_type c); // constexpr since C++20
197 void pop_back(); // constexpr since C++20
198 reference front(); // constexpr since C++20
199 const_reference front() const; // constexpr since C++20
200 reference back(); // constexpr since C++20
201 const_reference back() const; // constexpr since C++20
202
203 basic_string& assign(const basic_string& str); // constexpr since C++20
204 template <class T>
205 basic_string& assign(const T& t); // C++17, constexpr since C++20
206 basic_string& assign(basic_string&& str); // constexpr since C++20
207 basic_string& assign(const basic_string& str, size_type pos, size_type n=npos); // C++14, constexpr since C++20
208 template <class T>
209 basic_string& assign(const T& t, size_type pos, size_type n=npos); // C++17, constexpr since C++20
210 basic_string& assign(const value_type* s, size_type n); // constexpr since C++20
211 basic_string& assign(const value_type* s); // constexpr since C++20
212 basic_string& assign(size_type n, value_type c); // constexpr since C++20
213 template<class InputIterator>
214 basic_string& assign(InputIterator first, InputIterator last); // constexpr since C++20
215 basic_string& assign(initializer_list<value_type>); // constexpr since C++20
216
217 basic_string& insert(size_type pos1, const basic_string& str); // constexpr since C++20
218 template <class T>
219 basic_string& insert(size_type pos1, const T& t); // constexpr since C++20
220 basic_string& insert(size_type pos1, const basic_string& str,
221 size_type pos2, size_type n); // constexpr since C++20
222 template <class T>
223 basic_string& insert(size_type pos1, const T& t, size_type pos2, size_type n); // C++17, constexpr since C++20
224 basic_string& insert(size_type pos, const value_type* s, size_type n=npos); // C++14, constexpr since C++20
225 basic_string& insert(size_type pos, const value_type* s); // constexpr since C++20
226 basic_string& insert(size_type pos, size_type n, value_type c); // constexpr since C++20
227 iterator insert(const_iterator p, value_type c); // constexpr since C++20
228 iterator insert(const_iterator p, size_type n, value_type c); // constexpr since C++20
229 template<class InputIterator>
230 iterator insert(const_iterator p, InputIterator first, InputIterator last); // constexpr since C++20
231 iterator insert(const_iterator p, initializer_list<value_type>); // constexpr since C++20
232
233 basic_string& erase(size_type pos = 0, size_type n = npos); // constexpr since C++20
234 iterator erase(const_iterator position); // constexpr since C++20
235 iterator erase(const_iterator first, const_iterator last); // constexpr since C++20
236
237 basic_string& replace(size_type pos1, size_type n1, const basic_string& str); // constexpr since C++20
238 template <class T>
239 basic_string& replace(size_type pos1, size_type n1, const T& t); // C++17, constexpr since C++20
240 basic_string& replace(size_type pos1, size_type n1, const basic_string& str,
241 size_type pos2, size_type n2=npos); // C++14, constexpr since C++20
242 template <class T>
243 basic_string& replace(size_type pos1, size_type n1, const T& t,
244 size_type pos2, size_type n); // C++17, constexpr since C++20
245 basic_string& replace(size_type pos, size_type n1, const value_type* s, size_type n2); // constexpr since C++20
246 basic_string& replace(size_type pos, size_type n1, const value_type* s); // constexpr since C++20
247 basic_string& replace(size_type pos, size_type n1, size_type n2, value_type c); // constexpr since C++20
248 basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str); // constexpr since C++20
249 template <class T>
250 basic_string& replace(const_iterator i1, const_iterator i2, const T& t); // C++17, constexpr since C++20
251 basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s, size_type n); // constexpr since C++20
252 basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s); // constexpr since C++20
253 basic_string& replace(const_iterator i1, const_iterator i2, size_type n, value_type c); // constexpr since C++20
254 template<class InputIterator>
255 basic_string& replace(const_iterator i1, const_iterator i2, InputIterator j1, InputIterator j2); // constexpr since C++20
256 basic_string& replace(const_iterator i1, const_iterator i2, initializer_list<value_type>); // constexpr since C++20
257
258 size_type copy(value_type* s, size_type n, size_type pos = 0) const; // constexpr since C++20
259 basic_string substr(size_type pos = 0, size_type n = npos) const; // constexpr since C++20
260
261 void swap(basic_string& str)
262 noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
263 allocator_traits<allocator_type>::is_always_equal::value); // C++17, constexpr since C++20
264
265 const value_type* c_str() const noexcept; // constexpr since C++20
266 const value_type* data() const noexcept; // constexpr since C++20
267 value_type* data() noexcept; // C++17, constexpr since C++20
268
269 allocator_type get_allocator() const noexcept; // constexpr since C++20
270
271 size_type find(const basic_string& str, size_type pos = 0) const noexcept; // constexpr since C++20
272 template <class T>
273 size_type find(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension, constexpr since C++20
274 size_type find(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20
275 size_type find(const value_type* s, size_type pos = 0) const noexcept; // constexpr since C++20
276 size_type find(value_type c, size_type pos = 0) const noexcept; // constexpr since C++20
277
278 size_type rfind(const basic_string& str, size_type pos = npos) const noexcept; // constexpr since C++20
279 template <class T>
280 size_type rfind(const T& t, size_type pos = npos) const noexcept; // C++17, noexcept as an extension, constexpr since C++20
281 size_type rfind(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20
282 size_type rfind(const value_type* s, size_type pos = npos) const noexcept; // constexpr since C++20
283 size_type rfind(value_type c, size_type pos = npos) const noexcept; // constexpr since C++20
284
285 size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept; // constexpr since C++20
286 template <class T>
287 size_type find_first_of(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension, constexpr since C++20
288 size_type find_first_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20
289 size_type find_first_of(const value_type* s, size_type pos = 0) const noexcept; // constexpr since C++20
290 size_type find_first_of(value_type c, size_type pos = 0) const noexcept; // constexpr since C++20
291
292 size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept; // constexpr since C++20
293 template <class T>
294 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
295 size_type find_last_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20
296 size_type find_last_of(const value_type* s, size_type pos = npos) const noexcept; // constexpr since C++20
297 size_type find_last_of(value_type c, size_type pos = npos) const noexcept; // constexpr since C++20
298
299 size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept; // constexpr since C++20
300 template <class T>
301 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
302 size_type find_first_not_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20
303 size_type find_first_not_of(const value_type* s, size_type pos = 0) const noexcept; // constexpr since C++20
304 size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept; // constexpr since C++20
305
306 size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept; // constexpr since C++20
307 template <class T>
308 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
309 size_type find_last_not_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20
310 size_type find_last_not_of(const value_type* s, size_type pos = npos) const noexcept; // constexpr since C++20
311 size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept; // constexpr since C++20
312
313 int compare(const basic_string& str) const noexcept; // constexpr since C++20
314 template <class T>
315 int compare(const T& t) const noexcept; // C++17, noexcept as an extension, constexpr since C++20
316 int compare(size_type pos1, size_type n1, const basic_string& str) const; // constexpr since C++20
317 template <class T>
318 int compare(size_type pos1, size_type n1, const T& t) const; // C++17, constexpr since C++20
319 int compare(size_type pos1, size_type n1, const basic_string& str,
320 size_type pos2, size_type n2=npos) const; // C++14, constexpr since C++20
321 template <class T>
322 int compare(size_type pos1, size_type n1, const T& t,
323 size_type pos2, size_type n2=npos) const; // C++17, constexpr since C++20
324 int compare(const value_type* s) const noexcept; // constexpr since C++20
325 int compare(size_type pos1, size_type n1, const value_type* s) const; // constexpr since C++20
326 int compare(size_type pos1, size_type n1, const value_type* s, size_type n2) const; // constexpr since C++20
327
328 constexpr bool starts_with(basic_string_view<charT, traits> sv) const noexcept; // C++20
329 constexpr bool starts_with(charT c) const noexcept; // C++20
330 constexpr bool starts_with(const charT* s) const; // C++20
331 constexpr bool ends_with(basic_string_view<charT, traits> sv) const noexcept; // C++20
332 constexpr bool ends_with(charT c) const noexcept; // C++20
333 constexpr bool ends_with(const charT* s) const; // C++20
334
335 constexpr bool contains(basic_string_view<charT, traits> sv) const noexcept; // C++2b
336 constexpr bool contains(charT c) const noexcept; // C++2b
337 constexpr bool contains(const charT* s) const; // C++2b
338};
339
340template<class InputIterator,
341 class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
342basic_string(InputIterator, InputIterator, Allocator = Allocator())
343 -> basic_string<typename iterator_traits<InputIterator>::value_type,
344 char_traits<typename iterator_traits<InputIterator>::value_type>,
345 Allocator>; // C++17
346
347template<class charT, class traits, class Allocator>
348basic_string<charT, traits, Allocator>
349operator+(const basic_string<charT, traits, Allocator>& lhs,
350 const basic_string<charT, traits, Allocator>& rhs); // constexpr since C++20
351
352template<class charT, class traits, class Allocator>
353basic_string<charT, traits, Allocator>
354operator+(const charT* lhs , const basic_string<charT,traits,Allocator>&rhs); // constexpr since C++20
355
356template<class charT, class traits, class Allocator>
357basic_string<charT, traits, Allocator>
358operator+(charT lhs, const basic_string<charT,traits,Allocator>& rhs); // constexpr since C++20
359
360template<class charT, class traits, class Allocator>
361basic_string<charT, traits, Allocator>
362operator+(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs); // constexpr since C++20
363
364template<class charT, class traits, class Allocator>
365basic_string<charT, traits, Allocator>
366operator+(const basic_string<charT, traits, Allocator>& lhs, charT rhs); // constexpr since C++20
367
368template<class charT, class traits, class Allocator>
369bool operator==(const basic_string<charT, traits, Allocator>& lhs,
370 const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20
371
372template<class charT, class traits, class Allocator>
373bool operator==(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20
374
375template<class charT, class traits, class Allocator>
376bool operator==(const basic_string<charT,traits,Allocator>& lhs, const charT* rhs) noexcept; // constexpr since C++20
377
378template<class charT, class traits, class Allocator>
379bool operator!=(const basic_string<charT,traits,Allocator>& lhs,
380 const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20
381
382template<class charT, class traits, class Allocator>
383bool operator!=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20
384
385template<class charT, class traits, class Allocator>
386bool operator!=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // constexpr since C++20
387
388template<class charT, class traits, class Allocator>
389bool operator< (const basic_string<charT, traits, Allocator>& lhs,
390 const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20
391
392template<class charT, class traits, class Allocator>
393bool operator< (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // constexpr since C++20
394
395template<class charT, class traits, class Allocator>
396bool operator< (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20
397
398template<class charT, class traits, class Allocator>
399bool operator> (const basic_string<charT, traits, Allocator>& lhs,
400 const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20
401
402template<class charT, class traits, class Allocator>
403bool operator> (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // constexpr since C++20
404
405template<class charT, class traits, class Allocator>
406bool operator> (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20
407
408template<class charT, class traits, class Allocator>
409bool operator<=(const basic_string<charT, traits, Allocator>& lhs,
410 const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20
411
412template<class charT, class traits, class Allocator>
413bool operator<=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // constexpr since C++20
414
415template<class charT, class traits, class Allocator>
416bool operator<=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20
417
418template<class charT, class traits, class Allocator>
419bool operator>=(const basic_string<charT, traits, Allocator>& lhs,
420 const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20
421
422template<class charT, class traits, class Allocator>
423bool operator>=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // constexpr since C++20
424
425template<class charT, class traits, class Allocator>
426bool operator>=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20
427
428template<class charT, class traits, class Allocator>
429void swap(basic_string<charT, traits, Allocator>& lhs,
430 basic_string<charT, traits, Allocator>& rhs)
431 noexcept(noexcept(lhs.swap(rhs))); // constexpr since C++20
432
433template<class charT, class traits, class Allocator>
434basic_istream<charT, traits>&
435operator>>(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str);
436
437template<class charT, class traits, class Allocator>
438basic_ostream<charT, traits>&
439operator<<(basic_ostream<charT, traits>& os, const basic_string<charT, traits, Allocator>& str);
440
441template<class charT, class traits, class Allocator>
442basic_istream<charT, traits>&
443getline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str,
444 charT delim);
445
446template<class charT, class traits, class Allocator>
447basic_istream<charT, traits>&
448getline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str);
449
450template<class charT, class traits, class Allocator, class U>
451typename basic_string<charT, traits, Allocator>::size_type
452erase(basic_string<charT, traits, Allocator>& c, const U& value); // C++20
453template<class charT, class traits, class Allocator, class Predicate>
454typename basic_string<charT, traits, Allocator>::size_type
455erase_if(basic_string<charT, traits, Allocator>& c, Predicate pred); // C++20
456
457typedef basic_string<char> string;
458typedef basic_string<wchar_t> wstring;
459typedef basic_string<char8_t> u8string; // C++20
460typedef basic_string<char16_t> u16string;
461typedef basic_string<char32_t> u32string;
462
463int stoi (const string& str, size_t* idx = nullptr, int base = 10);
464long stol (const string& str, size_t* idx = nullptr, int base = 10);
465unsigned long stoul (const string& str, size_t* idx = nullptr, int base = 10);
466long long stoll (const string& str, size_t* idx = nullptr, int base = 10);
467unsigned long long stoull(const string& str, size_t* idx = nullptr, int base = 10);
468
469float stof (const string& str, size_t* idx = nullptr);
470double stod (const string& str, size_t* idx = nullptr);
471long double stold(const string& str, size_t* idx = nullptr);
472
473string to_string(int val);
474string to_string(unsigned val);
475string to_string(long val);
476string to_string(unsigned long val);
477string to_string(long long val);
478string to_string(unsigned long long val);
479string to_string(float val);
480string to_string(double val);
481string to_string(long double val);
482
483int stoi (const wstring& str, size_t* idx = nullptr, int base = 10);
484long stol (const wstring& str, size_t* idx = nullptr, int base = 10);
485unsigned long stoul (const wstring& str, size_t* idx = nullptr, int base = 10);
486long long stoll (const wstring& str, size_t* idx = nullptr, int base = 10);
487unsigned long long stoull(const wstring& str, size_t* idx = nullptr, int base = 10);
488
489float stof (const wstring& str, size_t* idx = nullptr);
490double stod (const wstring& str, size_t* idx = nullptr);
491long double stold(const wstring& str, size_t* idx = nullptr);
492
493wstring to_wstring(int val);
494wstring to_wstring(unsigned val);
495wstring to_wstring(long val);
496wstring to_wstring(unsigned long val);
497wstring to_wstring(long long val);
498wstring to_wstring(unsigned long long val);
499wstring to_wstring(float val);
500wstring to_wstring(double val);
501wstring to_wstring(long double val);
502
503template <> struct hash<string>;
504template <> struct hash<u8string>; // C++20
505template <> struct hash<u16string>;
506template <> struct hash<u32string>;
507template <> struct hash<wstring>;
508
509basic_string<char> operator "" s( const char *str, size_t len ); // C++14, constexpr since C++20
510basic_string<wchar_t> operator "" s( const wchar_t *str, size_t len ); // C++14, constexpr since C++20
511constexpr basic_string<char8_t> operator "" s( const char8_t *str, size_t len ); // C++20
512basic_string<char16_t> operator "" s( const char16_t *str, size_t len ); // C++14, constexpr since C++20
513basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++14, constexpr since C++20
514
515} // std
516
517*/
518
519#include <__algorithm/max.h>
520#include <__algorithm/min.h>
521#include <__algorithm/remove.h>
522#include <__algorithm/remove_if.h>
523#include <__assert> // all public C++ headers provide the assertion handler
524#include <__config>
525#include <__debug>
526#include <__format/enable_insertable.h>
527#include <__functional/hash.h>
528#include <__functional/unary_function.h>
529#include <__ios/fpos.h>
530#include <__iterator/distance.h>
531#include <__iterator/iterator_traits.h>
532#include <__iterator/reverse_iterator.h>
533#include <__iterator/wrap_iter.h>
534#include <__memory/allocate_at_least.h>
535#include <__string/char_traits.h>
536#include <__string/extern_template_lists.h>
537#include <__utility/auto_cast.h>
538#include <__utility/move.h>
539#include <__utility/swap.h>
540#include <__utility/unreachable.h>
541#include <climits>
542#include <cstdint>
543#include <cstdio> // EOF
544#include <cstdlib>
545#include <cstring>
546#include <iosfwd>
547#include <limits>
548#include <memory>
549#include <stdexcept>
550#include <string_view>
551#include <type_traits>
552#include <version>
553
554#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
555# include <cwchar>
556#endif
557
558#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
559# include <algorithm>
560# include <functional>
561# include <iterator>
562# include <new>
563# include <typeinfo>
564# include <utility>
565# include <vector>
566#endif
567
568// standard-mandated includes
569
570// [iterator.range]
571#include <__iterator/access.h>
572#include <__iterator/data.h>
573#include <__iterator/empty.h>
574#include <__iterator/reverse_access.h>
575#include <__iterator/size.h>
576
577// [string.syn]
578#include <compare>
579#include <initializer_list>
580
581#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
582# pragma GCC system_header
583#endif
584
585_LIBCPP_PUSH_MACROS
586#include <__undef_macros>
587
588
589_LIBCPP_BEGIN_NAMESPACE_STD
590
591// basic_string
592
593template<class _CharT, class _Traits, class _Allocator>
594basic_string<_CharT, _Traits, _Allocator>
595_LIBCPP_CONSTEXPR_AFTER_CXX17
596operator+(const basic_string<_CharT, _Traits, _Allocator>& __x,
597 const basic_string<_CharT, _Traits, _Allocator>& __y);
598
599template<class _CharT, class _Traits, class _Allocator>
600_LIBCPP_CONSTEXPR_AFTER_CXX17
601basic_string<_CharT, _Traits, _Allocator>
602operator+(const _CharT* __x, const basic_string<_CharT,_Traits,_Allocator>& __y);
603
604template<class _CharT, class _Traits, class _Allocator>
605_LIBCPP_CONSTEXPR_AFTER_CXX17
606basic_string<_CharT, _Traits, _Allocator>
607operator+(_CharT __x, const basic_string<_CharT,_Traits,_Allocator>& __y);
608
609template<class _CharT, class _Traits, class _Allocator>
610inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
611basic_string<_CharT, _Traits, _Allocator>
612operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const _CharT* __y);
613
614template<class _CharT, class _Traits, class _Allocator>
615_LIBCPP_CONSTEXPR_AFTER_CXX17
616basic_string<_CharT, _Traits, _Allocator>
617operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y);
618
619extern template _LIBCPP_FUNC_VIS string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
620
621template <class _Iter>
622struct __string_is_trivial_iterator : public false_type {};
623
624template <class _Tp>
625struct __string_is_trivial_iterator<_Tp*>
626 : public is_arithmetic<_Tp> {};
627
628template <class _Iter>
629struct __string_is_trivial_iterator<__wrap_iter<_Iter> >
630 : public __string_is_trivial_iterator<_Iter> {};
631
632template <class _CharT, class _Traits, class _Tp>
633struct __can_be_converted_to_string_view : public _BoolConstant<
634 is_convertible<const _Tp&, basic_string_view<_CharT, _Traits> >::value &&
635 !is_convertible<const _Tp&, const _CharT*>::value
636 > {};
637
638#ifndef _LIBCPP_HAS_NO_CHAR8_T
639typedef basic_string<char8_t> u8string;
640#endif
641typedef basic_string<char16_t> u16string;
642typedef basic_string<char32_t> u32string;
643
644struct __uninitialized_size_tag {};
645
646template<class _CharT, class _Traits, class _Allocator>
647class
648 _LIBCPP_TEMPLATE_VIS
649#ifndef _LIBCPP_HAS_NO_CHAR8_T
650 _LIBCPP_PREFERRED_NAME(u8string)
651#endif
652 _LIBCPP_PREFERRED_NAME(u16string)
653 _LIBCPP_PREFERRED_NAME(u32string)
654 basic_string
655{
656public:
657 typedef basic_string __self;
658 typedef basic_string_view<_CharT, _Traits> __self_view;
659 typedef _Traits traits_type;
660 typedef _CharT value_type;
661 typedef _Allocator allocator_type;
662 typedef allocator_traits<allocator_type> __alloc_traits;
663 typedef typename __alloc_traits::size_type size_type;
664 typedef typename __alloc_traits::difference_type difference_type;
665 typedef value_type& reference;
666 typedef const value_type& const_reference;
667 typedef typename __alloc_traits::pointer pointer;
668 typedef typename __alloc_traits::const_pointer const_pointer;
669
670 static_assert((!is_array<value_type>::value), "Character type of basic_string must not be an array");
671 static_assert(( is_standard_layout<value_type>::value), "Character type of basic_string must be standard-layout");
672 static_assert(( is_trivial<value_type>::value), "Character type of basic_string must be trivial");
673 static_assert(( is_same<_CharT, typename traits_type::char_type>::value),
674 "traits_type::char_type must be the same type as CharT");
675 static_assert(( is_same<typename allocator_type::value_type, value_type>::value),
676 "Allocator::value_type must be same type as value_type");
677
678 typedef __wrap_iter<pointer> iterator;
679 typedef __wrap_iter<const_pointer> const_iterator;
680 typedef std::reverse_iterator<iterator> reverse_iterator;
681 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
682
683private:
684 static_assert(CHAR_BIT == 8, "This implementation assumes that one byte contains 8 bits");
685
686#ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
687
688 struct __long
689 {
690 pointer __data_;
691 size_type __size_;
692 size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1;
693 size_type __is_long_ : 1;
694 };
695
696 enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ?
697 (sizeof(__long) - 1)/sizeof(value_type) : 2};
698
699 struct __short
700 {
701 value_type __data_[__min_cap];
702 unsigned char __padding_[sizeof(value_type) - 1];
703 unsigned char __size_ : 7;
704 unsigned char __is_long_ : 1;
705 };
706
707// The __endian_factor is required because the field we use to store the size
708// has one fewer bit than it would if it were not a bitfield.
709//
710// If the LSB is used to store the short-flag in the short string representation,
711// we have to multiply the size by two when it is stored and divide it by two when
712// it is loaded to make sure that we always store an even number. In the long string
713// representation, we can ignore this because we can assume that we always allocate
714// an even amount of value_types.
715//
716// If the MSB is used for the short-flag, the max_size() is numeric_limits<size_type>::max() / 2.
717// This does not impact the short string representation, since we never need the MSB
718// for representing the size of a short string anyway.
719
720#ifdef _LIBCPP_BIG_ENDIAN
721 static const size_type __endian_factor = 2;
722#else
723 static const size_type __endian_factor = 1;
724#endif
725
726#else // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
727
728#ifdef _LIBCPP_BIG_ENDIAN
729 static const size_type __endian_factor = 1;
730#else
731 static const size_type __endian_factor = 2;
732#endif
733
734 // Attribute 'packed' is used to keep the layout compatible with the
735 // previous definition that did not use bit fields. This is because on
736 // some platforms bit fields have a default size rather than the actual
737 // size used, e.g., it is 4 bytes on AIX. See D128285 for details.
738 struct __long
739 {
740 struct _LIBCPP_PACKED {
741 size_type __is_long_ : 1;
742 size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1;
743 };
744 size_type __size_;
745 pointer __data_;
746 };
747
748 enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ?
749 (sizeof(__long) - 1)/sizeof(value_type) : 2};
750
751 struct __short
752 {
753 struct _LIBCPP_PACKED {
754 unsigned char __is_long_ : 1;
755 unsigned char __size_ : 7;
756 };
757 char __padding_[sizeof(value_type) - 1];
758 value_type __data_[__min_cap];
759 };
760
761#endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
762
763 static_assert(sizeof(__short) == (sizeof(value_type) * (__min_cap + 1)), "__short has an unexpected size.");
764
765 union __ulx{__long __lx; __short __lxx;};
766
767 enum {__n_words = sizeof(__ulx) / sizeof(size_type)};
768
769 struct __raw
770 {
771 size_type __words[__n_words];
772 };
773
774 struct __rep
775 {
776 union
777 {
778 __long __l;
779 __short __s;
780 __raw __r;
781 };
782 };
783
784 __compressed_pair<__rep, allocator_type> __r_;
785
786 // Construct a string with the given allocator and enough storage to hold `__size` characters, but
787 // don't initialize the characters. The contents of the string, including the null terminator, must be
788 // initialized separately.
789 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
790 explicit basic_string(__uninitialized_size_tag, size_type __size, const allocator_type& __a)
791 : __r_(__default_init_tag(), __a) {
792 if (__size > max_size())
793 __throw_length_error();
794 if (__fits_in_sso(sz: __size)) {
795 __zero();
796 __set_short_size(s: __size);
797 } else {
798 auto __capacity = __recommend(s: __size) + 1;
799 auto __allocation = __alloc_traits::allocate(__alloc(), __capacity);
800 __begin_lifetime(begin: __allocation, n: __capacity);
801 __set_long_cap(s: __capacity);
802 __set_long_pointer(p: __allocation);
803 __set_long_size(s: __size);
804 }
805 std::__debug_db_insert_c(this);
806 }
807
808public:
809 _LIBCPP_TEMPLATE_DATA_VIS
810 static const size_type npos = -1;
811
812 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string()
813 _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
814
815 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit basic_string(const allocator_type& __a)
816#if _LIBCPP_STD_VER <= 14
817 _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value);
818#else
819 _NOEXCEPT;
820#endif
821
822 _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const basic_string& __str);
823 _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const basic_string& __str, const allocator_type& __a);
824
825#ifndef _LIBCPP_CXX03_LANG
826 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
827 basic_string(basic_string&& __str)
828#if _LIBCPP_STD_VER <= 14
829 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
830#else
831 _NOEXCEPT;
832#endif
833
834 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
835 basic_string(basic_string&& __str, const allocator_type& __a);
836#endif // _LIBCPP_CXX03_LANG
837
838 template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> >
839 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
840 basic_string(const _CharT* __s) : __r_(__default_init_tag(), __default_init_tag()) {
841 _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr");
842 __init(__s, traits_type::length(__s));
843 std::__debug_db_insert_c(this);
844 }
845
846 template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> >
847 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
848 basic_string(const _CharT* __s, const _Allocator& __a);
849
850#if _LIBCPP_STD_VER > 20
851 basic_string(nullptr_t) = delete;
852#endif
853
854 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
855 basic_string(const _CharT* __s, size_type __n);
856 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
857 basic_string(const _CharT* __s, size_type __n, const _Allocator& __a);
858 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
859 basic_string(size_type __n, _CharT __c);
860
861 template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> >
862 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
863 basic_string(size_type __n, _CharT __c, const _Allocator& __a);
864
865 _LIBCPP_CONSTEXPR_AFTER_CXX17
866 basic_string(const basic_string& __str, size_type __pos, size_type __n,
867 const _Allocator& __a = _Allocator());
868 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
869 basic_string(const basic_string& __str, size_type __pos,
870 const _Allocator& __a = _Allocator());
871
872 template<class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> >
873 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
874 basic_string(const _Tp& __t, size_type __pos, size_type __n,
875 const allocator_type& __a = allocator_type());
876
877 template<class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
878 !__is_same_uncvref<_Tp, basic_string>::value> >
879 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
880 explicit basic_string(const _Tp& __t);
881
882 template<class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> >
883 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
884 explicit basic_string(const _Tp& __t, const allocator_type& __a);
885
886 template<class _InputIterator, class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value> >
887 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
888 basic_string(_InputIterator __first, _InputIterator __last);
889 template<class _InputIterator, class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value> >
890 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
891 basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a);
892#ifndef _LIBCPP_CXX03_LANG
893 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
894 basic_string(initializer_list<_CharT> __il);
895 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
896 basic_string(initializer_list<_CharT> __il, const _Allocator& __a);
897#endif // _LIBCPP_CXX03_LANG
898
899 inline _LIBCPP_CONSTEXPR_AFTER_CXX17 ~basic_string();
900
901 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
902 operator __self_view() const _NOEXCEPT { return __self_view(data(), size()); }
903
904 _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator=(const basic_string& __str);
905
906 template <class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
907 !__is_same_uncvref<_Tp, basic_string>::value> >
908 _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator=(const _Tp& __t) {
909 __self_view __sv = __t;
910 return assign(__sv);
911 }
912
913#ifndef _LIBCPP_CXX03_LANG
914 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
915 basic_string& operator=(basic_string&& __str)
916 _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));
917 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
918 basic_string& operator=(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}
919#endif
920 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
921 basic_string& operator=(const value_type* __s) {return assign(__s);}
922#if _LIBCPP_STD_VER > 20
923 basic_string& operator=(nullptr_t) = delete;
924#endif
925 _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator=(value_type __c);
926
927 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
928 iterator begin() _NOEXCEPT
929 {return iterator(this, __get_pointer());}
930 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
931 const_iterator begin() const _NOEXCEPT
932 {return const_iterator(this, __get_pointer());}
933 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
934 iterator end() _NOEXCEPT
935 {return iterator(this, __get_pointer() + size());}
936 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
937 const_iterator end() const _NOEXCEPT
938 {return const_iterator(this, __get_pointer() + size());}
939
940 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
941 reverse_iterator rbegin() _NOEXCEPT
942 {return reverse_iterator(end());}
943 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
944 const_reverse_iterator rbegin() const _NOEXCEPT
945 {return const_reverse_iterator(end());}
946 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
947 reverse_iterator rend() _NOEXCEPT
948 {return reverse_iterator(begin());}
949 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
950 const_reverse_iterator rend() const _NOEXCEPT
951 {return const_reverse_iterator(begin());}
952
953 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
954 const_iterator cbegin() const _NOEXCEPT
955 {return begin();}
956 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
957 const_iterator cend() const _NOEXCEPT
958 {return end();}
959 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
960 const_reverse_iterator crbegin() const _NOEXCEPT
961 {return rbegin();}
962 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
963 const_reverse_iterator crend() const _NOEXCEPT
964 {return rend();}
965
966 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type size() const _NOEXCEPT
967 {return __is_long() ? __get_long_size() : __get_short_size();}
968 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type length() const _NOEXCEPT {return size();}
969 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type max_size() const _NOEXCEPT;
970 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type capacity() const _NOEXCEPT {
971 return (__is_long() ? __get_long_cap() : static_cast<size_type>(__min_cap)) - 1;
972 }
973
974 _LIBCPP_CONSTEXPR_AFTER_CXX17 void resize(size_type __n, value_type __c);
975 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void resize(size_type __n) { resize(__n, value_type()); }
976
977 _LIBCPP_CONSTEXPR_AFTER_CXX17 void reserve(size_type __requested_capacity);
978
979#if _LIBCPP_STD_VER > 20
980 template <class _Op>
981 _LIBCPP_HIDE_FROM_ABI constexpr
982 void resize_and_overwrite(size_type __n, _Op __op) {
983 __resize_default_init(__n);
984 __erase_to_end(std::move(__op)(data(), _LIBCPP_AUTO_CAST(__n)));
985 }
986#endif
987
988 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __resize_default_init(size_type __n);
989
990 _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI void reserve() _NOEXCEPT { shrink_to_fit(); }
991 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void shrink_to_fit() _NOEXCEPT;
992 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void clear() _NOEXCEPT;
993
994 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
995 bool empty() const _NOEXCEPT {return size() == 0;}
996
997 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
998 const_reference operator[](size_type __pos) const _NOEXCEPT;
999 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 reference operator[](size_type __pos) _NOEXCEPT;
1000
1001 _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reference at(size_type __n) const;
1002 _LIBCPP_CONSTEXPR_AFTER_CXX17 reference at(size_type __n);
1003
1004 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator+=(const basic_string& __str) {
1005 return append(__str);
1006 }
1007
1008 template <class _Tp>
1009 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
1010 __enable_if_t
1011 <
1012 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
1013 && !__is_same_uncvref<_Tp, basic_string >::value,
1014 basic_string&
1015 >
1016 operator+=(const _Tp& __t) {
1017 __self_view __sv = __t; return append(__sv);
1018 }
1019
1020 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator+=(const value_type* __s) {
1021 return append(__s);
1022 }
1023
1024 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator+=(value_type __c) {
1025 push_back(__c);
1026 return *this;
1027 }
1028
1029#ifndef _LIBCPP_CXX03_LANG
1030 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1031 basic_string& operator+=(initializer_list<value_type> __il) { return append(__il); }
1032#endif // _LIBCPP_CXX03_LANG
1033
1034 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1035 basic_string& append(const basic_string& __str);
1036
1037 template <class _Tp>
1038 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
1039 __enable_if_t<
1040 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
1041 && !__is_same_uncvref<_Tp, basic_string>::value,
1042 basic_string&
1043 >
1044 append(const _Tp& __t) { __self_view __sv = __t; return append(__sv.data(), __sv.size()); }
1045 _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos);
1046
1047 template <class _Tp>
1048 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
1049 __enable_if_t
1050 <
1051 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
1052 && !__is_same_uncvref<_Tp, basic_string>::value,
1053 basic_string&
1054 >
1055 append(const _Tp& __t, size_type __pos, size_type __n=npos);
1056 _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& append(const value_type* __s, size_type __n);
1057 _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& append(const value_type* __s);
1058 _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& append(size_type __n, value_type __c);
1059
1060 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1061 void __append_default_init(size_type __n);
1062
1063 template<class _InputIterator>
1064 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
1065 __enable_if_t
1066 <
1067 __is_exactly_cpp17_input_iterator<_InputIterator>::value,
1068 basic_string&
1069 >
1070 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1071 append(_InputIterator __first, _InputIterator __last) {
1072 const basic_string __temp(__first, __last, __alloc());
1073 append(__temp.data(), __temp.size());
1074 return *this;
1075 }
1076 template<class _ForwardIterator>
1077 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
1078 __enable_if_t
1079 <
1080 __is_cpp17_forward_iterator<_ForwardIterator>::value,
1081 basic_string&
1082 >
1083 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1084 append(_ForwardIterator __first, _ForwardIterator __last);
1085
1086#ifndef _LIBCPP_CXX03_LANG
1087 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1088 basic_string& append(initializer_list<value_type> __il) {return append(__il.begin(), __il.size());}
1089#endif // _LIBCPP_CXX03_LANG
1090
1091 _LIBCPP_CONSTEXPR_AFTER_CXX17 void push_back(value_type __c);
1092 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void pop_back();
1093 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 reference front() _NOEXCEPT;
1094 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reference front() const _NOEXCEPT;
1095 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 reference back() _NOEXCEPT;
1096 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reference back() const _NOEXCEPT;
1097
1098 template <class _Tp>
1099 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
1100 __enable_if_t
1101 <
1102 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
1103 basic_string&
1104 >
1105 assign(const _Tp & __t) { __self_view __sv = __t; return assign(__sv.data(), __sv.size()); }
1106 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1107 basic_string& assign(const basic_string& __str) { return *this = __str; }
1108#ifndef _LIBCPP_CXX03_LANG
1109 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1110 basic_string& assign(basic_string&& __str)
1111 _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value))
1112 {*this = std::move(__str); return *this;}
1113#endif
1114 _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos);
1115 template <class _Tp>
1116 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
1117 __enable_if_t
1118 <
1119 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
1120 && !__is_same_uncvref<_Tp, basic_string>::value,
1121 basic_string&
1122 >
1123 assign(const _Tp & __t, size_type __pos, size_type __n=npos);
1124 _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(const value_type* __s, size_type __n);
1125 _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(const value_type* __s);
1126 _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(size_type __n, value_type __c);
1127 template<class _InputIterator>
1128 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
1129 __enable_if_t
1130 <
1131 __is_exactly_cpp17_input_iterator<_InputIterator>::value,
1132 basic_string&
1133 >
1134 assign(_InputIterator __first, _InputIterator __last);
1135 template<class _ForwardIterator>
1136 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
1137 __enable_if_t
1138 <
1139 __is_cpp17_forward_iterator<_ForwardIterator>::value,
1140 basic_string&
1141 >
1142 assign(_ForwardIterator __first, _ForwardIterator __last);
1143#ifndef _LIBCPP_CXX03_LANG
1144 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1145 basic_string& assign(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}
1146#endif // _LIBCPP_CXX03_LANG
1147
1148 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1149 basic_string& insert(size_type __pos1, const basic_string& __str);
1150
1151 template <class _Tp>
1152 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
1153 __enable_if_t
1154 <
1155 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
1156 basic_string&
1157 >
1158 insert(size_type __pos1, const _Tp& __t)
1159 { __self_view __sv = __t; return insert(__pos1, __sv.data(), __sv.size()); }
1160
1161 template <class _Tp>
1162 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
1163 __enable_if_t
1164 <
1165 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value,
1166 basic_string&
1167 >
1168 insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n=npos);
1169 _LIBCPP_CONSTEXPR_AFTER_CXX17
1170 basic_string& insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n=npos);
1171 _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& insert(size_type __pos, const value_type* __s, size_type __n);
1172 _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& insert(size_type __pos, const value_type* __s);
1173 _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& insert(size_type __pos, size_type __n, value_type __c);
1174 _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator insert(const_iterator __pos, value_type __c);
1175 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1176 iterator insert(const_iterator __pos, size_type __n, value_type __c);
1177 template<class _InputIterator>
1178 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
1179 __enable_if_t
1180 <
1181 __is_exactly_cpp17_input_iterator<_InputIterator>::value,
1182 iterator
1183 >
1184 insert(const_iterator __pos, _InputIterator __first, _InputIterator __last);
1185 template<class _ForwardIterator>
1186 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
1187 __enable_if_t
1188 <
1189 __is_cpp17_forward_iterator<_ForwardIterator>::value,
1190 iterator
1191 >
1192 insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last);
1193#ifndef _LIBCPP_CXX03_LANG
1194 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1195 iterator insert(const_iterator __pos, initializer_list<value_type> __il)
1196 {return insert(__pos, __il.begin(), __il.end());}
1197#endif // _LIBCPP_CXX03_LANG
1198
1199 _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& erase(size_type __pos = 0, size_type __n = npos);
1200 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1201 iterator erase(const_iterator __pos);
1202 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1203 iterator erase(const_iterator __first, const_iterator __last);
1204
1205 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1206 basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str);
1207
1208 template <class _Tp>
1209 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
1210 __enable_if_t
1211 <
1212 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
1213 basic_string&
1214 >
1215 replace(size_type __pos1, size_type __n1, const _Tp& __t) { __self_view __sv = __t; return replace(__pos1, __n1, __sv.data(), __sv.size()); }
1216 _LIBCPP_CONSTEXPR_AFTER_CXX17
1217 basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos);
1218 template <class _Tp>
1219 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
1220 __enable_if_t
1221 <
1222 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value,
1223 basic_string&
1224 >
1225 replace(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos);
1226 _LIBCPP_CONSTEXPR_AFTER_CXX17
1227 basic_string& replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2);
1228 _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& replace(size_type __pos, size_type __n1, const value_type* __s);
1229 _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c);
1230 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1231 basic_string& replace(const_iterator __i1, const_iterator __i2, const basic_string& __str);
1232
1233 template <class _Tp>
1234 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
1235 __enable_if_t
1236 <
1237 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
1238 basic_string&
1239 >
1240 replace(const_iterator __i1, const_iterator __i2, const _Tp& __t) { __self_view __sv = __t; return replace(__i1 - begin(), __i2 - __i1, __sv); }
1241
1242 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1243 basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n);
1244 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1245 basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s);
1246 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1247 basic_string& replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c);
1248 template<class _InputIterator>
1249 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
1250 __enable_if_t
1251 <
1252 __is_cpp17_input_iterator<_InputIterator>::value,
1253 basic_string&
1254 >
1255 replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2);
1256#ifndef _LIBCPP_CXX03_LANG
1257 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1258 basic_string& replace(const_iterator __i1, const_iterator __i2, initializer_list<value_type> __il)
1259 {return replace(__i1, __i2, __il.begin(), __il.end());}
1260#endif // _LIBCPP_CXX03_LANG
1261
1262 _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type copy(value_type* __s, size_type __n, size_type __pos = 0) const;
1263 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1264 basic_string substr(size_type __pos = 0, size_type __n = npos) const;
1265
1266 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1267 void swap(basic_string& __str)
1268#if _LIBCPP_STD_VER >= 14
1269 _NOEXCEPT;
1270#else
1271 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
1272 __is_nothrow_swappable<allocator_type>::value);
1273#endif
1274
1275 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1276 const value_type* c_str() const _NOEXCEPT {return data();}
1277 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1278 const value_type* data() const _NOEXCEPT {return std::__to_address(__get_pointer());}
1279#if _LIBCPP_STD_VER > 14 || defined(_LIBCPP_BUILDING_LIBRARY)
1280 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1281 value_type* data() _NOEXCEPT {return std::__to_address(__get_pointer());}
1282#endif
1283
1284 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1285 allocator_type get_allocator() const _NOEXCEPT {return __alloc();}
1286
1287 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1288 size_type find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
1289
1290 template <class _Tp>
1291 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
1292 __enable_if_t
1293 <
1294 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
1295 size_type
1296 >
1297 find(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
1298 _LIBCPP_CONSTEXPR_AFTER_CXX17
1299 size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1300 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1301 size_type find(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
1302 _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT;
1303
1304 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1305 size_type rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
1306
1307 template <class _Tp>
1308 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
1309 __enable_if_t
1310 <
1311 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
1312 size_type
1313 >
1314 rfind(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
1315 _LIBCPP_CONSTEXPR_AFTER_CXX17
1316 size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1317 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1318 size_type rfind(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
1319 _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type rfind(value_type __c, size_type __pos = npos) const _NOEXCEPT;
1320
1321 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1322 size_type find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
1323
1324 template <class _Tp>
1325 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
1326 __enable_if_t
1327 <
1328 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
1329 size_type
1330 >
1331 find_first_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
1332 _LIBCPP_CONSTEXPR_AFTER_CXX17
1333 size_type find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1334 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1335 size_type find_first_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
1336 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1337 size_type find_first_of(value_type __c, size_type __pos = 0) const _NOEXCEPT;
1338
1339 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1340 size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
1341
1342 template <class _Tp>
1343 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
1344 __enable_if_t
1345 <
1346 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
1347 size_type
1348 >
1349 find_last_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
1350 _LIBCPP_CONSTEXPR_AFTER_CXX17
1351 size_type find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1352 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1353 size_type find_last_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
1354 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1355 size_type find_last_of(value_type __c, size_type __pos = npos) const _NOEXCEPT;
1356
1357 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1358 size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
1359
1360 template <class _Tp>
1361 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
1362 __enable_if_t
1363 <
1364 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
1365 size_type
1366 >
1367 find_first_not_of(const _Tp &__t, size_type __pos = 0) const _NOEXCEPT;
1368 _LIBCPP_CONSTEXPR_AFTER_CXX17
1369 size_type find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1370 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1371 size_type find_first_not_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
1372 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1373 size_type find_first_not_of(value_type __c, size_type __pos = 0) const _NOEXCEPT;
1374
1375 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1376 size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
1377
1378 template <class _Tp>
1379 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
1380 __enable_if_t
1381 <
1382 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
1383 size_type
1384 >
1385 find_last_not_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
1386 _LIBCPP_CONSTEXPR_AFTER_CXX17
1387 size_type find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1388 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1389 size_type find_last_not_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
1390 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1391 size_type find_last_not_of(value_type __c, size_type __pos = npos) const _NOEXCEPT;
1392
1393 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1394 int compare(const basic_string& __str) const _NOEXCEPT;
1395
1396 template <class _Tp>
1397 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
1398 __enable_if_t
1399 <
1400 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
1401 int
1402 >
1403 compare(const _Tp &__t) const _NOEXCEPT;
1404
1405 template <class _Tp>
1406 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
1407 __enable_if_t
1408 <
1409 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
1410 int
1411 >
1412 compare(size_type __pos1, size_type __n1, const _Tp& __t) const;
1413
1414 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1415 int compare(size_type __pos1, size_type __n1, const basic_string& __str) const;
1416 _LIBCPP_CONSTEXPR_AFTER_CXX17
1417 int compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2,
1418 size_type __n2 = npos) const;
1419
1420 template <class _Tp>
1421 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1422 __enable_if_t
1423 <
1424 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value,
1425 int
1426 >
1427 compare(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos) const;
1428 _LIBCPP_CONSTEXPR_AFTER_CXX17 int compare(const value_type* __s) const _NOEXCEPT;
1429 _LIBCPP_CONSTEXPR_AFTER_CXX17 int compare(size_type __pos1, size_type __n1, const value_type* __s) const;
1430 _LIBCPP_CONSTEXPR_AFTER_CXX17
1431 int compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const;
1432
1433#if _LIBCPP_STD_VER > 17
1434 constexpr _LIBCPP_HIDE_FROM_ABI
1435 bool starts_with(__self_view __sv) const noexcept
1436 { return __self_view(data(), size()).starts_with(__sv); }
1437
1438 constexpr _LIBCPP_HIDE_FROM_ABI
1439 bool starts_with(value_type __c) const noexcept
1440 { return !empty() && _Traits::eq(front(), __c); }
1441
1442 constexpr _LIBCPP_HIDE_FROM_ABI
1443 bool starts_with(const value_type* __s) const noexcept
1444 { return starts_with(__self_view(__s)); }
1445
1446 constexpr _LIBCPP_HIDE_FROM_ABI
1447 bool ends_with(__self_view __sv) const noexcept
1448 { return __self_view(data(), size()).ends_with( __sv); }
1449
1450 constexpr _LIBCPP_HIDE_FROM_ABI
1451 bool ends_with(value_type __c) const noexcept
1452 { return !empty() && _Traits::eq(back(), __c); }
1453
1454 constexpr _LIBCPP_HIDE_FROM_ABI
1455 bool ends_with(const value_type* __s) const noexcept
1456 { return ends_with(__self_view(__s)); }
1457#endif
1458
1459#if _LIBCPP_STD_VER > 20
1460 constexpr _LIBCPP_HIDE_FROM_ABI
1461 bool contains(__self_view __sv) const noexcept
1462 { return __self_view(data(), size()).contains(__sv); }
1463
1464 constexpr _LIBCPP_HIDE_FROM_ABI
1465 bool contains(value_type __c) const noexcept
1466 { return __self_view(data(), size()).contains(__c); }
1467
1468 constexpr _LIBCPP_HIDE_FROM_ABI
1469 bool contains(const value_type* __s) const
1470 { return __self_view(data(), size()).contains(__s); }
1471#endif
1472
1473 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 bool __invariants() const;
1474
1475 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __clear_and_shrink() _NOEXCEPT;
1476
1477#ifdef _LIBCPP_ENABLE_DEBUG_MODE
1478
1479 bool __dereferenceable(const const_iterator* __i) const;
1480 bool __decrementable(const const_iterator* __i) const;
1481 bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
1482 bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
1483
1484#endif // _LIBCPP_ENABLE_DEBUG_MODE
1485
1486private:
1487 template<class _Alloc>
1488 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1489 bool friend operator==(const basic_string<char, char_traits<char>, _Alloc>& __lhs,
1490 const basic_string<char, char_traits<char>, _Alloc>& __rhs) _NOEXCEPT;
1491
1492 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __shrink_or_extend(size_type __target_capacity);
1493
1494 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1495 bool __is_long() const _NOEXCEPT {
1496 if (__libcpp_is_constant_evaluated())
1497 return true;
1498 return __r_.first().__s.__is_long_;
1499 }
1500
1501 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __begin_lifetime(pointer __begin, size_type __n) {
1502#if _LIBCPP_STD_VER > 17
1503 if (__libcpp_is_constant_evaluated()) {
1504 for (size_type __i = 0; __i != __n; ++__i)
1505 std::construct_at(std::addressof(__begin[__i]));
1506 }
1507#else
1508 (void)__begin;
1509 (void)__n;
1510#endif // _LIBCPP_STD_VER > 17
1511 }
1512
1513 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __default_init() {
1514 __zero();
1515 if (__libcpp_is_constant_evaluated()) {
1516 size_type __sz = __recommend(s: 0) + 1;
1517 pointer __ptr = __alloc_traits::allocate(__alloc(), __sz);
1518 __begin_lifetime(begin: __ptr, n: __sz);
1519 __set_long_pointer(p: __ptr);
1520 __set_long_cap(s: __sz);
1521 __set_long_size(s: 0);
1522 }
1523 }
1524
1525 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __deallocate_constexpr() {
1526 if (__libcpp_is_constant_evaluated() && __get_pointer() != nullptr)
1527 __alloc_traits::deallocate(__alloc(), __get_pointer(), __get_long_cap());
1528 }
1529
1530 _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI static bool __fits_in_sso(size_type __sz) {
1531 // SSO is disabled during constant evaluation because `__is_long` isn't constexpr friendly
1532 return !__libcpp_is_constant_evaluated() && (__sz < __min_cap);
1533 }
1534
1535 template <class _ForwardIterator>
1536 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
1537 iterator __insert_from_safe_copy(size_type __n, size_type __ip, _ForwardIterator __first, _ForwardIterator __last) {
1538 size_type __sz = size();
1539 size_type __cap = capacity();
1540 value_type* __p;
1541 if (__cap - __sz >= __n)
1542 {
1543 __p = std::__to_address(__get_pointer());
1544 size_type __n_move = __sz - __ip;
1545 if (__n_move != 0)
1546 traits_type::move(__p + __ip + __n, __p + __ip, __n_move);
1547 }
1548 else
1549 {
1550 __grow_by(old_cap: __cap, delta_cap: __sz + __n - __cap, old_sz: __sz, n_copy: __ip, n_del: 0, n_add: __n);
1551 __p = std::__to_address(__get_long_pointer());
1552 }
1553 __sz += __n;
1554 __set_size(s: __sz);
1555 traits_type::assign(__p[__sz], value_type());
1556 for (__p += __ip; __first != __last; ++__p, ++__first)
1557 traits_type::assign(*__p, *__first);
1558
1559 return begin() + __ip;
1560 }
1561
1562 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 allocator_type& __alloc() _NOEXCEPT { return __r_.second(); }
1563 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const allocator_type& __alloc() const _NOEXCEPT { return __r_.second(); }
1564
1565 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1566 void __set_short_size(size_type __s) _NOEXCEPT {
1567 _LIBCPP_ASSERT(__s < __min_cap, "__s should never be greater than or equal to the short string capacity");
1568 __r_.first().__s.__size_ = __s;
1569 __r_.first().__s.__is_long_ = false;
1570 }
1571
1572 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1573 size_type __get_short_size() const _NOEXCEPT {
1574 _LIBCPP_ASSERT(!__r_.first().__s.__is_long_, "String has to be short when trying to get the short size");
1575 return __r_.first().__s.__size_;
1576 }
1577
1578 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1579 void __set_long_size(size_type __s) _NOEXCEPT
1580 {__r_.first().__l.__size_ = __s;}
1581 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1582 size_type __get_long_size() const _NOEXCEPT
1583 {return __r_.first().__l.__size_;}
1584 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1585 void __set_size(size_type __s) _NOEXCEPT
1586 {if (__is_long()) __set_long_size(__s); else __set_short_size(__s);}
1587
1588 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1589 void __set_long_cap(size_type __s) _NOEXCEPT {
1590 __r_.first().__l.__cap_ = __s / __endian_factor;
1591 __r_.first().__l.__is_long_ = true;
1592 }
1593
1594 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1595 size_type __get_long_cap() const _NOEXCEPT {
1596 return __r_.first().__l.__cap_ * __endian_factor;
1597 }
1598
1599 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1600 void __set_long_pointer(pointer __p) _NOEXCEPT
1601 {__r_.first().__l.__data_ = __p;}
1602 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1603 pointer __get_long_pointer() _NOEXCEPT
1604 {return __r_.first().__l.__data_;}
1605 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1606 const_pointer __get_long_pointer() const _NOEXCEPT
1607 {return __r_.first().__l.__data_;}
1608 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1609 pointer __get_short_pointer() _NOEXCEPT
1610 {return pointer_traits<pointer>::pointer_to(__r_.first().__s.__data_[0]);}
1611 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1612 const_pointer __get_short_pointer() const _NOEXCEPT
1613 {return pointer_traits<const_pointer>::pointer_to(__r_.first().__s.__data_[0]);}
1614 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1615 pointer __get_pointer() _NOEXCEPT
1616 {return __is_long() ? __get_long_pointer() : __get_short_pointer();}
1617 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1618 const_pointer __get_pointer() const _NOEXCEPT
1619 {return __is_long() ? __get_long_pointer() : __get_short_pointer();}
1620
1621 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1622 void __zero() _NOEXCEPT {
1623 __r_.first() = __rep();
1624 }
1625
1626 template <size_type __a> static
1627 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1628 size_type __align_it(size_type __s) _NOEXCEPT
1629 {return (__s + (__a-1)) & ~(__a-1);}
1630 enum {__alignment = 16};
1631 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1632 size_type __recommend(size_type __s) _NOEXCEPT
1633 {
1634 if (__s < __min_cap) {
1635 if (__libcpp_is_constant_evaluated())
1636 return static_cast<size_type>(__min_cap);
1637 else
1638 return static_cast<size_type>(__min_cap) - 1;
1639 }
1640 size_type __guess = __align_it<sizeof(value_type) < __alignment ?
1641 __alignment/sizeof(value_type) : 1 > (__s+1) - 1;
1642 if (__guess == __min_cap) ++__guess;
1643 return __guess;
1644 }
1645
1646 inline _LIBCPP_CONSTEXPR_AFTER_CXX17
1647 void __init(const value_type* __s, size_type __sz, size_type __reserve);
1648 inline _LIBCPP_CONSTEXPR_AFTER_CXX17
1649 void __init(const value_type* __s, size_type __sz);
1650 inline _LIBCPP_CONSTEXPR_AFTER_CXX17
1651 void __init(size_type __n, value_type __c);
1652
1653 // Slow path for the (inlined) copy constructor for 'long' strings.
1654 // Always externally instantiated and not inlined.
1655 // Requires that __s is zero terminated.
1656 // The main reason for this function to exist is because for unstable, we
1657 // want to allow inlining of the copy constructor. However, we don't want
1658 // to call the __init() functions as those are marked as inline which may
1659 // result in over-aggressive inlining by the compiler, where our aim is
1660 // to only inline the fast path code directly in the ctor.
1661 _LIBCPP_CONSTEXPR_AFTER_CXX17 void __init_copy_ctor_external(const value_type* __s, size_type __sz);
1662
1663 template <class _InputIterator>
1664 inline _LIBCPP_CONSTEXPR_AFTER_CXX17
1665 __enable_if_t
1666 <
1667 __is_exactly_cpp17_input_iterator<_InputIterator>::value
1668 >
1669 __init(_InputIterator __first, _InputIterator __last);
1670
1671 template <class _ForwardIterator>
1672 inline _LIBCPP_CONSTEXPR_AFTER_CXX17
1673 __enable_if_t
1674 <
1675 __is_cpp17_forward_iterator<_ForwardIterator>::value
1676 >
1677 __init(_ForwardIterator __first, _ForwardIterator __last);
1678
1679 _LIBCPP_CONSTEXPR_AFTER_CXX17
1680 void __grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
1681 size_type __n_copy, size_type __n_del, size_type __n_add = 0);
1682 _LIBCPP_CONSTEXPR_AFTER_CXX17
1683 void __grow_by_and_replace(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
1684 size_type __n_copy, size_type __n_del,
1685 size_type __n_add, const value_type* __p_new_stuff);
1686
1687 // __assign_no_alias is invoked for assignment operations where we
1688 // have proof that the input does not alias the current instance.
1689 // For example, operator=(basic_string) performs a 'self' check.
1690 template <bool __is_short>
1691 _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& __assign_no_alias(const value_type* __s, size_type __n);
1692
1693 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1694 void __erase_to_end(size_type __pos);
1695
1696 // __erase_external_with_move is invoked for erase() invocations where
1697 // `n ~= npos`, likely requiring memory moves on the string data.
1698 _LIBCPP_CONSTEXPR_AFTER_CXX17 void __erase_external_with_move(size_type __pos, size_type __n);
1699
1700 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1701 void __copy_assign_alloc(const basic_string& __str)
1702 {__copy_assign_alloc(__str, integral_constant<bool,
1703 __alloc_traits::propagate_on_container_copy_assignment::value>());}
1704
1705 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1706 void __copy_assign_alloc(const basic_string& __str, true_type)
1707 {
1708 if (__alloc() == __str.__alloc())
1709 __alloc() = __str.__alloc();
1710 else
1711 {
1712 if (!__str.__is_long())
1713 {
1714 __clear_and_shrink();
1715 __alloc() = __str.__alloc();
1716 }
1717 else
1718 {
1719 allocator_type __a = __str.__alloc();
1720 auto __allocation = std::__allocate_at_least(__a, __str.__get_long_cap());
1721 __begin_lifetime(begin: __allocation.ptr, n: __allocation.count);
1722 __clear_and_shrink();
1723 __alloc() = std::move(__a);
1724 __set_long_pointer(p: __allocation.ptr);
1725 __set_long_cap(s: __allocation.count);
1726 __set_long_size(s: __str.size());
1727 }
1728 }
1729 }
1730
1731 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1732 void __copy_assign_alloc(const basic_string&, false_type) _NOEXCEPT
1733 {}
1734
1735#ifndef _LIBCPP_CXX03_LANG
1736 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1737 void __move_assign(basic_string& __str, false_type)
1738 _NOEXCEPT_(__alloc_traits::is_always_equal::value);
1739 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1740 void __move_assign(basic_string& __str, true_type)
1741#if _LIBCPP_STD_VER > 14
1742 _NOEXCEPT;
1743#else
1744 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
1745#endif
1746#endif
1747
1748 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1749 void
1750 __move_assign_alloc(basic_string& __str)
1751 _NOEXCEPT_(
1752 !__alloc_traits::propagate_on_container_move_assignment::value ||
1753 is_nothrow_move_assignable<allocator_type>::value)
1754 {__move_assign_alloc(__str, integral_constant<bool,
1755 __alloc_traits::propagate_on_container_move_assignment::value>());}
1756
1757 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1758 void __move_assign_alloc(basic_string& __c, true_type)
1759 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
1760 {
1761 __alloc() = std::move(__c.__alloc());
1762 }
1763
1764 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1765 void __move_assign_alloc(basic_string&, false_type)
1766 _NOEXCEPT
1767 {}
1768
1769 _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& __assign_external(const value_type* __s);
1770 _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& __assign_external(const value_type* __s, size_type __n);
1771
1772 // Assigns the value in __s, guaranteed to be __n < __min_cap in length.
1773 inline basic_string& __assign_short(const value_type* __s, size_type __n) {
1774 pointer __p = __is_long()
1775 ? (__set_long_size(s: __n), __get_long_pointer())
1776 : (__set_short_size(s: __n), __get_short_pointer());
1777 traits_type::move(std::__to_address(__p), __s, __n);
1778 traits_type::assign(__p[__n], value_type());
1779 return *this;
1780 }
1781
1782 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1783 basic_string& __null_terminate_at(value_type* __p, size_type __newsz) {
1784 __set_size(s: __newsz);
1785 __invalidate_iterators_past(__newsz);
1786 traits_type::assign(__p[__newsz], value_type());
1787 return *this;
1788 }
1789
1790 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __invalidate_iterators_past(size_type);
1791
1792 template<class _Tp>
1793 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
1794 bool __addr_in_range(_Tp&& __t) const {
1795 // assume that the ranges overlap, because we can't check during constant evaluation
1796 if (__libcpp_is_constant_evaluated())
1797 return true;
1798 const volatile void *__p = std::addressof(__t);
1799 return data() <= __p && __p <= data() + size();
1800 }
1801
1802 _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI
1803 void __throw_length_error() const {
1804 std::__throw_length_error(msg: "basic_string");
1805 }
1806
1807 _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI
1808 void __throw_out_of_range() const {
1809 std::__throw_out_of_range(msg: "basic_string");
1810 }
1811
1812 friend _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator+<>(const basic_string&, const basic_string&);
1813 friend _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator+<>(const value_type*, const basic_string&);
1814 friend _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator+<>(value_type, const basic_string&);
1815 friend _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator+<>(const basic_string&, const value_type*);
1816 friend _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator+<>(const basic_string&, value_type);
1817};
1818
1819// These declarations must appear before any functions are implicitly used
1820// so that they have the correct visibility specifier.
1821#define _LIBCPP_DECLARE(...) extern template __VA_ARGS__;
1822#ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
1823 _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, char)
1824# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
1825 _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, wchar_t)
1826# endif
1827#else
1828 _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, char)
1829# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
1830 _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, wchar_t)
1831# endif
1832#endif
1833#undef _LIBCPP_DECLARE
1834
1835
1836#if _LIBCPP_STD_VER >= 17
1837template<class _InputIterator,
1838 class _CharT = __iter_value_type<_InputIterator>,
1839 class _Allocator = allocator<_CharT>,
1840 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
1841 class = enable_if_t<__is_allocator<_Allocator>::value>
1842 >
1843basic_string(_InputIterator, _InputIterator, _Allocator = _Allocator())
1844 -> basic_string<_CharT, char_traits<_CharT>, _Allocator>;
1845
1846template<class _CharT,
1847 class _Traits,
1848 class _Allocator = allocator<_CharT>,
1849 class = enable_if_t<__is_allocator<_Allocator>::value>
1850 >
1851explicit basic_string(basic_string_view<_CharT, _Traits>, const _Allocator& = _Allocator())
1852 -> basic_string<_CharT, _Traits, _Allocator>;
1853
1854template<class _CharT,
1855 class _Traits,
1856 class _Allocator = allocator<_CharT>,
1857 class = enable_if_t<__is_allocator<_Allocator>::value>,
1858 class _Sz = typename allocator_traits<_Allocator>::size_type
1859 >
1860basic_string(basic_string_view<_CharT, _Traits>, _Sz, _Sz, const _Allocator& = _Allocator())
1861 -> basic_string<_CharT, _Traits, _Allocator>;
1862#endif
1863
1864template <class _CharT, class _Traits, class _Allocator>
1865inline _LIBCPP_CONSTEXPR_AFTER_CXX17
1866void
1867basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type __pos)
1868{
1869#ifdef _LIBCPP_ENABLE_DEBUG_MODE
1870 if (!__libcpp_is_constant_evaluated()) {
1871 __c_node* __c = __get_db()->__find_c_and_lock(this);
1872 if (__c)
1873 {
1874 const_pointer __new_last = __get_pointer() + __pos;
1875 for (__i_node** __p = __c->end_; __p != __c->beg_; )
1876 {
1877 --__p;
1878 const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
1879 if (__i->base() > __new_last)
1880 {
1881 (*__p)->__c_ = nullptr;
1882 if (--__c->end_ != __p)
1883 std::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
1884 }
1885 }
1886 __get_db()->unlock();
1887 }
1888 }
1889#else
1890 (void)__pos;
1891#endif // _LIBCPP_ENABLE_DEBUG_MODE
1892}
1893
1894template <class _CharT, class _Traits, class _Allocator>
1895inline _LIBCPP_CONSTEXPR_AFTER_CXX17
1896basic_string<_CharT, _Traits, _Allocator>::basic_string()
1897 _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
1898 : __r_(__default_init_tag(), __default_init_tag())
1899{
1900 std::__debug_db_insert_c(this);
1901 __default_init();
1902}
1903
1904template <class _CharT, class _Traits, class _Allocator>
1905inline _LIBCPP_CONSTEXPR_AFTER_CXX17
1906basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __a)
1907#if _LIBCPP_STD_VER <= 14
1908 _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
1909#else
1910 _NOEXCEPT
1911#endif
1912: __r_(__default_init_tag(), __a)
1913{
1914 std::__debug_db_insert_c(this);
1915 __default_init();
1916}
1917
1918template <class _CharT, class _Traits, class _Allocator>
1919_LIBCPP_CONSTEXPR_AFTER_CXX17
1920void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s,
1921 size_type __sz,
1922 size_type __reserve)
1923{
1924 if (__libcpp_is_constant_evaluated())
1925 __zero();
1926 if (__reserve > max_size())
1927 __throw_length_error();
1928 pointer __p;
1929 if (__fits_in_sso(sz: __reserve))
1930 {
1931 __set_short_size(s: __sz);
1932 __p = __get_short_pointer();
1933 }
1934 else
1935 {
1936 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(s: __reserve) + 1);
1937 __p = __allocation.ptr;
1938 __begin_lifetime(begin: __p, n: __allocation.count);
1939 __set_long_pointer(__p);
1940 __set_long_cap(s: __allocation.count);
1941 __set_long_size(s: __sz);
1942 }
1943 traits_type::copy(std::__to_address(__p), __s, __sz);
1944 traits_type::assign(__p[__sz], value_type());
1945}
1946
1947template <class _CharT, class _Traits, class _Allocator>
1948_LIBCPP_CONSTEXPR_AFTER_CXX17
1949void
1950basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz)
1951{
1952 if (__libcpp_is_constant_evaluated())
1953 __zero();
1954 if (__sz > max_size())
1955 __throw_length_error();
1956 pointer __p;
1957 if (__fits_in_sso(__sz))
1958 {
1959 __set_short_size(s: __sz);
1960 __p = __get_short_pointer();
1961 }
1962 else
1963 {
1964 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(s: __sz) + 1);
1965 __p = __allocation.ptr;
1966 __begin_lifetime(begin: __p, n: __allocation.count);
1967 __set_long_pointer(__p);
1968 __set_long_cap(s: __allocation.count);
1969 __set_long_size(s: __sz);
1970 }
1971 traits_type::copy(std::__to_address(__p), __s, __sz);
1972 traits_type::assign(__p[__sz], value_type());
1973}
1974
1975template <class _CharT, class _Traits, class _Allocator>
1976template <class>
1977_LIBCPP_CONSTEXPR_AFTER_CXX17
1978basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const _Allocator& __a)
1979 : __r_(__default_init_tag(), __a)
1980{
1981 _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr");
1982 __init(__s, traits_type::length(__s));
1983 std::__debug_db_insert_c(this);
1984}
1985
1986template <class _CharT, class _Traits, class _Allocator>
1987inline _LIBCPP_CONSTEXPR_AFTER_CXX17
1988basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n)
1989 : __r_(__default_init_tag(), __default_init_tag())
1990{
1991 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr");
1992 __init(__s, __n);
1993 std::__debug_db_insert_c(this);
1994}
1995
1996template <class _CharT, class _Traits, class _Allocator>
1997inline _LIBCPP_CONSTEXPR_AFTER_CXX17
1998basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n, const _Allocator& __a)
1999 : __r_(__default_init_tag(), __a)
2000{
2001 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr");
2002 __init(__s, __n);
2003 std::__debug_db_insert_c(this);
2004}
2005
2006template <class _CharT, class _Traits, class _Allocator>
2007_LIBCPP_CONSTEXPR_AFTER_CXX17
2008basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str)
2009 : __r_(__default_init_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc()))
2010{
2011 if (!__str.__is_long())
2012 __r_.first().__r = __str.__r_.first().__r;
2013 else
2014 __init_copy_ctor_external(s: std::__to_address(__str.__get_long_pointer()),
2015 sz: __str.__get_long_size());
2016 std::__debug_db_insert_c(this);
2017}
2018
2019template <class _CharT, class _Traits, class _Allocator>
2020_LIBCPP_CONSTEXPR_AFTER_CXX17
2021basic_string<_CharT, _Traits, _Allocator>::basic_string(
2022 const basic_string& __str, const allocator_type& __a)
2023 : __r_(__default_init_tag(), __a)
2024{
2025 if (!__str.__is_long())
2026 __r_.first().__r = __str.__r_.first().__r;
2027 else
2028 __init_copy_ctor_external(s: std::__to_address(__str.__get_long_pointer()),
2029 sz: __str.__get_long_size());
2030 std::__debug_db_insert_c(this);
2031}
2032
2033template <class _CharT, class _Traits, class _Allocator>
2034_LIBCPP_CONSTEXPR_AFTER_CXX17
2035void basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external(
2036 const value_type* __s, size_type __sz) {
2037 if (__libcpp_is_constant_evaluated())
2038 __zero();
2039 pointer __p;
2040 if (__fits_in_sso(__sz)) {
2041 __p = __get_short_pointer();
2042 __set_short_size(s: __sz);
2043 } else {
2044 if (__sz > max_size())
2045 __throw_length_error();
2046 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(s: __sz) + 1);
2047 __p = __allocation.ptr;
2048 __begin_lifetime(begin: __p, n: __allocation.count);
2049 __set_long_pointer(__p);
2050 __set_long_cap(s: __allocation.count);
2051 __set_long_size(s: __sz);
2052 }
2053 traits_type::copy(std::__to_address(__p), __s, __sz + 1);
2054}
2055
2056#ifndef _LIBCPP_CXX03_LANG
2057
2058template <class _CharT, class _Traits, class _Allocator>
2059inline _LIBCPP_CONSTEXPR_AFTER_CXX17
2060basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str)
2061#if _LIBCPP_STD_VER <= 14
2062 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
2063#else
2064 _NOEXCEPT
2065#endif
2066 : __r_(std::move(__str.__r_))
2067{
2068 __str.__default_init();
2069 std::__debug_db_insert_c(this);
2070 if (__is_long())
2071 std::__debug_db_swap(this, &__str);
2072}
2073
2074template <class _CharT, class _Traits, class _Allocator>
2075inline _LIBCPP_CONSTEXPR_AFTER_CXX17
2076basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, const allocator_type& __a)
2077 : __r_(__default_init_tag(), __a)
2078{
2079 if (__str.__is_long() && __a != __str.__alloc()) // copy, not move
2080 __init(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size());
2081 else
2082 {
2083 if (__libcpp_is_constant_evaluated()) {
2084 __zero();
2085 __r_.first().__l = __str.__r_.first().__l;
2086 } else {
2087 __r_.first().__r = __str.__r_.first().__r;
2088 }
2089 __str.__default_init();
2090 }
2091 std::__debug_db_insert_c(this);
2092 if (__is_long())
2093 std::__debug_db_swap(this, &__str);
2094}
2095
2096#endif // _LIBCPP_CXX03_LANG
2097
2098template <class _CharT, class _Traits, class _Allocator>
2099_LIBCPP_CONSTEXPR_AFTER_CXX17
2100void
2101basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c)
2102{
2103 if (__libcpp_is_constant_evaluated())
2104 __zero();
2105 if (__n > max_size())
2106 __throw_length_error();
2107 pointer __p;
2108 if (__fits_in_sso(sz: __n))
2109 {
2110 __set_short_size(s: __n);
2111 __p = __get_short_pointer();
2112 }
2113 else
2114 {
2115 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(s: __n) + 1);
2116 __p = __allocation.ptr;
2117 __begin_lifetime(begin: __p, n: __allocation.count);
2118 __set_long_pointer(__p);
2119 __set_long_cap(s: __allocation.count);
2120 __set_long_size(s: __n);
2121 }
2122 traits_type::assign(std::__to_address(__p), __n, __c);
2123 traits_type::assign(__p[__n], value_type());
2124}
2125
2126template <class _CharT, class _Traits, class _Allocator>
2127inline _LIBCPP_CONSTEXPR_AFTER_CXX17
2128basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c)
2129 : __r_(__default_init_tag(), __default_init_tag())
2130{
2131 __init(__n, __c);
2132 std::__debug_db_insert_c(this);
2133}
2134
2135template <class _CharT, class _Traits, class _Allocator>
2136template <class>
2137_LIBCPP_CONSTEXPR_AFTER_CXX17
2138basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c, const _Allocator& __a)
2139 : __r_(__default_init_tag(), __a)
2140{
2141 __init(__n, __c);
2142 std::__debug_db_insert_c(this);
2143}
2144
2145template <class _CharT, class _Traits, class _Allocator>
2146_LIBCPP_CONSTEXPR_AFTER_CXX17
2147basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str,
2148 size_type __pos, size_type __n,
2149 const _Allocator& __a)
2150 : __r_(__default_init_tag(), __a)
2151{
2152 size_type __str_sz = __str.size();
2153 if (__pos > __str_sz)
2154 __throw_out_of_range();
2155 __init(__str.data() + __pos, std::min(__n, __str_sz - __pos));
2156 std::__debug_db_insert_c(this);
2157}
2158
2159template <class _CharT, class _Traits, class _Allocator>
2160inline _LIBCPP_CONSTEXPR_AFTER_CXX17
2161basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos,
2162 const _Allocator& __a)
2163 : __r_(__default_init_tag(), __a)
2164{
2165 size_type __str_sz = __str.size();
2166 if (__pos > __str_sz)
2167 __throw_out_of_range();
2168 __init(__str.data() + __pos, __str_sz - __pos);
2169 std::__debug_db_insert_c(this);
2170}
2171
2172template <class _CharT, class _Traits, class _Allocator>
2173template <class _Tp, class>
2174_LIBCPP_CONSTEXPR_AFTER_CXX17
2175basic_string<_CharT, _Traits, _Allocator>::basic_string(
2176 const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a)
2177 : __r_(__default_init_tag(), __a)
2178{
2179 __self_view __sv0 = __t;
2180 __self_view __sv = __sv0.substr(__pos, __n);
2181 __init(__sv.data(), __sv.size());
2182 std::__debug_db_insert_c(this);
2183}
2184
2185template <class _CharT, class _Traits, class _Allocator>
2186template <class _Tp, class>
2187_LIBCPP_CONSTEXPR_AFTER_CXX17
2188basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t)
2189 : __r_(__default_init_tag(), __default_init_tag())
2190{
2191 __self_view __sv = __t;
2192 __init(__sv.data(), __sv.size());
2193 std::__debug_db_insert_c(this);
2194}
2195
2196template <class _CharT, class _Traits, class _Allocator>
2197template <class _Tp, class>
2198_LIBCPP_CONSTEXPR_AFTER_CXX17
2199basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t, const _Allocator& __a)
2200 : __r_(__default_init_tag(), __a)
2201{
2202 __self_view __sv = __t;
2203 __init(__sv.data(), __sv.size());
2204 std::__debug_db_insert_c(this);
2205}
2206
2207template <class _CharT, class _Traits, class _Allocator>
2208template <class _InputIterator>
2209_LIBCPP_CONSTEXPR_AFTER_CXX17
2210__enable_if_t
2211<
2212 __is_exactly_cpp17_input_iterator<_InputIterator>::value
2213>
2214basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last)
2215{
2216 __default_init();
2217#ifndef _LIBCPP_NO_EXCEPTIONS
2218 try
2219 {
2220#endif // _LIBCPP_NO_EXCEPTIONS
2221 for (; __first != __last; ++__first)
2222 push_back(c: *__first);
2223#ifndef _LIBCPP_NO_EXCEPTIONS
2224 }
2225 catch (...)
2226 {
2227 if (__is_long())
2228 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
2229 throw;
2230 }
2231#endif // _LIBCPP_NO_EXCEPTIONS
2232}
2233
2234template <class _CharT, class _Traits, class _Allocator>
2235template <class _ForwardIterator>
2236_LIBCPP_CONSTEXPR_AFTER_CXX17
2237__enable_if_t
2238<
2239 __is_cpp17_forward_iterator<_ForwardIterator>::value
2240>
2241basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last)
2242{
2243 if (__libcpp_is_constant_evaluated())
2244 __zero();
2245 size_type __sz = static_cast<size_type>(std::distance(__first, __last));
2246 if (__sz > max_size())
2247 __throw_length_error();
2248 pointer __p;
2249 if (__fits_in_sso(__sz))
2250 {
2251 __set_short_size(s: __sz);
2252 __p = __get_short_pointer();
2253 }
2254 else
2255 {
2256 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(s: __sz) + 1);
2257 __p = __allocation.ptr;
2258 __begin_lifetime(begin: __p, n: __allocation.count);
2259 __set_long_pointer(__p);
2260 __set_long_cap(s: __allocation.count);
2261 __set_long_size(s: __sz);
2262 }
2263
2264#ifndef _LIBCPP_NO_EXCEPTIONS
2265 try
2266 {
2267#endif // _LIBCPP_NO_EXCEPTIONS
2268 for (; __first != __last; ++__first, (void) ++__p)
2269 traits_type::assign(*__p, *__first);
2270 traits_type::assign(*__p, value_type());
2271#ifndef _LIBCPP_NO_EXCEPTIONS
2272 }
2273 catch (...)
2274 {
2275 if (__is_long())
2276 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
2277 throw;
2278 }
2279#endif // _LIBCPP_NO_EXCEPTIONS
2280}
2281
2282template <class _CharT, class _Traits, class _Allocator>
2283template<class _InputIterator, class>
2284inline _LIBCPP_CONSTEXPR_AFTER_CXX17
2285basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last)
2286 : __r_(__default_init_tag(), __default_init_tag())
2287{
2288 __init(__first, __last);
2289 std::__debug_db_insert_c(this);
2290}
2291
2292template <class _CharT, class _Traits, class _Allocator>
2293template<class _InputIterator, class>
2294inline _LIBCPP_CONSTEXPR_AFTER_CXX17
2295basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last,
2296 const allocator_type& __a)
2297 : __r_(__default_init_tag(), __a)
2298{
2299 __init(__first, __last);
2300 std::__debug_db_insert_c(this);
2301}
2302
2303#ifndef _LIBCPP_CXX03_LANG
2304
2305template <class _CharT, class _Traits, class _Allocator>
2306inline _LIBCPP_CONSTEXPR_AFTER_CXX17
2307basic_string<_CharT, _Traits, _Allocator>::basic_string(
2308 initializer_list<_CharT> __il)
2309 : __r_(__default_init_tag(), __default_init_tag())
2310{
2311 __init(__il.begin(), __il.end());
2312 std::__debug_db_insert_c(this);
2313}
2314
2315template <class _CharT, class _Traits, class _Allocator>
2316inline _LIBCPP_CONSTEXPR_AFTER_CXX17
2317basic_string<_CharT, _Traits, _Allocator>::basic_string(
2318 initializer_list<_CharT> __il, const _Allocator& __a)
2319 : __r_(__default_init_tag(), __a)
2320{
2321 __init(__il.begin(), __il.end());
2322 std::__debug_db_insert_c(this);
2323}
2324
2325#endif // _LIBCPP_CXX03_LANG
2326
2327template <class _CharT, class _Traits, class _Allocator>
2328_LIBCPP_CONSTEXPR_AFTER_CXX17
2329basic_string<_CharT, _Traits, _Allocator>::~basic_string()
2330{
2331 std::__debug_db_erase_c(this);
2332 if (__is_long())
2333 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
2334}
2335
2336template <class _CharT, class _Traits, class _Allocator>
2337_LIBCPP_CONSTEXPR_AFTER_CXX17
2338void
2339basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace
2340 (size_type __old_cap, size_type __delta_cap, size_type __old_sz,
2341 size_type __n_copy, size_type __n_del, size_type __n_add, const value_type* __p_new_stuff)
2342{
2343 size_type __ms = max_size();
2344 if (__delta_cap > __ms - __old_cap - 1)
2345 __throw_length_error();
2346 pointer __old_p = __get_pointer();
2347 size_type __cap = __old_cap < __ms / 2 - __alignment ?
2348 __recommend(s: std::max(__old_cap + __delta_cap, 2 * __old_cap)) :
2349 __ms - 1;
2350 auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1);
2351 pointer __p = __allocation.ptr;
2352 __begin_lifetime(begin: __p, n: __allocation.count);
2353 std::__debug_db_invalidate_all(this);
2354 if (__n_copy != 0)
2355 traits_type::copy(std::__to_address(__p),
2356 std::__to_address(__old_p), __n_copy);
2357 if (__n_add != 0)
2358 traits_type::copy(std::__to_address(__p) + __n_copy, __p_new_stuff, __n_add);
2359 size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
2360 if (__sec_cp_sz != 0)
2361 traits_type::copy(std::__to_address(__p) + __n_copy + __n_add,
2362 std::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz);
2363 if (__old_cap+1 != __min_cap || __libcpp_is_constant_evaluated())
2364 __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1);
2365 __set_long_pointer(__p);
2366 __set_long_cap(s: __allocation.count);
2367 __old_sz = __n_copy + __n_add + __sec_cp_sz;
2368 __set_long_size(s: __old_sz);
2369 traits_type::assign(__p[__old_sz], value_type());
2370}
2371
2372template <class _CharT, class _Traits, class _Allocator>
2373void
2374_LIBCPP_CONSTEXPR_AFTER_CXX17
2375basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
2376 size_type __n_copy, size_type __n_del, size_type __n_add)
2377{
2378 size_type __ms = max_size();
2379 if (__delta_cap > __ms - __old_cap)
2380 __throw_length_error();
2381 pointer __old_p = __get_pointer();
2382 size_type __cap = __old_cap < __ms / 2 - __alignment ?
2383 __recommend(s: std::max(__old_cap + __delta_cap, 2 * __old_cap)) :
2384 __ms - 1;
2385 auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1);
2386 pointer __p = __allocation.ptr;
2387 __begin_lifetime(begin: __p, n: __allocation.count);
2388 std::__debug_db_invalidate_all(this);
2389 if (__n_copy != 0)
2390 traits_type::copy(std::__to_address(__p),
2391 std::__to_address(__old_p), __n_copy);
2392 size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
2393 if (__sec_cp_sz != 0)
2394 traits_type::copy(std::__to_address(__p) + __n_copy + __n_add,
2395 std::__to_address(__old_p) + __n_copy + __n_del,
2396 __sec_cp_sz);
2397 if (__libcpp_is_constant_evaluated() || __old_cap + 1 != __min_cap)
2398 __alloc_traits::deallocate(__alloc(), __old_p, __old_cap + 1);
2399 __set_long_pointer(__p);
2400 __set_long_cap(s: __allocation.count);
2401}
2402
2403// assign
2404
2405template <class _CharT, class _Traits, class _Allocator>
2406template <bool __is_short>
2407_LIBCPP_CONSTEXPR_AFTER_CXX17
2408basic_string<_CharT, _Traits, _Allocator>&
2409basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias(
2410 const value_type* __s, size_type __n) {
2411 size_type __cap = __is_short ? static_cast<size_type>(__min_cap) : __get_long_cap();
2412 if (__n < __cap) {
2413 pointer __p = __is_short ? __get_short_pointer() : __get_long_pointer();
2414 __is_short ? __set_short_size(s: __n) : __set_long_size(s: __n);
2415 traits_type::copy(std::__to_address(__p), __s, __n);
2416 traits_type::assign(__p[__n], value_type());
2417 __invalidate_iterators_past(pos: __n);
2418 } else {
2419 size_type __sz = __is_short ? __get_short_size() : __get_long_size();
2420 __grow_by_and_replace(old_cap: __cap - 1, delta_cap: __n - __cap + 1, old_sz: __sz, n_copy: 0, n_del: __sz, n_add: __n, p_new_stuff: __s);
2421 }
2422 return *this;
2423}
2424
2425template <class _CharT, class _Traits, class _Allocator>
2426_LIBCPP_CONSTEXPR_AFTER_CXX17
2427basic_string<_CharT, _Traits, _Allocator>&
2428basic_string<_CharT, _Traits, _Allocator>::__assign_external(
2429 const value_type* __s, size_type __n) {
2430 size_type __cap = capacity();
2431 if (__cap >= __n) {
2432 value_type* __p = std::__to_address(__get_pointer());
2433 traits_type::move(__p, __s, __n);
2434 return __null_terminate_at(__p, newsz: __n);
2435 } else {
2436 size_type __sz = size();
2437 __grow_by_and_replace(old_cap: __cap, delta_cap: __n - __cap, old_sz: __sz, n_copy: 0, n_del: __sz, n_add: __n, p_new_stuff: __s);
2438 return *this;
2439 }
2440}
2441
2442template <class _CharT, class _Traits, class _Allocator>
2443_LIBCPP_CONSTEXPR_AFTER_CXX17
2444basic_string<_CharT, _Traits, _Allocator>&
2445basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n)
2446{
2447 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::assign received nullptr");
2448 return (__builtin_constant_p(__n) && __fits_in_sso(sz: __n))
2449 ? __assign_short(__s, __n)
2450 : __assign_external(__s, __n);
2451}
2452
2453template <class _CharT, class _Traits, class _Allocator>
2454_LIBCPP_CONSTEXPR_AFTER_CXX17
2455basic_string<_CharT, _Traits, _Allocator>&
2456basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c)
2457{
2458 size_type __cap = capacity();
2459 if (__cap < __n)
2460 {
2461 size_type __sz = size();
2462 __grow_by(old_cap: __cap, delta_cap: __n - __cap, old_sz: __sz, n_copy: 0, n_del: __sz);
2463 }
2464 value_type* __p = std::__to_address(__get_pointer());
2465 traits_type::assign(__p, __n, __c);
2466 return __null_terminate_at(__p, newsz: __n);
2467}
2468
2469template <class _CharT, class _Traits, class _Allocator>
2470_LIBCPP_CONSTEXPR_AFTER_CXX17
2471basic_string<_CharT, _Traits, _Allocator>&
2472basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c)
2473{
2474 pointer __p;
2475 if (__is_long())
2476 {
2477 __p = __get_long_pointer();
2478 __set_long_size(s: 1);
2479 }
2480 else
2481 {
2482 __p = __get_short_pointer();
2483 __set_short_size(s: 1);
2484 }
2485 traits_type::assign(*__p, __c);
2486 traits_type::assign(*++__p, value_type());
2487 __invalidate_iterators_past(pos: 1);
2488 return *this;
2489}
2490
2491template <class _CharT, class _Traits, class _Allocator>
2492_LIBCPP_CONSTEXPR_AFTER_CXX17
2493basic_string<_CharT, _Traits, _Allocator>&
2494basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str)
2495{
2496 if (this != &__str) {
2497 __copy_assign_alloc(__str);
2498 if (!__is_long()) {
2499 if (!__str.__is_long()) {
2500 __r_.first().__r = __str.__r_.first().__r;
2501 } else {
2502 return __assign_no_alias<true>(__str.data(), __str.size());
2503 }
2504 } else {
2505 return __assign_no_alias<false>(__str.data(), __str.size());
2506 }
2507 }
2508 return *this;
2509}
2510
2511#ifndef _LIBCPP_CXX03_LANG
2512
2513template <class _CharT, class _Traits, class _Allocator>
2514inline _LIBCPP_CONSTEXPR_AFTER_CXX17
2515void
2516basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, false_type)
2517 _NOEXCEPT_(__alloc_traits::is_always_equal::value)
2518{
2519 if (__alloc() != __str.__alloc())
2520 assign(__str);
2521 else
2522 __move_assign(__str, true_type());
2523}
2524
2525template <class _CharT, class _Traits, class _Allocator>
2526inline _LIBCPP_CONSTEXPR_AFTER_CXX17
2527void
2528basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type)
2529#if _LIBCPP_STD_VER > 14
2530 _NOEXCEPT
2531#else
2532 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
2533#endif
2534{
2535 if (__is_long()) {
2536 __alloc_traits::deallocate(__alloc(), __get_long_pointer(),
2537 __get_long_cap());
2538#if _LIBCPP_STD_VER <= 14
2539 if (!is_nothrow_move_assignable<allocator_type>::value) {
2540 __set_short_size(0);
2541 traits_type::assign(__get_short_pointer()[0], value_type());
2542 }
2543#endif
2544 }
2545 __move_assign_alloc(__str);
2546 __r_.first() = __str.__r_.first();
2547 if (__libcpp_is_constant_evaluated()) {
2548 __str.__default_init();
2549 } else {
2550 __str.__set_short_size(0);
2551 traits_type::assign(__str.__get_short_pointer()[0], value_type());
2552 }
2553}
2554
2555template <class _CharT, class _Traits, class _Allocator>
2556inline _LIBCPP_CONSTEXPR_AFTER_CXX17
2557basic_string<_CharT, _Traits, _Allocator>&
2558basic_string<_CharT, _Traits, _Allocator>::operator=(basic_string&& __str)
2559 _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value))
2560{
2561 __move_assign(__str, integral_constant<bool,
2562 __alloc_traits::propagate_on_container_move_assignment::value>());
2563 return *this;
2564}
2565
2566#endif
2567
2568template <class _CharT, class _Traits, class _Allocator>
2569template<class _InputIterator>
2570_LIBCPP_CONSTEXPR_AFTER_CXX17
2571__enable_if_t
2572<
2573 __is_exactly_cpp17_input_iterator<_InputIterator>::value,
2574 basic_string<_CharT, _Traits, _Allocator>&
2575>
2576basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
2577{
2578 const basic_string __temp(__first, __last, __alloc());
2579 assign(__temp.data(), __temp.size());
2580 return *this;
2581}
2582
2583template <class _CharT, class _Traits, class _Allocator>
2584template<class _ForwardIterator>
2585_LIBCPP_CONSTEXPR_AFTER_CXX17
2586__enable_if_t
2587<
2588 __is_cpp17_forward_iterator<_ForwardIterator>::value,
2589 basic_string<_CharT, _Traits, _Allocator>&
2590>
2591basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)
2592{
2593 size_type __cap = capacity();
2594 size_type __n = __string_is_trivial_iterator<_ForwardIterator>::value ?
2595 static_cast<size_type>(std::distance(__first, __last)) : 0;
2596
2597 if (__string_is_trivial_iterator<_ForwardIterator>::value &&
2598 (__cap >= __n || !__addr_in_range(*__first)))
2599 {
2600 if (__cap < __n)
2601 {
2602 size_type __sz = size();
2603 __grow_by(old_cap: __cap, delta_cap: __n - __cap, old_sz: __sz, n_copy: 0, n_del: __sz);
2604 }
2605 pointer __p = __get_pointer();
2606 for (; __first != __last; ++__p, (void) ++__first)
2607 traits_type::assign(*__p, *__first);
2608 traits_type::assign(*__p, value_type());
2609 __set_size(s: __n);
2610 __invalidate_iterators_past(pos: __n);
2611 }
2612 else
2613 {
2614 const basic_string __temp(__first, __last, __alloc());
2615 assign(__temp.data(), __temp.size());
2616 }
2617 return *this;
2618}
2619
2620template <class _CharT, class _Traits, class _Allocator>
2621_LIBCPP_CONSTEXPR_AFTER_CXX17
2622basic_string<_CharT, _Traits, _Allocator>&
2623basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, size_type __pos, size_type __n)
2624{
2625 size_type __sz = __str.size();
2626 if (__pos > __sz)
2627 __throw_out_of_range();
2628 return assign(__str.data() + __pos, std::min(__n, __sz - __pos));
2629}
2630
2631template <class _CharT, class _Traits, class _Allocator>
2632template <class _Tp>
2633_LIBCPP_CONSTEXPR_AFTER_CXX17
2634__enable_if_t
2635<
2636 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
2637 && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
2638 basic_string<_CharT, _Traits, _Allocator>&
2639>
2640basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t, size_type __pos, size_type __n)
2641{
2642 __self_view __sv = __t;
2643 size_type __sz = __sv.size();
2644 if (__pos > __sz)
2645 __throw_out_of_range();
2646 return assign(__sv.data() + __pos, std::min(__n, __sz - __pos));
2647}
2648
2649
2650template <class _CharT, class _Traits, class _Allocator>
2651_LIBCPP_CONSTEXPR_AFTER_CXX17
2652basic_string<_CharT, _Traits, _Allocator>&
2653basic_string<_CharT, _Traits, _Allocator>::__assign_external(const value_type* __s) {
2654 return __assign_external(__s, traits_type::length(__s));
2655}
2656
2657template <class _CharT, class _Traits, class _Allocator>
2658_LIBCPP_CONSTEXPR_AFTER_CXX17
2659basic_string<_CharT, _Traits, _Allocator>&
2660basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s)
2661{
2662 _LIBCPP_ASSERT(__s != nullptr, "string::assign received nullptr");
2663 return __builtin_constant_p(*__s)
2664 ? (__fits_in_sso(sz: traits_type::length(__s))
2665 ? __assign_short(__s, n: traits_type::length(__s))
2666 : __assign_external(__s, traits_type::length(__s)))
2667 : __assign_external(__s);
2668}
2669// append
2670
2671template <class _CharT, class _Traits, class _Allocator>
2672_LIBCPP_CONSTEXPR_AFTER_CXX17
2673basic_string<_CharT, _Traits, _Allocator>&
2674basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n)
2675{
2676 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::append received nullptr");
2677 size_type __cap = capacity();
2678 size_type __sz = size();
2679 if (__cap - __sz >= __n)
2680 {
2681 if (__n)
2682 {
2683 value_type* __p = std::__to_address(__get_pointer());
2684 traits_type::copy(__p + __sz, __s, __n);
2685 __sz += __n;
2686 __set_size(s: __sz);
2687 traits_type::assign(__p[__sz], value_type());
2688 }
2689 }
2690 else
2691 __grow_by_and_replace(old_cap: __cap, delta_cap: __sz + __n - __cap, old_sz: __sz, n_copy: __sz, n_del: 0, n_add: __n, p_new_stuff: __s);
2692 return *this;
2693}
2694
2695template <class _CharT, class _Traits, class _Allocator>
2696_LIBCPP_CONSTEXPR_AFTER_CXX17
2697basic_string<_CharT, _Traits, _Allocator>&
2698basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c)
2699{
2700 if (__n)
2701 {
2702 size_type __cap = capacity();
2703 size_type __sz = size();
2704 if (__cap - __sz < __n)
2705 __grow_by(old_cap: __cap, delta_cap: __sz + __n - __cap, old_sz: __sz, n_copy: __sz, n_del: 0);
2706 pointer __p = __get_pointer();
2707 traits_type::assign(std::__to_address(__p) + __sz, __n, __c);
2708 __sz += __n;
2709 __set_size(s: __sz);
2710 traits_type::assign(__p[__sz], value_type());
2711 }
2712 return *this;
2713}
2714
2715template <class _CharT, class _Traits, class _Allocator>
2716_LIBCPP_CONSTEXPR_AFTER_CXX17 inline void
2717basic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n)
2718{
2719 if (__n)
2720 {
2721 size_type __cap = capacity();
2722 size_type __sz = size();
2723 if (__cap - __sz < __n)
2724 __grow_by(old_cap: __cap, delta_cap: __sz + __n - __cap, old_sz: __sz, n_copy: __sz, n_del: 0);
2725 pointer __p = __get_pointer();
2726 __sz += __n;
2727 __set_size(s: __sz);
2728 traits_type::assign(__p[__sz], value_type());
2729 }
2730}
2731
2732template <class _CharT, class _Traits, class _Allocator>
2733_LIBCPP_CONSTEXPR_AFTER_CXX17
2734void
2735basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c)
2736{
2737 bool __is_short = !__is_long();
2738 size_type __cap;
2739 size_type __sz;
2740 if (__is_short)
2741 {
2742 __cap = __min_cap - 1;
2743 __sz = __get_short_size();
2744 }
2745 else
2746 {
2747 __cap = __get_long_cap() - 1;
2748 __sz = __get_long_size();
2749 }
2750 if (__sz == __cap)
2751 {
2752 __grow_by(old_cap: __cap, delta_cap: 1, old_sz: __sz, n_copy: __sz, n_del: 0);
2753 __is_short = false; // the string is always long after __grow_by
2754 }
2755 pointer __p = __get_pointer();
2756 if (__is_short)
2757 {
2758 __p = __get_short_pointer() + __sz;
2759 __set_short_size(s: __sz+1);
2760 }
2761 else
2762 {
2763 __p = __get_long_pointer() + __sz;
2764 __set_long_size(s: __sz+1);
2765 }
2766 traits_type::assign(*__p, __c);
2767 traits_type::assign(*++__p, value_type());
2768}
2769
2770template <class _CharT, class _Traits, class _Allocator>
2771template<class _ForwardIterator>
2772_LIBCPP_CONSTEXPR_AFTER_CXX17
2773__enable_if_t
2774<
2775 __is_cpp17_forward_iterator<_ForwardIterator>::value,
2776 basic_string<_CharT, _Traits, _Allocator>&
2777>
2778basic_string<_CharT, _Traits, _Allocator>::append(
2779 _ForwardIterator __first, _ForwardIterator __last)
2780{
2781 size_type __sz = size();
2782 size_type __cap = capacity();
2783 size_type __n = static_cast<size_type>(std::distance(__first, __last));
2784 if (__n)
2785 {
2786 if (__string_is_trivial_iterator<_ForwardIterator>::value &&
2787 !__addr_in_range(*__first))
2788 {
2789 if (__cap - __sz < __n)
2790 __grow_by(old_cap: __cap, delta_cap: __sz + __n - __cap, old_sz: __sz, n_copy: __sz, n_del: 0);
2791 pointer __p = __get_pointer() + __sz;
2792 for (; __first != __last; ++__p, (void) ++__first)
2793 traits_type::assign(*__p, *__first);
2794 traits_type::assign(*__p, value_type());
2795 __set_size(s: __sz + __n);
2796 }
2797 else
2798 {
2799 const basic_string __temp(__first, __last, __alloc());
2800 append(__temp.data(), __temp.size());
2801 }
2802 }
2803 return *this;
2804}
2805
2806template <class _CharT, class _Traits, class _Allocator>
2807inline _LIBCPP_CONSTEXPR_AFTER_CXX17
2808basic_string<_CharT, _Traits, _Allocator>&
2809basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str)
2810{
2811 return append(__str.data(), __str.size());
2812}
2813
2814template <class _CharT, class _Traits, class _Allocator>
2815_LIBCPP_CONSTEXPR_AFTER_CXX17
2816basic_string<_CharT, _Traits, _Allocator>&
2817basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, size_type __pos, size_type __n)
2818{
2819 size_type __sz = __str.size();
2820 if (__pos > __sz)
2821 __throw_out_of_range();
2822 return append(__str.data() + __pos, std::min(__n, __sz - __pos));
2823}
2824
2825template <class _CharT, class _Traits, class _Allocator>
2826template <class _Tp>
2827_LIBCPP_CONSTEXPR_AFTER_CXX17
2828 __enable_if_t
2829 <
2830 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
2831 basic_string<_CharT, _Traits, _Allocator>&
2832 >
2833basic_string<_CharT, _Traits, _Allocator>::append(const _Tp & __t, size_type __pos, size_type __n)
2834{
2835 __self_view __sv = __t;
2836 size_type __sz = __sv.size();
2837 if (__pos > __sz)
2838 __throw_out_of_range();
2839 return append(__sv.data() + __pos, std::min(__n, __sz - __pos));
2840}
2841
2842template <class _CharT, class _Traits, class _Allocator>
2843_LIBCPP_CONSTEXPR_AFTER_CXX17
2844basic_string<_CharT, _Traits, _Allocator>&
2845basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s)
2846{
2847 _LIBCPP_ASSERT(__s != nullptr, "string::append received nullptr");
2848 return append(__s, traits_type::length(__s));
2849}
2850
2851// insert
2852
2853template <class _CharT, class _Traits, class _Allocator>
2854_LIBCPP_CONSTEXPR_AFTER_CXX17
2855basic_string<_CharT, _Traits, _Allocator>&
2856basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n)
2857{
2858 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::insert received nullptr");
2859 size_type __sz = size();
2860 if (__pos > __sz)
2861 __throw_out_of_range();
2862 size_type __cap = capacity();
2863 if (__libcpp_is_constant_evaluated()) {
2864 if (__cap - __sz >= __n)
2865 __grow_by_and_replace(old_cap: __cap, delta_cap: 0, old_sz: __sz, n_copy: __pos, n_del: 0, n_add: __n, p_new_stuff: __s);
2866 else
2867 __grow_by_and_replace(old_cap: __cap, delta_cap: __sz + __n - __cap, old_sz: __sz, n_copy: __pos, n_del: 0, n_add: __n, p_new_stuff: __s);
2868 return *this;
2869 }
2870 if (__cap - __sz >= __n)
2871 {
2872 if (__n)
2873 {
2874 value_type* __p = std::__to_address(__get_pointer());
2875 size_type __n_move = __sz - __pos;
2876 if (__n_move != 0)
2877 {
2878 if (__p + __pos <= __s && __s < __p + __sz)
2879 __s += __n;
2880 traits_type::move(__p + __pos + __n, __p + __pos, __n_move);
2881 }
2882 traits_type::move(__p + __pos, __s, __n);
2883 __sz += __n;
2884 __set_size(s: __sz);
2885 traits_type::assign(__p[__sz], value_type());
2886 }
2887 }
2888 else
2889 __grow_by_and_replace(old_cap: __cap, delta_cap: __sz + __n - __cap, old_sz: __sz, n_copy: __pos, n_del: 0, n_add: __n, p_new_stuff: __s);
2890 return *this;
2891}
2892
2893template <class _CharT, class _Traits, class _Allocator>
2894_LIBCPP_CONSTEXPR_AFTER_CXX17
2895basic_string<_CharT, _Traits, _Allocator>&
2896basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n, value_type __c)
2897{
2898 size_type __sz = size();
2899 if (__pos > __sz)
2900 __throw_out_of_range();
2901 if (__n)
2902 {
2903 size_type __cap = capacity();
2904 value_type* __p;
2905 if (__cap - __sz >= __n)
2906 {
2907 __p = std::__to_address(__get_pointer());
2908 size_type __n_move = __sz - __pos;
2909 if (__n_move != 0)
2910 traits_type::move(__p + __pos + __n, __p + __pos, __n_move);
2911 }
2912 else
2913 {
2914 __grow_by(old_cap: __cap, delta_cap: __sz + __n - __cap, old_sz: __sz, n_copy: __pos, n_del: 0, n_add: __n);
2915 __p = std::__to_address(__get_long_pointer());
2916 }
2917 traits_type::assign(__p + __pos, __n, __c);
2918 __sz += __n;
2919 __set_size(s: __sz);
2920 traits_type::assign(__p[__sz], value_type());
2921 }
2922 return *this;
2923}
2924
2925template <class _CharT, class _Traits, class _Allocator>
2926template<class _InputIterator>
2927_LIBCPP_CONSTEXPR_AFTER_CXX17
2928__enable_if_t
2929<
2930 __is_exactly_cpp17_input_iterator<_InputIterator>::value,
2931 typename basic_string<_CharT, _Traits, _Allocator>::iterator
2932>
2933basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last)
2934{
2935 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
2936 "string::insert(iterator, range) called with an iterator not"
2937 " referring to this string");
2938 const basic_string __temp(__first, __last, __alloc());
2939 return insert(__pos, __temp.data(), __temp.data() + __temp.size());
2940}
2941
2942template <class _CharT, class _Traits, class _Allocator>
2943template<class _ForwardIterator>
2944_LIBCPP_CONSTEXPR_AFTER_CXX17
2945__enable_if_t
2946<
2947 __is_cpp17_forward_iterator<_ForwardIterator>::value,
2948 typename basic_string<_CharT, _Traits, _Allocator>::iterator
2949>
2950basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last)
2951{
2952 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
2953 "string::insert(iterator, range) called with an iterator not referring to this string");
2954
2955 size_type __ip = static_cast<size_type>(__pos - begin());
2956 size_type __n = static_cast<size_type>(std::distance(__first, __last));
2957 if (__n == 0)
2958 return begin() + __ip;
2959
2960 if (__string_is_trivial_iterator<_ForwardIterator>::value && !__addr_in_range(*__first))
2961 {
2962 return __insert_from_safe_copy(__n, __ip, __first, __last);
2963 }
2964 else
2965 {
2966 const basic_string __temp(__first, __last, __alloc());
2967 return __insert_from_safe_copy(__n, __ip, __temp.begin(), __temp.end());
2968 }
2969}
2970
2971template <class _CharT, class _Traits, class _Allocator>
2972inline _LIBCPP_CONSTEXPR_AFTER_CXX17
2973basic_string<_CharT, _Traits, _Allocator>&
2974basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str)
2975{
2976 return insert(__pos1, __str.data(), __str.size());
2977}
2978
2979template <class _CharT, class _Traits, class _Allocator>
2980_LIBCPP_CONSTEXPR_AFTER_CXX17
2981basic_string<_CharT, _Traits, _Allocator>&
2982basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str,
2983 size_type __pos2, size_type __n)
2984{
2985 size_type __str_sz = __str.size();
2986 if (__pos2 > __str_sz)
2987 __throw_out_of_range();
2988 return insert(__pos1, __str.data() + __pos2, std::min(__n, __str_sz - __pos2));
2989}
2990
2991template <class _CharT, class _Traits, class _Allocator>
2992template <class _Tp>
2993_LIBCPP_CONSTEXPR_AFTER_CXX17
2994__enable_if_t
2995<
2996 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
2997 basic_string<_CharT, _Traits, _Allocator>&
2998>
2999basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& __t,
3000 size_type __pos2, size_type __n)
3001{
3002 __self_view __sv = __t;
3003 size_type __str_sz = __sv.size();
3004 if (__pos2 > __str_sz)
3005 __throw_out_of_range();
3006 return insert(__pos1, __sv.data() + __pos2, std::min(__n, __str_sz - __pos2));
3007}
3008
3009template <class _CharT, class _Traits, class _Allocator>
3010_LIBCPP_CONSTEXPR_AFTER_CXX17
3011basic_string<_CharT, _Traits, _Allocator>&
3012basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s)
3013{
3014 _LIBCPP_ASSERT(__s != nullptr, "string::insert received nullptr");
3015 return insert(__pos, __s, traits_type::length(__s));
3016}
3017
3018template <class _CharT, class _Traits, class _Allocator>
3019_LIBCPP_CONSTEXPR_AFTER_CXX17
3020typename basic_string<_CharT, _Traits, _Allocator>::iterator
3021basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c)
3022{
3023 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
3024 "string::insert(iterator, character) called with an iterator not"
3025 " referring to this string");
3026
3027 size_type __ip = static_cast<size_type>(__pos - begin());
3028 size_type __sz = size();
3029 size_type __cap = capacity();
3030 value_type* __p;
3031 if (__cap == __sz)
3032 {
3033 __grow_by(old_cap: __cap, delta_cap: 1, old_sz: __sz, n_copy: __ip, n_del: 0, n_add: 1);
3034 __p = std::__to_address(__get_long_pointer());
3035 }
3036 else
3037 {
3038 __p = std::__to_address(__get_pointer());
3039 size_type __n_move = __sz - __ip;
3040 if (__n_move != 0)
3041 traits_type::move(__p + __ip + 1, __p + __ip, __n_move);
3042 }
3043 traits_type::assign(__p[__ip], __c);
3044 traits_type::assign(__p[++__sz], value_type());
3045 __set_size(s: __sz);
3046 return begin() + static_cast<difference_type>(__ip);
3047}
3048
3049template <class _CharT, class _Traits, class _Allocator>
3050inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3051typename basic_string<_CharT, _Traits, _Allocator>::iterator
3052basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, size_type __n, value_type __c)
3053{
3054 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
3055 "string::insert(iterator, n, value) called with an iterator not"
3056 " referring to this string");
3057 difference_type __p = __pos - begin();
3058 insert(static_cast<size_type>(__p), __n, __c);
3059 return begin() + __p;
3060}
3061
3062// replace
3063
3064template <class _CharT, class _Traits, class _Allocator>
3065_LIBCPP_CONSTEXPR_AFTER_CXX17
3066basic_string<_CharT, _Traits, _Allocator>&
3067basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2)
3068 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
3069{
3070 _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::replace received nullptr");
3071 size_type __sz = size();
3072 if (__pos > __sz)
3073 __throw_out_of_range();
3074 __n1 = std::min(__n1, __sz - __pos);
3075 size_type __cap = capacity();
3076 if (__cap - __sz + __n1 >= __n2)
3077 {
3078 if (__libcpp_is_constant_evaluated()) {
3079 __grow_by_and_replace(old_cap: __cap, delta_cap: 0, old_sz: __sz, n_copy: __pos, n_del: __n1, n_add: __n2, p_new_stuff: __s);
3080 return *this;
3081 }
3082 value_type* __p = std::__to_address(__get_pointer());
3083 if (__n1 != __n2)
3084 {
3085 size_type __n_move = __sz - __pos - __n1;
3086 if (__n_move != 0)
3087 {
3088 if (__n1 > __n2)
3089 {
3090 traits_type::move(__p + __pos, __s, __n2);
3091 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
3092 return __null_terminate_at(__p, newsz: __sz + (__n2 - __n1));
3093 }
3094 if (__p + __pos < __s && __s < __p + __sz)
3095 {
3096 if (__p + __pos + __n1 <= __s)
3097 __s += __n2 - __n1;
3098 else // __p + __pos < __s < __p + __pos + __n1
3099 {
3100 traits_type::move(__p + __pos, __s, __n1);
3101 __pos += __n1;
3102 __s += __n2;
3103 __n2 -= __n1;
3104 __n1 = 0;
3105 }
3106 }
3107 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
3108 }
3109 }
3110 traits_type::move(__p + __pos, __s, __n2);
3111 return __null_terminate_at(__p, newsz: __sz + (__n2 - __n1));
3112 }
3113 else
3114 __grow_by_and_replace(old_cap: __cap, delta_cap: __sz - __n1 + __n2 - __cap, old_sz: __sz, n_copy: __pos, n_del: __n1, n_add: __n2, p_new_stuff: __s);
3115 return *this;
3116}
3117
3118template <class _CharT, class _Traits, class _Allocator>
3119_LIBCPP_CONSTEXPR_AFTER_CXX17
3120basic_string<_CharT, _Traits, _Allocator>&
3121basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, size_type __n2, value_type __c)
3122{
3123 size_type __sz = size();
3124 if (__pos > __sz)
3125 __throw_out_of_range();
3126 __n1 = std::min(__n1, __sz - __pos);
3127 size_type __cap = capacity();
3128 value_type* __p;
3129 if (__cap - __sz + __n1 >= __n2)
3130 {
3131 __p = std::__to_address(__get_pointer());
3132 if (__n1 != __n2)
3133 {
3134 size_type __n_move = __sz - __pos - __n1;
3135 if (__n_move != 0)
3136 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
3137 }
3138 }
3139 else
3140 {
3141 __grow_by(old_cap: __cap, delta_cap: __sz - __n1 + __n2 - __cap, old_sz: __sz, n_copy: __pos, n_del: __n1, n_add: __n2);
3142 __p = std::__to_address(__get_long_pointer());
3143 }
3144 traits_type::assign(__p + __pos, __n2, __c);
3145 return __null_terminate_at(__p, newsz: __sz - (__n1 - __n2));
3146}
3147
3148template <class _CharT, class _Traits, class _Allocator>
3149template<class _InputIterator>
3150_LIBCPP_CONSTEXPR_AFTER_CXX17
3151__enable_if_t
3152<
3153 __is_cpp17_input_iterator<_InputIterator>::value,
3154 basic_string<_CharT, _Traits, _Allocator>&
3155>
3156basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2,
3157 _InputIterator __j1, _InputIterator __j2)
3158{
3159 const basic_string __temp(__j1, __j2, __alloc());
3160 return replace(__i1, __i2, __temp);
3161}
3162
3163template <class _CharT, class _Traits, class _Allocator>
3164inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3165basic_string<_CharT, _Traits, _Allocator>&
3166basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str)
3167{
3168 return replace(__pos1, __n1, __str.data(), __str.size());
3169}
3170
3171template <class _CharT, class _Traits, class _Allocator>
3172_LIBCPP_CONSTEXPR_AFTER_CXX17
3173basic_string<_CharT, _Traits, _Allocator>&
3174basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str,
3175 size_type __pos2, size_type __n2)
3176{
3177 size_type __str_sz = __str.size();
3178 if (__pos2 > __str_sz)
3179 __throw_out_of_range();
3180 return replace(__pos1, __n1, __str.data() + __pos2, std::min(__n2, __str_sz - __pos2));
3181}
3182
3183template <class _CharT, class _Traits, class _Allocator>
3184template <class _Tp>
3185_LIBCPP_CONSTEXPR_AFTER_CXX17
3186__enable_if_t
3187<
3188 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
3189 basic_string<_CharT, _Traits, _Allocator>&
3190>
3191basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const _Tp& __t,
3192 size_type __pos2, size_type __n2)
3193{
3194 __self_view __sv = __t;
3195 size_type __str_sz = __sv.size();
3196 if (__pos2 > __str_sz)
3197 __throw_out_of_range();
3198 return replace(__pos1, __n1, __sv.data() + __pos2, std::min(__n2, __str_sz - __pos2));
3199}
3200
3201template <class _CharT, class _Traits, class _Allocator>
3202_LIBCPP_CONSTEXPR_AFTER_CXX17
3203basic_string<_CharT, _Traits, _Allocator>&
3204basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s)
3205{
3206 _LIBCPP_ASSERT(__s != nullptr, "string::replace received nullptr");
3207 return replace(__pos, __n1, __s, traits_type::length(__s));
3208}
3209
3210template <class _CharT, class _Traits, class _Allocator>
3211inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3212basic_string<_CharT, _Traits, _Allocator>&
3213basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const basic_string& __str)
3214{
3215 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1),
3216 __str.data(), __str.size());
3217}
3218
3219template <class _CharT, class _Traits, class _Allocator>
3220inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3221basic_string<_CharT, _Traits, _Allocator>&
3222basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n)
3223{
3224 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s, __n);
3225}
3226
3227template <class _CharT, class _Traits, class _Allocator>
3228inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3229basic_string<_CharT, _Traits, _Allocator>&
3230basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s)
3231{
3232 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s);
3233}
3234
3235template <class _CharT, class _Traits, class _Allocator>
3236inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3237basic_string<_CharT, _Traits, _Allocator>&
3238basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c)
3239{
3240 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __n, __c);
3241}
3242
3243// erase
3244
3245// 'externally instantiated' erase() implementation, called when __n != npos.
3246// Does not check __pos against size()
3247template <class _CharT, class _Traits, class _Allocator>
3248_LIBCPP_CONSTEXPR_AFTER_CXX17
3249void
3250basic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move(
3251 size_type __pos, size_type __n)
3252{
3253 if (__n)
3254 {
3255 size_type __sz = size();
3256 value_type* __p = std::__to_address(__get_pointer());
3257 __n = std::min(__n, __sz - __pos);
3258 size_type __n_move = __sz - __pos - __n;
3259 if (__n_move != 0)
3260 traits_type::move(__p + __pos, __p + __pos + __n, __n_move);
3261 __null_terminate_at(__p, newsz: __sz - __n);
3262 }
3263}
3264
3265template <class _CharT, class _Traits, class _Allocator>
3266_LIBCPP_CONSTEXPR_AFTER_CXX17
3267basic_string<_CharT, _Traits, _Allocator>&
3268basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos,
3269 size_type __n) {
3270 if (__pos > size())
3271 __throw_out_of_range();
3272 if (__n == npos) {
3273 __erase_to_end(__pos);
3274 } else {
3275 __erase_external_with_move(__pos, __n);
3276 }
3277 return *this;
3278}
3279
3280template <class _CharT, class _Traits, class _Allocator>
3281inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3282typename basic_string<_CharT, _Traits, _Allocator>::iterator
3283basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos)
3284{
3285 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
3286 "string::erase(iterator) called with an iterator not"
3287 " referring to this string");
3288
3289 _LIBCPP_ASSERT(__pos != end(), "string::erase(iterator) called with a non-dereferenceable iterator");
3290 iterator __b = begin();
3291 size_type __r = static_cast<size_type>(__pos - __b);
3292 erase(__r, 1);
3293 return __b + static_cast<difference_type>(__r);
3294}
3295
3296template <class _CharT, class _Traits, class _Allocator>
3297inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3298typename basic_string<_CharT, _Traits, _Allocator>::iterator
3299basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last)
3300{
3301 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this,
3302 "string::erase(iterator, iterator) called with an iterator not"
3303 " referring to this string");
3304
3305 _LIBCPP_ASSERT(__first <= __last, "string::erase(first, last) called with invalid range");
3306 iterator __b = begin();
3307 size_type __r = static_cast<size_type>(__first - __b);
3308 erase(__r, static_cast<size_type>(__last - __first));
3309 return __b + static_cast<difference_type>(__r);
3310}
3311
3312template <class _CharT, class _Traits, class _Allocator>
3313inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3314void
3315basic_string<_CharT, _Traits, _Allocator>::pop_back()
3316{
3317 _LIBCPP_ASSERT(!empty(), "string::pop_back(): string is already empty");
3318 __erase_to_end(pos: size() - 1);
3319}
3320
3321template <class _CharT, class _Traits, class _Allocator>
3322inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3323void
3324basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT
3325{
3326 std::__debug_db_invalidate_all(this);
3327 if (__is_long())
3328 {
3329 traits_type::assign(*__get_long_pointer(), value_type());
3330 __set_long_size(s: 0);
3331 }
3332 else
3333 {
3334 traits_type::assign(*__get_short_pointer(), value_type());
3335 __set_short_size(s: 0);
3336 }
3337}
3338
3339template <class _CharT, class _Traits, class _Allocator>
3340inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3341void
3342basic_string<_CharT, _Traits, _Allocator>::__erase_to_end(size_type __pos)
3343{
3344 __null_terminate_at(p: std::__to_address(__get_pointer()), newsz: __pos);
3345}
3346
3347template <class _CharT, class _Traits, class _Allocator>
3348_LIBCPP_CONSTEXPR_AFTER_CXX17
3349void
3350basic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c)
3351{
3352 size_type __sz = size();
3353 if (__n > __sz)
3354 append(__n - __sz, __c);
3355 else
3356 __erase_to_end(pos: __n);
3357}
3358
3359template <class _CharT, class _Traits, class _Allocator>
3360_LIBCPP_CONSTEXPR_AFTER_CXX17 inline void
3361basic_string<_CharT, _Traits, _Allocator>::__resize_default_init(size_type __n)
3362{
3363 size_type __sz = size();
3364 if (__n > __sz) {
3365 __append_default_init(n: __n - __sz);
3366 } else
3367 __erase_to_end(pos: __n);
3368}
3369
3370template <class _CharT, class _Traits, class _Allocator>
3371inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3372typename basic_string<_CharT, _Traits, _Allocator>::size_type
3373basic_string<_CharT, _Traits, _Allocator>::max_size() const _NOEXCEPT
3374{
3375 size_type __m = __alloc_traits::max_size(__alloc());
3376 if (__m <= std::numeric_limits<size_type>::max() / 2) {
3377 return __m - __alignment;
3378 } else {
3379 bool __uses_lsb = __endian_factor == 2;
3380 return __uses_lsb ? __m - __alignment : (__m / 2) - __alignment;
3381 }
3382}
3383
3384template <class _CharT, class _Traits, class _Allocator>
3385_LIBCPP_CONSTEXPR_AFTER_CXX17
3386void
3387basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacity)
3388{
3389 if (__requested_capacity > max_size())
3390 __throw_length_error();
3391
3392 // Make sure reserve(n) never shrinks. This is technically only required in C++20
3393 // and later (since P0966R1), however we provide consistent behavior in all Standard
3394 // modes because this function is instantiated in the shared library.
3395 if (__requested_capacity <= capacity())
3396 return;
3397
3398 size_type __target_capacity = std::max(__requested_capacity, size());
3399 __target_capacity = __recommend(s: __target_capacity);
3400 if (__target_capacity == capacity()) return;
3401
3402 __shrink_or_extend(__target_capacity);
3403}
3404
3405template <class _CharT, class _Traits, class _Allocator>
3406inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3407void
3408basic_string<_CharT, _Traits, _Allocator>::shrink_to_fit() _NOEXCEPT
3409{
3410 size_type __target_capacity = __recommend(s: size());
3411 if (__target_capacity == capacity()) return;
3412
3413 __shrink_or_extend(__target_capacity);
3414}
3415
3416template <class _CharT, class _Traits, class _Allocator>
3417inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3418void
3419basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target_capacity)
3420{
3421 size_type __cap = capacity();
3422 size_type __sz = size();
3423
3424 pointer __new_data, __p;
3425 bool __was_long, __now_long;
3426 if (__fits_in_sso(sz: __target_capacity))
3427 {
3428 __was_long = true;
3429 __now_long = false;
3430 __new_data = __get_short_pointer();
3431 __p = __get_long_pointer();
3432 }
3433 else
3434 {
3435 if (__target_capacity > __cap) {
3436 auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1);
3437 __new_data = __allocation.ptr;
3438 __target_capacity = __allocation.count - 1;
3439 }
3440 else
3441 {
3442 #ifndef _LIBCPP_NO_EXCEPTIONS
3443 try
3444 {
3445 #endif // _LIBCPP_NO_EXCEPTIONS
3446 auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1);
3447 __new_data = __allocation.ptr;
3448 __target_capacity = __allocation.count - 1;
3449 #ifndef _LIBCPP_NO_EXCEPTIONS
3450 }
3451 catch (...)
3452 {
3453 return;
3454 }
3455 #else // _LIBCPP_NO_EXCEPTIONS
3456 if (__new_data == nullptr)
3457 return;
3458 #endif // _LIBCPP_NO_EXCEPTIONS
3459 }
3460 __begin_lifetime(begin: __new_data, n: __target_capacity + 1);
3461 __now_long = true;
3462 __was_long = __is_long();
3463 __p = __get_pointer();
3464 }
3465 traits_type::copy(std::__to_address(__new_data),
3466 std::__to_address(__p), size()+1);
3467 if (__was_long)
3468 __alloc_traits::deallocate(__alloc(), __p, __cap+1);
3469 if (__now_long)
3470 {
3471 __set_long_cap(s: __target_capacity+1);
3472 __set_long_size(s: __sz);
3473 __set_long_pointer(p: __new_data);
3474 }
3475 else
3476 __set_short_size(s: __sz);
3477 std::__debug_db_invalidate_all(this);
3478}
3479
3480template <class _CharT, class _Traits, class _Allocator>
3481inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3482typename basic_string<_CharT, _Traits, _Allocator>::const_reference
3483basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const _NOEXCEPT
3484{
3485 _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
3486 return *(data() + __pos);
3487}
3488
3489template <class _CharT, class _Traits, class _Allocator>
3490inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3491typename basic_string<_CharT, _Traits, _Allocator>::reference
3492basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) _NOEXCEPT
3493{
3494 _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
3495 return *(__get_pointer() + __pos);
3496}
3497
3498template <class _CharT, class _Traits, class _Allocator>
3499_LIBCPP_CONSTEXPR_AFTER_CXX17
3500typename basic_string<_CharT, _Traits, _Allocator>::const_reference
3501basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const
3502{
3503 if (__n >= size())
3504 __throw_out_of_range();
3505 return (*this)[__n];
3506}
3507
3508template <class _CharT, class _Traits, class _Allocator>
3509_LIBCPP_CONSTEXPR_AFTER_CXX17
3510typename basic_string<_CharT, _Traits, _Allocator>::reference
3511basic_string<_CharT, _Traits, _Allocator>::at(size_type __n)
3512{
3513 if (__n >= size())
3514 __throw_out_of_range();
3515 return (*this)[__n];
3516}
3517
3518template <class _CharT, class _Traits, class _Allocator>
3519inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3520typename basic_string<_CharT, _Traits, _Allocator>::reference
3521basic_string<_CharT, _Traits, _Allocator>::front() _NOEXCEPT
3522{
3523 _LIBCPP_ASSERT(!empty(), "string::front(): string is empty");
3524 return *__get_pointer();
3525}
3526
3527template <class _CharT, class _Traits, class _Allocator>
3528inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3529typename basic_string<_CharT, _Traits, _Allocator>::const_reference
3530basic_string<_CharT, _Traits, _Allocator>::front() const _NOEXCEPT
3531{
3532 _LIBCPP_ASSERT(!empty(), "string::front(): string is empty");
3533 return *data();
3534}
3535
3536template <class _CharT, class _Traits, class _Allocator>
3537inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3538typename basic_string<_CharT, _Traits, _Allocator>::reference
3539basic_string<_CharT, _Traits, _Allocator>::back() _NOEXCEPT
3540{
3541 _LIBCPP_ASSERT(!empty(), "string::back(): string is empty");
3542 return *(__get_pointer() + size() - 1);
3543}
3544
3545template <class _CharT, class _Traits, class _Allocator>
3546inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3547typename basic_string<_CharT, _Traits, _Allocator>::const_reference
3548basic_string<_CharT, _Traits, _Allocator>::back() const _NOEXCEPT
3549{
3550 _LIBCPP_ASSERT(!empty(), "string::back(): string is empty");
3551 return *(data() + size() - 1);
3552}
3553
3554template <class _CharT, class _Traits, class _Allocator>
3555_LIBCPP_CONSTEXPR_AFTER_CXX17
3556typename basic_string<_CharT, _Traits, _Allocator>::size_type
3557basic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n, size_type __pos) const
3558{
3559 size_type __sz = size();
3560 if (__pos > __sz)
3561 __throw_out_of_range();
3562 size_type __rlen = std::min(__n, __sz - __pos);
3563 traits_type::copy(__s, data() + __pos, __rlen);
3564 return __rlen;
3565}
3566
3567template <class _CharT, class _Traits, class _Allocator>
3568inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3569basic_string<_CharT, _Traits, _Allocator>
3570basic_string<_CharT, _Traits, _Allocator>::substr(size_type __pos, size_type __n) const
3571{
3572 return basic_string(*this, __pos, __n, __alloc());
3573}
3574
3575template <class _CharT, class _Traits, class _Allocator>
3576inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3577void
3578basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str)
3579#if _LIBCPP_STD_VER >= 14
3580 _NOEXCEPT
3581#else
3582 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
3583 __is_nothrow_swappable<allocator_type>::value)
3584#endif
3585{
3586 if (!__is_long())
3587 std::__debug_db_invalidate_all(this);
3588 if (!__str.__is_long())
3589 std::__debug_db_invalidate_all(&__str);
3590 std::__debug_db_swap(this, &__str);
3591
3592 _LIBCPP_ASSERT(
3593 __alloc_traits::propagate_on_container_swap::value ||
3594 __alloc_traits::is_always_equal::value ||
3595 __alloc() == __str.__alloc(), "swapping non-equal allocators");
3596 std::swap(__r_.first(), __str.__r_.first());
3597 std::__swap_allocator(__alloc(), __str.__alloc());
3598}
3599
3600// find
3601
3602template <class _Traits>
3603struct _LIBCPP_HIDDEN __traits_eq
3604{
3605 typedef typename _Traits::char_type char_type;
3606 _LIBCPP_HIDE_FROM_ABI
3607 bool operator()(const char_type& __x, const char_type& __y) _NOEXCEPT
3608 {return _Traits::eq(__x, __y);}
3609};
3610
3611template<class _CharT, class _Traits, class _Allocator>
3612_LIBCPP_CONSTEXPR_AFTER_CXX17
3613typename basic_string<_CharT, _Traits, _Allocator>::size_type
3614basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
3615 size_type __pos,
3616 size_type __n) const _NOEXCEPT
3617{
3618 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find(): received nullptr");
3619 return __str_find<value_type, size_type, traits_type, npos>
3620 (data(), size(), __s, __pos, __n);
3621}
3622
3623template<class _CharT, class _Traits, class _Allocator>
3624inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3625typename basic_string<_CharT, _Traits, _Allocator>::size_type
3626basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str,
3627 size_type __pos) const _NOEXCEPT
3628{
3629 return __str_find<value_type, size_type, traits_type, npos>
3630 (data(), size(), __str.data(), __pos, __str.size());
3631}
3632
3633template<class _CharT, class _Traits, class _Allocator>
3634template <class _Tp>
3635_LIBCPP_CONSTEXPR_AFTER_CXX17
3636__enable_if_t
3637<
3638 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
3639 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3640>
3641basic_string<_CharT, _Traits, _Allocator>::find(const _Tp &__t,
3642 size_type __pos) const _NOEXCEPT
3643{
3644 __self_view __sv = __t;
3645 return __str_find<value_type, size_type, traits_type, npos>
3646 (data(), size(), __sv.data(), __pos, __sv.size());
3647}
3648
3649template<class _CharT, class _Traits, class _Allocator>
3650inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3651typename basic_string<_CharT, _Traits, _Allocator>::size_type
3652basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
3653 size_type __pos) const _NOEXCEPT
3654{
3655 _LIBCPP_ASSERT(__s != nullptr, "string::find(): received nullptr");
3656 return __str_find<value_type, size_type, traits_type, npos>
3657 (data(), size(), __s, __pos, traits_type::length(__s));
3658}
3659
3660template<class _CharT, class _Traits, class _Allocator>
3661_LIBCPP_CONSTEXPR_AFTER_CXX17
3662typename basic_string<_CharT, _Traits, _Allocator>::size_type
3663basic_string<_CharT, _Traits, _Allocator>::find(value_type __c,
3664 size_type __pos) const _NOEXCEPT
3665{
3666 return __str_find<value_type, size_type, traits_type, npos>
3667 (data(), size(), __c, __pos);
3668}
3669
3670// rfind
3671
3672template<class _CharT, class _Traits, class _Allocator>
3673_LIBCPP_CONSTEXPR_AFTER_CXX17
3674typename basic_string<_CharT, _Traits, _Allocator>::size_type
3675basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
3676 size_type __pos,
3677 size_type __n) const _NOEXCEPT
3678{
3679 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::rfind(): received nullptr");
3680 return __str_rfind<value_type, size_type, traits_type, npos>
3681 (data(), size(), __s, __pos, __n);
3682}
3683
3684template<class _CharT, class _Traits, class _Allocator>
3685inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3686typename basic_string<_CharT, _Traits, _Allocator>::size_type
3687basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str,
3688 size_type __pos) const _NOEXCEPT
3689{
3690 return __str_rfind<value_type, size_type, traits_type, npos>
3691 (data(), size(), __str.data(), __pos, __str.size());
3692}
3693
3694template<class _CharT, class _Traits, class _Allocator>
3695template <class _Tp>
3696_LIBCPP_CONSTEXPR_AFTER_CXX17
3697__enable_if_t
3698<
3699 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
3700 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3701>
3702basic_string<_CharT, _Traits, _Allocator>::rfind(const _Tp& __t,
3703 size_type __pos) const _NOEXCEPT
3704{
3705 __self_view __sv = __t;
3706 return __str_rfind<value_type, size_type, traits_type, npos>
3707 (data(), size(), __sv.data(), __pos, __sv.size());
3708}
3709
3710template<class _CharT, class _Traits, class _Allocator>
3711inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3712typename basic_string<_CharT, _Traits, _Allocator>::size_type
3713basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
3714 size_type __pos) const _NOEXCEPT
3715{
3716 _LIBCPP_ASSERT(__s != nullptr, "string::rfind(): received nullptr");
3717 return __str_rfind<value_type, size_type, traits_type, npos>
3718 (data(), size(), __s, __pos, traits_type::length(__s));
3719}
3720
3721template<class _CharT, class _Traits, class _Allocator>
3722_LIBCPP_CONSTEXPR_AFTER_CXX17
3723typename basic_string<_CharT, _Traits, _Allocator>::size_type
3724basic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c,
3725 size_type __pos) const _NOEXCEPT
3726{
3727 return __str_rfind<value_type, size_type, traits_type, npos>
3728 (data(), size(), __c, __pos);
3729}
3730
3731// find_first_of
3732
3733template<class _CharT, class _Traits, class _Allocator>
3734_LIBCPP_CONSTEXPR_AFTER_CXX17
3735typename basic_string<_CharT, _Traits, _Allocator>::size_type
3736basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
3737 size_type __pos,
3738 size_type __n) const _NOEXCEPT
3739{
3740 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr");
3741 return __str_find_first_of<value_type, size_type, traits_type, npos>
3742 (data(), size(), __s, __pos, __n);
3743}
3744
3745template<class _CharT, class _Traits, class _Allocator>
3746inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3747typename basic_string<_CharT, _Traits, _Allocator>::size_type
3748basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str,
3749 size_type __pos) const _NOEXCEPT
3750{
3751 return __str_find_first_of<value_type, size_type, traits_type, npos>
3752 (data(), size(), __str.data(), __pos, __str.size());
3753}
3754
3755template<class _CharT, class _Traits, class _Allocator>
3756template <class _Tp>
3757_LIBCPP_CONSTEXPR_AFTER_CXX17
3758__enable_if_t
3759<
3760 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
3761 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3762>
3763basic_string<_CharT, _Traits, _Allocator>::find_first_of(const _Tp& __t,
3764 size_type __pos) const _NOEXCEPT
3765{
3766 __self_view __sv = __t;
3767 return __str_find_first_of<value_type, size_type, traits_type, npos>
3768 (data(), size(), __sv.data(), __pos, __sv.size());
3769}
3770
3771template<class _CharT, class _Traits, class _Allocator>
3772inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3773typename basic_string<_CharT, _Traits, _Allocator>::size_type
3774basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
3775 size_type __pos) const _NOEXCEPT
3776{
3777 _LIBCPP_ASSERT(__s != nullptr, "string::find_first_of(): received nullptr");
3778 return __str_find_first_of<value_type, size_type, traits_type, npos>
3779 (data(), size(), __s, __pos, traits_type::length(__s));
3780}
3781
3782template<class _CharT, class _Traits, class _Allocator>
3783inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3784typename basic_string<_CharT, _Traits, _Allocator>::size_type
3785basic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c,
3786 size_type __pos) const _NOEXCEPT
3787{
3788 return find(__c, __pos);
3789}
3790
3791// find_last_of
3792
3793template<class _CharT, class _Traits, class _Allocator>
3794inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3795typename basic_string<_CharT, _Traits, _Allocator>::size_type
3796basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
3797 size_type __pos,
3798 size_type __n) const _NOEXCEPT
3799{
3800 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr");
3801 return __str_find_last_of<value_type, size_type, traits_type, npos>
3802 (data(), size(), __s, __pos, __n);
3803}
3804
3805template<class _CharT, class _Traits, class _Allocator>
3806inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3807typename basic_string<_CharT, _Traits, _Allocator>::size_type
3808basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str,
3809 size_type __pos) const _NOEXCEPT
3810{
3811 return __str_find_last_of<value_type, size_type, traits_type, npos>
3812 (data(), size(), __str.data(), __pos, __str.size());
3813}
3814
3815template<class _CharT, class _Traits, class _Allocator>
3816template <class _Tp>
3817_LIBCPP_CONSTEXPR_AFTER_CXX17
3818__enable_if_t
3819<
3820 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
3821 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3822>
3823basic_string<_CharT, _Traits, _Allocator>::find_last_of(const _Tp& __t,
3824 size_type __pos) const _NOEXCEPT
3825{
3826 __self_view __sv = __t;
3827 return __str_find_last_of<value_type, size_type, traits_type, npos>
3828 (data(), size(), __sv.data(), __pos, __sv.size());
3829}
3830
3831template<class _CharT, class _Traits, class _Allocator>
3832inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3833typename basic_string<_CharT, _Traits, _Allocator>::size_type
3834basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
3835 size_type __pos) const _NOEXCEPT
3836{
3837 _LIBCPP_ASSERT(__s != nullptr, "string::find_last_of(): received nullptr");
3838 return __str_find_last_of<value_type, size_type, traits_type, npos>
3839 (data(), size(), __s, __pos, traits_type::length(__s));
3840}
3841
3842template<class _CharT, class _Traits, class _Allocator>
3843inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3844typename basic_string<_CharT, _Traits, _Allocator>::size_type
3845basic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c,
3846 size_type __pos) const _NOEXCEPT
3847{
3848 return rfind(__c, __pos);
3849}
3850
3851// find_first_not_of
3852
3853template<class _CharT, class _Traits, class _Allocator>
3854_LIBCPP_CONSTEXPR_AFTER_CXX17
3855typename basic_string<_CharT, _Traits, _Allocator>::size_type
3856basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s,
3857 size_type __pos,
3858 size_type __n) const _NOEXCEPT
3859{
3860 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr");
3861 return __str_find_first_not_of<value_type, size_type, traits_type, npos>
3862 (data(), size(), __s, __pos, __n);
3863}
3864
3865template<class _CharT, class _Traits, class _Allocator>
3866inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3867typename basic_string<_CharT, _Traits, _Allocator>::size_type
3868basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string& __str,
3869 size_type __pos) const _NOEXCEPT
3870{
3871 return __str_find_first_not_of<value_type, size_type, traits_type, npos>
3872 (data(), size(), __str.data(), __pos, __str.size());
3873}
3874
3875template<class _CharT, class _Traits, class _Allocator>
3876template <class _Tp>
3877_LIBCPP_CONSTEXPR_AFTER_CXX17
3878__enable_if_t
3879<
3880 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
3881 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3882>
3883basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const _Tp& __t,
3884 size_type __pos) const _NOEXCEPT
3885{
3886 __self_view __sv = __t;
3887 return __str_find_first_not_of<value_type, size_type, traits_type, npos>
3888 (data(), size(), __sv.data(), __pos, __sv.size());
3889}
3890
3891template<class _CharT, class _Traits, class _Allocator>
3892inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3893typename basic_string<_CharT, _Traits, _Allocator>::size_type
3894basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s,
3895 size_type __pos) const _NOEXCEPT
3896{
3897 _LIBCPP_ASSERT(__s != nullptr, "string::find_first_not_of(): received nullptr");
3898 return __str_find_first_not_of<value_type, size_type, traits_type, npos>
3899 (data(), size(), __s, __pos, traits_type::length(__s));
3900}
3901
3902template<class _CharT, class _Traits, class _Allocator>
3903inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3904typename basic_string<_CharT, _Traits, _Allocator>::size_type
3905basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c,
3906 size_type __pos) const _NOEXCEPT
3907{
3908 return __str_find_first_not_of<value_type, size_type, traits_type, npos>
3909 (data(), size(), __c, __pos);
3910}
3911
3912// find_last_not_of
3913
3914template<class _CharT, class _Traits, class _Allocator>
3915_LIBCPP_CONSTEXPR_AFTER_CXX17
3916typename basic_string<_CharT, _Traits, _Allocator>::size_type
3917basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s,
3918 size_type __pos,
3919 size_type __n) const _NOEXCEPT
3920{
3921 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr");
3922 return __str_find_last_not_of<value_type, size_type, traits_type, npos>
3923 (data(), size(), __s, __pos, __n);
3924}
3925
3926template<class _CharT, class _Traits, class _Allocator>
3927inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3928typename basic_string<_CharT, _Traits, _Allocator>::size_type
3929basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string& __str,
3930 size_type __pos) const _NOEXCEPT
3931{
3932 return __str_find_last_not_of<value_type, size_type, traits_type, npos>
3933 (data(), size(), __str.data(), __pos, __str.size());
3934}
3935
3936template<class _CharT, class _Traits, class _Allocator>
3937template <class _Tp>
3938_LIBCPP_CONSTEXPR_AFTER_CXX17
3939__enable_if_t
3940<
3941 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
3942 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3943>
3944basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const _Tp& __t,
3945 size_type __pos) const _NOEXCEPT
3946{
3947 __self_view __sv = __t;
3948 return __str_find_last_not_of<value_type, size_type, traits_type, npos>
3949 (data(), size(), __sv.data(), __pos, __sv.size());
3950}
3951
3952template<class _CharT, class _Traits, class _Allocator>
3953inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3954typename basic_string<_CharT, _Traits, _Allocator>::size_type
3955basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s,
3956 size_type __pos) const _NOEXCEPT
3957{
3958 _LIBCPP_ASSERT(__s != nullptr, "string::find_last_not_of(): received nullptr");
3959 return __str_find_last_not_of<value_type, size_type, traits_type, npos>
3960 (data(), size(), __s, __pos, traits_type::length(__s));
3961}
3962
3963template<class _CharT, class _Traits, class _Allocator>
3964inline _LIBCPP_CONSTEXPR_AFTER_CXX17
3965typename basic_string<_CharT, _Traits, _Allocator>::size_type
3966basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c,
3967 size_type __pos) const _NOEXCEPT
3968{
3969 return __str_find_last_not_of<value_type, size_type, traits_type, npos>
3970 (data(), size(), __c, __pos);
3971}
3972
3973// compare
3974
3975template <class _CharT, class _Traits, class _Allocator>
3976template <class _Tp>
3977_LIBCPP_CONSTEXPR_AFTER_CXX17
3978__enable_if_t
3979<
3980 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
3981 int
3982>
3983basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const _NOEXCEPT
3984{
3985 __self_view __sv = __t;
3986 size_t __lhs_sz = size();
3987 size_t __rhs_sz = __sv.size();
3988 int __result = traits_type::compare(data(), __sv.data(),
3989 std::min(a: __lhs_sz, b: __rhs_sz));
3990 if (__result != 0)
3991 return __result;
3992 if (__lhs_sz < __rhs_sz)
3993 return -1;
3994 if (__lhs_sz > __rhs_sz)
3995 return 1;
3996 return 0;
3997}
3998
3999template <class _CharT, class _Traits, class _Allocator>
4000inline _LIBCPP_CONSTEXPR_AFTER_CXX17
4001int
4002basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT
4003{
4004 return compare(__self_view(__str));
4005}
4006
4007template <class _CharT, class _Traits, class _Allocator>
4008inline _LIBCPP_CONSTEXPR_AFTER_CXX17
4009int
4010basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
4011 size_type __n1,
4012 const value_type* __s,
4013 size_type __n2) const
4014{
4015 _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr");
4016 size_type __sz = size();
4017 if (__pos1 > __sz || __n2 == npos)
4018 __throw_out_of_range();
4019 size_type __rlen = std::min(__n1, __sz - __pos1);
4020 int __r = traits_type::compare(data() + __pos1, __s, std::min(__rlen, __n2));
4021 if (__r == 0)
4022 {
4023 if (__rlen < __n2)
4024 __r = -1;
4025 else if (__rlen > __n2)
4026 __r = 1;
4027 }
4028 return __r;
4029}
4030
4031template <class _CharT, class _Traits, class _Allocator>
4032template <class _Tp>
4033_LIBCPP_CONSTEXPR_AFTER_CXX17
4034__enable_if_t
4035<
4036 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
4037 int
4038>
4039basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
4040 size_type __n1,
4041 const _Tp& __t) const
4042{
4043 __self_view __sv = __t;
4044 return compare(__pos1, __n1, __sv.data(), __sv.size());
4045}
4046
4047template <class _CharT, class _Traits, class _Allocator>
4048inline _LIBCPP_CONSTEXPR_AFTER_CXX17
4049int
4050basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
4051 size_type __n1,
4052 const basic_string& __str) const
4053{
4054 return compare(__pos1, __n1, __str.data(), __str.size());
4055}
4056
4057template <class _CharT, class _Traits, class _Allocator>
4058template <class _Tp>
4059_LIBCPP_CONSTEXPR_AFTER_CXX17
4060__enable_if_t
4061<
4062 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
4063 && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
4064 int
4065>
4066basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
4067 size_type __n1,
4068 const _Tp& __t,
4069 size_type __pos2,
4070 size_type __n2) const
4071{
4072 __self_view __sv = __t;
4073 return __self_view(*this).substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
4074}
4075
4076template <class _CharT, class _Traits, class _Allocator>
4077_LIBCPP_CONSTEXPR_AFTER_CXX17
4078int
4079basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
4080 size_type __n1,
4081 const basic_string& __str,
4082 size_type __pos2,
4083 size_type __n2) const
4084{
4085 return compare(__pos1, __n1, __self_view(__str), __pos2, __n2);
4086}
4087
4088template <class _CharT, class _Traits, class _Allocator>
4089_LIBCPP_CONSTEXPR_AFTER_CXX17
4090int
4091basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT
4092{
4093 _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr");
4094 return compare(0, npos, __s, traits_type::length(__s));
4095}
4096
4097template <class _CharT, class _Traits, class _Allocator>
4098_LIBCPP_CONSTEXPR_AFTER_CXX17
4099int
4100basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
4101 size_type __n1,
4102 const value_type* __s) const
4103{
4104 _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr");
4105 return compare(__pos1, __n1, __s, traits_type::length(__s));
4106}
4107
4108// __invariants
4109
4110template<class _CharT, class _Traits, class _Allocator>
4111inline _LIBCPP_CONSTEXPR_AFTER_CXX17
4112bool
4113basic_string<_CharT, _Traits, _Allocator>::__invariants() const
4114{
4115 if (size() > capacity())
4116 return false;
4117 if (capacity() < __min_cap - 1)
4118 return false;
4119 if (data() == nullptr)
4120 return false;
4121 if (data()[size()] != value_type())
4122 return false;
4123 return true;
4124}
4125
4126// __clear_and_shrink
4127
4128template<class _CharT, class _Traits, class _Allocator>
4129inline _LIBCPP_CONSTEXPR_AFTER_CXX17
4130void
4131basic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT
4132{
4133 clear();
4134 if(__is_long())
4135 {
4136 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), capacity() + 1);
4137 __set_long_cap(s: 0);
4138 __set_short_size(s: 0);
4139 traits_type::assign(*__get_short_pointer(), value_type());
4140 }
4141}
4142
4143// operator==
4144
4145template<class _CharT, class _Traits, class _Allocator>
4146inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
4147bool
4148operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
4149 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
4150{
4151 size_t __lhs_sz = __lhs.size();
4152 return __lhs_sz == __rhs.size() && _Traits::compare(__lhs.data(),
4153 __rhs.data(),
4154 __lhs_sz) == 0;
4155}
4156
4157template<class _Allocator>
4158inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
4159bool
4160operator==(const basic_string<char, char_traits<char>, _Allocator>& __lhs,
4161 const basic_string<char, char_traits<char>, _Allocator>& __rhs) _NOEXCEPT
4162{
4163 size_t __lhs_sz = __lhs.size();
4164 if (__lhs_sz != __rhs.size())
4165 return false;
4166 const char* __lp = __lhs.data();
4167 const char* __rp = __rhs.data();
4168 if (__lhs.__is_long())
4169 return char_traits<char>::compare(s1: __lp, s2: __rp, n: __lhs_sz) == 0;
4170 for (; __lhs_sz != 0; --__lhs_sz, ++__lp, ++__rp)
4171 if (*__lp != *__rp)
4172 return false;
4173 return true;
4174}
4175
4176template<class _CharT, class _Traits, class _Allocator>
4177inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
4178bool
4179operator==(const _CharT* __lhs,
4180 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
4181{
4182 typedef basic_string<_CharT, _Traits, _Allocator> _String;
4183 _LIBCPP_ASSERT(__lhs != nullptr, "operator==(char*, basic_string): received nullptr");
4184 size_t __lhs_len = _Traits::length(__lhs);
4185 if (__lhs_len != __rhs.size()) return false;
4186 return __rhs.compare(0, _String::npos, __lhs, __lhs_len) == 0;
4187}
4188
4189template<class _CharT, class _Traits, class _Allocator>
4190inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
4191bool
4192operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
4193 const _CharT* __rhs) _NOEXCEPT
4194{
4195 typedef basic_string<_CharT, _Traits, _Allocator> _String;
4196 _LIBCPP_ASSERT(__rhs != nullptr, "operator==(basic_string, char*): received nullptr");
4197 size_t __rhs_len = _Traits::length(__rhs);
4198 if (__rhs_len != __lhs.size()) return false;
4199 return __lhs.compare(0, _String::npos, __rhs, __rhs_len) == 0;
4200}
4201
4202template<class _CharT, class _Traits, class _Allocator>
4203inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
4204bool
4205operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
4206 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
4207{
4208 return !(__lhs == __rhs);
4209}
4210
4211template<class _CharT, class _Traits, class _Allocator>
4212inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
4213bool
4214operator!=(const _CharT* __lhs,
4215 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
4216{
4217 return !(__lhs == __rhs);
4218}
4219
4220template<class _CharT, class _Traits, class _Allocator>
4221inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
4222bool
4223operator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
4224 const _CharT* __rhs) _NOEXCEPT
4225{
4226 return !(__lhs == __rhs);
4227}
4228
4229// operator<
4230
4231template<class _CharT, class _Traits, class _Allocator>
4232inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
4233bool
4234operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
4235 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
4236{
4237 return __lhs.compare(__rhs) < 0;
4238}
4239
4240template<class _CharT, class _Traits, class _Allocator>
4241inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
4242bool
4243operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
4244 const _CharT* __rhs) _NOEXCEPT
4245{
4246 return __lhs.compare(__rhs) < 0;
4247}
4248
4249template<class _CharT, class _Traits, class _Allocator>
4250inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
4251bool
4252operator< (const _CharT* __lhs,
4253 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
4254{
4255 return __rhs.compare(__lhs) > 0;
4256}
4257
4258// operator>
4259
4260template<class _CharT, class _Traits, class _Allocator>
4261inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
4262bool
4263operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
4264 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
4265{
4266 return __rhs < __lhs;
4267}
4268
4269template<class _CharT, class _Traits, class _Allocator>
4270inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
4271bool
4272operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
4273 const _CharT* __rhs) _NOEXCEPT
4274{
4275 return __rhs < __lhs;
4276}
4277
4278template<class _CharT, class _Traits, class _Allocator>
4279inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
4280bool
4281operator> (const _CharT* __lhs,
4282 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
4283{
4284 return __rhs < __lhs;
4285}
4286
4287// operator<=
4288
4289template<class _CharT, class _Traits, class _Allocator>
4290inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
4291bool
4292operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
4293 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
4294{
4295 return !(__rhs < __lhs);
4296}
4297
4298template<class _CharT, class _Traits, class _Allocator>
4299inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
4300bool
4301operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
4302 const _CharT* __rhs) _NOEXCEPT
4303{
4304 return !(__rhs < __lhs);
4305}
4306
4307template<class _CharT, class _Traits, class _Allocator>
4308inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
4309bool
4310operator<=(const _CharT* __lhs,
4311 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
4312{
4313 return !(__rhs < __lhs);
4314}
4315
4316// operator>=
4317
4318template<class _CharT, class _Traits, class _Allocator>
4319inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
4320bool
4321operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
4322 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
4323{
4324 return !(__lhs < __rhs);
4325}
4326
4327template<class _CharT, class _Traits, class _Allocator>
4328inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
4329bool
4330operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
4331 const _CharT* __rhs) _NOEXCEPT
4332{
4333 return !(__lhs < __rhs);
4334}
4335
4336template<class _CharT, class _Traits, class _Allocator>
4337inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
4338bool
4339operator>=(const _CharT* __lhs,
4340 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
4341{
4342 return !(__lhs < __rhs);
4343}
4344
4345// operator +
4346
4347template<class _CharT, class _Traits, class _Allocator>
4348_LIBCPP_CONSTEXPR_AFTER_CXX17
4349basic_string<_CharT, _Traits, _Allocator>
4350operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
4351 const basic_string<_CharT, _Traits, _Allocator>& __rhs)
4352{
4353 using _String = basic_string<_CharT, _Traits, _Allocator>;
4354 auto __lhs_sz = __lhs.size();
4355 auto __rhs_sz = __rhs.size();
4356 _String __r(__uninitialized_size_tag(),
4357 __lhs_sz + __rhs_sz,
4358 _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator()));
4359 auto __ptr = std::__to_address(__r.__get_pointer());
4360 _Traits::copy(__ptr, __lhs.data(), __lhs_sz);
4361 _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz);
4362 _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());
4363 return __r;
4364}
4365
4366template<class _CharT, class _Traits, class _Allocator>
4367_LIBCPP_CONSTEXPR_AFTER_CXX17
4368basic_string<_CharT, _Traits, _Allocator>
4369operator+(const _CharT* __lhs , const basic_string<_CharT,_Traits,_Allocator>& __rhs)
4370{
4371 using _String = basic_string<_CharT, _Traits, _Allocator>;
4372 auto __lhs_sz = _Traits::length(__lhs);
4373 auto __rhs_sz = __rhs.size();
4374 _String __r(__uninitialized_size_tag(),
4375 __lhs_sz + __rhs_sz,
4376 _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator()));
4377 auto __ptr = std::__to_address(__r.__get_pointer());
4378 _Traits::copy(__ptr, __lhs, __lhs_sz);
4379 _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz);
4380 _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());
4381 return __r;
4382}
4383
4384template<class _CharT, class _Traits, class _Allocator>
4385_LIBCPP_CONSTEXPR_AFTER_CXX17
4386basic_string<_CharT, _Traits, _Allocator>
4387operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Allocator>& __rhs)
4388{
4389 using _String = basic_string<_CharT, _Traits, _Allocator>;
4390 typename _String::size_type __rhs_sz = __rhs.size();
4391 _String __r(__uninitialized_size_tag(),
4392 __rhs_sz + 1,
4393 _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator()));
4394 auto __ptr = std::__to_address(__r.__get_pointer());
4395 _Traits::assign(__ptr, 1, __lhs);
4396 _Traits::copy(__ptr + 1, __rhs.data(), __rhs_sz);
4397 _Traits::assign(__ptr + 1 + __rhs_sz, 1, _CharT());
4398 return __r;
4399}
4400
4401template<class _CharT, class _Traits, class _Allocator>
4402inline _LIBCPP_CONSTEXPR_AFTER_CXX17
4403basic_string<_CharT, _Traits, _Allocator>
4404operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs)
4405{
4406 using _String = basic_string<_CharT, _Traits, _Allocator>;
4407 typename _String::size_type __lhs_sz = __lhs.size();
4408 typename _String::size_type __rhs_sz = _Traits::length(__rhs);
4409 _String __r(__uninitialized_size_tag(),
4410 __lhs_sz + __rhs_sz,
4411 _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator()));
4412 auto __ptr = std::__to_address(__r.__get_pointer());
4413 _Traits::copy(__ptr, __lhs.data(), __lhs_sz);
4414 _Traits::copy(__ptr + __lhs_sz, __rhs, __rhs_sz);
4415 _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());
4416 return __r;
4417}
4418
4419template<class _CharT, class _Traits, class _Allocator>
4420_LIBCPP_CONSTEXPR_AFTER_CXX17
4421basic_string<_CharT, _Traits, _Allocator>
4422operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs)
4423{
4424 using _String = basic_string<_CharT, _Traits, _Allocator>;
4425 typename _String::size_type __lhs_sz = __lhs.size();
4426 _String __r(__uninitialized_size_tag(),
4427 __lhs_sz + 1,
4428 _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator()));
4429 auto __ptr = std::__to_address(__r.__get_pointer());
4430 _Traits::copy(__ptr, __lhs.data(), __lhs_sz);
4431 _Traits::assign(__ptr + __lhs_sz, 1, __rhs);
4432 _Traits::assign(__ptr + 1 + __lhs_sz, 1, _CharT());
4433 return __r;
4434}
4435
4436#ifndef _LIBCPP_CXX03_LANG
4437
4438template<class _CharT, class _Traits, class _Allocator>
4439inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
4440basic_string<_CharT, _Traits, _Allocator>
4441operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs)
4442{
4443 return std::move(__lhs.append(__rhs));
4444}
4445
4446template<class _CharT, class _Traits, class _Allocator>
4447inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
4448basic_string<_CharT, _Traits, _Allocator>
4449operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs)
4450{
4451 return std::move(__rhs.insert(0, __lhs));
4452}
4453
4454template<class _CharT, class _Traits, class _Allocator>
4455inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
4456basic_string<_CharT, _Traits, _Allocator>
4457operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs)
4458{
4459 return std::move(__lhs.append(__rhs));
4460}
4461
4462template<class _CharT, class _Traits, class _Allocator>
4463inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
4464basic_string<_CharT, _Traits, _Allocator>
4465operator+(const _CharT* __lhs , basic_string<_CharT,_Traits,_Allocator>&& __rhs)
4466{
4467 return std::move(__rhs.insert(0, __lhs));
4468}
4469
4470template<class _CharT, class _Traits, class _Allocator>
4471inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
4472basic_string<_CharT, _Traits, _Allocator>
4473operator+(_CharT __lhs, basic_string<_CharT,_Traits,_Allocator>&& __rhs)
4474{
4475 __rhs.insert(__rhs.begin(), __lhs);
4476 return std::move(__rhs);
4477}
4478
4479template<class _CharT, class _Traits, class _Allocator>
4480inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
4481basic_string<_CharT, _Traits, _Allocator>
4482operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const _CharT* __rhs)
4483{
4484 return std::move(__lhs.append(__rhs));
4485}
4486
4487template<class _CharT, class _Traits, class _Allocator>
4488inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
4489basic_string<_CharT, _Traits, _Allocator>
4490operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT __rhs)
4491{
4492 __lhs.push_back(__rhs);
4493 return std::move(__lhs);
4494}
4495
4496#endif // _LIBCPP_CXX03_LANG
4497
4498// swap
4499
4500template<class _CharT, class _Traits, class _Allocator>
4501inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
4502void
4503swap(basic_string<_CharT, _Traits, _Allocator>& __lhs,
4504 basic_string<_CharT, _Traits, _Allocator>& __rhs)
4505 _NOEXCEPT_(_NOEXCEPT_(__lhs.swap(__rhs)))
4506{
4507 __lhs.swap(__rhs);
4508}
4509
4510_LIBCPP_FUNC_VIS int stoi (const string& __str, size_t* __idx = nullptr, int __base = 10);
4511_LIBCPP_FUNC_VIS long stol (const string& __str, size_t* __idx = nullptr, int __base = 10);
4512_LIBCPP_FUNC_VIS unsigned long stoul (const string& __str, size_t* __idx = nullptr, int __base = 10);
4513_LIBCPP_FUNC_VIS long long stoll (const string& __str, size_t* __idx = nullptr, int __base = 10);
4514_LIBCPP_FUNC_VIS unsigned long long stoull(const string& __str, size_t* __idx = nullptr, int __base = 10);
4515
4516_LIBCPP_FUNC_VIS float stof (const string& __str, size_t* __idx = nullptr);
4517_LIBCPP_FUNC_VIS double stod (const string& __str, size_t* __idx = nullptr);
4518_LIBCPP_FUNC_VIS long double stold(const string& __str, size_t* __idx = nullptr);
4519
4520_LIBCPP_FUNC_VIS string to_string(int __val);
4521_LIBCPP_FUNC_VIS string to_string(unsigned __val);
4522_LIBCPP_FUNC_VIS string to_string(long __val);
4523_LIBCPP_FUNC_VIS string to_string(unsigned long __val);
4524_LIBCPP_FUNC_VIS string to_string(long long __val);
4525_LIBCPP_FUNC_VIS string to_string(unsigned long long __val);
4526_LIBCPP_FUNC_VIS string to_string(float __val);
4527_LIBCPP_FUNC_VIS string to_string(double __val);
4528_LIBCPP_FUNC_VIS string to_string(long double __val);
4529
4530#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4531_LIBCPP_FUNC_VIS int stoi (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
4532_LIBCPP_FUNC_VIS long stol (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
4533_LIBCPP_FUNC_VIS unsigned long stoul (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
4534_LIBCPP_FUNC_VIS long long stoll (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
4535_LIBCPP_FUNC_VIS unsigned long long stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
4536
4537_LIBCPP_FUNC_VIS float stof (const wstring& __str, size_t* __idx = nullptr);
4538_LIBCPP_FUNC_VIS double stod (const wstring& __str, size_t* __idx = nullptr);
4539_LIBCPP_FUNC_VIS long double stold(const wstring& __str, size_t* __idx = nullptr);
4540
4541_LIBCPP_FUNC_VIS wstring to_wstring(int __val);
4542_LIBCPP_FUNC_VIS wstring to_wstring(unsigned __val);
4543_LIBCPP_FUNC_VIS wstring to_wstring(long __val);
4544_LIBCPP_FUNC_VIS wstring to_wstring(unsigned long __val);
4545_LIBCPP_FUNC_VIS wstring to_wstring(long long __val);
4546_LIBCPP_FUNC_VIS wstring to_wstring(unsigned long long __val);
4547_LIBCPP_FUNC_VIS wstring to_wstring(float __val);
4548_LIBCPP_FUNC_VIS wstring to_wstring(double __val);
4549_LIBCPP_FUNC_VIS wstring to_wstring(long double __val);
4550#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4551
4552template<class _CharT, class _Traits, class _Allocator>
4553_LIBCPP_TEMPLATE_DATA_VIS
4554const typename basic_string<_CharT, _Traits, _Allocator>::size_type
4555 basic_string<_CharT, _Traits, _Allocator>::npos;
4556
4557template <class _CharT, class _Allocator>
4558struct _LIBCPP_TEMPLATE_VIS
4559 hash<basic_string<_CharT, char_traits<_CharT>, _Allocator> >
4560 : public __unary_function<basic_string<_CharT, char_traits<_CharT>, _Allocator>, size_t>
4561{
4562 size_t
4563 operator()(const basic_string<_CharT, char_traits<_CharT>, _Allocator>& __val) const _NOEXCEPT
4564 { return __do_string_hash(__val.data(), __val.data() + __val.size()); }
4565};
4566
4567template<class _CharT, class _Traits, class _Allocator>
4568basic_ostream<_CharT, _Traits>&
4569operator<<(basic_ostream<_CharT, _Traits>& __os,
4570 const basic_string<_CharT, _Traits, _Allocator>& __str);
4571
4572template<class _CharT, class _Traits, class _Allocator>
4573basic_istream<_CharT, _Traits>&
4574operator>>(basic_istream<_CharT, _Traits>& __is,
4575 basic_string<_CharT, _Traits, _Allocator>& __str);
4576
4577template<class _CharT, class _Traits, class _Allocator>
4578basic_istream<_CharT, _Traits>&
4579getline(basic_istream<_CharT, _Traits>& __is,
4580 basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm);
4581
4582template<class _CharT, class _Traits, class _Allocator>
4583inline _LIBCPP_HIDE_FROM_ABI
4584basic_istream<_CharT, _Traits>&
4585getline(basic_istream<_CharT, _Traits>& __is,
4586 basic_string<_CharT, _Traits, _Allocator>& __str);
4587
4588template<class _CharT, class _Traits, class _Allocator>
4589inline _LIBCPP_HIDE_FROM_ABI
4590basic_istream<_CharT, _Traits>&
4591getline(basic_istream<_CharT, _Traits>&& __is,
4592 basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm);
4593
4594template<class _CharT, class _Traits, class _Allocator>
4595inline _LIBCPP_HIDE_FROM_ABI
4596basic_istream<_CharT, _Traits>&
4597getline(basic_istream<_CharT, _Traits>&& __is,
4598 basic_string<_CharT, _Traits, _Allocator>& __str);
4599
4600#if _LIBCPP_STD_VER > 17
4601template <class _CharT, class _Traits, class _Allocator, class _Up>
4602inline _LIBCPP_HIDE_FROM_ABI
4603 typename basic_string<_CharT, _Traits, _Allocator>::size_type
4604 erase(basic_string<_CharT, _Traits, _Allocator>& __str, const _Up& __v) {
4605 auto __old_size = __str.size();
4606 __str.erase(std::remove(__str.begin(), __str.end(), __v), __str.end());
4607 return __old_size - __str.size();
4608}
4609
4610template <class _CharT, class _Traits, class _Allocator, class _Predicate>
4611inline _LIBCPP_HIDE_FROM_ABI
4612 typename basic_string<_CharT, _Traits, _Allocator>::size_type
4613 erase_if(basic_string<_CharT, _Traits, _Allocator>& __str,
4614 _Predicate __pred) {
4615 auto __old_size = __str.size();
4616 __str.erase(std::remove_if(__str.begin(), __str.end(), __pred),
4617 __str.end());
4618 return __old_size - __str.size();
4619}
4620#endif
4621
4622#ifdef _LIBCPP_ENABLE_DEBUG_MODE
4623
4624template<class _CharT, class _Traits, class _Allocator>
4625bool
4626basic_string<_CharT, _Traits, _Allocator>::__dereferenceable(const const_iterator* __i) const
4627{
4628 return data() <= std::__to_address(__i->base()) &&
4629 std::__to_address(__i->base()) < data() + size();
4630}
4631
4632template<class _CharT, class _Traits, class _Allocator>
4633bool
4634basic_string<_CharT, _Traits, _Allocator>::__decrementable(const const_iterator* __i) const
4635{
4636 return data() < std::__to_address(__i->base()) &&
4637 std::__to_address(__i->base()) <= data() + size();
4638}
4639
4640template<class _CharT, class _Traits, class _Allocator>
4641bool
4642basic_string<_CharT, _Traits, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const
4643{
4644 const value_type* __p = std::__to_address(__i->base()) + __n;
4645 return data() <= __p && __p <= data() + size();
4646}
4647
4648template<class _CharT, class _Traits, class _Allocator>
4649bool
4650basic_string<_CharT, _Traits, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const
4651{
4652 const value_type* __p = std::__to_address(__i->base()) + __n;
4653 return data() <= __p && __p < data() + size();
4654}
4655
4656#endif // _LIBCPP_ENABLE_DEBUG_MODE
4657
4658#if _LIBCPP_STD_VER > 11
4659// Literal suffixes for basic_string [basic.string.literals]
4660inline namespace literals
4661{
4662 inline namespace string_literals
4663 {
4664 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
4665 basic_string<char> operator "" s( const char *__str, size_t __len )
4666 {
4667 return basic_string<char> (__str, __len);
4668 }
4669
4670#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4671 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
4672 basic_string<wchar_t> operator "" s( const wchar_t *__str, size_t __len )
4673 {
4674 return basic_string<wchar_t> (__str, __len);
4675 }
4676#endif
4677
4678#ifndef _LIBCPP_HAS_NO_CHAR8_T
4679 inline _LIBCPP_HIDE_FROM_ABI constexpr
4680 basic_string<char8_t> operator "" s(const char8_t *__str, size_t __len) _NOEXCEPT
4681 {
4682 return basic_string<char8_t> (__str, __len);
4683 }
4684#endif
4685
4686 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
4687 basic_string<char16_t> operator "" s( const char16_t *__str, size_t __len )
4688 {
4689 return basic_string<char16_t> (__str, __len);
4690 }
4691
4692 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
4693 basic_string<char32_t> operator "" s( const char32_t *__str, size_t __len )
4694 {
4695 return basic_string<char32_t> (__str, __len);
4696 }
4697 } // namespace string_literals
4698} // namespace literals
4699
4700#if _LIBCPP_STD_VER > 17
4701template <>
4702inline constexpr bool __format::__enable_insertable<std::basic_string<char>> = true;
4703#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4704template <>
4705inline constexpr bool __format::__enable_insertable<std::basic_string<wchar_t>> = true;
4706#endif
4707#endif
4708
4709#endif
4710
4711_LIBCPP_END_NAMESPACE_STD
4712
4713_LIBCPP_POP_MACROS
4714
4715#endif // _LIBCPP_STRING
4716

source code of flutter_engine/third_party/libcxx/include/string