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