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