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