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