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