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