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