1// -*- C++ -*- 2//===--------------------------- string -----------------------------------===// 3// 4// The LLVM Compiler Infrastructure 5// 6// This file is distributed under the University of Illinois Open Source 7// License. See LICENSE.TXT for details. 8// 9//===----------------------------------------------------------------------===// 10 11#ifndef _LIBCPP_STRING 12#define _LIBCPP_STRING 13 14/* 15 string synopsis 16 17namespace std 18{ 19 20template <class stateT> 21class fpos 22{ 23private: 24 stateT st; 25public: 26 fpos(streamoff = streamoff()); 27 28 operator streamoff() const; 29 30 stateT state() const; 31 void state(stateT); 32 33 fpos& operator+=(streamoff); 34 fpos operator+ (streamoff) const; 35 fpos& operator-=(streamoff); 36 fpos operator- (streamoff) const; 37}; 38 39template <class stateT> streamoff operator-(const fpos<stateT>& x, const fpos<stateT>& y); 40 41template <class stateT> bool operator==(const fpos<stateT>& x, const fpos<stateT>& y); 42template <class stateT> bool operator!=(const fpos<stateT>& x, const fpos<stateT>& y); 43 44template <class charT> 45struct char_traits 46{ 47 typedef charT char_type; 48 typedef ... int_type; 49 typedef streamoff off_type; 50 typedef streampos pos_type; 51 typedef mbstate_t state_type; 52 53 static void assign(char_type& c1, const char_type& c2) 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; 56 57 static int compare(const char_type* s1, const char_type* s2, size_t n); 58 static size_t length(const char_type* s); 59 static const char_type* find(const char_type* s, size_t n, const char_type& a); 60 static char_type* move(char_type* s1, const char_type* s2, size_t n); 61 static char_type* copy(char_type* s1, const char_type* s2, size_t n); 62 static char_type* assign(char_type* s, size_t n, char_type a); 63 64 static 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; 69}; 70 71template <> struct char_traits<char>; 72template <> struct char_traits<wchar_t>; 73 74template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> > 75class basic_string 76{ 77public: 78// types: 79 typedef traits traits_type; 80 typedef typename traits_type::char_type value_type; 81 typedef Allocator allocator_type; 82 typedef typename allocator_type::size_type size_type; 83 typedef typename allocator_type::difference_type difference_type; 84 typedef typename allocator_type::reference reference; 85 typedef typename allocator_type::const_reference const_reference; 86 typedef typename allocator_type::pointer pointer; 87 typedef typename allocator_type::const_pointer const_pointer; 88 typedef implementation-defined iterator; 89 typedef implementation-defined const_iterator; 90 typedef std::reverse_iterator<iterator> reverse_iterator; 91 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 92 93 static const size_type npos = -1; 94 95 basic_string() 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&); 112 113 ~basic_string(); 114 115 basic_string& operator=(const basic_string& str); 116 basic_string& operator=(basic_string&& str) 117 noexcept( 118 allocator_type::propagate_on_container_move_assignment::value && 119 is_nothrow_move_assignable<allocator_type>::value); 120 basic_string& operator=(const value_type* s); 121 basic_string& operator=(value_type c); 122 basic_string& operator=(initializer_list<value_type>); 123 124 iterator begin() noexcept; 125 const_iterator begin() const noexcept; 126 iterator end() noexcept; 127 const_iterator end() const noexcept; 128 129 reverse_iterator rbegin() noexcept; 130 const_reverse_iterator rbegin() const noexcept; 131 reverse_iterator rend() noexcept; 132 const_reverse_iterator rend() const noexcept; 133 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; 138 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; 143 144 void resize(size_type n, value_type c); 145 void resize(size_type n); 146 147 void reserve(size_type res_arg = 0); 148 void shrink_to_fit(); 149 void clear() noexcept; 150 bool empty() const noexcept; 151 152 const_reference operator[](size_type pos) const; 153 reference operator[](size_type pos); 154 155 const_reference at(size_type n) const; 156 reference at(size_type n); 157 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>); 162 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>); 171 172 void push_back(value_type c); 173 void pop_back(); 174 reference front(); 175 const_reference front() const; 176 reference back(); 177 const_reference back() const; 178 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>); 188 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>); 200 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); 204 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>); 218 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; 221 222 void swap(basic_string& str) 223 noexcept(!allocator_type::propagate_on_container_swap::value || 224 __is_nothrow_swappable<allocator_type>::value) 225 226 const value_type* c_str() const noexcept; 227 const value_type* data() const noexcept; 228 229 allocator_type get_allocator() const noexcept; 230 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; 235 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; 240 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; 245 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; 250 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; 255 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; 260 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; 268 269 bool __invariants() const; 270}; 271 272template<class charT, class traits, class Allocator> 273basic_string<charT, traits, Allocator> 274operator+(const basic_string<charT, traits, Allocator>& lhs, 275 const basic_string<charT, traits, Allocator>& rhs); 276 277template<class charT, class traits, class Allocator> 278basic_string<charT, traits, Allocator> 279operator+(const charT* lhs , const basic_string<charT,traits,Allocator>&rhs); 280 281template<class charT, class traits, class Allocator> 282basic_string<charT, traits, Allocator> 283operator+(charT lhs, const basic_string<charT,traits,Allocator>& rhs); 284 285template<class charT, class traits, class Allocator> 286basic_string<charT, traits, Allocator> 287operator+(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs); 288 289template<class charT, class traits, class Allocator> 290basic_string<charT, traits, Allocator> 291operator+(const basic_string<charT, traits, Allocator>& lhs, charT rhs); 292 293template<class charT, class traits, class Allocator> 294bool operator==(const basic_string<charT, traits, Allocator>& lhs, 295 const basic_string<charT, traits, Allocator>& rhs) noexcept; 296 297template<class charT, class traits, class Allocator> 298bool operator==(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; 299 300template<class charT, class traits, class Allocator> 301bool operator==(const basic_string<charT,traits,Allocator>& lhs, const charT* rhs) noexcept; 302 303template<class charT, class traits, class Allocator> 304bool operator!=(const basic_string<charT,traits,Allocator>& lhs, 305 const basic_string<charT, traits, Allocator>& rhs) noexcept; 306 307template<class charT, class traits, class Allocator> 308bool operator!=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; 309 310template<class charT, class traits, class Allocator> 311bool operator!=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; 312 313template<class charT, class traits, class Allocator> 314bool operator< (const basic_string<charT, traits, Allocator>& lhs, 315 const basic_string<charT, traits, Allocator>& rhs) noexcept; 316 317template<class charT, class traits, class Allocator> 318bool operator< (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; 319 320template<class charT, class traits, class Allocator> 321bool operator< (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; 322 323template<class charT, class traits, class Allocator> 324bool operator> (const basic_string<charT, traits, Allocator>& lhs, 325 const basic_string<charT, traits, Allocator>& rhs) noexcept; 326 327template<class charT, class traits, class Allocator> 328bool operator> (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; 329 330template<class charT, class traits, class Allocator> 331bool operator> (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; 332 333template<class charT, class traits, class Allocator> 334bool operator<=(const basic_string<charT, traits, Allocator>& lhs, 335 const basic_string<charT, traits, Allocator>& rhs) noexcept; 336 337template<class charT, class traits, class Allocator> 338bool operator<=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; 339 340template<class charT, class traits, class Allocator> 341bool operator<=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; 342 343template<class charT, class traits, class Allocator> 344bool operator>=(const basic_string<charT, traits, Allocator>& lhs, 345 const basic_string<charT, traits, Allocator>& rhs) noexcept; 346 347template<class charT, class traits, class Allocator> 348bool operator>=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; 349 350template<class charT, class traits, class Allocator> 351bool operator>=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; 352 353template<class charT, class traits, class Allocator> 354void swap(basic_string<charT, traits, Allocator>& lhs, 355 basic_string<charT, traits, Allocator>& rhs) 356 noexcept(noexcept(lhs.swap(rhs))); 357 358template<class charT, class traits, class Allocator> 359basic_istream<charT, traits>& 360operator>>(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str); 361 362template<class charT, class traits, class Allocator> 363basic_ostream<charT, traits>& 364operator<<(basic_ostream<charT, traits>& os, const basic_string<charT, traits, Allocator>& str); 365 366template<class charT, class traits, class Allocator> 367basic_istream<charT, traits>& 368getline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str, 369 charT delim); 370 371template<class charT, class traits, class Allocator> 372basic_istream<charT, traits>& 373getline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str); 374 375typedef basic_string<char> string; 376typedef basic_string<wchar_t> wstring; 377typedef basic_string<char16_t> u16string; 378typedef basic_string<char32_t> u32string; 379 380int stoi (const string& str, size_t* idx = 0, int base = 10); 381long stol (const string& str, size_t* idx = 0, int base = 10); 382unsigned long stoul (const string& str, size_t* idx = 0, int base = 10); 383long long stoll (const string& str, size_t* idx = 0, int base = 10); 384unsigned long long stoull(const string& str, size_t* idx = 0, int base = 10); 385 386float stof (const string& str, size_t* idx = 0); 387double stod (const string& str, size_t* idx = 0); 388long double stold(const string& str, size_t* idx = 0); 389 390string to_string(int val); 391string to_string(unsigned val); 392string to_string(long val); 393string to_string(unsigned long val); 394string to_string(long long val); 395string to_string(unsigned long long val); 396string to_string(float val); 397string to_string(double val); 398string to_string(long double val); 399 400int stoi (const wstring& str, size_t* idx = 0, int base = 10); 401long stol (const wstring& str, size_t* idx = 0, int base = 10); 402unsigned long stoul (const wstring& str, size_t* idx = 0, int base = 10); 403long long stoll (const wstring& str, size_t* idx = 0, int base = 10); 404unsigned long long stoull(const wstring& str, size_t* idx = 0, int base = 10); 405 406float stof (const wstring& str, size_t* idx = 0); 407double stod (const wstring& str, size_t* idx = 0); 408long double stold(const wstring& str, size_t* idx = 0); 409 410wstring to_wstring(int val); 411wstring to_wstring(unsigned val); 412wstring to_wstring(long val); 413wstring to_wstring(unsigned long val); 414wstring to_wstring(long long val); 415wstring to_wstring(unsigned long long val); 416wstring to_wstring(float val); 417wstring to_wstring(double val); 418wstring to_wstring(long double val); 419 420template <> struct hash<string>; 421template <> struct hash<u16string>; 422template <> struct hash<u32string>; 423template <> struct hash<wstring>; 424 425basic_string<char> operator "" s( const char *str, size_t len ); // C++14 426basic_string<wchar_t> operator "" s( const wchar_t *str, size_t len ); // C++14 427basic_string<char16_t> operator "" s( const char16_t *str, size_t len ); // C++14 428basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++14 429 430} // std 431 432*/ 433 434#include <__config> 435#include <iosfwd> 436#include <cstring> 437#include <cstdio> // For EOF. 438#include <cwchar> 439#include <algorithm> 440#include <iterator> 441#include <utility> 442#include <memory> 443#include <stdexcept> 444#include <type_traits> 445#include <initializer_list> 446#include <__functional_base> 447#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS 448#include <cstdint> 449#endif 450#if defined(_LIBCPP_NO_EXCEPTIONS) 451#include <cassert> 452#endif 453 454#include <__undef_min_max> 455 456#include <__debug> 457 458#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 459#pragma GCC system_header 460#endif 461 462_LIBCPP_BEGIN_NAMESPACE_STD 463 464// fpos 465 466template <class _StateT> 467class _LIBCPP_TYPE_VIS_ONLY fpos 468{ 469private: 470 _StateT __st_; 471 streamoff __off_; 472public: 473 _LIBCPP_INLINE_VISIBILITY fpos(streamoff __off = streamoff()) : __st_(), __off_(__off) {} 474 475 _LIBCPP_INLINE_VISIBILITY operator streamoff() const {return __off_;} 476 477 _LIBCPP_INLINE_VISIBILITY _StateT state() const {return __st_;} 478 _LIBCPP_INLINE_VISIBILITY void state(_StateT __st) {__st_ = __st;} 479 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;} 484}; 485 486template <class _StateT> 487inline _LIBCPP_INLINE_VISIBILITY 488streamoff operator-(const fpos<_StateT>& __x, const fpos<_StateT>& __y) 489 {return streamoff(__x) - streamoff(__y);} 490 491template <class _StateT> 492inline _LIBCPP_INLINE_VISIBILITY 493bool operator==(const fpos<_StateT>& __x, const fpos<_StateT>& __y) 494 {return streamoff(__x) == streamoff(__y);} 495 496template <class _StateT> 497inline _LIBCPP_INLINE_VISIBILITY 498bool operator!=(const fpos<_StateT>& __x, const fpos<_StateT>& __y) 499 {return streamoff(__x) != streamoff(__y);} 500 501// char_traits 502 503template <class _CharT> 504struct _LIBCPP_TYPE_VIS_ONLY char_traits 505{ 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; 511 512 _LIBCPP_INLINE_VISIBILITY 513 static void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT 514 {__c1 = __c2;} 515 _LIBCPP_INLINE_VISIBILITY 516 static _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT 517 {return __c1 == __c2;} 518 _LIBCPP_INLINE_VISIBILITY 519 static _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT 520 {return __c1 < __c2;} 521 522 static int compare(const char_type* __s1, const char_type* __s2, size_t __n); 523 static size_t length(const char_type* __s); 524 static const char_type* find(const char_type* __s, size_t __n, const char_type& __a); 525 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n); 526 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n); 527 static char_type* assign(char_type* __s, size_t __n, char_type __a); 528 529 _LIBCPP_INLINE_VISIBILITY 530 static _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT 531 {return eq_int_type(__c, eof()) ? ~eof() : __c;} 532 _LIBCPP_INLINE_VISIBILITY 533 static _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT 534 {return char_type(__c);} 535 _LIBCPP_INLINE_VISIBILITY 536 static _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT 537 {return int_type(__c);} 538 _LIBCPP_INLINE_VISIBILITY 539 static _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT 540 {return __c1 == __c2;} 541 _LIBCPP_INLINE_VISIBILITY 542 static _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT 543 {return int_type(EOF);} 544}; 545 546template <class _CharT> 547int 548char_traits<_CharT>::compare(const char_type* __s1, const char_type* __s2, size_t __n) 549{ 550 for (; __n; --__n, ++__s1, ++__s2) 551 { 552 if (lt(*__s1, *__s2)) 553 return -1; 554 if (lt(*__s2, *__s1)) 555 return 1; 556 } 557 return 0; 558} 559 560template <class _CharT> 561inline _LIBCPP_INLINE_VISIBILITY 562size_t 563char_traits<_CharT>::length(const char_type* __s) 564{ 565 size_t __len = 0; 566 for (; !eq(*__s, char_type(0)); ++__s) 567 ++__len; 568 return __len; 569} 570 571template <class _CharT> 572inline _LIBCPP_INLINE_VISIBILITY 573const _CharT* 574char_traits<_CharT>::find(const char_type* __s, size_t __n, const char_type& __a) 575{ 576 for (; __n; --__n) 577 { 578 if (eq(*__s, __a)) 579 return __s; 580 ++__s; 581 } 582 return 0; 583} 584 585template <class _CharT> 586_CharT* 587char_traits<_CharT>::move(char_type* __s1, const char_type* __s2, size_t __n) 588{ 589 char_type* __r = __s1; 590 if (__s1 < __s2) 591 { 592 for (; __n; --__n, ++__s1, ++__s2) 593 assign(*__s1, *__s2); 594 } 595 else if (__s2 < __s1) 596 { 597 __s1 += __n; 598 __s2 += __n; 599 for (; __n; --__n) 600 assign(*--__s1, *--__s2); 601 } 602 return __r; 603} 604 605template <class _CharT> 606inline _LIBCPP_INLINE_VISIBILITY 607_CharT* 608char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n) 609{ 610 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); 611 char_type* __r = __s1; 612 for (; __n; --__n, ++__s1, ++__s2) 613 assign(*__s1, *__s2); 614 return __r; 615} 616 617template <class _CharT> 618inline _LIBCPP_INLINE_VISIBILITY 619_CharT* 620char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a) 621{ 622 char_type* __r = __s; 623 for (; __n; --__n, ++__s) 624 assign(*__s, __a); 625 return __r; 626} 627 628// char_traits<char> 629 630template <> 631struct _LIBCPP_TYPE_VIS_ONLY char_traits<char> 632{ 633 typedef char char_type; 634 typedef int int_type; 635 typedef streamoff off_type; 636 typedef streampos pos_type; 637 typedef mbstate_t state_type; 638 639 _LIBCPP_INLINE_VISIBILITY 640 static void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT 641 {__c1 = __c2;} 642 _LIBCPP_INLINE_VISIBILITY 643 static _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT 644 {return __c1 == __c2;} 645 _LIBCPP_INLINE_VISIBILITY 646 static _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT 647 {return (unsigned char)__c1 < (unsigned char)__c2;} 648 649 _LIBCPP_INLINE_VISIBILITY 650 static int compare(const char_type* __s1, const char_type* __s2, size_t __n) 651 {return memcmp(__s1, __s2, __n);} 652 _LIBCPP_INLINE_VISIBILITY 653 static size_t length(const char_type* __s) {return strlen(__s);} 654 _LIBCPP_INLINE_VISIBILITY 655 static const char_type* find(const char_type* __s, size_t __n, const char_type& __a) 656 {return (const char_type*)memchr(__s, to_int_type(__a), __n);} 657 _LIBCPP_INLINE_VISIBILITY 658 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) 659 {return (char_type*)memmove(__s1, __s2, __n);} 660 _LIBCPP_INLINE_VISIBILITY 661 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) 662 { 663 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); 664 return (char_type*)memcpy(__s1, __s2, __n); 665 } 666 _LIBCPP_INLINE_VISIBILITY 667 static char_type* assign(char_type* __s, size_t __n, char_type __a) 668 {return (char_type*)memset(__s, to_int_type(__a), __n);} 669 670 _LIBCPP_INLINE_VISIBILITY 671 static _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT 672 {return eq_int_type(__c, eof()) ? ~eof() : __c;} 673 _LIBCPP_INLINE_VISIBILITY 674 static _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT 675 {return char_type(__c);} 676 _LIBCPP_INLINE_VISIBILITY 677 static _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT 678 {return int_type((unsigned char)__c);} 679 _LIBCPP_INLINE_VISIBILITY 680 static _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT 681 {return __c1 == __c2;} 682 _LIBCPP_INLINE_VISIBILITY 683 static _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT 684 {return int_type(EOF);} 685}; 686 687// char_traits<wchar_t> 688 689template <> 690struct _LIBCPP_TYPE_VIS_ONLY char_traits<wchar_t> 691{ 692 typedef wchar_t char_type; 693 typedef wint_t int_type; 694 typedef streamoff off_type; 695 typedef streampos pos_type; 696 typedef mbstate_t state_type; 697 698 _LIBCPP_INLINE_VISIBILITY 699 static void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT 700 {__c1 = __c2;} 701 _LIBCPP_INLINE_VISIBILITY 702 static _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT 703 {return __c1 == __c2;} 704 _LIBCPP_INLINE_VISIBILITY 705 static _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT 706 {return __c1 < __c2;} 707 708 _LIBCPP_INLINE_VISIBILITY 709 static int compare(const char_type* __s1, const char_type* __s2, size_t __n) 710 {return wmemcmp(__s1, __s2, __n);} 711 _LIBCPP_INLINE_VISIBILITY 712 static size_t length(const char_type* __s) 713 {return wcslen(__s);} 714 _LIBCPP_INLINE_VISIBILITY 715 static const char_type* find(const char_type* __s, size_t __n, const char_type& __a) 716 {return (const char_type*)wmemchr(__s, __a, __n);} 717 _LIBCPP_INLINE_VISIBILITY 718 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) 719 {return (char_type*)wmemmove(__s1, __s2, __n);} 720 _LIBCPP_INLINE_VISIBILITY 721 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) 722 { 723 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); 724 return (char_type*)wmemcpy(__s1, __s2, __n); 725 } 726 _LIBCPP_INLINE_VISIBILITY 727 static char_type* assign(char_type* __s, size_t __n, char_type __a) 728 {return (char_type*)wmemset(__s, __a, __n);} 729 730 _LIBCPP_INLINE_VISIBILITY 731 static _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT 732 {return eq_int_type(__c, eof()) ? ~eof() : __c;} 733 _LIBCPP_INLINE_VISIBILITY 734 static _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT 735 {return char_type(__c);} 736 _LIBCPP_INLINE_VISIBILITY 737 static _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT 738 {return int_type(__c);} 739 _LIBCPP_INLINE_VISIBILITY 740 static _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT 741 {return __c1 == __c2;} 742 _LIBCPP_INLINE_VISIBILITY 743 static _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT 744 {return int_type(WEOF);} 745}; 746 747#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS 748 749template <> 750struct _LIBCPP_TYPE_VIS_ONLY char_traits<char16_t> 751{ 752 typedef char16_t char_type; 753 typedef uint_least16_t int_type; 754 typedef streamoff off_type; 755 typedef u16streampos pos_type; 756 typedef mbstate_t state_type; 757 758 _LIBCPP_INLINE_VISIBILITY 759 static void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT 760 {__c1 = __c2;} 761 _LIBCPP_INLINE_VISIBILITY 762 static _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT 763 {return __c1 == __c2;} 764 _LIBCPP_INLINE_VISIBILITY 765 static _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT 766 {return __c1 < __c2;} 767 768 static int compare(const char_type* __s1, const char_type* __s2, size_t __n); 769 static size_t length(const char_type* __s); 770 static const char_type* find(const char_type* __s, size_t __n, const char_type& __a); 771 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n); 772 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n); 773 static char_type* assign(char_type* __s, size_t __n, char_type __a); 774 775 _LIBCPP_INLINE_VISIBILITY 776 static _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT 777 {return eq_int_type(__c, eof()) ? ~eof() : __c;} 778 _LIBCPP_INLINE_VISIBILITY 779 static _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT 780 {return char_type(__c);} 781 _LIBCPP_INLINE_VISIBILITY 782 static _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT 783 {return int_type(__c);} 784 _LIBCPP_INLINE_VISIBILITY 785 static _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT 786 {return __c1 == __c2;} 787 _LIBCPP_INLINE_VISIBILITY 788 static _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT 789 {return int_type(0xDFFF);} 790}; 791 792inline _LIBCPP_INLINE_VISIBILITY 793int 794char_traits<char16_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) 795{ 796 for (; __n; --__n, ++__s1, ++__s2) 797 { 798 if (lt(*__s1, *__s2)) 799 return -1; 800 if (lt(*__s2, *__s1)) 801 return 1; 802 } 803 return 0; 804} 805 806inline _LIBCPP_INLINE_VISIBILITY 807size_t 808char_traits<char16_t>::length(const char_type* __s) 809{ 810 size_t __len = 0; 811 for (; !eq(*__s, char_type(0)); ++__s) 812 ++__len; 813 return __len; 814} 815 816inline _LIBCPP_INLINE_VISIBILITY 817const char16_t* 818char_traits<char16_t>::find(const char_type* __s, size_t __n, const char_type& __a) 819{ 820 for (; __n; --__n) 821 { 822 if (eq(*__s, __a)) 823 return __s; 824 ++__s; 825 } 826 return 0; 827} 828 829inline _LIBCPP_INLINE_VISIBILITY 830char16_t* 831char_traits<char16_t>::move(char_type* __s1, const char_type* __s2, size_t __n) 832{ 833 char_type* __r = __s1; 834 if (__s1 < __s2) 835 { 836 for (; __n; --__n, ++__s1, ++__s2) 837 assign(*__s1, *__s2); 838 } 839 else if (__s2 < __s1) 840 { 841 __s1 += __n; 842 __s2 += __n; 843 for (; __n; --__n) 844 assign(*--__s1, *--__s2); 845 } 846 return __r; 847} 848 849inline _LIBCPP_INLINE_VISIBILITY 850char16_t* 851char_traits<char16_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) 852{ 853 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); 854 char_type* __r = __s1; 855 for (; __n; --__n, ++__s1, ++__s2) 856 assign(*__s1, *__s2); 857 return __r; 858} 859 860inline _LIBCPP_INLINE_VISIBILITY 861char16_t* 862char_traits<char16_t>::assign(char_type* __s, size_t __n, char_type __a) 863{ 864 char_type* __r = __s; 865 for (; __n; --__n, ++__s) 866 assign(*__s, __a); 867 return __r; 868} 869 870template <> 871struct _LIBCPP_TYPE_VIS_ONLY char_traits<char32_t> 872{ 873 typedef char32_t char_type; 874 typedef uint_least32_t int_type; 875 typedef streamoff off_type; 876 typedef u32streampos pos_type; 877 typedef mbstate_t state_type; 878 879 _LIBCPP_INLINE_VISIBILITY 880 static void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT 881 {__c1 = __c2;} 882 _LIBCPP_INLINE_VISIBILITY 883 static _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT 884 {return __c1 == __c2;} 885 _LIBCPP_INLINE_VISIBILITY 886 static _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT 887 {return __c1 < __c2;} 888 889 static int compare(const char_type* __s1, const char_type* __s2, size_t __n); 890 static size_t length(const char_type* __s); 891 static const char_type* find(const char_type* __s, size_t __n, const char_type& __a); 892 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n); 893 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n); 894 static char_type* assign(char_type* __s, size_t __n, char_type __a); 895 896 _LIBCPP_INLINE_VISIBILITY 897 static _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT 898 {return eq_int_type(__c, eof()) ? ~eof() : __c;} 899 _LIBCPP_INLINE_VISIBILITY 900 static _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT 901 {return char_type(__c);} 902 _LIBCPP_INLINE_VISIBILITY 903 static _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT 904 {return int_type(__c);} 905 _LIBCPP_INLINE_VISIBILITY 906 static _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT 907 {return __c1 == __c2;} 908 _LIBCPP_INLINE_VISIBILITY 909 static _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT 910 {return int_type(0xFFFFFFFF);} 911}; 912 913inline _LIBCPP_INLINE_VISIBILITY 914int 915char_traits<char32_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) 916{ 917 for (; __n; --__n, ++__s1, ++__s2) 918 { 919 if (lt(*__s1, *__s2)) 920 return -1; 921 if (lt(*__s2, *__s1)) 922 return 1; 923 } 924 return 0; 925} 926 927inline _LIBCPP_INLINE_VISIBILITY 928size_t 929char_traits<char32_t>::length(const char_type* __s) 930{ 931 size_t __len = 0; 932 for (; !eq(*__s, char_type(0)); ++__s) 933 ++__len; 934 return __len; 935} 936 937inline _LIBCPP_INLINE_VISIBILITY 938const char32_t* 939char_traits<char32_t>::find(const char_type* __s, size_t __n, const char_type& __a) 940{ 941 for (; __n; --__n) 942 { 943 if (eq(*__s, __a)) 944 return __s; 945 ++__s; 946 } 947 return 0; 948} 949 950inline _LIBCPP_INLINE_VISIBILITY 951char32_t* 952char_traits<char32_t>::move(char_type* __s1, const char_type* __s2, size_t __n) 953{ 954 char_type* __r = __s1; 955 if (__s1 < __s2) 956 { 957 for (; __n; --__n, ++__s1, ++__s2) 958 assign(*__s1, *__s2); 959 } 960 else if (__s2 < __s1) 961 { 962 __s1 += __n; 963 __s2 += __n; 964 for (; __n; --__n) 965 assign(*--__s1, *--__s2); 966 } 967 return __r; 968} 969 970inline _LIBCPP_INLINE_VISIBILITY 971char32_t* 972char_traits<char32_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) 973{ 974 _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); 975 char_type* __r = __s1; 976 for (; __n; --__n, ++__s1, ++__s2) 977 assign(*__s1, *__s2); 978 return __r; 979} 980 981inline _LIBCPP_INLINE_VISIBILITY 982char32_t* 983char_traits<char32_t>::assign(char_type* __s, size_t __n, char_type __a) 984{ 985 char_type* __r = __s; 986 for (; __n; --__n, ++__s) 987 assign(*__s, __a); 988 return __r; 989} 990 991#endif // _LIBCPP_HAS_NO_UNICODE_CHARS 992 993// helper fns for basic_string 994 995// __str_find 996template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> 997_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 998__str_find(const _CharT *__p, _SizeT __sz, 999 _CharT __c, _SizeT __pos) _NOEXCEPT 1000{ 1001 if (__pos >= __sz) 1002 return __npos; 1003 const _CharT* __r = _Traits::find(__p + __pos, __sz - __pos, __c); 1004 if (__r == 0) 1005 return __npos; 1006 return static_cast<_SizeT>(__r - __p); 1007} 1008 1009template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> 1010_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 1011__str_find(const _CharT *__p, _SizeT __sz, 1012 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT 1013{ 1014 if (__pos > __sz || __sz - __pos < __n) 1015 return __npos; 1016 if (__n == 0) 1017 return __pos; 1018 const _CharT* __r = 1019 _VSTD::__search(__p + __pos, __p + __sz, 1020 __s, __s + __n, _Traits::eq, 1021 random_access_iterator_tag(), random_access_iterator_tag()); 1022 if (__r == __p + __sz) 1023 return __npos; 1024 return static_cast<_SizeT>(__r - __p); 1025} 1026 1027 1028// __str_rfind 1029 1030template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> 1031_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 1032__str_rfind(const _CharT *__p, _SizeT __sz, 1033 _CharT __c, _SizeT __pos) _NOEXCEPT 1034{ 1035 if (__sz < 1) 1036 return __npos; 1037 if (__pos < __sz) 1038 ++__pos; 1039 else 1040 __pos = __sz; 1041 for (const _CharT* __ps = __p + __pos; __ps != __p;) 1042 { 1043 if (_Traits::eq(*--__ps, __c)) 1044 return static_cast<_SizeT>(__ps - __p); 1045 } 1046 return __npos; 1047} 1048 1049template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> 1050_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 1051__str_rfind(const _CharT *__p, _SizeT __sz, 1052 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT 1053{ 1054 __pos = _VSTD::min(__pos, __sz); 1055 if (__n < __sz - __pos) 1056 __pos += __n; 1057 else 1058 __pos = __sz; 1059 const _CharT* __r = _VSTD::__find_end( 1060 __p, __p + __pos, __s, __s + __n, _Traits::eq, 1061 random_access_iterator_tag(), random_access_iterator_tag()); 1062 if (__n > 0 && __r == __p + __pos) 1063 return __npos; 1064 return static_cast<_SizeT>(__r - __p); 1065} 1066 1067// __str_find_first_of 1068template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> 1069_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 1070__str_find_first_of(const _CharT *__p, _SizeT __sz, 1071 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT 1072{ 1073 if (__pos >= __sz || __n == 0) 1074 return __npos; 1075 const _CharT* __r = _VSTD::__find_first_of_ce 1076 (__p + __pos, __p + __sz, __s, __s + __n, _Traits::eq ); 1077 if (__r == __p + __sz) 1078 return __npos; 1079 return static_cast<_SizeT>(__r - __p); 1080} 1081 1082 1083// __str_find_last_of 1084template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> 1085_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 1086__str_find_last_of(const _CharT *__p, _SizeT __sz, 1087 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT 1088 { 1089 if (__n != 0) 1090 { 1091 if (__pos < __sz) 1092 ++__pos; 1093 else 1094 __pos = __sz; 1095 for (const _CharT* __ps = __p + __pos; __ps != __p;) 1096 { 1097 const _CharT* __r = _Traits::find(__s, __n, *--__ps); 1098 if (__r) 1099 return static_cast<_SizeT>(__ps - __p); 1100 } 1101 } 1102 return __npos; 1103} 1104 1105 1106// __str_find_first_not_of 1107template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> 1108_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 1109__str_find_first_not_of(const _CharT *__p, _SizeT __sz, 1110 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT 1111{ 1112 if (__pos < __sz) 1113 { 1114 const _CharT* __pe = __p + __sz; 1115 for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps) 1116 if (_Traits::find(__s, __n, *__ps) == 0) 1117 return static_cast<_SizeT>(__ps - __p); 1118 } 1119 return __npos; 1120} 1121 1122 1123template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> 1124_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 1125__str_find_first_not_of(const _CharT *__p, _SizeT __sz, 1126 _CharT __c, _SizeT __pos) _NOEXCEPT 1127{ 1128 if (__pos < __sz) 1129 { 1130 const _CharT* __pe = __p + __sz; 1131 for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps) 1132 if (!_Traits::eq(*__ps, __c)) 1133 return static_cast<_SizeT>(__ps - __p); 1134 } 1135 return __npos; 1136} 1137 1138 1139// __str_find_last_not_of 1140template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> 1141_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 1142__str_find_last_not_of(const _CharT *__p, _SizeT __sz, 1143 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT 1144{ 1145 if (__pos < __sz) 1146 ++__pos; 1147 else 1148 __pos = __sz; 1149 for (const _CharT* __ps = __p + __pos; __ps != __p;) 1150 if (_Traits::find(__s, __n, *--__ps) == 0) 1151 return static_cast<_SizeT>(__ps - __p); 1152 return __npos; 1153} 1154 1155 1156template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> 1157_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 1158__str_find_last_not_of(const _CharT *__p, _SizeT __sz, 1159 _CharT __c, _SizeT __pos) _NOEXCEPT 1160{ 1161 if (__pos < __sz) 1162 ++__pos; 1163 else 1164 __pos = __sz; 1165 for (const _CharT* __ps = __p + __pos; __ps != __p;) 1166 if (!_Traits::eq(*--__ps, __c)) 1167 return static_cast<_SizeT>(__ps - __p); 1168 return __npos; 1169} 1170 1171template<class _Ptr> 1172size_t _LIBCPP_INLINE_VISIBILITY __do_string_hash(_Ptr __p, _Ptr __e) 1173{ 1174 typedef typename iterator_traits<_Ptr>::value_type value_type; 1175 return __murmur2_or_cityhash<size_t>()(__p, (__e-__p)*sizeof(value_type)); 1176} 1177 1178// basic_string 1179 1180template<class _CharT, class _Traits, class _Allocator> 1181basic_string<_CharT, _Traits, _Allocator> 1182operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, 1183 const basic_string<_CharT, _Traits, _Allocator>& __y); 1184 1185template<class _CharT, class _Traits, class _Allocator> 1186basic_string<_CharT, _Traits, _Allocator> 1187operator+(const _CharT* __x, const basic_string<_CharT,_Traits,_Allocator>& __y); 1188 1189template<class _CharT, class _Traits, class _Allocator> 1190basic_string<_CharT, _Traits, _Allocator> 1191operator+(_CharT __x, const basic_string<_CharT,_Traits,_Allocator>& __y); 1192 1193template<class _CharT, class _Traits, class _Allocator> 1194basic_string<_CharT, _Traits, _Allocator> 1195operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const _CharT* __y); 1196 1197template<class _CharT, class _Traits, class _Allocator> 1198basic_string<_CharT, _Traits, _Allocator> 1199operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y); 1200 1201template <bool> 1202class _LIBCPP_TYPE_VIS_ONLY __basic_string_common 1203{ 1204protected: 1205 void __throw_length_error() const; 1206 void __throw_out_of_range() const; 1207}; 1208 1209template <bool __b> 1210void 1211__basic_string_common<__b>::__throw_length_error() const 1212{ 1213#ifndef _LIBCPP_NO_EXCEPTIONS 1214 throw length_error("basic_string"); 1215#else 1216 assert(!"basic_string length_error"); 1217#endif 1218} 1219 1220template <bool __b> 1221void 1222__basic_string_common<__b>::__throw_out_of_range() const 1223{ 1224#ifndef _LIBCPP_NO_EXCEPTIONS 1225 throw out_of_range("basic_string"); 1226#else 1227 assert(!"basic_string out_of_range"); 1228#endif 1229} 1230 1231#ifdef _LIBCPP_MSVC 1232#pragma warning( push ) 1233#pragma warning( disable: 4231 ) 1234#endif // _LIBCPP_MSVC 1235_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS __basic_string_common<true>) 1236#ifdef _LIBCPP_MSVC 1237#pragma warning( pop ) 1238#endif // _LIBCPP_MSVC 1239 1240#ifdef _LIBCPP_ALTERNATE_STRING_LAYOUT 1241 1242template <class _CharT, size_t = sizeof(_CharT)> 1243struct __padding 1244{ 1245 unsigned char __xx[sizeof(_CharT)-1]; 1246}; 1247 1248template <class _CharT> 1249struct __padding<_CharT, 1> 1250{ 1251}; 1252 1253#endif // _LIBCPP_ALTERNATE_STRING_LAYOUT 1254 1255template<class _CharT, class _Traits, class _Allocator> 1256class _LIBCPP_TYPE_VIS_ONLY basic_string 1257 : private __basic_string_common<true> 1258{ 1259public: 1260 typedef basic_string __self; 1261 typedef _Traits traits_type; 1262 typedef typename traits_type::char_type value_type; 1263 typedef _Allocator allocator_type; 1264 typedef allocator_traits<allocator_type> __alloc_traits; 1265 typedef typename __alloc_traits::size_type size_type; 1266 typedef typename __alloc_traits::difference_type difference_type; 1267 typedef value_type& reference; 1268 typedef const value_type& const_reference; 1269 typedef typename __alloc_traits::pointer pointer; 1270 typedef typename __alloc_traits::const_pointer const_pointer; 1271 1272 static_assert(is_pod<value_type>::value, "Character type of basic_string must be a POD"); 1273 static_assert((is_same<_CharT, value_type>::value), 1274 "traits_type::char_type must be the same type as CharT"); 1275 static_assert((is_same<typename allocator_type::value_type, value_type>::value), 1276 "Allocator::value_type must be same type as value_type"); 1277#if defined(_LIBCPP_RAW_ITERATORS) 1278 typedef pointer iterator; 1279 typedef const_pointer const_iterator; 1280#else // defined(_LIBCPP_RAW_ITERATORS) 1281 typedef __wrap_iter<pointer> iterator; 1282 typedef __wrap_iter<const_pointer> const_iterator; 1283#endif // defined(_LIBCPP_RAW_ITERATORS) 1284 typedef _VSTD::reverse_iterator<iterator> reverse_iterator; 1285 typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator; 1286 1287private: 1288 1289#ifdef _LIBCPP_ALTERNATE_STRING_LAYOUT 1290 1291 struct __long 1292 { 1293 pointer __data_; 1294 size_type __size_; 1295 size_type __cap_; 1296 }; 1297 1298#if _LIBCPP_BIG_ENDIAN 1299 enum {__short_mask = 0x01}; 1300 enum {__long_mask = 0x1ul}; 1301#else // _LIBCPP_BIG_ENDIAN 1302 enum {__short_mask = 0x80}; 1303 enum {__long_mask = ~(size_type(~0) >> 1)}; 1304#endif // _LIBCPP_BIG_ENDIAN 1305 1306 enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ? 1307 (sizeof(__long) - 1)/sizeof(value_type) : 2}; 1308 1309 struct __short 1310 { 1311 value_type __data_[__min_cap]; 1312 struct 1313 : __padding<value_type> 1314 { 1315 unsigned char __size_; 1316 }; 1317 }; 1318 1319#else 1320 1321 struct __long 1322 { 1323 size_type __cap_; 1324 size_type __size_; 1325 pointer __data_; 1326 }; 1327 1328#if _LIBCPP_BIG_ENDIAN 1329 enum {__short_mask = 0x80}; 1330 enum {__long_mask = ~(size_type(~0) >> 1)}; 1331#else // _LIBCPP_BIG_ENDIAN 1332 enum {__short_mask = 0x01}; 1333 enum {__long_mask = 0x1ul}; 1334#endif // _LIBCPP_BIG_ENDIAN 1335 1336 enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ? 1337 (sizeof(__long) - 1)/sizeof(value_type) : 2}; 1338 1339 struct __short 1340 { 1341 union 1342 { 1343 unsigned char __size_; 1344 value_type __lx; 1345 }; 1346 value_type __data_[__min_cap]; 1347 }; 1348 1349#endif // _LIBCPP_ALTERNATE_STRING_LAYOUT 1350 1351 union __ulx{__long __lx; __short __lxx;}; 1352 1353 enum {__n_words = sizeof(__ulx) / sizeof(size_type)}; 1354 1355 struct __raw 1356 { 1357 size_type __words[__n_words]; 1358 }; 1359 1360 struct __rep 1361 { 1362 union 1363 { 1364 __long __l; 1365 __short __s; 1366 __raw __r; 1367 }; 1368 }; 1369 1370 __compressed_pair<__rep, allocator_type> __r_; 1371 1372public: 1373 static const size_type npos = -1; 1374 1375 _LIBCPP_INLINE_VISIBILITY basic_string() 1376 _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value); 1377 _LIBCPP_INLINE_VISIBILITY explicit basic_string(const allocator_type& __a); 1378 basic_string(const basic_string& __str); 1379 basic_string(const basic_string& __str, const allocator_type& __a); 1380#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1381 _LIBCPP_INLINE_VISIBILITY 1382 basic_string(basic_string&& __str) 1383 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value); 1384 _LIBCPP_INLINE_VISIBILITY 1385 basic_string(basic_string&& __str, const allocator_type& __a); 1386#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1387 _LIBCPP_INLINE_VISIBILITY basic_string(const value_type* __s); 1388 _LIBCPP_INLINE_VISIBILITY 1389 basic_string(const value_type* __s, const allocator_type& __a); 1390 _LIBCPP_INLINE_VISIBILITY 1391 basic_string(const value_type* __s, size_type __n); 1392 _LIBCPP_INLINE_VISIBILITY 1393 basic_string(const value_type* __s, size_type __n, const allocator_type& __a); 1394 _LIBCPP_INLINE_VISIBILITY 1395 basic_string(size_type __n, value_type __c); 1396 _LIBCPP_INLINE_VISIBILITY 1397 basic_string(size_type __n, value_type __c, const allocator_type& __a); 1398 basic_string(const basic_string& __str, size_type __pos, size_type __n = npos, 1399 const allocator_type& __a = allocator_type()); 1400 template<class _InputIterator> 1401 _LIBCPP_INLINE_VISIBILITY 1402 basic_string(_InputIterator __first, _InputIterator __last); 1403 template<class _InputIterator> 1404 _LIBCPP_INLINE_VISIBILITY 1405 basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a); 1406#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS 1407 _LIBCPP_INLINE_VISIBILITY 1408 basic_string(initializer_list<value_type> __il); 1409 _LIBCPP_INLINE_VISIBILITY 1410 basic_string(initializer_list<value_type> __il, const allocator_type& __a); 1411#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS 1412 1413 ~basic_string(); 1414 1415 basic_string& operator=(const basic_string& __str); 1416#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1417 _LIBCPP_INLINE_VISIBILITY 1418 basic_string& operator=(basic_string&& __str) 1419 _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value && 1420 is_nothrow_move_assignable<allocator_type>::value); 1421#endif 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 1428 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());} 1442#else 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());} 1468 1469 _LIBCPP_INLINE_VISIBILITY 1470 const_iterator cbegin() const _NOEXCEPT 1471 {return begin();} 1472 _LIBCPP_INLINE_VISIBILITY 1473 const_iterator cend() const _NOEXCEPT 1474 {return end();} 1475 _LIBCPP_INLINE_VISIBILITY 1476 const_reverse_iterator crbegin() const _NOEXCEPT 1477 {return rbegin();} 1478 _LIBCPP_INLINE_VISIBILITY 1479 const_reverse_iterator crend() const _NOEXCEPT 1480 {return rend();} 1481 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() : __min_cap) - 1;} 1488 1489 void resize(size_type __n, value_type __c); 1490 _LIBCPP_INLINE_VISIBILITY void resize(size_type __n) {resize(__n, value_type());} 1491 1492 void reserve(size_type res_arg = 0); 1493 _LIBCPP_INLINE_VISIBILITY 1494 void shrink_to_fit() _NOEXCEPT {reserve();} 1495 _LIBCPP_INLINE_VISIBILITY 1496 void clear() _NOEXCEPT; 1497 _LIBCPP_INLINE_VISIBILITY bool empty() const _NOEXCEPT {return size() == 0;} 1498 1499 _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __pos) const; 1500 _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __pos); 1501 1502 const_reference at(size_type __n) const; 1503 reference at(size_type __n); 1504 1505 _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const basic_string& __str) {return append(__str);} 1506 _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const value_type* __s) {return append(__s);} 1507 _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(value_type __c) {push_back(__c); return *this;} 1508#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS 1509 _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(initializer_list<value_type> __il) {return append(__il);} 1510#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS 1511 1512 _LIBCPP_INLINE_VISIBILITY 1513 basic_string& append(const basic_string& __str); 1514 basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos); 1515 basic_string& append(const value_type* __s, size_type __n); 1516 basic_string& append(const value_type* __s); 1517 basic_string& append(size_type __n, value_type __c); 1518 template<class _InputIterator> 1519 typename enable_if 1520 < 1521 __is_input_iterator <_InputIterator>::value && 1522 !__is_forward_iterator<_InputIterator>::value, 1523 basic_string& 1524 >::type 1525 append(_InputIterator __first, _InputIterator __last); 1526 template<class _ForwardIterator> 1527 typename enable_if 1528 < 1529 __is_forward_iterator<_ForwardIterator>::value, 1530 basic_string& 1531 >::type 1532 append(_ForwardIterator __first, _ForwardIterator __last); 1533#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS 1534 _LIBCPP_INLINE_VISIBILITY 1535 basic_string& append(initializer_list<value_type> __il) {return append(__il.begin(), __il.size());} 1536#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS 1537 1538 void push_back(value_type __c); 1539 _LIBCPP_INLINE_VISIBILITY 1540 void pop_back(); 1541 _LIBCPP_INLINE_VISIBILITY reference front(); 1542 _LIBCPP_INLINE_VISIBILITY const_reference front() const; 1543 _LIBCPP_INLINE_VISIBILITY reference back(); 1544 _LIBCPP_INLINE_VISIBILITY const_reference back() const; 1545 1546 _LIBCPP_INLINE_VISIBILITY 1547 basic_string& assign(const basic_string& __str); 1548#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1549 _LIBCPP_INLINE_VISIBILITY 1550 basic_string& assign(basic_string&& str) 1551 {*this = _VSTD::move(str); return *this;} 1552#endif 1553 basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos); 1554 basic_string& assign(const value_type* __s, size_type __n); 1555 basic_string& assign(const value_type* __s); 1556 basic_string& assign(size_type __n, value_type __c); 1557 template<class _InputIterator> 1558 typename enable_if 1559 < 1560 __is_input_iterator <_InputIterator>::value && 1561 !__is_forward_iterator<_InputIterator>::value, 1562 basic_string& 1563 >::type 1564 assign(_InputIterator __first, _InputIterator __last); 1565 template<class _ForwardIterator> 1566 typename enable_if 1567 < 1568 __is_forward_iterator<_ForwardIterator>::value, 1569 basic_string& 1570 >::type 1571 assign(_ForwardIterator __first, _ForwardIterator __last); 1572#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS 1573 _LIBCPP_INLINE_VISIBILITY 1574 basic_string& assign(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());} 1575#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS 1576 1577 _LIBCPP_INLINE_VISIBILITY 1578 basic_string& insert(size_type __pos1, const basic_string& __str); 1579 basic_string& insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n=npos); 1580 basic_string& insert(size_type __pos, const value_type* __s, size_type __n); 1581 basic_string& insert(size_type __pos, const value_type* __s); 1582 basic_string& insert(size_type __pos, size_type __n, value_type __c); 1583 iterator insert(const_iterator __pos, value_type __c); 1584 _LIBCPP_INLINE_VISIBILITY 1585 iterator insert(const_iterator __pos, size_type __n, value_type __c); 1586 template<class _InputIterator> 1587 typename enable_if 1588 < 1589 __is_input_iterator <_InputIterator>::value && 1590 !__is_forward_iterator<_InputIterator>::value, 1591 iterator 1592 >::type 1593 insert(const_iterator __pos, _InputIterator __first, _InputIterator __last); 1594 template<class _ForwardIterator> 1595 typename enable_if 1596 < 1597 __is_forward_iterator<_ForwardIterator>::value, 1598 iterator 1599 >::type 1600 insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last); 1601#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS 1602 _LIBCPP_INLINE_VISIBILITY 1603 iterator insert(const_iterator __pos, initializer_list<value_type> __il) 1604 {return insert(__pos, __il.begin(), __il.end());} 1605#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS 1606 1607 basic_string& erase(size_type __pos = 0, size_type __n = npos); 1608 _LIBCPP_INLINE_VISIBILITY 1609 iterator erase(const_iterator __pos); 1610 _LIBCPP_INLINE_VISIBILITY 1611 iterator erase(const_iterator __first, const_iterator __last); 1612 1613 _LIBCPP_INLINE_VISIBILITY 1614 basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str); 1615 basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos); 1616 basic_string& replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2); 1617 basic_string& replace(size_type __pos, size_type __n1, const value_type* __s); 1618 basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c); 1619 _LIBCPP_INLINE_VISIBILITY 1620 basic_string& replace(const_iterator __i1, const_iterator __i2, const basic_string& __str); 1621 _LIBCPP_INLINE_VISIBILITY 1622 basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n); 1623 _LIBCPP_INLINE_VISIBILITY 1624 basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s); 1625 _LIBCPP_INLINE_VISIBILITY 1626 basic_string& replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c); 1627 template<class _InputIterator> 1628 typename enable_if 1629 < 1630 __is_input_iterator<_InputIterator>::value, 1631 basic_string& 1632 >::type 1633 replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2); 1634#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS 1635 _LIBCPP_INLINE_VISIBILITY 1636 basic_string& replace(const_iterator __i1, const_iterator __i2, initializer_list<value_type> __il) 1637 {return replace(__i1, __i2, __il.begin(), __il.end());} 1638#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS 1639 1640 size_type copy(value_type* __s, size_type __n, size_type __pos = 0) const; 1641 _LIBCPP_INLINE_VISIBILITY 1642 basic_string substr(size_type __pos = 0, size_type __n = npos) const; 1643 1644 _LIBCPP_INLINE_VISIBILITY 1645 void swap(basic_string& __str) 1646 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || 1647 __is_nothrow_swappable<allocator_type>::value); 1648 1649 _LIBCPP_INLINE_VISIBILITY 1650 const value_type* c_str() const _NOEXCEPT {return data();} 1651 _LIBCPP_INLINE_VISIBILITY 1652 const value_type* data() const _NOEXCEPT {return _VSTD::__to_raw_pointer(__get_pointer());} 1653 1654 _LIBCPP_INLINE_VISIBILITY 1655 allocator_type get_allocator() const _NOEXCEPT {return __alloc();} 1656 1657 _LIBCPP_INLINE_VISIBILITY 1658 size_type find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; 1659 size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; 1660 _LIBCPP_INLINE_VISIBILITY 1661 size_type find(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; 1662 size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT; 1663 1664 _LIBCPP_INLINE_VISIBILITY 1665 size_type rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; 1666 size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; 1667 _LIBCPP_INLINE_VISIBILITY 1668 size_type rfind(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; 1669 size_type rfind(value_type __c, size_type __pos = npos) const _NOEXCEPT; 1670 1671 _LIBCPP_INLINE_VISIBILITY 1672 size_type find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; 1673 size_type find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; 1674 _LIBCPP_INLINE_VISIBILITY 1675 size_type find_first_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; 1676 _LIBCPP_INLINE_VISIBILITY 1677 size_type find_first_of(value_type __c, size_type __pos = 0) const _NOEXCEPT; 1678 1679 _LIBCPP_INLINE_VISIBILITY 1680 size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; 1681 size_type find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; 1682 _LIBCPP_INLINE_VISIBILITY 1683 size_type find_last_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; 1684 _LIBCPP_INLINE_VISIBILITY 1685 size_type find_last_of(value_type __c, size_type __pos = npos) const _NOEXCEPT; 1686 1687 _LIBCPP_INLINE_VISIBILITY 1688 size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; 1689 size_type find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; 1690 _LIBCPP_INLINE_VISIBILITY 1691 size_type find_first_not_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; 1692 _LIBCPP_INLINE_VISIBILITY 1693 size_type find_first_not_of(value_type __c, size_type __pos = 0) const _NOEXCEPT; 1694 1695 _LIBCPP_INLINE_VISIBILITY 1696 size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; 1697 size_type find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; 1698 _LIBCPP_INLINE_VISIBILITY 1699 size_type find_last_not_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; 1700 _LIBCPP_INLINE_VISIBILITY 1701 size_type find_last_not_of(value_type __c, size_type __pos = npos) const _NOEXCEPT; 1702 1703 _LIBCPP_INLINE_VISIBILITY 1704 int compare(const basic_string& __str) const _NOEXCEPT; 1705 _LIBCPP_INLINE_VISIBILITY 1706 int compare(size_type __pos1, size_type __n1, const basic_string& __str) const; 1707 int compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos) const; 1708 int compare(const value_type* __s) const _NOEXCEPT; 1709 int compare(size_type __pos1, size_type __n1, const value_type* __s) const; 1710 int compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const; 1711 1712 _LIBCPP_INLINE_VISIBILITY bool __invariants() const; 1713 1714 _LIBCPP_INLINE_VISIBILITY 1715 bool __is_long() const _NOEXCEPT 1716 {return bool(__r_.first().__s.__size_ & __short_mask);} 1717 1718#if _LIBCPP_DEBUG_LEVEL >= 2 1719 1720 bool __dereferenceable(const const_iterator* __i) const; 1721 bool __decrementable(const const_iterator* __i) const; 1722 bool __addable(const const_iterator* __i, ptrdiff_t __n) const; 1723 bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const; 1724 1725#endif // _LIBCPP_DEBUG_LEVEL >= 2 1726 1727private: 1728 _LIBCPP_INLINE_VISIBILITY 1729 allocator_type& __alloc() _NOEXCEPT 1730 {return __r_.second();} 1731 _LIBCPP_INLINE_VISIBILITY 1732 const allocator_type& __alloc() const _NOEXCEPT 1733 {return __r_.second();} 1734 1735#ifdef _LIBCPP_ALTERNATE_STRING_LAYOUT 1736 1737 _LIBCPP_INLINE_VISIBILITY 1738 void __set_short_size(size_type __s) _NOEXCEPT 1739# if _LIBCPP_BIG_ENDIAN 1740 {__r_.first().__s.__size_ = (unsigned char)(__s << 1);} 1741# else 1742 {__r_.first().__s.__size_ = (unsigned char)(__s);} 1743# endif 1744 1745 _LIBCPP_INLINE_VISIBILITY 1746 size_type __get_short_size() const _NOEXCEPT 1747# if _LIBCPP_BIG_ENDIAN 1748 {return __r_.first().__s.__size_ >> 1;} 1749# else 1750 {return __r_.first().__s.__size_;} 1751# endif 1752 1753#else // _LIBCPP_ALTERNATE_STRING_LAYOUT 1754 1755 _LIBCPP_INLINE_VISIBILITY 1756 void __set_short_size(size_type __s) _NOEXCEPT 1757# if _LIBCPP_BIG_ENDIAN 1758 {__r_.first().__s.__size_ = (unsigned char)(__s);} 1759# else 1760 {__r_.first().__s.__size_ = (unsigned char)(__s << 1);} 1761# endif 1762 1763 _LIBCPP_INLINE_VISIBILITY 1764 size_type __get_short_size() const _NOEXCEPT 1765# if _LIBCPP_BIG_ENDIAN 1766 {return __r_.first().__s.__size_;} 1767# else 1768 {return __r_.first().__s.__size_ >> 1;} 1769# endif 1770 1771#endif // _LIBCPP_ALTERNATE_STRING_LAYOUT 1772 1773 _LIBCPP_INLINE_VISIBILITY 1774 void __set_long_size(size_type __s) _NOEXCEPT 1775 {__r_.first().__l.__size_ = __s;} 1776 _LIBCPP_INLINE_VISIBILITY 1777 size_type __get_long_size() const _NOEXCEPT 1778 {return __r_.first().__l.__size_;} 1779 _LIBCPP_INLINE_VISIBILITY 1780 void __set_size(size_type __s) _NOEXCEPT 1781 {if (__is_long()) __set_long_size(__s); else __set_short_size(__s);} 1782 1783 _LIBCPP_INLINE_VISIBILITY 1784 void __set_long_cap(size_type __s) _NOEXCEPT 1785 {__r_.first().__l.__cap_ = __long_mask | __s;} 1786 _LIBCPP_INLINE_VISIBILITY 1787 size_type __get_long_cap() const _NOEXCEPT 1788 {return __r_.first().__l.__cap_ & size_type(~__long_mask);} 1789 1790 _LIBCPP_INLINE_VISIBILITY 1791 void __set_long_pointer(pointer __p) _NOEXCEPT 1792 {__r_.first().__l.__data_ = __p;} 1793 _LIBCPP_INLINE_VISIBILITY 1794 pointer __get_long_pointer() _NOEXCEPT 1795 {return __r_.first().__l.__data_;} 1796 _LIBCPP_INLINE_VISIBILITY 1797 const_pointer __get_long_pointer() const _NOEXCEPT 1798 {return __r_.first().__l.__data_;} 1799 _LIBCPP_INLINE_VISIBILITY 1800 pointer __get_short_pointer() _NOEXCEPT 1801 {return pointer_traits<pointer>::pointer_to(__r_.first().__s.__data_[0]);} 1802 _LIBCPP_INLINE_VISIBILITY 1803 const_pointer __get_short_pointer() const _NOEXCEPT 1804 {return pointer_traits<const_pointer>::pointer_to(__r_.first().__s.__data_[0]);} 1805 _LIBCPP_INLINE_VISIBILITY 1806 pointer __get_pointer() _NOEXCEPT 1807 {return __is_long() ? __get_long_pointer() : __get_short_pointer();} 1808 _LIBCPP_INLINE_VISIBILITY 1809 const_pointer __get_pointer() const _NOEXCEPT 1810 {return __is_long() ? __get_long_pointer() : __get_short_pointer();} 1811 1812 _LIBCPP_INLINE_VISIBILITY 1813 void __zero() _NOEXCEPT 1814 { 1815 size_type (&__a)[__n_words] = __r_.first().__r.__words; 1816 for (unsigned __i = 0; __i < __n_words; ++__i) 1817 __a[__i] = 0; 1818 } 1819 1820 template <size_type __a> static 1821 _LIBCPP_INLINE_VISIBILITY 1822 size_type __align_it(size_type __s) _NOEXCEPT 1823 {return __s + (__a-1) & ~(__a-1);} 1824 enum {__alignment = 16}; 1825 static _LIBCPP_INLINE_VISIBILITY 1826 size_type __recommend(size_type __s) _NOEXCEPT 1827 {return (__s < __min_cap ? __min_cap : 1828 __align_it<sizeof(value_type) < __alignment ? 1829 __alignment/sizeof(value_type) : 1 > (__s+1)) - 1;} 1830 1831 void __init(const value_type* __s, size_type __sz, size_type __reserve); 1832 void __init(const value_type* __s, size_type __sz); 1833 void __init(size_type __n, value_type __c); 1834 1835 template <class _InputIterator> 1836 typename enable_if 1837 < 1838 __is_input_iterator <_InputIterator>::value && 1839 !__is_forward_iterator<_InputIterator>::value, 1840 void 1841 >::type 1842 __init(_InputIterator __first, _InputIterator __last); 1843 1844 template <class _ForwardIterator> 1845 typename enable_if 1846 < 1847 __is_forward_iterator<_ForwardIterator>::value, 1848 void 1849 >::type 1850 __init(_ForwardIterator __first, _ForwardIterator __last); 1851 1852 void __grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz, 1853 size_type __n_copy, size_type __n_del, size_type __n_add = 0); 1854 void __grow_by_and_replace(size_type __old_cap, size_type __delta_cap, size_type __old_sz, 1855 size_type __n_copy, size_type __n_del, 1856 size_type __n_add, const value_type* __p_new_stuff); 1857 1858 _LIBCPP_INLINE_VISIBILITY 1859 void __erase_to_end(size_type __pos); 1860 1861 _LIBCPP_INLINE_VISIBILITY 1862 void __copy_assign_alloc(const basic_string& __str) 1863 {__copy_assign_alloc(__str, integral_constant<bool, 1864 __alloc_traits::propagate_on_container_copy_assignment::value>());} 1865 1866 _LIBCPP_INLINE_VISIBILITY 1867 void __copy_assign_alloc(const basic_string& __str, true_type) 1868 { 1869 if (__alloc() != __str.__alloc()) 1870 { 1871 clear(); 1872 shrink_to_fit(); 1873 } 1874 __alloc() = __str.__alloc(); 1875 } 1876 1877 _LIBCPP_INLINE_VISIBILITY 1878 void __copy_assign_alloc(const basic_string&, false_type) _NOEXCEPT 1879 {} 1880 1881#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1882 _LIBCPP_INLINE_VISIBILITY 1883 void __move_assign(basic_string& __str, false_type); 1884 _LIBCPP_INLINE_VISIBILITY 1885 void __move_assign(basic_string& __str, true_type) 1886 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value); 1887#endif 1888 1889 _LIBCPP_INLINE_VISIBILITY 1890 void 1891 __move_assign_alloc(basic_string& __str) 1892 _NOEXCEPT_( 1893 !__alloc_traits::propagate_on_container_move_assignment::value || 1894 is_nothrow_move_assignable<allocator_type>::value) 1895 {__move_assign_alloc(__str, integral_constant<bool, 1896 __alloc_traits::propagate_on_container_move_assignment::value>());} 1897 1898 _LIBCPP_INLINE_VISIBILITY 1899 void __move_assign_alloc(basic_string& __c, true_type) 1900 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) 1901 { 1902 __alloc() = _VSTD::move(__c.__alloc()); 1903 } 1904 1905 _LIBCPP_INLINE_VISIBILITY 1906 void __move_assign_alloc(basic_string&, false_type) 1907 _NOEXCEPT 1908 {} 1909 1910 _LIBCPP_INLINE_VISIBILITY 1911 static void __swap_alloc(allocator_type& __x, allocator_type& __y) 1912 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || 1913 __is_nothrow_swappable<allocator_type>::value) 1914 {__swap_alloc(__x, __y, integral_constant<bool, 1915 __alloc_traits::propagate_on_container_swap::value>());} 1916 1917 _LIBCPP_INLINE_VISIBILITY 1918 static void __swap_alloc(allocator_type& __x, allocator_type& __y, true_type) 1919 _NOEXCEPT_(__is_nothrow_swappable<allocator_type>::value) 1920 { 1921 using _VSTD::swap; 1922 swap(__x, __y); 1923 } 1924 _LIBCPP_INLINE_VISIBILITY 1925 static void __swap_alloc(allocator_type&, allocator_type&, false_type) _NOEXCEPT 1926 {} 1927 1928 _LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators(); 1929 _LIBCPP_INLINE_VISIBILITY void __invalidate_iterators_past(size_type); 1930 1931 friend basic_string operator+<>(const basic_string&, const basic_string&); 1932 friend basic_string operator+<>(const value_type*, const basic_string&); 1933 friend basic_string operator+<>(value_type, const basic_string&); 1934 friend basic_string operator+<>(const basic_string&, const value_type*); 1935 friend basic_string operator+<>(const basic_string&, value_type); 1936}; 1937 1938template <class _CharT, class _Traits, class _Allocator> 1939inline _LIBCPP_INLINE_VISIBILITY 1940void 1941basic_string<_CharT, _Traits, _Allocator>::__invalidate_all_iterators() 1942{ 1943#if _LIBCPP_DEBUG_LEVEL >= 2 1944 __get_db()->__invalidate_all(this); 1945#endif // _LIBCPP_DEBUG_LEVEL >= 2 1946} 1947 1948template <class _CharT, class _Traits, class _Allocator> 1949inline _LIBCPP_INLINE_VISIBILITY 1950void 1951basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type 1952#if _LIBCPP_DEBUG_LEVEL >= 2 1953 __pos 1954#endif 1955 ) 1956{ 1957#if _LIBCPP_DEBUG_LEVEL >= 2 1958 __c_node* __c = __get_db()->__find_c_and_lock(this); 1959 if (__c) 1960 { 1961 const_pointer __new_last = __get_pointer() + __pos; 1962 for (__i_node** __p = __c->end_; __p != __c->beg_; ) 1963 { 1964 --__p; 1965 const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_); 1966 if (__i->base() > __new_last) 1967 { 1968 (*__p)->__c_ = nullptr; 1969 if (--__c->end_ != __p) 1970 memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); 1971 } 1972 } 1973 __get_db()->unlock(); 1974 } 1975#endif // _LIBCPP_DEBUG_LEVEL >= 2 1976} 1977 1978template <class _CharT, class _Traits, class _Allocator> 1979inline _LIBCPP_INLINE_VISIBILITY 1980basic_string<_CharT, _Traits, _Allocator>::basic_string() 1981 _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) 1982{ 1983#if _LIBCPP_DEBUG_LEVEL >= 2 1984 __get_db()->__insert_c(this); 1985#endif 1986 __zero(); 1987} 1988 1989template <class _CharT, class _Traits, class _Allocator> 1990inline _LIBCPP_INLINE_VISIBILITY 1991basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __a) 1992 : __r_(__a) 1993{ 1994#if _LIBCPP_DEBUG_LEVEL >= 2 1995 __get_db()->__insert_c(this); 1996#endif 1997 __zero(); 1998} 1999 2000template <class _CharT, class _Traits, class _Allocator> 2001void 2002basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz, size_type __reserve) 2003{ 2004 if (__reserve > max_size()) 2005 this->__throw_length_error(); 2006 pointer __p; 2007 if (__reserve < __min_cap) 2008 { 2009 __set_short_size(__sz); 2010 __p = __get_short_pointer(); 2011 } 2012 else 2013 { 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); 2019 } 2020 traits_type::copy(_VSTD::__to_raw_pointer(__p), __s, __sz); 2021 traits_type::assign(__p[__sz], value_type()); 2022} 2023 2024template <class _CharT, class _Traits, class _Allocator> 2025void 2026basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz) 2027{ 2028 if (__sz > max_size()) 2029 this->__throw_length_error(); 2030 pointer __p; 2031 if (__sz < __min_cap) 2032 { 2033 __set_short_size(__sz); 2034 __p = __get_short_pointer(); 2035 } 2036 else 2037 { 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); 2043 } 2044 traits_type::copy(_VSTD::__to_raw_pointer(__p), __s, __sz); 2045 traits_type::assign(__p[__sz], value_type()); 2046} 2047 2048template <class _CharT, class _Traits, class _Allocator> 2049inline _LIBCPP_INLINE_VISIBILITY 2050basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s) 2051{ 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); 2056#endif 2057} 2058 2059template <class _CharT, class _Traits, class _Allocator> 2060inline _LIBCPP_INLINE_VISIBILITY 2061basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, const allocator_type& __a) 2062 : __r_(__a) 2063{ 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); 2068#endif 2069} 2070 2071template <class _CharT, class _Traits, class _Allocator> 2072inline _LIBCPP_INLINE_VISIBILITY 2073basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, size_type __n) 2074{ 2075 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr"); 2076 __init(__s, __n); 2077#if _LIBCPP_DEBUG_LEVEL >= 2 2078 __get_db()->__insert_c(this); 2079#endif 2080} 2081 2082template <class _CharT, class _Traits, class _Allocator> 2083inline _LIBCPP_INLINE_VISIBILITY 2084basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, size_type __n, const allocator_type& __a) 2085 : __r_(__a) 2086{ 2087 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr"); 2088 __init(__s, __n); 2089#if _LIBCPP_DEBUG_LEVEL >= 2 2090 __get_db()->__insert_c(this); 2091#endif 2092} 2093 2094template <class _CharT, class _Traits, class _Allocator> 2095basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str) 2096 : __r_(__alloc_traits::select_on_container_copy_construction(__str.__alloc())) 2097{ 2098 if (!__str.__is_long()) 2099 __r_.first().__r = __str.__r_.first().__r; 2100 else 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); 2104#endif 2105} 2106 2107template <class _CharT, class _Traits, class _Allocator> 2108basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, const allocator_type& __a) 2109 : __r_(__a) 2110{ 2111 if (!__str.__is_long()) 2112 __r_.first().__r = __str.__r_.first().__r; 2113 else 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); 2117#endif 2118} 2119 2120#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 2121 2122template <class _CharT, class _Traits, class _Allocator> 2123inline _LIBCPP_INLINE_VISIBILITY 2124basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str) 2125 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value) 2126 : __r_(_VSTD::move(__str.__r_)) 2127{ 2128 __str.__zero(); 2129#if _LIBCPP_DEBUG_LEVEL >= 2 2130 __get_db()->__insert_c(this); 2131 if (__is_long()) 2132 __get_db()->swap(this, &__str); 2133#endif 2134} 2135 2136template <class _CharT, class _Traits, class _Allocator> 2137inline _LIBCPP_INLINE_VISIBILITY 2138basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, const allocator_type& __a) 2139 : __r_(__a) 2140{ 2141 if (__str.__is_long() && __a != __str.__alloc()) // copy, not move 2142 __init(_VSTD::__to_raw_pointer(__str.__get_long_pointer()), __str.__get_long_size()); 2143 else 2144 { 2145 __r_.first().__r = __str.__r_.first().__r; 2146 __str.__zero(); 2147 } 2148#if _LIBCPP_DEBUG_LEVEL >= 2 2149 __get_db()->__insert_c(this); 2150 if (__is_long()) 2151 __get_db()->swap(this, &__str); 2152#endif 2153} 2154 2155#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 2156 2157template <class _CharT, class _Traits, class _Allocator> 2158void 2159basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c) 2160{ 2161 if (__n > max_size()) 2162 this->__throw_length_error(); 2163 pointer __p; 2164 if (__n < __min_cap) 2165 { 2166 __set_short_size(__n); 2167 __p = __get_short_pointer(); 2168 } 2169 else 2170 { 2171 size_type __cap = __recommend(__n); 2172 __p = __alloc_traits::allocate(__alloc(), __cap+1); 2173 __set_long_pointer(__p); 2174 __set_long_cap(__cap+1); 2175 __set_long_size(__n); 2176 } 2177 traits_type::assign(_VSTD::__to_raw_pointer(__p), __n, __c); 2178 traits_type::assign(__p[__n], value_type()); 2179} 2180 2181template <class _CharT, class _Traits, class _Allocator> 2182inline _LIBCPP_INLINE_VISIBILITY 2183basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, value_type __c) 2184{ 2185 __init(__n, __c); 2186#if _LIBCPP_DEBUG_LEVEL >= 2 2187 __get_db()->__insert_c(this); 2188#endif 2189} 2190 2191template <class _CharT, class _Traits, class _Allocator> 2192inline _LIBCPP_INLINE_VISIBILITY 2193basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, value_type __c, const allocator_type& __a) 2194 : __r_(__a) 2195{ 2196 __init(__n, __c); 2197#if _LIBCPP_DEBUG_LEVEL >= 2 2198 __get_db()->__insert_c(this); 2199#endif 2200} 2201 2202template <class _CharT, class _Traits, class _Allocator> 2203basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos, size_type __n, 2204 const allocator_type& __a) 2205 : __r_(__a) 2206{ 2207 size_type __str_sz = __str.size(); 2208 if (__pos > __str_sz) 2209 this->__throw_out_of_range(); 2210 __init(__str.data() + __pos, _VSTD::min(__n, __str_sz - __pos)); 2211#if _LIBCPP_DEBUG_LEVEL >= 2 2212 __get_db()->__insert_c(this); 2213#endif 2214} 2215 2216template <class _CharT, class _Traits, class _Allocator> 2217template <class _InputIterator> 2218typename enable_if 2219< 2220 __is_input_iterator <_InputIterator>::value && 2221 !__is_forward_iterator<_InputIterator>::value, 2222 void 2223>::type 2224basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last) 2225{ 2226 __zero(); 2227#ifndef _LIBCPP_NO_EXCEPTIONS 2228 try 2229 { 2230#endif // _LIBCPP_NO_EXCEPTIONS 2231 for (; __first != __last; ++__first) 2232 push_back(*__first); 2233#ifndef _LIBCPP_NO_EXCEPTIONS 2234 } 2235 catch (...) 2236 { 2237 if (__is_long()) 2238 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 2239 throw; 2240 } 2241#endif // _LIBCPP_NO_EXCEPTIONS 2242} 2243 2244template <class _CharT, class _Traits, class _Allocator> 2245template <class _ForwardIterator> 2246typename enable_if 2247< 2248 __is_forward_iterator<_ForwardIterator>::value, 2249 void 2250>::type 2251basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last) 2252{ 2253 size_type __sz = static_cast<size_type>(_VSTD::distance(__first, __last)); 2254 if (__sz > max_size()) 2255 this->__throw_length_error(); 2256 pointer __p; 2257 if (__sz < __min_cap) 2258 { 2259 __set_short_size(__sz); 2260 __p = __get_short_pointer(); 2261 } 2262 else 2263 { 2264 size_type __cap = __recommend(__sz); 2265 __p = __alloc_traits::allocate(__alloc(), __cap+1); 2266 __set_long_pointer(__p); 2267 __set_long_cap(__cap+1); 2268 __set_long_size(__sz); 2269 } 2270 for (; __first != __last; ++__first, ++__p) 2271 traits_type::assign(*__p, *__first); 2272 traits_type::assign(*__p, value_type()); 2273} 2274 2275template <class _CharT, class _Traits, class _Allocator> 2276template<class _InputIterator> 2277inline _LIBCPP_INLINE_VISIBILITY 2278basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last) 2279{ 2280 __init(__first, __last); 2281#if _LIBCPP_DEBUG_LEVEL >= 2 2282 __get_db()->__insert_c(this); 2283#endif 2284} 2285 2286template <class _CharT, class _Traits, class _Allocator> 2287template<class _InputIterator> 2288inline _LIBCPP_INLINE_VISIBILITY 2289basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last, 2290 const allocator_type& __a) 2291 : __r_(__a) 2292{ 2293 __init(__first, __last); 2294#if _LIBCPP_DEBUG_LEVEL >= 2 2295 __get_db()->__insert_c(this); 2296#endif 2297} 2298 2299#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS 2300 2301template <class _CharT, class _Traits, class _Allocator> 2302inline _LIBCPP_INLINE_VISIBILITY 2303basic_string<_CharT, _Traits, _Allocator>::basic_string(initializer_list<value_type> __il) 2304{ 2305 __init(__il.begin(), __il.end()); 2306#if _LIBCPP_DEBUG_LEVEL >= 2 2307 __get_db()->__insert_c(this); 2308#endif 2309} 2310 2311template <class _CharT, class _Traits, class _Allocator> 2312inline _LIBCPP_INLINE_VISIBILITY 2313basic_string<_CharT, _Traits, _Allocator>::basic_string(initializer_list<value_type> __il, const allocator_type& __a) 2314 : __r_(__a) 2315{ 2316 __init(__il.begin(), __il.end()); 2317#if _LIBCPP_DEBUG_LEVEL >= 2 2318 __get_db()->__insert_c(this); 2319#endif 2320} 2321 2322#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS 2323 2324template <class _CharT, class _Traits, class _Allocator> 2325basic_string<_CharT, _Traits, _Allocator>::~basic_string() 2326{ 2327#if _LIBCPP_DEBUG_LEVEL >= 2 2328 __get_db()->__erase_c(this); 2329#endif 2330 if (__is_long()) 2331 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 2332} 2333 2334template <class _CharT, class _Traits, class _Allocator> 2335void 2336basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace 2337 (size_type __old_cap, size_type __delta_cap, size_type __old_sz, 2338 size_type __n_copy, size_type __n_del, size_type __n_add, const value_type* __p_new_stuff) 2339{ 2340 size_type __ms = max_size(); 2341 if (__delta_cap > __ms - __old_cap - 1) 2342 this->__throw_length_error(); 2343 pointer __old_p = __get_pointer(); 2344 size_type __cap = __old_cap < __ms / 2 - __alignment ? 2345 __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) : 2346 __ms - 1; 2347 pointer __p = __alloc_traits::allocate(__alloc(), __cap+1); 2348 __invalidate_all_iterators(); 2349 if (__n_copy != 0) 2350 traits_type::copy(_VSTD::__to_raw_pointer(__p), 2351 _VSTD::__to_raw_pointer(__old_p), __n_copy); 2352 if (__n_add != 0) 2353 traits_type::copy(_VSTD::__to_raw_pointer(__p) + __n_copy, __p_new_stuff, __n_add); 2354 size_type __sec_cp_sz = __old_sz - __n_del - __n_copy; 2355 if (__sec_cp_sz != 0) 2356 traits_type::copy(_VSTD::__to_raw_pointer(__p) + __n_copy + __n_add, 2357 _VSTD::__to_raw_pointer(__old_p) + __n_copy + __n_del, __sec_cp_sz); 2358 if (__old_cap+1 != __min_cap) 2359 __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1); 2360 __set_long_pointer(__p); 2361 __set_long_cap(__cap+1); 2362 __old_sz = __n_copy + __n_add + __sec_cp_sz; 2363 __set_long_size(__old_sz); 2364 traits_type::assign(__p[__old_sz], value_type()); 2365} 2366 2367template <class _CharT, class _Traits, class _Allocator> 2368void 2369basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz, 2370 size_type __n_copy, size_type __n_del, size_type __n_add) 2371{ 2372 size_type __ms = max_size(); 2373 if (__delta_cap > __ms - __old_cap) 2374 this->__throw_length_error(); 2375 pointer __old_p = __get_pointer(); 2376 size_type __cap = __old_cap < __ms / 2 - __alignment ? 2377 __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) : 2378 __ms - 1; 2379 pointer __p = __alloc_traits::allocate(__alloc(), __cap+1); 2380 __invalidate_all_iterators(); 2381 if (__n_copy != 0) 2382 traits_type::copy(_VSTD::__to_raw_pointer(__p), 2383 _VSTD::__to_raw_pointer(__old_p), __n_copy); 2384 size_type __sec_cp_sz = __old_sz - __n_del - __n_copy; 2385 if (__sec_cp_sz != 0) 2386 traits_type::copy(_VSTD::__to_raw_pointer(__p) + __n_copy + __n_add, 2387 _VSTD::__to_raw_pointer(__old_p) + __n_copy + __n_del, 2388 __sec_cp_sz); 2389 if (__old_cap+1 != __min_cap) 2390 __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1); 2391 __set_long_pointer(__p); 2392 __set_long_cap(__cap+1); 2393} 2394 2395// assign 2396 2397template <class _CharT, class _Traits, class _Allocator> 2398basic_string<_CharT, _Traits, _Allocator>& 2399basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n) 2400{ 2401 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::assign received nullptr"); 2402 size_type __cap = capacity(); 2403 if (__cap >= __n) 2404 { 2405 value_type* __p = _VSTD::__to_raw_pointer(__get_pointer()); 2406 traits_type::move(__p, __s, __n); 2407 traits_type::assign(__p[__n], value_type()); 2408 __set_size(__n); 2409 __invalidate_iterators_past(__n); 2410 } 2411 else 2412 { 2413 size_type __sz = size(); 2414 __grow_by_and_replace(__cap, __n - __cap, __sz, 0, __sz, __n, __s); 2415 } 2416 return *this; 2417} 2418 2419template <class _CharT, class _Traits, class _Allocator> 2420basic_string<_CharT, _Traits, _Allocator>& 2421basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c) 2422{ 2423 size_type __cap = capacity(); 2424 if (__cap < __n) 2425 { 2426 size_type __sz = size(); 2427 __grow_by(__cap, __n - __cap, __sz, 0, __sz); 2428 } 2429 else 2430 __invalidate_iterators_past(__n); 2431 value_type* __p = _VSTD::__to_raw_pointer(__get_pointer()); 2432 traits_type::assign(__p, __n, __c); 2433 traits_type::assign(__p[__n], value_type()); 2434 __set_size(__n); 2435 return *this; 2436} 2437 2438template <class _CharT, class _Traits, class _Allocator> 2439basic_string<_CharT, _Traits, _Allocator>& 2440basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c) 2441{ 2442 pointer __p; 2443 if (__is_long()) 2444 { 2445 __p = __get_long_pointer(); 2446 __set_long_size(1); 2447 } 2448 else 2449 { 2450 __p = __get_short_pointer(); 2451 __set_short_size(1); 2452 } 2453 traits_type::assign(*__p, __c); 2454 traits_type::assign(*++__p, value_type()); 2455 __invalidate_iterators_past(1); 2456 return *this; 2457} 2458 2459template <class _CharT, class _Traits, class _Allocator> 2460basic_string<_CharT, _Traits, _Allocator>& 2461basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str) 2462{ 2463 if (this != &__str) 2464 { 2465 __copy_assign_alloc(__str); 2466 assign(__str); 2467 } 2468 return *this; 2469} 2470 2471#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 2472 2473template <class _CharT, class _Traits, class _Allocator> 2474inline _LIBCPP_INLINE_VISIBILITY 2475void 2476basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, false_type) 2477{ 2478 if (__alloc() != __str.__alloc()) 2479 assign(__str); 2480 else 2481 __move_assign(__str, true_type()); 2482} 2483 2484template <class _CharT, class _Traits, class _Allocator> 2485inline _LIBCPP_INLINE_VISIBILITY 2486void 2487basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type) 2488 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) 2489{ 2490 clear(); 2491 shrink_to_fit(); 2492 __r_.first() = __str.__r_.first(); 2493 __move_assign_alloc(__str); 2494 __str.__zero(); 2495} 2496 2497template <class _CharT, class _Traits, class _Allocator> 2498inline _LIBCPP_INLINE_VISIBILITY 2499basic_string<_CharT, _Traits, _Allocator>& 2500basic_string<_CharT, _Traits, _Allocator>::operator=(basic_string&& __str) 2501 _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value && 2502 is_nothrow_move_assignable<allocator_type>::value) 2503{ 2504 __move_assign(__str, integral_constant<bool, 2505 __alloc_traits::propagate_on_container_move_assignment::value>()); 2506 return *this; 2507} 2508 2509#endif 2510 2511template <class _CharT, class _Traits, class _Allocator> 2512template<class _InputIterator> 2513typename enable_if 2514< 2515 __is_input_iterator <_InputIterator>::value && 2516 !__is_forward_iterator<_InputIterator>::value, 2517 basic_string<_CharT, _Traits, _Allocator>& 2518>::type 2519basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last) 2520{ 2521 clear(); 2522 for (; __first != __last; ++__first) 2523 push_back(*__first); 2524 return *this; 2525} 2526 2527template <class _CharT, class _Traits, class _Allocator> 2528template<class _ForwardIterator> 2529typename enable_if 2530< 2531 __is_forward_iterator<_ForwardIterator>::value, 2532 basic_string<_CharT, _Traits, _Allocator>& 2533>::type 2534basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last) 2535{ 2536 size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last)); 2537 size_type __cap = capacity(); 2538 if (__cap < __n) 2539 { 2540 size_type __sz = size(); 2541 __grow_by(__cap, __n - __cap, __sz, 0, __sz); 2542 } 2543 else 2544 __invalidate_iterators_past(__n); 2545 pointer __p = __get_pointer(); 2546 for (; __first != __last; ++__first, ++__p) 2547 traits_type::assign(*__p, *__first); 2548 traits_type::assign(*__p, value_type()); 2549 __set_size(__n); 2550 return *this; 2551} 2552 2553template <class _CharT, class _Traits, class _Allocator> 2554inline _LIBCPP_INLINE_VISIBILITY 2555basic_string<_CharT, _Traits, _Allocator>& 2556basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str) 2557{ 2558 return assign(__str.data(), __str.size()); 2559} 2560 2561template <class _CharT, class _Traits, class _Allocator> 2562basic_string<_CharT, _Traits, _Allocator>& 2563basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, size_type __pos, size_type __n) 2564{ 2565 size_type __sz = __str.size(); 2566 if (__pos > __sz) 2567 this->__throw_out_of_range(); 2568 return assign(__str.data() + __pos, _VSTD::min(__n, __sz - __pos)); 2569} 2570 2571template <class _CharT, class _Traits, class _Allocator> 2572basic_string<_CharT, _Traits, _Allocator>& 2573basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s) 2574{ 2575 _LIBCPP_ASSERT(__s != nullptr, "string::assign received nullptr"); 2576 return assign(__s, traits_type::length(__s)); 2577} 2578 2579// append 2580 2581template <class _CharT, class _Traits, class _Allocator> 2582basic_string<_CharT, _Traits, _Allocator>& 2583basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n) 2584{ 2585 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::append received nullptr"); 2586 size_type __cap = capacity(); 2587 size_type __sz = size(); 2588 if (__cap - __sz >= __n) 2589 { 2590 if (__n) 2591 { 2592 value_type* __p = _VSTD::__to_raw_pointer(__get_pointer()); 2593 traits_type::copy(__p + __sz, __s, __n); 2594 __sz += __n; 2595 __set_size(__sz); 2596 traits_type::assign(__p[__sz], value_type()); 2597 } 2598 } 2599 else 2600 __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __sz, 0, __n, __s); 2601 return *this; 2602} 2603 2604template <class _CharT, class _Traits, class _Allocator> 2605basic_string<_CharT, _Traits, _Allocator>& 2606basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c) 2607{ 2608 if (__n) 2609 { 2610 size_type __cap = capacity(); 2611 size_type __sz = size(); 2612 if (__cap - __sz < __n) 2613 __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); 2614 pointer __p = __get_pointer(); 2615 traits_type::assign(_VSTD::__to_raw_pointer(__p) + __sz, __n, __c); 2616 __sz += __n; 2617 __set_size(__sz); 2618 traits_type::assign(__p[__sz], value_type()); 2619 } 2620 return *this; 2621} 2622 2623template <class _CharT, class _Traits, class _Allocator> 2624void 2625basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c) 2626{ 2627 bool __is_short = !__is_long(); 2628 size_type __cap; 2629 size_type __sz; 2630 if (__is_short) 2631 { 2632 __cap = __min_cap - 1; 2633 __sz = __get_short_size(); 2634 } 2635 else 2636 { 2637 __cap = __get_long_cap() - 1; 2638 __sz = __get_long_size(); 2639 } 2640 if (__sz == __cap) 2641 { 2642 __grow_by(__cap, 1, __sz, __sz, 0); 2643 __is_short = !__is_long(); 2644 } 2645 pointer __p; 2646 if (__is_short) 2647 { 2648 __p = __get_short_pointer() + __sz; 2649 __set_short_size(__sz+1); 2650 } 2651 else 2652 { 2653 __p = __get_long_pointer() + __sz; 2654 __set_long_size(__sz+1); 2655 } 2656 traits_type::assign(*__p, __c); 2657 traits_type::assign(*++__p, value_type()); 2658} 2659 2660template <class _CharT, class _Traits, class _Allocator> 2661template<class _InputIterator> 2662typename enable_if 2663< 2664 __is_input_iterator <_InputIterator>::value && 2665 !__is_forward_iterator<_InputIterator>::value, 2666 basic_string<_CharT, _Traits, _Allocator>& 2667>::type 2668basic_string<_CharT, _Traits, _Allocator>::append(_InputIterator __first, _InputIterator __last) 2669{ 2670 for (; __first != __last; ++__first) 2671 push_back(*__first); 2672 return *this; 2673} 2674 2675template <class _CharT, class _Traits, class _Allocator> 2676template<class _ForwardIterator> 2677typename enable_if 2678< 2679 __is_forward_iterator<_ForwardIterator>::value, 2680 basic_string<_CharT, _Traits, _Allocator>& 2681>::type 2682basic_string<_CharT, _Traits, _Allocator>::append(_ForwardIterator __first, _ForwardIterator __last) 2683{ 2684 size_type __sz = size(); 2685 size_type __cap = capacity(); 2686 size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last)); 2687 if (__n) 2688 { 2689 if (__cap - __sz < __n) 2690 __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); 2691 pointer __p = __get_pointer() + __sz; 2692 for (; __first != __last; ++__p, ++__first) 2693 traits_type::assign(*__p, *__first); 2694 traits_type::assign(*__p, value_type()); 2695 __set_size(__sz + __n); 2696 } 2697 return *this; 2698} 2699 2700template <class _CharT, class _Traits, class _Allocator> 2701inline _LIBCPP_INLINE_VISIBILITY 2702basic_string<_CharT, _Traits, _Allocator>& 2703basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str) 2704{ 2705 return append(__str.data(), __str.size()); 2706} 2707 2708template <class _CharT, class _Traits, class _Allocator> 2709basic_string<_CharT, _Traits, _Allocator>& 2710basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, size_type __pos, size_type __n) 2711{ 2712 size_type __sz = __str.size(); 2713 if (__pos > __sz) 2714 this->__throw_out_of_range(); 2715 return append(__str.data() + __pos, _VSTD::min(__n, __sz - __pos)); 2716} 2717 2718template <class _CharT, class _Traits, class _Allocator> 2719basic_string<_CharT, _Traits, _Allocator>& 2720basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s) 2721{ 2722 _LIBCPP_ASSERT(__s != nullptr, "string::append received nullptr"); 2723 return append(__s, traits_type::length(__s)); 2724} 2725 2726// insert 2727 2728template <class _CharT, class _Traits, class _Allocator> 2729basic_string<_CharT, _Traits, _Allocator>& 2730basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n) 2731{ 2732 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::insert received nullptr"); 2733 size_type __sz = size(); 2734 if (__pos > __sz) 2735 this->__throw_out_of_range(); 2736 size_type __cap = capacity(); 2737 if (__cap - __sz >= __n) 2738 { 2739 if (__n) 2740 { 2741 value_type* __p = _VSTD::__to_raw_pointer(__get_pointer()); 2742 size_type __n_move = __sz - __pos; 2743 if (__n_move != 0) 2744 { 2745 if (__p + __pos <= __s && __s < __p + __sz) 2746 __s += __n; 2747 traits_type::move(__p + __pos + __n, __p + __pos, __n_move); 2748 } 2749 traits_type::move(__p + __pos, __s, __n); 2750 __sz += __n; 2751 __set_size(__sz); 2752 traits_type::assign(__p[__sz], value_type()); 2753 } 2754 } 2755 else 2756 __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s); 2757 return *this; 2758} 2759 2760template <class _CharT, class _Traits, class _Allocator> 2761basic_string<_CharT, _Traits, _Allocator>& 2762basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n, value_type __c) 2763{ 2764 size_type __sz = size(); 2765 if (__pos > __sz) 2766 this->__throw_out_of_range(); 2767 if (__n) 2768 { 2769 size_type __cap = capacity(); 2770 value_type* __p; 2771 if (__cap - __sz >= __n) 2772 { 2773 __p = _VSTD::__to_raw_pointer(__get_pointer()); 2774 size_type __n_move = __sz - __pos; 2775 if (__n_move != 0) 2776 traits_type::move(__p + __pos + __n, __p + __pos, __n_move); 2777 } 2778 else 2779 { 2780 __grow_by(__cap, __sz + __n - __cap, __sz, __pos, 0, __n); 2781 __p = _VSTD::__to_raw_pointer(__get_long_pointer()); 2782 } 2783 traits_type::assign(__p + __pos, __n, __c); 2784 __sz += __n; 2785 __set_size(__sz); 2786 traits_type::assign(__p[__sz], value_type()); 2787 } 2788 return *this; 2789} 2790 2791template <class _CharT, class _Traits, class _Allocator> 2792template<class _InputIterator> 2793typename enable_if 2794< 2795 __is_input_iterator <_InputIterator>::value && 2796 !__is_forward_iterator<_InputIterator>::value, 2797 typename basic_string<_CharT, _Traits, _Allocator>::iterator 2798>::type 2799basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last) 2800{ 2801#if _LIBCPP_DEBUG_LEVEL >= 2 2802 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, 2803 "string::insert(iterator, range) called with an iterator not" 2804 " referring to this string"); 2805#endif 2806 size_type __old_sz = size(); 2807 difference_type __ip = __pos - begin(); 2808 for (; __first != __last; ++__first) 2809 push_back(*__first); 2810 pointer __p = __get_pointer(); 2811 _VSTD::rotate(__p + __ip, __p + __old_sz, __p + size()); 2812#if _LIBCPP_DEBUG_LEVEL >= 2 2813 return iterator(this, __p + __ip); 2814#else 2815 return iterator(__p + __ip); 2816#endif 2817} 2818 2819template <class _CharT, class _Traits, class _Allocator> 2820template<class _ForwardIterator> 2821typename enable_if 2822< 2823 __is_forward_iterator<_ForwardIterator>::value, 2824 typename basic_string<_CharT, _Traits, _Allocator>::iterator 2825>::type 2826basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last) 2827{ 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"); 2832#endif 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)); 2837 if (__n) 2838 { 2839 value_type* __p; 2840 if (__cap - __sz >= __n) 2841 { 2842 __p = _VSTD::__to_raw_pointer(__get_pointer()); 2843 size_type __n_move = __sz - __ip; 2844 if (__n_move != 0) 2845 traits_type::move(__p + __ip + __n, __p + __ip, __n_move); 2846 } 2847 else 2848 { 2849 __grow_by(__cap, __sz + __n - __cap, __sz, __ip, 0, __n); 2850 __p = _VSTD::__to_raw_pointer(__get_long_pointer()); 2851 } 2852 __sz += __n; 2853 __set_size(__sz); 2854 traits_type::assign(__p[__sz], value_type()); 2855 for (__p += __ip; __first != __last; ++__p, ++__first) 2856 traits_type::assign(*__p, *__first); 2857 } 2858 return begin() + __ip; 2859} 2860 2861template <class _CharT, class _Traits, class _Allocator> 2862inline _LIBCPP_INLINE_VISIBILITY 2863basic_string<_CharT, _Traits, _Allocator>& 2864basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str) 2865{ 2866 return insert(__pos1, __str.data(), __str.size()); 2867} 2868 2869template <class _CharT, class _Traits, class _Allocator> 2870basic_string<_CharT, _Traits, _Allocator>& 2871basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str, 2872 size_type __pos2, size_type __n) 2873{ 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)); 2878} 2879 2880template <class _CharT, class _Traits, class _Allocator> 2881basic_string<_CharT, _Traits, _Allocator>& 2882basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s) 2883{ 2884 _LIBCPP_ASSERT(__s != nullptr, "string::insert received nullptr"); 2885 return insert(__pos, __s, traits_type::length(__s)); 2886} 2887 2888template <class _CharT, class _Traits, class _Allocator> 2889typename basic_string<_CharT, _Traits, _Allocator>::iterator 2890basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c) 2891{ 2892 size_type __ip = static_cast<size_type>(__pos - begin()); 2893 size_type __sz = size(); 2894 size_type __cap = capacity(); 2895 value_type* __p; 2896 if (__cap == __sz) 2897 { 2898 __grow_by(__cap, 1, __sz, __ip, 0, 1); 2899 __p = _VSTD::__to_raw_pointer(__get_long_pointer()); 2900 } 2901 else 2902 { 2903 __p = _VSTD::__to_raw_pointer(__get_pointer()); 2904 size_type __n_move = __sz - __ip; 2905 if (__n_move != 0) 2906 traits_type::move(__p + __ip + 1, __p + __ip, __n_move); 2907 } 2908 traits_type::assign(__p[__ip], __c); 2909 traits_type::assign(__p[++__sz], value_type()); 2910 __set_size(__sz); 2911 return begin() + static_cast<difference_type>(__ip); 2912} 2913 2914template <class _CharT, class _Traits, class _Allocator> 2915inline _LIBCPP_INLINE_VISIBILITY 2916typename basic_string<_CharT, _Traits, _Allocator>::iterator 2917basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, size_type __n, value_type __c) 2918{ 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"); 2923#endif 2924 difference_type __p = __pos - begin(); 2925 insert(static_cast<size_type>(__p), __n, __c); 2926 return begin() + __p; 2927} 2928 2929// replace 2930 2931template <class _CharT, class _Traits, class _Allocator> 2932basic_string<_CharT, _Traits, _Allocator>& 2933basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2) 2934{ 2935 _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::replace received nullptr"); 2936 size_type __sz = size(); 2937 if (__pos > __sz) 2938 this->__throw_out_of_range(); 2939 __n1 = _VSTD::min(__n1, __sz - __pos); 2940 size_type __cap = capacity(); 2941 if (__cap - __sz + __n1 >= __n2) 2942 { 2943 value_type* __p = _VSTD::__to_raw_pointer(__get_pointer()); 2944 if (__n1 != __n2) 2945 { 2946 size_type __n_move = __sz - __pos - __n1; 2947 if (__n_move != 0) 2948 { 2949 if (__n1 > __n2) 2950 { 2951 traits_type::move(__p + __pos, __s, __n2); 2952 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move); 2953 goto __finish; 2954 } 2955 if (__p + __pos < __s && __s < __p + __sz) 2956 { 2957 if (__p + __pos + __n1 <= __s) 2958 __s += __n2 - __n1; 2959 else // __p + __pos < __s < __p + __pos + __n1 2960 { 2961 traits_type::move(__p + __pos, __s, __n1); 2962 __pos += __n1; 2963 __s += __n2; 2964 __n2 -= __n1; 2965 __n1 = 0; 2966 } 2967 } 2968 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move); 2969 } 2970 } 2971 traits_type::move(__p + __pos, __s, __n2); 2972__finish: 2973 __sz += __n2 - __n1; 2974 __set_size(__sz); 2975 __invalidate_iterators_past(__sz); 2976 traits_type::assign(__p[__sz], value_type()); 2977 } 2978 else 2979 __grow_by_and_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2, __s); 2980 return *this; 2981} 2982 2983template <class _CharT, class _Traits, class _Allocator> 2984basic_string<_CharT, _Traits, _Allocator>& 2985basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, size_type __n2, value_type __c) 2986{ 2987 size_type __sz = size(); 2988 if (__pos > __sz) 2989 this->__throw_out_of_range(); 2990 __n1 = _VSTD::min(__n1, __sz - __pos); 2991 size_type __cap = capacity(); 2992 value_type* __p; 2993 if (__cap - __sz + __n1 >= __n2) 2994 { 2995 __p = _VSTD::__to_raw_pointer(__get_pointer()); 2996 if (__n1 != __n2) 2997 { 2998 size_type __n_move = __sz - __pos - __n1; 2999 if (__n_move != 0) 3000 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move); 3001 } 3002 } 3003 else 3004 { 3005 __grow_by(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2); 3006 __p = _VSTD::__to_raw_pointer(__get_long_pointer()); 3007 } 3008 traits_type::assign(__p + __pos, __n2, __c); 3009 __sz += __n2 - __n1; 3010 __set_size(__sz); 3011 __invalidate_iterators_past(__sz); 3012 traits_type::assign(__p[__sz], value_type()); 3013 return *this; 3014} 3015 3016template <class _CharT, class _Traits, class _Allocator> 3017template<class _InputIterator> 3018typename enable_if 3019< 3020 __is_input_iterator<_InputIterator>::value, 3021 basic_string<_CharT, _Traits, _Allocator>& 3022>::type 3023basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, 3024 _InputIterator __j1, _InputIterator __j2) 3025{ 3026 for (; true; ++__i1, ++__j1) 3027 { 3028 if (__i1 == __i2) 3029 { 3030 if (__j1 != __j2) 3031 insert(__i1, __j1, __j2); 3032 break; 3033 } 3034 if (__j1 == __j2) 3035 { 3036 erase(__i1, __i2); 3037 break; 3038 } 3039 traits_type::assign(const_cast<value_type&>(*__i1), *__j1); 3040 } 3041 return *this; 3042} 3043 3044template <class _CharT, class _Traits, class _Allocator> 3045inline _LIBCPP_INLINE_VISIBILITY 3046basic_string<_CharT, _Traits, _Allocator>& 3047basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str) 3048{ 3049 return replace(__pos1, __n1, __str.data(), __str.size()); 3050} 3051 3052template <class _CharT, class _Traits, class _Allocator> 3053basic_string<_CharT, _Traits, _Allocator>& 3054basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str, 3055 size_type __pos2, size_type __n2) 3056{ 3057 size_type __str_sz = __str.size(); 3058 if (__pos2 > __str_sz) 3059 this->__throw_out_of_range(); 3060 return replace(__pos1, __n1, __str.data() + __pos2, _VSTD::min(__n2, __str_sz - __pos2)); 3061} 3062 3063template <class _CharT, class _Traits, class _Allocator> 3064basic_string<_CharT, _Traits, _Allocator>& 3065basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s) 3066{ 3067 _LIBCPP_ASSERT(__s != nullptr, "string::replace received nullptr"); 3068 return replace(__pos, __n1, __s, traits_type::length(__s)); 3069} 3070 3071template <class _CharT, class _Traits, class _Allocator> 3072inline _LIBCPP_INLINE_VISIBILITY 3073basic_string<_CharT, _Traits, _Allocator>& 3074basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const basic_string& __str) 3075{ 3076 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), 3077 __str.data(), __str.size()); 3078} 3079 3080template <class _CharT, class _Traits, class _Allocator> 3081inline _LIBCPP_INLINE_VISIBILITY 3082basic_string<_CharT, _Traits, _Allocator>& 3083basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n) 3084{ 3085 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s, __n); 3086} 3087 3088template <class _CharT, class _Traits, class _Allocator> 3089inline _LIBCPP_INLINE_VISIBILITY 3090basic_string<_CharT, _Traits, _Allocator>& 3091basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s) 3092{ 3093 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s); 3094} 3095 3096template <class _CharT, class _Traits, class _Allocator> 3097inline _LIBCPP_INLINE_VISIBILITY 3098basic_string<_CharT, _Traits, _Allocator>& 3099basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c) 3100{ 3101 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __n, __c); 3102} 3103 3104// erase 3105 3106template <class _CharT, class _Traits, class _Allocator> 3107basic_string<_CharT, _Traits, _Allocator>& 3108basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, size_type __n) 3109{ 3110 size_type __sz = size(); 3111 if (__pos > __sz) 3112 this->__throw_out_of_range(); 3113 if (__n) 3114 { 3115 value_type* __p = _VSTD::__to_raw_pointer(__get_pointer()); 3116 __n = _VSTD::min(__n, __sz - __pos); 3117 size_type __n_move = __sz - __pos - __n; 3118 if (__n_move != 0) 3119 traits_type::move(__p + __pos, __p + __pos + __n, __n_move); 3120 __sz -= __n; 3121 __set_size(__sz); 3122 __invalidate_iterators_past(__sz); 3123 traits_type::assign(__p[__sz], value_type()); 3124 } 3125 return *this; 3126} 3127 3128template <class _CharT, class _Traits, class _Allocator> 3129inline _LIBCPP_INLINE_VISIBILITY 3130typename basic_string<_CharT, _Traits, _Allocator>::iterator 3131basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos) 3132{ 3133#if _LIBCPP_DEBUG_LEVEL >= 2 3134 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, 3135 "string::erase(iterator) called with an iterator not" 3136 " referring to this string"); 3137#endif 3138 _LIBCPP_ASSERT(__pos != end(), 3139 "string::erase(iterator) called with a non-dereferenceable iterator"); 3140 iterator __b = begin(); 3141 size_type __r = static_cast<size_type>(__pos - __b); 3142 erase(__r, 1); 3143 return __b + static_cast<difference_type>(__r); 3144} 3145 3146template <class _CharT, class _Traits, class _Allocator> 3147inline _LIBCPP_INLINE_VISIBILITY 3148typename basic_string<_CharT, _Traits, _Allocator>::iterator 3149basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last) 3150{ 3151#if _LIBCPP_DEBUG_LEVEL >= 2 3152 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this, 3153 "string::erase(iterator, iterator) called with an iterator not" 3154 " referring to this string"); 3155#endif 3156 _LIBCPP_ASSERT(__first <= __last, "string::erase(first, last) called with invalid range"); 3157 iterator __b = begin(); 3158 size_type __r = static_cast<size_type>(__first - __b); 3159 erase(__r, static_cast<size_type>(__last - __first)); 3160 return __b + static_cast<difference_type>(__r); 3161} 3162 3163template <class _CharT, class _Traits, class _Allocator> 3164inline _LIBCPP_INLINE_VISIBILITY 3165void 3166basic_string<_CharT, _Traits, _Allocator>::pop_back() 3167{ 3168 _LIBCPP_ASSERT(!empty(), "string::pop_back(): string is already empty"); 3169 size_type __sz; 3170 if (__is_long()) 3171 { 3172 __sz = __get_long_size() - 1; 3173 __set_long_size(__sz); 3174 traits_type::assign(*(__get_long_pointer() + __sz), value_type()); 3175 } 3176 else 3177 { 3178 __sz = __get_short_size() - 1; 3179 __set_short_size(__sz); 3180 traits_type::assign(*(__get_short_pointer() + __sz), value_type()); 3181 } 3182 __invalidate_iterators_past(__sz); 3183} 3184 3185template <class _CharT, class _Traits, class _Allocator> 3186inline _LIBCPP_INLINE_VISIBILITY 3187void 3188basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT 3189{ 3190 __invalidate_all_iterators(); 3191 if (__is_long()) 3192 { 3193 traits_type::assign(*__get_long_pointer(), value_type()); 3194 __set_long_size(0); 3195 } 3196 else 3197 { 3198 traits_type::assign(*__get_short_pointer(), value_type()); 3199 __set_short_size(0); 3200 } 3201} 3202 3203template <class _CharT, class _Traits, class _Allocator> 3204inline _LIBCPP_INLINE_VISIBILITY 3205void 3206basic_string<_CharT, _Traits, _Allocator>::__erase_to_end(size_type __pos) 3207{ 3208 if (__is_long()) 3209 { 3210 traits_type::assign(*(__get_long_pointer() + __pos), value_type()); 3211 __set_long_size(__pos); 3212 } 3213 else 3214 { 3215 traits_type::assign(*(__get_short_pointer() + __pos), value_type()); 3216 __set_short_size(__pos); 3217 } 3218 __invalidate_iterators_past(__pos); 3219} 3220 3221template <class _CharT, class _Traits, class _Allocator> 3222void 3223basic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c) 3224{ 3225 size_type __sz = size(); 3226 if (__n > __sz) 3227 append(__n - __sz, __c); 3228 else 3229 __erase_to_end(__n); 3230} 3231 3232template <class _CharT, class _Traits, class _Allocator> 3233inline _LIBCPP_INLINE_VISIBILITY 3234typename basic_string<_CharT, _Traits, _Allocator>::size_type 3235basic_string<_CharT, _Traits, _Allocator>::max_size() const _NOEXCEPT 3236{ 3237 size_type __m = __alloc_traits::max_size(__alloc()); 3238#if _LIBCPP_BIG_ENDIAN 3239 return (__m <= ~__long_mask ? __m : __m/2) - __alignment; 3240#else 3241 return __m - __alignment; 3242#endif 3243} 3244 3245template <class _CharT, class _Traits, class _Allocator> 3246void 3247basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __res_arg) 3248{ 3249 if (__res_arg > max_size()) 3250 this->__throw_length_error(); 3251 size_type __cap = capacity(); 3252 size_type __sz = size(); 3253 __res_arg = _VSTD::max(__res_arg, __sz); 3254 __res_arg = __recommend(__res_arg); 3255 if (__res_arg != __cap) 3256 { 3257 pointer __new_data, __p; 3258 bool __was_long, __now_long; 3259 if (__res_arg == __min_cap - 1) 3260 { 3261 __was_long = true; 3262 __now_long = false; 3263 __new_data = __get_short_pointer(); 3264 __p = __get_long_pointer(); 3265 } 3266 else 3267 { 3268 if (__res_arg > __cap) 3269 __new_data = __alloc_traits::allocate(__alloc(), __res_arg+1); 3270 else 3271 { 3272 #ifndef _LIBCPP_NO_EXCEPTIONS 3273 try 3274 { 3275 #endif // _LIBCPP_NO_EXCEPTIONS 3276 __new_data = __alloc_traits::allocate(__alloc(), __res_arg+1); 3277 #ifndef _LIBCPP_NO_EXCEPTIONS 3278 } 3279 catch (...) 3280 { 3281 return; 3282 } 3283 #else // _LIBCPP_NO_EXCEPTIONS 3284 if (__new_data == nullptr) 3285 return; 3286 #endif // _LIBCPP_NO_EXCEPTIONS 3287 } 3288 __now_long = true; 3289 __was_long = __is_long(); 3290 __p = __get_pointer(); 3291 } 3292 traits_type::copy(_VSTD::__to_raw_pointer(__new_data), 3293 _VSTD::__to_raw_pointer(__p), size()+1); 3294 if (__was_long) 3295 __alloc_traits::deallocate(__alloc(), __p, __cap+1); 3296 if (__now_long) 3297 { 3298 __set_long_cap(__res_arg+1); 3299 __set_long_size(__sz); 3300 __set_long_pointer(__new_data); 3301 } 3302 else 3303 __set_short_size(__sz); 3304 __invalidate_all_iterators(); 3305 } 3306} 3307 3308template <class _CharT, class _Traits, class _Allocator> 3309inline _LIBCPP_INLINE_VISIBILITY 3310typename basic_string<_CharT, _Traits, _Allocator>::const_reference 3311basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const 3312{ 3313 _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds"); 3314 return *(data() + __pos); 3315} 3316 3317template <class _CharT, class _Traits, class _Allocator> 3318inline _LIBCPP_INLINE_VISIBILITY 3319typename basic_string<_CharT, _Traits, _Allocator>::reference 3320basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) 3321{ 3322 _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds"); 3323 return *(__get_pointer() + __pos); 3324} 3325 3326template <class _CharT, class _Traits, class _Allocator> 3327typename basic_string<_CharT, _Traits, _Allocator>::const_reference 3328basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const 3329{ 3330 if (__n >= size()) 3331 this->__throw_out_of_range(); 3332 return (*this)[__n]; 3333} 3334 3335template <class _CharT, class _Traits, class _Allocator> 3336typename basic_string<_CharT, _Traits, _Allocator>::reference 3337basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) 3338{ 3339 if (__n >= size()) 3340 this->__throw_out_of_range(); 3341 return (*this)[__n]; 3342} 3343 3344template <class _CharT, class _Traits, class _Allocator> 3345inline _LIBCPP_INLINE_VISIBILITY 3346typename basic_string<_CharT, _Traits, _Allocator>::reference 3347basic_string<_CharT, _Traits, _Allocator>::front() 3348{ 3349 _LIBCPP_ASSERT(!empty(), "string::front(): string is empty"); 3350 return *__get_pointer(); 3351} 3352 3353template <class _CharT, class _Traits, class _Allocator> 3354inline _LIBCPP_INLINE_VISIBILITY 3355typename basic_string<_CharT, _Traits, _Allocator>::const_reference 3356basic_string<_CharT, _Traits, _Allocator>::front() const 3357{ 3358 _LIBCPP_ASSERT(!empty(), "string::front(): string is empty"); 3359 return *data(); 3360} 3361 3362template <class _CharT, class _Traits, class _Allocator> 3363inline _LIBCPP_INLINE_VISIBILITY 3364typename basic_string<_CharT, _Traits, _Allocator>::reference 3365basic_string<_CharT, _Traits, _Allocator>::back() 3366{ 3367 _LIBCPP_ASSERT(!empty(), "string::back(): string is empty"); 3368 return *(__get_pointer() + size() - 1); 3369} 3370 3371template <class _CharT, class _Traits, class _Allocator> 3372inline _LIBCPP_INLINE_VISIBILITY 3373typename basic_string<_CharT, _Traits, _Allocator>::const_reference 3374basic_string<_CharT, _Traits, _Allocator>::back() const 3375{ 3376 _LIBCPP_ASSERT(!empty(), "string::back(): string is empty"); 3377 return *(data() + size() - 1); 3378} 3379 3380template <class _CharT, class _Traits, class _Allocator> 3381typename basic_string<_CharT, _Traits, _Allocator>::size_type 3382basic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n, size_type __pos) const 3383{ 3384 size_type __sz = size(); 3385 if (__pos > __sz) 3386 this->__throw_out_of_range(); 3387 size_type __rlen = _VSTD::min(__n, __sz - __pos); 3388 traits_type::copy(__s, data() + __pos, __rlen); 3389 return __rlen; 3390} 3391 3392template <class _CharT, class _Traits, class _Allocator> 3393inline _LIBCPP_INLINE_VISIBILITY 3394basic_string<_CharT, _Traits, _Allocator> 3395basic_string<_CharT, _Traits, _Allocator>::substr(size_type __pos, size_type __n) const 3396{ 3397 return basic_string(*this, __pos, __n, __alloc()); 3398} 3399 3400template <class _CharT, class _Traits, class _Allocator> 3401inline _LIBCPP_INLINE_VISIBILITY 3402void 3403basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str) 3404 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || 3405 __is_nothrow_swappable<allocator_type>::value) 3406{ 3407#if _LIBCPP_DEBUG_LEVEL >= 2 3408 if (!__is_long()) 3409 __get_db()->__invalidate_all(this); 3410 if (!__str.__is_long()) 3411 __get_db()->__invalidate_all(&__str); 3412 __get_db()->swap(this, &__str); 3413#endif 3414 _VSTD::swap(__r_.first(), __str.__r_.first()); 3415 __swap_alloc(__alloc(), __str.__alloc()); 3416} 3417 3418// find 3419 3420template <class _Traits> 3421struct _LIBCPP_HIDDEN __traits_eq 3422{ 3423 typedef typename _Traits::char_type char_type; 3424 _LIBCPP_INLINE_VISIBILITY 3425 bool operator()(const char_type& __x, const char_type& __y) _NOEXCEPT 3426 {return _Traits::eq(__x, __y);} 3427}; 3428 3429template<class _CharT, class _Traits, class _Allocator> 3430typename basic_string<_CharT, _Traits, _Allocator>::size_type 3431basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, 3432 size_type __pos, 3433 size_type __n) const _NOEXCEPT 3434{ 3435 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find(): received nullptr"); 3436 return _VSTD::__str_find<value_type, size_type, traits_type, npos> 3437 (data(), size(), __s, __pos, __n); 3438} 3439 3440template<class _CharT, class _Traits, class _Allocator> 3441inline _LIBCPP_INLINE_VISIBILITY 3442typename basic_string<_CharT, _Traits, _Allocator>::size_type 3443basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str, 3444 size_type __pos) const _NOEXCEPT 3445{ 3446 return _VSTD::__str_find<value_type, size_type, traits_type, npos> 3447 (data(), size(), __str.data(), __pos, __str.size()); 3448} 3449 3450template<class _CharT, class _Traits, class _Allocator> 3451inline _LIBCPP_INLINE_VISIBILITY 3452typename basic_string<_CharT, _Traits, _Allocator>::size_type 3453basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, 3454 size_type __pos) const _NOEXCEPT 3455{ 3456 _LIBCPP_ASSERT(__s != nullptr, "string::find(): received nullptr"); 3457 return _VSTD::__str_find<value_type, size_type, traits_type, npos> 3458 (data(), size(), __s, __pos, traits_type::length(__s)); 3459} 3460 3461template<class _CharT, class _Traits, class _Allocator> 3462typename basic_string<_CharT, _Traits, _Allocator>::size_type 3463basic_string<_CharT, _Traits, _Allocator>::find(value_type __c, 3464 size_type __pos) const _NOEXCEPT 3465{ 3466 return _VSTD::__str_find<value_type, size_type, traits_type, npos> 3467 (data(), size(), __c, __pos); 3468} 3469 3470// rfind 3471 3472template<class _CharT, class _Traits, class _Allocator> 3473typename basic_string<_CharT, _Traits, _Allocator>::size_type 3474basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, 3475 size_type __pos, 3476 size_type __n) const _NOEXCEPT 3477{ 3478 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::rfind(): received nullptr"); 3479 return _VSTD::__str_rfind<value_type, size_type, traits_type, npos> 3480 (data(), size(), __s, __pos, __n); 3481} 3482 3483template<class _CharT, class _Traits, class _Allocator> 3484inline _LIBCPP_INLINE_VISIBILITY 3485typename basic_string<_CharT, _Traits, _Allocator>::size_type 3486basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str, 3487 size_type __pos) const _NOEXCEPT 3488{ 3489 return _VSTD::__str_rfind<value_type, size_type, traits_type, npos> 3490 (data(), size(), __str.data(), __pos, __str.size()); 3491} 3492 3493template<class _CharT, class _Traits, class _Allocator> 3494inline _LIBCPP_INLINE_VISIBILITY 3495typename basic_string<_CharT, _Traits, _Allocator>::size_type 3496basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, 3497 size_type __pos) const _NOEXCEPT 3498{ 3499 _LIBCPP_ASSERT(__s != nullptr, "string::rfind(): received nullptr"); 3500 return _VSTD::__str_rfind<value_type, size_type, traits_type, npos> 3501 (data(), size(), __s, __pos, traits_type::length(__s)); 3502} 3503 3504template<class _CharT, class _Traits, class _Allocator> 3505typename basic_string<_CharT, _Traits, _Allocator>::size_type 3506basic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c, 3507 size_type __pos) const _NOEXCEPT 3508{ 3509 return _VSTD::__str_rfind<value_type, size_type, traits_type, npos> 3510 (data(), size(), __c, __pos); 3511} 3512 3513// find_first_of 3514 3515template<class _CharT, class _Traits, class _Allocator> 3516typename basic_string<_CharT, _Traits, _Allocator>::size_type 3517basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, 3518 size_type __pos, 3519 size_type __n) const _NOEXCEPT 3520{ 3521 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr"); 3522 return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos> 3523 (data(), size(), __s, __pos, __n); 3524} 3525 3526template<class _CharT, class _Traits, class _Allocator> 3527inline _LIBCPP_INLINE_VISIBILITY 3528typename basic_string<_CharT, _Traits, _Allocator>::size_type 3529basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str, 3530 size_type __pos) const _NOEXCEPT 3531{ 3532 return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos> 3533 (data(), size(), __str.data(), __pos, __str.size()); 3534} 3535 3536template<class _CharT, class _Traits, class _Allocator> 3537inline _LIBCPP_INLINE_VISIBILITY 3538typename basic_string<_CharT, _Traits, _Allocator>::size_type 3539basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, 3540 size_type __pos) const _NOEXCEPT 3541{ 3542 _LIBCPP_ASSERT(__s != nullptr, "string::find_first_of(): received nullptr"); 3543 return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos> 3544 (data(), size(), __s, __pos, traits_type::length(__s)); 3545} 3546 3547template<class _CharT, class _Traits, class _Allocator> 3548inline _LIBCPP_INLINE_VISIBILITY 3549typename basic_string<_CharT, _Traits, _Allocator>::size_type 3550basic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c, 3551 size_type __pos) const _NOEXCEPT 3552{ 3553 return find(__c, __pos); 3554} 3555 3556// find_last_of 3557 3558template<class _CharT, class _Traits, class _Allocator> 3559typename basic_string<_CharT, _Traits, _Allocator>::size_type 3560basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, 3561 size_type __pos, 3562 size_type __n) const _NOEXCEPT 3563{ 3564 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr"); 3565 return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos> 3566 (data(), size(), __s, __pos, __n); 3567} 3568 3569template<class _CharT, class _Traits, class _Allocator> 3570inline _LIBCPP_INLINE_VISIBILITY 3571typename basic_string<_CharT, _Traits, _Allocator>::size_type 3572basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str, 3573 size_type __pos) const _NOEXCEPT 3574{ 3575 return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos> 3576 (data(), size(), __str.data(), __pos, __str.size()); 3577} 3578 3579template<class _CharT, class _Traits, class _Allocator> 3580inline _LIBCPP_INLINE_VISIBILITY 3581typename basic_string<_CharT, _Traits, _Allocator>::size_type 3582basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, 3583 size_type __pos) const _NOEXCEPT 3584{ 3585 _LIBCPP_ASSERT(__s != nullptr, "string::find_last_of(): received nullptr"); 3586 return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos> 3587 (data(), size(), __s, __pos, traits_type::length(__s)); 3588} 3589 3590template<class _CharT, class _Traits, class _Allocator> 3591inline _LIBCPP_INLINE_VISIBILITY 3592typename basic_string<_CharT, _Traits, _Allocator>::size_type 3593basic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c, 3594 size_type __pos) const _NOEXCEPT 3595{ 3596 return rfind(__c, __pos); 3597} 3598 3599// find_first_not_of 3600 3601template<class _CharT, class _Traits, class _Allocator> 3602typename basic_string<_CharT, _Traits, _Allocator>::size_type 3603basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s, 3604 size_type __pos, 3605 size_type __n) const _NOEXCEPT 3606{ 3607 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr"); 3608 return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos> 3609 (data(), size(), __s, __pos, __n); 3610} 3611 3612template<class _CharT, class _Traits, class _Allocator> 3613inline _LIBCPP_INLINE_VISIBILITY 3614typename basic_string<_CharT, _Traits, _Allocator>::size_type 3615basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string& __str, 3616 size_type __pos) const _NOEXCEPT 3617{ 3618 return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos> 3619 (data(), size(), __str.data(), __pos, __str.size()); 3620} 3621 3622template<class _CharT, class _Traits, class _Allocator> 3623inline _LIBCPP_INLINE_VISIBILITY 3624typename basic_string<_CharT, _Traits, _Allocator>::size_type 3625basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s, 3626 size_type __pos) const _NOEXCEPT 3627{ 3628 _LIBCPP_ASSERT(__s != nullptr, "string::find_first_not_of(): received nullptr"); 3629 return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos> 3630 (data(), size(), __s, __pos, traits_type::length(__s)); 3631} 3632 3633template<class _CharT, class _Traits, class _Allocator> 3634inline _LIBCPP_INLINE_VISIBILITY 3635typename basic_string<_CharT, _Traits, _Allocator>::size_type 3636basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c, 3637 size_type __pos) const _NOEXCEPT 3638{ 3639 return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos> 3640 (data(), size(), __c, __pos); 3641} 3642 3643// find_last_not_of 3644 3645template<class _CharT, class _Traits, class _Allocator> 3646typename basic_string<_CharT, _Traits, _Allocator>::size_type 3647basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s, 3648 size_type __pos, 3649 size_type __n) const _NOEXCEPT 3650{ 3651 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr"); 3652 return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos> 3653 (data(), size(), __s, __pos, __n); 3654} 3655 3656template<class _CharT, class _Traits, class _Allocator> 3657inline _LIBCPP_INLINE_VISIBILITY 3658typename basic_string<_CharT, _Traits, _Allocator>::size_type 3659basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string& __str, 3660 size_type __pos) const _NOEXCEPT 3661{ 3662 return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos> 3663 (data(), size(), __str.data(), __pos, __str.size()); 3664} 3665 3666template<class _CharT, class _Traits, class _Allocator> 3667inline _LIBCPP_INLINE_VISIBILITY 3668typename basic_string<_CharT, _Traits, _Allocator>::size_type 3669basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s, 3670 size_type __pos) const _NOEXCEPT 3671{ 3672 _LIBCPP_ASSERT(__s != nullptr, "string::find_last_not_of(): received nullptr"); 3673 return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos> 3674 (data(), size(), __s, __pos, traits_type::length(__s)); 3675} 3676 3677template<class _CharT, class _Traits, class _Allocator> 3678inline _LIBCPP_INLINE_VISIBILITY 3679typename basic_string<_CharT, _Traits, _Allocator>::size_type 3680basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c, 3681 size_type __pos) const _NOEXCEPT 3682{ 3683 return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos> 3684 (data(), size(), __c, __pos); 3685} 3686 3687// compare 3688 3689template <class _CharT, class _Traits, class _Allocator> 3690inline _LIBCPP_INLINE_VISIBILITY 3691int 3692basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT 3693{ 3694 size_t __lhs_sz = size(); 3695 size_t __rhs_sz = __str.size(); 3696 int __result = traits_type::compare(data(), __str.data(), 3697 _VSTD::min(__lhs_sz, __rhs_sz)); 3698 if (__result != 0) 3699 return __result; 3700 if (__lhs_sz < __rhs_sz) 3701 return -1; 3702 if (__lhs_sz > __rhs_sz) 3703 return 1; 3704 return 0; 3705} 3706 3707template <class _CharT, class _Traits, class _Allocator> 3708inline _LIBCPP_INLINE_VISIBILITY 3709int 3710basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, 3711 size_type __n1, 3712 const basic_string& __str) const 3713{ 3714 return compare(__pos1, __n1, __str.data(), __str.size()); 3715} 3716 3717template <class _CharT, class _Traits, class _Allocator> 3718int 3719basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, 3720 size_type __n1, 3721 const basic_string& __str, 3722 size_type __pos2, 3723 size_type __n2) const 3724{ 3725 size_type __sz = __str.size(); 3726 if (__pos2 > __sz) 3727 this->__throw_out_of_range(); 3728 return compare(__pos1, __n1, __str.data() + __pos2, _VSTD::min(__n2, 3729 __sz - __pos2)); 3730} 3731 3732template <class _CharT, class _Traits, class _Allocator> 3733int 3734basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT 3735{ 3736 _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr"); 3737 return compare(0, npos, __s, traits_type::length(__s)); 3738} 3739 3740template <class _CharT, class _Traits, class _Allocator> 3741int 3742basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, 3743 size_type __n1, 3744 const value_type* __s) const 3745{ 3746 _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr"); 3747 return compare(__pos1, __n1, __s, traits_type::length(__s)); 3748} 3749 3750template <class _CharT, class _Traits, class _Allocator> 3751int 3752basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, 3753 size_type __n1, 3754 const value_type* __s, 3755 size_type __n2) const 3756{ 3757 _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr"); 3758 size_type __sz = size(); 3759 if (__pos1 > __sz || __n2 == npos) 3760 this->__throw_out_of_range(); 3761 size_type __rlen = _VSTD::min(__n1, __sz - __pos1); 3762 int __r = traits_type::compare(data() + __pos1, __s, _VSTD::min(__rlen, __n2)); 3763 if (__r == 0) 3764 { 3765 if (__rlen < __n2) 3766 __r = -1; 3767 else if (__rlen > __n2) 3768 __r = 1; 3769 } 3770 return __r; 3771} 3772 3773// __invariants 3774 3775template<class _CharT, class _Traits, class _Allocator> 3776inline _LIBCPP_INLINE_VISIBILITY 3777bool 3778basic_string<_CharT, _Traits, _Allocator>::__invariants() const 3779{ 3780 if (size() > capacity()) 3781 return false; 3782 if (capacity() < __min_cap - 1) 3783 return false; 3784 if (data() == 0) 3785 return false; 3786 if (data()[size()] != value_type(0)) 3787 return false; 3788 return true; 3789} 3790 3791// operator== 3792 3793template<class _CharT, class _Traits, class _Allocator> 3794inline _LIBCPP_INLINE_VISIBILITY 3795bool 3796operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3797 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 3798{ 3799 size_t __lhs_sz = __lhs.size(); 3800 return __lhs_sz == __rhs.size() && _Traits::compare(__lhs.data(), 3801 __rhs.data(), 3802 __lhs_sz) == 0; 3803} 3804 3805template<class _Allocator> 3806inline _LIBCPP_INLINE_VISIBILITY 3807bool 3808operator==(const basic_string<char, char_traits<char>, _Allocator>& __lhs, 3809 const basic_string<char, char_traits<char>, _Allocator>& __rhs) _NOEXCEPT 3810{ 3811 size_t __lhs_sz = __lhs.size(); 3812 if (__lhs_sz != __rhs.size()) 3813 return false; 3814 const char* __lp = __lhs.data(); 3815 const char* __rp = __rhs.data(); 3816 if (__lhs.__is_long()) 3817 return char_traits<char>::compare(__lp, __rp, __lhs_sz) == 0; 3818 for (; __lhs_sz != 0; --__lhs_sz, ++__lp, ++__rp) 3819 if (*__lp != *__rp) 3820 return false; 3821 return true; 3822} 3823 3824template<class _CharT, class _Traits, class _Allocator> 3825inline _LIBCPP_INLINE_VISIBILITY 3826bool 3827operator==(const _CharT* __lhs, 3828 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 3829{ 3830 return __rhs.compare(__lhs) == 0; 3831} 3832 3833template<class _CharT, class _Traits, class _Allocator> 3834inline _LIBCPP_INLINE_VISIBILITY 3835bool 3836operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 3837 const _CharT* __rhs) _NOEXCEPT 3838{ 3839 return __lhs.compare(__rhs) == 0; 3840} 3841 3842// operator!= 3843 3844template<class _CharT, class _Traits, class _Allocator> 3845inline _LIBCPP_INLINE_VISIBILITY 3846bool 3847operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 3848 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 3849{ 3850 return !(__lhs == __rhs); 3851} 3852 3853template<class _CharT, class _Traits, class _Allocator> 3854inline _LIBCPP_INLINE_VISIBILITY 3855bool 3856operator!=(const _CharT* __lhs, 3857 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 3858{ 3859 return !(__lhs == __rhs); 3860} 3861 3862template<class _CharT, class _Traits, class _Allocator> 3863inline _LIBCPP_INLINE_VISIBILITY 3864bool 3865operator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3866 const _CharT* __rhs) _NOEXCEPT 3867{ 3868 return !(__lhs == __rhs); 3869} 3870 3871// operator< 3872 3873template<class _CharT, class _Traits, class _Allocator> 3874inline _LIBCPP_INLINE_VISIBILITY 3875bool 3876operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3877 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 3878{ 3879 return __lhs.compare(__rhs) < 0; 3880} 3881 3882template<class _CharT, class _Traits, class _Allocator> 3883inline _LIBCPP_INLINE_VISIBILITY 3884bool 3885operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3886 const _CharT* __rhs) _NOEXCEPT 3887{ 3888 return __lhs.compare(__rhs) < 0; 3889} 3890 3891template<class _CharT, class _Traits, class _Allocator> 3892inline _LIBCPP_INLINE_VISIBILITY 3893bool 3894operator< (const _CharT* __lhs, 3895 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 3896{ 3897 return __rhs.compare(__lhs) > 0; 3898} 3899 3900// operator> 3901 3902template<class _CharT, class _Traits, class _Allocator> 3903inline _LIBCPP_INLINE_VISIBILITY 3904bool 3905operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3906 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 3907{ 3908 return __rhs < __lhs; 3909} 3910 3911template<class _CharT, class _Traits, class _Allocator> 3912inline _LIBCPP_INLINE_VISIBILITY 3913bool 3914operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3915 const _CharT* __rhs) _NOEXCEPT 3916{ 3917 return __rhs < __lhs; 3918} 3919 3920template<class _CharT, class _Traits, class _Allocator> 3921inline _LIBCPP_INLINE_VISIBILITY 3922bool 3923operator> (const _CharT* __lhs, 3924 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 3925{ 3926 return __rhs < __lhs; 3927} 3928 3929// operator<= 3930 3931template<class _CharT, class _Traits, class _Allocator> 3932inline _LIBCPP_INLINE_VISIBILITY 3933bool 3934operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3935 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 3936{ 3937 return !(__rhs < __lhs); 3938} 3939 3940template<class _CharT, class _Traits, class _Allocator> 3941inline _LIBCPP_INLINE_VISIBILITY 3942bool 3943operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3944 const _CharT* __rhs) _NOEXCEPT 3945{ 3946 return !(__rhs < __lhs); 3947} 3948 3949template<class _CharT, class _Traits, class _Allocator> 3950inline _LIBCPP_INLINE_VISIBILITY 3951bool 3952operator<=(const _CharT* __lhs, 3953 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 3954{ 3955 return !(__rhs < __lhs); 3956} 3957 3958// operator>= 3959 3960template<class _CharT, class _Traits, class _Allocator> 3961inline _LIBCPP_INLINE_VISIBILITY 3962bool 3963operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3964 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 3965{ 3966 return !(__lhs < __rhs); 3967} 3968 3969template<class _CharT, class _Traits, class _Allocator> 3970inline _LIBCPP_INLINE_VISIBILITY 3971bool 3972operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3973 const _CharT* __rhs) _NOEXCEPT 3974{ 3975 return !(__lhs < __rhs); 3976} 3977 3978template<class _CharT, class _Traits, class _Allocator> 3979inline _LIBCPP_INLINE_VISIBILITY 3980bool 3981operator>=(const _CharT* __lhs, 3982 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 3983{ 3984 return !(__lhs < __rhs); 3985} 3986 3987// operator + 3988 3989template<class _CharT, class _Traits, class _Allocator> 3990basic_string<_CharT, _Traits, _Allocator> 3991operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3992 const basic_string<_CharT, _Traits, _Allocator>& __rhs) 3993{ 3994 basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator()); 3995 typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size(); 3996 typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size(); 3997 __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + __rhs_sz); 3998 __r.append(__rhs.data(), __rhs_sz); 3999 return __r; 4000} 4001 4002template<class _CharT, class _Traits, class _Allocator> 4003basic_string<_CharT, _Traits, _Allocator> 4004operator+(const _CharT* __lhs , const basic_string<_CharT,_Traits,_Allocator>& __rhs) 4005{ 4006 basic_string<_CharT, _Traits, _Allocator> __r(__rhs.get_allocator()); 4007 typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = _Traits::length(__lhs); 4008 typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size(); 4009 __r.__init(__lhs, __lhs_sz, __lhs_sz + __rhs_sz); 4010 __r.append(__rhs.data(), __rhs_sz); 4011 return __r; 4012} 4013 4014template<class _CharT, class _Traits, class _Allocator> 4015basic_string<_CharT, _Traits, _Allocator> 4016operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Allocator>& __rhs) 4017{ 4018 basic_string<_CharT, _Traits, _Allocator> __r(__rhs.get_allocator()); 4019 typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size(); 4020 __r.__init(&__lhs, 1, 1 + __rhs_sz); 4021 __r.append(__rhs.data(), __rhs_sz); 4022 return __r; 4023} 4024 4025template<class _CharT, class _Traits, class _Allocator> 4026basic_string<_CharT, _Traits, _Allocator> 4027operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) 4028{ 4029 basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator()); 4030 typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size(); 4031 typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = _Traits::length(__rhs); 4032 __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + __rhs_sz); 4033 __r.append(__rhs, __rhs_sz); 4034 return __r; 4035} 4036 4037template<class _CharT, class _Traits, class _Allocator> 4038basic_string<_CharT, _Traits, _Allocator> 4039operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs) 4040{ 4041 basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator()); 4042 typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size(); 4043 __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + 1); 4044 __r.push_back(__rhs); 4045 return __r; 4046} 4047 4048#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 4049 4050template<class _CharT, class _Traits, class _Allocator> 4051inline _LIBCPP_INLINE_VISIBILITY 4052basic_string<_CharT, _Traits, _Allocator> 4053operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) 4054{ 4055 return _VSTD::move(__lhs.append(__rhs)); 4056} 4057 4058template<class _CharT, class _Traits, class _Allocator> 4059inline _LIBCPP_INLINE_VISIBILITY 4060basic_string<_CharT, _Traits, _Allocator> 4061operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs) 4062{ 4063 return _VSTD::move(__rhs.insert(0, __lhs)); 4064} 4065 4066template<class _CharT, class _Traits, class _Allocator> 4067inline _LIBCPP_INLINE_VISIBILITY 4068basic_string<_CharT, _Traits, _Allocator> 4069operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs) 4070{ 4071 return _VSTD::move(__lhs.append(__rhs)); 4072} 4073 4074template<class _CharT, class _Traits, class _Allocator> 4075inline _LIBCPP_INLINE_VISIBILITY 4076basic_string<_CharT, _Traits, _Allocator> 4077operator+(const _CharT* __lhs , basic_string<_CharT,_Traits,_Allocator>&& __rhs) 4078{ 4079 return _VSTD::move(__rhs.insert(0, __lhs)); 4080} 4081 4082template<class _CharT, class _Traits, class _Allocator> 4083inline _LIBCPP_INLINE_VISIBILITY 4084basic_string<_CharT, _Traits, _Allocator> 4085operator+(_CharT __lhs, basic_string<_CharT,_Traits,_Allocator>&& __rhs) 4086{ 4087 __rhs.insert(__rhs.begin(), __lhs); 4088 return _VSTD::move(__rhs); 4089} 4090 4091template<class _CharT, class _Traits, class _Allocator> 4092inline _LIBCPP_INLINE_VISIBILITY 4093basic_string<_CharT, _Traits, _Allocator> 4094operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const _CharT* __rhs) 4095{ 4096 return _VSTD::move(__lhs.append(__rhs)); 4097} 4098 4099template<class _CharT, class _Traits, class _Allocator> 4100inline _LIBCPP_INLINE_VISIBILITY 4101basic_string<_CharT, _Traits, _Allocator> 4102operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT __rhs) 4103{ 4104 __lhs.push_back(__rhs); 4105 return _VSTD::move(__lhs); 4106} 4107 4108#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 4109 4110// swap 4111 4112template<class _CharT, class _Traits, class _Allocator> 4113inline _LIBCPP_INLINE_VISIBILITY 4114void 4115swap(basic_string<_CharT, _Traits, _Allocator>& __lhs, 4116 basic_string<_CharT, _Traits, _Allocator>& __rhs) 4117 _NOEXCEPT_(_NOEXCEPT_(__lhs.swap(__rhs))) 4118{ 4119 __lhs.swap(__rhs); 4120} 4121 4122#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS 4123 4124typedef basic_string<char16_t> u16string; 4125typedef basic_string<char32_t> u32string; 4126 4127#endif // _LIBCPP_HAS_NO_UNICODE_CHARS 4128 4129_LIBCPP_FUNC_VIS int stoi (const string& __str, size_t* __idx = 0, int __base = 10); 4130_LIBCPP_FUNC_VIS long stol (const string& __str, size_t* __idx = 0, int __base = 10); 4131_LIBCPP_FUNC_VIS unsigned long stoul (const string& __str, size_t* __idx = 0, int __base = 10); 4132_LIBCPP_FUNC_VIS long long stoll (const string& __str, size_t* __idx = 0, int __base = 10); 4133_LIBCPP_FUNC_VIS unsigned long long stoull(const string& __str, size_t* __idx = 0, int __base = 10); 4134 4135_LIBCPP_FUNC_VIS float stof (const string& __str, size_t* __idx = 0); 4136_LIBCPP_FUNC_VIS double stod (const string& __str, size_t* __idx = 0); 4137_LIBCPP_FUNC_VIS long double stold(const string& __str, size_t* __idx = 0); 4138 4139_LIBCPP_FUNC_VIS string to_string(int __val); 4140_LIBCPP_FUNC_VIS string to_string(unsigned __val); 4141_LIBCPP_FUNC_VIS string to_string(long __val); 4142_LIBCPP_FUNC_VIS string to_string(unsigned long __val); 4143_LIBCPP_FUNC_VIS string to_string(long long __val); 4144_LIBCPP_FUNC_VIS string to_string(unsigned long long __val); 4145_LIBCPP_FUNC_VIS string to_string(float __val); 4146_LIBCPP_FUNC_VIS string to_string(double __val); 4147_LIBCPP_FUNC_VIS string to_string(long double __val); 4148 4149_LIBCPP_FUNC_VIS int stoi (const wstring& __str, size_t* __idx = 0, int __base = 10); 4150_LIBCPP_FUNC_VIS long stol (const wstring& __str, size_t* __idx = 0, int __base = 10); 4151_LIBCPP_FUNC_VIS unsigned long stoul (const wstring& __str, size_t* __idx = 0, int __base = 10); 4152_LIBCPP_FUNC_VIS long long stoll (const wstring& __str, size_t* __idx = 0, int __base = 10); 4153_LIBCPP_FUNC_VIS unsigned long long stoull(const wstring& __str, size_t* __idx = 0, int __base = 10); 4154 4155_LIBCPP_FUNC_VIS float stof (const wstring& __str, size_t* __idx = 0); 4156_LIBCPP_FUNC_VIS double stod (const wstring& __str, size_t* __idx = 0); 4157_LIBCPP_FUNC_VIS long double stold(const wstring& __str, size_t* __idx = 0); 4158 4159_LIBCPP_FUNC_VIS wstring to_wstring(int __val); 4160_LIBCPP_FUNC_VIS wstring to_wstring(unsigned __val); 4161_LIBCPP_FUNC_VIS wstring to_wstring(long __val); 4162_LIBCPP_FUNC_VIS wstring to_wstring(unsigned long __val); 4163_LIBCPP_FUNC_VIS wstring to_wstring(long long __val); 4164_LIBCPP_FUNC_VIS wstring to_wstring(unsigned long long __val); 4165_LIBCPP_FUNC_VIS wstring to_wstring(float __val); 4166_LIBCPP_FUNC_VIS wstring to_wstring(double __val); 4167_LIBCPP_FUNC_VIS wstring to_wstring(long double __val); 4168 4169template<class _CharT, class _Traits, class _Allocator> 4170 const typename basic_string<_CharT, _Traits, _Allocator>::size_type 4171 basic_string<_CharT, _Traits, _Allocator>::npos; 4172 4173template<class _CharT, class _Traits, class _Allocator> 4174struct _LIBCPP_TYPE_VIS_ONLY hash<basic_string<_CharT, _Traits, _Allocator> > 4175 : public unary_function<basic_string<_CharT, _Traits, _Allocator>, size_t> 4176{ 4177 size_t 4178 operator()(const basic_string<_CharT, _Traits, _Allocator>& __val) const _NOEXCEPT; 4179}; 4180 4181template<class _CharT, class _Traits, class _Allocator> 4182size_t 4183hash<basic_string<_CharT, _Traits, _Allocator> >::operator()( 4184 const basic_string<_CharT, _Traits, _Allocator>& __val) const _NOEXCEPT 4185{ 4186 return __do_string_hash(__val.data(), __val.data() + __val.size()); 4187} 4188 4189template<class _CharT, class _Traits, class _Allocator> 4190basic_ostream<_CharT, _Traits>& 4191operator<<(basic_ostream<_CharT, _Traits>& __os, 4192 const basic_string<_CharT, _Traits, _Allocator>& __str); 4193 4194template<class _CharT, class _Traits, class _Allocator> 4195basic_istream<_CharT, _Traits>& 4196operator>>(basic_istream<_CharT, _Traits>& __is, 4197 basic_string<_CharT, _Traits, _Allocator>& __str); 4198 4199template<class _CharT, class _Traits, class _Allocator> 4200basic_istream<_CharT, _Traits>& 4201getline(basic_istream<_CharT, _Traits>& __is, 4202 basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm); 4203 4204template<class _CharT, class _Traits, class _Allocator> 4205inline _LIBCPP_INLINE_VISIBILITY 4206basic_istream<_CharT, _Traits>& 4207getline(basic_istream<_CharT, _Traits>& __is, 4208 basic_string<_CharT, _Traits, _Allocator>& __str); 4209 4210#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 4211 4212template<class _CharT, class _Traits, class _Allocator> 4213inline _LIBCPP_INLINE_VISIBILITY 4214basic_istream<_CharT, _Traits>& 4215getline(basic_istream<_CharT, _Traits>&& __is, 4216 basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm); 4217 4218template<class _CharT, class _Traits, class _Allocator> 4219inline _LIBCPP_INLINE_VISIBILITY 4220basic_istream<_CharT, _Traits>& 4221getline(basic_istream<_CharT, _Traits>&& __is, 4222 basic_string<_CharT, _Traits, _Allocator>& __str); 4223 4224#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 4225 4226#if _LIBCPP_DEBUG_LEVEL >= 2 4227 4228template<class _CharT, class _Traits, class _Allocator> 4229bool 4230basic_string<_CharT, _Traits, _Allocator>::__dereferenceable(const const_iterator* __i) const 4231{ 4232 return this->data() <= _VSTD::__to_raw_pointer(__i->base()) && 4233 _VSTD::__to_raw_pointer(__i->base()) < this->data() + this->size(); 4234} 4235 4236template<class _CharT, class _Traits, class _Allocator> 4237bool 4238basic_string<_CharT, _Traits, _Allocator>::__decrementable(const const_iterator* __i) const 4239{ 4240 return this->data() < _VSTD::__to_raw_pointer(__i->base()) && 4241 _VSTD::__to_raw_pointer(__i->base()) <= this->data() + this->size(); 4242} 4243 4244template<class _CharT, class _Traits, class _Allocator> 4245bool 4246basic_string<_CharT, _Traits, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const 4247{ 4248 const value_type* __p = _VSTD::__to_raw_pointer(__i->base()) + __n; 4249 return this->data() <= __p && __p <= this->data() + this->size(); 4250} 4251 4252template<class _CharT, class _Traits, class _Allocator> 4253bool 4254basic_string<_CharT, _Traits, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const 4255{ 4256 const value_type* __p = _VSTD::__to_raw_pointer(__i->base()) + __n; 4257 return this->data() <= __p && __p < this->data() + this->size(); 4258} 4259 4260#endif // _LIBCPP_DEBUG_LEVEL >= 2 4261 4262#if _LIBCPP_STD_VER > 11 4263// Literal suffixes for basic_string [basic.string.literals] 4264inline namespace literals 4265{ 4266 inline namespace string_literals 4267 { 4268 inline _LIBCPP_INLINE_VISIBILITY 4269 basic_string<char> operator "" s( const char *__str, size_t __len ) 4270 { 4271 return basic_string<char> (__str, __len); 4272 } 4273 4274 inline _LIBCPP_INLINE_VISIBILITY 4275 basic_string<wchar_t> operator "" s( const wchar_t *__str, size_t __len ) 4276 { 4277 return basic_string<wchar_t> (__str, __len); 4278 } 4279 4280 inline _LIBCPP_INLINE_VISIBILITY 4281 basic_string<char16_t> operator "" s( const char16_t *__str, size_t __len ) 4282 { 4283 return basic_string<char16_t> (__str, __len); 4284 } 4285 4286 inline _LIBCPP_INLINE_VISIBILITY 4287 basic_string<char32_t> operator "" s( const char32_t *__str, size_t __len ) 4288 { 4289 return basic_string<char32_t> (__str, __len); 4290 } 4291 } 4292} 4293#endif 4294 4295_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_string<char>) 4296_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_string<wchar_t>) 4297_LIBCPP_EXTERN_TEMPLATE(string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&)) 4298 4299_LIBCPP_END_NAMESPACE_STD 4300 4301#endif // _LIBCPP_STRING 4302