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