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