2 //===--------------------------- string -----------------------------------===//
4 // The LLVM Compiler Infrastructure
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
11 #ifndef _LIBCPP_STRING
12 #define _LIBCPP_STRING
20 template <class stateT>
26 fpos(streamoff = streamoff());
28 operator streamoff() const;
33 fpos& operator+=(streamoff);
34 fpos operator+ (streamoff) const;
35 fpos& operator-=(streamoff);
36 fpos operator- (streamoff) const;
39 template <class stateT> streamoff operator-(const fpos<stateT>& x, const fpos<stateT>& y);
41 template <class stateT> bool operator==(const fpos<stateT>& x, const fpos<stateT>& y);
42 template <class stateT> bool operator!=(const fpos<stateT>& x, const fpos<stateT>& y);
44 template <class charT>
47 typedef charT char_type;
49 typedef streamoff off_type;
50 typedef streampos pos_type;
51 typedef mbstate_t state_type;
53 static void assign(char_type& c1, const char_type& c2) noexcept;
54 static constexpr bool eq(char_type c1, char_type c2) noexcept;
55 static constexpr bool lt(char_type c1, char_type c2) noexcept;
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);
64 static constexpr int_type not_eof(int_type c) noexcept;
65 static constexpr char_type to_char_type(int_type c) noexcept;
66 static constexpr int_type to_int_type(char_type c) noexcept;
67 static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept;
68 static constexpr int_type eof() noexcept;
71 template <> struct char_traits<char>;
72 template <> struct char_traits<wchar_t>;
74 template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
79 typedef traits traits_type;
80 typedef typename traits_type::char_type value_type;
81 typedef Allocator allocator_type;
82 typedef typename allocator_type::size_type size_type;
83 typedef typename allocator_type::difference_type difference_type;
84 typedef typename allocator_type::reference reference;
85 typedef typename allocator_type::const_reference const_reference;
86 typedef typename allocator_type::pointer pointer;
87 typedef typename allocator_type::const_pointer const_pointer;
88 typedef implementation-defined iterator;
89 typedef implementation-defined const_iterator;
90 typedef std::reverse_iterator<iterator> reverse_iterator;
91 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
93 static const size_type npos = -1;
96 noexcept(is_nothrow_default_constructible<allocator_type>::value);
97 explicit basic_string(const allocator_type& a);
98 basic_string(const basic_string& str);
99 basic_string(basic_string&& str)
100 noexcept(is_nothrow_move_constructible<allocator_type>::value);
101 basic_string(const basic_string& str, size_type pos, size_type n = npos,
102 const allocator_type& a = allocator_type());
103 basic_string(const value_type* s, const allocator_type& a = allocator_type());
104 basic_string(const value_type* s, size_type n, const allocator_type& a = allocator_type());
105 basic_string(size_type n, value_type c, const allocator_type& a = allocator_type());
106 template<class InputIterator>
107 basic_string(InputIterator begin, InputIterator end,
108 const allocator_type& a = allocator_type());
109 basic_string(initializer_list<value_type>, const Allocator& = Allocator());
110 basic_string(const basic_string&, const Allocator&);
111 basic_string(basic_string&&, const Allocator&);
115 basic_string& operator=(const basic_string& str);
116 basic_string& operator=(basic_string&& str)
118 allocator_type::propagate_on_container_move_assignment::value ||
119 allocator_type::is_always_equal::value ); // C++17
120 basic_string& operator=(const value_type* s);
121 basic_string& operator=(value_type c);
122 basic_string& operator=(initializer_list<value_type>);
124 iterator begin() noexcept;
125 const_iterator begin() const noexcept;
126 iterator end() noexcept;
127 const_iterator end() const noexcept;
129 reverse_iterator rbegin() noexcept;
130 const_reverse_iterator rbegin() const noexcept;
131 reverse_iterator rend() noexcept;
132 const_reverse_iterator rend() const noexcept;
134 const_iterator cbegin() const noexcept;
135 const_iterator cend() const noexcept;
136 const_reverse_iterator crbegin() const noexcept;
137 const_reverse_iterator crend() const noexcept;
139 size_type size() const noexcept;
140 size_type length() const noexcept;
141 size_type max_size() const noexcept;
142 size_type capacity() const noexcept;
144 void resize(size_type n, value_type c);
145 void resize(size_type n);
147 void reserve(size_type res_arg = 0);
148 void shrink_to_fit();
149 void clear() noexcept;
150 bool empty() const noexcept;
152 const_reference operator[](size_type pos) const;
153 reference operator[](size_type pos);
155 const_reference at(size_type n) const;
156 reference at(size_type n);
158 basic_string& operator+=(const basic_string& str);
159 basic_string& operator+=(const value_type* s);
160 basic_string& operator+=(value_type c);
161 basic_string& operator+=(initializer_list<value_type>);
163 basic_string& append(const basic_string& str);
164 basic_string& append(const basic_string& str, size_type pos, size_type n=npos); //C++14
165 basic_string& append(const value_type* s, size_type n);
166 basic_string& append(const value_type* s);
167 basic_string& append(size_type n, value_type c);
168 template<class InputIterator>
169 basic_string& append(InputIterator first, InputIterator last);
170 basic_string& append(initializer_list<value_type>);
172 void push_back(value_type c);
175 const_reference front() const;
177 const_reference back() const;
179 basic_string& assign(const basic_string& str);
180 basic_string& assign(basic_string&& str);
181 basic_string& assign(const basic_string& str, size_type pos, size_type n=npos); // C++14
182 basic_string& assign(const value_type* s, size_type n);
183 basic_string& assign(const value_type* s);
184 basic_string& assign(size_type n, value_type c);
185 template<class InputIterator>
186 basic_string& assign(InputIterator first, InputIterator last);
187 basic_string& assign(initializer_list<value_type>);
189 basic_string& insert(size_type pos1, const basic_string& str);
190 basic_string& insert(size_type pos1, const basic_string& str,
191 size_type pos2, size_type n);
192 basic_string& insert(size_type pos, const value_type* s, size_type n=npos); //C++14
193 basic_string& insert(size_type pos, const value_type* s);
194 basic_string& insert(size_type pos, size_type n, value_type c);
195 iterator insert(const_iterator p, value_type c);
196 iterator insert(const_iterator p, size_type n, value_type c);
197 template<class InputIterator>
198 iterator insert(const_iterator p, InputIterator first, InputIterator last);
199 iterator insert(const_iterator p, initializer_list<value_type>);
201 basic_string& erase(size_type pos = 0, size_type n = npos);
202 iterator erase(const_iterator position);
203 iterator erase(const_iterator first, const_iterator last);
205 basic_string& replace(size_type pos1, size_type n1, const basic_string& str);
206 basic_string& replace(size_type pos1, size_type n1, const basic_string& str,
207 size_type pos2, size_type n2=npos); // C++14
208 basic_string& replace(size_type pos, size_type n1, const value_type* s, size_type n2);
209 basic_string& replace(size_type pos, size_type n1, const value_type* s);
210 basic_string& replace(size_type pos, size_type n1, size_type n2, value_type c);
211 basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str);
212 basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s, size_type n);
213 basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s);
214 basic_string& replace(const_iterator i1, const_iterator i2, size_type n, value_type c);
215 template<class InputIterator>
216 basic_string& replace(const_iterator i1, const_iterator i2, InputIterator j1, InputIterator j2);
217 basic_string& replace(const_iterator i1, const_iterator i2, initializer_list<value_type>);
219 size_type copy(value_type* s, size_type n, size_type pos = 0) const;
220 basic_string substr(size_type pos = 0, size_type n = npos) const;
222 void swap(basic_string& str)
223 noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
224 allocator_traits<allocator_type>::is_always_equal::value); // C++17
226 const value_type* c_str() const noexcept;
227 const value_type* data() const noexcept;
229 allocator_type get_allocator() const noexcept;
231 size_type find(const basic_string& str, size_type pos = 0) const noexcept;
232 size_type find(const value_type* s, size_type pos, size_type n) const noexcept;
233 size_type find(const value_type* s, size_type pos = 0) const noexcept;
234 size_type find(value_type c, size_type pos = 0) const noexcept;
236 size_type rfind(const basic_string& str, size_type pos = npos) const noexcept;
237 size_type rfind(const value_type* s, size_type pos, size_type n) const noexcept;
238 size_type rfind(const value_type* s, size_type pos = npos) const noexcept;
239 size_type rfind(value_type c, size_type pos = npos) const noexcept;
241 size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept;
242 size_type find_first_of(const value_type* s, size_type pos, size_type n) const noexcept;
243 size_type find_first_of(const value_type* s, size_type pos = 0) const noexcept;
244 size_type find_first_of(value_type c, size_type pos = 0) const noexcept;
246 size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept;
247 size_type find_last_of(const value_type* s, size_type pos, size_type n) const noexcept;
248 size_type find_last_of(const value_type* s, size_type pos = npos) const noexcept;
249 size_type find_last_of(value_type c, size_type pos = npos) const noexcept;
251 size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept;
252 size_type find_first_not_of(const value_type* s, size_type pos, size_type n) const noexcept;
253 size_type find_first_not_of(const value_type* s, size_type pos = 0) const noexcept;
254 size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept;
256 size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept;
257 size_type find_last_not_of(const value_type* s, size_type pos, size_type n) const noexcept;
258 size_type find_last_not_of(const value_type* s, size_type pos = npos) const noexcept;
259 size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept;
261 int compare(const basic_string& str) const noexcept;
262 int compare(size_type pos1, size_type n1, const basic_string& str) const;
263 int compare(size_type pos1, size_type n1, const basic_string& str,
264 size_type pos2, size_type n2=npos) const; // C++14
265 int compare(const value_type* s) const noexcept;
266 int compare(size_type pos1, size_type n1, const value_type* s) const;
267 int compare(size_type pos1, size_type n1, const value_type* s, size_type n2) const;
269 bool __invariants() const;
272 template<class charT, class traits, class Allocator>
273 basic_string<charT, traits, Allocator>
274 operator+(const basic_string<charT, traits, Allocator>& lhs,
275 const basic_string<charT, traits, Allocator>& rhs);
277 template<class charT, class traits, class Allocator>
278 basic_string<charT, traits, Allocator>
279 operator+(const charT* lhs , const basic_string<charT,traits,Allocator>&rhs);
281 template<class charT, class traits, class Allocator>
282 basic_string<charT, traits, Allocator>
283 operator+(charT lhs, const basic_string<charT,traits,Allocator>& rhs);
285 template<class charT, class traits, class Allocator>
286 basic_string<charT, traits, Allocator>
287 operator+(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs);
289 template<class charT, class traits, class Allocator>
290 basic_string<charT, traits, Allocator>
291 operator+(const basic_string<charT, traits, Allocator>& lhs, charT rhs);
293 template<class charT, class traits, class Allocator>
294 bool operator==(const basic_string<charT, traits, Allocator>& lhs,
295 const basic_string<charT, traits, Allocator>& rhs) noexcept;
297 template<class charT, class traits, class Allocator>
298 bool operator==(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;
300 template<class charT, class traits, class Allocator>
301 bool operator==(const basic_string<charT,traits,Allocator>& lhs, const charT* rhs) noexcept;
303 template<class charT, class traits, class Allocator>
304 bool operator!=(const basic_string<charT,traits,Allocator>& lhs,
305 const basic_string<charT, traits, Allocator>& rhs) noexcept;
307 template<class charT, class traits, class Allocator>
308 bool operator!=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;
310 template<class charT, class traits, class Allocator>
311 bool operator!=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;
313 template<class charT, class traits, class Allocator>
314 bool operator< (const basic_string<charT, traits, Allocator>& lhs,
315 const basic_string<charT, traits, Allocator>& rhs) noexcept;
317 template<class charT, class traits, class Allocator>
318 bool operator< (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;
320 template<class charT, class traits, class Allocator>
321 bool operator< (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;
323 template<class charT, class traits, class Allocator>
324 bool operator> (const basic_string<charT, traits, Allocator>& lhs,
325 const basic_string<charT, traits, Allocator>& rhs) noexcept;
327 template<class charT, class traits, class Allocator>
328 bool operator> (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;
330 template<class charT, class traits, class Allocator>
331 bool operator> (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;
333 template<class charT, class traits, class Allocator>
334 bool operator<=(const basic_string<charT, traits, Allocator>& lhs,
335 const basic_string<charT, traits, Allocator>& rhs) noexcept;
337 template<class charT, class traits, class Allocator>
338 bool operator<=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;
340 template<class charT, class traits, class Allocator>
341 bool operator<=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;
343 template<class charT, class traits, class Allocator>
344 bool operator>=(const basic_string<charT, traits, Allocator>& lhs,
345 const basic_string<charT, traits, Allocator>& rhs) noexcept;
347 template<class charT, class traits, class Allocator>
348 bool operator>=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;
350 template<class charT, class traits, class Allocator>
351 bool operator>=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;
353 template<class charT, class traits, class Allocator>
354 void swap(basic_string<charT, traits, Allocator>& lhs,
355 basic_string<charT, traits, Allocator>& rhs)
356 noexcept(noexcept(lhs.swap(rhs)));
358 template<class charT, class traits, class Allocator>
359 basic_istream<charT, traits>&
360 operator>>(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str);
362 template<class charT, class traits, class Allocator>
363 basic_ostream<charT, traits>&
364 operator<<(basic_ostream<charT, traits>& os, const basic_string<charT, traits, Allocator>& str);
366 template<class charT, class traits, class Allocator>
367 basic_istream<charT, traits>&
368 getline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str,
371 template<class charT, class traits, class Allocator>
372 basic_istream<charT, traits>&
373 getline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str);
375 typedef basic_string<char> string;
376 typedef basic_string<wchar_t> wstring;
377 typedef basic_string<char16_t> u16string;
378 typedef basic_string<char32_t> u32string;
380 int stoi (const string& str, size_t* idx = 0, int base = 10);
381 long stol (const string& str, size_t* idx = 0, int base = 10);
382 unsigned long stoul (const string& str, size_t* idx = 0, int base = 10);
383 long long stoll (const string& str, size_t* idx = 0, int base = 10);
384 unsigned long long stoull(const string& str, size_t* idx = 0, int base = 10);
386 float stof (const string& str, size_t* idx = 0);
387 double stod (const string& str, size_t* idx = 0);
388 long double stold(const string& str, size_t* idx = 0);
390 string to_string(int val);
391 string to_string(unsigned val);
392 string to_string(long val);
393 string to_string(unsigned long val);
394 string to_string(long long val);
395 string to_string(unsigned long long val);
396 string to_string(float val);
397 string to_string(double val);
398 string to_string(long double val);
400 int stoi (const wstring& str, size_t* idx = 0, int base = 10);
401 long stol (const wstring& str, size_t* idx = 0, int base = 10);
402 unsigned long stoul (const wstring& str, size_t* idx = 0, int base = 10);
403 long long stoll (const wstring& str, size_t* idx = 0, int base = 10);
404 unsigned long long stoull(const wstring& str, size_t* idx = 0, int base = 10);
406 float stof (const wstring& str, size_t* idx = 0);
407 double stod (const wstring& str, size_t* idx = 0);
408 long double stold(const wstring& str, size_t* idx = 0);
410 wstring to_wstring(int val);
411 wstring to_wstring(unsigned val);
412 wstring to_wstring(long val);
413 wstring to_wstring(unsigned long val);
414 wstring to_wstring(long long val);
415 wstring to_wstring(unsigned long long val);
416 wstring to_wstring(float val);
417 wstring to_wstring(double val);
418 wstring to_wstring(long double val);
420 template <> struct hash<string>;
421 template <> struct hash<u16string>;
422 template <> struct hash<u32string>;
423 template <> struct hash<wstring>;
425 basic_string<char> operator "" s( const char *str, size_t len ); // C++14
426 basic_string<wchar_t> operator "" s( const wchar_t *str, size_t len ); // C++14
427 basic_string<char16_t> operator "" s( const char16_t *str, size_t len ); // C++14
428 basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++14
437 #include <cstdio> // For EOF.
444 #include <type_traits>
445 #include <initializer_list>
446 #include <__functional_base>
447 #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
450 #if defined(_LIBCPP_NO_EXCEPTIONS)
454 #include <__undef_min_max>
458 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
459 #pragma GCC system_header
462 _LIBCPP_BEGIN_NAMESPACE_STD
466 template <class _StateT>
467 class _LIBCPP_TYPE_VIS_ONLY fpos
473 _LIBCPP_INLINE_VISIBILITY fpos(streamoff __off = streamoff()) : __st_(), __off_(__off) {}
475 _LIBCPP_INLINE_VISIBILITY operator streamoff() const {return __off_;}
477 _LIBCPP_INLINE_VISIBILITY _StateT state() const {return __st_;}
478 _LIBCPP_INLINE_VISIBILITY void state(_StateT __st) {__st_ = __st;}
480 _LIBCPP_INLINE_VISIBILITY fpos& operator+=(streamoff __off) {__off_ += __off; return *this;}
481 _LIBCPP_INLINE_VISIBILITY fpos operator+ (streamoff __off) const {fpos __t(*this); __t += __off; return __t;}
482 _LIBCPP_INLINE_VISIBILITY fpos& operator-=(streamoff __off) {__off_ -= __off; return *this;}
483 _LIBCPP_INLINE_VISIBILITY fpos operator- (streamoff __off) const {fpos __t(*this); __t -= __off; return __t;}
486 template <class _StateT>
487 inline _LIBCPP_INLINE_VISIBILITY
488 streamoff operator-(const fpos<_StateT>& __x, const fpos<_StateT>& __y)
489 {return streamoff(__x) - streamoff(__y);}
491 template <class _StateT>
492 inline _LIBCPP_INLINE_VISIBILITY
493 bool operator==(const fpos<_StateT>& __x, const fpos<_StateT>& __y)
494 {return streamoff(__x) == streamoff(__y);}
496 template <class _StateT>
497 inline _LIBCPP_INLINE_VISIBILITY
498 bool operator!=(const fpos<_StateT>& __x, const fpos<_StateT>& __y)
499 {return streamoff(__x) != streamoff(__y);}
503 template <class _CharT>
504 struct _LIBCPP_TYPE_VIS_ONLY char_traits
506 typedef _CharT char_type;
507 typedef int int_type;
508 typedef streamoff off_type;
509 typedef streampos pos_type;
510 typedef mbstate_t state_type;
512 static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
514 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
515 {return __c1 == __c2;}
516 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
517 {return __c1 < __c2;}
519 static int compare(const char_type* __s1, const char_type* __s2, size_t __n);
520 _LIBCPP_INLINE_VISIBILITY
521 static size_t length(const char_type* __s);
522 _LIBCPP_INLINE_VISIBILITY
523 static const char_type* find(const char_type* __s, size_t __n, const char_type& __a);
524 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n);
525 _LIBCPP_INLINE_VISIBILITY
526 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n);
527 _LIBCPP_INLINE_VISIBILITY
528 static char_type* assign(char_type* __s, size_t __n, char_type __a);
530 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
531 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
532 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
533 {return char_type(__c);}
534 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
535 {return int_type(__c);}
536 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
537 {return __c1 == __c2;}
538 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
539 {return int_type(EOF);}
542 template <class _CharT>
544 char_traits<_CharT>::compare(const char_type* __s1, const char_type* __s2, size_t __n)
546 for (; __n; --__n, ++__s1, ++__s2)
548 if (lt(*__s1, *__s2))
550 if (lt(*__s2, *__s1))
556 template <class _CharT>
559 char_traits<_CharT>::length(const char_type* __s)
562 for (; !eq(*__s, char_type(0)); ++__s)
567 template <class _CharT>
570 char_traits<_CharT>::find(const char_type* __s, size_t __n, const char_type& __a)
581 template <class _CharT>
583 char_traits<_CharT>::move(char_type* __s1, const char_type* __s2, size_t __n)
585 char_type* __r = __s1;
588 for (; __n; --__n, ++__s1, ++__s2)
589 assign(*__s1, *__s2);
591 else if (__s2 < __s1)
596 assign(*--__s1, *--__s2);
601 template <class _CharT>
604 char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n)
606 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
607 char_type* __r = __s1;
608 for (; __n; --__n, ++__s1, ++__s2)
609 assign(*__s1, *__s2);
613 template <class _CharT>
616 char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a)
618 char_type* __r = __s;
619 for (; __n; --__n, ++__s)
627 struct _LIBCPP_TYPE_VIS_ONLY char_traits<char>
629 typedef char char_type;
630 typedef int int_type;
631 typedef streamoff off_type;
632 typedef streampos pos_type;
633 typedef mbstate_t state_type;
635 static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
637 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
638 {return __c1 == __c2;}
639 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
640 {return (unsigned char)__c1 < (unsigned char)__c2;}
642 static inline int compare(const char_type* __s1, const char_type* __s2, size_t __n)
643 {return __n == 0 ? 0 : memcmp(__s1, __s2, __n);}
644 static inline size_t length(const char_type* __s) {return strlen(__s);}
645 static inline const char_type* find(const char_type* __s, size_t __n, const char_type& __a)
646 {return __n == 0 ? NULL : (const char_type*) memchr(__s, to_int_type(__a), __n);}
647 static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n)
648 {return __n == 0 ? __s1 : (char_type*) memmove(__s1, __s2, __n);}
649 static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n)
651 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
652 return __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n);
654 static inline char_type* assign(char_type* __s, size_t __n, char_type __a)
655 {return __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);}
657 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
658 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
659 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
660 {return char_type(__c);}
661 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
662 {return int_type((unsigned char)__c);}
663 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
664 {return __c1 == __c2;}
665 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
666 {return int_type(EOF);}
669 // char_traits<wchar_t>
672 struct _LIBCPP_TYPE_VIS_ONLY char_traits<wchar_t>
674 typedef wchar_t char_type;
675 typedef wint_t int_type;
676 typedef streamoff off_type;
677 typedef streampos pos_type;
678 typedef mbstate_t state_type;
680 static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
682 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
683 {return __c1 == __c2;}
684 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
685 {return __c1 < __c2;}
687 static inline int compare(const char_type* __s1, const char_type* __s2, size_t __n)
688 {return __n == 0 ? 0 : wmemcmp(__s1, __s2, __n);}
689 static inline size_t length(const char_type* __s)
690 {return wcslen(__s);}
691 static inline const char_type* find(const char_type* __s, size_t __n, const char_type& __a)
692 {return __n == 0 ? NULL : (const char_type*)wmemchr(__s, __a, __n);}
693 static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n)
694 {return __n == 0 ? __s1 : (char_type*)wmemmove(__s1, __s2, __n);}
695 static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n)
697 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
698 return __n == 0 ? __s1 : (char_type*)wmemcpy(__s1, __s2, __n);
700 static inline char_type* assign(char_type* __s, size_t __n, char_type __a)
701 {return __n == 0 ? __s : (char_type*)wmemset(__s, __a, __n);}
703 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
704 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
705 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
706 {return char_type(__c);}
707 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
708 {return int_type(__c);}
709 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
710 {return __c1 == __c2;}
711 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
712 {return int_type(WEOF);}
715 #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
718 struct _LIBCPP_TYPE_VIS_ONLY char_traits<char16_t>
720 typedef char16_t char_type;
721 typedef uint_least16_t int_type;
722 typedef streamoff off_type;
723 typedef u16streampos pos_type;
724 typedef mbstate_t state_type;
726 static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
728 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
729 {return __c1 == __c2;}
730 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
731 {return __c1 < __c2;}
733 _LIBCPP_INLINE_VISIBILITY
734 static int compare(const char_type* __s1, const char_type* __s2, size_t __n);
735 _LIBCPP_INLINE_VISIBILITY
736 static size_t length(const char_type* __s);
737 _LIBCPP_INLINE_VISIBILITY
738 static const char_type* find(const char_type* __s, size_t __n, const char_type& __a);
739 _LIBCPP_INLINE_VISIBILITY
740 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n);
741 _LIBCPP_INLINE_VISIBILITY
742 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n);
743 _LIBCPP_INLINE_VISIBILITY
744 static char_type* assign(char_type* __s, size_t __n, char_type __a);
746 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
747 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
748 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
749 {return char_type(__c);}
750 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
751 {return int_type(__c);}
752 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
753 {return __c1 == __c2;}
754 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
755 {return int_type(0xFFFF);}
760 char_traits<char16_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n)
762 for (; __n; --__n, ++__s1, ++__s2)
764 if (lt(*__s1, *__s2))
766 if (lt(*__s2, *__s1))
774 char_traits<char16_t>::length(const char_type* __s)
777 for (; !eq(*__s, char_type(0)); ++__s)
784 char_traits<char16_t>::find(const char_type* __s, size_t __n, const char_type& __a)
797 char_traits<char16_t>::move(char_type* __s1, const char_type* __s2, size_t __n)
799 char_type* __r = __s1;
802 for (; __n; --__n, ++__s1, ++__s2)
803 assign(*__s1, *__s2);
805 else if (__s2 < __s1)
810 assign(*--__s1, *--__s2);
817 char_traits<char16_t>::copy(char_type* __s1, const char_type* __s2, size_t __n)
819 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
820 char_type* __r = __s1;
821 for (; __n; --__n, ++__s1, ++__s2)
822 assign(*__s1, *__s2);
828 char_traits<char16_t>::assign(char_type* __s, size_t __n, char_type __a)
830 char_type* __r = __s;
831 for (; __n; --__n, ++__s)
837 struct _LIBCPP_TYPE_VIS_ONLY char_traits<char32_t>
839 typedef char32_t char_type;
840 typedef uint_least32_t int_type;
841 typedef streamoff off_type;
842 typedef u32streampos pos_type;
843 typedef mbstate_t state_type;
845 static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
847 static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
848 {return __c1 == __c2;}
849 static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
850 {return __c1 < __c2;}
852 _LIBCPP_INLINE_VISIBILITY
853 static int compare(const char_type* __s1, const char_type* __s2, size_t __n);
854 _LIBCPP_INLINE_VISIBILITY
855 static size_t length(const char_type* __s);
856 _LIBCPP_INLINE_VISIBILITY
857 static const char_type* find(const char_type* __s, size_t __n, const char_type& __a);
858 _LIBCPP_INLINE_VISIBILITY
859 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n);
860 _LIBCPP_INLINE_VISIBILITY
861 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n);
862 _LIBCPP_INLINE_VISIBILITY
863 static char_type* assign(char_type* __s, size_t __n, char_type __a);
865 static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
866 {return eq_int_type(__c, eof()) ? ~eof() : __c;}
867 static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
868 {return char_type(__c);}
869 static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
870 {return int_type(__c);}
871 static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
872 {return __c1 == __c2;}
873 static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
874 {return int_type(0xFFFFFFFF);}
879 char_traits<char32_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n)
881 for (; __n; --__n, ++__s1, ++__s2)
883 if (lt(*__s1, *__s2))
885 if (lt(*__s2, *__s1))
893 char_traits<char32_t>::length(const char_type* __s)
896 for (; !eq(*__s, char_type(0)); ++__s)
903 char_traits<char32_t>::find(const char_type* __s, size_t __n, const char_type& __a)
916 char_traits<char32_t>::move(char_type* __s1, const char_type* __s2, size_t __n)
918 char_type* __r = __s1;
921 for (; __n; --__n, ++__s1, ++__s2)
922 assign(*__s1, *__s2);
924 else if (__s2 < __s1)
929 assign(*--__s1, *--__s2);
936 char_traits<char32_t>::copy(char_type* __s1, const char_type* __s2, size_t __n)
938 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
939 char_type* __r = __s1;
940 for (; __n; --__n, ++__s1, ++__s2)
941 assign(*__s1, *__s2);
947 char_traits<char32_t>::assign(char_type* __s, size_t __n, char_type __a)
949 char_type* __r = __s;
950 for (; __n; --__n, ++__s)
955 #endif // _LIBCPP_HAS_NO_UNICODE_CHARS
957 // helper fns for basic_string
960 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
961 _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
962 __str_find(const _CharT *__p, _SizeT __sz,
963 _CharT __c, _SizeT __pos) _NOEXCEPT
967 const _CharT* __r = _Traits::find(__p + __pos, __sz - __pos, __c);
970 return static_cast<_SizeT>(__r - __p);
973 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
974 _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
975 __str_find(const _CharT *__p, _SizeT __sz,
976 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
978 if (__pos > __sz || __sz - __pos < __n)
983 _VSTD::__search(__p + __pos, __p + __sz,
984 __s, __s + __n, _Traits::eq,
985 random_access_iterator_tag(), random_access_iterator_tag());
986 if (__r == __p + __sz)
988 return static_cast<_SizeT>(__r - __p);
994 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
995 _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
996 __str_rfind(const _CharT *__p, _SizeT __sz,
997 _CharT __c, _SizeT __pos) _NOEXCEPT
1005 for (const _CharT* __ps = __p + __pos; __ps != __p;)
1007 if (_Traits::eq(*--__ps, __c))
1008 return static_cast<_SizeT>(__ps - __p);
1013 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1014 _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1015 __str_rfind(const _CharT *__p, _SizeT __sz,
1016 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
1018 __pos = _VSTD::min(__pos, __sz);
1019 if (__n < __sz - __pos)
1023 const _CharT* __r = _VSTD::__find_end(
1024 __p, __p + __pos, __s, __s + __n, _Traits::eq,
1025 random_access_iterator_tag(), random_access_iterator_tag());
1026 if (__n > 0 && __r == __p + __pos)
1028 return static_cast<_SizeT>(__r - __p);
1031 // __str_find_first_of
1032 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1033 _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1034 __str_find_first_of(const _CharT *__p, _SizeT __sz,
1035 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
1037 if (__pos >= __sz || __n == 0)
1039 const _CharT* __r = _VSTD::__find_first_of_ce
1040 (__p + __pos, __p + __sz, __s, __s + __n, _Traits::eq );
1041 if (__r == __p + __sz)
1043 return static_cast<_SizeT>(__r - __p);
1047 // __str_find_last_of
1048 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1049 _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1050 __str_find_last_of(const _CharT *__p, _SizeT __sz,
1051 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
1059 for (const _CharT* __ps = __p + __pos; __ps != __p;)
1061 const _CharT* __r = _Traits::find(__s, __n, *--__ps);
1063 return static_cast<_SizeT>(__ps - __p);
1070 // __str_find_first_not_of
1071 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1072 _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1073 __str_find_first_not_of(const _CharT *__p, _SizeT __sz,
1074 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
1078 const _CharT* __pe = __p + __sz;
1079 for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
1080 if (_Traits::find(__s, __n, *__ps) == 0)
1081 return static_cast<_SizeT>(__ps - __p);
1087 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1088 _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1089 __str_find_first_not_of(const _CharT *__p, _SizeT __sz,
1090 _CharT __c, _SizeT __pos) _NOEXCEPT
1094 const _CharT* __pe = __p + __sz;
1095 for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
1096 if (!_Traits::eq(*__ps, __c))
1097 return static_cast<_SizeT>(__ps - __p);
1103 // __str_find_last_not_of
1104 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1105 _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1106 __str_find_last_not_of(const _CharT *__p, _SizeT __sz,
1107 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
1113 for (const _CharT* __ps = __p + __pos; __ps != __p;)
1114 if (_Traits::find(__s, __n, *--__ps) == 0)
1115 return static_cast<_SizeT>(__ps - __p);
1120 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
1121 _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1122 __str_find_last_not_of(const _CharT *__p, _SizeT __sz,
1123 _CharT __c, _SizeT __pos) _NOEXCEPT
1129 for (const _CharT* __ps = __p + __pos; __ps != __p;)
1130 if (!_Traits::eq(*--__ps, __c))
1131 return static_cast<_SizeT>(__ps - __p);
1135 template<class _Ptr>
1136 size_t _LIBCPP_INLINE_VISIBILITY __do_string_hash(_Ptr __p, _Ptr __e)
1138 typedef typename iterator_traits<_Ptr>::value_type value_type;
1139 return __murmur2_or_cityhash<size_t>()(__p, (__e-__p)*sizeof(value_type));
1144 template<class _CharT, class _Traits, class _Allocator>
1145 basic_string<_CharT, _Traits, _Allocator>
1146 operator+(const basic_string<_CharT, _Traits, _Allocator>& __x,
1147 const basic_string<_CharT, _Traits, _Allocator>& __y);
1149 template<class _CharT, class _Traits, class _Allocator>
1150 basic_string<_CharT, _Traits, _Allocator>
1151 operator+(const _CharT* __x, const basic_string<_CharT,_Traits,_Allocator>& __y);
1153 template<class _CharT, class _Traits, class _Allocator>
1154 basic_string<_CharT, _Traits, _Allocator>
1155 operator+(_CharT __x, const basic_string<_CharT,_Traits,_Allocator>& __y);
1157 template<class _CharT, class _Traits, class _Allocator>
1158 basic_string<_CharT, _Traits, _Allocator>
1159 operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const _CharT* __y);
1161 template<class _CharT, class _Traits, class _Allocator>
1162 basic_string<_CharT, _Traits, _Allocator>
1163 operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y);
1166 class _LIBCPP_TYPE_VIS_ONLY __basic_string_common
1169 void __throw_length_error() const;
1170 void __throw_out_of_range() const;
1175 __basic_string_common<__b>::__throw_length_error() const
1177 #ifndef _LIBCPP_NO_EXCEPTIONS
1178 throw length_error("basic_string");
1180 assert(!"basic_string length_error");
1186 __basic_string_common<__b>::__throw_out_of_range() const
1188 #ifndef _LIBCPP_NO_EXCEPTIONS
1189 throw out_of_range("basic_string");
1191 assert(!"basic_string out_of_range");
1196 #pragma warning( push )
1197 #pragma warning( disable: 4231 )
1198 #endif // _LIBCPP_MSVC
1199 _LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS __basic_string_common<true>)
1201 #pragma warning( pop )
1202 #endif // _LIBCPP_MSVC
1204 #ifdef _LIBCPP_NO_EXCEPTIONS
1205 template <class _Iter>
1206 struct __libcpp_string_gets_noexcept_iterator_impl : public true_type {};
1207 #elif defined(_LIBCPP_HAS_NO_NOEXCEPT)
1208 template <class _Iter>
1209 struct __libcpp_string_gets_noexcept_iterator_impl : public false_type {};
1211 template <class _Iter, bool = __is_forward_iterator<_Iter>::value>
1212 struct __libcpp_string_gets_noexcept_iterator_impl : public _LIBCPP_BOOL_CONSTANT((
1213 noexcept(++(declval<_Iter&>())) &&
1214 is_nothrow_assignable<_Iter&, _Iter>::value &&
1215 noexcept(declval<_Iter>() == declval<_Iter>()) &&
1216 noexcept(*declval<_Iter>())
1219 template <class _Iter>
1220 struct __libcpp_string_gets_noexcept_iterator_impl<_Iter, false> : public false_type {};
1224 template <class _Iter>
1225 struct __libcpp_string_gets_noexcept_iterator
1226 : public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value || __libcpp_string_gets_noexcept_iterator_impl<_Iter>::value) {};
1228 #ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
1230 template <class _CharT, size_t = sizeof(_CharT)>
1233 unsigned char __xx[sizeof(_CharT)-1];
1236 template <class _CharT>
1237 struct __padding<_CharT, 1>
1241 #endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
1243 template<class _CharT, class _Traits, class _Allocator>
1244 class _LIBCPP_TYPE_VIS_ONLY basic_string
1245 : private __basic_string_common<true>
1248 typedef basic_string __self;
1249 typedef _Traits traits_type;
1250 typedef typename traits_type::char_type value_type;
1251 typedef _Allocator allocator_type;
1252 typedef allocator_traits<allocator_type> __alloc_traits;
1253 typedef typename __alloc_traits::size_type size_type;
1254 typedef typename __alloc_traits::difference_type difference_type;
1255 typedef value_type& reference;
1256 typedef const value_type& const_reference;
1257 typedef typename __alloc_traits::pointer pointer;
1258 typedef typename __alloc_traits::const_pointer const_pointer;
1260 static_assert(is_pod<value_type>::value, "Character type of basic_string must be a POD");
1261 static_assert((is_same<_CharT, value_type>::value),
1262 "traits_type::char_type must be the same type as CharT");
1263 static_assert((is_same<typename allocator_type::value_type, value_type>::value),
1264 "Allocator::value_type must be same type as value_type");
1265 #if defined(_LIBCPP_RAW_ITERATORS)
1266 typedef pointer iterator;
1267 typedef const_pointer const_iterator;
1268 #else // defined(_LIBCPP_RAW_ITERATORS)
1269 typedef __wrap_iter<pointer> iterator;
1270 typedef __wrap_iter<const_pointer> const_iterator;
1271 #endif // defined(_LIBCPP_RAW_ITERATORS)
1272 typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
1273 typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
1277 #ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
1286 #if _LIBCPP_BIG_ENDIAN
1287 enum {__short_mask = 0x01};
1288 enum {__long_mask = 0x1ul};
1289 #else // _LIBCPP_BIG_ENDIAN
1290 enum {__short_mask = 0x80};
1291 enum {__long_mask = ~(size_type(~0) >> 1)};
1292 #endif // _LIBCPP_BIG_ENDIAN
1294 enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ?
1295 (sizeof(__long) - 1)/sizeof(value_type) : 2};
1299 value_type __data_[__min_cap];
1301 : __padding<value_type>
1303 unsigned char __size_;
1316 #if _LIBCPP_BIG_ENDIAN
1317 enum {__short_mask = 0x80};
1318 enum {__long_mask = ~(size_type(~0) >> 1)};
1319 #else // _LIBCPP_BIG_ENDIAN
1320 enum {__short_mask = 0x01};
1321 enum {__long_mask = 0x1ul};
1322 #endif // _LIBCPP_BIG_ENDIAN
1324 enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ?
1325 (sizeof(__long) - 1)/sizeof(value_type) : 2};
1331 unsigned char __size_;
1334 value_type __data_[__min_cap];
1337 #endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
1339 union __ulx{__long __lx; __short __lxx;};
1341 enum {__n_words = sizeof(__ulx) / sizeof(size_type)};
1345 size_type __words[__n_words];
1358 __compressed_pair<__rep, allocator_type> __r_;
1361 static const size_type npos = -1;
1363 _LIBCPP_INLINE_VISIBILITY basic_string()
1364 _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
1366 _LIBCPP_INLINE_VISIBILITY explicit basic_string(const allocator_type& __a)
1367 #if _LIBCPP_STD_VER <= 14
1368 _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value);
1373 basic_string(const basic_string& __str);
1374 basic_string(const basic_string& __str, const allocator_type& __a);
1376 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1377 _LIBCPP_INLINE_VISIBILITY
1378 basic_string(basic_string&& __str)
1379 #if _LIBCPP_STD_VER <= 14
1380 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
1385 _LIBCPP_INLINE_VISIBILITY
1386 basic_string(basic_string&& __str, const allocator_type& __a);
1387 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1388 _LIBCPP_INLINE_VISIBILITY basic_string(const value_type* __s);
1389 _LIBCPP_INLINE_VISIBILITY
1390 basic_string(const value_type* __s, const allocator_type& __a);
1391 _LIBCPP_INLINE_VISIBILITY
1392 basic_string(const value_type* __s, size_type __n);
1393 _LIBCPP_INLINE_VISIBILITY
1394 basic_string(const value_type* __s, size_type __n, const allocator_type& __a);
1395 _LIBCPP_INLINE_VISIBILITY
1396 basic_string(size_type __n, value_type __c);
1397 _LIBCPP_INLINE_VISIBILITY
1398 basic_string(size_type __n, value_type __c, const allocator_type& __a);
1399 basic_string(const basic_string& __str, size_type __pos, size_type __n = npos,
1400 const allocator_type& __a = allocator_type());
1401 template<class _InputIterator>
1402 _LIBCPP_INLINE_VISIBILITY
1403 basic_string(_InputIterator __first, _InputIterator __last);
1404 template<class _InputIterator>
1405 _LIBCPP_INLINE_VISIBILITY
1406 basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a);
1407 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
1408 _LIBCPP_INLINE_VISIBILITY
1409 basic_string(initializer_list<value_type> __il);
1410 _LIBCPP_INLINE_VISIBILITY
1411 basic_string(initializer_list<value_type> __il, const allocator_type& __a);
1412 #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
1416 basic_string& operator=(const basic_string& __str);
1417 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1418 _LIBCPP_INLINE_VISIBILITY
1419 basic_string& operator=(basic_string&& __str)
1420 _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));
1422 _LIBCPP_INLINE_VISIBILITY basic_string& operator=(const value_type* __s) {return assign(__s);}
1423 basic_string& operator=(value_type __c);
1424 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
1425 _LIBCPP_INLINE_VISIBILITY
1426 basic_string& operator=(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}
1427 #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
1429 #if _LIBCPP_DEBUG_LEVEL >= 2
1430 _LIBCPP_INLINE_VISIBILITY
1431 iterator begin() _NOEXCEPT
1432 {return iterator(this, __get_pointer());}
1433 _LIBCPP_INLINE_VISIBILITY
1434 const_iterator begin() const _NOEXCEPT
1435 {return const_iterator(this, __get_pointer());}
1436 _LIBCPP_INLINE_VISIBILITY
1437 iterator end() _NOEXCEPT
1438 {return iterator(this, __get_pointer() + size());}
1439 _LIBCPP_INLINE_VISIBILITY
1440 const_iterator end() const _NOEXCEPT
1441 {return const_iterator(this, __get_pointer() + size());}
1443 _LIBCPP_INLINE_VISIBILITY
1444 iterator begin() _NOEXCEPT
1445 {return iterator(__get_pointer());}
1446 _LIBCPP_INLINE_VISIBILITY
1447 const_iterator begin() const _NOEXCEPT
1448 {return const_iterator(__get_pointer());}
1449 _LIBCPP_INLINE_VISIBILITY
1450 iterator end() _NOEXCEPT
1451 {return iterator(__get_pointer() + size());}
1452 _LIBCPP_INLINE_VISIBILITY
1453 const_iterator end() const _NOEXCEPT
1454 {return const_iterator(__get_pointer() + size());}
1455 #endif // _LIBCPP_DEBUG_LEVEL >= 2
1456 _LIBCPP_INLINE_VISIBILITY
1457 reverse_iterator rbegin() _NOEXCEPT
1458 {return reverse_iterator(end());}
1459 _LIBCPP_INLINE_VISIBILITY
1460 const_reverse_iterator rbegin() const _NOEXCEPT
1461 {return const_reverse_iterator(end());}
1462 _LIBCPP_INLINE_VISIBILITY
1463 reverse_iterator rend() _NOEXCEPT
1464 {return reverse_iterator(begin());}
1465 _LIBCPP_INLINE_VISIBILITY
1466 const_reverse_iterator rend() const _NOEXCEPT
1467 {return const_reverse_iterator(begin());}
1469 _LIBCPP_INLINE_VISIBILITY
1470 const_iterator cbegin() const _NOEXCEPT
1472 _LIBCPP_INLINE_VISIBILITY
1473 const_iterator cend() const _NOEXCEPT
1475 _LIBCPP_INLINE_VISIBILITY
1476 const_reverse_iterator crbegin() const _NOEXCEPT
1478 _LIBCPP_INLINE_VISIBILITY
1479 const_reverse_iterator crend() const _NOEXCEPT
1482 _LIBCPP_INLINE_VISIBILITY size_type size() const _NOEXCEPT
1483 {return __is_long() ? __get_long_size() : __get_short_size();}
1484 _LIBCPP_INLINE_VISIBILITY size_type length() const _NOEXCEPT {return size();}
1485 _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT;
1486 _LIBCPP_INLINE_VISIBILITY size_type capacity() const _NOEXCEPT
1487 {return (__is_long() ? __get_long_cap()
1488 : static_cast<size_type>(__min_cap)) - 1;}
1490 void resize(size_type __n, value_type __c);
1491 _LIBCPP_INLINE_VISIBILITY void resize(size_type __n) {resize(__n, value_type());}
1493 void reserve(size_type res_arg = 0);
1494 _LIBCPP_INLINE_VISIBILITY
1495 void shrink_to_fit() _NOEXCEPT {reserve();}
1496 _LIBCPP_INLINE_VISIBILITY
1497 void clear() _NOEXCEPT;
1498 _LIBCPP_INLINE_VISIBILITY bool empty() const _NOEXCEPT {return size() == 0;}
1500 _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __pos) const;
1501 _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __pos);
1503 const_reference at(size_type __n) const;
1504 reference at(size_type __n);
1506 _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const basic_string& __str) {return append(__str);}
1507 _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const value_type* __s) {return append(__s);}
1508 _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(value_type __c) {push_back(__c); return *this;}
1509 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
1510 _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(initializer_list<value_type> __il) {return append(__il);}
1511 #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
1513 _LIBCPP_INLINE_VISIBILITY
1514 basic_string& append(const basic_string& __str);
1515 basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos);
1516 basic_string& append(const value_type* __s, size_type __n);
1517 basic_string& append(const value_type* __s);
1518 basic_string& append(size_type __n, value_type __c);
1519 template<class _InputIterator>
1522 __is_exactly_input_iterator<_InputIterator>::value
1523 || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
1526 append(_InputIterator __first, _InputIterator __last);
1527 template<class _ForwardIterator>
1530 __is_forward_iterator<_ForwardIterator>::value
1531 && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
1534 append(_ForwardIterator __first, _ForwardIterator __last);
1535 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
1536 _LIBCPP_INLINE_VISIBILITY
1537 basic_string& append(initializer_list<value_type> __il) {return append(__il.begin(), __il.size());}
1538 #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
1540 void push_back(value_type __c);
1541 _LIBCPP_INLINE_VISIBILITY
1543 _LIBCPP_INLINE_VISIBILITY reference front();
1544 _LIBCPP_INLINE_VISIBILITY const_reference front() const;
1545 _LIBCPP_INLINE_VISIBILITY reference back();
1546 _LIBCPP_INLINE_VISIBILITY const_reference back() const;
1548 _LIBCPP_INLINE_VISIBILITY
1549 basic_string& assign(const basic_string& __str);
1550 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1551 _LIBCPP_INLINE_VISIBILITY
1552 basic_string& assign(basic_string&& str)
1553 _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value))
1554 {*this = _VSTD::move(str); return *this;}
1556 basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos);
1557 basic_string& assign(const value_type* __s, size_type __n);
1558 basic_string& assign(const value_type* __s);
1559 basic_string& assign(size_type __n, value_type __c);
1560 template<class _InputIterator>
1563 __is_exactly_input_iterator<_InputIterator>::value
1564 || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
1567 assign(_InputIterator __first, _InputIterator __last);
1568 template<class _ForwardIterator>
1571 __is_forward_iterator<_ForwardIterator>::value
1572 && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
1575 assign(_ForwardIterator __first, _ForwardIterator __last);
1576 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
1577 _LIBCPP_INLINE_VISIBILITY
1578 basic_string& assign(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}
1579 #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
1581 _LIBCPP_INLINE_VISIBILITY
1582 basic_string& insert(size_type __pos1, const basic_string& __str);
1583 basic_string& insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n=npos);
1584 basic_string& insert(size_type __pos, const value_type* __s, size_type __n);
1585 basic_string& insert(size_type __pos, const value_type* __s);
1586 basic_string& insert(size_type __pos, size_type __n, value_type __c);
1587 iterator insert(const_iterator __pos, value_type __c);
1588 _LIBCPP_INLINE_VISIBILITY
1589 iterator insert(const_iterator __pos, size_type __n, value_type __c);
1590 template<class _InputIterator>
1593 __is_exactly_input_iterator<_InputIterator>::value
1594 || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
1597 insert(const_iterator __pos, _InputIterator __first, _InputIterator __last);
1598 template<class _ForwardIterator>
1601 __is_forward_iterator<_ForwardIterator>::value
1602 && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
1605 insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last);
1606 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
1607 _LIBCPP_INLINE_VISIBILITY
1608 iterator insert(const_iterator __pos, initializer_list<value_type> __il)
1609 {return insert(__pos, __il.begin(), __il.end());}
1610 #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
1612 basic_string& erase(size_type __pos = 0, size_type __n = npos);
1613 _LIBCPP_INLINE_VISIBILITY
1614 iterator erase(const_iterator __pos);
1615 _LIBCPP_INLINE_VISIBILITY
1616 iterator erase(const_iterator __first, const_iterator __last);
1618 _LIBCPP_INLINE_VISIBILITY
1619 basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str);
1620 basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos);
1621 basic_string& replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2);
1622 basic_string& replace(size_type __pos, size_type __n1, const value_type* __s);
1623 basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c);
1624 _LIBCPP_INLINE_VISIBILITY
1625 basic_string& replace(const_iterator __i1, const_iterator __i2, const basic_string& __str);
1626 _LIBCPP_INLINE_VISIBILITY
1627 basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n);
1628 _LIBCPP_INLINE_VISIBILITY
1629 basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s);
1630 _LIBCPP_INLINE_VISIBILITY
1631 basic_string& replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c);
1632 template<class _InputIterator>
1635 __is_input_iterator<_InputIterator>::value,
1638 replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2);
1639 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
1640 _LIBCPP_INLINE_VISIBILITY
1641 basic_string& replace(const_iterator __i1, const_iterator __i2, initializer_list<value_type> __il)
1642 {return replace(__i1, __i2, __il.begin(), __il.end());}
1643 #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
1645 size_type copy(value_type* __s, size_type __n, size_type __pos = 0) const;
1646 _LIBCPP_INLINE_VISIBILITY
1647 basic_string substr(size_type __pos = 0, size_type __n = npos) const;
1649 _LIBCPP_INLINE_VISIBILITY
1650 void swap(basic_string& __str)
1651 #if _LIBCPP_STD_VER >= 14
1654 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
1655 __is_nothrow_swappable<allocator_type>::value);
1658 _LIBCPP_INLINE_VISIBILITY
1659 const value_type* c_str() const _NOEXCEPT {return data();}
1660 _LIBCPP_INLINE_VISIBILITY
1661 const value_type* data() const _NOEXCEPT {return _VSTD::__to_raw_pointer(__get_pointer());}
1663 _LIBCPP_INLINE_VISIBILITY
1664 allocator_type get_allocator() const _NOEXCEPT {return __alloc();}
1666 _LIBCPP_INLINE_VISIBILITY
1667 size_type find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
1668 size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1669 _LIBCPP_INLINE_VISIBILITY
1670 size_type find(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
1671 size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT;
1673 _LIBCPP_INLINE_VISIBILITY
1674 size_type rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
1675 size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1676 _LIBCPP_INLINE_VISIBILITY
1677 size_type rfind(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
1678 size_type rfind(value_type __c, size_type __pos = npos) const _NOEXCEPT;
1680 _LIBCPP_INLINE_VISIBILITY
1681 size_type find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
1682 size_type find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1683 _LIBCPP_INLINE_VISIBILITY
1684 size_type find_first_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
1685 _LIBCPP_INLINE_VISIBILITY
1686 size_type find_first_of(value_type __c, size_type __pos = 0) const _NOEXCEPT;
1688 _LIBCPP_INLINE_VISIBILITY
1689 size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
1690 size_type find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1691 _LIBCPP_INLINE_VISIBILITY
1692 size_type find_last_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
1693 _LIBCPP_INLINE_VISIBILITY
1694 size_type find_last_of(value_type __c, size_type __pos = npos) const _NOEXCEPT;
1696 _LIBCPP_INLINE_VISIBILITY
1697 size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
1698 size_type find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1699 _LIBCPP_INLINE_VISIBILITY
1700 size_type find_first_not_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
1701 _LIBCPP_INLINE_VISIBILITY
1702 size_type find_first_not_of(value_type __c, size_type __pos = 0) const _NOEXCEPT;
1704 _LIBCPP_INLINE_VISIBILITY
1705 size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
1706 size_type find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1707 _LIBCPP_INLINE_VISIBILITY
1708 size_type find_last_not_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
1709 _LIBCPP_INLINE_VISIBILITY
1710 size_type find_last_not_of(value_type __c, size_type __pos = npos) const _NOEXCEPT;
1712 _LIBCPP_INLINE_VISIBILITY
1713 int compare(const basic_string& __str) const _NOEXCEPT;
1714 _LIBCPP_INLINE_VISIBILITY
1715 int compare(size_type __pos1, size_type __n1, const basic_string& __str) const;
1716 int compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos) const;
1717 int compare(const value_type* __s) const _NOEXCEPT;
1718 int compare(size_type __pos1, size_type __n1, const value_type* __s) const;
1719 int compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const;
1721 _LIBCPP_INLINE_VISIBILITY bool __invariants() const;
1723 _LIBCPP_INLINE_VISIBILITY
1724 bool __is_long() const _NOEXCEPT
1725 {return bool(__r_.first().__s.__size_ & __short_mask);}
1727 #if _LIBCPP_DEBUG_LEVEL >= 2
1729 bool __dereferenceable(const const_iterator* __i) const;
1730 bool __decrementable(const const_iterator* __i) const;
1731 bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
1732 bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
1734 #endif // _LIBCPP_DEBUG_LEVEL >= 2
1737 _LIBCPP_INLINE_VISIBILITY
1738 allocator_type& __alloc() _NOEXCEPT
1739 {return __r_.second();}
1740 _LIBCPP_INLINE_VISIBILITY
1741 const allocator_type& __alloc() const _NOEXCEPT
1742 {return __r_.second();}
1744 #ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
1746 _LIBCPP_INLINE_VISIBILITY
1747 void __set_short_size(size_type __s) _NOEXCEPT
1748 # if _LIBCPP_BIG_ENDIAN
1749 {__r_.first().__s.__size_ = (unsigned char)(__s << 1);}
1751 {__r_.first().__s.__size_ = (unsigned char)(__s);}
1754 _LIBCPP_INLINE_VISIBILITY
1755 size_type __get_short_size() const _NOEXCEPT
1756 # if _LIBCPP_BIG_ENDIAN
1757 {return __r_.first().__s.__size_ >> 1;}
1759 {return __r_.first().__s.__size_;}
1762 #else // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
1764 _LIBCPP_INLINE_VISIBILITY
1765 void __set_short_size(size_type __s) _NOEXCEPT
1766 # if _LIBCPP_BIG_ENDIAN
1767 {__r_.first().__s.__size_ = (unsigned char)(__s);}
1769 {__r_.first().__s.__size_ = (unsigned char)(__s << 1);}
1772 _LIBCPP_INLINE_VISIBILITY
1773 size_type __get_short_size() const _NOEXCEPT
1774 # if _LIBCPP_BIG_ENDIAN
1775 {return __r_.first().__s.__size_;}
1777 {return __r_.first().__s.__size_ >> 1;}
1780 #endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
1782 _LIBCPP_INLINE_VISIBILITY
1783 void __set_long_size(size_type __s) _NOEXCEPT
1784 {__r_.first().__l.__size_ = __s;}
1785 _LIBCPP_INLINE_VISIBILITY
1786 size_type __get_long_size() const _NOEXCEPT
1787 {return __r_.first().__l.__size_;}
1788 _LIBCPP_INLINE_VISIBILITY
1789 void __set_size(size_type __s) _NOEXCEPT
1790 {if (__is_long()) __set_long_size(__s); else __set_short_size(__s);}
1792 _LIBCPP_INLINE_VISIBILITY
1793 void __set_long_cap(size_type __s) _NOEXCEPT
1794 {__r_.first().__l.__cap_ = __long_mask | __s;}
1795 _LIBCPP_INLINE_VISIBILITY
1796 size_type __get_long_cap() const _NOEXCEPT
1797 {return __r_.first().__l.__cap_ & size_type(~__long_mask);}
1799 _LIBCPP_INLINE_VISIBILITY
1800 void __set_long_pointer(pointer __p) _NOEXCEPT
1801 {__r_.first().__l.__data_ = __p;}
1802 _LIBCPP_INLINE_VISIBILITY
1803 pointer __get_long_pointer() _NOEXCEPT
1804 {return __r_.first().__l.__data_;}
1805 _LIBCPP_INLINE_VISIBILITY
1806 const_pointer __get_long_pointer() const _NOEXCEPT
1807 {return __r_.first().__l.__data_;}
1808 _LIBCPP_INLINE_VISIBILITY
1809 pointer __get_short_pointer() _NOEXCEPT
1810 {return pointer_traits<pointer>::pointer_to(__r_.first().__s.__data_[0]);}
1811 _LIBCPP_INLINE_VISIBILITY
1812 const_pointer __get_short_pointer() const _NOEXCEPT
1813 {return pointer_traits<const_pointer>::pointer_to(__r_.first().__s.__data_[0]);}
1814 _LIBCPP_INLINE_VISIBILITY
1815 pointer __get_pointer() _NOEXCEPT
1816 {return __is_long() ? __get_long_pointer() : __get_short_pointer();}
1817 _LIBCPP_INLINE_VISIBILITY
1818 const_pointer __get_pointer() const _NOEXCEPT
1819 {return __is_long() ? __get_long_pointer() : __get_short_pointer();}
1821 _LIBCPP_INLINE_VISIBILITY
1822 void __zero() _NOEXCEPT
1824 size_type (&__a)[__n_words] = __r_.first().__r.__words;
1825 for (unsigned __i = 0; __i < __n_words; ++__i)
1829 template <size_type __a> static
1830 _LIBCPP_INLINE_VISIBILITY
1831 size_type __align_it(size_type __s) _NOEXCEPT
1832 {return (__s + (__a-1)) & ~(__a-1);}
1833 enum {__alignment = 16};
1834 static _LIBCPP_INLINE_VISIBILITY
1835 size_type __recommend(size_type __s) _NOEXCEPT
1836 {return (__s < __min_cap ? static_cast<size_type>(__min_cap) :
1837 __align_it<sizeof(value_type) < __alignment ?
1838 __alignment/sizeof(value_type) : 1 > (__s+1)) - 1;}
1840 void __init(const value_type* __s, size_type __sz, size_type __reserve);
1841 void __init(const value_type* __s, size_type __sz);
1842 void __init(size_type __n, value_type __c);
1844 template <class _InputIterator>
1847 __is_exactly_input_iterator<_InputIterator>::value,
1850 __init(_InputIterator __first, _InputIterator __last);
1852 template <class _ForwardIterator>
1855 __is_forward_iterator<_ForwardIterator>::value,
1858 __init(_ForwardIterator __first, _ForwardIterator __last);
1860 void __grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
1861 size_type __n_copy, size_type __n_del, size_type __n_add = 0);
1862 void __grow_by_and_replace(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
1863 size_type __n_copy, size_type __n_del,
1864 size_type __n_add, const value_type* __p_new_stuff);
1866 _LIBCPP_INLINE_VISIBILITY
1867 void __erase_to_end(size_type __pos);
1869 _LIBCPP_INLINE_VISIBILITY
1870 void __copy_assign_alloc(const basic_string& __str)
1871 {__copy_assign_alloc(__str, integral_constant<bool,
1872 __alloc_traits::propagate_on_container_copy_assignment::value>());}
1874 _LIBCPP_INLINE_VISIBILITY
1875 void __copy_assign_alloc(const basic_string& __str, true_type)
1877 if (__alloc() != __str.__alloc())
1882 __alloc() = __str.__alloc();
1885 _LIBCPP_INLINE_VISIBILITY
1886 void __copy_assign_alloc(const basic_string&, false_type) _NOEXCEPT
1889 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1890 _LIBCPP_INLINE_VISIBILITY
1891 void __move_assign(basic_string& __str, false_type)
1892 _NOEXCEPT_(__alloc_traits::is_always_equal::value);
1893 _LIBCPP_INLINE_VISIBILITY
1894 void __move_assign(basic_string& __str, true_type)
1895 #if _LIBCPP_STD_VER > 14
1898 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
1902 _LIBCPP_INLINE_VISIBILITY
1904 __move_assign_alloc(basic_string& __str)
1906 !__alloc_traits::propagate_on_container_move_assignment::value ||
1907 is_nothrow_move_assignable<allocator_type>::value)
1908 {__move_assign_alloc(__str, integral_constant<bool,
1909 __alloc_traits::propagate_on_container_move_assignment::value>());}
1911 _LIBCPP_INLINE_VISIBILITY
1912 void __move_assign_alloc(basic_string& __c, true_type)
1913 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
1915 __alloc() = _VSTD::move(__c.__alloc());
1918 _LIBCPP_INLINE_VISIBILITY
1919 void __move_assign_alloc(basic_string&, false_type)
1923 _LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators();
1924 _LIBCPP_INLINE_VISIBILITY void __invalidate_iterators_past(size_type);
1926 friend basic_string operator+<>(const basic_string&, const basic_string&);
1927 friend basic_string operator+<>(const value_type*, const basic_string&);
1928 friend basic_string operator+<>(value_type, const basic_string&);
1929 friend basic_string operator+<>(const basic_string&, const value_type*);
1930 friend basic_string operator+<>(const basic_string&, value_type);
1933 template <class _CharT, class _Traits, class _Allocator>
1934 inline _LIBCPP_INLINE_VISIBILITY
1936 basic_string<_CharT, _Traits, _Allocator>::__invalidate_all_iterators()
1938 #if _LIBCPP_DEBUG_LEVEL >= 2
1939 __get_db()->__invalidate_all(this);
1940 #endif // _LIBCPP_DEBUG_LEVEL >= 2
1943 template <class _CharT, class _Traits, class _Allocator>
1944 inline _LIBCPP_INLINE_VISIBILITY
1946 basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type
1947 #if _LIBCPP_DEBUG_LEVEL >= 2
1952 #if _LIBCPP_DEBUG_LEVEL >= 2
1953 __c_node* __c = __get_db()->__find_c_and_lock(this);
1956 const_pointer __new_last = __get_pointer() + __pos;
1957 for (__i_node** __p = __c->end_; __p != __c->beg_; )
1960 const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
1961 if (__i->base() > __new_last)
1963 (*__p)->__c_ = nullptr;
1964 if (--__c->end_ != __p)
1965 memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
1968 __get_db()->unlock();
1970 #endif // _LIBCPP_DEBUG_LEVEL >= 2
1973 template <class _CharT, class _Traits, class _Allocator>
1974 inline _LIBCPP_INLINE_VISIBILITY
1975 basic_string<_CharT, _Traits, _Allocator>::basic_string()
1976 _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
1978 #if _LIBCPP_DEBUG_LEVEL >= 2
1979 __get_db()->__insert_c(this);
1984 template <class _CharT, class _Traits, class _Allocator>
1985 inline _LIBCPP_INLINE_VISIBILITY
1986 basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __a)
1987 #if _LIBCPP_STD_VER <= 14
1988 _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
1994 #if _LIBCPP_DEBUG_LEVEL >= 2
1995 __get_db()->__insert_c(this);
2000 template <class _CharT, class _Traits, class _Allocator>
2002 basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz, size_type __reserve)
2004 if (__reserve > max_size())
2005 this->__throw_length_error();
2007 if (__reserve < __min_cap)
2009 __set_short_size(__sz);
2010 __p = __get_short_pointer();
2014 size_type __cap = __recommend(__reserve);
2015 __p = __alloc_traits::allocate(__alloc(), __cap+1);
2016 __set_long_pointer(__p);
2017 __set_long_cap(__cap+1);
2018 __set_long_size(__sz);
2020 traits_type::copy(_VSTD::__to_raw_pointer(__p), __s, __sz);
2021 traits_type::assign(__p[__sz], value_type());
2024 template <class _CharT, class _Traits, class _Allocator>
2026 basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz)
2028 if (__sz > max_size())
2029 this->__throw_length_error();
2031 if (__sz < __min_cap)
2033 __set_short_size(__sz);
2034 __p = __get_short_pointer();
2038 size_type __cap = __recommend(__sz);
2039 __p = __alloc_traits::allocate(__alloc(), __cap+1);
2040 __set_long_pointer(__p);
2041 __set_long_cap(__cap+1);
2042 __set_long_size(__sz);
2044 traits_type::copy(_VSTD::__to_raw_pointer(__p), __s, __sz);
2045 traits_type::assign(__p[__sz], value_type());
2048 template <class _CharT, class _Traits, class _Allocator>
2049 inline _LIBCPP_INLINE_VISIBILITY
2050 basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s)
2052 _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr");
2053 __init(__s, traits_type::length(__s));
2054 #if _LIBCPP_DEBUG_LEVEL >= 2
2055 __get_db()->__insert_c(this);
2059 template <class _CharT, class _Traits, class _Allocator>
2060 inline _LIBCPP_INLINE_VISIBILITY
2061 basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, const allocator_type& __a)
2064 _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr");
2065 __init(__s, traits_type::length(__s));
2066 #if _LIBCPP_DEBUG_LEVEL >= 2
2067 __get_db()->__insert_c(this);
2071 template <class _CharT, class _Traits, class _Allocator>
2072 inline _LIBCPP_INLINE_VISIBILITY
2073 basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, size_type __n)
2075 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr");
2077 #if _LIBCPP_DEBUG_LEVEL >= 2
2078 __get_db()->__insert_c(this);
2082 template <class _CharT, class _Traits, class _Allocator>
2083 inline _LIBCPP_INLINE_VISIBILITY
2084 basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, size_type __n, const allocator_type& __a)
2087 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr");
2089 #if _LIBCPP_DEBUG_LEVEL >= 2
2090 __get_db()->__insert_c(this);
2094 template <class _CharT, class _Traits, class _Allocator>
2095 basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str)
2096 : __r_(__alloc_traits::select_on_container_copy_construction(__str.__alloc()))
2098 if (!__str.__is_long())
2099 __r_.first().__r = __str.__r_.first().__r;
2101 __init(_VSTD::__to_raw_pointer(__str.__get_long_pointer()), __str.__get_long_size());
2102 #if _LIBCPP_DEBUG_LEVEL >= 2
2103 __get_db()->__insert_c(this);
2107 template <class _CharT, class _Traits, class _Allocator>
2108 basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, const allocator_type& __a)
2111 if (!__str.__is_long())
2112 __r_.first().__r = __str.__r_.first().__r;
2114 __init(_VSTD::__to_raw_pointer(__str.__get_long_pointer()), __str.__get_long_size());
2115 #if _LIBCPP_DEBUG_LEVEL >= 2
2116 __get_db()->__insert_c(this);
2120 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2122 template <class _CharT, class _Traits, class _Allocator>
2123 inline _LIBCPP_INLINE_VISIBILITY
2124 basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str)
2125 #if _LIBCPP_STD_VER <= 14
2126 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
2130 : __r_(_VSTD::move(__str.__r_))
2133 #if _LIBCPP_DEBUG_LEVEL >= 2
2134 __get_db()->__insert_c(this);
2136 __get_db()->swap(this, &__str);
2140 template <class _CharT, class _Traits, class _Allocator>
2141 inline _LIBCPP_INLINE_VISIBILITY
2142 basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, const allocator_type& __a)
2145 if (__str.__is_long() && __a != __str.__alloc()) // copy, not move
2146 __init(_VSTD::__to_raw_pointer(__str.__get_long_pointer()), __str.__get_long_size());
2149 __r_.first().__r = __str.__r_.first().__r;
2152 #if _LIBCPP_DEBUG_LEVEL >= 2
2153 __get_db()->__insert_c(this);
2155 __get_db()->swap(this, &__str);
2159 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2161 template <class _CharT, class _Traits, class _Allocator>
2163 basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c)
2165 if (__n > max_size())
2166 this->__throw_length_error();
2168 if (__n < __min_cap)
2170 __set_short_size(__n);
2171 __p = __get_short_pointer();
2175 size_type __cap = __recommend(__n);
2176 __p = __alloc_traits::allocate(__alloc(), __cap+1);
2177 __set_long_pointer(__p);
2178 __set_long_cap(__cap+1);
2179 __set_long_size(__n);
2181 traits_type::assign(_VSTD::__to_raw_pointer(__p), __n, __c);
2182 traits_type::assign(__p[__n], value_type());
2185 template <class _CharT, class _Traits, class _Allocator>
2186 inline _LIBCPP_INLINE_VISIBILITY
2187 basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, value_type __c)
2190 #if _LIBCPP_DEBUG_LEVEL >= 2
2191 __get_db()->__insert_c(this);
2195 template <class _CharT, class _Traits, class _Allocator>
2196 inline _LIBCPP_INLINE_VISIBILITY
2197 basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, value_type __c, const allocator_type& __a)
2201 #if _LIBCPP_DEBUG_LEVEL >= 2
2202 __get_db()->__insert_c(this);
2206 template <class _CharT, class _Traits, class _Allocator>
2207 basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos, size_type __n,
2208 const allocator_type& __a)
2211 size_type __str_sz = __str.size();
2212 if (__pos > __str_sz)
2213 this->__throw_out_of_range();
2214 __init(__str.data() + __pos, _VSTD::min(__n, __str_sz - __pos));
2215 #if _LIBCPP_DEBUG_LEVEL >= 2
2216 __get_db()->__insert_c(this);
2220 template <class _CharT, class _Traits, class _Allocator>
2221 template <class _InputIterator>
2224 __is_exactly_input_iterator<_InputIterator>::value,
2227 basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last)
2230 #ifndef _LIBCPP_NO_EXCEPTIONS
2233 #endif // _LIBCPP_NO_EXCEPTIONS
2234 for (; __first != __last; ++__first)
2235 push_back(*__first);
2236 #ifndef _LIBCPP_NO_EXCEPTIONS
2241 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
2244 #endif // _LIBCPP_NO_EXCEPTIONS
2247 template <class _CharT, class _Traits, class _Allocator>
2248 template <class _ForwardIterator>
2251 __is_forward_iterator<_ForwardIterator>::value,
2254 basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last)
2256 size_type __sz = static_cast<size_type>(_VSTD::distance(__first, __last));
2257 if (__sz > max_size())
2258 this->__throw_length_error();
2260 if (__sz < __min_cap)
2262 __set_short_size(__sz);
2263 __p = __get_short_pointer();
2267 size_type __cap = __recommend(__sz);
2268 __p = __alloc_traits::allocate(__alloc(), __cap+1);
2269 __set_long_pointer(__p);
2270 __set_long_cap(__cap+1);
2271 __set_long_size(__sz);
2273 for (; __first != __last; ++__first, (void) ++__p)
2274 traits_type::assign(*__p, *__first);
2275 traits_type::assign(*__p, value_type());
2278 template <class _CharT, class _Traits, class _Allocator>
2279 template<class _InputIterator>
2280 inline _LIBCPP_INLINE_VISIBILITY
2281 basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last)
2283 __init(__first, __last);
2284 #if _LIBCPP_DEBUG_LEVEL >= 2
2285 __get_db()->__insert_c(this);
2289 template <class _CharT, class _Traits, class _Allocator>
2290 template<class _InputIterator>
2291 inline _LIBCPP_INLINE_VISIBILITY
2292 basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last,
2293 const allocator_type& __a)
2296 __init(__first, __last);
2297 #if _LIBCPP_DEBUG_LEVEL >= 2
2298 __get_db()->__insert_c(this);
2302 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
2304 template <class _CharT, class _Traits, class _Allocator>
2305 inline _LIBCPP_INLINE_VISIBILITY
2306 basic_string<_CharT, _Traits, _Allocator>::basic_string(initializer_list<value_type> __il)
2308 __init(__il.begin(), __il.end());
2309 #if _LIBCPP_DEBUG_LEVEL >= 2
2310 __get_db()->__insert_c(this);
2314 template <class _CharT, class _Traits, class _Allocator>
2315 inline _LIBCPP_INLINE_VISIBILITY
2316 basic_string<_CharT, _Traits, _Allocator>::basic_string(initializer_list<value_type> __il, const allocator_type& __a)
2319 __init(__il.begin(), __il.end());
2320 #if _LIBCPP_DEBUG_LEVEL >= 2
2321 __get_db()->__insert_c(this);
2325 #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
2327 template <class _CharT, class _Traits, class _Allocator>
2328 basic_string<_CharT, _Traits, _Allocator>::~basic_string()
2330 #if _LIBCPP_DEBUG_LEVEL >= 2
2331 __get_db()->__erase_c(this);
2334 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
2337 template <class _CharT, class _Traits, class _Allocator>
2339 basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace
2340 (size_type __old_cap, size_type __delta_cap, size_type __old_sz,
2341 size_type __n_copy, size_type __n_del, size_type __n_add, const value_type* __p_new_stuff)
2343 size_type __ms = max_size();
2344 if (__delta_cap > __ms - __old_cap - 1)
2345 this->__throw_length_error();
2346 pointer __old_p = __get_pointer();
2347 size_type __cap = __old_cap < __ms / 2 - __alignment ?
2348 __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) :
2350 pointer __p = __alloc_traits::allocate(__alloc(), __cap+1);
2351 __invalidate_all_iterators();
2353 traits_type::copy(_VSTD::__to_raw_pointer(__p),
2354 _VSTD::__to_raw_pointer(__old_p), __n_copy);
2356 traits_type::copy(_VSTD::__to_raw_pointer(__p) + __n_copy, __p_new_stuff, __n_add);
2357 size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
2358 if (__sec_cp_sz != 0)
2359 traits_type::copy(_VSTD::__to_raw_pointer(__p) + __n_copy + __n_add,
2360 _VSTD::__to_raw_pointer(__old_p) + __n_copy + __n_del, __sec_cp_sz);
2361 if (__old_cap+1 != __min_cap)
2362 __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1);
2363 __set_long_pointer(__p);
2364 __set_long_cap(__cap+1);
2365 __old_sz = __n_copy + __n_add + __sec_cp_sz;
2366 __set_long_size(__old_sz);
2367 traits_type::assign(__p[__old_sz], value_type());
2370 template <class _CharT, class _Traits, class _Allocator>
2372 basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
2373 size_type __n_copy, size_type __n_del, size_type __n_add)
2375 size_type __ms = max_size();
2376 if (__delta_cap > __ms - __old_cap)
2377 this->__throw_length_error();
2378 pointer __old_p = __get_pointer();
2379 size_type __cap = __old_cap < __ms / 2 - __alignment ?
2380 __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) :
2382 pointer __p = __alloc_traits::allocate(__alloc(), __cap+1);
2383 __invalidate_all_iterators();
2385 traits_type::copy(_VSTD::__to_raw_pointer(__p),
2386 _VSTD::__to_raw_pointer(__old_p), __n_copy);
2387 size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
2388 if (__sec_cp_sz != 0)
2389 traits_type::copy(_VSTD::__to_raw_pointer(__p) + __n_copy + __n_add,
2390 _VSTD::__to_raw_pointer(__old_p) + __n_copy + __n_del,
2392 if (__old_cap+1 != __min_cap)
2393 __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1);
2394 __set_long_pointer(__p);
2395 __set_long_cap(__cap+1);
2400 template <class _CharT, class _Traits, class _Allocator>
2401 basic_string<_CharT, _Traits, _Allocator>&
2402 basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n)
2404 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::assign received nullptr");
2405 size_type __cap = capacity();
2408 value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());
2409 traits_type::move(__p, __s, __n);
2410 traits_type::assign(__p[__n], value_type());
2412 __invalidate_iterators_past(__n);
2416 size_type __sz = size();
2417 __grow_by_and_replace(__cap, __n - __cap, __sz, 0, __sz, __n, __s);
2422 template <class _CharT, class _Traits, class _Allocator>
2423 basic_string<_CharT, _Traits, _Allocator>&
2424 basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c)
2426 size_type __cap = capacity();
2429 size_type __sz = size();
2430 __grow_by(__cap, __n - __cap, __sz, 0, __sz);
2433 __invalidate_iterators_past(__n);
2434 value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());
2435 traits_type::assign(__p, __n, __c);
2436 traits_type::assign(__p[__n], value_type());
2441 template <class _CharT, class _Traits, class _Allocator>
2442 basic_string<_CharT, _Traits, _Allocator>&
2443 basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c)
2448 __p = __get_long_pointer();
2453 __p = __get_short_pointer();
2454 __set_short_size(1);
2456 traits_type::assign(*__p, __c);
2457 traits_type::assign(*++__p, value_type());
2458 __invalidate_iterators_past(1);
2462 template <class _CharT, class _Traits, class _Allocator>
2463 basic_string<_CharT, _Traits, _Allocator>&
2464 basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str)
2468 __copy_assign_alloc(__str);
2474 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2476 template <class _CharT, class _Traits, class _Allocator>
2477 inline _LIBCPP_INLINE_VISIBILITY
2479 basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, false_type)
2480 _NOEXCEPT_(__alloc_traits::is_always_equal::value)
2482 if (__alloc() != __str.__alloc())
2485 __move_assign(__str, true_type());
2488 template <class _CharT, class _Traits, class _Allocator>
2489 inline _LIBCPP_INLINE_VISIBILITY
2491 basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type)
2492 #if _LIBCPP_STD_VER > 14
2495 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
2500 __r_.first() = __str.__r_.first();
2501 __move_assign_alloc(__str);
2505 template <class _CharT, class _Traits, class _Allocator>
2506 inline _LIBCPP_INLINE_VISIBILITY
2507 basic_string<_CharT, _Traits, _Allocator>&
2508 basic_string<_CharT, _Traits, _Allocator>::operator=(basic_string&& __str)
2509 _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value))
2511 __move_assign(__str, integral_constant<bool,
2512 __alloc_traits::propagate_on_container_move_assignment::value>());
2518 template <class _CharT, class _Traits, class _Allocator>
2519 template<class _InputIterator>
2522 __is_exactly_input_iterator <_InputIterator>::value
2523 || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
2524 basic_string<_CharT, _Traits, _Allocator>&
2526 basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
2528 basic_string __temp(__first, __last, __alloc());
2529 assign(__temp.data(), __temp.size());
2533 template <class _CharT, class _Traits, class _Allocator>
2534 template<class _ForwardIterator>
2537 __is_forward_iterator<_ForwardIterator>::value
2538 && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
2539 basic_string<_CharT, _Traits, _Allocator>&
2541 basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)
2543 size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
2544 size_type __cap = capacity();
2547 size_type __sz = size();
2548 __grow_by(__cap, __n - __cap, __sz, 0, __sz);
2551 __invalidate_iterators_past(__n);
2552 pointer __p = __get_pointer();
2553 for (; __first != __last; ++__first, ++__p)
2554 traits_type::assign(*__p, *__first);
2555 traits_type::assign(*__p, value_type());
2560 template <class _CharT, class _Traits, class _Allocator>
2561 inline _LIBCPP_INLINE_VISIBILITY
2562 basic_string<_CharT, _Traits, _Allocator>&
2563 basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str)
2565 return assign(__str.data(), __str.size());
2568 template <class _CharT, class _Traits, class _Allocator>
2569 basic_string<_CharT, _Traits, _Allocator>&
2570 basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, size_type __pos, size_type __n)
2572 size_type __sz = __str.size();
2574 this->__throw_out_of_range();
2575 return assign(__str.data() + __pos, _VSTD::min(__n, __sz - __pos));
2578 template <class _CharT, class _Traits, class _Allocator>
2579 basic_string<_CharT, _Traits, _Allocator>&
2580 basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s)
2582 _LIBCPP_ASSERT(__s != nullptr, "string::assign received nullptr");
2583 return assign(__s, traits_type::length(__s));
2588 template <class _CharT, class _Traits, class _Allocator>
2589 basic_string<_CharT, _Traits, _Allocator>&
2590 basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n)
2592 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::append received nullptr");
2593 size_type __cap = capacity();
2594 size_type __sz = size();
2595 if (__cap - __sz >= __n)
2599 value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());
2600 traits_type::copy(__p + __sz, __s, __n);
2603 traits_type::assign(__p[__sz], value_type());
2607 __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __sz, 0, __n, __s);
2611 template <class _CharT, class _Traits, class _Allocator>
2612 basic_string<_CharT, _Traits, _Allocator>&
2613 basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c)
2617 size_type __cap = capacity();
2618 size_type __sz = size();
2619 if (__cap - __sz < __n)
2620 __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
2621 pointer __p = __get_pointer();
2622 traits_type::assign(_VSTD::__to_raw_pointer(__p) + __sz, __n, __c);
2625 traits_type::assign(__p[__sz], value_type());
2630 template <class _CharT, class _Traits, class _Allocator>
2632 basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c)
2634 bool __is_short = !__is_long();
2639 __cap = __min_cap - 1;
2640 __sz = __get_short_size();
2644 __cap = __get_long_cap() - 1;
2645 __sz = __get_long_size();
2649 __grow_by(__cap, 1, __sz, __sz, 0);
2650 __is_short = !__is_long();
2655 __p = __get_short_pointer() + __sz;
2656 __set_short_size(__sz+1);
2660 __p = __get_long_pointer() + __sz;
2661 __set_long_size(__sz+1);
2663 traits_type::assign(*__p, __c);
2664 traits_type::assign(*++__p, value_type());
2667 template <class _CharT, class _Traits, class _Allocator>
2668 template<class _InputIterator>
2671 __is_exactly_input_iterator<_InputIterator>::value
2672 || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
2673 basic_string<_CharT, _Traits, _Allocator>&
2675 basic_string<_CharT, _Traits, _Allocator>::append(_InputIterator __first, _InputIterator __last)
2677 basic_string __temp (__first, __last, __alloc());
2678 append(__temp.data(), __temp.size());
2682 template <class _CharT, class _Traits, class _Allocator>
2683 template<class _ForwardIterator>
2686 __is_forward_iterator<_ForwardIterator>::value
2687 && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
2688 basic_string<_CharT, _Traits, _Allocator>&
2690 basic_string<_CharT, _Traits, _Allocator>::append(_ForwardIterator __first, _ForwardIterator __last)
2692 size_type __sz = size();
2693 size_type __cap = capacity();
2694 size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
2697 if (__cap - __sz < __n)
2698 __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
2699 pointer __p = __get_pointer() + __sz;
2700 for (; __first != __last; ++__p, ++__first)
2701 traits_type::assign(*__p, *__first);
2702 traits_type::assign(*__p, value_type());
2703 __set_size(__sz + __n);
2708 template <class _CharT, class _Traits, class _Allocator>
2709 inline _LIBCPP_INLINE_VISIBILITY
2710 basic_string<_CharT, _Traits, _Allocator>&
2711 basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str)
2713 return append(__str.data(), __str.size());
2716 template <class _CharT, class _Traits, class _Allocator>
2717 basic_string<_CharT, _Traits, _Allocator>&
2718 basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, size_type __pos, size_type __n)
2720 size_type __sz = __str.size();
2722 this->__throw_out_of_range();
2723 return append(__str.data() + __pos, _VSTD::min(__n, __sz - __pos));
2726 template <class _CharT, class _Traits, class _Allocator>
2727 basic_string<_CharT, _Traits, _Allocator>&
2728 basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s)
2730 _LIBCPP_ASSERT(__s != nullptr, "string::append received nullptr");
2731 return append(__s, traits_type::length(__s));
2736 template <class _CharT, class _Traits, class _Allocator>
2737 basic_string<_CharT, _Traits, _Allocator>&
2738 basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n)
2740 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::insert received nullptr");
2741 size_type __sz = size();
2743 this->__throw_out_of_range();
2744 size_type __cap = capacity();
2745 if (__cap - __sz >= __n)
2749 value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());
2750 size_type __n_move = __sz - __pos;
2753 if (__p + __pos <= __s && __s < __p + __sz)
2755 traits_type::move(__p + __pos + __n, __p + __pos, __n_move);
2757 traits_type::move(__p + __pos, __s, __n);
2760 traits_type::assign(__p[__sz], value_type());
2764 __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s);
2768 template <class _CharT, class _Traits, class _Allocator>
2769 basic_string<_CharT, _Traits, _Allocator>&
2770 basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n, value_type __c)
2772 size_type __sz = size();
2774 this->__throw_out_of_range();
2777 size_type __cap = capacity();
2779 if (__cap - __sz >= __n)
2781 __p = _VSTD::__to_raw_pointer(__get_pointer());
2782 size_type __n_move = __sz - __pos;
2784 traits_type::move(__p + __pos + __n, __p + __pos, __n_move);
2788 __grow_by(__cap, __sz + __n - __cap, __sz, __pos, 0, __n);
2789 __p = _VSTD::__to_raw_pointer(__get_long_pointer());
2791 traits_type::assign(__p + __pos, __n, __c);
2794 traits_type::assign(__p[__sz], value_type());
2799 template <class _CharT, class _Traits, class _Allocator>
2800 template<class _InputIterator>
2803 __is_exactly_input_iterator<_InputIterator>::value
2804 || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
2805 typename basic_string<_CharT, _Traits, _Allocator>::iterator
2807 basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last)
2809 #if _LIBCPP_DEBUG_LEVEL >= 2
2810 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
2811 "string::insert(iterator, range) called with an iterator not"
2812 " referring to this string");
2814 basic_string __temp(__first, __last, __alloc());
2815 return insert(__pos, __temp.data(), __temp.data() + __temp.size());
2818 template <class _CharT, class _Traits, class _Allocator>
2819 template<class _ForwardIterator>
2822 __is_forward_iterator<_ForwardIterator>::value
2823 && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
2824 typename basic_string<_CharT, _Traits, _Allocator>::iterator
2826 basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last)
2828 #if _LIBCPP_DEBUG_LEVEL >= 2
2829 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
2830 "string::insert(iterator, range) called with an iterator not"
2831 " referring to this string");
2833 size_type __ip = static_cast<size_type>(__pos - begin());
2834 size_type __sz = size();
2835 size_type __cap = capacity();
2836 size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
2840 if (__cap - __sz >= __n)
2842 __p = _VSTD::__to_raw_pointer(__get_pointer());
2843 size_type __n_move = __sz - __ip;
2845 traits_type::move(__p + __ip + __n, __p + __ip, __n_move);
2849 __grow_by(__cap, __sz + __n - __cap, __sz, __ip, 0, __n);
2850 __p = _VSTD::__to_raw_pointer(__get_long_pointer());
2854 traits_type::assign(__p[__sz], value_type());
2855 for (__p += __ip; __first != __last; ++__p, ++__first)
2856 traits_type::assign(*__p, *__first);
2858 return begin() + __ip;
2861 template <class _CharT, class _Traits, class _Allocator>
2862 inline _LIBCPP_INLINE_VISIBILITY
2863 basic_string<_CharT, _Traits, _Allocator>&
2864 basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str)
2866 return insert(__pos1, __str.data(), __str.size());
2869 template <class _CharT, class _Traits, class _Allocator>
2870 basic_string<_CharT, _Traits, _Allocator>&
2871 basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str,
2872 size_type __pos2, size_type __n)
2874 size_type __str_sz = __str.size();
2875 if (__pos2 > __str_sz)
2876 this->__throw_out_of_range();
2877 return insert(__pos1, __str.data() + __pos2, _VSTD::min(__n, __str_sz - __pos2));
2880 template <class _CharT, class _Traits, class _Allocator>
2881 basic_string<_CharT, _Traits, _Allocator>&
2882 basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s)
2884 _LIBCPP_ASSERT(__s != nullptr, "string::insert received nullptr");
2885 return insert(__pos, __s, traits_type::length(__s));
2888 template <class _CharT, class _Traits, class _Allocator>
2889 typename basic_string<_CharT, _Traits, _Allocator>::iterator
2890 basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c)
2892 size_type __ip = static_cast<size_type>(__pos - begin());
2893 size_type __sz = size();
2894 size_type __cap = capacity();
2898 __grow_by(__cap, 1, __sz, __ip, 0, 1);
2899 __p = _VSTD::__to_raw_pointer(__get_long_pointer());
2903 __p = _VSTD::__to_raw_pointer(__get_pointer());
2904 size_type __n_move = __sz - __ip;
2906 traits_type::move(__p + __ip + 1, __p + __ip, __n_move);
2908 traits_type::assign(__p[__ip], __c);
2909 traits_type::assign(__p[++__sz], value_type());
2911 return begin() + static_cast<difference_type>(__ip);
2914 template <class _CharT, class _Traits, class _Allocator>
2915 inline _LIBCPP_INLINE_VISIBILITY
2916 typename basic_string<_CharT, _Traits, _Allocator>::iterator
2917 basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, size_type __n, value_type __c)
2919 #if _LIBCPP_DEBUG_LEVEL >= 2
2920 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
2921 "string::insert(iterator, n, value) called with an iterator not"
2922 " referring to this string");
2924 difference_type __p = __pos - begin();
2925 insert(static_cast<size_type>(__p), __n, __c);
2926 return begin() + __p;
2931 template <class _CharT, class _Traits, class _Allocator>
2932 basic_string<_CharT, _Traits, _Allocator>&
2933 basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2)
2935 _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::replace received nullptr");
2936 size_type __sz = size();
2938 this->__throw_out_of_range();
2939 __n1 = _VSTD::min(__n1, __sz - __pos);
2940 size_type __cap = capacity();
2941 if (__cap - __sz + __n1 >= __n2)
2943 value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());
2946 size_type __n_move = __sz - __pos - __n1;
2951 traits_type::move(__p + __pos, __s, __n2);
2952 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
2955 if (__p + __pos < __s && __s < __p + __sz)
2957 if (__p + __pos + __n1 <= __s)
2959 else // __p + __pos < __s < __p + __pos + __n1
2961 traits_type::move(__p + __pos, __s, __n1);
2968 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
2971 traits_type::move(__p + __pos, __s, __n2);
2973 __sz += __n2 - __n1;
2975 __invalidate_iterators_past(__sz);
2976 traits_type::assign(__p[__sz], value_type());
2979 __grow_by_and_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2, __s);
2983 template <class _CharT, class _Traits, class _Allocator>
2984 basic_string<_CharT, _Traits, _Allocator>&
2985 basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, size_type __n2, value_type __c)
2987 size_type __sz = size();
2989 this->__throw_out_of_range();
2990 __n1 = _VSTD::min(__n1, __sz - __pos);
2991 size_type __cap = capacity();
2993 if (__cap - __sz + __n1 >= __n2)
2995 __p = _VSTD::__to_raw_pointer(__get_pointer());
2998 size_type __n_move = __sz - __pos - __n1;
3000 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
3005 __grow_by(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2);
3006 __p = _VSTD::__to_raw_pointer(__get_long_pointer());
3008 traits_type::assign(__p + __pos, __n2, __c);
3009 __sz += __n2 - __n1;
3011 __invalidate_iterators_past(__sz);
3012 traits_type::assign(__p[__sz], value_type());
3016 template <class _CharT, class _Traits, class _Allocator>
3017 template<class _InputIterator>
3020 __is_input_iterator<_InputIterator>::value,
3021 basic_string<_CharT, _Traits, _Allocator>&
3023 basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2,
3024 _InputIterator __j1, _InputIterator __j2)
3026 basic_string __temp(__j1, __j2, __alloc());
3027 return this->replace(__i1, __i2, __temp);
3030 template <class _CharT, class _Traits, class _Allocator>
3031 inline _LIBCPP_INLINE_VISIBILITY
3032 basic_string<_CharT, _Traits, _Allocator>&
3033 basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str)
3035 return replace(__pos1, __n1, __str.data(), __str.size());
3038 template <class _CharT, class _Traits, class _Allocator>
3039 basic_string<_CharT, _Traits, _Allocator>&
3040 basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str,
3041 size_type __pos2, size_type __n2)
3043 size_type __str_sz = __str.size();
3044 if (__pos2 > __str_sz)
3045 this->__throw_out_of_range();
3046 return replace(__pos1, __n1, __str.data() + __pos2, _VSTD::min(__n2, __str_sz - __pos2));
3049 template <class _CharT, class _Traits, class _Allocator>
3050 basic_string<_CharT, _Traits, _Allocator>&
3051 basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s)
3053 _LIBCPP_ASSERT(__s != nullptr, "string::replace received nullptr");
3054 return replace(__pos, __n1, __s, traits_type::length(__s));
3057 template <class _CharT, class _Traits, class _Allocator>
3058 inline _LIBCPP_INLINE_VISIBILITY
3059 basic_string<_CharT, _Traits, _Allocator>&
3060 basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const basic_string& __str)
3062 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1),
3063 __str.data(), __str.size());
3066 template <class _CharT, class _Traits, class _Allocator>
3067 inline _LIBCPP_INLINE_VISIBILITY
3068 basic_string<_CharT, _Traits, _Allocator>&
3069 basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n)
3071 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s, __n);
3074 template <class _CharT, class _Traits, class _Allocator>
3075 inline _LIBCPP_INLINE_VISIBILITY
3076 basic_string<_CharT, _Traits, _Allocator>&
3077 basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s)
3079 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s);
3082 template <class _CharT, class _Traits, class _Allocator>
3083 inline _LIBCPP_INLINE_VISIBILITY
3084 basic_string<_CharT, _Traits, _Allocator>&
3085 basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c)
3087 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __n, __c);
3092 template <class _CharT, class _Traits, class _Allocator>
3093 basic_string<_CharT, _Traits, _Allocator>&
3094 basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, size_type __n)
3096 size_type __sz = size();
3098 this->__throw_out_of_range();
3101 value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());
3102 __n = _VSTD::min(__n, __sz - __pos);
3103 size_type __n_move = __sz - __pos - __n;
3105 traits_type::move(__p + __pos, __p + __pos + __n, __n_move);
3108 __invalidate_iterators_past(__sz);
3109 traits_type::assign(__p[__sz], value_type());
3114 template <class _CharT, class _Traits, class _Allocator>
3115 inline _LIBCPP_INLINE_VISIBILITY
3116 typename basic_string<_CharT, _Traits, _Allocator>::iterator
3117 basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos)
3119 #if _LIBCPP_DEBUG_LEVEL >= 2
3120 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
3121 "string::erase(iterator) called with an iterator not"
3122 " referring to this string");
3124 _LIBCPP_ASSERT(__pos != end(),
3125 "string::erase(iterator) called with a non-dereferenceable iterator");
3126 iterator __b = begin();
3127 size_type __r = static_cast<size_type>(__pos - __b);
3129 return __b + static_cast<difference_type>(__r);
3132 template <class _CharT, class _Traits, class _Allocator>
3133 inline _LIBCPP_INLINE_VISIBILITY
3134 typename basic_string<_CharT, _Traits, _Allocator>::iterator
3135 basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last)
3137 #if _LIBCPP_DEBUG_LEVEL >= 2
3138 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this,
3139 "string::erase(iterator, iterator) called with an iterator not"
3140 " referring to this string");
3142 _LIBCPP_ASSERT(__first <= __last, "string::erase(first, last) called with invalid range");
3143 iterator __b = begin();
3144 size_type __r = static_cast<size_type>(__first - __b);
3145 erase(__r, static_cast<size_type>(__last - __first));
3146 return __b + static_cast<difference_type>(__r);
3149 template <class _CharT, class _Traits, class _Allocator>
3150 inline _LIBCPP_INLINE_VISIBILITY
3152 basic_string<_CharT, _Traits, _Allocator>::pop_back()
3154 _LIBCPP_ASSERT(!empty(), "string::pop_back(): string is already empty");
3158 __sz = __get_long_size() - 1;
3159 __set_long_size(__sz);
3160 traits_type::assign(*(__get_long_pointer() + __sz), value_type());
3164 __sz = __get_short_size() - 1;
3165 __set_short_size(__sz);
3166 traits_type::assign(*(__get_short_pointer() + __sz), value_type());
3168 __invalidate_iterators_past(__sz);
3171 template <class _CharT, class _Traits, class _Allocator>
3172 inline _LIBCPP_INLINE_VISIBILITY
3174 basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT
3176 __invalidate_all_iterators();
3179 traits_type::assign(*__get_long_pointer(), value_type());
3184 traits_type::assign(*__get_short_pointer(), value_type());
3185 __set_short_size(0);
3189 template <class _CharT, class _Traits, class _Allocator>
3190 inline _LIBCPP_INLINE_VISIBILITY
3192 basic_string<_CharT, _Traits, _Allocator>::__erase_to_end(size_type __pos)
3196 traits_type::assign(*(__get_long_pointer() + __pos), value_type());
3197 __set_long_size(__pos);
3201 traits_type::assign(*(__get_short_pointer() + __pos), value_type());
3202 __set_short_size(__pos);
3204 __invalidate_iterators_past(__pos);
3207 template <class _CharT, class _Traits, class _Allocator>
3209 basic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c)
3211 size_type __sz = size();
3213 append(__n - __sz, __c);
3215 __erase_to_end(__n);
3218 template <class _CharT, class _Traits, class _Allocator>
3219 inline _LIBCPP_INLINE_VISIBILITY
3220 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3221 basic_string<_CharT, _Traits, _Allocator>::max_size() const _NOEXCEPT
3223 size_type __m = __alloc_traits::max_size(__alloc());
3224 #if _LIBCPP_BIG_ENDIAN
3225 return (__m <= ~__long_mask ? __m : __m/2) - __alignment;
3227 return __m - __alignment;
3231 template <class _CharT, class _Traits, class _Allocator>
3233 basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __res_arg)
3235 if (__res_arg > max_size())
3236 this->__throw_length_error();
3237 size_type __cap = capacity();
3238 size_type __sz = size();
3239 __res_arg = _VSTD::max(__res_arg, __sz);
3240 __res_arg = __recommend(__res_arg);
3241 if (__res_arg != __cap)
3243 pointer __new_data, __p;
3244 bool __was_long, __now_long;
3245 if (__res_arg == __min_cap - 1)
3249 __new_data = __get_short_pointer();
3250 __p = __get_long_pointer();
3254 if (__res_arg > __cap)
3255 __new_data = __alloc_traits::allocate(__alloc(), __res_arg+1);
3258 #ifndef _LIBCPP_NO_EXCEPTIONS
3261 #endif // _LIBCPP_NO_EXCEPTIONS
3262 __new_data = __alloc_traits::allocate(__alloc(), __res_arg+1);
3263 #ifndef _LIBCPP_NO_EXCEPTIONS
3269 #else // _LIBCPP_NO_EXCEPTIONS
3270 if (__new_data == nullptr)
3272 #endif // _LIBCPP_NO_EXCEPTIONS
3275 __was_long = __is_long();
3276 __p = __get_pointer();
3278 traits_type::copy(_VSTD::__to_raw_pointer(__new_data),
3279 _VSTD::__to_raw_pointer(__p), size()+1);
3281 __alloc_traits::deallocate(__alloc(), __p, __cap+1);
3284 __set_long_cap(__res_arg+1);
3285 __set_long_size(__sz);
3286 __set_long_pointer(__new_data);
3289 __set_short_size(__sz);
3290 __invalidate_all_iterators();
3294 template <class _CharT, class _Traits, class _Allocator>
3295 inline _LIBCPP_INLINE_VISIBILITY
3296 typename basic_string<_CharT, _Traits, _Allocator>::const_reference
3297 basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const
3299 _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
3300 return *(data() + __pos);
3303 template <class _CharT, class _Traits, class _Allocator>
3304 inline _LIBCPP_INLINE_VISIBILITY
3305 typename basic_string<_CharT, _Traits, _Allocator>::reference
3306 basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos)
3308 _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
3309 return *(__get_pointer() + __pos);
3312 template <class _CharT, class _Traits, class _Allocator>
3313 typename basic_string<_CharT, _Traits, _Allocator>::const_reference
3314 basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const
3317 this->__throw_out_of_range();
3318 return (*this)[__n];
3321 template <class _CharT, class _Traits, class _Allocator>
3322 typename basic_string<_CharT, _Traits, _Allocator>::reference
3323 basic_string<_CharT, _Traits, _Allocator>::at(size_type __n)
3326 this->__throw_out_of_range();
3327 return (*this)[__n];
3330 template <class _CharT, class _Traits, class _Allocator>
3331 inline _LIBCPP_INLINE_VISIBILITY
3332 typename basic_string<_CharT, _Traits, _Allocator>::reference
3333 basic_string<_CharT, _Traits, _Allocator>::front()
3335 _LIBCPP_ASSERT(!empty(), "string::front(): string is empty");
3336 return *__get_pointer();
3339 template <class _CharT, class _Traits, class _Allocator>
3340 inline _LIBCPP_INLINE_VISIBILITY
3341 typename basic_string<_CharT, _Traits, _Allocator>::const_reference
3342 basic_string<_CharT, _Traits, _Allocator>::front() const
3344 _LIBCPP_ASSERT(!empty(), "string::front(): string is empty");
3348 template <class _CharT, class _Traits, class _Allocator>
3349 inline _LIBCPP_INLINE_VISIBILITY
3350 typename basic_string<_CharT, _Traits, _Allocator>::reference
3351 basic_string<_CharT, _Traits, _Allocator>::back()
3353 _LIBCPP_ASSERT(!empty(), "string::back(): string is empty");
3354 return *(__get_pointer() + size() - 1);
3357 template <class _CharT, class _Traits, class _Allocator>
3358 inline _LIBCPP_INLINE_VISIBILITY
3359 typename basic_string<_CharT, _Traits, _Allocator>::const_reference
3360 basic_string<_CharT, _Traits, _Allocator>::back() const
3362 _LIBCPP_ASSERT(!empty(), "string::back(): string is empty");
3363 return *(data() + size() - 1);
3366 template <class _CharT, class _Traits, class _Allocator>
3367 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3368 basic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n, size_type __pos) const
3370 size_type __sz = size();
3372 this->__throw_out_of_range();
3373 size_type __rlen = _VSTD::min(__n, __sz - __pos);
3374 traits_type::copy(__s, data() + __pos, __rlen);
3378 template <class _CharT, class _Traits, class _Allocator>
3379 inline _LIBCPP_INLINE_VISIBILITY
3380 basic_string<_CharT, _Traits, _Allocator>
3381 basic_string<_CharT, _Traits, _Allocator>::substr(size_type __pos, size_type __n) const
3383 return basic_string(*this, __pos, __n, __alloc());
3386 template <class _CharT, class _Traits, class _Allocator>
3387 inline _LIBCPP_INLINE_VISIBILITY
3389 basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str)
3390 #if _LIBCPP_STD_VER >= 14
3393 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
3394 __is_nothrow_swappable<allocator_type>::value)
3397 #if _LIBCPP_DEBUG_LEVEL >= 2
3399 __get_db()->__invalidate_all(this);
3400 if (!__str.__is_long())
3401 __get_db()->__invalidate_all(&__str);
3402 __get_db()->swap(this, &__str);
3404 _VSTD::swap(__r_.first(), __str.__r_.first());
3405 __swap_allocator(__alloc(), __str.__alloc());
3410 template <class _Traits>
3411 struct _LIBCPP_HIDDEN __traits_eq
3413 typedef typename _Traits::char_type char_type;
3414 _LIBCPP_INLINE_VISIBILITY
3415 bool operator()(const char_type& __x, const char_type& __y) _NOEXCEPT
3416 {return _Traits::eq(__x, __y);}
3419 template<class _CharT, class _Traits, class _Allocator>
3420 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3421 basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
3423 size_type __n) const _NOEXCEPT
3425 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find(): received nullptr");
3426 return _VSTD::__str_find<value_type, size_type, traits_type, npos>
3427 (data(), size(), __s, __pos, __n);
3430 template<class _CharT, class _Traits, class _Allocator>
3431 inline _LIBCPP_INLINE_VISIBILITY
3432 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3433 basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str,
3434 size_type __pos) const _NOEXCEPT
3436 return _VSTD::__str_find<value_type, size_type, traits_type, npos>
3437 (data(), size(), __str.data(), __pos, __str.size());
3440 template<class _CharT, class _Traits, class _Allocator>
3441 inline _LIBCPP_INLINE_VISIBILITY
3442 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3443 basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
3444 size_type __pos) const _NOEXCEPT
3446 _LIBCPP_ASSERT(__s != nullptr, "string::find(): received nullptr");
3447 return _VSTD::__str_find<value_type, size_type, traits_type, npos>
3448 (data(), size(), __s, __pos, traits_type::length(__s));
3451 template<class _CharT, class _Traits, class _Allocator>
3452 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3453 basic_string<_CharT, _Traits, _Allocator>::find(value_type __c,
3454 size_type __pos) const _NOEXCEPT
3456 return _VSTD::__str_find<value_type, size_type, traits_type, npos>
3457 (data(), size(), __c, __pos);
3462 template<class _CharT, class _Traits, class _Allocator>
3463 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3464 basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
3466 size_type __n) const _NOEXCEPT
3468 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::rfind(): received nullptr");
3469 return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
3470 (data(), size(), __s, __pos, __n);
3473 template<class _CharT, class _Traits, class _Allocator>
3474 inline _LIBCPP_INLINE_VISIBILITY
3475 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3476 basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str,
3477 size_type __pos) const _NOEXCEPT
3479 return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
3480 (data(), size(), __str.data(), __pos, __str.size());
3483 template<class _CharT, class _Traits, class _Allocator>
3484 inline _LIBCPP_INLINE_VISIBILITY
3485 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3486 basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
3487 size_type __pos) const _NOEXCEPT
3489 _LIBCPP_ASSERT(__s != nullptr, "string::rfind(): received nullptr");
3490 return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
3491 (data(), size(), __s, __pos, traits_type::length(__s));
3494 template<class _CharT, class _Traits, class _Allocator>
3495 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3496 basic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c,
3497 size_type __pos) const _NOEXCEPT
3499 return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
3500 (data(), size(), __c, __pos);
3505 template<class _CharT, class _Traits, class _Allocator>
3506 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3507 basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
3509 size_type __n) const _NOEXCEPT
3511 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr");
3512 return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos>
3513 (data(), size(), __s, __pos, __n);
3516 template<class _CharT, class _Traits, class _Allocator>
3517 inline _LIBCPP_INLINE_VISIBILITY
3518 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3519 basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str,
3520 size_type __pos) const _NOEXCEPT
3522 return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos>
3523 (data(), size(), __str.data(), __pos, __str.size());
3526 template<class _CharT, class _Traits, class _Allocator>
3527 inline _LIBCPP_INLINE_VISIBILITY
3528 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3529 basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
3530 size_type __pos) const _NOEXCEPT
3532 _LIBCPP_ASSERT(__s != nullptr, "string::find_first_of(): received nullptr");
3533 return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos>
3534 (data(), size(), __s, __pos, traits_type::length(__s));
3537 template<class _CharT, class _Traits, class _Allocator>
3538 inline _LIBCPP_INLINE_VISIBILITY
3539 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3540 basic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c,
3541 size_type __pos) const _NOEXCEPT
3543 return find(__c, __pos);
3548 template<class _CharT, class _Traits, class _Allocator>
3549 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3550 basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
3552 size_type __n) const _NOEXCEPT
3554 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr");
3555 return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos>
3556 (data(), size(), __s, __pos, __n);
3559 template<class _CharT, class _Traits, class _Allocator>
3560 inline _LIBCPP_INLINE_VISIBILITY
3561 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3562 basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str,
3563 size_type __pos) const _NOEXCEPT
3565 return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos>
3566 (data(), size(), __str.data(), __pos, __str.size());
3569 template<class _CharT, class _Traits, class _Allocator>
3570 inline _LIBCPP_INLINE_VISIBILITY
3571 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3572 basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
3573 size_type __pos) const _NOEXCEPT
3575 _LIBCPP_ASSERT(__s != nullptr, "string::find_last_of(): received nullptr");
3576 return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos>
3577 (data(), size(), __s, __pos, traits_type::length(__s));
3580 template<class _CharT, class _Traits, class _Allocator>
3581 inline _LIBCPP_INLINE_VISIBILITY
3582 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3583 basic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c,
3584 size_type __pos) const _NOEXCEPT
3586 return rfind(__c, __pos);
3589 // find_first_not_of
3591 template<class _CharT, class _Traits, class _Allocator>
3592 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3593 basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s,
3595 size_type __n) const _NOEXCEPT
3597 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr");
3598 return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>
3599 (data(), size(), __s, __pos, __n);
3602 template<class _CharT, class _Traits, class _Allocator>
3603 inline _LIBCPP_INLINE_VISIBILITY
3604 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3605 basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string& __str,
3606 size_type __pos) const _NOEXCEPT
3608 return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>
3609 (data(), size(), __str.data(), __pos, __str.size());
3612 template<class _CharT, class _Traits, class _Allocator>
3613 inline _LIBCPP_INLINE_VISIBILITY
3614 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3615 basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s,
3616 size_type __pos) const _NOEXCEPT
3618 _LIBCPP_ASSERT(__s != nullptr, "string::find_first_not_of(): received nullptr");
3619 return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>
3620 (data(), size(), __s, __pos, traits_type::length(__s));
3623 template<class _CharT, class _Traits, class _Allocator>
3624 inline _LIBCPP_INLINE_VISIBILITY
3625 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3626 basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c,
3627 size_type __pos) const _NOEXCEPT
3629 return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>
3630 (data(), size(), __c, __pos);
3635 template<class _CharT, class _Traits, class _Allocator>
3636 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3637 basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s,
3639 size_type __n) const _NOEXCEPT
3641 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr");
3642 return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
3643 (data(), size(), __s, __pos, __n);
3646 template<class _CharT, class _Traits, class _Allocator>
3647 inline _LIBCPP_INLINE_VISIBILITY
3648 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3649 basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string& __str,
3650 size_type __pos) const _NOEXCEPT
3652 return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
3653 (data(), size(), __str.data(), __pos, __str.size());
3656 template<class _CharT, class _Traits, class _Allocator>
3657 inline _LIBCPP_INLINE_VISIBILITY
3658 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3659 basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s,
3660 size_type __pos) const _NOEXCEPT
3662 _LIBCPP_ASSERT(__s != nullptr, "string::find_last_not_of(): received nullptr");
3663 return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
3664 (data(), size(), __s, __pos, traits_type::length(__s));
3667 template<class _CharT, class _Traits, class _Allocator>
3668 inline _LIBCPP_INLINE_VISIBILITY
3669 typename basic_string<_CharT, _Traits, _Allocator>::size_type
3670 basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c,
3671 size_type __pos) const _NOEXCEPT
3673 return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
3674 (data(), size(), __c, __pos);
3679 template <class _CharT, class _Traits, class _Allocator>
3680 inline _LIBCPP_INLINE_VISIBILITY
3682 basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT
3684 size_t __lhs_sz = size();
3685 size_t __rhs_sz = __str.size();
3686 int __result = traits_type::compare(data(), __str.data(),
3687 _VSTD::min(__lhs_sz, __rhs_sz));
3690 if (__lhs_sz < __rhs_sz)
3692 if (__lhs_sz > __rhs_sz)
3697 template <class _CharT, class _Traits, class _Allocator>
3698 inline _LIBCPP_INLINE_VISIBILITY
3700 basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
3702 const basic_string& __str) const
3704 return compare(__pos1, __n1, __str.data(), __str.size());
3707 template <class _CharT, class _Traits, class _Allocator>
3709 basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
3711 const basic_string& __str,
3713 size_type __n2) const
3715 size_type __sz = __str.size();
3717 this->__throw_out_of_range();
3718 return compare(__pos1, __n1, __str.data() + __pos2, _VSTD::min(__n2,
3722 template <class _CharT, class _Traits, class _Allocator>
3724 basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT
3726 _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr");
3727 return compare(0, npos, __s, traits_type::length(__s));
3730 template <class _CharT, class _Traits, class _Allocator>
3732 basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
3734 const value_type* __s) const
3736 _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr");
3737 return compare(__pos1, __n1, __s, traits_type::length(__s));
3740 template <class _CharT, class _Traits, class _Allocator>
3742 basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
3744 const value_type* __s,
3745 size_type __n2) const
3747 _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr");
3748 size_type __sz = size();
3749 if (__pos1 > __sz || __n2 == npos)
3750 this->__throw_out_of_range();
3751 size_type __rlen = _VSTD::min(__n1, __sz - __pos1);
3752 int __r = traits_type::compare(data() + __pos1, __s, _VSTD::min(__rlen, __n2));
3757 else if (__rlen > __n2)
3765 template<class _CharT, class _Traits, class _Allocator>
3766 inline _LIBCPP_INLINE_VISIBILITY
3768 basic_string<_CharT, _Traits, _Allocator>::__invariants() const
3770 if (size() > capacity())
3772 if (capacity() < __min_cap - 1)
3776 if (data()[size()] != value_type(0))
3783 template<class _CharT, class _Traits, class _Allocator>
3784 inline _LIBCPP_INLINE_VISIBILITY
3786 operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3787 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
3789 size_t __lhs_sz = __lhs.size();
3790 return __lhs_sz == __rhs.size() && _Traits::compare(__lhs.data(),
3795 template<class _Allocator>
3796 inline _LIBCPP_INLINE_VISIBILITY
3798 operator==(const basic_string<char, char_traits<char>, _Allocator>& __lhs,
3799 const basic_string<char, char_traits<char>, _Allocator>& __rhs) _NOEXCEPT
3801 size_t __lhs_sz = __lhs.size();
3802 if (__lhs_sz != __rhs.size())
3804 const char* __lp = __lhs.data();
3805 const char* __rp = __rhs.data();
3806 if (__lhs.__is_long())
3807 return char_traits<char>::compare(__lp, __rp, __lhs_sz) == 0;
3808 for (; __lhs_sz != 0; --__lhs_sz, ++__lp, ++__rp)
3814 template<class _CharT, class _Traits, class _Allocator>
3815 inline _LIBCPP_INLINE_VISIBILITY
3817 operator==(const _CharT* __lhs,
3818 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
3820 typedef basic_string<_CharT, _Traits, _Allocator> _String;
3821 _LIBCPP_ASSERT(__lhs != nullptr, "operator==(char*, basic_string): received nullptr");
3822 size_t __lhs_len = _Traits::length(__lhs);
3823 if (__lhs_len != __rhs.size()) return false;
3824 return __rhs.compare(0, _String::npos, __lhs, __lhs_len) == 0;
3827 template<class _CharT, class _Traits, class _Allocator>
3828 inline _LIBCPP_INLINE_VISIBILITY
3830 operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
3831 const _CharT* __rhs) _NOEXCEPT
3833 typedef basic_string<_CharT, _Traits, _Allocator> _String;
3834 _LIBCPP_ASSERT(__rhs != nullptr, "operator==(basic_string, char*): received nullptr");
3835 size_t __rhs_len = _Traits::length(__rhs);
3836 if (__rhs_len != __lhs.size()) return false;
3837 return __lhs.compare(0, _String::npos, __rhs, __rhs_len) == 0;
3842 template<class _CharT, class _Traits, class _Allocator>
3843 inline _LIBCPP_INLINE_VISIBILITY
3845 operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
3846 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
3848 return !(__lhs == __rhs);
3851 template<class _CharT, class _Traits, class _Allocator>
3852 inline _LIBCPP_INLINE_VISIBILITY
3854 operator!=(const _CharT* __lhs,
3855 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
3857 return !(__lhs == __rhs);
3860 template<class _CharT, class _Traits, class _Allocator>
3861 inline _LIBCPP_INLINE_VISIBILITY
3863 operator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3864 const _CharT* __rhs) _NOEXCEPT
3866 return !(__lhs == __rhs);
3871 template<class _CharT, class _Traits, class _Allocator>
3872 inline _LIBCPP_INLINE_VISIBILITY
3874 operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3875 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
3877 return __lhs.compare(__rhs) < 0;
3880 template<class _CharT, class _Traits, class _Allocator>
3881 inline _LIBCPP_INLINE_VISIBILITY
3883 operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3884 const _CharT* __rhs) _NOEXCEPT
3886 return __lhs.compare(__rhs) < 0;
3889 template<class _CharT, class _Traits, class _Allocator>
3890 inline _LIBCPP_INLINE_VISIBILITY
3892 operator< (const _CharT* __lhs,
3893 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
3895 return __rhs.compare(__lhs) > 0;
3900 template<class _CharT, class _Traits, class _Allocator>
3901 inline _LIBCPP_INLINE_VISIBILITY
3903 operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3904 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
3906 return __rhs < __lhs;
3909 template<class _CharT, class _Traits, class _Allocator>
3910 inline _LIBCPP_INLINE_VISIBILITY
3912 operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3913 const _CharT* __rhs) _NOEXCEPT
3915 return __rhs < __lhs;
3918 template<class _CharT, class _Traits, class _Allocator>
3919 inline _LIBCPP_INLINE_VISIBILITY
3921 operator> (const _CharT* __lhs,
3922 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
3924 return __rhs < __lhs;
3929 template<class _CharT, class _Traits, class _Allocator>
3930 inline _LIBCPP_INLINE_VISIBILITY
3932 operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3933 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
3935 return !(__rhs < __lhs);
3938 template<class _CharT, class _Traits, class _Allocator>
3939 inline _LIBCPP_INLINE_VISIBILITY
3941 operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3942 const _CharT* __rhs) _NOEXCEPT
3944 return !(__rhs < __lhs);
3947 template<class _CharT, class _Traits, class _Allocator>
3948 inline _LIBCPP_INLINE_VISIBILITY
3950 operator<=(const _CharT* __lhs,
3951 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
3953 return !(__rhs < __lhs);
3958 template<class _CharT, class _Traits, class _Allocator>
3959 inline _LIBCPP_INLINE_VISIBILITY
3961 operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3962 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
3964 return !(__lhs < __rhs);
3967 template<class _CharT, class _Traits, class _Allocator>
3968 inline _LIBCPP_INLINE_VISIBILITY
3970 operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3971 const _CharT* __rhs) _NOEXCEPT
3973 return !(__lhs < __rhs);
3976 template<class _CharT, class _Traits, class _Allocator>
3977 inline _LIBCPP_INLINE_VISIBILITY
3979 operator>=(const _CharT* __lhs,
3980 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
3982 return !(__lhs < __rhs);
3987 template<class _CharT, class _Traits, class _Allocator>
3988 basic_string<_CharT, _Traits, _Allocator>
3989 operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3990 const basic_string<_CharT, _Traits, _Allocator>& __rhs)
3992 basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator());
3993 typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size();
3994 typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size();
3995 __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + __rhs_sz);
3996 __r.append(__rhs.data(), __rhs_sz);
4000 template<class _CharT, class _Traits, class _Allocator>
4001 basic_string<_CharT, _Traits, _Allocator>
4002 operator+(const _CharT* __lhs , const basic_string<_CharT,_Traits,_Allocator>& __rhs)
4004 basic_string<_CharT, _Traits, _Allocator> __r(__rhs.get_allocator());
4005 typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = _Traits::length(__lhs);
4006 typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size();
4007 __r.__init(__lhs, __lhs_sz, __lhs_sz + __rhs_sz);
4008 __r.append(__rhs.data(), __rhs_sz);
4012 template<class _CharT, class _Traits, class _Allocator>
4013 basic_string<_CharT, _Traits, _Allocator>
4014 operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Allocator>& __rhs)
4016 basic_string<_CharT, _Traits, _Allocator> __r(__rhs.get_allocator());
4017 typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size();
4018 __r.__init(&__lhs, 1, 1 + __rhs_sz);
4019 __r.append(__rhs.data(), __rhs_sz);
4023 template<class _CharT, class _Traits, class _Allocator>
4024 basic_string<_CharT, _Traits, _Allocator>
4025 operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs)
4027 basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator());
4028 typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size();
4029 typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = _Traits::length(__rhs);
4030 __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + __rhs_sz);
4031 __r.append(__rhs, __rhs_sz);
4035 template<class _CharT, class _Traits, class _Allocator>
4036 basic_string<_CharT, _Traits, _Allocator>
4037 operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs)
4039 basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator());
4040 typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size();
4041 __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + 1);
4042 __r.push_back(__rhs);
4046 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
4048 template<class _CharT, class _Traits, class _Allocator>
4049 inline _LIBCPP_INLINE_VISIBILITY
4050 basic_string<_CharT, _Traits, _Allocator>
4051 operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs)
4053 return _VSTD::move(__lhs.append(__rhs));
4056 template<class _CharT, class _Traits, class _Allocator>
4057 inline _LIBCPP_INLINE_VISIBILITY
4058 basic_string<_CharT, _Traits, _Allocator>
4059 operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs)
4061 return _VSTD::move(__rhs.insert(0, __lhs));
4064 template<class _CharT, class _Traits, class _Allocator>
4065 inline _LIBCPP_INLINE_VISIBILITY
4066 basic_string<_CharT, _Traits, _Allocator>
4067 operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs)
4069 return _VSTD::move(__lhs.append(__rhs));
4072 template<class _CharT, class _Traits, class _Allocator>
4073 inline _LIBCPP_INLINE_VISIBILITY
4074 basic_string<_CharT, _Traits, _Allocator>
4075 operator+(const _CharT* __lhs , basic_string<_CharT,_Traits,_Allocator>&& __rhs)
4077 return _VSTD::move(__rhs.insert(0, __lhs));
4080 template<class _CharT, class _Traits, class _Allocator>
4081 inline _LIBCPP_INLINE_VISIBILITY
4082 basic_string<_CharT, _Traits, _Allocator>
4083 operator+(_CharT __lhs, basic_string<_CharT,_Traits,_Allocator>&& __rhs)
4085 __rhs.insert(__rhs.begin(), __lhs);
4086 return _VSTD::move(__rhs);
4089 template<class _CharT, class _Traits, class _Allocator>
4090 inline _LIBCPP_INLINE_VISIBILITY
4091 basic_string<_CharT, _Traits, _Allocator>
4092 operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const _CharT* __rhs)
4094 return _VSTD::move(__lhs.append(__rhs));
4097 template<class _CharT, class _Traits, class _Allocator>
4098 inline _LIBCPP_INLINE_VISIBILITY
4099 basic_string<_CharT, _Traits, _Allocator>
4100 operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT __rhs)
4102 __lhs.push_back(__rhs);
4103 return _VSTD::move(__lhs);
4106 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
4110 template<class _CharT, class _Traits, class _Allocator>
4111 inline _LIBCPP_INLINE_VISIBILITY
4113 swap(basic_string<_CharT, _Traits, _Allocator>& __lhs,
4114 basic_string<_CharT, _Traits, _Allocator>& __rhs)
4115 _NOEXCEPT_(_NOEXCEPT_(__lhs.swap(__rhs)))
4120 #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
4122 typedef basic_string<char16_t> u16string;
4123 typedef basic_string<char32_t> u32string;
4125 #endif // _LIBCPP_HAS_NO_UNICODE_CHARS
4127 _LIBCPP_FUNC_VIS int stoi (const string& __str, size_t* __idx = 0, int __base = 10);
4128 _LIBCPP_FUNC_VIS long stol (const string& __str, size_t* __idx = 0, int __base = 10);
4129 _LIBCPP_FUNC_VIS unsigned long stoul (const string& __str, size_t* __idx = 0, int __base = 10);
4130 _LIBCPP_FUNC_VIS long long stoll (const string& __str, size_t* __idx = 0, int __base = 10);
4131 _LIBCPP_FUNC_VIS unsigned long long stoull(const string& __str, size_t* __idx = 0, int __base = 10);
4133 _LIBCPP_FUNC_VIS float stof (const string& __str, size_t* __idx = 0);
4134 _LIBCPP_FUNC_VIS double stod (const string& __str, size_t* __idx = 0);
4135 _LIBCPP_FUNC_VIS long double stold(const string& __str, size_t* __idx = 0);
4137 _LIBCPP_FUNC_VIS string to_string(int __val);
4138 _LIBCPP_FUNC_VIS string to_string(unsigned __val);
4139 _LIBCPP_FUNC_VIS string to_string(long __val);
4140 _LIBCPP_FUNC_VIS string to_string(unsigned long __val);
4141 _LIBCPP_FUNC_VIS string to_string(long long __val);
4142 _LIBCPP_FUNC_VIS string to_string(unsigned long long __val);
4143 _LIBCPP_FUNC_VIS string to_string(float __val);
4144 _LIBCPP_FUNC_VIS string to_string(double __val);
4145 _LIBCPP_FUNC_VIS string to_string(long double __val);
4147 _LIBCPP_FUNC_VIS int stoi (const wstring& __str, size_t* __idx = 0, int __base = 10);
4148 _LIBCPP_FUNC_VIS long stol (const wstring& __str, size_t* __idx = 0, int __base = 10);
4149 _LIBCPP_FUNC_VIS unsigned long stoul (const wstring& __str, size_t* __idx = 0, int __base = 10);
4150 _LIBCPP_FUNC_VIS long long stoll (const wstring& __str, size_t* __idx = 0, int __base = 10);
4151 _LIBCPP_FUNC_VIS unsigned long long stoull(const wstring& __str, size_t* __idx = 0, int __base = 10);
4153 _LIBCPP_FUNC_VIS float stof (const wstring& __str, size_t* __idx = 0);
4154 _LIBCPP_FUNC_VIS double stod (const wstring& __str, size_t* __idx = 0);
4155 _LIBCPP_FUNC_VIS long double stold(const wstring& __str, size_t* __idx = 0);
4157 _LIBCPP_FUNC_VIS wstring to_wstring(int __val);
4158 _LIBCPP_FUNC_VIS wstring to_wstring(unsigned __val);
4159 _LIBCPP_FUNC_VIS wstring to_wstring(long __val);
4160 _LIBCPP_FUNC_VIS wstring to_wstring(unsigned long __val);
4161 _LIBCPP_FUNC_VIS wstring to_wstring(long long __val);
4162 _LIBCPP_FUNC_VIS wstring to_wstring(unsigned long long __val);
4163 _LIBCPP_FUNC_VIS wstring to_wstring(float __val);
4164 _LIBCPP_FUNC_VIS wstring to_wstring(double __val);
4165 _LIBCPP_FUNC_VIS wstring to_wstring(long double __val);
4167 template<class _CharT, class _Traits, class _Allocator>
4168 const typename basic_string<_CharT, _Traits, _Allocator>::size_type
4169 basic_string<_CharT, _Traits, _Allocator>::npos;
4171 template<class _CharT, class _Traits, class _Allocator>
4172 struct _LIBCPP_TYPE_VIS_ONLY hash<basic_string<_CharT, _Traits, _Allocator> >
4173 : public unary_function<basic_string<_CharT, _Traits, _Allocator>, size_t>
4176 operator()(const basic_string<_CharT, _Traits, _Allocator>& __val) const _NOEXCEPT;
4179 template<class _CharT, class _Traits, class _Allocator>
4181 hash<basic_string<_CharT, _Traits, _Allocator> >::operator()(
4182 const basic_string<_CharT, _Traits, _Allocator>& __val) const _NOEXCEPT
4184 return __do_string_hash(__val.data(), __val.data() + __val.size());
4187 template<class _CharT, class _Traits, class _Allocator>
4188 basic_ostream<_CharT, _Traits>&
4189 operator<<(basic_ostream<_CharT, _Traits>& __os,
4190 const basic_string<_CharT, _Traits, _Allocator>& __str);
4192 template<class _CharT, class _Traits, class _Allocator>
4193 basic_istream<_CharT, _Traits>&
4194 operator>>(basic_istream<_CharT, _Traits>& __is,
4195 basic_string<_CharT, _Traits, _Allocator>& __str);
4197 template<class _CharT, class _Traits, class _Allocator>
4198 basic_istream<_CharT, _Traits>&
4199 getline(basic_istream<_CharT, _Traits>& __is,
4200 basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm);
4202 template<class _CharT, class _Traits, class _Allocator>
4203 inline _LIBCPP_INLINE_VISIBILITY
4204 basic_istream<_CharT, _Traits>&
4205 getline(basic_istream<_CharT, _Traits>& __is,
4206 basic_string<_CharT, _Traits, _Allocator>& __str);
4208 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
4210 template<class _CharT, class _Traits, class _Allocator>
4211 inline _LIBCPP_INLINE_VISIBILITY
4212 basic_istream<_CharT, _Traits>&
4213 getline(basic_istream<_CharT, _Traits>&& __is,
4214 basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm);
4216 template<class _CharT, class _Traits, class _Allocator>
4217 inline _LIBCPP_INLINE_VISIBILITY
4218 basic_istream<_CharT, _Traits>&
4219 getline(basic_istream<_CharT, _Traits>&& __is,
4220 basic_string<_CharT, _Traits, _Allocator>& __str);
4222 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
4224 #if _LIBCPP_DEBUG_LEVEL >= 2
4226 template<class _CharT, class _Traits, class _Allocator>
4228 basic_string<_CharT, _Traits, _Allocator>::__dereferenceable(const const_iterator* __i) const
4230 return this->data() <= _VSTD::__to_raw_pointer(__i->base()) &&
4231 _VSTD::__to_raw_pointer(__i->base()) < this->data() + this->size();
4234 template<class _CharT, class _Traits, class _Allocator>
4236 basic_string<_CharT, _Traits, _Allocator>::__decrementable(const const_iterator* __i) const
4238 return this->data() < _VSTD::__to_raw_pointer(__i->base()) &&
4239 _VSTD::__to_raw_pointer(__i->base()) <= this->data() + this->size();
4242 template<class _CharT, class _Traits, class _Allocator>
4244 basic_string<_CharT, _Traits, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const
4246 const value_type* __p = _VSTD::__to_raw_pointer(__i->base()) + __n;
4247 return this->data() <= __p && __p <= this->data() + this->size();
4250 template<class _CharT, class _Traits, class _Allocator>
4252 basic_string<_CharT, _Traits, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const
4254 const value_type* __p = _VSTD::__to_raw_pointer(__i->base()) + __n;
4255 return this->data() <= __p && __p < this->data() + this->size();
4258 #endif // _LIBCPP_DEBUG_LEVEL >= 2
4260 #if _LIBCPP_STD_VER > 11
4261 // Literal suffixes for basic_string [basic.string.literals]
4262 inline namespace literals
4264 inline namespace string_literals
4266 inline _LIBCPP_INLINE_VISIBILITY
4267 basic_string<char> operator "" s( const char *__str, size_t __len )
4269 return basic_string<char> (__str, __len);
4272 inline _LIBCPP_INLINE_VISIBILITY
4273 basic_string<wchar_t> operator "" s( const wchar_t *__str, size_t __len )
4275 return basic_string<wchar_t> (__str, __len);
4278 inline _LIBCPP_INLINE_VISIBILITY
4279 basic_string<char16_t> operator "" s( const char16_t *__str, size_t __len )
4281 return basic_string<char16_t> (__str, __len);
4284 inline _LIBCPP_INLINE_VISIBILITY
4285 basic_string<char32_t> operator "" s( const char32_t *__str, size_t __len )
4287 return basic_string<char32_t> (__str, __len);
4293 _LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_string<char>)
4294 _LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_string<wchar_t>)
4295 _LIBCPP_EXTERN_TEMPLATE(string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&))
4297 _LIBCPP_END_NAMESPACE_STD
4299 #endif // _LIBCPP_STRING