xref: /freebsd/contrib/llvm-project/libcxx/include/__cxx03/string (revision 700637cbb5e582861067a11aaca4d053546871d2)
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___CXX03_STRING
11#define _LIBCPP___CXX03_STRING
12
13// clang-format off
14
15/*
16    string synopsis
17
18#include <__cxx03/compare>
19#include <__cxx03/initializer_list>
20
21namespace std
22{
23
24template <class stateT>
25class fpos
26{
27private:
28    stateT st;
29public:
30    fpos(streamoff = streamoff());
31
32    operator streamoff() const;
33
34    stateT state() const;
35    void state(stateT);
36
37    fpos& operator+=(streamoff);
38    fpos  operator+ (streamoff) const;
39    fpos& operator-=(streamoff);
40    fpos  operator- (streamoff) const;
41};
42
43template <class stateT> streamoff operator-(const fpos<stateT>& x, const fpos<stateT>& y);
44
45template <class stateT> bool operator==(const fpos<stateT>& x, const fpos<stateT>& y);
46template <class stateT> bool operator!=(const fpos<stateT>& x, const fpos<stateT>& y);
47
48template <class charT>
49struct char_traits
50{
51    using char_type           = charT;
52    using int_type            = ...;
53    using off_type            = streamoff;
54    using pos_type            = streampos;
55    using state_type          = mbstate_t;
56    using comparison_category = strong_ordering; // Since C++20 only for the specializations
57                                                 // char, wchar_t, char8_t, char16_t, and char32_t.
58
59    static void assign(char_type& c1, const char_type& c2) noexcept;
60    static constexpr bool eq(char_type c1, char_type c2) noexcept;
61    static constexpr bool lt(char_type c1, char_type c2) noexcept;
62
63    static int              compare(const char_type* s1, const char_type* s2, size_t n);
64    static size_t           length(const char_type* s);
65    static const char_type* find(const char_type* s, size_t n, const char_type& a);
66    static char_type*       move(char_type* s1, const char_type* s2, size_t n);
67    static char_type*       copy(char_type* s1, const char_type* s2, size_t n);
68    static char_type*       assign(char_type* s, size_t n, char_type a);
69
70    static constexpr int_type  not_eof(int_type c) noexcept;
71    static constexpr char_type to_char_type(int_type c) noexcept;
72    static constexpr int_type  to_int_type(char_type c) noexcept;
73    static constexpr bool      eq_int_type(int_type c1, int_type c2) noexcept;
74    static constexpr int_type  eof() noexcept;
75};
76
77template <> struct char_traits<char>;
78template <> struct char_traits<wchar_t>;
79template <> struct char_traits<char8_t>;  // C++20
80template <> struct char_traits<char16_t>;
81template <> struct char_traits<char32_t>;
82
83template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
84class basic_string
85{
86public:
87// types:
88    typedef traits traits_type;
89    typedef typename traits_type::char_type value_type;
90    typedef Allocator allocator_type;
91    typedef typename allocator_type::size_type size_type;
92    typedef typename allocator_type::difference_type difference_type;
93    typedef typename allocator_type::reference reference;
94    typedef typename allocator_type::const_reference const_reference;
95    typedef typename allocator_type::pointer pointer;
96    typedef typename allocator_type::const_pointer const_pointer;
97    typedef implementation-defined iterator;
98    typedef implementation-defined const_iterator;
99    typedef std::reverse_iterator<iterator> reverse_iterator;
100    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
101
102    static const size_type npos = -1;
103
104    basic_string()
105        noexcept(is_nothrow_default_constructible<allocator_type>::value);                      // constexpr since C++20
106    explicit basic_string(const allocator_type& a);                                             // constexpr since C++20
107    basic_string(const basic_string& str);                                                      // constexpr since C++20
108    basic_string(basic_string&& str)
109        noexcept(is_nothrow_move_constructible<allocator_type>::value);                         // constexpr since C++20
110    basic_string(const basic_string& str, size_type pos,
111                 const allocator_type& a = allocator_type());                                   // constexpr since C++20
112    basic_string(const basic_string& str, size_type pos, size_type n,
113                 const Allocator& a = Allocator());                                             // constexpr since C++20
114    constexpr basic_string(
115        basic_string&& str, size_type pos, const Allocator& a = Allocator());                   // since C++23
116    constexpr basic_string(
117        basic_string&& str, size_type pos, size_type n, const Allocator& a = Allocator());      // since C++23
118    template<class T>
119        basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator()); // C++17, constexpr since C++20
120    template <class T>
121        explicit basic_string(const T& t, const Allocator& a = Allocator());                    // C++17, constexpr since C++20
122    basic_string(const value_type* s, const allocator_type& a = allocator_type());              // constexpr since C++20
123    basic_string(const value_type* s, size_type n, const allocator_type& a = allocator_type()); // constexpr since C++20
124    basic_string(nullptr_t) = delete; // C++23
125    basic_string(size_type n, value_type c, const allocator_type& a = allocator_type());        // constexpr since C++20
126    template<class InputIterator>
127        basic_string(InputIterator begin, InputIterator end,
128                     const allocator_type& a = allocator_type());                               // constexpr since C++20
129    template<container-compatible-range<charT> R>
130      constexpr basic_string(from_range_t, R&& rg, const Allocator& a = Allocator());           // since C++23
131    basic_string(initializer_list<value_type>, const Allocator& = Allocator());                 // constexpr since C++20
132    basic_string(const basic_string&, const Allocator&);                                        // constexpr since C++20
133    basic_string(basic_string&&, const Allocator&);                                             // constexpr since C++20
134
135    ~basic_string();                                                                            // constexpr since C++20
136
137    operator basic_string_view<charT, traits>() const noexcept;                                 // constexpr since C++20
138
139    basic_string& operator=(const basic_string& str);                                           // constexpr since C++20
140    template <class T>
141        basic_string& operator=(const T& t);                                                    // C++17, constexpr since C++20
142    basic_string& operator=(basic_string&& str)
143        noexcept(
144             allocator_type::propagate_on_container_move_assignment::value ||
145             allocator_type::is_always_equal::value );                                          // C++17, constexpr since C++20
146    basic_string& operator=(const value_type* s);                                               // constexpr since C++20
147    basic_string& operator=(nullptr_t) = delete; // C++23
148    basic_string& operator=(value_type c);                                                      // constexpr since C++20
149    basic_string& operator=(initializer_list<value_type>);                                      // constexpr since C++20
150
151    iterator       begin() noexcept;                                                            // constexpr since C++20
152    const_iterator begin() const noexcept;                                                      // constexpr since C++20
153    iterator       end() noexcept;                                                              // constexpr since C++20
154    const_iterator end() const noexcept;                                                        // constexpr since C++20
155
156    reverse_iterator       rbegin() noexcept;                                                   // constexpr since C++20
157    const_reverse_iterator rbegin() const noexcept;                                             // constexpr since C++20
158    reverse_iterator       rend() noexcept;                                                     // constexpr since C++20
159    const_reverse_iterator rend() const noexcept;                                               // constexpr since C++20
160
161    const_iterator         cbegin() const noexcept;                                             // constexpr since C++20
162    const_iterator         cend() const noexcept;                                               // constexpr since C++20
163    const_reverse_iterator crbegin() const noexcept;                                            // constexpr since C++20
164    const_reverse_iterator crend() const noexcept;                                              // constexpr since C++20
165
166    size_type size() const noexcept;                                                            // constexpr since C++20
167    size_type length() const noexcept;                                                          // constexpr since C++20
168    size_type max_size() const noexcept;                                                        // constexpr since C++20
169    size_type capacity() const noexcept;                                                        // constexpr since C++20
170
171    void resize(size_type n, value_type c);                                                     // constexpr since C++20
172    void resize(size_type n);                                                                   // constexpr since C++20
173
174    template<class Operation>
175    constexpr void resize_and_overwrite(size_type n, Operation op); // since C++23
176
177    void reserve(size_type res_arg);                                                            // constexpr since C++20
178    void reserve();                                                                             // deprecated in C++20, removed in C++26
179    void shrink_to_fit();                                                                       // constexpr since C++20
180    void clear() noexcept;                                                                      // constexpr since C++20
181    bool empty() const noexcept;                                                                // constexpr since C++20
182
183    const_reference operator[](size_type pos) const;                                            // constexpr since C++20
184    reference       operator[](size_type pos);                                                  // constexpr since C++20
185
186    const_reference at(size_type n) const;                                                      // constexpr since C++20
187    reference       at(size_type n);                                                            // constexpr since C++20
188
189    basic_string& operator+=(const basic_string& str);                                          // constexpr since C++20
190    template <class T>
191        basic_string& operator+=(const T& t);                                                   // C++17, constexpr since C++20
192    basic_string& operator+=(const value_type* s);                                              // constexpr since C++20
193    basic_string& operator+=(value_type c);                                                     // constexpr since C++20
194    basic_string& operator+=(initializer_list<value_type>);                                     // constexpr since C++20
195
196    basic_string& append(const basic_string& str);                                              // constexpr since C++20
197    template <class T>
198        basic_string& append(const T& t);                                                       // C++17, constexpr since C++20
199    basic_string& append(const basic_string& str, size_type pos, size_type n=npos);             // C++14, constexpr since C++20
200    template <class T>
201        basic_string& append(const T& t, size_type pos, size_type n=npos);                      // C++17, constexpr since C++20
202    basic_string& append(const value_type* s, size_type n);                                     // constexpr since C++20
203    basic_string& append(const value_type* s);                                                  // constexpr since C++20
204    basic_string& append(size_type n, value_type c);                                            // constexpr since C++20
205    template<class InputIterator>
206        basic_string& append(InputIterator first, InputIterator last);                          // constexpr since C++20
207    template<container-compatible-range<charT> R>
208      constexpr basic_string& append_range(R&& rg);                                             // C++23
209    basic_string& append(initializer_list<value_type>);                                         // constexpr since C++20
210
211    void push_back(value_type c);                                                               // constexpr since C++20
212    void pop_back();                                                                            // constexpr since C++20
213    reference       front();                                                                    // constexpr since C++20
214    const_reference front() const;                                                              // constexpr since C++20
215    reference       back();                                                                     // constexpr since C++20
216    const_reference back() const;                                                               // constexpr since C++20
217
218    basic_string& assign(const basic_string& str);                                              // constexpr since C++20
219    template <class T>
220        basic_string& assign(const T& t);                                                       // C++17, constexpr since C++20
221    basic_string& assign(basic_string&& str);                                                   // constexpr since C++20
222    basic_string& assign(const basic_string& str, size_type pos, size_type n=npos);             // C++14, constexpr since C++20
223    template <class T>
224        basic_string& assign(const T& t, size_type pos, size_type n=npos);                      // C++17, constexpr since C++20
225    basic_string& assign(const value_type* s, size_type n);                                     // constexpr since C++20
226    basic_string& assign(const value_type* s);                                                  // constexpr since C++20
227    basic_string& assign(size_type n, value_type c);                                            // constexpr since C++20
228    template<class InputIterator>
229        basic_string& assign(InputIterator first, InputIterator last);                          // constexpr since C++20
230    template<container-compatible-range<charT> R>
231      constexpr basic_string& assign_range(R&& rg);                                             // C++23
232    basic_string& assign(initializer_list<value_type>);                                         // constexpr since C++20
233
234    basic_string& insert(size_type pos1, const basic_string& str);                              // constexpr since C++20
235    template <class T>
236        basic_string& insert(size_type pos1, const T& t);                                       // constexpr since C++20
237    basic_string& insert(size_type pos1, const basic_string& str,
238                         size_type pos2, size_type n);                                          // constexpr since C++20
239    template <class T>
240        basic_string& insert(size_type pos1, const T& t, size_type pos2, size_type n);          // C++17, constexpr since C++20
241    basic_string& insert(size_type pos, const value_type* s, size_type n=npos);                 // C++14, constexpr since C++20
242    basic_string& insert(size_type pos, const value_type* s);                                   // constexpr since C++20
243    basic_string& insert(size_type pos, size_type n, value_type c);                             // constexpr since C++20
244    iterator      insert(const_iterator p, value_type c);                                       // constexpr since C++20
245    iterator      insert(const_iterator p, size_type n, value_type c);                          // constexpr since C++20
246    template<class InputIterator>
247        iterator insert(const_iterator p, InputIterator first, InputIterator last);             // constexpr since C++20
248    template<container-compatible-range<charT> R>
249      constexpr iterator insert_range(const_iterator p, R&& rg);                                // C++23
250    iterator      insert(const_iterator p, initializer_list<value_type>);                       // constexpr since C++20
251
252    basic_string& erase(size_type pos = 0, size_type n = npos);                                 // constexpr since C++20
253    iterator      erase(const_iterator position);                                               // constexpr since C++20
254    iterator      erase(const_iterator first, const_iterator last);                             // constexpr since C++20
255
256    basic_string& replace(size_type pos1, size_type n1, const basic_string& str);               // constexpr since C++20
257    template <class T>
258    basic_string& replace(size_type pos1, size_type n1, const T& t);                            // C++17, constexpr since C++20
259    basic_string& replace(size_type pos1, size_type n1, const basic_string& str,
260                          size_type pos2, size_type n2=npos);                                   // C++14, constexpr since C++20
261    template <class T>
262        basic_string& replace(size_type pos1, size_type n1, const T& t,
263                              size_type pos2, size_type n);                                     // C++17, constexpr since C++20
264    basic_string& replace(size_type pos, size_type n1, const value_type* s, size_type n2);      // constexpr since C++20
265    basic_string& replace(size_type pos, size_type n1, const value_type* s);                    // constexpr since C++20
266    basic_string& replace(size_type pos, size_type n1, size_type n2, value_type c);             // constexpr since C++20
267    basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str);       // constexpr since C++20
268    template <class T>
269        basic_string& replace(const_iterator i1, const_iterator i2, const T& t);                // C++17, constexpr since C++20
270    basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s, size_type n); // constexpr since C++20
271    basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s);           // constexpr since C++20
272    basic_string& replace(const_iterator i1, const_iterator i2, size_type n, value_type c);     // constexpr since C++20
273    template<class InputIterator>
274        basic_string& replace(const_iterator i1, const_iterator i2, InputIterator j1, InputIterator j2); // constexpr since C++20
275    template<container-compatible-range<charT> R>
276      constexpr basic_string& replace_with_range(const_iterator i1, const_iterator i2, R&& rg); // C++23
277    basic_string& replace(const_iterator i1, const_iterator i2, initializer_list<value_type>);  // constexpr since C++20
278
279    size_type copy(value_type* s, size_type n, size_type pos = 0) const;                        // constexpr since C++20
280    basic_string substr(size_type pos = 0, size_type n = npos) const;                           // constexpr in C++20, removed in C++23
281    basic_string substr(size_type pos = 0, size_type n = npos) const&;                          // since C++23
282    constexpr basic_string substr(size_type pos = 0, size_type n = npos) &&;                    // since C++23
283    void swap(basic_string& str)
284        noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
285                 allocator_traits<allocator_type>::is_always_equal::value);                     // C++17, constexpr since C++20
286
287    const value_type* c_str() const noexcept;                                                   // constexpr since C++20
288    const value_type* data() const noexcept;                                                    // constexpr since C++20
289          value_type* data()       noexcept;                                                    // C++17, constexpr since C++20
290
291    allocator_type get_allocator() const noexcept;                                              // constexpr since C++20
292
293    size_type find(const basic_string& str, size_type pos = 0) const noexcept;                  // constexpr since C++20
294    template <class T>
295        size_type find(const T& t, size_type pos = 0) const noexcept;                           // C++17, noexcept as an extension, constexpr since C++20
296    size_type find(const value_type* s, size_type pos, size_type n) const noexcept;             // constexpr since C++20
297    size_type find(const value_type* s, size_type pos = 0) const noexcept;                      // constexpr since C++20
298    size_type find(value_type c, size_type pos = 0) const noexcept;                             // constexpr since C++20
299
300    size_type rfind(const basic_string& str, size_type pos = npos) const noexcept;              // constexpr since C++20
301    template <class T>
302        size_type rfind(const T& t, size_type pos = npos) const noexcept;                       // C++17, noexcept as an extension, constexpr since C++20
303    size_type rfind(const value_type* s, size_type pos, size_type n) const noexcept;            // constexpr since C++20
304    size_type rfind(const value_type* s, size_type pos = npos) const noexcept;                  // constexpr since C++20
305    size_type rfind(value_type c, size_type pos = npos) const noexcept;                         // constexpr since C++20
306
307    size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept;         // constexpr since C++20
308    template <class T>
309        size_type find_first_of(const T& t, size_type pos = 0) const noexcept;                  // C++17, noexcept as an extension, constexpr since C++20
310    size_type find_first_of(const value_type* s, size_type pos, size_type n) const noexcept;    // constexpr since C++20
311    size_type find_first_of(const value_type* s, size_type pos = 0) const noexcept;             // constexpr since C++20
312    size_type find_first_of(value_type c, size_type pos = 0) const noexcept;                    // constexpr since C++20
313
314    size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept;       // constexpr since C++20
315    template <class T>
316        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
317    size_type find_last_of(const value_type* s, size_type pos, size_type n) const noexcept;     // constexpr since C++20
318    size_type find_last_of(const value_type* s, size_type pos = npos) const noexcept;           // constexpr since C++20
319    size_type find_last_of(value_type c, size_type pos = npos) const noexcept;                  // constexpr since C++20
320
321    size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept;     // constexpr since C++20
322    template <class T>
323        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
324    size_type find_first_not_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20
325    size_type find_first_not_of(const value_type* s, size_type pos = 0) const noexcept;         // constexpr since C++20
326    size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept;                // constexpr since C++20
327
328    size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept;   // constexpr since C++20
329    template <class T>
330        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
331    size_type find_last_not_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20
332    size_type find_last_not_of(const value_type* s, size_type pos = npos) const noexcept;       // constexpr since C++20
333    size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept;              // constexpr since C++20
334
335    int compare(const basic_string& str) const noexcept;                                        // constexpr since C++20
336    template <class T>
337        int compare(const T& t) const noexcept;                                                 // C++17, noexcept as an extension, constexpr since C++20
338    int compare(size_type pos1, size_type n1, const basic_string& str) const;                   // constexpr since C++20
339    template <class T>
340        int compare(size_type pos1, size_type n1, const T& t) const;                            // C++17, constexpr since C++20
341    int compare(size_type pos1, size_type n1, const basic_string& str,
342                size_type pos2, size_type n2=npos) const;                                       // C++14, constexpr since C++20
343    template <class T>
344        int compare(size_type pos1, size_type n1, const T& t,
345                    size_type pos2, size_type n2=npos) const;                                   // C++17, constexpr since C++20
346    int compare(const value_type* s) const noexcept;                                            // constexpr since C++20
347    int compare(size_type pos1, size_type n1, const value_type* s) const;                       // constexpr since C++20
348    int compare(size_type pos1, size_type n1, const value_type* s, size_type n2) const;         // constexpr since C++20
349
350    constexpr bool starts_with(basic_string_view<charT, traits> sv) const noexcept;             // C++20
351    constexpr bool starts_with(charT c) const noexcept;                                         // C++20
352    constexpr bool starts_with(const charT* s) const;                                           // C++20
353    constexpr bool ends_with(basic_string_view<charT, traits> sv) const noexcept;               // C++20
354    constexpr bool ends_with(charT c) const noexcept;                                           // C++20
355    constexpr bool ends_with(const charT* s) const;                                             // C++20
356
357    constexpr bool contains(basic_string_view<charT, traits> sv) const noexcept;                // C++23
358    constexpr bool contains(charT c) const noexcept;                                            // C++23
359    constexpr bool contains(const charT* s) const;                                              // C++23
360};
361
362template<class InputIterator,
363         class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
364basic_string(InputIterator, InputIterator, Allocator = Allocator())
365   -> basic_string<typename iterator_traits<InputIterator>::value_type,
366                  char_traits<typename iterator_traits<InputIterator>::value_type>,
367                  Allocator>;   // C++17
368
369template<ranges::input_range R,
370         class Allocator = allocator<ranges::range_value_t<R>>>
371  basic_string(from_range_t, R&&, Allocator = Allocator())
372    -> basic_string<ranges::range_value_t<R>, char_traits<ranges::range_value_t<R>>,
373                    Allocator>; // C++23
374
375template<class charT,
376         class traits,
377         class Allocator = allocator<charT>>
378  explicit basic_string(basic_string_view<charT, traits>, const Allocator& = Allocator())
379    -> basic_string<charT, traits, Allocator>; // C++17
380
381template<class charT,
382         class traits,
383         class Allocator = allocator<charT>>
384  basic_string(basic_string_view<charT, traits>,
385                typename see below::size_type, typename see below::size_type,
386                const Allocator& = Allocator())
387    -> basic_string<charT, traits, Allocator>; // C++17
388
389template<class charT, class traits, class Allocator>
390basic_string<charT, traits, Allocator>
391operator+(const basic_string<charT, traits, Allocator>& lhs,
392          const basic_string<charT, traits, Allocator>& rhs);                                   // constexpr since C++20
393
394template<class charT, class traits, class Allocator>
395basic_string<charT, traits, Allocator>
396operator+(const charT* lhs , const basic_string<charT,traits,Allocator>&rhs);                   // constexpr since C++20
397
398template<class charT, class traits, class Allocator>
399basic_string<charT, traits, Allocator>
400operator+(charT lhs, const basic_string<charT,traits,Allocator>& rhs);                          // constexpr since C++20
401
402template<class charT, class traits, class Allocator>
403basic_string<charT, traits, Allocator>
404operator+(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs);                 // constexpr since C++20
405
406template<class charT, class traits, class Allocator>
407basic_string<charT, traits, Allocator>
408operator+(const basic_string<charT, traits, Allocator>& lhs, charT rhs);                        // constexpr since C++20
409
410template<class charT, class traits, class Allocator>
411  constexpr basic_string<charT, traits, Allocator>
412    operator+(const basic_string<charT, traits, Allocator>& lhs,
413              type_identity_t<basic_string_view<charT, traits>> rhs);                           // Since C++26
414template<class charT, class traits, class Allocator>
415  constexpr basic_string<charT, traits, Allocator>
416    operator+(basic_string<charT, traits, Allocator>&& lhs,
417              type_identity_t<basic_string_view<charT, traits>> rhs);                           // Since C++26
418template<class charT, class traits, class Allocator>
419  constexpr basic_string<charT, traits, Allocator>
420    operator+(type_identity_t<basic_string_view<charT, traits>> lhs,
421              const basic_string<charT, traits, Allocator>& rhs);                               // Since C++26
422template<class charT, class traits, class Allocator>
423  constexpr basic_string<charT, traits, Allocator>
424    operator+(type_identity_t<basic_string_view<charT, traits>> lhs,
425              basic_string<charT, traits, Allocator>&& rhs);                                    // Since C++26
426
427
428template<class charT, class traits, class Allocator>
429bool operator==(const basic_string<charT, traits, Allocator>& lhs,
430                const basic_string<charT, traits, Allocator>& rhs) noexcept;                    // constexpr since C++20
431
432template<class charT, class traits, class Allocator>
433bool operator==(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;  // removed in C++20
434
435template<class charT, class traits, class Allocator>
436bool operator==(const basic_string<charT,traits,Allocator>& lhs, const charT* rhs) noexcept;    // constexpr since C++20
437
438template<class charT, class traits, class Allocator>
439bool operator!=(const basic_string<charT,traits,Allocator>& lhs,
440                const basic_string<charT, traits, Allocator>& rhs) noexcept;                    // removed in C++20
441
442template<class charT, class traits, class Allocator>
443bool operator!=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;  // removed in C++20
444
445template<class charT, class traits, class Allocator>
446bool operator!=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;  // removed in C++20
447
448template<class charT, class traits, class Allocator>
449bool operator< (const basic_string<charT, traits, Allocator>& lhs,
450                const basic_string<charT, traits, Allocator>& rhs) noexcept;                    // removed in C++20
451
452template<class charT, class traits, class Allocator>
453bool operator< (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;  // removed in C++20
454
455template<class charT, class traits, class Allocator>
456bool operator< (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;  // removed in C++20
457
458template<class charT, class traits, class Allocator>
459bool operator> (const basic_string<charT, traits, Allocator>& lhs,
460                const basic_string<charT, traits, Allocator>& rhs) noexcept;                    // removed in C++20
461
462template<class charT, class traits, class Allocator>
463bool operator> (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;  // removed in C++20
464
465template<class charT, class traits, class Allocator>
466bool operator> (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;  // removed in C++20
467
468template<class charT, class traits, class Allocator>
469bool operator<=(const basic_string<charT, traits, Allocator>& lhs,
470                const basic_string<charT, traits, Allocator>& rhs) noexcept;                    // removed in C++20
471
472template<class charT, class traits, class Allocator>
473bool operator<=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;  // removed in C++20
474
475template<class charT, class traits, class Allocator>
476bool operator<=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;  // removed in C++20
477
478template<class charT, class traits, class Allocator>
479bool operator>=(const basic_string<charT, traits, Allocator>& lhs,
480                const basic_string<charT, traits, Allocator>& rhs) noexcept;                    // removed in C++20
481
482template<class charT, class traits, class Allocator>
483bool operator>=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;  // removed in C++20
484
485template<class charT, class traits, class Allocator>
486bool operator>=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;  // removed in C++20
487
488template<class charT, class traits, class Allocator>                                            // since C++20
489constexpr see below operator<=>(const basic_string<charT, traits, Allocator>& lhs,
490                                const basic_string<charT, traits, Allocator>& rhs) noexcept;
491
492template<class charT, class traits, class Allocator>                                            // since C++20
493constexpr see below operator<=>(const basic_string<charT, traits, Allocator>& lhs,
494                                const charT* rhs) noexcept;
495
496template<class charT, class traits, class Allocator>
497void swap(basic_string<charT, traits, Allocator>& lhs,
498          basic_string<charT, traits, Allocator>& rhs)
499            noexcept(noexcept(lhs.swap(rhs)));                                                  // constexpr since C++20
500
501template<class charT, class traits, class Allocator>
502basic_istream<charT, traits>&
503operator>>(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str);
504
505template<class charT, class traits, class Allocator>
506basic_ostream<charT, traits>&
507operator<<(basic_ostream<charT, traits>& os, const basic_string<charT, traits, Allocator>& str);
508
509template<class charT, class traits, class Allocator>
510basic_istream<charT, traits>&
511getline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str,
512        charT delim);
513
514template<class charT, class traits, class Allocator>
515basic_istream<charT, traits>&
516getline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str);
517
518template<class charT, class traits, class Allocator, class U>
519typename basic_string<charT, traits, Allocator>::size_type
520erase(basic_string<charT, traits, Allocator>& c, const U& value);    // C++20
521template<class charT, class traits, class Allocator, class Predicate>
522typename basic_string<charT, traits, Allocator>::size_type
523erase_if(basic_string<charT, traits, Allocator>& c, Predicate pred); // C++20
524
525typedef basic_string<char>    string;
526typedef basic_string<wchar_t> wstring;
527typedef basic_string<char8_t> u8string; // C++20
528typedef basic_string<char16_t> u16string;
529typedef basic_string<char32_t> u32string;
530
531int                stoi  (const string& str, size_t* idx = nullptr, int base = 10);
532long               stol  (const string& str, size_t* idx = nullptr, int base = 10);
533unsigned long      stoul (const string& str, size_t* idx = nullptr, int base = 10);
534long long          stoll (const string& str, size_t* idx = nullptr, int base = 10);
535unsigned long long stoull(const string& str, size_t* idx = nullptr, int base = 10);
536
537float       stof (const string& str, size_t* idx = nullptr);
538double      stod (const string& str, size_t* idx = nullptr);
539long double stold(const string& str, size_t* idx = nullptr);
540
541string to_string(int val);
542string to_string(unsigned val);
543string to_string(long val);
544string to_string(unsigned long val);
545string to_string(long long val);
546string to_string(unsigned long long val);
547string to_string(float val);
548string to_string(double val);
549string to_string(long double val);
550
551int                stoi  (const wstring& str, size_t* idx = nullptr, int base = 10);
552long               stol  (const wstring& str, size_t* idx = nullptr, int base = 10);
553unsigned long      stoul (const wstring& str, size_t* idx = nullptr, int base = 10);
554long long          stoll (const wstring& str, size_t* idx = nullptr, int base = 10);
555unsigned long long stoull(const wstring& str, size_t* idx = nullptr, int base = 10);
556
557float       stof (const wstring& str, size_t* idx = nullptr);
558double      stod (const wstring& str, size_t* idx = nullptr);
559long double stold(const wstring& str, size_t* idx = nullptr);
560
561wstring to_wstring(int val);
562wstring to_wstring(unsigned val);
563wstring to_wstring(long val);
564wstring to_wstring(unsigned long val);
565wstring to_wstring(long long val);
566wstring to_wstring(unsigned long long val);
567wstring to_wstring(float val);
568wstring to_wstring(double val);
569wstring to_wstring(long double val);
570
571template <> struct hash<string>;
572template <> struct hash<u8string>; // C++20
573template <> struct hash<u16string>;
574template <> struct hash<u32string>;
575template <> struct hash<wstring>;
576
577basic_string<char>     operator""s( const char *str,     size_t len );           // C++14, constexpr since C++20
578basic_string<wchar_t>  operator""s( const wchar_t *str,  size_t len );           // C++14, constexpr since C++20
579constexpr basic_string<char8_t>  operator""s( const char8_t *str,  size_t len ); // C++20
580basic_string<char16_t> operator""s( const char16_t *str, size_t len );           // C++14, constexpr since C++20
581basic_string<char32_t> operator""s( const char32_t *str, size_t len );           // C++14, constexpr since C++20
582
583}  // std
584
585*/
586
587// clang-format on
588
589#include <__cxx03/__algorithm/max.h>
590#include <__cxx03/__algorithm/min.h>
591#include <__cxx03/__algorithm/remove.h>
592#include <__cxx03/__algorithm/remove_if.h>
593#include <__cxx03/__assert>
594#include <__cxx03/__config>
595#include <__cxx03/__debug_utils/sanitizers.h>
596#include <__cxx03/__functional/hash.h>
597#include <__cxx03/__functional/unary_function.h>
598#include <__cxx03/__fwd/string.h>
599#include <__cxx03/__ios/fpos.h>
600#include <__cxx03/__iterator/bounded_iter.h>
601#include <__cxx03/__iterator/distance.h>
602#include <__cxx03/__iterator/iterator_traits.h>
603#include <__cxx03/__iterator/reverse_iterator.h>
604#include <__cxx03/__iterator/wrap_iter.h>
605#include <__cxx03/__memory/addressof.h>
606#include <__cxx03/__memory/allocate_at_least.h>
607#include <__cxx03/__memory/allocator.h>
608#include <__cxx03/__memory/allocator_traits.h>
609#include <__cxx03/__memory/compressed_pair.h>
610#include <__cxx03/__memory/construct_at.h>
611#include <__cxx03/__memory/pointer_traits.h>
612#include <__cxx03/__memory/swap_allocator.h>
613#include <__cxx03/__string/char_traits.h>
614#include <__cxx03/__string/extern_template_lists.h>
615#include <__cxx03/__type_traits/conditional.h>
616#include <__cxx03/__type_traits/is_allocator.h>
617#include <__cxx03/__type_traits/is_array.h>
618#include <__cxx03/__type_traits/is_convertible.h>
619#include <__cxx03/__type_traits/is_nothrow_assignable.h>
620#include <__cxx03/__type_traits/is_nothrow_constructible.h>
621#include <__cxx03/__type_traits/is_same.h>
622#include <__cxx03/__type_traits/is_standard_layout.h>
623#include <__cxx03/__type_traits/is_trivial.h>
624#include <__cxx03/__type_traits/is_trivially_relocatable.h>
625#include <__cxx03/__type_traits/noexcept_move_assign_container.h>
626#include <__cxx03/__type_traits/remove_cvref.h>
627#include <__cxx03/__type_traits/void_t.h>
628#include <__cxx03/__utility/auto_cast.h>
629#include <__cxx03/__utility/declval.h>
630#include <__cxx03/__utility/forward.h>
631#include <__cxx03/__utility/is_pointer_in_range.h>
632#include <__cxx03/__utility/move.h>
633#include <__cxx03/__utility/swap.h>
634#include <__cxx03/__utility/unreachable.h>
635#include <__cxx03/climits>
636#include <__cxx03/cstdio> // EOF
637#include <__cxx03/cstring>
638#include <__cxx03/limits>
639#include <__cxx03/stdexcept>
640#include <__cxx03/string_view>
641#include <__cxx03/version>
642
643#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
644#  include <__cxx03/cwchar>
645#endif
646
647// standard-mandated includes
648
649// [iterator.range]
650#include <__cxx03/__iterator/access.h>
651
652#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
653#  pragma GCC system_header
654#endif
655
656_LIBCPP_PUSH_MACROS
657#include <__cxx03/__undef_macros>
658
659#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN)
660#  define _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS __attribute__((__no_sanitize__("address")))
661// This macro disables AddressSanitizer (ASan) instrumentation for a specific function,
662// allowing memory accesses that would normally trigger ASan errors to proceed without crashing.
663// This is useful for accessing parts of objects memory, which should not be accessed,
664// such as unused bytes in short strings, that should never be accessed
665// by other parts of the program.
666#else
667#  define _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS
668#endif
669
670_LIBCPP_BEGIN_NAMESPACE_STD
671
672// basic_string
673
674template <class _CharT, class _Traits, class _Allocator>
675basic_string<_CharT, _Traits, _Allocator> _LIBCPP_HIDE_FROM_ABI
676operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const basic_string<_CharT, _Traits, _Allocator>& __y);
677
678template <class _CharT, class _Traits, class _Allocator>
679_LIBCPP_HIDDEN basic_string<_CharT, _Traits, _Allocator>
680operator+(const _CharT* __x, const basic_string<_CharT, _Traits, _Allocator>& __y);
681
682template <class _CharT, class _Traits, class _Allocator>
683_LIBCPP_HIDE_FROM_ABI basic_string<_CharT, _Traits, _Allocator>
684operator+(_CharT __x, const basic_string<_CharT, _Traits, _Allocator>& __y);
685
686template <class _CharT, class _Traits, class _Allocator>
687inline _LIBCPP_HIDE_FROM_ABI basic_string<_CharT, _Traits, _Allocator>
688operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const _CharT* __y);
689
690template <class _CharT, class _Traits, class _Allocator>
691_LIBCPP_HIDE_FROM_ABI basic_string<_CharT, _Traits, _Allocator>
692operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y);
693
694extern template _LIBCPP_EXPORTED_FROM_ABI string operator+
695    <char, char_traits<char>, allocator<char> >(char const*, string const&);
696
697template <class _Iter>
698struct __string_is_trivial_iterator : public false_type {};
699
700template <class _Tp>
701struct __string_is_trivial_iterator<_Tp*> : public is_arithmetic<_Tp> {};
702
703template <class _Iter>
704struct __string_is_trivial_iterator<__wrap_iter<_Iter> > : public __string_is_trivial_iterator<_Iter> {};
705
706template <class _CharT, class _Traits, class _Tp>
707struct __can_be_converted_to_string_view
708    : public _BoolConstant< is_convertible<const _Tp&, basic_string_view<_CharT, _Traits> >::value &&
709                            !is_convertible<const _Tp&, const _CharT*>::value > {};
710
711struct __uninitialized_size_tag {};
712struct __init_with_sentinel_tag {};
713
714template <class _CharT, class _Traits, class _Allocator>
715class basic_string {
716private:
717  using __default_allocator_type = allocator<_CharT>;
718
719public:
720  typedef basic_string __self;
721  typedef basic_string_view<_CharT, _Traits> __self_view;
722  typedef _Traits traits_type;
723  typedef _CharT value_type;
724  typedef _Allocator allocator_type;
725  typedef allocator_traits<allocator_type> __alloc_traits;
726  typedef typename __alloc_traits::size_type size_type;
727  typedef typename __alloc_traits::difference_type difference_type;
728  typedef value_type& reference;
729  typedef const value_type& const_reference;
730  typedef typename __alloc_traits::pointer pointer;
731  typedef typename __alloc_traits::const_pointer const_pointer;
732
733  // A basic_string contains the following members which may be trivially relocatable:
734  // - pointer: is currently assumed to be trivially relocatable, but is still checked in case that changes
735  // - size_type: is always trivially relocatable, since it has to be an integral type
736  // - value_type: is always trivially relocatable, since it has to be trivial
737  // - unsigned char: is a fundamental type, so it's trivially relocatable
738  // - allocator_type: may or may not be trivially relocatable, so it's checked
739  //
740  // This string implementation doesn't contain any references into itself. It only contains a bit that says whether
741  // it is in small or large string mode, so the entire structure is trivially relocatable if its members are.
742#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN)
743  // When compiling with AddressSanitizer (ASan), basic_string cannot be trivially
744  // relocatable. Because the object's memory might be poisoned when its content
745  // is kept inside objects memory (short string optimization), instead of in allocated
746  // external memory. In such cases, the destructor is responsible for unpoisoning
747  // the memory to avoid triggering false positives.
748  // Therefore it's crucial to ensure the destructor is called.
749  using __trivially_relocatable = void;
750#else
751  using __trivially_relocatable = __conditional_t<
752      __libcpp_is_trivially_relocatable<allocator_type>::value && __libcpp_is_trivially_relocatable<pointer>::value,
753      basic_string,
754      void>;
755#endif
756#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN)
757  _LIBCPP_HIDE_FROM_ABI pointer __asan_volatile_wrapper(pointer const& __ptr) const {
758    if (__libcpp_is_constant_evaluated())
759      return __ptr;
760
761    pointer volatile __copy_ptr = __ptr;
762
763    return const_cast<pointer&>(__copy_ptr);
764  }
765
766  _LIBCPP_HIDE_FROM_ABI const_pointer __asan_volatile_wrapper(const_pointer const& __ptr) const {
767    if (__libcpp_is_constant_evaluated())
768      return __ptr;
769
770    const_pointer volatile __copy_ptr = __ptr;
771
772    return const_cast<const_pointer&>(__copy_ptr);
773  }
774#  define _LIBCPP_ASAN_VOLATILE_WRAPPER(PTR) __asan_volatile_wrapper(PTR)
775#else
776#  define _LIBCPP_ASAN_VOLATILE_WRAPPER(PTR) PTR
777#endif
778
779  static_assert(!is_array<value_type>::value, "Character type of basic_string must not be an array");
780  static_assert(is_standard_layout<value_type>::value, "Character type of basic_string must be standard-layout");
781  static_assert(is_trivial<value_type>::value, "Character type of basic_string must be trivial");
782  static_assert(is_same<_CharT, typename traits_type::char_type>::value,
783                "traits_type::char_type must be the same type as CharT");
784  static_assert(is_same<typename allocator_type::value_type, value_type>::value,
785                "Allocator::value_type must be same type as value_type");
786  static_assert(__check_valid_allocator<allocator_type>::value, "");
787
788#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING
789  // Users might provide custom allocators, and prior to C++20 we have no existing way to detect whether the allocator's
790  // pointer type is contiguous (though it has to be by the Standard). Using the wrapper type ensures the iterator is
791  // considered contiguous.
792  typedef __bounded_iter<__wrap_iter<pointer>> iterator;
793  typedef __bounded_iter<__wrap_iter<const_pointer>> const_iterator;
794#else
795  typedef __wrap_iter<pointer> iterator;
796  typedef __wrap_iter<const_pointer> const_iterator;
797#endif
798  typedef std::reverse_iterator<iterator> reverse_iterator;
799  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
800
801private:
802  static_assert(CHAR_BIT == 8, "This implementation assumes that one byte contains 8 bits");
803
804#ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
805
806  struct __long {
807    pointer __data_;
808    size_type __size_;
809    size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1;
810    size_type __is_long_ : 1;
811  };
812
813  enum { __min_cap = (sizeof(__long) - 1) / sizeof(value_type) > 2 ? (sizeof(__long) - 1) / sizeof(value_type) : 2 };
814
815  struct __short {
816    value_type __data_[__min_cap];
817    unsigned char __padding_[sizeof(value_type) - 1];
818    unsigned char __size_    : 7;
819    unsigned char __is_long_ : 1;
820  };
821
822  // The __endian_factor is required because the field we use to store the size
823  // has one fewer bit than it would if it were not a bitfield.
824  //
825  // If the LSB is used to store the short-flag in the short string representation,
826  // we have to multiply the size by two when it is stored and divide it by two when
827  // it is loaded to make sure that we always store an even number. In the long string
828  // representation, we can ignore this because we can assume that we always allocate
829  // an even amount of value_types.
830  //
831  // If the MSB is used for the short-flag, the max_size() is numeric_limits<size_type>::max() / 2.
832  // This does not impact the short string representation, since we never need the MSB
833  // for representing the size of a short string anyway.
834
835#  ifdef _LIBCPP_BIG_ENDIAN
836  static const size_type __endian_factor = 2;
837#  else
838  static const size_type __endian_factor = 1;
839#  endif
840
841#else // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
842
843#  ifdef _LIBCPP_BIG_ENDIAN
844  static const size_type __endian_factor = 1;
845#  else
846  static const size_type __endian_factor = 2;
847#  endif
848
849  // Attribute 'packed' is used to keep the layout compatible with the
850  // previous definition that did not use bit fields. This is because on
851  // some platforms bit fields have a default size rather than the actual
852  // size used, e.g., it is 4 bytes on AIX. See D128285 for details.
853  struct __long {
854    struct _LIBCPP_PACKED {
855      size_type __is_long_ : 1;
856      size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1;
857    };
858    size_type __size_;
859    pointer __data_;
860  };
861
862  enum { __min_cap = (sizeof(__long) - 1) / sizeof(value_type) > 2 ? (sizeof(__long) - 1) / sizeof(value_type) : 2 };
863
864  struct __short {
865    struct _LIBCPP_PACKED {
866      unsigned char __is_long_ : 1;
867      unsigned char __size_    : 7;
868    };
869    char __padding_[sizeof(value_type) - 1];
870    value_type __data_[__min_cap];
871  };
872
873#endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
874
875  static_assert(sizeof(__short) == (sizeof(value_type) * (__min_cap + 1)), "__short has an unexpected size.");
876
877  union __rep {
878    __short __s;
879    __long __l;
880  };
881
882  __compressed_pair<__rep, allocator_type> __r_;
883
884  // Construct a string with the given allocator and enough storage to hold `__size` characters, but
885  // don't initialize the characters. The contents of the string, including the null terminator, must be
886  // initialized separately.
887  _LIBCPP_HIDE_FROM_ABI explicit basic_string(__uninitialized_size_tag, size_type __size, const allocator_type& __a)
888      : __r_(__default_init_tag(), __a) {
889    if (__size > max_size())
890      __throw_length_error();
891    if (__fits_in_sso(__size)) {
892      __r_.first() = __rep();
893      __set_short_size(__size);
894    } else {
895      auto __capacity   = __recommend(__size) + 1;
896      auto __allocation = __alloc_traits::allocate(__alloc(), __capacity);
897      __begin_lifetime(__allocation, __capacity);
898      __set_long_cap(__capacity);
899      __set_long_pointer(__allocation);
900      __set_long_size(__size);
901    }
902    __annotate_new(__size);
903  }
904
905  template <class _Iter, class _Sent>
906  _LIBCPP_HIDE_FROM_ABI basic_string(__init_with_sentinel_tag, _Iter __first, _Sent __last, const allocator_type& __a)
907      : __r_(__default_init_tag(), __a) {
908    __init_with_sentinel(std::move(__first), std::move(__last));
909  }
910
911  _LIBCPP_HIDE_FROM_ABI iterator __make_iterator(pointer __p) {
912#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING
913    // Bound the iterator according to the size (and not the capacity, unlike vector).
914    //
915    // By the Standard, string iterators are generally not guaranteed to stay valid when the container is modified,
916    // regardless of whether reallocation occurs. This allows us to check for out-of-bounds accesses using logical size,
917    // a stricter check, since correct code can never rely on being able to access newly-added elements via an existing
918    // iterator.
919    return std::__make_bounded_iter(
920        std::__wrap_iter<pointer>(__p),
921        std::__wrap_iter<pointer>(__get_pointer()),
922        std::__wrap_iter<pointer>(__get_pointer() + size()));
923#else
924    return iterator(__p);
925#endif // _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING
926  }
927
928  _LIBCPP_HIDE_FROM_ABI const_iterator __make_const_iterator(const_pointer __p) const {
929#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING
930    // Bound the iterator according to the size (and not the capacity, unlike vector).
931    return std::__make_bounded_iter(
932        std::__wrap_iter<const_pointer>(__p),
933        std::__wrap_iter<const_pointer>(__get_pointer()),
934        std::__wrap_iter<const_pointer>(__get_pointer() + size()));
935#else
936    return const_iterator(__p);
937#endif // _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING
938  }
939
940public:
941  _LIBCPP_TEMPLATE_DATA_VIS static const size_type npos = -1;
942
943  _LIBCPP_HIDE_FROM_ABI basic_string() : __r_(__value_init_tag(), __default_init_tag()) { __annotate_new(0); }
944
945  _LIBCPP_HIDE_FROM_ABI explicit basic_string(const allocator_type& __a) : __r_(__value_init_tag(), __a) {
946    __annotate_new(0);
947  }
948
949  _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS basic_string(const basic_string& __str)
950      : __r_(__default_init_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc())) {
951    if (!__str.__is_long()) {
952      __r_.first() = __str.__r_.first();
953      __annotate_new(__get_short_size());
954    } else
955      __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size());
956  }
957
958  _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS
959  basic_string(const basic_string& __str, const allocator_type& __a) : __r_(__default_init_tag(), __a) {
960    if (!__str.__is_long()) {
961      __r_.first() = __str.__r_.first();
962      __annotate_new(__get_short_size());
963    } else
964      __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size());
965  }
966
967  template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0>
968  _LIBCPP_HIDE_FROM_ABI basic_string(const _CharT* __s) : __r_(__default_init_tag(), __default_init_tag()) {
969    _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "basic_string(const char*) detected nullptr");
970    __init(__s, traits_type::length(__s));
971  }
972
973  template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0>
974  _LIBCPP_HIDE_FROM_ABI basic_string(const _CharT* __s, const _Allocator& __a) : __r_(__default_init_tag(), __a) {
975    _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "basic_string(const char*, allocator) detected nullptr");
976    __init(__s, traits_type::length(__s));
977  }
978
979  _LIBCPP_HIDE_FROM_ABI basic_string(const _CharT* __s, size_type __n)
980      : __r_(__default_init_tag(), __default_init_tag()) {
981    _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr");
982    __init(__s, __n);
983  }
984
985  _LIBCPP_HIDE_FROM_ABI basic_string(const _CharT* __s, size_type __n, const _Allocator& __a)
986      : __r_(__default_init_tag(), __a) {
987    _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr");
988    __init(__s, __n);
989  }
990
991  _LIBCPP_HIDE_FROM_ABI basic_string(size_type __n, _CharT __c) : __r_(__default_init_tag(), __default_init_tag()) {
992    __init(__n, __c);
993  }
994
995  template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0>
996  _LIBCPP_HIDE_FROM_ABI basic_string(size_type __n, _CharT __c, const _Allocator& __a)
997      : __r_(__default_init_tag(), __a) {
998    __init(__n, __c);
999  }
1000
1001  basic_string(const basic_string& __str, size_type __pos, size_type __n, const _Allocator& __a = _Allocator())
1002      : __r_(__default_init_tag(), __a) {
1003    size_type __str_sz = __str.size();
1004    if (__pos > __str_sz)
1005      __throw_out_of_range();
1006    __init(__str.data() + __pos, std::min(__n, __str_sz - __pos));
1007  }
1008
1009  _LIBCPP_HIDE_FROM_ABI basic_string(const basic_string& __str, size_type __pos, const _Allocator& __a = _Allocator())
1010      : __r_(__default_init_tag(), __a) {
1011    size_type __str_sz = __str.size();
1012    if (__pos > __str_sz)
1013      __throw_out_of_range();
1014    __init(__str.data() + __pos, __str_sz - __pos);
1015  }
1016
1017  template <class _Tp,
1018            __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1019                              !__is_same_uncvref<_Tp, basic_string>::value,
1020                          int> = 0>
1021  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
1022  basic_string(const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a = allocator_type())
1023      : __r_(__default_init_tag(), __a) {
1024    __self_view __sv0 = __t;
1025    __self_view __sv  = __sv0.substr(__pos, __n);
1026    __init(__sv.data(), __sv.size());
1027  }
1028
1029  template <class _Tp,
1030            __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1031                              !__is_same_uncvref<_Tp, basic_string>::value,
1032                          int> = 0>
1033  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS explicit basic_string(const _Tp& __t)
1034      : __r_(__default_init_tag(), __default_init_tag()) {
1035    __self_view __sv = __t;
1036    __init(__sv.data(), __sv.size());
1037  }
1038
1039  template <class _Tp,
1040            __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1041                              !__is_same_uncvref<_Tp, basic_string>::value,
1042                          int> = 0>
1043  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS explicit basic_string(const _Tp& __t, const allocator_type& __a)
1044      : __r_(__default_init_tag(), __a) {
1045    __self_view __sv = __t;
1046    __init(__sv.data(), __sv.size());
1047  }
1048
1049  template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0>
1050  _LIBCPP_HIDE_FROM_ABI basic_string(_InputIterator __first, _InputIterator __last)
1051      : __r_(__default_init_tag(), __default_init_tag()) {
1052    __init(__first, __last);
1053  }
1054
1055  template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0>
1056  _LIBCPP_HIDE_FROM_ABI basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a)
1057      : __r_(__default_init_tag(), __a) {
1058    __init(__first, __last);
1059  }
1060
1061  inline ~basic_string() {
1062    __annotate_delete();
1063    if (__is_long())
1064      __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
1065  }
1066
1067  _LIBCPP_HIDE_FROM_ABI operator __self_view() const _NOEXCEPT { return __self_view(data(), size()); }
1068
1069  _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS basic_string& operator=(const basic_string& __str);
1070
1071  template <class _Tp,
1072            __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1073                              !__is_same_uncvref<_Tp, basic_string>::value,
1074                          int> = 0>
1075  basic_string& operator=(const _Tp& __t) {
1076    __self_view __sv = __t;
1077    return assign(__sv);
1078  }
1079
1080  _LIBCPP_HIDE_FROM_ABI basic_string& operator=(const value_type* __s) { return assign(__s); }
1081  basic_string& operator=(value_type __c);
1082
1083  _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __make_iterator(__get_pointer()); }
1084  _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __make_const_iterator(__get_pointer()); }
1085  _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __make_iterator(__get_pointer() + size()); }
1086  _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __make_const_iterator(__get_pointer() + size()); }
1087
1088  _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); }
1089  _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); }
1090  _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); }
1091  _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); }
1092
1093  _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); }
1094  _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); }
1095  _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return rbegin(); }
1096  _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return rend(); }
1097
1098  _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT {
1099    return __is_long() ? __get_long_size() : __get_short_size();
1100  }
1101  _LIBCPP_HIDE_FROM_ABI size_type length() const _NOEXCEPT { return size(); }
1102
1103  _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
1104    size_type __m = __alloc_traits::max_size(__alloc());
1105    if (__m <= std::numeric_limits<size_type>::max() / 2) {
1106      return __m - __alignment;
1107    } else {
1108      bool __uses_lsb = __endian_factor == 2;
1109      return __uses_lsb ? __m - __alignment : (__m / 2) - __alignment;
1110    }
1111  }
1112
1113  _LIBCPP_HIDE_FROM_ABI size_type capacity() const _NOEXCEPT {
1114    return (__is_long() ? __get_long_cap() : static_cast<size_type>(__min_cap)) - 1;
1115  }
1116
1117  void resize(size_type __n, value_type __c);
1118  _LIBCPP_HIDE_FROM_ABI void resize(size_type __n) { resize(__n, value_type()); }
1119
1120  void reserve(size_type __requested_capacity);
1121
1122  _LIBCPP_HIDE_FROM_ABI void __resize_default_init(size_type __n);
1123
1124  _LIBCPP_HIDE_FROM_ABI void reserve() _NOEXCEPT { shrink_to_fit(); }
1125  _LIBCPP_HIDE_FROM_ABI void shrink_to_fit() _NOEXCEPT;
1126  _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT;
1127
1128  _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return size() == 0; }
1129
1130  _LIBCPP_HIDE_FROM_ABI const_reference operator[](size_type __pos) const _NOEXCEPT {
1131    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos <= size(), "string index out of bounds");
1132    if (__builtin_constant_p(__pos) && !__fits_in_sso(__pos)) {
1133      return *(__get_long_pointer() + __pos);
1134    }
1135    return *(data() + __pos);
1136  }
1137
1138  _LIBCPP_HIDE_FROM_ABI reference operator[](size_type __pos) _NOEXCEPT {
1139    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos <= size(), "string index out of bounds");
1140    if (__builtin_constant_p(__pos) && !__fits_in_sso(__pos)) {
1141      return *(__get_long_pointer() + __pos);
1142    }
1143    return *(__get_pointer() + __pos);
1144  }
1145
1146  const_reference at(size_type __n) const;
1147  reference at(size_type __n);
1148
1149  _LIBCPP_HIDE_FROM_ABI basic_string& operator+=(const basic_string& __str) { return append(__str); }
1150
1151  template <class _Tp,
1152            __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1153                              !__is_same_uncvref<_Tp, basic_string >::value,
1154                          int> = 0>
1155  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string& operator+=(const _Tp& __t) {
1156    __self_view __sv = __t;
1157    return append(__sv);
1158  }
1159
1160  _LIBCPP_HIDE_FROM_ABI basic_string& operator+=(const value_type* __s) { return append(__s); }
1161
1162  _LIBCPP_HIDE_FROM_ABI basic_string& operator+=(value_type __c) {
1163    push_back(__c);
1164    return *this;
1165  }
1166
1167  _LIBCPP_HIDE_FROM_ABI basic_string& append(const basic_string& __str) { return append(__str.data(), __str.size()); }
1168
1169  template <class _Tp,
1170            __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1171                              !__is_same_uncvref<_Tp, basic_string>::value,
1172                          int> = 0>
1173  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string& append(const _Tp& __t) {
1174    __self_view __sv = __t;
1175    return append(__sv.data(), __sv.size());
1176  }
1177
1178  basic_string& append(const basic_string& __str, size_type __pos, size_type __n = npos);
1179
1180  template <class _Tp,
1181            __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1182                              !__is_same_uncvref<_Tp, basic_string>::value,
1183                          int> = 0>
1184  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string&
1185  append(const _Tp& __t, size_type __pos, size_type __n = npos);
1186
1187  basic_string& append(const value_type* __s, size_type __n);
1188  basic_string& append(const value_type* __s);
1189  basic_string& append(size_type __n, value_type __c);
1190
1191  _LIBCPP_HIDE_FROM_ABI void __append_default_init(size_type __n);
1192
1193  template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
1194  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_HIDE_FROM_ABI basic_string&
1195  append(_InputIterator __first, _InputIterator __last) {
1196    const basic_string __temp(__first, __last, __alloc());
1197    append(__temp.data(), __temp.size());
1198    return *this;
1199  }
1200
1201  template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>
1202  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_HIDE_FROM_ABI basic_string&
1203  append(_ForwardIterator __first, _ForwardIterator __last);
1204
1205  void push_back(value_type __c);
1206  _LIBCPP_HIDE_FROM_ABI void pop_back();
1207
1208  _LIBCPP_HIDE_FROM_ABI reference front() _NOEXCEPT {
1209    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::front(): string is empty");
1210    return *__get_pointer();
1211  }
1212
1213  _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT {
1214    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::front(): string is empty");
1215    return *data();
1216  }
1217
1218  _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT {
1219    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::back(): string is empty");
1220    return *(__get_pointer() + size() - 1);
1221  }
1222
1223  _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT {
1224    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::back(): string is empty");
1225    return *(data() + size() - 1);
1226  }
1227
1228  template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1229  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string& assign(const _Tp& __t) {
1230    __self_view __sv = __t;
1231    return assign(__sv.data(), __sv.size());
1232  }
1233
1234  _LIBCPP_HIDE_FROM_ABI basic_string& assign(const basic_string& __str) { return *this = __str; }
1235
1236  basic_string& assign(const basic_string& __str, size_type __pos, size_type __n = npos);
1237
1238  template <class _Tp,
1239            __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1240                              !__is_same_uncvref<_Tp, basic_string>::value,
1241                          int> = 0>
1242  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string&
1243  assign(const _Tp& __t, size_type __pos, size_type __n = npos);
1244
1245  basic_string& assign(const value_type* __s, size_type __n);
1246  basic_string& assign(const value_type* __s);
1247  basic_string& assign(size_type __n, value_type __c);
1248  template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
1249  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string&
1250  assign(_InputIterator __first, _InputIterator __last);
1251
1252  template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>
1253  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string&
1254  assign(_ForwardIterator __first, _ForwardIterator __last);
1255
1256  _LIBCPP_HIDE_FROM_ABI basic_string& insert(size_type __pos1, const basic_string& __str) {
1257    return insert(__pos1, __str.data(), __str.size());
1258  }
1259
1260  template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1261  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string& insert(size_type __pos1, const _Tp& __t) {
1262    __self_view __sv = __t;
1263    return insert(__pos1, __sv.data(), __sv.size());
1264  }
1265
1266  template <class _Tp,
1267            __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1268                              !__is_same_uncvref<_Tp, basic_string>::value,
1269                          int> = 0>
1270  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string&
1271  insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n = npos);
1272
1273  basic_string& insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n = npos);
1274  basic_string& insert(size_type __pos, const value_type* __s, size_type __n);
1275  basic_string& insert(size_type __pos, const value_type* __s);
1276  basic_string& insert(size_type __pos, size_type __n, value_type __c);
1277  iterator insert(const_iterator __pos, value_type __c);
1278
1279  _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __pos, size_type __n, value_type __c) {
1280    difference_type __p = __pos - begin();
1281    insert(static_cast<size_type>(__p), __n, __c);
1282    return begin() + __p;
1283  }
1284
1285  template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
1286  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS iterator
1287  insert(const_iterator __pos, _InputIterator __first, _InputIterator __last);
1288
1289  template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>
1290  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS iterator
1291  insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last);
1292
1293  basic_string& erase(size_type __pos = 0, size_type __n = npos);
1294  _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __pos);
1295  _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __first, const_iterator __last);
1296
1297  _LIBCPP_HIDE_FROM_ABI basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str) {
1298    return replace(__pos1, __n1, __str.data(), __str.size());
1299  }
1300
1301  template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1302  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string&
1303  replace(size_type __pos1, size_type __n1, const _Tp& __t) {
1304    __self_view __sv = __t;
1305    return replace(__pos1, __n1, __sv.data(), __sv.size());
1306  }
1307
1308  basic_string&
1309  replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2 = npos);
1310
1311  template <class _Tp,
1312            __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1313                              !__is_same_uncvref<_Tp, basic_string>::value,
1314                          int> = 0>
1315  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string&
1316  replace(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2 = npos);
1317
1318  basic_string& replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2);
1319  basic_string& replace(size_type __pos, size_type __n1, const value_type* __s);
1320  basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c);
1321
1322  _LIBCPP_HIDE_FROM_ABI basic_string& replace(const_iterator __i1, const_iterator __i2, const basic_string& __str) {
1323    return replace(
1324        static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __str.data(), __str.size());
1325  }
1326
1327  template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1328  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string&
1329  replace(const_iterator __i1, const_iterator __i2, const _Tp& __t) {
1330    __self_view __sv = __t;
1331    return replace(__i1 - begin(), __i2 - __i1, __sv);
1332  }
1333
1334  _LIBCPP_HIDE_FROM_ABI basic_string&
1335  replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n) {
1336    return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s, __n);
1337  }
1338
1339  _LIBCPP_HIDE_FROM_ABI basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s) {
1340    return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s);
1341  }
1342
1343  _LIBCPP_HIDE_FROM_ABI basic_string& replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c) {
1344    return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __n, __c);
1345  }
1346
1347  template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0>
1348  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string&
1349  replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2);
1350
1351  size_type copy(value_type* __s, size_type __n, size_type __pos = 0) const;
1352
1353  _LIBCPP_HIDE_FROM_ABI basic_string substr(size_type __pos = 0, size_type __n = npos) const {
1354    return basic_string(*this, __pos, __n);
1355  }
1356
1357  _LIBCPP_HIDE_FROM_ABI void swap(basic_string& __str);
1358
1359  _LIBCPP_HIDE_FROM_ABI const value_type* c_str() const _NOEXCEPT { return data(); }
1360  _LIBCPP_HIDE_FROM_ABI const value_type* data() const _NOEXCEPT { return std::__to_address(__get_pointer()); }
1361
1362  _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT { return __alloc(); }
1363
1364  _LIBCPP_HIDE_FROM_ABI size_type find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
1365
1366  template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1367  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS size_type
1368  find(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
1369
1370  size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1371  _LIBCPP_HIDE_FROM_ABI size_type find(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
1372  size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT;
1373
1374  _LIBCPP_HIDE_FROM_ABI size_type rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
1375
1376  template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1377  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS size_type
1378  rfind(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
1379
1380  size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1381  _LIBCPP_HIDE_FROM_ABI size_type rfind(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
1382  size_type rfind(value_type __c, size_type __pos = npos) const _NOEXCEPT;
1383
1384  _LIBCPP_HIDE_FROM_ABI size_type find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
1385
1386  template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1387  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS size_type
1388  find_first_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
1389
1390  size_type find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1391  _LIBCPP_HIDE_FROM_ABI size_type find_first_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
1392  _LIBCPP_HIDE_FROM_ABI size_type find_first_of(value_type __c, size_type __pos = 0) const _NOEXCEPT;
1393
1394  _LIBCPP_HIDE_FROM_ABI size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
1395
1396  template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1397  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS size_type
1398  find_last_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
1399
1400  size_type find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1401  _LIBCPP_HIDE_FROM_ABI size_type find_last_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
1402  _LIBCPP_HIDE_FROM_ABI size_type find_last_of(value_type __c, size_type __pos = npos) const _NOEXCEPT;
1403
1404  _LIBCPP_HIDE_FROM_ABI size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
1405
1406  template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1407  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS size_type
1408  find_first_not_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
1409
1410  size_type find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1411  _LIBCPP_HIDE_FROM_ABI size_type find_first_not_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
1412  _LIBCPP_HIDE_FROM_ABI size_type find_first_not_of(value_type __c, size_type __pos = 0) const _NOEXCEPT;
1413
1414  _LIBCPP_HIDE_FROM_ABI size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
1415
1416  template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1417  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS size_type
1418  find_last_not_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
1419
1420  size_type find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1421  _LIBCPP_HIDE_FROM_ABI size_type find_last_not_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
1422  _LIBCPP_HIDE_FROM_ABI size_type find_last_not_of(value_type __c, size_type __pos = npos) const _NOEXCEPT;
1423
1424  _LIBCPP_HIDE_FROM_ABI int compare(const basic_string& __str) const _NOEXCEPT;
1425
1426  template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1427  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS int compare(const _Tp& __t) const _NOEXCEPT;
1428
1429  template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1430  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS int
1431  compare(size_type __pos1, size_type __n1, const _Tp& __t) const;
1432
1433  _LIBCPP_HIDE_FROM_ABI int compare(size_type __pos1, size_type __n1, const basic_string& __str) const;
1434  int compare(
1435      size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2 = npos) const;
1436
1437  template <class _Tp,
1438            __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1439                              !__is_same_uncvref<_Tp, basic_string>::value,
1440                          int> = 0>
1441  inline _LIBCPP_HIDE_FROM_ABI int
1442  compare(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2 = npos) const;
1443
1444  int compare(const value_type* __s) const _NOEXCEPT;
1445  int compare(size_type __pos1, size_type __n1, const value_type* __s) const;
1446  int compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const;
1447
1448  _LIBCPP_HIDE_FROM_ABI bool __invariants() const;
1449
1450  _LIBCPP_HIDE_FROM_ABI void __clear_and_shrink() _NOEXCEPT;
1451
1452private:
1453  template <class _Alloc>
1454  inline _LIBCPP_HIDE_FROM_ABI bool friend
1455  operator==(const basic_string<char, char_traits<char>, _Alloc>& __lhs,
1456             const basic_string<char, char_traits<char>, _Alloc>& __rhs) _NOEXCEPT;
1457
1458  _LIBCPP_HIDE_FROM_ABI void __shrink_or_extend(size_type __target_capacity);
1459
1460  _LIBCPP_HIDE_FROM_ABI _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS bool __is_long() const _NOEXCEPT {
1461    if (__libcpp_is_constant_evaluated() && __builtin_constant_p(__r_.first().__l.__is_long_)) {
1462      return __r_.first().__l.__is_long_;
1463    }
1464    return __r_.first().__s.__is_long_;
1465  }
1466
1467  static _LIBCPP_HIDE_FROM_ABI void __begin_lifetime(pointer __begin, size_type __n) {
1468    (void)__begin;
1469    (void)__n;
1470  }
1471
1472  _LIBCPP_HIDE_FROM_ABI static bool __fits_in_sso(size_type __sz) { return __sz < __min_cap; }
1473
1474  template <class _Iterator, class _Sentinel>
1475  _LIBCPP_HIDE_FROM_ABI void __assign_trivial(_Iterator __first, _Sentinel __last, size_type __n);
1476
1477  template <class _Iterator, class _Sentinel>
1478  _LIBCPP_HIDE_FROM_ABI void __assign_with_sentinel(_Iterator __first, _Sentinel __last);
1479
1480  // Copy [__first, __last) into [__dest, __dest + (__last - __first)). Assumes that the ranges don't overlap.
1481  template <class _ForwardIter, class _Sent>
1482  _LIBCPP_HIDE_FROM_ABI static value_type*
1483  __copy_non_overlapping_range(_ForwardIter __first, _Sent __last, value_type* __dest) {
1484    for (; __first != __last; ++__first)
1485      traits_type::assign(*__dest++, *__first);
1486    return __dest;
1487  }
1488
1489  template <class _ForwardIterator, class _Sentinel>
1490  _LIBCPP_HIDE_FROM_ABI iterator
1491  __insert_from_safe_copy(size_type __n, size_type __ip, _ForwardIterator __first, _Sentinel __last) {
1492    size_type __sz  = size();
1493    size_type __cap = capacity();
1494    value_type* __p;
1495    if (__cap - __sz >= __n) {
1496      __annotate_increase(__n);
1497      __p                = std::__to_address(__get_pointer());
1498      size_type __n_move = __sz - __ip;
1499      if (__n_move != 0)
1500        traits_type::move(__p + __ip + __n, __p + __ip, __n_move);
1501    } else {
1502      __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __ip, 0, __n);
1503      __p = std::__to_address(__get_long_pointer());
1504    }
1505    __sz += __n;
1506    __set_size(__sz);
1507    traits_type::assign(__p[__sz], value_type());
1508    __copy_non_overlapping_range(__first, __last, __p + __ip);
1509
1510    return begin() + __ip;
1511  }
1512
1513  template <class _Iterator, class _Sentinel>
1514  iterator __insert_with_size(const_iterator __pos, _Iterator __first, _Sentinel __last, size_type __n);
1515
1516  _LIBCPP_HIDE_FROM_ABI allocator_type& __alloc() _NOEXCEPT { return __r_.second(); }
1517  _LIBCPP_HIDE_FROM_ABI const allocator_type& __alloc() const _NOEXCEPT { return __r_.second(); }
1518
1519  _LIBCPP_HIDE_FROM_ABI _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS void __set_short_size(size_type __s) _NOEXCEPT {
1520    _LIBCPP_ASSERT_INTERNAL(__s < __min_cap, "__s should never be greater than or equal to the short string capacity");
1521    __r_.first().__s.__size_    = __s;
1522    __r_.first().__s.__is_long_ = false;
1523  }
1524
1525  _LIBCPP_HIDE_FROM_ABI _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS size_type __get_short_size() const _NOEXCEPT {
1526    _LIBCPP_ASSERT_INTERNAL(!__r_.first().__s.__is_long_, "String has to be short when trying to get the short size");
1527    return __r_.first().__s.__size_;
1528  }
1529
1530  _LIBCPP_HIDE_FROM_ABI void __set_long_size(size_type __s) _NOEXCEPT { __r_.first().__l.__size_ = __s; }
1531  _LIBCPP_HIDE_FROM_ABI size_type __get_long_size() const _NOEXCEPT { return __r_.first().__l.__size_; }
1532  _LIBCPP_HIDE_FROM_ABI void __set_size(size_type __s) _NOEXCEPT {
1533    if (__is_long())
1534      __set_long_size(__s);
1535    else
1536      __set_short_size(__s);
1537  }
1538
1539  _LIBCPP_HIDE_FROM_ABI void __set_long_cap(size_type __s) _NOEXCEPT {
1540    __r_.first().__l.__cap_     = __s / __endian_factor;
1541    __r_.first().__l.__is_long_ = true;
1542  }
1543
1544  _LIBCPP_HIDE_FROM_ABI size_type __get_long_cap() const _NOEXCEPT { return __r_.first().__l.__cap_ * __endian_factor; }
1545
1546  _LIBCPP_HIDE_FROM_ABI void __set_long_pointer(pointer __p) _NOEXCEPT { __r_.first().__l.__data_ = __p; }
1547  _LIBCPP_HIDE_FROM_ABI pointer __get_long_pointer() _NOEXCEPT {
1548    return _LIBCPP_ASAN_VOLATILE_WRAPPER(__r_.first().__l.__data_);
1549  }
1550  _LIBCPP_HIDE_FROM_ABI const_pointer __get_long_pointer() const _NOEXCEPT {
1551    return _LIBCPP_ASAN_VOLATILE_WRAPPER(__r_.first().__l.__data_);
1552  }
1553  _LIBCPP_HIDE_FROM_ABI _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS pointer __get_short_pointer() _NOEXCEPT {
1554    return _LIBCPP_ASAN_VOLATILE_WRAPPER(pointer_traits<pointer>::pointer_to(__r_.first().__s.__data_[0]));
1555  }
1556  _LIBCPP_HIDE_FROM_ABI _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS const_pointer __get_short_pointer() const _NOEXCEPT {
1557    return _LIBCPP_ASAN_VOLATILE_WRAPPER(pointer_traits<const_pointer>::pointer_to(__r_.first().__s.__data_[0]));
1558  }
1559  _LIBCPP_HIDE_FROM_ABI pointer __get_pointer() _NOEXCEPT {
1560    return __is_long() ? __get_long_pointer() : __get_short_pointer();
1561  }
1562  _LIBCPP_HIDE_FROM_ABI const_pointer __get_pointer() const _NOEXCEPT {
1563    return __is_long() ? __get_long_pointer() : __get_short_pointer();
1564  }
1565
1566  // The following functions are no-ops outside of AddressSanitizer mode.
1567  _LIBCPP_HIDE_FROM_ABI void __annotate_contiguous_container(const void* __old_mid, const void* __new_mid) const {
1568    (void)__old_mid;
1569    (void)__new_mid;
1570#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN)
1571#  if defined(__APPLE__)
1572    // TODO: remove after addressing issue #96099 (https://github.com/llvm/llvm-project/issues/96099)
1573    if (!__is_long())
1574      return;
1575#  endif
1576    std::__annotate_contiguous_container<_Allocator>(data(), data() + capacity() + 1, __old_mid, __new_mid);
1577#endif
1578  }
1579
1580  _LIBCPP_HIDE_FROM_ABI void __annotate_new(size_type __current_size) const _NOEXCEPT {
1581    (void)__current_size;
1582#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN)
1583    if (!__libcpp_is_constant_evaluated())
1584      __annotate_contiguous_container(data() + capacity() + 1, data() + __current_size + 1);
1585#endif
1586  }
1587
1588  _LIBCPP_HIDE_FROM_ABI void __annotate_delete() const _NOEXCEPT {
1589#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN)
1590    if (!__libcpp_is_constant_evaluated())
1591      __annotate_contiguous_container(data() + size() + 1, data() + capacity() + 1);
1592#endif
1593  }
1594
1595  _LIBCPP_HIDE_FROM_ABI void __annotate_increase(size_type __n) const _NOEXCEPT {
1596    (void)__n;
1597#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN)
1598    if (!__libcpp_is_constant_evaluated())
1599      __annotate_contiguous_container(data() + size() + 1, data() + size() + 1 + __n);
1600#endif
1601  }
1602
1603  _LIBCPP_HIDE_FROM_ABI void __annotate_shrink(size_type __old_size) const _NOEXCEPT {
1604    (void)__old_size;
1605#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN)
1606    if (!__libcpp_is_constant_evaluated())
1607      __annotate_contiguous_container(data() + __old_size + 1, data() + size() + 1);
1608#endif
1609  }
1610
1611  template <size_type __a>
1612  static _LIBCPP_HIDE_FROM_ABI size_type __align_it(size_type __s) _NOEXCEPT {
1613    return (__s + (__a - 1)) & ~(__a - 1);
1614  }
1615  enum { __alignment = 8 };
1616  static _LIBCPP_HIDE_FROM_ABI size_type __recommend(size_type __s) _NOEXCEPT {
1617    if (__s < __min_cap) {
1618      return static_cast<size_type>(__min_cap) - 1;
1619    }
1620    const size_type __boundary = sizeof(value_type) < __alignment ? __alignment / sizeof(value_type) : __endian_factor;
1621    size_type __guess          = __align_it<__boundary>(__s + 1) - 1;
1622    if (__guess == __min_cap)
1623      __guess += __endian_factor;
1624    return __guess;
1625  }
1626
1627  inline void __init(const value_type* __s, size_type __sz, size_type __reserve);
1628  inline void __init(const value_type* __s, size_type __sz);
1629  inline void __init(size_type __n, value_type __c);
1630
1631  // Slow path for the (inlined) copy constructor for 'long' strings.
1632  // Always externally instantiated and not inlined.
1633  // Requires that __s is zero terminated.
1634  // The main reason for this function to exist is because for unstable, we
1635  // want to allow inlining of the copy constructor. However, we don't want
1636  // to call the __init() functions as those are marked as inline which may
1637  // result in over-aggressive inlining by the compiler, where our aim is
1638  // to only inline the fast path code directly in the ctor.
1639  _LIBCPP_NOINLINE void __init_copy_ctor_external(const value_type* __s, size_type __sz);
1640
1641  template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
1642  inline void __init(_InputIterator __first, _InputIterator __last);
1643
1644  template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>
1645  inline void __init(_ForwardIterator __first, _ForwardIterator __last);
1646
1647  template <class _InputIterator, class _Sentinel>
1648  _LIBCPP_HIDE_FROM_ABI void __init_with_sentinel(_InputIterator __first, _Sentinel __last);
1649  template <class _InputIterator, class _Sentinel>
1650  _LIBCPP_HIDE_FROM_ABI void __init_with_size(_InputIterator __first, _Sentinel __last, size_type __sz);
1651
1652#if _LIBCPP_ABI_VERSION >= 2 //  We want to use the function in the dylib in ABIv1
1653  _LIBCPP_HIDE_FROM_ABI
1654#endif
1655  _LIBCPP_DEPRECATED_("use __grow_by_without_replace") void __grow_by(
1656      size_type __old_cap,
1657      size_type __delta_cap,
1658      size_type __old_sz,
1659      size_type __n_copy,
1660      size_type __n_del,
1661      size_type __n_add = 0);
1662  _LIBCPP_HIDE_FROM_ABI void __grow_by_without_replace(
1663      size_type __old_cap,
1664      size_type __delta_cap,
1665      size_type __old_sz,
1666      size_type __n_copy,
1667      size_type __n_del,
1668      size_type __n_add = 0);
1669  void __grow_by_and_replace(
1670      size_type __old_cap,
1671      size_type __delta_cap,
1672      size_type __old_sz,
1673      size_type __n_copy,
1674      size_type __n_del,
1675      size_type __n_add,
1676      const value_type* __p_new_stuff);
1677
1678  // __assign_no_alias is invoked for assignment operations where we
1679  // have proof that the input does not alias the current instance.
1680  // For example, operator=(basic_string) performs a 'self' check.
1681  template <bool __is_short>
1682  _LIBCPP_NOINLINE basic_string& __assign_no_alias(const value_type* __s, size_type __n);
1683
1684  _LIBCPP_HIDE_FROM_ABI void __erase_to_end(size_type __pos) {
1685    __null_terminate_at(std::__to_address(__get_pointer()), __pos);
1686  }
1687
1688  // __erase_external_with_move is invoked for erase() invocations where
1689  // `n ~= npos`, likely requiring memory moves on the string data.
1690  _LIBCPP_NOINLINE void __erase_external_with_move(size_type __pos, size_type __n);
1691
1692  _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const basic_string& __str) {
1693    __copy_assign_alloc(
1694        __str, integral_constant<bool, __alloc_traits::propagate_on_container_copy_assignment::value>());
1695  }
1696
1697  _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const basic_string& __str, true_type) {
1698    if (__alloc() == __str.__alloc())
1699      __alloc() = __str.__alloc();
1700    else {
1701      if (!__str.__is_long()) {
1702        __clear_and_shrink();
1703        __alloc() = __str.__alloc();
1704      } else {
1705        __annotate_delete();
1706        allocator_type __a = __str.__alloc();
1707        auto __allocation  = std::__allocate_at_least(__a, __str.__get_long_cap());
1708        __begin_lifetime(__allocation.ptr, __allocation.count);
1709        if (__is_long())
1710          __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
1711        __alloc() = std::move(__a);
1712        __set_long_pointer(__allocation.ptr);
1713        __set_long_cap(__allocation.count);
1714        __set_long_size(__str.size());
1715        __annotate_new(__get_long_size());
1716      }
1717    }
1718  }
1719
1720  _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const basic_string&, false_type) _NOEXCEPT {}
1721
1722  _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(basic_string& __str) {
1723    __move_assign_alloc(
1724        __str, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>());
1725  }
1726
1727  _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(basic_string& __c, true_type) { __alloc() = std::move(__c.__alloc()); }
1728
1729  _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(basic_string&, false_type) _NOEXCEPT {}
1730
1731  _LIBCPP_NOINLINE basic_string& __assign_external(const value_type* __s);
1732  _LIBCPP_NOINLINE basic_string& __assign_external(const value_type* __s, size_type __n);
1733
1734  // Assigns the value in __s, guaranteed to be __n < __min_cap in length.
1735  inline basic_string& __assign_short(const value_type* __s, size_type __n) {
1736    size_type __old_size = size();
1737    if (__n > __old_size)
1738      __annotate_increase(__n - __old_size);
1739    pointer __p =
1740        __is_long() ? (__set_long_size(__n), __get_long_pointer()) : (__set_short_size(__n), __get_short_pointer());
1741    traits_type::move(std::__to_address(__p), __s, __n);
1742    traits_type::assign(__p[__n], value_type());
1743    if (__old_size > __n)
1744      __annotate_shrink(__old_size);
1745    return *this;
1746  }
1747
1748  _LIBCPP_HIDE_FROM_ABI basic_string& __null_terminate_at(value_type* __p, size_type __newsz) {
1749    size_type __old_size = size();
1750    if (__newsz > __old_size)
1751      __annotate_increase(__newsz - __old_size);
1752    __set_size(__newsz);
1753    traits_type::assign(__p[__newsz], value_type());
1754    if (__old_size > __newsz)
1755      __annotate_shrink(__old_size);
1756    return *this;
1757  }
1758
1759  template <class _Tp>
1760  _LIBCPP_HIDE_FROM_ABI bool __addr_in_range(const _Tp& __v) const {
1761    return std::__is_pointer_in_range(data(), data() + size() + 1, std::addressof(__v));
1762  }
1763
1764  _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void __throw_length_error() const {
1765    std::__throw_length_error("basic_string");
1766  }
1767
1768  _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void __throw_out_of_range() const {
1769    std::__throw_out_of_range("basic_string");
1770  }
1771
1772  friend basic_string operator+ <>(const basic_string&, const basic_string&);
1773  friend basic_string operator+ <>(const value_type*, const basic_string&);
1774  friend basic_string operator+ <>(value_type, const basic_string&);
1775  friend basic_string operator+ <>(const basic_string&, const value_type*);
1776  friend basic_string operator+ <>(const basic_string&, value_type);
1777};
1778
1779// These declarations must appear before any functions are implicitly used
1780// so that they have the correct visibility specifier.
1781#define _LIBCPP_DECLARE(...) extern template __VA_ARGS__;
1782#ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
1783_LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, char)
1784#  ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
1785_LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, wchar_t)
1786#  endif
1787#else
1788_LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, char)
1789#  ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
1790_LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, wchar_t)
1791#  endif
1792#endif
1793#undef _LIBCPP_DECLARE
1794
1795template <class _CharT, class _Traits, class _Allocator>
1796void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz, size_type __reserve) {
1797  if (__libcpp_is_constant_evaluated())
1798    __r_.first() = __rep();
1799  if (__reserve > max_size())
1800    __throw_length_error();
1801  pointer __p;
1802  if (__fits_in_sso(__reserve)) {
1803    __set_short_size(__sz);
1804    __p = __get_short_pointer();
1805  } else {
1806    auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__reserve) + 1);
1807    __p               = __allocation.ptr;
1808    __begin_lifetime(__p, __allocation.count);
1809    __set_long_pointer(__p);
1810    __set_long_cap(__allocation.count);
1811    __set_long_size(__sz);
1812  }
1813  traits_type::copy(std::__to_address(__p), __s, __sz);
1814  traits_type::assign(__p[__sz], value_type());
1815  __annotate_new(__sz);
1816}
1817
1818template <class _CharT, class _Traits, class _Allocator>
1819void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz) {
1820  if (__libcpp_is_constant_evaluated())
1821    __r_.first() = __rep();
1822  if (__sz > max_size())
1823    __throw_length_error();
1824  pointer __p;
1825  if (__fits_in_sso(__sz)) {
1826    __set_short_size(__sz);
1827    __p = __get_short_pointer();
1828  } else {
1829    auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1);
1830    __p               = __allocation.ptr;
1831    __begin_lifetime(__p, __allocation.count);
1832    __set_long_pointer(__p);
1833    __set_long_cap(__allocation.count);
1834    __set_long_size(__sz);
1835  }
1836  traits_type::copy(std::__to_address(__p), __s, __sz);
1837  traits_type::assign(__p[__sz], value_type());
1838  __annotate_new(__sz);
1839}
1840
1841template <class _CharT, class _Traits, class _Allocator>
1842_LIBCPP_NOINLINE void
1843basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external(const value_type* __s, size_type __sz) {
1844  if (__libcpp_is_constant_evaluated())
1845    __r_.first() = __rep();
1846
1847  pointer __p;
1848  if (__fits_in_sso(__sz)) {
1849    __p = __get_short_pointer();
1850    __set_short_size(__sz);
1851  } else {
1852    if (__sz > max_size())
1853      __throw_length_error();
1854    auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1);
1855    __p               = __allocation.ptr;
1856    __begin_lifetime(__p, __allocation.count);
1857    __set_long_pointer(__p);
1858    __set_long_cap(__allocation.count);
1859    __set_long_size(__sz);
1860  }
1861  traits_type::copy(std::__to_address(__p), __s, __sz + 1);
1862  __annotate_new(__sz);
1863}
1864
1865template <class _CharT, class _Traits, class _Allocator>
1866void basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c) {
1867  if (__libcpp_is_constant_evaluated())
1868    __r_.first() = __rep();
1869
1870  if (__n > max_size())
1871    __throw_length_error();
1872  pointer __p;
1873  if (__fits_in_sso(__n)) {
1874    __set_short_size(__n);
1875    __p = __get_short_pointer();
1876  } else {
1877    auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__n) + 1);
1878    __p               = __allocation.ptr;
1879    __begin_lifetime(__p, __allocation.count);
1880    __set_long_pointer(__p);
1881    __set_long_cap(__allocation.count);
1882    __set_long_size(__n);
1883  }
1884  traits_type::assign(std::__to_address(__p), __n, __c);
1885  traits_type::assign(__p[__n], value_type());
1886  __annotate_new(__n);
1887}
1888
1889template <class _CharT, class _Traits, class _Allocator>
1890template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> >
1891void basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last) {
1892  __init_with_sentinel(std::move(__first), std::move(__last));
1893}
1894
1895template <class _CharT, class _Traits, class _Allocator>
1896template <class _InputIterator, class _Sentinel>
1897_LIBCPP_HIDE_FROM_ABI void
1898basic_string<_CharT, _Traits, _Allocator>::__init_with_sentinel(_InputIterator __first, _Sentinel __last) {
1899  __r_.first() = __rep();
1900  __annotate_new(0);
1901
1902#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1903  try {
1904#endif // _LIBCPP_HAS_NO_EXCEPTIONS
1905    for (; __first != __last; ++__first)
1906      push_back(*__first);
1907#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1908  } catch (...) {
1909    __annotate_delete();
1910    if (__is_long())
1911      __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
1912    throw;
1913  }
1914#endif // _LIBCPP_HAS_NO_EXCEPTIONS
1915}
1916
1917template <class _CharT, class _Traits, class _Allocator>
1918template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> >
1919void basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last) {
1920  size_type __sz = static_cast<size_type>(std::distance(__first, __last));
1921  __init_with_size(__first, __last, __sz);
1922}
1923
1924template <class _CharT, class _Traits, class _Allocator>
1925template <class _InputIterator, class _Sentinel>
1926_LIBCPP_HIDE_FROM_ABI void
1927basic_string<_CharT, _Traits, _Allocator>::__init_with_size(_InputIterator __first, _Sentinel __last, size_type __sz) {
1928  if (__libcpp_is_constant_evaluated())
1929    __r_.first() = __rep();
1930
1931  if (__sz > max_size())
1932    __throw_length_error();
1933
1934  pointer __p;
1935  if (__fits_in_sso(__sz)) {
1936    __set_short_size(__sz);
1937    __p = __get_short_pointer();
1938
1939  } else {
1940    auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1);
1941    __p               = __allocation.ptr;
1942    __begin_lifetime(__p, __allocation.count);
1943    __set_long_pointer(__p);
1944    __set_long_cap(__allocation.count);
1945    __set_long_size(__sz);
1946  }
1947
1948#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1949  try {
1950#endif // _LIBCPP_HAS_NO_EXCEPTIONS
1951    auto __end = __copy_non_overlapping_range(__first, __last, std::__to_address(__p));
1952    traits_type::assign(*__end, value_type());
1953#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1954  } catch (...) {
1955    if (__is_long())
1956      __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
1957    throw;
1958  }
1959#endif // _LIBCPP_HAS_NO_EXCEPTIONS
1960  __annotate_new(__sz);
1961}
1962
1963template <class _CharT, class _Traits, class _Allocator>
1964void basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace(
1965    size_type __old_cap,
1966    size_type __delta_cap,
1967    size_type __old_sz,
1968    size_type __n_copy,
1969    size_type __n_del,
1970    size_type __n_add,
1971    const value_type* __p_new_stuff) {
1972  size_type __ms = max_size();
1973  if (__delta_cap > __ms - __old_cap - 1)
1974    __throw_length_error();
1975  pointer __old_p = __get_pointer();
1976  size_type __cap =
1977      __old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms - 1;
1978  __annotate_delete();
1979  auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1);
1980  pointer __p       = __allocation.ptr;
1981  __begin_lifetime(__p, __allocation.count);
1982  if (__n_copy != 0)
1983    traits_type::copy(std::__to_address(__p), std::__to_address(__old_p), __n_copy);
1984  if (__n_add != 0)
1985    traits_type::copy(std::__to_address(__p) + __n_copy, __p_new_stuff, __n_add);
1986  size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
1987  if (__sec_cp_sz != 0)
1988    traits_type::copy(
1989        std::__to_address(__p) + __n_copy + __n_add, std::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz);
1990  if (__old_cap + 1 != __min_cap)
1991    __alloc_traits::deallocate(__alloc(), __old_p, __old_cap + 1);
1992  __set_long_pointer(__p);
1993  __set_long_cap(__allocation.count);
1994  __old_sz = __n_copy + __n_add + __sec_cp_sz;
1995  __set_long_size(__old_sz);
1996  traits_type::assign(__p[__old_sz], value_type());
1997  __annotate_new(__old_sz);
1998}
1999
2000// __grow_by is deprecated because it does not set the size. It may not update the size when the size is changed, and it
2001// may also not set the size at all when the string was short initially. This leads to unpredictable size value. It is
2002// not removed or changed to avoid breaking the ABI.
2003template <class _CharT, class _Traits, class _Allocator>
2004void
2005#if _LIBCPP_ABI_VERSION >= 2 // We want to use the function in the dylib in ABIv1
2006    _LIBCPP_HIDE_FROM_ABI
2007#endif
2008    _LIBCPP_DEPRECATED_("use __grow_by_without_replace") basic_string<_CharT, _Traits, _Allocator>::__grow_by(
2009        size_type __old_cap,
2010        size_type __delta_cap,
2011        size_type __old_sz,
2012        size_type __n_copy,
2013        size_type __n_del,
2014        size_type __n_add) {
2015  size_type __ms = max_size();
2016  if (__delta_cap > __ms - __old_cap)
2017    __throw_length_error();
2018  pointer __old_p = __get_pointer();
2019  size_type __cap =
2020      __old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms - 1;
2021  __annotate_delete();
2022  auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1);
2023  pointer __p       = __allocation.ptr;
2024  __begin_lifetime(__p, __allocation.count);
2025  if (__n_copy != 0)
2026    traits_type::copy(std::__to_address(__p), std::__to_address(__old_p), __n_copy);
2027  size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
2028  if (__sec_cp_sz != 0)
2029    traits_type::copy(
2030        std::__to_address(__p) + __n_copy + __n_add, std::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz);
2031  if (__old_cap + 1 != __min_cap)
2032    __alloc_traits::deallocate(__alloc(), __old_p, __old_cap + 1);
2033  __set_long_pointer(__p);
2034  __set_long_cap(__allocation.count);
2035}
2036
2037template <class _CharT, class _Traits, class _Allocator>
2038void _LIBCPP_HIDE_FROM_ABI basic_string<_CharT, _Traits, _Allocator>::__grow_by_without_replace(
2039    size_type __old_cap,
2040    size_type __delta_cap,
2041    size_type __old_sz,
2042    size_type __n_copy,
2043    size_type __n_del,
2044    size_type __n_add) {
2045  _LIBCPP_SUPPRESS_DEPRECATED_PUSH
2046  __grow_by(__old_cap, __delta_cap, __old_sz, __n_copy, __n_del, __n_add);
2047  _LIBCPP_SUPPRESS_DEPRECATED_POP
2048  __set_long_size(__old_sz - __n_del + __n_add);
2049  __annotate_new(__old_sz - __n_del + __n_add);
2050}
2051
2052// assign
2053
2054template <class _CharT, class _Traits, class _Allocator>
2055template <bool __is_short>
2056_LIBCPP_NOINLINE basic_string<_CharT, _Traits, _Allocator>&
2057basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias(const value_type* __s, size_type __n) {
2058  size_type __cap = __is_short ? static_cast<size_type>(__min_cap) : __get_long_cap();
2059  if (__n < __cap) {
2060    size_type __old_size = __is_short ? __get_short_size() : __get_long_size();
2061    if (__n > __old_size)
2062      __annotate_increase(__n - __old_size);
2063    pointer __p = __is_short ? __get_short_pointer() : __get_long_pointer();
2064    __is_short ? __set_short_size(__n) : __set_long_size(__n);
2065    traits_type::copy(std::__to_address(__p), __s, __n);
2066    traits_type::assign(__p[__n], value_type());
2067    if (__old_size > __n)
2068      __annotate_shrink(__old_size);
2069  } else {
2070    size_type __sz = __is_short ? __get_short_size() : __get_long_size();
2071    __grow_by_and_replace(__cap - 1, __n - __cap + 1, __sz, 0, __sz, __n, __s);
2072  }
2073  return *this;
2074}
2075
2076template <class _CharT, class _Traits, class _Allocator>
2077_LIBCPP_NOINLINE basic_string<_CharT, _Traits, _Allocator>&
2078basic_string<_CharT, _Traits, _Allocator>::__assign_external(const value_type* __s, size_type __n) {
2079  size_type __cap = capacity();
2080  if (__cap >= __n) {
2081    size_type __old_size = size();
2082    if (__n > __old_size)
2083      __annotate_increase(__n - __old_size);
2084    value_type* __p = std::__to_address(__get_pointer());
2085    traits_type::move(__p, __s, __n);
2086    return __null_terminate_at(__p, __n);
2087  } else {
2088    size_type __sz = size();
2089    __grow_by_and_replace(__cap, __n - __cap, __sz, 0, __sz, __n, __s);
2090    return *this;
2091  }
2092}
2093
2094template <class _CharT, class _Traits, class _Allocator>
2095basic_string<_CharT, _Traits, _Allocator>&
2096basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n) {
2097  _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::assign received nullptr");
2098  return (__builtin_constant_p(__n) && __fits_in_sso(__n)) ? __assign_short(__s, __n) : __assign_external(__s, __n);
2099}
2100
2101template <class _CharT, class _Traits, class _Allocator>
2102basic_string<_CharT, _Traits, _Allocator>&
2103basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c) {
2104  size_type __cap      = capacity();
2105  size_type __old_size = size();
2106  if (__cap < __n) {
2107    size_type __sz = size();
2108    __grow_by_without_replace(__cap, __n - __cap, __sz, 0, __sz);
2109    __annotate_increase(__n);
2110  } else if (__n > __old_size)
2111    __annotate_increase(__n - __old_size);
2112  value_type* __p = std::__to_address(__get_pointer());
2113  traits_type::assign(__p, __n, __c);
2114  return __null_terminate_at(__p, __n);
2115}
2116
2117template <class _CharT, class _Traits, class _Allocator>
2118basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c) {
2119  pointer __p;
2120  size_type __old_size = size();
2121  if (__old_size == 0)
2122    __annotate_increase(1);
2123  if (__is_long()) {
2124    __p = __get_long_pointer();
2125    __set_long_size(1);
2126  } else {
2127    __p = __get_short_pointer();
2128    __set_short_size(1);
2129  }
2130  traits_type::assign(*__p, __c);
2131  traits_type::assign(*++__p, value_type());
2132  if (__old_size > 1)
2133    __annotate_shrink(__old_size);
2134  return *this;
2135}
2136
2137template <class _CharT, class _Traits, class _Allocator>
2138_LIBCPP_STRING_INTERNAL_MEMORY_ACCESS basic_string<_CharT, _Traits, _Allocator>&
2139basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str) {
2140  if (this != std::addressof(__str)) {
2141    __copy_assign_alloc(__str);
2142    if (!__is_long()) {
2143      if (!__str.__is_long()) {
2144        size_type __old_size = __get_short_size();
2145        if (__get_short_size() < __str.__get_short_size())
2146          __annotate_increase(__str.__get_short_size() - __get_short_size());
2147        __r_.first() = __str.__r_.first();
2148        if (__old_size > __get_short_size())
2149          __annotate_shrink(__old_size);
2150      } else {
2151        return __assign_no_alias<true>(__str.data(), __str.size());
2152      }
2153    } else {
2154      return __assign_no_alias<false>(__str.data(), __str.size());
2155    }
2156  }
2157  return *this;
2158}
2159
2160template <class _CharT, class _Traits, class _Allocator>
2161template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> >
2162basic_string<_CharT, _Traits, _Allocator>&
2163basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last) {
2164  __assign_with_sentinel(__first, __last);
2165  return *this;
2166}
2167
2168template <class _CharT, class _Traits, class _Allocator>
2169template <class _InputIterator, class _Sentinel>
2170_LIBCPP_HIDE_FROM_ABI void
2171basic_string<_CharT, _Traits, _Allocator>::__assign_with_sentinel(_InputIterator __first, _Sentinel __last) {
2172  const basic_string __temp(__init_with_sentinel_tag(), std::move(__first), std::move(__last), __alloc());
2173  assign(__temp.data(), __temp.size());
2174}
2175
2176template <class _CharT, class _Traits, class _Allocator>
2177template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> >
2178basic_string<_CharT, _Traits, _Allocator>&
2179basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last) {
2180  if (__string_is_trivial_iterator<_ForwardIterator>::value) {
2181    size_type __n = static_cast<size_type>(std::distance(__first, __last));
2182    __assign_trivial(__first, __last, __n);
2183  } else {
2184    __assign_with_sentinel(__first, __last);
2185  }
2186
2187  return *this;
2188}
2189
2190template <class _CharT, class _Traits, class _Allocator>
2191template <class _Iterator, class _Sentinel>
2192_LIBCPP_HIDE_FROM_ABI void
2193basic_string<_CharT, _Traits, _Allocator>::__assign_trivial(_Iterator __first, _Sentinel __last, size_type __n) {
2194  _LIBCPP_ASSERT_INTERNAL(
2195      __string_is_trivial_iterator<_Iterator>::value, "The iterator type given to `__assign_trivial` must be trivial");
2196
2197  size_type __old_size = size();
2198  size_type __cap      = capacity();
2199  if (__cap < __n) {
2200    // Unlike `append` functions, if the input range points into the string itself, there is no case that the input
2201    // range could get invalidated by reallocation:
2202    // 1. If the input range is a subset of the string itself, its size cannot exceed the capacity of the string,
2203    //    thus no reallocation would happen.
2204    // 2. In the exotic case where the input range is the byte representation of the string itself, the string
2205    //    object itself stays valid even if reallocation happens.
2206    size_type __sz = size();
2207    __grow_by_without_replace(__cap, __n - __cap, __sz, 0, __sz);
2208    __annotate_increase(__n);
2209  } else if (__n > __old_size)
2210    __annotate_increase(__n - __old_size);
2211  pointer __p = __get_pointer();
2212  for (; __first != __last; ++__p, (void)++__first)
2213    traits_type::assign(*__p, *__first);
2214  traits_type::assign(*__p, value_type());
2215  __set_size(__n);
2216  if (__n < __old_size)
2217    __annotate_shrink(__old_size);
2218}
2219
2220template <class _CharT, class _Traits, class _Allocator>
2221basic_string<_CharT, _Traits, _Allocator>&
2222basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, size_type __pos, size_type __n) {
2223  size_type __sz = __str.size();
2224  if (__pos > __sz)
2225    __throw_out_of_range();
2226  return assign(__str.data() + __pos, std::min(__n, __sz - __pos));
2227}
2228
2229template <class _CharT, class _Traits, class _Allocator>
2230template <class _Tp,
2231          __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
2232                            !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
2233                        int> >
2234basic_string<_CharT, _Traits, _Allocator>&
2235basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp& __t, size_type __pos, size_type __n) {
2236  __self_view __sv = __t;
2237  size_type __sz   = __sv.size();
2238  if (__pos > __sz)
2239    __throw_out_of_range();
2240  return assign(__sv.data() + __pos, std::min(__n, __sz - __pos));
2241}
2242
2243template <class _CharT, class _Traits, class _Allocator>
2244_LIBCPP_NOINLINE basic_string<_CharT, _Traits, _Allocator>&
2245basic_string<_CharT, _Traits, _Allocator>::__assign_external(const value_type* __s) {
2246  return __assign_external(__s, traits_type::length(__s));
2247}
2248
2249template <class _CharT, class _Traits, class _Allocator>
2250basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s) {
2251  _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::assign received nullptr");
2252  return __builtin_constant_p(*__s)
2253           ? (__fits_in_sso(traits_type::length(__s)) ? __assign_short(__s, traits_type::length(__s))
2254                                                      : __assign_external(__s, traits_type::length(__s)))
2255           : __assign_external(__s);
2256}
2257// append
2258
2259template <class _CharT, class _Traits, class _Allocator>
2260basic_string<_CharT, _Traits, _Allocator>&
2261basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n) {
2262  _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::append received nullptr");
2263  size_type __cap = capacity();
2264  size_type __sz  = size();
2265  if (__cap - __sz >= __n) {
2266    if (__n) {
2267      __annotate_increase(__n);
2268      value_type* __p = std::__to_address(__get_pointer());
2269      traits_type::copy(__p + __sz, __s, __n);
2270      __sz += __n;
2271      __set_size(__sz);
2272      traits_type::assign(__p[__sz], value_type());
2273    }
2274  } else
2275    __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __sz, 0, __n, __s);
2276  return *this;
2277}
2278
2279template <class _CharT, class _Traits, class _Allocator>
2280basic_string<_CharT, _Traits, _Allocator>&
2281basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c) {
2282  if (__n) {
2283    size_type __cap = capacity();
2284    size_type __sz  = size();
2285    if (__cap - __sz < __n)
2286      __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
2287    __annotate_increase(__n);
2288    pointer __p = __get_pointer();
2289    traits_type::assign(std::__to_address(__p) + __sz, __n, __c);
2290    __sz += __n;
2291    __set_size(__sz);
2292    traits_type::assign(__p[__sz], value_type());
2293  }
2294  return *this;
2295}
2296
2297template <class _CharT, class _Traits, class _Allocator>
2298inline void basic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n) {
2299  if (__n) {
2300    size_type __cap = capacity();
2301    size_type __sz  = size();
2302    if (__cap - __sz < __n)
2303      __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
2304    __annotate_increase(__n);
2305    pointer __p = __get_pointer();
2306    __sz += __n;
2307    __set_size(__sz);
2308    traits_type::assign(__p[__sz], value_type());
2309  }
2310}
2311
2312template <class _CharT, class _Traits, class _Allocator>
2313void basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c) {
2314  bool __is_short = !__is_long();
2315  size_type __cap;
2316  size_type __sz;
2317  if (__is_short) {
2318    __cap = __min_cap - 1;
2319    __sz  = __get_short_size();
2320  } else {
2321    __cap = __get_long_cap() - 1;
2322    __sz  = __get_long_size();
2323  }
2324  if (__sz == __cap) {
2325    __grow_by_without_replace(__cap, 1, __sz, __sz, 0);
2326    __annotate_increase(1);
2327    __is_short = false; // the string is always long after __grow_by
2328  } else
2329    __annotate_increase(1);
2330  pointer __p = __get_pointer();
2331  if (__is_short) {
2332    __p = __get_short_pointer() + __sz;
2333    __set_short_size(__sz + 1);
2334  } else {
2335    __p = __get_long_pointer() + __sz;
2336    __set_long_size(__sz + 1);
2337  }
2338  traits_type::assign(*__p, __c);
2339  traits_type::assign(*++__p, value_type());
2340}
2341
2342template <class _CharT, class _Traits, class _Allocator>
2343template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> >
2344basic_string<_CharT, _Traits, _Allocator>&
2345basic_string<_CharT, _Traits, _Allocator>::append(_ForwardIterator __first, _ForwardIterator __last) {
2346  size_type __sz  = size();
2347  size_type __cap = capacity();
2348  size_type __n   = static_cast<size_type>(std::distance(__first, __last));
2349  if (__n) {
2350    if (__string_is_trivial_iterator<_ForwardIterator>::value && !__addr_in_range(*__first)) {
2351      if (__cap - __sz < __n)
2352        __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
2353      __annotate_increase(__n);
2354      auto __end = __copy_non_overlapping_range(__first, __last, std::__to_address(__get_pointer() + __sz));
2355      traits_type::assign(*__end, value_type());
2356      __set_size(__sz + __n);
2357    } else {
2358      const basic_string __temp(__first, __last, __alloc());
2359      append(__temp.data(), __temp.size());
2360    }
2361  }
2362  return *this;
2363}
2364
2365template <class _CharT, class _Traits, class _Allocator>
2366basic_string<_CharT, _Traits, _Allocator>&
2367basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, size_type __pos, size_type __n) {
2368  size_type __sz = __str.size();
2369  if (__pos > __sz)
2370    __throw_out_of_range();
2371  return append(__str.data() + __pos, std::min(__n, __sz - __pos));
2372}
2373
2374template <class _CharT, class _Traits, class _Allocator>
2375template <class _Tp,
2376          __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
2377                            !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
2378                        int> >
2379basic_string<_CharT, _Traits, _Allocator>&
2380basic_string<_CharT, _Traits, _Allocator>::append(const _Tp& __t, size_type __pos, size_type __n) {
2381  __self_view __sv = __t;
2382  size_type __sz   = __sv.size();
2383  if (__pos > __sz)
2384    __throw_out_of_range();
2385  return append(__sv.data() + __pos, std::min(__n, __sz - __pos));
2386}
2387
2388template <class _CharT, class _Traits, class _Allocator>
2389basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s) {
2390  _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::append received nullptr");
2391  return append(__s, traits_type::length(__s));
2392}
2393
2394// insert
2395
2396template <class _CharT, class _Traits, class _Allocator>
2397basic_string<_CharT, _Traits, _Allocator>&
2398basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n) {
2399  _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::insert received nullptr");
2400  size_type __sz = size();
2401  if (__pos > __sz)
2402    __throw_out_of_range();
2403  size_type __cap = capacity();
2404  if (__cap - __sz >= __n) {
2405    if (__n) {
2406      __annotate_increase(__n);
2407      value_type* __p    = std::__to_address(__get_pointer());
2408      size_type __n_move = __sz - __pos;
2409      if (__n_move != 0) {
2410        if (std::__is_pointer_in_range(__p + __pos, __p + __sz, __s))
2411          __s += __n;
2412        traits_type::move(__p + __pos + __n, __p + __pos, __n_move);
2413      }
2414      traits_type::move(__p + __pos, __s, __n);
2415      __sz += __n;
2416      __set_size(__sz);
2417      traits_type::assign(__p[__sz], value_type());
2418    }
2419  } else
2420    __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s);
2421  return *this;
2422}
2423
2424template <class _CharT, class _Traits, class _Allocator>
2425basic_string<_CharT, _Traits, _Allocator>&
2426basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n, value_type __c) {
2427  size_type __sz = size();
2428  if (__pos > __sz)
2429    __throw_out_of_range();
2430  if (__n) {
2431    size_type __cap = capacity();
2432    value_type* __p;
2433    if (__cap - __sz >= __n) {
2434      __annotate_increase(__n);
2435      __p                = std::__to_address(__get_pointer());
2436      size_type __n_move = __sz - __pos;
2437      if (__n_move != 0)
2438        traits_type::move(__p + __pos + __n, __p + __pos, __n_move);
2439    } else {
2440      __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n);
2441      __p = std::__to_address(__get_long_pointer());
2442    }
2443    traits_type::assign(__p + __pos, __n, __c);
2444    __sz += __n;
2445    __set_size(__sz);
2446    traits_type::assign(__p[__sz], value_type());
2447  }
2448  return *this;
2449}
2450
2451template <class _CharT, class _Traits, class _Allocator>
2452template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> >
2453typename basic_string<_CharT, _Traits, _Allocator>::iterator
2454basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last) {
2455  const basic_string __temp(__first, __last, __alloc());
2456  return insert(__pos, __temp.data(), __temp.data() + __temp.size());
2457}
2458
2459template <class _CharT, class _Traits, class _Allocator>
2460template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> >
2461typename basic_string<_CharT, _Traits, _Allocator>::iterator basic_string<_CharT, _Traits, _Allocator>::insert(
2462    const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last) {
2463  auto __n = static_cast<size_type>(std::distance(__first, __last));
2464  return __insert_with_size(__pos, __first, __last, __n);
2465}
2466
2467template <class _CharT, class _Traits, class _Allocator>
2468template <class _Iterator, class _Sentinel>
2469typename basic_string<_CharT, _Traits, _Allocator>::iterator
2470basic_string<_CharT, _Traits, _Allocator>::__insert_with_size(
2471    const_iterator __pos, _Iterator __first, _Sentinel __last, size_type __n) {
2472  size_type __ip = static_cast<size_type>(__pos - begin());
2473  if (__n == 0)
2474    return begin() + __ip;
2475
2476  if (__string_is_trivial_iterator<_Iterator>::value && !__addr_in_range(*__first)) {
2477    return __insert_from_safe_copy(__n, __ip, __first, __last);
2478  } else {
2479    const basic_string __temp(__init_with_sentinel_tag(), __first, __last, __alloc());
2480    return __insert_from_safe_copy(__n, __ip, __temp.begin(), __temp.end());
2481  }
2482}
2483
2484template <class _CharT, class _Traits, class _Allocator>
2485basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::insert(
2486    size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n) {
2487  size_type __str_sz = __str.size();
2488  if (__pos2 > __str_sz)
2489    __throw_out_of_range();
2490  return insert(__pos1, __str.data() + __pos2, std::min(__n, __str_sz - __pos2));
2491}
2492
2493template <class _CharT, class _Traits, class _Allocator>
2494template <class _Tp,
2495          __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
2496                            !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
2497                        int> >
2498basic_string<_CharT, _Traits, _Allocator>&
2499basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n) {
2500  __self_view __sv   = __t;
2501  size_type __str_sz = __sv.size();
2502  if (__pos2 > __str_sz)
2503    __throw_out_of_range();
2504  return insert(__pos1, __sv.data() + __pos2, std::min(__n, __str_sz - __pos2));
2505}
2506
2507template <class _CharT, class _Traits, class _Allocator>
2508basic_string<_CharT, _Traits, _Allocator>&
2509basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s) {
2510  _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::insert received nullptr");
2511  return insert(__pos, __s, traits_type::length(__s));
2512}
2513
2514template <class _CharT, class _Traits, class _Allocator>
2515typename basic_string<_CharT, _Traits, _Allocator>::iterator
2516basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c) {
2517  size_type __ip  = static_cast<size_type>(__pos - begin());
2518  size_type __sz  = size();
2519  size_type __cap = capacity();
2520  value_type* __p;
2521  if (__cap == __sz) {
2522    __grow_by_without_replace(__cap, 1, __sz, __ip, 0, 1);
2523    __p = std::__to_address(__get_long_pointer());
2524  } else {
2525    __annotate_increase(1);
2526    __p                = std::__to_address(__get_pointer());
2527    size_type __n_move = __sz - __ip;
2528    if (__n_move != 0)
2529      traits_type::move(__p + __ip + 1, __p + __ip, __n_move);
2530  }
2531  traits_type::assign(__p[__ip], __c);
2532  traits_type::assign(__p[++__sz], value_type());
2533  __set_size(__sz);
2534  return begin() + static_cast<difference_type>(__ip);
2535}
2536
2537// replace
2538
2539template <class _CharT, class _Traits, class _Allocator>
2540basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(
2541    size_type __pos, size_type __n1, const value_type* __s, size_type __n2)
2542    _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK {
2543  _LIBCPP_ASSERT_NON_NULL(__n2 == 0 || __s != nullptr, "string::replace received nullptr");
2544  size_type __sz = size();
2545  if (__pos > __sz)
2546    __throw_out_of_range();
2547  __n1            = std::min(__n1, __sz - __pos);
2548  size_type __cap = capacity();
2549  if (__cap - __sz + __n1 >= __n2) {
2550    value_type* __p = std::__to_address(__get_pointer());
2551    if (__n1 != __n2) {
2552      if (__n2 > __n1)
2553        __annotate_increase(__n2 - __n1);
2554      size_type __n_move = __sz - __pos - __n1;
2555      if (__n_move != 0) {
2556        if (__n1 > __n2) {
2557          traits_type::move(__p + __pos, __s, __n2);
2558          traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
2559          return __null_terminate_at(__p, __sz + (__n2 - __n1));
2560        }
2561        if (std::__is_pointer_in_range(__p + __pos + 1, __p + __sz, __s)) {
2562          if (__p + __pos + __n1 <= __s)
2563            __s += __n2 - __n1;
2564          else // __p + __pos < __s < __p + __pos + __n1
2565          {
2566            traits_type::move(__p + __pos, __s, __n1);
2567            __pos += __n1;
2568            __s += __n2;
2569            __n2 -= __n1;
2570            __n1 = 0;
2571          }
2572        }
2573        traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
2574      }
2575    }
2576    traits_type::move(__p + __pos, __s, __n2);
2577    return __null_terminate_at(__p, __sz + (__n2 - __n1));
2578  } else
2579    __grow_by_and_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2, __s);
2580  return *this;
2581}
2582
2583template <class _CharT, class _Traits, class _Allocator>
2584basic_string<_CharT, _Traits, _Allocator>&
2585basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, size_type __n2, value_type __c) {
2586  size_type __sz = size();
2587  if (__pos > __sz)
2588    __throw_out_of_range();
2589  __n1            = std::min(__n1, __sz - __pos);
2590  size_type __cap = capacity();
2591  value_type* __p;
2592  if (__cap - __sz + __n1 >= __n2) {
2593    __p = std::__to_address(__get_pointer());
2594    if (__n1 != __n2) {
2595      if (__n2 > __n1)
2596        __annotate_increase(__n2 - __n1);
2597      size_type __n_move = __sz - __pos - __n1;
2598      if (__n_move != 0)
2599        traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
2600    }
2601  } else {
2602    __grow_by_without_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2);
2603    __p = std::__to_address(__get_long_pointer());
2604  }
2605  traits_type::assign(__p + __pos, __n2, __c);
2606  return __null_terminate_at(__p, __sz - (__n1 - __n2));
2607}
2608
2609template <class _CharT, class _Traits, class _Allocator>
2610template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> >
2611basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(
2612    const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2) {
2613  const basic_string __temp(__j1, __j2, __alloc());
2614  return replace(__i1, __i2, __temp);
2615}
2616
2617template <class _CharT, class _Traits, class _Allocator>
2618basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(
2619    size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2) {
2620  size_type __str_sz = __str.size();
2621  if (__pos2 > __str_sz)
2622    __throw_out_of_range();
2623  return replace(__pos1, __n1, __str.data() + __pos2, std::min(__n2, __str_sz - __pos2));
2624}
2625
2626template <class _CharT, class _Traits, class _Allocator>
2627template <class _Tp,
2628          __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
2629                            !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
2630                        int> >
2631basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(
2632    size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2) {
2633  __self_view __sv   = __t;
2634  size_type __str_sz = __sv.size();
2635  if (__pos2 > __str_sz)
2636    __throw_out_of_range();
2637  return replace(__pos1, __n1, __sv.data() + __pos2, std::min(__n2, __str_sz - __pos2));
2638}
2639
2640template <class _CharT, class _Traits, class _Allocator>
2641basic_string<_CharT, _Traits, _Allocator>&
2642basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s) {
2643  _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::replace received nullptr");
2644  return replace(__pos, __n1, __s, traits_type::length(__s));
2645}
2646
2647// erase
2648
2649// 'externally instantiated' erase() implementation, called when __n != npos.
2650// Does not check __pos against size()
2651template <class _CharT, class _Traits, class _Allocator>
2652_LIBCPP_NOINLINE void
2653basic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move(size_type __pos, size_type __n) {
2654  if (__n) {
2655    size_type __sz     = size();
2656    value_type* __p    = std::__to_address(__get_pointer());
2657    __n                = std::min(__n, __sz - __pos);
2658    size_type __n_move = __sz - __pos - __n;
2659    if (__n_move != 0)
2660      traits_type::move(__p + __pos, __p + __pos + __n, __n_move);
2661    __null_terminate_at(__p, __sz - __n);
2662  }
2663}
2664
2665template <class _CharT, class _Traits, class _Allocator>
2666basic_string<_CharT, _Traits, _Allocator>&
2667basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, size_type __n) {
2668  if (__pos > size())
2669    __throw_out_of_range();
2670  if (__n == npos) {
2671    __erase_to_end(__pos);
2672  } else {
2673    __erase_external_with_move(__pos, __n);
2674  }
2675  return *this;
2676}
2677
2678template <class _CharT, class _Traits, class _Allocator>
2679inline typename basic_string<_CharT, _Traits, _Allocator>::iterator
2680basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos) {
2681  _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
2682      __pos != end(), "string::erase(iterator) called with a non-dereferenceable iterator");
2683  iterator __b  = begin();
2684  size_type __r = static_cast<size_type>(__pos - __b);
2685  erase(__r, 1);
2686  return __b + static_cast<difference_type>(__r);
2687}
2688
2689template <class _CharT, class _Traits, class _Allocator>
2690inline typename basic_string<_CharT, _Traits, _Allocator>::iterator
2691basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last) {
2692  _LIBCPP_ASSERT_VALID_INPUT_RANGE(__first <= __last, "string::erase(first, last) called with invalid range");
2693  iterator __b  = begin();
2694  size_type __r = static_cast<size_type>(__first - __b);
2695  erase(__r, static_cast<size_type>(__last - __first));
2696  return __b + static_cast<difference_type>(__r);
2697}
2698
2699template <class _CharT, class _Traits, class _Allocator>
2700inline void basic_string<_CharT, _Traits, _Allocator>::pop_back() {
2701  _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::pop_back(): string is already empty");
2702  __erase_to_end(size() - 1);
2703}
2704
2705template <class _CharT, class _Traits, class _Allocator>
2706inline void basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT {
2707  size_type __old_size = size();
2708  if (__is_long()) {
2709    traits_type::assign(*__get_long_pointer(), value_type());
2710    __set_long_size(0);
2711  } else {
2712    traits_type::assign(*__get_short_pointer(), value_type());
2713    __set_short_size(0);
2714  }
2715  __annotate_shrink(__old_size);
2716}
2717
2718template <class _CharT, class _Traits, class _Allocator>
2719void basic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c) {
2720  size_type __sz = size();
2721  if (__n > __sz)
2722    append(__n - __sz, __c);
2723  else
2724    __erase_to_end(__n);
2725}
2726
2727template <class _CharT, class _Traits, class _Allocator>
2728inline void basic_string<_CharT, _Traits, _Allocator>::__resize_default_init(size_type __n) {
2729  size_type __sz = size();
2730  if (__n > __sz) {
2731    __append_default_init(__n - __sz);
2732  } else
2733    __erase_to_end(__n);
2734}
2735
2736template <class _CharT, class _Traits, class _Allocator>
2737void basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacity) {
2738  if (__requested_capacity > max_size())
2739    __throw_length_error();
2740
2741  // Make sure reserve(n) never shrinks. This is technically only required in C++20
2742  // and later (since P0966R1), however we provide consistent behavior in all Standard
2743  // modes because this function is instantiated in the shared library.
2744  if (__requested_capacity <= capacity())
2745    return;
2746
2747  size_type __target_capacity = std::max(__requested_capacity, size());
2748  __target_capacity           = __recommend(__target_capacity);
2749  if (__target_capacity == capacity())
2750    return;
2751
2752  __shrink_or_extend(__target_capacity);
2753}
2754
2755template <class _CharT, class _Traits, class _Allocator>
2756inline void basic_string<_CharT, _Traits, _Allocator>::shrink_to_fit() _NOEXCEPT {
2757  size_type __target_capacity = __recommend(size());
2758  if (__target_capacity == capacity())
2759    return;
2760
2761  __shrink_or_extend(__target_capacity);
2762}
2763
2764template <class _CharT, class _Traits, class _Allocator>
2765inline void basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target_capacity) {
2766  __annotate_delete();
2767  size_type __cap = capacity();
2768  size_type __sz  = size();
2769
2770  pointer __new_data, __p;
2771  bool __was_long, __now_long;
2772  if (__fits_in_sso(__target_capacity)) {
2773    __was_long = true;
2774    __now_long = false;
2775    __new_data = __get_short_pointer();
2776    __p        = __get_long_pointer();
2777  } else {
2778    if (__target_capacity > __cap) {
2779      // Extend
2780      // - called from reserve should propagate the exception thrown.
2781      auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1);
2782      __new_data        = __allocation.ptr;
2783      __target_capacity = __allocation.count - 1;
2784    } else {
2785      // Shrink
2786      // - called from shrink_to_fit should not throw.
2787      // - called from reserve may throw but is not required to.
2788#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
2789      try {
2790#endif // _LIBCPP_HAS_NO_EXCEPTIONS
2791        auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1);
2792
2793        // The Standard mandates shrink_to_fit() does not increase the capacity.
2794        // With equal capacity keep the existing buffer. This avoids extra work
2795        // due to swapping the elements.
2796        if (__allocation.count - 1 > __target_capacity) {
2797          __alloc_traits::deallocate(__alloc(), __allocation.ptr, __allocation.count);
2798          __annotate_new(__sz); // Undoes the __annotate_delete()
2799          return;
2800        }
2801        __new_data        = __allocation.ptr;
2802        __target_capacity = __allocation.count - 1;
2803#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
2804      } catch (...) {
2805        return;
2806      }
2807#endif // _LIBCPP_HAS_NO_EXCEPTIONS
2808    }
2809    __begin_lifetime(__new_data, __target_capacity + 1);
2810    __now_long = true;
2811    __was_long = __is_long();
2812    __p        = __get_pointer();
2813  }
2814  traits_type::copy(std::__to_address(__new_data), std::__to_address(__p), size() + 1);
2815  if (__was_long)
2816    __alloc_traits::deallocate(__alloc(), __p, __cap + 1);
2817  if (__now_long) {
2818    __set_long_cap(__target_capacity + 1);
2819    __set_long_size(__sz);
2820    __set_long_pointer(__new_data);
2821  } else
2822    __set_short_size(__sz);
2823  __annotate_new(__sz);
2824}
2825
2826template <class _CharT, class _Traits, class _Allocator>
2827typename basic_string<_CharT, _Traits, _Allocator>::const_reference
2828basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const {
2829  if (__n >= size())
2830    __throw_out_of_range();
2831  return (*this)[__n];
2832}
2833
2834template <class _CharT, class _Traits, class _Allocator>
2835typename basic_string<_CharT, _Traits, _Allocator>::reference
2836basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) {
2837  if (__n >= size())
2838    __throw_out_of_range();
2839  return (*this)[__n];
2840}
2841
2842template <class _CharT, class _Traits, class _Allocator>
2843typename basic_string<_CharT, _Traits, _Allocator>::size_type
2844basic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n, size_type __pos) const {
2845  size_type __sz = size();
2846  if (__pos > __sz)
2847    __throw_out_of_range();
2848  size_type __rlen = std::min(__n, __sz - __pos);
2849  traits_type::copy(__s, data() + __pos, __rlen);
2850  return __rlen;
2851}
2852
2853template <class _CharT, class _Traits, class _Allocator>
2854inline void basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str) {
2855  _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
2856      __alloc_traits::propagate_on_container_swap::value || __alloc_traits::is_always_equal::value ||
2857          __alloc() == __str.__alloc(),
2858      "swapping non-equal allocators");
2859  if (!__is_long())
2860    __annotate_delete();
2861  if (this != &__str && !__str.__is_long())
2862    __str.__annotate_delete();
2863  std::swap(__r_.first(), __str.__r_.first());
2864  std::__swap_allocator(__alloc(), __str.__alloc());
2865  if (!__is_long())
2866    __annotate_new(__get_short_size());
2867  if (this != &__str && !__str.__is_long())
2868    __str.__annotate_new(__str.__get_short_size());
2869}
2870
2871// find
2872
2873template <class _Traits>
2874struct _LIBCPP_HIDDEN __traits_eq {
2875  typedef typename _Traits::char_type char_type;
2876  _LIBCPP_HIDE_FROM_ABI bool operator()(const char_type& __x, const char_type& __y) _NOEXCEPT {
2877    return _Traits::eq(__x, __y);
2878  }
2879};
2880
2881template <class _CharT, class _Traits, class _Allocator>
2882typename basic_string<_CharT, _Traits, _Allocator>::size_type
2883basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT {
2884  _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find(): received nullptr");
2885  return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
2886}
2887
2888template <class _CharT, class _Traits, class _Allocator>
2889inline typename basic_string<_CharT, _Traits, _Allocator>::size_type
2890basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str, size_type __pos) const _NOEXCEPT {
2891  return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __str.data(), __pos, __str.size());
2892}
2893
2894template <class _CharT, class _Traits, class _Allocator>
2895template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
2896typename basic_string<_CharT, _Traits, _Allocator>::size_type
2897basic_string<_CharT, _Traits, _Allocator>::find(const _Tp& __t, size_type __pos) const _NOEXCEPT {
2898  __self_view __sv = __t;
2899  return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __sv.data(), __pos, __sv.size());
2900}
2901
2902template <class _CharT, class _Traits, class _Allocator>
2903inline typename basic_string<_CharT, _Traits, _Allocator>::size_type
2904basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, size_type __pos) const _NOEXCEPT {
2905  _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find(): received nullptr");
2906  return std::__str_find<value_type, size_type, traits_type, npos>(
2907      data(), size(), __s, __pos, traits_type::length(__s));
2908}
2909
2910template <class _CharT, class _Traits, class _Allocator>
2911typename basic_string<_CharT, _Traits, _Allocator>::size_type
2912basic_string<_CharT, _Traits, _Allocator>::find(value_type __c, size_type __pos) const _NOEXCEPT {
2913  return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);
2914}
2915
2916// rfind
2917
2918template <class _CharT, class _Traits, class _Allocator>
2919typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::rfind(
2920    const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT {
2921  _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::rfind(): received nullptr");
2922  return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
2923}
2924
2925template <class _CharT, class _Traits, class _Allocator>
2926inline typename basic_string<_CharT, _Traits, _Allocator>::size_type
2927basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str, size_type __pos) const _NOEXCEPT {
2928  return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __str.data(), __pos, __str.size());
2929}
2930
2931template <class _CharT, class _Traits, class _Allocator>
2932template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
2933typename basic_string<_CharT, _Traits, _Allocator>::size_type
2934basic_string<_CharT, _Traits, _Allocator>::rfind(const _Tp& __t, size_type __pos) const _NOEXCEPT {
2935  __self_view __sv = __t;
2936  return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __sv.data(), __pos, __sv.size());
2937}
2938
2939template <class _CharT, class _Traits, class _Allocator>
2940inline typename basic_string<_CharT, _Traits, _Allocator>::size_type
2941basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, size_type __pos) const _NOEXCEPT {
2942  _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::rfind(): received nullptr");
2943  return std::__str_rfind<value_type, size_type, traits_type, npos>(
2944      data(), size(), __s, __pos, traits_type::length(__s));
2945}
2946
2947template <class _CharT, class _Traits, class _Allocator>
2948typename basic_string<_CharT, _Traits, _Allocator>::size_type
2949basic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c, size_type __pos) const _NOEXCEPT {
2950  return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);
2951}
2952
2953// find_first_of
2954
2955template <class _CharT, class _Traits, class _Allocator>
2956typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_first_of(
2957    const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT {
2958  _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr");
2959  return std::__str_find_first_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
2960}
2961
2962template <class _CharT, class _Traits, class _Allocator>
2963inline typename basic_string<_CharT, _Traits, _Allocator>::size_type
2964basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str, size_type __pos) const _NOEXCEPT {
2965  return std::__str_find_first_of<value_type, size_type, traits_type, npos>(
2966      data(), size(), __str.data(), __pos, __str.size());
2967}
2968
2969template <class _CharT, class _Traits, class _Allocator>
2970template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
2971typename basic_string<_CharT, _Traits, _Allocator>::size_type
2972basic_string<_CharT, _Traits, _Allocator>::find_first_of(const _Tp& __t, size_type __pos) const _NOEXCEPT {
2973  __self_view __sv = __t;
2974  return std::__str_find_first_of<value_type, size_type, traits_type, npos>(
2975      data(), size(), __sv.data(), __pos, __sv.size());
2976}
2977
2978template <class _CharT, class _Traits, class _Allocator>
2979inline typename basic_string<_CharT, _Traits, _Allocator>::size_type
2980basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, size_type __pos) const _NOEXCEPT {
2981  _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_first_of(): received nullptr");
2982  return std::__str_find_first_of<value_type, size_type, traits_type, npos>(
2983      data(), size(), __s, __pos, traits_type::length(__s));
2984}
2985
2986template <class _CharT, class _Traits, class _Allocator>
2987inline typename basic_string<_CharT, _Traits, _Allocator>::size_type
2988basic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c, size_type __pos) const _NOEXCEPT {
2989  return find(__c, __pos);
2990}
2991
2992// find_last_of
2993
2994template <class _CharT, class _Traits, class _Allocator>
2995inline typename basic_string<_CharT, _Traits, _Allocator>::size_type
2996basic_string<_CharT, _Traits, _Allocator>::find_last_of(
2997    const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT {
2998  _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr");
2999  return std::__str_find_last_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
3000}
3001
3002template <class _CharT, class _Traits, class _Allocator>
3003inline typename basic_string<_CharT, _Traits, _Allocator>::size_type
3004basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str, size_type __pos) const _NOEXCEPT {
3005  return std::__str_find_last_of<value_type, size_type, traits_type, npos>(
3006      data(), size(), __str.data(), __pos, __str.size());
3007}
3008
3009template <class _CharT, class _Traits, class _Allocator>
3010template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
3011typename basic_string<_CharT, _Traits, _Allocator>::size_type
3012basic_string<_CharT, _Traits, _Allocator>::find_last_of(const _Tp& __t, size_type __pos) const _NOEXCEPT {
3013  __self_view __sv = __t;
3014  return std::__str_find_last_of<value_type, size_type, traits_type, npos>(
3015      data(), size(), __sv.data(), __pos, __sv.size());
3016}
3017
3018template <class _CharT, class _Traits, class _Allocator>
3019inline typename basic_string<_CharT, _Traits, _Allocator>::size_type
3020basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, size_type __pos) const _NOEXCEPT {
3021  _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_last_of(): received nullptr");
3022  return std::__str_find_last_of<value_type, size_type, traits_type, npos>(
3023      data(), size(), __s, __pos, traits_type::length(__s));
3024}
3025
3026template <class _CharT, class _Traits, class _Allocator>
3027inline typename basic_string<_CharT, _Traits, _Allocator>::size_type
3028basic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c, size_type __pos) const _NOEXCEPT {
3029  return rfind(__c, __pos);
3030}
3031
3032// find_first_not_of
3033
3034template <class _CharT, class _Traits, class _Allocator>
3035typename basic_string<_CharT, _Traits, _Allocator>::size_type
3036basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(
3037    const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT {
3038  _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr");
3039  return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
3040}
3041
3042template <class _CharT, class _Traits, class _Allocator>
3043inline typename basic_string<_CharT, _Traits, _Allocator>::size_type
3044basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(
3045    const basic_string& __str, size_type __pos) const _NOEXCEPT {
3046  return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(
3047      data(), size(), __str.data(), __pos, __str.size());
3048}
3049
3050template <class _CharT, class _Traits, class _Allocator>
3051template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
3052typename basic_string<_CharT, _Traits, _Allocator>::size_type
3053basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const _Tp& __t, size_type __pos) const _NOEXCEPT {
3054  __self_view __sv = __t;
3055  return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(
3056      data(), size(), __sv.data(), __pos, __sv.size());
3057}
3058
3059template <class _CharT, class _Traits, class _Allocator>
3060inline typename basic_string<_CharT, _Traits, _Allocator>::size_type
3061basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s, size_type __pos) const _NOEXCEPT {
3062  _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_first_not_of(): received nullptr");
3063  return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(
3064      data(), size(), __s, __pos, traits_type::length(__s));
3065}
3066
3067template <class _CharT, class _Traits, class _Allocator>
3068inline typename basic_string<_CharT, _Traits, _Allocator>::size_type
3069basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c, size_type __pos) const _NOEXCEPT {
3070  return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);
3071}
3072
3073// find_last_not_of
3074
3075template <class _CharT, class _Traits, class _Allocator>
3076typename basic_string<_CharT, _Traits, _Allocator>::size_type
3077basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(
3078    const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT {
3079  _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr");
3080  return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
3081}
3082
3083template <class _CharT, class _Traits, class _Allocator>
3084inline typename basic_string<_CharT, _Traits, _Allocator>::size_type
3085basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(
3086    const basic_string& __str, size_type __pos) const _NOEXCEPT {
3087  return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(
3088      data(), size(), __str.data(), __pos, __str.size());
3089}
3090
3091template <class _CharT, class _Traits, class _Allocator>
3092template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
3093typename basic_string<_CharT, _Traits, _Allocator>::size_type
3094basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const _Tp& __t, size_type __pos) const _NOEXCEPT {
3095  __self_view __sv = __t;
3096  return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(
3097      data(), size(), __sv.data(), __pos, __sv.size());
3098}
3099
3100template <class _CharT, class _Traits, class _Allocator>
3101inline typename basic_string<_CharT, _Traits, _Allocator>::size_type
3102basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s, size_type __pos) const _NOEXCEPT {
3103  _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_last_not_of(): received nullptr");
3104  return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(
3105      data(), size(), __s, __pos, traits_type::length(__s));
3106}
3107
3108template <class _CharT, class _Traits, class _Allocator>
3109inline typename basic_string<_CharT, _Traits, _Allocator>::size_type
3110basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c, size_type __pos) const _NOEXCEPT {
3111  return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);
3112}
3113
3114// compare
3115
3116template <class _CharT, class _Traits, class _Allocator>
3117template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
3118int basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const _NOEXCEPT {
3119  __self_view __sv = __t;
3120  size_t __lhs_sz  = size();
3121  size_t __rhs_sz  = __sv.size();
3122  int __result     = traits_type::compare(data(), __sv.data(), std::min(__lhs_sz, __rhs_sz));
3123  if (__result != 0)
3124    return __result;
3125  if (__lhs_sz < __rhs_sz)
3126    return -1;
3127  if (__lhs_sz > __rhs_sz)
3128    return 1;
3129  return 0;
3130}
3131
3132template <class _CharT, class _Traits, class _Allocator>
3133inline int basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT {
3134  return compare(__self_view(__str));
3135}
3136
3137template <class _CharT, class _Traits, class _Allocator>
3138inline int basic_string<_CharT, _Traits, _Allocator>::compare(
3139    size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const {
3140  _LIBCPP_ASSERT_NON_NULL(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr");
3141  size_type __sz = size();
3142  if (__pos1 > __sz || __n2 == npos)
3143    __throw_out_of_range();
3144  size_type __rlen = std::min(__n1, __sz - __pos1);
3145  int __r          = traits_type::compare(data() + __pos1, __s, std::min(__rlen, __n2));
3146  if (__r == 0) {
3147    if (__rlen < __n2)
3148      __r = -1;
3149    else if (__rlen > __n2)
3150      __r = 1;
3151  }
3152  return __r;
3153}
3154
3155template <class _CharT, class _Traits, class _Allocator>
3156template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
3157int basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, const _Tp& __t) const {
3158  __self_view __sv = __t;
3159  return compare(__pos1, __n1, __sv.data(), __sv.size());
3160}
3161
3162template <class _CharT, class _Traits, class _Allocator>
3163inline int
3164basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, const basic_string& __str) const {
3165  return compare(__pos1, __n1, __str.data(), __str.size());
3166}
3167
3168template <class _CharT, class _Traits, class _Allocator>
3169template <class _Tp,
3170          __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
3171                            !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
3172                        int> >
3173int basic_string<_CharT, _Traits, _Allocator>::compare(
3174    size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2) const {
3175  __self_view __sv = __t;
3176  return __self_view(*this).substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
3177}
3178
3179template <class _CharT, class _Traits, class _Allocator>
3180int basic_string<_CharT, _Traits, _Allocator>::compare(
3181    size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2) const {
3182  return compare(__pos1, __n1, __self_view(__str), __pos2, __n2);
3183}
3184
3185template <class _CharT, class _Traits, class _Allocator>
3186int basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT {
3187  _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::compare(): received nullptr");
3188  return compare(0, npos, __s, traits_type::length(__s));
3189}
3190
3191template <class _CharT, class _Traits, class _Allocator>
3192int basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, const value_type* __s) const {
3193  _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::compare(): received nullptr");
3194  return compare(__pos1, __n1, __s, traits_type::length(__s));
3195}
3196
3197// __invariants
3198
3199template <class _CharT, class _Traits, class _Allocator>
3200inline bool basic_string<_CharT, _Traits, _Allocator>::__invariants() const {
3201  if (size() > capacity())
3202    return false;
3203  if (capacity() < __min_cap - 1)
3204    return false;
3205  if (data() == nullptr)
3206    return false;
3207  if (!_Traits::eq(data()[size()], value_type()))
3208    return false;
3209  return true;
3210}
3211
3212// __clear_and_shrink
3213
3214template <class _CharT, class _Traits, class _Allocator>
3215inline void basic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT {
3216  clear();
3217  if (__is_long()) {
3218    __annotate_delete();
3219    __alloc_traits::deallocate(__alloc(), __get_long_pointer(), capacity() + 1);
3220    __r_.first() = __rep();
3221  }
3222}
3223
3224// operator==
3225
3226template <class _CharT, class _Traits, class _Allocator>
3227inline _LIBCPP_HIDE_FROM_ABI bool operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3228                                             const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT {
3229  size_t __lhs_sz = __lhs.size();
3230  return __lhs_sz == __rhs.size() && _Traits::compare(__lhs.data(), __rhs.data(), __lhs_sz) == 0;
3231}
3232
3233template <class _Allocator>
3234inline _LIBCPP_HIDE_FROM_ABI bool operator==(const basic_string<char, char_traits<char>, _Allocator>& __lhs,
3235                                             const basic_string<char, char_traits<char>, _Allocator>& __rhs) _NOEXCEPT {
3236  size_t __sz = __lhs.size();
3237  if (__sz != __rhs.size())
3238    return false;
3239  return char_traits<char>::compare(__lhs.data(), __rhs.data(), __sz) == 0;
3240}
3241
3242template <class _CharT, class _Traits, class _Allocator>
3243inline _LIBCPP_HIDE_FROM_ABI bool
3244operator==(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT {
3245  typedef basic_string<_CharT, _Traits, _Allocator> _String;
3246  _LIBCPP_ASSERT_NON_NULL(__lhs != nullptr, "operator==(char*, basic_string): received nullptr");
3247  size_t __lhs_len = _Traits::length(__lhs);
3248  if (__lhs_len != __rhs.size())
3249    return false;
3250  return __rhs.compare(0, _String::npos, __lhs, __lhs_len) == 0;
3251}
3252
3253template <class _CharT, class _Traits, class _Allocator>
3254inline _LIBCPP_HIDE_FROM_ABI bool
3255operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT {
3256  typedef basic_string<_CharT, _Traits, _Allocator> _String;
3257  _LIBCPP_ASSERT_NON_NULL(__rhs != nullptr, "operator==(basic_string, char*): received nullptr");
3258  size_t __rhs_len = _Traits::length(__rhs);
3259  if (__rhs_len != __lhs.size())
3260    return false;
3261  return __lhs.compare(0, _String::npos, __rhs, __rhs_len) == 0;
3262}
3263
3264template <class _CharT, class _Traits, class _Allocator>
3265inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3266                                             const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT {
3267  return !(__lhs == __rhs);
3268}
3269
3270template <class _CharT, class _Traits, class _Allocator>
3271inline _LIBCPP_HIDE_FROM_ABI bool
3272operator!=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT {
3273  return !(__lhs == __rhs);
3274}
3275
3276template <class _CharT, class _Traits, class _Allocator>
3277inline _LIBCPP_HIDE_FROM_ABI bool
3278operator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT {
3279  return !(__lhs == __rhs);
3280}
3281
3282// operator<
3283
3284template <class _CharT, class _Traits, class _Allocator>
3285inline _LIBCPP_HIDE_FROM_ABI bool operator<(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3286                                            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT {
3287  return __lhs.compare(__rhs) < 0;
3288}
3289
3290template <class _CharT, class _Traits, class _Allocator>
3291inline _LIBCPP_HIDE_FROM_ABI bool
3292operator<(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT {
3293  return __lhs.compare(__rhs) < 0;
3294}
3295
3296template <class _CharT, class _Traits, class _Allocator>
3297inline _LIBCPP_HIDE_FROM_ABI bool
3298operator<(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT {
3299  return __rhs.compare(__lhs) > 0;
3300}
3301
3302// operator>
3303
3304template <class _CharT, class _Traits, class _Allocator>
3305inline _LIBCPP_HIDE_FROM_ABI bool operator>(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3306                                            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT {
3307  return __rhs < __lhs;
3308}
3309
3310template <class _CharT, class _Traits, class _Allocator>
3311inline _LIBCPP_HIDE_FROM_ABI bool
3312operator>(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT {
3313  return __rhs < __lhs;
3314}
3315
3316template <class _CharT, class _Traits, class _Allocator>
3317inline _LIBCPP_HIDE_FROM_ABI bool
3318operator>(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT {
3319  return __rhs < __lhs;
3320}
3321
3322// operator<=
3323
3324template <class _CharT, class _Traits, class _Allocator>
3325inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3326                                             const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT {
3327  return !(__rhs < __lhs);
3328}
3329
3330template <class _CharT, class _Traits, class _Allocator>
3331inline _LIBCPP_HIDE_FROM_ABI bool
3332operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT {
3333  return !(__rhs < __lhs);
3334}
3335
3336template <class _CharT, class _Traits, class _Allocator>
3337inline _LIBCPP_HIDE_FROM_ABI bool
3338operator<=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT {
3339  return !(__rhs < __lhs);
3340}
3341
3342// operator>=
3343
3344template <class _CharT, class _Traits, class _Allocator>
3345inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3346                                             const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT {
3347  return !(__lhs < __rhs);
3348}
3349
3350template <class _CharT, class _Traits, class _Allocator>
3351inline _LIBCPP_HIDE_FROM_ABI bool
3352operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT {
3353  return !(__lhs < __rhs);
3354}
3355
3356template <class _CharT, class _Traits, class _Allocator>
3357inline _LIBCPP_HIDE_FROM_ABI bool
3358operator>=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT {
3359  return !(__lhs < __rhs);
3360}
3361
3362// operator +
3363
3364template <class _CharT, class _Traits, class _Allocator>
3365_LIBCPP_HIDE_FROM_ABI basic_string<_CharT, _Traits, _Allocator>
3366operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3367          const basic_string<_CharT, _Traits, _Allocator>& __rhs) {
3368  using _String = basic_string<_CharT, _Traits, _Allocator>;
3369  auto __lhs_sz = __lhs.size();
3370  auto __rhs_sz = __rhs.size();
3371  _String __r(__uninitialized_size_tag(),
3372              __lhs_sz + __rhs_sz,
3373              _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator()));
3374  auto __ptr = std::__to_address(__r.__get_pointer());
3375  _Traits::copy(__ptr, __lhs.data(), __lhs_sz);
3376  _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz);
3377  _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());
3378  return __r;
3379}
3380
3381template <class _CharT, class _Traits, class _Allocator>
3382_LIBCPP_HIDDEN basic_string<_CharT, _Traits, _Allocator>
3383operator+(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) {
3384  using _String = basic_string<_CharT, _Traits, _Allocator>;
3385  auto __lhs_sz = _Traits::length(__lhs);
3386  auto __rhs_sz = __rhs.size();
3387  _String __r(__uninitialized_size_tag(),
3388              __lhs_sz + __rhs_sz,
3389              _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator()));
3390  auto __ptr = std::__to_address(__r.__get_pointer());
3391  _Traits::copy(__ptr, __lhs, __lhs_sz);
3392  _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz);
3393  _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());
3394  return __r;
3395}
3396
3397template <class _CharT, class _Traits, class _Allocator>
3398_LIBCPP_HIDE_FROM_ABI basic_string<_CharT, _Traits, _Allocator>
3399operator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) {
3400  using _String                        = basic_string<_CharT, _Traits, _Allocator>;
3401  typename _String::size_type __rhs_sz = __rhs.size();
3402  _String __r(__uninitialized_size_tag(),
3403              __rhs_sz + 1,
3404              _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator()));
3405  auto __ptr = std::__to_address(__r.__get_pointer());
3406  _Traits::assign(__ptr, 1, __lhs);
3407  _Traits::copy(__ptr + 1, __rhs.data(), __rhs_sz);
3408  _Traits::assign(__ptr + 1 + __rhs_sz, 1, _CharT());
3409  return __r;
3410}
3411
3412template <class _CharT, class _Traits, class _Allocator>
3413inline basic_string<_CharT, _Traits, _Allocator>
3414operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) {
3415  using _String                        = basic_string<_CharT, _Traits, _Allocator>;
3416  typename _String::size_type __lhs_sz = __lhs.size();
3417  typename _String::size_type __rhs_sz = _Traits::length(__rhs);
3418  _String __r(__uninitialized_size_tag(),
3419              __lhs_sz + __rhs_sz,
3420              _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator()));
3421  auto __ptr = std::__to_address(__r.__get_pointer());
3422  _Traits::copy(__ptr, __lhs.data(), __lhs_sz);
3423  _Traits::copy(__ptr + __lhs_sz, __rhs, __rhs_sz);
3424  _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());
3425  return __r;
3426}
3427
3428template <class _CharT, class _Traits, class _Allocator>
3429_LIBCPP_HIDE_FROM_ABI basic_string<_CharT, _Traits, _Allocator>
3430operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs) {
3431  using _String                        = basic_string<_CharT, _Traits, _Allocator>;
3432  typename _String::size_type __lhs_sz = __lhs.size();
3433  _String __r(__uninitialized_size_tag(),
3434              __lhs_sz + 1,
3435              _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator()));
3436  auto __ptr = std::__to_address(__r.__get_pointer());
3437  _Traits::copy(__ptr, __lhs.data(), __lhs_sz);
3438  _Traits::assign(__ptr + __lhs_sz, 1, __rhs);
3439  _Traits::assign(__ptr + 1 + __lhs_sz, 1, _CharT());
3440  return __r;
3441}
3442
3443// swap
3444
3445template <class _CharT, class _Traits, class _Allocator>
3446inline _LIBCPP_HIDE_FROM_ABI void
3447swap(basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>& __rhs) {
3448  __lhs.swap(__rhs);
3449}
3450
3451_LIBCPP_EXPORTED_FROM_ABI int stoi(const string& __str, size_t* __idx = nullptr, int __base = 10);
3452_LIBCPP_EXPORTED_FROM_ABI long stol(const string& __str, size_t* __idx = nullptr, int __base = 10);
3453_LIBCPP_EXPORTED_FROM_ABI unsigned long stoul(const string& __str, size_t* __idx = nullptr, int __base = 10);
3454_LIBCPP_EXPORTED_FROM_ABI long long stoll(const string& __str, size_t* __idx = nullptr, int __base = 10);
3455_LIBCPP_EXPORTED_FROM_ABI unsigned long long stoull(const string& __str, size_t* __idx = nullptr, int __base = 10);
3456
3457_LIBCPP_EXPORTED_FROM_ABI float stof(const string& __str, size_t* __idx = nullptr);
3458_LIBCPP_EXPORTED_FROM_ABI double stod(const string& __str, size_t* __idx = nullptr);
3459_LIBCPP_EXPORTED_FROM_ABI long double stold(const string& __str, size_t* __idx = nullptr);
3460
3461_LIBCPP_EXPORTED_FROM_ABI string to_string(int __val);
3462_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned __val);
3463_LIBCPP_EXPORTED_FROM_ABI string to_string(long __val);
3464_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long __val);
3465_LIBCPP_EXPORTED_FROM_ABI string to_string(long long __val);
3466_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long long __val);
3467_LIBCPP_EXPORTED_FROM_ABI string to_string(float __val);
3468_LIBCPP_EXPORTED_FROM_ABI string to_string(double __val);
3469_LIBCPP_EXPORTED_FROM_ABI string to_string(long double __val);
3470
3471#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
3472_LIBCPP_EXPORTED_FROM_ABI int stoi(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
3473_LIBCPP_EXPORTED_FROM_ABI long stol(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
3474_LIBCPP_EXPORTED_FROM_ABI unsigned long stoul(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
3475_LIBCPP_EXPORTED_FROM_ABI long long stoll(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
3476_LIBCPP_EXPORTED_FROM_ABI unsigned long long stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
3477
3478_LIBCPP_EXPORTED_FROM_ABI float stof(const wstring& __str, size_t* __idx = nullptr);
3479_LIBCPP_EXPORTED_FROM_ABI double stod(const wstring& __str, size_t* __idx = nullptr);
3480_LIBCPP_EXPORTED_FROM_ABI long double stold(const wstring& __str, size_t* __idx = nullptr);
3481
3482_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(int __val);
3483_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned __val);
3484_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long __val);
3485_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long __val);
3486_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long long __val);
3487_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long long __val);
3488_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(float __val);
3489_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(double __val);
3490_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long double __val);
3491#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
3492
3493template <class _CharT, class _Traits, class _Allocator>
3494_LIBCPP_TEMPLATE_DATA_VIS const typename basic_string<_CharT, _Traits, _Allocator>::size_type
3495    basic_string<_CharT, _Traits, _Allocator>::npos;
3496
3497template <class _CharT, class _Allocator>
3498struct __string_hash : public __unary_function<basic_string<_CharT, char_traits<_CharT>, _Allocator>, size_t> {
3499  _LIBCPP_HIDE_FROM_ABI size_t
3500  operator()(const basic_string<_CharT, char_traits<_CharT>, _Allocator>& __val) const _NOEXCEPT {
3501    return std::__do_string_hash(__val.data(), __val.data() + __val.size());
3502  }
3503};
3504
3505template <class _Allocator>
3506struct hash<basic_string<char, char_traits<char>, _Allocator> > : __string_hash<char, _Allocator> {};
3507
3508#ifndef _LIBCPP_HAS_NO_CHAR8_T
3509template <class _Allocator>
3510struct hash<basic_string<char8_t, char_traits<char8_t>, _Allocator> > : __string_hash<char8_t, _Allocator> {};
3511#endif
3512
3513template <class _Allocator>
3514struct hash<basic_string<char16_t, char_traits<char16_t>, _Allocator> > : __string_hash<char16_t, _Allocator> {};
3515
3516template <class _Allocator>
3517struct hash<basic_string<char32_t, char_traits<char32_t>, _Allocator> > : __string_hash<char32_t, _Allocator> {};
3518
3519#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
3520template <class _Allocator>
3521struct hash<basic_string<wchar_t, char_traits<wchar_t>, _Allocator> > : __string_hash<wchar_t, _Allocator> {};
3522#endif
3523
3524template <class _CharT, class _Traits, class _Allocator>
3525_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
3526operator<<(basic_ostream<_CharT, _Traits>& __os, const basic_string<_CharT, _Traits, _Allocator>& __str);
3527
3528template <class _CharT, class _Traits, class _Allocator>
3529_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
3530operator>>(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Allocator>& __str);
3531
3532template <class _CharT, class _Traits, class _Allocator>
3533_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
3534getline(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm);
3535
3536template <class _CharT, class _Traits, class _Allocator>
3537inline _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
3538getline(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Allocator>& __str);
3539
3540template <class _CharT, class _Traits, class _Allocator>
3541inline _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
3542getline(basic_istream<_CharT, _Traits>&& __is, basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm);
3543
3544template <class _CharT, class _Traits, class _Allocator>
3545inline _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
3546getline(basic_istream<_CharT, _Traits>&& __is, basic_string<_CharT, _Traits, _Allocator>& __str);
3547
3548_LIBCPP_END_NAMESPACE_STD
3549
3550_LIBCPP_POP_MACROS
3551
3552#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES)
3553#  include <__cxx03/algorithm>
3554#  include <__cxx03/cstdlib>
3555#  include <__cxx03/iterator>
3556#  include <__cxx03/new>
3557#  include <__cxx03/type_traits>
3558#  include <__cxx03/typeinfo>
3559#  include <__cxx03/utility>
3560#endif
3561
3562#endif // _LIBCPP___CXX03_STRING
3563