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_([](basic_string &__s) -> decltype(__s.__r_)&& { if(!__s.__is_long()) __s.__annotate_delete(); return std::move(__s.__r_); }(__str)) { 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 (__asan_annotate_container_with_allocator<allocator_type>::value && !__libcpp_is_constant_evaluated()) 1895 __sanitizer_annotate_contiguous_container(__begin, __end, __old_mid, __new_mid); 1896#endif 1897 } 1898 1899 // ASan: short string is poisoned if and only if this function returns true. 1900 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __asan_short_string_is_annotated() const _NOEXCEPT { 1901 return _LIBCPP_SHORT_STRING_ANNOTATIONS_ALLOWED && !__libcpp_is_constant_evaluated(); 1902 } 1903 1904 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __annotate_new(size_type __current_size) const _NOEXCEPT { 1905 (void) __current_size; 1906#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN) 1907 if (!__libcpp_is_constant_evaluated() && (__asan_short_string_is_annotated() || __is_long())) 1908 __annotate_contiguous_container(data() + capacity() + 1, data() + __current_size + 1); 1909#endif 1910 } 1911 1912 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __annotate_delete() const _NOEXCEPT { 1913#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN) 1914 if (!__libcpp_is_constant_evaluated() && (__asan_short_string_is_annotated() || __is_long())) 1915 __annotate_contiguous_container(data() + size() + 1, data() + capacity() + 1); 1916#endif 1917 } 1918 1919 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __annotate_increase(size_type __n) const _NOEXCEPT { 1920 (void) __n; 1921#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN) 1922 if (!__libcpp_is_constant_evaluated() && (__asan_short_string_is_annotated() || __is_long())) 1923 __annotate_contiguous_container(data() + size() + 1, data() + size() + 1 + __n); 1924#endif 1925 } 1926 1927 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __annotate_shrink(size_type __old_size) const _NOEXCEPT { 1928 (void) __old_size; 1929#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN) 1930 if (!__libcpp_is_constant_evaluated() && (__asan_short_string_is_annotated() || __is_long())) 1931 __annotate_contiguous_container(data() + __old_size + 1, data() + size() + 1); 1932#endif 1933 } 1934 1935 template <size_type __a> 1936 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __align_it(size_type __s) _NOEXCEPT { 1937 return (__s + (__a - 1)) & ~(__a - 1); 1938 } 1939 enum { 1940 __alignment = 8 1941 }; 1942 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __recommend(size_type __s) _NOEXCEPT { 1943 if (__s < __min_cap) { 1944 return static_cast<size_type>(__min_cap) - 1; 1945 } 1946 const size_type __boundary = sizeof(value_type) < __alignment ? __alignment / sizeof(value_type) : __endian_factor; 1947 size_type __guess = __align_it<__boundary>(__s + 1) - 1; 1948 if (__guess == __min_cap) 1949 __guess += __endian_factor; 1950 return __guess; 1951 } 1952 1953 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init(const value_type* __s, size_type __sz, size_type __reserve); 1954 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init(const value_type* __s, size_type __sz); 1955 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init(size_type __n, value_type __c); 1956 1957 // Slow path for the (inlined) copy constructor for 'long' strings. 1958 // Always externally instantiated and not inlined. 1959 // Requires that __s is zero terminated. 1960 // The main reason for this function to exist is because for unstable, we 1961 // want to allow inlining of the copy constructor. However, we don't want 1962 // to call the __init() functions as those are marked as inline which may 1963 // result in over-aggressive inlining by the compiler, where our aim is 1964 // to only inline the fast path code directly in the ctor. 1965 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE void __init_copy_ctor_external(const value_type* __s, size_type __sz); 1966 1967 template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0> 1968 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init(_InputIterator __first, _InputIterator __last); 1969 1970 template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0> 1971 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init(_ForwardIterator __first, _ForwardIterator __last); 1972 1973 template <class _InputIterator, class _Sentinel> 1974 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 1975 __init_with_sentinel(_InputIterator __first, _Sentinel __last); 1976 template <class _InputIterator, class _Sentinel> 1977 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 1978 __init_with_size(_InputIterator __first, _Sentinel __last, size_type __sz); 1979 1980 _LIBCPP_CONSTEXPR_SINCE_CXX20 1981#if _LIBCPP_ABI_VERSION >= 2 // We want to use the function in the dylib in ABIv1 1982 _LIBCPP_HIDE_FROM_ABI 1983#endif 1984 _LIBCPP_DEPRECATED_("use __grow_by_without_replace") void __grow_by( 1985 size_type __old_cap, 1986 size_type __delta_cap, 1987 size_type __old_sz, 1988 size_type __n_copy, 1989 size_type __n_del, 1990 size_type __n_add = 0); 1991 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __grow_by_without_replace( 1992 size_type __old_cap, 1993 size_type __delta_cap, 1994 size_type __old_sz, 1995 size_type __n_copy, 1996 size_type __n_del, 1997 size_type __n_add = 0); 1998 _LIBCPP_CONSTEXPR_SINCE_CXX20 void __grow_by_and_replace( 1999 size_type __old_cap, 2000 size_type __delta_cap, 2001 size_type __old_sz, 2002 size_type __n_copy, 2003 size_type __n_del, 2004 size_type __n_add, 2005 const value_type* __p_new_stuff); 2006 2007 // __assign_no_alias is invoked for assignment operations where we 2008 // have proof that the input does not alias the current instance. 2009 // For example, operator=(basic_string) performs a 'self' check. 2010 template <bool __is_short> 2011 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE basic_string& __assign_no_alias(const value_type* __s, size_type __n); 2012 2013 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __erase_to_end(size_type __pos) { 2014 __null_terminate_at(std::__to_address(__get_pointer()), __pos); 2015 } 2016 2017 // __erase_external_with_move is invoked for erase() invocations where 2018 // `n ~= npos`, likely requiring memory moves on the string data. 2019 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE void __erase_external_with_move(size_type __pos, size_type __n); 2020 2021 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __copy_assign_alloc(const basic_string& __str) { 2022 __copy_assign_alloc( 2023 __str, integral_constant<bool, __alloc_traits::propagate_on_container_copy_assignment::value>()); 2024 } 2025 2026 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __copy_assign_alloc(const basic_string& __str, true_type) { 2027 if (__alloc() == __str.__alloc()) 2028 __alloc() = __str.__alloc(); 2029 else { 2030 if (!__str.__is_long()) { 2031 __clear_and_shrink(); 2032 __alloc() = __str.__alloc(); 2033 } else { 2034 __annotate_delete(); 2035 allocator_type __a = __str.__alloc(); 2036 auto __allocation = std::__allocate_at_least(__a, __str.__get_long_cap()); 2037 __begin_lifetime(__allocation.ptr, __allocation.count); 2038 if (__is_long()) 2039 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 2040 __alloc() = std::move(__a); 2041 __set_long_pointer(__allocation.ptr); 2042 __set_long_cap(__allocation.count); 2043 __set_long_size(__str.size()); 2044 __annotate_new(__get_long_size()); 2045 } 2046 } 2047 } 2048 2049 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 2050 __copy_assign_alloc(const basic_string&, false_type) _NOEXCEPT {} 2051 2052#ifndef _LIBCPP_CXX03_LANG 2053 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign(basic_string& __str, false_type) 2054 _NOEXCEPT_(__alloc_traits::is_always_equal::value); 2055 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS void 2056 __move_assign(basic_string& __str, true_type) 2057# if _LIBCPP_STD_VER >= 17 2058 _NOEXCEPT; 2059# else 2060 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value); 2061# endif 2062#endif 2063 2064 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign_alloc(basic_string& __str) 2065 _NOEXCEPT_(!__alloc_traits::propagate_on_container_move_assignment::value || 2066 is_nothrow_move_assignable<allocator_type>::value) { 2067 __move_assign_alloc( 2068 __str, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>()); 2069 } 2070 2071 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign_alloc(basic_string& __c, true_type) 2072 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) { 2073 __alloc() = std::move(__c.__alloc()); 2074 } 2075 2076 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign_alloc(basic_string&, false_type) _NOEXCEPT {} 2077 2078 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE basic_string& __assign_external(const value_type* __s); 2079 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE basic_string& __assign_external(const value_type* __s, size_type __n); 2080 2081 // Assigns the value in __s, guaranteed to be __n < __min_cap in length. 2082 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& __assign_short(const value_type* __s, size_type __n) { 2083 size_type __old_size = size(); 2084 if (__n > __old_size) 2085 __annotate_increase(__n - __old_size); 2086 pointer __p = 2087 __is_long() ? (__set_long_size(__n), __get_long_pointer()) : (__set_short_size(__n), __get_short_pointer()); 2088 traits_type::move(std::__to_address(__p), __s, __n); 2089 traits_type::assign(__p[__n], value_type()); 2090 if (__old_size > __n) 2091 __annotate_shrink(__old_size); 2092 return *this; 2093 } 2094 2095 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 2096 __null_terminate_at(value_type* __p, size_type __newsz) { 2097 size_type __old_size = size(); 2098 if (__newsz > __old_size) 2099 __annotate_increase(__newsz - __old_size); 2100 __set_size(__newsz); 2101 traits_type::assign(__p[__newsz], value_type()); 2102 if (__old_size > __newsz) 2103 __annotate_shrink(__old_size); 2104 return *this; 2105 } 2106 2107 template <class _Tp> 2108 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __addr_in_range(const _Tp& __v) const { 2109 return std::__is_pointer_in_range(data(), data() + size() + 1, std::addressof(__v)); 2110 } 2111 2112 _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void __throw_length_error() const { 2113 std::__throw_length_error("basic_string"); 2114 } 2115 2116 _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void __throw_out_of_range() const { 2117 std::__throw_out_of_range("basic_string"); 2118 } 2119 2120 friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+ <>(const basic_string&, const basic_string&); 2121 friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+ <>(const value_type*, const basic_string&); 2122 friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+ <>(value_type, const basic_string&); 2123 friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+ <>(const basic_string&, const value_type*); 2124 friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+ <>(const basic_string&, value_type); 2125}; 2126 2127// These declarations must appear before any functions are implicitly used 2128// so that they have the correct visibility specifier. 2129#define _LIBCPP_DECLARE(...) extern template __VA_ARGS__; 2130#ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION 2131_LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, char) 2132# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 2133_LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, wchar_t) 2134# endif 2135#else 2136_LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, char) 2137# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 2138_LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, wchar_t) 2139# endif 2140#endif 2141#undef _LIBCPP_DECLARE 2142 2143#if _LIBCPP_STD_VER >= 17 2144template <class _InputIterator, 2145 class _CharT = __iter_value_type<_InputIterator>, 2146 class _Allocator = allocator<_CharT>, 2147 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, 2148 class = enable_if_t<__is_allocator<_Allocator>::value> > 2149basic_string(_InputIterator, _InputIterator, _Allocator = _Allocator()) 2150 -> basic_string<_CharT, char_traits<_CharT>, _Allocator>; 2151 2152template <class _CharT, 2153 class _Traits, 2154 class _Allocator = allocator<_CharT>, 2155 class = enable_if_t<__is_allocator<_Allocator>::value> > 2156explicit basic_string(basic_string_view<_CharT, _Traits>, const _Allocator& = _Allocator()) 2157 -> basic_string<_CharT, _Traits, _Allocator>; 2158 2159template <class _CharT, 2160 class _Traits, 2161 class _Allocator = allocator<_CharT>, 2162 class = enable_if_t<__is_allocator<_Allocator>::value>, 2163 class _Sz = typename allocator_traits<_Allocator>::size_type > 2164basic_string(basic_string_view<_CharT, _Traits>, _Sz, _Sz, const _Allocator& = _Allocator()) 2165 -> basic_string<_CharT, _Traits, _Allocator>; 2166#endif 2167 2168#if _LIBCPP_STD_VER >= 23 2169template <ranges::input_range _Range, 2170 class _Allocator = allocator<ranges::range_value_t<_Range>>, 2171 class = enable_if_t<__is_allocator<_Allocator>::value> > 2172basic_string(from_range_t, _Range&&, _Allocator = _Allocator()) 2173 -> basic_string<ranges::range_value_t<_Range>, char_traits<ranges::range_value_t<_Range>>, _Allocator>; 2174#endif 2175 2176template <class _CharT, class _Traits, class _Allocator> 2177_LIBCPP_CONSTEXPR_SINCE_CXX20 void 2178basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz, size_type __reserve) { 2179 if (__libcpp_is_constant_evaluated()) 2180 __r_.first() = __rep(); 2181 if (__reserve > max_size()) 2182 __throw_length_error(); 2183 pointer __p; 2184 if (__fits_in_sso(__reserve)) { 2185 __set_short_size(__sz); 2186 __p = __get_short_pointer(); 2187 } else { 2188 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__reserve) + 1); 2189 __p = __allocation.ptr; 2190 __begin_lifetime(__p, __allocation.count); 2191 __set_long_pointer(__p); 2192 __set_long_cap(__allocation.count); 2193 __set_long_size(__sz); 2194 } 2195 traits_type::copy(std::__to_address(__p), __s, __sz); 2196 traits_type::assign(__p[__sz], value_type()); 2197 __annotate_new(__sz); 2198} 2199 2200template <class _CharT, class _Traits, class _Allocator> 2201_LIBCPP_CONSTEXPR_SINCE_CXX20 void 2202basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz) { 2203 if (__libcpp_is_constant_evaluated()) 2204 __r_.first() = __rep(); 2205 if (__sz > max_size()) 2206 __throw_length_error(); 2207 pointer __p; 2208 if (__fits_in_sso(__sz)) { 2209 __set_short_size(__sz); 2210 __p = __get_short_pointer(); 2211 } else { 2212 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1); 2213 __p = __allocation.ptr; 2214 __begin_lifetime(__p, __allocation.count); 2215 __set_long_pointer(__p); 2216 __set_long_cap(__allocation.count); 2217 __set_long_size(__sz); 2218 } 2219 traits_type::copy(std::__to_address(__p), __s, __sz); 2220 traits_type::assign(__p[__sz], value_type()); 2221 __annotate_new(__sz); 2222} 2223 2224template <class _CharT, class _Traits, class _Allocator> 2225_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE void 2226basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external(const value_type* __s, size_type __sz) { 2227 if (__libcpp_is_constant_evaluated()) 2228 __r_.first() = __rep(); 2229 2230 pointer __p; 2231 if (__fits_in_sso(__sz)) { 2232 __p = __get_short_pointer(); 2233 __set_short_size(__sz); 2234 } else { 2235 if (__sz > max_size()) 2236 __throw_length_error(); 2237 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1); 2238 __p = __allocation.ptr; 2239 __begin_lifetime(__p, __allocation.count); 2240 __set_long_pointer(__p); 2241 __set_long_cap(__allocation.count); 2242 __set_long_size(__sz); 2243 } 2244 traits_type::copy(std::__to_address(__p), __s, __sz + 1); 2245 __annotate_new(__sz); 2246} 2247 2248template <class _CharT, class _Traits, class _Allocator> 2249_LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c) { 2250 if (__libcpp_is_constant_evaluated()) 2251 __r_.first() = __rep(); 2252 2253 if (__n > max_size()) 2254 __throw_length_error(); 2255 pointer __p; 2256 if (__fits_in_sso(__n)) { 2257 __set_short_size(__n); 2258 __p = __get_short_pointer(); 2259 } else { 2260 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__n) + 1); 2261 __p = __allocation.ptr; 2262 __begin_lifetime(__p, __allocation.count); 2263 __set_long_pointer(__p); 2264 __set_long_cap(__allocation.count); 2265 __set_long_size(__n); 2266 } 2267 traits_type::assign(std::__to_address(__p), __n, __c); 2268 traits_type::assign(__p[__n], value_type()); 2269 __annotate_new(__n); 2270} 2271 2272template <class _CharT, class _Traits, class _Allocator> 2273template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> > 2274_LIBCPP_CONSTEXPR_SINCE_CXX20 void 2275basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last) { 2276 __init_with_sentinel(std::move(__first), std::move(__last)); 2277} 2278 2279template <class _CharT, class _Traits, class _Allocator> 2280template <class _InputIterator, class _Sentinel> 2281_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 2282basic_string<_CharT, _Traits, _Allocator>::__init_with_sentinel(_InputIterator __first, _Sentinel __last) { 2283 __r_.first() = __rep(); 2284 __annotate_new(0); 2285 2286#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 2287 try { 2288#endif // _LIBCPP_HAS_NO_EXCEPTIONS 2289 for (; __first != __last; ++__first) 2290 push_back(*__first); 2291#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 2292 } catch (...) { 2293 __annotate_delete(); 2294 if (__is_long()) 2295 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 2296 throw; 2297 } 2298#endif // _LIBCPP_HAS_NO_EXCEPTIONS 2299} 2300 2301template <class _CharT, class _Traits, class _Allocator> 2302template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> > 2303_LIBCPP_CONSTEXPR_SINCE_CXX20 void 2304basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last) { 2305 size_type __sz = static_cast<size_type>(std::distance(__first, __last)); 2306 __init_with_size(__first, __last, __sz); 2307} 2308 2309template <class _CharT, class _Traits, class _Allocator> 2310template <class _InputIterator, class _Sentinel> 2311_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 2312basic_string<_CharT, _Traits, _Allocator>::__init_with_size(_InputIterator __first, _Sentinel __last, size_type __sz) { 2313 if (__libcpp_is_constant_evaluated()) 2314 __r_.first() = __rep(); 2315 2316 if (__sz > max_size()) 2317 __throw_length_error(); 2318 2319 pointer __p; 2320 if (__fits_in_sso(__sz)) { 2321 __set_short_size(__sz); 2322 __p = __get_short_pointer(); 2323 2324 } else { 2325 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1); 2326 __p = __allocation.ptr; 2327 __begin_lifetime(__p, __allocation.count); 2328 __set_long_pointer(__p); 2329 __set_long_cap(__allocation.count); 2330 __set_long_size(__sz); 2331 } 2332 2333#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 2334 try { 2335#endif // _LIBCPP_HAS_NO_EXCEPTIONS 2336 for (; __first != __last; ++__first, (void)++__p) 2337 traits_type::assign(*__p, *__first); 2338 traits_type::assign(*__p, value_type()); 2339#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 2340 } catch (...) { 2341 if (__is_long()) 2342 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 2343 throw; 2344 } 2345#endif // _LIBCPP_HAS_NO_EXCEPTIONS 2346 __annotate_new(__sz); 2347} 2348 2349template <class _CharT, class _Traits, class _Allocator> 2350_LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace( 2351 size_type __old_cap, 2352 size_type __delta_cap, 2353 size_type __old_sz, 2354 size_type __n_copy, 2355 size_type __n_del, 2356 size_type __n_add, 2357 const value_type* __p_new_stuff) { 2358 size_type __ms = max_size(); 2359 if (__delta_cap > __ms - __old_cap - 1) 2360 __throw_length_error(); 2361 pointer __old_p = __get_pointer(); 2362 size_type __cap = 2363 __old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms - 1; 2364 __annotate_delete(); 2365 auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1); 2366 pointer __p = __allocation.ptr; 2367 __begin_lifetime(__p, __allocation.count); 2368 if (__n_copy != 0) 2369 traits_type::copy(std::__to_address(__p), std::__to_address(__old_p), __n_copy); 2370 if (__n_add != 0) 2371 traits_type::copy(std::__to_address(__p) + __n_copy, __p_new_stuff, __n_add); 2372 size_type __sec_cp_sz = __old_sz - __n_del - __n_copy; 2373 if (__sec_cp_sz != 0) 2374 traits_type::copy( 2375 std::__to_address(__p) + __n_copy + __n_add, std::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz); 2376 if (__old_cap + 1 != __min_cap) 2377 __alloc_traits::deallocate(__alloc(), __old_p, __old_cap + 1); 2378 __set_long_pointer(__p); 2379 __set_long_cap(__allocation.count); 2380 __old_sz = __n_copy + __n_add + __sec_cp_sz; 2381 __set_long_size(__old_sz); 2382 traits_type::assign(__p[__old_sz], value_type()); 2383 __annotate_new(__old_cap + __delta_cap); 2384} 2385 2386// __grow_by is deprecated because it does not set the size. It may not update the size when the size is changed, and it 2387// may also not set the size at all when the string was short initially. This leads to unpredictable size value. It is 2388// not removed or changed to avoid breaking the ABI. 2389template <class _CharT, class _Traits, class _Allocator> 2390void _LIBCPP_CONSTEXPR_SINCE_CXX20 2391#if _LIBCPP_ABI_VERSION >= 2 // We want to use the function in the dylib in ABIv1 2392 _LIBCPP_HIDE_FROM_ABI 2393#endif 2394 _LIBCPP_DEPRECATED_("use __grow_by_without_replace") basic_string<_CharT, _Traits, _Allocator>::__grow_by( 2395 size_type __old_cap, 2396 size_type __delta_cap, 2397 size_type __old_sz, 2398 size_type __n_copy, 2399 size_type __n_del, 2400 size_type __n_add) { 2401 size_type __ms = max_size(); 2402 if (__delta_cap > __ms - __old_cap) 2403 __throw_length_error(); 2404 pointer __old_p = __get_pointer(); 2405 size_type __cap = 2406 __old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms - 1; 2407 __annotate_delete(); 2408 auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1); 2409 pointer __p = __allocation.ptr; 2410 __begin_lifetime(__p, __allocation.count); 2411 if (__n_copy != 0) 2412 traits_type::copy(std::__to_address(__p), std::__to_address(__old_p), __n_copy); 2413 size_type __sec_cp_sz = __old_sz - __n_del - __n_copy; 2414 if (__sec_cp_sz != 0) 2415 traits_type::copy( 2416 std::__to_address(__p) + __n_copy + __n_add, std::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz); 2417 if (__old_cap + 1 != __min_cap) 2418 __alloc_traits::deallocate(__alloc(), __old_p, __old_cap + 1); 2419 __set_long_pointer(__p); 2420 __set_long_cap(__allocation.count); 2421} 2422 2423template <class _CharT, class _Traits, class _Allocator> 2424void _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI 2425basic_string<_CharT, _Traits, _Allocator>::__grow_by_without_replace( 2426 size_type __old_cap, 2427 size_type __delta_cap, 2428 size_type __old_sz, 2429 size_type __n_copy, 2430 size_type __n_del, 2431 size_type __n_add) { 2432 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 2433 __grow_by(__old_cap, __delta_cap, __old_sz, __n_copy, __n_del, __n_add); 2434 _LIBCPP_SUPPRESS_DEPRECATED_POP 2435 __set_long_size(__old_sz - __n_del + __n_add); 2436 __annotate_new(__old_sz - __n_del + __n_add); 2437} 2438 2439// assign 2440 2441template <class _CharT, class _Traits, class _Allocator> 2442template <bool __is_short> 2443_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE basic_string<_CharT, _Traits, _Allocator>& 2444basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias(const value_type* __s, size_type __n) { 2445 size_type __cap = __is_short ? static_cast<size_type>(__min_cap) : __get_long_cap(); 2446 if (__n < __cap) { 2447 size_type __old_size = __is_short ? __get_short_size() : __get_long_size(); 2448 if (__n > __old_size) 2449 __annotate_increase(__n - __old_size); 2450 pointer __p = __is_short ? __get_short_pointer() : __get_long_pointer(); 2451 __is_short ? __set_short_size(__n) : __set_long_size(__n); 2452 traits_type::copy(std::__to_address(__p), __s, __n); 2453 traits_type::assign(__p[__n], value_type()); 2454 if (__old_size > __n) 2455 __annotate_shrink(__old_size); 2456 } else { 2457 size_type __sz = __is_short ? __get_short_size() : __get_long_size(); 2458 __grow_by_and_replace(__cap - 1, __n - __cap + 1, __sz, 0, __sz, __n, __s); 2459 } 2460 return *this; 2461} 2462 2463template <class _CharT, class _Traits, class _Allocator> 2464_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE basic_string<_CharT, _Traits, _Allocator>& 2465basic_string<_CharT, _Traits, _Allocator>::__assign_external(const value_type* __s, size_type __n) { 2466 size_type __cap = capacity(); 2467 if (__cap >= __n) { 2468 size_type __old_size = size(); 2469 if (__n > __old_size) 2470 __annotate_increase(__n - __old_size); 2471 value_type* __p = std::__to_address(__get_pointer()); 2472 traits_type::move(__p, __s, __n); 2473 return __null_terminate_at(__p, __n); 2474 } else { 2475 size_type __sz = size(); 2476 __grow_by_and_replace(__cap, __n - __cap, __sz, 0, __sz, __n, __s); 2477 return *this; 2478 } 2479} 2480 2481template <class _CharT, class _Traits, class _Allocator> 2482_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2483basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n) { 2484 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::assign received nullptr"); 2485 return (__builtin_constant_p(__n) && __fits_in_sso(__n)) ? __assign_short(__s, __n) : __assign_external(__s, __n); 2486} 2487 2488template <class _CharT, class _Traits, class _Allocator> 2489_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2490basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c) { 2491 size_type __cap = capacity(); 2492 size_type __old_size = size(); 2493 if (__cap < __n) { 2494 size_type __sz = size(); 2495 __grow_by_without_replace(__cap, __n - __cap, __sz, 0, __sz); 2496 __annotate_increase(__n); 2497 } else if (__n > __old_size) 2498 __annotate_increase(__n - __old_size); 2499 value_type* __p = std::__to_address(__get_pointer()); 2500 traits_type::assign(__p, __n, __c); 2501 return __null_terminate_at(__p, __n); 2502} 2503 2504template <class _CharT, class _Traits, class _Allocator> 2505_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2506basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c) { 2507 pointer __p; 2508 size_type __old_size = size(); 2509 if (__old_size == 0) 2510 __annotate_increase(1); 2511 if (__is_long()) { 2512 __p = __get_long_pointer(); 2513 __set_long_size(1); 2514 } else { 2515 __p = __get_short_pointer(); 2516 __set_short_size(1); 2517 } 2518 traits_type::assign(*__p, __c); 2519 traits_type::assign(*++__p, value_type()); 2520 if (__old_size > 1) 2521 __annotate_shrink(__old_size); 2522 return *this; 2523} 2524 2525template <class _CharT, class _Traits, class _Allocator> 2526_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS basic_string<_CharT, _Traits, _Allocator>& 2527basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str) { 2528 if (this != std::addressof(__str)) { 2529 __copy_assign_alloc(__str); 2530 if (!__is_long()) { 2531 if (!__str.__is_long()) { 2532 size_type __old_size = __get_short_size(); 2533 if (__get_short_size() < __str.__get_short_size()) 2534 __annotate_increase(__str.__get_short_size() - __get_short_size()); 2535 __r_.first() = __str.__r_.first(); 2536 if (__old_size > __get_short_size()) 2537 __annotate_shrink(__old_size); 2538 } else { 2539 return __assign_no_alias<true>(__str.data(), __str.size()); 2540 } 2541 } else { 2542 return __assign_no_alias<false>(__str.data(), __str.size()); 2543 } 2544 } 2545 return *this; 2546} 2547 2548#ifndef _LIBCPP_CXX03_LANG 2549 2550template <class _CharT, class _Traits, class _Allocator> 2551inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void 2552basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, false_type) 2553 _NOEXCEPT_(__alloc_traits::is_always_equal::value) { 2554 if (__alloc() != __str.__alloc()) 2555 assign(__str); 2556 else 2557 __move_assign(__str, true_type()); 2558} 2559 2560template <class _CharT, class _Traits, class _Allocator> 2561inline _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS void 2562basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type) 2563# if _LIBCPP_STD_VER >= 17 2564 _NOEXCEPT 2565# else 2566 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) 2567# endif 2568{ 2569 __annotate_delete(); 2570 if (__is_long()) { 2571 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 2572# if _LIBCPP_STD_VER <= 14 2573 if (!is_nothrow_move_assignable<allocator_type>::value) { 2574 __set_short_size(0); 2575 traits_type::assign(__get_short_pointer()[0], value_type()); 2576 __annotate_new(0); 2577 } 2578# endif 2579 } 2580 size_type __str_old_size = __str.size(); 2581 bool __str_was_short = !__str.__is_long(); 2582 2583 __move_assign_alloc(__str); 2584 __r_.first() = __str.__r_.first(); 2585 __str.__set_short_size(0); 2586 traits_type::assign(__str.__get_short_pointer()[0], value_type()); 2587 2588 if (__str_was_short && this != &__str) 2589 __str.__annotate_shrink(__str_old_size); 2590 else 2591 // ASan annotations: was long, so object memory is unpoisoned as new. 2592 // Or is same as *this, and __annotate_delete() was called. 2593 __str.__annotate_new(0); 2594 2595 // ASan annotations: Guard against `std::string s; s = std::move(s);` 2596 // You can find more here: https://en.cppreference.com/w/cpp/utility/move 2597 // Quote: "Unless otherwise specified, all standard library objects that have been moved 2598 // from are placed in a "valid but unspecified state", meaning the object's class 2599 // invariants hold (so functions without preconditions, such as the assignment operator, 2600 // can be safely used on the object after it was moved from):" 2601 // Quote: "v = std::move(v); // the value of v is unspecified" 2602 if (!__is_long() && &__str != this) 2603 // If it is long string, delete was never called on original __str's buffer. 2604 __annotate_new(__get_short_size()); 2605} 2606 2607#endif 2608 2609template <class _CharT, class _Traits, class _Allocator> 2610template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> > 2611_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2612basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last) { 2613 __assign_with_sentinel(__first, __last); 2614 return *this; 2615} 2616 2617template <class _CharT, class _Traits, class _Allocator> 2618template <class _InputIterator, class _Sentinel> 2619_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 2620basic_string<_CharT, _Traits, _Allocator>::__assign_with_sentinel(_InputIterator __first, _Sentinel __last) { 2621 const basic_string __temp(__init_with_sentinel_tag(), std::move(__first), std::move(__last), __alloc()); 2622 assign(__temp.data(), __temp.size()); 2623} 2624 2625template <class _CharT, class _Traits, class _Allocator> 2626template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> > 2627_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2628basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last) { 2629 if (__string_is_trivial_iterator<_ForwardIterator>::value) { 2630 size_type __n = static_cast<size_type>(std::distance(__first, __last)); 2631 __assign_trivial(__first, __last, __n); 2632 } else { 2633 __assign_with_sentinel(__first, __last); 2634 } 2635 2636 return *this; 2637} 2638 2639template <class _CharT, class _Traits, class _Allocator> 2640template <class _Iterator, class _Sentinel> 2641_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void 2642basic_string<_CharT, _Traits, _Allocator>::__assign_trivial(_Iterator __first, _Sentinel __last, size_type __n) { 2643 _LIBCPP_ASSERT_INTERNAL( 2644 __string_is_trivial_iterator<_Iterator>::value, "The iterator type given to `__assign_trivial` must be trivial"); 2645 2646 size_type __old_size = size(); 2647 size_type __cap = capacity(); 2648 if (__cap < __n) { 2649 // Unlike `append` functions, if the input range points into the string itself, there is no case that the input 2650 // range could get invalidated by reallocation: 2651 // 1. If the input range is a subset of the string itself, its size cannot exceed the capacity of the string, 2652 // thus no reallocation would happen. 2653 // 2. In the exotic case where the input range is the byte representation of the string itself, the string 2654 // object itself stays valid even if reallocation happens. 2655 size_type __sz = size(); 2656 __grow_by_without_replace(__cap, __n - __cap, __sz, 0, __sz); 2657 __annotate_increase(__n); 2658 } else if (__n > __old_size) 2659 __annotate_increase(__n - __old_size); 2660 pointer __p = __get_pointer(); 2661 for (; __first != __last; ++__p, (void)++__first) 2662 traits_type::assign(*__p, *__first); 2663 traits_type::assign(*__p, value_type()); 2664 __set_size(__n); 2665 if (__n < __old_size) 2666 __annotate_shrink(__old_size); 2667} 2668 2669template <class _CharT, class _Traits, class _Allocator> 2670_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2671basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, size_type __pos, size_type __n) { 2672 size_type __sz = __str.size(); 2673 if (__pos > __sz) 2674 __throw_out_of_range(); 2675 return assign(__str.data() + __pos, std::min(__n, __sz - __pos)); 2676} 2677 2678template <class _CharT, class _Traits, class _Allocator> 2679template <class _Tp, 2680 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 2681 !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 2682 int> > 2683_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2684basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp& __t, size_type __pos, size_type __n) { 2685 __self_view __sv = __t; 2686 size_type __sz = __sv.size(); 2687 if (__pos > __sz) 2688 __throw_out_of_range(); 2689 return assign(__sv.data() + __pos, std::min(__n, __sz - __pos)); 2690} 2691 2692template <class _CharT, class _Traits, class _Allocator> 2693_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE basic_string<_CharT, _Traits, _Allocator>& 2694basic_string<_CharT, _Traits, _Allocator>::__assign_external(const value_type* __s) { 2695 return __assign_external(__s, traits_type::length(__s)); 2696} 2697 2698template <class _CharT, class _Traits, class _Allocator> 2699_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2700basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s) { 2701 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::assign received nullptr"); 2702 return __builtin_constant_p(*__s) 2703 ? (__fits_in_sso(traits_type::length(__s)) ? __assign_short(__s, traits_type::length(__s)) 2704 : __assign_external(__s, traits_type::length(__s))) 2705 : __assign_external(__s); 2706} 2707// append 2708 2709template <class _CharT, class _Traits, class _Allocator> 2710_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2711basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n) { 2712 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::append received nullptr"); 2713 size_type __cap = capacity(); 2714 size_type __sz = size(); 2715 if (__cap - __sz >= __n) { 2716 if (__n) { 2717 __annotate_increase(__n); 2718 value_type* __p = std::__to_address(__get_pointer()); 2719 traits_type::copy(__p + __sz, __s, __n); 2720 __sz += __n; 2721 __set_size(__sz); 2722 traits_type::assign(__p[__sz], value_type()); 2723 } 2724 } else 2725 __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __sz, 0, __n, __s); 2726 return *this; 2727} 2728 2729template <class _CharT, class _Traits, class _Allocator> 2730_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2731basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c) { 2732 if (__n) { 2733 size_type __cap = capacity(); 2734 size_type __sz = size(); 2735 if (__cap - __sz < __n) 2736 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0); 2737 __annotate_increase(__n); 2738 pointer __p = __get_pointer(); 2739 traits_type::assign(std::__to_address(__p) + __sz, __n, __c); 2740 __sz += __n; 2741 __set_size(__sz); 2742 traits_type::assign(__p[__sz], value_type()); 2743 } 2744 return *this; 2745} 2746 2747template <class _CharT, class _Traits, class _Allocator> 2748_LIBCPP_CONSTEXPR_SINCE_CXX20 inline void 2749basic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n) { 2750 if (__n) { 2751 size_type __cap = capacity(); 2752 size_type __sz = size(); 2753 if (__cap - __sz < __n) 2754 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0); 2755 __annotate_increase(__n); 2756 pointer __p = __get_pointer(); 2757 __sz += __n; 2758 __set_size(__sz); 2759 traits_type::assign(__p[__sz], value_type()); 2760 } 2761} 2762 2763template <class _CharT, class _Traits, class _Allocator> 2764_LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c) { 2765 bool __is_short = !__is_long(); 2766 size_type __cap; 2767 size_type __sz; 2768 if (__is_short) { 2769 __cap = __min_cap - 1; 2770 __sz = __get_short_size(); 2771 } else { 2772 __cap = __get_long_cap() - 1; 2773 __sz = __get_long_size(); 2774 } 2775 if (__sz == __cap) { 2776 __grow_by_without_replace(__cap, 1, __sz, __sz, 0); 2777 __annotate_increase(1); 2778 __is_short = false; // the string is always long after __grow_by 2779 } else 2780 __annotate_increase(1); 2781 pointer __p = __get_pointer(); 2782 if (__is_short) { 2783 __p = __get_short_pointer() + __sz; 2784 __set_short_size(__sz + 1); 2785 } else { 2786 __p = __get_long_pointer() + __sz; 2787 __set_long_size(__sz + 1); 2788 } 2789 traits_type::assign(*__p, __c); 2790 traits_type::assign(*++__p, value_type()); 2791} 2792 2793template <class _CharT, class _Traits, class _Allocator> 2794template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> > 2795_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2796basic_string<_CharT, _Traits, _Allocator>::append(_ForwardIterator __first, _ForwardIterator __last) { 2797 size_type __sz = size(); 2798 size_type __cap = capacity(); 2799 size_type __n = static_cast<size_type>(std::distance(__first, __last)); 2800 if (__n) { 2801 if (__string_is_trivial_iterator<_ForwardIterator>::value && !__addr_in_range(*__first)) { 2802 if (__cap - __sz < __n) 2803 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0); 2804 __annotate_increase(__n); 2805 pointer __p = __get_pointer() + __sz; 2806 for (; __first != __last; ++__p, (void)++__first) 2807 traits_type::assign(*__p, *__first); 2808 traits_type::assign(*__p, value_type()); 2809 __set_size(__sz + __n); 2810 } else { 2811 const basic_string __temp(__first, __last, __alloc()); 2812 append(__temp.data(), __temp.size()); 2813 } 2814 } 2815 return *this; 2816} 2817 2818template <class _CharT, class _Traits, class _Allocator> 2819_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2820basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, size_type __pos, size_type __n) { 2821 size_type __sz = __str.size(); 2822 if (__pos > __sz) 2823 __throw_out_of_range(); 2824 return append(__str.data() + __pos, std::min(__n, __sz - __pos)); 2825} 2826 2827template <class _CharT, class _Traits, class _Allocator> 2828template <class _Tp, 2829 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 2830 !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 2831 int> > 2832_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2833basic_string<_CharT, _Traits, _Allocator>::append(const _Tp& __t, size_type __pos, size_type __n) { 2834 __self_view __sv = __t; 2835 size_type __sz = __sv.size(); 2836 if (__pos > __sz) 2837 __throw_out_of_range(); 2838 return append(__sv.data() + __pos, std::min(__n, __sz - __pos)); 2839} 2840 2841template <class _CharT, class _Traits, class _Allocator> 2842_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2843basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s) { 2844 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::append received nullptr"); 2845 return append(__s, traits_type::length(__s)); 2846} 2847 2848// insert 2849 2850template <class _CharT, class _Traits, class _Allocator> 2851_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2852basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n) { 2853 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::insert received nullptr"); 2854 size_type __sz = size(); 2855 if (__pos > __sz) 2856 __throw_out_of_range(); 2857 size_type __cap = capacity(); 2858 if (__cap - __sz >= __n) { 2859 if (__n) { 2860 __annotate_increase(__n); 2861 value_type* __p = std::__to_address(__get_pointer()); 2862 size_type __n_move = __sz - __pos; 2863 if (__n_move != 0) { 2864 if (std::__is_pointer_in_range(__p + __pos, __p + __sz, __s)) 2865 __s += __n; 2866 traits_type::move(__p + __pos + __n, __p + __pos, __n_move); 2867 } 2868 traits_type::move(__p + __pos, __s, __n); 2869 __sz += __n; 2870 __set_size(__sz); 2871 traits_type::assign(__p[__sz], value_type()); 2872 } 2873 } else 2874 __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s); 2875 return *this; 2876} 2877 2878template <class _CharT, class _Traits, class _Allocator> 2879_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2880basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n, value_type __c) { 2881 size_type __sz = size(); 2882 if (__pos > __sz) 2883 __throw_out_of_range(); 2884 if (__n) { 2885 size_type __cap = capacity(); 2886 value_type* __p; 2887 if (__cap - __sz >= __n) { 2888 __annotate_increase(__n); 2889 __p = std::__to_address(__get_pointer()); 2890 size_type __n_move = __sz - __pos; 2891 if (__n_move != 0) 2892 traits_type::move(__p + __pos + __n, __p + __pos, __n_move); 2893 } else { 2894 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n); 2895 __p = std::__to_address(__get_long_pointer()); 2896 } 2897 traits_type::assign(__p + __pos, __n, __c); 2898 __sz += __n; 2899 __set_size(__sz); 2900 traits_type::assign(__p[__sz], value_type()); 2901 } 2902 return *this; 2903} 2904 2905template <class _CharT, class _Traits, class _Allocator> 2906template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> > 2907_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator 2908basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last) { 2909 const basic_string __temp(__first, __last, __alloc()); 2910 return insert(__pos, __temp.data(), __temp.data() + __temp.size()); 2911} 2912 2913template <class _CharT, class _Traits, class _Allocator> 2914template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> > 2915_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator 2916basic_string<_CharT, _Traits, _Allocator>::insert( 2917 const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last) { 2918 auto __n = static_cast<size_type>(std::distance(__first, __last)); 2919 return __insert_with_size(__pos, __first, __last, __n); 2920} 2921 2922template <class _CharT, class _Traits, class _Allocator> 2923template <class _Iterator, class _Sentinel> 2924_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator 2925basic_string<_CharT, _Traits, _Allocator>::__insert_with_size( 2926 const_iterator __pos, _Iterator __first, _Sentinel __last, size_type __n) { 2927 size_type __ip = static_cast<size_type>(__pos - begin()); 2928 if (__n == 0) 2929 return begin() + __ip; 2930 2931 if (__string_is_trivial_iterator<_Iterator>::value && !__addr_in_range(*__first)) { 2932 return __insert_from_safe_copy(__n, __ip, __first, __last); 2933 } else { 2934 const basic_string __temp(__init_with_sentinel_tag(), __first, __last, __alloc()); 2935 return __insert_from_safe_copy(__n, __ip, __temp.begin(), __temp.end()); 2936 } 2937} 2938 2939template <class _CharT, class _Traits, class _Allocator> 2940_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2941basic_string<_CharT, _Traits, _Allocator>::insert( 2942 size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n) { 2943 size_type __str_sz = __str.size(); 2944 if (__pos2 > __str_sz) 2945 __throw_out_of_range(); 2946 return insert(__pos1, __str.data() + __pos2, std::min(__n, __str_sz - __pos2)); 2947} 2948 2949template <class _CharT, class _Traits, class _Allocator> 2950template <class _Tp, 2951 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 2952 !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 2953 int> > 2954_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2955basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n) { 2956 __self_view __sv = __t; 2957 size_type __str_sz = __sv.size(); 2958 if (__pos2 > __str_sz) 2959 __throw_out_of_range(); 2960 return insert(__pos1, __sv.data() + __pos2, std::min(__n, __str_sz - __pos2)); 2961} 2962 2963template <class _CharT, class _Traits, class _Allocator> 2964_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2965basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s) { 2966 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::insert received nullptr"); 2967 return insert(__pos, __s, traits_type::length(__s)); 2968} 2969 2970template <class _CharT, class _Traits, class _Allocator> 2971_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator 2972basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c) { 2973 size_type __ip = static_cast<size_type>(__pos - begin()); 2974 size_type __sz = size(); 2975 size_type __cap = capacity(); 2976 value_type* __p; 2977 if (__cap == __sz) { 2978 __grow_by_without_replace(__cap, 1, __sz, __ip, 0, 1); 2979 __p = std::__to_address(__get_long_pointer()); 2980 } else { 2981 __annotate_increase(1); 2982 __p = std::__to_address(__get_pointer()); 2983 size_type __n_move = __sz - __ip; 2984 if (__n_move != 0) 2985 traits_type::move(__p + __ip + 1, __p + __ip, __n_move); 2986 } 2987 traits_type::assign(__p[__ip], __c); 2988 traits_type::assign(__p[++__sz], value_type()); 2989 __set_size(__sz); 2990 return begin() + static_cast<difference_type>(__ip); 2991} 2992 2993// replace 2994 2995template <class _CharT, class _Traits, class _Allocator> 2996_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2997basic_string<_CharT, _Traits, _Allocator>::replace( 2998 size_type __pos, size_type __n1, const value_type* __s, size_type __n2) 2999 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK { 3000 _LIBCPP_ASSERT_NON_NULL(__n2 == 0 || __s != nullptr, "string::replace received nullptr"); 3001 size_type __sz = size(); 3002 if (__pos > __sz) 3003 __throw_out_of_range(); 3004 __n1 = std::min(__n1, __sz - __pos); 3005 size_type __cap = capacity(); 3006 if (__cap - __sz + __n1 >= __n2) { 3007 value_type* __p = std::__to_address(__get_pointer()); 3008 if (__n1 != __n2) { 3009 if (__n2 > __n1) 3010 __annotate_increase(__n2 - __n1); 3011 size_type __n_move = __sz - __pos - __n1; 3012 if (__n_move != 0) { 3013 if (__n1 > __n2) { 3014 traits_type::move(__p + __pos, __s, __n2); 3015 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move); 3016 return __null_terminate_at(__p, __sz + (__n2 - __n1)); 3017 } 3018 if (std::__is_pointer_in_range(__p + __pos + 1, __p + __sz, __s)) { 3019 if (__p + __pos + __n1 <= __s) 3020 __s += __n2 - __n1; 3021 else // __p + __pos < __s < __p + __pos + __n1 3022 { 3023 traits_type::move(__p + __pos, __s, __n1); 3024 __pos += __n1; 3025 __s += __n2; 3026 __n2 -= __n1; 3027 __n1 = 0; 3028 } 3029 } 3030 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move); 3031 } 3032 } 3033 traits_type::move(__p + __pos, __s, __n2); 3034 return __null_terminate_at(__p, __sz + (__n2 - __n1)); 3035 } else 3036 __grow_by_and_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2, __s); 3037 return *this; 3038} 3039 3040template <class _CharT, class _Traits, class _Allocator> 3041_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 3042basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, size_type __n2, value_type __c) { 3043 size_type __sz = size(); 3044 if (__pos > __sz) 3045 __throw_out_of_range(); 3046 __n1 = std::min(__n1, __sz - __pos); 3047 size_type __cap = capacity(); 3048 value_type* __p; 3049 if (__cap - __sz + __n1 >= __n2) { 3050 __p = std::__to_address(__get_pointer()); 3051 if (__n1 != __n2) { 3052 if (__n2 > __n1) 3053 __annotate_increase(__n2 - __n1); 3054 size_type __n_move = __sz - __pos - __n1; 3055 if (__n_move != 0) 3056 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move); 3057 } 3058 } else { 3059 __grow_by_without_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2); 3060 __p = std::__to_address(__get_long_pointer()); 3061 } 3062 traits_type::assign(__p + __pos, __n2, __c); 3063 return __null_terminate_at(__p, __sz - (__n1 - __n2)); 3064} 3065 3066template <class _CharT, class _Traits, class _Allocator> 3067template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> > 3068_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 3069basic_string<_CharT, _Traits, _Allocator>::replace( 3070 const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2) { 3071 const basic_string __temp(__j1, __j2, __alloc()); 3072 return replace(__i1, __i2, __temp); 3073} 3074 3075template <class _CharT, class _Traits, class _Allocator> 3076_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 3077basic_string<_CharT, _Traits, _Allocator>::replace( 3078 size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2) { 3079 size_type __str_sz = __str.size(); 3080 if (__pos2 > __str_sz) 3081 __throw_out_of_range(); 3082 return replace(__pos1, __n1, __str.data() + __pos2, std::min(__n2, __str_sz - __pos2)); 3083} 3084 3085template <class _CharT, class _Traits, class _Allocator> 3086template <class _Tp, 3087 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 3088 !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 3089 int> > 3090_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 3091basic_string<_CharT, _Traits, _Allocator>::replace( 3092 size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2) { 3093 __self_view __sv = __t; 3094 size_type __str_sz = __sv.size(); 3095 if (__pos2 > __str_sz) 3096 __throw_out_of_range(); 3097 return replace(__pos1, __n1, __sv.data() + __pos2, std::min(__n2, __str_sz - __pos2)); 3098} 3099 3100template <class _CharT, class _Traits, class _Allocator> 3101_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 3102basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s) { 3103 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::replace received nullptr"); 3104 return replace(__pos, __n1, __s, traits_type::length(__s)); 3105} 3106 3107// erase 3108 3109// 'externally instantiated' erase() implementation, called when __n != npos. 3110// Does not check __pos against size() 3111template <class _CharT, class _Traits, class _Allocator> 3112_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE void 3113basic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move(size_type __pos, size_type __n) { 3114 if (__n) { 3115 size_type __sz = size(); 3116 value_type* __p = std::__to_address(__get_pointer()); 3117 __n = std::min(__n, __sz - __pos); 3118 size_type __n_move = __sz - __pos - __n; 3119 if (__n_move != 0) 3120 traits_type::move(__p + __pos, __p + __pos + __n, __n_move); 3121 __null_terminate_at(__p, __sz - __n); 3122 } 3123} 3124 3125template <class _CharT, class _Traits, class _Allocator> 3126_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 3127basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, size_type __n) { 3128 if (__pos > size()) 3129 __throw_out_of_range(); 3130 if (__n == npos) { 3131 __erase_to_end(__pos); 3132 } else { 3133 __erase_external_with_move(__pos, __n); 3134 } 3135 return *this; 3136} 3137 3138template <class _CharT, class _Traits, class _Allocator> 3139inline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator 3140basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos) { 3141 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 3142 __pos != end(), "string::erase(iterator) called with a non-dereferenceable iterator"); 3143 iterator __b = begin(); 3144 size_type __r = static_cast<size_type>(__pos - __b); 3145 erase(__r, 1); 3146 return __b + static_cast<difference_type>(__r); 3147} 3148 3149template <class _CharT, class _Traits, class _Allocator> 3150inline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator 3151basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last) { 3152 _LIBCPP_ASSERT_VALID_INPUT_RANGE(__first <= __last, "string::erase(first, last) called with invalid range"); 3153 iterator __b = begin(); 3154 size_type __r = static_cast<size_type>(__first - __b); 3155 erase(__r, static_cast<size_type>(__last - __first)); 3156 return __b + static_cast<difference_type>(__r); 3157} 3158 3159template <class _CharT, class _Traits, class _Allocator> 3160inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::pop_back() { 3161 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::pop_back(): string is already empty"); 3162 __erase_to_end(size() - 1); 3163} 3164 3165template <class _CharT, class _Traits, class _Allocator> 3166inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT { 3167 size_type __old_size = size(); 3168 if (__is_long()) { 3169 traits_type::assign(*__get_long_pointer(), value_type()); 3170 __set_long_size(0); 3171 } else { 3172 traits_type::assign(*__get_short_pointer(), value_type()); 3173 __set_short_size(0); 3174 } 3175 __annotate_shrink(__old_size); 3176} 3177 3178template <class _CharT, class _Traits, class _Allocator> 3179_LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c) { 3180 size_type __sz = size(); 3181 if (__n > __sz) 3182 append(__n - __sz, __c); 3183 else 3184 __erase_to_end(__n); 3185} 3186 3187template <class _CharT, class _Traits, class _Allocator> 3188_LIBCPP_CONSTEXPR_SINCE_CXX20 inline void 3189basic_string<_CharT, _Traits, _Allocator>::__resize_default_init(size_type __n) { 3190 size_type __sz = size(); 3191 if (__n > __sz) { 3192 __append_default_init(__n - __sz); 3193 } else 3194 __erase_to_end(__n); 3195} 3196 3197template <class _CharT, class _Traits, class _Allocator> 3198_LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacity) { 3199 if (__requested_capacity > max_size()) 3200 __throw_length_error(); 3201 3202 // Make sure reserve(n) never shrinks. This is technically only required in C++20 3203 // and later (since P0966R1), however we provide consistent behavior in all Standard 3204 // modes because this function is instantiated in the shared library. 3205 if (__requested_capacity <= capacity()) 3206 return; 3207 3208 size_type __target_capacity = std::max(__requested_capacity, size()); 3209 __target_capacity = __recommend(__target_capacity); 3210 if (__target_capacity == capacity()) 3211 return; 3212 3213 __shrink_or_extend(__target_capacity); 3214} 3215 3216template <class _CharT, class _Traits, class _Allocator> 3217inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::shrink_to_fit() _NOEXCEPT { 3218 size_type __target_capacity = __recommend(size()); 3219 if (__target_capacity == capacity()) 3220 return; 3221 3222 __shrink_or_extend(__target_capacity); 3223} 3224 3225template <class _CharT, class _Traits, class _Allocator> 3226inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void 3227basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target_capacity) { 3228 __annotate_delete(); 3229 size_type __cap = capacity(); 3230 size_type __sz = size(); 3231 3232 pointer __new_data, __p; 3233 bool __was_long, __now_long; 3234 if (__fits_in_sso(__target_capacity)) { 3235 __was_long = true; 3236 __now_long = false; 3237 __new_data = __get_short_pointer(); 3238 __p = __get_long_pointer(); 3239 } else { 3240 if (__target_capacity > __cap) { 3241 auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1); 3242 __new_data = __allocation.ptr; 3243 __target_capacity = __allocation.count - 1; 3244 } else { 3245#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 3246 try { 3247#endif // _LIBCPP_HAS_NO_EXCEPTIONS 3248 auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1); 3249 __new_data = __allocation.ptr; 3250 __target_capacity = __allocation.count - 1; 3251#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 3252 } catch (...) { 3253 return; 3254 } 3255#else // _LIBCPP_HAS_NO_EXCEPTIONS 3256 if (__new_data == nullptr) 3257 return; 3258#endif // _LIBCPP_HAS_NO_EXCEPTIONS 3259 } 3260 __begin_lifetime(__new_data, __target_capacity + 1); 3261 __now_long = true; 3262 __was_long = __is_long(); 3263 __p = __get_pointer(); 3264 } 3265 traits_type::copy(std::__to_address(__new_data), std::__to_address(__p), size() + 1); 3266 if (__was_long) 3267 __alloc_traits::deallocate(__alloc(), __p, __cap + 1); 3268 if (__now_long) { 3269 __set_long_cap(__target_capacity + 1); 3270 __set_long_size(__sz); 3271 __set_long_pointer(__new_data); 3272 } else 3273 __set_short_size(__sz); 3274 __annotate_new(__sz); 3275} 3276 3277template <class _CharT, class _Traits, class _Allocator> 3278_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::const_reference 3279basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const { 3280 if (__n >= size()) 3281 __throw_out_of_range(); 3282 return (*this)[__n]; 3283} 3284 3285template <class _CharT, class _Traits, class _Allocator> 3286_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::reference 3287basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) { 3288 if (__n >= size()) 3289 __throw_out_of_range(); 3290 return (*this)[__n]; 3291} 3292 3293template <class _CharT, class _Traits, class _Allocator> 3294_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3295basic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n, size_type __pos) const { 3296 size_type __sz = size(); 3297 if (__pos > __sz) 3298 __throw_out_of_range(); 3299 size_type __rlen = std::min(__n, __sz - __pos); 3300 traits_type::copy(__s, data() + __pos, __rlen); 3301 return __rlen; 3302} 3303 3304template <class _CharT, class _Traits, class _Allocator> 3305inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str) 3306#if _LIBCPP_STD_VER >= 14 3307 _NOEXCEPT 3308#else 3309 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<allocator_type>::value) 3310#endif 3311{ 3312 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR( 3313 __alloc_traits::propagate_on_container_swap::value || __alloc_traits::is_always_equal::value || 3314 __alloc() == __str.__alloc(), 3315 "swapping non-equal allocators"); 3316 if (!__is_long()) 3317 __annotate_delete(); 3318 if (this != &__str && !__str.__is_long()) 3319 __str.__annotate_delete(); 3320 std::swap(__r_.first(), __str.__r_.first()); 3321 std::__swap_allocator(__alloc(), __str.__alloc()); 3322 if (!__is_long()) 3323 __annotate_new(__get_short_size()); 3324 if (this != &__str && !__str.__is_long()) 3325 __str.__annotate_new(__str.__get_short_size()); 3326} 3327 3328// find 3329 3330template <class _Traits> 3331struct _LIBCPP_HIDDEN __traits_eq { 3332 typedef typename _Traits::char_type char_type; 3333 _LIBCPP_HIDE_FROM_ABI bool operator()(const char_type& __x, const char_type& __y) _NOEXCEPT { 3334 return _Traits::eq(__x, __y); 3335 } 3336}; 3337 3338template <class _CharT, class _Traits, class _Allocator> 3339_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3340basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT { 3341 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find(): received nullptr"); 3342 return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); 3343} 3344 3345template <class _CharT, class _Traits, class _Allocator> 3346inline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3347basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str, size_type __pos) const _NOEXCEPT { 3348 return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __str.data(), __pos, __str.size()); 3349} 3350 3351template <class _CharT, class _Traits, class _Allocator> 3352template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 3353_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3354basic_string<_CharT, _Traits, _Allocator>::find(const _Tp& __t, size_type __pos) const _NOEXCEPT { 3355 __self_view __sv = __t; 3356 return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __sv.data(), __pos, __sv.size()); 3357} 3358 3359template <class _CharT, class _Traits, class _Allocator> 3360inline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3361basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, size_type __pos) const _NOEXCEPT { 3362 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find(): received nullptr"); 3363 return std::__str_find<value_type, size_type, traits_type, npos>( 3364 data(), size(), __s, __pos, traits_type::length(__s)); 3365} 3366 3367template <class _CharT, class _Traits, class _Allocator> 3368_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3369basic_string<_CharT, _Traits, _Allocator>::find(value_type __c, size_type __pos) const _NOEXCEPT { 3370 return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos); 3371} 3372 3373// rfind 3374 3375template <class _CharT, class _Traits, class _Allocator> 3376_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3377basic_string<_CharT, _Traits, _Allocator>::rfind( 3378 const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT { 3379 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::rfind(): received nullptr"); 3380 return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); 3381} 3382 3383template <class _CharT, class _Traits, class _Allocator> 3384inline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3385basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str, size_type __pos) const _NOEXCEPT { 3386 return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __str.data(), __pos, __str.size()); 3387} 3388 3389template <class _CharT, class _Traits, class _Allocator> 3390template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 3391_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3392basic_string<_CharT, _Traits, _Allocator>::rfind(const _Tp& __t, size_type __pos) const _NOEXCEPT { 3393 __self_view __sv = __t; 3394 return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __sv.data(), __pos, __sv.size()); 3395} 3396 3397template <class _CharT, class _Traits, class _Allocator> 3398inline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3399basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, size_type __pos) const _NOEXCEPT { 3400 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::rfind(): received nullptr"); 3401 return std::__str_rfind<value_type, size_type, traits_type, npos>( 3402 data(), size(), __s, __pos, traits_type::length(__s)); 3403} 3404 3405template <class _CharT, class _Traits, class _Allocator> 3406_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3407basic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c, size_type __pos) const _NOEXCEPT { 3408 return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos); 3409} 3410 3411// find_first_of 3412 3413template <class _CharT, class _Traits, class _Allocator> 3414_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3415basic_string<_CharT, _Traits, _Allocator>::find_first_of( 3416 const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT { 3417 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr"); 3418 return std::__str_find_first_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); 3419} 3420 3421template <class _CharT, class _Traits, class _Allocator> 3422inline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3423basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str, size_type __pos) const _NOEXCEPT { 3424 return std::__str_find_first_of<value_type, size_type, traits_type, npos>( 3425 data(), size(), __str.data(), __pos, __str.size()); 3426} 3427 3428template <class _CharT, class _Traits, class _Allocator> 3429template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 3430_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3431basic_string<_CharT, _Traits, _Allocator>::find_first_of(const _Tp& __t, size_type __pos) const _NOEXCEPT { 3432 __self_view __sv = __t; 3433 return std::__str_find_first_of<value_type, size_type, traits_type, npos>( 3434 data(), size(), __sv.data(), __pos, __sv.size()); 3435} 3436 3437template <class _CharT, class _Traits, class _Allocator> 3438inline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3439basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, size_type __pos) const _NOEXCEPT { 3440 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_first_of(): received nullptr"); 3441 return std::__str_find_first_of<value_type, size_type, traits_type, npos>( 3442 data(), size(), __s, __pos, traits_type::length(__s)); 3443} 3444 3445template <class _CharT, class _Traits, class _Allocator> 3446inline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3447basic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c, size_type __pos) const _NOEXCEPT { 3448 return find(__c, __pos); 3449} 3450 3451// find_last_of 3452 3453template <class _CharT, class _Traits, class _Allocator> 3454inline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3455basic_string<_CharT, _Traits, _Allocator>::find_last_of( 3456 const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT { 3457 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr"); 3458 return std::__str_find_last_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); 3459} 3460 3461template <class _CharT, class _Traits, class _Allocator> 3462inline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3463basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str, size_type __pos) const _NOEXCEPT { 3464 return std::__str_find_last_of<value_type, size_type, traits_type, npos>( 3465 data(), size(), __str.data(), __pos, __str.size()); 3466} 3467 3468template <class _CharT, class _Traits, class _Allocator> 3469template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 3470_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3471basic_string<_CharT, _Traits, _Allocator>::find_last_of(const _Tp& __t, size_type __pos) const _NOEXCEPT { 3472 __self_view __sv = __t; 3473 return std::__str_find_last_of<value_type, size_type, traits_type, npos>( 3474 data(), size(), __sv.data(), __pos, __sv.size()); 3475} 3476 3477template <class _CharT, class _Traits, class _Allocator> 3478inline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3479basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, size_type __pos) const _NOEXCEPT { 3480 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_last_of(): received nullptr"); 3481 return std::__str_find_last_of<value_type, size_type, traits_type, npos>( 3482 data(), size(), __s, __pos, traits_type::length(__s)); 3483} 3484 3485template <class _CharT, class _Traits, class _Allocator> 3486inline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3487basic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c, size_type __pos) const _NOEXCEPT { 3488 return rfind(__c, __pos); 3489} 3490 3491// find_first_not_of 3492 3493template <class _CharT, class _Traits, class _Allocator> 3494_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3495basic_string<_CharT, _Traits, _Allocator>::find_first_not_of( 3496 const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT { 3497 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr"); 3498 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); 3499} 3500 3501template <class _CharT, class _Traits, class _Allocator> 3502inline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3503basic_string<_CharT, _Traits, _Allocator>::find_first_not_of( 3504 const basic_string& __str, size_type __pos) const _NOEXCEPT { 3505 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>( 3506 data(), size(), __str.data(), __pos, __str.size()); 3507} 3508 3509template <class _CharT, class _Traits, class _Allocator> 3510template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 3511_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3512basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const _Tp& __t, size_type __pos) const _NOEXCEPT { 3513 __self_view __sv = __t; 3514 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>( 3515 data(), size(), __sv.data(), __pos, __sv.size()); 3516} 3517 3518template <class _CharT, class _Traits, class _Allocator> 3519inline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3520basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s, size_type __pos) const _NOEXCEPT { 3521 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_first_not_of(): received nullptr"); 3522 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>( 3523 data(), size(), __s, __pos, traits_type::length(__s)); 3524} 3525 3526template <class _CharT, class _Traits, class _Allocator> 3527inline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3528basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c, size_type __pos) const _NOEXCEPT { 3529 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos); 3530} 3531 3532// find_last_not_of 3533 3534template <class _CharT, class _Traits, class _Allocator> 3535_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3536basic_string<_CharT, _Traits, _Allocator>::find_last_not_of( 3537 const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT { 3538 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr"); 3539 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); 3540} 3541 3542template <class _CharT, class _Traits, class _Allocator> 3543inline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3544basic_string<_CharT, _Traits, _Allocator>::find_last_not_of( 3545 const basic_string& __str, size_type __pos) const _NOEXCEPT { 3546 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>( 3547 data(), size(), __str.data(), __pos, __str.size()); 3548} 3549 3550template <class _CharT, class _Traits, class _Allocator> 3551template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 3552_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3553basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const _Tp& __t, size_type __pos) const _NOEXCEPT { 3554 __self_view __sv = __t; 3555 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>( 3556 data(), size(), __sv.data(), __pos, __sv.size()); 3557} 3558 3559template <class _CharT, class _Traits, class _Allocator> 3560inline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3561basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s, size_type __pos) const _NOEXCEPT { 3562 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_last_not_of(): received nullptr"); 3563 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>( 3564 data(), size(), __s, __pos, traits_type::length(__s)); 3565} 3566 3567template <class _CharT, class _Traits, class _Allocator> 3568inline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3569basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c, size_type __pos) const _NOEXCEPT { 3570 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos); 3571} 3572 3573// compare 3574 3575template <class _CharT, class _Traits, class _Allocator> 3576template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 3577_LIBCPP_CONSTEXPR_SINCE_CXX20 int basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const _NOEXCEPT { 3578 __self_view __sv = __t; 3579 size_t __lhs_sz = size(); 3580 size_t __rhs_sz = __sv.size(); 3581 int __result = traits_type::compare(data(), __sv.data(), std::min(__lhs_sz, __rhs_sz)); 3582 if (__result != 0) 3583 return __result; 3584 if (__lhs_sz < __rhs_sz) 3585 return -1; 3586 if (__lhs_sz > __rhs_sz) 3587 return 1; 3588 return 0; 3589} 3590 3591template <class _CharT, class _Traits, class _Allocator> 3592inline _LIBCPP_CONSTEXPR_SINCE_CXX20 int 3593basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT { 3594 return compare(__self_view(__str)); 3595} 3596 3597template <class _CharT, class _Traits, class _Allocator> 3598inline _LIBCPP_CONSTEXPR_SINCE_CXX20 int basic_string<_CharT, _Traits, _Allocator>::compare( 3599 size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const { 3600 _LIBCPP_ASSERT_NON_NULL(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr"); 3601 size_type __sz = size(); 3602 if (__pos1 > __sz || __n2 == npos) 3603 __throw_out_of_range(); 3604 size_type __rlen = std::min(__n1, __sz - __pos1); 3605 int __r = traits_type::compare(data() + __pos1, __s, std::min(__rlen, __n2)); 3606 if (__r == 0) { 3607 if (__rlen < __n2) 3608 __r = -1; 3609 else if (__rlen > __n2) 3610 __r = 1; 3611 } 3612 return __r; 3613} 3614 3615template <class _CharT, class _Traits, class _Allocator> 3616template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 3617_LIBCPP_CONSTEXPR_SINCE_CXX20 int 3618basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, const _Tp& __t) const { 3619 __self_view __sv = __t; 3620 return compare(__pos1, __n1, __sv.data(), __sv.size()); 3621} 3622 3623template <class _CharT, class _Traits, class _Allocator> 3624inline _LIBCPP_CONSTEXPR_SINCE_CXX20 int 3625basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, const basic_string& __str) const { 3626 return compare(__pos1, __n1, __str.data(), __str.size()); 3627} 3628 3629template <class _CharT, class _Traits, class _Allocator> 3630template <class _Tp, 3631 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 3632 !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 3633 int> > 3634_LIBCPP_CONSTEXPR_SINCE_CXX20 int basic_string<_CharT, _Traits, _Allocator>::compare( 3635 size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2) const { 3636 __self_view __sv = __t; 3637 return __self_view(*this).substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2)); 3638} 3639 3640template <class _CharT, class _Traits, class _Allocator> 3641_LIBCPP_CONSTEXPR_SINCE_CXX20 int basic_string<_CharT, _Traits, _Allocator>::compare( 3642 size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2) const { 3643 return compare(__pos1, __n1, __self_view(__str), __pos2, __n2); 3644} 3645 3646template <class _CharT, class _Traits, class _Allocator> 3647_LIBCPP_CONSTEXPR_SINCE_CXX20 int 3648basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT { 3649 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::compare(): received nullptr"); 3650 return compare(0, npos, __s, traits_type::length(__s)); 3651} 3652 3653template <class _CharT, class _Traits, class _Allocator> 3654_LIBCPP_CONSTEXPR_SINCE_CXX20 int 3655basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, const value_type* __s) const { 3656 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::compare(): received nullptr"); 3657 return compare(__pos1, __n1, __s, traits_type::length(__s)); 3658} 3659 3660// __invariants 3661 3662template <class _CharT, class _Traits, class _Allocator> 3663inline _LIBCPP_CONSTEXPR_SINCE_CXX20 bool basic_string<_CharT, _Traits, _Allocator>::__invariants() const { 3664 if (size() > capacity()) 3665 return false; 3666 if (capacity() < __min_cap - 1) 3667 return false; 3668 if (data() == nullptr) 3669 return false; 3670 if (!_Traits::eq(data()[size()], value_type())) 3671 return false; 3672 return true; 3673} 3674 3675// __clear_and_shrink 3676 3677template <class _CharT, class _Traits, class _Allocator> 3678inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT { 3679 clear(); 3680 if (__is_long()) { 3681 __annotate_delete(); 3682 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), capacity() + 1); 3683 __r_.first() = __rep(); 3684 } 3685} 3686 3687// operator== 3688 3689template <class _CharT, class _Traits, class _Allocator> 3690inline _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool 3691operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3692 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 3693#if _LIBCPP_STD_VER >= 20 3694 return basic_string_view<_CharT, _Traits>(__lhs) == basic_string_view<_CharT, _Traits>(__rhs); 3695#else 3696 size_t __lhs_sz = __lhs.size(); 3697 return __lhs_sz == __rhs.size() && _Traits::compare(__lhs.data(), __rhs.data(), __lhs_sz) == 0; 3698#endif 3699} 3700 3701template <class _Allocator> 3702inline _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool 3703operator==(const basic_string<char, char_traits<char>, _Allocator>& __lhs, 3704 const basic_string<char, char_traits<char>, _Allocator>& __rhs) _NOEXCEPT { 3705 size_t __lhs_sz = __lhs.size(); 3706 if (__lhs_sz != __rhs.size()) 3707 return false; 3708 const char* __lp = __lhs.data(); 3709 const char* __rp = __rhs.data(); 3710 if (__lhs.__is_long()) 3711 return char_traits<char>::compare(__lp, __rp, __lhs_sz) == 0; 3712 for (; __lhs_sz != 0; --__lhs_sz, ++__lp, ++__rp) 3713 if (*__lp != *__rp) 3714 return false; 3715 return true; 3716} 3717 3718#if _LIBCPP_STD_VER <= 17 3719template <class _CharT, class _Traits, class _Allocator> 3720inline _LIBCPP_HIDE_FROM_ABI bool 3721operator==(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 3722 typedef basic_string<_CharT, _Traits, _Allocator> _String; 3723 _LIBCPP_ASSERT_NON_NULL(__lhs != nullptr, "operator==(char*, basic_string): received nullptr"); 3724 size_t __lhs_len = _Traits::length(__lhs); 3725 if (__lhs_len != __rhs.size()) 3726 return false; 3727 return __rhs.compare(0, _String::npos, __lhs, __lhs_len) == 0; 3728} 3729#endif // _LIBCPP_STD_VER <= 17 3730 3731template <class _CharT, class _Traits, class _Allocator> 3732inline _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool 3733operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT { 3734#if _LIBCPP_STD_VER >= 20 3735 return basic_string_view<_CharT, _Traits>(__lhs) == basic_string_view<_CharT, _Traits>(__rhs); 3736#else 3737 typedef basic_string<_CharT, _Traits, _Allocator> _String; 3738 _LIBCPP_ASSERT_NON_NULL(__rhs != nullptr, "operator==(basic_string, char*): received nullptr"); 3739 size_t __rhs_len = _Traits::length(__rhs); 3740 if (__rhs_len != __lhs.size()) 3741 return false; 3742 return __lhs.compare(0, _String::npos, __rhs, __rhs_len) == 0; 3743#endif 3744} 3745 3746#if _LIBCPP_STD_VER >= 20 3747 3748template <class _CharT, class _Traits, class _Allocator> 3749_LIBCPP_HIDE_FROM_ABI constexpr auto operator<=>(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3750 const basic_string<_CharT, _Traits, _Allocator>& __rhs) noexcept { 3751 return basic_string_view<_CharT, _Traits>(__lhs) <=> basic_string_view<_CharT, _Traits>(__rhs); 3752} 3753 3754template <class _CharT, class _Traits, class _Allocator> 3755_LIBCPP_HIDE_FROM_ABI constexpr auto 3756operator<=>(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) { 3757 return basic_string_view<_CharT, _Traits>(__lhs) <=> basic_string_view<_CharT, _Traits>(__rhs); 3758} 3759 3760#else // _LIBCPP_STD_VER >= 20 3761 3762template <class _CharT, class _Traits, class _Allocator> 3763inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3764 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 3765 return !(__lhs == __rhs); 3766} 3767 3768template <class _CharT, class _Traits, class _Allocator> 3769inline _LIBCPP_HIDE_FROM_ABI bool 3770operator!=(const _CharT* __lhs, 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 basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT { 3777 return !(__lhs == __rhs); 3778} 3779 3780// operator< 3781 3782template <class _CharT, class _Traits, class _Allocator> 3783inline _LIBCPP_HIDE_FROM_ABI bool operator<(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3784 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 3785 return __lhs.compare(__rhs) < 0; 3786} 3787 3788template <class _CharT, class _Traits, class _Allocator> 3789inline _LIBCPP_HIDE_FROM_ABI bool 3790operator<(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __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 _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 3797 return __rhs.compare(__lhs) > 0; 3798} 3799 3800// operator> 3801 3802template <class _CharT, class _Traits, class _Allocator> 3803inline _LIBCPP_HIDE_FROM_ABI bool operator>(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3804 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 3805 return __rhs < __lhs; 3806} 3807 3808template <class _CharT, class _Traits, class _Allocator> 3809inline _LIBCPP_HIDE_FROM_ABI bool 3810operator>(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT { 3811 return __rhs < __lhs; 3812} 3813 3814template <class _CharT, class _Traits, class _Allocator> 3815inline _LIBCPP_HIDE_FROM_ABI bool 3816operator>(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 3817 return __rhs < __lhs; 3818} 3819 3820// operator<= 3821 3822template <class _CharT, class _Traits, class _Allocator> 3823inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3824 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 3825 return !(__rhs < __lhs); 3826} 3827 3828template <class _CharT, class _Traits, class _Allocator> 3829inline _LIBCPP_HIDE_FROM_ABI bool 3830operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT { 3831 return !(__rhs < __lhs); 3832} 3833 3834template <class _CharT, class _Traits, class _Allocator> 3835inline _LIBCPP_HIDE_FROM_ABI bool 3836operator<=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 3837 return !(__rhs < __lhs); 3838} 3839 3840// operator>= 3841 3842template <class _CharT, class _Traits, class _Allocator> 3843inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3844 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 3845 return !(__lhs < __rhs); 3846} 3847 3848template <class _CharT, class _Traits, class _Allocator> 3849inline _LIBCPP_HIDE_FROM_ABI bool 3850operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT { 3851 return !(__lhs < __rhs); 3852} 3853 3854template <class _CharT, class _Traits, class _Allocator> 3855inline _LIBCPP_HIDE_FROM_ABI bool 3856operator>=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 3857 return !(__lhs < __rhs); 3858} 3859#endif // _LIBCPP_STD_VER >= 20 3860 3861// operator + 3862 3863template <class _CharT, class _Traits, class _Allocator> 3864_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 3865operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3866 const basic_string<_CharT, _Traits, _Allocator>& __rhs) { 3867 using _String = basic_string<_CharT, _Traits, _Allocator>; 3868 auto __lhs_sz = __lhs.size(); 3869 auto __rhs_sz = __rhs.size(); 3870 _String __r(__uninitialized_size_tag(), 3871 __lhs_sz + __rhs_sz, 3872 _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator())); 3873 auto __ptr = std::__to_address(__r.__get_pointer()); 3874 _Traits::copy(__ptr, __lhs.data(), __lhs_sz); 3875 _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz); 3876 _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT()); 3877 return __r; 3878} 3879 3880template <class _CharT, class _Traits, class _Allocator> 3881_LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 3882operator+(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) { 3883 using _String = basic_string<_CharT, _Traits, _Allocator>; 3884 auto __lhs_sz = _Traits::length(__lhs); 3885 auto __rhs_sz = __rhs.size(); 3886 _String __r(__uninitialized_size_tag(), 3887 __lhs_sz + __rhs_sz, 3888 _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator())); 3889 auto __ptr = std::__to_address(__r.__get_pointer()); 3890 _Traits::copy(__ptr, __lhs, __lhs_sz); 3891 _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz); 3892 _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT()); 3893 return __r; 3894} 3895 3896template <class _CharT, class _Traits, class _Allocator> 3897_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 3898operator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) { 3899 using _String = basic_string<_CharT, _Traits, _Allocator>; 3900 typename _String::size_type __rhs_sz = __rhs.size(); 3901 _String __r(__uninitialized_size_tag(), 3902 __rhs_sz + 1, 3903 _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator())); 3904 auto __ptr = std::__to_address(__r.__get_pointer()); 3905 _Traits::assign(__ptr, 1, __lhs); 3906 _Traits::copy(__ptr + 1, __rhs.data(), __rhs_sz); 3907 _Traits::assign(__ptr + 1 + __rhs_sz, 1, _CharT()); 3908 return __r; 3909} 3910 3911template <class _CharT, class _Traits, class _Allocator> 3912inline _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 3913operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) { 3914 using _String = basic_string<_CharT, _Traits, _Allocator>; 3915 typename _String::size_type __lhs_sz = __lhs.size(); 3916 typename _String::size_type __rhs_sz = _Traits::length(__rhs); 3917 _String __r(__uninitialized_size_tag(), 3918 __lhs_sz + __rhs_sz, 3919 _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator())); 3920 auto __ptr = std::__to_address(__r.__get_pointer()); 3921 _Traits::copy(__ptr, __lhs.data(), __lhs_sz); 3922 _Traits::copy(__ptr + __lhs_sz, __rhs, __rhs_sz); 3923 _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT()); 3924 return __r; 3925} 3926 3927template <class _CharT, class _Traits, class _Allocator> 3928_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 3929operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs) { 3930 using _String = basic_string<_CharT, _Traits, _Allocator>; 3931 typename _String::size_type __lhs_sz = __lhs.size(); 3932 _String __r(__uninitialized_size_tag(), 3933 __lhs_sz + 1, 3934 _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator())); 3935 auto __ptr = std::__to_address(__r.__get_pointer()); 3936 _Traits::copy(__ptr, __lhs.data(), __lhs_sz); 3937 _Traits::assign(__ptr + __lhs_sz, 1, __rhs); 3938 _Traits::assign(__ptr + 1 + __lhs_sz, 1, _CharT()); 3939 return __r; 3940} 3941 3942#ifndef _LIBCPP_CXX03_LANG 3943 3944template <class _CharT, class _Traits, class _Allocator> 3945inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 3946operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) { 3947 return std::move(__lhs.append(__rhs)); 3948} 3949 3950template <class _CharT, class _Traits, class _Allocator> 3951inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 3952operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs) { 3953 return std::move(__rhs.insert(0, __lhs)); 3954} 3955 3956template <class _CharT, class _Traits, class _Allocator> 3957inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 3958operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs) { 3959 return std::move(__lhs.append(__rhs)); 3960} 3961 3962template <class _CharT, class _Traits, class _Allocator> 3963inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 3964operator+(const _CharT* __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs) { 3965 return std::move(__rhs.insert(0, __lhs)); 3966} 3967 3968template <class _CharT, class _Traits, class _Allocator> 3969inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 3970operator+(_CharT __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs) { 3971 __rhs.insert(__rhs.begin(), __lhs); 3972 return std::move(__rhs); 3973} 3974 3975template <class _CharT, class _Traits, class _Allocator> 3976inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 3977operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const _CharT* __rhs) { 3978 return std::move(__lhs.append(__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, _CharT __rhs) { 3984 __lhs.push_back(__rhs); 3985 return std::move(__lhs); 3986} 3987 3988#endif // _LIBCPP_CXX03_LANG 3989 3990// swap 3991 3992template <class _CharT, class _Traits, class _Allocator> 3993inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 3994swap(basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>& __rhs) 3995 _NOEXCEPT_(_NOEXCEPT_(__lhs.swap(__rhs))) { 3996 __lhs.swap(__rhs); 3997} 3998 3999_LIBCPP_EXPORTED_FROM_ABI int stoi(const string& __str, size_t* __idx = nullptr, int __base = 10); 4000_LIBCPP_EXPORTED_FROM_ABI long stol(const string& __str, size_t* __idx = nullptr, int __base = 10); 4001_LIBCPP_EXPORTED_FROM_ABI unsigned long stoul(const string& __str, size_t* __idx = nullptr, int __base = 10); 4002_LIBCPP_EXPORTED_FROM_ABI long long stoll(const string& __str, size_t* __idx = nullptr, int __base = 10); 4003_LIBCPP_EXPORTED_FROM_ABI unsigned long long stoull(const string& __str, size_t* __idx = nullptr, int __base = 10); 4004 4005_LIBCPP_EXPORTED_FROM_ABI float stof(const string& __str, size_t* __idx = nullptr); 4006_LIBCPP_EXPORTED_FROM_ABI double stod(const string& __str, size_t* __idx = nullptr); 4007_LIBCPP_EXPORTED_FROM_ABI long double stold(const string& __str, size_t* __idx = nullptr); 4008 4009_LIBCPP_EXPORTED_FROM_ABI string to_string(int __val); 4010_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned __val); 4011_LIBCPP_EXPORTED_FROM_ABI string to_string(long __val); 4012_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long __val); 4013_LIBCPP_EXPORTED_FROM_ABI string to_string(long long __val); 4014_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long long __val); 4015_LIBCPP_EXPORTED_FROM_ABI string to_string(float __val); 4016_LIBCPP_EXPORTED_FROM_ABI string to_string(double __val); 4017_LIBCPP_EXPORTED_FROM_ABI string to_string(long double __val); 4018 4019#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 4020_LIBCPP_EXPORTED_FROM_ABI int stoi(const wstring& __str, size_t* __idx = nullptr, int __base = 10); 4021_LIBCPP_EXPORTED_FROM_ABI long stol(const wstring& __str, size_t* __idx = nullptr, int __base = 10); 4022_LIBCPP_EXPORTED_FROM_ABI unsigned long stoul(const wstring& __str, size_t* __idx = nullptr, int __base = 10); 4023_LIBCPP_EXPORTED_FROM_ABI long long stoll(const wstring& __str, size_t* __idx = nullptr, int __base = 10); 4024_LIBCPP_EXPORTED_FROM_ABI unsigned long long stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10); 4025 4026_LIBCPP_EXPORTED_FROM_ABI float stof(const wstring& __str, size_t* __idx = nullptr); 4027_LIBCPP_EXPORTED_FROM_ABI double stod(const wstring& __str, size_t* __idx = nullptr); 4028_LIBCPP_EXPORTED_FROM_ABI long double stold(const wstring& __str, size_t* __idx = nullptr); 4029 4030_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(int __val); 4031_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned __val); 4032_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long __val); 4033_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long __val); 4034_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long long __val); 4035_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long long __val); 4036_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(float __val); 4037_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(double __val); 4038_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long double __val); 4039#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS 4040 4041template <class _CharT, class _Traits, class _Allocator> 4042_LIBCPP_TEMPLATE_DATA_VIS const typename basic_string<_CharT, _Traits, _Allocator>::size_type 4043 basic_string<_CharT, _Traits, _Allocator>::npos; 4044 4045template <class _CharT, class _Allocator> 4046struct __string_hash : public __unary_function<basic_string<_CharT, char_traits<_CharT>, _Allocator>, size_t> { 4047 _LIBCPP_HIDE_FROM_ABI size_t 4048 operator()(const basic_string<_CharT, char_traits<_CharT>, _Allocator>& __val) const _NOEXCEPT { 4049 return std::__do_string_hash(__val.data(), __val.data() + __val.size()); 4050 } 4051}; 4052 4053template <class _Allocator> 4054struct hash<basic_string<char, char_traits<char>, _Allocator> > : __string_hash<char, _Allocator> {}; 4055 4056#ifndef _LIBCPP_HAS_NO_CHAR8_T 4057template <class _Allocator> 4058struct hash<basic_string<char8_t, char_traits<char8_t>, _Allocator> > : __string_hash<char8_t, _Allocator> {}; 4059#endif 4060 4061template <class _Allocator> 4062struct hash<basic_string<char16_t, char_traits<char16_t>, _Allocator> > : __string_hash<char16_t, _Allocator> {}; 4063 4064template <class _Allocator> 4065struct hash<basic_string<char32_t, char_traits<char32_t>, _Allocator> > : __string_hash<char32_t, _Allocator> {}; 4066 4067#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 4068template <class _Allocator> 4069struct hash<basic_string<wchar_t, char_traits<wchar_t>, _Allocator> > : __string_hash<wchar_t, _Allocator> {}; 4070#endif 4071 4072template <class _CharT, class _Traits, class _Allocator> 4073_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& 4074operator<<(basic_ostream<_CharT, _Traits>& __os, const basic_string<_CharT, _Traits, _Allocator>& __str); 4075 4076template <class _CharT, class _Traits, class _Allocator> 4077_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& 4078operator>>(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Allocator>& __str); 4079 4080template <class _CharT, class _Traits, class _Allocator> 4081_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& 4082getline(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm); 4083 4084template <class _CharT, class _Traits, class _Allocator> 4085inline _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& 4086getline(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Allocator>& __str); 4087 4088template <class _CharT, class _Traits, class _Allocator> 4089inline _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& 4090getline(basic_istream<_CharT, _Traits>&& __is, basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm); 4091 4092template <class _CharT, class _Traits, class _Allocator> 4093inline _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& 4094getline(basic_istream<_CharT, _Traits>&& __is, basic_string<_CharT, _Traits, _Allocator>& __str); 4095 4096#if _LIBCPP_STD_VER >= 20 4097template <class _CharT, class _Traits, class _Allocator, class _Up> 4098inline _LIBCPP_HIDE_FROM_ABI typename basic_string<_CharT, _Traits, _Allocator>::size_type 4099erase(basic_string<_CharT, _Traits, _Allocator>& __str, const _Up& __v) { 4100 auto __old_size = __str.size(); 4101 __str.erase(std::remove(__str.begin(), __str.end(), __v), __str.end()); 4102 return __old_size - __str.size(); 4103} 4104 4105template <class _CharT, class _Traits, class _Allocator, class _Predicate> 4106inline _LIBCPP_HIDE_FROM_ABI typename basic_string<_CharT, _Traits, _Allocator>::size_type 4107erase_if(basic_string<_CharT, _Traits, _Allocator>& __str, _Predicate __pred) { 4108 auto __old_size = __str.size(); 4109 __str.erase(std::remove_if(__str.begin(), __str.end(), __pred), __str.end()); 4110 return __old_size - __str.size(); 4111} 4112#endif 4113 4114#if _LIBCPP_STD_VER >= 14 4115// Literal suffixes for basic_string [basic.string.literals] 4116inline namespace literals { 4117inline namespace string_literals { 4118inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<char> 4119operator""s(const char* __str, size_t __len) { 4120 return basic_string<char>(__str, __len); 4121} 4122 4123# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 4124inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<wchar_t> 4125operator""s(const wchar_t* __str, size_t __len) { 4126 return basic_string<wchar_t>(__str, __len); 4127} 4128# endif 4129 4130# ifndef _LIBCPP_HAS_NO_CHAR8_T 4131inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string<char8_t> operator""s(const char8_t* __str, size_t __len) { 4132 return basic_string<char8_t>(__str, __len); 4133} 4134# endif 4135 4136inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<char16_t> 4137operator""s(const char16_t* __str, size_t __len) { 4138 return basic_string<char16_t>(__str, __len); 4139} 4140 4141inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<char32_t> 4142operator""s(const char32_t* __str, size_t __len) { 4143 return basic_string<char32_t>(__str, __len); 4144} 4145} // namespace string_literals 4146} // namespace literals 4147 4148# if _LIBCPP_STD_VER >= 20 4149template <> 4150inline constexpr bool __format::__enable_insertable<std::basic_string<char>> = true; 4151# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 4152template <> 4153inline constexpr bool __format::__enable_insertable<std::basic_string<wchar_t>> = true; 4154# endif 4155# endif 4156 4157#endif 4158 4159_LIBCPP_END_NAMESPACE_STD 4160 4161_LIBCPP_POP_MACROS 4162 4163#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 4164# include <algorithm> 4165# include <concepts> 4166# include <cstdlib> 4167# include <iterator> 4168# include <new> 4169# include <type_traits> 4170# include <typeinfo> 4171# include <utility> 4172#endif 4173 4174#endif // _LIBCPP_STRING 4175