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