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