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