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