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