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