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