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