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