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