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