xref: /llvm-project-15.0.7/libcxx/include/string (revision a7ac2cb6)
1// -*- C++ -*-
2//===--------------------------- string -----------------------------------===//
3//
4//                     The LLVM Compiler Infrastructure
5//
6// This file is distributed under the University of Illinois Open Source
7// License. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_STRING
12#define _LIBCPP_STRING
13
14/*
15    string synopsis
16
17namespace std
18{
19
20template <class stateT>
21class fpos
22{
23private:
24    stateT st;
25public:
26    fpos(streamoff = streamoff());
27
28    operator streamoff() const;
29
30    stateT state() const;
31    void state(stateT);
32
33    fpos& operator+=(streamoff);
34    fpos  operator+ (streamoff) const;
35    fpos& operator-=(streamoff);
36    fpos  operator- (streamoff) const;
37};
38
39template <class stateT> streamoff operator-(const fpos<stateT>& x, const fpos<stateT>& y);
40
41template <class stateT> bool operator==(const fpos<stateT>& x, const fpos<stateT>& y);
42template <class stateT> bool operator!=(const fpos<stateT>& x, const fpos<stateT>& y);
43
44template <class charT>
45struct char_traits
46{
47    typedef charT     char_type;
48    typedef ...       int_type;
49    typedef streamoff off_type;
50    typedef streampos pos_type;
51    typedef mbstate_t state_type;
52
53    static void assign(char_type& c1, const char_type& c2) noexcept;
54    static constexpr bool eq(char_type c1, char_type c2) noexcept;
55    static constexpr bool lt(char_type c1, char_type c2) noexcept;
56
57    static int              compare(const char_type* s1, const char_type* s2, size_t n);
58    static size_t           length(const char_type* s);
59    static const char_type* find(const char_type* s, size_t n, const char_type& a);
60    static char_type*       move(char_type* s1, const char_type* s2, size_t n);
61    static char_type*       copy(char_type* s1, const char_type* s2, size_t n);
62    static char_type*       assign(char_type* s, size_t n, char_type a);
63
64    static constexpr int_type  not_eof(int_type c) noexcept;
65    static constexpr char_type to_char_type(int_type c) noexcept;
66    static constexpr int_type  to_int_type(char_type c) noexcept;
67    static constexpr bool      eq_int_type(int_type c1, int_type c2) noexcept;
68    static constexpr int_type  eof() noexcept;
69};
70
71template <> struct char_traits<char>;
72template <> struct char_traits<wchar_t>;
73
74template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
75class basic_string
76{
77public:
78// types:
79    typedef traits traits_type;
80    typedef typename traits_type::char_type value_type;
81    typedef Allocator allocator_type;
82    typedef typename allocator_type::size_type size_type;
83    typedef typename allocator_type::difference_type difference_type;
84    typedef typename allocator_type::reference reference;
85    typedef typename allocator_type::const_reference const_reference;
86    typedef typename allocator_type::pointer pointer;
87    typedef typename allocator_type::const_pointer const_pointer;
88    typedef implementation-defined iterator;
89    typedef implementation-defined const_iterator;
90    typedef std::reverse_iterator<iterator> reverse_iterator;
91    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
92
93    static const size_type npos = -1;
94
95    basic_string()
96        noexcept(is_nothrow_default_constructible<allocator_type>::value);
97    explicit basic_string(const allocator_type& a);
98    basic_string(const basic_string& str);
99    basic_string(basic_string&& str)
100        noexcept(is_nothrow_move_constructible<allocator_type>::value);
101    basic_string(const basic_string& str, size_type pos,
102                 const allocator_type& a = allocator_type());
103    basic_string(const basic_string& str, size_type pos, size_type n,
104                 const Allocator& a = Allocator());
105    template<class T>
106        basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator()); // C++17
107    explicit basic_string(const basic_string_view<charT, traits> sv, const Allocator& a = Allocator());
108    basic_string(const value_type* s, const allocator_type& a = allocator_type());
109    basic_string(const value_type* s, size_type n, const allocator_type& a = allocator_type());
110    basic_string(size_type n, value_type c, const allocator_type& a = allocator_type());
111    template<class InputIterator>
112        basic_string(InputIterator begin, InputIterator end,
113                     const allocator_type& a = allocator_type());
114    basic_string(initializer_list<value_type>, const Allocator& = Allocator());
115    basic_string(const basic_string&, const Allocator&);
116    basic_string(basic_string&&, const Allocator&);
117
118    ~basic_string();
119
120    operator basic_string_view<charT, traits>() const noexcept;
121
122    basic_string& operator=(const basic_string& str);
123    basic_string& operator=(basic_string_view<charT, traits> sv);
124    basic_string& operator=(basic_string&& str)
125        noexcept(
126             allocator_type::propagate_on_container_move_assignment::value ||
127             allocator_type::is_always_equal::value ); // C++17
128    basic_string& operator=(const value_type* s);
129    basic_string& operator=(value_type c);
130    basic_string& operator=(initializer_list<value_type>);
131
132    iterator       begin() noexcept;
133    const_iterator begin() const noexcept;
134    iterator       end() noexcept;
135    const_iterator end() const noexcept;
136
137    reverse_iterator       rbegin() noexcept;
138    const_reverse_iterator rbegin() const noexcept;
139    reverse_iterator       rend() noexcept;
140    const_reverse_iterator rend() const noexcept;
141
142    const_iterator         cbegin() const noexcept;
143    const_iterator         cend() const noexcept;
144    const_reverse_iterator crbegin() const noexcept;
145    const_reverse_iterator crend() const noexcept;
146
147    size_type size() const noexcept;
148    size_type length() const noexcept;
149    size_type max_size() const noexcept;
150    size_type capacity() const noexcept;
151
152    void resize(size_type n, value_type c);
153    void resize(size_type n);
154
155    void reserve(size_type res_arg = 0);
156    void shrink_to_fit();
157    void clear() noexcept;
158    bool empty() const noexcept;
159
160    const_reference operator[](size_type pos) const;
161    reference       operator[](size_type pos);
162
163    const_reference at(size_type n) const;
164    reference       at(size_type n);
165
166    basic_string& operator+=(const basic_string& str);
167    basic_string& operator+=(basic_string_view<charT, traits> sv);
168    basic_string& operator+=(const value_type* s);
169    basic_string& operator+=(value_type c);
170    basic_string& operator+=(initializer_list<value_type>);
171
172    basic_string& append(const basic_string& str);
173    basic_string& append(basic_string_view<charT, traits> sv);
174    basic_string& append(const basic_string& str, size_type pos, size_type n=npos); //C++14
175    template <class T>
176        basic_string& append(const T& t, size_type pos, size_type n=npos); // C++17
177    basic_string& append(const value_type* s, size_type n);
178    basic_string& append(const value_type* s);
179    basic_string& append(size_type n, value_type c);
180    template<class InputIterator>
181        basic_string& append(InputIterator first, InputIterator last);
182    basic_string& append(initializer_list<value_type>);
183
184    void push_back(value_type c);
185    void pop_back();
186    reference       front();
187    const_reference front() const;
188    reference       back();
189    const_reference back() const;
190
191    basic_string& assign(const basic_string& str);
192    basic_string& assign(basic_string_view<charT, traits> sv);
193    basic_string& assign(basic_string&& str);
194    basic_string& assign(const basic_string& str, size_type pos, size_type n=npos); // C++14
195    template <class T>
196        basic_string& assign(const T& t, size_type pos, size_type n=npos); // C++17
197    basic_string& assign(const value_type* s, size_type n);
198    basic_string& assign(const value_type* s);
199    basic_string& assign(size_type n, value_type c);
200    template<class InputIterator>
201        basic_string& assign(InputIterator first, InputIterator last);
202    basic_string& assign(initializer_list<value_type>);
203
204    basic_string& insert(size_type pos1, const basic_string& str);
205    basic_string& insert(size_type pos1, basic_string_view<charT, traits> sv);
206    basic_string& insert(size_type pos1, const basic_string& str,
207                         size_type pos2, size_type n);
208    template <class T>
209        basic_string& insert(size_type pos1, const T& t, size_type pos2, size_type n); // C++17
210    basic_string& insert(size_type pos, const value_type* s, size_type n=npos); //C++14
211    basic_string& insert(size_type pos, const value_type* s);
212    basic_string& insert(size_type pos, size_type n, value_type c);
213    iterator      insert(const_iterator p, value_type c);
214    iterator      insert(const_iterator p, size_type n, value_type c);
215    template<class InputIterator>
216        iterator insert(const_iterator p, InputIterator first, InputIterator last);
217    iterator      insert(const_iterator p, initializer_list<value_type>);
218
219    basic_string& erase(size_type pos = 0, size_type n = npos);
220    iterator      erase(const_iterator position);
221    iterator      erase(const_iterator first, const_iterator last);
222
223    basic_string& replace(size_type pos1, size_type n1, const basic_string& str);
224    basic_string& replace(size_type pos1, size_type n1, basic_string_view<charT, traits> sv);
225    basic_string& replace(size_type pos1, size_type n1, const basic_string& str,
226                          size_type pos2, size_type n2=npos); // C++14
227    template <class T>
228        basic_string& replace(size_type pos1, size_type n1, const T& t,
229                              size_type pos2, size_type n); // C++17
230    basic_string& replace(size_type pos, size_type n1, const value_type* s, size_type n2);
231    basic_string& replace(size_type pos, size_type n1, const value_type* s);
232    basic_string& replace(size_type pos, size_type n1, size_type n2, value_type c);
233    basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str);
234    basic_string& replace(const_iterator i1, const_iterator i2, basic_string_view<charT, traits> sv);
235    basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s, size_type n);
236    basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s);
237    basic_string& replace(const_iterator i1, const_iterator i2, size_type n, value_type c);
238    template<class InputIterator>
239        basic_string& replace(const_iterator i1, const_iterator i2, InputIterator j1, InputIterator j2);
240    basic_string& replace(const_iterator i1, const_iterator i2, initializer_list<value_type>);
241
242    size_type copy(value_type* s, size_type n, size_type pos = 0) const;
243    basic_string substr(size_type pos = 0, size_type n = npos) const;
244
245    void swap(basic_string& str)
246        noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
247                 allocator_traits<allocator_type>::is_always_equal::value);  // C++17
248
249    const value_type* c_str() const noexcept;
250    const value_type* data() const noexcept;
251          value_type* data()       noexcept;   // C++17
252
253    allocator_type get_allocator() const noexcept;
254
255    size_type find(const basic_string& str, size_type pos = 0) const noexcept;
256    size_type find(basic_string_view<charT, traits> sv, size_type pos = 0) const noexcept;
257    size_type find(const value_type* s, size_type pos, size_type n) const noexcept;
258    size_type find(const value_type* s, size_type pos = 0) const noexcept;
259    size_type find(value_type c, size_type pos = 0) const noexcept;
260
261    size_type rfind(const basic_string& str, size_type pos = npos) const noexcept;
262    size_type rfind(basic_string_view<charT, traits> sv, size_type pos = npos) const noexcept;
263    size_type rfind(const value_type* s, size_type pos, size_type n) const noexcept;
264    size_type rfind(const value_type* s, size_type pos = npos) const noexcept;
265    size_type rfind(value_type c, size_type pos = npos) const noexcept;
266
267    size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept;
268    size_type find_first_of(basic_string_view<charT, traits> sv, size_type pos = 0) const noexcept;
269    size_type find_first_of(const value_type* s, size_type pos, size_type n) const noexcept;
270    size_type find_first_of(const value_type* s, size_type pos = 0) const noexcept;
271    size_type find_first_of(value_type c, size_type pos = 0) const noexcept;
272
273    size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept;
274    size_type find_last_of(basic_string_view<charT, traits> sv, size_type pos = npos) const noexcept;
275    size_type find_last_of(const value_type* s, size_type pos, size_type n) const noexcept;
276    size_type find_last_of(const value_type* s, size_type pos = npos) const noexcept;
277    size_type find_last_of(value_type c, size_type pos = npos) const noexcept;
278
279    size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept;
280    size_type find_first_not_of(basic_string_view<charT, traits> sv, size_type pos = 0) const noexcept;
281    size_type find_first_not_of(const value_type* s, size_type pos, size_type n) const noexcept;
282    size_type find_first_not_of(const value_type* s, size_type pos = 0) const noexcept;
283    size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept;
284
285    size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept;
286    size_type find_last_not_of(basic_string_view<charT, traits> sv, size_type pos = npos) const noexcept;
287    size_type find_last_not_of(const value_type* s, size_type pos, size_type n) const noexcept;
288    size_type find_last_not_of(const value_type* s, size_type pos = npos) const noexcept;
289    size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept;
290
291    int compare(const basic_string& str) const noexcept;
292    int compare(basic_string_view<charT, traits> sv) const noexcept;
293    int compare(size_type pos1, size_type n1, const basic_string& str) const;
294    int compare(size_type pos1, size_type n1, basic_string_view<charT, traits> sv) const;
295    int compare(size_type pos1, size_type n1, const basic_string& str,
296                size_type pos2, size_type n2=npos) const; // C++14
297    template <class T>
298        int compare(size_type pos1, size_type n1, const T& t,
299                    size_type pos2, size_type n2=npos) const; // C++17
300    int compare(const value_type* s) const noexcept;
301    int compare(size_type pos1, size_type n1, const value_type* s) const;
302    int compare(size_type pos1, size_type n1, const value_type* s, size_type n2) const;
303
304    bool __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 <__debug>
488
489#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
490#pragma GCC system_header
491#endif
492
493_LIBCPP_PUSH_MACROS
494#include <__undef_macros>
495
496
497_LIBCPP_BEGIN_NAMESPACE_STD
498
499// fpos
500
501template <class _StateT>
502class _LIBCPP_TEMPLATE_VIS fpos
503{
504private:
505    _StateT __st_;
506    streamoff __off_;
507public:
508    _LIBCPP_INLINE_VISIBILITY fpos(streamoff __off = streamoff()) : __st_(), __off_(__off) {}
509
510    _LIBCPP_INLINE_VISIBILITY operator streamoff() const {return __off_;}
511
512    _LIBCPP_INLINE_VISIBILITY _StateT state() const {return __st_;}
513    _LIBCPP_INLINE_VISIBILITY void state(_StateT __st) {__st_ = __st;}
514
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    _LIBCPP_INLINE_VISIBILITY fpos& operator-=(streamoff __off) {__off_ -= __off; return *this;}
518    _LIBCPP_INLINE_VISIBILITY fpos  operator- (streamoff __off) const {fpos __t(*this); __t -= __off; return __t;}
519};
520
521template <class _StateT>
522inline _LIBCPP_INLINE_VISIBILITY
523streamoff operator-(const fpos<_StateT>& __x, const fpos<_StateT>& __y)
524    {return streamoff(__x) - streamoff(__y);}
525
526template <class _StateT>
527inline _LIBCPP_INLINE_VISIBILITY
528bool operator==(const fpos<_StateT>& __x, const fpos<_StateT>& __y)
529    {return streamoff(__x) == streamoff(__y);}
530
531template <class _StateT>
532inline _LIBCPP_INLINE_VISIBILITY
533bool operator!=(const fpos<_StateT>& __x, const fpos<_StateT>& __y)
534    {return streamoff(__x) != streamoff(__y);}
535
536// basic_string
537
538template<class _CharT, class _Traits, class _Allocator>
539basic_string<_CharT, _Traits, _Allocator>
540operator+(const basic_string<_CharT, _Traits, _Allocator>& __x,
541          const basic_string<_CharT, _Traits, _Allocator>& __y);
542
543template<class _CharT, class _Traits, class _Allocator>
544basic_string<_CharT, _Traits, _Allocator>
545operator+(const _CharT* __x, const basic_string<_CharT,_Traits,_Allocator>& __y);
546
547template<class _CharT, class _Traits, class _Allocator>
548basic_string<_CharT, _Traits, _Allocator>
549operator+(_CharT __x, const basic_string<_CharT,_Traits,_Allocator>& __y);
550
551template<class _CharT, class _Traits, class _Allocator>
552basic_string<_CharT, _Traits, _Allocator>
553operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const _CharT* __y);
554
555template<class _CharT, class _Traits, class _Allocator>
556basic_string<_CharT, _Traits, _Allocator>
557operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y);
558
559_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&))
560
561template <bool>
562class _LIBCPP_TEMPLATE_VIS __basic_string_common
563{
564protected:
565    _LIBCPP_NORETURN void __throw_length_error() const;
566    _LIBCPP_NORETURN void __throw_out_of_range() const;
567};
568
569template <bool __b>
570void
571__basic_string_common<__b>::__throw_length_error() const
572{
573    _VSTD::__throw_length_error("basic_string");
574}
575
576template <bool __b>
577void
578__basic_string_common<__b>::__throw_out_of_range() const
579{
580    _VSTD::__throw_out_of_range("basic_string");
581}
582
583_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __basic_string_common<true>)
584
585#ifdef _LIBCPP_NO_EXCEPTIONS
586template <class _Iter>
587struct __libcpp_string_gets_noexcept_iterator_impl : public true_type {};
588#elif defined(_LIBCPP_HAS_NO_NOEXCEPT)
589template <class _Iter>
590struct __libcpp_string_gets_noexcept_iterator_impl : public false_type {};
591#else
592template <class _Iter, bool = __is_forward_iterator<_Iter>::value>
593struct __libcpp_string_gets_noexcept_iterator_impl : public _LIBCPP_BOOL_CONSTANT((
594    noexcept(++(declval<_Iter&>())) &&
595    is_nothrow_assignable<_Iter&, _Iter>::value &&
596    noexcept(declval<_Iter>() == declval<_Iter>()) &&
597    noexcept(*declval<_Iter>())
598)) {};
599
600template <class _Iter>
601struct __libcpp_string_gets_noexcept_iterator_impl<_Iter, false> : public false_type {};
602#endif
603
604
605template <class _Iter>
606struct __libcpp_string_gets_noexcept_iterator
607    : public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value || __libcpp_string_gets_noexcept_iterator_impl<_Iter>::value) {};
608
609template <class _CharT, class _Traits, class _Tp>
610struct __can_be_converted_to_string_view : public _LIBCPP_BOOL_CONSTANT(
611    ( is_convertible<const _Tp&, basic_string_view<_CharT, _Traits> >::value &&
612     !is_convertible<const _Tp&, const _CharT*>::value)) {};
613
614#ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
615
616template <class _CharT, size_t = sizeof(_CharT)>
617struct __padding
618{
619    unsigned char __xx[sizeof(_CharT)-1];
620};
621
622template <class _CharT>
623struct __padding<_CharT, 1>
624{
625};
626
627#endif  // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
628
629template<class _CharT, class _Traits, class _Allocator>
630class _LIBCPP_TEMPLATE_VIS basic_string
631    : private __basic_string_common<true>
632{
633public:
634    typedef basic_string                                 __self;
635    typedef basic_string_view<_CharT, _Traits>           __self_view;
636    typedef _Traits                                      traits_type;
637    typedef _CharT                                       value_type;
638    typedef _Allocator                                   allocator_type;
639    typedef allocator_traits<allocator_type>             __alloc_traits;
640    typedef typename __alloc_traits::size_type           size_type;
641    typedef typename __alloc_traits::difference_type     difference_type;
642    typedef value_type&                                  reference;
643    typedef const value_type&                            const_reference;
644    typedef typename __alloc_traits::pointer             pointer;
645    typedef typename __alloc_traits::const_pointer       const_pointer;
646
647    static_assert(is_pod<value_type>::value, "Character type of basic_string must be a POD");
648    static_assert((is_same<_CharT, typename traits_type::char_type>::value),
649                  "traits_type::char_type must be the same type as CharT");
650    static_assert((is_same<typename allocator_type::value_type, value_type>::value),
651                  "Allocator::value_type must be same type as value_type");
652#if defined(_LIBCPP_RAW_ITERATORS)
653    typedef pointer                                      iterator;
654    typedef const_pointer                                const_iterator;
655#else  // defined(_LIBCPP_RAW_ITERATORS)
656    typedef __wrap_iter<pointer>                         iterator;
657    typedef __wrap_iter<const_pointer>                   const_iterator;
658#endif  // defined(_LIBCPP_RAW_ITERATORS)
659    typedef _VSTD::reverse_iterator<iterator>             reverse_iterator;
660    typedef _VSTD::reverse_iterator<const_iterator>       const_reverse_iterator;
661
662private:
663
664#ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
665
666    struct __long
667    {
668        pointer   __data_;
669        size_type __size_;
670        size_type __cap_;
671    };
672
673#ifdef _LIBCPP_BIG_ENDIAN
674    static const size_type __short_mask = 0x01;
675    static const size_type __long_mask  = 0x1ul;
676#else  // _LIBCPP_BIG_ENDIAN
677    static const size_type __short_mask = 0x80;
678    static const size_type __long_mask  = ~(size_type(~0) >> 1);
679#endif  // _LIBCPP_BIG_ENDIAN
680
681    enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ?
682                      (sizeof(__long) - 1)/sizeof(value_type) : 2};
683
684    struct __short
685    {
686        value_type __data_[__min_cap];
687        struct
688            : __padding<value_type>
689        {
690            unsigned char __size_;
691        };
692    };
693
694#else
695
696    struct __long
697    {
698        size_type __cap_;
699        size_type __size_;
700        pointer   __data_;
701    };
702
703#ifdef _LIBCPP_BIG_ENDIAN
704    static const size_type __short_mask = 0x80;
705    static const size_type __long_mask  = ~(size_type(~0) >> 1);
706#else  // _LIBCPP_BIG_ENDIAN
707    static const size_type __short_mask = 0x01;
708    static const size_type __long_mask  = 0x1ul;
709#endif  // _LIBCPP_BIG_ENDIAN
710
711    enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ?
712                      (sizeof(__long) - 1)/sizeof(value_type) : 2};
713
714    struct __short
715    {
716        union
717        {
718            unsigned char __size_;
719            value_type __lx;
720        };
721        value_type __data_[__min_cap];
722    };
723
724#endif  // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
725
726    union __ulx{__long __lx; __short __lxx;};
727
728    enum {__n_words = sizeof(__ulx) / sizeof(size_type)};
729
730    struct __raw
731    {
732        size_type __words[__n_words];
733    };
734
735    struct __rep
736    {
737        union
738        {
739            __long  __l;
740            __short __s;
741            __raw   __r;
742        };
743    };
744
745    __compressed_pair<__rep, allocator_type> __r_;
746
747public:
748    static const size_type npos = -1;
749
750    _LIBCPP_INLINE_VISIBILITY basic_string()
751        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
752
753    _LIBCPP_INLINE_VISIBILITY explicit basic_string(const allocator_type& __a)
754#if _LIBCPP_STD_VER <= 14
755        _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value);
756#else
757        _NOEXCEPT;
758#endif
759
760    basic_string(const basic_string& __str);
761    basic_string(const basic_string& __str, const allocator_type& __a);
762
763#ifndef _LIBCPP_CXX03_LANG
764    _LIBCPP_INLINE_VISIBILITY
765    basic_string(basic_string&& __str)
766#if _LIBCPP_STD_VER <= 14
767        _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
768#else
769        _NOEXCEPT;
770#endif
771
772    _LIBCPP_INLINE_VISIBILITY
773    basic_string(basic_string&& __str, const allocator_type& __a);
774#endif  // _LIBCPP_CXX03_LANG
775    _LIBCPP_INLINE_VISIBILITY basic_string(const _CharT* __s);
776    _LIBCPP_INLINE_VISIBILITY
777    basic_string(const _CharT* __s, const _Allocator& __a);
778    _LIBCPP_INLINE_VISIBILITY
779    basic_string(const _CharT* __s, size_type __n);
780    _LIBCPP_INLINE_VISIBILITY
781    basic_string(const _CharT* __s, size_type __n, const _Allocator& __a);
782    _LIBCPP_INLINE_VISIBILITY
783    basic_string(size_type __n, _CharT __c);
784    _LIBCPP_INLINE_VISIBILITY
785    basic_string(size_type __n, _CharT __c, const _Allocator& __a);
786    basic_string(const basic_string& __str, size_type __pos, size_type __n,
787                 const _Allocator& __a = _Allocator());
788    _LIBCPP_INLINE_VISIBILITY
789    basic_string(const basic_string& __str, size_type __pos,
790                 const _Allocator& __a = _Allocator());
791    template<class _Tp>
792        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
793        basic_string(const _Tp& __t, size_type __pos, size_type __n,
794                     const allocator_type& __a = allocator_type(),
795                     typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type* = 0);
796    _LIBCPP_INLINE_VISIBILITY explicit
797    basic_string(__self_view __sv);
798    _LIBCPP_INLINE_VISIBILITY
799    basic_string(__self_view __sv, const _Allocator& __a);
800    template<class _InputIterator>
801        _LIBCPP_INLINE_VISIBILITY
802        basic_string(_InputIterator __first, _InputIterator __last);
803    template<class _InputIterator>
804        _LIBCPP_INLINE_VISIBILITY
805        basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a);
806#ifndef _LIBCPP_CXX03_LANG
807    _LIBCPP_INLINE_VISIBILITY
808    basic_string(initializer_list<_CharT> __il);
809    _LIBCPP_INLINE_VISIBILITY
810    basic_string(initializer_list<_CharT> __il, const _Allocator& __a);
811#endif  // _LIBCPP_CXX03_LANG
812
813    inline ~basic_string();
814
815    _LIBCPP_INLINE_VISIBILITY
816    operator __self_view() const _NOEXCEPT { return __self_view(data(), size()); }
817
818    basic_string& operator=(const basic_string& __str);
819
820#ifndef _LIBCPP_CXX03_LANG
821    template <class = void>
822#endif
823    _LIBCPP_INLINE_VISIBILITY
824    basic_string& operator=(__self_view __sv)  {return assign(__sv);}
825#ifndef _LIBCPP_CXX03_LANG
826    _LIBCPP_INLINE_VISIBILITY
827    basic_string& operator=(basic_string&& __str)
828        _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));
829     _LIBCPP_INLINE_VISIBILITY
830    basic_string& operator=(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}
831#endif
832    _LIBCPP_INLINE_VISIBILITY basic_string& operator=(const value_type* __s) {return assign(__s);}
833    basic_string& operator=(value_type __c);
834
835#if _LIBCPP_DEBUG_LEVEL >= 2
836    _LIBCPP_INLINE_VISIBILITY
837    iterator begin() _NOEXCEPT
838        {return iterator(this, __get_pointer());}
839    _LIBCPP_INLINE_VISIBILITY
840    const_iterator begin() const _NOEXCEPT
841        {return const_iterator(this, __get_pointer());}
842    _LIBCPP_INLINE_VISIBILITY
843    iterator end() _NOEXCEPT
844        {return iterator(this, __get_pointer() + size());}
845    _LIBCPP_INLINE_VISIBILITY
846    const_iterator end() const _NOEXCEPT
847        {return const_iterator(this, __get_pointer() + size());}
848#else
849    _LIBCPP_INLINE_VISIBILITY
850    iterator begin() _NOEXCEPT
851        {return iterator(__get_pointer());}
852    _LIBCPP_INLINE_VISIBILITY
853    const_iterator begin() const _NOEXCEPT
854        {return const_iterator(__get_pointer());}
855    _LIBCPP_INLINE_VISIBILITY
856    iterator end() _NOEXCEPT
857        {return iterator(__get_pointer() + size());}
858    _LIBCPP_INLINE_VISIBILITY
859    const_iterator end() const _NOEXCEPT
860        {return const_iterator(__get_pointer() + size());}
861#endif  // _LIBCPP_DEBUG_LEVEL >= 2
862    _LIBCPP_INLINE_VISIBILITY
863    reverse_iterator rbegin() _NOEXCEPT
864        {return reverse_iterator(end());}
865    _LIBCPP_INLINE_VISIBILITY
866    const_reverse_iterator rbegin() const _NOEXCEPT
867        {return const_reverse_iterator(end());}
868    _LIBCPP_INLINE_VISIBILITY
869    reverse_iterator rend() _NOEXCEPT
870        {return reverse_iterator(begin());}
871    _LIBCPP_INLINE_VISIBILITY
872    const_reverse_iterator rend() const _NOEXCEPT
873        {return const_reverse_iterator(begin());}
874
875    _LIBCPP_INLINE_VISIBILITY
876    const_iterator cbegin() const _NOEXCEPT
877        {return begin();}
878    _LIBCPP_INLINE_VISIBILITY
879    const_iterator cend() const _NOEXCEPT
880        {return end();}
881    _LIBCPP_INLINE_VISIBILITY
882    const_reverse_iterator crbegin() const _NOEXCEPT
883        {return rbegin();}
884    _LIBCPP_INLINE_VISIBILITY
885    const_reverse_iterator crend() const _NOEXCEPT
886        {return rend();}
887
888    _LIBCPP_INLINE_VISIBILITY size_type size() const _NOEXCEPT
889        {return __is_long() ? __get_long_size() : __get_short_size();}
890    _LIBCPP_INLINE_VISIBILITY size_type length() const _NOEXCEPT {return size();}
891    _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT;
892    _LIBCPP_INLINE_VISIBILITY size_type capacity() const _NOEXCEPT
893        {return (__is_long() ? __get_long_cap()
894                             : static_cast<size_type>(__min_cap)) - 1;}
895
896    void resize(size_type __n, value_type __c);
897    _LIBCPP_INLINE_VISIBILITY void resize(size_type __n) {resize(__n, value_type());}
898
899    void reserve(size_type __res_arg = 0);
900    _LIBCPP_INLINE_VISIBILITY
901    void shrink_to_fit() _NOEXCEPT {reserve();}
902    _LIBCPP_INLINE_VISIBILITY
903    void clear() _NOEXCEPT;
904    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
905    bool empty() const _NOEXCEPT {return size() == 0;}
906
907    _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __pos) const _NOEXCEPT;
908    _LIBCPP_INLINE_VISIBILITY reference       operator[](size_type __pos)       _NOEXCEPT;
909
910    const_reference at(size_type __n) const;
911    reference       at(size_type __n);
912
913    _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const basic_string& __str) {return append(__str);}
914    _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(__self_view __sv)          {return append(__sv);}
915    _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const value_type* __s)     {return append(__s);}
916    _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(value_type __c)            {push_back(__c); return *this;}
917#ifndef _LIBCPP_CXX03_LANG
918    _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(initializer_list<value_type> __il) {return append(__il);}
919#endif  // _LIBCPP_CXX03_LANG
920
921    _LIBCPP_INLINE_VISIBILITY
922    basic_string& append(const basic_string& __str);
923    _LIBCPP_INLINE_VISIBILITY
924    basic_string& append(__self_view __sv) { return append(__sv.data(), __sv.size()); }
925    basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos);
926    template <class _Tp>
927    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
928    typename enable_if
929        <
930            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
931            basic_string&
932        >::type
933                  append(const _Tp& __t, size_type __pos, size_type __n=npos);
934    basic_string& append(const value_type* __s, size_type __n);
935    basic_string& append(const value_type* __s);
936    basic_string& append(size_type __n, value_type __c);
937    template <class _ForwardIterator>
938    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
939    basic_string& __append_forward_unsafe(_ForwardIterator, _ForwardIterator);
940    template<class _InputIterator>
941    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
942    typename enable_if
943        <
944            __is_exactly_input_iterator<_InputIterator>::value
945                || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
946            basic_string&
947        >::type
948    _LIBCPP_INLINE_VISIBILITY
949    append(_InputIterator __first, _InputIterator __last) {
950      const basic_string __temp (__first, __last, __alloc());
951      append(__temp.data(), __temp.size());
952      return *this;
953    }
954    template<class _ForwardIterator>
955    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
956    typename enable_if
957        <
958            __is_forward_iterator<_ForwardIterator>::value
959                && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
960            basic_string&
961        >::type
962    _LIBCPP_INLINE_VISIBILITY
963    append(_ForwardIterator __first, _ForwardIterator __last) {
964      return __append_forward_unsafe(__first, __last);
965    }
966
967#ifndef _LIBCPP_CXX03_LANG
968    _LIBCPP_INLINE_VISIBILITY
969    basic_string& append(initializer_list<value_type> __il) {return append(__il.begin(), __il.size());}
970#endif  // _LIBCPP_CXX03_LANG
971
972    void push_back(value_type __c);
973    _LIBCPP_INLINE_VISIBILITY
974    void pop_back();
975    _LIBCPP_INLINE_VISIBILITY reference       front();
976    _LIBCPP_INLINE_VISIBILITY const_reference front() const;
977    _LIBCPP_INLINE_VISIBILITY reference       back();
978    _LIBCPP_INLINE_VISIBILITY const_reference back() const;
979
980    _LIBCPP_INLINE_VISIBILITY
981    basic_string& assign(__self_view __sv) { return assign(__sv.data(), __sv.size()); }
982    _LIBCPP_INLINE_VISIBILITY
983    basic_string& assign(const basic_string& __str) { return *this = __str; }
984#ifndef _LIBCPP_CXX03_LANG
985    _LIBCPP_INLINE_VISIBILITY
986    basic_string& assign(basic_string&& __str)
987        _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value))
988        {*this = _VSTD::move(__str); return *this;}
989#endif
990    basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos);
991    template <class _Tp>
992    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
993    typename enable_if
994        <
995            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
996            basic_string&
997        >::type
998                  assign(const _Tp & __t, size_type __pos, size_type __n=npos);
999    basic_string& assign(const value_type* __s, size_type __n);
1000    basic_string& assign(const value_type* __s);
1001    basic_string& assign(size_type __n, value_type __c);
1002    template<class _InputIterator>
1003    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
1004    typename enable_if
1005        <
1006           __is_exactly_input_iterator<_InputIterator>::value
1007                || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
1008            basic_string&
1009        >::type
1010        assign(_InputIterator __first, _InputIterator __last);
1011    template<class _ForwardIterator>
1012    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
1013    typename enable_if
1014        <
1015            __is_forward_iterator<_ForwardIterator>::value
1016                 && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
1017            basic_string&
1018        >::type
1019        assign(_ForwardIterator __first, _ForwardIterator __last);
1020#ifndef _LIBCPP_CXX03_LANG
1021    _LIBCPP_INLINE_VISIBILITY
1022    basic_string& assign(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}
1023#endif  // _LIBCPP_CXX03_LANG
1024
1025    _LIBCPP_INLINE_VISIBILITY
1026    basic_string& insert(size_type __pos1, const basic_string& __str);
1027    _LIBCPP_INLINE_VISIBILITY
1028    basic_string& insert(size_type __pos1, __self_view __sv) { return insert(__pos1, __sv.data(), __sv.size()); }
1029    template <class _Tp>
1030    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
1031    typename enable_if
1032        <
1033            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
1034            basic_string&
1035        >::type
1036                  insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n=npos);
1037    basic_string& insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n=npos);
1038    basic_string& insert(size_type __pos, const value_type* __s, size_type __n);
1039    basic_string& insert(size_type __pos, const value_type* __s);
1040    basic_string& insert(size_type __pos, size_type __n, value_type __c);
1041    iterator      insert(const_iterator __pos, value_type __c);
1042    _LIBCPP_INLINE_VISIBILITY
1043    iterator      insert(const_iterator __pos, size_type __n, value_type __c);
1044    template<class _InputIterator>
1045    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
1046    typename enable_if
1047        <
1048           __is_exactly_input_iterator<_InputIterator>::value
1049                || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
1050            iterator
1051        >::type
1052        insert(const_iterator __pos, _InputIterator __first, _InputIterator __last);
1053    template<class _ForwardIterator>
1054    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
1055    typename enable_if
1056        <
1057            __is_forward_iterator<_ForwardIterator>::value
1058                 && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
1059            iterator
1060        >::type
1061        insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last);
1062#ifndef _LIBCPP_CXX03_LANG
1063    _LIBCPP_INLINE_VISIBILITY
1064    iterator insert(const_iterator __pos, initializer_list<value_type> __il)
1065                    {return insert(__pos, __il.begin(), __il.end());}
1066#endif  // _LIBCPP_CXX03_LANG
1067
1068    basic_string& erase(size_type __pos = 0, size_type __n = npos);
1069    _LIBCPP_INLINE_VISIBILITY
1070    iterator      erase(const_iterator __pos);
1071    _LIBCPP_INLINE_VISIBILITY
1072    iterator      erase(const_iterator __first, const_iterator __last);
1073
1074    _LIBCPP_INLINE_VISIBILITY
1075    basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str);
1076    _LIBCPP_INLINE_VISIBILITY
1077    basic_string& replace(size_type __pos1, size_type __n1, __self_view __sv) { return replace(__pos1, __n1, __sv.data(), __sv.size()); }
1078    basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos);
1079    template <class _Tp>
1080    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
1081    typename enable_if
1082        <
1083            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
1084            basic_string&
1085        >::type
1086                  replace(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos);
1087    basic_string& replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2);
1088    basic_string& replace(size_type __pos, size_type __n1, const value_type* __s);
1089    basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c);
1090    _LIBCPP_INLINE_VISIBILITY
1091    basic_string& replace(const_iterator __i1, const_iterator __i2, const basic_string& __str);
1092    _LIBCPP_INLINE_VISIBILITY
1093    basic_string& replace(const_iterator __i1, const_iterator __i2, __self_view __sv) { return replace(__i1 - begin(), __i2 - __i1, __sv); }
1094    _LIBCPP_INLINE_VISIBILITY
1095    basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n);
1096    _LIBCPP_INLINE_VISIBILITY
1097    basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s);
1098    _LIBCPP_INLINE_VISIBILITY
1099    basic_string& replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c);
1100    template<class _InputIterator>
1101    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
1102    typename enable_if
1103        <
1104            __is_input_iterator<_InputIterator>::value,
1105            basic_string&
1106        >::type
1107        replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2);
1108#ifndef _LIBCPP_CXX03_LANG
1109    _LIBCPP_INLINE_VISIBILITY
1110    basic_string& replace(const_iterator __i1, const_iterator __i2, initializer_list<value_type> __il)
1111        {return replace(__i1, __i2, __il.begin(), __il.end());}
1112#endif  // _LIBCPP_CXX03_LANG
1113
1114    size_type copy(value_type* __s, size_type __n, size_type __pos = 0) const;
1115    _LIBCPP_INLINE_VISIBILITY
1116    basic_string substr(size_type __pos = 0, size_type __n = npos) const;
1117
1118    _LIBCPP_INLINE_VISIBILITY
1119    void swap(basic_string& __str)
1120#if _LIBCPP_STD_VER >= 14
1121        _NOEXCEPT_DEBUG;
1122#else
1123        _NOEXCEPT_DEBUG_(!__alloc_traits::propagate_on_container_swap::value ||
1124                    __is_nothrow_swappable<allocator_type>::value);
1125#endif
1126
1127    _LIBCPP_INLINE_VISIBILITY
1128    const value_type* c_str() const _NOEXCEPT {return data();}
1129    _LIBCPP_INLINE_VISIBILITY
1130    const value_type* data() const _NOEXCEPT  {return _VSTD::__to_raw_pointer(__get_pointer());}
1131#if _LIBCPP_STD_VER > 14 || defined(_LIBCPP_BUILDING_LIBRARY)
1132    _LIBCPP_INLINE_VISIBILITY
1133    value_type* data()             _NOEXCEPT  {return _VSTD::__to_raw_pointer(__get_pointer());}
1134#endif
1135
1136    _LIBCPP_INLINE_VISIBILITY
1137    allocator_type get_allocator() const _NOEXCEPT {return __alloc();}
1138
1139    _LIBCPP_INLINE_VISIBILITY
1140    size_type find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
1141    _LIBCPP_INLINE_VISIBILITY
1142    size_type find(__self_view __sv, size_type __pos = 0) const _NOEXCEPT;
1143    size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1144    _LIBCPP_INLINE_VISIBILITY
1145    size_type find(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
1146    size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT;
1147
1148    _LIBCPP_INLINE_VISIBILITY
1149    size_type rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
1150    _LIBCPP_INLINE_VISIBILITY
1151    size_type rfind(__self_view __sv, size_type __pos = npos) const _NOEXCEPT;
1152    size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1153    _LIBCPP_INLINE_VISIBILITY
1154    size_type rfind(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
1155    size_type rfind(value_type __c, size_type __pos = npos) const _NOEXCEPT;
1156
1157    _LIBCPP_INLINE_VISIBILITY
1158    size_type find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
1159    _LIBCPP_INLINE_VISIBILITY
1160    size_type find_first_of(__self_view __sv, size_type __pos = 0) const _NOEXCEPT;
1161    size_type find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1162    _LIBCPP_INLINE_VISIBILITY
1163    size_type find_first_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
1164    _LIBCPP_INLINE_VISIBILITY
1165    size_type find_first_of(value_type __c, size_type __pos = 0) const _NOEXCEPT;
1166
1167    _LIBCPP_INLINE_VISIBILITY
1168    size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
1169    _LIBCPP_INLINE_VISIBILITY
1170    size_type find_last_of(__self_view __sv, size_type __pos = npos) const _NOEXCEPT;
1171    size_type find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1172    _LIBCPP_INLINE_VISIBILITY
1173    size_type find_last_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
1174    _LIBCPP_INLINE_VISIBILITY
1175    size_type find_last_of(value_type __c, size_type __pos = npos) const _NOEXCEPT;
1176
1177    _LIBCPP_INLINE_VISIBILITY
1178    size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
1179    _LIBCPP_INLINE_VISIBILITY
1180    size_type find_first_not_of(__self_view __sv, size_type __pos = 0) const _NOEXCEPT;
1181    size_type find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1182    _LIBCPP_INLINE_VISIBILITY
1183    size_type find_first_not_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
1184    _LIBCPP_INLINE_VISIBILITY
1185    size_type find_first_not_of(value_type __c, size_type __pos = 0) const _NOEXCEPT;
1186
1187    _LIBCPP_INLINE_VISIBILITY
1188    size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
1189    _LIBCPP_INLINE_VISIBILITY
1190    size_type find_last_not_of(__self_view __sv, size_type __pos = npos) const _NOEXCEPT;
1191    size_type find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1192    _LIBCPP_INLINE_VISIBILITY
1193    size_type find_last_not_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
1194    _LIBCPP_INLINE_VISIBILITY
1195    size_type find_last_not_of(value_type __c, size_type __pos = npos) const _NOEXCEPT;
1196
1197    _LIBCPP_INLINE_VISIBILITY
1198    int compare(const basic_string& __str) const _NOEXCEPT;
1199    _LIBCPP_INLINE_VISIBILITY
1200    int compare(__self_view __sv) const _NOEXCEPT;
1201    _LIBCPP_INLINE_VISIBILITY
1202    int compare(size_type __pos1, size_type __n1, __self_view __sv) const;
1203    _LIBCPP_INLINE_VISIBILITY
1204    int compare(size_type __pos1, size_type __n1, const basic_string& __str) const;
1205    int compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos) const;
1206    template <class _Tp>
1207    inline _LIBCPP_INLINE_VISIBILITY
1208        typename enable_if
1209        <
1210            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
1211            int
1212        >::type
1213        compare(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos) const;
1214    int compare(const value_type* __s) const _NOEXCEPT;
1215    int compare(size_type __pos1, size_type __n1, const value_type* __s) const;
1216    int compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const;
1217
1218    _LIBCPP_INLINE_VISIBILITY bool __invariants() const;
1219
1220    _LIBCPP_INLINE_VISIBILITY
1221    bool __is_long() const _NOEXCEPT
1222        {return bool(__r_.first().__s.__size_ & __short_mask);}
1223
1224#if _LIBCPP_DEBUG_LEVEL >= 2
1225
1226    bool __dereferenceable(const const_iterator* __i) const;
1227    bool __decrementable(const const_iterator* __i) const;
1228    bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
1229    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
1230
1231#endif  // _LIBCPP_DEBUG_LEVEL >= 2
1232
1233private:
1234    _LIBCPP_INLINE_VISIBILITY
1235    allocator_type& __alloc() _NOEXCEPT
1236        {return __r_.second();}
1237    _LIBCPP_INLINE_VISIBILITY
1238    const allocator_type& __alloc() const _NOEXCEPT
1239        {return __r_.second();}
1240
1241#ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
1242
1243    _LIBCPP_INLINE_VISIBILITY
1244    void __set_short_size(size_type __s) _NOEXCEPT
1245#   ifdef _LIBCPP_BIG_ENDIAN
1246        {__r_.first().__s.__size_ = (unsigned char)(__s << 1);}
1247#   else
1248        {__r_.first().__s.__size_ = (unsigned char)(__s);}
1249#   endif
1250
1251    _LIBCPP_INLINE_VISIBILITY
1252    size_type __get_short_size() const _NOEXCEPT
1253#   ifdef _LIBCPP_BIG_ENDIAN
1254        {return __r_.first().__s.__size_ >> 1;}
1255#   else
1256        {return __r_.first().__s.__size_;}
1257#   endif
1258
1259#else  // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
1260
1261    _LIBCPP_INLINE_VISIBILITY
1262    void __set_short_size(size_type __s) _NOEXCEPT
1263#   ifdef _LIBCPP_BIG_ENDIAN
1264        {__r_.first().__s.__size_ = (unsigned char)(__s);}
1265#   else
1266        {__r_.first().__s.__size_ = (unsigned char)(__s << 1);}
1267#   endif
1268
1269    _LIBCPP_INLINE_VISIBILITY
1270    size_type __get_short_size() const _NOEXCEPT
1271#   ifdef _LIBCPP_BIG_ENDIAN
1272        {return __r_.first().__s.__size_;}
1273#   else
1274        {return __r_.first().__s.__size_ >> 1;}
1275#   endif
1276
1277#endif  // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
1278
1279    _LIBCPP_INLINE_VISIBILITY
1280    void __set_long_size(size_type __s) _NOEXCEPT
1281        {__r_.first().__l.__size_ = __s;}
1282    _LIBCPP_INLINE_VISIBILITY
1283    size_type __get_long_size() const _NOEXCEPT
1284        {return __r_.first().__l.__size_;}
1285    _LIBCPP_INLINE_VISIBILITY
1286    void __set_size(size_type __s) _NOEXCEPT
1287        {if (__is_long()) __set_long_size(__s); else __set_short_size(__s);}
1288
1289    _LIBCPP_INLINE_VISIBILITY
1290    void __set_long_cap(size_type __s) _NOEXCEPT
1291        {__r_.first().__l.__cap_  = __long_mask | __s;}
1292    _LIBCPP_INLINE_VISIBILITY
1293    size_type __get_long_cap() const _NOEXCEPT
1294        {return __r_.first().__l.__cap_ & size_type(~__long_mask);}
1295
1296    _LIBCPP_INLINE_VISIBILITY
1297    void __set_long_pointer(pointer __p) _NOEXCEPT
1298        {__r_.first().__l.__data_ = __p;}
1299    _LIBCPP_INLINE_VISIBILITY
1300    pointer __get_long_pointer() _NOEXCEPT
1301        {return __r_.first().__l.__data_;}
1302    _LIBCPP_INLINE_VISIBILITY
1303    const_pointer __get_long_pointer() const _NOEXCEPT
1304        {return __r_.first().__l.__data_;}
1305    _LIBCPP_INLINE_VISIBILITY
1306    pointer __get_short_pointer() _NOEXCEPT
1307        {return pointer_traits<pointer>::pointer_to(__r_.first().__s.__data_[0]);}
1308    _LIBCPP_INLINE_VISIBILITY
1309    const_pointer __get_short_pointer() const _NOEXCEPT
1310        {return pointer_traits<const_pointer>::pointer_to(__r_.first().__s.__data_[0]);}
1311    _LIBCPP_INLINE_VISIBILITY
1312    pointer __get_pointer() _NOEXCEPT
1313        {return __is_long() ? __get_long_pointer() : __get_short_pointer();}
1314    _LIBCPP_INLINE_VISIBILITY
1315    const_pointer __get_pointer() const _NOEXCEPT
1316        {return __is_long() ? __get_long_pointer() : __get_short_pointer();}
1317
1318    _LIBCPP_INLINE_VISIBILITY
1319    void __zero() _NOEXCEPT
1320        {
1321            size_type (&__a)[__n_words] = __r_.first().__r.__words;
1322            for (unsigned __i = 0; __i < __n_words; ++__i)
1323                __a[__i] = 0;
1324        }
1325
1326    template <size_type __a> static
1327        _LIBCPP_INLINE_VISIBILITY
1328        size_type __align_it(size_type __s) _NOEXCEPT
1329            {return (__s + (__a-1)) & ~(__a-1);}
1330    enum {__alignment = 16};
1331    static _LIBCPP_INLINE_VISIBILITY
1332    size_type __recommend(size_type __s) _NOEXCEPT
1333        {return (__s < __min_cap ? static_cast<size_type>(__min_cap) :
1334                 __align_it<sizeof(value_type) < __alignment ?
1335                            __alignment/sizeof(value_type) : 1 > (__s+1)) - 1;}
1336
1337    inline
1338    void __init(const value_type* __s, size_type __sz, size_type __reserve);
1339    inline
1340    void __init(const value_type* __s, size_type __sz);
1341    inline
1342    void __init(size_type __n, value_type __c);
1343
1344    template <class _InputIterator>
1345    inline
1346    typename enable_if
1347    <
1348        __is_exactly_input_iterator<_InputIterator>::value,
1349        void
1350    >::type
1351    __init(_InputIterator __first, _InputIterator __last);
1352
1353    template <class _ForwardIterator>
1354    inline
1355    typename enable_if
1356    <
1357        __is_forward_iterator<_ForwardIterator>::value,
1358        void
1359    >::type
1360    __init(_ForwardIterator __first, _ForwardIterator __last);
1361
1362    void __grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
1363                   size_type __n_copy,  size_type __n_del,     size_type __n_add = 0);
1364    void __grow_by_and_replace(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
1365                               size_type __n_copy,  size_type __n_del,
1366                               size_type __n_add, const value_type* __p_new_stuff);
1367
1368    _LIBCPP_INLINE_VISIBILITY
1369    void __erase_to_end(size_type __pos);
1370
1371    _LIBCPP_INLINE_VISIBILITY
1372    void __copy_assign_alloc(const basic_string& __str)
1373        {__copy_assign_alloc(__str, integral_constant<bool,
1374                      __alloc_traits::propagate_on_container_copy_assignment::value>());}
1375
1376    _LIBCPP_INLINE_VISIBILITY
1377    void __copy_assign_alloc(const basic_string& __str, true_type)
1378        {
1379            if (__alloc() == __str.__alloc())
1380                __alloc() = __str.__alloc();
1381            else
1382            {
1383                if (!__str.__is_long())
1384                {
1385                    clear();
1386                    shrink_to_fit();
1387                    __alloc() = __str.__alloc();
1388                }
1389                else
1390                {
1391                    allocator_type __a = __str.__alloc();
1392                    pointer __p = __alloc_traits::allocate(__a, __str.__get_long_cap());
1393                    clear();
1394                    shrink_to_fit();
1395                    __alloc() = _VSTD::move(__a);
1396                    __set_long_pointer(__p);
1397                    __set_long_cap(__str.__get_long_cap());
1398                    __set_long_size(__str.size());
1399                }
1400            }
1401        }
1402
1403    _LIBCPP_INLINE_VISIBILITY
1404    void __copy_assign_alloc(const basic_string&, false_type) _NOEXCEPT
1405        {}
1406
1407#ifndef _LIBCPP_CXX03_LANG
1408    _LIBCPP_INLINE_VISIBILITY
1409    void __move_assign(basic_string& __str, false_type)
1410        _NOEXCEPT_(__alloc_traits::is_always_equal::value);
1411    _LIBCPP_INLINE_VISIBILITY
1412    void __move_assign(basic_string& __str, true_type)
1413#if _LIBCPP_STD_VER > 14
1414        _NOEXCEPT;
1415#else
1416        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
1417#endif
1418#endif
1419
1420    _LIBCPP_INLINE_VISIBILITY
1421    void
1422    __move_assign_alloc(basic_string& __str)
1423        _NOEXCEPT_(
1424            !__alloc_traits::propagate_on_container_move_assignment::value ||
1425            is_nothrow_move_assignable<allocator_type>::value)
1426    {__move_assign_alloc(__str, integral_constant<bool,
1427                      __alloc_traits::propagate_on_container_move_assignment::value>());}
1428
1429    _LIBCPP_INLINE_VISIBILITY
1430    void __move_assign_alloc(basic_string& __c, true_type)
1431        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
1432        {
1433            __alloc() = _VSTD::move(__c.__alloc());
1434        }
1435
1436    _LIBCPP_INLINE_VISIBILITY
1437    void __move_assign_alloc(basic_string&, false_type)
1438        _NOEXCEPT
1439        {}
1440
1441    _LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators();
1442    _LIBCPP_INLINE_VISIBILITY void __invalidate_iterators_past(size_type);
1443
1444    friend basic_string operator+<>(const basic_string&, const basic_string&);
1445    friend basic_string operator+<>(const value_type*, const basic_string&);
1446    friend basic_string operator+<>(value_type, const basic_string&);
1447    friend basic_string operator+<>(const basic_string&, const value_type*);
1448    friend basic_string operator+<>(const basic_string&, value_type);
1449};
1450
1451template <class _CharT, class _Traits, class _Allocator>
1452inline _LIBCPP_INLINE_VISIBILITY
1453void
1454basic_string<_CharT, _Traits, _Allocator>::__invalidate_all_iterators()
1455{
1456#if _LIBCPP_DEBUG_LEVEL >= 2
1457    __get_db()->__invalidate_all(this);
1458#endif  // _LIBCPP_DEBUG_LEVEL >= 2
1459}
1460
1461template <class _CharT, class _Traits, class _Allocator>
1462inline _LIBCPP_INLINE_VISIBILITY
1463void
1464basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type
1465#if _LIBCPP_DEBUG_LEVEL >= 2
1466                                                                        __pos
1467#endif
1468                                                                      )
1469{
1470#if _LIBCPP_DEBUG_LEVEL >= 2
1471    __c_node* __c = __get_db()->__find_c_and_lock(this);
1472    if (__c)
1473    {
1474        const_pointer __new_last = __get_pointer() + __pos;
1475        for (__i_node** __p = __c->end_; __p != __c->beg_; )
1476        {
1477            --__p;
1478            const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
1479            if (__i->base() > __new_last)
1480            {
1481                (*__p)->__c_ = nullptr;
1482                if (--__c->end_ != __p)
1483                    memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
1484            }
1485        }
1486        __get_db()->unlock();
1487    }
1488#endif  // _LIBCPP_DEBUG_LEVEL >= 2
1489}
1490
1491template <class _CharT, class _Traits, class _Allocator>
1492inline _LIBCPP_INLINE_VISIBILITY
1493basic_string<_CharT, _Traits, _Allocator>::basic_string()
1494    _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
1495{
1496#if _LIBCPP_DEBUG_LEVEL >= 2
1497    __get_db()->__insert_c(this);
1498#endif
1499    __zero();
1500}
1501
1502template <class _CharT, class _Traits, class _Allocator>
1503inline _LIBCPP_INLINE_VISIBILITY
1504basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __a)
1505#if _LIBCPP_STD_VER <= 14
1506        _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
1507#else
1508        _NOEXCEPT
1509#endif
1510: __r_(__second_tag(), __a)
1511{
1512#if _LIBCPP_DEBUG_LEVEL >= 2
1513    __get_db()->__insert_c(this);
1514#endif
1515    __zero();
1516}
1517
1518template <class _CharT, class _Traits, class _Allocator>
1519void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s,
1520                                                       size_type __sz,
1521                                                       size_type __reserve)
1522{
1523    if (__reserve > max_size())
1524        this->__throw_length_error();
1525    pointer __p;
1526    if (__reserve < __min_cap)
1527    {
1528        __set_short_size(__sz);
1529        __p = __get_short_pointer();
1530    }
1531    else
1532    {
1533        size_type __cap = __recommend(__reserve);
1534        __p = __alloc_traits::allocate(__alloc(), __cap+1);
1535        __set_long_pointer(__p);
1536        __set_long_cap(__cap+1);
1537        __set_long_size(__sz);
1538    }
1539    traits_type::copy(_VSTD::__to_raw_pointer(__p), __s, __sz);
1540    traits_type::assign(__p[__sz], value_type());
1541}
1542
1543template <class _CharT, class _Traits, class _Allocator>
1544void
1545basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz)
1546{
1547    if (__sz > max_size())
1548        this->__throw_length_error();
1549    pointer __p;
1550    if (__sz < __min_cap)
1551    {
1552        __set_short_size(__sz);
1553        __p = __get_short_pointer();
1554    }
1555    else
1556    {
1557        size_type __cap = __recommend(__sz);
1558        __p = __alloc_traits::allocate(__alloc(), __cap+1);
1559        __set_long_pointer(__p);
1560        __set_long_cap(__cap+1);
1561        __set_long_size(__sz);
1562    }
1563    traits_type::copy(_VSTD::__to_raw_pointer(__p), __s, __sz);
1564    traits_type::assign(__p[__sz], value_type());
1565}
1566
1567template <class _CharT, class _Traits, class _Allocator>
1568inline _LIBCPP_INLINE_VISIBILITY
1569basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s)
1570{
1571    _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr");
1572    __init(__s, traits_type::length(__s));
1573#if _LIBCPP_DEBUG_LEVEL >= 2
1574    __get_db()->__insert_c(this);
1575#endif
1576}
1577
1578template <class _CharT, class _Traits, class _Allocator>
1579inline _LIBCPP_INLINE_VISIBILITY
1580basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const _Allocator& __a)
1581    : __r_(__second_tag(), __a)
1582{
1583    _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr");
1584    __init(__s, traits_type::length(__s));
1585#if _LIBCPP_DEBUG_LEVEL >= 2
1586    __get_db()->__insert_c(this);
1587#endif
1588}
1589
1590template <class _CharT, class _Traits, class _Allocator>
1591inline _LIBCPP_INLINE_VISIBILITY
1592basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n)
1593{
1594    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr");
1595    __init(__s, __n);
1596#if _LIBCPP_DEBUG_LEVEL >= 2
1597    __get_db()->__insert_c(this);
1598#endif
1599}
1600
1601template <class _CharT, class _Traits, class _Allocator>
1602inline _LIBCPP_INLINE_VISIBILITY
1603basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n, const _Allocator& __a)
1604    : __r_(__second_tag(), __a)
1605{
1606    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr");
1607    __init(__s, __n);
1608#if _LIBCPP_DEBUG_LEVEL >= 2
1609    __get_db()->__insert_c(this);
1610#endif
1611}
1612
1613template <class _CharT, class _Traits, class _Allocator>
1614basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str)
1615    : __r_(__second_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc()))
1616{
1617    if (!__str.__is_long())
1618        __r_.first().__r = __str.__r_.first().__r;
1619    else
1620        __init(_VSTD::__to_raw_pointer(__str.__get_long_pointer()), __str.__get_long_size());
1621#if _LIBCPP_DEBUG_LEVEL >= 2
1622    __get_db()->__insert_c(this);
1623#endif
1624}
1625
1626template <class _CharT, class _Traits, class _Allocator>
1627basic_string<_CharT, _Traits, _Allocator>::basic_string(
1628    const basic_string& __str, const allocator_type& __a)
1629    : __r_(__second_tag(), __a)
1630{
1631    if (!__str.__is_long())
1632        __r_.first().__r = __str.__r_.first().__r;
1633    else
1634        __init(_VSTD::__to_raw_pointer(__str.__get_long_pointer()), __str.__get_long_size());
1635#if _LIBCPP_DEBUG_LEVEL >= 2
1636    __get_db()->__insert_c(this);
1637#endif
1638}
1639
1640#ifndef _LIBCPP_CXX03_LANG
1641
1642template <class _CharT, class _Traits, class _Allocator>
1643inline _LIBCPP_INLINE_VISIBILITY
1644basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str)
1645#if _LIBCPP_STD_VER <= 14
1646        _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
1647#else
1648        _NOEXCEPT
1649#endif
1650    : __r_(_VSTD::move(__str.__r_))
1651{
1652    __str.__zero();
1653#if _LIBCPP_DEBUG_LEVEL >= 2
1654    __get_db()->__insert_c(this);
1655    if (__is_long())
1656        __get_db()->swap(this, &__str);
1657#endif
1658}
1659
1660template <class _CharT, class _Traits, class _Allocator>
1661inline _LIBCPP_INLINE_VISIBILITY
1662basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, const allocator_type& __a)
1663    : __r_(__second_tag(), __a)
1664{
1665    if (__str.__is_long() && __a != __str.__alloc()) // copy, not move
1666        __init(_VSTD::__to_raw_pointer(__str.__get_long_pointer()), __str.__get_long_size());
1667    else
1668    {
1669        __r_.first().__r = __str.__r_.first().__r;
1670        __str.__zero();
1671    }
1672#if _LIBCPP_DEBUG_LEVEL >= 2
1673    __get_db()->__insert_c(this);
1674    if (__is_long())
1675        __get_db()->swap(this, &__str);
1676#endif
1677}
1678
1679#endif  // _LIBCPP_CXX03_LANG
1680
1681template <class _CharT, class _Traits, class _Allocator>
1682void
1683basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c)
1684{
1685    if (__n > max_size())
1686        this->__throw_length_error();
1687    pointer __p;
1688    if (__n < __min_cap)
1689    {
1690        __set_short_size(__n);
1691        __p = __get_short_pointer();
1692    }
1693    else
1694    {
1695        size_type __cap = __recommend(__n);
1696        __p = __alloc_traits::allocate(__alloc(), __cap+1);
1697        __set_long_pointer(__p);
1698        __set_long_cap(__cap+1);
1699        __set_long_size(__n);
1700    }
1701    traits_type::assign(_VSTD::__to_raw_pointer(__p), __n, __c);
1702    traits_type::assign(__p[__n], value_type());
1703}
1704
1705template <class _CharT, class _Traits, class _Allocator>
1706inline _LIBCPP_INLINE_VISIBILITY
1707basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c)
1708{
1709    __init(__n, __c);
1710#if _LIBCPP_DEBUG_LEVEL >= 2
1711    __get_db()->__insert_c(this);
1712#endif
1713}
1714
1715template <class _CharT, class _Traits, class _Allocator>
1716inline _LIBCPP_INLINE_VISIBILITY
1717basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c, const _Allocator& __a)
1718    : __r_(__second_tag(), __a)
1719{
1720    __init(__n, __c);
1721#if _LIBCPP_DEBUG_LEVEL >= 2
1722    __get_db()->__insert_c(this);
1723#endif
1724}
1725
1726template <class _CharT, class _Traits, class _Allocator>
1727basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str,
1728                                                        size_type __pos, size_type __n,
1729                                                        const _Allocator& __a)
1730    : __r_(__second_tag(), __a)
1731{
1732    size_type __str_sz = __str.size();
1733    if (__pos > __str_sz)
1734        this->__throw_out_of_range();
1735    __init(__str.data() + __pos, _VSTD::min(__n, __str_sz - __pos));
1736#if _LIBCPP_DEBUG_LEVEL >= 2
1737    __get_db()->__insert_c(this);
1738#endif
1739}
1740
1741template <class _CharT, class _Traits, class _Allocator>
1742inline _LIBCPP_INLINE_VISIBILITY
1743basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos,
1744                                                        const _Allocator& __a)
1745    : __r_(__second_tag(), __a)
1746{
1747    size_type __str_sz = __str.size();
1748    if (__pos > __str_sz)
1749        this->__throw_out_of_range();
1750    __init(__str.data() + __pos, __str_sz - __pos);
1751#if _LIBCPP_DEBUG_LEVEL >= 2
1752    __get_db()->__insert_c(this);
1753#endif
1754}
1755
1756template <class _CharT, class _Traits, class _Allocator>
1757template <class _Tp>
1758basic_string<_CharT, _Traits, _Allocator>::basic_string(
1759             const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a,
1760             typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type *)
1761    : __r_(__second_tag(), __a)
1762{
1763    __self_view __sv = __self_view(__t).substr(__pos, __n);
1764    __init(__sv.data(), __sv.size());
1765#if _LIBCPP_DEBUG_LEVEL >= 2
1766    __get_db()->__insert_c(this);
1767#endif
1768}
1769
1770template <class _CharT, class _Traits, class _Allocator>
1771inline _LIBCPP_INLINE_VISIBILITY
1772basic_string<_CharT, _Traits, _Allocator>::basic_string(__self_view __sv)
1773{
1774    __init(__sv.data(), __sv.size());
1775#if _LIBCPP_DEBUG_LEVEL >= 2
1776    __get_db()->__insert_c(this);
1777#endif
1778}
1779
1780template <class _CharT, class _Traits, class _Allocator>
1781inline _LIBCPP_INLINE_VISIBILITY
1782basic_string<_CharT, _Traits, _Allocator>::basic_string(__self_view __sv, const _Allocator& __a)
1783    : __r_(__second_tag(), __a)
1784{
1785    __init(__sv.data(), __sv.size());
1786#if _LIBCPP_DEBUG_LEVEL >= 2
1787    __get_db()->__insert_c(this);
1788#endif
1789}
1790
1791template <class _CharT, class _Traits, class _Allocator>
1792template <class _InputIterator>
1793typename enable_if
1794<
1795    __is_exactly_input_iterator<_InputIterator>::value,
1796    void
1797>::type
1798basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last)
1799{
1800    __zero();
1801#ifndef _LIBCPP_NO_EXCEPTIONS
1802    try
1803    {
1804#endif  // _LIBCPP_NO_EXCEPTIONS
1805    for (; __first != __last; ++__first)
1806        push_back(*__first);
1807#ifndef _LIBCPP_NO_EXCEPTIONS
1808    }
1809    catch (...)
1810    {
1811        if (__is_long())
1812            __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
1813        throw;
1814    }
1815#endif  // _LIBCPP_NO_EXCEPTIONS
1816}
1817
1818template <class _CharT, class _Traits, class _Allocator>
1819template <class _ForwardIterator>
1820typename enable_if
1821<
1822    __is_forward_iterator<_ForwardIterator>::value,
1823    void
1824>::type
1825basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last)
1826{
1827    size_type __sz = static_cast<size_type>(_VSTD::distance(__first, __last));
1828    if (__sz > max_size())
1829        this->__throw_length_error();
1830    pointer __p;
1831    if (__sz < __min_cap)
1832    {
1833        __set_short_size(__sz);
1834        __p = __get_short_pointer();
1835    }
1836    else
1837    {
1838        size_type __cap = __recommend(__sz);
1839        __p = __alloc_traits::allocate(__alloc(), __cap+1);
1840        __set_long_pointer(__p);
1841        __set_long_cap(__cap+1);
1842        __set_long_size(__sz);
1843    }
1844    for (; __first != __last; ++__first, (void) ++__p)
1845        traits_type::assign(*__p, *__first);
1846    traits_type::assign(*__p, value_type());
1847}
1848
1849template <class _CharT, class _Traits, class _Allocator>
1850template<class _InputIterator>
1851inline _LIBCPP_INLINE_VISIBILITY
1852basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last)
1853{
1854    __init(__first, __last);
1855#if _LIBCPP_DEBUG_LEVEL >= 2
1856    __get_db()->__insert_c(this);
1857#endif
1858}
1859
1860template <class _CharT, class _Traits, class _Allocator>
1861template<class _InputIterator>
1862inline _LIBCPP_INLINE_VISIBILITY
1863basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last,
1864                                                        const allocator_type& __a)
1865    : __r_(__second_tag(), __a)
1866{
1867    __init(__first, __last);
1868#if _LIBCPP_DEBUG_LEVEL >= 2
1869    __get_db()->__insert_c(this);
1870#endif
1871}
1872
1873#ifndef _LIBCPP_CXX03_LANG
1874
1875template <class _CharT, class _Traits, class _Allocator>
1876inline _LIBCPP_INLINE_VISIBILITY
1877basic_string<_CharT, _Traits, _Allocator>::basic_string(
1878    initializer_list<_CharT> __il)
1879{
1880    __init(__il.begin(), __il.end());
1881#if _LIBCPP_DEBUG_LEVEL >= 2
1882    __get_db()->__insert_c(this);
1883#endif
1884}
1885
1886template <class _CharT, class _Traits, class _Allocator>
1887inline _LIBCPP_INLINE_VISIBILITY
1888
1889basic_string<_CharT, _Traits, _Allocator>::basic_string(
1890    initializer_list<_CharT> __il, const _Allocator& __a)
1891    : __r_(__second_tag(), __a)
1892{
1893    __init(__il.begin(), __il.end());
1894#if _LIBCPP_DEBUG_LEVEL >= 2
1895    __get_db()->__insert_c(this);
1896#endif
1897}
1898
1899#endif  // _LIBCPP_CXX03_LANG
1900
1901template <class _CharT, class _Traits, class _Allocator>
1902basic_string<_CharT, _Traits, _Allocator>::~basic_string()
1903{
1904#if _LIBCPP_DEBUG_LEVEL >= 2
1905    __get_db()->__erase_c(this);
1906#endif
1907    if (__is_long())
1908        __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
1909}
1910
1911template <class _CharT, class _Traits, class _Allocator>
1912void
1913basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace
1914    (size_type __old_cap, size_type __delta_cap, size_type __old_sz,
1915     size_type __n_copy,  size_type __n_del,     size_type __n_add, const value_type* __p_new_stuff)
1916{
1917    size_type __ms = max_size();
1918    if (__delta_cap > __ms - __old_cap - 1)
1919        this->__throw_length_error();
1920    pointer __old_p = __get_pointer();
1921    size_type __cap = __old_cap < __ms / 2 - __alignment ?
1922                          __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) :
1923                          __ms - 1;
1924    pointer __p = __alloc_traits::allocate(__alloc(), __cap+1);
1925    __invalidate_all_iterators();
1926    if (__n_copy != 0)
1927        traits_type::copy(_VSTD::__to_raw_pointer(__p),
1928                          _VSTD::__to_raw_pointer(__old_p), __n_copy);
1929    if (__n_add != 0)
1930        traits_type::copy(_VSTD::__to_raw_pointer(__p) + __n_copy, __p_new_stuff, __n_add);
1931    size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
1932    if (__sec_cp_sz != 0)
1933        traits_type::copy(_VSTD::__to_raw_pointer(__p) + __n_copy + __n_add,
1934                          _VSTD::__to_raw_pointer(__old_p) + __n_copy + __n_del, __sec_cp_sz);
1935    if (__old_cap+1 != __min_cap)
1936        __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1);
1937    __set_long_pointer(__p);
1938    __set_long_cap(__cap+1);
1939    __old_sz = __n_copy + __n_add + __sec_cp_sz;
1940    __set_long_size(__old_sz);
1941    traits_type::assign(__p[__old_sz], value_type());
1942}
1943
1944template <class _CharT, class _Traits, class _Allocator>
1945void
1946basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
1947                                                     size_type __n_copy,  size_type __n_del,     size_type __n_add)
1948{
1949    size_type __ms = max_size();
1950    if (__delta_cap > __ms - __old_cap)
1951        this->__throw_length_error();
1952    pointer __old_p = __get_pointer();
1953    size_type __cap = __old_cap < __ms / 2 - __alignment ?
1954                          __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) :
1955                          __ms - 1;
1956    pointer __p = __alloc_traits::allocate(__alloc(), __cap+1);
1957    __invalidate_all_iterators();
1958    if (__n_copy != 0)
1959        traits_type::copy(_VSTD::__to_raw_pointer(__p),
1960                          _VSTD::__to_raw_pointer(__old_p), __n_copy);
1961    size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
1962    if (__sec_cp_sz != 0)
1963        traits_type::copy(_VSTD::__to_raw_pointer(__p) + __n_copy + __n_add,
1964                          _VSTD::__to_raw_pointer(__old_p) + __n_copy + __n_del,
1965                          __sec_cp_sz);
1966    if (__old_cap+1 != __min_cap)
1967        __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1);
1968    __set_long_pointer(__p);
1969    __set_long_cap(__cap+1);
1970}
1971
1972// assign
1973
1974template <class _CharT, class _Traits, class _Allocator>
1975basic_string<_CharT, _Traits, _Allocator>&
1976basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n)
1977{
1978    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::assign received nullptr");
1979    size_type __cap = capacity();
1980    if (__cap >= __n)
1981    {
1982        value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());
1983        traits_type::move(__p, __s, __n);
1984        traits_type::assign(__p[__n], value_type());
1985        __set_size(__n);
1986        __invalidate_iterators_past(__n);
1987    }
1988    else
1989    {
1990        size_type __sz = size();
1991        __grow_by_and_replace(__cap, __n - __cap, __sz, 0, __sz, __n, __s);
1992    }
1993    return *this;
1994}
1995
1996template <class _CharT, class _Traits, class _Allocator>
1997basic_string<_CharT, _Traits, _Allocator>&
1998basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c)
1999{
2000    size_type __cap = capacity();
2001    if (__cap < __n)
2002    {
2003        size_type __sz = size();
2004        __grow_by(__cap, __n - __cap, __sz, 0, __sz);
2005    }
2006    else
2007        __invalidate_iterators_past(__n);
2008    value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());
2009    traits_type::assign(__p, __n, __c);
2010    traits_type::assign(__p[__n], value_type());
2011    __set_size(__n);
2012    return *this;
2013}
2014
2015template <class _CharT, class _Traits, class _Allocator>
2016basic_string<_CharT, _Traits, _Allocator>&
2017basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c)
2018{
2019    pointer __p;
2020    if (__is_long())
2021    {
2022        __p = __get_long_pointer();
2023        __set_long_size(1);
2024    }
2025    else
2026    {
2027        __p = __get_short_pointer();
2028        __set_short_size(1);
2029    }
2030    traits_type::assign(*__p, __c);
2031    traits_type::assign(*++__p, value_type());
2032    __invalidate_iterators_past(1);
2033    return *this;
2034}
2035
2036template <class _CharT, class _Traits, class _Allocator>
2037basic_string<_CharT, _Traits, _Allocator>&
2038basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str)
2039{
2040    if (this != &__str)
2041    {
2042        __copy_assign_alloc(__str);
2043        assign(__str.data(), __str.size());
2044    }
2045    return *this;
2046}
2047
2048#ifndef _LIBCPP_CXX03_LANG
2049
2050template <class _CharT, class _Traits, class _Allocator>
2051inline _LIBCPP_INLINE_VISIBILITY
2052void
2053basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, false_type)
2054    _NOEXCEPT_(__alloc_traits::is_always_equal::value)
2055{
2056    if (__alloc() != __str.__alloc())
2057        assign(__str);
2058    else
2059        __move_assign(__str, true_type());
2060}
2061
2062template <class _CharT, class _Traits, class _Allocator>
2063inline _LIBCPP_INLINE_VISIBILITY
2064void
2065basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type)
2066#if _LIBCPP_STD_VER > 14
2067    _NOEXCEPT
2068#else
2069    _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
2070#endif
2071{
2072    clear();
2073    shrink_to_fit();
2074    __r_.first() = __str.__r_.first();
2075    __move_assign_alloc(__str);
2076    __str.__zero();
2077}
2078
2079template <class _CharT, class _Traits, class _Allocator>
2080inline _LIBCPP_INLINE_VISIBILITY
2081basic_string<_CharT, _Traits, _Allocator>&
2082basic_string<_CharT, _Traits, _Allocator>::operator=(basic_string&& __str)
2083    _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value))
2084{
2085    __move_assign(__str, integral_constant<bool,
2086          __alloc_traits::propagate_on_container_move_assignment::value>());
2087    return *this;
2088}
2089
2090#endif
2091
2092template <class _CharT, class _Traits, class _Allocator>
2093template<class _InputIterator>
2094typename enable_if
2095<
2096     __is_exactly_input_iterator <_InputIterator>::value
2097          || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
2098    basic_string<_CharT, _Traits, _Allocator>&
2099>::type
2100basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
2101{
2102    const basic_string __temp(__first, __last, __alloc());
2103    assign(__temp.data(), __temp.size());
2104    return *this;
2105}
2106
2107template <class _CharT, class _Traits, class _Allocator>
2108template<class _ForwardIterator>
2109typename enable_if
2110<
2111    __is_forward_iterator<_ForwardIterator>::value
2112         && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
2113    basic_string<_CharT, _Traits, _Allocator>&
2114>::type
2115basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)
2116{
2117    size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
2118    size_type __cap = capacity();
2119    if (__cap < __n)
2120    {
2121        size_type __sz = size();
2122        __grow_by(__cap, __n - __cap, __sz, 0, __sz);
2123    }
2124    else
2125        __invalidate_iterators_past(__n);
2126    pointer __p = __get_pointer();
2127    for (; __first != __last; ++__first, ++__p)
2128        traits_type::assign(*__p, *__first);
2129    traits_type::assign(*__p, value_type());
2130    __set_size(__n);
2131    return *this;
2132}
2133
2134template <class _CharT, class _Traits, class _Allocator>
2135basic_string<_CharT, _Traits, _Allocator>&
2136basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, size_type __pos, size_type __n)
2137{
2138    size_type __sz = __str.size();
2139    if (__pos > __sz)
2140        this->__throw_out_of_range();
2141    return assign(__str.data() + __pos, _VSTD::min(__n, __sz - __pos));
2142}
2143
2144template <class _CharT, class _Traits, class _Allocator>
2145template <class _Tp>
2146typename enable_if
2147<
2148    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
2149    basic_string<_CharT, _Traits, _Allocator>&
2150>::type
2151basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t, size_type __pos, size_type __n)
2152{
2153    __self_view __sv = __t;
2154    size_type __sz = __sv.size();
2155    if (__pos > __sz)
2156        this->__throw_out_of_range();
2157    return assign(__sv.data() + __pos, _VSTD::min(__n, __sz - __pos));
2158}
2159
2160
2161template <class _CharT, class _Traits, class _Allocator>
2162basic_string<_CharT, _Traits, _Allocator>&
2163basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s)
2164{
2165    _LIBCPP_ASSERT(__s != nullptr, "string::assign received nullptr");
2166    return assign(__s, traits_type::length(__s));
2167}
2168
2169// append
2170
2171template <class _CharT, class _Traits, class _Allocator>
2172basic_string<_CharT, _Traits, _Allocator>&
2173basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n)
2174{
2175    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::append received nullptr");
2176    size_type __cap = capacity();
2177    size_type __sz = size();
2178    if (__cap - __sz >= __n)
2179    {
2180        if (__n)
2181        {
2182            value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());
2183            traits_type::copy(__p + __sz, __s, __n);
2184            __sz += __n;
2185            __set_size(__sz);
2186            traits_type::assign(__p[__sz], value_type());
2187        }
2188    }
2189    else
2190        __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __sz, 0, __n, __s);
2191    return *this;
2192}
2193
2194template <class _CharT, class _Traits, class _Allocator>
2195basic_string<_CharT, _Traits, _Allocator>&
2196basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c)
2197{
2198    if (__n)
2199    {
2200        size_type __cap = capacity();
2201        size_type __sz = size();
2202        if (__cap - __sz < __n)
2203            __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
2204        pointer __p = __get_pointer();
2205        traits_type::assign(_VSTD::__to_raw_pointer(__p) + __sz, __n, __c);
2206        __sz += __n;
2207        __set_size(__sz);
2208        traits_type::assign(__p[__sz], value_type());
2209    }
2210    return *this;
2211}
2212
2213template <class _CharT, class _Traits, class _Allocator>
2214void
2215basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c)
2216{
2217    bool __is_short = !__is_long();
2218    size_type __cap;
2219    size_type __sz;
2220    if (__is_short)
2221    {
2222        __cap = __min_cap - 1;
2223        __sz = __get_short_size();
2224    }
2225    else
2226    {
2227        __cap = __get_long_cap() - 1;
2228        __sz = __get_long_size();
2229    }
2230    if (__sz == __cap)
2231    {
2232        __grow_by(__cap, 1, __sz, __sz, 0);
2233        __is_short = !__is_long();
2234    }
2235    pointer __p;
2236    if (__is_short)
2237    {
2238        __p = __get_short_pointer() + __sz;
2239        __set_short_size(__sz+1);
2240    }
2241    else
2242    {
2243        __p = __get_long_pointer() + __sz;
2244        __set_long_size(__sz+1);
2245    }
2246    traits_type::assign(*__p, __c);
2247    traits_type::assign(*++__p, value_type());
2248}
2249
2250template <class _Tp>
2251bool __ptr_in_range (const _Tp* __p, const _Tp* __first, const _Tp* __last)
2252{
2253    return __first <= __p && __p < __last;
2254}
2255
2256template <class _Tp1, class _Tp2>
2257bool __ptr_in_range (const _Tp1*, const _Tp2*, const _Tp2*)
2258{
2259    return false;
2260}
2261
2262template <class _CharT, class _Traits, class _Allocator>
2263template<class _ForwardIterator>
2264basic_string<_CharT, _Traits, _Allocator>&
2265basic_string<_CharT, _Traits, _Allocator>::__append_forward_unsafe(
2266    _ForwardIterator __first, _ForwardIterator __last)
2267{
2268    static_assert(__is_forward_iterator<_ForwardIterator>::value,
2269                  "function requires a ForwardIterator");
2270    size_type __sz = size();
2271    size_type __cap = capacity();
2272    size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
2273    if (__n)
2274    {
2275        typedef typename iterator_traits<_ForwardIterator>::reference _CharRef;
2276        _CharRef __tmp_ref = *__first;
2277        if (__ptr_in_range(_VSTD::addressof(__tmp_ref), data(), data() + size()))
2278        {
2279            const basic_string __temp (__first, __last, __alloc());
2280            append(__temp.data(), __temp.size());
2281        }
2282        else
2283        {
2284            if (__cap - __sz < __n)
2285                __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
2286            pointer __p = __get_pointer() + __sz;
2287            for (; __first != __last; ++__p, ++__first)
2288                traits_type::assign(*__p, *__first);
2289            traits_type::assign(*__p, value_type());
2290            __set_size(__sz + __n);
2291        }
2292    }
2293    return *this;
2294}
2295
2296template <class _CharT, class _Traits, class _Allocator>
2297inline _LIBCPP_INLINE_VISIBILITY
2298basic_string<_CharT, _Traits, _Allocator>&
2299basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str)
2300{
2301    return append(__str.data(), __str.size());
2302}
2303
2304template <class _CharT, class _Traits, class _Allocator>
2305basic_string<_CharT, _Traits, _Allocator>&
2306basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, size_type __pos, size_type __n)
2307{
2308    size_type __sz = __str.size();
2309    if (__pos > __sz)
2310        this->__throw_out_of_range();
2311    return append(__str.data() + __pos, _VSTD::min(__n, __sz - __pos));
2312}
2313
2314template <class _CharT, class _Traits, class _Allocator>
2315template <class _Tp>
2316    typename enable_if
2317    <
2318        __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
2319        basic_string<_CharT, _Traits, _Allocator>&
2320    >::type
2321basic_string<_CharT, _Traits, _Allocator>::append(const _Tp & __t, size_type __pos, size_type __n)
2322{
2323    __self_view __sv = __t;
2324    size_type __sz = __sv.size();
2325    if (__pos > __sz)
2326        this->__throw_out_of_range();
2327    return append(__sv.data() + __pos, _VSTD::min(__n, __sz - __pos));
2328}
2329
2330template <class _CharT, class _Traits, class _Allocator>
2331basic_string<_CharT, _Traits, _Allocator>&
2332basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s)
2333{
2334    _LIBCPP_ASSERT(__s != nullptr, "string::append received nullptr");
2335    return append(__s, traits_type::length(__s));
2336}
2337
2338// insert
2339
2340template <class _CharT, class _Traits, class _Allocator>
2341basic_string<_CharT, _Traits, _Allocator>&
2342basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n)
2343{
2344    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::insert received nullptr");
2345    size_type __sz = size();
2346    if (__pos > __sz)
2347        this->__throw_out_of_range();
2348    size_type __cap = capacity();
2349    if (__cap - __sz >= __n)
2350    {
2351        if (__n)
2352        {
2353            value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());
2354            size_type __n_move = __sz - __pos;
2355            if (__n_move != 0)
2356            {
2357                if (__p + __pos <= __s && __s < __p + __sz)
2358                    __s += __n;
2359                traits_type::move(__p + __pos + __n, __p + __pos, __n_move);
2360            }
2361            traits_type::move(__p + __pos, __s, __n);
2362            __sz += __n;
2363            __set_size(__sz);
2364            traits_type::assign(__p[__sz], value_type());
2365        }
2366    }
2367    else
2368        __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s);
2369    return *this;
2370}
2371
2372template <class _CharT, class _Traits, class _Allocator>
2373basic_string<_CharT, _Traits, _Allocator>&
2374basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n, value_type __c)
2375{
2376    size_type __sz = size();
2377    if (__pos > __sz)
2378        this->__throw_out_of_range();
2379    if (__n)
2380    {
2381        size_type __cap = capacity();
2382        value_type* __p;
2383        if (__cap - __sz >= __n)
2384        {
2385            __p = _VSTD::__to_raw_pointer(__get_pointer());
2386            size_type __n_move = __sz - __pos;
2387            if (__n_move != 0)
2388                traits_type::move(__p + __pos + __n, __p + __pos, __n_move);
2389        }
2390        else
2391        {
2392            __grow_by(__cap, __sz + __n - __cap, __sz, __pos, 0, __n);
2393            __p = _VSTD::__to_raw_pointer(__get_long_pointer());
2394        }
2395        traits_type::assign(__p + __pos, __n, __c);
2396        __sz += __n;
2397        __set_size(__sz);
2398        traits_type::assign(__p[__sz], value_type());
2399    }
2400    return *this;
2401}
2402
2403template <class _CharT, class _Traits, class _Allocator>
2404template<class _InputIterator>
2405typename enable_if
2406<
2407   __is_exactly_input_iterator<_InputIterator>::value
2408        || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
2409   typename basic_string<_CharT, _Traits, _Allocator>::iterator
2410>::type
2411basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last)
2412{
2413#if _LIBCPP_DEBUG_LEVEL >= 2
2414    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
2415        "string::insert(iterator, range) called with an iterator not"
2416        " referring to this string");
2417#endif
2418    const basic_string __temp(__first, __last, __alloc());
2419    return insert(__pos, __temp.data(), __temp.data() + __temp.size());
2420}
2421
2422template <class _CharT, class _Traits, class _Allocator>
2423template<class _ForwardIterator>
2424typename enable_if
2425<
2426    __is_forward_iterator<_ForwardIterator>::value
2427        && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
2428    typename basic_string<_CharT, _Traits, _Allocator>::iterator
2429>::type
2430basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last)
2431{
2432#if _LIBCPP_DEBUG_LEVEL >= 2
2433    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
2434        "string::insert(iterator, range) called with an iterator not"
2435        " referring to this string");
2436#endif
2437    size_type __ip = static_cast<size_type>(__pos - begin());
2438    size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
2439    if (__n)
2440    {
2441        typedef typename iterator_traits<_ForwardIterator>::reference _CharRef;
2442        _CharRef __tmp_char = *__first;
2443        if (__ptr_in_range(_VSTD::addressof(__tmp_char), 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#ifdef _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_CXX03_LANG
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_CXX03_LANG
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_CXX03_LANG
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_CXX03_LANG
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_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_string<char>)
4004_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_string<wchar_t>)
4005
4006#if _LIBCPP_STD_VER > 11
4007// Literal suffixes for basic_string [basic.string.literals]
4008inline namespace literals
4009{
4010  inline namespace string_literals
4011  {
4012    inline _LIBCPP_INLINE_VISIBILITY
4013    basic_string<char> operator "" s( const char *__str, size_t __len )
4014    {
4015        return basic_string<char> (__str, __len);
4016    }
4017
4018    inline _LIBCPP_INLINE_VISIBILITY
4019    basic_string<wchar_t> operator "" s( const wchar_t *__str, size_t __len )
4020    {
4021        return basic_string<wchar_t> (__str, __len);
4022    }
4023
4024    inline _LIBCPP_INLINE_VISIBILITY
4025    basic_string<char16_t> operator "" s( const char16_t *__str, size_t __len )
4026    {
4027        return basic_string<char16_t> (__str, __len);
4028    }
4029
4030    inline _LIBCPP_INLINE_VISIBILITY
4031    basic_string<char32_t> operator "" s( const char32_t *__str, size_t __len )
4032    {
4033        return basic_string<char32_t> (__str, __len);
4034    }
4035  }
4036}
4037#endif
4038
4039_LIBCPP_END_NAMESPACE_STD
4040
4041_LIBCPP_POP_MACROS
4042
4043#endif  // _LIBCPP_STRING
4044