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