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