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