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