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