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 600_LIBCPP_EXTERN_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#if _LIBCPP_DEBUG_LEVEL == 2 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_DEBUG_LEVEL == 2 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#ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION 1798 _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, char) 1799# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 1800 _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, wchar_t) 1801# endif 1802#else 1803 _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, char) 1804# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 1805 _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, wchar_t) 1806# endif 1807#endif 1808 1809 1810#if _LIBCPP_STD_VER >= 17 1811template<class _InputIterator, 1812 class _CharT = __iter_value_type<_InputIterator>, 1813 class _Allocator = allocator<_CharT>, 1814 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, 1815 class = enable_if_t<__is_allocator<_Allocator>::value> 1816 > 1817basic_string(_InputIterator, _InputIterator, _Allocator = _Allocator()) 1818 -> basic_string<_CharT, char_traits<_CharT>, _Allocator>; 1819 1820template<class _CharT, 1821 class _Traits, 1822 class _Allocator = allocator<_CharT>, 1823 class = enable_if_t<__is_allocator<_Allocator>::value> 1824 > 1825explicit basic_string(basic_string_view<_CharT, _Traits>, const _Allocator& = _Allocator()) 1826 -> basic_string<_CharT, _Traits, _Allocator>; 1827 1828template<class _CharT, 1829 class _Traits, 1830 class _Allocator = allocator<_CharT>, 1831 class = enable_if_t<__is_allocator<_Allocator>::value>, 1832 class _Sz = typename allocator_traits<_Allocator>::size_type 1833 > 1834basic_string(basic_string_view<_CharT, _Traits>, _Sz, _Sz, const _Allocator& = _Allocator()) 1835 -> basic_string<_CharT, _Traits, _Allocator>; 1836#endif 1837 1838template <class _CharT, class _Traits, class _Allocator> 1839inline _LIBCPP_CONSTEXPR_AFTER_CXX17 1840void 1841basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type __pos) 1842{ 1843#if _LIBCPP_DEBUG_LEVEL == 2 1844 if (!__libcpp_is_constant_evaluated()) { 1845 __c_node* __c = __get_db()->__find_c_and_lock(this); 1846 if (__c) 1847 { 1848 const_pointer __new_last = __get_pointer() + __pos; 1849 for (__i_node** __p = __c->end_; __p != __c->beg_; ) 1850 { 1851 --__p; 1852 const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_); 1853 if (__i->base() > __new_last) 1854 { 1855 (*__p)->__c_ = nullptr; 1856 if (--__c->end_ != __p) 1857 std::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); 1858 } 1859 } 1860 __get_db()->unlock(); 1861 } 1862 } 1863#else 1864 (void)__pos; 1865#endif // _LIBCPP_DEBUG_LEVEL == 2 1866} 1867 1868template <class _CharT, class _Traits, class _Allocator> 1869inline _LIBCPP_CONSTEXPR_AFTER_CXX17 1870basic_string<_CharT, _Traits, _Allocator>::basic_string() 1871 _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) 1872 : __r_(__default_init_tag(), __default_init_tag()) 1873{ 1874 std::__debug_db_insert_c(this); 1875 __default_init(); 1876} 1877 1878template <class _CharT, class _Traits, class _Allocator> 1879inline _LIBCPP_CONSTEXPR_AFTER_CXX17 1880basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __a) 1881#if _LIBCPP_STD_VER <= 14 1882 _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value) 1883#else 1884 _NOEXCEPT 1885#endif 1886: __r_(__default_init_tag(), __a) 1887{ 1888 std::__debug_db_insert_c(this); 1889 __default_init(); 1890} 1891 1892template <class _CharT, class _Traits, class _Allocator> 1893_LIBCPP_CONSTEXPR_AFTER_CXX17 1894void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, 1895 size_type __sz, 1896 size_type __reserve) 1897{ 1898 if (__libcpp_is_constant_evaluated()) 1899 __zero(); 1900 if (__reserve > max_size()) 1901 __throw_length_error(); 1902 pointer __p; 1903 if (__fits_in_sso(__reserve)) 1904 { 1905 __set_short_size(__sz); 1906 __p = __get_short_pointer(); 1907 } 1908 else 1909 { 1910 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__reserve) + 1); 1911 __p = __allocation.ptr; 1912 __begin_lifetime(__p, __allocation.count); 1913 __set_long_pointer(__p); 1914 __set_long_cap(__allocation.count); 1915 __set_long_size(__sz); 1916 } 1917 traits_type::copy(std::__to_address(__p), __s, __sz); 1918 traits_type::assign(__p[__sz], value_type()); 1919} 1920 1921template <class _CharT, class _Traits, class _Allocator> 1922_LIBCPP_CONSTEXPR_AFTER_CXX17 1923void 1924basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz) 1925{ 1926 if (__libcpp_is_constant_evaluated()) 1927 __zero(); 1928 if (__sz > max_size()) 1929 __throw_length_error(); 1930 pointer __p; 1931 if (__fits_in_sso(__sz)) 1932 { 1933 __set_short_size(__sz); 1934 __p = __get_short_pointer(); 1935 } 1936 else 1937 { 1938 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1); 1939 __p = __allocation.ptr; 1940 __begin_lifetime(__p, __allocation.count); 1941 __set_long_pointer(__p); 1942 __set_long_cap(__allocation.count); 1943 __set_long_size(__sz); 1944 } 1945 traits_type::copy(std::__to_address(__p), __s, __sz); 1946 traits_type::assign(__p[__sz], value_type()); 1947} 1948 1949template <class _CharT, class _Traits, class _Allocator> 1950template <class> 1951_LIBCPP_CONSTEXPR_AFTER_CXX17 1952basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const _Allocator& __a) 1953 : __r_(__default_init_tag(), __a) 1954{ 1955 _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr"); 1956 __init(__s, traits_type::length(__s)); 1957 std::__debug_db_insert_c(this); 1958} 1959 1960template <class _CharT, class _Traits, class _Allocator> 1961inline _LIBCPP_CONSTEXPR_AFTER_CXX17 1962basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n) 1963 : __r_(__default_init_tag(), __default_init_tag()) 1964{ 1965 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr"); 1966 __init(__s, __n); 1967 std::__debug_db_insert_c(this); 1968} 1969 1970template <class _CharT, class _Traits, class _Allocator> 1971inline _LIBCPP_CONSTEXPR_AFTER_CXX17 1972basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n, const _Allocator& __a) 1973 : __r_(__default_init_tag(), __a) 1974{ 1975 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr"); 1976 __init(__s, __n); 1977 std::__debug_db_insert_c(this); 1978} 1979 1980template <class _CharT, class _Traits, class _Allocator> 1981_LIBCPP_CONSTEXPR_AFTER_CXX17 1982basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str) 1983 : __r_(__default_init_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc())) 1984{ 1985 if (!__str.__is_long()) 1986 __r_.first().__r = __str.__r_.first().__r; 1987 else 1988 __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), 1989 __str.__get_long_size()); 1990 std::__debug_db_insert_c(this); 1991} 1992 1993template <class _CharT, class _Traits, class _Allocator> 1994_LIBCPP_CONSTEXPR_AFTER_CXX17 1995basic_string<_CharT, _Traits, _Allocator>::basic_string( 1996 const basic_string& __str, const allocator_type& __a) 1997 : __r_(__default_init_tag(), __a) 1998{ 1999 if (!__str.__is_long()) 2000 __r_.first().__r = __str.__r_.first().__r; 2001 else 2002 __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), 2003 __str.__get_long_size()); 2004 std::__debug_db_insert_c(this); 2005} 2006 2007template <class _CharT, class _Traits, class _Allocator> 2008_LIBCPP_CONSTEXPR_AFTER_CXX17 2009void basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external( 2010 const value_type* __s, size_type __sz) { 2011 if (__libcpp_is_constant_evaluated()) 2012 __zero(); 2013 pointer __p; 2014 if (__fits_in_sso(__sz)) { 2015 __p = __get_short_pointer(); 2016 __set_short_size(__sz); 2017 } else { 2018 if (__sz > max_size()) 2019 __throw_length_error(); 2020 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1); 2021 __p = __allocation.ptr; 2022 __begin_lifetime(__p, __allocation.count); 2023 __set_long_pointer(__p); 2024 __set_long_cap(__allocation.count); 2025 __set_long_size(__sz); 2026 } 2027 traits_type::copy(std::__to_address(__p), __s, __sz + 1); 2028} 2029 2030#ifndef _LIBCPP_CXX03_LANG 2031 2032template <class _CharT, class _Traits, class _Allocator> 2033inline _LIBCPP_CONSTEXPR_AFTER_CXX17 2034basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str) 2035#if _LIBCPP_STD_VER <= 14 2036 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value) 2037#else 2038 _NOEXCEPT 2039#endif 2040 : __r_(std::move(__str.__r_)) 2041{ 2042 __str.__default_init(); 2043 std::__debug_db_insert_c(this); 2044 if (__is_long()) 2045 std::__debug_db_swap(this, &__str); 2046} 2047 2048template <class _CharT, class _Traits, class _Allocator> 2049inline _LIBCPP_CONSTEXPR_AFTER_CXX17 2050basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, const allocator_type& __a) 2051 : __r_(__default_init_tag(), __a) 2052{ 2053 if (__str.__is_long() && __a != __str.__alloc()) // copy, not move 2054 __init(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); 2055 else 2056 { 2057 if (__libcpp_is_constant_evaluated()) { 2058 __zero(); 2059 __r_.first().__l = __str.__r_.first().__l; 2060 } else { 2061 __r_.first().__r = __str.__r_.first().__r; 2062 } 2063 __str.__default_init(); 2064 } 2065 std::__debug_db_insert_c(this); 2066 if (__is_long()) 2067 std::__debug_db_swap(this, &__str); 2068} 2069 2070#endif // _LIBCPP_CXX03_LANG 2071 2072template <class _CharT, class _Traits, class _Allocator> 2073_LIBCPP_CONSTEXPR_AFTER_CXX17 2074void 2075basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c) 2076{ 2077 if (__libcpp_is_constant_evaluated()) 2078 __zero(); 2079 if (__n > max_size()) 2080 __throw_length_error(); 2081 pointer __p; 2082 if (__fits_in_sso(__n)) 2083 { 2084 __set_short_size(__n); 2085 __p = __get_short_pointer(); 2086 } 2087 else 2088 { 2089 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__n) + 1); 2090 __p = __allocation.ptr; 2091 __begin_lifetime(__p, __allocation.count); 2092 __set_long_pointer(__p); 2093 __set_long_cap(__allocation.count); 2094 __set_long_size(__n); 2095 } 2096 traits_type::assign(std::__to_address(__p), __n, __c); 2097 traits_type::assign(__p[__n], value_type()); 2098} 2099 2100template <class _CharT, class _Traits, class _Allocator> 2101inline _LIBCPP_CONSTEXPR_AFTER_CXX17 2102basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c) 2103 : __r_(__default_init_tag(), __default_init_tag()) 2104{ 2105 __init(__n, __c); 2106 std::__debug_db_insert_c(this); 2107} 2108 2109template <class _CharT, class _Traits, class _Allocator> 2110template <class> 2111_LIBCPP_CONSTEXPR_AFTER_CXX17 2112basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c, const _Allocator& __a) 2113 : __r_(__default_init_tag(), __a) 2114{ 2115 __init(__n, __c); 2116 std::__debug_db_insert_c(this); 2117} 2118 2119template <class _CharT, class _Traits, class _Allocator> 2120_LIBCPP_CONSTEXPR_AFTER_CXX17 2121basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, 2122 size_type __pos, size_type __n, 2123 const _Allocator& __a) 2124 : __r_(__default_init_tag(), __a) 2125{ 2126 size_type __str_sz = __str.size(); 2127 if (__pos > __str_sz) 2128 __throw_out_of_range(); 2129 __init(__str.data() + __pos, std::min(__n, __str_sz - __pos)); 2130 std::__debug_db_insert_c(this); 2131} 2132 2133template <class _CharT, class _Traits, class _Allocator> 2134inline _LIBCPP_CONSTEXPR_AFTER_CXX17 2135basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos, 2136 const _Allocator& __a) 2137 : __r_(__default_init_tag(), __a) 2138{ 2139 size_type __str_sz = __str.size(); 2140 if (__pos > __str_sz) 2141 __throw_out_of_range(); 2142 __init(__str.data() + __pos, __str_sz - __pos); 2143 std::__debug_db_insert_c(this); 2144} 2145 2146template <class _CharT, class _Traits, class _Allocator> 2147template <class _Tp, class> 2148_LIBCPP_CONSTEXPR_AFTER_CXX17 2149basic_string<_CharT, _Traits, _Allocator>::basic_string( 2150 const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a) 2151 : __r_(__default_init_tag(), __a) 2152{ 2153 __self_view __sv0 = __t; 2154 __self_view __sv = __sv0.substr(__pos, __n); 2155 __init(__sv.data(), __sv.size()); 2156 std::__debug_db_insert_c(this); 2157} 2158 2159template <class _CharT, class _Traits, class _Allocator> 2160template <class _Tp, class> 2161_LIBCPP_CONSTEXPR_AFTER_CXX17 2162basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t) 2163 : __r_(__default_init_tag(), __default_init_tag()) 2164{ 2165 __self_view __sv = __t; 2166 __init(__sv.data(), __sv.size()); 2167 std::__debug_db_insert_c(this); 2168} 2169 2170template <class _CharT, class _Traits, class _Allocator> 2171template <class _Tp, class> 2172_LIBCPP_CONSTEXPR_AFTER_CXX17 2173basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t, const _Allocator& __a) 2174 : __r_(__default_init_tag(), __a) 2175{ 2176 __self_view __sv = __t; 2177 __init(__sv.data(), __sv.size()); 2178 std::__debug_db_insert_c(this); 2179} 2180 2181template <class _CharT, class _Traits, class _Allocator> 2182template <class _InputIterator> 2183_LIBCPP_CONSTEXPR_AFTER_CXX17 2184__enable_if_t 2185< 2186 __is_exactly_cpp17_input_iterator<_InputIterator>::value 2187> 2188basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last) 2189{ 2190 __default_init(); 2191#ifndef _LIBCPP_NO_EXCEPTIONS 2192 try 2193 { 2194#endif // _LIBCPP_NO_EXCEPTIONS 2195 for (; __first != __last; ++__first) 2196 push_back(*__first); 2197#ifndef _LIBCPP_NO_EXCEPTIONS 2198 } 2199 catch (...) 2200 { 2201 if (__is_long()) 2202 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 2203 throw; 2204 } 2205#endif // _LIBCPP_NO_EXCEPTIONS 2206} 2207 2208template <class _CharT, class _Traits, class _Allocator> 2209template <class _ForwardIterator> 2210_LIBCPP_CONSTEXPR_AFTER_CXX17 2211__enable_if_t 2212< 2213 __is_cpp17_forward_iterator<_ForwardIterator>::value 2214> 2215basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last) 2216{ 2217 if (__libcpp_is_constant_evaluated()) 2218 __zero(); 2219 size_type __sz = static_cast<size_type>(std::distance(__first, __last)); 2220 if (__sz > max_size()) 2221 __throw_length_error(); 2222 pointer __p; 2223 if (__fits_in_sso(__sz)) 2224 { 2225 __set_short_size(__sz); 2226 __p = __get_short_pointer(); 2227 } 2228 else 2229 { 2230 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1); 2231 __p = __allocation.ptr; 2232 __begin_lifetime(__p, __allocation.count); 2233 __set_long_pointer(__p); 2234 __set_long_cap(__allocation.count); 2235 __set_long_size(__sz); 2236 } 2237 2238#ifndef _LIBCPP_NO_EXCEPTIONS 2239 try 2240 { 2241#endif // _LIBCPP_NO_EXCEPTIONS 2242 for (; __first != __last; ++__first, (void) ++__p) 2243 traits_type::assign(*__p, *__first); 2244 traits_type::assign(*__p, value_type()); 2245#ifndef _LIBCPP_NO_EXCEPTIONS 2246 } 2247 catch (...) 2248 { 2249 if (__is_long()) 2250 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 2251 throw; 2252 } 2253#endif // _LIBCPP_NO_EXCEPTIONS 2254} 2255 2256template <class _CharT, class _Traits, class _Allocator> 2257template<class _InputIterator, class> 2258inline _LIBCPP_CONSTEXPR_AFTER_CXX17 2259basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last) 2260 : __r_(__default_init_tag(), __default_init_tag()) 2261{ 2262 __init(__first, __last); 2263 std::__debug_db_insert_c(this); 2264} 2265 2266template <class _CharT, class _Traits, class _Allocator> 2267template<class _InputIterator, class> 2268inline _LIBCPP_CONSTEXPR_AFTER_CXX17 2269basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last, 2270 const allocator_type& __a) 2271 : __r_(__default_init_tag(), __a) 2272{ 2273 __init(__first, __last); 2274 std::__debug_db_insert_c(this); 2275} 2276 2277#ifndef _LIBCPP_CXX03_LANG 2278 2279template <class _CharT, class _Traits, class _Allocator> 2280inline _LIBCPP_CONSTEXPR_AFTER_CXX17 2281basic_string<_CharT, _Traits, _Allocator>::basic_string( 2282 initializer_list<_CharT> __il) 2283 : __r_(__default_init_tag(), __default_init_tag()) 2284{ 2285 __init(__il.begin(), __il.end()); 2286 std::__debug_db_insert_c(this); 2287} 2288 2289template <class _CharT, class _Traits, class _Allocator> 2290inline _LIBCPP_CONSTEXPR_AFTER_CXX17 2291basic_string<_CharT, _Traits, _Allocator>::basic_string( 2292 initializer_list<_CharT> __il, const _Allocator& __a) 2293 : __r_(__default_init_tag(), __a) 2294{ 2295 __init(__il.begin(), __il.end()); 2296 std::__debug_db_insert_c(this); 2297} 2298 2299#endif // _LIBCPP_CXX03_LANG 2300 2301template <class _CharT, class _Traits, class _Allocator> 2302_LIBCPP_CONSTEXPR_AFTER_CXX17 2303basic_string<_CharT, _Traits, _Allocator>::~basic_string() 2304{ 2305 std::__debug_db_erase_c(this); 2306 if (__is_long()) 2307 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 2308} 2309 2310template <class _CharT, class _Traits, class _Allocator> 2311_LIBCPP_CONSTEXPR_AFTER_CXX17 2312void 2313basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace 2314 (size_type __old_cap, size_type __delta_cap, size_type __old_sz, 2315 size_type __n_copy, size_type __n_del, size_type __n_add, const value_type* __p_new_stuff) 2316{ 2317 size_type __ms = max_size(); 2318 if (__delta_cap > __ms - __old_cap - 1) 2319 __throw_length_error(); 2320 pointer __old_p = __get_pointer(); 2321 size_type __cap = __old_cap < __ms / 2 - __alignment ? 2322 __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : 2323 __ms - 1; 2324 auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1); 2325 pointer __p = __allocation.ptr; 2326 __begin_lifetime(__p, __allocation.count); 2327 std::__debug_db_invalidate_all(this); 2328 if (__n_copy != 0) 2329 traits_type::copy(std::__to_address(__p), 2330 std::__to_address(__old_p), __n_copy); 2331 if (__n_add != 0) 2332 traits_type::copy(std::__to_address(__p) + __n_copy, __p_new_stuff, __n_add); 2333 size_type __sec_cp_sz = __old_sz - __n_del - __n_copy; 2334 if (__sec_cp_sz != 0) 2335 traits_type::copy(std::__to_address(__p) + __n_copy + __n_add, 2336 std::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz); 2337 if (__old_cap+1 != __min_cap || __libcpp_is_constant_evaluated()) 2338 __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1); 2339 __set_long_pointer(__p); 2340 __set_long_cap(__allocation.count); 2341 __old_sz = __n_copy + __n_add + __sec_cp_sz; 2342 __set_long_size(__old_sz); 2343 traits_type::assign(__p[__old_sz], value_type()); 2344} 2345 2346template <class _CharT, class _Traits, class _Allocator> 2347void 2348_LIBCPP_CONSTEXPR_AFTER_CXX17 2349basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz, 2350 size_type __n_copy, size_type __n_del, size_type __n_add) 2351{ 2352 size_type __ms = max_size(); 2353 if (__delta_cap > __ms - __old_cap) 2354 __throw_length_error(); 2355 pointer __old_p = __get_pointer(); 2356 size_type __cap = __old_cap < __ms / 2 - __alignment ? 2357 __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : 2358 __ms - 1; 2359 auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1); 2360 pointer __p = __allocation.ptr; 2361 __begin_lifetime(__p, __allocation.count); 2362 std::__debug_db_invalidate_all(this); 2363 if (__n_copy != 0) 2364 traits_type::copy(std::__to_address(__p), 2365 std::__to_address(__old_p), __n_copy); 2366 size_type __sec_cp_sz = __old_sz - __n_del - __n_copy; 2367 if (__sec_cp_sz != 0) 2368 traits_type::copy(std::__to_address(__p) + __n_copy + __n_add, 2369 std::__to_address(__old_p) + __n_copy + __n_del, 2370 __sec_cp_sz); 2371 if (__libcpp_is_constant_evaluated() || __old_cap + 1 != __min_cap) 2372 __alloc_traits::deallocate(__alloc(), __old_p, __old_cap + 1); 2373 __set_long_pointer(__p); 2374 __set_long_cap(__allocation.count); 2375} 2376 2377// assign 2378 2379template <class _CharT, class _Traits, class _Allocator> 2380template <bool __is_short> 2381_LIBCPP_CONSTEXPR_AFTER_CXX17 2382basic_string<_CharT, _Traits, _Allocator>& 2383basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias( 2384 const value_type* __s, size_type __n) { 2385 size_type __cap = __is_short ? static_cast<size_type>(__min_cap) : __get_long_cap(); 2386 if (__n < __cap) { 2387 pointer __p = __is_short ? __get_short_pointer() : __get_long_pointer(); 2388 __is_short ? __set_short_size(__n) : __set_long_size(__n); 2389 traits_type::copy(std::__to_address(__p), __s, __n); 2390 traits_type::assign(__p[__n], value_type()); 2391 __invalidate_iterators_past(__n); 2392 } else { 2393 size_type __sz = __is_short ? __get_short_size() : __get_long_size(); 2394 __grow_by_and_replace(__cap - 1, __n - __cap + 1, __sz, 0, __sz, __n, __s); 2395 } 2396 return *this; 2397} 2398 2399template <class _CharT, class _Traits, class _Allocator> 2400_LIBCPP_CONSTEXPR_AFTER_CXX17 2401basic_string<_CharT, _Traits, _Allocator>& 2402basic_string<_CharT, _Traits, _Allocator>::__assign_external( 2403 const value_type* __s, size_type __n) { 2404 size_type __cap = capacity(); 2405 if (__cap >= __n) { 2406 value_type* __p = std::__to_address(__get_pointer()); 2407 traits_type::move(__p, __s, __n); 2408 return __null_terminate_at(__p, __n); 2409 } else { 2410 size_type __sz = size(); 2411 __grow_by_and_replace(__cap, __n - __cap, __sz, 0, __sz, __n, __s); 2412 return *this; 2413 } 2414} 2415 2416template <class _CharT, class _Traits, class _Allocator> 2417_LIBCPP_CONSTEXPR_AFTER_CXX17 2418basic_string<_CharT, _Traits, _Allocator>& 2419basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n) 2420{ 2421 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::assign received nullptr"); 2422 return (__builtin_constant_p(__n) && __fits_in_sso(__n)) 2423 ? __assign_short(__s, __n) 2424 : __assign_external(__s, __n); 2425} 2426 2427template <class _CharT, class _Traits, class _Allocator> 2428_LIBCPP_CONSTEXPR_AFTER_CXX17 2429basic_string<_CharT, _Traits, _Allocator>& 2430basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c) 2431{ 2432 size_type __cap = capacity(); 2433 if (__cap < __n) 2434 { 2435 size_type __sz = size(); 2436 __grow_by(__cap, __n - __cap, __sz, 0, __sz); 2437 } 2438 value_type* __p = std::__to_address(__get_pointer()); 2439 traits_type::assign(__p, __n, __c); 2440 return __null_terminate_at(__p, __n); 2441} 2442 2443template <class _CharT, class _Traits, class _Allocator> 2444_LIBCPP_CONSTEXPR_AFTER_CXX17 2445basic_string<_CharT, _Traits, _Allocator>& 2446basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c) 2447{ 2448 pointer __p; 2449 if (__is_long()) 2450 { 2451 __p = __get_long_pointer(); 2452 __set_long_size(1); 2453 } 2454 else 2455 { 2456 __p = __get_short_pointer(); 2457 __set_short_size(1); 2458 } 2459 traits_type::assign(*__p, __c); 2460 traits_type::assign(*++__p, value_type()); 2461 __invalidate_iterators_past(1); 2462 return *this; 2463} 2464 2465template <class _CharT, class _Traits, class _Allocator> 2466_LIBCPP_CONSTEXPR_AFTER_CXX17 2467basic_string<_CharT, _Traits, _Allocator>& 2468basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str) 2469{ 2470 if (this != &__str) { 2471 __copy_assign_alloc(__str); 2472 if (!__is_long()) { 2473 if (!__str.__is_long()) { 2474 __r_.first().__r = __str.__r_.first().__r; 2475 } else { 2476 return __assign_no_alias<true>(__str.data(), __str.size()); 2477 } 2478 } else { 2479 return __assign_no_alias<false>(__str.data(), __str.size()); 2480 } 2481 } 2482 return *this; 2483} 2484 2485#ifndef _LIBCPP_CXX03_LANG 2486 2487template <class _CharT, class _Traits, class _Allocator> 2488inline _LIBCPP_CONSTEXPR_AFTER_CXX17 2489void 2490basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, false_type) 2491 _NOEXCEPT_(__alloc_traits::is_always_equal::value) 2492{ 2493 if (__alloc() != __str.__alloc()) 2494 assign(__str); 2495 else 2496 __move_assign(__str, true_type()); 2497} 2498 2499template <class _CharT, class _Traits, class _Allocator> 2500inline _LIBCPP_CONSTEXPR_AFTER_CXX17 2501void 2502basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type) 2503#if _LIBCPP_STD_VER > 14 2504 _NOEXCEPT 2505#else 2506 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) 2507#endif 2508{ 2509 if (__is_long()) { 2510 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), 2511 __get_long_cap()); 2512#if _LIBCPP_STD_VER <= 14 2513 if (!is_nothrow_move_assignable<allocator_type>::value) { 2514 __set_short_size(0); 2515 traits_type::assign(__get_short_pointer()[0], value_type()); 2516 } 2517#endif 2518 } 2519 __move_assign_alloc(__str); 2520 __r_.first() = __str.__r_.first(); 2521 if (__libcpp_is_constant_evaluated()) { 2522 __str.__default_init(); 2523 } else { 2524 __str.__set_short_size(0); 2525 traits_type::assign(__str.__get_short_pointer()[0], value_type()); 2526 } 2527} 2528 2529template <class _CharT, class _Traits, class _Allocator> 2530inline _LIBCPP_CONSTEXPR_AFTER_CXX17 2531basic_string<_CharT, _Traits, _Allocator>& 2532basic_string<_CharT, _Traits, _Allocator>::operator=(basic_string&& __str) 2533 _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value)) 2534{ 2535 __move_assign(__str, integral_constant<bool, 2536 __alloc_traits::propagate_on_container_move_assignment::value>()); 2537 return *this; 2538} 2539 2540#endif 2541 2542template <class _CharT, class _Traits, class _Allocator> 2543template<class _InputIterator> 2544_LIBCPP_CONSTEXPR_AFTER_CXX17 2545__enable_if_t 2546< 2547 __is_exactly_cpp17_input_iterator<_InputIterator>::value, 2548 basic_string<_CharT, _Traits, _Allocator>& 2549> 2550basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last) 2551{ 2552 const basic_string __temp(__first, __last, __alloc()); 2553 assign(__temp.data(), __temp.size()); 2554 return *this; 2555} 2556 2557template <class _CharT, class _Traits, class _Allocator> 2558template<class _ForwardIterator> 2559_LIBCPP_CONSTEXPR_AFTER_CXX17 2560__enable_if_t 2561< 2562 __is_cpp17_forward_iterator<_ForwardIterator>::value, 2563 basic_string<_CharT, _Traits, _Allocator>& 2564> 2565basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last) 2566{ 2567 size_type __cap = capacity(); 2568 size_type __n = __string_is_trivial_iterator<_ForwardIterator>::value ? 2569 static_cast<size_type>(std::distance(__first, __last)) : 0; 2570 2571 if (__string_is_trivial_iterator<_ForwardIterator>::value && 2572 (__cap >= __n || !__addr_in_range(*__first))) 2573 { 2574 if (__cap < __n) 2575 { 2576 size_type __sz = size(); 2577 __grow_by(__cap, __n - __cap, __sz, 0, __sz); 2578 } 2579 pointer __p = __get_pointer(); 2580 for (; __first != __last; ++__p, (void) ++__first) 2581 traits_type::assign(*__p, *__first); 2582 traits_type::assign(*__p, value_type()); 2583 __set_size(__n); 2584 __invalidate_iterators_past(__n); 2585 } 2586 else 2587 { 2588 const basic_string __temp(__first, __last, __alloc()); 2589 assign(__temp.data(), __temp.size()); 2590 } 2591 return *this; 2592} 2593 2594template <class _CharT, class _Traits, class _Allocator> 2595_LIBCPP_CONSTEXPR_AFTER_CXX17 2596basic_string<_CharT, _Traits, _Allocator>& 2597basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, size_type __pos, size_type __n) 2598{ 2599 size_type __sz = __str.size(); 2600 if (__pos > __sz) 2601 __throw_out_of_range(); 2602 return assign(__str.data() + __pos, std::min(__n, __sz - __pos)); 2603} 2604 2605template <class _CharT, class _Traits, class _Allocator> 2606template <class _Tp> 2607_LIBCPP_CONSTEXPR_AFTER_CXX17 2608__enable_if_t 2609< 2610 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value 2611 && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 2612 basic_string<_CharT, _Traits, _Allocator>& 2613> 2614basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t, size_type __pos, size_type __n) 2615{ 2616 __self_view __sv = __t; 2617 size_type __sz = __sv.size(); 2618 if (__pos > __sz) 2619 __throw_out_of_range(); 2620 return assign(__sv.data() + __pos, std::min(__n, __sz - __pos)); 2621} 2622 2623 2624template <class _CharT, class _Traits, class _Allocator> 2625_LIBCPP_CONSTEXPR_AFTER_CXX17 2626basic_string<_CharT, _Traits, _Allocator>& 2627basic_string<_CharT, _Traits, _Allocator>::__assign_external(const value_type* __s) { 2628 return __assign_external(__s, traits_type::length(__s)); 2629} 2630 2631template <class _CharT, class _Traits, class _Allocator> 2632_LIBCPP_CONSTEXPR_AFTER_CXX17 2633basic_string<_CharT, _Traits, _Allocator>& 2634basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s) 2635{ 2636 _LIBCPP_ASSERT(__s != nullptr, "string::assign received nullptr"); 2637 return __builtin_constant_p(*__s) 2638 ? (__fits_in_sso(traits_type::length(__s)) 2639 ? __assign_short(__s, traits_type::length(__s)) 2640 : __assign_external(__s, traits_type::length(__s))) 2641 : __assign_external(__s); 2642} 2643// append 2644 2645template <class _CharT, class _Traits, class _Allocator> 2646_LIBCPP_CONSTEXPR_AFTER_CXX17 2647basic_string<_CharT, _Traits, _Allocator>& 2648basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n) 2649{ 2650 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::append received nullptr"); 2651 size_type __cap = capacity(); 2652 size_type __sz = size(); 2653 if (__cap - __sz >= __n) 2654 { 2655 if (__n) 2656 { 2657 value_type* __p = std::__to_address(__get_pointer()); 2658 traits_type::copy(__p + __sz, __s, __n); 2659 __sz += __n; 2660 __set_size(__sz); 2661 traits_type::assign(__p[__sz], value_type()); 2662 } 2663 } 2664 else 2665 __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __sz, 0, __n, __s); 2666 return *this; 2667} 2668 2669template <class _CharT, class _Traits, class _Allocator> 2670_LIBCPP_CONSTEXPR_AFTER_CXX17 2671basic_string<_CharT, _Traits, _Allocator>& 2672basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c) 2673{ 2674 if (__n) 2675 { 2676 size_type __cap = capacity(); 2677 size_type __sz = size(); 2678 if (__cap - __sz < __n) 2679 __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); 2680 pointer __p = __get_pointer(); 2681 traits_type::assign(std::__to_address(__p) + __sz, __n, __c); 2682 __sz += __n; 2683 __set_size(__sz); 2684 traits_type::assign(__p[__sz], value_type()); 2685 } 2686 return *this; 2687} 2688 2689template <class _CharT, class _Traits, class _Allocator> 2690_LIBCPP_CONSTEXPR_AFTER_CXX17 inline void 2691basic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n) 2692{ 2693 if (__n) 2694 { 2695 size_type __cap = capacity(); 2696 size_type __sz = size(); 2697 if (__cap - __sz < __n) 2698 __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); 2699 pointer __p = __get_pointer(); 2700 __sz += __n; 2701 __set_size(__sz); 2702 traits_type::assign(__p[__sz], value_type()); 2703 } 2704} 2705 2706template <class _CharT, class _Traits, class _Allocator> 2707_LIBCPP_CONSTEXPR_AFTER_CXX17 2708void 2709basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c) 2710{ 2711 bool __is_short = !__is_long(); 2712 size_type __cap; 2713 size_type __sz; 2714 if (__is_short) 2715 { 2716 __cap = __min_cap - 1; 2717 __sz = __get_short_size(); 2718 } 2719 else 2720 { 2721 __cap = __get_long_cap() - 1; 2722 __sz = __get_long_size(); 2723 } 2724 if (__sz == __cap) 2725 { 2726 __grow_by(__cap, 1, __sz, __sz, 0); 2727 __is_short = false; // the string is always long after __grow_by 2728 } 2729 pointer __p = __get_pointer(); 2730 if (__is_short) 2731 { 2732 __p = __get_short_pointer() + __sz; 2733 __set_short_size(__sz+1); 2734 } 2735 else 2736 { 2737 __p = __get_long_pointer() + __sz; 2738 __set_long_size(__sz+1); 2739 } 2740 traits_type::assign(*__p, __c); 2741 traits_type::assign(*++__p, value_type()); 2742} 2743 2744template <class _CharT, class _Traits, class _Allocator> 2745template<class _ForwardIterator> 2746_LIBCPP_CONSTEXPR_AFTER_CXX17 2747__enable_if_t 2748< 2749 __is_cpp17_forward_iterator<_ForwardIterator>::value, 2750 basic_string<_CharT, _Traits, _Allocator>& 2751> 2752basic_string<_CharT, _Traits, _Allocator>::append( 2753 _ForwardIterator __first, _ForwardIterator __last) 2754{ 2755 size_type __sz = size(); 2756 size_type __cap = capacity(); 2757 size_type __n = static_cast<size_type>(std::distance(__first, __last)); 2758 if (__n) 2759 { 2760 if (__string_is_trivial_iterator<_ForwardIterator>::value && 2761 !__addr_in_range(*__first)) 2762 { 2763 if (__cap - __sz < __n) 2764 __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); 2765 pointer __p = __get_pointer() + __sz; 2766 for (; __first != __last; ++__p, (void) ++__first) 2767 traits_type::assign(*__p, *__first); 2768 traits_type::assign(*__p, value_type()); 2769 __set_size(__sz + __n); 2770 } 2771 else 2772 { 2773 const basic_string __temp(__first, __last, __alloc()); 2774 append(__temp.data(), __temp.size()); 2775 } 2776 } 2777 return *this; 2778} 2779 2780template <class _CharT, class _Traits, class _Allocator> 2781inline _LIBCPP_CONSTEXPR_AFTER_CXX17 2782basic_string<_CharT, _Traits, _Allocator>& 2783basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str) 2784{ 2785 return append(__str.data(), __str.size()); 2786} 2787 2788template <class _CharT, class _Traits, class _Allocator> 2789_LIBCPP_CONSTEXPR_AFTER_CXX17 2790basic_string<_CharT, _Traits, _Allocator>& 2791basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, size_type __pos, size_type __n) 2792{ 2793 size_type __sz = __str.size(); 2794 if (__pos > __sz) 2795 __throw_out_of_range(); 2796 return append(__str.data() + __pos, std::min(__n, __sz - __pos)); 2797} 2798 2799template <class _CharT, class _Traits, class _Allocator> 2800template <class _Tp> 2801_LIBCPP_CONSTEXPR_AFTER_CXX17 2802 __enable_if_t 2803 < 2804 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 2805 basic_string<_CharT, _Traits, _Allocator>& 2806 > 2807basic_string<_CharT, _Traits, _Allocator>::append(const _Tp & __t, size_type __pos, size_type __n) 2808{ 2809 __self_view __sv = __t; 2810 size_type __sz = __sv.size(); 2811 if (__pos > __sz) 2812 __throw_out_of_range(); 2813 return append(__sv.data() + __pos, std::min(__n, __sz - __pos)); 2814} 2815 2816template <class _CharT, class _Traits, class _Allocator> 2817_LIBCPP_CONSTEXPR_AFTER_CXX17 2818basic_string<_CharT, _Traits, _Allocator>& 2819basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s) 2820{ 2821 _LIBCPP_ASSERT(__s != nullptr, "string::append received nullptr"); 2822 return append(__s, traits_type::length(__s)); 2823} 2824 2825// insert 2826 2827template <class _CharT, class _Traits, class _Allocator> 2828_LIBCPP_CONSTEXPR_AFTER_CXX17 2829basic_string<_CharT, _Traits, _Allocator>& 2830basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n) 2831{ 2832 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::insert received nullptr"); 2833 size_type __sz = size(); 2834 if (__pos > __sz) 2835 __throw_out_of_range(); 2836 size_type __cap = capacity(); 2837 if (__libcpp_is_constant_evaluated()) { 2838 if (__cap - __sz >= __n) 2839 __grow_by_and_replace(__cap, 0, __sz, __pos, 0, __n, __s); 2840 else 2841 __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s); 2842 return *this; 2843 } 2844 if (__cap - __sz >= __n) 2845 { 2846 if (__n) 2847 { 2848 value_type* __p = std::__to_address(__get_pointer()); 2849 size_type __n_move = __sz - __pos; 2850 if (__n_move != 0) 2851 { 2852 if (__p + __pos <= __s && __s < __p + __sz) 2853 __s += __n; 2854 traits_type::move(__p + __pos + __n, __p + __pos, __n_move); 2855 } 2856 traits_type::move(__p + __pos, __s, __n); 2857 __sz += __n; 2858 __set_size(__sz); 2859 traits_type::assign(__p[__sz], value_type()); 2860 } 2861 } 2862 else 2863 __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s); 2864 return *this; 2865} 2866 2867template <class _CharT, class _Traits, class _Allocator> 2868_LIBCPP_CONSTEXPR_AFTER_CXX17 2869basic_string<_CharT, _Traits, _Allocator>& 2870basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n, value_type __c) 2871{ 2872 size_type __sz = size(); 2873 if (__pos > __sz) 2874 __throw_out_of_range(); 2875 if (__n) 2876 { 2877 size_type __cap = capacity(); 2878 value_type* __p; 2879 if (__cap - __sz >= __n) 2880 { 2881 __p = std::__to_address(__get_pointer()); 2882 size_type __n_move = __sz - __pos; 2883 if (__n_move != 0) 2884 traits_type::move(__p + __pos + __n, __p + __pos, __n_move); 2885 } 2886 else 2887 { 2888 __grow_by(__cap, __sz + __n - __cap, __sz, __pos, 0, __n); 2889 __p = std::__to_address(__get_long_pointer()); 2890 } 2891 traits_type::assign(__p + __pos, __n, __c); 2892 __sz += __n; 2893 __set_size(__sz); 2894 traits_type::assign(__p[__sz], value_type()); 2895 } 2896 return *this; 2897} 2898 2899template <class _CharT, class _Traits, class _Allocator> 2900template<class _InputIterator> 2901_LIBCPP_CONSTEXPR_AFTER_CXX17 2902__enable_if_t 2903< 2904 __is_exactly_cpp17_input_iterator<_InputIterator>::value, 2905 typename basic_string<_CharT, _Traits, _Allocator>::iterator 2906> 2907basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last) 2908{ 2909 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, 2910 "string::insert(iterator, range) called with an iterator not" 2911 " referring to this string"); 2912 const basic_string __temp(__first, __last, __alloc()); 2913 return insert(__pos, __temp.data(), __temp.data() + __temp.size()); 2914} 2915 2916template <class _CharT, class _Traits, class _Allocator> 2917template<class _ForwardIterator> 2918_LIBCPP_CONSTEXPR_AFTER_CXX17 2919__enable_if_t 2920< 2921 __is_cpp17_forward_iterator<_ForwardIterator>::value, 2922 typename basic_string<_CharT, _Traits, _Allocator>::iterator 2923> 2924basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last) 2925{ 2926 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, 2927 "string::insert(iterator, range) called with an iterator not referring to this string"); 2928 2929 size_type __ip = static_cast<size_type>(__pos - begin()); 2930 size_type __n = static_cast<size_type>(std::distance(__first, __last)); 2931 if (__n == 0) 2932 return begin() + __ip; 2933 2934 if (__string_is_trivial_iterator<_ForwardIterator>::value && !__addr_in_range(*__first)) 2935 { 2936 return __insert_from_safe_copy(__n, __ip, __first, __last); 2937 } 2938 else 2939 { 2940 const basic_string __temp(__first, __last, __alloc()); 2941 return __insert_from_safe_copy(__n, __ip, __temp.begin(), __temp.end()); 2942 } 2943} 2944 2945template <class _CharT, class _Traits, class _Allocator> 2946inline _LIBCPP_CONSTEXPR_AFTER_CXX17 2947basic_string<_CharT, _Traits, _Allocator>& 2948basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str) 2949{ 2950 return insert(__pos1, __str.data(), __str.size()); 2951} 2952 2953template <class _CharT, class _Traits, class _Allocator> 2954_LIBCPP_CONSTEXPR_AFTER_CXX17 2955basic_string<_CharT, _Traits, _Allocator>& 2956basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str, 2957 size_type __pos2, size_type __n) 2958{ 2959 size_type __str_sz = __str.size(); 2960 if (__pos2 > __str_sz) 2961 __throw_out_of_range(); 2962 return insert(__pos1, __str.data() + __pos2, std::min(__n, __str_sz - __pos2)); 2963} 2964 2965template <class _CharT, class _Traits, class _Allocator> 2966template <class _Tp> 2967_LIBCPP_CONSTEXPR_AFTER_CXX17 2968__enable_if_t 2969< 2970 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 2971 basic_string<_CharT, _Traits, _Allocator>& 2972> 2973basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& __t, 2974 size_type __pos2, size_type __n) 2975{ 2976 __self_view __sv = __t; 2977 size_type __str_sz = __sv.size(); 2978 if (__pos2 > __str_sz) 2979 __throw_out_of_range(); 2980 return insert(__pos1, __sv.data() + __pos2, std::min(__n, __str_sz - __pos2)); 2981} 2982 2983template <class _CharT, class _Traits, class _Allocator> 2984_LIBCPP_CONSTEXPR_AFTER_CXX17 2985basic_string<_CharT, _Traits, _Allocator>& 2986basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s) 2987{ 2988 _LIBCPP_ASSERT(__s != nullptr, "string::insert received nullptr"); 2989 return insert(__pos, __s, traits_type::length(__s)); 2990} 2991 2992template <class _CharT, class _Traits, class _Allocator> 2993_LIBCPP_CONSTEXPR_AFTER_CXX17 2994typename basic_string<_CharT, _Traits, _Allocator>::iterator 2995basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c) 2996{ 2997 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, 2998 "string::insert(iterator, character) called with an iterator not" 2999 " referring to this string"); 3000 3001 size_type __ip = static_cast<size_type>(__pos - begin()); 3002 size_type __sz = size(); 3003 size_type __cap = capacity(); 3004 value_type* __p; 3005 if (__cap == __sz) 3006 { 3007 __grow_by(__cap, 1, __sz, __ip, 0, 1); 3008 __p = std::__to_address(__get_long_pointer()); 3009 } 3010 else 3011 { 3012 __p = std::__to_address(__get_pointer()); 3013 size_type __n_move = __sz - __ip; 3014 if (__n_move != 0) 3015 traits_type::move(__p + __ip + 1, __p + __ip, __n_move); 3016 } 3017 traits_type::assign(__p[__ip], __c); 3018 traits_type::assign(__p[++__sz], value_type()); 3019 __set_size(__sz); 3020 return begin() + static_cast<difference_type>(__ip); 3021} 3022 3023template <class _CharT, class _Traits, class _Allocator> 3024inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3025typename basic_string<_CharT, _Traits, _Allocator>::iterator 3026basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, size_type __n, value_type __c) 3027{ 3028 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, 3029 "string::insert(iterator, n, value) called with an iterator not" 3030 " referring to this string"); 3031 difference_type __p = __pos - begin(); 3032 insert(static_cast<size_type>(__p), __n, __c); 3033 return begin() + __p; 3034} 3035 3036// replace 3037 3038template <class _CharT, class _Traits, class _Allocator> 3039_LIBCPP_CONSTEXPR_AFTER_CXX17 3040basic_string<_CharT, _Traits, _Allocator>& 3041basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2) 3042 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK 3043{ 3044 _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::replace received nullptr"); 3045 size_type __sz = size(); 3046 if (__pos > __sz) 3047 __throw_out_of_range(); 3048 __n1 = std::min(__n1, __sz - __pos); 3049 size_type __cap = capacity(); 3050 if (__cap - __sz + __n1 >= __n2) 3051 { 3052 if (__libcpp_is_constant_evaluated()) { 3053 __grow_by_and_replace(__cap, 0, __sz, __pos, __n1, __n2, __s); 3054 return *this; 3055 } 3056 value_type* __p = std::__to_address(__get_pointer()); 3057 if (__n1 != __n2) 3058 { 3059 size_type __n_move = __sz - __pos - __n1; 3060 if (__n_move != 0) 3061 { 3062 if (__n1 > __n2) 3063 { 3064 traits_type::move(__p + __pos, __s, __n2); 3065 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move); 3066 return __null_terminate_at(__p, __sz + (__n2 - __n1)); 3067 } 3068 if (__p + __pos < __s && __s < __p + __sz) 3069 { 3070 if (__p + __pos + __n1 <= __s) 3071 __s += __n2 - __n1; 3072 else // __p + __pos < __s < __p + __pos + __n1 3073 { 3074 traits_type::move(__p + __pos, __s, __n1); 3075 __pos += __n1; 3076 __s += __n2; 3077 __n2 -= __n1; 3078 __n1 = 0; 3079 } 3080 } 3081 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move); 3082 } 3083 } 3084 traits_type::move(__p + __pos, __s, __n2); 3085 return __null_terminate_at(__p, __sz + (__n2 - __n1)); 3086 } 3087 else 3088 __grow_by_and_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2, __s); 3089 return *this; 3090} 3091 3092template <class _CharT, class _Traits, class _Allocator> 3093_LIBCPP_CONSTEXPR_AFTER_CXX17 3094basic_string<_CharT, _Traits, _Allocator>& 3095basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, size_type __n2, value_type __c) 3096{ 3097 size_type __sz = size(); 3098 if (__pos > __sz) 3099 __throw_out_of_range(); 3100 __n1 = std::min(__n1, __sz - __pos); 3101 size_type __cap = capacity(); 3102 value_type* __p; 3103 if (__cap - __sz + __n1 >= __n2) 3104 { 3105 __p = std::__to_address(__get_pointer()); 3106 if (__n1 != __n2) 3107 { 3108 size_type __n_move = __sz - __pos - __n1; 3109 if (__n_move != 0) 3110 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move); 3111 } 3112 } 3113 else 3114 { 3115 __grow_by(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2); 3116 __p = std::__to_address(__get_long_pointer()); 3117 } 3118 traits_type::assign(__p + __pos, __n2, __c); 3119 return __null_terminate_at(__p, __sz - (__n1 - __n2)); 3120} 3121 3122template <class _CharT, class _Traits, class _Allocator> 3123template<class _InputIterator> 3124_LIBCPP_CONSTEXPR_AFTER_CXX17 3125__enable_if_t 3126< 3127 __is_cpp17_input_iterator<_InputIterator>::value, 3128 basic_string<_CharT, _Traits, _Allocator>& 3129> 3130basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, 3131 _InputIterator __j1, _InputIterator __j2) 3132{ 3133 const basic_string __temp(__j1, __j2, __alloc()); 3134 return replace(__i1, __i2, __temp); 3135} 3136 3137template <class _CharT, class _Traits, class _Allocator> 3138inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3139basic_string<_CharT, _Traits, _Allocator>& 3140basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str) 3141{ 3142 return replace(__pos1, __n1, __str.data(), __str.size()); 3143} 3144 3145template <class _CharT, class _Traits, class _Allocator> 3146_LIBCPP_CONSTEXPR_AFTER_CXX17 3147basic_string<_CharT, _Traits, _Allocator>& 3148basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str, 3149 size_type __pos2, size_type __n2) 3150{ 3151 size_type __str_sz = __str.size(); 3152 if (__pos2 > __str_sz) 3153 __throw_out_of_range(); 3154 return replace(__pos1, __n1, __str.data() + __pos2, std::min(__n2, __str_sz - __pos2)); 3155} 3156 3157template <class _CharT, class _Traits, class _Allocator> 3158template <class _Tp> 3159_LIBCPP_CONSTEXPR_AFTER_CXX17 3160__enable_if_t 3161< 3162 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 3163 basic_string<_CharT, _Traits, _Allocator>& 3164> 3165basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const _Tp& __t, 3166 size_type __pos2, size_type __n2) 3167{ 3168 __self_view __sv = __t; 3169 size_type __str_sz = __sv.size(); 3170 if (__pos2 > __str_sz) 3171 __throw_out_of_range(); 3172 return replace(__pos1, __n1, __sv.data() + __pos2, std::min(__n2, __str_sz - __pos2)); 3173} 3174 3175template <class _CharT, class _Traits, class _Allocator> 3176_LIBCPP_CONSTEXPR_AFTER_CXX17 3177basic_string<_CharT, _Traits, _Allocator>& 3178basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s) 3179{ 3180 _LIBCPP_ASSERT(__s != nullptr, "string::replace received nullptr"); 3181 return replace(__pos, __n1, __s, traits_type::length(__s)); 3182} 3183 3184template <class _CharT, class _Traits, class _Allocator> 3185inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3186basic_string<_CharT, _Traits, _Allocator>& 3187basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const basic_string& __str) 3188{ 3189 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), 3190 __str.data(), __str.size()); 3191} 3192 3193template <class _CharT, class _Traits, class _Allocator> 3194inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3195basic_string<_CharT, _Traits, _Allocator>& 3196basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n) 3197{ 3198 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s, __n); 3199} 3200 3201template <class _CharT, class _Traits, class _Allocator> 3202inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3203basic_string<_CharT, _Traits, _Allocator>& 3204basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s) 3205{ 3206 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s); 3207} 3208 3209template <class _CharT, class _Traits, class _Allocator> 3210inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3211basic_string<_CharT, _Traits, _Allocator>& 3212basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c) 3213{ 3214 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __n, __c); 3215} 3216 3217// erase 3218 3219// 'externally instantiated' erase() implementation, called when __n != npos. 3220// Does not check __pos against size() 3221template <class _CharT, class _Traits, class _Allocator> 3222_LIBCPP_CONSTEXPR_AFTER_CXX17 3223void 3224basic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move( 3225 size_type __pos, size_type __n) 3226{ 3227 if (__n) 3228 { 3229 size_type __sz = size(); 3230 value_type* __p = std::__to_address(__get_pointer()); 3231 __n = std::min(__n, __sz - __pos); 3232 size_type __n_move = __sz - __pos - __n; 3233 if (__n_move != 0) 3234 traits_type::move(__p + __pos, __p + __pos + __n, __n_move); 3235 __null_terminate_at(__p, __sz - __n); 3236 } 3237} 3238 3239template <class _CharT, class _Traits, class _Allocator> 3240_LIBCPP_CONSTEXPR_AFTER_CXX17 3241basic_string<_CharT, _Traits, _Allocator>& 3242basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, 3243 size_type __n) { 3244 if (__pos > size()) 3245 __throw_out_of_range(); 3246 if (__n == npos) { 3247 __erase_to_end(__pos); 3248 } else { 3249 __erase_external_with_move(__pos, __n); 3250 } 3251 return *this; 3252} 3253 3254template <class _CharT, class _Traits, class _Allocator> 3255inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3256typename basic_string<_CharT, _Traits, _Allocator>::iterator 3257basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos) 3258{ 3259 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, 3260 "string::erase(iterator) called with an iterator not" 3261 " referring to this string"); 3262 3263 _LIBCPP_ASSERT(__pos != end(), "string::erase(iterator) called with a non-dereferenceable iterator"); 3264 iterator __b = begin(); 3265 size_type __r = static_cast<size_type>(__pos - __b); 3266 erase(__r, 1); 3267 return __b + static_cast<difference_type>(__r); 3268} 3269 3270template <class _CharT, class _Traits, class _Allocator> 3271inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3272typename basic_string<_CharT, _Traits, _Allocator>::iterator 3273basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last) 3274{ 3275 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this, 3276 "string::erase(iterator, iterator) called with an iterator not" 3277 " referring to this string"); 3278 3279 _LIBCPP_ASSERT(__first <= __last, "string::erase(first, last) called with invalid range"); 3280 iterator __b = begin(); 3281 size_type __r = static_cast<size_type>(__first - __b); 3282 erase(__r, static_cast<size_type>(__last - __first)); 3283 return __b + static_cast<difference_type>(__r); 3284} 3285 3286template <class _CharT, class _Traits, class _Allocator> 3287inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3288void 3289basic_string<_CharT, _Traits, _Allocator>::pop_back() 3290{ 3291 _LIBCPP_ASSERT(!empty(), "string::pop_back(): string is already empty"); 3292 __erase_to_end(size() - 1); 3293} 3294 3295template <class _CharT, class _Traits, class _Allocator> 3296inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3297void 3298basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT 3299{ 3300 std::__debug_db_invalidate_all(this); 3301 if (__is_long()) 3302 { 3303 traits_type::assign(*__get_long_pointer(), value_type()); 3304 __set_long_size(0); 3305 } 3306 else 3307 { 3308 traits_type::assign(*__get_short_pointer(), value_type()); 3309 __set_short_size(0); 3310 } 3311} 3312 3313template <class _CharT, class _Traits, class _Allocator> 3314inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3315void 3316basic_string<_CharT, _Traits, _Allocator>::__erase_to_end(size_type __pos) 3317{ 3318 __null_terminate_at(std::__to_address(__get_pointer()), __pos); 3319} 3320 3321template <class _CharT, class _Traits, class _Allocator> 3322_LIBCPP_CONSTEXPR_AFTER_CXX17 3323void 3324basic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c) 3325{ 3326 size_type __sz = size(); 3327 if (__n > __sz) 3328 append(__n - __sz, __c); 3329 else 3330 __erase_to_end(__n); 3331} 3332 3333template <class _CharT, class _Traits, class _Allocator> 3334_LIBCPP_CONSTEXPR_AFTER_CXX17 inline void 3335basic_string<_CharT, _Traits, _Allocator>::__resize_default_init(size_type __n) 3336{ 3337 size_type __sz = size(); 3338 if (__n > __sz) { 3339 __append_default_init(__n - __sz); 3340 } else 3341 __erase_to_end(__n); 3342} 3343 3344template <class _CharT, class _Traits, class _Allocator> 3345inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3346typename basic_string<_CharT, _Traits, _Allocator>::size_type 3347basic_string<_CharT, _Traits, _Allocator>::max_size() const _NOEXCEPT 3348{ 3349 size_type __m = __alloc_traits::max_size(__alloc()); 3350 if (__m <= std::numeric_limits<size_type>::max() / 2) { 3351 return __m - __alignment; 3352 } else { 3353 bool __uses_lsb = __endian_factor == 2; 3354 return __uses_lsb ? __m - __alignment : (__m / 2) - __alignment; 3355 } 3356} 3357 3358template <class _CharT, class _Traits, class _Allocator> 3359_LIBCPP_CONSTEXPR_AFTER_CXX17 3360void 3361basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacity) 3362{ 3363 if (__requested_capacity > max_size()) 3364 __throw_length_error(); 3365 3366 // Make sure reserve(n) never shrinks. This is technically only required in C++20 3367 // and later (since P0966R1), however we provide consistent behavior in all Standard 3368 // modes because this function is instantiated in the shared library. 3369 if (__requested_capacity <= capacity()) 3370 return; 3371 3372 size_type __target_capacity = std::max(__requested_capacity, size()); 3373 __target_capacity = __recommend(__target_capacity); 3374 if (__target_capacity == capacity()) return; 3375 3376 __shrink_or_extend(__target_capacity); 3377} 3378 3379template <class _CharT, class _Traits, class _Allocator> 3380inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3381void 3382basic_string<_CharT, _Traits, _Allocator>::shrink_to_fit() _NOEXCEPT 3383{ 3384 size_type __target_capacity = __recommend(size()); 3385 if (__target_capacity == capacity()) return; 3386 3387 __shrink_or_extend(__target_capacity); 3388} 3389 3390template <class _CharT, class _Traits, class _Allocator> 3391inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3392void 3393basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target_capacity) 3394{ 3395 size_type __cap = capacity(); 3396 size_type __sz = size(); 3397 3398 pointer __new_data, __p; 3399 bool __was_long, __now_long; 3400 if (__fits_in_sso(__target_capacity)) 3401 { 3402 __was_long = true; 3403 __now_long = false; 3404 __new_data = __get_short_pointer(); 3405 __p = __get_long_pointer(); 3406 } 3407 else 3408 { 3409 if (__target_capacity > __cap) { 3410 auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1); 3411 __new_data = __allocation.ptr; 3412 __target_capacity = __allocation.count - 1; 3413 } 3414 else 3415 { 3416 #ifndef _LIBCPP_NO_EXCEPTIONS 3417 try 3418 { 3419 #endif // _LIBCPP_NO_EXCEPTIONS 3420 auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1); 3421 __new_data = __allocation.ptr; 3422 __target_capacity = __allocation.count - 1; 3423 #ifndef _LIBCPP_NO_EXCEPTIONS 3424 } 3425 catch (...) 3426 { 3427 return; 3428 } 3429 #else // _LIBCPP_NO_EXCEPTIONS 3430 if (__new_data == nullptr) 3431 return; 3432 #endif // _LIBCPP_NO_EXCEPTIONS 3433 } 3434 __begin_lifetime(__new_data, __target_capacity + 1); 3435 __now_long = true; 3436 __was_long = __is_long(); 3437 __p = __get_pointer(); 3438 } 3439 traits_type::copy(std::__to_address(__new_data), 3440 std::__to_address(__p), size()+1); 3441 if (__was_long) 3442 __alloc_traits::deallocate(__alloc(), __p, __cap+1); 3443 if (__now_long) 3444 { 3445 __set_long_cap(__target_capacity+1); 3446 __set_long_size(__sz); 3447 __set_long_pointer(__new_data); 3448 } 3449 else 3450 __set_short_size(__sz); 3451 std::__debug_db_invalidate_all(this); 3452} 3453 3454template <class _CharT, class _Traits, class _Allocator> 3455inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3456typename basic_string<_CharT, _Traits, _Allocator>::const_reference 3457basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const _NOEXCEPT 3458{ 3459 _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds"); 3460 return *(data() + __pos); 3461} 3462 3463template <class _CharT, class _Traits, class _Allocator> 3464inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3465typename basic_string<_CharT, _Traits, _Allocator>::reference 3466basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) _NOEXCEPT 3467{ 3468 _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds"); 3469 return *(__get_pointer() + __pos); 3470} 3471 3472template <class _CharT, class _Traits, class _Allocator> 3473_LIBCPP_CONSTEXPR_AFTER_CXX17 3474typename basic_string<_CharT, _Traits, _Allocator>::const_reference 3475basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const 3476{ 3477 if (__n >= size()) 3478 __throw_out_of_range(); 3479 return (*this)[__n]; 3480} 3481 3482template <class _CharT, class _Traits, class _Allocator> 3483_LIBCPP_CONSTEXPR_AFTER_CXX17 3484typename basic_string<_CharT, _Traits, _Allocator>::reference 3485basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) 3486{ 3487 if (__n >= size()) 3488 __throw_out_of_range(); 3489 return (*this)[__n]; 3490} 3491 3492template <class _CharT, class _Traits, class _Allocator> 3493inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3494typename basic_string<_CharT, _Traits, _Allocator>::reference 3495basic_string<_CharT, _Traits, _Allocator>::front() _NOEXCEPT 3496{ 3497 _LIBCPP_ASSERT(!empty(), "string::front(): string is empty"); 3498 return *__get_pointer(); 3499} 3500 3501template <class _CharT, class _Traits, class _Allocator> 3502inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3503typename basic_string<_CharT, _Traits, _Allocator>::const_reference 3504basic_string<_CharT, _Traits, _Allocator>::front() const _NOEXCEPT 3505{ 3506 _LIBCPP_ASSERT(!empty(), "string::front(): string is empty"); 3507 return *data(); 3508} 3509 3510template <class _CharT, class _Traits, class _Allocator> 3511inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3512typename basic_string<_CharT, _Traits, _Allocator>::reference 3513basic_string<_CharT, _Traits, _Allocator>::back() _NOEXCEPT 3514{ 3515 _LIBCPP_ASSERT(!empty(), "string::back(): string is empty"); 3516 return *(__get_pointer() + size() - 1); 3517} 3518 3519template <class _CharT, class _Traits, class _Allocator> 3520inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3521typename basic_string<_CharT, _Traits, _Allocator>::const_reference 3522basic_string<_CharT, _Traits, _Allocator>::back() const _NOEXCEPT 3523{ 3524 _LIBCPP_ASSERT(!empty(), "string::back(): string is empty"); 3525 return *(data() + size() - 1); 3526} 3527 3528template <class _CharT, class _Traits, class _Allocator> 3529_LIBCPP_CONSTEXPR_AFTER_CXX17 3530typename basic_string<_CharT, _Traits, _Allocator>::size_type 3531basic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n, size_type __pos) const 3532{ 3533 size_type __sz = size(); 3534 if (__pos > __sz) 3535 __throw_out_of_range(); 3536 size_type __rlen = std::min(__n, __sz - __pos); 3537 traits_type::copy(__s, data() + __pos, __rlen); 3538 return __rlen; 3539} 3540 3541template <class _CharT, class _Traits, class _Allocator> 3542inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3543basic_string<_CharT, _Traits, _Allocator> 3544basic_string<_CharT, _Traits, _Allocator>::substr(size_type __pos, size_type __n) const 3545{ 3546 return basic_string(*this, __pos, __n, __alloc()); 3547} 3548 3549template <class _CharT, class _Traits, class _Allocator> 3550inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3551void 3552basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str) 3553#if _LIBCPP_STD_VER >= 14 3554 _NOEXCEPT 3555#else 3556 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || 3557 __is_nothrow_swappable<allocator_type>::value) 3558#endif 3559{ 3560 if (!__is_long()) 3561 std::__debug_db_invalidate_all(this); 3562 if (!__str.__is_long()) 3563 std::__debug_db_invalidate_all(&__str); 3564 std::__debug_db_swap(this, &__str); 3565 3566 _LIBCPP_ASSERT( 3567 __alloc_traits::propagate_on_container_swap::value || 3568 __alloc_traits::is_always_equal::value || 3569 __alloc() == __str.__alloc(), "swapping non-equal allocators"); 3570 std::swap(__r_.first(), __str.__r_.first()); 3571 std::__swap_allocator(__alloc(), __str.__alloc()); 3572} 3573 3574// find 3575 3576template <class _Traits> 3577struct _LIBCPP_HIDDEN __traits_eq 3578{ 3579 typedef typename _Traits::char_type char_type; 3580 _LIBCPP_HIDE_FROM_ABI 3581 bool operator()(const char_type& __x, const char_type& __y) _NOEXCEPT 3582 {return _Traits::eq(__x, __y);} 3583}; 3584 3585template<class _CharT, class _Traits, class _Allocator> 3586_LIBCPP_CONSTEXPR_AFTER_CXX17 3587typename basic_string<_CharT, _Traits, _Allocator>::size_type 3588basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, 3589 size_type __pos, 3590 size_type __n) const _NOEXCEPT 3591{ 3592 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find(): received nullptr"); 3593 return __str_find<value_type, size_type, traits_type, npos> 3594 (data(), size(), __s, __pos, __n); 3595} 3596 3597template<class _CharT, class _Traits, class _Allocator> 3598inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3599typename basic_string<_CharT, _Traits, _Allocator>::size_type 3600basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str, 3601 size_type __pos) const _NOEXCEPT 3602{ 3603 return __str_find<value_type, size_type, traits_type, npos> 3604 (data(), size(), __str.data(), __pos, __str.size()); 3605} 3606 3607template<class _CharT, class _Traits, class _Allocator> 3608template <class _Tp> 3609_LIBCPP_CONSTEXPR_AFTER_CXX17 3610__enable_if_t 3611< 3612 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 3613 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3614> 3615basic_string<_CharT, _Traits, _Allocator>::find(const _Tp &__t, 3616 size_type __pos) const _NOEXCEPT 3617{ 3618 __self_view __sv = __t; 3619 return __str_find<value_type, size_type, traits_type, npos> 3620 (data(), size(), __sv.data(), __pos, __sv.size()); 3621} 3622 3623template<class _CharT, class _Traits, class _Allocator> 3624inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3625typename basic_string<_CharT, _Traits, _Allocator>::size_type 3626basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, 3627 size_type __pos) const _NOEXCEPT 3628{ 3629 _LIBCPP_ASSERT(__s != nullptr, "string::find(): received nullptr"); 3630 return __str_find<value_type, size_type, traits_type, npos> 3631 (data(), size(), __s, __pos, traits_type::length(__s)); 3632} 3633 3634template<class _CharT, class _Traits, class _Allocator> 3635_LIBCPP_CONSTEXPR_AFTER_CXX17 3636typename basic_string<_CharT, _Traits, _Allocator>::size_type 3637basic_string<_CharT, _Traits, _Allocator>::find(value_type __c, 3638 size_type __pos) const _NOEXCEPT 3639{ 3640 return __str_find<value_type, size_type, traits_type, npos> 3641 (data(), size(), __c, __pos); 3642} 3643 3644// rfind 3645 3646template<class _CharT, class _Traits, class _Allocator> 3647_LIBCPP_CONSTEXPR_AFTER_CXX17 3648typename basic_string<_CharT, _Traits, _Allocator>::size_type 3649basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, 3650 size_type __pos, 3651 size_type __n) const _NOEXCEPT 3652{ 3653 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::rfind(): received nullptr"); 3654 return __str_rfind<value_type, size_type, traits_type, npos> 3655 (data(), size(), __s, __pos, __n); 3656} 3657 3658template<class _CharT, class _Traits, class _Allocator> 3659inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3660typename basic_string<_CharT, _Traits, _Allocator>::size_type 3661basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str, 3662 size_type __pos) const _NOEXCEPT 3663{ 3664 return __str_rfind<value_type, size_type, traits_type, npos> 3665 (data(), size(), __str.data(), __pos, __str.size()); 3666} 3667 3668template<class _CharT, class _Traits, class _Allocator> 3669template <class _Tp> 3670_LIBCPP_CONSTEXPR_AFTER_CXX17 3671__enable_if_t 3672< 3673 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 3674 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3675> 3676basic_string<_CharT, _Traits, _Allocator>::rfind(const _Tp& __t, 3677 size_type __pos) const _NOEXCEPT 3678{ 3679 __self_view __sv = __t; 3680 return __str_rfind<value_type, size_type, traits_type, npos> 3681 (data(), size(), __sv.data(), __pos, __sv.size()); 3682} 3683 3684template<class _CharT, class _Traits, class _Allocator> 3685inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3686typename basic_string<_CharT, _Traits, _Allocator>::size_type 3687basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, 3688 size_type __pos) const _NOEXCEPT 3689{ 3690 _LIBCPP_ASSERT(__s != nullptr, "string::rfind(): received nullptr"); 3691 return __str_rfind<value_type, size_type, traits_type, npos> 3692 (data(), size(), __s, __pos, traits_type::length(__s)); 3693} 3694 3695template<class _CharT, class _Traits, class _Allocator> 3696_LIBCPP_CONSTEXPR_AFTER_CXX17 3697typename basic_string<_CharT, _Traits, _Allocator>::size_type 3698basic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c, 3699 size_type __pos) const _NOEXCEPT 3700{ 3701 return __str_rfind<value_type, size_type, traits_type, npos> 3702 (data(), size(), __c, __pos); 3703} 3704 3705// find_first_of 3706 3707template<class _CharT, class _Traits, class _Allocator> 3708_LIBCPP_CONSTEXPR_AFTER_CXX17 3709typename basic_string<_CharT, _Traits, _Allocator>::size_type 3710basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, 3711 size_type __pos, 3712 size_type __n) const _NOEXCEPT 3713{ 3714 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr"); 3715 return __str_find_first_of<value_type, size_type, traits_type, npos> 3716 (data(), size(), __s, __pos, __n); 3717} 3718 3719template<class _CharT, class _Traits, class _Allocator> 3720inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3721typename basic_string<_CharT, _Traits, _Allocator>::size_type 3722basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str, 3723 size_type __pos) const _NOEXCEPT 3724{ 3725 return __str_find_first_of<value_type, size_type, traits_type, npos> 3726 (data(), size(), __str.data(), __pos, __str.size()); 3727} 3728 3729template<class _CharT, class _Traits, class _Allocator> 3730template <class _Tp> 3731_LIBCPP_CONSTEXPR_AFTER_CXX17 3732__enable_if_t 3733< 3734 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 3735 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3736> 3737basic_string<_CharT, _Traits, _Allocator>::find_first_of(const _Tp& __t, 3738 size_type __pos) const _NOEXCEPT 3739{ 3740 __self_view __sv = __t; 3741 return __str_find_first_of<value_type, size_type, traits_type, npos> 3742 (data(), size(), __sv.data(), __pos, __sv.size()); 3743} 3744 3745template<class _CharT, class _Traits, class _Allocator> 3746inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3747typename basic_string<_CharT, _Traits, _Allocator>::size_type 3748basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, 3749 size_type __pos) const _NOEXCEPT 3750{ 3751 _LIBCPP_ASSERT(__s != nullptr, "string::find_first_of(): received nullptr"); 3752 return __str_find_first_of<value_type, size_type, traits_type, npos> 3753 (data(), size(), __s, __pos, traits_type::length(__s)); 3754} 3755 3756template<class _CharT, class _Traits, class _Allocator> 3757inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3758typename basic_string<_CharT, _Traits, _Allocator>::size_type 3759basic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c, 3760 size_type __pos) const _NOEXCEPT 3761{ 3762 return find(__c, __pos); 3763} 3764 3765// find_last_of 3766 3767template<class _CharT, class _Traits, class _Allocator> 3768inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3769typename basic_string<_CharT, _Traits, _Allocator>::size_type 3770basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, 3771 size_type __pos, 3772 size_type __n) const _NOEXCEPT 3773{ 3774 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr"); 3775 return __str_find_last_of<value_type, size_type, traits_type, npos> 3776 (data(), size(), __s, __pos, __n); 3777} 3778 3779template<class _CharT, class _Traits, class _Allocator> 3780inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3781typename basic_string<_CharT, _Traits, _Allocator>::size_type 3782basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str, 3783 size_type __pos) const _NOEXCEPT 3784{ 3785 return __str_find_last_of<value_type, size_type, traits_type, npos> 3786 (data(), size(), __str.data(), __pos, __str.size()); 3787} 3788 3789template<class _CharT, class _Traits, class _Allocator> 3790template <class _Tp> 3791_LIBCPP_CONSTEXPR_AFTER_CXX17 3792__enable_if_t 3793< 3794 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 3795 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3796> 3797basic_string<_CharT, _Traits, _Allocator>::find_last_of(const _Tp& __t, 3798 size_type __pos) const _NOEXCEPT 3799{ 3800 __self_view __sv = __t; 3801 return __str_find_last_of<value_type, size_type, traits_type, npos> 3802 (data(), size(), __sv.data(), __pos, __sv.size()); 3803} 3804 3805template<class _CharT, class _Traits, class _Allocator> 3806inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3807typename basic_string<_CharT, _Traits, _Allocator>::size_type 3808basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, 3809 size_type __pos) const _NOEXCEPT 3810{ 3811 _LIBCPP_ASSERT(__s != nullptr, "string::find_last_of(): received nullptr"); 3812 return __str_find_last_of<value_type, size_type, traits_type, npos> 3813 (data(), size(), __s, __pos, traits_type::length(__s)); 3814} 3815 3816template<class _CharT, class _Traits, class _Allocator> 3817inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3818typename basic_string<_CharT, _Traits, _Allocator>::size_type 3819basic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c, 3820 size_type __pos) const _NOEXCEPT 3821{ 3822 return rfind(__c, __pos); 3823} 3824 3825// find_first_not_of 3826 3827template<class _CharT, class _Traits, class _Allocator> 3828_LIBCPP_CONSTEXPR_AFTER_CXX17 3829typename basic_string<_CharT, _Traits, _Allocator>::size_type 3830basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s, 3831 size_type __pos, 3832 size_type __n) const _NOEXCEPT 3833{ 3834 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr"); 3835 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 3836 (data(), size(), __s, __pos, __n); 3837} 3838 3839template<class _CharT, class _Traits, class _Allocator> 3840inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3841typename basic_string<_CharT, _Traits, _Allocator>::size_type 3842basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string& __str, 3843 size_type __pos) const _NOEXCEPT 3844{ 3845 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 3846 (data(), size(), __str.data(), __pos, __str.size()); 3847} 3848 3849template<class _CharT, class _Traits, class _Allocator> 3850template <class _Tp> 3851_LIBCPP_CONSTEXPR_AFTER_CXX17 3852__enable_if_t 3853< 3854 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 3855 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3856> 3857basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const _Tp& __t, 3858 size_type __pos) const _NOEXCEPT 3859{ 3860 __self_view __sv = __t; 3861 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 3862 (data(), size(), __sv.data(), __pos, __sv.size()); 3863} 3864 3865template<class _CharT, class _Traits, class _Allocator> 3866inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3867typename basic_string<_CharT, _Traits, _Allocator>::size_type 3868basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s, 3869 size_type __pos) const _NOEXCEPT 3870{ 3871 _LIBCPP_ASSERT(__s != nullptr, "string::find_first_not_of(): received nullptr"); 3872 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 3873 (data(), size(), __s, __pos, traits_type::length(__s)); 3874} 3875 3876template<class _CharT, class _Traits, class _Allocator> 3877inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3878typename basic_string<_CharT, _Traits, _Allocator>::size_type 3879basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c, 3880 size_type __pos) const _NOEXCEPT 3881{ 3882 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 3883 (data(), size(), __c, __pos); 3884} 3885 3886// find_last_not_of 3887 3888template<class _CharT, class _Traits, class _Allocator> 3889_LIBCPP_CONSTEXPR_AFTER_CXX17 3890typename basic_string<_CharT, _Traits, _Allocator>::size_type 3891basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s, 3892 size_type __pos, 3893 size_type __n) const _NOEXCEPT 3894{ 3895 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr"); 3896 return __str_find_last_not_of<value_type, size_type, traits_type, npos> 3897 (data(), size(), __s, __pos, __n); 3898} 3899 3900template<class _CharT, class _Traits, class _Allocator> 3901inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3902typename basic_string<_CharT, _Traits, _Allocator>::size_type 3903basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string& __str, 3904 size_type __pos) const _NOEXCEPT 3905{ 3906 return __str_find_last_not_of<value_type, size_type, traits_type, npos> 3907 (data(), size(), __str.data(), __pos, __str.size()); 3908} 3909 3910template<class _CharT, class _Traits, class _Allocator> 3911template <class _Tp> 3912_LIBCPP_CONSTEXPR_AFTER_CXX17 3913__enable_if_t 3914< 3915 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 3916 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3917> 3918basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const _Tp& __t, 3919 size_type __pos) const _NOEXCEPT 3920{ 3921 __self_view __sv = __t; 3922 return __str_find_last_not_of<value_type, size_type, traits_type, npos> 3923 (data(), size(), __sv.data(), __pos, __sv.size()); 3924} 3925 3926template<class _CharT, class _Traits, class _Allocator> 3927inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3928typename basic_string<_CharT, _Traits, _Allocator>::size_type 3929basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s, 3930 size_type __pos) const _NOEXCEPT 3931{ 3932 _LIBCPP_ASSERT(__s != nullptr, "string::find_last_not_of(): received nullptr"); 3933 return __str_find_last_not_of<value_type, size_type, traits_type, npos> 3934 (data(), size(), __s, __pos, traits_type::length(__s)); 3935} 3936 3937template<class _CharT, class _Traits, class _Allocator> 3938inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3939typename basic_string<_CharT, _Traits, _Allocator>::size_type 3940basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c, 3941 size_type __pos) const _NOEXCEPT 3942{ 3943 return __str_find_last_not_of<value_type, size_type, traits_type, npos> 3944 (data(), size(), __c, __pos); 3945} 3946 3947// compare 3948 3949template <class _CharT, class _Traits, class _Allocator> 3950template <class _Tp> 3951_LIBCPP_CONSTEXPR_AFTER_CXX17 3952__enable_if_t 3953< 3954 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 3955 int 3956> 3957basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const _NOEXCEPT 3958{ 3959 __self_view __sv = __t; 3960 size_t __lhs_sz = size(); 3961 size_t __rhs_sz = __sv.size(); 3962 int __result = traits_type::compare(data(), __sv.data(), 3963 std::min(__lhs_sz, __rhs_sz)); 3964 if (__result != 0) 3965 return __result; 3966 if (__lhs_sz < __rhs_sz) 3967 return -1; 3968 if (__lhs_sz > __rhs_sz) 3969 return 1; 3970 return 0; 3971} 3972 3973template <class _CharT, class _Traits, class _Allocator> 3974inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3975int 3976basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT 3977{ 3978 return compare(__self_view(__str)); 3979} 3980 3981template <class _CharT, class _Traits, class _Allocator> 3982inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3983int 3984basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, 3985 size_type __n1, 3986 const value_type* __s, 3987 size_type __n2) const 3988{ 3989 _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr"); 3990 size_type __sz = size(); 3991 if (__pos1 > __sz || __n2 == npos) 3992 __throw_out_of_range(); 3993 size_type __rlen = std::min(__n1, __sz - __pos1); 3994 int __r = traits_type::compare(data() + __pos1, __s, std::min(__rlen, __n2)); 3995 if (__r == 0) 3996 { 3997 if (__rlen < __n2) 3998 __r = -1; 3999 else if (__rlen > __n2) 4000 __r = 1; 4001 } 4002 return __r; 4003} 4004 4005template <class _CharT, class _Traits, class _Allocator> 4006template <class _Tp> 4007_LIBCPP_CONSTEXPR_AFTER_CXX17 4008__enable_if_t 4009< 4010 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 4011 int 4012> 4013basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, 4014 size_type __n1, 4015 const _Tp& __t) const 4016{ 4017 __self_view __sv = __t; 4018 return compare(__pos1, __n1, __sv.data(), __sv.size()); 4019} 4020 4021template <class _CharT, class _Traits, class _Allocator> 4022inline _LIBCPP_CONSTEXPR_AFTER_CXX17 4023int 4024basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, 4025 size_type __n1, 4026 const basic_string& __str) const 4027{ 4028 return compare(__pos1, __n1, __str.data(), __str.size()); 4029} 4030 4031template <class _CharT, class _Traits, class _Allocator> 4032template <class _Tp> 4033_LIBCPP_CONSTEXPR_AFTER_CXX17 4034__enable_if_t 4035< 4036 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value 4037 && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 4038 int 4039> 4040basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, 4041 size_type __n1, 4042 const _Tp& __t, 4043 size_type __pos2, 4044 size_type __n2) const 4045{ 4046 __self_view __sv = __t; 4047 return __self_view(*this).substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2)); 4048} 4049 4050template <class _CharT, class _Traits, class _Allocator> 4051_LIBCPP_CONSTEXPR_AFTER_CXX17 4052int 4053basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, 4054 size_type __n1, 4055 const basic_string& __str, 4056 size_type __pos2, 4057 size_type __n2) const 4058{ 4059 return compare(__pos1, __n1, __self_view(__str), __pos2, __n2); 4060} 4061 4062template <class _CharT, class _Traits, class _Allocator> 4063_LIBCPP_CONSTEXPR_AFTER_CXX17 4064int 4065basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT 4066{ 4067 _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr"); 4068 return compare(0, npos, __s, traits_type::length(__s)); 4069} 4070 4071template <class _CharT, class _Traits, class _Allocator> 4072_LIBCPP_CONSTEXPR_AFTER_CXX17 4073int 4074basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, 4075 size_type __n1, 4076 const value_type* __s) const 4077{ 4078 _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr"); 4079 return compare(__pos1, __n1, __s, traits_type::length(__s)); 4080} 4081 4082// __invariants 4083 4084template<class _CharT, class _Traits, class _Allocator> 4085inline _LIBCPP_CONSTEXPR_AFTER_CXX17 4086bool 4087basic_string<_CharT, _Traits, _Allocator>::__invariants() const 4088{ 4089 if (size() > capacity()) 4090 return false; 4091 if (capacity() < __min_cap - 1) 4092 return false; 4093 if (data() == nullptr) 4094 return false; 4095 if (data()[size()] != value_type()) 4096 return false; 4097 return true; 4098} 4099 4100// __clear_and_shrink 4101 4102template<class _CharT, class _Traits, class _Allocator> 4103inline _LIBCPP_CONSTEXPR_AFTER_CXX17 4104void 4105basic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT 4106{ 4107 clear(); 4108 if(__is_long()) 4109 { 4110 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), capacity() + 1); 4111 __set_long_cap(0); 4112 __set_short_size(0); 4113 traits_type::assign(*__get_short_pointer(), value_type()); 4114 } 4115} 4116 4117// operator== 4118 4119template<class _CharT, class _Traits, class _Allocator> 4120inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4121bool 4122operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4123 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4124{ 4125 size_t __lhs_sz = __lhs.size(); 4126 return __lhs_sz == __rhs.size() && _Traits::compare(__lhs.data(), 4127 __rhs.data(), 4128 __lhs_sz) == 0; 4129} 4130 4131template<class _Allocator> 4132inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4133bool 4134operator==(const basic_string<char, char_traits<char>, _Allocator>& __lhs, 4135 const basic_string<char, char_traits<char>, _Allocator>& __rhs) _NOEXCEPT 4136{ 4137 size_t __lhs_sz = __lhs.size(); 4138 if (__lhs_sz != __rhs.size()) 4139 return false; 4140 const char* __lp = __lhs.data(); 4141 const char* __rp = __rhs.data(); 4142 if (__lhs.__is_long()) 4143 return char_traits<char>::compare(__lp, __rp, __lhs_sz) == 0; 4144 for (; __lhs_sz != 0; --__lhs_sz, ++__lp, ++__rp) 4145 if (*__lp != *__rp) 4146 return false; 4147 return true; 4148} 4149 4150template<class _CharT, class _Traits, class _Allocator> 4151inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4152bool 4153operator==(const _CharT* __lhs, 4154 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4155{ 4156 typedef basic_string<_CharT, _Traits, _Allocator> _String; 4157 _LIBCPP_ASSERT(__lhs != nullptr, "operator==(char*, basic_string): received nullptr"); 4158 size_t __lhs_len = _Traits::length(__lhs); 4159 if (__lhs_len != __rhs.size()) return false; 4160 return __rhs.compare(0, _String::npos, __lhs, __lhs_len) == 0; 4161} 4162 4163template<class _CharT, class _Traits, class _Allocator> 4164inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4165bool 4166operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 4167 const _CharT* __rhs) _NOEXCEPT 4168{ 4169 typedef basic_string<_CharT, _Traits, _Allocator> _String; 4170 _LIBCPP_ASSERT(__rhs != nullptr, "operator==(basic_string, char*): received nullptr"); 4171 size_t __rhs_len = _Traits::length(__rhs); 4172 if (__rhs_len != __lhs.size()) return false; 4173 return __lhs.compare(0, _String::npos, __rhs, __rhs_len) == 0; 4174} 4175 4176template<class _CharT, class _Traits, class _Allocator> 4177inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4178bool 4179operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 4180 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4181{ 4182 return !(__lhs == __rhs); 4183} 4184 4185template<class _CharT, class _Traits, class _Allocator> 4186inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4187bool 4188operator!=(const _CharT* __lhs, 4189 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4190{ 4191 return !(__lhs == __rhs); 4192} 4193 4194template<class _CharT, class _Traits, class _Allocator> 4195inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4196bool 4197operator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4198 const _CharT* __rhs) _NOEXCEPT 4199{ 4200 return !(__lhs == __rhs); 4201} 4202 4203// operator< 4204 4205template<class _CharT, class _Traits, class _Allocator> 4206inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4207bool 4208operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4209 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4210{ 4211 return __lhs.compare(__rhs) < 0; 4212} 4213 4214template<class _CharT, class _Traits, class _Allocator> 4215inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4216bool 4217operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4218 const _CharT* __rhs) _NOEXCEPT 4219{ 4220 return __lhs.compare(__rhs) < 0; 4221} 4222 4223template<class _CharT, class _Traits, class _Allocator> 4224inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4225bool 4226operator< (const _CharT* __lhs, 4227 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4228{ 4229 return __rhs.compare(__lhs) > 0; 4230} 4231 4232// operator> 4233 4234template<class _CharT, class _Traits, class _Allocator> 4235inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4236bool 4237operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4238 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4239{ 4240 return __rhs < __lhs; 4241} 4242 4243template<class _CharT, class _Traits, class _Allocator> 4244inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4245bool 4246operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4247 const _CharT* __rhs) _NOEXCEPT 4248{ 4249 return __rhs < __lhs; 4250} 4251 4252template<class _CharT, class _Traits, class _Allocator> 4253inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4254bool 4255operator> (const _CharT* __lhs, 4256 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4257{ 4258 return __rhs < __lhs; 4259} 4260 4261// operator<= 4262 4263template<class _CharT, class _Traits, class _Allocator> 4264inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4265bool 4266operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4267 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4268{ 4269 return !(__rhs < __lhs); 4270} 4271 4272template<class _CharT, class _Traits, class _Allocator> 4273inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4274bool 4275operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4276 const _CharT* __rhs) _NOEXCEPT 4277{ 4278 return !(__rhs < __lhs); 4279} 4280 4281template<class _CharT, class _Traits, class _Allocator> 4282inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4283bool 4284operator<=(const _CharT* __lhs, 4285 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4286{ 4287 return !(__rhs < __lhs); 4288} 4289 4290// operator>= 4291 4292template<class _CharT, class _Traits, class _Allocator> 4293inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4294bool 4295operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4296 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4297{ 4298 return !(__lhs < __rhs); 4299} 4300 4301template<class _CharT, class _Traits, class _Allocator> 4302inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4303bool 4304operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4305 const _CharT* __rhs) _NOEXCEPT 4306{ 4307 return !(__lhs < __rhs); 4308} 4309 4310template<class _CharT, class _Traits, class _Allocator> 4311inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4312bool 4313operator>=(const _CharT* __lhs, 4314 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4315{ 4316 return !(__lhs < __rhs); 4317} 4318 4319// operator + 4320 4321template<class _CharT, class _Traits, class _Allocator> 4322_LIBCPP_CONSTEXPR_AFTER_CXX17 4323basic_string<_CharT, _Traits, _Allocator> 4324operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4325 const basic_string<_CharT, _Traits, _Allocator>& __rhs) 4326{ 4327 using _String = basic_string<_CharT, _Traits, _Allocator>; 4328 auto __lhs_sz = __lhs.size(); 4329 auto __rhs_sz = __rhs.size(); 4330 _String __r(__uninitialized_size_tag(), 4331 __lhs_sz + __rhs_sz, 4332 _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator())); 4333 auto __ptr = std::__to_address(__r.__get_pointer()); 4334 _Traits::copy(__ptr, __lhs.data(), __lhs_sz); 4335 _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz); 4336 _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT()); 4337 return __r; 4338} 4339 4340template<class _CharT, class _Traits, class _Allocator> 4341_LIBCPP_CONSTEXPR_AFTER_CXX17 4342basic_string<_CharT, _Traits, _Allocator> 4343operator+(const _CharT* __lhs , const basic_string<_CharT,_Traits,_Allocator>& __rhs) 4344{ 4345 using _String = basic_string<_CharT, _Traits, _Allocator>; 4346 auto __lhs_sz = _Traits::length(__lhs); 4347 auto __rhs_sz = __rhs.size(); 4348 _String __r(__uninitialized_size_tag(), 4349 __lhs_sz + __rhs_sz, 4350 _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator())); 4351 auto __ptr = std::__to_address(__r.__get_pointer()); 4352 _Traits::copy(__ptr, __lhs, __lhs_sz); 4353 _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz); 4354 _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT()); 4355 return __r; 4356} 4357 4358template<class _CharT, class _Traits, class _Allocator> 4359_LIBCPP_CONSTEXPR_AFTER_CXX17 4360basic_string<_CharT, _Traits, _Allocator> 4361operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Allocator>& __rhs) 4362{ 4363 using _String = basic_string<_CharT, _Traits, _Allocator>; 4364 typename _String::size_type __rhs_sz = __rhs.size(); 4365 _String __r(__uninitialized_size_tag(), 4366 __rhs_sz + 1, 4367 _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator())); 4368 auto __ptr = std::__to_address(__r.__get_pointer()); 4369 _Traits::assign(__ptr, 1, __lhs); 4370 _Traits::copy(__ptr + 1, __rhs.data(), __rhs_sz); 4371 _Traits::assign(__ptr + 1 + __rhs_sz, 1, _CharT()); 4372 return __r; 4373} 4374 4375template<class _CharT, class _Traits, class _Allocator> 4376inline _LIBCPP_CONSTEXPR_AFTER_CXX17 4377basic_string<_CharT, _Traits, _Allocator> 4378operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) 4379{ 4380 using _String = basic_string<_CharT, _Traits, _Allocator>; 4381 typename _String::size_type __lhs_sz = __lhs.size(); 4382 typename _String::size_type __rhs_sz = _Traits::length(__rhs); 4383 _String __r(__uninitialized_size_tag(), 4384 __lhs_sz + __rhs_sz, 4385 _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator())); 4386 auto __ptr = std::__to_address(__r.__get_pointer()); 4387 _Traits::copy(__ptr, __lhs.data(), __lhs_sz); 4388 _Traits::copy(__ptr + __lhs_sz, __rhs, __rhs_sz); 4389 _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT()); 4390 return __r; 4391} 4392 4393template<class _CharT, class _Traits, class _Allocator> 4394_LIBCPP_CONSTEXPR_AFTER_CXX17 4395basic_string<_CharT, _Traits, _Allocator> 4396operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs) 4397{ 4398 using _String = basic_string<_CharT, _Traits, _Allocator>; 4399 typename _String::size_type __lhs_sz = __lhs.size(); 4400 _String __r(__uninitialized_size_tag(), 4401 __lhs_sz + 1, 4402 _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator())); 4403 auto __ptr = std::__to_address(__r.__get_pointer()); 4404 _Traits::copy(__ptr, __lhs.data(), __lhs_sz); 4405 _Traits::assign(__ptr + __lhs_sz, 1, __rhs); 4406 _Traits::assign(__ptr + 1 + __lhs_sz, 1, _CharT()); 4407 return __r; 4408} 4409 4410#ifndef _LIBCPP_CXX03_LANG 4411 4412template<class _CharT, class _Traits, class _Allocator> 4413inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 4414basic_string<_CharT, _Traits, _Allocator> 4415operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) 4416{ 4417 return std::move(__lhs.append(__rhs)); 4418} 4419 4420template<class _CharT, class _Traits, class _Allocator> 4421inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 4422basic_string<_CharT, _Traits, _Allocator> 4423operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs) 4424{ 4425 return std::move(__rhs.insert(0, __lhs)); 4426} 4427 4428template<class _CharT, class _Traits, class _Allocator> 4429inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 4430basic_string<_CharT, _Traits, _Allocator> 4431operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs) 4432{ 4433 return std::move(__lhs.append(__rhs)); 4434} 4435 4436template<class _CharT, class _Traits, class _Allocator> 4437inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 4438basic_string<_CharT, _Traits, _Allocator> 4439operator+(const _CharT* __lhs , basic_string<_CharT,_Traits,_Allocator>&& __rhs) 4440{ 4441 return std::move(__rhs.insert(0, __lhs)); 4442} 4443 4444template<class _CharT, class _Traits, class _Allocator> 4445inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 4446basic_string<_CharT, _Traits, _Allocator> 4447operator+(_CharT __lhs, basic_string<_CharT,_Traits,_Allocator>&& __rhs) 4448{ 4449 __rhs.insert(__rhs.begin(), __lhs); 4450 return std::move(__rhs); 4451} 4452 4453template<class _CharT, class _Traits, class _Allocator> 4454inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 4455basic_string<_CharT, _Traits, _Allocator> 4456operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const _CharT* __rhs) 4457{ 4458 return std::move(__lhs.append(__rhs)); 4459} 4460 4461template<class _CharT, class _Traits, class _Allocator> 4462inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 4463basic_string<_CharT, _Traits, _Allocator> 4464operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT __rhs) 4465{ 4466 __lhs.push_back(__rhs); 4467 return std::move(__lhs); 4468} 4469 4470#endif // _LIBCPP_CXX03_LANG 4471 4472// swap 4473 4474template<class _CharT, class _Traits, class _Allocator> 4475inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 4476void 4477swap(basic_string<_CharT, _Traits, _Allocator>& __lhs, 4478 basic_string<_CharT, _Traits, _Allocator>& __rhs) 4479 _NOEXCEPT_(_NOEXCEPT_(__lhs.swap(__rhs))) 4480{ 4481 __lhs.swap(__rhs); 4482} 4483 4484_LIBCPP_FUNC_VIS int stoi (const string& __str, size_t* __idx = nullptr, int __base = 10); 4485_LIBCPP_FUNC_VIS long stol (const string& __str, size_t* __idx = nullptr, int __base = 10); 4486_LIBCPP_FUNC_VIS unsigned long stoul (const string& __str, size_t* __idx = nullptr, int __base = 10); 4487_LIBCPP_FUNC_VIS long long stoll (const string& __str, size_t* __idx = nullptr, int __base = 10); 4488_LIBCPP_FUNC_VIS unsigned long long stoull(const string& __str, size_t* __idx = nullptr, int __base = 10); 4489 4490_LIBCPP_FUNC_VIS float stof (const string& __str, size_t* __idx = nullptr); 4491_LIBCPP_FUNC_VIS double stod (const string& __str, size_t* __idx = nullptr); 4492_LIBCPP_FUNC_VIS long double stold(const string& __str, size_t* __idx = nullptr); 4493 4494_LIBCPP_FUNC_VIS string to_string(int __val); 4495_LIBCPP_FUNC_VIS string to_string(unsigned __val); 4496_LIBCPP_FUNC_VIS string to_string(long __val); 4497_LIBCPP_FUNC_VIS string to_string(unsigned long __val); 4498_LIBCPP_FUNC_VIS string to_string(long long __val); 4499_LIBCPP_FUNC_VIS string to_string(unsigned long long __val); 4500_LIBCPP_FUNC_VIS string to_string(float __val); 4501_LIBCPP_FUNC_VIS string to_string(double __val); 4502_LIBCPP_FUNC_VIS string to_string(long double __val); 4503 4504#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 4505_LIBCPP_FUNC_VIS int stoi (const wstring& __str, size_t* __idx = nullptr, int __base = 10); 4506_LIBCPP_FUNC_VIS long stol (const wstring& __str, size_t* __idx = nullptr, int __base = 10); 4507_LIBCPP_FUNC_VIS unsigned long stoul (const wstring& __str, size_t* __idx = nullptr, int __base = 10); 4508_LIBCPP_FUNC_VIS long long stoll (const wstring& __str, size_t* __idx = nullptr, int __base = 10); 4509_LIBCPP_FUNC_VIS unsigned long long stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10); 4510 4511_LIBCPP_FUNC_VIS float stof (const wstring& __str, size_t* __idx = nullptr); 4512_LIBCPP_FUNC_VIS double stod (const wstring& __str, size_t* __idx = nullptr); 4513_LIBCPP_FUNC_VIS long double stold(const wstring& __str, size_t* __idx = nullptr); 4514 4515_LIBCPP_FUNC_VIS wstring to_wstring(int __val); 4516_LIBCPP_FUNC_VIS wstring to_wstring(unsigned __val); 4517_LIBCPP_FUNC_VIS wstring to_wstring(long __val); 4518_LIBCPP_FUNC_VIS wstring to_wstring(unsigned long __val); 4519_LIBCPP_FUNC_VIS wstring to_wstring(long long __val); 4520_LIBCPP_FUNC_VIS wstring to_wstring(unsigned long long __val); 4521_LIBCPP_FUNC_VIS wstring to_wstring(float __val); 4522_LIBCPP_FUNC_VIS wstring to_wstring(double __val); 4523_LIBCPP_FUNC_VIS wstring to_wstring(long double __val); 4524#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS 4525 4526template<class _CharT, class _Traits, class _Allocator> 4527_LIBCPP_TEMPLATE_DATA_VIS 4528const typename basic_string<_CharT, _Traits, _Allocator>::size_type 4529 basic_string<_CharT, _Traits, _Allocator>::npos; 4530 4531template <class _CharT, class _Allocator> 4532struct _LIBCPP_TEMPLATE_VIS 4533 hash<basic_string<_CharT, char_traits<_CharT>, _Allocator> > 4534 : public unary_function< 4535 basic_string<_CharT, char_traits<_CharT>, _Allocator>, size_t> 4536{ 4537 size_t 4538 operator()(const basic_string<_CharT, char_traits<_CharT>, _Allocator>& __val) const _NOEXCEPT 4539 { return __do_string_hash(__val.data(), __val.data() + __val.size()); } 4540}; 4541 4542 4543template<class _CharT, class _Traits, class _Allocator> 4544basic_ostream<_CharT, _Traits>& 4545operator<<(basic_ostream<_CharT, _Traits>& __os, 4546 const basic_string<_CharT, _Traits, _Allocator>& __str); 4547 4548template<class _CharT, class _Traits, class _Allocator> 4549basic_istream<_CharT, _Traits>& 4550operator>>(basic_istream<_CharT, _Traits>& __is, 4551 basic_string<_CharT, _Traits, _Allocator>& __str); 4552 4553template<class _CharT, class _Traits, class _Allocator> 4554basic_istream<_CharT, _Traits>& 4555getline(basic_istream<_CharT, _Traits>& __is, 4556 basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm); 4557 4558template<class _CharT, class _Traits, class _Allocator> 4559inline _LIBCPP_HIDE_FROM_ABI 4560basic_istream<_CharT, _Traits>& 4561getline(basic_istream<_CharT, _Traits>& __is, 4562 basic_string<_CharT, _Traits, _Allocator>& __str); 4563 4564template<class _CharT, class _Traits, class _Allocator> 4565inline _LIBCPP_HIDE_FROM_ABI 4566basic_istream<_CharT, _Traits>& 4567getline(basic_istream<_CharT, _Traits>&& __is, 4568 basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm); 4569 4570template<class _CharT, class _Traits, class _Allocator> 4571inline _LIBCPP_HIDE_FROM_ABI 4572basic_istream<_CharT, _Traits>& 4573getline(basic_istream<_CharT, _Traits>&& __is, 4574 basic_string<_CharT, _Traits, _Allocator>& __str); 4575 4576#if _LIBCPP_STD_VER > 17 4577template <class _CharT, class _Traits, class _Allocator, class _Up> 4578inline _LIBCPP_HIDE_FROM_ABI 4579 typename basic_string<_CharT, _Traits, _Allocator>::size_type 4580 erase(basic_string<_CharT, _Traits, _Allocator>& __str, const _Up& __v) { 4581 auto __old_size = __str.size(); 4582 __str.erase(std::remove(__str.begin(), __str.end(), __v), __str.end()); 4583 return __old_size - __str.size(); 4584} 4585 4586template <class _CharT, class _Traits, class _Allocator, class _Predicate> 4587inline _LIBCPP_HIDE_FROM_ABI 4588 typename basic_string<_CharT, _Traits, _Allocator>::size_type 4589 erase_if(basic_string<_CharT, _Traits, _Allocator>& __str, 4590 _Predicate __pred) { 4591 auto __old_size = __str.size(); 4592 __str.erase(std::remove_if(__str.begin(), __str.end(), __pred), 4593 __str.end()); 4594 return __old_size - __str.size(); 4595} 4596#endif 4597 4598#if _LIBCPP_DEBUG_LEVEL == 2 4599 4600template<class _CharT, class _Traits, class _Allocator> 4601bool 4602basic_string<_CharT, _Traits, _Allocator>::__dereferenceable(const const_iterator* __i) const 4603{ 4604 return data() <= std::__to_address(__i->base()) && 4605 std::__to_address(__i->base()) < data() + size(); 4606} 4607 4608template<class _CharT, class _Traits, class _Allocator> 4609bool 4610basic_string<_CharT, _Traits, _Allocator>::__decrementable(const const_iterator* __i) const 4611{ 4612 return data() < std::__to_address(__i->base()) && 4613 std::__to_address(__i->base()) <= data() + size(); 4614} 4615 4616template<class _CharT, class _Traits, class _Allocator> 4617bool 4618basic_string<_CharT, _Traits, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const 4619{ 4620 const value_type* __p = std::__to_address(__i->base()) + __n; 4621 return data() <= __p && __p <= data() + size(); 4622} 4623 4624template<class _CharT, class _Traits, class _Allocator> 4625bool 4626basic_string<_CharT, _Traits, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const 4627{ 4628 const value_type* __p = std::__to_address(__i->base()) + __n; 4629 return data() <= __p && __p < data() + size(); 4630} 4631 4632#endif // _LIBCPP_DEBUG_LEVEL == 2 4633 4634#if _LIBCPP_STD_VER > 11 4635// Literal suffixes for basic_string [basic.string.literals] 4636inline namespace literals 4637{ 4638 inline namespace string_literals 4639 { 4640 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 4641 basic_string<char> operator "" s( const char *__str, size_t __len ) 4642 { 4643 return basic_string<char> (__str, __len); 4644 } 4645 4646#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 4647 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 4648 basic_string<wchar_t> operator "" s( const wchar_t *__str, size_t __len ) 4649 { 4650 return basic_string<wchar_t> (__str, __len); 4651 } 4652#endif 4653 4654#ifndef _LIBCPP_HAS_NO_CHAR8_T 4655 inline _LIBCPP_HIDE_FROM_ABI constexpr 4656 basic_string<char8_t> operator "" s(const char8_t *__str, size_t __len) _NOEXCEPT 4657 { 4658 return basic_string<char8_t> (__str, __len); 4659 } 4660#endif 4661 4662 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 4663 basic_string<char16_t> operator "" s( const char16_t *__str, size_t __len ) 4664 { 4665 return basic_string<char16_t> (__str, __len); 4666 } 4667 4668 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 4669 basic_string<char32_t> operator "" s( const char32_t *__str, size_t __len ) 4670 { 4671 return basic_string<char32_t> (__str, __len); 4672 } 4673 } // namespace string_literals 4674} // namespace literals 4675 4676#if _LIBCPP_STD_VER > 17 4677template <> 4678inline constexpr bool __format::__enable_insertable<std::basic_string<char>> = true; 4679#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 4680template <> 4681inline constexpr bool __format::__enable_insertable<std::basic_string<wchar_t>> = true; 4682#endif 4683#endif 4684 4685#endif 4686 4687_LIBCPP_END_NAMESPACE_STD 4688 4689_LIBCPP_POP_MACROS 4690 4691#endif // _LIBCPP_STRING 4692