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