blob: 47aed108070b8af580dbd0b3934e178d454f5a1e [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>
Howard Hinnant8d7a9552010-09-23 17:31:07 +0000445class _LIBCPP_VISIBLE fpos
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000446{
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>
Howard Hinnant36cdf022010-09-10 16:42:26 +0000482struct _LIBCPP_VISIBLE char_traits
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000483{
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 <>
Howard Hinnant36cdf022010-09-10 16:42:26 +0000594struct _LIBCPP_VISIBLE char_traits<char>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000595{
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 <>
Howard Hinnant8d7a9552010-09-23 17:31:07 +0000631struct _LIBCPP_VISIBLE char_traits<wchar_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000632{
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 <>
Howard Hinnant8d7a9552010-09-23 17:31:07 +0000668struct _LIBCPP_VISIBLE char_traits<char16_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000669{
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 <>
Howard Hinnant8d7a9552010-09-23 17:31:07 +0000774struct _LIBCPP_VISIBLE char_traits<char32_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000775{
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 Hinnant36cdf022010-09-10 16:42:26 +0000936class _LIBCPP_VISIBLE basic_string
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000937 : 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);
Howard Hinnant8d7a9552010-09-23 17:31:07 +00001061 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001062 basic_string& operator=(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}
1063
1064#ifndef _LIBCPP_DEBUG
1065 _LIBCPP_INLINE_VISIBILITY iterator begin() {return iterator(__get_pointer());}
1066 _LIBCPP_INLINE_VISIBILITY const_iterator begin() const {return const_iterator(data());}
1067 _LIBCPP_INLINE_VISIBILITY iterator end() {return iterator(__get_pointer() + size());}
1068 _LIBCPP_INLINE_VISIBILITY const_iterator end() const {return const_iterator(data() + size());}
1069#else // _LIBCPP_DEBUG
1070 _LIBCPP_INLINE_VISIBILITY iterator begin() {return iterator(this, __get_pointer());}
1071 _LIBCPP_INLINE_VISIBILITY const_iterator begin() const {return const_iterator(this, data());}
1072 _LIBCPP_INLINE_VISIBILITY iterator end() {return iterator(this, __get_pointer() + size());}
1073 _LIBCPP_INLINE_VISIBILITY const_iterator end() const {return const_iterator(this, data() + size());}
1074#endif // _LIBCPP_DEBUG
1075 _LIBCPP_INLINE_VISIBILITY reverse_iterator rbegin() {return reverse_iterator(end());}
1076 _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rbegin() const {return const_reverse_iterator(end());}
1077 _LIBCPP_INLINE_VISIBILITY reverse_iterator rend() {return reverse_iterator(begin());}
1078 _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rend() const {return const_reverse_iterator(begin());}
1079
1080 _LIBCPP_INLINE_VISIBILITY const_iterator cbegin() const {return begin();}
1081 _LIBCPP_INLINE_VISIBILITY const_iterator cend() const {return end();}
1082 _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crbegin() const {return rbegin();}
1083 _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crend() const {return rend();}
1084
1085 _LIBCPP_INLINE_VISIBILITY size_type size() const
1086 {return __is_long() ? __get_long_size() : __get_short_size();}
1087 _LIBCPP_INLINE_VISIBILITY size_type length() const {return size();}
1088 size_type max_size() const;
1089 _LIBCPP_INLINE_VISIBILITY size_type capacity() const
1090 {return (__is_long() ? __get_long_cap() : __min_cap) - 1;}
1091
1092 void resize(size_type __n, value_type __c);
1093 _LIBCPP_INLINE_VISIBILITY void resize(size_type __n) {resize(__n, value_type());}
1094
1095 void reserve(size_type res_arg = 0);
Howard Hinnant8d7a9552010-09-23 17:31:07 +00001096 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001097 void shrink_to_fit() {reserve();}
1098 void clear();
1099 _LIBCPP_INLINE_VISIBILITY bool empty() const {return size() == 0;}
1100
1101 _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __pos) const;
1102 _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __pos);
1103
1104 const_reference at(size_type __n) const;
1105 reference at(size_type __n);
1106
1107 _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const basic_string& __str) {return append(__str);}
1108 _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const_pointer __s) {return append(__s);}
1109 _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(value_type __c) {push_back(__c); return *this;}
1110 _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(initializer_list<value_type> __il) {return append(__il);}
1111
1112 basic_string& append(const basic_string& __str);
1113 basic_string& append(const basic_string& __str, size_type __pos, size_type __n);
1114 basic_string& append(const_pointer __s, size_type __n);
1115 basic_string& append(const_pointer __s);
1116 basic_string& append(size_type __n, value_type __c);
1117 template<class _InputIterator>
1118 typename enable_if
1119 <
1120 __is_input_iterator <_InputIterator>::value &&
1121 !__is_forward_iterator<_InputIterator>::value,
1122 basic_string&
1123 >::type
1124 append(_InputIterator __first, _InputIterator __last);
1125 template<class _ForwardIterator>
1126 typename enable_if
1127 <
1128 __is_forward_iterator<_ForwardIterator>::value,
1129 basic_string&
1130 >::type
1131 append(_ForwardIterator __first, _ForwardIterator __last);
Howard Hinnant8d7a9552010-09-23 17:31:07 +00001132 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001133 basic_string& append(initializer_list<value_type> __il) {return append(__il.begin(), __il.size());}
1134
1135 void push_back(value_type __c);
1136 void pop_back();
1137 reference front();
1138 const_reference front() const;
1139 reference back();
1140 const_reference back() const;
1141
1142 basic_string& assign(const basic_string& __str);
1143 basic_string& assign(const basic_string& __str, size_type __pos, size_type __n);
1144 basic_string& assign(const_pointer __s, size_type __n);
1145 basic_string& assign(const_pointer __s);
1146 basic_string& assign(size_type __n, value_type __c);
1147 template<class _InputIterator>
1148 typename enable_if
1149 <
1150 __is_input_iterator <_InputIterator>::value &&
1151 !__is_forward_iterator<_InputIterator>::value,
1152 basic_string&
1153 >::type
1154 assign(_InputIterator __first, _InputIterator __last);
1155 template<class _ForwardIterator>
1156 typename enable_if
1157 <
1158 __is_forward_iterator<_ForwardIterator>::value,
1159 basic_string&
1160 >::type
1161 assign(_ForwardIterator __first, _ForwardIterator __last);
Howard Hinnant8d7a9552010-09-23 17:31:07 +00001162 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001163 basic_string& assign(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}
1164
1165 basic_string& insert(size_type __pos1, const basic_string& __str);
1166 basic_string& insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n);
1167 basic_string& insert(size_type __pos, const_pointer __s, size_type __n);
1168 basic_string& insert(size_type __pos, const_pointer __s);
1169 basic_string& insert(size_type __pos, size_type __n, value_type __c);
1170 iterator insert(const_iterator __pos, value_type __c);
1171 iterator insert(const_iterator __pos, size_type __n, value_type __c);
1172 template<class _InputIterator>
1173 typename enable_if
1174 <
1175 __is_input_iterator <_InputIterator>::value &&
1176 !__is_forward_iterator<_InputIterator>::value,
1177 iterator
1178 >::type
1179 insert(const_iterator __pos, _InputIterator __first, _InputIterator __last);
1180 template<class _ForwardIterator>
1181 typename enable_if
1182 <
1183 __is_forward_iterator<_ForwardIterator>::value,
1184 iterator
1185 >::type
1186 insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last);
Howard Hinnant8d7a9552010-09-23 17:31:07 +00001187 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001188 iterator insert(const_iterator __pos, initializer_list<value_type> __il)
1189 {return insert(__pos, __il.begin(), __il.end());}
1190
1191 basic_string& erase(size_type __pos = 0, size_type __n = npos);
1192 iterator erase(const_iterator __pos);
1193 iterator erase(const_iterator __first, const_iterator __last);
1194
1195 basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str);
1196 basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2);
1197 basic_string& replace(size_type __pos, size_type __n1, const_pointer __s, size_type __n2);
1198 basic_string& replace(size_type __pos, size_type __n1, const_pointer __s);
1199 basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c);
1200 basic_string& replace(iterator __i1, iterator __i2, const basic_string& __str);
1201 basic_string& replace(iterator __i1, iterator __i2, const_pointer __s, size_type __n);
1202 basic_string& replace(iterator __i1, iterator __i2, const_pointer __s);
1203 basic_string& replace(iterator __i1, iterator __i2, size_type __n, value_type __c);
1204 template<class _InputIterator>
1205 typename enable_if
1206 <
1207 __is_input_iterator<_InputIterator>::value,
1208 basic_string&
1209 >::type
1210 replace(iterator __i1, iterator __i2, _InputIterator __j1, _InputIterator __j2);
Howard Hinnant8d7a9552010-09-23 17:31:07 +00001211 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001212 basic_string& replace(iterator __i1, iterator __i2, initializer_list<value_type> __il)
1213 {return replace(__i1, __i2, __il.begin(), __il.end());}
1214
1215 size_type copy(pointer __s, size_type __n, size_type __pos = 0) const;
1216 basic_string substr(size_type __pos = 0, size_type __n = npos) const;
1217
1218 void swap(basic_string& __str);
1219
1220 _LIBCPP_INLINE_VISIBILITY const_pointer c_str() const {return data();}
1221 _LIBCPP_INLINE_VISIBILITY const_pointer data() const {return __get_pointer();}
1222
1223 _LIBCPP_INLINE_VISIBILITY allocator_type get_allocator() const {return __alloc();}
1224
1225 size_type find(const basic_string& __str, size_type __pos = 0) const;
1226 size_type find(const_pointer __s, size_type __pos, size_type __n) const;
1227 size_type find(const_pointer __s, size_type __pos = 0) const;
1228 size_type find(value_type __c, size_type __pos = 0) const;
1229
1230 size_type rfind(const basic_string& __str, size_type __pos = npos) const;
1231 size_type rfind(const_pointer __s, size_type __pos, size_type __n) const;
1232 size_type rfind(const_pointer __s, size_type __pos = npos) const;
1233 size_type rfind(value_type __c, size_type __pos = npos) const;
1234
1235 size_type find_first_of(const basic_string& __str, size_type __pos = 0) const;
1236 size_type find_first_of(const_pointer __s, size_type __pos, size_type __n) const;
1237 size_type find_first_of(const_pointer __s, size_type __pos = 0) const;
1238 size_type find_first_of(value_type __c, size_type __pos = 0) const;
1239
1240 size_type find_last_of(const basic_string& __str, size_type __pos = npos) const;
1241 size_type find_last_of(const_pointer __s, size_type __pos, size_type __n) const;
1242 size_type find_last_of(const_pointer __s, size_type __pos = npos) const;
1243 size_type find_last_of(value_type __c, size_type __pos = npos) const;
1244
1245 size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const;
1246 size_type find_first_not_of(const_pointer __s, size_type __pos, size_type __n) const;
1247 size_type find_first_not_of(const_pointer __s, size_type __pos = 0) const;
1248 size_type find_first_not_of(value_type __c, size_type __pos = 0) const;
1249
1250 size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const;
1251 size_type find_last_not_of(const_pointer __s, size_type __pos, size_type __n) const;
1252 size_type find_last_not_of(const_pointer __s, size_type __pos = npos) const;
1253 size_type find_last_not_of(value_type __c, size_type __pos = npos) const;
1254
1255 int compare(const basic_string& __str) const;
1256 int compare(size_type __pos1, size_type __n1, const basic_string& __str) const;
1257 int compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2) const;
1258 int compare(const_pointer __s) const;
1259 int compare(size_type __pos1, size_type __n1, const_pointer __s) const;
1260 int compare(size_type __pos1, size_type __n1, const_pointer __s, size_type __n2) const;
1261
1262 bool __invariants() const;
1263private:
1264 _LIBCPP_INLINE_VISIBILITY allocator_type& __alloc() {return __r_.second();}
1265 _LIBCPP_INLINE_VISIBILITY const allocator_type& __alloc() const {return __r_.second();}
1266
1267 _LIBCPP_INLINE_VISIBILITY bool __is_long() const {return bool(__r_.first().__s.__size_ & __short_mask);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001268
1269 _LIBCPP_INLINE_VISIBILITY void __set_short_size(size_type __s)
1270#if _LIBCPP_BIG_ENDIAN
1271 {__r_.first().__s.__size_ = (unsigned char)(__s);}
1272#else
1273 {__r_.first().__s.__size_ = (unsigned char)(__s << 1);}
1274#endif
1275 _LIBCPP_INLINE_VISIBILITY size_type __get_short_size() const
1276#if _LIBCPP_BIG_ENDIAN
1277 {return __r_.first().__s.__size_;}
1278#else
1279 {return __r_.first().__s.__size_ >> 1;}
1280#endif
1281 _LIBCPP_INLINE_VISIBILITY void __set_long_size(size_type __s) {__r_.first().__l.__size_ = __s;}
1282 _LIBCPP_INLINE_VISIBILITY size_type __get_long_size() const {return __r_.first().__l.__size_;}
1283 _LIBCPP_INLINE_VISIBILITY void __set_size(size_type __s)
1284 {if (__is_long()) __set_long_size(__s); else __set_short_size(__s);}
1285
1286 _LIBCPP_INLINE_VISIBILITY void __set_long_cap(size_type __s) {__r_.first().__l.__cap_ = __long_mask | __s;}
1287 _LIBCPP_INLINE_VISIBILITY size_type __get_long_cap() const {return __r_.first().__l.__cap_ & ~__long_mask;}
1288
1289 _LIBCPP_INLINE_VISIBILITY void __set_long_pointer(pointer __p) {__r_.first().__l.__data_ = __p;}
1290 _LIBCPP_INLINE_VISIBILITY pointer __get_long_pointer() {return __r_.first().__l.__data_;}
1291 _LIBCPP_INLINE_VISIBILITY const_pointer __get_long_pointer() const {return __r_.first().__l.__data_;}
1292 _LIBCPP_INLINE_VISIBILITY pointer __get_short_pointer() {return __r_.first().__s.__data_;}
1293 _LIBCPP_INLINE_VISIBILITY const_pointer __get_short_pointer() const {return __r_.first().__s.__data_;}
1294 _LIBCPP_INLINE_VISIBILITY pointer __get_pointer()
1295 {return __is_long() ? __get_long_pointer() : __get_short_pointer();}
1296 _LIBCPP_INLINE_VISIBILITY const_pointer __get_pointer() const
1297 {return __is_long() ? __get_long_pointer() : __get_short_pointer();}
1298
1299 _LIBCPP_INLINE_VISIBILITY void __zero()
1300 {
1301 size_type (&__a)[__n_words] = __r_.first().__r.__words;
1302 for (unsigned __i = 0; __i < __n_words; ++__i)
1303 __a[__i] = 0;
1304 }
1305
1306 template <size_type __a> static
1307 _LIBCPP_INLINE_VISIBILITY size_type __align(size_type __s) {return __s + (__a-1) & ~(__a-1);}
1308 enum {__alignment = 16};
1309 static _LIBCPP_INLINE_VISIBILITY size_type __recommend(size_type __s)
1310 {return (__s < __min_cap ? __min_cap :
1311 __align<sizeof(value_type) < __alignment ? __alignment/sizeof(value_type) : 1>(__s+1)) - 1;}
1312
1313 void __init(const_pointer __s, size_type __sz, size_type __reserve);
1314 void __init(const_pointer __s, size_type __sz);
1315 void __init(size_type __n, value_type __c);
Howard Hinnant324bb032010-08-22 00:02:43 +00001316
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001317 template <class _InputIterator>
1318 typename enable_if
1319 <
1320 __is_input_iterator <_InputIterator>::value &&
1321 !__is_forward_iterator<_InputIterator>::value,
1322 void
1323 >::type
1324 __init(_InputIterator __first, _InputIterator __last);
1325
1326 template <class _ForwardIterator>
1327 typename enable_if
1328 <
1329 __is_forward_iterator<_ForwardIterator>::value,
1330 void
1331 >::type
1332 __init(_ForwardIterator __first, _ForwardIterator __last);
1333
1334 void __grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
Howard Hinnant324bb032010-08-22 00:02:43 +00001335 size_type __n_copy, size_type __n_del, size_type __n_add = 0);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001336 void __grow_by_and_replace(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
1337 size_type __n_copy, size_type __n_del,
1338 size_type __n_add, const_pointer __p_new_stuff);
1339
1340 void __erase_to_end(size_type __pos);
1341
1342 void __invalidate_all_iterators();
1343 void __invalidate_iterators_past(size_type);
1344
1345 friend basic_string operator+<>(const basic_string&, const basic_string&);
1346 friend basic_string operator+<>(const value_type*, const basic_string&);
1347 friend basic_string operator+<>(value_type, const basic_string&);
1348 friend basic_string operator+<>(const basic_string&, const value_type*);
1349 friend basic_string operator+<>(const basic_string&, value_type);
1350};
1351
1352template <class _CharT, class _Traits, class _Allocator>
1353#ifndef _LIBCPP_DEBUG
1354_LIBCPP_INLINE_VISIBILITY inline
1355#endif
1356void
1357basic_string<_CharT, _Traits, _Allocator>::__invalidate_all_iterators()
1358{
1359#ifdef _LIBCPP_DEBUG
1360 iterator::__remove_all(this);
1361 const_iterator::__remove_all(this);
Howard Hinnant324bb032010-08-22 00:02:43 +00001362#endif // _LIBCPP_DEBUG
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001363}
1364
1365template <class _CharT, class _Traits, class _Allocator>
1366#ifndef _LIBCPP_DEBUG
1367_LIBCPP_INLINE_VISIBILITY inline
1368#endif
1369void
1370basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type __pos)
1371{
1372#ifdef _LIBCPP_DEBUG
1373 const_iterator __beg = begin();
1374 if (__iterator_list_.first)
1375 {
1376 for (iterator* __p = __iterator_list_.first; __p;)
1377 {
1378 if (*__p - __beg > static_cast<difference_type>(__pos))
1379 {
1380 iterator* __n = __p;
1381 __p = __p->__next;
1382 __n->__remove_owner();
1383 }
1384 else
1385 __p = __p->__next;
1386 }
1387 }
1388 if (__iterator_list_.second)
1389 {
1390 for (const_iterator* __p = __iterator_list_.second; __p;)
1391 {
1392 if (*__p - __beg > static_cast<difference_type>(__pos))
1393 {
1394 const_iterator* __n = __p;
1395 __p = __p->__next;
1396 __n->__remove_owner();
1397 }
1398 else
1399 __p = __p->__next;
1400 }
1401 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001402#endif // _LIBCPP_DEBUG
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001403}
1404
1405template <class _CharT, class _Traits, class _Allocator>
1406_LIBCPP_INLINE_VISIBILITY inline
1407basic_string<_CharT, _Traits, _Allocator>::basic_string()
1408{
1409 __zero();
1410}
1411
1412template <class _CharT, class _Traits, class _Allocator>
1413_LIBCPP_INLINE_VISIBILITY inline
1414basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __a)
1415 : __r_(__a)
1416{
1417 __zero();
1418}
1419
1420template <class _CharT, class _Traits, class _Allocator>
1421void
1422basic_string<_CharT, _Traits, _Allocator>::__init(const_pointer __s, size_type __sz, size_type __reserve)
1423{
1424 if (__reserve > max_size())
1425 this->__throw_length_error();
1426 pointer __p;
1427 if (__reserve < __min_cap)
1428 {
1429 __set_short_size(__sz);
1430 __p = __get_short_pointer();
1431 }
1432 else
1433 {
1434 size_type __cap = __recommend(__reserve);
1435 __p = __alloc().allocate(__cap+1);
1436 __set_long_pointer(__p);
1437 __set_long_cap(__cap+1);
1438 __set_long_size(__sz);
1439 }
1440 traits_type::copy(__p, __s, __sz);
1441 traits_type::assign(__p[__sz], value_type());
1442}
1443
1444template <class _CharT, class _Traits, class _Allocator>
1445void
1446basic_string<_CharT, _Traits, _Allocator>::__init(const_pointer __s, size_type __sz)
1447{
1448 if (__sz > max_size())
1449 this->__throw_length_error();
1450 pointer __p;
1451 if (__sz < __min_cap)
1452 {
1453 __set_short_size(__sz);
1454 __p = __get_short_pointer();
1455 }
1456 else
1457 {
1458 size_type __cap = __recommend(__sz);
1459 __p = __alloc().allocate(__cap+1);
1460 __set_long_pointer(__p);
1461 __set_long_cap(__cap+1);
1462 __set_long_size(__sz);
1463 }
1464 traits_type::copy(__p, __s, __sz);
1465 traits_type::assign(__p[__sz], value_type());
1466}
1467
1468template <class _CharT, class _Traits, class _Allocator>
1469_LIBCPP_INLINE_VISIBILITY inline
1470basic_string<_CharT, _Traits, _Allocator>::basic_string(const_pointer __s)
1471{
1472#ifdef _LIBCPP_DEBUG
1473 assert(__s != 0);
1474#endif
1475 __init(__s, traits_type::length(__s));
1476}
1477
1478template <class _CharT, class _Traits, class _Allocator>
1479_LIBCPP_INLINE_VISIBILITY inline
1480basic_string<_CharT, _Traits, _Allocator>::basic_string(const_pointer __s, const allocator_type& __a)
1481 : __r_(__a)
1482{
1483#ifdef _LIBCPP_DEBUG
1484 assert(__s != 0);
1485#endif
1486 __init(__s, traits_type::length(__s));
1487}
1488
1489template <class _CharT, class _Traits, class _Allocator>
1490_LIBCPP_INLINE_VISIBILITY inline
1491basic_string<_CharT, _Traits, _Allocator>::basic_string(const_pointer __s, size_type __n)
1492{
1493#ifdef _LIBCPP_DEBUG
1494 assert(__s != 0);
1495#endif
1496 __init(__s, __n);
1497}
1498
1499template <class _CharT, class _Traits, class _Allocator>
1500_LIBCPP_INLINE_VISIBILITY inline
1501basic_string<_CharT, _Traits, _Allocator>::basic_string(const_pointer __s, size_type __n, const allocator_type& __a)
1502 : __r_(__a)
1503{
1504#ifdef _LIBCPP_DEBUG
1505 assert(__s != 0);
1506#endif
1507 __init(__s, __n);
1508}
1509
1510template <class _CharT, class _Traits, class _Allocator>
1511basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str)
1512 : __r_(__str.__alloc())
1513{
1514 if (!__str.__is_long())
1515 __r_.first().__r = __str.__r_.first().__r;
1516 else
1517 __init(__str.__get_long_pointer(), __str.__get_long_size());
1518}
1519
1520template <class _CharT, class _Traits, class _Allocator>
1521basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, const allocator_type& __a)
1522 : __r_(__a)
1523{
1524 if (!__str.__is_long())
1525 __r_.first().__r = __str.__r_.first().__r;
1526 else
1527 __init(__str.__get_long_pointer(), __str.__get_long_size());
1528}
1529
Howard Hinnant73d21a42010-09-04 23:28:19 +00001530#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001531
1532template <class _CharT, class _Traits, class _Allocator>
1533_LIBCPP_INLINE_VISIBILITY inline
1534basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str)
1535 : __r_(_STD::move(__str.__r_))
1536{
1537 __str.__zero();
1538#ifdef _LIBCPP_DEBUG
1539 __str.__invalidate_all_iterators();
1540#endif
1541}
1542
1543template <class _CharT, class _Traits, class _Allocator>
1544_LIBCPP_INLINE_VISIBILITY inline
1545basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, const allocator_type& __a)
1546 : __r_(__str.__r_.first(), __a)
1547{
1548 __str.__zero();
1549#ifdef _LIBCPP_DEBUG
1550 __str.__invalidate_all_iterators();
1551#endif
1552}
1553
Howard Hinnant73d21a42010-09-04 23:28:19 +00001554#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001555
1556template <class _CharT, class _Traits, class _Allocator>
1557void
1558basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c)
1559{
1560 if (__n > max_size())
1561 this->__throw_length_error();
1562 pointer __p;
1563 if (__n < __min_cap)
1564 {
1565 __set_short_size(__n);
1566 __p = __get_short_pointer();
1567 }
1568 else
1569 {
1570 size_type __cap = __recommend(__n);
1571 __p = __alloc().allocate(__cap+1);
1572 __set_long_pointer(__p);
1573 __set_long_cap(__cap+1);
1574 __set_long_size(__n);
1575 }
1576 traits_type::assign(__p, __n, __c);
1577 traits_type::assign(__p[__n], value_type());
1578}
1579
1580template <class _CharT, class _Traits, class _Allocator>
1581_LIBCPP_INLINE_VISIBILITY inline
1582basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, value_type __c)
1583{
1584 __init(__n, __c);
1585}
1586
1587template <class _CharT, class _Traits, class _Allocator>
1588_LIBCPP_INLINE_VISIBILITY inline
1589basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, value_type __c, const allocator_type& __a)
1590 : __r_(__a)
1591{
1592 __init(__n, __c);
1593}
1594
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001595template <class _CharT, class _Traits, class _Allocator>
1596basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos, size_type __n,
1597 const allocator_type& __a)
1598 : __r_(__a)
1599{
1600 size_type __str_sz = __str.size();
1601 if (__pos > __str_sz)
1602 this->__throw_out_of_range();
1603 __init(__str.data() + __pos, _STD::min(__n, __str_sz - __pos));
1604}
1605
1606template <class _CharT, class _Traits, class _Allocator>
1607template <class _InputIterator>
1608typename enable_if
1609<
1610 __is_input_iterator <_InputIterator>::value &&
1611 !__is_forward_iterator<_InputIterator>::value,
1612 void
1613>::type
1614basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last)
1615{
1616 __zero();
1617#ifndef _LIBCPP_NO_EXCEPTIONS
1618 try
1619 {
Howard Hinnant324bb032010-08-22 00:02:43 +00001620#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001621 for (; __first != __last; ++__first)
1622 push_back(*__first);
1623#ifndef _LIBCPP_NO_EXCEPTIONS
1624 }
1625 catch (...)
1626 {
1627 if (__is_long())
1628 __alloc().deallocate(__get_long_pointer(), __get_long_cap());
1629 throw;
1630 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001631#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001632}
1633
1634template <class _CharT, class _Traits, class _Allocator>
1635template <class _ForwardIterator>
1636typename enable_if
1637<
1638 __is_forward_iterator<_ForwardIterator>::value,
1639 void
1640>::type
1641basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last)
1642{
1643 size_type __sz = static_cast<size_type>(_STD::distance(__first, __last));
1644 if (__sz > max_size())
1645 this->__throw_length_error();
1646 pointer __p;
1647 if (__sz < __min_cap)
1648 {
1649 __set_short_size(__sz);
1650 __p = __get_short_pointer();
1651 }
1652 else
1653 {
1654 size_type __cap = __recommend(__sz);
1655 __p = __alloc().allocate(__cap+1);
1656 __set_long_pointer(__p);
1657 __set_long_cap(__cap+1);
1658 __set_long_size(__sz);
1659 }
1660 for (; __first != __last; ++__first, ++__p)
1661 traits_type::assign(*__p, *__first);
1662 traits_type::assign(*__p, value_type());
1663}
1664
1665template <class _CharT, class _Traits, class _Allocator>
1666template<class _InputIterator>
1667_LIBCPP_INLINE_VISIBILITY inline
1668basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last)
1669{
1670 __init(__first, __last);
1671}
1672
1673template <class _CharT, class _Traits, class _Allocator>
1674template<class _InputIterator>
1675_LIBCPP_INLINE_VISIBILITY inline
1676basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last,
1677 const allocator_type& __a)
1678 : __r_(__a)
1679{
1680 __init(__first, __last);
1681}
1682
1683template <class _CharT, class _Traits, class _Allocator>
1684_LIBCPP_INLINE_VISIBILITY inline
1685basic_string<_CharT, _Traits, _Allocator>::basic_string(initializer_list<value_type> __il)
1686{
1687 __init(__il.begin(), __il.end());
1688}
1689
1690template <class _CharT, class _Traits, class _Allocator>
1691_LIBCPP_INLINE_VISIBILITY inline
1692basic_string<_CharT, _Traits, _Allocator>::basic_string(initializer_list<value_type> __il, const allocator_type& __a)
1693 : __r_(__a)
1694{
1695 __init(__il.begin(), __il.end());
1696}
1697
1698template <class _CharT, class _Traits, class _Allocator>
1699_LIBCPP_INLINE_VISIBILITY inline
1700basic_string<_CharT, _Traits, _Allocator>::~basic_string()
1701{
1702 __invalidate_all_iterators();
1703 if (__is_long())
1704 __alloc().deallocate(__get_long_pointer(), __get_long_cap());
1705}
1706
1707template <class _CharT, class _Traits, class _Allocator>
1708void
1709basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace
1710 (size_type __old_cap, size_type __delta_cap, size_type __old_sz,
1711 size_type __n_copy, size_type __n_del, size_type __n_add, const_pointer __p_new_stuff)
1712{
1713 size_type __ms = max_size();
1714 if (__delta_cap > __ms - __old_cap - 1)
1715 this->__throw_length_error();
1716 pointer __old_p = __get_pointer();
1717 size_type __cap = __old_cap < __ms / 2 - __alignment ?
1718 __recommend(_STD::max(__old_cap + __delta_cap, 2 * __old_cap)) :
1719 __ms - 1;
1720 pointer __p = __alloc().allocate(__cap+1);
1721 __invalidate_all_iterators();
1722 if (__n_copy != 0)
1723 traits_type::copy(__p, __old_p, __n_copy);
1724 if (__n_add != 0)
1725 traits_type::copy(__p + __n_copy, __p_new_stuff, __n_add);
1726 size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
1727 if (__sec_cp_sz != 0)
1728 traits_type::copy(__p + __n_copy + __n_add, __old_p + __n_copy + __n_del, __sec_cp_sz);
1729 if (__old_cap+1 != __min_cap)
1730 __alloc().deallocate(__old_p, __old_cap+1);
1731 __set_long_pointer(__p);
1732 __set_long_cap(__cap+1);
1733 __old_sz = __n_copy + __n_add + __sec_cp_sz;
1734 __set_long_size(__old_sz);
1735 traits_type::assign(__p[__old_sz], value_type());
1736}
1737
1738template <class _CharT, class _Traits, class _Allocator>
1739void
1740basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
1741 size_type __n_copy, size_type __n_del, size_type __n_add)
1742{
1743 size_type __ms = max_size();
1744 if (__delta_cap > __ms - __old_cap - 1)
1745 this->__throw_length_error();
1746 pointer __old_p = __get_pointer();
1747 size_type __cap = __old_cap < __ms / 2 - __alignment ?
1748 __recommend(_STD::max(__old_cap + __delta_cap, 2 * __old_cap)) :
1749 __ms - 1;
1750 pointer __p = __alloc().allocate(__cap+1);
1751 __invalidate_all_iterators();
1752 if (__n_copy != 0)
1753 traits_type::copy(__p, __old_p, __n_copy);
1754 size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
1755 if (__sec_cp_sz != 0)
1756 traits_type::copy(__p + __n_copy + __n_add, __old_p + __n_copy + __n_del, __sec_cp_sz);
1757 if (__old_cap+1 != __min_cap)
1758 __alloc().deallocate(__old_p, __old_cap+1);
1759 __set_long_pointer(__p);
1760 __set_long_cap(__cap+1);
1761}
1762
1763// assign
1764
1765template <class _CharT, class _Traits, class _Allocator>
1766basic_string<_CharT, _Traits, _Allocator>&
1767basic_string<_CharT, _Traits, _Allocator>::assign(const_pointer __s, size_type __n)
1768{
1769#ifdef _LIBCPP_DEBUG
1770 assert(__s != 0);
1771#endif
1772 size_type __cap = capacity();
1773 if (__cap >= __n)
1774 {
1775 pointer __p = __get_pointer();
1776 traits_type::move(__p, __s, __n);
1777 traits_type::assign(__p[__n], value_type());
1778 __set_size(__n);
1779 __invalidate_iterators_past(__n);
1780 }
1781 else
1782 {
1783 size_type __sz = size();
1784 __grow_by_and_replace(__cap, __n - __cap, __sz, 0, __sz, __n, __s);
1785 }
1786 return *this;
1787}
1788
1789template <class _CharT, class _Traits, class _Allocator>
1790basic_string<_CharT, _Traits, _Allocator>&
1791basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c)
1792{
1793 size_type __cap = capacity();
1794 if (__cap < __n)
1795 {
1796 size_type __sz = size();
1797 __grow_by(__cap, __n - __cap, __sz, 0, __sz);
1798 }
1799 else
1800 __invalidate_iterators_past(__n);
1801 pointer __p = __get_pointer();
1802 traits_type::assign(__p, __n, __c);
1803 traits_type::assign(__p[__n], value_type());
1804 __set_size(__n);
1805 return *this;
1806}
1807
1808template <class _CharT, class _Traits, class _Allocator>
1809basic_string<_CharT, _Traits, _Allocator>&
1810basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c)
1811{
1812 pointer __p;
1813 if (__is_long())
1814 {
1815 __p = __get_long_pointer();
1816 __set_long_size(1);
1817 }
1818 else
1819 {
1820 __p = __get_short_pointer();
1821 __set_short_size(1);
1822 }
1823 traits_type::assign(*__p, __c);
1824 traits_type::assign(*++__p, value_type());
1825 __invalidate_iterators_past(1);
1826 return *this;
1827}
1828
1829template <class _CharT, class _Traits, class _Allocator>
1830template<class _InputIterator>
1831typename enable_if
1832<
1833 __is_input_iterator <_InputIterator>::value &&
1834 !__is_forward_iterator<_InputIterator>::value,
1835 basic_string<_CharT, _Traits, _Allocator>&
1836>::type
1837basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
1838{
1839 clear();
1840 for (; __first != __last; ++__first)
1841 push_back(*__first);
1842}
1843
1844template <class _CharT, class _Traits, class _Allocator>
1845template<class _ForwardIterator>
1846typename enable_if
1847<
1848 __is_forward_iterator<_ForwardIterator>::value,
1849 basic_string<_CharT, _Traits, _Allocator>&
1850>::type
1851basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)
1852{
1853 size_type __n = static_cast<size_type>(_STD::distance(__first, __last));
1854 size_type __cap = capacity();
1855 if (__cap < __n)
1856 {
1857 size_type __sz = size();
1858 __grow_by(__cap, __n - __cap, __sz, 0, __sz);
1859 }
1860 else
1861 __invalidate_iterators_past(__n);
1862 pointer __p = __get_pointer();
1863 for (; __first != __last; ++__first, ++__p)
1864 traits_type::assign(*__p, *__first);
1865 traits_type::assign(*__p, value_type());
1866 __set_size(__n);
1867 return *this;
1868}
1869
1870template <class _CharT, class _Traits, class _Allocator>
1871_LIBCPP_INLINE_VISIBILITY inline
1872basic_string<_CharT, _Traits, _Allocator>&
1873basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str)
1874{
1875 return assign(__str.data(), __str.size());
1876}
1877
1878template <class _CharT, class _Traits, class _Allocator>
1879basic_string<_CharT, _Traits, _Allocator>&
1880basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, size_type __pos, size_type __n)
1881{
1882 size_type __sz = __str.size();
1883 if (__pos > __sz)
1884 this->__throw_out_of_range();
1885 return assign(__str.data() + __pos, _STD::min(__n, __sz - __pos));
1886}
1887
1888template <class _CharT, class _Traits, class _Allocator>
1889basic_string<_CharT, _Traits, _Allocator>&
1890basic_string<_CharT, _Traits, _Allocator>::assign(const_pointer __s)
1891{
1892#ifdef _LIBCPP_DEBUG
1893 assert(__s != 0);
1894#endif
1895 return assign(__s, traits_type::length(__s));
1896}
1897
1898// append
1899
1900template <class _CharT, class _Traits, class _Allocator>
1901basic_string<_CharT, _Traits, _Allocator>&
1902basic_string<_CharT, _Traits, _Allocator>::append(const_pointer __s, size_type __n)
1903{
1904#ifdef _LIBCPP_DEBUG
1905 assert(__s != 0);
1906#endif
1907 size_type __cap = capacity();
1908 size_type __sz = size();
1909 if (__cap - __sz >= __n)
1910 {
1911 if (__n)
1912 {
1913 pointer __p = __get_pointer();
1914 traits_type::copy(__p + __sz, __s, __n);
1915 __sz += __n;
1916 __set_size(__sz);
1917 traits_type::assign(__p[__sz], value_type());
1918 }
1919 }
1920 else
1921 __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __sz, 0, __n, __s);
1922 return *this;
1923}
1924
1925template <class _CharT, class _Traits, class _Allocator>
1926basic_string<_CharT, _Traits, _Allocator>&
1927basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c)
1928{
1929 if (__n)
1930 {
1931 size_type __cap = capacity();
1932 size_type __sz = size();
1933 if (__cap - __sz < __n)
1934 __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
1935 pointer __p = __get_pointer();
1936 traits_type::assign(__p + __sz, __n, __c);
1937 __sz += __n;
1938 __set_size(__sz);
1939 traits_type::assign(__p[__sz], value_type());
1940 }
1941 return *this;
1942}
1943
1944template <class _CharT, class _Traits, class _Allocator>
1945void
1946basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c)
1947{
1948 size_type __cap = capacity();
1949 size_type __sz = size();
1950 if (__sz == __cap)
1951 __grow_by(__cap, 1, __sz, __sz, 0);
1952 pointer __p = __get_pointer() + __sz;
1953 traits_type::assign(*__p, __c);
1954 traits_type::assign(*++__p, value_type());
1955 __set_size(__sz+1);
1956}
1957
1958template <class _CharT, class _Traits, class _Allocator>
1959template<class _InputIterator>
1960typename enable_if
1961<
1962 __is_input_iterator <_InputIterator>::value &&
1963 !__is_forward_iterator<_InputIterator>::value,
1964 basic_string<_CharT, _Traits, _Allocator>&
1965>::type
1966basic_string<_CharT, _Traits, _Allocator>::append(_InputIterator __first, _InputIterator __last)
1967{
1968 for (; __first != __last; ++__first)
1969 push_back(*__first);
1970 return *this;
1971}
1972
1973template <class _CharT, class _Traits, class _Allocator>
1974template<class _ForwardIterator>
1975typename enable_if
1976<
1977 __is_forward_iterator<_ForwardIterator>::value,
1978 basic_string<_CharT, _Traits, _Allocator>&
1979>::type
1980basic_string<_CharT, _Traits, _Allocator>::append(_ForwardIterator __first, _ForwardIterator __last)
1981{
1982 size_type __sz = size();
1983 size_type __cap = capacity();
1984 size_type __n = static_cast<size_type>(_STD::distance(__first, __last));
1985 if (__n)
1986 {
1987 if (__cap - __sz < __n)
1988 __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
1989 pointer __p = __get_pointer() + __sz;
1990 for (; __first != __last; ++__p, ++__first)
1991 traits_type::assign(*__p, *__first);
1992 traits_type::assign(*__p, value_type());
1993 __set_size(__sz + __n);
1994 }
1995 return *this;
1996}
1997
1998template <class _CharT, class _Traits, class _Allocator>
1999_LIBCPP_INLINE_VISIBILITY inline
2000basic_string<_CharT, _Traits, _Allocator>&
2001basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str)
2002{
2003 return append(__str.data(), __str.size());
2004}
2005
2006template <class _CharT, class _Traits, class _Allocator>
2007basic_string<_CharT, _Traits, _Allocator>&
2008basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, size_type __pos, size_type __n)
2009{
2010 size_type __sz = __str.size();
2011 if (__pos > __sz)
2012 this->__throw_out_of_range();
2013 return append(__str.data() + __pos, _STD::min(__n, __sz - __pos));
2014}
2015
2016template <class _CharT, class _Traits, class _Allocator>
2017basic_string<_CharT, _Traits, _Allocator>&
2018basic_string<_CharT, _Traits, _Allocator>::append(const_pointer __s)
2019{
2020#ifdef _LIBCPP_DEBUG
2021 assert(__s != 0);
2022#endif
2023 return append(__s, traits_type::length(__s));
2024}
2025
2026// insert
2027
2028template <class _CharT, class _Traits, class _Allocator>
2029basic_string<_CharT, _Traits, _Allocator>&
2030basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const_pointer __s, size_type __n)
2031{
2032#ifdef _LIBCPP_DEBUG
2033 assert(__s != 0);
2034#endif
2035 size_type __sz = size();
2036 if (__pos > __sz)
2037 this->__throw_out_of_range();
2038 size_type __cap = capacity();
2039 if (__cap - __sz >= __n)
2040 {
2041 if (__n)
2042 {
2043 pointer __p = __get_pointer();
2044 size_type __n_move = __sz - __pos;
2045 if (__n_move != 0)
2046 {
2047 if (__p + __pos <= __s && __s < __p + __sz)
2048 __s += __n;
2049 traits_type::move(__p + __pos + __n, __p + __pos, __n_move);
2050 }
2051 traits_type::move(__p + __pos, __s, __n);
2052 __sz += __n;
2053 __set_size(__sz);
2054 traits_type::assign(__p[__sz], value_type());
2055 }
2056 }
2057 else
2058 __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s);
2059 return *this;
2060}
2061
2062template <class _CharT, class _Traits, class _Allocator>
2063basic_string<_CharT, _Traits, _Allocator>&
2064basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n, value_type __c)
2065{
2066 size_type __sz = size();
2067 if (__pos > __sz)
2068 this->__throw_out_of_range();
2069 if (__n)
2070 {
2071 size_type __cap = capacity();
2072 pointer __p;
2073 if (__cap - __sz >= __n)
2074 {
2075 __p = __get_pointer();
2076 size_type __n_move = __sz - __pos;
2077 if (__n_move != 0)
2078 traits_type::move(__p + __pos + __n, __p + __pos, __n_move);
2079 }
2080 else
2081 {
2082 __grow_by(__cap, __sz + __n - __cap, __sz, __pos, 0, __n);
2083 __p = __get_long_pointer();
2084 }
2085 traits_type::assign(__p + __pos, __n, __c);
2086 __sz += __n;
2087 __set_size(__sz);
2088 traits_type::assign(__p[__sz], value_type());
2089 }
2090 return *this;
2091}
2092
2093template <class _CharT, class _Traits, class _Allocator>
2094template<class _InputIterator>
2095typename enable_if
2096<
2097 __is_input_iterator <_InputIterator>::value &&
2098 !__is_forward_iterator<_InputIterator>::value,
2099 typename basic_string<_CharT, _Traits, _Allocator>::iterator
2100>::type
2101basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last)
2102{
2103 size_type __old_sz = size();
2104 difference_type __ip = __pos - begin();
2105 for (; __first != __last; ++__first)
2106 push_back(*__first);
2107 pointer __p = __get_pointer();
2108 _STD::rotate(__p + __ip, __p + __old_sz, __p + size());
2109 return iterator(__p + __ip);
2110}
2111
2112template <class _CharT, class _Traits, class _Allocator>
2113template<class _ForwardIterator>
2114typename enable_if
2115<
2116 __is_forward_iterator<_ForwardIterator>::value,
2117 typename basic_string<_CharT, _Traits, _Allocator>::iterator
2118>::type
2119basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last)
2120{
2121 size_type __ip = static_cast<size_type>(__pos - begin());
2122 size_type __sz = size();
2123 size_type __cap = capacity();
2124 size_type __n = static_cast<size_type>(_STD::distance(__first, __last));
2125 if (__n)
2126 {
2127 pointer __p;
2128 if (__cap - __sz >= __n)
2129 {
2130 __p = __get_pointer();
2131 size_type __n_move = __sz - __ip;
2132 if (__n_move != 0)
2133 traits_type::move(__p + __ip + __n, __p + __ip, __n_move);
2134 }
2135 else
2136 {
2137 __grow_by(__cap, __sz + __n - __cap, __sz, __ip, 0, __n);
2138 __p = __get_long_pointer();
2139 }
2140 __sz += __n;
2141 __set_size(__sz);
2142 traits_type::assign(__p[__sz], value_type());
2143 for (__p += __ip; __first != __last; ++__p, ++__first)
2144 traits_type::assign(*__p, *__first);
2145 }
2146 return begin() + __ip;
2147}
2148
2149template <class _CharT, class _Traits, class _Allocator>
2150_LIBCPP_INLINE_VISIBILITY inline
2151basic_string<_CharT, _Traits, _Allocator>&
2152basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str)
2153{
2154 return insert(__pos1, __str.data(), __str.size());
2155}
2156
2157template <class _CharT, class _Traits, class _Allocator>
2158basic_string<_CharT, _Traits, _Allocator>&
2159basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str,
2160 size_type __pos2, size_type __n)
2161{
2162 size_type __str_sz = __str.size();
2163 if (__pos2 > __str_sz)
2164 this->__throw_out_of_range();
2165 return insert(__pos1, __str.data() + __pos2, _STD::min(__n, __str_sz - __pos2));
2166}
2167
2168template <class _CharT, class _Traits, class _Allocator>
2169basic_string<_CharT, _Traits, _Allocator>&
2170basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const_pointer __s)
2171{
2172#ifdef _LIBCPP_DEBUG
2173 assert(__s != 0);
2174#endif
2175 return insert(__pos, __s, traits_type::length(__s));
2176}
2177
2178template <class _CharT, class _Traits, class _Allocator>
2179typename basic_string<_CharT, _Traits, _Allocator>::iterator
2180basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c)
2181{
2182 size_type __ip = static_cast<size_type>(__pos - begin());
2183 size_type __sz = size();
2184 size_type __cap = capacity();
2185 pointer __p;
2186 if (__cap == __sz)
2187 {
2188 __grow_by(__cap, 1, __sz, __ip, 0, 1);
2189 __p = __get_long_pointer();
2190 }
2191 else
2192 {
2193 __p = __get_pointer();
2194 size_type __n_move = __sz - __ip;
2195 if (__n_move != 0)
2196 traits_type::move(__p + __ip + 1, __p + __ip, __n_move);
2197 }
2198 traits_type::assign(__p[__ip], __c);
2199 traits_type::assign(__p[++__sz], value_type());
2200 __set_size(__sz);
2201 return begin() + static_cast<difference_type>(__ip);
2202}
2203
2204template <class _CharT, class _Traits, class _Allocator>
2205_LIBCPP_INLINE_VISIBILITY inline
2206typename basic_string<_CharT, _Traits, _Allocator>::iterator
2207basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, size_type __n, value_type __c)
2208{
2209 difference_type __p = __pos - begin();
2210 insert(static_cast<size_type>(__p), __n, __c);
2211 return begin() + __p;
2212}
2213
2214// replace
2215
2216template <class _CharT, class _Traits, class _Allocator>
2217basic_string<_CharT, _Traits, _Allocator>&
2218basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const_pointer __s, size_type __n2)
2219{
2220#ifdef _LIBCPP_DEBUG
2221 assert(__s != 0);
2222#endif
2223 size_type __sz = size();
2224 if (__pos > __sz)
2225 this->__throw_out_of_range();
2226 __n1 = _STD::min(__n1, __sz - __pos);
2227 size_type __cap = capacity();
2228 if (__cap - __sz + __n1 >= __n2)
2229 {
2230 pointer __p = __get_pointer();
2231 if (__n1 != __n2)
2232 {
2233 size_type __n_move = __sz - __pos - __n1;
2234 if (__n_move != 0)
2235 {
2236 if (__n1 > __n2)
2237 {
2238 traits_type::move(__p + __pos, __s, __n2);
2239 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
2240 goto __finish;
2241 }
2242 if (__p + __pos < __s && __s < __p + __sz)
2243 {
2244 if (__p + __pos + __n1 <= __s)
2245 __s += __n2 - __n1;
2246 else // __p + __pos < __s < __p + __pos + __n1
2247 {
2248 traits_type::move(__p + __pos, __s, __n1);
2249 __pos += __n1;
2250 __s += __n2;
2251 __n2 -= __n1;
2252 __n1 = 0;
2253 }
2254 }
2255 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
2256 }
2257 }
2258 traits_type::move(__p + __pos, __s, __n2);
2259__finish:
2260 __sz += __n2 - __n1;
2261 __set_size(__sz);
2262 __invalidate_iterators_past(__sz);
2263 traits_type::assign(__p[__sz], value_type());
2264 }
2265 else
2266 __grow_by_and_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2, __s);
2267 return *this;
2268}
2269
2270template <class _CharT, class _Traits, class _Allocator>
2271basic_string<_CharT, _Traits, _Allocator>&
2272basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, size_type __n2, value_type __c)
2273{
2274 size_type __sz = size();
2275 if (__pos > __sz)
2276 this->__throw_out_of_range();
2277 __n1 = _STD::min(__n1, __sz - __pos);
2278 size_type __cap = capacity();
2279 pointer __p;
2280 if (__cap - __sz + __n1 >= __n2)
2281 {
2282 __p = __get_pointer();
2283 if (__n1 != __n2)
2284 {
2285 size_type __n_move = __sz - __pos - __n1;
2286 if (__n_move != 0)
2287 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
2288 }
2289 }
2290 else
2291 {
2292 __grow_by(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2);
2293 __p = __get_long_pointer();
2294 }
2295 traits_type::assign(__p + __pos, __n2, __c);
2296 __sz += __n2 - __n1;
2297 __set_size(__sz);
2298 __invalidate_iterators_past(__sz);
2299 traits_type::assign(__p[__sz], value_type());
2300 return *this;
2301}
2302
2303template <class _CharT, class _Traits, class _Allocator>
2304template<class _InputIterator>
2305typename enable_if
2306<
2307 __is_input_iterator<_InputIterator>::value,
2308 basic_string<_CharT, _Traits, _Allocator>&
2309>::type
2310basic_string<_CharT, _Traits, _Allocator>::replace(iterator __i1, iterator __i2,
2311 _InputIterator __j1, _InputIterator __j2)
2312{
2313 for (; true; ++__i1, ++__j1)
2314 {
2315 if (__i1 == __i2)
2316 {
2317 if (__j1 != __j2)
2318 insert(__i1, __j1, __j2);
2319 break;
2320 }
2321 if (__j1 == __j2)
2322 {
2323 erase(__i1, __i2);
2324 break;
2325 }
2326 traits_type::assign(*__i1, *__j1);
2327 }
2328 return *this;
2329}
2330
2331template <class _CharT, class _Traits, class _Allocator>
2332_LIBCPP_INLINE_VISIBILITY inline
2333basic_string<_CharT, _Traits, _Allocator>&
2334basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str)
2335{
2336 return replace(__pos1, __n1, __str.data(), __str.size());
2337}
2338
2339template <class _CharT, class _Traits, class _Allocator>
2340basic_string<_CharT, _Traits, _Allocator>&
2341basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str,
2342 size_type __pos2, size_type __n2)
2343{
2344 size_type __str_sz = __str.size();
2345 if (__pos2 > __str_sz)
2346 this->__throw_out_of_range();
2347 return replace(__pos1, __n1, __str.data() + __pos2, _STD::min(__n2, __str_sz - __pos2));
2348}
2349
2350template <class _CharT, class _Traits, class _Allocator>
2351basic_string<_CharT, _Traits, _Allocator>&
2352basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const_pointer __s)
2353{
2354#ifdef _LIBCPP_DEBUG
2355 assert(__s != 0);
2356#endif
2357 return replace(__pos, __n1, __s, traits_type::length(__s));
2358}
2359
2360template <class _CharT, class _Traits, class _Allocator>
2361_LIBCPP_INLINE_VISIBILITY inline
2362basic_string<_CharT, _Traits, _Allocator>&
2363basic_string<_CharT, _Traits, _Allocator>::replace(iterator __i1, iterator __i2, const basic_string& __str)
2364{
2365 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1),
2366 __str.data(), __str.size());
2367}
2368
2369template <class _CharT, class _Traits, class _Allocator>
2370_LIBCPP_INLINE_VISIBILITY inline
2371basic_string<_CharT, _Traits, _Allocator>&
2372basic_string<_CharT, _Traits, _Allocator>::replace(iterator __i1, iterator __i2, const_pointer __s, size_type __n)
2373{
2374 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s, __n);
2375}
2376
2377template <class _CharT, class _Traits, class _Allocator>
2378_LIBCPP_INLINE_VISIBILITY inline
2379basic_string<_CharT, _Traits, _Allocator>&
2380basic_string<_CharT, _Traits, _Allocator>::replace(iterator __i1, iterator __i2, const_pointer __s)
2381{
2382 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s);
2383}
2384
2385template <class _CharT, class _Traits, class _Allocator>
2386_LIBCPP_INLINE_VISIBILITY inline
2387basic_string<_CharT, _Traits, _Allocator>&
2388basic_string<_CharT, _Traits, _Allocator>::replace(iterator __i1, iterator __i2, size_type __n, value_type __c)
2389{
2390 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __n, __c);
2391}
2392
2393// erase
2394
2395template <class _CharT, class _Traits, class _Allocator>
2396basic_string<_CharT, _Traits, _Allocator>&
2397basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, size_type __n)
2398{
2399 size_type __sz = size();
2400 if (__pos > __sz)
2401 this->__throw_out_of_range();
2402 if (__n)
2403 {
2404 pointer __p = __get_pointer();
2405 __n = _STD::min(__n, __sz - __pos);
2406 size_type __n_move = __sz - __pos - __n;
2407 if (__n_move != 0)
2408 traits_type::move(__p + __pos, __p + __pos + __n, __n_move);
2409 __sz -= __n;
2410 __set_size(__sz);
2411 __invalidate_iterators_past(__sz);
2412 traits_type::assign(__p[__sz], value_type());
2413 }
2414 return *this;
2415}
2416
2417template <class _CharT, class _Traits, class _Allocator>
2418_LIBCPP_INLINE_VISIBILITY inline
2419typename basic_string<_CharT, _Traits, _Allocator>::iterator
2420basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos)
2421{
2422 iterator __b = begin();
2423 size_type __r = static_cast<size_type>(__pos - __b);
2424 erase(__r, 1);
2425 return __b + __r;
2426}
2427
2428template <class _CharT, class _Traits, class _Allocator>
2429_LIBCPP_INLINE_VISIBILITY inline
2430typename basic_string<_CharT, _Traits, _Allocator>::iterator
2431basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last)
2432{
2433 iterator __b = begin();
2434 size_type __r = static_cast<size_type>(__first - __b);
2435 erase(__r, static_cast<size_type>(__last - __first));
2436 return __b + __r;
2437}
2438
2439template <class _CharT, class _Traits, class _Allocator>
2440_LIBCPP_INLINE_VISIBILITY inline
2441void
2442basic_string<_CharT, _Traits, _Allocator>::pop_back()
2443{
2444#ifdef _LIBCPP_DEBUG
2445 assert(!empty());
2446#endif
2447 size_type __sz;
2448 if (__is_long())
2449 {
2450 __sz = __get_long_size() - 1;
2451 __set_long_size(__sz);
2452 traits_type::assign(*(__get_long_pointer() + __sz), value_type());
2453 }
2454 else
2455 {
2456 __sz = __get_short_size() - 1;
2457 __set_short_size(__sz);
2458 traits_type::assign(*(__get_short_pointer() + __sz), value_type());
2459 }
2460 __invalidate_iterators_past(__sz);
2461}
2462
2463template <class _CharT, class _Traits, class _Allocator>
2464_LIBCPP_INLINE_VISIBILITY inline
2465void
2466basic_string<_CharT, _Traits, _Allocator>::clear()
2467{
2468 __invalidate_all_iterators();
2469 if (__is_long())
2470 {
2471 traits_type::assign(*__get_long_pointer(), value_type());
2472 __set_long_size(0);
2473 }
2474 else
2475 {
2476 traits_type::assign(*__get_short_pointer(), value_type());
2477 __set_short_size(0);
2478 }
2479}
2480
2481template <class _CharT, class _Traits, class _Allocator>
2482_LIBCPP_INLINE_VISIBILITY inline
2483void
2484basic_string<_CharT, _Traits, _Allocator>::__erase_to_end(size_type __pos)
2485{
2486 if (__is_long())
2487 {
2488 traits_type::assign(*(__get_long_pointer() + __pos), value_type());
2489 __set_long_size(__pos);
2490 }
2491 else
2492 {
2493 traits_type::assign(*(__get_short_pointer() + __pos), value_type());
2494 __set_short_size(__pos);
2495 }
2496 __invalidate_iterators_past(__pos);
2497}
2498
2499template <class _CharT, class _Traits, class _Allocator>
2500void
2501basic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c)
2502{
2503 size_type __sz = size();
2504 if (__n > __sz)
2505 append(__n - __sz, __c);
2506 else
2507 __erase_to_end(__n);
2508}
2509
2510template <class _CharT, class _Traits, class _Allocator>
2511_LIBCPP_INLINE_VISIBILITY inline
2512typename basic_string<_CharT, _Traits, _Allocator>::size_type
2513basic_string<_CharT, _Traits, _Allocator>::max_size() const
2514{
2515 size_type __m = __alloc().max_size();
2516#if _LIBCPP_BIG_ENDIAN
2517 return (__m <= ~__long_mask ? __m : __m/2) - 1;
2518#else
2519 return __m - 1;
2520#endif
2521}
2522
2523template <class _CharT, class _Traits, class _Allocator>
2524void
2525basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __res_arg)
2526{
2527 if (__res_arg > max_size())
2528 this->__throw_length_error();
2529 size_type __cap = capacity();
2530 size_type __sz = size();
2531 __res_arg = _STD::max(__res_arg, __sz);
2532 __res_arg = __recommend(__res_arg);
2533 if (__res_arg != __cap)
2534 {
2535 pointer __new_data, __p;
2536 bool __was_long, __now_long;
2537 if (__res_arg == __min_cap - 1)
2538 {
2539 __was_long = true;
2540 __now_long = false;
2541 __new_data = __get_short_pointer();
2542 __p = __get_long_pointer();
2543 }
2544 else
2545 {
2546 if (__res_arg > __cap)
2547 __new_data = __alloc().allocate(__res_arg+1);
2548 else
2549 {
2550 #ifndef _LIBCPP_NO_EXCEPTIONS
2551 try
2552 {
Howard Hinnant324bb032010-08-22 00:02:43 +00002553 #endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002554 __new_data = __alloc().allocate(__res_arg+1);
2555 #ifndef _LIBCPP_NO_EXCEPTIONS
2556 }
2557 catch (...)
2558 {
2559 return;
2560 }
Howard Hinnant324bb032010-08-22 00:02:43 +00002561 #else // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002562 if (__new_data == 0)
2563 return;
Howard Hinnant324bb032010-08-22 00:02:43 +00002564 #endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002565 }
2566 __now_long = true;
2567 __was_long = __is_long();
2568 __p = __get_pointer();
2569 }
2570 traits_type::copy(__new_data, __p, size()+1);
2571 if (__was_long)
2572 __alloc().deallocate(__p, __cap+1);
2573 if (__now_long)
2574 {
2575 __set_long_cap(__res_arg+1);
2576 __set_long_size(__sz);
2577 __set_long_pointer(__new_data);
2578 }
2579 else
2580 __set_short_size(__sz);
2581 __invalidate_all_iterators();
2582 }
2583}
2584
2585template <class _CharT, class _Traits, class _Allocator>
2586_LIBCPP_INLINE_VISIBILITY inline
2587typename basic_string<_CharT, _Traits, _Allocator>::const_reference
2588basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const
2589{
2590#ifdef __LIBCPP_DEBUG
2591 assert(__pos <= size());
2592#endif
2593 return *(data() + __pos);
2594}
2595
2596template <class _CharT, class _Traits, class _Allocator>
2597_LIBCPP_INLINE_VISIBILITY inline
2598typename basic_string<_CharT, _Traits, _Allocator>::reference
2599basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos)
2600{
2601#ifdef __LIBCPP_DEBUG
2602 assert(__pos < size());
2603#endif
2604 return *(__get_pointer() + __pos);
2605}
2606
2607template <class _CharT, class _Traits, class _Allocator>
2608typename basic_string<_CharT, _Traits, _Allocator>::const_reference
2609basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const
2610{
2611 if (__n >= size())
2612 this->__throw_out_of_range();
2613 return (*this)[__n];
2614}
2615
2616template <class _CharT, class _Traits, class _Allocator>
2617typename basic_string<_CharT, _Traits, _Allocator>::reference
2618basic_string<_CharT, _Traits, _Allocator>::at(size_type __n)
2619{
2620 if (__n >= size())
2621 this->__throw_out_of_range();
2622 return (*this)[__n];
2623}
2624
2625template <class _CharT, class _Traits, class _Allocator>
2626_LIBCPP_INLINE_VISIBILITY inline
2627typename basic_string<_CharT, _Traits, _Allocator>::reference
2628basic_string<_CharT, _Traits, _Allocator>::front()
2629{
2630#ifdef _LIBCPP_DEBUG
2631 assert(!empty());
2632#endif
2633 return *__get_pointer();
2634}
2635
2636template <class _CharT, class _Traits, class _Allocator>
2637_LIBCPP_INLINE_VISIBILITY inline
2638typename basic_string<_CharT, _Traits, _Allocator>::const_reference
2639basic_string<_CharT, _Traits, _Allocator>::front() const
2640{
2641#ifdef _LIBCPP_DEBUG
2642 assert(!empty());
2643#endif
2644 return *data();
2645}
2646
2647template <class _CharT, class _Traits, class _Allocator>
2648_LIBCPP_INLINE_VISIBILITY inline
2649typename basic_string<_CharT, _Traits, _Allocator>::reference
2650basic_string<_CharT, _Traits, _Allocator>::back()
2651{
2652#ifdef _LIBCPP_DEBUG
2653 assert(!empty());
2654#endif
2655 return *(__get_pointer() + size() - 1);
2656}
2657
2658template <class _CharT, class _Traits, class _Allocator>
2659_LIBCPP_INLINE_VISIBILITY inline
2660typename basic_string<_CharT, _Traits, _Allocator>::const_reference
2661basic_string<_CharT, _Traits, _Allocator>::back() const
2662{
2663#ifdef _LIBCPP_DEBUG
2664 assert(!empty());
2665#endif
2666 return *(data() + size() - 1);
2667}
2668
2669template <class _CharT, class _Traits, class _Allocator>
2670typename basic_string<_CharT, _Traits, _Allocator>::size_type
2671basic_string<_CharT, _Traits, _Allocator>::copy(pointer __s, size_type __n, size_type __pos) const
2672{
2673 size_type __sz = size();
2674 if (__pos > __sz)
2675 this->__throw_out_of_range();
2676 size_type __rlen = _STD::min(__n, __sz - __pos);
2677 traits_type::copy(__s, data() + __pos, __rlen);
2678 return __rlen;
2679}
2680
2681template <class _CharT, class _Traits, class _Allocator>
2682_LIBCPP_INLINE_VISIBILITY inline
2683basic_string<_CharT, _Traits, _Allocator>
2684basic_string<_CharT, _Traits, _Allocator>::substr(size_type __pos, size_type __n) const
2685{
2686 return basic_string(*this, __pos, __n, __alloc());
2687}
2688
2689template <class _CharT, class _Traits, class _Allocator>
2690_LIBCPP_INLINE_VISIBILITY inline
2691void
2692basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str)
2693{
2694 __r_.swap(__str.__r_);
2695#ifdef _LIBCPP_DEBUG
2696 __invalidate_all_iterators();
2697 __str.__invalidate_all_iterators();
Howard Hinnant324bb032010-08-22 00:02:43 +00002698#endif // _LIBCPP_DEBUG
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002699}
2700
2701// find
2702
2703template <class _Traits>
2704struct _LIBCPP_HIDDEN __traits_eq
2705{
2706 typedef typename _Traits::char_type char_type;
2707 _LIBCPP_INLINE_VISIBILITY bool operator()(const char_type& __x, const char_type& __y) {return _Traits::eq(__x, __y);}
2708};
2709
2710template<class _CharT, class _Traits, class _Allocator>
2711typename basic_string<_CharT, _Traits, _Allocator>::size_type
2712basic_string<_CharT, _Traits, _Allocator>::find(const_pointer __s, size_type __pos, size_type __n) const
2713{
2714#ifdef _LIBCPP_DEBUG
2715 assert(__s != 0);
2716#endif
2717 size_type __sz = size();
2718 if (__pos > __sz || __sz - __pos < __n)
2719 return npos;
2720 if (__n == 0)
2721 return __pos;
2722 const_pointer __p = data();
2723 const_pointer __r = _STD::search(__p + __pos, __p + __sz, __s, __s + __n, __traits_eq<traits_type>());
2724 if (__r == __p + __sz)
2725 return npos;
2726 return static_cast<size_type>(__r - __p);
2727}
2728
2729template<class _CharT, class _Traits, class _Allocator>
2730_LIBCPP_INLINE_VISIBILITY inline
2731typename basic_string<_CharT, _Traits, _Allocator>::size_type
2732basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str, size_type __pos) const
2733{
2734 return find(__str.data(), __pos, __str.size());
2735}
2736
2737template<class _CharT, class _Traits, class _Allocator>
2738_LIBCPP_INLINE_VISIBILITY inline
2739typename basic_string<_CharT, _Traits, _Allocator>::size_type
2740basic_string<_CharT, _Traits, _Allocator>::find(const_pointer __s, size_type __pos) const
2741{
2742#ifdef _LIBCPP_DEBUG
2743 assert(__s != 0);
2744#endif
2745 return find(__s, __pos, traits_type::length(__s));
2746}
2747
2748template<class _CharT, class _Traits, class _Allocator>
2749typename basic_string<_CharT, _Traits, _Allocator>::size_type
2750basic_string<_CharT, _Traits, _Allocator>::find(value_type __c, size_type __pos) const
2751{
2752 size_type __sz = size();
2753 if (__pos >= __sz)
2754 return npos;
2755 const_pointer __p = data();
2756 const_pointer __r = traits_type::find(__p + __pos, __sz - __pos, __c);
2757 if (__r == 0)
2758 return npos;
2759 return static_cast<size_type>(__r - __p);
2760}
2761
2762// rfind
2763
2764template<class _CharT, class _Traits, class _Allocator>
2765typename basic_string<_CharT, _Traits, _Allocator>::size_type
2766basic_string<_CharT, _Traits, _Allocator>::rfind(const_pointer __s, size_type __pos, size_type __n) const
2767{
2768#ifdef _LIBCPP_DEBUG
2769 assert(__s != 0);
2770#endif
2771 size_type __sz = size();
2772 __pos = _STD::min(__pos, __sz);
2773 if (__n < __sz - __pos)
2774 __pos += __n;
2775 else
2776 __pos = __sz;
2777 const_pointer __p = data();
2778 const_pointer __r = _STD::find_end(__p, __p + __pos, __s, __s + __n, __traits_eq<traits_type>());
2779 if (__n > 0 && __r == __p + __pos)
2780 return npos;
2781 return static_cast<size_type>(__r - __p);
2782}
2783
2784template<class _CharT, class _Traits, class _Allocator>
2785_LIBCPP_INLINE_VISIBILITY inline
2786typename basic_string<_CharT, _Traits, _Allocator>::size_type
2787basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str, size_type __pos) const
2788{
2789 return rfind(__str.data(), __pos, __str.size());
2790}
2791
2792template<class _CharT, class _Traits, class _Allocator>
2793_LIBCPP_INLINE_VISIBILITY inline
2794typename basic_string<_CharT, _Traits, _Allocator>::size_type
2795basic_string<_CharT, _Traits, _Allocator>::rfind(const_pointer __s, size_type __pos) const
2796{
2797#ifdef _LIBCPP_DEBUG
2798 assert(__s != 0);
2799#endif
2800 return rfind(__s, __pos, traits_type::length(__s));
2801}
2802
2803template<class _CharT, class _Traits, class _Allocator>
2804typename basic_string<_CharT, _Traits, _Allocator>::size_type
2805basic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c, size_type __pos) const
2806{
2807 size_type __sz = size();
2808 if (__sz)
2809 {
2810 if (__pos < __sz)
2811 ++__pos;
2812 else
2813 __pos = __sz;
2814 const_pointer __p = data();
2815 for (const_pointer __ps = __p + __pos; __ps != __p;)
2816 {
2817 if (traits_type::eq(*--__ps, __c))
2818 return static_cast<size_type>(__ps - __p);
2819 }
2820 }
2821 return npos;
2822}
2823
2824// find_first_of
2825
2826template<class _CharT, class _Traits, class _Allocator>
2827typename basic_string<_CharT, _Traits, _Allocator>::size_type
2828basic_string<_CharT, _Traits, _Allocator>::find_first_of(const_pointer __s, size_type __pos, size_type __n) const
2829{
2830#ifdef _LIBCPP_DEBUG
2831 assert(__s != 0);
2832#endif
2833 size_type __sz = size();
2834 if (__pos >= __sz || __n == 0)
2835 return npos;
2836 const_pointer __p = data();
2837 const_pointer __r = _STD::find_first_of(__p + __pos, __p + __sz, __s, __s + __n, __traits_eq<traits_type>());
2838 if (__r == __p + __sz)
2839 return npos;
2840 return static_cast<size_type>(__r - __p);
2841}
2842
2843template<class _CharT, class _Traits, class _Allocator>
2844_LIBCPP_INLINE_VISIBILITY inline
2845typename basic_string<_CharT, _Traits, _Allocator>::size_type
2846basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str, size_type __pos) const
2847{
2848 return find_first_of(__str.data(), __pos, __str.size());
2849}
2850
2851template<class _CharT, class _Traits, class _Allocator>
2852_LIBCPP_INLINE_VISIBILITY inline
2853typename basic_string<_CharT, _Traits, _Allocator>::size_type
2854basic_string<_CharT, _Traits, _Allocator>::find_first_of(const_pointer __s, size_type __pos) const
2855{
2856#ifdef _LIBCPP_DEBUG
2857 assert(__s != 0);
2858#endif
2859 return find_first_of(__s, __pos, traits_type::length(__s));
2860}
2861
2862template<class _CharT, class _Traits, class _Allocator>
2863_LIBCPP_INLINE_VISIBILITY inline
2864typename basic_string<_CharT, _Traits, _Allocator>::size_type
2865basic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c, size_type __pos) const
2866{
2867 return find(__c, __pos);
2868}
2869
2870// find_last_of
2871
2872template<class _CharT, class _Traits, class _Allocator>
2873typename basic_string<_CharT, _Traits, _Allocator>::size_type
2874basic_string<_CharT, _Traits, _Allocator>::find_last_of(const_pointer __s, size_type __pos, size_type __n) const
2875{
2876#ifdef _LIBCPP_DEBUG
2877 assert(__s != 0);
2878#endif
2879 if (__n != 0)
2880 {
2881 size_type __sz = size();
2882 if (__pos < __sz)
2883 ++__pos;
2884 else
2885 __pos = __sz;
2886 const_pointer __p = data();
2887 for (const_pointer __ps = __p + __pos; __ps != __p;)
2888 {
2889 const_pointer __r = traits_type::find(__s, __n, *--__ps);
2890 if (__r)
2891 return static_cast<size_type>(__ps - __p);
2892 }
2893 }
2894 return npos;
2895}
2896
2897template<class _CharT, class _Traits, class _Allocator>
2898_LIBCPP_INLINE_VISIBILITY inline
2899typename basic_string<_CharT, _Traits, _Allocator>::size_type
2900basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str, size_type __pos) const
2901{
2902 return find_last_of(__str.data(), __pos, __str.size());
2903}
2904
2905template<class _CharT, class _Traits, class _Allocator>
2906_LIBCPP_INLINE_VISIBILITY inline
2907typename basic_string<_CharT, _Traits, _Allocator>::size_type
2908basic_string<_CharT, _Traits, _Allocator>::find_last_of(const_pointer __s, size_type __pos) const
2909{
2910#ifdef _LIBCPP_DEBUG
2911 assert(__s != 0);
2912#endif
2913 return find_last_of(__s, __pos, traits_type::length(__s));
2914}
2915
2916template<class _CharT, class _Traits, class _Allocator>
2917_LIBCPP_INLINE_VISIBILITY inline
2918typename basic_string<_CharT, _Traits, _Allocator>::size_type
2919basic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c, size_type __pos) const
2920{
2921 return rfind(__c, __pos);
2922}
2923
2924// find_first_not_of
2925
2926template<class _CharT, class _Traits, class _Allocator>
2927typename basic_string<_CharT, _Traits, _Allocator>::size_type
2928basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const_pointer __s, size_type __pos, size_type __n) const
2929{
2930#ifdef _LIBCPP_DEBUG
2931 assert(__s != 0);
2932#endif
2933 size_type __sz = size();
2934 if (__pos < __sz)
2935 {
2936 const_pointer __p = data();
2937 const_pointer __pe = __p + __sz;
2938 for (const_pointer __ps = __p + __pos; __ps != __pe; ++__ps)
2939 if (traits_type::find(__s, __n, *__ps) == 0)
2940 return static_cast<size_type>(__ps - __p);
2941 }
2942 return npos;
2943}
2944
2945template<class _CharT, class _Traits, class _Allocator>
2946_LIBCPP_INLINE_VISIBILITY inline
2947typename basic_string<_CharT, _Traits, _Allocator>::size_type
2948basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string& __str, size_type __pos) const
2949{
2950 return find_first_not_of(__str.data(), __pos, __str.size());
2951}
2952
2953template<class _CharT, class _Traits, class _Allocator>
2954_LIBCPP_INLINE_VISIBILITY inline
2955typename basic_string<_CharT, _Traits, _Allocator>::size_type
2956basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const_pointer __s, size_type __pos) const
2957{
2958#ifdef _LIBCPP_DEBUG
2959 assert(__s != 0);
2960#endif
2961 return find_first_not_of(__s, __pos, traits_type::length(__s));
2962}
2963
2964template<class _CharT, class _Traits, class _Allocator>
2965_LIBCPP_INLINE_VISIBILITY inline
2966typename basic_string<_CharT, _Traits, _Allocator>::size_type
2967basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c, size_type __pos) const
2968{
2969 size_type __sz = size();
2970 if (__pos < __sz)
2971 {
2972 const_pointer __p = data();
2973 const_pointer __pe = __p + __sz;
2974 for (const_pointer __ps = __p + __pos; __p != __pe; ++__ps)
2975 if (!traits_type::eq(*__ps, __c))
2976 return static_cast<size_type>(__ps - __p);
2977 }
2978 return npos;
2979}
2980
2981// find_last_not_of
2982
2983template<class _CharT, class _Traits, class _Allocator>
2984typename basic_string<_CharT, _Traits, _Allocator>::size_type
2985basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const_pointer __s, size_type __pos, size_type __n) const
2986{
2987#ifdef _LIBCPP_DEBUG
2988 assert(__s != 0);
2989#endif
2990 size_type __sz = size();
2991 if (__pos < __sz)
2992 ++__pos;
2993 else
2994 __pos = __sz;
2995 const_pointer __p = data();
2996 for (const_pointer __ps = __p + __pos; __ps != __p;)
2997 if (traits_type::find(__s, __n, *--__ps) == 0)
2998 return static_cast<size_type>(__ps - __p);
2999 return npos;
3000}
3001
3002template<class _CharT, class _Traits, class _Allocator>
3003_LIBCPP_INLINE_VISIBILITY inline
3004typename basic_string<_CharT, _Traits, _Allocator>::size_type
3005basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string& __str, size_type __pos) const
3006{
3007 return find_last_not_of(__str.data(), __pos, __str.size());
3008}
3009
3010template<class _CharT, class _Traits, class _Allocator>
3011_LIBCPP_INLINE_VISIBILITY inline
3012typename basic_string<_CharT, _Traits, _Allocator>::size_type
3013basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const_pointer __s, size_type __pos) const
3014{
3015#ifdef _LIBCPP_DEBUG
3016 assert(__s != 0);
3017#endif
3018 return find_last_not_of(__s, __pos, traits_type::length(__s));
3019}
3020
3021template<class _CharT, class _Traits, class _Allocator>
3022_LIBCPP_INLINE_VISIBILITY inline
3023typename basic_string<_CharT, _Traits, _Allocator>::size_type
3024basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c, size_type __pos) const
3025{
3026 size_type __sz = size();
3027 if (__pos < __sz)
3028 ++__pos;
3029 else
3030 __pos = __sz;
3031 const_pointer __p = data();
3032 for (const_pointer __ps = __p + __pos; __ps != __p;)
3033 if (!traits_type::eq(*--__ps, __c))
3034 return static_cast<size_type>(__ps - __p);
3035 return npos;
3036}
3037
3038// compare
3039
3040template <class _CharT, class _Traits, class _Allocator>
3041_LIBCPP_INLINE_VISIBILITY inline
3042int
3043basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const
3044{
3045 return compare(0, npos, __str.data(), __str.size());
3046}
3047
3048template <class _CharT, class _Traits, class _Allocator>
3049_LIBCPP_INLINE_VISIBILITY inline
3050int
3051basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, const basic_string& __str) const
3052{
3053 return compare(__pos1, __n1, __str.data(), __str.size());
3054}
3055
3056template <class _CharT, class _Traits, class _Allocator>
3057int
3058basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, const basic_string& __str,
3059 size_type __pos2, size_type __n2) const
3060{
3061 size_type __sz = __str.size();
3062 if (__pos2 > __sz)
3063 this->__throw_out_of_range();
3064 return compare(__pos1, __n1, __str.data() + __pos2, _STD::min(__n2, __sz - __pos2));
3065}
3066
3067template <class _CharT, class _Traits, class _Allocator>
3068int
3069basic_string<_CharT, _Traits, _Allocator>::compare(const_pointer __s) const
3070{
3071#ifdef _LIBCPP_DEBUG
3072 assert(__s != 0);
3073#endif
3074 return compare(0, npos, __s, traits_type::length(__s));
3075}
3076
3077template <class _CharT, class _Traits, class _Allocator>
3078int
3079basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, const_pointer __s) const
3080{
3081#ifdef _LIBCPP_DEBUG
3082 assert(__s != 0);
3083#endif
3084 return compare(__pos1, __n1, __s, traits_type::length(__s));
3085}
3086
3087template <class _CharT, class _Traits, class _Allocator>
3088int
3089basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1,
3090 const_pointer __s, size_type __n2) const
3091{
3092#ifdef _LIBCPP_DEBUG
3093 assert(__s != 0);
3094#endif
3095 size_type __sz = size();
3096 if (__pos1 > __sz || __n2 == npos)
3097 this->__throw_out_of_range();
3098 size_type __rlen = _STD::min(__n1, __sz - __pos1);
3099 int __r = traits_type::compare(data() + __pos1, __s, _STD::min(__rlen, __n2));
3100 if (__r == 0)
3101 {
3102 if (__rlen < __n2)
3103 __r = -1;
3104 else if (__rlen > __n2)
3105 __r = 1;
3106 }
3107 return __r;
3108}
3109
3110// __invariants
3111
3112template<class _CharT, class _Traits, class _Allocator>
3113bool
3114basic_string<_CharT, _Traits, _Allocator>::__invariants() const
3115{
3116 if (size() > capacity())
3117 return false;
3118 if (capacity() < __min_cap - 1)
3119 return false;
3120 if (data() == 0)
3121 return false;
3122 if (data()[size()] != value_type(0))
3123 return false;
3124 return true;
3125}
3126
3127// operator==
3128
3129template<class _CharT, class _Traits, class _Allocator>
3130_LIBCPP_INLINE_VISIBILITY inline
3131bool
3132operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3133 const basic_string<_CharT, _Traits, _Allocator>& __rhs)
3134{
3135 return __lhs.size() == __rhs.size() && _Traits::compare(__lhs.data(), __rhs.data(), __lhs.size()) == 0;
3136}
3137
3138template<class _CharT, class _Traits, class _Allocator>
3139_LIBCPP_INLINE_VISIBILITY inline
3140bool
3141operator==(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs)
3142{
3143 return __rhs.compare(__lhs) == 0;
3144}
3145
3146template<class _Allocator>
3147_LIBCPP_INLINE_VISIBILITY inline
3148bool
3149operator==(const char* __lhs, const basic_string<char, char_traits<char>, _Allocator>& __rhs)
3150{
3151 return strcmp(__lhs, __rhs.data()) == 0;
3152}
3153
3154template<class _Allocator>
3155_LIBCPP_INLINE_VISIBILITY inline
3156bool
3157operator==(const wchar_t* __lhs, const basic_string<wchar_t, char_traits<wchar_t>, _Allocator>& __rhs)
3158{
3159 return wcscmp(__lhs, __rhs.data()) == 0;
3160}
3161
3162template<class _CharT, class _Traits, class _Allocator>
3163_LIBCPP_INLINE_VISIBILITY inline
3164bool
3165operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, const _CharT* __rhs)
3166{
3167 return __lhs.compare(__rhs) == 0;
3168}
3169
3170template<class _Allocator>
3171_LIBCPP_INLINE_VISIBILITY inline
3172bool
3173operator==(const basic_string<char, char_traits<char>, _Allocator>& __lhs, const char* __rhs)
3174{
3175 return strcmp(__lhs.data(), __rhs) == 0;
3176}
3177
3178template<class _Allocator>
3179_LIBCPP_INLINE_VISIBILITY inline
3180bool
3181operator==(const basic_string<wchar_t, char_traits<wchar_t>, _Allocator>& __lhs, const wchar_t* __rhs)
3182{
3183 return wcscmp(__lhs.data(), __rhs) == 0;
3184}
3185
3186// operator!=
3187
Howard Hinnant324bb032010-08-22 00:02:43 +00003188template<class _CharT, class _Traits, class _Allocator>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003189_LIBCPP_INLINE_VISIBILITY inline
3190bool
3191operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
3192 const basic_string<_CharT, _Traits, _Allocator>& __rhs)
3193{
3194 return !(__lhs == __rhs);
3195}
3196
3197template<class _CharT, class _Traits, class _Allocator>
3198_LIBCPP_INLINE_VISIBILITY inline
3199bool
3200operator!=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs)
3201{
3202 return !(__lhs == __rhs);
3203}
3204
3205template<class _CharT, class _Traits, class _Allocator>
3206_LIBCPP_INLINE_VISIBILITY inline
3207bool
3208operator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs)
3209{
3210 return !(__lhs == __rhs);
3211}
3212
3213// operator<
3214
3215template<class _CharT, class _Traits, class _Allocator>
3216_LIBCPP_INLINE_VISIBILITY inline
3217bool
3218operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3219 const basic_string<_CharT, _Traits, _Allocator>& __rhs)
3220{
3221 return __lhs.cmpare(__rhs) < 0;
3222}
3223
3224template<class _Allocator>
3225_LIBCPP_INLINE_VISIBILITY inline
3226bool
3227operator< (const basic_string<char, char_traits<char>, _Allocator>& __lhs,
3228 const basic_string<char, char_traits<char>, _Allocator>& __rhs)
3229{
3230 return strcmp(__lhs.data(), __rhs.data()) < 0;
3231}
3232
3233template<class _Allocator>
3234_LIBCPP_INLINE_VISIBILITY inline
3235bool
3236operator< (const basic_string<wchar_t, char_traits<wchar_t>, _Allocator>& __lhs,
3237 const basic_string<wchar_t, char_traits<wchar_t>, _Allocator>& __rhs)
3238{
3239 return wcscmp(__lhs.data(), __rhs.data()) < 0;
3240}
3241
3242template<class _CharT, class _Traits, class _Allocator>
3243_LIBCPP_INLINE_VISIBILITY inline
3244bool
3245operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs)
3246{
3247 return __lhs.compare(__rhs);
3248}
3249
3250template<class _Allocator>
3251_LIBCPP_INLINE_VISIBILITY inline
3252bool
3253operator< (const basic_string<char, char_traits<char>, _Allocator>& __lhs, const char* __rhs)
3254{
3255 return strcmp(__lhs.data(), __rhs) < 0;
3256}
3257
3258template<class _Allocator>
3259_LIBCPP_INLINE_VISIBILITY inline
3260bool
3261operator< (const basic_string<wchar_t, char_traits<wchar_t>, _Allocator>& __lhs, const wchar_t* __rhs)
3262{
3263 return wcscmp(__lhs.data(), __rhs) < 0;
3264}
3265
3266template<class _CharT, class _Traits, class _Allocator>
3267_LIBCPP_INLINE_VISIBILITY inline
3268bool
3269operator< (const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs)
3270{
3271 return __rhs.compare(__lhs) > 0;
3272}
3273
3274template<class _Allocator>
3275_LIBCPP_INLINE_VISIBILITY inline
3276bool
3277operator< (const char* __lhs, const basic_string<char, char_traits<char>, _Allocator>& __rhs)
3278{
3279 return strcmp(__lhs, __rhs.data()) < 0;
3280}
3281
3282template<class _Allocator>
3283_LIBCPP_INLINE_VISIBILITY inline
3284bool
3285operator< (const wchar_t* __lhs, const basic_string<wchar_t, char_traits<wchar_t>, _Allocator>& __rhs)
3286{
3287 return wcscmp(__lhs, __rhs.data()) < 0;
3288}
3289
3290// operator>
3291
3292template<class _CharT, class _Traits, class _Allocator>
3293_LIBCPP_INLINE_VISIBILITY inline
3294bool
3295operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3296 const basic_string<_CharT, _Traits, _Allocator>& __rhs)
3297{
3298 return __rhs < __lhs;
3299}
3300
3301template<class _CharT, class _Traits, class _Allocator>
3302_LIBCPP_INLINE_VISIBILITY inline
3303bool
3304operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs)
3305{
3306 return __rhs < __lhs;
3307}
3308
3309template<class _CharT, class _Traits, class _Allocator>
3310_LIBCPP_INLINE_VISIBILITY inline
3311bool
3312operator> (const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs)
3313{
3314 return __rhs < __lhs;
3315}
3316
3317// operator<=
3318
3319template<class _CharT, class _Traits, class _Allocator>
3320_LIBCPP_INLINE_VISIBILITY inline
3321bool
3322operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3323 const basic_string<_CharT, _Traits, _Allocator>& __rhs)
3324{
3325 return !(__rhs < __lhs);
3326}
3327
3328template<class _CharT, class _Traits, class _Allocator>
3329_LIBCPP_INLINE_VISIBILITY inline
3330bool
3331operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs)
3332{
3333 return !(__rhs < __lhs);
3334}
3335
3336template<class _CharT, class _Traits, class _Allocator>
3337_LIBCPP_INLINE_VISIBILITY inline
3338bool
3339operator<=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs)
3340{
3341 return !(__rhs < __lhs);
3342}
3343
3344// operator>=
3345
3346template<class _CharT, class _Traits, class _Allocator>
3347_LIBCPP_INLINE_VISIBILITY inline
3348bool
3349operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3350 const basic_string<_CharT, _Traits, _Allocator>& __rhs)
3351{
3352 return !(__lhs < __rhs);
3353}
3354
3355template<class _CharT, class _Traits, class _Allocator>
3356_LIBCPP_INLINE_VISIBILITY inline
3357bool
3358operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs)
3359{
3360 return !(__lhs < __rhs);
3361}
3362
3363template<class _CharT, class _Traits, class _Allocator>
3364_LIBCPP_INLINE_VISIBILITY inline
3365bool
3366operator>=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs)
3367{
3368 return !(__lhs < __rhs);
3369}
3370
3371// operator +
3372
3373template<class _CharT, class _Traits, class _Allocator>
3374basic_string<_CharT, _Traits, _Allocator>
3375operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3376 const basic_string<_CharT, _Traits, _Allocator>& __rhs)
3377{
3378 basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator());
3379 typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size();
3380 typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size();
3381 __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + __rhs_sz);
3382 __r.append(__rhs.data(), __rhs_sz);
3383 return __r;
3384}
3385
3386template<class _CharT, class _Traits, class _Allocator>
3387basic_string<_CharT, _Traits, _Allocator>
3388operator+(const _CharT* __lhs , const basic_string<_CharT,_Traits,_Allocator>& __rhs)
3389{
3390 basic_string<_CharT, _Traits, _Allocator> __r(__rhs.get_allocator());
3391 typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = _Traits::length(__lhs);
3392 typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size();
3393 __r.__init(__lhs, __lhs_sz, __lhs_sz + __rhs_sz);
3394 __r.append(__rhs.data(), __rhs_sz);
3395 return __r;
3396}
3397
3398template<class _CharT, class _Traits, class _Allocator>
3399basic_string<_CharT, _Traits, _Allocator>
3400operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Allocator>& __rhs)
3401{
3402 basic_string<_CharT, _Traits, _Allocator> __r(__rhs.get_allocator());
3403 typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size();
3404 __r.__init(&__lhs, 1, 1 + __rhs_sz);
3405 __r.append(__rhs.data(), __rhs_sz);
3406 return __r;
3407}
3408
3409template<class _CharT, class _Traits, class _Allocator>
3410basic_string<_CharT, _Traits, _Allocator>
3411operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs)
3412{
3413 basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator());
3414 typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size();
3415 typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = _Traits::length(__rhs);
3416 __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + __rhs_sz);
3417 __r.append(__rhs, __rhs_sz);
3418 return __r;
3419}
3420
3421template<class _CharT, class _Traits, class _Allocator>
3422basic_string<_CharT, _Traits, _Allocator>
3423operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs)
3424{
3425 basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator());
3426 typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size();
3427 __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + 1);
3428 __r.push_back(__rhs);
3429 return __r;
3430}
3431
Howard Hinnant73d21a42010-09-04 23:28:19 +00003432#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003433
3434template<class _CharT, class _Traits, class _Allocator>
3435_LIBCPP_INLINE_VISIBILITY inline
3436basic_string<_CharT, _Traits, _Allocator>
3437operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs)
3438{
3439 return _STD::move(__lhs.append(__rhs));
3440}
3441
3442template<class _CharT, class _Traits, class _Allocator>
3443_LIBCPP_INLINE_VISIBILITY inline
3444basic_string<_CharT, _Traits, _Allocator>
3445operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs)
3446{
3447 return _STD::move(__rhs.insert(0, __lhs));
3448}
3449
3450template<class _CharT, class _Traits, class _Allocator>
3451_LIBCPP_INLINE_VISIBILITY inline
3452basic_string<_CharT, _Traits, _Allocator>
3453operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs)
3454{
3455 return _STD::move(__lhs.append(__rhs));
3456}
3457
3458template<class _CharT, class _Traits, class _Allocator>
3459_LIBCPP_INLINE_VISIBILITY inline
3460basic_string<_CharT, _Traits, _Allocator>
3461operator+(const _CharT* __lhs , basic_string<_CharT,_Traits,_Allocator>&& __rhs)
3462{
3463 return _STD::move(__rhs.insert(0, __lhs));
3464}
3465
3466template<class _CharT, class _Traits, class _Allocator>
3467_LIBCPP_INLINE_VISIBILITY inline
3468basic_string<_CharT, _Traits, _Allocator>
3469operator+(_CharT __lhs, basic_string<_CharT,_Traits,_Allocator>&& __rhs)
3470{
3471 __rhs.insert(__rhs.begin(), __lhs);
3472 return _STD::move(__rhs);
3473}
3474
3475template<class _CharT, class _Traits, class _Allocator>
3476_LIBCPP_INLINE_VISIBILITY inline
3477basic_string<_CharT, _Traits, _Allocator>
3478operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const _CharT* __rhs)
3479{
3480 return _STD::move(__lhs.append(__rhs));
3481}
3482
3483template<class _CharT, class _Traits, class _Allocator>
3484_LIBCPP_INLINE_VISIBILITY inline
3485basic_string<_CharT, _Traits, _Allocator>
3486operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT __rhs)
3487{
3488 __lhs.push_back(__rhs);
3489 return _STD::move(__lhs);
3490}
3491
Howard Hinnant73d21a42010-09-04 23:28:19 +00003492#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003493
3494// swap
3495
3496template<class _CharT, class _Traits, class _Allocator>
3497_LIBCPP_INLINE_VISIBILITY inline
3498void
3499swap(basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>& __rhs)
3500{
3501 __lhs.swap(__rhs);
3502}
3503
3504template<class _CharT, class _Traits, class _Allocator>
3505struct __is_zero_default_constructible<basic_string<_CharT, _Traits, _Allocator> >
3506 : public integral_constant<bool, __is_zero_default_constructible<_Allocator>::value> {};
3507
3508#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
3509
3510typedef basic_string<char16_t> u16string;
3511typedef basic_string<char32_t> u32string;
3512
Howard Hinnant324bb032010-08-22 00:02:43 +00003513#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003514
Howard Hinnanta6a062d2010-06-02 18:20:39 +00003515int stoi (const string& __str, size_t* __idx = 0, int __base = 10);
3516long stol (const string& __str, size_t* __idx = 0, int __base = 10);
3517unsigned long stoul (const string& __str, size_t* __idx = 0, int __base = 10);
3518long long stoll (const string& __str, size_t* __idx = 0, int __base = 10);
3519unsigned long long stoull(const string& __str, size_t* __idx = 0, int __base = 10);
3520
3521float stof (const string& __str, size_t* __idx = 0);
3522double stod (const string& __str, size_t* __idx = 0);
3523long double stold(const string& __str, size_t* __idx = 0);
3524
3525string to_string(int __val);
3526string to_string(unsigned __val);
3527string to_string(long __val);
3528string to_string(unsigned long __val);
3529string to_string(long long __val);
3530string to_string(unsigned long long __val);
3531string to_string(float __val);
3532string to_string(double __val);
3533string to_string(long double __val);
3534
3535int stoi (const wstring& __str, size_t* __idx = 0, int __base = 10);
3536long stol (const wstring& __str, size_t* __idx = 0, int __base = 10);
3537unsigned long stoul (const wstring& __str, size_t* __idx = 0, int __base = 10);
3538long long stoll (const wstring& __str, size_t* __idx = 0, int __base = 10);
3539unsigned long long stoull(const wstring& __str, size_t* __idx = 0, int __base = 10);
3540
3541float stof (const wstring& __str, size_t* __idx = 0);
3542double stod (const wstring& __str, size_t* __idx = 0);
3543long double stold(const wstring& __str, size_t* __idx = 0);
3544
3545wstring to_wstring(int __val);
3546wstring to_wstring(unsigned __val);
3547wstring to_wstring(long __val);
3548wstring to_wstring(unsigned long __val);
3549wstring to_wstring(long long __val);
3550wstring to_wstring(unsigned long long __val);
3551wstring to_wstring(float __val);
3552wstring to_wstring(double __val);
3553wstring to_wstring(long double __val);
3554
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003555template<class _CharT, class _Traits, class _Allocator>
3556 const typename basic_string<_CharT, _Traits, _Allocator>::size_type
3557 basic_string<_CharT, _Traits, _Allocator>::npos;
3558
3559template<class _CharT, class _Traits, class _Allocator>
Howard Hinnant8d7a9552010-09-23 17:31:07 +00003560struct _LIBCPP_VISIBLE hash<basic_string<_CharT, _Traits, _Allocator> >
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00003561 : public unary_function<basic_string<_CharT, _Traits, _Allocator>, size_t>
3562{
3563 size_t
3564 operator()(const basic_string<_CharT, _Traits, _Allocator>& __val) const;
3565};
3566
3567template<class _CharT, class _Traits, class _Allocator>
3568size_t
3569hash<basic_string<_CharT, _Traits, _Allocator> >::operator()(
3570 const basic_string<_CharT, _Traits, _Allocator>& __val) const
3571{
3572 typedef basic_string<_CharT, _Traits, _Allocator> S;
3573 typedef typename S::const_pointer const_pointer;
3574 size_t __r = 0;
3575 const size_t __sr = __CHAR_BIT__ * sizeof(size_t) - 8;
3576 const size_t __m = size_t(0xF) << (__sr + 4);
3577 const_pointer __p = __val.data();
3578 const_pointer __e = __p + __val.size();
3579 for (; __p != __e; ++__p)
3580 {
3581 __r = (__r << 4) + *__p;
3582 size_t __g = __r & __m;
3583 __r ^= __g | (__g >> __sr);
3584 }
3585 return __r;
3586}
3587
3588extern template class basic_string<char>;
3589extern template class basic_string<wchar_t>;
3590
3591extern template
3592 enable_if<__is_forward_iterator<char const*>::value, void>::type
3593 basic_string<char, char_traits<char>, allocator<char> >::
3594 __init<char const*>(char const*, char const*);
3595
3596extern template
3597 enable_if<__is_forward_iterator<wchar_t const*>::value, void>::type
3598 basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> >::
3599 __init<wchar_t const*>(wchar_t const*, wchar_t const*);
3600
3601extern template
3602 enable_if<__is_forward_iterator<char*>::value,
3603 basic_string<char, char_traits<char>, allocator<char> >&>::type
3604 basic_string<char, char_traits<char>, allocator<char> >::
3605 append<char*>(char*, char*);
3606
3607extern template
3608 enable_if<__is_forward_iterator<wchar_t*>::value,
3609 basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> >&>::type
3610 basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> >::
3611 append<wchar_t*>(wchar_t*, wchar_t*);
3612
3613extern template
3614 enable_if<__is_forward_iterator<char const*>::value,
3615 string::iterator>::type
3616 string::
3617 insert<char const*>(string::const_iterator, char const*, char const*);
3618
3619extern template
3620 enable_if<__is_forward_iterator<wchar_t const*>::value,
3621 wstring::iterator>::type
3622 wstring::
3623 insert<wchar_t const*>(wstring::const_iterator, wchar_t const*, wchar_t const*);
3624
3625extern template
3626 enable_if<__is_input_iterator<char const*>::value, string&>::type
3627 string::
3628 replace<char const*>(string::iterator, string::iterator, char const*, char const*);
3629
3630extern template
3631 enable_if<__is_input_iterator<wchar_t const*>::value, wstring&>::type
3632 wstring::
3633 replace<wchar_t const*>(wstring::iterator, wstring::iterator, wchar_t const*, wchar_t const*);
3634
3635extern template
3636 enable_if<__is_forward_iterator<wchar_t*>::value, wstring&>::type
3637 wstring::assign<wchar_t*>(wchar_t*, wchar_t*);
3638
3639extern template
3640 string
3641 operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
3642
3643_LIBCPP_END_NAMESPACE_STD
3644
3645#endif // _LIBCPP_STRING