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