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