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