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_HIDE_FROM_ABI basic_string& __null_terminate_at(value_type* __p, size_type __newsz) { 1698 __set_size(__newsz); 1699 __invalidate_iterators_past(__newsz); 1700 traits_type::assign(__p[__newsz], value_type()); 1701 return *this; 1702 } 1703 1704 _LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators(); 1705 _LIBCPP_INLINE_VISIBILITY void __invalidate_iterators_past(size_type); 1706 1707 template<class _Tp> 1708 _LIBCPP_INLINE_VISIBILITY 1709 bool __addr_in_range(_Tp&& __t) const { 1710 const volatile void *__p = _VSTD::addressof(__t); 1711 return data() <= __p && __p <= data() + size(); 1712 } 1713 1714 _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI 1715 void __throw_length_error() const { 1716#ifndef _LIBCPP_NO_EXCEPTIONS 1717 __basic_string_common<true>::__throw_length_error(); 1718#else 1719 _VSTD::abort(); 1720#endif 1721 } 1722 1723 _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI 1724 void __throw_out_of_range() const { 1725#ifndef _LIBCPP_NO_EXCEPTIONS 1726 __basic_string_common<true>::__throw_out_of_range(); 1727#else 1728 _VSTD::abort(); 1729#endif 1730 } 1731 1732 friend basic_string operator+<>(const basic_string&, const basic_string&); 1733 friend basic_string operator+<>(const value_type*, const basic_string&); 1734 friend basic_string operator+<>(value_type, const basic_string&); 1735 friend basic_string operator+<>(const basic_string&, const value_type*); 1736 friend basic_string operator+<>(const basic_string&, value_type); 1737}; 1738 1739// These declarations must appear before any functions are implicitly used 1740// so that they have the correct visibility specifier. 1741#ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION 1742 _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, char) 1743# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 1744 _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, wchar_t) 1745# endif 1746#else 1747 _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, char) 1748# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 1749 _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, wchar_t) 1750# endif 1751#endif 1752 1753 1754#if _LIBCPP_STD_VER >= 17 1755template<class _InputIterator, 1756 class _CharT = __iter_value_type<_InputIterator>, 1757 class _Allocator = allocator<_CharT>, 1758 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, 1759 class = enable_if_t<__is_allocator<_Allocator>::value> 1760 > 1761basic_string(_InputIterator, _InputIterator, _Allocator = _Allocator()) 1762 -> basic_string<_CharT, char_traits<_CharT>, _Allocator>; 1763 1764template<class _CharT, 1765 class _Traits, 1766 class _Allocator = allocator<_CharT>, 1767 class = enable_if_t<__is_allocator<_Allocator>::value> 1768 > 1769explicit basic_string(basic_string_view<_CharT, _Traits>, const _Allocator& = _Allocator()) 1770 -> basic_string<_CharT, _Traits, _Allocator>; 1771 1772template<class _CharT, 1773 class _Traits, 1774 class _Allocator = allocator<_CharT>, 1775 class = enable_if_t<__is_allocator<_Allocator>::value>, 1776 class _Sz = typename allocator_traits<_Allocator>::size_type 1777 > 1778basic_string(basic_string_view<_CharT, _Traits>, _Sz, _Sz, const _Allocator& = _Allocator()) 1779 -> basic_string<_CharT, _Traits, _Allocator>; 1780#endif 1781 1782template <class _CharT, class _Traits, class _Allocator> 1783inline 1784void 1785basic_string<_CharT, _Traits, _Allocator>::__invalidate_all_iterators() 1786{ 1787#if _LIBCPP_DEBUG_LEVEL == 2 1788 __get_db()->__invalidate_all(this); 1789#endif 1790} 1791 1792template <class _CharT, class _Traits, class _Allocator> 1793inline 1794void 1795basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type __pos) 1796{ 1797#if _LIBCPP_DEBUG_LEVEL == 2 1798 __c_node* __c = __get_db()->__find_c_and_lock(this); 1799 if (__c) 1800 { 1801 const_pointer __new_last = __get_pointer() + __pos; 1802 for (__i_node** __p = __c->end_; __p != __c->beg_; ) 1803 { 1804 --__p; 1805 const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_); 1806 if (__i->base() > __new_last) 1807 { 1808 (*__p)->__c_ = nullptr; 1809 if (--__c->end_ != __p) 1810 _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); 1811 } 1812 } 1813 __get_db()->unlock(); 1814 } 1815#else 1816 (void)__pos; 1817#endif // _LIBCPP_DEBUG_LEVEL == 2 1818} 1819 1820template <class _CharT, class _Traits, class _Allocator> 1821inline 1822basic_string<_CharT, _Traits, _Allocator>::basic_string() 1823 _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) 1824 : __r_(__default_init_tag(), __default_init_tag()) 1825{ 1826#if _LIBCPP_DEBUG_LEVEL == 2 1827 __get_db()->__insert_c(this); 1828#endif 1829 __zero(); 1830} 1831 1832template <class _CharT, class _Traits, class _Allocator> 1833inline 1834basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __a) 1835#if _LIBCPP_STD_VER <= 14 1836 _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value) 1837#else 1838 _NOEXCEPT 1839#endif 1840: __r_(__default_init_tag(), __a) 1841{ 1842#if _LIBCPP_DEBUG_LEVEL == 2 1843 __get_db()->__insert_c(this); 1844#endif 1845 __zero(); 1846} 1847 1848template <class _CharT, class _Traits, class _Allocator> 1849void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, 1850 size_type __sz, 1851 size_type __reserve) 1852{ 1853 if (__reserve > max_size()) 1854 this->__throw_length_error(); 1855 pointer __p; 1856 if (__reserve < __min_cap) 1857 { 1858 __set_short_size(__sz); 1859 __p = __get_short_pointer(); 1860 } 1861 else 1862 { 1863 size_type __cap = __recommend(__reserve); 1864 __p = __alloc_traits::allocate(__alloc(), __cap+1); 1865 __set_long_pointer(__p); 1866 __set_long_cap(__cap+1); 1867 __set_long_size(__sz); 1868 } 1869 traits_type::copy(_VSTD::__to_address(__p), __s, __sz); 1870 traits_type::assign(__p[__sz], value_type()); 1871} 1872 1873template <class _CharT, class _Traits, class _Allocator> 1874void 1875basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz) 1876{ 1877 if (__sz > max_size()) 1878 this->__throw_length_error(); 1879 pointer __p; 1880 if (__sz < __min_cap) 1881 { 1882 __set_short_size(__sz); 1883 __p = __get_short_pointer(); 1884 } 1885 else 1886 { 1887 size_type __cap = __recommend(__sz); 1888 __p = __alloc_traits::allocate(__alloc(), __cap+1); 1889 __set_long_pointer(__p); 1890 __set_long_cap(__cap+1); 1891 __set_long_size(__sz); 1892 } 1893 traits_type::copy(_VSTD::__to_address(__p), __s, __sz); 1894 traits_type::assign(__p[__sz], value_type()); 1895} 1896 1897template <class _CharT, class _Traits, class _Allocator> 1898template <class> 1899basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const _Allocator& __a) 1900 : __r_(__default_init_tag(), __a) 1901{ 1902 _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr"); 1903 __init(__s, traits_type::length(__s)); 1904#if _LIBCPP_DEBUG_LEVEL == 2 1905 __get_db()->__insert_c(this); 1906#endif 1907} 1908 1909template <class _CharT, class _Traits, class _Allocator> 1910inline 1911basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n) 1912 : __r_(__default_init_tag(), __default_init_tag()) 1913{ 1914 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr"); 1915 __init(__s, __n); 1916#if _LIBCPP_DEBUG_LEVEL == 2 1917 __get_db()->__insert_c(this); 1918#endif 1919} 1920 1921template <class _CharT, class _Traits, class _Allocator> 1922inline 1923basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n, const _Allocator& __a) 1924 : __r_(__default_init_tag(), __a) 1925{ 1926 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr"); 1927 __init(__s, __n); 1928#if _LIBCPP_DEBUG_LEVEL == 2 1929 __get_db()->__insert_c(this); 1930#endif 1931} 1932 1933template <class _CharT, class _Traits, class _Allocator> 1934basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str) 1935 : __r_(__default_init_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc())) 1936{ 1937 if (!__str.__is_long()) 1938 __r_.first().__r = __str.__r_.first().__r; 1939 else 1940 __init_copy_ctor_external(_VSTD::__to_address(__str.__get_long_pointer()), 1941 __str.__get_long_size()); 1942 1943#if _LIBCPP_DEBUG_LEVEL == 2 1944 __get_db()->__insert_c(this); 1945#endif 1946} 1947 1948template <class _CharT, class _Traits, class _Allocator> 1949basic_string<_CharT, _Traits, _Allocator>::basic_string( 1950 const basic_string& __str, const allocator_type& __a) 1951 : __r_(__default_init_tag(), __a) 1952{ 1953 if (!__str.__is_long()) 1954 __r_.first().__r = __str.__r_.first().__r; 1955 else 1956 __init_copy_ctor_external(_VSTD::__to_address(__str.__get_long_pointer()), 1957 __str.__get_long_size()); 1958#if _LIBCPP_DEBUG_LEVEL == 2 1959 __get_db()->__insert_c(this); 1960#endif 1961} 1962 1963template <class _CharT, class _Traits, class _Allocator> 1964void basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external( 1965 const value_type* __s, size_type __sz) { 1966 pointer __p; 1967 if (__sz < __min_cap) { 1968 __p = __get_short_pointer(); 1969 __set_short_size(__sz); 1970 } else { 1971 if (__sz > max_size()) 1972 this->__throw_length_error(); 1973 size_t __cap = __recommend(__sz); 1974 __p = __alloc_traits::allocate(__alloc(), __cap + 1); 1975 __set_long_pointer(__p); 1976 __set_long_cap(__cap + 1); 1977 __set_long_size(__sz); 1978 } 1979 traits_type::copy(_VSTD::__to_address(__p), __s, __sz + 1); 1980} 1981 1982#ifndef _LIBCPP_CXX03_LANG 1983 1984template <class _CharT, class _Traits, class _Allocator> 1985inline 1986basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str) 1987#if _LIBCPP_STD_VER <= 14 1988 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value) 1989#else 1990 _NOEXCEPT 1991#endif 1992 : __r_(_VSTD::move(__str.__r_)) 1993{ 1994 __str.__zero(); 1995#if _LIBCPP_DEBUG_LEVEL == 2 1996 __get_db()->__insert_c(this); 1997 if (__is_long()) 1998 __get_db()->swap(this, &__str); 1999#endif 2000} 2001 2002template <class _CharT, class _Traits, class _Allocator> 2003inline 2004basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, const allocator_type& __a) 2005 : __r_(__default_init_tag(), __a) 2006{ 2007 if (__str.__is_long() && __a != __str.__alloc()) // copy, not move 2008 __init(_VSTD::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); 2009 else 2010 { 2011 __r_.first().__r = __str.__r_.first().__r; 2012 __str.__zero(); 2013 } 2014#if _LIBCPP_DEBUG_LEVEL == 2 2015 __get_db()->__insert_c(this); 2016 if (__is_long()) 2017 __get_db()->swap(this, &__str); 2018#endif 2019} 2020 2021#endif // _LIBCPP_CXX03_LANG 2022 2023template <class _CharT, class _Traits, class _Allocator> 2024void 2025basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c) 2026{ 2027 if (__n > max_size()) 2028 this->__throw_length_error(); 2029 pointer __p; 2030 if (__n < __min_cap) 2031 { 2032 __set_short_size(__n); 2033 __p = __get_short_pointer(); 2034 } 2035 else 2036 { 2037 size_type __cap = __recommend(__n); 2038 __p = __alloc_traits::allocate(__alloc(), __cap+1); 2039 __set_long_pointer(__p); 2040 __set_long_cap(__cap+1); 2041 __set_long_size(__n); 2042 } 2043 traits_type::assign(_VSTD::__to_address(__p), __n, __c); 2044 traits_type::assign(__p[__n], value_type()); 2045} 2046 2047template <class _CharT, class _Traits, class _Allocator> 2048inline 2049basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c) 2050 : __r_(__default_init_tag(), __default_init_tag()) 2051{ 2052 __init(__n, __c); 2053#if _LIBCPP_DEBUG_LEVEL == 2 2054 __get_db()->__insert_c(this); 2055#endif 2056} 2057 2058template <class _CharT, class _Traits, class _Allocator> 2059template <class> 2060basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c, const _Allocator& __a) 2061 : __r_(__default_init_tag(), __a) 2062{ 2063 __init(__n, __c); 2064#if _LIBCPP_DEBUG_LEVEL == 2 2065 __get_db()->__insert_c(this); 2066#endif 2067} 2068 2069template <class _CharT, class _Traits, class _Allocator> 2070basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, 2071 size_type __pos, size_type __n, 2072 const _Allocator& __a) 2073 : __r_(__default_init_tag(), __a) 2074{ 2075 size_type __str_sz = __str.size(); 2076 if (__pos > __str_sz) 2077 this->__throw_out_of_range(); 2078 __init(__str.data() + __pos, _VSTD::min(__n, __str_sz - __pos)); 2079#if _LIBCPP_DEBUG_LEVEL == 2 2080 __get_db()->__insert_c(this); 2081#endif 2082} 2083 2084template <class _CharT, class _Traits, class _Allocator> 2085inline 2086basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos, 2087 const _Allocator& __a) 2088 : __r_(__default_init_tag(), __a) 2089{ 2090 size_type __str_sz = __str.size(); 2091 if (__pos > __str_sz) 2092 this->__throw_out_of_range(); 2093 __init(__str.data() + __pos, __str_sz - __pos); 2094#if _LIBCPP_DEBUG_LEVEL == 2 2095 __get_db()->__insert_c(this); 2096#endif 2097} 2098 2099template <class _CharT, class _Traits, class _Allocator> 2100template <class _Tp, class> 2101basic_string<_CharT, _Traits, _Allocator>::basic_string( 2102 const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a) 2103 : __r_(__default_init_tag(), __a) 2104{ 2105 __self_view __sv0 = __t; 2106 __self_view __sv = __sv0.substr(__pos, __n); 2107 __init(__sv.data(), __sv.size()); 2108#if _LIBCPP_DEBUG_LEVEL == 2 2109 __get_db()->__insert_c(this); 2110#endif 2111} 2112 2113template <class _CharT, class _Traits, class _Allocator> 2114template <class _Tp, class> 2115basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t) 2116 : __r_(__default_init_tag(), __default_init_tag()) 2117{ 2118 __self_view __sv = __t; 2119 __init(__sv.data(), __sv.size()); 2120#if _LIBCPP_DEBUG_LEVEL == 2 2121 __get_db()->__insert_c(this); 2122#endif 2123} 2124 2125template <class _CharT, class _Traits, class _Allocator> 2126template <class _Tp, class> 2127basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t, const _Allocator& __a) 2128 : __r_(__default_init_tag(), __a) 2129{ 2130 __self_view __sv = __t; 2131 __init(__sv.data(), __sv.size()); 2132#if _LIBCPP_DEBUG_LEVEL == 2 2133 __get_db()->__insert_c(this); 2134#endif 2135} 2136 2137template <class _CharT, class _Traits, class _Allocator> 2138template <class _InputIterator> 2139__enable_if_t 2140< 2141 __is_exactly_cpp17_input_iterator<_InputIterator>::value 2142> 2143basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last) 2144{ 2145 __zero(); 2146#ifndef _LIBCPP_NO_EXCEPTIONS 2147 try 2148 { 2149#endif // _LIBCPP_NO_EXCEPTIONS 2150 for (; __first != __last; ++__first) 2151 push_back(*__first); 2152#ifndef _LIBCPP_NO_EXCEPTIONS 2153 } 2154 catch (...) 2155 { 2156 if (__is_long()) 2157 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 2158 throw; 2159 } 2160#endif // _LIBCPP_NO_EXCEPTIONS 2161} 2162 2163template <class _CharT, class _Traits, class _Allocator> 2164template <class _ForwardIterator> 2165__enable_if_t 2166< 2167 __is_cpp17_forward_iterator<_ForwardIterator>::value 2168> 2169basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last) 2170{ 2171 size_type __sz = static_cast<size_type>(_VSTD::distance(__first, __last)); 2172 if (__sz > max_size()) 2173 this->__throw_length_error(); 2174 pointer __p; 2175 if (__sz < __min_cap) 2176 { 2177 __set_short_size(__sz); 2178 __p = __get_short_pointer(); 2179 } 2180 else 2181 { 2182 size_type __cap = __recommend(__sz); 2183 __p = __alloc_traits::allocate(__alloc(), __cap+1); 2184 __set_long_pointer(__p); 2185 __set_long_cap(__cap+1); 2186 __set_long_size(__sz); 2187 } 2188 2189#ifndef _LIBCPP_NO_EXCEPTIONS 2190 try 2191 { 2192#endif // _LIBCPP_NO_EXCEPTIONS 2193 for (; __first != __last; ++__first, (void) ++__p) 2194 traits_type::assign(*__p, *__first); 2195 traits_type::assign(*__p, value_type()); 2196#ifndef _LIBCPP_NO_EXCEPTIONS 2197 } 2198 catch (...) 2199 { 2200 if (__is_long()) 2201 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 2202 throw; 2203 } 2204#endif // _LIBCPP_NO_EXCEPTIONS 2205} 2206 2207template <class _CharT, class _Traits, class _Allocator> 2208template<class _InputIterator, class> 2209inline 2210basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last) 2211 : __r_(__default_init_tag(), __default_init_tag()) 2212{ 2213 __init(__first, __last); 2214#if _LIBCPP_DEBUG_LEVEL == 2 2215 __get_db()->__insert_c(this); 2216#endif 2217} 2218 2219template <class _CharT, class _Traits, class _Allocator> 2220template<class _InputIterator, class> 2221inline 2222basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last, 2223 const allocator_type& __a) 2224 : __r_(__default_init_tag(), __a) 2225{ 2226 __init(__first, __last); 2227#if _LIBCPP_DEBUG_LEVEL == 2 2228 __get_db()->__insert_c(this); 2229#endif 2230} 2231 2232#ifndef _LIBCPP_CXX03_LANG 2233 2234template <class _CharT, class _Traits, class _Allocator> 2235inline 2236basic_string<_CharT, _Traits, _Allocator>::basic_string( 2237 initializer_list<_CharT> __il) 2238 : __r_(__default_init_tag(), __default_init_tag()) 2239{ 2240 __init(__il.begin(), __il.end()); 2241#if _LIBCPP_DEBUG_LEVEL == 2 2242 __get_db()->__insert_c(this); 2243#endif 2244} 2245 2246template <class _CharT, class _Traits, class _Allocator> 2247inline 2248 2249basic_string<_CharT, _Traits, _Allocator>::basic_string( 2250 initializer_list<_CharT> __il, const _Allocator& __a) 2251 : __r_(__default_init_tag(), __a) 2252{ 2253 __init(__il.begin(), __il.end()); 2254#if _LIBCPP_DEBUG_LEVEL == 2 2255 __get_db()->__insert_c(this); 2256#endif 2257} 2258 2259#endif // _LIBCPP_CXX03_LANG 2260 2261template <class _CharT, class _Traits, class _Allocator> 2262basic_string<_CharT, _Traits, _Allocator>::~basic_string() 2263{ 2264#if _LIBCPP_DEBUG_LEVEL == 2 2265 __get_db()->__erase_c(this); 2266#endif 2267 if (__is_long()) 2268 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 2269} 2270 2271template <class _CharT, class _Traits, class _Allocator> 2272void 2273basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace 2274 (size_type __old_cap, size_type __delta_cap, size_type __old_sz, 2275 size_type __n_copy, size_type __n_del, size_type __n_add, const value_type* __p_new_stuff) 2276{ 2277 size_type __ms = max_size(); 2278 if (__delta_cap > __ms - __old_cap - 1) 2279 this->__throw_length_error(); 2280 pointer __old_p = __get_pointer(); 2281 size_type __cap = __old_cap < __ms / 2 - __alignment ? 2282 __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) : 2283 __ms - 1; 2284 pointer __p = __alloc_traits::allocate(__alloc(), __cap+1); 2285 __invalidate_all_iterators(); 2286 if (__n_copy != 0) 2287 traits_type::copy(_VSTD::__to_address(__p), 2288 _VSTD::__to_address(__old_p), __n_copy); 2289 if (__n_add != 0) 2290 traits_type::copy(_VSTD::__to_address(__p) + __n_copy, __p_new_stuff, __n_add); 2291 size_type __sec_cp_sz = __old_sz - __n_del - __n_copy; 2292 if (__sec_cp_sz != 0) 2293 traits_type::copy(_VSTD::__to_address(__p) + __n_copy + __n_add, 2294 _VSTD::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz); 2295 if (__old_cap+1 != __min_cap) 2296 __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1); 2297 __set_long_pointer(__p); 2298 __set_long_cap(__cap+1); 2299 __old_sz = __n_copy + __n_add + __sec_cp_sz; 2300 __set_long_size(__old_sz); 2301 traits_type::assign(__p[__old_sz], value_type()); 2302} 2303 2304template <class _CharT, class _Traits, class _Allocator> 2305void 2306basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz, 2307 size_type __n_copy, size_type __n_del, size_type __n_add) 2308{ 2309 size_type __ms = max_size(); 2310 if (__delta_cap > __ms - __old_cap) 2311 this->__throw_length_error(); 2312 pointer __old_p = __get_pointer(); 2313 size_type __cap = __old_cap < __ms / 2 - __alignment ? 2314 __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) : 2315 __ms - 1; 2316 pointer __p = __alloc_traits::allocate(__alloc(), __cap+1); 2317 __invalidate_all_iterators(); 2318 if (__n_copy != 0) 2319 traits_type::copy(_VSTD::__to_address(__p), 2320 _VSTD::__to_address(__old_p), __n_copy); 2321 size_type __sec_cp_sz = __old_sz - __n_del - __n_copy; 2322 if (__sec_cp_sz != 0) 2323 traits_type::copy(_VSTD::__to_address(__p) + __n_copy + __n_add, 2324 _VSTD::__to_address(__old_p) + __n_copy + __n_del, 2325 __sec_cp_sz); 2326 if (__old_cap+1 != __min_cap) 2327 __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1); 2328 __set_long_pointer(__p); 2329 __set_long_cap(__cap+1); 2330} 2331 2332// assign 2333 2334template <class _CharT, class _Traits, class _Allocator> 2335template <bool __is_short> 2336basic_string<_CharT, _Traits, _Allocator>& 2337basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias( 2338 const value_type* __s, size_type __n) { 2339 size_type __cap = __is_short ? __min_cap : __get_long_cap(); 2340 if (__n < __cap) { 2341 pointer __p = __is_short ? __get_short_pointer() : __get_long_pointer(); 2342 __is_short ? __set_short_size(__n) : __set_long_size(__n); 2343 traits_type::copy(_VSTD::__to_address(__p), __s, __n); 2344 traits_type::assign(__p[__n], value_type()); 2345 __invalidate_iterators_past(__n); 2346 } else { 2347 size_type __sz = __is_short ? __get_short_size() : __get_long_size(); 2348 __grow_by_and_replace(__cap - 1, __n - __cap + 1, __sz, 0, __sz, __n, __s); 2349 } 2350 return *this; 2351} 2352 2353template <class _CharT, class _Traits, class _Allocator> 2354basic_string<_CharT, _Traits, _Allocator>& 2355basic_string<_CharT, _Traits, _Allocator>::__assign_external( 2356 const value_type* __s, size_type __n) { 2357 size_type __cap = capacity(); 2358 if (__cap >= __n) { 2359 value_type* __p = _VSTD::__to_address(__get_pointer()); 2360 traits_type::move(__p, __s, __n); 2361 return __null_terminate_at(__p, __n); 2362 } else { 2363 size_type __sz = size(); 2364 __grow_by_and_replace(__cap, __n - __cap, __sz, 0, __sz, __n, __s); 2365 return *this; 2366 } 2367} 2368 2369template <class _CharT, class _Traits, class _Allocator> 2370basic_string<_CharT, _Traits, _Allocator>& 2371basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n) 2372{ 2373 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::assign received nullptr"); 2374 return (__builtin_constant_p(__n) && __n < __min_cap) 2375 ? __assign_short(__s, __n) 2376 : __assign_external(__s, __n); 2377} 2378 2379template <class _CharT, class _Traits, class _Allocator> 2380basic_string<_CharT, _Traits, _Allocator>& 2381basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c) 2382{ 2383 size_type __cap = capacity(); 2384 if (__cap < __n) 2385 { 2386 size_type __sz = size(); 2387 __grow_by(__cap, __n - __cap, __sz, 0, __sz); 2388 } 2389 value_type* __p = _VSTD::__to_address(__get_pointer()); 2390 traits_type::assign(__p, __n, __c); 2391 return __null_terminate_at(__p, __n); 2392} 2393 2394template <class _CharT, class _Traits, class _Allocator> 2395basic_string<_CharT, _Traits, _Allocator>& 2396basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c) 2397{ 2398 pointer __p; 2399 if (__is_long()) 2400 { 2401 __p = __get_long_pointer(); 2402 __set_long_size(1); 2403 } 2404 else 2405 { 2406 __p = __get_short_pointer(); 2407 __set_short_size(1); 2408 } 2409 traits_type::assign(*__p, __c); 2410 traits_type::assign(*++__p, value_type()); 2411 __invalidate_iterators_past(1); 2412 return *this; 2413} 2414 2415template <class _CharT, class _Traits, class _Allocator> 2416basic_string<_CharT, _Traits, _Allocator>& 2417basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str) 2418{ 2419 if (this != &__str) { 2420 __copy_assign_alloc(__str); 2421 if (!__is_long()) { 2422 if (!__str.__is_long()) { 2423 __r_.first().__r = __str.__r_.first().__r; 2424 } else { 2425 return __assign_no_alias<true>(__str.data(), __str.size()); 2426 } 2427 } else { 2428 return __assign_no_alias<false>(__str.data(), __str.size()); 2429 } 2430 } 2431 return *this; 2432} 2433 2434#ifndef _LIBCPP_CXX03_LANG 2435 2436template <class _CharT, class _Traits, class _Allocator> 2437inline 2438void 2439basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, false_type) 2440 _NOEXCEPT_(__alloc_traits::is_always_equal::value) 2441{ 2442 if (__alloc() != __str.__alloc()) 2443 assign(__str); 2444 else 2445 __move_assign(__str, true_type()); 2446} 2447 2448template <class _CharT, class _Traits, class _Allocator> 2449inline 2450void 2451basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type) 2452#if _LIBCPP_STD_VER > 14 2453 _NOEXCEPT 2454#else 2455 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) 2456#endif 2457{ 2458 if (__is_long()) { 2459 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), 2460 __get_long_cap()); 2461#if _LIBCPP_STD_VER <= 14 2462 if (!is_nothrow_move_assignable<allocator_type>::value) { 2463 __set_short_size(0); 2464 traits_type::assign(__get_short_pointer()[0], value_type()); 2465 } 2466#endif 2467 } 2468 __move_assign_alloc(__str); 2469 __r_.first() = __str.__r_.first(); 2470 __str.__set_short_size(0); 2471 traits_type::assign(__str.__get_short_pointer()[0], value_type()); 2472} 2473 2474template <class _CharT, class _Traits, class _Allocator> 2475inline 2476basic_string<_CharT, _Traits, _Allocator>& 2477basic_string<_CharT, _Traits, _Allocator>::operator=(basic_string&& __str) 2478 _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value)) 2479{ 2480 __move_assign(__str, integral_constant<bool, 2481 __alloc_traits::propagate_on_container_move_assignment::value>()); 2482 return *this; 2483} 2484 2485#endif 2486 2487template <class _CharT, class _Traits, class _Allocator> 2488template<class _InputIterator> 2489__enable_if_t 2490< 2491 __is_exactly_cpp17_input_iterator<_InputIterator>::value, 2492 basic_string<_CharT, _Traits, _Allocator>& 2493> 2494basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last) 2495{ 2496 const basic_string __temp(__first, __last, __alloc()); 2497 assign(__temp.data(), __temp.size()); 2498 return *this; 2499} 2500 2501template <class _CharT, class _Traits, class _Allocator> 2502template<class _ForwardIterator> 2503__enable_if_t 2504< 2505 __is_cpp17_forward_iterator<_ForwardIterator>::value, 2506 basic_string<_CharT, _Traits, _Allocator>& 2507> 2508basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last) 2509{ 2510 size_type __cap = capacity(); 2511 size_type __n = __string_is_trivial_iterator<_ForwardIterator>::value ? 2512 static_cast<size_type>(_VSTD::distance(__first, __last)) : 0; 2513 2514 if (__string_is_trivial_iterator<_ForwardIterator>::value && 2515 (__cap >= __n || !__addr_in_range(*__first))) 2516 { 2517 if (__cap < __n) 2518 { 2519 size_type __sz = size(); 2520 __grow_by(__cap, __n - __cap, __sz, 0, __sz); 2521 } 2522 pointer __p = __get_pointer(); 2523 for (; __first != __last; ++__p, (void) ++__first) 2524 traits_type::assign(*__p, *__first); 2525 traits_type::assign(*__p, value_type()); 2526 __set_size(__n); 2527 __invalidate_iterators_past(__n); 2528 } 2529 else 2530 { 2531 const basic_string __temp(__first, __last, __alloc()); 2532 assign(__temp.data(), __temp.size()); 2533 } 2534 return *this; 2535} 2536 2537template <class _CharT, class _Traits, class _Allocator> 2538basic_string<_CharT, _Traits, _Allocator>& 2539basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, size_type __pos, size_type __n) 2540{ 2541 size_type __sz = __str.size(); 2542 if (__pos > __sz) 2543 this->__throw_out_of_range(); 2544 return assign(__str.data() + __pos, _VSTD::min(__n, __sz - __pos)); 2545} 2546 2547template <class _CharT, class _Traits, class _Allocator> 2548template <class _Tp> 2549__enable_if_t 2550< 2551 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value 2552 && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 2553 basic_string<_CharT, _Traits, _Allocator>& 2554> 2555basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t, size_type __pos, size_type __n) 2556{ 2557 __self_view __sv = __t; 2558 size_type __sz = __sv.size(); 2559 if (__pos > __sz) 2560 this->__throw_out_of_range(); 2561 return assign(__sv.data() + __pos, _VSTD::min(__n, __sz - __pos)); 2562} 2563 2564 2565template <class _CharT, class _Traits, class _Allocator> 2566basic_string<_CharT, _Traits, _Allocator>& 2567basic_string<_CharT, _Traits, _Allocator>::__assign_external(const value_type* __s) { 2568 return __assign_external(__s, traits_type::length(__s)); 2569} 2570 2571template <class _CharT, class _Traits, class _Allocator> 2572basic_string<_CharT, _Traits, _Allocator>& 2573basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s) 2574{ 2575 _LIBCPP_ASSERT(__s != nullptr, "string::assign received nullptr"); 2576 return __builtin_constant_p(*__s) 2577 ? (traits_type::length(__s) < __min_cap 2578 ? __assign_short(__s, traits_type::length(__s)) 2579 : __assign_external(__s, traits_type::length(__s))) 2580 : __assign_external(__s); 2581} 2582// append 2583 2584template <class _CharT, class _Traits, class _Allocator> 2585basic_string<_CharT, _Traits, _Allocator>& 2586basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n) 2587{ 2588 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::append received nullptr"); 2589 size_type __cap = capacity(); 2590 size_type __sz = size(); 2591 if (__cap - __sz >= __n) 2592 { 2593 if (__n) 2594 { 2595 value_type* __p = _VSTD::__to_address(__get_pointer()); 2596 traits_type::copy(__p + __sz, __s, __n); 2597 __sz += __n; 2598 __set_size(__sz); 2599 traits_type::assign(__p[__sz], value_type()); 2600 } 2601 } 2602 else 2603 __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __sz, 0, __n, __s); 2604 return *this; 2605} 2606 2607template <class _CharT, class _Traits, class _Allocator> 2608basic_string<_CharT, _Traits, _Allocator>& 2609basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c) 2610{ 2611 if (__n) 2612 { 2613 size_type __cap = capacity(); 2614 size_type __sz = size(); 2615 if (__cap - __sz < __n) 2616 __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); 2617 pointer __p = __get_pointer(); 2618 traits_type::assign(_VSTD::__to_address(__p) + __sz, __n, __c); 2619 __sz += __n; 2620 __set_size(__sz); 2621 traits_type::assign(__p[__sz], value_type()); 2622 } 2623 return *this; 2624} 2625 2626template <class _CharT, class _Traits, class _Allocator> 2627inline void 2628basic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n) 2629{ 2630 if (__n) 2631 { 2632 size_type __cap = capacity(); 2633 size_type __sz = size(); 2634 if (__cap - __sz < __n) 2635 __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); 2636 pointer __p = __get_pointer(); 2637 __sz += __n; 2638 __set_size(__sz); 2639 traits_type::assign(__p[__sz], value_type()); 2640 } 2641} 2642 2643template <class _CharT, class _Traits, class _Allocator> 2644void 2645basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c) 2646{ 2647 bool __is_short = !__is_long(); 2648 size_type __cap; 2649 size_type __sz; 2650 if (__is_short) 2651 { 2652 __cap = __min_cap - 1; 2653 __sz = __get_short_size(); 2654 } 2655 else 2656 { 2657 __cap = __get_long_cap() - 1; 2658 __sz = __get_long_size(); 2659 } 2660 if (__sz == __cap) 2661 { 2662 __grow_by(__cap, 1, __sz, __sz, 0); 2663 __is_short = false; // the string is always long after __grow_by 2664 } 2665 pointer __p; 2666 if (__is_short) 2667 { 2668 __p = __get_short_pointer() + __sz; 2669 __set_short_size(__sz+1); 2670 } 2671 else 2672 { 2673 __p = __get_long_pointer() + __sz; 2674 __set_long_size(__sz+1); 2675 } 2676 traits_type::assign(*__p, __c); 2677 traits_type::assign(*++__p, value_type()); 2678} 2679 2680template <class _CharT, class _Traits, class _Allocator> 2681template<class _ForwardIterator> 2682__enable_if_t 2683< 2684 __is_cpp17_forward_iterator<_ForwardIterator>::value, 2685 basic_string<_CharT, _Traits, _Allocator>& 2686> 2687basic_string<_CharT, _Traits, _Allocator>::append( 2688 _ForwardIterator __first, _ForwardIterator __last) 2689{ 2690 size_type __sz = size(); 2691 size_type __cap = capacity(); 2692 size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last)); 2693 if (__n) 2694 { 2695 if (__string_is_trivial_iterator<_ForwardIterator>::value && 2696 !__addr_in_range(*__first)) 2697 { 2698 if (__cap - __sz < __n) 2699 __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); 2700 pointer __p = __get_pointer() + __sz; 2701 for (; __first != __last; ++__p, (void) ++__first) 2702 traits_type::assign(*__p, *__first); 2703 traits_type::assign(*__p, value_type()); 2704 __set_size(__sz + __n); 2705 } 2706 else 2707 { 2708 const basic_string __temp(__first, __last, __alloc()); 2709 append(__temp.data(), __temp.size()); 2710 } 2711 } 2712 return *this; 2713} 2714 2715template <class _CharT, class _Traits, class _Allocator> 2716inline 2717basic_string<_CharT, _Traits, _Allocator>& 2718basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str) 2719{ 2720 return append(__str.data(), __str.size()); 2721} 2722 2723template <class _CharT, class _Traits, class _Allocator> 2724basic_string<_CharT, _Traits, _Allocator>& 2725basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, size_type __pos, size_type __n) 2726{ 2727 size_type __sz = __str.size(); 2728 if (__pos > __sz) 2729 this->__throw_out_of_range(); 2730 return append(__str.data() + __pos, _VSTD::min(__n, __sz - __pos)); 2731} 2732 2733template <class _CharT, class _Traits, class _Allocator> 2734template <class _Tp> 2735 __enable_if_t 2736 < 2737 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 2738 basic_string<_CharT, _Traits, _Allocator>& 2739 > 2740basic_string<_CharT, _Traits, _Allocator>::append(const _Tp & __t, size_type __pos, size_type __n) 2741{ 2742 __self_view __sv = __t; 2743 size_type __sz = __sv.size(); 2744 if (__pos > __sz) 2745 this->__throw_out_of_range(); 2746 return append(__sv.data() + __pos, _VSTD::min(__n, __sz - __pos)); 2747} 2748 2749template <class _CharT, class _Traits, class _Allocator> 2750basic_string<_CharT, _Traits, _Allocator>& 2751basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s) 2752{ 2753 _LIBCPP_ASSERT(__s != nullptr, "string::append received nullptr"); 2754 return append(__s, traits_type::length(__s)); 2755} 2756 2757// insert 2758 2759template <class _CharT, class _Traits, class _Allocator> 2760basic_string<_CharT, _Traits, _Allocator>& 2761basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n) 2762{ 2763 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::insert received nullptr"); 2764 size_type __sz = size(); 2765 if (__pos > __sz) 2766 this->__throw_out_of_range(); 2767 size_type __cap = capacity(); 2768 if (__cap - __sz >= __n) 2769 { 2770 if (__n) 2771 { 2772 value_type* __p = _VSTD::__to_address(__get_pointer()); 2773 size_type __n_move = __sz - __pos; 2774 if (__n_move != 0) 2775 { 2776 if (__p + __pos <= __s && __s < __p + __sz) 2777 __s += __n; 2778 traits_type::move(__p + __pos + __n, __p + __pos, __n_move); 2779 } 2780 traits_type::move(__p + __pos, __s, __n); 2781 __sz += __n; 2782 __set_size(__sz); 2783 traits_type::assign(__p[__sz], value_type()); 2784 } 2785 } 2786 else 2787 __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s); 2788 return *this; 2789} 2790 2791template <class _CharT, class _Traits, class _Allocator> 2792basic_string<_CharT, _Traits, _Allocator>& 2793basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n, value_type __c) 2794{ 2795 size_type __sz = size(); 2796 if (__pos > __sz) 2797 this->__throw_out_of_range(); 2798 if (__n) 2799 { 2800 size_type __cap = capacity(); 2801 value_type* __p; 2802 if (__cap - __sz >= __n) 2803 { 2804 __p = _VSTD::__to_address(__get_pointer()); 2805 size_type __n_move = __sz - __pos; 2806 if (__n_move != 0) 2807 traits_type::move(__p + __pos + __n, __p + __pos, __n_move); 2808 } 2809 else 2810 { 2811 __grow_by(__cap, __sz + __n - __cap, __sz, __pos, 0, __n); 2812 __p = _VSTD::__to_address(__get_long_pointer()); 2813 } 2814 traits_type::assign(__p + __pos, __n, __c); 2815 __sz += __n; 2816 __set_size(__sz); 2817 traits_type::assign(__p[__sz], value_type()); 2818 } 2819 return *this; 2820} 2821 2822template <class _CharT, class _Traits, class _Allocator> 2823template<class _InputIterator> 2824__enable_if_t 2825< 2826 __is_exactly_cpp17_input_iterator<_InputIterator>::value, 2827 typename basic_string<_CharT, _Traits, _Allocator>::iterator 2828> 2829basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last) 2830{ 2831#if _LIBCPP_DEBUG_LEVEL == 2 2832 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, 2833 "string::insert(iterator, range) called with an iterator not" 2834 " referring to this string"); 2835#endif 2836 const basic_string __temp(__first, __last, __alloc()); 2837 return insert(__pos, __temp.data(), __temp.data() + __temp.size()); 2838} 2839 2840template <class _CharT, class _Traits, class _Allocator> 2841template<class _ForwardIterator> 2842__enable_if_t 2843< 2844 __is_cpp17_forward_iterator<_ForwardIterator>::value, 2845 typename basic_string<_CharT, _Traits, _Allocator>::iterator 2846> 2847basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last) 2848{ 2849#if _LIBCPP_DEBUG_LEVEL == 2 2850 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, 2851 "string::insert(iterator, range) called with an iterator not" 2852 " referring to this string"); 2853#endif 2854 size_type __ip = static_cast<size_type>(__pos - begin()); 2855 size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last)); 2856 if (__n) 2857 { 2858 if (__string_is_trivial_iterator<_ForwardIterator>::value && 2859 !__addr_in_range(*__first)) 2860 { 2861 size_type __sz = size(); 2862 size_type __cap = capacity(); 2863 value_type* __p; 2864 if (__cap - __sz >= __n) 2865 { 2866 __p = _VSTD::__to_address(__get_pointer()); 2867 size_type __n_move = __sz - __ip; 2868 if (__n_move != 0) 2869 traits_type::move(__p + __ip + __n, __p + __ip, __n_move); 2870 } 2871 else 2872 { 2873 __grow_by(__cap, __sz + __n - __cap, __sz, __ip, 0, __n); 2874 __p = _VSTD::__to_address(__get_long_pointer()); 2875 } 2876 __sz += __n; 2877 __set_size(__sz); 2878 traits_type::assign(__p[__sz], value_type()); 2879 for (__p += __ip; __first != __last; ++__p, (void) ++__first) 2880 traits_type::assign(*__p, *__first); 2881 } 2882 else 2883 { 2884 const basic_string __temp(__first, __last, __alloc()); 2885 return insert(__pos, __temp.data(), __temp.data() + __temp.size()); 2886 } 2887 } 2888 return begin() + __ip; 2889} 2890 2891template <class _CharT, class _Traits, class _Allocator> 2892inline 2893basic_string<_CharT, _Traits, _Allocator>& 2894basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str) 2895{ 2896 return insert(__pos1, __str.data(), __str.size()); 2897} 2898 2899template <class _CharT, class _Traits, class _Allocator> 2900basic_string<_CharT, _Traits, _Allocator>& 2901basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str, 2902 size_type __pos2, size_type __n) 2903{ 2904 size_type __str_sz = __str.size(); 2905 if (__pos2 > __str_sz) 2906 this->__throw_out_of_range(); 2907 return insert(__pos1, __str.data() + __pos2, _VSTD::min(__n, __str_sz - __pos2)); 2908} 2909 2910template <class _CharT, class _Traits, class _Allocator> 2911template <class _Tp> 2912__enable_if_t 2913< 2914 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 2915 basic_string<_CharT, _Traits, _Allocator>& 2916> 2917basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& __t, 2918 size_type __pos2, size_type __n) 2919{ 2920 __self_view __sv = __t; 2921 size_type __str_sz = __sv.size(); 2922 if (__pos2 > __str_sz) 2923 this->__throw_out_of_range(); 2924 return insert(__pos1, __sv.data() + __pos2, _VSTD::min(__n, __str_sz - __pos2)); 2925} 2926 2927template <class _CharT, class _Traits, class _Allocator> 2928basic_string<_CharT, _Traits, _Allocator>& 2929basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s) 2930{ 2931 _LIBCPP_ASSERT(__s != nullptr, "string::insert received nullptr"); 2932 return insert(__pos, __s, traits_type::length(__s)); 2933} 2934 2935template <class _CharT, class _Traits, class _Allocator> 2936typename basic_string<_CharT, _Traits, _Allocator>::iterator 2937basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c) 2938{ 2939 size_type __ip = static_cast<size_type>(__pos - begin()); 2940 size_type __sz = size(); 2941 size_type __cap = capacity(); 2942 value_type* __p; 2943 if (__cap == __sz) 2944 { 2945 __grow_by(__cap, 1, __sz, __ip, 0, 1); 2946 __p = _VSTD::__to_address(__get_long_pointer()); 2947 } 2948 else 2949 { 2950 __p = _VSTD::__to_address(__get_pointer()); 2951 size_type __n_move = __sz - __ip; 2952 if (__n_move != 0) 2953 traits_type::move(__p + __ip + 1, __p + __ip, __n_move); 2954 } 2955 traits_type::assign(__p[__ip], __c); 2956 traits_type::assign(__p[++__sz], value_type()); 2957 __set_size(__sz); 2958 return begin() + static_cast<difference_type>(__ip); 2959} 2960 2961template <class _CharT, class _Traits, class _Allocator> 2962inline 2963typename basic_string<_CharT, _Traits, _Allocator>::iterator 2964basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, size_type __n, value_type __c) 2965{ 2966#if _LIBCPP_DEBUG_LEVEL == 2 2967 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, 2968 "string::insert(iterator, n, value) called with an iterator not" 2969 " referring to this string"); 2970#endif 2971 difference_type __p = __pos - begin(); 2972 insert(static_cast<size_type>(__p), __n, __c); 2973 return begin() + __p; 2974} 2975 2976// replace 2977 2978template <class _CharT, class _Traits, class _Allocator> 2979basic_string<_CharT, _Traits, _Allocator>& 2980basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2) 2981 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK 2982{ 2983 _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::replace received nullptr"); 2984 size_type __sz = size(); 2985 if (__pos > __sz) 2986 this->__throw_out_of_range(); 2987 __n1 = _VSTD::min(__n1, __sz - __pos); 2988 size_type __cap = capacity(); 2989 if (__cap - __sz + __n1 >= __n2) 2990 { 2991 value_type* __p = _VSTD::__to_address(__get_pointer()); 2992 if (__n1 != __n2) 2993 { 2994 size_type __n_move = __sz - __pos - __n1; 2995 if (__n_move != 0) 2996 { 2997 if (__n1 > __n2) 2998 { 2999 traits_type::move(__p + __pos, __s, __n2); 3000 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move); 3001 return __null_terminate_at(__p, __sz + (__n2 - __n1)); 3002 } 3003 if (__p + __pos < __s && __s < __p + __sz) 3004 { 3005 if (__p + __pos + __n1 <= __s) 3006 __s += __n2 - __n1; 3007 else // __p + __pos < __s < __p + __pos + __n1 3008 { 3009 traits_type::move(__p + __pos, __s, __n1); 3010 __pos += __n1; 3011 __s += __n2; 3012 __n2 -= __n1; 3013 __n1 = 0; 3014 } 3015 } 3016 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move); 3017 } 3018 } 3019 traits_type::move(__p + __pos, __s, __n2); 3020 return __null_terminate_at(__p, __sz + (__n2 - __n1)); 3021 } 3022 else 3023 __grow_by_and_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2, __s); 3024 return *this; 3025} 3026 3027template <class _CharT, class _Traits, class _Allocator> 3028basic_string<_CharT, _Traits, _Allocator>& 3029basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, size_type __n2, value_type __c) 3030{ 3031 size_type __sz = size(); 3032 if (__pos > __sz) 3033 this->__throw_out_of_range(); 3034 __n1 = _VSTD::min(__n1, __sz - __pos); 3035 size_type __cap = capacity(); 3036 value_type* __p; 3037 if (__cap - __sz + __n1 >= __n2) 3038 { 3039 __p = _VSTD::__to_address(__get_pointer()); 3040 if (__n1 != __n2) 3041 { 3042 size_type __n_move = __sz - __pos - __n1; 3043 if (__n_move != 0) 3044 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move); 3045 } 3046 } 3047 else 3048 { 3049 __grow_by(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2); 3050 __p = _VSTD::__to_address(__get_long_pointer()); 3051 } 3052 traits_type::assign(__p + __pos, __n2, __c); 3053 return __null_terminate_at(__p, __sz - (__n1 - __n2)); 3054} 3055 3056template <class _CharT, class _Traits, class _Allocator> 3057template<class _InputIterator> 3058__enable_if_t 3059< 3060 __is_cpp17_input_iterator<_InputIterator>::value, 3061 basic_string<_CharT, _Traits, _Allocator>& 3062> 3063basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, 3064 _InputIterator __j1, _InputIterator __j2) 3065{ 3066 const basic_string __temp(__j1, __j2, __alloc()); 3067 return this->replace(__i1, __i2, __temp); 3068} 3069 3070template <class _CharT, class _Traits, class _Allocator> 3071inline 3072basic_string<_CharT, _Traits, _Allocator>& 3073basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str) 3074{ 3075 return replace(__pos1, __n1, __str.data(), __str.size()); 3076} 3077 3078template <class _CharT, class _Traits, class _Allocator> 3079basic_string<_CharT, _Traits, _Allocator>& 3080basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str, 3081 size_type __pos2, size_type __n2) 3082{ 3083 size_type __str_sz = __str.size(); 3084 if (__pos2 > __str_sz) 3085 this->__throw_out_of_range(); 3086 return replace(__pos1, __n1, __str.data() + __pos2, _VSTD::min(__n2, __str_sz - __pos2)); 3087} 3088 3089template <class _CharT, class _Traits, class _Allocator> 3090template <class _Tp> 3091__enable_if_t 3092< 3093 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 3094 basic_string<_CharT, _Traits, _Allocator>& 3095> 3096basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const _Tp& __t, 3097 size_type __pos2, size_type __n2) 3098{ 3099 __self_view __sv = __t; 3100 size_type __str_sz = __sv.size(); 3101 if (__pos2 > __str_sz) 3102 this->__throw_out_of_range(); 3103 return replace(__pos1, __n1, __sv.data() + __pos2, _VSTD::min(__n2, __str_sz - __pos2)); 3104} 3105 3106template <class _CharT, class _Traits, class _Allocator> 3107basic_string<_CharT, _Traits, _Allocator>& 3108basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s) 3109{ 3110 _LIBCPP_ASSERT(__s != nullptr, "string::replace received nullptr"); 3111 return replace(__pos, __n1, __s, traits_type::length(__s)); 3112} 3113 3114template <class _CharT, class _Traits, class _Allocator> 3115inline 3116basic_string<_CharT, _Traits, _Allocator>& 3117basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const basic_string& __str) 3118{ 3119 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), 3120 __str.data(), __str.size()); 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 value_type* __s, size_type __n) 3127{ 3128 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s, __n); 3129} 3130 3131template <class _CharT, class _Traits, class _Allocator> 3132inline 3133basic_string<_CharT, _Traits, _Allocator>& 3134basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s) 3135{ 3136 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s); 3137} 3138 3139template <class _CharT, class _Traits, class _Allocator> 3140inline 3141basic_string<_CharT, _Traits, _Allocator>& 3142basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c) 3143{ 3144 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __n, __c); 3145} 3146 3147// erase 3148 3149// 'externally instantiated' erase() implementation, called when __n != npos. 3150// Does not check __pos against size() 3151template <class _CharT, class _Traits, class _Allocator> 3152void 3153basic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move( 3154 size_type __pos, size_type __n) 3155{ 3156 if (__n) 3157 { 3158 size_type __sz = size(); 3159 value_type* __p = _VSTD::__to_address(__get_pointer()); 3160 __n = _VSTD::min(__n, __sz - __pos); 3161 size_type __n_move = __sz - __pos - __n; 3162 if (__n_move != 0) 3163 traits_type::move(__p + __pos, __p + __pos + __n, __n_move); 3164 __null_terminate_at(__p, __sz - __n); 3165 } 3166} 3167 3168template <class _CharT, class _Traits, class _Allocator> 3169basic_string<_CharT, _Traits, _Allocator>& 3170basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, 3171 size_type __n) { 3172 if (__pos > size()) this->__throw_out_of_range(); 3173 if (__n == npos) { 3174 __erase_to_end(__pos); 3175 } else { 3176 __erase_external_with_move(__pos, __n); 3177 } 3178 return *this; 3179} 3180 3181template <class _CharT, class _Traits, class _Allocator> 3182inline 3183typename basic_string<_CharT, _Traits, _Allocator>::iterator 3184basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos) 3185{ 3186#if _LIBCPP_DEBUG_LEVEL == 2 3187 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, 3188 "string::erase(iterator) called with an iterator not" 3189 " referring to this string"); 3190#endif 3191 _LIBCPP_ASSERT(__pos != end(), 3192 "string::erase(iterator) called with a non-dereferenceable iterator"); 3193 iterator __b = begin(); 3194 size_type __r = static_cast<size_type>(__pos - __b); 3195 erase(__r, 1); 3196 return __b + static_cast<difference_type>(__r); 3197} 3198 3199template <class _CharT, class _Traits, class _Allocator> 3200inline 3201typename basic_string<_CharT, _Traits, _Allocator>::iterator 3202basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last) 3203{ 3204#if _LIBCPP_DEBUG_LEVEL == 2 3205 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this, 3206 "string::erase(iterator, iterator) called with an iterator not" 3207 " referring to this string"); 3208#endif 3209 _LIBCPP_ASSERT(__first <= __last, "string::erase(first, last) called with invalid range"); 3210 iterator __b = begin(); 3211 size_type __r = static_cast<size_type>(__first - __b); 3212 erase(__r, static_cast<size_type>(__last - __first)); 3213 return __b + static_cast<difference_type>(__r); 3214} 3215 3216template <class _CharT, class _Traits, class _Allocator> 3217inline 3218void 3219basic_string<_CharT, _Traits, _Allocator>::pop_back() 3220{ 3221 _LIBCPP_ASSERT(!empty(), "string::pop_back(): string is already empty"); 3222 __erase_to_end(size() - 1); 3223} 3224 3225template <class _CharT, class _Traits, class _Allocator> 3226inline 3227void 3228basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT 3229{ 3230 __invalidate_all_iterators(); 3231 if (__is_long()) 3232 { 3233 traits_type::assign(*__get_long_pointer(), value_type()); 3234 __set_long_size(0); 3235 } 3236 else 3237 { 3238 traits_type::assign(*__get_short_pointer(), value_type()); 3239 __set_short_size(0); 3240 } 3241} 3242 3243template <class _CharT, class _Traits, class _Allocator> 3244inline 3245void 3246basic_string<_CharT, _Traits, _Allocator>::__erase_to_end(size_type __pos) 3247{ 3248 __null_terminate_at(_VSTD::__to_address(__get_pointer()), __pos); 3249} 3250 3251template <class _CharT, class _Traits, class _Allocator> 3252void 3253basic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c) 3254{ 3255 size_type __sz = size(); 3256 if (__n > __sz) 3257 append(__n - __sz, __c); 3258 else 3259 __erase_to_end(__n); 3260} 3261 3262template <class _CharT, class _Traits, class _Allocator> 3263inline void 3264basic_string<_CharT, _Traits, _Allocator>::__resize_default_init(size_type __n) 3265{ 3266 size_type __sz = size(); 3267 if (__n > __sz) { 3268 __append_default_init(__n - __sz); 3269 } else 3270 __erase_to_end(__n); 3271} 3272 3273template <class _CharT, class _Traits, class _Allocator> 3274inline 3275typename basic_string<_CharT, _Traits, _Allocator>::size_type 3276basic_string<_CharT, _Traits, _Allocator>::max_size() const _NOEXCEPT 3277{ 3278 size_type __m = __alloc_traits::max_size(__alloc()); 3279#ifdef _LIBCPP_BIG_ENDIAN 3280 return (__m <= ~__long_mask ? __m : __m/2) - __alignment; 3281#else 3282 return __m - __alignment; 3283#endif 3284} 3285 3286template <class _CharT, class _Traits, class _Allocator> 3287void 3288basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacity) 3289{ 3290 if (__requested_capacity > max_size()) 3291 this->__throw_length_error(); 3292 3293#if _LIBCPP_STD_VER > 17 3294 // Reserve never shrinks as of C++20. 3295 if (__requested_capacity <= capacity()) return; 3296#endif 3297 3298 size_type __target_capacity = _VSTD::max(__requested_capacity, size()); 3299 __target_capacity = __recommend(__target_capacity); 3300 if (__target_capacity == capacity()) return; 3301 3302 __shrink_or_extend(__target_capacity); 3303} 3304 3305template <class _CharT, class _Traits, class _Allocator> 3306inline 3307void 3308basic_string<_CharT, _Traits, _Allocator>::shrink_to_fit() _NOEXCEPT 3309{ 3310 size_type __target_capacity = __recommend(size()); 3311 if (__target_capacity == capacity()) return; 3312 3313 __shrink_or_extend(__target_capacity); 3314} 3315 3316template <class _CharT, class _Traits, class _Allocator> 3317inline 3318void 3319basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target_capacity) 3320{ 3321 size_type __cap = capacity(); 3322 size_type __sz = size(); 3323 3324 pointer __new_data, __p; 3325 bool __was_long, __now_long; 3326 if (__target_capacity == __min_cap - 1) 3327 { 3328 __was_long = true; 3329 __now_long = false; 3330 __new_data = __get_short_pointer(); 3331 __p = __get_long_pointer(); 3332 } 3333 else 3334 { 3335 if (__target_capacity > __cap) 3336 __new_data = __alloc_traits::allocate(__alloc(), __target_capacity+1); 3337 else 3338 { 3339 #ifndef _LIBCPP_NO_EXCEPTIONS 3340 try 3341 { 3342 #endif // _LIBCPP_NO_EXCEPTIONS 3343 __new_data = __alloc_traits::allocate(__alloc(), __target_capacity+1); 3344 #ifndef _LIBCPP_NO_EXCEPTIONS 3345 } 3346 catch (...) 3347 { 3348 return; 3349 } 3350 #else // _LIBCPP_NO_EXCEPTIONS 3351 if (__new_data == nullptr) 3352 return; 3353 #endif // _LIBCPP_NO_EXCEPTIONS 3354 } 3355 __now_long = true; 3356 __was_long = __is_long(); 3357 __p = __get_pointer(); 3358 } 3359 traits_type::copy(_VSTD::__to_address(__new_data), 3360 _VSTD::__to_address(__p), size()+1); 3361 if (__was_long) 3362 __alloc_traits::deallocate(__alloc(), __p, __cap+1); 3363 if (__now_long) 3364 { 3365 __set_long_cap(__target_capacity+1); 3366 __set_long_size(__sz); 3367 __set_long_pointer(__new_data); 3368 } 3369 else 3370 __set_short_size(__sz); 3371 __invalidate_all_iterators(); 3372} 3373 3374template <class _CharT, class _Traits, class _Allocator> 3375inline 3376typename basic_string<_CharT, _Traits, _Allocator>::const_reference 3377basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const _NOEXCEPT 3378{ 3379 _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds"); 3380 return *(data() + __pos); 3381} 3382 3383template <class _CharT, class _Traits, class _Allocator> 3384inline 3385typename basic_string<_CharT, _Traits, _Allocator>::reference 3386basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) _NOEXCEPT 3387{ 3388 _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds"); 3389 return *(__get_pointer() + __pos); 3390} 3391 3392template <class _CharT, class _Traits, class _Allocator> 3393typename basic_string<_CharT, _Traits, _Allocator>::const_reference 3394basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const 3395{ 3396 if (__n >= size()) 3397 this->__throw_out_of_range(); 3398 return (*this)[__n]; 3399} 3400 3401template <class _CharT, class _Traits, class _Allocator> 3402typename basic_string<_CharT, _Traits, _Allocator>::reference 3403basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) 3404{ 3405 if (__n >= size()) 3406 this->__throw_out_of_range(); 3407 return (*this)[__n]; 3408} 3409 3410template <class _CharT, class _Traits, class _Allocator> 3411inline 3412typename basic_string<_CharT, _Traits, _Allocator>::reference 3413basic_string<_CharT, _Traits, _Allocator>::front() _NOEXCEPT 3414{ 3415 _LIBCPP_ASSERT(!empty(), "string::front(): string is empty"); 3416 return *__get_pointer(); 3417} 3418 3419template <class _CharT, class _Traits, class _Allocator> 3420inline 3421typename basic_string<_CharT, _Traits, _Allocator>::const_reference 3422basic_string<_CharT, _Traits, _Allocator>::front() const _NOEXCEPT 3423{ 3424 _LIBCPP_ASSERT(!empty(), "string::front(): string is empty"); 3425 return *data(); 3426} 3427 3428template <class _CharT, class _Traits, class _Allocator> 3429inline 3430typename basic_string<_CharT, _Traits, _Allocator>::reference 3431basic_string<_CharT, _Traits, _Allocator>::back() _NOEXCEPT 3432{ 3433 _LIBCPP_ASSERT(!empty(), "string::back(): string is empty"); 3434 return *(__get_pointer() + size() - 1); 3435} 3436 3437template <class _CharT, class _Traits, class _Allocator> 3438inline 3439typename basic_string<_CharT, _Traits, _Allocator>::const_reference 3440basic_string<_CharT, _Traits, _Allocator>::back() const _NOEXCEPT 3441{ 3442 _LIBCPP_ASSERT(!empty(), "string::back(): string is empty"); 3443 return *(data() + size() - 1); 3444} 3445 3446template <class _CharT, class _Traits, class _Allocator> 3447typename basic_string<_CharT, _Traits, _Allocator>::size_type 3448basic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n, size_type __pos) const 3449{ 3450 size_type __sz = size(); 3451 if (__pos > __sz) 3452 this->__throw_out_of_range(); 3453 size_type __rlen = _VSTD::min(__n, __sz - __pos); 3454 traits_type::copy(__s, data() + __pos, __rlen); 3455 return __rlen; 3456} 3457 3458template <class _CharT, class _Traits, class _Allocator> 3459inline 3460basic_string<_CharT, _Traits, _Allocator> 3461basic_string<_CharT, _Traits, _Allocator>::substr(size_type __pos, size_type __n) const 3462{ 3463 return basic_string(*this, __pos, __n, __alloc()); 3464} 3465 3466template <class _CharT, class _Traits, class _Allocator> 3467inline 3468void 3469basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str) 3470#if _LIBCPP_STD_VER >= 14 3471 _NOEXCEPT 3472#else 3473 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || 3474 __is_nothrow_swappable<allocator_type>::value) 3475#endif 3476{ 3477#if _LIBCPP_DEBUG_LEVEL == 2 3478 if (!__is_long()) 3479 __get_db()->__invalidate_all(this); 3480 if (!__str.__is_long()) 3481 __get_db()->__invalidate_all(&__str); 3482 __get_db()->swap(this, &__str); 3483#endif 3484 _LIBCPP_ASSERT( 3485 __alloc_traits::propagate_on_container_swap::value || 3486 __alloc_traits::is_always_equal::value || 3487 __alloc() == __str.__alloc(), "swapping non-equal allocators"); 3488 _VSTD::swap(__r_.first(), __str.__r_.first()); 3489 _VSTD::__swap_allocator(__alloc(), __str.__alloc()); 3490} 3491 3492// find 3493 3494template <class _Traits> 3495struct _LIBCPP_HIDDEN __traits_eq 3496{ 3497 typedef typename _Traits::char_type char_type; 3498 _LIBCPP_INLINE_VISIBILITY 3499 bool operator()(const char_type& __x, const char_type& __y) _NOEXCEPT 3500 {return _Traits::eq(__x, __y);} 3501}; 3502 3503template<class _CharT, class _Traits, class _Allocator> 3504typename basic_string<_CharT, _Traits, _Allocator>::size_type 3505basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, 3506 size_type __pos, 3507 size_type __n) const _NOEXCEPT 3508{ 3509 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find(): received nullptr"); 3510 return __str_find<value_type, size_type, traits_type, npos> 3511 (data(), size(), __s, __pos, __n); 3512} 3513 3514template<class _CharT, class _Traits, class _Allocator> 3515inline 3516typename basic_string<_CharT, _Traits, _Allocator>::size_type 3517basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str, 3518 size_type __pos) const _NOEXCEPT 3519{ 3520 return __str_find<value_type, size_type, traits_type, npos> 3521 (data(), size(), __str.data(), __pos, __str.size()); 3522} 3523 3524template<class _CharT, class _Traits, class _Allocator> 3525template <class _Tp> 3526__enable_if_t 3527< 3528 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 3529 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3530> 3531basic_string<_CharT, _Traits, _Allocator>::find(const _Tp &__t, 3532 size_type __pos) const _NOEXCEPT 3533{ 3534 __self_view __sv = __t; 3535 return __str_find<value_type, size_type, traits_type, npos> 3536 (data(), size(), __sv.data(), __pos, __sv.size()); 3537} 3538 3539template<class _CharT, class _Traits, class _Allocator> 3540inline 3541typename basic_string<_CharT, _Traits, _Allocator>::size_type 3542basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, 3543 size_type __pos) const _NOEXCEPT 3544{ 3545 _LIBCPP_ASSERT(__s != nullptr, "string::find(): received nullptr"); 3546 return __str_find<value_type, size_type, traits_type, npos> 3547 (data(), size(), __s, __pos, traits_type::length(__s)); 3548} 3549 3550template<class _CharT, class _Traits, class _Allocator> 3551typename basic_string<_CharT, _Traits, _Allocator>::size_type 3552basic_string<_CharT, _Traits, _Allocator>::find(value_type __c, 3553 size_type __pos) const _NOEXCEPT 3554{ 3555 return __str_find<value_type, size_type, traits_type, npos> 3556 (data(), size(), __c, __pos); 3557} 3558 3559// rfind 3560 3561template<class _CharT, class _Traits, class _Allocator> 3562typename basic_string<_CharT, _Traits, _Allocator>::size_type 3563basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, 3564 size_type __pos, 3565 size_type __n) const _NOEXCEPT 3566{ 3567 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::rfind(): received nullptr"); 3568 return __str_rfind<value_type, size_type, traits_type, npos> 3569 (data(), size(), __s, __pos, __n); 3570} 3571 3572template<class _CharT, class _Traits, class _Allocator> 3573inline 3574typename basic_string<_CharT, _Traits, _Allocator>::size_type 3575basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str, 3576 size_type __pos) const _NOEXCEPT 3577{ 3578 return __str_rfind<value_type, size_type, traits_type, npos> 3579 (data(), size(), __str.data(), __pos, __str.size()); 3580} 3581 3582template<class _CharT, class _Traits, class _Allocator> 3583template <class _Tp> 3584__enable_if_t 3585< 3586 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 3587 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3588> 3589basic_string<_CharT, _Traits, _Allocator>::rfind(const _Tp& __t, 3590 size_type __pos) const _NOEXCEPT 3591{ 3592 __self_view __sv = __t; 3593 return __str_rfind<value_type, size_type, traits_type, npos> 3594 (data(), size(), __sv.data(), __pos, __sv.size()); 3595} 3596 3597template<class _CharT, class _Traits, class _Allocator> 3598inline 3599typename basic_string<_CharT, _Traits, _Allocator>::size_type 3600basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, 3601 size_type __pos) const _NOEXCEPT 3602{ 3603 _LIBCPP_ASSERT(__s != nullptr, "string::rfind(): received nullptr"); 3604 return __str_rfind<value_type, size_type, traits_type, npos> 3605 (data(), size(), __s, __pos, traits_type::length(__s)); 3606} 3607 3608template<class _CharT, class _Traits, class _Allocator> 3609typename basic_string<_CharT, _Traits, _Allocator>::size_type 3610basic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c, 3611 size_type __pos) const _NOEXCEPT 3612{ 3613 return __str_rfind<value_type, size_type, traits_type, npos> 3614 (data(), size(), __c, __pos); 3615} 3616 3617// find_first_of 3618 3619template<class _CharT, class _Traits, class _Allocator> 3620typename basic_string<_CharT, _Traits, _Allocator>::size_type 3621basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, 3622 size_type __pos, 3623 size_type __n) const _NOEXCEPT 3624{ 3625 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr"); 3626 return __str_find_first_of<value_type, size_type, traits_type, npos> 3627 (data(), size(), __s, __pos, __n); 3628} 3629 3630template<class _CharT, class _Traits, class _Allocator> 3631inline 3632typename basic_string<_CharT, _Traits, _Allocator>::size_type 3633basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str, 3634 size_type __pos) const _NOEXCEPT 3635{ 3636 return __str_find_first_of<value_type, size_type, traits_type, npos> 3637 (data(), size(), __str.data(), __pos, __str.size()); 3638} 3639 3640template<class _CharT, class _Traits, class _Allocator> 3641template <class _Tp> 3642__enable_if_t 3643< 3644 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 3645 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3646> 3647basic_string<_CharT, _Traits, _Allocator>::find_first_of(const _Tp& __t, 3648 size_type __pos) const _NOEXCEPT 3649{ 3650 __self_view __sv = __t; 3651 return __str_find_first_of<value_type, size_type, traits_type, npos> 3652 (data(), size(), __sv.data(), __pos, __sv.size()); 3653} 3654 3655template<class _CharT, class _Traits, class _Allocator> 3656inline 3657typename basic_string<_CharT, _Traits, _Allocator>::size_type 3658basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, 3659 size_type __pos) const _NOEXCEPT 3660{ 3661 _LIBCPP_ASSERT(__s != nullptr, "string::find_first_of(): received nullptr"); 3662 return __str_find_first_of<value_type, size_type, traits_type, npos> 3663 (data(), size(), __s, __pos, traits_type::length(__s)); 3664} 3665 3666template<class _CharT, class _Traits, class _Allocator> 3667inline 3668typename basic_string<_CharT, _Traits, _Allocator>::size_type 3669basic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c, 3670 size_type __pos) const _NOEXCEPT 3671{ 3672 return find(__c, __pos); 3673} 3674 3675// find_last_of 3676 3677template<class _CharT, class _Traits, class _Allocator> 3678typename basic_string<_CharT, _Traits, _Allocator>::size_type 3679basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, 3680 size_type __pos, 3681 size_type __n) const _NOEXCEPT 3682{ 3683 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr"); 3684 return __str_find_last_of<value_type, size_type, traits_type, npos> 3685 (data(), size(), __s, __pos, __n); 3686} 3687 3688template<class _CharT, class _Traits, class _Allocator> 3689inline 3690typename basic_string<_CharT, _Traits, _Allocator>::size_type 3691basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str, 3692 size_type __pos) const _NOEXCEPT 3693{ 3694 return __str_find_last_of<value_type, size_type, traits_type, npos> 3695 (data(), size(), __str.data(), __pos, __str.size()); 3696} 3697 3698template<class _CharT, class _Traits, class _Allocator> 3699template <class _Tp> 3700__enable_if_t 3701< 3702 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 3703 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3704> 3705basic_string<_CharT, _Traits, _Allocator>::find_last_of(const _Tp& __t, 3706 size_type __pos) const _NOEXCEPT 3707{ 3708 __self_view __sv = __t; 3709 return __str_find_last_of<value_type, size_type, traits_type, npos> 3710 (data(), size(), __sv.data(), __pos, __sv.size()); 3711} 3712 3713template<class _CharT, class _Traits, class _Allocator> 3714inline 3715typename basic_string<_CharT, _Traits, _Allocator>::size_type 3716basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, 3717 size_type __pos) const _NOEXCEPT 3718{ 3719 _LIBCPP_ASSERT(__s != nullptr, "string::find_last_of(): received nullptr"); 3720 return __str_find_last_of<value_type, size_type, traits_type, npos> 3721 (data(), size(), __s, __pos, traits_type::length(__s)); 3722} 3723 3724template<class _CharT, class _Traits, class _Allocator> 3725inline 3726typename basic_string<_CharT, _Traits, _Allocator>::size_type 3727basic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c, 3728 size_type __pos) const _NOEXCEPT 3729{ 3730 return rfind(__c, __pos); 3731} 3732 3733// find_first_not_of 3734 3735template<class _CharT, class _Traits, class _Allocator> 3736typename basic_string<_CharT, _Traits, _Allocator>::size_type 3737basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s, 3738 size_type __pos, 3739 size_type __n) const _NOEXCEPT 3740{ 3741 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr"); 3742 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 3743 (data(), size(), __s, __pos, __n); 3744} 3745 3746template<class _CharT, class _Traits, class _Allocator> 3747inline 3748typename basic_string<_CharT, _Traits, _Allocator>::size_type 3749basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string& __str, 3750 size_type __pos) const _NOEXCEPT 3751{ 3752 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 3753 (data(), size(), __str.data(), __pos, __str.size()); 3754} 3755 3756template<class _CharT, class _Traits, class _Allocator> 3757template <class _Tp> 3758__enable_if_t 3759< 3760 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 3761 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3762> 3763basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const _Tp& __t, 3764 size_type __pos) const _NOEXCEPT 3765{ 3766 __self_view __sv = __t; 3767 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 3768 (data(), size(), __sv.data(), __pos, __sv.size()); 3769} 3770 3771template<class _CharT, class _Traits, class _Allocator> 3772inline 3773typename basic_string<_CharT, _Traits, _Allocator>::size_type 3774basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s, 3775 size_type __pos) const _NOEXCEPT 3776{ 3777 _LIBCPP_ASSERT(__s != nullptr, "string::find_first_not_of(): received nullptr"); 3778 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 3779 (data(), size(), __s, __pos, traits_type::length(__s)); 3780} 3781 3782template<class _CharT, class _Traits, class _Allocator> 3783inline 3784typename basic_string<_CharT, _Traits, _Allocator>::size_type 3785basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c, 3786 size_type __pos) const _NOEXCEPT 3787{ 3788 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 3789 (data(), size(), __c, __pos); 3790} 3791 3792// find_last_not_of 3793 3794template<class _CharT, class _Traits, class _Allocator> 3795typename basic_string<_CharT, _Traits, _Allocator>::size_type 3796basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s, 3797 size_type __pos, 3798 size_type __n) const _NOEXCEPT 3799{ 3800 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr"); 3801 return __str_find_last_not_of<value_type, size_type, traits_type, npos> 3802 (data(), size(), __s, __pos, __n); 3803} 3804 3805template<class _CharT, class _Traits, class _Allocator> 3806inline 3807typename basic_string<_CharT, _Traits, _Allocator>::size_type 3808basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string& __str, 3809 size_type __pos) const _NOEXCEPT 3810{ 3811 return __str_find_last_not_of<value_type, size_type, traits_type, npos> 3812 (data(), size(), __str.data(), __pos, __str.size()); 3813} 3814 3815template<class _CharT, class _Traits, class _Allocator> 3816template <class _Tp> 3817__enable_if_t 3818< 3819 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 3820 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3821> 3822basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const _Tp& __t, 3823 size_type __pos) const _NOEXCEPT 3824{ 3825 __self_view __sv = __t; 3826 return __str_find_last_not_of<value_type, size_type, traits_type, npos> 3827 (data(), size(), __sv.data(), __pos, __sv.size()); 3828} 3829 3830template<class _CharT, class _Traits, class _Allocator> 3831inline 3832typename basic_string<_CharT, _Traits, _Allocator>::size_type 3833basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s, 3834 size_type __pos) const _NOEXCEPT 3835{ 3836 _LIBCPP_ASSERT(__s != nullptr, "string::find_last_not_of(): received nullptr"); 3837 return __str_find_last_not_of<value_type, size_type, traits_type, npos> 3838 (data(), size(), __s, __pos, traits_type::length(__s)); 3839} 3840 3841template<class _CharT, class _Traits, class _Allocator> 3842inline 3843typename basic_string<_CharT, _Traits, _Allocator>::size_type 3844basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c, 3845 size_type __pos) const _NOEXCEPT 3846{ 3847 return __str_find_last_not_of<value_type, size_type, traits_type, npos> 3848 (data(), size(), __c, __pos); 3849} 3850 3851// compare 3852 3853template <class _CharT, class _Traits, class _Allocator> 3854template <class _Tp> 3855__enable_if_t 3856< 3857 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 3858 int 3859> 3860basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const _NOEXCEPT 3861{ 3862 __self_view __sv = __t; 3863 size_t __lhs_sz = size(); 3864 size_t __rhs_sz = __sv.size(); 3865 int __result = traits_type::compare(data(), __sv.data(), 3866 _VSTD::min(__lhs_sz, __rhs_sz)); 3867 if (__result != 0) 3868 return __result; 3869 if (__lhs_sz < __rhs_sz) 3870 return -1; 3871 if (__lhs_sz > __rhs_sz) 3872 return 1; 3873 return 0; 3874} 3875 3876template <class _CharT, class _Traits, class _Allocator> 3877inline 3878int 3879basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT 3880{ 3881 return compare(__self_view(__str)); 3882} 3883 3884template <class _CharT, class _Traits, class _Allocator> 3885int 3886basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, 3887 size_type __n1, 3888 const value_type* __s, 3889 size_type __n2) const 3890{ 3891 _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr"); 3892 size_type __sz = size(); 3893 if (__pos1 > __sz || __n2 == npos) 3894 this->__throw_out_of_range(); 3895 size_type __rlen = _VSTD::min(__n1, __sz - __pos1); 3896 int __r = traits_type::compare(data() + __pos1, __s, _VSTD::min(__rlen, __n2)); 3897 if (__r == 0) 3898 { 3899 if (__rlen < __n2) 3900 __r = -1; 3901 else if (__rlen > __n2) 3902 __r = 1; 3903 } 3904 return __r; 3905} 3906 3907template <class _CharT, class _Traits, class _Allocator> 3908template <class _Tp> 3909__enable_if_t 3910< 3911 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 3912 int 3913> 3914basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, 3915 size_type __n1, 3916 const _Tp& __t) const 3917{ 3918 __self_view __sv = __t; 3919 return compare(__pos1, __n1, __sv.data(), __sv.size()); 3920} 3921 3922template <class _CharT, class _Traits, class _Allocator> 3923inline 3924int 3925basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, 3926 size_type __n1, 3927 const basic_string& __str) const 3928{ 3929 return compare(__pos1, __n1, __str.data(), __str.size()); 3930} 3931 3932template <class _CharT, class _Traits, class _Allocator> 3933template <class _Tp> 3934__enable_if_t 3935< 3936 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value 3937 && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 3938 int 3939> 3940basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, 3941 size_type __n1, 3942 const _Tp& __t, 3943 size_type __pos2, 3944 size_type __n2) const 3945{ 3946 __self_view __sv = __t; 3947 return __self_view(*this).substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2)); 3948} 3949 3950template <class _CharT, class _Traits, class _Allocator> 3951int 3952basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, 3953 size_type __n1, 3954 const basic_string& __str, 3955 size_type __pos2, 3956 size_type __n2) const 3957{ 3958 return compare(__pos1, __n1, __self_view(__str), __pos2, __n2); 3959} 3960 3961template <class _CharT, class _Traits, class _Allocator> 3962int 3963basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT 3964{ 3965 _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr"); 3966 return compare(0, npos, __s, traits_type::length(__s)); 3967} 3968 3969template <class _CharT, class _Traits, class _Allocator> 3970int 3971basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, 3972 size_type __n1, 3973 const value_type* __s) const 3974{ 3975 _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr"); 3976 return compare(__pos1, __n1, __s, traits_type::length(__s)); 3977} 3978 3979// __invariants 3980 3981template<class _CharT, class _Traits, class _Allocator> 3982inline 3983bool 3984basic_string<_CharT, _Traits, _Allocator>::__invariants() const 3985{ 3986 if (size() > capacity()) 3987 return false; 3988 if (capacity() < __min_cap - 1) 3989 return false; 3990 if (data() == nullptr) 3991 return false; 3992 if (data()[size()] != value_type()) 3993 return false; 3994 return true; 3995} 3996 3997// __clear_and_shrink 3998 3999template<class _CharT, class _Traits, class _Allocator> 4000inline 4001void 4002basic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT 4003{ 4004 clear(); 4005 if(__is_long()) 4006 { 4007 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), capacity() + 1); 4008 __set_long_cap(0); 4009 __set_short_size(0); 4010 traits_type::assign(*__get_short_pointer(), value_type()); 4011 } 4012} 4013 4014// operator== 4015 4016template<class _CharT, class _Traits, class _Allocator> 4017inline _LIBCPP_INLINE_VISIBILITY 4018bool 4019operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4020 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4021{ 4022 size_t __lhs_sz = __lhs.size(); 4023 return __lhs_sz == __rhs.size() && _Traits::compare(__lhs.data(), 4024 __rhs.data(), 4025 __lhs_sz) == 0; 4026} 4027 4028template<class _Allocator> 4029inline _LIBCPP_INLINE_VISIBILITY 4030bool 4031operator==(const basic_string<char, char_traits<char>, _Allocator>& __lhs, 4032 const basic_string<char, char_traits<char>, _Allocator>& __rhs) _NOEXCEPT 4033{ 4034 size_t __lhs_sz = __lhs.size(); 4035 if (__lhs_sz != __rhs.size()) 4036 return false; 4037 const char* __lp = __lhs.data(); 4038 const char* __rp = __rhs.data(); 4039 if (__lhs.__is_long()) 4040 return char_traits<char>::compare(__lp, __rp, __lhs_sz) == 0; 4041 for (; __lhs_sz != 0; --__lhs_sz, ++__lp, ++__rp) 4042 if (*__lp != *__rp) 4043 return false; 4044 return true; 4045} 4046 4047template<class _CharT, class _Traits, class _Allocator> 4048inline _LIBCPP_INLINE_VISIBILITY 4049bool 4050operator==(const _CharT* __lhs, 4051 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4052{ 4053 typedef basic_string<_CharT, _Traits, _Allocator> _String; 4054 _LIBCPP_ASSERT(__lhs != nullptr, "operator==(char*, basic_string): received nullptr"); 4055 size_t __lhs_len = _Traits::length(__lhs); 4056 if (__lhs_len != __rhs.size()) return false; 4057 return __rhs.compare(0, _String::npos, __lhs, __lhs_len) == 0; 4058} 4059 4060template<class _CharT, class _Traits, class _Allocator> 4061inline _LIBCPP_INLINE_VISIBILITY 4062bool 4063operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 4064 const _CharT* __rhs) _NOEXCEPT 4065{ 4066 typedef basic_string<_CharT, _Traits, _Allocator> _String; 4067 _LIBCPP_ASSERT(__rhs != nullptr, "operator==(basic_string, char*): received nullptr"); 4068 size_t __rhs_len = _Traits::length(__rhs); 4069 if (__rhs_len != __lhs.size()) return false; 4070 return __lhs.compare(0, _String::npos, __rhs, __rhs_len) == 0; 4071} 4072 4073template<class _CharT, class _Traits, class _Allocator> 4074inline _LIBCPP_INLINE_VISIBILITY 4075bool 4076operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 4077 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4078{ 4079 return !(__lhs == __rhs); 4080} 4081 4082template<class _CharT, class _Traits, class _Allocator> 4083inline _LIBCPP_INLINE_VISIBILITY 4084bool 4085operator!=(const _CharT* __lhs, 4086 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4087{ 4088 return !(__lhs == __rhs); 4089} 4090 4091template<class _CharT, class _Traits, class _Allocator> 4092inline _LIBCPP_INLINE_VISIBILITY 4093bool 4094operator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4095 const _CharT* __rhs) _NOEXCEPT 4096{ 4097 return !(__lhs == __rhs); 4098} 4099 4100// operator< 4101 4102template<class _CharT, class _Traits, class _Allocator> 4103inline _LIBCPP_INLINE_VISIBILITY 4104bool 4105operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4106 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4107{ 4108 return __lhs.compare(__rhs) < 0; 4109} 4110 4111template<class _CharT, class _Traits, class _Allocator> 4112inline _LIBCPP_INLINE_VISIBILITY 4113bool 4114operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4115 const _CharT* __rhs) _NOEXCEPT 4116{ 4117 return __lhs.compare(__rhs) < 0; 4118} 4119 4120template<class _CharT, class _Traits, class _Allocator> 4121inline _LIBCPP_INLINE_VISIBILITY 4122bool 4123operator< (const _CharT* __lhs, 4124 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4125{ 4126 return __rhs.compare(__lhs) > 0; 4127} 4128 4129// operator> 4130 4131template<class _CharT, class _Traits, class _Allocator> 4132inline _LIBCPP_INLINE_VISIBILITY 4133bool 4134operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4135 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4136{ 4137 return __rhs < __lhs; 4138} 4139 4140template<class _CharT, class _Traits, class _Allocator> 4141inline _LIBCPP_INLINE_VISIBILITY 4142bool 4143operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4144 const _CharT* __rhs) _NOEXCEPT 4145{ 4146 return __rhs < __lhs; 4147} 4148 4149template<class _CharT, class _Traits, class _Allocator> 4150inline _LIBCPP_INLINE_VISIBILITY 4151bool 4152operator> (const _CharT* __lhs, 4153 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4154{ 4155 return __rhs < __lhs; 4156} 4157 4158// operator<= 4159 4160template<class _CharT, class _Traits, class _Allocator> 4161inline _LIBCPP_INLINE_VISIBILITY 4162bool 4163operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4164 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4165{ 4166 return !(__rhs < __lhs); 4167} 4168 4169template<class _CharT, class _Traits, class _Allocator> 4170inline _LIBCPP_INLINE_VISIBILITY 4171bool 4172operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4173 const _CharT* __rhs) _NOEXCEPT 4174{ 4175 return !(__rhs < __lhs); 4176} 4177 4178template<class _CharT, class _Traits, class _Allocator> 4179inline _LIBCPP_INLINE_VISIBILITY 4180bool 4181operator<=(const _CharT* __lhs, 4182 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4183{ 4184 return !(__rhs < __lhs); 4185} 4186 4187// operator>= 4188 4189template<class _CharT, class _Traits, class _Allocator> 4190inline _LIBCPP_INLINE_VISIBILITY 4191bool 4192operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4193 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4194{ 4195 return !(__lhs < __rhs); 4196} 4197 4198template<class _CharT, class _Traits, class _Allocator> 4199inline _LIBCPP_INLINE_VISIBILITY 4200bool 4201operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4202 const _CharT* __rhs) _NOEXCEPT 4203{ 4204 return !(__lhs < __rhs); 4205} 4206 4207template<class _CharT, class _Traits, class _Allocator> 4208inline _LIBCPP_INLINE_VISIBILITY 4209bool 4210operator>=(const _CharT* __lhs, 4211 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4212{ 4213 return !(__lhs < __rhs); 4214} 4215 4216// operator + 4217 4218template<class _CharT, class _Traits, class _Allocator> 4219basic_string<_CharT, _Traits, _Allocator> 4220operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4221 const basic_string<_CharT, _Traits, _Allocator>& __rhs) 4222{ 4223 basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator()); 4224 typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size(); 4225 typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size(); 4226 __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + __rhs_sz); 4227 __r.append(__rhs.data(), __rhs_sz); 4228 return __r; 4229} 4230 4231template<class _CharT, class _Traits, class _Allocator> 4232basic_string<_CharT, _Traits, _Allocator> 4233operator+(const _CharT* __lhs , const basic_string<_CharT,_Traits,_Allocator>& __rhs) 4234{ 4235 basic_string<_CharT, _Traits, _Allocator> __r(__rhs.get_allocator()); 4236 typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = _Traits::length(__lhs); 4237 typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size(); 4238 __r.__init(__lhs, __lhs_sz, __lhs_sz + __rhs_sz); 4239 __r.append(__rhs.data(), __rhs_sz); 4240 return __r; 4241} 4242 4243template<class _CharT, class _Traits, class _Allocator> 4244basic_string<_CharT, _Traits, _Allocator> 4245operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Allocator>& __rhs) 4246{ 4247 basic_string<_CharT, _Traits, _Allocator> __r(__rhs.get_allocator()); 4248 typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size(); 4249 __r.__init(&__lhs, 1, 1 + __rhs_sz); 4250 __r.append(__rhs.data(), __rhs_sz); 4251 return __r; 4252} 4253 4254template<class _CharT, class _Traits, class _Allocator> 4255inline 4256basic_string<_CharT, _Traits, _Allocator> 4257operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) 4258{ 4259 basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator()); 4260 typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size(); 4261 typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = _Traits::length(__rhs); 4262 __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + __rhs_sz); 4263 __r.append(__rhs, __rhs_sz); 4264 return __r; 4265} 4266 4267template<class _CharT, class _Traits, class _Allocator> 4268basic_string<_CharT, _Traits, _Allocator> 4269operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs) 4270{ 4271 basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator()); 4272 typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size(); 4273 __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + 1); 4274 __r.push_back(__rhs); 4275 return __r; 4276} 4277 4278#ifndef _LIBCPP_CXX03_LANG 4279 4280template<class _CharT, class _Traits, class _Allocator> 4281inline _LIBCPP_INLINE_VISIBILITY 4282basic_string<_CharT, _Traits, _Allocator> 4283operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) 4284{ 4285 return _VSTD::move(__lhs.append(__rhs)); 4286} 4287 4288template<class _CharT, class _Traits, class _Allocator> 4289inline _LIBCPP_INLINE_VISIBILITY 4290basic_string<_CharT, _Traits, _Allocator> 4291operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs) 4292{ 4293 return _VSTD::move(__rhs.insert(0, __lhs)); 4294} 4295 4296template<class _CharT, class _Traits, class _Allocator> 4297inline _LIBCPP_INLINE_VISIBILITY 4298basic_string<_CharT, _Traits, _Allocator> 4299operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs) 4300{ 4301 return _VSTD::move(__lhs.append(__rhs)); 4302} 4303 4304template<class _CharT, class _Traits, class _Allocator> 4305inline _LIBCPP_INLINE_VISIBILITY 4306basic_string<_CharT, _Traits, _Allocator> 4307operator+(const _CharT* __lhs , basic_string<_CharT,_Traits,_Allocator>&& __rhs) 4308{ 4309 return _VSTD::move(__rhs.insert(0, __lhs)); 4310} 4311 4312template<class _CharT, class _Traits, class _Allocator> 4313inline _LIBCPP_INLINE_VISIBILITY 4314basic_string<_CharT, _Traits, _Allocator> 4315operator+(_CharT __lhs, basic_string<_CharT,_Traits,_Allocator>&& __rhs) 4316{ 4317 __rhs.insert(__rhs.begin(), __lhs); 4318 return _VSTD::move(__rhs); 4319} 4320 4321template<class _CharT, class _Traits, class _Allocator> 4322inline _LIBCPP_INLINE_VISIBILITY 4323basic_string<_CharT, _Traits, _Allocator> 4324operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const _CharT* __rhs) 4325{ 4326 return _VSTD::move(__lhs.append(__rhs)); 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, _CharT __rhs) 4333{ 4334 __lhs.push_back(__rhs); 4335 return _VSTD::move(__lhs); 4336} 4337 4338#endif // _LIBCPP_CXX03_LANG 4339 4340// swap 4341 4342template<class _CharT, class _Traits, class _Allocator> 4343inline _LIBCPP_INLINE_VISIBILITY 4344void 4345swap(basic_string<_CharT, _Traits, _Allocator>& __lhs, 4346 basic_string<_CharT, _Traits, _Allocator>& __rhs) 4347 _NOEXCEPT_(_NOEXCEPT_(__lhs.swap(__rhs))) 4348{ 4349 __lhs.swap(__rhs); 4350} 4351 4352_LIBCPP_FUNC_VIS int stoi (const string& __str, size_t* __idx = nullptr, int __base = 10); 4353_LIBCPP_FUNC_VIS long stol (const string& __str, size_t* __idx = nullptr, int __base = 10); 4354_LIBCPP_FUNC_VIS unsigned long stoul (const string& __str, size_t* __idx = nullptr, int __base = 10); 4355_LIBCPP_FUNC_VIS long long stoll (const string& __str, size_t* __idx = nullptr, int __base = 10); 4356_LIBCPP_FUNC_VIS unsigned long long stoull(const string& __str, size_t* __idx = nullptr, int __base = 10); 4357 4358_LIBCPP_FUNC_VIS float stof (const string& __str, size_t* __idx = nullptr); 4359_LIBCPP_FUNC_VIS double stod (const string& __str, size_t* __idx = nullptr); 4360_LIBCPP_FUNC_VIS long double stold(const string& __str, size_t* __idx = nullptr); 4361 4362_LIBCPP_FUNC_VIS string to_string(int __val); 4363_LIBCPP_FUNC_VIS string to_string(unsigned __val); 4364_LIBCPP_FUNC_VIS string to_string(long __val); 4365_LIBCPP_FUNC_VIS string to_string(unsigned long __val); 4366_LIBCPP_FUNC_VIS string to_string(long long __val); 4367_LIBCPP_FUNC_VIS string to_string(unsigned long long __val); 4368_LIBCPP_FUNC_VIS string to_string(float __val); 4369_LIBCPP_FUNC_VIS string to_string(double __val); 4370_LIBCPP_FUNC_VIS string to_string(long double __val); 4371 4372#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 4373_LIBCPP_FUNC_VIS int stoi (const wstring& __str, size_t* __idx = nullptr, int __base = 10); 4374_LIBCPP_FUNC_VIS long stol (const wstring& __str, size_t* __idx = nullptr, int __base = 10); 4375_LIBCPP_FUNC_VIS unsigned long stoul (const wstring& __str, size_t* __idx = nullptr, int __base = 10); 4376_LIBCPP_FUNC_VIS long long stoll (const wstring& __str, size_t* __idx = nullptr, int __base = 10); 4377_LIBCPP_FUNC_VIS unsigned long long stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10); 4378 4379_LIBCPP_FUNC_VIS float stof (const wstring& __str, size_t* __idx = nullptr); 4380_LIBCPP_FUNC_VIS double stod (const wstring& __str, size_t* __idx = nullptr); 4381_LIBCPP_FUNC_VIS long double stold(const wstring& __str, size_t* __idx = nullptr); 4382 4383_LIBCPP_FUNC_VIS wstring to_wstring(int __val); 4384_LIBCPP_FUNC_VIS wstring to_wstring(unsigned __val); 4385_LIBCPP_FUNC_VIS wstring to_wstring(long __val); 4386_LIBCPP_FUNC_VIS wstring to_wstring(unsigned long __val); 4387_LIBCPP_FUNC_VIS wstring to_wstring(long long __val); 4388_LIBCPP_FUNC_VIS wstring to_wstring(unsigned long long __val); 4389_LIBCPP_FUNC_VIS wstring to_wstring(float __val); 4390_LIBCPP_FUNC_VIS wstring to_wstring(double __val); 4391_LIBCPP_FUNC_VIS wstring to_wstring(long double __val); 4392#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS 4393 4394template<class _CharT, class _Traits, class _Allocator> 4395_LIBCPP_TEMPLATE_DATA_VIS 4396const typename basic_string<_CharT, _Traits, _Allocator>::size_type 4397 basic_string<_CharT, _Traits, _Allocator>::npos; 4398 4399template <class _CharT, class _Allocator> 4400struct _LIBCPP_TEMPLATE_VIS 4401 hash<basic_string<_CharT, char_traits<_CharT>, _Allocator> > 4402 : public unary_function< 4403 basic_string<_CharT, char_traits<_CharT>, _Allocator>, size_t> 4404{ 4405 size_t 4406 operator()(const basic_string<_CharT, char_traits<_CharT>, _Allocator>& __val) const _NOEXCEPT 4407 { return __do_string_hash(__val.data(), __val.data() + __val.size()); } 4408}; 4409 4410 4411template<class _CharT, class _Traits, class _Allocator> 4412basic_ostream<_CharT, _Traits>& 4413operator<<(basic_ostream<_CharT, _Traits>& __os, 4414 const basic_string<_CharT, _Traits, _Allocator>& __str); 4415 4416template<class _CharT, class _Traits, class _Allocator> 4417basic_istream<_CharT, _Traits>& 4418operator>>(basic_istream<_CharT, _Traits>& __is, 4419 basic_string<_CharT, _Traits, _Allocator>& __str); 4420 4421template<class _CharT, class _Traits, class _Allocator> 4422basic_istream<_CharT, _Traits>& 4423getline(basic_istream<_CharT, _Traits>& __is, 4424 basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm); 4425 4426template<class _CharT, class _Traits, class _Allocator> 4427inline _LIBCPP_INLINE_VISIBILITY 4428basic_istream<_CharT, _Traits>& 4429getline(basic_istream<_CharT, _Traits>& __is, 4430 basic_string<_CharT, _Traits, _Allocator>& __str); 4431 4432template<class _CharT, class _Traits, class _Allocator> 4433inline _LIBCPP_INLINE_VISIBILITY 4434basic_istream<_CharT, _Traits>& 4435getline(basic_istream<_CharT, _Traits>&& __is, 4436 basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm); 4437 4438template<class _CharT, class _Traits, class _Allocator> 4439inline _LIBCPP_INLINE_VISIBILITY 4440basic_istream<_CharT, _Traits>& 4441getline(basic_istream<_CharT, _Traits>&& __is, 4442 basic_string<_CharT, _Traits, _Allocator>& __str); 4443 4444#if _LIBCPP_STD_VER > 17 4445template <class _CharT, class _Traits, class _Allocator, class _Up> 4446inline _LIBCPP_INLINE_VISIBILITY 4447 typename basic_string<_CharT, _Traits, _Allocator>::size_type 4448 erase(basic_string<_CharT, _Traits, _Allocator>& __str, const _Up& __v) { 4449 auto __old_size = __str.size(); 4450 __str.erase(_VSTD::remove(__str.begin(), __str.end(), __v), __str.end()); 4451 return __old_size - __str.size(); 4452} 4453 4454template <class _CharT, class _Traits, class _Allocator, class _Predicate> 4455inline _LIBCPP_INLINE_VISIBILITY 4456 typename basic_string<_CharT, _Traits, _Allocator>::size_type 4457 erase_if(basic_string<_CharT, _Traits, _Allocator>& __str, 4458 _Predicate __pred) { 4459 auto __old_size = __str.size(); 4460 __str.erase(_VSTD::remove_if(__str.begin(), __str.end(), __pred), 4461 __str.end()); 4462 return __old_size - __str.size(); 4463} 4464#endif 4465 4466#if _LIBCPP_DEBUG_LEVEL == 2 4467 4468template<class _CharT, class _Traits, class _Allocator> 4469bool 4470basic_string<_CharT, _Traits, _Allocator>::__dereferenceable(const const_iterator* __i) const 4471{ 4472 return this->data() <= _VSTD::__to_address(__i->base()) && 4473 _VSTD::__to_address(__i->base()) < this->data() + this->size(); 4474} 4475 4476template<class _CharT, class _Traits, class _Allocator> 4477bool 4478basic_string<_CharT, _Traits, _Allocator>::__decrementable(const const_iterator* __i) const 4479{ 4480 return this->data() < _VSTD::__to_address(__i->base()) && 4481 _VSTD::__to_address(__i->base()) <= this->data() + this->size(); 4482} 4483 4484template<class _CharT, class _Traits, class _Allocator> 4485bool 4486basic_string<_CharT, _Traits, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const 4487{ 4488 const value_type* __p = _VSTD::__to_address(__i->base()) + __n; 4489 return this->data() <= __p && __p <= this->data() + this->size(); 4490} 4491 4492template<class _CharT, class _Traits, class _Allocator> 4493bool 4494basic_string<_CharT, _Traits, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const 4495{ 4496 const value_type* __p = _VSTD::__to_address(__i->base()) + __n; 4497 return this->data() <= __p && __p < this->data() + this->size(); 4498} 4499 4500#endif // _LIBCPP_DEBUG_LEVEL == 2 4501 4502#if _LIBCPP_STD_VER > 11 4503// Literal suffixes for basic_string [basic.string.literals] 4504inline namespace literals 4505{ 4506 inline namespace string_literals 4507 { 4508 inline _LIBCPP_INLINE_VISIBILITY 4509 basic_string<char> operator "" s( const char *__str, size_t __len ) 4510 { 4511 return basic_string<char> (__str, __len); 4512 } 4513 4514#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 4515 inline _LIBCPP_INLINE_VISIBILITY 4516 basic_string<wchar_t> operator "" s( const wchar_t *__str, size_t __len ) 4517 { 4518 return basic_string<wchar_t> (__str, __len); 4519 } 4520#endif 4521 4522#ifndef _LIBCPP_HAS_NO_CHAR8_T 4523 inline _LIBCPP_INLINE_VISIBILITY 4524 basic_string<char8_t> operator "" s(const char8_t *__str, size_t __len) _NOEXCEPT 4525 { 4526 return basic_string<char8_t> (__str, __len); 4527 } 4528#endif 4529 4530 inline _LIBCPP_INLINE_VISIBILITY 4531 basic_string<char16_t> operator "" s( const char16_t *__str, size_t __len ) 4532 { 4533 return basic_string<char16_t> (__str, __len); 4534 } 4535 4536 inline _LIBCPP_INLINE_VISIBILITY 4537 basic_string<char32_t> operator "" s( const char32_t *__str, size_t __len ) 4538 { 4539 return basic_string<char32_t> (__str, __len); 4540 } 4541 } // namespace string_literals 4542} // namespace literals 4543#endif 4544 4545_LIBCPP_END_NAMESPACE_STD 4546 4547_LIBCPP_POP_MACROS 4548 4549#endif // _LIBCPP_STRING 4550