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