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