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