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