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