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