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