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