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