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