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