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