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