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