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