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