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