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