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