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