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