xref: /freebsd-12.1/contrib/libc++/include/string (revision bd47c7ec)
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(0xDFFF);}
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    : __r_(__a)
1940{
1941#if _LIBCPP_DEBUG_LEVEL >= 2
1942    __get_db()->__insert_c(this);
1943#endif
1944    __zero();
1945}
1946
1947template <class _CharT, class _Traits, class _Allocator>
1948void
1949basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz, size_type __reserve)
1950{
1951    if (__reserve > max_size())
1952        this->__throw_length_error();
1953    pointer __p;
1954    if (__reserve < __min_cap)
1955    {
1956        __set_short_size(__sz);
1957        __p = __get_short_pointer();
1958    }
1959    else
1960    {
1961        size_type __cap = __recommend(__reserve);
1962        __p = __alloc_traits::allocate(__alloc(), __cap+1);
1963        __set_long_pointer(__p);
1964        __set_long_cap(__cap+1);
1965        __set_long_size(__sz);
1966    }
1967    traits_type::copy(_VSTD::__to_raw_pointer(__p), __s, __sz);
1968    traits_type::assign(__p[__sz], value_type());
1969}
1970
1971template <class _CharT, class _Traits, class _Allocator>
1972void
1973basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz)
1974{
1975    if (__sz > max_size())
1976        this->__throw_length_error();
1977    pointer __p;
1978    if (__sz < __min_cap)
1979    {
1980        __set_short_size(__sz);
1981        __p = __get_short_pointer();
1982    }
1983    else
1984    {
1985        size_type __cap = __recommend(__sz);
1986        __p = __alloc_traits::allocate(__alloc(), __cap+1);
1987        __set_long_pointer(__p);
1988        __set_long_cap(__cap+1);
1989        __set_long_size(__sz);
1990    }
1991    traits_type::copy(_VSTD::__to_raw_pointer(__p), __s, __sz);
1992    traits_type::assign(__p[__sz], value_type());
1993}
1994
1995template <class _CharT, class _Traits, class _Allocator>
1996inline _LIBCPP_INLINE_VISIBILITY
1997basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s)
1998{
1999    _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr");
2000    __init(__s, traits_type::length(__s));
2001#if _LIBCPP_DEBUG_LEVEL >= 2
2002    __get_db()->__insert_c(this);
2003#endif
2004}
2005
2006template <class _CharT, class _Traits, class _Allocator>
2007inline _LIBCPP_INLINE_VISIBILITY
2008basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, const allocator_type& __a)
2009    : __r_(__a)
2010{
2011    _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr");
2012    __init(__s, traits_type::length(__s));
2013#if _LIBCPP_DEBUG_LEVEL >= 2
2014    __get_db()->__insert_c(this);
2015#endif
2016}
2017
2018template <class _CharT, class _Traits, class _Allocator>
2019inline _LIBCPP_INLINE_VISIBILITY
2020basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, size_type __n)
2021{
2022    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr");
2023    __init(__s, __n);
2024#if _LIBCPP_DEBUG_LEVEL >= 2
2025    __get_db()->__insert_c(this);
2026#endif
2027}
2028
2029template <class _CharT, class _Traits, class _Allocator>
2030inline _LIBCPP_INLINE_VISIBILITY
2031basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, size_type __n, const allocator_type& __a)
2032    : __r_(__a)
2033{
2034    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr");
2035    __init(__s, __n);
2036#if _LIBCPP_DEBUG_LEVEL >= 2
2037    __get_db()->__insert_c(this);
2038#endif
2039}
2040
2041template <class _CharT, class _Traits, class _Allocator>
2042basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str)
2043    : __r_(__alloc_traits::select_on_container_copy_construction(__str.__alloc()))
2044{
2045    if (!__str.__is_long())
2046        __r_.first().__r = __str.__r_.first().__r;
2047    else
2048        __init(_VSTD::__to_raw_pointer(__str.__get_long_pointer()), __str.__get_long_size());
2049#if _LIBCPP_DEBUG_LEVEL >= 2
2050    __get_db()->__insert_c(this);
2051#endif
2052}
2053
2054template <class _CharT, class _Traits, class _Allocator>
2055basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, const allocator_type& __a)
2056    : __r_(__a)
2057{
2058    if (!__str.__is_long())
2059        __r_.first().__r = __str.__r_.first().__r;
2060    else
2061        __init(_VSTD::__to_raw_pointer(__str.__get_long_pointer()), __str.__get_long_size());
2062#if _LIBCPP_DEBUG_LEVEL >= 2
2063    __get_db()->__insert_c(this);
2064#endif
2065}
2066
2067#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2068
2069template <class _CharT, class _Traits, class _Allocator>
2070inline _LIBCPP_INLINE_VISIBILITY
2071basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str)
2072#if _LIBCPP_STD_VER <= 14
2073        _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
2074#else
2075        _NOEXCEPT
2076#endif
2077    : __r_(_VSTD::move(__str.__r_))
2078{
2079    __str.__zero();
2080#if _LIBCPP_DEBUG_LEVEL >= 2
2081    __get_db()->__insert_c(this);
2082    if (__is_long())
2083        __get_db()->swap(this, &__str);
2084#endif
2085}
2086
2087template <class _CharT, class _Traits, class _Allocator>
2088inline _LIBCPP_INLINE_VISIBILITY
2089basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, const allocator_type& __a)
2090    : __r_(__a)
2091{
2092    if (__str.__is_long() && __a != __str.__alloc()) // copy, not move
2093        __init(_VSTD::__to_raw_pointer(__str.__get_long_pointer()), __str.__get_long_size());
2094    else
2095    {
2096        __r_.first().__r = __str.__r_.first().__r;
2097        __str.__zero();
2098    }
2099#if _LIBCPP_DEBUG_LEVEL >= 2
2100    __get_db()->__insert_c(this);
2101    if (__is_long())
2102        __get_db()->swap(this, &__str);
2103#endif
2104}
2105
2106#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2107
2108template <class _CharT, class _Traits, class _Allocator>
2109void
2110basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c)
2111{
2112    if (__n > max_size())
2113        this->__throw_length_error();
2114    pointer __p;
2115    if (__n < __min_cap)
2116    {
2117        __set_short_size(__n);
2118        __p = __get_short_pointer();
2119    }
2120    else
2121    {
2122        size_type __cap = __recommend(__n);
2123        __p = __alloc_traits::allocate(__alloc(), __cap+1);
2124        __set_long_pointer(__p);
2125        __set_long_cap(__cap+1);
2126        __set_long_size(__n);
2127    }
2128    traits_type::assign(_VSTD::__to_raw_pointer(__p), __n, __c);
2129    traits_type::assign(__p[__n], value_type());
2130}
2131
2132template <class _CharT, class _Traits, class _Allocator>
2133inline _LIBCPP_INLINE_VISIBILITY
2134basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, value_type __c)
2135{
2136    __init(__n, __c);
2137#if _LIBCPP_DEBUG_LEVEL >= 2
2138    __get_db()->__insert_c(this);
2139#endif
2140}
2141
2142template <class _CharT, class _Traits, class _Allocator>
2143inline _LIBCPP_INLINE_VISIBILITY
2144basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, value_type __c, const allocator_type& __a)
2145    : __r_(__a)
2146{
2147    __init(__n, __c);
2148#if _LIBCPP_DEBUG_LEVEL >= 2
2149    __get_db()->__insert_c(this);
2150#endif
2151}
2152
2153template <class _CharT, class _Traits, class _Allocator>
2154basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos, size_type __n,
2155                                                        const allocator_type& __a)
2156    : __r_(__a)
2157{
2158    size_type __str_sz = __str.size();
2159    if (__pos > __str_sz)
2160        this->__throw_out_of_range();
2161    __init(__str.data() + __pos, _VSTD::min(__n, __str_sz - __pos));
2162#if _LIBCPP_DEBUG_LEVEL >= 2
2163    __get_db()->__insert_c(this);
2164#endif
2165}
2166
2167template <class _CharT, class _Traits, class _Allocator>
2168template <class _InputIterator>
2169typename enable_if
2170<
2171     __is_input_iterator  <_InputIterator>::value &&
2172    !__is_forward_iterator<_InputIterator>::value,
2173    void
2174>::type
2175basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last)
2176{
2177    __zero();
2178#ifndef _LIBCPP_NO_EXCEPTIONS
2179    try
2180    {
2181#endif  // _LIBCPP_NO_EXCEPTIONS
2182    for (; __first != __last; ++__first)
2183        push_back(*__first);
2184#ifndef _LIBCPP_NO_EXCEPTIONS
2185    }
2186    catch (...)
2187    {
2188        if (__is_long())
2189            __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
2190        throw;
2191    }
2192#endif  // _LIBCPP_NO_EXCEPTIONS
2193}
2194
2195template <class _CharT, class _Traits, class _Allocator>
2196template <class _ForwardIterator>
2197typename enable_if
2198<
2199    __is_forward_iterator<_ForwardIterator>::value,
2200    void
2201>::type
2202basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last)
2203{
2204    size_type __sz = static_cast<size_type>(_VSTD::distance(__first, __last));
2205    if (__sz > max_size())
2206        this->__throw_length_error();
2207    pointer __p;
2208    if (__sz < __min_cap)
2209    {
2210        __set_short_size(__sz);
2211        __p = __get_short_pointer();
2212    }
2213    else
2214    {
2215        size_type __cap = __recommend(__sz);
2216        __p = __alloc_traits::allocate(__alloc(), __cap+1);
2217        __set_long_pointer(__p);
2218        __set_long_cap(__cap+1);
2219        __set_long_size(__sz);
2220    }
2221    for (; __first != __last; ++__first, (void) ++__p)
2222        traits_type::assign(*__p, *__first);
2223    traits_type::assign(*__p, value_type());
2224}
2225
2226template <class _CharT, class _Traits, class _Allocator>
2227template<class _InputIterator>
2228inline _LIBCPP_INLINE_VISIBILITY
2229basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last)
2230{
2231    __init(__first, __last);
2232#if _LIBCPP_DEBUG_LEVEL >= 2
2233    __get_db()->__insert_c(this);
2234#endif
2235}
2236
2237template <class _CharT, class _Traits, class _Allocator>
2238template<class _InputIterator>
2239inline _LIBCPP_INLINE_VISIBILITY
2240basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last,
2241                                                        const allocator_type& __a)
2242    : __r_(__a)
2243{
2244    __init(__first, __last);
2245#if _LIBCPP_DEBUG_LEVEL >= 2
2246    __get_db()->__insert_c(this);
2247#endif
2248}
2249
2250#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
2251
2252template <class _CharT, class _Traits, class _Allocator>
2253inline _LIBCPP_INLINE_VISIBILITY
2254basic_string<_CharT, _Traits, _Allocator>::basic_string(initializer_list<value_type> __il)
2255{
2256    __init(__il.begin(), __il.end());
2257#if _LIBCPP_DEBUG_LEVEL >= 2
2258    __get_db()->__insert_c(this);
2259#endif
2260}
2261
2262template <class _CharT, class _Traits, class _Allocator>
2263inline _LIBCPP_INLINE_VISIBILITY
2264basic_string<_CharT, _Traits, _Allocator>::basic_string(initializer_list<value_type> __il, const allocator_type& __a)
2265    : __r_(__a)
2266{
2267    __init(__il.begin(), __il.end());
2268#if _LIBCPP_DEBUG_LEVEL >= 2
2269    __get_db()->__insert_c(this);
2270#endif
2271}
2272
2273#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
2274
2275template <class _CharT, class _Traits, class _Allocator>
2276basic_string<_CharT, _Traits, _Allocator>::~basic_string()
2277{
2278#if _LIBCPP_DEBUG_LEVEL >= 2
2279    __get_db()->__erase_c(this);
2280#endif
2281    if (__is_long())
2282        __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
2283}
2284
2285template <class _CharT, class _Traits, class _Allocator>
2286void
2287basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace
2288    (size_type __old_cap, size_type __delta_cap, size_type __old_sz,
2289     size_type __n_copy,  size_type __n_del,     size_type __n_add, const value_type* __p_new_stuff)
2290{
2291    size_type __ms = max_size();
2292    if (__delta_cap > __ms - __old_cap - 1)
2293        this->__throw_length_error();
2294    pointer __old_p = __get_pointer();
2295    size_type __cap = __old_cap < __ms / 2 - __alignment ?
2296                          __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) :
2297                          __ms - 1;
2298    pointer __p = __alloc_traits::allocate(__alloc(), __cap+1);
2299    __invalidate_all_iterators();
2300    if (__n_copy != 0)
2301        traits_type::copy(_VSTD::__to_raw_pointer(__p),
2302                          _VSTD::__to_raw_pointer(__old_p), __n_copy);
2303    if (__n_add != 0)
2304        traits_type::copy(_VSTD::__to_raw_pointer(__p) + __n_copy, __p_new_stuff, __n_add);
2305    size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
2306    if (__sec_cp_sz != 0)
2307        traits_type::copy(_VSTD::__to_raw_pointer(__p) + __n_copy + __n_add,
2308                          _VSTD::__to_raw_pointer(__old_p) + __n_copy + __n_del, __sec_cp_sz);
2309    if (__old_cap+1 != __min_cap)
2310        __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1);
2311    __set_long_pointer(__p);
2312    __set_long_cap(__cap+1);
2313    __old_sz = __n_copy + __n_add + __sec_cp_sz;
2314    __set_long_size(__old_sz);
2315    traits_type::assign(__p[__old_sz], value_type());
2316}
2317
2318template <class _CharT, class _Traits, class _Allocator>
2319void
2320basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
2321                                                     size_type __n_copy,  size_type __n_del,     size_type __n_add)
2322{
2323    size_type __ms = max_size();
2324    if (__delta_cap > __ms - __old_cap)
2325        this->__throw_length_error();
2326    pointer __old_p = __get_pointer();
2327    size_type __cap = __old_cap < __ms / 2 - __alignment ?
2328                          __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) :
2329                          __ms - 1;
2330    pointer __p = __alloc_traits::allocate(__alloc(), __cap+1);
2331    __invalidate_all_iterators();
2332    if (__n_copy != 0)
2333        traits_type::copy(_VSTD::__to_raw_pointer(__p),
2334                          _VSTD::__to_raw_pointer(__old_p), __n_copy);
2335    size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
2336    if (__sec_cp_sz != 0)
2337        traits_type::copy(_VSTD::__to_raw_pointer(__p) + __n_copy + __n_add,
2338                          _VSTD::__to_raw_pointer(__old_p) + __n_copy + __n_del,
2339                          __sec_cp_sz);
2340    if (__old_cap+1 != __min_cap)
2341        __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1);
2342    __set_long_pointer(__p);
2343    __set_long_cap(__cap+1);
2344}
2345
2346// assign
2347
2348template <class _CharT, class _Traits, class _Allocator>
2349basic_string<_CharT, _Traits, _Allocator>&
2350basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n)
2351{
2352    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::assign received nullptr");
2353    size_type __cap = capacity();
2354    if (__cap >= __n)
2355    {
2356        value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());
2357        traits_type::move(__p, __s, __n);
2358        traits_type::assign(__p[__n], value_type());
2359        __set_size(__n);
2360        __invalidate_iterators_past(__n);
2361    }
2362    else
2363    {
2364        size_type __sz = size();
2365        __grow_by_and_replace(__cap, __n - __cap, __sz, 0, __sz, __n, __s);
2366    }
2367    return *this;
2368}
2369
2370template <class _CharT, class _Traits, class _Allocator>
2371basic_string<_CharT, _Traits, _Allocator>&
2372basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c)
2373{
2374    size_type __cap = capacity();
2375    if (__cap < __n)
2376    {
2377        size_type __sz = size();
2378        __grow_by(__cap, __n - __cap, __sz, 0, __sz);
2379    }
2380    else
2381        __invalidate_iterators_past(__n);
2382    value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());
2383    traits_type::assign(__p, __n, __c);
2384    traits_type::assign(__p[__n], value_type());
2385    __set_size(__n);
2386    return *this;
2387}
2388
2389template <class _CharT, class _Traits, class _Allocator>
2390basic_string<_CharT, _Traits, _Allocator>&
2391basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c)
2392{
2393    pointer __p;
2394    if (__is_long())
2395    {
2396        __p = __get_long_pointer();
2397        __set_long_size(1);
2398    }
2399    else
2400    {
2401        __p = __get_short_pointer();
2402        __set_short_size(1);
2403    }
2404    traits_type::assign(*__p, __c);
2405    traits_type::assign(*++__p, value_type());
2406    __invalidate_iterators_past(1);
2407    return *this;
2408}
2409
2410template <class _CharT, class _Traits, class _Allocator>
2411basic_string<_CharT, _Traits, _Allocator>&
2412basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str)
2413{
2414    if (this != &__str)
2415    {
2416        __copy_assign_alloc(__str);
2417        assign(__str);
2418    }
2419    return *this;
2420}
2421
2422#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2423
2424template <class _CharT, class _Traits, class _Allocator>
2425inline _LIBCPP_INLINE_VISIBILITY
2426void
2427basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, false_type)
2428{
2429    if (__alloc() != __str.__alloc())
2430        assign(__str);
2431    else
2432        __move_assign(__str, true_type());
2433}
2434
2435template <class _CharT, class _Traits, class _Allocator>
2436inline _LIBCPP_INLINE_VISIBILITY
2437void
2438basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type)
2439    _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
2440{
2441    clear();
2442    shrink_to_fit();
2443    __r_.first() = __str.__r_.first();
2444    __move_assign_alloc(__str);
2445    __str.__zero();
2446}
2447
2448template <class _CharT, class _Traits, class _Allocator>
2449inline _LIBCPP_INLINE_VISIBILITY
2450basic_string<_CharT, _Traits, _Allocator>&
2451basic_string<_CharT, _Traits, _Allocator>::operator=(basic_string&& __str)
2452    _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
2453               is_nothrow_move_assignable<allocator_type>::value)
2454{
2455    __move_assign(__str, integral_constant<bool,
2456          __alloc_traits::propagate_on_container_move_assignment::value>());
2457    return *this;
2458}
2459
2460#endif
2461
2462template <class _CharT, class _Traits, class _Allocator>
2463template<class _InputIterator>
2464typename enable_if
2465<
2466     __is_input_iterator  <_InputIterator>::value &&
2467    !__is_forward_iterator<_InputIterator>::value,
2468    basic_string<_CharT, _Traits, _Allocator>&
2469>::type
2470basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
2471{
2472    clear();
2473    for (; __first != __last; ++__first)
2474        push_back(*__first);
2475    return *this;
2476}
2477
2478template <class _CharT, class _Traits, class _Allocator>
2479template<class _ForwardIterator>
2480typename enable_if
2481<
2482    __is_forward_iterator<_ForwardIterator>::value,
2483    basic_string<_CharT, _Traits, _Allocator>&
2484>::type
2485basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)
2486{
2487    size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
2488    size_type __cap = capacity();
2489    if (__cap < __n)
2490    {
2491        size_type __sz = size();
2492        __grow_by(__cap, __n - __cap, __sz, 0, __sz);
2493    }
2494    else
2495        __invalidate_iterators_past(__n);
2496    pointer __p = __get_pointer();
2497    for (; __first != __last; ++__first, ++__p)
2498        traits_type::assign(*__p, *__first);
2499    traits_type::assign(*__p, value_type());
2500    __set_size(__n);
2501    return *this;
2502}
2503
2504template <class _CharT, class _Traits, class _Allocator>
2505inline _LIBCPP_INLINE_VISIBILITY
2506basic_string<_CharT, _Traits, _Allocator>&
2507basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str)
2508{
2509    return assign(__str.data(), __str.size());
2510}
2511
2512template <class _CharT, class _Traits, class _Allocator>
2513basic_string<_CharT, _Traits, _Allocator>&
2514basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, size_type __pos, size_type __n)
2515{
2516    size_type __sz = __str.size();
2517    if (__pos > __sz)
2518        this->__throw_out_of_range();
2519    return assign(__str.data() + __pos, _VSTD::min(__n, __sz - __pos));
2520}
2521
2522template <class _CharT, class _Traits, class _Allocator>
2523basic_string<_CharT, _Traits, _Allocator>&
2524basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s)
2525{
2526    _LIBCPP_ASSERT(__s != nullptr, "string::assign received nullptr");
2527    return assign(__s, traits_type::length(__s));
2528}
2529
2530// append
2531
2532template <class _CharT, class _Traits, class _Allocator>
2533basic_string<_CharT, _Traits, _Allocator>&
2534basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n)
2535{
2536    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::append received nullptr");
2537    size_type __cap = capacity();
2538    size_type __sz = size();
2539    if (__cap - __sz >= __n)
2540    {
2541        if (__n)
2542        {
2543            value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());
2544            traits_type::copy(__p + __sz, __s, __n);
2545            __sz += __n;
2546            __set_size(__sz);
2547            traits_type::assign(__p[__sz], value_type());
2548        }
2549    }
2550    else
2551        __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __sz, 0, __n, __s);
2552    return *this;
2553}
2554
2555template <class _CharT, class _Traits, class _Allocator>
2556basic_string<_CharT, _Traits, _Allocator>&
2557basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c)
2558{
2559    if (__n)
2560    {
2561        size_type __cap = capacity();
2562        size_type __sz = size();
2563        if (__cap - __sz < __n)
2564            __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
2565        pointer __p = __get_pointer();
2566        traits_type::assign(_VSTD::__to_raw_pointer(__p) + __sz, __n, __c);
2567        __sz += __n;
2568        __set_size(__sz);
2569        traits_type::assign(__p[__sz], value_type());
2570    }
2571    return *this;
2572}
2573
2574template <class _CharT, class _Traits, class _Allocator>
2575void
2576basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c)
2577{
2578    bool __is_short = !__is_long();
2579    size_type __cap;
2580    size_type __sz;
2581    if (__is_short)
2582    {
2583        __cap = __min_cap - 1;
2584        __sz = __get_short_size();
2585    }
2586    else
2587    {
2588        __cap = __get_long_cap() - 1;
2589        __sz = __get_long_size();
2590    }
2591    if (__sz == __cap)
2592    {
2593        __grow_by(__cap, 1, __sz, __sz, 0);
2594        __is_short = !__is_long();
2595    }
2596    pointer __p;
2597    if (__is_short)
2598    {
2599        __p = __get_short_pointer() + __sz;
2600        __set_short_size(__sz+1);
2601    }
2602    else
2603    {
2604        __p = __get_long_pointer() + __sz;
2605        __set_long_size(__sz+1);
2606    }
2607    traits_type::assign(*__p, __c);
2608    traits_type::assign(*++__p, value_type());
2609}
2610
2611template <class _CharT, class _Traits, class _Allocator>
2612template<class _InputIterator>
2613typename enable_if
2614<
2615     __is_input_iterator  <_InputIterator>::value &&
2616    !__is_forward_iterator<_InputIterator>::value,
2617    basic_string<_CharT, _Traits, _Allocator>&
2618>::type
2619basic_string<_CharT, _Traits, _Allocator>::append(_InputIterator __first, _InputIterator __last)
2620{
2621    for (; __first != __last; ++__first)
2622        push_back(*__first);
2623    return *this;
2624}
2625
2626template <class _CharT, class _Traits, class _Allocator>
2627template<class _ForwardIterator>
2628typename enable_if
2629<
2630    __is_forward_iterator<_ForwardIterator>::value,
2631    basic_string<_CharT, _Traits, _Allocator>&
2632>::type
2633basic_string<_CharT, _Traits, _Allocator>::append(_ForwardIterator __first, _ForwardIterator __last)
2634{
2635    size_type __sz = size();
2636    size_type __cap = capacity();
2637    size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
2638    if (__n)
2639    {
2640        if (__cap - __sz < __n)
2641            __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
2642        pointer __p = __get_pointer() + __sz;
2643        for (; __first != __last; ++__p, ++__first)
2644            traits_type::assign(*__p, *__first);
2645        traits_type::assign(*__p, value_type());
2646        __set_size(__sz + __n);
2647    }
2648    return *this;
2649}
2650
2651template <class _CharT, class _Traits, class _Allocator>
2652inline _LIBCPP_INLINE_VISIBILITY
2653basic_string<_CharT, _Traits, _Allocator>&
2654basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str)
2655{
2656    return append(__str.data(), __str.size());
2657}
2658
2659template <class _CharT, class _Traits, class _Allocator>
2660basic_string<_CharT, _Traits, _Allocator>&
2661basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, size_type __pos, size_type __n)
2662{
2663    size_type __sz = __str.size();
2664    if (__pos > __sz)
2665        this->__throw_out_of_range();
2666    return append(__str.data() + __pos, _VSTD::min(__n, __sz - __pos));
2667}
2668
2669template <class _CharT, class _Traits, class _Allocator>
2670basic_string<_CharT, _Traits, _Allocator>&
2671basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s)
2672{
2673    _LIBCPP_ASSERT(__s != nullptr, "string::append received nullptr");
2674    return append(__s, traits_type::length(__s));
2675}
2676
2677// insert
2678
2679template <class _CharT, class _Traits, class _Allocator>
2680basic_string<_CharT, _Traits, _Allocator>&
2681basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n)
2682{
2683    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::insert received nullptr");
2684    size_type __sz = size();
2685    if (__pos > __sz)
2686        this->__throw_out_of_range();
2687    size_type __cap = capacity();
2688    if (__cap - __sz >= __n)
2689    {
2690        if (__n)
2691        {
2692            value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());
2693            size_type __n_move = __sz - __pos;
2694            if (__n_move != 0)
2695            {
2696                if (__p + __pos <= __s && __s < __p + __sz)
2697                    __s += __n;
2698                traits_type::move(__p + __pos + __n, __p + __pos, __n_move);
2699            }
2700            traits_type::move(__p + __pos, __s, __n);
2701            __sz += __n;
2702            __set_size(__sz);
2703            traits_type::assign(__p[__sz], value_type());
2704        }
2705    }
2706    else
2707        __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s);
2708    return *this;
2709}
2710
2711template <class _CharT, class _Traits, class _Allocator>
2712basic_string<_CharT, _Traits, _Allocator>&
2713basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n, value_type __c)
2714{
2715    size_type __sz = size();
2716    if (__pos > __sz)
2717        this->__throw_out_of_range();
2718    if (__n)
2719    {
2720        size_type __cap = capacity();
2721        value_type* __p;
2722        if (__cap - __sz >= __n)
2723        {
2724            __p = _VSTD::__to_raw_pointer(__get_pointer());
2725            size_type __n_move = __sz - __pos;
2726            if (__n_move != 0)
2727                traits_type::move(__p + __pos + __n, __p + __pos, __n_move);
2728        }
2729        else
2730        {
2731            __grow_by(__cap, __sz + __n - __cap, __sz, __pos, 0, __n);
2732            __p = _VSTD::__to_raw_pointer(__get_long_pointer());
2733        }
2734        traits_type::assign(__p + __pos, __n, __c);
2735        __sz += __n;
2736        __set_size(__sz);
2737        traits_type::assign(__p[__sz], value_type());
2738    }
2739    return *this;
2740}
2741
2742template <class _CharT, class _Traits, class _Allocator>
2743template<class _InputIterator>
2744typename enable_if
2745<
2746     __is_input_iterator  <_InputIterator>::value &&
2747    !__is_forward_iterator<_InputIterator>::value,
2748    typename basic_string<_CharT, _Traits, _Allocator>::iterator
2749>::type
2750basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last)
2751{
2752#if _LIBCPP_DEBUG_LEVEL >= 2
2753    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
2754        "string::insert(iterator, range) called with an iterator not"
2755        " referring to this string");
2756#endif
2757    size_type __old_sz = size();
2758    difference_type __ip = __pos - begin();
2759    for (; __first != __last; ++__first)
2760        push_back(*__first);
2761    pointer __p = __get_pointer();
2762    _VSTD::rotate(__p + __ip, __p + __old_sz, __p + size());
2763#if _LIBCPP_DEBUG_LEVEL >= 2
2764    return iterator(this, __p + __ip);
2765#else
2766    return iterator(__p + __ip);
2767#endif
2768}
2769
2770template <class _CharT, class _Traits, class _Allocator>
2771template<class _ForwardIterator>
2772typename enable_if
2773<
2774    __is_forward_iterator<_ForwardIterator>::value,
2775    typename basic_string<_CharT, _Traits, _Allocator>::iterator
2776>::type
2777basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last)
2778{
2779#if _LIBCPP_DEBUG_LEVEL >= 2
2780    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
2781        "string::insert(iterator, range) called with an iterator not"
2782        " referring to this string");
2783#endif
2784    size_type __ip = static_cast<size_type>(__pos - begin());
2785    size_type __sz = size();
2786    size_type __cap = capacity();
2787    size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
2788    if (__n)
2789    {
2790        value_type* __p;
2791        if (__cap - __sz >= __n)
2792        {
2793            __p = _VSTD::__to_raw_pointer(__get_pointer());
2794            size_type __n_move = __sz - __ip;
2795            if (__n_move != 0)
2796                traits_type::move(__p + __ip + __n, __p + __ip, __n_move);
2797        }
2798        else
2799        {
2800            __grow_by(__cap, __sz + __n - __cap, __sz, __ip, 0, __n);
2801            __p = _VSTD::__to_raw_pointer(__get_long_pointer());
2802        }
2803        __sz += __n;
2804        __set_size(__sz);
2805        traits_type::assign(__p[__sz], value_type());
2806        for (__p += __ip; __first != __last; ++__p, ++__first)
2807            traits_type::assign(*__p, *__first);
2808    }
2809    return begin() + __ip;
2810}
2811
2812template <class _CharT, class _Traits, class _Allocator>
2813inline _LIBCPP_INLINE_VISIBILITY
2814basic_string<_CharT, _Traits, _Allocator>&
2815basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str)
2816{
2817    return insert(__pos1, __str.data(), __str.size());
2818}
2819
2820template <class _CharT, class _Traits, class _Allocator>
2821basic_string<_CharT, _Traits, _Allocator>&
2822basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str,
2823                                                  size_type __pos2, size_type __n)
2824{
2825    size_type __str_sz = __str.size();
2826    if (__pos2 > __str_sz)
2827        this->__throw_out_of_range();
2828    return insert(__pos1, __str.data() + __pos2, _VSTD::min(__n, __str_sz - __pos2));
2829}
2830
2831template <class _CharT, class _Traits, class _Allocator>
2832basic_string<_CharT, _Traits, _Allocator>&
2833basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s)
2834{
2835    _LIBCPP_ASSERT(__s != nullptr, "string::insert received nullptr");
2836    return insert(__pos, __s, traits_type::length(__s));
2837}
2838
2839template <class _CharT, class _Traits, class _Allocator>
2840typename basic_string<_CharT, _Traits, _Allocator>::iterator
2841basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c)
2842{
2843    size_type __ip = static_cast<size_type>(__pos - begin());
2844    size_type __sz = size();
2845    size_type __cap = capacity();
2846    value_type* __p;
2847    if (__cap == __sz)
2848    {
2849        __grow_by(__cap, 1, __sz, __ip, 0, 1);
2850        __p = _VSTD::__to_raw_pointer(__get_long_pointer());
2851    }
2852    else
2853    {
2854        __p = _VSTD::__to_raw_pointer(__get_pointer());
2855        size_type __n_move = __sz - __ip;
2856        if (__n_move != 0)
2857            traits_type::move(__p + __ip + 1, __p + __ip, __n_move);
2858    }
2859    traits_type::assign(__p[__ip], __c);
2860    traits_type::assign(__p[++__sz], value_type());
2861    __set_size(__sz);
2862    return begin() + static_cast<difference_type>(__ip);
2863}
2864
2865template <class _CharT, class _Traits, class _Allocator>
2866inline _LIBCPP_INLINE_VISIBILITY
2867typename basic_string<_CharT, _Traits, _Allocator>::iterator
2868basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, size_type __n, value_type __c)
2869{
2870#if _LIBCPP_DEBUG_LEVEL >= 2
2871    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
2872        "string::insert(iterator, n, value) called with an iterator not"
2873        " referring to this string");
2874#endif
2875    difference_type __p = __pos - begin();
2876    insert(static_cast<size_type>(__p), __n, __c);
2877    return begin() + __p;
2878}
2879
2880// replace
2881
2882template <class _CharT, class _Traits, class _Allocator>
2883basic_string<_CharT, _Traits, _Allocator>&
2884basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2)
2885{
2886    _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::replace received nullptr");
2887    size_type __sz = size();
2888    if (__pos > __sz)
2889        this->__throw_out_of_range();
2890    __n1 = _VSTD::min(__n1, __sz - __pos);
2891    size_type __cap = capacity();
2892    if (__cap - __sz + __n1 >= __n2)
2893    {
2894        value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());
2895        if (__n1 != __n2)
2896        {
2897            size_type __n_move = __sz - __pos - __n1;
2898            if (__n_move != 0)
2899            {
2900                if (__n1 > __n2)
2901                {
2902                    traits_type::move(__p + __pos, __s, __n2);
2903                    traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
2904                    goto __finish;
2905                }
2906                if (__p + __pos < __s && __s < __p + __sz)
2907                {
2908                    if (__p + __pos + __n1 <= __s)
2909                        __s += __n2 - __n1;
2910                    else // __p + __pos < __s < __p + __pos + __n1
2911                    {
2912                        traits_type::move(__p + __pos, __s, __n1);
2913                        __pos += __n1;
2914                        __s += __n2;
2915                        __n2 -= __n1;
2916                        __n1 = 0;
2917                    }
2918                }
2919                traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
2920            }
2921        }
2922        traits_type::move(__p + __pos, __s, __n2);
2923__finish:
2924        __sz += __n2 - __n1;
2925        __set_size(__sz);
2926        __invalidate_iterators_past(__sz);
2927        traits_type::assign(__p[__sz], value_type());
2928    }
2929    else
2930        __grow_by_and_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2, __s);
2931    return *this;
2932}
2933
2934template <class _CharT, class _Traits, class _Allocator>
2935basic_string<_CharT, _Traits, _Allocator>&
2936basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, size_type __n2, value_type __c)
2937{
2938    size_type __sz = size();
2939    if (__pos > __sz)
2940        this->__throw_out_of_range();
2941    __n1 = _VSTD::min(__n1, __sz - __pos);
2942    size_type __cap = capacity();
2943    value_type* __p;
2944    if (__cap - __sz + __n1 >= __n2)
2945    {
2946        __p = _VSTD::__to_raw_pointer(__get_pointer());
2947        if (__n1 != __n2)
2948        {
2949            size_type __n_move = __sz - __pos - __n1;
2950            if (__n_move != 0)
2951                traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
2952        }
2953    }
2954    else
2955    {
2956        __grow_by(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2);
2957        __p = _VSTD::__to_raw_pointer(__get_long_pointer());
2958    }
2959    traits_type::assign(__p + __pos, __n2, __c);
2960    __sz += __n2 - __n1;
2961    __set_size(__sz);
2962    __invalidate_iterators_past(__sz);
2963    traits_type::assign(__p[__sz], value_type());
2964    return *this;
2965}
2966
2967template <class _CharT, class _Traits, class _Allocator>
2968template<class _InputIterator>
2969typename enable_if
2970<
2971    __is_input_iterator<_InputIterator>::value,
2972    basic_string<_CharT, _Traits, _Allocator>&
2973>::type
2974basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2,
2975                                                   _InputIterator __j1, _InputIterator __j2)
2976{
2977    for (; true; ++__i1, ++__j1)
2978    {
2979        if (__i1 == __i2)
2980        {
2981            if (__j1 != __j2)
2982                insert(__i1, __j1, __j2);
2983            break;
2984        }
2985        if (__j1 == __j2)
2986        {
2987            erase(__i1, __i2);
2988            break;
2989        }
2990        traits_type::assign(const_cast<value_type&>(*__i1), *__j1);
2991    }
2992    return *this;
2993}
2994
2995template <class _CharT, class _Traits, class _Allocator>
2996inline _LIBCPP_INLINE_VISIBILITY
2997basic_string<_CharT, _Traits, _Allocator>&
2998basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str)
2999{
3000    return replace(__pos1, __n1, __str.data(), __str.size());
3001}
3002
3003template <class _CharT, class _Traits, class _Allocator>
3004basic_string<_CharT, _Traits, _Allocator>&
3005basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str,
3006                                                   size_type __pos2, size_type __n2)
3007{
3008    size_type __str_sz = __str.size();
3009    if (__pos2 > __str_sz)
3010        this->__throw_out_of_range();
3011    return replace(__pos1, __n1, __str.data() + __pos2, _VSTD::min(__n2, __str_sz - __pos2));
3012}
3013
3014template <class _CharT, class _Traits, class _Allocator>
3015basic_string<_CharT, _Traits, _Allocator>&
3016basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s)
3017{
3018    _LIBCPP_ASSERT(__s != nullptr, "string::replace received nullptr");
3019    return replace(__pos, __n1, __s, traits_type::length(__s));
3020}
3021
3022template <class _CharT, class _Traits, class _Allocator>
3023inline _LIBCPP_INLINE_VISIBILITY
3024basic_string<_CharT, _Traits, _Allocator>&
3025basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const basic_string& __str)
3026{
3027    return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1),
3028                   __str.data(), __str.size());
3029}
3030
3031template <class _CharT, class _Traits, class _Allocator>
3032inline _LIBCPP_INLINE_VISIBILITY
3033basic_string<_CharT, _Traits, _Allocator>&
3034basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n)
3035{
3036    return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s, __n);
3037}
3038
3039template <class _CharT, class _Traits, class _Allocator>
3040inline _LIBCPP_INLINE_VISIBILITY
3041basic_string<_CharT, _Traits, _Allocator>&
3042basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s)
3043{
3044    return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s);
3045}
3046
3047template <class _CharT, class _Traits, class _Allocator>
3048inline _LIBCPP_INLINE_VISIBILITY
3049basic_string<_CharT, _Traits, _Allocator>&
3050basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c)
3051{
3052    return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __n, __c);
3053}
3054
3055// erase
3056
3057template <class _CharT, class _Traits, class _Allocator>
3058basic_string<_CharT, _Traits, _Allocator>&
3059basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, size_type __n)
3060{
3061    size_type __sz = size();
3062    if (__pos > __sz)
3063        this->__throw_out_of_range();
3064    if (__n)
3065    {
3066        value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());
3067        __n = _VSTD::min(__n, __sz - __pos);
3068        size_type __n_move = __sz - __pos - __n;
3069        if (__n_move != 0)
3070            traits_type::move(__p + __pos, __p + __pos + __n, __n_move);
3071        __sz -= __n;
3072        __set_size(__sz);
3073        __invalidate_iterators_past(__sz);
3074        traits_type::assign(__p[__sz], value_type());
3075    }
3076    return *this;
3077}
3078
3079template <class _CharT, class _Traits, class _Allocator>
3080inline _LIBCPP_INLINE_VISIBILITY
3081typename basic_string<_CharT, _Traits, _Allocator>::iterator
3082basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos)
3083{
3084#if _LIBCPP_DEBUG_LEVEL >= 2
3085    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
3086        "string::erase(iterator) called with an iterator not"
3087        " referring to this string");
3088#endif
3089    _LIBCPP_ASSERT(__pos != end(),
3090        "string::erase(iterator) called with a non-dereferenceable iterator");
3091    iterator __b = begin();
3092    size_type __r = static_cast<size_type>(__pos - __b);
3093    erase(__r, 1);
3094    return __b + static_cast<difference_type>(__r);
3095}
3096
3097template <class _CharT, class _Traits, class _Allocator>
3098inline _LIBCPP_INLINE_VISIBILITY
3099typename basic_string<_CharT, _Traits, _Allocator>::iterator
3100basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last)
3101{
3102#if _LIBCPP_DEBUG_LEVEL >= 2
3103    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this,
3104        "string::erase(iterator,  iterator) called with an iterator not"
3105        " referring to this string");
3106#endif
3107    _LIBCPP_ASSERT(__first <= __last, "string::erase(first, last) called with invalid range");
3108    iterator __b = begin();
3109    size_type __r = static_cast<size_type>(__first - __b);
3110    erase(__r, static_cast<size_type>(__last - __first));
3111    return __b + static_cast<difference_type>(__r);
3112}
3113
3114template <class _CharT, class _Traits, class _Allocator>
3115inline _LIBCPP_INLINE_VISIBILITY
3116void
3117basic_string<_CharT, _Traits, _Allocator>::pop_back()
3118{
3119    _LIBCPP_ASSERT(!empty(), "string::pop_back(): string is already empty");
3120    size_type __sz;
3121    if (__is_long())
3122    {
3123        __sz = __get_long_size() - 1;
3124        __set_long_size(__sz);
3125        traits_type::assign(*(__get_long_pointer() + __sz), value_type());
3126    }
3127    else
3128    {
3129        __sz = __get_short_size() - 1;
3130        __set_short_size(__sz);
3131        traits_type::assign(*(__get_short_pointer() + __sz), value_type());
3132    }
3133    __invalidate_iterators_past(__sz);
3134}
3135
3136template <class _CharT, class _Traits, class _Allocator>
3137inline _LIBCPP_INLINE_VISIBILITY
3138void
3139basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT
3140{
3141    __invalidate_all_iterators();
3142    if (__is_long())
3143    {
3144        traits_type::assign(*__get_long_pointer(), value_type());
3145        __set_long_size(0);
3146    }
3147    else
3148    {
3149        traits_type::assign(*__get_short_pointer(), value_type());
3150        __set_short_size(0);
3151    }
3152}
3153
3154template <class _CharT, class _Traits, class _Allocator>
3155inline _LIBCPP_INLINE_VISIBILITY
3156void
3157basic_string<_CharT, _Traits, _Allocator>::__erase_to_end(size_type __pos)
3158{
3159    if (__is_long())
3160    {
3161        traits_type::assign(*(__get_long_pointer() + __pos), value_type());
3162        __set_long_size(__pos);
3163    }
3164    else
3165    {
3166        traits_type::assign(*(__get_short_pointer() + __pos), value_type());
3167        __set_short_size(__pos);
3168    }
3169    __invalidate_iterators_past(__pos);
3170}
3171
3172template <class _CharT, class _Traits, class _Allocator>
3173void
3174basic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c)
3175{
3176    size_type __sz = size();
3177    if (__n > __sz)
3178        append(__n - __sz, __c);
3179    else
3180        __erase_to_end(__n);
3181}
3182
3183template <class _CharT, class _Traits, class _Allocator>
3184inline _LIBCPP_INLINE_VISIBILITY
3185typename basic_string<_CharT, _Traits, _Allocator>::size_type
3186basic_string<_CharT, _Traits, _Allocator>::max_size() const _NOEXCEPT
3187{
3188    size_type __m = __alloc_traits::max_size(__alloc());
3189#if _LIBCPP_BIG_ENDIAN
3190    return (__m <= ~__long_mask ? __m : __m/2) - __alignment;
3191#else
3192    return __m - __alignment;
3193#endif
3194}
3195
3196template <class _CharT, class _Traits, class _Allocator>
3197void
3198basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __res_arg)
3199{
3200    if (__res_arg > max_size())
3201        this->__throw_length_error();
3202    size_type __cap = capacity();
3203    size_type __sz = size();
3204    __res_arg = _VSTD::max(__res_arg, __sz);
3205    __res_arg = __recommend(__res_arg);
3206    if (__res_arg != __cap)
3207    {
3208        pointer __new_data, __p;
3209        bool __was_long, __now_long;
3210        if (__res_arg == __min_cap - 1)
3211        {
3212            __was_long = true;
3213            __now_long = false;
3214            __new_data = __get_short_pointer();
3215            __p = __get_long_pointer();
3216        }
3217        else
3218        {
3219            if (__res_arg > __cap)
3220                __new_data = __alloc_traits::allocate(__alloc(), __res_arg+1);
3221            else
3222            {
3223            #ifndef _LIBCPP_NO_EXCEPTIONS
3224                try
3225                {
3226            #endif  // _LIBCPP_NO_EXCEPTIONS
3227                    __new_data = __alloc_traits::allocate(__alloc(), __res_arg+1);
3228            #ifndef _LIBCPP_NO_EXCEPTIONS
3229                }
3230                catch (...)
3231                {
3232                    return;
3233                }
3234            #else  // _LIBCPP_NO_EXCEPTIONS
3235                if (__new_data == nullptr)
3236                    return;
3237            #endif  // _LIBCPP_NO_EXCEPTIONS
3238            }
3239            __now_long = true;
3240            __was_long = __is_long();
3241            __p = __get_pointer();
3242        }
3243        traits_type::copy(_VSTD::__to_raw_pointer(__new_data),
3244                          _VSTD::__to_raw_pointer(__p), size()+1);
3245        if (__was_long)
3246            __alloc_traits::deallocate(__alloc(), __p, __cap+1);
3247        if (__now_long)
3248        {
3249            __set_long_cap(__res_arg+1);
3250            __set_long_size(__sz);
3251            __set_long_pointer(__new_data);
3252        }
3253        else
3254            __set_short_size(__sz);
3255        __invalidate_all_iterators();
3256    }
3257}
3258
3259template <class _CharT, class _Traits, class _Allocator>
3260inline _LIBCPP_INLINE_VISIBILITY
3261typename basic_string<_CharT, _Traits, _Allocator>::const_reference
3262basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const
3263{
3264    _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
3265    return *(data() + __pos);
3266}
3267
3268template <class _CharT, class _Traits, class _Allocator>
3269inline _LIBCPP_INLINE_VISIBILITY
3270typename basic_string<_CharT, _Traits, _Allocator>::reference
3271basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos)
3272{
3273    _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
3274    return *(__get_pointer() + __pos);
3275}
3276
3277template <class _CharT, class _Traits, class _Allocator>
3278typename basic_string<_CharT, _Traits, _Allocator>::const_reference
3279basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const
3280{
3281    if (__n >= size())
3282        this->__throw_out_of_range();
3283    return (*this)[__n];
3284}
3285
3286template <class _CharT, class _Traits, class _Allocator>
3287typename basic_string<_CharT, _Traits, _Allocator>::reference
3288basic_string<_CharT, _Traits, _Allocator>::at(size_type __n)
3289{
3290    if (__n >= size())
3291        this->__throw_out_of_range();
3292    return (*this)[__n];
3293}
3294
3295template <class _CharT, class _Traits, class _Allocator>
3296inline _LIBCPP_INLINE_VISIBILITY
3297typename basic_string<_CharT, _Traits, _Allocator>::reference
3298basic_string<_CharT, _Traits, _Allocator>::front()
3299{
3300    _LIBCPP_ASSERT(!empty(), "string::front(): string is empty");
3301    return *__get_pointer();
3302}
3303
3304template <class _CharT, class _Traits, class _Allocator>
3305inline _LIBCPP_INLINE_VISIBILITY
3306typename basic_string<_CharT, _Traits, _Allocator>::const_reference
3307basic_string<_CharT, _Traits, _Allocator>::front() const
3308{
3309    _LIBCPP_ASSERT(!empty(), "string::front(): string is empty");
3310    return *data();
3311}
3312
3313template <class _CharT, class _Traits, class _Allocator>
3314inline _LIBCPP_INLINE_VISIBILITY
3315typename basic_string<_CharT, _Traits, _Allocator>::reference
3316basic_string<_CharT, _Traits, _Allocator>::back()
3317{
3318    _LIBCPP_ASSERT(!empty(), "string::back(): string is empty");
3319    return *(__get_pointer() + size() - 1);
3320}
3321
3322template <class _CharT, class _Traits, class _Allocator>
3323inline _LIBCPP_INLINE_VISIBILITY
3324typename basic_string<_CharT, _Traits, _Allocator>::const_reference
3325basic_string<_CharT, _Traits, _Allocator>::back() const
3326{
3327    _LIBCPP_ASSERT(!empty(), "string::back(): string is empty");
3328    return *(data() + size() - 1);
3329}
3330
3331template <class _CharT, class _Traits, class _Allocator>
3332typename basic_string<_CharT, _Traits, _Allocator>::size_type
3333basic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n, size_type __pos) const
3334{
3335    size_type __sz = size();
3336    if (__pos > __sz)
3337        this->__throw_out_of_range();
3338    size_type __rlen = _VSTD::min(__n, __sz - __pos);
3339    traits_type::copy(__s, data() + __pos, __rlen);
3340    return __rlen;
3341}
3342
3343template <class _CharT, class _Traits, class _Allocator>
3344inline _LIBCPP_INLINE_VISIBILITY
3345basic_string<_CharT, _Traits, _Allocator>
3346basic_string<_CharT, _Traits, _Allocator>::substr(size_type __pos, size_type __n) const
3347{
3348    return basic_string(*this, __pos, __n, __alloc());
3349}
3350
3351template <class _CharT, class _Traits, class _Allocator>
3352inline _LIBCPP_INLINE_VISIBILITY
3353void
3354basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str)
3355#if _LIBCPP_STD_VER >= 14
3356        _NOEXCEPT
3357#else
3358        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
3359                    __is_nothrow_swappable<allocator_type>::value)
3360#endif
3361{
3362#if _LIBCPP_DEBUG_LEVEL >= 2
3363    if (!__is_long())
3364        __get_db()->__invalidate_all(this);
3365    if (!__str.__is_long())
3366        __get_db()->__invalidate_all(&__str);
3367    __get_db()->swap(this, &__str);
3368#endif
3369    _VSTD::swap(__r_.first(), __str.__r_.first());
3370    __swap_allocator(__alloc(), __str.__alloc());
3371}
3372
3373// find
3374
3375template <class _Traits>
3376struct _LIBCPP_HIDDEN __traits_eq
3377{
3378    typedef typename _Traits::char_type char_type;
3379    _LIBCPP_INLINE_VISIBILITY
3380    bool operator()(const char_type& __x, const char_type& __y) _NOEXCEPT
3381        {return _Traits::eq(__x, __y);}
3382};
3383
3384template<class _CharT, class _Traits, class _Allocator>
3385typename basic_string<_CharT, _Traits, _Allocator>::size_type
3386basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
3387                                                size_type __pos,
3388                                                size_type __n) const _NOEXCEPT
3389{
3390    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find(): received nullptr");
3391    return _VSTD::__str_find<value_type, size_type, traits_type, npos>
3392        (data(), size(), __s, __pos, __n);
3393}
3394
3395template<class _CharT, class _Traits, class _Allocator>
3396inline _LIBCPP_INLINE_VISIBILITY
3397typename basic_string<_CharT, _Traits, _Allocator>::size_type
3398basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str,
3399                                                size_type __pos) const _NOEXCEPT
3400{
3401    return _VSTD::__str_find<value_type, size_type, traits_type, npos>
3402        (data(), size(), __str.data(), __pos, __str.size());
3403}
3404
3405template<class _CharT, class _Traits, class _Allocator>
3406inline _LIBCPP_INLINE_VISIBILITY
3407typename basic_string<_CharT, _Traits, _Allocator>::size_type
3408basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
3409                                                size_type __pos) const _NOEXCEPT
3410{
3411    _LIBCPP_ASSERT(__s != nullptr, "string::find(): received nullptr");
3412    return _VSTD::__str_find<value_type, size_type, traits_type, npos>
3413        (data(), size(), __s, __pos, traits_type::length(__s));
3414}
3415
3416template<class _CharT, class _Traits, class _Allocator>
3417typename basic_string<_CharT, _Traits, _Allocator>::size_type
3418basic_string<_CharT, _Traits, _Allocator>::find(value_type __c,
3419                                                size_type __pos) const _NOEXCEPT
3420{
3421    return _VSTD::__str_find<value_type, size_type, traits_type, npos>
3422        (data(), size(), __c, __pos);
3423}
3424
3425// rfind
3426
3427template<class _CharT, class _Traits, class _Allocator>
3428typename basic_string<_CharT, _Traits, _Allocator>::size_type
3429basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
3430                                                 size_type __pos,
3431                                                 size_type __n) const _NOEXCEPT
3432{
3433    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::rfind(): received nullptr");
3434    return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
3435        (data(), size(), __s, __pos, __n);
3436}
3437
3438template<class _CharT, class _Traits, class _Allocator>
3439inline _LIBCPP_INLINE_VISIBILITY
3440typename basic_string<_CharT, _Traits, _Allocator>::size_type
3441basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str,
3442                                                 size_type __pos) const _NOEXCEPT
3443{
3444    return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
3445        (data(), size(), __str.data(), __pos, __str.size());
3446}
3447
3448template<class _CharT, class _Traits, class _Allocator>
3449inline _LIBCPP_INLINE_VISIBILITY
3450typename basic_string<_CharT, _Traits, _Allocator>::size_type
3451basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
3452                                                 size_type __pos) const _NOEXCEPT
3453{
3454    _LIBCPP_ASSERT(__s != nullptr, "string::rfind(): received nullptr");
3455    return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
3456        (data(), size(), __s, __pos, traits_type::length(__s));
3457}
3458
3459template<class _CharT, class _Traits, class _Allocator>
3460typename basic_string<_CharT, _Traits, _Allocator>::size_type
3461basic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c,
3462                                                 size_type __pos) const _NOEXCEPT
3463{
3464    return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
3465        (data(), size(), __c, __pos);
3466}
3467
3468// find_first_of
3469
3470template<class _CharT, class _Traits, class _Allocator>
3471typename basic_string<_CharT, _Traits, _Allocator>::size_type
3472basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
3473                                                         size_type __pos,
3474                                                         size_type __n) const _NOEXCEPT
3475{
3476    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr");
3477    return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos>
3478        (data(), size(), __s, __pos, __n);
3479}
3480
3481template<class _CharT, class _Traits, class _Allocator>
3482inline _LIBCPP_INLINE_VISIBILITY
3483typename basic_string<_CharT, _Traits, _Allocator>::size_type
3484basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str,
3485                                                         size_type __pos) const _NOEXCEPT
3486{
3487    return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos>
3488        (data(), size(), __str.data(), __pos, __str.size());
3489}
3490
3491template<class _CharT, class _Traits, class _Allocator>
3492inline _LIBCPP_INLINE_VISIBILITY
3493typename basic_string<_CharT, _Traits, _Allocator>::size_type
3494basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
3495                                                         size_type __pos) const _NOEXCEPT
3496{
3497    _LIBCPP_ASSERT(__s != nullptr, "string::find_first_of(): received nullptr");
3498    return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos>
3499        (data(), size(), __s, __pos, traits_type::length(__s));
3500}
3501
3502template<class _CharT, class _Traits, class _Allocator>
3503inline _LIBCPP_INLINE_VISIBILITY
3504typename basic_string<_CharT, _Traits, _Allocator>::size_type
3505basic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c,
3506                                                         size_type __pos) const _NOEXCEPT
3507{
3508    return find(__c, __pos);
3509}
3510
3511// find_last_of
3512
3513template<class _CharT, class _Traits, class _Allocator>
3514typename basic_string<_CharT, _Traits, _Allocator>::size_type
3515basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
3516                                                        size_type __pos,
3517                                                        size_type __n) const _NOEXCEPT
3518{
3519    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr");
3520    return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos>
3521        (data(), size(), __s, __pos, __n);
3522}
3523
3524template<class _CharT, class _Traits, class _Allocator>
3525inline _LIBCPP_INLINE_VISIBILITY
3526typename basic_string<_CharT, _Traits, _Allocator>::size_type
3527basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str,
3528                                                        size_type __pos) const _NOEXCEPT
3529{
3530    return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos>
3531        (data(), size(), __str.data(), __pos, __str.size());
3532}
3533
3534template<class _CharT, class _Traits, class _Allocator>
3535inline _LIBCPP_INLINE_VISIBILITY
3536typename basic_string<_CharT, _Traits, _Allocator>::size_type
3537basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
3538                                                        size_type __pos) const _NOEXCEPT
3539{
3540    _LIBCPP_ASSERT(__s != nullptr, "string::find_last_of(): received nullptr");
3541    return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos>
3542        (data(), size(), __s, __pos, traits_type::length(__s));
3543}
3544
3545template<class _CharT, class _Traits, class _Allocator>
3546inline _LIBCPP_INLINE_VISIBILITY
3547typename basic_string<_CharT, _Traits, _Allocator>::size_type
3548basic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c,
3549                                                        size_type __pos) const _NOEXCEPT
3550{
3551    return rfind(__c, __pos);
3552}
3553
3554// find_first_not_of
3555
3556template<class _CharT, class _Traits, class _Allocator>
3557typename basic_string<_CharT, _Traits, _Allocator>::size_type
3558basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s,
3559                                                             size_type __pos,
3560                                                             size_type __n) const _NOEXCEPT
3561{
3562    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr");
3563    return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>
3564        (data(), size(), __s, __pos, __n);
3565}
3566
3567template<class _CharT, class _Traits, class _Allocator>
3568inline _LIBCPP_INLINE_VISIBILITY
3569typename basic_string<_CharT, _Traits, _Allocator>::size_type
3570basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string& __str,
3571                                                             size_type __pos) const _NOEXCEPT
3572{
3573    return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>
3574        (data(), size(), __str.data(), __pos, __str.size());
3575}
3576
3577template<class _CharT, class _Traits, class _Allocator>
3578inline _LIBCPP_INLINE_VISIBILITY
3579typename basic_string<_CharT, _Traits, _Allocator>::size_type
3580basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s,
3581                                                             size_type __pos) const _NOEXCEPT
3582{
3583    _LIBCPP_ASSERT(__s != nullptr, "string::find_first_not_of(): received nullptr");
3584    return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>
3585        (data(), size(), __s, __pos, traits_type::length(__s));
3586}
3587
3588template<class _CharT, class _Traits, class _Allocator>
3589inline _LIBCPP_INLINE_VISIBILITY
3590typename basic_string<_CharT, _Traits, _Allocator>::size_type
3591basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c,
3592                                                             size_type __pos) const _NOEXCEPT
3593{
3594    return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>
3595        (data(), size(), __c, __pos);
3596}
3597
3598// find_last_not_of
3599
3600template<class _CharT, class _Traits, class _Allocator>
3601typename basic_string<_CharT, _Traits, _Allocator>::size_type
3602basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s,
3603                                                            size_type __pos,
3604                                                            size_type __n) const _NOEXCEPT
3605{
3606    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr");
3607    return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
3608        (data(), size(), __s, __pos, __n);
3609}
3610
3611template<class _CharT, class _Traits, class _Allocator>
3612inline _LIBCPP_INLINE_VISIBILITY
3613typename basic_string<_CharT, _Traits, _Allocator>::size_type
3614basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string& __str,
3615                                                            size_type __pos) const _NOEXCEPT
3616{
3617    return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
3618        (data(), size(), __str.data(), __pos, __str.size());
3619}
3620
3621template<class _CharT, class _Traits, class _Allocator>
3622inline _LIBCPP_INLINE_VISIBILITY
3623typename basic_string<_CharT, _Traits, _Allocator>::size_type
3624basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s,
3625                                                            size_type __pos) const _NOEXCEPT
3626{
3627    _LIBCPP_ASSERT(__s != nullptr, "string::find_last_not_of(): received nullptr");
3628    return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
3629        (data(), size(), __s, __pos, traits_type::length(__s));
3630}
3631
3632template<class _CharT, class _Traits, class _Allocator>
3633inline _LIBCPP_INLINE_VISIBILITY
3634typename basic_string<_CharT, _Traits, _Allocator>::size_type
3635basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c,
3636                                                            size_type __pos) const _NOEXCEPT
3637{
3638    return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
3639        (data(), size(), __c, __pos);
3640}
3641
3642// compare
3643
3644template <class _CharT, class _Traits, class _Allocator>
3645inline _LIBCPP_INLINE_VISIBILITY
3646int
3647basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT
3648{
3649    size_t __lhs_sz = size();
3650    size_t __rhs_sz = __str.size();
3651    int __result = traits_type::compare(data(), __str.data(),
3652                                        _VSTD::min(__lhs_sz, __rhs_sz));
3653    if (__result != 0)
3654        return __result;
3655    if (__lhs_sz < __rhs_sz)
3656        return -1;
3657    if (__lhs_sz > __rhs_sz)
3658        return 1;
3659    return 0;
3660}
3661
3662template <class _CharT, class _Traits, class _Allocator>
3663inline _LIBCPP_INLINE_VISIBILITY
3664int
3665basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
3666                                                   size_type __n1,
3667                                                   const basic_string& __str) const
3668{
3669    return compare(__pos1, __n1, __str.data(), __str.size());
3670}
3671
3672template <class _CharT, class _Traits, class _Allocator>
3673int
3674basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
3675                                                   size_type __n1,
3676                                                   const basic_string& __str,
3677                                                   size_type __pos2,
3678                                                   size_type __n2) const
3679{
3680    size_type __sz = __str.size();
3681    if (__pos2 > __sz)
3682        this->__throw_out_of_range();
3683    return compare(__pos1, __n1, __str.data() + __pos2, _VSTD::min(__n2,
3684                                                                  __sz - __pos2));
3685}
3686
3687template <class _CharT, class _Traits, class _Allocator>
3688int
3689basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT
3690{
3691    _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr");
3692    return compare(0, npos, __s, traits_type::length(__s));
3693}
3694
3695template <class _CharT, class _Traits, class _Allocator>
3696int
3697basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
3698                                                   size_type __n1,
3699                                                   const value_type* __s) const
3700{
3701    _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr");
3702    return compare(__pos1, __n1, __s, traits_type::length(__s));
3703}
3704
3705template <class _CharT, class _Traits, class _Allocator>
3706int
3707basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
3708                                                   size_type __n1,
3709                                                   const value_type* __s,
3710                                                   size_type __n2) const
3711{
3712    _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr");
3713    size_type __sz = size();
3714    if (__pos1 > __sz || __n2 == npos)
3715        this->__throw_out_of_range();
3716    size_type __rlen = _VSTD::min(__n1, __sz - __pos1);
3717    int __r = traits_type::compare(data() + __pos1, __s, _VSTD::min(__rlen, __n2));
3718    if (__r == 0)
3719    {
3720        if (__rlen < __n2)
3721            __r = -1;
3722        else if (__rlen > __n2)
3723            __r = 1;
3724    }
3725    return __r;
3726}
3727
3728// __invariants
3729
3730template<class _CharT, class _Traits, class _Allocator>
3731inline _LIBCPP_INLINE_VISIBILITY
3732bool
3733basic_string<_CharT, _Traits, _Allocator>::__invariants() const
3734{
3735    if (size() > capacity())
3736        return false;
3737    if (capacity() < __min_cap - 1)
3738        return false;
3739    if (data() == 0)
3740        return false;
3741    if (data()[size()] != value_type(0))
3742        return false;
3743    return true;
3744}
3745
3746// operator==
3747
3748template<class _CharT, class _Traits, class _Allocator>
3749inline _LIBCPP_INLINE_VISIBILITY
3750bool
3751operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3752           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
3753{
3754    size_t __lhs_sz = __lhs.size();
3755    return __lhs_sz == __rhs.size() && _Traits::compare(__lhs.data(),
3756                                                        __rhs.data(),
3757                                                        __lhs_sz) == 0;
3758}
3759
3760template<class _Allocator>
3761inline _LIBCPP_INLINE_VISIBILITY
3762bool
3763operator==(const basic_string<char, char_traits<char>, _Allocator>& __lhs,
3764           const basic_string<char, char_traits<char>, _Allocator>& __rhs) _NOEXCEPT
3765{
3766    size_t __lhs_sz = __lhs.size();
3767    if (__lhs_sz != __rhs.size())
3768        return false;
3769    const char* __lp = __lhs.data();
3770    const char* __rp = __rhs.data();
3771    if (__lhs.__is_long())
3772        return char_traits<char>::compare(__lp, __rp, __lhs_sz) == 0;
3773    for (; __lhs_sz != 0; --__lhs_sz, ++__lp, ++__rp)
3774        if (*__lp != *__rp)
3775            return false;
3776    return true;
3777}
3778
3779template<class _CharT, class _Traits, class _Allocator>
3780inline _LIBCPP_INLINE_VISIBILITY
3781bool
3782operator==(const _CharT* __lhs,
3783           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
3784{
3785    return __rhs.compare(__lhs) == 0;
3786}
3787
3788template<class _CharT, class _Traits, class _Allocator>
3789inline _LIBCPP_INLINE_VISIBILITY
3790bool
3791operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
3792           const _CharT* __rhs) _NOEXCEPT
3793{
3794    return __lhs.compare(__rhs) == 0;
3795}
3796
3797// operator!=
3798
3799template<class _CharT, class _Traits, class _Allocator>
3800inline _LIBCPP_INLINE_VISIBILITY
3801bool
3802operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
3803           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
3804{
3805    return !(__lhs == __rhs);
3806}
3807
3808template<class _CharT, class _Traits, class _Allocator>
3809inline _LIBCPP_INLINE_VISIBILITY
3810bool
3811operator!=(const _CharT* __lhs,
3812           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
3813{
3814    return !(__lhs == __rhs);
3815}
3816
3817template<class _CharT, class _Traits, class _Allocator>
3818inline _LIBCPP_INLINE_VISIBILITY
3819bool
3820operator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3821           const _CharT* __rhs) _NOEXCEPT
3822{
3823    return !(__lhs == __rhs);
3824}
3825
3826// operator<
3827
3828template<class _CharT, class _Traits, class _Allocator>
3829inline _LIBCPP_INLINE_VISIBILITY
3830bool
3831operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3832           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
3833{
3834    return __lhs.compare(__rhs) < 0;
3835}
3836
3837template<class _CharT, class _Traits, class _Allocator>
3838inline _LIBCPP_INLINE_VISIBILITY
3839bool
3840operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3841           const _CharT* __rhs) _NOEXCEPT
3842{
3843    return __lhs.compare(__rhs) < 0;
3844}
3845
3846template<class _CharT, class _Traits, class _Allocator>
3847inline _LIBCPP_INLINE_VISIBILITY
3848bool
3849operator< (const _CharT* __lhs,
3850           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
3851{
3852    return __rhs.compare(__lhs) > 0;
3853}
3854
3855// operator>
3856
3857template<class _CharT, class _Traits, class _Allocator>
3858inline _LIBCPP_INLINE_VISIBILITY
3859bool
3860operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3861           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
3862{
3863    return __rhs < __lhs;
3864}
3865
3866template<class _CharT, class _Traits, class _Allocator>
3867inline _LIBCPP_INLINE_VISIBILITY
3868bool
3869operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3870           const _CharT* __rhs) _NOEXCEPT
3871{
3872    return __rhs < __lhs;
3873}
3874
3875template<class _CharT, class _Traits, class _Allocator>
3876inline _LIBCPP_INLINE_VISIBILITY
3877bool
3878operator> (const _CharT* __lhs,
3879           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
3880{
3881    return __rhs < __lhs;
3882}
3883
3884// operator<=
3885
3886template<class _CharT, class _Traits, class _Allocator>
3887inline _LIBCPP_INLINE_VISIBILITY
3888bool
3889operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3890           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
3891{
3892    return !(__rhs < __lhs);
3893}
3894
3895template<class _CharT, class _Traits, class _Allocator>
3896inline _LIBCPP_INLINE_VISIBILITY
3897bool
3898operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3899           const _CharT* __rhs) _NOEXCEPT
3900{
3901    return !(__rhs < __lhs);
3902}
3903
3904template<class _CharT, class _Traits, class _Allocator>
3905inline _LIBCPP_INLINE_VISIBILITY
3906bool
3907operator<=(const _CharT* __lhs,
3908           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
3909{
3910    return !(__rhs < __lhs);
3911}
3912
3913// operator>=
3914
3915template<class _CharT, class _Traits, class _Allocator>
3916inline _LIBCPP_INLINE_VISIBILITY
3917bool
3918operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3919           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
3920{
3921    return !(__lhs < __rhs);
3922}
3923
3924template<class _CharT, class _Traits, class _Allocator>
3925inline _LIBCPP_INLINE_VISIBILITY
3926bool
3927operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3928           const _CharT* __rhs) _NOEXCEPT
3929{
3930    return !(__lhs < __rhs);
3931}
3932
3933template<class _CharT, class _Traits, class _Allocator>
3934inline _LIBCPP_INLINE_VISIBILITY
3935bool
3936operator>=(const _CharT* __lhs,
3937           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
3938{
3939    return !(__lhs < __rhs);
3940}
3941
3942// operator +
3943
3944template<class _CharT, class _Traits, class _Allocator>
3945basic_string<_CharT, _Traits, _Allocator>
3946operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3947          const basic_string<_CharT, _Traits, _Allocator>& __rhs)
3948{
3949    basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator());
3950    typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size();
3951    typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size();
3952    __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + __rhs_sz);
3953    __r.append(__rhs.data(), __rhs_sz);
3954    return __r;
3955}
3956
3957template<class _CharT, class _Traits, class _Allocator>
3958basic_string<_CharT, _Traits, _Allocator>
3959operator+(const _CharT* __lhs , const basic_string<_CharT,_Traits,_Allocator>& __rhs)
3960{
3961    basic_string<_CharT, _Traits, _Allocator> __r(__rhs.get_allocator());
3962    typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = _Traits::length(__lhs);
3963    typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size();
3964    __r.__init(__lhs, __lhs_sz, __lhs_sz + __rhs_sz);
3965    __r.append(__rhs.data(), __rhs_sz);
3966    return __r;
3967}
3968
3969template<class _CharT, class _Traits, class _Allocator>
3970basic_string<_CharT, _Traits, _Allocator>
3971operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Allocator>& __rhs)
3972{
3973    basic_string<_CharT, _Traits, _Allocator> __r(__rhs.get_allocator());
3974    typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size();
3975    __r.__init(&__lhs, 1, 1 + __rhs_sz);
3976    __r.append(__rhs.data(), __rhs_sz);
3977    return __r;
3978}
3979
3980template<class _CharT, class _Traits, class _Allocator>
3981basic_string<_CharT, _Traits, _Allocator>
3982operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs)
3983{
3984    basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator());
3985    typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size();
3986    typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = _Traits::length(__rhs);
3987    __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + __rhs_sz);
3988    __r.append(__rhs, __rhs_sz);
3989    return __r;
3990}
3991
3992template<class _CharT, class _Traits, class _Allocator>
3993basic_string<_CharT, _Traits, _Allocator>
3994operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs)
3995{
3996    basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator());
3997    typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size();
3998    __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + 1);
3999    __r.push_back(__rhs);
4000    return __r;
4001}
4002
4003#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
4004
4005template<class _CharT, class _Traits, class _Allocator>
4006inline _LIBCPP_INLINE_VISIBILITY
4007basic_string<_CharT, _Traits, _Allocator>
4008operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs)
4009{
4010    return _VSTD::move(__lhs.append(__rhs));
4011}
4012
4013template<class _CharT, class _Traits, class _Allocator>
4014inline _LIBCPP_INLINE_VISIBILITY
4015basic_string<_CharT, _Traits, _Allocator>
4016operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs)
4017{
4018    return _VSTD::move(__rhs.insert(0, __lhs));
4019}
4020
4021template<class _CharT, class _Traits, class _Allocator>
4022inline _LIBCPP_INLINE_VISIBILITY
4023basic_string<_CharT, _Traits, _Allocator>
4024operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs)
4025{
4026    return _VSTD::move(__lhs.append(__rhs));
4027}
4028
4029template<class _CharT, class _Traits, class _Allocator>
4030inline _LIBCPP_INLINE_VISIBILITY
4031basic_string<_CharT, _Traits, _Allocator>
4032operator+(const _CharT* __lhs , basic_string<_CharT,_Traits,_Allocator>&& __rhs)
4033{
4034    return _VSTD::move(__rhs.insert(0, __lhs));
4035}
4036
4037template<class _CharT, class _Traits, class _Allocator>
4038inline _LIBCPP_INLINE_VISIBILITY
4039basic_string<_CharT, _Traits, _Allocator>
4040operator+(_CharT __lhs, basic_string<_CharT,_Traits,_Allocator>&& __rhs)
4041{
4042    __rhs.insert(__rhs.begin(), __lhs);
4043    return _VSTD::move(__rhs);
4044}
4045
4046template<class _CharT, class _Traits, class _Allocator>
4047inline _LIBCPP_INLINE_VISIBILITY
4048basic_string<_CharT, _Traits, _Allocator>
4049operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const _CharT* __rhs)
4050{
4051    return _VSTD::move(__lhs.append(__rhs));
4052}
4053
4054template<class _CharT, class _Traits, class _Allocator>
4055inline _LIBCPP_INLINE_VISIBILITY
4056basic_string<_CharT, _Traits, _Allocator>
4057operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT __rhs)
4058{
4059    __lhs.push_back(__rhs);
4060    return _VSTD::move(__lhs);
4061}
4062
4063#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
4064
4065// swap
4066
4067template<class _CharT, class _Traits, class _Allocator>
4068inline _LIBCPP_INLINE_VISIBILITY
4069void
4070swap(basic_string<_CharT, _Traits, _Allocator>& __lhs,
4071     basic_string<_CharT, _Traits, _Allocator>& __rhs)
4072     _NOEXCEPT_(_NOEXCEPT_(__lhs.swap(__rhs)))
4073{
4074    __lhs.swap(__rhs);
4075}
4076
4077#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
4078
4079typedef basic_string<char16_t> u16string;
4080typedef basic_string<char32_t> u32string;
4081
4082#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
4083
4084_LIBCPP_FUNC_VIS int                stoi  (const string& __str, size_t* __idx = 0, int __base = 10);
4085_LIBCPP_FUNC_VIS long               stol  (const string& __str, size_t* __idx = 0, int __base = 10);
4086_LIBCPP_FUNC_VIS unsigned long      stoul (const string& __str, size_t* __idx = 0, int __base = 10);
4087_LIBCPP_FUNC_VIS long long          stoll (const string& __str, size_t* __idx = 0, int __base = 10);
4088_LIBCPP_FUNC_VIS unsigned long long stoull(const string& __str, size_t* __idx = 0, int __base = 10);
4089
4090_LIBCPP_FUNC_VIS float       stof (const string& __str, size_t* __idx = 0);
4091_LIBCPP_FUNC_VIS double      stod (const string& __str, size_t* __idx = 0);
4092_LIBCPP_FUNC_VIS long double stold(const string& __str, size_t* __idx = 0);
4093
4094_LIBCPP_FUNC_VIS string to_string(int __val);
4095_LIBCPP_FUNC_VIS string to_string(unsigned __val);
4096_LIBCPP_FUNC_VIS string to_string(long __val);
4097_LIBCPP_FUNC_VIS string to_string(unsigned long __val);
4098_LIBCPP_FUNC_VIS string to_string(long long __val);
4099_LIBCPP_FUNC_VIS string to_string(unsigned long long __val);
4100_LIBCPP_FUNC_VIS string to_string(float __val);
4101_LIBCPP_FUNC_VIS string to_string(double __val);
4102_LIBCPP_FUNC_VIS string to_string(long double __val);
4103
4104_LIBCPP_FUNC_VIS int                stoi  (const wstring& __str, size_t* __idx = 0, int __base = 10);
4105_LIBCPP_FUNC_VIS long               stol  (const wstring& __str, size_t* __idx = 0, int __base = 10);
4106_LIBCPP_FUNC_VIS unsigned long      stoul (const wstring& __str, size_t* __idx = 0, int __base = 10);
4107_LIBCPP_FUNC_VIS long long          stoll (const wstring& __str, size_t* __idx = 0, int __base = 10);
4108_LIBCPP_FUNC_VIS unsigned long long stoull(const wstring& __str, size_t* __idx = 0, int __base = 10);
4109
4110_LIBCPP_FUNC_VIS float       stof (const wstring& __str, size_t* __idx = 0);
4111_LIBCPP_FUNC_VIS double      stod (const wstring& __str, size_t* __idx = 0);
4112_LIBCPP_FUNC_VIS long double stold(const wstring& __str, size_t* __idx = 0);
4113
4114_LIBCPP_FUNC_VIS wstring to_wstring(int __val);
4115_LIBCPP_FUNC_VIS wstring to_wstring(unsigned __val);
4116_LIBCPP_FUNC_VIS wstring to_wstring(long __val);
4117_LIBCPP_FUNC_VIS wstring to_wstring(unsigned long __val);
4118_LIBCPP_FUNC_VIS wstring to_wstring(long long __val);
4119_LIBCPP_FUNC_VIS wstring to_wstring(unsigned long long __val);
4120_LIBCPP_FUNC_VIS wstring to_wstring(float __val);
4121_LIBCPP_FUNC_VIS wstring to_wstring(double __val);
4122_LIBCPP_FUNC_VIS wstring to_wstring(long double __val);
4123
4124template<class _CharT, class _Traits, class _Allocator>
4125    const typename basic_string<_CharT, _Traits, _Allocator>::size_type
4126                   basic_string<_CharT, _Traits, _Allocator>::npos;
4127
4128template<class _CharT, class _Traits, class _Allocator>
4129struct _LIBCPP_TYPE_VIS_ONLY hash<basic_string<_CharT, _Traits, _Allocator> >
4130    : public unary_function<basic_string<_CharT, _Traits, _Allocator>, size_t>
4131{
4132    size_t
4133        operator()(const basic_string<_CharT, _Traits, _Allocator>& __val) const _NOEXCEPT;
4134};
4135
4136template<class _CharT, class _Traits, class _Allocator>
4137size_t
4138hash<basic_string<_CharT, _Traits, _Allocator> >::operator()(
4139        const basic_string<_CharT, _Traits, _Allocator>& __val) const _NOEXCEPT
4140{
4141    return __do_string_hash(__val.data(), __val.data() + __val.size());
4142}
4143
4144template<class _CharT, class _Traits, class _Allocator>
4145basic_ostream<_CharT, _Traits>&
4146operator<<(basic_ostream<_CharT, _Traits>& __os,
4147           const basic_string<_CharT, _Traits, _Allocator>& __str);
4148
4149template<class _CharT, class _Traits, class _Allocator>
4150basic_istream<_CharT, _Traits>&
4151operator>>(basic_istream<_CharT, _Traits>& __is,
4152           basic_string<_CharT, _Traits, _Allocator>& __str);
4153
4154template<class _CharT, class _Traits, class _Allocator>
4155basic_istream<_CharT, _Traits>&
4156getline(basic_istream<_CharT, _Traits>& __is,
4157        basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm);
4158
4159template<class _CharT, class _Traits, class _Allocator>
4160inline _LIBCPP_INLINE_VISIBILITY
4161basic_istream<_CharT, _Traits>&
4162getline(basic_istream<_CharT, _Traits>& __is,
4163        basic_string<_CharT, _Traits, _Allocator>& __str);
4164
4165#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
4166
4167template<class _CharT, class _Traits, class _Allocator>
4168inline _LIBCPP_INLINE_VISIBILITY
4169basic_istream<_CharT, _Traits>&
4170getline(basic_istream<_CharT, _Traits>&& __is,
4171        basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm);
4172
4173template<class _CharT, class _Traits, class _Allocator>
4174inline _LIBCPP_INLINE_VISIBILITY
4175basic_istream<_CharT, _Traits>&
4176getline(basic_istream<_CharT, _Traits>&& __is,
4177        basic_string<_CharT, _Traits, _Allocator>& __str);
4178
4179#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
4180
4181#if _LIBCPP_DEBUG_LEVEL >= 2
4182
4183template<class _CharT, class _Traits, class _Allocator>
4184bool
4185basic_string<_CharT, _Traits, _Allocator>::__dereferenceable(const const_iterator* __i) const
4186{
4187    return this->data() <= _VSTD::__to_raw_pointer(__i->base()) &&
4188           _VSTD::__to_raw_pointer(__i->base()) < this->data() + this->size();
4189}
4190
4191template<class _CharT, class _Traits, class _Allocator>
4192bool
4193basic_string<_CharT, _Traits, _Allocator>::__decrementable(const const_iterator* __i) const
4194{
4195    return this->data() < _VSTD::__to_raw_pointer(__i->base()) &&
4196           _VSTD::__to_raw_pointer(__i->base()) <= this->data() + this->size();
4197}
4198
4199template<class _CharT, class _Traits, class _Allocator>
4200bool
4201basic_string<_CharT, _Traits, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const
4202{
4203    const value_type* __p = _VSTD::__to_raw_pointer(__i->base()) + __n;
4204    return this->data() <= __p && __p <= this->data() + this->size();
4205}
4206
4207template<class _CharT, class _Traits, class _Allocator>
4208bool
4209basic_string<_CharT, _Traits, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const
4210{
4211    const value_type* __p = _VSTD::__to_raw_pointer(__i->base()) + __n;
4212    return this->data() <= __p && __p < this->data() + this->size();
4213}
4214
4215#endif  // _LIBCPP_DEBUG_LEVEL >= 2
4216
4217#if _LIBCPP_STD_VER > 11
4218// Literal suffixes for basic_string [basic.string.literals]
4219inline namespace literals
4220{
4221  inline namespace string_literals
4222  {
4223    inline _LIBCPP_INLINE_VISIBILITY
4224    basic_string<char> operator "" s( const char *__str, size_t __len )
4225    {
4226        return basic_string<char> (__str, __len);
4227    }
4228
4229    inline _LIBCPP_INLINE_VISIBILITY
4230    basic_string<wchar_t> operator "" s( const wchar_t *__str, size_t __len )
4231    {
4232        return basic_string<wchar_t> (__str, __len);
4233    }
4234
4235    inline _LIBCPP_INLINE_VISIBILITY
4236    basic_string<char16_t> operator "" s( const char16_t *__str, size_t __len )
4237    {
4238        return basic_string<char16_t> (__str, __len);
4239    }
4240
4241    inline _LIBCPP_INLINE_VISIBILITY
4242    basic_string<char32_t> operator "" s( const char32_t *__str, size_t __len )
4243    {
4244        return basic_string<char32_t> (__str, __len);
4245    }
4246  }
4247}
4248#endif
4249
4250_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_string<char>)
4251_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_string<wchar_t>)
4252_LIBCPP_EXTERN_TEMPLATE(string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&))
4253
4254_LIBCPP_END_NAMESPACE_STD
4255
4256#endif  // _LIBCPP_STRING
4257