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