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