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