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