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 _LIBCPP_INLINE_VISIBILITY 1578 void __copy_assign_alloc(const basic_string& __str) 1579 {__copy_assign_alloc(__str, integral_constant<bool, 1580 __alloc_traits::propagate_on_container_copy_assignment::value>());} 1581 1582 _LIBCPP_INLINE_VISIBILITY 1583 void __copy_assign_alloc(const basic_string& __str, true_type) 1584 { 1585 if (__alloc() == __str.__alloc()) 1586 __alloc() = __str.__alloc(); 1587 else 1588 { 1589 if (!__str.__is_long()) 1590 { 1591 __clear_and_shrink(); 1592 __alloc() = __str.__alloc(); 1593 } 1594 else 1595 { 1596 allocator_type __a = __str.__alloc(); 1597 pointer __p = __alloc_traits::allocate(__a, __str.__get_long_cap()); 1598 __clear_and_shrink(); 1599 __alloc() = _VSTD::move(__a); 1600 __set_long_pointer(__p); 1601 __set_long_cap(__str.__get_long_cap()); 1602 __set_long_size(__str.size()); 1603 } 1604 } 1605 } 1606 1607 _LIBCPP_INLINE_VISIBILITY 1608 void __copy_assign_alloc(const basic_string&, false_type) _NOEXCEPT 1609 {} 1610 1611#ifndef _LIBCPP_CXX03_LANG 1612 _LIBCPP_INLINE_VISIBILITY 1613 void __move_assign(basic_string& __str, false_type) 1614 _NOEXCEPT_(__alloc_traits::is_always_equal::value); 1615 _LIBCPP_INLINE_VISIBILITY 1616 void __move_assign(basic_string& __str, true_type) 1617#if _LIBCPP_STD_VER > 14 1618 _NOEXCEPT; 1619#else 1620 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value); 1621#endif 1622#endif 1623 1624 _LIBCPP_INLINE_VISIBILITY 1625 void 1626 __move_assign_alloc(basic_string& __str) 1627 _NOEXCEPT_( 1628 !__alloc_traits::propagate_on_container_move_assignment::value || 1629 is_nothrow_move_assignable<allocator_type>::value) 1630 {__move_assign_alloc(__str, integral_constant<bool, 1631 __alloc_traits::propagate_on_container_move_assignment::value>());} 1632 1633 _LIBCPP_INLINE_VISIBILITY 1634 void __move_assign_alloc(basic_string& __c, true_type) 1635 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) 1636 { 1637 __alloc() = _VSTD::move(__c.__alloc()); 1638 } 1639 1640 _LIBCPP_INLINE_VISIBILITY 1641 void __move_assign_alloc(basic_string&, false_type) 1642 _NOEXCEPT 1643 {} 1644 1645 _LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators(); 1646 _LIBCPP_INLINE_VISIBILITY void __invalidate_iterators_past(size_type); 1647 1648 friend basic_string operator+<>(const basic_string&, const basic_string&); 1649 friend basic_string operator+<>(const value_type*, const basic_string&); 1650 friend basic_string operator+<>(value_type, const basic_string&); 1651 friend basic_string operator+<>(const basic_string&, const value_type*); 1652 friend basic_string operator+<>(const basic_string&, value_type); 1653}; 1654 1655#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES 1656template<class _InputIterator, 1657 class _CharT = typename iterator_traits<_InputIterator>::value_type, 1658 class _Allocator = allocator<_CharT>, 1659 class = _EnableIf<__is_cpp17_input_iterator<_InputIterator>::value>, 1660 class = _EnableIf<__is_allocator<_Allocator>::value> 1661 > 1662basic_string(_InputIterator, _InputIterator, _Allocator = _Allocator()) 1663 -> basic_string<_CharT, char_traits<_CharT>, _Allocator>; 1664 1665template<class _CharT, 1666 class _Traits, 1667 class _Allocator = allocator<_CharT>, 1668 class = _EnableIf<__is_allocator<_Allocator>::value> 1669 > 1670explicit basic_string(basic_string_view<_CharT, _Traits>, const _Allocator& = _Allocator()) 1671 -> basic_string<_CharT, _Traits, _Allocator>; 1672 1673template<class _CharT, 1674 class _Traits, 1675 class _Allocator = allocator<_CharT>, 1676 class = _EnableIf<__is_allocator<_Allocator>::value>, 1677 class _Sz = typename allocator_traits<_Allocator>::size_type 1678 > 1679basic_string(basic_string_view<_CharT, _Traits>, _Sz, _Sz, const _Allocator& = _Allocator()) 1680 -> basic_string<_CharT, _Traits, _Allocator>; 1681#endif 1682 1683template <class _CharT, class _Traits, class _Allocator> 1684inline 1685void 1686basic_string<_CharT, _Traits, _Allocator>::__invalidate_all_iterators() 1687{ 1688#if _LIBCPP_DEBUG_LEVEL >= 2 1689 __get_db()->__invalidate_all(this); 1690#endif // _LIBCPP_DEBUG_LEVEL >= 2 1691} 1692 1693template <class _CharT, class _Traits, class _Allocator> 1694inline 1695void 1696basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type 1697#if _LIBCPP_DEBUG_LEVEL >= 2 1698 __pos 1699#endif 1700 ) 1701{ 1702#if _LIBCPP_DEBUG_LEVEL >= 2 1703 __c_node* __c = __get_db()->__find_c_and_lock(this); 1704 if (__c) 1705 { 1706 const_pointer __new_last = __get_pointer() + __pos; 1707 for (__i_node** __p = __c->end_; __p != __c->beg_; ) 1708 { 1709 --__p; 1710 const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_); 1711 if (__i->base() > __new_last) 1712 { 1713 (*__p)->__c_ = nullptr; 1714 if (--__c->end_ != __p) 1715 memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); 1716 } 1717 } 1718 __get_db()->unlock(); 1719 } 1720#endif // _LIBCPP_DEBUG_LEVEL >= 2 1721} 1722 1723template <class _CharT, class _Traits, class _Allocator> 1724inline 1725basic_string<_CharT, _Traits, _Allocator>::basic_string() 1726 _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) 1727 : __r_(__default_init_tag(), __default_init_tag()) 1728{ 1729#if _LIBCPP_DEBUG_LEVEL >= 2 1730 __get_db()->__insert_c(this); 1731#endif 1732 __zero(); 1733} 1734 1735template <class _CharT, class _Traits, class _Allocator> 1736inline 1737basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __a) 1738#if _LIBCPP_STD_VER <= 14 1739 _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value) 1740#else 1741 _NOEXCEPT 1742#endif 1743: __r_(__default_init_tag(), __a) 1744{ 1745#if _LIBCPP_DEBUG_LEVEL >= 2 1746 __get_db()->__insert_c(this); 1747#endif 1748 __zero(); 1749} 1750 1751template <class _CharT, class _Traits, class _Allocator> 1752void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, 1753 size_type __sz, 1754 size_type __reserve) 1755{ 1756 if (__reserve > max_size()) 1757 this->__throw_length_error(); 1758 pointer __p; 1759 if (__reserve < __min_cap) 1760 { 1761 __set_short_size(__sz); 1762 __p = __get_short_pointer(); 1763 } 1764 else 1765 { 1766 size_type __cap = __recommend(__reserve); 1767 __p = __alloc_traits::allocate(__alloc(), __cap+1); 1768 __set_long_pointer(__p); 1769 __set_long_cap(__cap+1); 1770 __set_long_size(__sz); 1771 } 1772 traits_type::copy(_VSTD::__to_address(__p), __s, __sz); 1773 traits_type::assign(__p[__sz], value_type()); 1774} 1775 1776template <class _CharT, class _Traits, class _Allocator> 1777void 1778basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz) 1779{ 1780 if (__sz > max_size()) 1781 this->__throw_length_error(); 1782 pointer __p; 1783 if (__sz < __min_cap) 1784 { 1785 __set_short_size(__sz); 1786 __p = __get_short_pointer(); 1787 } 1788 else 1789 { 1790 size_type __cap = __recommend(__sz); 1791 __p = __alloc_traits::allocate(__alloc(), __cap+1); 1792 __set_long_pointer(__p); 1793 __set_long_cap(__cap+1); 1794 __set_long_size(__sz); 1795 } 1796 traits_type::copy(_VSTD::__to_address(__p), __s, __sz); 1797 traits_type::assign(__p[__sz], value_type()); 1798} 1799 1800template <class _CharT, class _Traits, class _Allocator> 1801template <class> 1802basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const _Allocator& __a) 1803 : __r_(__default_init_tag(), __a) 1804{ 1805 _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr"); 1806 __init(__s, traits_type::length(__s)); 1807#if _LIBCPP_DEBUG_LEVEL >= 2 1808 __get_db()->__insert_c(this); 1809#endif 1810} 1811 1812template <class _CharT, class _Traits, class _Allocator> 1813inline 1814basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n) 1815 : __r_(__default_init_tag(), __default_init_tag()) 1816{ 1817 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr"); 1818 __init(__s, __n); 1819#if _LIBCPP_DEBUG_LEVEL >= 2 1820 __get_db()->__insert_c(this); 1821#endif 1822} 1823 1824template <class _CharT, class _Traits, class _Allocator> 1825inline 1826basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n, const _Allocator& __a) 1827 : __r_(__default_init_tag(), __a) 1828{ 1829 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr"); 1830 __init(__s, __n); 1831#if _LIBCPP_DEBUG_LEVEL >= 2 1832 __get_db()->__insert_c(this); 1833#endif 1834} 1835 1836template <class _CharT, class _Traits, class _Allocator> 1837basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str) 1838 : __r_(__default_init_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc())) 1839{ 1840 if (!__str.__is_long()) 1841 __r_.first().__r = __str.__r_.first().__r; 1842 else 1843 __init(_VSTD::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); 1844#if _LIBCPP_DEBUG_LEVEL >= 2 1845 __get_db()->__insert_c(this); 1846#endif 1847} 1848 1849template <class _CharT, class _Traits, class _Allocator> 1850basic_string<_CharT, _Traits, _Allocator>::basic_string( 1851 const basic_string& __str, const allocator_type& __a) 1852 : __r_(__default_init_tag(), __a) 1853{ 1854 if (!__str.__is_long()) 1855 __r_.first().__r = __str.__r_.first().__r; 1856 else 1857 __init(_VSTD::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); 1858#if _LIBCPP_DEBUG_LEVEL >= 2 1859 __get_db()->__insert_c(this); 1860#endif 1861} 1862 1863#ifndef _LIBCPP_CXX03_LANG 1864 1865template <class _CharT, class _Traits, class _Allocator> 1866inline 1867basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str) 1868#if _LIBCPP_STD_VER <= 14 1869 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value) 1870#else 1871 _NOEXCEPT 1872#endif 1873 : __r_(_VSTD::move(__str.__r_)) 1874{ 1875 __str.__zero(); 1876#if _LIBCPP_DEBUG_LEVEL >= 2 1877 __get_db()->__insert_c(this); 1878 if (__is_long()) 1879 __get_db()->swap(this, &__str); 1880#endif 1881} 1882 1883template <class _CharT, class _Traits, class _Allocator> 1884inline 1885basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, const allocator_type& __a) 1886 : __r_(__default_init_tag(), __a) 1887{ 1888 if (__str.__is_long() && __a != __str.__alloc()) // copy, not move 1889 __init(_VSTD::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); 1890 else 1891 { 1892 __r_.first().__r = __str.__r_.first().__r; 1893 __str.__zero(); 1894 } 1895#if _LIBCPP_DEBUG_LEVEL >= 2 1896 __get_db()->__insert_c(this); 1897 if (__is_long()) 1898 __get_db()->swap(this, &__str); 1899#endif 1900} 1901 1902#endif // _LIBCPP_CXX03_LANG 1903 1904template <class _CharT, class _Traits, class _Allocator> 1905void 1906basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c) 1907{ 1908 if (__n > max_size()) 1909 this->__throw_length_error(); 1910 pointer __p; 1911 if (__n < __min_cap) 1912 { 1913 __set_short_size(__n); 1914 __p = __get_short_pointer(); 1915 } 1916 else 1917 { 1918 size_type __cap = __recommend(__n); 1919 __p = __alloc_traits::allocate(__alloc(), __cap+1); 1920 __set_long_pointer(__p); 1921 __set_long_cap(__cap+1); 1922 __set_long_size(__n); 1923 } 1924 traits_type::assign(_VSTD::__to_address(__p), __n, __c); 1925 traits_type::assign(__p[__n], value_type()); 1926} 1927 1928template <class _CharT, class _Traits, class _Allocator> 1929inline 1930basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c) 1931 : __r_(__default_init_tag(), __default_init_tag()) 1932{ 1933 __init(__n, __c); 1934#if _LIBCPP_DEBUG_LEVEL >= 2 1935 __get_db()->__insert_c(this); 1936#endif 1937} 1938 1939template <class _CharT, class _Traits, class _Allocator> 1940template <class> 1941basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c, const _Allocator& __a) 1942 : __r_(__default_init_tag(), __a) 1943{ 1944 __init(__n, __c); 1945#if _LIBCPP_DEBUG_LEVEL >= 2 1946 __get_db()->__insert_c(this); 1947#endif 1948} 1949 1950template <class _CharT, class _Traits, class _Allocator> 1951basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, 1952 size_type __pos, size_type __n, 1953 const _Allocator& __a) 1954 : __r_(__default_init_tag(), __a) 1955{ 1956 size_type __str_sz = __str.size(); 1957 if (__pos > __str_sz) 1958 this->__throw_out_of_range(); 1959 __init(__str.data() + __pos, _VSTD::min(__n, __str_sz - __pos)); 1960#if _LIBCPP_DEBUG_LEVEL >= 2 1961 __get_db()->__insert_c(this); 1962#endif 1963} 1964 1965template <class _CharT, class _Traits, class _Allocator> 1966inline 1967basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos, 1968 const _Allocator& __a) 1969 : __r_(__default_init_tag(), __a) 1970{ 1971 size_type __str_sz = __str.size(); 1972 if (__pos > __str_sz) 1973 this->__throw_out_of_range(); 1974 __init(__str.data() + __pos, __str_sz - __pos); 1975#if _LIBCPP_DEBUG_LEVEL >= 2 1976 __get_db()->__insert_c(this); 1977#endif 1978} 1979 1980template <class _CharT, class _Traits, class _Allocator> 1981template <class _Tp, class> 1982basic_string<_CharT, _Traits, _Allocator>::basic_string( 1983 const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a) 1984 : __r_(__default_init_tag(), __a) 1985{ 1986 __self_view __sv0 = __t; 1987 __self_view __sv = __sv0.substr(__pos, __n); 1988 __init(__sv.data(), __sv.size()); 1989#if _LIBCPP_DEBUG_LEVEL >= 2 1990 __get_db()->__insert_c(this); 1991#endif 1992} 1993 1994template <class _CharT, class _Traits, class _Allocator> 1995template <class _Tp, class> 1996basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t) 1997 : __r_(__default_init_tag(), __default_init_tag()) 1998{ 1999 __self_view __sv = __t; 2000 __init(__sv.data(), __sv.size()); 2001#if _LIBCPP_DEBUG_LEVEL >= 2 2002 __get_db()->__insert_c(this); 2003#endif 2004} 2005 2006template <class _CharT, class _Traits, class _Allocator> 2007template <class _Tp, class> 2008basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t, const _Allocator& __a) 2009 : __r_(__default_init_tag(), __a) 2010{ 2011 __self_view __sv = __t; 2012 __init(__sv.data(), __sv.size()); 2013#if _LIBCPP_DEBUG_LEVEL >= 2 2014 __get_db()->__insert_c(this); 2015#endif 2016} 2017 2018template <class _CharT, class _Traits, class _Allocator> 2019template <class _InputIterator> 2020_EnableIf 2021< 2022 __is_exactly_cpp17_input_iterator<_InputIterator>::value 2023> 2024basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last) 2025{ 2026 __zero(); 2027#ifndef _LIBCPP_NO_EXCEPTIONS 2028 try 2029 { 2030#endif // _LIBCPP_NO_EXCEPTIONS 2031 for (; __first != __last; ++__first) 2032 push_back(*__first); 2033#ifndef _LIBCPP_NO_EXCEPTIONS 2034 } 2035 catch (...) 2036 { 2037 if (__is_long()) 2038 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 2039 throw; 2040 } 2041#endif // _LIBCPP_NO_EXCEPTIONS 2042} 2043 2044template <class _CharT, class _Traits, class _Allocator> 2045template <class _ForwardIterator> 2046_EnableIf 2047< 2048 __is_cpp17_forward_iterator<_ForwardIterator>::value 2049> 2050basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last) 2051{ 2052 size_type __sz = static_cast<size_type>(_VSTD::distance(__first, __last)); 2053 if (__sz > max_size()) 2054 this->__throw_length_error(); 2055 pointer __p; 2056 if (__sz < __min_cap) 2057 { 2058 __set_short_size(__sz); 2059 __p = __get_short_pointer(); 2060 } 2061 else 2062 { 2063 size_type __cap = __recommend(__sz); 2064 __p = __alloc_traits::allocate(__alloc(), __cap+1); 2065 __set_long_pointer(__p); 2066 __set_long_cap(__cap+1); 2067 __set_long_size(__sz); 2068 } 2069 for (; __first != __last; ++__first, (void) ++__p) 2070 traits_type::assign(*__p, *__first); 2071 traits_type::assign(*__p, value_type()); 2072} 2073 2074template <class _CharT, class _Traits, class _Allocator> 2075template<class _InputIterator, class> 2076inline 2077basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last) 2078 : __r_(__default_init_tag(), __default_init_tag()) 2079{ 2080 __init(__first, __last); 2081#if _LIBCPP_DEBUG_LEVEL >= 2 2082 __get_db()->__insert_c(this); 2083#endif 2084} 2085 2086template <class _CharT, class _Traits, class _Allocator> 2087template<class _InputIterator, class> 2088inline 2089basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last, 2090 const allocator_type& __a) 2091 : __r_(__default_init_tag(), __a) 2092{ 2093 __init(__first, __last); 2094#if _LIBCPP_DEBUG_LEVEL >= 2 2095 __get_db()->__insert_c(this); 2096#endif 2097} 2098 2099#ifndef _LIBCPP_CXX03_LANG 2100 2101template <class _CharT, class _Traits, class _Allocator> 2102inline 2103basic_string<_CharT, _Traits, _Allocator>::basic_string( 2104 initializer_list<_CharT> __il) 2105 : __r_(__default_init_tag(), __default_init_tag()) 2106{ 2107 __init(__il.begin(), __il.end()); 2108#if _LIBCPP_DEBUG_LEVEL >= 2 2109 __get_db()->__insert_c(this); 2110#endif 2111} 2112 2113template <class _CharT, class _Traits, class _Allocator> 2114inline 2115 2116basic_string<_CharT, _Traits, _Allocator>::basic_string( 2117 initializer_list<_CharT> __il, const _Allocator& __a) 2118 : __r_(__default_init_tag(), __a) 2119{ 2120 __init(__il.begin(), __il.end()); 2121#if _LIBCPP_DEBUG_LEVEL >= 2 2122 __get_db()->__insert_c(this); 2123#endif 2124} 2125 2126#endif // _LIBCPP_CXX03_LANG 2127 2128template <class _CharT, class _Traits, class _Allocator> 2129basic_string<_CharT, _Traits, _Allocator>::~basic_string() 2130{ 2131#if _LIBCPP_DEBUG_LEVEL >= 2 2132 __get_db()->__erase_c(this); 2133#endif 2134 if (__is_long()) 2135 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 2136} 2137 2138template <class _CharT, class _Traits, class _Allocator> 2139void 2140basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace 2141 (size_type __old_cap, size_type __delta_cap, size_type __old_sz, 2142 size_type __n_copy, size_type __n_del, size_type __n_add, const value_type* __p_new_stuff) 2143{ 2144 size_type __ms = max_size(); 2145 if (__delta_cap > __ms - __old_cap - 1) 2146 this->__throw_length_error(); 2147 pointer __old_p = __get_pointer(); 2148 size_type __cap = __old_cap < __ms / 2 - __alignment ? 2149 __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) : 2150 __ms - 1; 2151 pointer __p = __alloc_traits::allocate(__alloc(), __cap+1); 2152 __invalidate_all_iterators(); 2153 if (__n_copy != 0) 2154 traits_type::copy(_VSTD::__to_address(__p), 2155 _VSTD::__to_address(__old_p), __n_copy); 2156 if (__n_add != 0) 2157 traits_type::copy(_VSTD::__to_address(__p) + __n_copy, __p_new_stuff, __n_add); 2158 size_type __sec_cp_sz = __old_sz - __n_del - __n_copy; 2159 if (__sec_cp_sz != 0) 2160 traits_type::copy(_VSTD::__to_address(__p) + __n_copy + __n_add, 2161 _VSTD::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz); 2162 if (__old_cap+1 != __min_cap) 2163 __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1); 2164 __set_long_pointer(__p); 2165 __set_long_cap(__cap+1); 2166 __old_sz = __n_copy + __n_add + __sec_cp_sz; 2167 __set_long_size(__old_sz); 2168 traits_type::assign(__p[__old_sz], value_type()); 2169} 2170 2171template <class _CharT, class _Traits, class _Allocator> 2172void 2173basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz, 2174 size_type __n_copy, size_type __n_del, size_type __n_add) 2175{ 2176 size_type __ms = max_size(); 2177 if (__delta_cap > __ms - __old_cap) 2178 this->__throw_length_error(); 2179 pointer __old_p = __get_pointer(); 2180 size_type __cap = __old_cap < __ms / 2 - __alignment ? 2181 __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) : 2182 __ms - 1; 2183 pointer __p = __alloc_traits::allocate(__alloc(), __cap+1); 2184 __invalidate_all_iterators(); 2185 if (__n_copy != 0) 2186 traits_type::copy(_VSTD::__to_address(__p), 2187 _VSTD::__to_address(__old_p), __n_copy); 2188 size_type __sec_cp_sz = __old_sz - __n_del - __n_copy; 2189 if (__sec_cp_sz != 0) 2190 traits_type::copy(_VSTD::__to_address(__p) + __n_copy + __n_add, 2191 _VSTD::__to_address(__old_p) + __n_copy + __n_del, 2192 __sec_cp_sz); 2193 if (__old_cap+1 != __min_cap) 2194 __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1); 2195 __set_long_pointer(__p); 2196 __set_long_cap(__cap+1); 2197} 2198 2199// assign 2200 2201template <class _CharT, class _Traits, class _Allocator> 2202basic_string<_CharT, _Traits, _Allocator>& 2203basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n) 2204{ 2205 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::assign received nullptr"); 2206 size_type __cap = capacity(); 2207 if (__cap >= __n) 2208 { 2209 value_type* __p = _VSTD::__to_address(__get_pointer()); 2210 traits_type::move(__p, __s, __n); 2211 traits_type::assign(__p[__n], value_type()); 2212 __set_size(__n); 2213 __invalidate_iterators_past(__n); 2214 } 2215 else 2216 { 2217 size_type __sz = size(); 2218 __grow_by_and_replace(__cap, __n - __cap, __sz, 0, __sz, __n, __s); 2219 } 2220 return *this; 2221} 2222 2223template <class _CharT, class _Traits, class _Allocator> 2224basic_string<_CharT, _Traits, _Allocator>& 2225basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c) 2226{ 2227 size_type __cap = capacity(); 2228 if (__cap < __n) 2229 { 2230 size_type __sz = size(); 2231 __grow_by(__cap, __n - __cap, __sz, 0, __sz); 2232 } 2233 else 2234 __invalidate_iterators_past(__n); 2235 value_type* __p = _VSTD::__to_address(__get_pointer()); 2236 traits_type::assign(__p, __n, __c); 2237 traits_type::assign(__p[__n], value_type()); 2238 __set_size(__n); 2239 return *this; 2240} 2241 2242template <class _CharT, class _Traits, class _Allocator> 2243basic_string<_CharT, _Traits, _Allocator>& 2244basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c) 2245{ 2246 pointer __p; 2247 if (__is_long()) 2248 { 2249 __p = __get_long_pointer(); 2250 __set_long_size(1); 2251 } 2252 else 2253 { 2254 __p = __get_short_pointer(); 2255 __set_short_size(1); 2256 } 2257 traits_type::assign(*__p, __c); 2258 traits_type::assign(*++__p, value_type()); 2259 __invalidate_iterators_past(1); 2260 return *this; 2261} 2262 2263template <class _CharT, class _Traits, class _Allocator> 2264basic_string<_CharT, _Traits, _Allocator>& 2265basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str) 2266{ 2267 if (this != &__str) 2268 { 2269 __copy_assign_alloc(__str); 2270 const bool __str_is_long = __str.__is_long(); // Force single branch 2271 if (__is_long() || __str_is_long) { 2272 return assign(__str.data(), __str.size()); 2273 } 2274 __r_.first().__r = __str.__r_.first().__r; 2275 } 2276 return *this; 2277} 2278 2279#ifndef _LIBCPP_CXX03_LANG 2280 2281template <class _CharT, class _Traits, class _Allocator> 2282inline 2283void 2284basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, false_type) 2285 _NOEXCEPT_(__alloc_traits::is_always_equal::value) 2286{ 2287 if (__alloc() != __str.__alloc()) 2288 assign(__str); 2289 else 2290 __move_assign(__str, true_type()); 2291} 2292 2293template <class _CharT, class _Traits, class _Allocator> 2294inline 2295void 2296basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type) 2297#if _LIBCPP_STD_VER > 14 2298 _NOEXCEPT 2299#else 2300 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) 2301#endif 2302{ 2303 if (__is_long()) { 2304 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), 2305 __get_long_cap()); 2306#if _LIBCPP_STD_VER <= 14 2307 if (!is_nothrow_move_assignable<allocator_type>::value) { 2308 __set_short_size(0); 2309 traits_type::assign(__get_short_pointer()[0], value_type()); 2310 } 2311#endif 2312 } 2313 __move_assign_alloc(__str); 2314 __r_.first() = __str.__r_.first(); 2315 __str.__set_short_size(0); 2316 traits_type::assign(__str.__get_short_pointer()[0], value_type()); 2317} 2318 2319template <class _CharT, class _Traits, class _Allocator> 2320inline 2321basic_string<_CharT, _Traits, _Allocator>& 2322basic_string<_CharT, _Traits, _Allocator>::operator=(basic_string&& __str) 2323 _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value)) 2324{ 2325 __move_assign(__str, integral_constant<bool, 2326 __alloc_traits::propagate_on_container_move_assignment::value>()); 2327 return *this; 2328} 2329 2330#endif 2331 2332template <class _CharT, class _Traits, class _Allocator> 2333template<class _InputIterator> 2334_EnableIf 2335< 2336 __is_exactly_cpp17_input_iterator <_InputIterator>::value 2337 || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value, 2338 basic_string<_CharT, _Traits, _Allocator>& 2339> 2340basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last) 2341{ 2342 const basic_string __temp(__first, __last, __alloc()); 2343 assign(__temp.data(), __temp.size()); 2344 return *this; 2345} 2346 2347template <class _CharT, class _Traits, class _Allocator> 2348template<class _ForwardIterator> 2349_EnableIf 2350< 2351 __is_cpp17_forward_iterator<_ForwardIterator>::value 2352 && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value, 2353 basic_string<_CharT, _Traits, _Allocator>& 2354> 2355basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last) 2356{ 2357 size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last)); 2358 size_type __cap = capacity(); 2359 if (__cap < __n) 2360 { 2361 size_type __sz = size(); 2362 __grow_by(__cap, __n - __cap, __sz, 0, __sz); 2363 } 2364 else 2365 __invalidate_iterators_past(__n); 2366 pointer __p = __get_pointer(); 2367 for (; __first != __last; ++__first, ++__p) 2368 traits_type::assign(*__p, *__first); 2369 traits_type::assign(*__p, value_type()); 2370 __set_size(__n); 2371 return *this; 2372} 2373 2374template <class _CharT, class _Traits, class _Allocator> 2375basic_string<_CharT, _Traits, _Allocator>& 2376basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, size_type __pos, size_type __n) 2377{ 2378 size_type __sz = __str.size(); 2379 if (__pos > __sz) 2380 this->__throw_out_of_range(); 2381 return assign(__str.data() + __pos, _VSTD::min(__n, __sz - __pos)); 2382} 2383 2384template <class _CharT, class _Traits, class _Allocator> 2385template <class _Tp> 2386_EnableIf 2387< 2388 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value 2389 && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 2390 basic_string<_CharT, _Traits, _Allocator>& 2391> 2392basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t, size_type __pos, size_type __n) 2393{ 2394 __self_view __sv = __t; 2395 size_type __sz = __sv.size(); 2396 if (__pos > __sz) 2397 this->__throw_out_of_range(); 2398 return assign(__sv.data() + __pos, _VSTD::min(__n, __sz - __pos)); 2399} 2400 2401 2402template <class _CharT, class _Traits, class _Allocator> 2403basic_string<_CharT, _Traits, _Allocator>& 2404basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s) 2405{ 2406 _LIBCPP_ASSERT(__s != nullptr, "string::assign received nullptr"); 2407 return assign(__s, traits_type::length(__s)); 2408} 2409 2410// append 2411 2412template <class _CharT, class _Traits, class _Allocator> 2413basic_string<_CharT, _Traits, _Allocator>& 2414basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n) 2415{ 2416 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::append received nullptr"); 2417 size_type __cap = capacity(); 2418 size_type __sz = size(); 2419 if (__cap - __sz >= __n) 2420 { 2421 if (__n) 2422 { 2423 value_type* __p = _VSTD::__to_address(__get_pointer()); 2424 traits_type::copy(__p + __sz, __s, __n); 2425 __sz += __n; 2426 __set_size(__sz); 2427 traits_type::assign(__p[__sz], value_type()); 2428 } 2429 } 2430 else 2431 __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __sz, 0, __n, __s); 2432 return *this; 2433} 2434 2435template <class _CharT, class _Traits, class _Allocator> 2436basic_string<_CharT, _Traits, _Allocator>& 2437basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c) 2438{ 2439 if (__n) 2440 { 2441 size_type __cap = capacity(); 2442 size_type __sz = size(); 2443 if (__cap - __sz < __n) 2444 __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); 2445 pointer __p = __get_pointer(); 2446 traits_type::assign(_VSTD::__to_address(__p) + __sz, __n, __c); 2447 __sz += __n; 2448 __set_size(__sz); 2449 traits_type::assign(__p[__sz], value_type()); 2450 } 2451 return *this; 2452} 2453 2454template <class _CharT, class _Traits, class _Allocator> 2455inline void 2456basic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n) 2457{ 2458 if (__n) 2459 { 2460 size_type __cap = capacity(); 2461 size_type __sz = size(); 2462 if (__cap - __sz < __n) 2463 __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); 2464 pointer __p = __get_pointer(); 2465 __sz += __n; 2466 __set_size(__sz); 2467 traits_type::assign(__p[__sz], value_type()); 2468 } 2469} 2470 2471template <class _CharT, class _Traits, class _Allocator> 2472void 2473basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c) 2474{ 2475 bool __is_short = !__is_long(); 2476 size_type __cap; 2477 size_type __sz; 2478 if (__is_short) 2479 { 2480 __cap = __min_cap - 1; 2481 __sz = __get_short_size(); 2482 } 2483 else 2484 { 2485 __cap = __get_long_cap() - 1; 2486 __sz = __get_long_size(); 2487 } 2488 if (__sz == __cap) 2489 { 2490 __grow_by(__cap, 1, __sz, __sz, 0); 2491 __is_short = !__is_long(); 2492 } 2493 pointer __p; 2494 if (__is_short) 2495 { 2496 __p = __get_short_pointer() + __sz; 2497 __set_short_size(__sz+1); 2498 } 2499 else 2500 { 2501 __p = __get_long_pointer() + __sz; 2502 __set_long_size(__sz+1); 2503 } 2504 traits_type::assign(*__p, __c); 2505 traits_type::assign(*++__p, value_type()); 2506} 2507 2508template <class _Tp> 2509bool __ptr_in_range (const _Tp* __p, const _Tp* __first, const _Tp* __last) 2510{ 2511 return __first <= __p && __p < __last; 2512} 2513 2514template <class _Tp1, class _Tp2> 2515bool __ptr_in_range (const _Tp1*, const _Tp2*, const _Tp2*) 2516{ 2517 return false; 2518} 2519 2520template <class _CharT, class _Traits, class _Allocator> 2521template<class _ForwardIterator> 2522basic_string<_CharT, _Traits, _Allocator>& 2523basic_string<_CharT, _Traits, _Allocator>::__append_forward_unsafe( 2524 _ForwardIterator __first, _ForwardIterator __last) 2525{ 2526 static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value, 2527 "function requires a ForwardIterator"); 2528 size_type __sz = size(); 2529 size_type __cap = capacity(); 2530 size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last)); 2531 if (__n) 2532 { 2533 typedef typename iterator_traits<_ForwardIterator>::reference _CharRef; 2534 _CharRef __tmp_ref = *__first; 2535 if (__ptr_in_range(_VSTD::addressof(__tmp_ref), data(), data() + size())) 2536 { 2537 const basic_string __temp (__first, __last, __alloc()); 2538 append(__temp.data(), __temp.size()); 2539 } 2540 else 2541 { 2542 if (__cap - __sz < __n) 2543 __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); 2544 pointer __p = __get_pointer() + __sz; 2545 for (; __first != __last; ++__p, ++__first) 2546 traits_type::assign(*__p, *__first); 2547 traits_type::assign(*__p, value_type()); 2548 __set_size(__sz + __n); 2549 } 2550 } 2551 return *this; 2552} 2553 2554template <class _CharT, class _Traits, class _Allocator> 2555inline 2556basic_string<_CharT, _Traits, _Allocator>& 2557basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str) 2558{ 2559 return append(__str.data(), __str.size()); 2560} 2561 2562template <class _CharT, class _Traits, class _Allocator> 2563basic_string<_CharT, _Traits, _Allocator>& 2564basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, size_type __pos, size_type __n) 2565{ 2566 size_type __sz = __str.size(); 2567 if (__pos > __sz) 2568 this->__throw_out_of_range(); 2569 return append(__str.data() + __pos, _VSTD::min(__n, __sz - __pos)); 2570} 2571 2572template <class _CharT, class _Traits, class _Allocator> 2573template <class _Tp> 2574 _EnableIf 2575 < 2576 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 2577 basic_string<_CharT, _Traits, _Allocator>& 2578 > 2579basic_string<_CharT, _Traits, _Allocator>::append(const _Tp & __t, size_type __pos, size_type __n) 2580{ 2581 __self_view __sv = __t; 2582 size_type __sz = __sv.size(); 2583 if (__pos > __sz) 2584 this->__throw_out_of_range(); 2585 return append(__sv.data() + __pos, _VSTD::min(__n, __sz - __pos)); 2586} 2587 2588template <class _CharT, class _Traits, class _Allocator> 2589basic_string<_CharT, _Traits, _Allocator>& 2590basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s) 2591{ 2592 _LIBCPP_ASSERT(__s != nullptr, "string::append received nullptr"); 2593 return append(__s, traits_type::length(__s)); 2594} 2595 2596// insert 2597 2598template <class _CharT, class _Traits, class _Allocator> 2599basic_string<_CharT, _Traits, _Allocator>& 2600basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n) 2601{ 2602 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::insert received nullptr"); 2603 size_type __sz = size(); 2604 if (__pos > __sz) 2605 this->__throw_out_of_range(); 2606 size_type __cap = capacity(); 2607 if (__cap - __sz >= __n) 2608 { 2609 if (__n) 2610 { 2611 value_type* __p = _VSTD::__to_address(__get_pointer()); 2612 size_type __n_move = __sz - __pos; 2613 if (__n_move != 0) 2614 { 2615 if (__p + __pos <= __s && __s < __p + __sz) 2616 __s += __n; 2617 traits_type::move(__p + __pos + __n, __p + __pos, __n_move); 2618 } 2619 traits_type::move(__p + __pos, __s, __n); 2620 __sz += __n; 2621 __set_size(__sz); 2622 traits_type::assign(__p[__sz], value_type()); 2623 } 2624 } 2625 else 2626 __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s); 2627 return *this; 2628} 2629 2630template <class _CharT, class _Traits, class _Allocator> 2631basic_string<_CharT, _Traits, _Allocator>& 2632basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n, value_type __c) 2633{ 2634 size_type __sz = size(); 2635 if (__pos > __sz) 2636 this->__throw_out_of_range(); 2637 if (__n) 2638 { 2639 size_type __cap = capacity(); 2640 value_type* __p; 2641 if (__cap - __sz >= __n) 2642 { 2643 __p = _VSTD::__to_address(__get_pointer()); 2644 size_type __n_move = __sz - __pos; 2645 if (__n_move != 0) 2646 traits_type::move(__p + __pos + __n, __p + __pos, __n_move); 2647 } 2648 else 2649 { 2650 __grow_by(__cap, __sz + __n - __cap, __sz, __pos, 0, __n); 2651 __p = _VSTD::__to_address(__get_long_pointer()); 2652 } 2653 traits_type::assign(__p + __pos, __n, __c); 2654 __sz += __n; 2655 __set_size(__sz); 2656 traits_type::assign(__p[__sz], value_type()); 2657 } 2658 return *this; 2659} 2660 2661template <class _CharT, class _Traits, class _Allocator> 2662template<class _InputIterator> 2663_EnableIf 2664< 2665 __is_exactly_cpp17_input_iterator<_InputIterator>::value 2666 || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value, 2667 typename basic_string<_CharT, _Traits, _Allocator>::iterator 2668> 2669basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last) 2670{ 2671#if _LIBCPP_DEBUG_LEVEL >= 2 2672 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, 2673 "string::insert(iterator, range) called with an iterator not" 2674 " referring to this string"); 2675#endif 2676 const basic_string __temp(__first, __last, __alloc()); 2677 return insert(__pos, __temp.data(), __temp.data() + __temp.size()); 2678} 2679 2680template <class _CharT, class _Traits, class _Allocator> 2681template<class _ForwardIterator> 2682_EnableIf 2683< 2684 __is_cpp17_forward_iterator<_ForwardIterator>::value 2685 && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value, 2686 typename basic_string<_CharT, _Traits, _Allocator>::iterator 2687> 2688basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last) 2689{ 2690#if _LIBCPP_DEBUG_LEVEL >= 2 2691 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, 2692 "string::insert(iterator, range) called with an iterator not" 2693 " referring to this string"); 2694#endif 2695 size_type __ip = static_cast<size_type>(__pos - begin()); 2696 size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last)); 2697 if (__n) 2698 { 2699 typedef typename iterator_traits<_ForwardIterator>::reference _CharRef; 2700 _CharRef __tmp_char = *__first; 2701 if (__ptr_in_range(_VSTD::addressof(__tmp_char), data(), data() + size())) 2702 { 2703 const basic_string __temp(__first, __last, __alloc()); 2704 return insert(__pos, __temp.data(), __temp.data() + __temp.size()); 2705 } 2706 2707 size_type __sz = size(); 2708 size_type __cap = capacity(); 2709 value_type* __p; 2710 if (__cap - __sz >= __n) 2711 { 2712 __p = _VSTD::__to_address(__get_pointer()); 2713 size_type __n_move = __sz - __ip; 2714 if (__n_move != 0) 2715 traits_type::move(__p + __ip + __n, __p + __ip, __n_move); 2716 } 2717 else 2718 { 2719 __grow_by(__cap, __sz + __n - __cap, __sz, __ip, 0, __n); 2720 __p = _VSTD::__to_address(__get_long_pointer()); 2721 } 2722 __sz += __n; 2723 __set_size(__sz); 2724 traits_type::assign(__p[__sz], value_type()); 2725 for (__p += __ip; __first != __last; ++__p, ++__first) 2726 traits_type::assign(*__p, *__first); 2727 } 2728 return begin() + __ip; 2729} 2730 2731template <class _CharT, class _Traits, class _Allocator> 2732inline 2733basic_string<_CharT, _Traits, _Allocator>& 2734basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str) 2735{ 2736 return insert(__pos1, __str.data(), __str.size()); 2737} 2738 2739template <class _CharT, class _Traits, class _Allocator> 2740basic_string<_CharT, _Traits, _Allocator>& 2741basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str, 2742 size_type __pos2, size_type __n) 2743{ 2744 size_type __str_sz = __str.size(); 2745 if (__pos2 > __str_sz) 2746 this->__throw_out_of_range(); 2747 return insert(__pos1, __str.data() + __pos2, _VSTD::min(__n, __str_sz - __pos2)); 2748} 2749 2750template <class _CharT, class _Traits, class _Allocator> 2751template <class _Tp> 2752_EnableIf 2753< 2754 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 2755 basic_string<_CharT, _Traits, _Allocator>& 2756> 2757basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& __t, 2758 size_type __pos2, size_type __n) 2759{ 2760 __self_view __sv = __t; 2761 size_type __str_sz = __sv.size(); 2762 if (__pos2 > __str_sz) 2763 this->__throw_out_of_range(); 2764 return insert(__pos1, __sv.data() + __pos2, _VSTD::min(__n, __str_sz - __pos2)); 2765} 2766 2767template <class _CharT, class _Traits, class _Allocator> 2768basic_string<_CharT, _Traits, _Allocator>& 2769basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s) 2770{ 2771 _LIBCPP_ASSERT(__s != nullptr, "string::insert received nullptr"); 2772 return insert(__pos, __s, traits_type::length(__s)); 2773} 2774 2775template <class _CharT, class _Traits, class _Allocator> 2776typename basic_string<_CharT, _Traits, _Allocator>::iterator 2777basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c) 2778{ 2779 size_type __ip = static_cast<size_type>(__pos - begin()); 2780 size_type __sz = size(); 2781 size_type __cap = capacity(); 2782 value_type* __p; 2783 if (__cap == __sz) 2784 { 2785 __grow_by(__cap, 1, __sz, __ip, 0, 1); 2786 __p = _VSTD::__to_address(__get_long_pointer()); 2787 } 2788 else 2789 { 2790 __p = _VSTD::__to_address(__get_pointer()); 2791 size_type __n_move = __sz - __ip; 2792 if (__n_move != 0) 2793 traits_type::move(__p + __ip + 1, __p + __ip, __n_move); 2794 } 2795 traits_type::assign(__p[__ip], __c); 2796 traits_type::assign(__p[++__sz], value_type()); 2797 __set_size(__sz); 2798 return begin() + static_cast<difference_type>(__ip); 2799} 2800 2801template <class _CharT, class _Traits, class _Allocator> 2802inline 2803typename basic_string<_CharT, _Traits, _Allocator>::iterator 2804basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, size_type __n, value_type __c) 2805{ 2806#if _LIBCPP_DEBUG_LEVEL >= 2 2807 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, 2808 "string::insert(iterator, n, value) called with an iterator not" 2809 " referring to this string"); 2810#endif 2811 difference_type __p = __pos - begin(); 2812 insert(static_cast<size_type>(__p), __n, __c); 2813 return begin() + __p; 2814} 2815 2816// replace 2817 2818template <class _CharT, class _Traits, class _Allocator> 2819basic_string<_CharT, _Traits, _Allocator>& 2820basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2) 2821 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK 2822{ 2823 _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::replace received nullptr"); 2824 size_type __sz = size(); 2825 if (__pos > __sz) 2826 this->__throw_out_of_range(); 2827 __n1 = _VSTD::min(__n1, __sz - __pos); 2828 size_type __cap = capacity(); 2829 if (__cap - __sz + __n1 >= __n2) 2830 { 2831 value_type* __p = _VSTD::__to_address(__get_pointer()); 2832 if (__n1 != __n2) 2833 { 2834 size_type __n_move = __sz - __pos - __n1; 2835 if (__n_move != 0) 2836 { 2837 if (__n1 > __n2) 2838 { 2839 traits_type::move(__p + __pos, __s, __n2); 2840 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move); 2841 goto __finish; 2842 } 2843 if (__p + __pos < __s && __s < __p + __sz) 2844 { 2845 if (__p + __pos + __n1 <= __s) 2846 __s += __n2 - __n1; 2847 else // __p + __pos < __s < __p + __pos + __n1 2848 { 2849 traits_type::move(__p + __pos, __s, __n1); 2850 __pos += __n1; 2851 __s += __n2; 2852 __n2 -= __n1; 2853 __n1 = 0; 2854 } 2855 } 2856 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move); 2857 } 2858 } 2859 traits_type::move(__p + __pos, __s, __n2); 2860__finish: 2861// __sz += __n2 - __n1; in this and the below function below can cause unsigned integer overflow, 2862// but this is a safe operation, so we disable the check. 2863 __sz += __n2 - __n1; 2864 __set_size(__sz); 2865 __invalidate_iterators_past(__sz); 2866 traits_type::assign(__p[__sz], value_type()); 2867 } 2868 else 2869 __grow_by_and_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2, __s); 2870 return *this; 2871} 2872 2873template <class _CharT, class _Traits, class _Allocator> 2874basic_string<_CharT, _Traits, _Allocator>& 2875basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, size_type __n2, value_type __c) 2876 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK 2877{ 2878 size_type __sz = size(); 2879 if (__pos > __sz) 2880 this->__throw_out_of_range(); 2881 __n1 = _VSTD::min(__n1, __sz - __pos); 2882 size_type __cap = capacity(); 2883 value_type* __p; 2884 if (__cap - __sz + __n1 >= __n2) 2885 { 2886 __p = _VSTD::__to_address(__get_pointer()); 2887 if (__n1 != __n2) 2888 { 2889 size_type __n_move = __sz - __pos - __n1; 2890 if (__n_move != 0) 2891 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move); 2892 } 2893 } 2894 else 2895 { 2896 __grow_by(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2); 2897 __p = _VSTD::__to_address(__get_long_pointer()); 2898 } 2899 traits_type::assign(__p + __pos, __n2, __c); 2900 __sz += __n2 - __n1; 2901 __set_size(__sz); 2902 __invalidate_iterators_past(__sz); 2903 traits_type::assign(__p[__sz], value_type()); 2904 return *this; 2905} 2906 2907template <class _CharT, class _Traits, class _Allocator> 2908template<class _InputIterator> 2909_EnableIf 2910< 2911 __is_cpp17_input_iterator<_InputIterator>::value, 2912 basic_string<_CharT, _Traits, _Allocator>& 2913> 2914basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, 2915 _InputIterator __j1, _InputIterator __j2) 2916{ 2917 const basic_string __temp(__j1, __j2, __alloc()); 2918 return this->replace(__i1, __i2, __temp); 2919} 2920 2921template <class _CharT, class _Traits, class _Allocator> 2922inline 2923basic_string<_CharT, _Traits, _Allocator>& 2924basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str) 2925{ 2926 return replace(__pos1, __n1, __str.data(), __str.size()); 2927} 2928 2929template <class _CharT, class _Traits, class _Allocator> 2930basic_string<_CharT, _Traits, _Allocator>& 2931basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str, 2932 size_type __pos2, size_type __n2) 2933{ 2934 size_type __str_sz = __str.size(); 2935 if (__pos2 > __str_sz) 2936 this->__throw_out_of_range(); 2937 return replace(__pos1, __n1, __str.data() + __pos2, _VSTD::min(__n2, __str_sz - __pos2)); 2938} 2939 2940template <class _CharT, class _Traits, class _Allocator> 2941template <class _Tp> 2942_EnableIf 2943< 2944 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 2945 basic_string<_CharT, _Traits, _Allocator>& 2946> 2947basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const _Tp& __t, 2948 size_type __pos2, size_type __n2) 2949{ 2950 __self_view __sv = __t; 2951 size_type __str_sz = __sv.size(); 2952 if (__pos2 > __str_sz) 2953 this->__throw_out_of_range(); 2954 return replace(__pos1, __n1, __sv.data() + __pos2, _VSTD::min(__n2, __str_sz - __pos2)); 2955} 2956 2957template <class _CharT, class _Traits, class _Allocator> 2958basic_string<_CharT, _Traits, _Allocator>& 2959basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s) 2960{ 2961 _LIBCPP_ASSERT(__s != nullptr, "string::replace received nullptr"); 2962 return replace(__pos, __n1, __s, traits_type::length(__s)); 2963} 2964 2965template <class _CharT, class _Traits, class _Allocator> 2966inline 2967basic_string<_CharT, _Traits, _Allocator>& 2968basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const basic_string& __str) 2969{ 2970 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), 2971 __str.data(), __str.size()); 2972} 2973 2974template <class _CharT, class _Traits, class _Allocator> 2975inline 2976basic_string<_CharT, _Traits, _Allocator>& 2977basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n) 2978{ 2979 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s, __n); 2980} 2981 2982template <class _CharT, class _Traits, class _Allocator> 2983inline 2984basic_string<_CharT, _Traits, _Allocator>& 2985basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s) 2986{ 2987 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s); 2988} 2989 2990template <class _CharT, class _Traits, class _Allocator> 2991inline 2992basic_string<_CharT, _Traits, _Allocator>& 2993basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c) 2994{ 2995 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __n, __c); 2996} 2997 2998// erase 2999 3000template <class _CharT, class _Traits, class _Allocator> 3001basic_string<_CharT, _Traits, _Allocator>& 3002basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, size_type __n) 3003{ 3004 size_type __sz = size(); 3005 if (__pos > __sz) 3006 this->__throw_out_of_range(); 3007 if (__n) 3008 { 3009 value_type* __p = _VSTD::__to_address(__get_pointer()); 3010 __n = _VSTD::min(__n, __sz - __pos); 3011 size_type __n_move = __sz - __pos - __n; 3012 if (__n_move != 0) 3013 traits_type::move(__p + __pos, __p + __pos + __n, __n_move); 3014 __sz -= __n; 3015 __set_size(__sz); 3016 __invalidate_iterators_past(__sz); 3017 traits_type::assign(__p[__sz], value_type()); 3018 } 3019 return *this; 3020} 3021 3022template <class _CharT, class _Traits, class _Allocator> 3023inline 3024typename basic_string<_CharT, _Traits, _Allocator>::iterator 3025basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos) 3026{ 3027#if _LIBCPP_DEBUG_LEVEL >= 2 3028 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, 3029 "string::erase(iterator) called with an iterator not" 3030 " referring to this string"); 3031#endif 3032 _LIBCPP_ASSERT(__pos != end(), 3033 "string::erase(iterator) called with a non-dereferenceable iterator"); 3034 iterator __b = begin(); 3035 size_type __r = static_cast<size_type>(__pos - __b); 3036 erase(__r, 1); 3037 return __b + static_cast<difference_type>(__r); 3038} 3039 3040template <class _CharT, class _Traits, class _Allocator> 3041inline 3042typename basic_string<_CharT, _Traits, _Allocator>::iterator 3043basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last) 3044{ 3045#if _LIBCPP_DEBUG_LEVEL >= 2 3046 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this, 3047 "string::erase(iterator, iterator) called with an iterator not" 3048 " referring to this string"); 3049#endif 3050 _LIBCPP_ASSERT(__first <= __last, "string::erase(first, last) called with invalid range"); 3051 iterator __b = begin(); 3052 size_type __r = static_cast<size_type>(__first - __b); 3053 erase(__r, static_cast<size_type>(__last - __first)); 3054 return __b + static_cast<difference_type>(__r); 3055} 3056 3057template <class _CharT, class _Traits, class _Allocator> 3058inline 3059void 3060basic_string<_CharT, _Traits, _Allocator>::pop_back() 3061{ 3062 _LIBCPP_ASSERT(!empty(), "string::pop_back(): string is already empty"); 3063 size_type __sz; 3064 if (__is_long()) 3065 { 3066 __sz = __get_long_size() - 1; 3067 __set_long_size(__sz); 3068 traits_type::assign(*(__get_long_pointer() + __sz), value_type()); 3069 } 3070 else 3071 { 3072 __sz = __get_short_size() - 1; 3073 __set_short_size(__sz); 3074 traits_type::assign(*(__get_short_pointer() + __sz), value_type()); 3075 } 3076 __invalidate_iterators_past(__sz); 3077} 3078 3079template <class _CharT, class _Traits, class _Allocator> 3080inline 3081void 3082basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT 3083{ 3084 __invalidate_all_iterators(); 3085 if (__is_long()) 3086 { 3087 traits_type::assign(*__get_long_pointer(), value_type()); 3088 __set_long_size(0); 3089 } 3090 else 3091 { 3092 traits_type::assign(*__get_short_pointer(), value_type()); 3093 __set_short_size(0); 3094 } 3095} 3096 3097template <class _CharT, class _Traits, class _Allocator> 3098inline 3099void 3100basic_string<_CharT, _Traits, _Allocator>::__erase_to_end(size_type __pos) 3101{ 3102 if (__is_long()) 3103 { 3104 traits_type::assign(*(__get_long_pointer() + __pos), value_type()); 3105 __set_long_size(__pos); 3106 } 3107 else 3108 { 3109 traits_type::assign(*(__get_short_pointer() + __pos), value_type()); 3110 __set_short_size(__pos); 3111 } 3112 __invalidate_iterators_past(__pos); 3113} 3114 3115template <class _CharT, class _Traits, class _Allocator> 3116void 3117basic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c) 3118{ 3119 size_type __sz = size(); 3120 if (__n > __sz) 3121 append(__n - __sz, __c); 3122 else 3123 __erase_to_end(__n); 3124} 3125 3126template <class _CharT, class _Traits, class _Allocator> 3127inline void 3128basic_string<_CharT, _Traits, _Allocator>::__resize_default_init(size_type __n) 3129{ 3130 size_type __sz = size(); 3131 if (__n > __sz) { 3132 __append_default_init(__n - __sz); 3133 } else 3134 __erase_to_end(__n); 3135} 3136 3137template <class _CharT, class _Traits, class _Allocator> 3138inline 3139typename basic_string<_CharT, _Traits, _Allocator>::size_type 3140basic_string<_CharT, _Traits, _Allocator>::max_size() const _NOEXCEPT 3141{ 3142 size_type __m = __alloc_traits::max_size(__alloc()); 3143#ifdef _LIBCPP_BIG_ENDIAN 3144 return (__m <= ~__long_mask ? __m : __m/2) - __alignment; 3145#else 3146 return __m - __alignment; 3147#endif 3148} 3149 3150template <class _CharT, class _Traits, class _Allocator> 3151void 3152basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __res_arg) 3153{ 3154 if (__res_arg > max_size()) 3155 this->__throw_length_error(); 3156 size_type __cap = capacity(); 3157 size_type __sz = size(); 3158 __res_arg = _VSTD::max(__res_arg, __sz); 3159 __res_arg = __recommend(__res_arg); 3160 if (__res_arg != __cap) 3161 { 3162 pointer __new_data, __p; 3163 bool __was_long, __now_long; 3164 if (__res_arg == __min_cap - 1) 3165 { 3166 __was_long = true; 3167 __now_long = false; 3168 __new_data = __get_short_pointer(); 3169 __p = __get_long_pointer(); 3170 } 3171 else 3172 { 3173 if (__res_arg > __cap) 3174 __new_data = __alloc_traits::allocate(__alloc(), __res_arg+1); 3175 else 3176 { 3177 #ifndef _LIBCPP_NO_EXCEPTIONS 3178 try 3179 { 3180 #endif // _LIBCPP_NO_EXCEPTIONS 3181 __new_data = __alloc_traits::allocate(__alloc(), __res_arg+1); 3182 #ifndef _LIBCPP_NO_EXCEPTIONS 3183 } 3184 catch (...) 3185 { 3186 return; 3187 } 3188 #else // _LIBCPP_NO_EXCEPTIONS 3189 if (__new_data == nullptr) 3190 return; 3191 #endif // _LIBCPP_NO_EXCEPTIONS 3192 } 3193 __now_long = true; 3194 __was_long = __is_long(); 3195 __p = __get_pointer(); 3196 } 3197 traits_type::copy(_VSTD::__to_address(__new_data), 3198 _VSTD::__to_address(__p), size()+1); 3199 if (__was_long) 3200 __alloc_traits::deallocate(__alloc(), __p, __cap+1); 3201 if (__now_long) 3202 { 3203 __set_long_cap(__res_arg+1); 3204 __set_long_size(__sz); 3205 __set_long_pointer(__new_data); 3206 } 3207 else 3208 __set_short_size(__sz); 3209 __invalidate_all_iterators(); 3210 } 3211} 3212 3213template <class _CharT, class _Traits, class _Allocator> 3214inline 3215typename basic_string<_CharT, _Traits, _Allocator>::const_reference 3216basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const _NOEXCEPT 3217{ 3218 _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds"); 3219 return *(data() + __pos); 3220} 3221 3222template <class _CharT, class _Traits, class _Allocator> 3223inline 3224typename basic_string<_CharT, _Traits, _Allocator>::reference 3225basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) _NOEXCEPT 3226{ 3227 _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds"); 3228 return *(__get_pointer() + __pos); 3229} 3230 3231template <class _CharT, class _Traits, class _Allocator> 3232typename basic_string<_CharT, _Traits, _Allocator>::const_reference 3233basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const 3234{ 3235 if (__n >= size()) 3236 this->__throw_out_of_range(); 3237 return (*this)[__n]; 3238} 3239 3240template <class _CharT, class _Traits, class _Allocator> 3241typename basic_string<_CharT, _Traits, _Allocator>::reference 3242basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) 3243{ 3244 if (__n >= size()) 3245 this->__throw_out_of_range(); 3246 return (*this)[__n]; 3247} 3248 3249template <class _CharT, class _Traits, class _Allocator> 3250inline 3251typename basic_string<_CharT, _Traits, _Allocator>::reference 3252basic_string<_CharT, _Traits, _Allocator>::front() _NOEXCEPT 3253{ 3254 _LIBCPP_ASSERT(!empty(), "string::front(): string is empty"); 3255 return *__get_pointer(); 3256} 3257 3258template <class _CharT, class _Traits, class _Allocator> 3259inline 3260typename basic_string<_CharT, _Traits, _Allocator>::const_reference 3261basic_string<_CharT, _Traits, _Allocator>::front() const _NOEXCEPT 3262{ 3263 _LIBCPP_ASSERT(!empty(), "string::front(): string is empty"); 3264 return *data(); 3265} 3266 3267template <class _CharT, class _Traits, class _Allocator> 3268inline 3269typename basic_string<_CharT, _Traits, _Allocator>::reference 3270basic_string<_CharT, _Traits, _Allocator>::back() _NOEXCEPT 3271{ 3272 _LIBCPP_ASSERT(!empty(), "string::back(): string is empty"); 3273 return *(__get_pointer() + size() - 1); 3274} 3275 3276template <class _CharT, class _Traits, class _Allocator> 3277inline 3278typename basic_string<_CharT, _Traits, _Allocator>::const_reference 3279basic_string<_CharT, _Traits, _Allocator>::back() const _NOEXCEPT 3280{ 3281 _LIBCPP_ASSERT(!empty(), "string::back(): string is empty"); 3282 return *(data() + size() - 1); 3283} 3284 3285template <class _CharT, class _Traits, class _Allocator> 3286typename basic_string<_CharT, _Traits, _Allocator>::size_type 3287basic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n, size_type __pos) const 3288{ 3289 size_type __sz = size(); 3290 if (__pos > __sz) 3291 this->__throw_out_of_range(); 3292 size_type __rlen = _VSTD::min(__n, __sz - __pos); 3293 traits_type::copy(__s, data() + __pos, __rlen); 3294 return __rlen; 3295} 3296 3297template <class _CharT, class _Traits, class _Allocator> 3298inline 3299basic_string<_CharT, _Traits, _Allocator> 3300basic_string<_CharT, _Traits, _Allocator>::substr(size_type __pos, size_type __n) const 3301{ 3302 return basic_string(*this, __pos, __n, __alloc()); 3303} 3304 3305template <class _CharT, class _Traits, class _Allocator> 3306inline 3307void 3308basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str) 3309#if _LIBCPP_STD_VER >= 14 3310 _NOEXCEPT 3311#else 3312 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || 3313 __is_nothrow_swappable<allocator_type>::value) 3314#endif 3315{ 3316#if _LIBCPP_DEBUG_LEVEL >= 2 3317 if (!__is_long()) 3318 __get_db()->__invalidate_all(this); 3319 if (!__str.__is_long()) 3320 __get_db()->__invalidate_all(&__str); 3321 __get_db()->swap(this, &__str); 3322#endif 3323 _LIBCPP_ASSERT( 3324 __alloc_traits::propagate_on_container_swap::value || 3325 __alloc_traits::is_always_equal::value || 3326 __alloc() == __str.__alloc(), "swapping non-equal allocators"); 3327 _VSTD::swap(__r_.first(), __str.__r_.first()); 3328 __swap_allocator(__alloc(), __str.__alloc()); 3329} 3330 3331// find 3332 3333template <class _Traits> 3334struct _LIBCPP_HIDDEN __traits_eq 3335{ 3336 typedef typename _Traits::char_type char_type; 3337 _LIBCPP_INLINE_VISIBILITY 3338 bool operator()(const char_type& __x, const char_type& __y) _NOEXCEPT 3339 {return _Traits::eq(__x, __y);} 3340}; 3341 3342template<class _CharT, class _Traits, class _Allocator> 3343typename basic_string<_CharT, _Traits, _Allocator>::size_type 3344basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, 3345 size_type __pos, 3346 size_type __n) const _NOEXCEPT 3347{ 3348 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find(): received nullptr"); 3349 return __str_find<value_type, size_type, traits_type, npos> 3350 (data(), size(), __s, __pos, __n); 3351} 3352 3353template<class _CharT, class _Traits, class _Allocator> 3354inline 3355typename basic_string<_CharT, _Traits, _Allocator>::size_type 3356basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str, 3357 size_type __pos) const _NOEXCEPT 3358{ 3359 return __str_find<value_type, size_type, traits_type, npos> 3360 (data(), size(), __str.data(), __pos, __str.size()); 3361} 3362 3363template<class _CharT, class _Traits, class _Allocator> 3364template <class _Tp> 3365_EnableIf 3366< 3367 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 3368 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3369> 3370basic_string<_CharT, _Traits, _Allocator>::find(const _Tp &__t, 3371 size_type __pos) const 3372{ 3373 __self_view __sv = __t; 3374 return __str_find<value_type, size_type, traits_type, npos> 3375 (data(), size(), __sv.data(), __pos, __sv.size()); 3376} 3377 3378template<class _CharT, class _Traits, class _Allocator> 3379inline 3380typename basic_string<_CharT, _Traits, _Allocator>::size_type 3381basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, 3382 size_type __pos) const _NOEXCEPT 3383{ 3384 _LIBCPP_ASSERT(__s != nullptr, "string::find(): received nullptr"); 3385 return __str_find<value_type, size_type, traits_type, npos> 3386 (data(), size(), __s, __pos, traits_type::length(__s)); 3387} 3388 3389template<class _CharT, class _Traits, class _Allocator> 3390typename basic_string<_CharT, _Traits, _Allocator>::size_type 3391basic_string<_CharT, _Traits, _Allocator>::find(value_type __c, 3392 size_type __pos) const _NOEXCEPT 3393{ 3394 return __str_find<value_type, size_type, traits_type, npos> 3395 (data(), size(), __c, __pos); 3396} 3397 3398// rfind 3399 3400template<class _CharT, class _Traits, class _Allocator> 3401typename basic_string<_CharT, _Traits, _Allocator>::size_type 3402basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, 3403 size_type __pos, 3404 size_type __n) const _NOEXCEPT 3405{ 3406 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::rfind(): received nullptr"); 3407 return __str_rfind<value_type, size_type, traits_type, npos> 3408 (data(), size(), __s, __pos, __n); 3409} 3410 3411template<class _CharT, class _Traits, class _Allocator> 3412inline 3413typename basic_string<_CharT, _Traits, _Allocator>::size_type 3414basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str, 3415 size_type __pos) const _NOEXCEPT 3416{ 3417 return __str_rfind<value_type, size_type, traits_type, npos> 3418 (data(), size(), __str.data(), __pos, __str.size()); 3419} 3420 3421template<class _CharT, class _Traits, class _Allocator> 3422template <class _Tp> 3423_EnableIf 3424< 3425 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 3426 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3427> 3428basic_string<_CharT, _Traits, _Allocator>::rfind(const _Tp& __t, 3429 size_type __pos) const 3430{ 3431 __self_view __sv = __t; 3432 return __str_rfind<value_type, size_type, traits_type, npos> 3433 (data(), size(), __sv.data(), __pos, __sv.size()); 3434} 3435 3436template<class _CharT, class _Traits, class _Allocator> 3437inline 3438typename basic_string<_CharT, _Traits, _Allocator>::size_type 3439basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, 3440 size_type __pos) const _NOEXCEPT 3441{ 3442 _LIBCPP_ASSERT(__s != nullptr, "string::rfind(): received nullptr"); 3443 return __str_rfind<value_type, size_type, traits_type, npos> 3444 (data(), size(), __s, __pos, traits_type::length(__s)); 3445} 3446 3447template<class _CharT, class _Traits, class _Allocator> 3448typename basic_string<_CharT, _Traits, _Allocator>::size_type 3449basic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c, 3450 size_type __pos) const _NOEXCEPT 3451{ 3452 return __str_rfind<value_type, size_type, traits_type, npos> 3453 (data(), size(), __c, __pos); 3454} 3455 3456// find_first_of 3457 3458template<class _CharT, class _Traits, class _Allocator> 3459typename basic_string<_CharT, _Traits, _Allocator>::size_type 3460basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, 3461 size_type __pos, 3462 size_type __n) const _NOEXCEPT 3463{ 3464 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr"); 3465 return __str_find_first_of<value_type, size_type, traits_type, npos> 3466 (data(), size(), __s, __pos, __n); 3467} 3468 3469template<class _CharT, class _Traits, class _Allocator> 3470inline 3471typename basic_string<_CharT, _Traits, _Allocator>::size_type 3472basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str, 3473 size_type __pos) const _NOEXCEPT 3474{ 3475 return __str_find_first_of<value_type, size_type, traits_type, npos> 3476 (data(), size(), __str.data(), __pos, __str.size()); 3477} 3478 3479template<class _CharT, class _Traits, class _Allocator> 3480template <class _Tp> 3481_EnableIf 3482< 3483 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 3484 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3485> 3486basic_string<_CharT, _Traits, _Allocator>::find_first_of(const _Tp& __t, 3487 size_type __pos) const 3488{ 3489 __self_view __sv = __t; 3490 return __str_find_first_of<value_type, size_type, traits_type, npos> 3491 (data(), size(), __sv.data(), __pos, __sv.size()); 3492} 3493 3494template<class _CharT, class _Traits, class _Allocator> 3495inline 3496typename basic_string<_CharT, _Traits, _Allocator>::size_type 3497basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, 3498 size_type __pos) const _NOEXCEPT 3499{ 3500 _LIBCPP_ASSERT(__s != nullptr, "string::find_first_of(): received nullptr"); 3501 return __str_find_first_of<value_type, size_type, traits_type, npos> 3502 (data(), size(), __s, __pos, traits_type::length(__s)); 3503} 3504 3505template<class _CharT, class _Traits, class _Allocator> 3506inline 3507typename basic_string<_CharT, _Traits, _Allocator>::size_type 3508basic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c, 3509 size_type __pos) const _NOEXCEPT 3510{ 3511 return find(__c, __pos); 3512} 3513 3514// find_last_of 3515 3516template<class _CharT, class _Traits, class _Allocator> 3517typename basic_string<_CharT, _Traits, _Allocator>::size_type 3518basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, 3519 size_type __pos, 3520 size_type __n) const _NOEXCEPT 3521{ 3522 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr"); 3523 return __str_find_last_of<value_type, size_type, traits_type, npos> 3524 (data(), size(), __s, __pos, __n); 3525} 3526 3527template<class _CharT, class _Traits, class _Allocator> 3528inline 3529typename basic_string<_CharT, _Traits, _Allocator>::size_type 3530basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str, 3531 size_type __pos) const _NOEXCEPT 3532{ 3533 return __str_find_last_of<value_type, size_type, traits_type, npos> 3534 (data(), size(), __str.data(), __pos, __str.size()); 3535} 3536 3537template<class _CharT, class _Traits, class _Allocator> 3538template <class _Tp> 3539_EnableIf 3540< 3541 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 3542 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3543> 3544basic_string<_CharT, _Traits, _Allocator>::find_last_of(const _Tp& __t, 3545 size_type __pos) const 3546{ 3547 __self_view __sv = __t; 3548 return __str_find_last_of<value_type, size_type, traits_type, npos> 3549 (data(), size(), __sv.data(), __pos, __sv.size()); 3550} 3551 3552template<class _CharT, class _Traits, class _Allocator> 3553inline 3554typename basic_string<_CharT, _Traits, _Allocator>::size_type 3555basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, 3556 size_type __pos) const _NOEXCEPT 3557{ 3558 _LIBCPP_ASSERT(__s != nullptr, "string::find_last_of(): received nullptr"); 3559 return __str_find_last_of<value_type, size_type, traits_type, npos> 3560 (data(), size(), __s, __pos, traits_type::length(__s)); 3561} 3562 3563template<class _CharT, class _Traits, class _Allocator> 3564inline 3565typename basic_string<_CharT, _Traits, _Allocator>::size_type 3566basic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c, 3567 size_type __pos) const _NOEXCEPT 3568{ 3569 return rfind(__c, __pos); 3570} 3571 3572// find_first_not_of 3573 3574template<class _CharT, class _Traits, class _Allocator> 3575typename basic_string<_CharT, _Traits, _Allocator>::size_type 3576basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s, 3577 size_type __pos, 3578 size_type __n) const _NOEXCEPT 3579{ 3580 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr"); 3581 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 3582 (data(), size(), __s, __pos, __n); 3583} 3584 3585template<class _CharT, class _Traits, class _Allocator> 3586inline 3587typename basic_string<_CharT, _Traits, _Allocator>::size_type 3588basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string& __str, 3589 size_type __pos) const _NOEXCEPT 3590{ 3591 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 3592 (data(), size(), __str.data(), __pos, __str.size()); 3593} 3594 3595template<class _CharT, class _Traits, class _Allocator> 3596template <class _Tp> 3597_EnableIf 3598< 3599 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 3600 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3601> 3602basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const _Tp& __t, 3603 size_type __pos) const 3604{ 3605 __self_view __sv = __t; 3606 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 3607 (data(), size(), __sv.data(), __pos, __sv.size()); 3608} 3609 3610template<class _CharT, class _Traits, class _Allocator> 3611inline 3612typename basic_string<_CharT, _Traits, _Allocator>::size_type 3613basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s, 3614 size_type __pos) const _NOEXCEPT 3615{ 3616 _LIBCPP_ASSERT(__s != nullptr, "string::find_first_not_of(): received nullptr"); 3617 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 3618 (data(), size(), __s, __pos, traits_type::length(__s)); 3619} 3620 3621template<class _CharT, class _Traits, class _Allocator> 3622inline 3623typename basic_string<_CharT, _Traits, _Allocator>::size_type 3624basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c, 3625 size_type __pos) const _NOEXCEPT 3626{ 3627 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 3628 (data(), size(), __c, __pos); 3629} 3630 3631// find_last_not_of 3632 3633template<class _CharT, class _Traits, class _Allocator> 3634typename basic_string<_CharT, _Traits, _Allocator>::size_type 3635basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s, 3636 size_type __pos, 3637 size_type __n) const _NOEXCEPT 3638{ 3639 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr"); 3640 return __str_find_last_not_of<value_type, size_type, traits_type, npos> 3641 (data(), size(), __s, __pos, __n); 3642} 3643 3644template<class _CharT, class _Traits, class _Allocator> 3645inline 3646typename basic_string<_CharT, _Traits, _Allocator>::size_type 3647basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string& __str, 3648 size_type __pos) const _NOEXCEPT 3649{ 3650 return __str_find_last_not_of<value_type, size_type, traits_type, npos> 3651 (data(), size(), __str.data(), __pos, __str.size()); 3652} 3653 3654template<class _CharT, class _Traits, class _Allocator> 3655template <class _Tp> 3656_EnableIf 3657< 3658 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 3659 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3660> 3661basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const _Tp& __t, 3662 size_type __pos) const 3663{ 3664 __self_view __sv = __t; 3665 return __str_find_last_not_of<value_type, size_type, traits_type, npos> 3666 (data(), size(), __sv.data(), __pos, __sv.size()); 3667} 3668 3669template<class _CharT, class _Traits, class _Allocator> 3670inline 3671typename basic_string<_CharT, _Traits, _Allocator>::size_type 3672basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s, 3673 size_type __pos) const _NOEXCEPT 3674{ 3675 _LIBCPP_ASSERT(__s != nullptr, "string::find_last_not_of(): received nullptr"); 3676 return __str_find_last_not_of<value_type, size_type, traits_type, npos> 3677 (data(), size(), __s, __pos, traits_type::length(__s)); 3678} 3679 3680template<class _CharT, class _Traits, class _Allocator> 3681inline 3682typename basic_string<_CharT, _Traits, _Allocator>::size_type 3683basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c, 3684 size_type __pos) const _NOEXCEPT 3685{ 3686 return __str_find_last_not_of<value_type, size_type, traits_type, npos> 3687 (data(), size(), __c, __pos); 3688} 3689 3690// compare 3691 3692template <class _CharT, class _Traits, class _Allocator> 3693template <class _Tp> 3694_EnableIf 3695< 3696 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 3697 int 3698> 3699basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const 3700{ 3701 __self_view __sv = __t; 3702 size_t __lhs_sz = size(); 3703 size_t __rhs_sz = __sv.size(); 3704 int __result = traits_type::compare(data(), __sv.data(), 3705 _VSTD::min(__lhs_sz, __rhs_sz)); 3706 if (__result != 0) 3707 return __result; 3708 if (__lhs_sz < __rhs_sz) 3709 return -1; 3710 if (__lhs_sz > __rhs_sz) 3711 return 1; 3712 return 0; 3713} 3714 3715template <class _CharT, class _Traits, class _Allocator> 3716inline 3717int 3718basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT 3719{ 3720 return compare(__self_view(__str)); 3721} 3722 3723template <class _CharT, class _Traits, class _Allocator> 3724int 3725basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, 3726 size_type __n1, 3727 const value_type* __s, 3728 size_type __n2) const 3729{ 3730 _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr"); 3731 size_type __sz = size(); 3732 if (__pos1 > __sz || __n2 == npos) 3733 this->__throw_out_of_range(); 3734 size_type __rlen = _VSTD::min(__n1, __sz - __pos1); 3735 int __r = traits_type::compare(data() + __pos1, __s, _VSTD::min(__rlen, __n2)); 3736 if (__r == 0) 3737 { 3738 if (__rlen < __n2) 3739 __r = -1; 3740 else if (__rlen > __n2) 3741 __r = 1; 3742 } 3743 return __r; 3744} 3745 3746template <class _CharT, class _Traits, class _Allocator> 3747template <class _Tp> 3748_EnableIf 3749< 3750 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 3751 int 3752> 3753basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, 3754 size_type __n1, 3755 const _Tp& __t) const 3756{ 3757 __self_view __sv = __t; 3758 return compare(__pos1, __n1, __sv.data(), __sv.size()); 3759} 3760 3761template <class _CharT, class _Traits, class _Allocator> 3762inline 3763int 3764basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, 3765 size_type __n1, 3766 const basic_string& __str) const 3767{ 3768 return compare(__pos1, __n1, __str.data(), __str.size()); 3769} 3770 3771template <class _CharT, class _Traits, class _Allocator> 3772template <class _Tp> 3773_EnableIf 3774< 3775 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value 3776 && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 3777 int 3778> 3779basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, 3780 size_type __n1, 3781 const _Tp& __t, 3782 size_type __pos2, 3783 size_type __n2) const 3784{ 3785 __self_view __sv = __t; 3786 return __self_view(*this).substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2)); 3787} 3788 3789template <class _CharT, class _Traits, class _Allocator> 3790int 3791basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, 3792 size_type __n1, 3793 const basic_string& __str, 3794 size_type __pos2, 3795 size_type __n2) const 3796{ 3797 return compare(__pos1, __n1, __self_view(__str), __pos2, __n2); 3798} 3799 3800template <class _CharT, class _Traits, class _Allocator> 3801int 3802basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT 3803{ 3804 _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr"); 3805 return compare(0, npos, __s, traits_type::length(__s)); 3806} 3807 3808template <class _CharT, class _Traits, class _Allocator> 3809int 3810basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, 3811 size_type __n1, 3812 const value_type* __s) const 3813{ 3814 _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr"); 3815 return compare(__pos1, __n1, __s, traits_type::length(__s)); 3816} 3817 3818// __invariants 3819 3820template<class _CharT, class _Traits, class _Allocator> 3821inline 3822bool 3823basic_string<_CharT, _Traits, _Allocator>::__invariants() const 3824{ 3825 if (size() > capacity()) 3826 return false; 3827 if (capacity() < __min_cap - 1) 3828 return false; 3829 if (data() == 0) 3830 return false; 3831 if (data()[size()] != value_type(0)) 3832 return false; 3833 return true; 3834} 3835 3836// __clear_and_shrink 3837 3838template<class _CharT, class _Traits, class _Allocator> 3839inline 3840void 3841basic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT 3842{ 3843 clear(); 3844 if(__is_long()) 3845 { 3846 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), capacity() + 1); 3847 __set_long_cap(0); 3848 __set_short_size(0); 3849 } 3850} 3851 3852// operator== 3853 3854template<class _CharT, class _Traits, class _Allocator> 3855inline _LIBCPP_INLINE_VISIBILITY 3856bool 3857operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3858 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 3859{ 3860 size_t __lhs_sz = __lhs.size(); 3861 return __lhs_sz == __rhs.size() && _Traits::compare(__lhs.data(), 3862 __rhs.data(), 3863 __lhs_sz) == 0; 3864} 3865 3866template<class _Allocator> 3867inline _LIBCPP_INLINE_VISIBILITY 3868bool 3869operator==(const basic_string<char, char_traits<char>, _Allocator>& __lhs, 3870 const basic_string<char, char_traits<char>, _Allocator>& __rhs) _NOEXCEPT 3871{ 3872 size_t __lhs_sz = __lhs.size(); 3873 if (__lhs_sz != __rhs.size()) 3874 return false; 3875 const char* __lp = __lhs.data(); 3876 const char* __rp = __rhs.data(); 3877 if (__lhs.__is_long()) 3878 return char_traits<char>::compare(__lp, __rp, __lhs_sz) == 0; 3879 for (; __lhs_sz != 0; --__lhs_sz, ++__lp, ++__rp) 3880 if (*__lp != *__rp) 3881 return false; 3882 return true; 3883} 3884 3885template<class _CharT, class _Traits, class _Allocator> 3886inline _LIBCPP_INLINE_VISIBILITY 3887bool 3888operator==(const _CharT* __lhs, 3889 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 3890{ 3891 typedef basic_string<_CharT, _Traits, _Allocator> _String; 3892 _LIBCPP_ASSERT(__lhs != nullptr, "operator==(char*, basic_string): received nullptr"); 3893 size_t __lhs_len = _Traits::length(__lhs); 3894 if (__lhs_len != __rhs.size()) return false; 3895 return __rhs.compare(0, _String::npos, __lhs, __lhs_len) == 0; 3896} 3897 3898template<class _CharT, class _Traits, class _Allocator> 3899inline _LIBCPP_INLINE_VISIBILITY 3900bool 3901operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 3902 const _CharT* __rhs) _NOEXCEPT 3903{ 3904 typedef basic_string<_CharT, _Traits, _Allocator> _String; 3905 _LIBCPP_ASSERT(__rhs != nullptr, "operator==(basic_string, char*): received nullptr"); 3906 size_t __rhs_len = _Traits::length(__rhs); 3907 if (__rhs_len != __lhs.size()) return false; 3908 return __lhs.compare(0, _String::npos, __rhs, __rhs_len) == 0; 3909} 3910 3911template<class _CharT, class _Traits, class _Allocator> 3912inline _LIBCPP_INLINE_VISIBILITY 3913bool 3914operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 3915 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 3916{ 3917 return !(__lhs == __rhs); 3918} 3919 3920template<class _CharT, class _Traits, class _Allocator> 3921inline _LIBCPP_INLINE_VISIBILITY 3922bool 3923operator!=(const _CharT* __lhs, 3924 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 3925{ 3926 return !(__lhs == __rhs); 3927} 3928 3929template<class _CharT, class _Traits, class _Allocator> 3930inline _LIBCPP_INLINE_VISIBILITY 3931bool 3932operator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3933 const _CharT* __rhs) _NOEXCEPT 3934{ 3935 return !(__lhs == __rhs); 3936} 3937 3938// operator< 3939 3940template<class _CharT, class _Traits, class _Allocator> 3941inline _LIBCPP_INLINE_VISIBILITY 3942bool 3943operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3944 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 3945{ 3946 return __lhs.compare(__rhs) < 0; 3947} 3948 3949template<class _CharT, class _Traits, class _Allocator> 3950inline _LIBCPP_INLINE_VISIBILITY 3951bool 3952operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3953 const _CharT* __rhs) _NOEXCEPT 3954{ 3955 return __lhs.compare(__rhs) < 0; 3956} 3957 3958template<class _CharT, class _Traits, class _Allocator> 3959inline _LIBCPP_INLINE_VISIBILITY 3960bool 3961operator< (const _CharT* __lhs, 3962 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 3963{ 3964 return __rhs.compare(__lhs) > 0; 3965} 3966 3967// operator> 3968 3969template<class _CharT, class _Traits, class _Allocator> 3970inline _LIBCPP_INLINE_VISIBILITY 3971bool 3972operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3973 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 3974{ 3975 return __rhs < __lhs; 3976} 3977 3978template<class _CharT, class _Traits, class _Allocator> 3979inline _LIBCPP_INLINE_VISIBILITY 3980bool 3981operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3982 const _CharT* __rhs) _NOEXCEPT 3983{ 3984 return __rhs < __lhs; 3985} 3986 3987template<class _CharT, class _Traits, class _Allocator> 3988inline _LIBCPP_INLINE_VISIBILITY 3989bool 3990operator> (const _CharT* __lhs, 3991 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 3992{ 3993 return __rhs < __lhs; 3994} 3995 3996// operator<= 3997 3998template<class _CharT, class _Traits, class _Allocator> 3999inline _LIBCPP_INLINE_VISIBILITY 4000bool 4001operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4002 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4003{ 4004 return !(__rhs < __lhs); 4005} 4006 4007template<class _CharT, class _Traits, class _Allocator> 4008inline _LIBCPP_INLINE_VISIBILITY 4009bool 4010operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4011 const _CharT* __rhs) _NOEXCEPT 4012{ 4013 return !(__rhs < __lhs); 4014} 4015 4016template<class _CharT, class _Traits, class _Allocator> 4017inline _LIBCPP_INLINE_VISIBILITY 4018bool 4019operator<=(const _CharT* __lhs, 4020 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4021{ 4022 return !(__rhs < __lhs); 4023} 4024 4025// operator>= 4026 4027template<class _CharT, class _Traits, class _Allocator> 4028inline _LIBCPP_INLINE_VISIBILITY 4029bool 4030operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4031 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4032{ 4033 return !(__lhs < __rhs); 4034} 4035 4036template<class _CharT, class _Traits, class _Allocator> 4037inline _LIBCPP_INLINE_VISIBILITY 4038bool 4039operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4040 const _CharT* __rhs) _NOEXCEPT 4041{ 4042 return !(__lhs < __rhs); 4043} 4044 4045template<class _CharT, class _Traits, class _Allocator> 4046inline _LIBCPP_INLINE_VISIBILITY 4047bool 4048operator>=(const _CharT* __lhs, 4049 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4050{ 4051 return !(__lhs < __rhs); 4052} 4053 4054// operator + 4055 4056template<class _CharT, class _Traits, class _Allocator> 4057basic_string<_CharT, _Traits, _Allocator> 4058operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4059 const basic_string<_CharT, _Traits, _Allocator>& __rhs) 4060{ 4061 basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator()); 4062 typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size(); 4063 typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size(); 4064 __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + __rhs_sz); 4065 __r.append(__rhs.data(), __rhs_sz); 4066 return __r; 4067} 4068 4069template<class _CharT, class _Traits, class _Allocator> 4070basic_string<_CharT, _Traits, _Allocator> 4071operator+(const _CharT* __lhs , const basic_string<_CharT,_Traits,_Allocator>& __rhs) 4072{ 4073 basic_string<_CharT, _Traits, _Allocator> __r(__rhs.get_allocator()); 4074 typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = _Traits::length(__lhs); 4075 typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size(); 4076 __r.__init(__lhs, __lhs_sz, __lhs_sz + __rhs_sz); 4077 __r.append(__rhs.data(), __rhs_sz); 4078 return __r; 4079} 4080 4081template<class _CharT, class _Traits, class _Allocator> 4082basic_string<_CharT, _Traits, _Allocator> 4083operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Allocator>& __rhs) 4084{ 4085 basic_string<_CharT, _Traits, _Allocator> __r(__rhs.get_allocator()); 4086 typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size(); 4087 __r.__init(&__lhs, 1, 1 + __rhs_sz); 4088 __r.append(__rhs.data(), __rhs_sz); 4089 return __r; 4090} 4091 4092template<class _CharT, class _Traits, class _Allocator> 4093inline 4094basic_string<_CharT, _Traits, _Allocator> 4095operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) 4096{ 4097 basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator()); 4098 typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size(); 4099 typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = _Traits::length(__rhs); 4100 __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + __rhs_sz); 4101 __r.append(__rhs, __rhs_sz); 4102 return __r; 4103} 4104 4105template<class _CharT, class _Traits, class _Allocator> 4106basic_string<_CharT, _Traits, _Allocator> 4107operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs) 4108{ 4109 basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator()); 4110 typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size(); 4111 __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + 1); 4112 __r.push_back(__rhs); 4113 return __r; 4114} 4115 4116#ifndef _LIBCPP_CXX03_LANG 4117 4118template<class _CharT, class _Traits, class _Allocator> 4119inline _LIBCPP_INLINE_VISIBILITY 4120basic_string<_CharT, _Traits, _Allocator> 4121operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) 4122{ 4123 return _VSTD::move(__lhs.append(__rhs)); 4124} 4125 4126template<class _CharT, class _Traits, class _Allocator> 4127inline _LIBCPP_INLINE_VISIBILITY 4128basic_string<_CharT, _Traits, _Allocator> 4129operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs) 4130{ 4131 return _VSTD::move(__rhs.insert(0, __lhs)); 4132} 4133 4134template<class _CharT, class _Traits, class _Allocator> 4135inline _LIBCPP_INLINE_VISIBILITY 4136basic_string<_CharT, _Traits, _Allocator> 4137operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs) 4138{ 4139 return _VSTD::move(__lhs.append(__rhs)); 4140} 4141 4142template<class _CharT, class _Traits, class _Allocator> 4143inline _LIBCPP_INLINE_VISIBILITY 4144basic_string<_CharT, _Traits, _Allocator> 4145operator+(const _CharT* __lhs , basic_string<_CharT,_Traits,_Allocator>&& __rhs) 4146{ 4147 return _VSTD::move(__rhs.insert(0, __lhs)); 4148} 4149 4150template<class _CharT, class _Traits, class _Allocator> 4151inline _LIBCPP_INLINE_VISIBILITY 4152basic_string<_CharT, _Traits, _Allocator> 4153operator+(_CharT __lhs, basic_string<_CharT,_Traits,_Allocator>&& __rhs) 4154{ 4155 __rhs.insert(__rhs.begin(), __lhs); 4156 return _VSTD::move(__rhs); 4157} 4158 4159template<class _CharT, class _Traits, class _Allocator> 4160inline _LIBCPP_INLINE_VISIBILITY 4161basic_string<_CharT, _Traits, _Allocator> 4162operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const _CharT* __rhs) 4163{ 4164 return _VSTD::move(__lhs.append(__rhs)); 4165} 4166 4167template<class _CharT, class _Traits, class _Allocator> 4168inline _LIBCPP_INLINE_VISIBILITY 4169basic_string<_CharT, _Traits, _Allocator> 4170operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT __rhs) 4171{ 4172 __lhs.push_back(__rhs); 4173 return _VSTD::move(__lhs); 4174} 4175 4176#endif // _LIBCPP_CXX03_LANG 4177 4178// swap 4179 4180template<class _CharT, class _Traits, class _Allocator> 4181inline _LIBCPP_INLINE_VISIBILITY 4182void 4183swap(basic_string<_CharT, _Traits, _Allocator>& __lhs, 4184 basic_string<_CharT, _Traits, _Allocator>& __rhs) 4185 _NOEXCEPT_(_NOEXCEPT_(__lhs.swap(__rhs))) 4186{ 4187 __lhs.swap(__rhs); 4188} 4189 4190#ifndef _LIBCPP_NO_HAS_CHAR8_T 4191typedef basic_string<char8_t> u8string; 4192#endif 4193 4194#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS 4195typedef basic_string<char16_t> u16string; 4196typedef basic_string<char32_t> u32string; 4197#endif // _LIBCPP_HAS_NO_UNICODE_CHARS 4198 4199_LIBCPP_FUNC_VIS int stoi (const string& __str, size_t* __idx = 0, int __base = 10); 4200_LIBCPP_FUNC_VIS long stol (const string& __str, size_t* __idx = 0, int __base = 10); 4201_LIBCPP_FUNC_VIS unsigned long stoul (const string& __str, size_t* __idx = 0, int __base = 10); 4202_LIBCPP_FUNC_VIS long long stoll (const string& __str, size_t* __idx = 0, int __base = 10); 4203_LIBCPP_FUNC_VIS unsigned long long stoull(const string& __str, size_t* __idx = 0, int __base = 10); 4204 4205_LIBCPP_FUNC_VIS float stof (const string& __str, size_t* __idx = 0); 4206_LIBCPP_FUNC_VIS double stod (const string& __str, size_t* __idx = 0); 4207_LIBCPP_FUNC_VIS long double stold(const string& __str, size_t* __idx = 0); 4208 4209_LIBCPP_FUNC_VIS string to_string(int __val); 4210_LIBCPP_FUNC_VIS string to_string(unsigned __val); 4211_LIBCPP_FUNC_VIS string to_string(long __val); 4212_LIBCPP_FUNC_VIS string to_string(unsigned long __val); 4213_LIBCPP_FUNC_VIS string to_string(long long __val); 4214_LIBCPP_FUNC_VIS string to_string(unsigned long long __val); 4215_LIBCPP_FUNC_VIS string to_string(float __val); 4216_LIBCPP_FUNC_VIS string to_string(double __val); 4217_LIBCPP_FUNC_VIS string to_string(long double __val); 4218 4219_LIBCPP_FUNC_VIS int stoi (const wstring& __str, size_t* __idx = 0, int __base = 10); 4220_LIBCPP_FUNC_VIS long stol (const wstring& __str, size_t* __idx = 0, int __base = 10); 4221_LIBCPP_FUNC_VIS unsigned long stoul (const wstring& __str, size_t* __idx = 0, int __base = 10); 4222_LIBCPP_FUNC_VIS long long stoll (const wstring& __str, size_t* __idx = 0, int __base = 10); 4223_LIBCPP_FUNC_VIS unsigned long long stoull(const wstring& __str, size_t* __idx = 0, int __base = 10); 4224 4225_LIBCPP_FUNC_VIS float stof (const wstring& __str, size_t* __idx = 0); 4226_LIBCPP_FUNC_VIS double stod (const wstring& __str, size_t* __idx = 0); 4227_LIBCPP_FUNC_VIS long double stold(const wstring& __str, size_t* __idx = 0); 4228 4229_LIBCPP_FUNC_VIS wstring to_wstring(int __val); 4230_LIBCPP_FUNC_VIS wstring to_wstring(unsigned __val); 4231_LIBCPP_FUNC_VIS wstring to_wstring(long __val); 4232_LIBCPP_FUNC_VIS wstring to_wstring(unsigned long __val); 4233_LIBCPP_FUNC_VIS wstring to_wstring(long long __val); 4234_LIBCPP_FUNC_VIS wstring to_wstring(unsigned long long __val); 4235_LIBCPP_FUNC_VIS wstring to_wstring(float __val); 4236_LIBCPP_FUNC_VIS wstring to_wstring(double __val); 4237_LIBCPP_FUNC_VIS wstring to_wstring(long double __val); 4238 4239template<class _CharT, class _Traits, class _Allocator> 4240_LIBCPP_FUNC_VIS 4241const typename basic_string<_CharT, _Traits, _Allocator>::size_type 4242 basic_string<_CharT, _Traits, _Allocator>::npos; 4243 4244template <class _CharT, class _Allocator> 4245struct _LIBCPP_TEMPLATE_VIS 4246 hash<basic_string<_CharT, char_traits<_CharT>, _Allocator> > 4247 : public unary_function< 4248 basic_string<_CharT, char_traits<_CharT>, _Allocator>, size_t> 4249{ 4250 size_t 4251 operator()(const basic_string<_CharT, char_traits<_CharT>, _Allocator>& __val) const _NOEXCEPT 4252 { return __do_string_hash(__val.data(), __val.data() + __val.size()); } 4253}; 4254 4255 4256template<class _CharT, class _Traits, class _Allocator> 4257basic_ostream<_CharT, _Traits>& 4258operator<<(basic_ostream<_CharT, _Traits>& __os, 4259 const basic_string<_CharT, _Traits, _Allocator>& __str); 4260 4261template<class _CharT, class _Traits, class _Allocator> 4262basic_istream<_CharT, _Traits>& 4263operator>>(basic_istream<_CharT, _Traits>& __is, 4264 basic_string<_CharT, _Traits, _Allocator>& __str); 4265 4266template<class _CharT, class _Traits, class _Allocator> 4267basic_istream<_CharT, _Traits>& 4268getline(basic_istream<_CharT, _Traits>& __is, 4269 basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm); 4270 4271template<class _CharT, class _Traits, class _Allocator> 4272inline _LIBCPP_INLINE_VISIBILITY 4273basic_istream<_CharT, _Traits>& 4274getline(basic_istream<_CharT, _Traits>& __is, 4275 basic_string<_CharT, _Traits, _Allocator>& __str); 4276 4277#ifndef _LIBCPP_CXX03_LANG 4278 4279template<class _CharT, class _Traits, class _Allocator> 4280inline _LIBCPP_INLINE_VISIBILITY 4281basic_istream<_CharT, _Traits>& 4282getline(basic_istream<_CharT, _Traits>&& __is, 4283 basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm); 4284 4285template<class _CharT, class _Traits, class _Allocator> 4286inline _LIBCPP_INLINE_VISIBILITY 4287basic_istream<_CharT, _Traits>& 4288getline(basic_istream<_CharT, _Traits>&& __is, 4289 basic_string<_CharT, _Traits, _Allocator>& __str); 4290 4291#endif // _LIBCPP_CXX03_LANG 4292 4293#if _LIBCPP_STD_VER > 17 4294template<class _CharT, class _Traits, class _Allocator, class _Up> 4295inline _LIBCPP_INLINE_VISIBILITY 4296void erase(basic_string<_CharT, _Traits, _Allocator>& __str, const _Up& __v) 4297{ __str.erase(_VSTD::remove(__str.begin(), __str.end(), __v), __str.end()); } 4298 4299template<class _CharT, class _Traits, class _Allocator, class _Predicate> 4300inline _LIBCPP_INLINE_VISIBILITY 4301void erase_if(basic_string<_CharT, _Traits, _Allocator>& __str, _Predicate __pred) 4302{ __str.erase(_VSTD::remove_if(__str.begin(), __str.end(), __pred), __str.end()); } 4303#endif 4304 4305#if _LIBCPP_DEBUG_LEVEL >= 2 4306 4307template<class _CharT, class _Traits, class _Allocator> 4308bool 4309basic_string<_CharT, _Traits, _Allocator>::__dereferenceable(const const_iterator* __i) const 4310{ 4311 return this->data() <= _VSTD::__to_address(__i->base()) && 4312 _VSTD::__to_address(__i->base()) < this->data() + this->size(); 4313} 4314 4315template<class _CharT, class _Traits, class _Allocator> 4316bool 4317basic_string<_CharT, _Traits, _Allocator>::__decrementable(const const_iterator* __i) const 4318{ 4319 return this->data() < _VSTD::__to_address(__i->base()) && 4320 _VSTD::__to_address(__i->base()) <= this->data() + this->size(); 4321} 4322 4323template<class _CharT, class _Traits, class _Allocator> 4324bool 4325basic_string<_CharT, _Traits, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const 4326{ 4327 const value_type* __p = _VSTD::__to_address(__i->base()) + __n; 4328 return this->data() <= __p && __p <= this->data() + this->size(); 4329} 4330 4331template<class _CharT, class _Traits, class _Allocator> 4332bool 4333basic_string<_CharT, _Traits, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const 4334{ 4335 const value_type* __p = _VSTD::__to_address(__i->base()) + __n; 4336 return this->data() <= __p && __p < this->data() + this->size(); 4337} 4338 4339#endif // _LIBCPP_DEBUG_LEVEL >= 2 4340 4341_LIBCPP_STRING_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, char) 4342_LIBCPP_STRING_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, wchar_t) 4343 4344#if _LIBCPP_STD_VER > 11 4345// Literal suffixes for basic_string [basic.string.literals] 4346inline namespace literals 4347{ 4348 inline namespace string_literals 4349 { 4350 inline _LIBCPP_INLINE_VISIBILITY 4351 basic_string<char> operator "" s( const char *__str, size_t __len ) 4352 { 4353 return basic_string<char> (__str, __len); 4354 } 4355 4356 inline _LIBCPP_INLINE_VISIBILITY 4357 basic_string<wchar_t> operator "" s( const wchar_t *__str, size_t __len ) 4358 { 4359 return basic_string<wchar_t> (__str, __len); 4360 } 4361 4362#ifndef _LIBCPP_NO_HAS_CHAR8_T 4363 inline _LIBCPP_INLINE_VISIBILITY 4364 basic_string<char8_t> operator "" s(const char8_t *__str, size_t __len) _NOEXCEPT 4365 { 4366 return basic_string<char8_t> (__str, __len); 4367 } 4368#endif 4369 4370 inline _LIBCPP_INLINE_VISIBILITY 4371 basic_string<char16_t> operator "" s( const char16_t *__str, size_t __len ) 4372 { 4373 return basic_string<char16_t> (__str, __len); 4374 } 4375 4376 inline _LIBCPP_INLINE_VISIBILITY 4377 basic_string<char32_t> operator "" s( const char32_t *__str, size_t __len ) 4378 { 4379 return basic_string<char32_t> (__str, __len); 4380 } 4381 } 4382} 4383#endif 4384 4385_LIBCPP_END_NAMESPACE_STD 4386 4387_LIBCPP_POP_MACROS 4388 4389#endif // _LIBCPP_STRING 4390