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