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