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