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