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