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