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