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 <__ios/fpos.h> 528#include <__iterator/wrap_iter.h> 529#include <__memory/allocate_at_least.h> 530#include <__utility/auto_cast.h> 531#include <__utility/move.h> 532#include <__utility/swap.h> 533#include <__utility/unreachable.h> 534#include <climits> 535#include <compare> 536#include <cstdio> // EOF 537#include <cstdlib> 538#include <cstring> 539#include <initializer_list> 540#include <iosfwd> 541#include <iterator> 542#include <limits> 543#include <memory> 544#include <stdexcept> 545#include <string_view> 546#include <type_traits> 547#include <version> 548 549// TODO: remove these headers 550#include <__functional/binary_function.h> 551#include <__functional/invoke.h> 552#include <__functional/operations.h> 553#include <__functional/reference_wrapper.h> 554#include <__functional/unary_function.h> 555#include <__functional/weak_result_type.h> 556#include <new> 557#include <typeinfo> 558 559#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 560# include <cwchar> 561#endif 562 563#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS 564# include <cstdint> 565#endif 566 567#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 568# pragma GCC system_header 569#endif 570 571_LIBCPP_PUSH_MACROS 572#include <__undef_macros> 573 574 575_LIBCPP_BEGIN_NAMESPACE_STD 576 577// basic_string 578 579template<class _CharT, class _Traits, class _Allocator> 580basic_string<_CharT, _Traits, _Allocator> 581_LIBCPP_CONSTEXPR_AFTER_CXX17 582operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, 583 const basic_string<_CharT, _Traits, _Allocator>& __y); 584 585template<class _CharT, class _Traits, class _Allocator> 586_LIBCPP_CONSTEXPR_AFTER_CXX17 587basic_string<_CharT, _Traits, _Allocator> 588operator+(const _CharT* __x, const basic_string<_CharT,_Traits,_Allocator>& __y); 589 590template<class _CharT, class _Traits, class _Allocator> 591_LIBCPP_CONSTEXPR_AFTER_CXX17 592basic_string<_CharT, _Traits, _Allocator> 593operator+(_CharT __x, const basic_string<_CharT,_Traits,_Allocator>& __y); 594 595template<class _CharT, class _Traits, class _Allocator> 596inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 597basic_string<_CharT, _Traits, _Allocator> 598operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const _CharT* __y); 599 600template<class _CharT, class _Traits, class _Allocator> 601_LIBCPP_CONSTEXPR_AFTER_CXX17 602basic_string<_CharT, _Traits, _Allocator> 603operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y); 604 605_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&)) 606 607template <class _Iter> 608struct __string_is_trivial_iterator : public false_type {}; 609 610template <class _Tp> 611struct __string_is_trivial_iterator<_Tp*> 612 : public is_arithmetic<_Tp> {}; 613 614template <class _Iter> 615struct __string_is_trivial_iterator<__wrap_iter<_Iter> > 616 : public __string_is_trivial_iterator<_Iter> {}; 617 618template <class _CharT, class _Traits, class _Tp> 619struct __can_be_converted_to_string_view : public _BoolConstant< 620 is_convertible<const _Tp&, basic_string_view<_CharT, _Traits> >::value && 621 !is_convertible<const _Tp&, const _CharT*>::value 622 > {}; 623 624#ifndef _LIBCPP_HAS_NO_CHAR8_T 625typedef basic_string<char8_t> u8string; 626#endif 627 628#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS 629typedef basic_string<char16_t> u16string; 630typedef basic_string<char32_t> u32string; 631#endif 632 633struct __uninitialized_size_tag {}; 634 635template<class _CharT, class _Traits, class _Allocator> 636class 637 _LIBCPP_TEMPLATE_VIS 638#ifndef _LIBCPP_HAS_NO_CHAR8_T 639 _LIBCPP_PREFERRED_NAME(u8string) 640#endif 641#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS 642 _LIBCPP_PREFERRED_NAME(u16string) 643 _LIBCPP_PREFERRED_NAME(u32string) 644#endif 645 basic_string 646{ 647public: 648 typedef basic_string __self; 649 typedef basic_string_view<_CharT, _Traits> __self_view; 650 typedef _Traits traits_type; 651 typedef _CharT value_type; 652 typedef _Allocator allocator_type; 653 typedef allocator_traits<allocator_type> __alloc_traits; 654 typedef typename __alloc_traits::size_type size_type; 655 typedef typename __alloc_traits::difference_type difference_type; 656 typedef value_type& reference; 657 typedef const value_type& const_reference; 658 typedef typename __alloc_traits::pointer pointer; 659 typedef typename __alloc_traits::const_pointer const_pointer; 660 661 static_assert((!is_array<value_type>::value), "Character type of basic_string must not be an array"); 662 static_assert(( is_standard_layout<value_type>::value), "Character type of basic_string must be standard-layout"); 663 static_assert(( is_trivial<value_type>::value), "Character type of basic_string must be trivial"); 664 static_assert(( is_same<_CharT, typename traits_type::char_type>::value), 665 "traits_type::char_type must be the same type as CharT"); 666 static_assert(( is_same<typename allocator_type::value_type, value_type>::value), 667 "Allocator::value_type must be same type as value_type"); 668 669 typedef __wrap_iter<pointer> iterator; 670 typedef __wrap_iter<const_pointer> const_iterator; 671 typedef std::reverse_iterator<iterator> reverse_iterator; 672 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 673 674private: 675 676#ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT 677 678 struct __long 679 { 680 pointer __data_; 681 size_type __size_; 682 size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1; 683 size_type __is_long_ : 1; 684 }; 685 686 enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ? 687 (sizeof(__long) - 1)/sizeof(value_type) : 2}; 688 689 struct __short 690 { 691 value_type __data_[__min_cap]; 692 unsigned char __padding[sizeof(value_type) - 1]; 693 unsigned char __size_ : 7; 694 unsigned char __is_long_ : 1; 695 }; 696 697// The __endian_factor is required because the field we use to store the size 698// (either size_type or unsigned char depending on long/short) has one fewer 699// bit than it would if it were not a bitfield. 700// 701// If the LSB is used to store the short-flag in the short string representation, 702// we have to multiply the size by two when it is stored and divide it by two when 703// it is loaded to make sure that we always store an even number. In the long string 704// representation, we can ignore this because we can assume that we always allocate 705// an even amount of value_types. 706// 707// If the MSB is used for the short-flag, the max_size() is numeric_limits<size_type>::max() / 2. 708// This does not impact the short string representation, since we never need the MSB 709// for representing the size of a short string anyway. 710 711#ifdef _LIBCPP_BIG_ENDIAN 712 static const size_type __endian_factor = 2; 713#else 714 static const size_type __endian_factor = 1; 715#endif 716 717#else // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT 718 719#ifdef _LIBCPP_BIG_ENDIAN 720 static const size_type __endian_factor = 1; 721#else 722 static const size_type __endian_factor = 2; 723#endif 724 725 struct __long 726 { 727 size_type __is_long_ : 1; 728 size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1; 729 size_type __size_; 730 pointer __data_; 731 }; 732 733 enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ? 734 (sizeof(__long) - 1)/sizeof(value_type) : 2}; 735 736 struct __short 737 { 738 union 739 { 740 struct { 741 unsigned char __is_long_ : 1; 742 unsigned char __size_ : 7; 743 }; 744 value_type __lx; 745 }; 746 value_type __data_[__min_cap]; 747 }; 748 749#endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT 750 751 union __ulx{__long __lx; __short __lxx;}; 752 753 enum {__n_words = sizeof(__ulx) / sizeof(size_type)}; 754 755 struct __raw 756 { 757 size_type __words[__n_words]; 758 }; 759 760 struct __rep 761 { 762 union 763 { 764 __long __l; 765 __short __s; 766 __raw __r; 767 }; 768 }; 769 770 __compressed_pair<__rep, allocator_type> __r_; 771 772 // Construct a string with the given allocator and enough storage to hold `__size` characters, but 773 // don't initialize the characters. The contents of the string, including the null terminator, must be 774 // initialized separately. 775 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 776 explicit basic_string(__uninitialized_size_tag, size_type __size, const allocator_type& __a) 777 : __r_(__default_init_tag(), __a) { 778 if (__size > max_size()) 779 __throw_length_error(); 780 if (__fits_in_sso(__size)) { 781 __zero(); 782 __set_short_size(__size); 783 } else { 784 auto __capacity = __recommend(__size) + 1; 785 auto __allocation = __alloc_traits::allocate(__alloc(), __capacity); 786 __begin_lifetime(__allocation, __capacity); 787 __set_long_cap(__capacity); 788 __set_long_pointer(__allocation); 789 __set_long_size(__size); 790 } 791 std::__debug_db_insert_c(this); 792 } 793 794public: 795 _LIBCPP_TEMPLATE_DATA_VIS 796 static const size_type npos = -1; 797 798 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string() 799 _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value); 800 801 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit basic_string(const allocator_type& __a) 802#if _LIBCPP_STD_VER <= 14 803 _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value); 804#else 805 _NOEXCEPT; 806#endif 807 808 _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const basic_string& __str); 809 _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const basic_string& __str, const allocator_type& __a); 810 811#ifndef _LIBCPP_CXX03_LANG 812 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 813 basic_string(basic_string&& __str) 814#if _LIBCPP_STD_VER <= 14 815 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value); 816#else 817 _NOEXCEPT; 818#endif 819 820 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 821 basic_string(basic_string&& __str, const allocator_type& __a); 822#endif // _LIBCPP_CXX03_LANG 823 824 template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> > 825 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 826 basic_string(const _CharT* __s) : __r_(__default_init_tag(), __default_init_tag()) { 827 _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr"); 828 __init(__s, traits_type::length(__s)); 829 std::__debug_db_insert_c(this); 830 } 831 832 template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> > 833 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 834 basic_string(const _CharT* __s, const _Allocator& __a); 835 836#if _LIBCPP_STD_VER > 20 837 basic_string(nullptr_t) = delete; 838#endif 839 840 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 841 basic_string(const _CharT* __s, size_type __n); 842 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 843 basic_string(const _CharT* __s, size_type __n, const _Allocator& __a); 844 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 845 basic_string(size_type __n, _CharT __c); 846 847 template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> > 848 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 849 basic_string(size_type __n, _CharT __c, const _Allocator& __a); 850 851 _LIBCPP_CONSTEXPR_AFTER_CXX17 852 basic_string(const basic_string& __str, size_type __pos, size_type __n, 853 const _Allocator& __a = _Allocator()); 854 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 855 basic_string(const basic_string& __str, size_type __pos, 856 const _Allocator& __a = _Allocator()); 857 858 template<class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> > 859 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 860 basic_string(const _Tp& __t, size_type __pos, size_type __n, 861 const allocator_type& __a = allocator_type()); 862 863 template<class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 864 !__is_same_uncvref<_Tp, basic_string>::value> > 865 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 866 explicit basic_string(const _Tp& __t); 867 868 template<class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> > 869 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 870 explicit basic_string(const _Tp& __t, const allocator_type& __a); 871 872 template<class _InputIterator, class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value> > 873 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 874 basic_string(_InputIterator __first, _InputIterator __last); 875 template<class _InputIterator, class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value> > 876 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 877 basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a); 878#ifndef _LIBCPP_CXX03_LANG 879 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 880 basic_string(initializer_list<_CharT> __il); 881 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 882 basic_string(initializer_list<_CharT> __il, const _Allocator& __a); 883#endif // _LIBCPP_CXX03_LANG 884 885 inline _LIBCPP_CONSTEXPR_AFTER_CXX17 ~basic_string(); 886 887 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 888 operator __self_view() const _NOEXCEPT { return __self_view(data(), size()); } 889 890 _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator=(const basic_string& __str); 891 892 template <class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 893 !__is_same_uncvref<_Tp, basic_string>::value> > 894 _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator=(const _Tp& __t) { 895 __self_view __sv = __t; 896 return assign(__sv); 897 } 898 899#ifndef _LIBCPP_CXX03_LANG 900 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 901 basic_string& operator=(basic_string&& __str) 902 _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value)); 903 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 904 basic_string& operator=(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());} 905#endif 906 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 907 basic_string& operator=(const value_type* __s) {return assign(__s);} 908#if _LIBCPP_STD_VER > 20 909 basic_string& operator=(nullptr_t) = delete; 910#endif 911 _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator=(value_type __c); 912 913#if _LIBCPP_DEBUG_LEVEL == 2 914 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 915 iterator begin() _NOEXCEPT 916 {return iterator(this, __get_pointer());} 917 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 918 const_iterator begin() const _NOEXCEPT 919 {return const_iterator(this, __get_pointer());} 920 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 921 iterator end() _NOEXCEPT 922 {return iterator(this, __get_pointer() + size());} 923 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 924 const_iterator end() const _NOEXCEPT 925 {return const_iterator(this, __get_pointer() + size());} 926#else 927 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 928 iterator begin() _NOEXCEPT 929 {return iterator(__get_pointer());} 930 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 931 const_iterator begin() const _NOEXCEPT 932 {return const_iterator(__get_pointer());} 933 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 934 iterator end() _NOEXCEPT 935 {return iterator(__get_pointer() + size());} 936 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 937 const_iterator end() const _NOEXCEPT 938 {return const_iterator(__get_pointer() + size());} 939#endif // _LIBCPP_DEBUG_LEVEL == 2 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#if _LIBCPP_DEBUG_LEVEL == 2 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_DEBUG_LEVEL == 2 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_all_iterators(); 1791 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __invalidate_iterators_past(size_type); 1792 1793 template<class _Tp> 1794 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 1795 bool __addr_in_range(_Tp&& __t) const { 1796 // assume that the ranges overlap, because we can't check during constant evaluation 1797 if (__libcpp_is_constant_evaluated()) 1798 return true; 1799 const volatile void *__p = std::addressof(__t); 1800 return data() <= __p && __p <= data() + size(); 1801 } 1802 1803 _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI 1804 void __throw_length_error() const { 1805 std::__throw_length_error("basic_string"); 1806 } 1807 1808 _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI 1809 void __throw_out_of_range() const { 1810 std::__throw_out_of_range("basic_string"); 1811 } 1812 1813 friend _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator+<>(const basic_string&, const basic_string&); 1814 friend _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator+<>(const value_type*, const basic_string&); 1815 friend _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator+<>(value_type, const basic_string&); 1816 friend _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator+<>(const basic_string&, const value_type*); 1817 friend _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator+<>(const basic_string&, value_type); 1818}; 1819 1820// These declarations must appear before any functions are implicitly used 1821// so that they have the correct visibility specifier. 1822#ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION 1823 _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, char) 1824# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 1825 _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, wchar_t) 1826# endif 1827#else 1828 _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, char) 1829# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 1830 _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, wchar_t) 1831# endif 1832#endif 1833 1834 1835#if _LIBCPP_STD_VER >= 17 1836template<class _InputIterator, 1837 class _CharT = __iter_value_type<_InputIterator>, 1838 class _Allocator = allocator<_CharT>, 1839 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, 1840 class = enable_if_t<__is_allocator<_Allocator>::value> 1841 > 1842basic_string(_InputIterator, _InputIterator, _Allocator = _Allocator()) 1843 -> basic_string<_CharT, char_traits<_CharT>, _Allocator>; 1844 1845template<class _CharT, 1846 class _Traits, 1847 class _Allocator = allocator<_CharT>, 1848 class = enable_if_t<__is_allocator<_Allocator>::value> 1849 > 1850explicit basic_string(basic_string_view<_CharT, _Traits>, const _Allocator& = _Allocator()) 1851 -> basic_string<_CharT, _Traits, _Allocator>; 1852 1853template<class _CharT, 1854 class _Traits, 1855 class _Allocator = allocator<_CharT>, 1856 class = enable_if_t<__is_allocator<_Allocator>::value>, 1857 class _Sz = typename allocator_traits<_Allocator>::size_type 1858 > 1859basic_string(basic_string_view<_CharT, _Traits>, _Sz, _Sz, const _Allocator& = _Allocator()) 1860 -> basic_string<_CharT, _Traits, _Allocator>; 1861#endif 1862 1863template <class _CharT, class _Traits, class _Allocator> 1864inline _LIBCPP_CONSTEXPR_AFTER_CXX17 1865void 1866basic_string<_CharT, _Traits, _Allocator>::__invalidate_all_iterators() 1867{ 1868#if _LIBCPP_DEBUG_LEVEL == 2 1869 if (!__libcpp_is_constant_evaluated()) 1870 __get_db()->__invalidate_all(this); 1871#endif 1872} 1873 1874template <class _CharT, class _Traits, class _Allocator> 1875inline _LIBCPP_CONSTEXPR_AFTER_CXX17 1876void 1877basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type __pos) 1878{ 1879#if _LIBCPP_DEBUG_LEVEL == 2 1880 if (!__libcpp_is_constant_evaluated()) { 1881 __c_node* __c = __get_db()->__find_c_and_lock(this); 1882 if (__c) 1883 { 1884 const_pointer __new_last = __get_pointer() + __pos; 1885 for (__i_node** __p = __c->end_; __p != __c->beg_; ) 1886 { 1887 --__p; 1888 const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_); 1889 if (__i->base() > __new_last) 1890 { 1891 (*__p)->__c_ = nullptr; 1892 if (--__c->end_ != __p) 1893 std::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); 1894 } 1895 } 1896 __get_db()->unlock(); 1897 } 1898 } 1899#else 1900 (void)__pos; 1901#endif // _LIBCPP_DEBUG_LEVEL == 2 1902} 1903 1904template <class _CharT, class _Traits, class _Allocator> 1905inline _LIBCPP_CONSTEXPR_AFTER_CXX17 1906basic_string<_CharT, _Traits, _Allocator>::basic_string() 1907 _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) 1908 : __r_(__default_init_tag(), __default_init_tag()) 1909{ 1910 std::__debug_db_insert_c(this); 1911 __default_init(); 1912} 1913 1914template <class _CharT, class _Traits, class _Allocator> 1915inline _LIBCPP_CONSTEXPR_AFTER_CXX17 1916basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __a) 1917#if _LIBCPP_STD_VER <= 14 1918 _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value) 1919#else 1920 _NOEXCEPT 1921#endif 1922: __r_(__default_init_tag(), __a) 1923{ 1924 std::__debug_db_insert_c(this); 1925 __default_init(); 1926} 1927 1928template <class _CharT, class _Traits, class _Allocator> 1929_LIBCPP_CONSTEXPR_AFTER_CXX17 1930void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, 1931 size_type __sz, 1932 size_type __reserve) 1933{ 1934 if (__libcpp_is_constant_evaluated()) 1935 __zero(); 1936 if (__reserve > max_size()) 1937 __throw_length_error(); 1938 pointer __p; 1939 if (__fits_in_sso(__reserve)) 1940 { 1941 __set_short_size(__sz); 1942 __p = __get_short_pointer(); 1943 } 1944 else 1945 { 1946 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__reserve) + 1); 1947 __p = __allocation.ptr; 1948 __begin_lifetime(__p, __allocation.count); 1949 __set_long_pointer(__p); 1950 __set_long_cap(__allocation.count); 1951 __set_long_size(__sz); 1952 } 1953 traits_type::copy(std::__to_address(__p), __s, __sz); 1954 traits_type::assign(__p[__sz], value_type()); 1955} 1956 1957template <class _CharT, class _Traits, class _Allocator> 1958_LIBCPP_CONSTEXPR_AFTER_CXX17 1959void 1960basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz) 1961{ 1962 if (__libcpp_is_constant_evaluated()) 1963 __zero(); 1964 if (__sz > max_size()) 1965 __throw_length_error(); 1966 pointer __p; 1967 if (__fits_in_sso(__sz)) 1968 { 1969 __set_short_size(__sz); 1970 __p = __get_short_pointer(); 1971 } 1972 else 1973 { 1974 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1); 1975 __p = __allocation.ptr; 1976 __begin_lifetime(__p, __allocation.count); 1977 __set_long_pointer(__p); 1978 __set_long_cap(__allocation.count); 1979 __set_long_size(__sz); 1980 } 1981 traits_type::copy(std::__to_address(__p), __s, __sz); 1982 traits_type::assign(__p[__sz], value_type()); 1983} 1984 1985template <class _CharT, class _Traits, class _Allocator> 1986template <class> 1987_LIBCPP_CONSTEXPR_AFTER_CXX17 1988basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const _Allocator& __a) 1989 : __r_(__default_init_tag(), __a) 1990{ 1991 _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr"); 1992 __init(__s, traits_type::length(__s)); 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) 1999 : __r_(__default_init_tag(), __default_init_tag()) 2000{ 2001 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr"); 2002 __init(__s, __n); 2003 std::__debug_db_insert_c(this); 2004} 2005 2006template <class _CharT, class _Traits, class _Allocator> 2007inline _LIBCPP_CONSTEXPR_AFTER_CXX17 2008basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n, const _Allocator& __a) 2009 : __r_(__default_init_tag(), __a) 2010{ 2011 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr"); 2012 __init(__s, __n); 2013 std::__debug_db_insert_c(this); 2014} 2015 2016template <class _CharT, class _Traits, class _Allocator> 2017_LIBCPP_CONSTEXPR_AFTER_CXX17 2018basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str) 2019 : __r_(__default_init_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc())) 2020{ 2021 if (!__str.__is_long()) 2022 __r_.first().__r = __str.__r_.first().__r; 2023 else 2024 __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), 2025 __str.__get_long_size()); 2026 std::__debug_db_insert_c(this); 2027} 2028 2029template <class _CharT, class _Traits, class _Allocator> 2030_LIBCPP_CONSTEXPR_AFTER_CXX17 2031basic_string<_CharT, _Traits, _Allocator>::basic_string( 2032 const basic_string& __str, const allocator_type& __a) 2033 : __r_(__default_init_tag(), __a) 2034{ 2035 if (!__str.__is_long()) 2036 __r_.first().__r = __str.__r_.first().__r; 2037 else 2038 __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), 2039 __str.__get_long_size()); 2040 std::__debug_db_insert_c(this); 2041} 2042 2043template <class _CharT, class _Traits, class _Allocator> 2044_LIBCPP_CONSTEXPR_AFTER_CXX17 2045void basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external( 2046 const value_type* __s, size_type __sz) { 2047 if (__libcpp_is_constant_evaluated()) 2048 __zero(); 2049 pointer __p; 2050 if (__fits_in_sso(__sz)) { 2051 __p = __get_short_pointer(); 2052 __set_short_size(__sz); 2053 } else { 2054 if (__sz > max_size()) 2055 __throw_length_error(); 2056 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1); 2057 __p = __allocation.ptr; 2058 __begin_lifetime(__p, __allocation.count); 2059 __set_long_pointer(__p); 2060 __set_long_cap(__allocation.count); 2061 __set_long_size(__sz); 2062 } 2063 traits_type::copy(std::__to_address(__p), __s, __sz + 1); 2064} 2065 2066#ifndef _LIBCPP_CXX03_LANG 2067 2068template <class _CharT, class _Traits, class _Allocator> 2069inline _LIBCPP_CONSTEXPR_AFTER_CXX17 2070basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str) 2071#if _LIBCPP_STD_VER <= 14 2072 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value) 2073#else 2074 _NOEXCEPT 2075#endif 2076 : __r_(std::move(__str.__r_)) 2077{ 2078 __str.__default_init(); 2079 std::__debug_db_insert_c(this); 2080#if _LIBCPP_DEBUG_LEVEL == 2 2081 if (!__libcpp_is_constant_evaluated() && __is_long()) 2082 __get_db()->swap(this, &__str); 2083#endif 2084} 2085 2086template <class _CharT, class _Traits, class _Allocator> 2087inline _LIBCPP_CONSTEXPR_AFTER_CXX17 2088basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, const allocator_type& __a) 2089 : __r_(__default_init_tag(), __a) 2090{ 2091 if (__str.__is_long() && __a != __str.__alloc()) // copy, not move 2092 __init(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); 2093 else 2094 { 2095 if (__libcpp_is_constant_evaluated()) { 2096 __zero(); 2097 __r_.first().__l = __str.__r_.first().__l; 2098 } else { 2099 __r_.first().__r = __str.__r_.first().__r; 2100 } 2101 __str.__default_init(); 2102 } 2103 std::__debug_db_insert_c(this); 2104#if _LIBCPP_DEBUG_LEVEL == 2 2105 if (!__libcpp_is_constant_evaluated() && __is_long()) 2106 __get_db()->swap(this, &__str); 2107#endif 2108} 2109 2110#endif // _LIBCPP_CXX03_LANG 2111 2112template <class _CharT, class _Traits, class _Allocator> 2113_LIBCPP_CONSTEXPR_AFTER_CXX17 2114void 2115basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c) 2116{ 2117 if (__libcpp_is_constant_evaluated()) 2118 __zero(); 2119 if (__n > max_size()) 2120 __throw_length_error(); 2121 pointer __p; 2122 if (__fits_in_sso(__n)) 2123 { 2124 __set_short_size(__n); 2125 __p = __get_short_pointer(); 2126 } 2127 else 2128 { 2129 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__n) + 1); 2130 __p = __allocation.ptr; 2131 __begin_lifetime(__p, __allocation.count); 2132 __set_long_pointer(__p); 2133 __set_long_cap(__allocation.count); 2134 __set_long_size(__n); 2135 } 2136 traits_type::assign(std::__to_address(__p), __n, __c); 2137 traits_type::assign(__p[__n], value_type()); 2138} 2139 2140template <class _CharT, class _Traits, class _Allocator> 2141inline _LIBCPP_CONSTEXPR_AFTER_CXX17 2142basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c) 2143 : __r_(__default_init_tag(), __default_init_tag()) 2144{ 2145 __init(__n, __c); 2146 std::__debug_db_insert_c(this); 2147} 2148 2149template <class _CharT, class _Traits, class _Allocator> 2150template <class> 2151_LIBCPP_CONSTEXPR_AFTER_CXX17 2152basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c, const _Allocator& __a) 2153 : __r_(__default_init_tag(), __a) 2154{ 2155 __init(__n, __c); 2156 std::__debug_db_insert_c(this); 2157} 2158 2159template <class _CharT, class _Traits, class _Allocator> 2160_LIBCPP_CONSTEXPR_AFTER_CXX17 2161basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, 2162 size_type __pos, size_type __n, 2163 const _Allocator& __a) 2164 : __r_(__default_init_tag(), __a) 2165{ 2166 size_type __str_sz = __str.size(); 2167 if (__pos > __str_sz) 2168 __throw_out_of_range(); 2169 __init(__str.data() + __pos, std::min(__n, __str_sz - __pos)); 2170 std::__debug_db_insert_c(this); 2171} 2172 2173template <class _CharT, class _Traits, class _Allocator> 2174inline _LIBCPP_CONSTEXPR_AFTER_CXX17 2175basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos, 2176 const _Allocator& __a) 2177 : __r_(__default_init_tag(), __a) 2178{ 2179 size_type __str_sz = __str.size(); 2180 if (__pos > __str_sz) 2181 __throw_out_of_range(); 2182 __init(__str.data() + __pos, __str_sz - __pos); 2183 std::__debug_db_insert_c(this); 2184} 2185 2186template <class _CharT, class _Traits, class _Allocator> 2187template <class _Tp, class> 2188_LIBCPP_CONSTEXPR_AFTER_CXX17 2189basic_string<_CharT, _Traits, _Allocator>::basic_string( 2190 const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a) 2191 : __r_(__default_init_tag(), __a) 2192{ 2193 __self_view __sv0 = __t; 2194 __self_view __sv = __sv0.substr(__pos, __n); 2195 __init(__sv.data(), __sv.size()); 2196 std::__debug_db_insert_c(this); 2197} 2198 2199template <class _CharT, class _Traits, class _Allocator> 2200template <class _Tp, class> 2201_LIBCPP_CONSTEXPR_AFTER_CXX17 2202basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t) 2203 : __r_(__default_init_tag(), __default_init_tag()) 2204{ 2205 __self_view __sv = __t; 2206 __init(__sv.data(), __sv.size()); 2207 std::__debug_db_insert_c(this); 2208} 2209 2210template <class _CharT, class _Traits, class _Allocator> 2211template <class _Tp, class> 2212_LIBCPP_CONSTEXPR_AFTER_CXX17 2213basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t, const _Allocator& __a) 2214 : __r_(__default_init_tag(), __a) 2215{ 2216 __self_view __sv = __t; 2217 __init(__sv.data(), __sv.size()); 2218 std::__debug_db_insert_c(this); 2219} 2220 2221template <class _CharT, class _Traits, class _Allocator> 2222template <class _InputIterator> 2223_LIBCPP_CONSTEXPR_AFTER_CXX17 2224__enable_if_t 2225< 2226 __is_exactly_cpp17_input_iterator<_InputIterator>::value 2227> 2228basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last) 2229{ 2230 __default_init(); 2231#ifndef _LIBCPP_NO_EXCEPTIONS 2232 try 2233 { 2234#endif // _LIBCPP_NO_EXCEPTIONS 2235 for (; __first != __last; ++__first) 2236 push_back(*__first); 2237#ifndef _LIBCPP_NO_EXCEPTIONS 2238 } 2239 catch (...) 2240 { 2241 if (__is_long()) 2242 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 2243 throw; 2244 } 2245#endif // _LIBCPP_NO_EXCEPTIONS 2246} 2247 2248template <class _CharT, class _Traits, class _Allocator> 2249template <class _ForwardIterator> 2250_LIBCPP_CONSTEXPR_AFTER_CXX17 2251__enable_if_t 2252< 2253 __is_cpp17_forward_iterator<_ForwardIterator>::value 2254> 2255basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last) 2256{ 2257 if (__libcpp_is_constant_evaluated()) 2258 __zero(); 2259 size_type __sz = static_cast<size_type>(std::distance(__first, __last)); 2260 if (__sz > max_size()) 2261 __throw_length_error(); 2262 pointer __p; 2263 if (__fits_in_sso(__sz)) 2264 { 2265 __set_short_size(__sz); 2266 __p = __get_short_pointer(); 2267 } 2268 else 2269 { 2270 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1); 2271 __p = __allocation.ptr; 2272 __begin_lifetime(__p, __allocation.count); 2273 __set_long_pointer(__p); 2274 __set_long_cap(__allocation.count); 2275 __set_long_size(__sz); 2276 } 2277 2278#ifndef _LIBCPP_NO_EXCEPTIONS 2279 try 2280 { 2281#endif // _LIBCPP_NO_EXCEPTIONS 2282 for (; __first != __last; ++__first, (void) ++__p) 2283 traits_type::assign(*__p, *__first); 2284 traits_type::assign(*__p, value_type()); 2285#ifndef _LIBCPP_NO_EXCEPTIONS 2286 } 2287 catch (...) 2288 { 2289 if (__is_long()) 2290 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 2291 throw; 2292 } 2293#endif // _LIBCPP_NO_EXCEPTIONS 2294} 2295 2296template <class _CharT, class _Traits, class _Allocator> 2297template<class _InputIterator, class> 2298inline _LIBCPP_CONSTEXPR_AFTER_CXX17 2299basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last) 2300 : __r_(__default_init_tag(), __default_init_tag()) 2301{ 2302 __init(__first, __last); 2303 std::__debug_db_insert_c(this); 2304} 2305 2306template <class _CharT, class _Traits, class _Allocator> 2307template<class _InputIterator, class> 2308inline _LIBCPP_CONSTEXPR_AFTER_CXX17 2309basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last, 2310 const allocator_type& __a) 2311 : __r_(__default_init_tag(), __a) 2312{ 2313 __init(__first, __last); 2314 std::__debug_db_insert_c(this); 2315} 2316 2317#ifndef _LIBCPP_CXX03_LANG 2318 2319template <class _CharT, class _Traits, class _Allocator> 2320inline _LIBCPP_CONSTEXPR_AFTER_CXX17 2321basic_string<_CharT, _Traits, _Allocator>::basic_string( 2322 initializer_list<_CharT> __il) 2323 : __r_(__default_init_tag(), __default_init_tag()) 2324{ 2325 __init(__il.begin(), __il.end()); 2326 std::__debug_db_insert_c(this); 2327} 2328 2329template <class _CharT, class _Traits, class _Allocator> 2330inline _LIBCPP_CONSTEXPR_AFTER_CXX17 2331basic_string<_CharT, _Traits, _Allocator>::basic_string( 2332 initializer_list<_CharT> __il, const _Allocator& __a) 2333 : __r_(__default_init_tag(), __a) 2334{ 2335 __init(__il.begin(), __il.end()); 2336 std::__debug_db_insert_c(this); 2337} 2338 2339#endif // _LIBCPP_CXX03_LANG 2340 2341template <class _CharT, class _Traits, class _Allocator> 2342_LIBCPP_CONSTEXPR_AFTER_CXX17 2343basic_string<_CharT, _Traits, _Allocator>::~basic_string() 2344{ 2345#if _LIBCPP_DEBUG_LEVEL == 2 2346 if (!__libcpp_is_constant_evaluated()) 2347 __get_db()->__erase_c(this); 2348#endif 2349 if (__is_long()) 2350 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 2351} 2352 2353template <class _CharT, class _Traits, class _Allocator> 2354_LIBCPP_CONSTEXPR_AFTER_CXX17 2355void 2356basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace 2357 (size_type __old_cap, size_type __delta_cap, size_type __old_sz, 2358 size_type __n_copy, size_type __n_del, size_type __n_add, const value_type* __p_new_stuff) 2359{ 2360 size_type __ms = max_size(); 2361 if (__delta_cap > __ms - __old_cap - 1) 2362 __throw_length_error(); 2363 pointer __old_p = __get_pointer(); 2364 size_type __cap = __old_cap < __ms / 2 - __alignment ? 2365 __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : 2366 __ms - 1; 2367 auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1); 2368 pointer __p = __allocation.ptr; 2369 __begin_lifetime(__p, __allocation.count); 2370 __invalidate_all_iterators(); 2371 if (__n_copy != 0) 2372 traits_type::copy(std::__to_address(__p), 2373 std::__to_address(__old_p), __n_copy); 2374 if (__n_add != 0) 2375 traits_type::copy(std::__to_address(__p) + __n_copy, __p_new_stuff, __n_add); 2376 size_type __sec_cp_sz = __old_sz - __n_del - __n_copy; 2377 if (__sec_cp_sz != 0) 2378 traits_type::copy(std::__to_address(__p) + __n_copy + __n_add, 2379 std::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz); 2380 if (__old_cap+1 != __min_cap || __libcpp_is_constant_evaluated()) 2381 __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1); 2382 __set_long_pointer(__p); 2383 __set_long_cap(__allocation.count); 2384 __old_sz = __n_copy + __n_add + __sec_cp_sz; 2385 __set_long_size(__old_sz); 2386 traits_type::assign(__p[__old_sz], value_type()); 2387} 2388 2389template <class _CharT, class _Traits, class _Allocator> 2390void 2391_LIBCPP_CONSTEXPR_AFTER_CXX17 2392basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz, 2393 size_type __n_copy, size_type __n_del, size_type __n_add) 2394{ 2395 size_type __ms = max_size(); 2396 if (__delta_cap > __ms - __old_cap) 2397 __throw_length_error(); 2398 pointer __old_p = __get_pointer(); 2399 size_type __cap = __old_cap < __ms / 2 - __alignment ? 2400 __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : 2401 __ms - 1; 2402 auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1); 2403 pointer __p = __allocation.ptr; 2404 __begin_lifetime(__p, __allocation.count); 2405 __invalidate_all_iterators(); 2406 if (__n_copy != 0) 2407 traits_type::copy(std::__to_address(__p), 2408 std::__to_address(__old_p), __n_copy); 2409 size_type __sec_cp_sz = __old_sz - __n_del - __n_copy; 2410 if (__sec_cp_sz != 0) 2411 traits_type::copy(std::__to_address(__p) + __n_copy + __n_add, 2412 std::__to_address(__old_p) + __n_copy + __n_del, 2413 __sec_cp_sz); 2414 if (__libcpp_is_constant_evaluated() || __old_cap + 1 != __min_cap) 2415 __alloc_traits::deallocate(__alloc(), __old_p, __old_cap + 1); 2416 __set_long_pointer(__p); 2417 __set_long_cap(__allocation.count); 2418} 2419 2420// assign 2421 2422template <class _CharT, class _Traits, class _Allocator> 2423template <bool __is_short> 2424_LIBCPP_CONSTEXPR_AFTER_CXX17 2425basic_string<_CharT, _Traits, _Allocator>& 2426basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias( 2427 const value_type* __s, size_type __n) { 2428 size_type __cap = __is_short ? static_cast<size_type>(__min_cap) : __get_long_cap(); 2429 if (__n < __cap) { 2430 pointer __p = __is_short ? __get_short_pointer() : __get_long_pointer(); 2431 __is_short ? __set_short_size(__n) : __set_long_size(__n); 2432 traits_type::copy(std::__to_address(__p), __s, __n); 2433 traits_type::assign(__p[__n], value_type()); 2434 __invalidate_iterators_past(__n); 2435 } else { 2436 size_type __sz = __is_short ? __get_short_size() : __get_long_size(); 2437 __grow_by_and_replace(__cap - 1, __n - __cap + 1, __sz, 0, __sz, __n, __s); 2438 } 2439 return *this; 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_external( 2446 const value_type* __s, size_type __n) { 2447 size_type __cap = capacity(); 2448 if (__cap >= __n) { 2449 value_type* __p = std::__to_address(__get_pointer()); 2450 traits_type::move(__p, __s, __n); 2451 return __null_terminate_at(__p, __n); 2452 } else { 2453 size_type __sz = size(); 2454 __grow_by_and_replace(__cap, __n - __cap, __sz, 0, __sz, __n, __s); 2455 return *this; 2456 } 2457} 2458 2459template <class _CharT, class _Traits, class _Allocator> 2460_LIBCPP_CONSTEXPR_AFTER_CXX17 2461basic_string<_CharT, _Traits, _Allocator>& 2462basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n) 2463{ 2464 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::assign received nullptr"); 2465 return (__builtin_constant_p(__n) && __fits_in_sso(__n)) 2466 ? __assign_short(__s, __n) 2467 : __assign_external(__s, __n); 2468} 2469 2470template <class _CharT, class _Traits, class _Allocator> 2471_LIBCPP_CONSTEXPR_AFTER_CXX17 2472basic_string<_CharT, _Traits, _Allocator>& 2473basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c) 2474{ 2475 size_type __cap = capacity(); 2476 if (__cap < __n) 2477 { 2478 size_type __sz = size(); 2479 __grow_by(__cap, __n - __cap, __sz, 0, __sz); 2480 } 2481 value_type* __p = std::__to_address(__get_pointer()); 2482 traits_type::assign(__p, __n, __c); 2483 return __null_terminate_at(__p, __n); 2484} 2485 2486template <class _CharT, class _Traits, class _Allocator> 2487_LIBCPP_CONSTEXPR_AFTER_CXX17 2488basic_string<_CharT, _Traits, _Allocator>& 2489basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c) 2490{ 2491 pointer __p; 2492 if (__is_long()) 2493 { 2494 __p = __get_long_pointer(); 2495 __set_long_size(1); 2496 } 2497 else 2498 { 2499 __p = __get_short_pointer(); 2500 __set_short_size(1); 2501 } 2502 traits_type::assign(*__p, __c); 2503 traits_type::assign(*++__p, value_type()); 2504 __invalidate_iterators_past(1); 2505 return *this; 2506} 2507 2508template <class _CharT, class _Traits, class _Allocator> 2509_LIBCPP_CONSTEXPR_AFTER_CXX17 2510basic_string<_CharT, _Traits, _Allocator>& 2511basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str) 2512{ 2513 if (this != &__str) { 2514 __copy_assign_alloc(__str); 2515 if (!__is_long()) { 2516 if (!__str.__is_long()) { 2517 __r_.first().__r = __str.__r_.first().__r; 2518 } else { 2519 return __assign_no_alias<true>(__str.data(), __str.size()); 2520 } 2521 } else { 2522 return __assign_no_alias<false>(__str.data(), __str.size()); 2523 } 2524 } 2525 return *this; 2526} 2527 2528#ifndef _LIBCPP_CXX03_LANG 2529 2530template <class _CharT, class _Traits, class _Allocator> 2531inline _LIBCPP_CONSTEXPR_AFTER_CXX17 2532void 2533basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, false_type) 2534 _NOEXCEPT_(__alloc_traits::is_always_equal::value) 2535{ 2536 if (__alloc() != __str.__alloc()) 2537 assign(__str); 2538 else 2539 __move_assign(__str, true_type()); 2540} 2541 2542template <class _CharT, class _Traits, class _Allocator> 2543inline _LIBCPP_CONSTEXPR_AFTER_CXX17 2544void 2545basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type) 2546#if _LIBCPP_STD_VER > 14 2547 _NOEXCEPT 2548#else 2549 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) 2550#endif 2551{ 2552 if (__is_long()) { 2553 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), 2554 __get_long_cap()); 2555#if _LIBCPP_STD_VER <= 14 2556 if (!is_nothrow_move_assignable<allocator_type>::value) { 2557 __set_short_size(0); 2558 traits_type::assign(__get_short_pointer()[0], value_type()); 2559 } 2560#endif 2561 } 2562 __move_assign_alloc(__str); 2563 __r_.first() = __str.__r_.first(); 2564 if (__libcpp_is_constant_evaluated()) { 2565 __str.__default_init(); 2566 } else { 2567 __str.__set_short_size(0); 2568 traits_type::assign(__str.__get_short_pointer()[0], value_type()); 2569 } 2570} 2571 2572template <class _CharT, class _Traits, class _Allocator> 2573inline _LIBCPP_CONSTEXPR_AFTER_CXX17 2574basic_string<_CharT, _Traits, _Allocator>& 2575basic_string<_CharT, _Traits, _Allocator>::operator=(basic_string&& __str) 2576 _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value)) 2577{ 2578 __move_assign(__str, integral_constant<bool, 2579 __alloc_traits::propagate_on_container_move_assignment::value>()); 2580 return *this; 2581} 2582 2583#endif 2584 2585template <class _CharT, class _Traits, class _Allocator> 2586template<class _InputIterator> 2587_LIBCPP_CONSTEXPR_AFTER_CXX17 2588__enable_if_t 2589< 2590 __is_exactly_cpp17_input_iterator<_InputIterator>::value, 2591 basic_string<_CharT, _Traits, _Allocator>& 2592> 2593basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last) 2594{ 2595 const basic_string __temp(__first, __last, __alloc()); 2596 assign(__temp.data(), __temp.size()); 2597 return *this; 2598} 2599 2600template <class _CharT, class _Traits, class _Allocator> 2601template<class _ForwardIterator> 2602_LIBCPP_CONSTEXPR_AFTER_CXX17 2603__enable_if_t 2604< 2605 __is_cpp17_forward_iterator<_ForwardIterator>::value, 2606 basic_string<_CharT, _Traits, _Allocator>& 2607> 2608basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last) 2609{ 2610 size_type __cap = capacity(); 2611 size_type __n = __string_is_trivial_iterator<_ForwardIterator>::value ? 2612 static_cast<size_type>(std::distance(__first, __last)) : 0; 2613 2614 if (__string_is_trivial_iterator<_ForwardIterator>::value && 2615 (__cap >= __n || !__addr_in_range(*__first))) 2616 { 2617 if (__cap < __n) 2618 { 2619 size_type __sz = size(); 2620 __grow_by(__cap, __n - __cap, __sz, 0, __sz); 2621 } 2622 pointer __p = __get_pointer(); 2623 for (; __first != __last; ++__p, (void) ++__first) 2624 traits_type::assign(*__p, *__first); 2625 traits_type::assign(*__p, value_type()); 2626 __set_size(__n); 2627 __invalidate_iterators_past(__n); 2628 } 2629 else 2630 { 2631 const basic_string __temp(__first, __last, __alloc()); 2632 assign(__temp.data(), __temp.size()); 2633 } 2634 return *this; 2635} 2636 2637template <class _CharT, class _Traits, class _Allocator> 2638_LIBCPP_CONSTEXPR_AFTER_CXX17 2639basic_string<_CharT, _Traits, _Allocator>& 2640basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, size_type __pos, size_type __n) 2641{ 2642 size_type __sz = __str.size(); 2643 if (__pos > __sz) 2644 __throw_out_of_range(); 2645 return assign(__str.data() + __pos, std::min(__n, __sz - __pos)); 2646} 2647 2648template <class _CharT, class _Traits, class _Allocator> 2649template <class _Tp> 2650_LIBCPP_CONSTEXPR_AFTER_CXX17 2651__enable_if_t 2652< 2653 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value 2654 && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 2655 basic_string<_CharT, _Traits, _Allocator>& 2656> 2657basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t, size_type __pos, size_type __n) 2658{ 2659 __self_view __sv = __t; 2660 size_type __sz = __sv.size(); 2661 if (__pos > __sz) 2662 __throw_out_of_range(); 2663 return assign(__sv.data() + __pos, std::min(__n, __sz - __pos)); 2664} 2665 2666 2667template <class _CharT, class _Traits, class _Allocator> 2668_LIBCPP_CONSTEXPR_AFTER_CXX17 2669basic_string<_CharT, _Traits, _Allocator>& 2670basic_string<_CharT, _Traits, _Allocator>::__assign_external(const value_type* __s) { 2671 return __assign_external(__s, traits_type::length(__s)); 2672} 2673 2674template <class _CharT, class _Traits, class _Allocator> 2675_LIBCPP_CONSTEXPR_AFTER_CXX17 2676basic_string<_CharT, _Traits, _Allocator>& 2677basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s) 2678{ 2679 _LIBCPP_ASSERT(__s != nullptr, "string::assign received nullptr"); 2680 return __builtin_constant_p(*__s) 2681 ? (__fits_in_sso(traits_type::length(__s)) 2682 ? __assign_short(__s, traits_type::length(__s)) 2683 : __assign_external(__s, traits_type::length(__s))) 2684 : __assign_external(__s); 2685} 2686// append 2687 2688template <class _CharT, class _Traits, class _Allocator> 2689_LIBCPP_CONSTEXPR_AFTER_CXX17 2690basic_string<_CharT, _Traits, _Allocator>& 2691basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n) 2692{ 2693 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::append received nullptr"); 2694 size_type __cap = capacity(); 2695 size_type __sz = size(); 2696 if (__cap - __sz >= __n) 2697 { 2698 if (__n) 2699 { 2700 value_type* __p = std::__to_address(__get_pointer()); 2701 traits_type::copy(__p + __sz, __s, __n); 2702 __sz += __n; 2703 __set_size(__sz); 2704 traits_type::assign(__p[__sz], value_type()); 2705 } 2706 } 2707 else 2708 __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __sz, 0, __n, __s); 2709 return *this; 2710} 2711 2712template <class _CharT, class _Traits, class _Allocator> 2713_LIBCPP_CONSTEXPR_AFTER_CXX17 2714basic_string<_CharT, _Traits, _Allocator>& 2715basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c) 2716{ 2717 if (__n) 2718 { 2719 size_type __cap = capacity(); 2720 size_type __sz = size(); 2721 if (__cap - __sz < __n) 2722 __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); 2723 pointer __p = __get_pointer(); 2724 traits_type::assign(std::__to_address(__p) + __sz, __n, __c); 2725 __sz += __n; 2726 __set_size(__sz); 2727 traits_type::assign(__p[__sz], value_type()); 2728 } 2729 return *this; 2730} 2731 2732template <class _CharT, class _Traits, class _Allocator> 2733_LIBCPP_CONSTEXPR_AFTER_CXX17 inline void 2734basic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n) 2735{ 2736 if (__n) 2737 { 2738 size_type __cap = capacity(); 2739 size_type __sz = size(); 2740 if (__cap - __sz < __n) 2741 __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); 2742 pointer __p = __get_pointer(); 2743 __sz += __n; 2744 __set_size(__sz); 2745 traits_type::assign(__p[__sz], value_type()); 2746 } 2747} 2748 2749template <class _CharT, class _Traits, class _Allocator> 2750_LIBCPP_CONSTEXPR_AFTER_CXX17 2751void 2752basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c) 2753{ 2754 bool __is_short = !__is_long(); 2755 size_type __cap; 2756 size_type __sz; 2757 if (__is_short) 2758 { 2759 __cap = __min_cap - 1; 2760 __sz = __get_short_size(); 2761 } 2762 else 2763 { 2764 __cap = __get_long_cap() - 1; 2765 __sz = __get_long_size(); 2766 } 2767 if (__sz == __cap) 2768 { 2769 __grow_by(__cap, 1, __sz, __sz, 0); 2770 __is_short = false; // the string is always long after __grow_by 2771 } 2772 pointer __p = __get_pointer(); 2773 if (__is_short) 2774 { 2775 __p = __get_short_pointer() + __sz; 2776 __set_short_size(__sz+1); 2777 } 2778 else 2779 { 2780 __p = __get_long_pointer() + __sz; 2781 __set_long_size(__sz+1); 2782 } 2783 traits_type::assign(*__p, __c); 2784 traits_type::assign(*++__p, value_type()); 2785} 2786 2787template <class _CharT, class _Traits, class _Allocator> 2788template<class _ForwardIterator> 2789_LIBCPP_CONSTEXPR_AFTER_CXX17 2790__enable_if_t 2791< 2792 __is_cpp17_forward_iterator<_ForwardIterator>::value, 2793 basic_string<_CharT, _Traits, _Allocator>& 2794> 2795basic_string<_CharT, _Traits, _Allocator>::append( 2796 _ForwardIterator __first, _ForwardIterator __last) 2797{ 2798 size_type __sz = size(); 2799 size_type __cap = capacity(); 2800 size_type __n = static_cast<size_type>(std::distance(__first, __last)); 2801 if (__n) 2802 { 2803 if (__string_is_trivial_iterator<_ForwardIterator>::value && 2804 !__addr_in_range(*__first)) 2805 { 2806 if (__cap - __sz < __n) 2807 __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); 2808 pointer __p = __get_pointer() + __sz; 2809 for (; __first != __last; ++__p, (void) ++__first) 2810 traits_type::assign(*__p, *__first); 2811 traits_type::assign(*__p, value_type()); 2812 __set_size(__sz + __n); 2813 } 2814 else 2815 { 2816 const basic_string __temp(__first, __last, __alloc()); 2817 append(__temp.data(), __temp.size()); 2818 } 2819 } 2820 return *this; 2821} 2822 2823template <class _CharT, class _Traits, class _Allocator> 2824inline _LIBCPP_CONSTEXPR_AFTER_CXX17 2825basic_string<_CharT, _Traits, _Allocator>& 2826basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str) 2827{ 2828 return append(__str.data(), __str.size()); 2829} 2830 2831template <class _CharT, class _Traits, class _Allocator> 2832_LIBCPP_CONSTEXPR_AFTER_CXX17 2833basic_string<_CharT, _Traits, _Allocator>& 2834basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, size_type __pos, size_type __n) 2835{ 2836 size_type __sz = __str.size(); 2837 if (__pos > __sz) 2838 __throw_out_of_range(); 2839 return append(__str.data() + __pos, std::min(__n, __sz - __pos)); 2840} 2841 2842template <class _CharT, class _Traits, class _Allocator> 2843template <class _Tp> 2844_LIBCPP_CONSTEXPR_AFTER_CXX17 2845 __enable_if_t 2846 < 2847 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 2848 basic_string<_CharT, _Traits, _Allocator>& 2849 > 2850basic_string<_CharT, _Traits, _Allocator>::append(const _Tp & __t, size_type __pos, size_type __n) 2851{ 2852 __self_view __sv = __t; 2853 size_type __sz = __sv.size(); 2854 if (__pos > __sz) 2855 __throw_out_of_range(); 2856 return append(__sv.data() + __pos, std::min(__n, __sz - __pos)); 2857} 2858 2859template <class _CharT, class _Traits, class _Allocator> 2860_LIBCPP_CONSTEXPR_AFTER_CXX17 2861basic_string<_CharT, _Traits, _Allocator>& 2862basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s) 2863{ 2864 _LIBCPP_ASSERT(__s != nullptr, "string::append received nullptr"); 2865 return append(__s, traits_type::length(__s)); 2866} 2867 2868// insert 2869 2870template <class _CharT, class _Traits, class _Allocator> 2871_LIBCPP_CONSTEXPR_AFTER_CXX17 2872basic_string<_CharT, _Traits, _Allocator>& 2873basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n) 2874{ 2875 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::insert received nullptr"); 2876 size_type __sz = size(); 2877 if (__pos > __sz) 2878 __throw_out_of_range(); 2879 size_type __cap = capacity(); 2880 if (__libcpp_is_constant_evaluated()) { 2881 if (__cap - __sz >= __n) 2882 __grow_by_and_replace(__cap, 0, __sz, __pos, 0, __n, __s); 2883 else 2884 __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s); 2885 return *this; 2886 } 2887 if (__cap - __sz >= __n) 2888 { 2889 if (__n) 2890 { 2891 value_type* __p = std::__to_address(__get_pointer()); 2892 size_type __n_move = __sz - __pos; 2893 if (__n_move != 0) 2894 { 2895 if (__p + __pos <= __s && __s < __p + __sz) 2896 __s += __n; 2897 traits_type::move(__p + __pos + __n, __p + __pos, __n_move); 2898 } 2899 traits_type::move(__p + __pos, __s, __n); 2900 __sz += __n; 2901 __set_size(__sz); 2902 traits_type::assign(__p[__sz], value_type()); 2903 } 2904 } 2905 else 2906 __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s); 2907 return *this; 2908} 2909 2910template <class _CharT, class _Traits, class _Allocator> 2911_LIBCPP_CONSTEXPR_AFTER_CXX17 2912basic_string<_CharT, _Traits, _Allocator>& 2913basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n, value_type __c) 2914{ 2915 size_type __sz = size(); 2916 if (__pos > __sz) 2917 __throw_out_of_range(); 2918 if (__n) 2919 { 2920 size_type __cap = capacity(); 2921 value_type* __p; 2922 if (__cap - __sz >= __n) 2923 { 2924 __p = std::__to_address(__get_pointer()); 2925 size_type __n_move = __sz - __pos; 2926 if (__n_move != 0) 2927 traits_type::move(__p + __pos + __n, __p + __pos, __n_move); 2928 } 2929 else 2930 { 2931 __grow_by(__cap, __sz + __n - __cap, __sz, __pos, 0, __n); 2932 __p = std::__to_address(__get_long_pointer()); 2933 } 2934 traits_type::assign(__p + __pos, __n, __c); 2935 __sz += __n; 2936 __set_size(__sz); 2937 traits_type::assign(__p[__sz], value_type()); 2938 } 2939 return *this; 2940} 2941 2942template <class _CharT, class _Traits, class _Allocator> 2943template<class _InputIterator> 2944_LIBCPP_CONSTEXPR_AFTER_CXX17 2945__enable_if_t 2946< 2947 __is_exactly_cpp17_input_iterator<_InputIterator>::value, 2948 typename basic_string<_CharT, _Traits, _Allocator>::iterator 2949> 2950basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __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" 2954 " referring to this string"); 2955 const basic_string __temp(__first, __last, __alloc()); 2956 return insert(__pos, __temp.data(), __temp.data() + __temp.size()); 2957} 2958 2959template <class _CharT, class _Traits, class _Allocator> 2960template<class _ForwardIterator> 2961_LIBCPP_CONSTEXPR_AFTER_CXX17 2962__enable_if_t 2963< 2964 __is_cpp17_forward_iterator<_ForwardIterator>::value, 2965 typename basic_string<_CharT, _Traits, _Allocator>::iterator 2966> 2967basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last) 2968{ 2969 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, 2970 "string::insert(iterator, range) called with an iterator not referring to this string"); 2971 2972 size_type __ip = static_cast<size_type>(__pos - begin()); 2973 size_type __n = static_cast<size_type>(std::distance(__first, __last)); 2974 if (__n == 0) 2975 return begin() + __ip; 2976 2977 if (__string_is_trivial_iterator<_ForwardIterator>::value && !__addr_in_range(*__first)) 2978 { 2979 return __insert_from_safe_copy(__n, __ip, __first, __last); 2980 } 2981 else 2982 { 2983 const basic_string __temp(__first, __last, __alloc()); 2984 return __insert_from_safe_copy(__n, __ip, __temp.begin(), __temp.end()); 2985 } 2986} 2987 2988template <class _CharT, class _Traits, class _Allocator> 2989inline _LIBCPP_CONSTEXPR_AFTER_CXX17 2990basic_string<_CharT, _Traits, _Allocator>& 2991basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str) 2992{ 2993 return insert(__pos1, __str.data(), __str.size()); 2994} 2995 2996template <class _CharT, class _Traits, class _Allocator> 2997_LIBCPP_CONSTEXPR_AFTER_CXX17 2998basic_string<_CharT, _Traits, _Allocator>& 2999basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str, 3000 size_type __pos2, size_type __n) 3001{ 3002 size_type __str_sz = __str.size(); 3003 if (__pos2 > __str_sz) 3004 __throw_out_of_range(); 3005 return insert(__pos1, __str.data() + __pos2, std::min(__n, __str_sz - __pos2)); 3006} 3007 3008template <class _CharT, class _Traits, class _Allocator> 3009template <class _Tp> 3010_LIBCPP_CONSTEXPR_AFTER_CXX17 3011__enable_if_t 3012< 3013 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 3014 basic_string<_CharT, _Traits, _Allocator>& 3015> 3016basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& __t, 3017 size_type __pos2, size_type __n) 3018{ 3019 __self_view __sv = __t; 3020 size_type __str_sz = __sv.size(); 3021 if (__pos2 > __str_sz) 3022 __throw_out_of_range(); 3023 return insert(__pos1, __sv.data() + __pos2, std::min(__n, __str_sz - __pos2)); 3024} 3025 3026template <class _CharT, class _Traits, class _Allocator> 3027_LIBCPP_CONSTEXPR_AFTER_CXX17 3028basic_string<_CharT, _Traits, _Allocator>& 3029basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s) 3030{ 3031 _LIBCPP_ASSERT(__s != nullptr, "string::insert received nullptr"); 3032 return insert(__pos, __s, traits_type::length(__s)); 3033} 3034 3035template <class _CharT, class _Traits, class _Allocator> 3036_LIBCPP_CONSTEXPR_AFTER_CXX17 3037typename basic_string<_CharT, _Traits, _Allocator>::iterator 3038basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c) 3039{ 3040 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, 3041 "string::insert(iterator, character) called with an iterator not" 3042 " referring to this string"); 3043 3044 size_type __ip = static_cast<size_type>(__pos - begin()); 3045 size_type __sz = size(); 3046 size_type __cap = capacity(); 3047 value_type* __p; 3048 if (__cap == __sz) 3049 { 3050 __grow_by(__cap, 1, __sz, __ip, 0, 1); 3051 __p = std::__to_address(__get_long_pointer()); 3052 } 3053 else 3054 { 3055 __p = std::__to_address(__get_pointer()); 3056 size_type __n_move = __sz - __ip; 3057 if (__n_move != 0) 3058 traits_type::move(__p + __ip + 1, __p + __ip, __n_move); 3059 } 3060 traits_type::assign(__p[__ip], __c); 3061 traits_type::assign(__p[++__sz], value_type()); 3062 __set_size(__sz); 3063 return begin() + static_cast<difference_type>(__ip); 3064} 3065 3066template <class _CharT, class _Traits, class _Allocator> 3067inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3068typename basic_string<_CharT, _Traits, _Allocator>::iterator 3069basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, size_type __n, value_type __c) 3070{ 3071 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, 3072 "string::insert(iterator, n, value) called with an iterator not" 3073 " referring to this string"); 3074 difference_type __p = __pos - begin(); 3075 insert(static_cast<size_type>(__p), __n, __c); 3076 return begin() + __p; 3077} 3078 3079// replace 3080 3081template <class _CharT, class _Traits, class _Allocator> 3082_LIBCPP_CONSTEXPR_AFTER_CXX17 3083basic_string<_CharT, _Traits, _Allocator>& 3084basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2) 3085 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK 3086{ 3087 _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::replace received nullptr"); 3088 size_type __sz = size(); 3089 if (__pos > __sz) 3090 __throw_out_of_range(); 3091 __n1 = std::min(__n1, __sz - __pos); 3092 size_type __cap = capacity(); 3093 if (__cap - __sz + __n1 >= __n2) 3094 { 3095 if (__libcpp_is_constant_evaluated()) { 3096 __grow_by_and_replace(__cap, 0, __sz, __pos, __n1, __n2, __s); 3097 return *this; 3098 } 3099 value_type* __p = std::__to_address(__get_pointer()); 3100 if (__n1 != __n2) 3101 { 3102 size_type __n_move = __sz - __pos - __n1; 3103 if (__n_move != 0) 3104 { 3105 if (__n1 > __n2) 3106 { 3107 traits_type::move(__p + __pos, __s, __n2); 3108 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move); 3109 return __null_terminate_at(__p, __sz + (__n2 - __n1)); 3110 } 3111 if (__p + __pos < __s && __s < __p + __sz) 3112 { 3113 if (__p + __pos + __n1 <= __s) 3114 __s += __n2 - __n1; 3115 else // __p + __pos < __s < __p + __pos + __n1 3116 { 3117 traits_type::move(__p + __pos, __s, __n1); 3118 __pos += __n1; 3119 __s += __n2; 3120 __n2 -= __n1; 3121 __n1 = 0; 3122 } 3123 } 3124 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move); 3125 } 3126 } 3127 traits_type::move(__p + __pos, __s, __n2); 3128 return __null_terminate_at(__p, __sz + (__n2 - __n1)); 3129 } 3130 else 3131 __grow_by_and_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2, __s); 3132 return *this; 3133} 3134 3135template <class _CharT, class _Traits, class _Allocator> 3136_LIBCPP_CONSTEXPR_AFTER_CXX17 3137basic_string<_CharT, _Traits, _Allocator>& 3138basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, size_type __n2, value_type __c) 3139{ 3140 size_type __sz = size(); 3141 if (__pos > __sz) 3142 __throw_out_of_range(); 3143 __n1 = std::min(__n1, __sz - __pos); 3144 size_type __cap = capacity(); 3145 value_type* __p; 3146 if (__cap - __sz + __n1 >= __n2) 3147 { 3148 __p = std::__to_address(__get_pointer()); 3149 if (__n1 != __n2) 3150 { 3151 size_type __n_move = __sz - __pos - __n1; 3152 if (__n_move != 0) 3153 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move); 3154 } 3155 } 3156 else 3157 { 3158 __grow_by(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2); 3159 __p = std::__to_address(__get_long_pointer()); 3160 } 3161 traits_type::assign(__p + __pos, __n2, __c); 3162 return __null_terminate_at(__p, __sz - (__n1 - __n2)); 3163} 3164 3165template <class _CharT, class _Traits, class _Allocator> 3166template<class _InputIterator> 3167_LIBCPP_CONSTEXPR_AFTER_CXX17 3168__enable_if_t 3169< 3170 __is_cpp17_input_iterator<_InputIterator>::value, 3171 basic_string<_CharT, _Traits, _Allocator>& 3172> 3173basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, 3174 _InputIterator __j1, _InputIterator __j2) 3175{ 3176 const basic_string __temp(__j1, __j2, __alloc()); 3177 return replace(__i1, __i2, __temp); 3178} 3179 3180template <class _CharT, class _Traits, class _Allocator> 3181inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3182basic_string<_CharT, _Traits, _Allocator>& 3183basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str) 3184{ 3185 return replace(__pos1, __n1, __str.data(), __str.size()); 3186} 3187 3188template <class _CharT, class _Traits, class _Allocator> 3189_LIBCPP_CONSTEXPR_AFTER_CXX17 3190basic_string<_CharT, _Traits, _Allocator>& 3191basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str, 3192 size_type __pos2, size_type __n2) 3193{ 3194 size_type __str_sz = __str.size(); 3195 if (__pos2 > __str_sz) 3196 __throw_out_of_range(); 3197 return replace(__pos1, __n1, __str.data() + __pos2, std::min(__n2, __str_sz - __pos2)); 3198} 3199 3200template <class _CharT, class _Traits, class _Allocator> 3201template <class _Tp> 3202_LIBCPP_CONSTEXPR_AFTER_CXX17 3203__enable_if_t 3204< 3205 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 3206 basic_string<_CharT, _Traits, _Allocator>& 3207> 3208basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const _Tp& __t, 3209 size_type __pos2, size_type __n2) 3210{ 3211 __self_view __sv = __t; 3212 size_type __str_sz = __sv.size(); 3213 if (__pos2 > __str_sz) 3214 __throw_out_of_range(); 3215 return replace(__pos1, __n1, __sv.data() + __pos2, std::min(__n2, __str_sz - __pos2)); 3216} 3217 3218template <class _CharT, class _Traits, class _Allocator> 3219_LIBCPP_CONSTEXPR_AFTER_CXX17 3220basic_string<_CharT, _Traits, _Allocator>& 3221basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s) 3222{ 3223 _LIBCPP_ASSERT(__s != nullptr, "string::replace received nullptr"); 3224 return replace(__pos, __n1, __s, traits_type::length(__s)); 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 basic_string& __str) 3231{ 3232 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), 3233 __str.data(), __str.size()); 3234} 3235 3236template <class _CharT, class _Traits, class _Allocator> 3237inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3238basic_string<_CharT, _Traits, _Allocator>& 3239basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n) 3240{ 3241 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s, __n); 3242} 3243 3244template <class _CharT, class _Traits, class _Allocator> 3245inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3246basic_string<_CharT, _Traits, _Allocator>& 3247basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s) 3248{ 3249 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s); 3250} 3251 3252template <class _CharT, class _Traits, class _Allocator> 3253inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3254basic_string<_CharT, _Traits, _Allocator>& 3255basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c) 3256{ 3257 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __n, __c); 3258} 3259 3260// erase 3261 3262// 'externally instantiated' erase() implementation, called when __n != npos. 3263// Does not check __pos against size() 3264template <class _CharT, class _Traits, class _Allocator> 3265_LIBCPP_CONSTEXPR_AFTER_CXX17 3266void 3267basic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move( 3268 size_type __pos, size_type __n) 3269{ 3270 if (__n) 3271 { 3272 size_type __sz = size(); 3273 value_type* __p = std::__to_address(__get_pointer()); 3274 __n = std::min(__n, __sz - __pos); 3275 size_type __n_move = __sz - __pos - __n; 3276 if (__n_move != 0) 3277 traits_type::move(__p + __pos, __p + __pos + __n, __n_move); 3278 __null_terminate_at(__p, __sz - __n); 3279 } 3280} 3281 3282template <class _CharT, class _Traits, class _Allocator> 3283_LIBCPP_CONSTEXPR_AFTER_CXX17 3284basic_string<_CharT, _Traits, _Allocator>& 3285basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, 3286 size_type __n) { 3287 if (__pos > size()) 3288 __throw_out_of_range(); 3289 if (__n == npos) { 3290 __erase_to_end(__pos); 3291 } else { 3292 __erase_external_with_move(__pos, __n); 3293 } 3294 return *this; 3295} 3296 3297template <class _CharT, class _Traits, class _Allocator> 3298inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3299typename basic_string<_CharT, _Traits, _Allocator>::iterator 3300basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos) 3301{ 3302 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, 3303 "string::erase(iterator) called with an iterator not" 3304 " referring to this string"); 3305 3306 _LIBCPP_ASSERT(__pos != end(), "string::erase(iterator) called with a non-dereferenceable iterator"); 3307 iterator __b = begin(); 3308 size_type __r = static_cast<size_type>(__pos - __b); 3309 erase(__r, 1); 3310 return __b + static_cast<difference_type>(__r); 3311} 3312 3313template <class _CharT, class _Traits, class _Allocator> 3314inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3315typename basic_string<_CharT, _Traits, _Allocator>::iterator 3316basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last) 3317{ 3318 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this, 3319 "string::erase(iterator, iterator) called with an iterator not" 3320 " referring to this string"); 3321 3322 _LIBCPP_ASSERT(__first <= __last, "string::erase(first, last) called with invalid range"); 3323 iterator __b = begin(); 3324 size_type __r = static_cast<size_type>(__first - __b); 3325 erase(__r, static_cast<size_type>(__last - __first)); 3326 return __b + static_cast<difference_type>(__r); 3327} 3328 3329template <class _CharT, class _Traits, class _Allocator> 3330inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3331void 3332basic_string<_CharT, _Traits, _Allocator>::pop_back() 3333{ 3334 _LIBCPP_ASSERT(!empty(), "string::pop_back(): string is already empty"); 3335 __erase_to_end(size() - 1); 3336} 3337 3338template <class _CharT, class _Traits, class _Allocator> 3339inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3340void 3341basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT 3342{ 3343 __invalidate_all_iterators(); 3344 if (__is_long()) 3345 { 3346 traits_type::assign(*__get_long_pointer(), value_type()); 3347 __set_long_size(0); 3348 } 3349 else 3350 { 3351 traits_type::assign(*__get_short_pointer(), value_type()); 3352 __set_short_size(0); 3353 } 3354} 3355 3356template <class _CharT, class _Traits, class _Allocator> 3357inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3358void 3359basic_string<_CharT, _Traits, _Allocator>::__erase_to_end(size_type __pos) 3360{ 3361 __null_terminate_at(std::__to_address(__get_pointer()), __pos); 3362} 3363 3364template <class _CharT, class _Traits, class _Allocator> 3365_LIBCPP_CONSTEXPR_AFTER_CXX17 3366void 3367basic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c) 3368{ 3369 size_type __sz = size(); 3370 if (__n > __sz) 3371 append(__n - __sz, __c); 3372 else 3373 __erase_to_end(__n); 3374} 3375 3376template <class _CharT, class _Traits, class _Allocator> 3377_LIBCPP_CONSTEXPR_AFTER_CXX17 inline void 3378basic_string<_CharT, _Traits, _Allocator>::__resize_default_init(size_type __n) 3379{ 3380 size_type __sz = size(); 3381 if (__n > __sz) { 3382 __append_default_init(__n - __sz); 3383 } else 3384 __erase_to_end(__n); 3385} 3386 3387template <class _CharT, class _Traits, class _Allocator> 3388inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3389typename basic_string<_CharT, _Traits, _Allocator>::size_type 3390basic_string<_CharT, _Traits, _Allocator>::max_size() const _NOEXCEPT 3391{ 3392 size_type __m = __alloc_traits::max_size(__alloc()); 3393 if (__m <= std::numeric_limits<size_type>::max() / 2) { 3394 return __m - __alignment; 3395 } else { 3396 bool __uses_lsb = __endian_factor == 2; 3397 return __uses_lsb ? __m - __alignment : (__m / 2) - __alignment; 3398 } 3399} 3400 3401template <class _CharT, class _Traits, class _Allocator> 3402_LIBCPP_CONSTEXPR_AFTER_CXX17 3403void 3404basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacity) 3405{ 3406 if (__requested_capacity > max_size()) 3407 __throw_length_error(); 3408 3409 // Make sure reserve(n) never shrinks. This is technically only required in C++20 3410 // and later (since P0966R1), however we provide consistent behavior in all Standard 3411 // modes because this function is instantiated in the shared library. 3412 if (__requested_capacity <= capacity()) 3413 return; 3414 3415 size_type __target_capacity = std::max(__requested_capacity, size()); 3416 __target_capacity = __recommend(__target_capacity); 3417 if (__target_capacity == capacity()) return; 3418 3419 __shrink_or_extend(__target_capacity); 3420} 3421 3422template <class _CharT, class _Traits, class _Allocator> 3423inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3424void 3425basic_string<_CharT, _Traits, _Allocator>::shrink_to_fit() _NOEXCEPT 3426{ 3427 size_type __target_capacity = __recommend(size()); 3428 if (__target_capacity == capacity()) return; 3429 3430 __shrink_or_extend(__target_capacity); 3431} 3432 3433template <class _CharT, class _Traits, class _Allocator> 3434inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3435void 3436basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target_capacity) 3437{ 3438 size_type __cap = capacity(); 3439 size_type __sz = size(); 3440 3441 pointer __new_data, __p; 3442 bool __was_long, __now_long; 3443 if (__fits_in_sso(__target_capacity)) 3444 { 3445 __was_long = true; 3446 __now_long = false; 3447 __new_data = __get_short_pointer(); 3448 __p = __get_long_pointer(); 3449 } 3450 else 3451 { 3452 if (__target_capacity > __cap) { 3453 auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1); 3454 __new_data = __allocation.ptr; 3455 __target_capacity = __allocation.count - 1; 3456 } 3457 else 3458 { 3459 #ifndef _LIBCPP_NO_EXCEPTIONS 3460 try 3461 { 3462 #endif // _LIBCPP_NO_EXCEPTIONS 3463 auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1); 3464 __new_data = __allocation.ptr; 3465 __target_capacity = __allocation.count - 1; 3466 #ifndef _LIBCPP_NO_EXCEPTIONS 3467 } 3468 catch (...) 3469 { 3470 return; 3471 } 3472 #else // _LIBCPP_NO_EXCEPTIONS 3473 if (__new_data == nullptr) 3474 return; 3475 #endif // _LIBCPP_NO_EXCEPTIONS 3476 } 3477 __begin_lifetime(__new_data, __target_capacity + 1); 3478 __now_long = true; 3479 __was_long = __is_long(); 3480 __p = __get_pointer(); 3481 } 3482 traits_type::copy(std::__to_address(__new_data), 3483 std::__to_address(__p), size()+1); 3484 if (__was_long) 3485 __alloc_traits::deallocate(__alloc(), __p, __cap+1); 3486 if (__now_long) 3487 { 3488 __set_long_cap(__target_capacity+1); 3489 __set_long_size(__sz); 3490 __set_long_pointer(__new_data); 3491 } 3492 else 3493 __set_short_size(__sz); 3494 __invalidate_all_iterators(); 3495} 3496 3497template <class _CharT, class _Traits, class _Allocator> 3498inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3499typename basic_string<_CharT, _Traits, _Allocator>::const_reference 3500basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const _NOEXCEPT 3501{ 3502 _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds"); 3503 return *(data() + __pos); 3504} 3505 3506template <class _CharT, class _Traits, class _Allocator> 3507inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3508typename basic_string<_CharT, _Traits, _Allocator>::reference 3509basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) _NOEXCEPT 3510{ 3511 _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds"); 3512 return *(__get_pointer() + __pos); 3513} 3514 3515template <class _CharT, class _Traits, class _Allocator> 3516_LIBCPP_CONSTEXPR_AFTER_CXX17 3517typename basic_string<_CharT, _Traits, _Allocator>::const_reference 3518basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const 3519{ 3520 if (__n >= size()) 3521 __throw_out_of_range(); 3522 return (*this)[__n]; 3523} 3524 3525template <class _CharT, class _Traits, class _Allocator> 3526_LIBCPP_CONSTEXPR_AFTER_CXX17 3527typename basic_string<_CharT, _Traits, _Allocator>::reference 3528basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) 3529{ 3530 if (__n >= size()) 3531 __throw_out_of_range(); 3532 return (*this)[__n]; 3533} 3534 3535template <class _CharT, class _Traits, class _Allocator> 3536inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3537typename basic_string<_CharT, _Traits, _Allocator>::reference 3538basic_string<_CharT, _Traits, _Allocator>::front() _NOEXCEPT 3539{ 3540 _LIBCPP_ASSERT(!empty(), "string::front(): string is empty"); 3541 return *__get_pointer(); 3542} 3543 3544template <class _CharT, class _Traits, class _Allocator> 3545inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3546typename basic_string<_CharT, _Traits, _Allocator>::const_reference 3547basic_string<_CharT, _Traits, _Allocator>::front() const _NOEXCEPT 3548{ 3549 _LIBCPP_ASSERT(!empty(), "string::front(): string is empty"); 3550 return *data(); 3551} 3552 3553template <class _CharT, class _Traits, class _Allocator> 3554inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3555typename basic_string<_CharT, _Traits, _Allocator>::reference 3556basic_string<_CharT, _Traits, _Allocator>::back() _NOEXCEPT 3557{ 3558 _LIBCPP_ASSERT(!empty(), "string::back(): string is empty"); 3559 return *(__get_pointer() + size() - 1); 3560} 3561 3562template <class _CharT, class _Traits, class _Allocator> 3563inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3564typename basic_string<_CharT, _Traits, _Allocator>::const_reference 3565basic_string<_CharT, _Traits, _Allocator>::back() const _NOEXCEPT 3566{ 3567 _LIBCPP_ASSERT(!empty(), "string::back(): string is empty"); 3568 return *(data() + size() - 1); 3569} 3570 3571template <class _CharT, class _Traits, class _Allocator> 3572_LIBCPP_CONSTEXPR_AFTER_CXX17 3573typename basic_string<_CharT, _Traits, _Allocator>::size_type 3574basic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n, size_type __pos) const 3575{ 3576 size_type __sz = size(); 3577 if (__pos > __sz) 3578 __throw_out_of_range(); 3579 size_type __rlen = std::min(__n, __sz - __pos); 3580 traits_type::copy(__s, data() + __pos, __rlen); 3581 return __rlen; 3582} 3583 3584template <class _CharT, class _Traits, class _Allocator> 3585inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3586basic_string<_CharT, _Traits, _Allocator> 3587basic_string<_CharT, _Traits, _Allocator>::substr(size_type __pos, size_type __n) const 3588{ 3589 return basic_string(*this, __pos, __n, __alloc()); 3590} 3591 3592template <class _CharT, class _Traits, class _Allocator> 3593inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3594void 3595basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str) 3596#if _LIBCPP_STD_VER >= 14 3597 _NOEXCEPT 3598#else 3599 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || 3600 __is_nothrow_swappable<allocator_type>::value) 3601#endif 3602{ 3603#if _LIBCPP_DEBUG_LEVEL == 2 3604 if (!__libcpp_is_constant_evaluated()) { 3605 if (!__is_long()) 3606 __get_db()->__invalidate_all(this); 3607 if (!__str.__is_long()) 3608 __get_db()->__invalidate_all(&__str); 3609 __get_db()->swap(this, &__str); 3610 } 3611#endif 3612 _LIBCPP_ASSERT( 3613 __alloc_traits::propagate_on_container_swap::value || 3614 __alloc_traits::is_always_equal::value || 3615 __alloc() == __str.__alloc(), "swapping non-equal allocators"); 3616 std::swap(__r_.first(), __str.__r_.first()); 3617 std::__swap_allocator(__alloc(), __str.__alloc()); 3618} 3619 3620// find 3621 3622template <class _Traits> 3623struct _LIBCPP_HIDDEN __traits_eq 3624{ 3625 typedef typename _Traits::char_type char_type; 3626 _LIBCPP_HIDE_FROM_ABI 3627 bool operator()(const char_type& __x, const char_type& __y) _NOEXCEPT 3628 {return _Traits::eq(__x, __y);} 3629}; 3630 3631template<class _CharT, class _Traits, class _Allocator> 3632_LIBCPP_CONSTEXPR_AFTER_CXX17 3633typename basic_string<_CharT, _Traits, _Allocator>::size_type 3634basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, 3635 size_type __pos, 3636 size_type __n) const _NOEXCEPT 3637{ 3638 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find(): received nullptr"); 3639 return __str_find<value_type, size_type, traits_type, npos> 3640 (data(), size(), __s, __pos, __n); 3641} 3642 3643template<class _CharT, class _Traits, class _Allocator> 3644inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3645typename basic_string<_CharT, _Traits, _Allocator>::size_type 3646basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str, 3647 size_type __pos) const _NOEXCEPT 3648{ 3649 return __str_find<value_type, size_type, traits_type, npos> 3650 (data(), size(), __str.data(), __pos, __str.size()); 3651} 3652 3653template<class _CharT, class _Traits, class _Allocator> 3654template <class _Tp> 3655_LIBCPP_CONSTEXPR_AFTER_CXX17 3656__enable_if_t 3657< 3658 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 3659 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3660> 3661basic_string<_CharT, _Traits, _Allocator>::find(const _Tp &__t, 3662 size_type __pos) const _NOEXCEPT 3663{ 3664 __self_view __sv = __t; 3665 return __str_find<value_type, size_type, traits_type, npos> 3666 (data(), size(), __sv.data(), __pos, __sv.size()); 3667} 3668 3669template<class _CharT, class _Traits, class _Allocator> 3670inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3671typename basic_string<_CharT, _Traits, _Allocator>::size_type 3672basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, 3673 size_type __pos) const _NOEXCEPT 3674{ 3675 _LIBCPP_ASSERT(__s != nullptr, "string::find(): received nullptr"); 3676 return __str_find<value_type, size_type, traits_type, npos> 3677 (data(), size(), __s, __pos, traits_type::length(__s)); 3678} 3679 3680template<class _CharT, class _Traits, class _Allocator> 3681_LIBCPP_CONSTEXPR_AFTER_CXX17 3682typename basic_string<_CharT, _Traits, _Allocator>::size_type 3683basic_string<_CharT, _Traits, _Allocator>::find(value_type __c, 3684 size_type __pos) const _NOEXCEPT 3685{ 3686 return __str_find<value_type, size_type, traits_type, npos> 3687 (data(), size(), __c, __pos); 3688} 3689 3690// rfind 3691 3692template<class _CharT, class _Traits, class _Allocator> 3693_LIBCPP_CONSTEXPR_AFTER_CXX17 3694typename basic_string<_CharT, _Traits, _Allocator>::size_type 3695basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, 3696 size_type __pos, 3697 size_type __n) const _NOEXCEPT 3698{ 3699 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::rfind(): received nullptr"); 3700 return __str_rfind<value_type, size_type, traits_type, npos> 3701 (data(), size(), __s, __pos, __n); 3702} 3703 3704template<class _CharT, class _Traits, class _Allocator> 3705inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3706typename basic_string<_CharT, _Traits, _Allocator>::size_type 3707basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str, 3708 size_type __pos) const _NOEXCEPT 3709{ 3710 return __str_rfind<value_type, size_type, traits_type, npos> 3711 (data(), size(), __str.data(), __pos, __str.size()); 3712} 3713 3714template<class _CharT, class _Traits, class _Allocator> 3715template <class _Tp> 3716_LIBCPP_CONSTEXPR_AFTER_CXX17 3717__enable_if_t 3718< 3719 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 3720 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3721> 3722basic_string<_CharT, _Traits, _Allocator>::rfind(const _Tp& __t, 3723 size_type __pos) const _NOEXCEPT 3724{ 3725 __self_view __sv = __t; 3726 return __str_rfind<value_type, size_type, traits_type, npos> 3727 (data(), size(), __sv.data(), __pos, __sv.size()); 3728} 3729 3730template<class _CharT, class _Traits, class _Allocator> 3731inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3732typename basic_string<_CharT, _Traits, _Allocator>::size_type 3733basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, 3734 size_type __pos) const _NOEXCEPT 3735{ 3736 _LIBCPP_ASSERT(__s != nullptr, "string::rfind(): received nullptr"); 3737 return __str_rfind<value_type, size_type, traits_type, npos> 3738 (data(), size(), __s, __pos, traits_type::length(__s)); 3739} 3740 3741template<class _CharT, class _Traits, class _Allocator> 3742_LIBCPP_CONSTEXPR_AFTER_CXX17 3743typename basic_string<_CharT, _Traits, _Allocator>::size_type 3744basic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c, 3745 size_type __pos) const _NOEXCEPT 3746{ 3747 return __str_rfind<value_type, size_type, traits_type, npos> 3748 (data(), size(), __c, __pos); 3749} 3750 3751// find_first_of 3752 3753template<class _CharT, class _Traits, class _Allocator> 3754_LIBCPP_CONSTEXPR_AFTER_CXX17 3755typename basic_string<_CharT, _Traits, _Allocator>::size_type 3756basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, 3757 size_type __pos, 3758 size_type __n) const _NOEXCEPT 3759{ 3760 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr"); 3761 return __str_find_first_of<value_type, size_type, traits_type, npos> 3762 (data(), size(), __s, __pos, __n); 3763} 3764 3765template<class _CharT, class _Traits, class _Allocator> 3766inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3767typename basic_string<_CharT, _Traits, _Allocator>::size_type 3768basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str, 3769 size_type __pos) const _NOEXCEPT 3770{ 3771 return __str_find_first_of<value_type, size_type, traits_type, npos> 3772 (data(), size(), __str.data(), __pos, __str.size()); 3773} 3774 3775template<class _CharT, class _Traits, class _Allocator> 3776template <class _Tp> 3777_LIBCPP_CONSTEXPR_AFTER_CXX17 3778__enable_if_t 3779< 3780 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 3781 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3782> 3783basic_string<_CharT, _Traits, _Allocator>::find_first_of(const _Tp& __t, 3784 size_type __pos) const _NOEXCEPT 3785{ 3786 __self_view __sv = __t; 3787 return __str_find_first_of<value_type, size_type, traits_type, npos> 3788 (data(), size(), __sv.data(), __pos, __sv.size()); 3789} 3790 3791template<class _CharT, class _Traits, class _Allocator> 3792inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3793typename basic_string<_CharT, _Traits, _Allocator>::size_type 3794basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, 3795 size_type __pos) const _NOEXCEPT 3796{ 3797 _LIBCPP_ASSERT(__s != nullptr, "string::find_first_of(): received nullptr"); 3798 return __str_find_first_of<value_type, size_type, traits_type, npos> 3799 (data(), size(), __s, __pos, traits_type::length(__s)); 3800} 3801 3802template<class _CharT, class _Traits, class _Allocator> 3803inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3804typename basic_string<_CharT, _Traits, _Allocator>::size_type 3805basic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c, 3806 size_type __pos) const _NOEXCEPT 3807{ 3808 return find(__c, __pos); 3809} 3810 3811// find_last_of 3812 3813template<class _CharT, class _Traits, class _Allocator> 3814inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3815typename basic_string<_CharT, _Traits, _Allocator>::size_type 3816basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, 3817 size_type __pos, 3818 size_type __n) const _NOEXCEPT 3819{ 3820 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr"); 3821 return __str_find_last_of<value_type, size_type, traits_type, npos> 3822 (data(), size(), __s, __pos, __n); 3823} 3824 3825template<class _CharT, class _Traits, class _Allocator> 3826inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3827typename basic_string<_CharT, _Traits, _Allocator>::size_type 3828basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str, 3829 size_type __pos) const _NOEXCEPT 3830{ 3831 return __str_find_last_of<value_type, size_type, traits_type, npos> 3832 (data(), size(), __str.data(), __pos, __str.size()); 3833} 3834 3835template<class _CharT, class _Traits, class _Allocator> 3836template <class _Tp> 3837_LIBCPP_CONSTEXPR_AFTER_CXX17 3838__enable_if_t 3839< 3840 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 3841 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3842> 3843basic_string<_CharT, _Traits, _Allocator>::find_last_of(const _Tp& __t, 3844 size_type __pos) const _NOEXCEPT 3845{ 3846 __self_view __sv = __t; 3847 return __str_find_last_of<value_type, size_type, traits_type, npos> 3848 (data(), size(), __sv.data(), __pos, __sv.size()); 3849} 3850 3851template<class _CharT, class _Traits, class _Allocator> 3852inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3853typename basic_string<_CharT, _Traits, _Allocator>::size_type 3854basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, 3855 size_type __pos) const _NOEXCEPT 3856{ 3857 _LIBCPP_ASSERT(__s != nullptr, "string::find_last_of(): received nullptr"); 3858 return __str_find_last_of<value_type, size_type, traits_type, npos> 3859 (data(), size(), __s, __pos, traits_type::length(__s)); 3860} 3861 3862template<class _CharT, class _Traits, class _Allocator> 3863inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3864typename basic_string<_CharT, _Traits, _Allocator>::size_type 3865basic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c, 3866 size_type __pos) const _NOEXCEPT 3867{ 3868 return rfind(__c, __pos); 3869} 3870 3871// find_first_not_of 3872 3873template<class _CharT, class _Traits, class _Allocator> 3874_LIBCPP_CONSTEXPR_AFTER_CXX17 3875typename basic_string<_CharT, _Traits, _Allocator>::size_type 3876basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s, 3877 size_type __pos, 3878 size_type __n) const _NOEXCEPT 3879{ 3880 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr"); 3881 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 3882 (data(), size(), __s, __pos, __n); 3883} 3884 3885template<class _CharT, class _Traits, class _Allocator> 3886inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3887typename basic_string<_CharT, _Traits, _Allocator>::size_type 3888basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string& __str, 3889 size_type __pos) const _NOEXCEPT 3890{ 3891 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 3892 (data(), size(), __str.data(), __pos, __str.size()); 3893} 3894 3895template<class _CharT, class _Traits, class _Allocator> 3896template <class _Tp> 3897_LIBCPP_CONSTEXPR_AFTER_CXX17 3898__enable_if_t 3899< 3900 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 3901 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3902> 3903basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const _Tp& __t, 3904 size_type __pos) const _NOEXCEPT 3905{ 3906 __self_view __sv = __t; 3907 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 3908 (data(), size(), __sv.data(), __pos, __sv.size()); 3909} 3910 3911template<class _CharT, class _Traits, class _Allocator> 3912inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3913typename basic_string<_CharT, _Traits, _Allocator>::size_type 3914basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s, 3915 size_type __pos) const _NOEXCEPT 3916{ 3917 _LIBCPP_ASSERT(__s != nullptr, "string::find_first_not_of(): received nullptr"); 3918 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 3919 (data(), size(), __s, __pos, traits_type::length(__s)); 3920} 3921 3922template<class _CharT, class _Traits, class _Allocator> 3923inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3924typename basic_string<_CharT, _Traits, _Allocator>::size_type 3925basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c, 3926 size_type __pos) const _NOEXCEPT 3927{ 3928 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 3929 (data(), size(), __c, __pos); 3930} 3931 3932// find_last_not_of 3933 3934template<class _CharT, class _Traits, class _Allocator> 3935_LIBCPP_CONSTEXPR_AFTER_CXX17 3936typename basic_string<_CharT, _Traits, _Allocator>::size_type 3937basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s, 3938 size_type __pos, 3939 size_type __n) const _NOEXCEPT 3940{ 3941 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr"); 3942 return __str_find_last_not_of<value_type, size_type, traits_type, npos> 3943 (data(), size(), __s, __pos, __n); 3944} 3945 3946template<class _CharT, class _Traits, class _Allocator> 3947inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3948typename basic_string<_CharT, _Traits, _Allocator>::size_type 3949basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string& __str, 3950 size_type __pos) const _NOEXCEPT 3951{ 3952 return __str_find_last_not_of<value_type, size_type, traits_type, npos> 3953 (data(), size(), __str.data(), __pos, __str.size()); 3954} 3955 3956template<class _CharT, class _Traits, class _Allocator> 3957template <class _Tp> 3958_LIBCPP_CONSTEXPR_AFTER_CXX17 3959__enable_if_t 3960< 3961 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 3962 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3963> 3964basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const _Tp& __t, 3965 size_type __pos) const _NOEXCEPT 3966{ 3967 __self_view __sv = __t; 3968 return __str_find_last_not_of<value_type, size_type, traits_type, npos> 3969 (data(), size(), __sv.data(), __pos, __sv.size()); 3970} 3971 3972template<class _CharT, class _Traits, class _Allocator> 3973inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3974typename basic_string<_CharT, _Traits, _Allocator>::size_type 3975basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s, 3976 size_type __pos) const _NOEXCEPT 3977{ 3978 _LIBCPP_ASSERT(__s != nullptr, "string::find_last_not_of(): received nullptr"); 3979 return __str_find_last_not_of<value_type, size_type, traits_type, npos> 3980 (data(), size(), __s, __pos, traits_type::length(__s)); 3981} 3982 3983template<class _CharT, class _Traits, class _Allocator> 3984inline _LIBCPP_CONSTEXPR_AFTER_CXX17 3985typename basic_string<_CharT, _Traits, _Allocator>::size_type 3986basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c, 3987 size_type __pos) const _NOEXCEPT 3988{ 3989 return __str_find_last_not_of<value_type, size_type, traits_type, npos> 3990 (data(), size(), __c, __pos); 3991} 3992 3993// compare 3994 3995template <class _CharT, class _Traits, class _Allocator> 3996template <class _Tp> 3997_LIBCPP_CONSTEXPR_AFTER_CXX17 3998__enable_if_t 3999< 4000 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 4001 int 4002> 4003basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const _NOEXCEPT 4004{ 4005 __self_view __sv = __t; 4006 size_t __lhs_sz = size(); 4007 size_t __rhs_sz = __sv.size(); 4008 int __result = traits_type::compare(data(), __sv.data(), 4009 std::min(__lhs_sz, __rhs_sz)); 4010 if (__result != 0) 4011 return __result; 4012 if (__lhs_sz < __rhs_sz) 4013 return -1; 4014 if (__lhs_sz > __rhs_sz) 4015 return 1; 4016 return 0; 4017} 4018 4019template <class _CharT, class _Traits, class _Allocator> 4020inline _LIBCPP_CONSTEXPR_AFTER_CXX17 4021int 4022basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT 4023{ 4024 return compare(__self_view(__str)); 4025} 4026 4027template <class _CharT, class _Traits, class _Allocator> 4028inline _LIBCPP_CONSTEXPR_AFTER_CXX17 4029int 4030basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, 4031 size_type __n1, 4032 const value_type* __s, 4033 size_type __n2) const 4034{ 4035 _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr"); 4036 size_type __sz = size(); 4037 if (__pos1 > __sz || __n2 == npos) 4038 __throw_out_of_range(); 4039 size_type __rlen = std::min(__n1, __sz - __pos1); 4040 int __r = traits_type::compare(data() + __pos1, __s, std::min(__rlen, __n2)); 4041 if (__r == 0) 4042 { 4043 if (__rlen < __n2) 4044 __r = -1; 4045 else if (__rlen > __n2) 4046 __r = 1; 4047 } 4048 return __r; 4049} 4050 4051template <class _CharT, class _Traits, class _Allocator> 4052template <class _Tp> 4053_LIBCPP_CONSTEXPR_AFTER_CXX17 4054__enable_if_t 4055< 4056 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, 4057 int 4058> 4059basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, 4060 size_type __n1, 4061 const _Tp& __t) const 4062{ 4063 __self_view __sv = __t; 4064 return compare(__pos1, __n1, __sv.data(), __sv.size()); 4065} 4066 4067template <class _CharT, class _Traits, class _Allocator> 4068inline _LIBCPP_CONSTEXPR_AFTER_CXX17 4069int 4070basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, 4071 size_type __n1, 4072 const basic_string& __str) const 4073{ 4074 return compare(__pos1, __n1, __str.data(), __str.size()); 4075} 4076 4077template <class _CharT, class _Traits, class _Allocator> 4078template <class _Tp> 4079_LIBCPP_CONSTEXPR_AFTER_CXX17 4080__enable_if_t 4081< 4082 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value 4083 && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 4084 int 4085> 4086basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, 4087 size_type __n1, 4088 const _Tp& __t, 4089 size_type __pos2, 4090 size_type __n2) const 4091{ 4092 __self_view __sv = __t; 4093 return __self_view(*this).substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2)); 4094} 4095 4096template <class _CharT, class _Traits, class _Allocator> 4097_LIBCPP_CONSTEXPR_AFTER_CXX17 4098int 4099basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, 4100 size_type __n1, 4101 const basic_string& __str, 4102 size_type __pos2, 4103 size_type __n2) const 4104{ 4105 return compare(__pos1, __n1, __self_view(__str), __pos2, __n2); 4106} 4107 4108template <class _CharT, class _Traits, class _Allocator> 4109_LIBCPP_CONSTEXPR_AFTER_CXX17 4110int 4111basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT 4112{ 4113 _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr"); 4114 return compare(0, npos, __s, traits_type::length(__s)); 4115} 4116 4117template <class _CharT, class _Traits, class _Allocator> 4118_LIBCPP_CONSTEXPR_AFTER_CXX17 4119int 4120basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, 4121 size_type __n1, 4122 const value_type* __s) const 4123{ 4124 _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr"); 4125 return compare(__pos1, __n1, __s, traits_type::length(__s)); 4126} 4127 4128// __invariants 4129 4130template<class _CharT, class _Traits, class _Allocator> 4131inline _LIBCPP_CONSTEXPR_AFTER_CXX17 4132bool 4133basic_string<_CharT, _Traits, _Allocator>::__invariants() const 4134{ 4135 if (size() > capacity()) 4136 return false; 4137 if (capacity() < __min_cap - 1) 4138 return false; 4139 if (data() == nullptr) 4140 return false; 4141 if (data()[size()] != value_type()) 4142 return false; 4143 return true; 4144} 4145 4146// __clear_and_shrink 4147 4148template<class _CharT, class _Traits, class _Allocator> 4149inline _LIBCPP_CONSTEXPR_AFTER_CXX17 4150void 4151basic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT 4152{ 4153 clear(); 4154 if(__is_long()) 4155 { 4156 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), capacity() + 1); 4157 __set_long_cap(0); 4158 __set_short_size(0); 4159 traits_type::assign(*__get_short_pointer(), value_type()); 4160 } 4161} 4162 4163// operator== 4164 4165template<class _CharT, class _Traits, class _Allocator> 4166inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4167bool 4168operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4169 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4170{ 4171 size_t __lhs_sz = __lhs.size(); 4172 return __lhs_sz == __rhs.size() && _Traits::compare(__lhs.data(), 4173 __rhs.data(), 4174 __lhs_sz) == 0; 4175} 4176 4177template<class _Allocator> 4178inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4179bool 4180operator==(const basic_string<char, char_traits<char>, _Allocator>& __lhs, 4181 const basic_string<char, char_traits<char>, _Allocator>& __rhs) _NOEXCEPT 4182{ 4183 size_t __lhs_sz = __lhs.size(); 4184 if (__lhs_sz != __rhs.size()) 4185 return false; 4186 const char* __lp = __lhs.data(); 4187 const char* __rp = __rhs.data(); 4188 if (__lhs.__is_long()) 4189 return char_traits<char>::compare(__lp, __rp, __lhs_sz) == 0; 4190 for (; __lhs_sz != 0; --__lhs_sz, ++__lp, ++__rp) 4191 if (*__lp != *__rp) 4192 return false; 4193 return true; 4194} 4195 4196template<class _CharT, class _Traits, class _Allocator> 4197inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4198bool 4199operator==(const _CharT* __lhs, 4200 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4201{ 4202 typedef basic_string<_CharT, _Traits, _Allocator> _String; 4203 _LIBCPP_ASSERT(__lhs != nullptr, "operator==(char*, basic_string): received nullptr"); 4204 size_t __lhs_len = _Traits::length(__lhs); 4205 if (__lhs_len != __rhs.size()) return false; 4206 return __rhs.compare(0, _String::npos, __lhs, __lhs_len) == 0; 4207} 4208 4209template<class _CharT, class _Traits, class _Allocator> 4210inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4211bool 4212operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 4213 const _CharT* __rhs) _NOEXCEPT 4214{ 4215 typedef basic_string<_CharT, _Traits, _Allocator> _String; 4216 _LIBCPP_ASSERT(__rhs != nullptr, "operator==(basic_string, char*): received nullptr"); 4217 size_t __rhs_len = _Traits::length(__rhs); 4218 if (__rhs_len != __lhs.size()) return false; 4219 return __lhs.compare(0, _String::npos, __rhs, __rhs_len) == 0; 4220} 4221 4222template<class _CharT, class _Traits, class _Allocator> 4223inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4224bool 4225operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, 4226 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4227{ 4228 return !(__lhs == __rhs); 4229} 4230 4231template<class _CharT, class _Traits, class _Allocator> 4232inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4233bool 4234operator!=(const _CharT* __lhs, 4235 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4236{ 4237 return !(__lhs == __rhs); 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 == __rhs); 4247} 4248 4249// operator< 4250 4251template<class _CharT, class _Traits, class _Allocator> 4252inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4253bool 4254operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4255 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4256{ 4257 return __lhs.compare(__rhs) < 0; 4258} 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 _CharT* __rhs) _NOEXCEPT 4265{ 4266 return __lhs.compare(__rhs) < 0; 4267} 4268 4269template<class _CharT, class _Traits, class _Allocator> 4270inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4271bool 4272operator< (const _CharT* __lhs, 4273 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4274{ 4275 return __rhs.compare(__lhs) > 0; 4276} 4277 4278// operator> 4279 4280template<class _CharT, class _Traits, class _Allocator> 4281inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4282bool 4283operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4284 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4285{ 4286 return __rhs < __lhs; 4287} 4288 4289template<class _CharT, class _Traits, class _Allocator> 4290inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4291bool 4292operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4293 const _CharT* __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 _CharT* __lhs, 4302 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4303{ 4304 return __rhs < __lhs; 4305} 4306 4307// operator<= 4308 4309template<class _CharT, class _Traits, class _Allocator> 4310inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4311bool 4312operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4313 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4314{ 4315 return !(__rhs < __lhs); 4316} 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 _CharT* __rhs) _NOEXCEPT 4323{ 4324 return !(__rhs < __lhs); 4325} 4326 4327template<class _CharT, class _Traits, class _Allocator> 4328inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4329bool 4330operator<=(const _CharT* __lhs, 4331 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4332{ 4333 return !(__rhs < __lhs); 4334} 4335 4336// operator>= 4337 4338template<class _CharT, class _Traits, class _Allocator> 4339inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4340bool 4341operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4342 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4343{ 4344 return !(__lhs < __rhs); 4345} 4346 4347template<class _CharT, class _Traits, class _Allocator> 4348inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4349bool 4350operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4351 const _CharT* __rhs) _NOEXCEPT 4352{ 4353 return !(__lhs < __rhs); 4354} 4355 4356template<class _CharT, class _Traits, class _Allocator> 4357inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI 4358bool 4359operator>=(const _CharT* __lhs, 4360 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT 4361{ 4362 return !(__lhs < __rhs); 4363} 4364 4365// operator + 4366 4367template<class _CharT, class _Traits, class _Allocator> 4368_LIBCPP_CONSTEXPR_AFTER_CXX17 4369basic_string<_CharT, _Traits, _Allocator> 4370operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 4371 const basic_string<_CharT, _Traits, _Allocator>& __rhs) 4372{ 4373 using _String = basic_string<_CharT, _Traits, _Allocator>; 4374 auto __lhs_sz = __lhs.size(); 4375 auto __rhs_sz = __rhs.size(); 4376 _String __r(__uninitialized_size_tag(), 4377 __lhs_sz + __rhs_sz, 4378 _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator())); 4379 auto __ptr = std::__to_address(__r.__get_pointer()); 4380 _Traits::copy(__ptr, __lhs.data(), __lhs_sz); 4381 _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz); 4382 _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT()); 4383 return __r; 4384} 4385 4386template<class _CharT, class _Traits, class _Allocator> 4387_LIBCPP_CONSTEXPR_AFTER_CXX17 4388basic_string<_CharT, _Traits, _Allocator> 4389operator+(const _CharT* __lhs , const basic_string<_CharT,_Traits,_Allocator>& __rhs) 4390{ 4391 using _String = basic_string<_CharT, _Traits, _Allocator>; 4392 auto __lhs_sz = _Traits::length(__lhs); 4393 auto __rhs_sz = __rhs.size(); 4394 _String __r(__uninitialized_size_tag(), 4395 __lhs_sz + __rhs_sz, 4396 _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator())); 4397 auto __ptr = std::__to_address(__r.__get_pointer()); 4398 _Traits::copy(__ptr, __lhs, __lhs_sz); 4399 _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz); 4400 _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT()); 4401 return __r; 4402} 4403 4404template<class _CharT, class _Traits, class _Allocator> 4405_LIBCPP_CONSTEXPR_AFTER_CXX17 4406basic_string<_CharT, _Traits, _Allocator> 4407operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Allocator>& __rhs) 4408{ 4409 using _String = basic_string<_CharT, _Traits, _Allocator>; 4410 typename _String::size_type __rhs_sz = __rhs.size(); 4411 _String __r(__uninitialized_size_tag(), 4412 __rhs_sz + 1, 4413 _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator())); 4414 auto __ptr = std::__to_address(__r.__get_pointer()); 4415 _Traits::assign(__ptr, 1, __lhs); 4416 _Traits::copy(__ptr + 1, __rhs.data(), __rhs_sz); 4417 _Traits::assign(__ptr + 1 + __rhs_sz, 1, _CharT()); 4418 return __r; 4419} 4420 4421template<class _CharT, class _Traits, class _Allocator> 4422inline _LIBCPP_CONSTEXPR_AFTER_CXX17 4423basic_string<_CharT, _Traits, _Allocator> 4424operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) 4425{ 4426 using _String = basic_string<_CharT, _Traits, _Allocator>; 4427 typename _String::size_type __lhs_sz = __lhs.size(); 4428 typename _String::size_type __rhs_sz = _Traits::length(__rhs); 4429 _String __r(__uninitialized_size_tag(), 4430 __lhs_sz + __rhs_sz, 4431 _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator())); 4432 auto __ptr = std::__to_address(__r.__get_pointer()); 4433 _Traits::copy(__ptr, __lhs.data(), __lhs_sz); 4434 _Traits::copy(__ptr + __lhs_sz, __rhs, __rhs_sz); 4435 _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT()); 4436 return __r; 4437} 4438 4439template<class _CharT, class _Traits, class _Allocator> 4440_LIBCPP_CONSTEXPR_AFTER_CXX17 4441basic_string<_CharT, _Traits, _Allocator> 4442operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs) 4443{ 4444 using _String = basic_string<_CharT, _Traits, _Allocator>; 4445 typename _String::size_type __lhs_sz = __lhs.size(); 4446 _String __r(__uninitialized_size_tag(), 4447 __lhs_sz + 1, 4448 _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator())); 4449 auto __ptr = std::__to_address(__r.__get_pointer()); 4450 _Traits::copy(__ptr, __lhs.data(), __lhs_sz); 4451 _Traits::assign(__ptr + __lhs_sz, 1, __rhs); 4452 _Traits::assign(__ptr + 1 + __lhs_sz, 1, _CharT()); 4453 return __r; 4454} 4455 4456#ifndef _LIBCPP_CXX03_LANG 4457 4458template<class _CharT, class _Traits, class _Allocator> 4459inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 4460basic_string<_CharT, _Traits, _Allocator> 4461operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) 4462{ 4463 return std::move(__lhs.append(__rhs)); 4464} 4465 4466template<class _CharT, class _Traits, class _Allocator> 4467inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 4468basic_string<_CharT, _Traits, _Allocator> 4469operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs) 4470{ 4471 return std::move(__rhs.insert(0, __lhs)); 4472} 4473 4474template<class _CharT, class _Traits, class _Allocator> 4475inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 4476basic_string<_CharT, _Traits, _Allocator> 4477operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs) 4478{ 4479 return std::move(__lhs.append(__rhs)); 4480} 4481 4482template<class _CharT, class _Traits, class _Allocator> 4483inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 4484basic_string<_CharT, _Traits, _Allocator> 4485operator+(const _CharT* __lhs , basic_string<_CharT,_Traits,_Allocator>&& __rhs) 4486{ 4487 return std::move(__rhs.insert(0, __lhs)); 4488} 4489 4490template<class _CharT, class _Traits, class _Allocator> 4491inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 4492basic_string<_CharT, _Traits, _Allocator> 4493operator+(_CharT __lhs, basic_string<_CharT,_Traits,_Allocator>&& __rhs) 4494{ 4495 __rhs.insert(__rhs.begin(), __lhs); 4496 return std::move(__rhs); 4497} 4498 4499template<class _CharT, class _Traits, class _Allocator> 4500inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 4501basic_string<_CharT, _Traits, _Allocator> 4502operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const _CharT* __rhs) 4503{ 4504 return std::move(__lhs.append(__rhs)); 4505} 4506 4507template<class _CharT, class _Traits, class _Allocator> 4508inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 4509basic_string<_CharT, _Traits, _Allocator> 4510operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT __rhs) 4511{ 4512 __lhs.push_back(__rhs); 4513 return std::move(__lhs); 4514} 4515 4516#endif // _LIBCPP_CXX03_LANG 4517 4518// swap 4519 4520template<class _CharT, class _Traits, class _Allocator> 4521inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 4522void 4523swap(basic_string<_CharT, _Traits, _Allocator>& __lhs, 4524 basic_string<_CharT, _Traits, _Allocator>& __rhs) 4525 _NOEXCEPT_(_NOEXCEPT_(__lhs.swap(__rhs))) 4526{ 4527 __lhs.swap(__rhs); 4528} 4529 4530_LIBCPP_FUNC_VIS int stoi (const string& __str, size_t* __idx = nullptr, int __base = 10); 4531_LIBCPP_FUNC_VIS long stol (const string& __str, size_t* __idx = nullptr, int __base = 10); 4532_LIBCPP_FUNC_VIS unsigned long stoul (const string& __str, size_t* __idx = nullptr, int __base = 10); 4533_LIBCPP_FUNC_VIS long long stoll (const string& __str, size_t* __idx = nullptr, int __base = 10); 4534_LIBCPP_FUNC_VIS unsigned long long stoull(const string& __str, size_t* __idx = nullptr, int __base = 10); 4535 4536_LIBCPP_FUNC_VIS float stof (const string& __str, size_t* __idx = nullptr); 4537_LIBCPP_FUNC_VIS double stod (const string& __str, size_t* __idx = nullptr); 4538_LIBCPP_FUNC_VIS long double stold(const string& __str, size_t* __idx = nullptr); 4539 4540_LIBCPP_FUNC_VIS string to_string(int __val); 4541_LIBCPP_FUNC_VIS string to_string(unsigned __val); 4542_LIBCPP_FUNC_VIS string to_string(long __val); 4543_LIBCPP_FUNC_VIS string to_string(unsigned long __val); 4544_LIBCPP_FUNC_VIS string to_string(long long __val); 4545_LIBCPP_FUNC_VIS string to_string(unsigned long long __val); 4546_LIBCPP_FUNC_VIS string to_string(float __val); 4547_LIBCPP_FUNC_VIS string to_string(double __val); 4548_LIBCPP_FUNC_VIS string to_string(long double __val); 4549 4550#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 4551_LIBCPP_FUNC_VIS int stoi (const wstring& __str, size_t* __idx = nullptr, int __base = 10); 4552_LIBCPP_FUNC_VIS long stol (const wstring& __str, size_t* __idx = nullptr, int __base = 10); 4553_LIBCPP_FUNC_VIS unsigned long stoul (const wstring& __str, size_t* __idx = nullptr, int __base = 10); 4554_LIBCPP_FUNC_VIS long long stoll (const wstring& __str, size_t* __idx = nullptr, int __base = 10); 4555_LIBCPP_FUNC_VIS unsigned long long stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10); 4556 4557_LIBCPP_FUNC_VIS float stof (const wstring& __str, size_t* __idx = nullptr); 4558_LIBCPP_FUNC_VIS double stod (const wstring& __str, size_t* __idx = nullptr); 4559_LIBCPP_FUNC_VIS long double stold(const wstring& __str, size_t* __idx = nullptr); 4560 4561_LIBCPP_FUNC_VIS wstring to_wstring(int __val); 4562_LIBCPP_FUNC_VIS wstring to_wstring(unsigned __val); 4563_LIBCPP_FUNC_VIS wstring to_wstring(long __val); 4564_LIBCPP_FUNC_VIS wstring to_wstring(unsigned long __val); 4565_LIBCPP_FUNC_VIS wstring to_wstring(long long __val); 4566_LIBCPP_FUNC_VIS wstring to_wstring(unsigned long long __val); 4567_LIBCPP_FUNC_VIS wstring to_wstring(float __val); 4568_LIBCPP_FUNC_VIS wstring to_wstring(double __val); 4569_LIBCPP_FUNC_VIS wstring to_wstring(long double __val); 4570#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS 4571 4572template<class _CharT, class _Traits, class _Allocator> 4573_LIBCPP_TEMPLATE_DATA_VIS 4574const typename basic_string<_CharT, _Traits, _Allocator>::size_type 4575 basic_string<_CharT, _Traits, _Allocator>::npos; 4576 4577template <class _CharT, class _Allocator> 4578struct _LIBCPP_TEMPLATE_VIS 4579 hash<basic_string<_CharT, char_traits<_CharT>, _Allocator> > 4580 : public unary_function< 4581 basic_string<_CharT, char_traits<_CharT>, _Allocator>, size_t> 4582{ 4583 size_t 4584 operator()(const basic_string<_CharT, char_traits<_CharT>, _Allocator>& __val) const _NOEXCEPT 4585 { return __do_string_hash(__val.data(), __val.data() + __val.size()); } 4586}; 4587 4588 4589template<class _CharT, class _Traits, class _Allocator> 4590basic_ostream<_CharT, _Traits>& 4591operator<<(basic_ostream<_CharT, _Traits>& __os, 4592 const basic_string<_CharT, _Traits, _Allocator>& __str); 4593 4594template<class _CharT, class _Traits, class _Allocator> 4595basic_istream<_CharT, _Traits>& 4596operator>>(basic_istream<_CharT, _Traits>& __is, 4597 basic_string<_CharT, _Traits, _Allocator>& __str); 4598 4599template<class _CharT, class _Traits, class _Allocator> 4600basic_istream<_CharT, _Traits>& 4601getline(basic_istream<_CharT, _Traits>& __is, 4602 basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm); 4603 4604template<class _CharT, class _Traits, class _Allocator> 4605inline _LIBCPP_HIDE_FROM_ABI 4606basic_istream<_CharT, _Traits>& 4607getline(basic_istream<_CharT, _Traits>& __is, 4608 basic_string<_CharT, _Traits, _Allocator>& __str); 4609 4610template<class _CharT, class _Traits, class _Allocator> 4611inline _LIBCPP_HIDE_FROM_ABI 4612basic_istream<_CharT, _Traits>& 4613getline(basic_istream<_CharT, _Traits>&& __is, 4614 basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm); 4615 4616template<class _CharT, class _Traits, class _Allocator> 4617inline _LIBCPP_HIDE_FROM_ABI 4618basic_istream<_CharT, _Traits>& 4619getline(basic_istream<_CharT, _Traits>&& __is, 4620 basic_string<_CharT, _Traits, _Allocator>& __str); 4621 4622#if _LIBCPP_STD_VER > 17 4623template <class _CharT, class _Traits, class _Allocator, class _Up> 4624inline _LIBCPP_HIDE_FROM_ABI 4625 typename basic_string<_CharT, _Traits, _Allocator>::size_type 4626 erase(basic_string<_CharT, _Traits, _Allocator>& __str, const _Up& __v) { 4627 auto __old_size = __str.size(); 4628 __str.erase(std::remove(__str.begin(), __str.end(), __v), __str.end()); 4629 return __old_size - __str.size(); 4630} 4631 4632template <class _CharT, class _Traits, class _Allocator, class _Predicate> 4633inline _LIBCPP_HIDE_FROM_ABI 4634 typename basic_string<_CharT, _Traits, _Allocator>::size_type 4635 erase_if(basic_string<_CharT, _Traits, _Allocator>& __str, 4636 _Predicate __pred) { 4637 auto __old_size = __str.size(); 4638 __str.erase(std::remove_if(__str.begin(), __str.end(), __pred), 4639 __str.end()); 4640 return __old_size - __str.size(); 4641} 4642#endif 4643 4644#if _LIBCPP_DEBUG_LEVEL == 2 4645 4646template<class _CharT, class _Traits, class _Allocator> 4647bool 4648basic_string<_CharT, _Traits, _Allocator>::__dereferenceable(const const_iterator* __i) const 4649{ 4650 return data() <= std::__to_address(__i->base()) && 4651 std::__to_address(__i->base()) < data() + size(); 4652} 4653 4654template<class _CharT, class _Traits, class _Allocator> 4655bool 4656basic_string<_CharT, _Traits, _Allocator>::__decrementable(const const_iterator* __i) const 4657{ 4658 return data() < std::__to_address(__i->base()) && 4659 std::__to_address(__i->base()) <= data() + size(); 4660} 4661 4662template<class _CharT, class _Traits, class _Allocator> 4663bool 4664basic_string<_CharT, _Traits, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const 4665{ 4666 const value_type* __p = std::__to_address(__i->base()) + __n; 4667 return data() <= __p && __p <= data() + size(); 4668} 4669 4670template<class _CharT, class _Traits, class _Allocator> 4671bool 4672basic_string<_CharT, _Traits, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const 4673{ 4674 const value_type* __p = std::__to_address(__i->base()) + __n; 4675 return data() <= __p && __p < data() + size(); 4676} 4677 4678#endif // _LIBCPP_DEBUG_LEVEL == 2 4679 4680#if _LIBCPP_STD_VER > 11 4681// Literal suffixes for basic_string [basic.string.literals] 4682inline namespace literals 4683{ 4684 inline namespace string_literals 4685 { 4686 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 4687 basic_string<char> operator "" s( const char *__str, size_t __len ) 4688 { 4689 return basic_string<char> (__str, __len); 4690 } 4691 4692#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 4693 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 4694 basic_string<wchar_t> operator "" s( const wchar_t *__str, size_t __len ) 4695 { 4696 return basic_string<wchar_t> (__str, __len); 4697 } 4698#endif 4699 4700#ifndef _LIBCPP_HAS_NO_CHAR8_T 4701 inline _LIBCPP_HIDE_FROM_ABI constexpr 4702 basic_string<char8_t> operator "" s(const char8_t *__str, size_t __len) _NOEXCEPT 4703 { 4704 return basic_string<char8_t> (__str, __len); 4705 } 4706#endif 4707 4708 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 4709 basic_string<char16_t> operator "" s( const char16_t *__str, size_t __len ) 4710 { 4711 return basic_string<char16_t> (__str, __len); 4712 } 4713 4714 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 4715 basic_string<char32_t> operator "" s( const char32_t *__str, size_t __len ) 4716 { 4717 return basic_string<char32_t> (__str, __len); 4718 } 4719 } // namespace string_literals 4720} // namespace literals 4721 4722#if _LIBCPP_STD_VER > 17 4723template <> 4724inline constexpr bool __format::__enable_insertable<std::basic_string<char>> = true; 4725#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 4726template <> 4727inline constexpr bool __format::__enable_insertable<std::basic_string<wchar_t>> = true; 4728#endif 4729#endif 4730 4731#endif 4732 4733_LIBCPP_END_NAMESPACE_STD 4734 4735_LIBCPP_POP_MACROS 4736 4737#endif // _LIBCPP_STRING 4738