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