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