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