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