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