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