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