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