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