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