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