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