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