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