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