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