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