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