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