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