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