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