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