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