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