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