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