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