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