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___CXX03_STRING 11#define _LIBCPP___CXX03_STRING 12 13// clang-format off 14 15/* 16 string synopsis 17 18#include <__cxx03/compare> 19#include <__cxx03/initializer_list> 20 21namespace std 22{ 23 24template <class stateT> 25class fpos 26{ 27private: 28 stateT st; 29public: 30 fpos(streamoff = streamoff()); 31 32 operator streamoff() const; 33 34 stateT state() const; 35 void state(stateT); 36 37 fpos& operator+=(streamoff); 38 fpos operator+ (streamoff) const; 39 fpos& operator-=(streamoff); 40 fpos operator- (streamoff) const; 41}; 42 43template <class stateT> streamoff operator-(const fpos<stateT>& x, const fpos<stateT>& y); 44 45template <class stateT> bool operator==(const fpos<stateT>& x, const fpos<stateT>& y); 46template <class stateT> bool operator!=(const fpos<stateT>& x, const fpos<stateT>& y); 47 48template <class charT> 49struct char_traits 50{ 51 using char_type = charT; 52 using int_type = ...; 53 using off_type = streamoff; 54 using pos_type = streampos; 55 using state_type = mbstate_t; 56 using comparison_category = strong_ordering; // Since C++20 only for the specializations 57 // char, wchar_t, char8_t, char16_t, and char32_t. 58 59 static void assign(char_type& c1, const char_type& c2) noexcept; 60 static constexpr bool eq(char_type c1, char_type c2) noexcept; 61 static constexpr bool lt(char_type c1, char_type c2) noexcept; 62 63 static int compare(const char_type* s1, const char_type* s2, size_t n); 64 static size_t length(const char_type* s); 65 static const char_type* find(const char_type* s, size_t n, const char_type& a); 66 static char_type* move(char_type* s1, const char_type* s2, size_t n); 67 static char_type* copy(char_type* s1, const char_type* s2, size_t n); 68 static char_type* assign(char_type* s, size_t n, char_type a); 69 70 static constexpr int_type not_eof(int_type c) noexcept; 71 static constexpr char_type to_char_type(int_type c) noexcept; 72 static constexpr int_type to_int_type(char_type c) noexcept; 73 static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept; 74 static constexpr int_type eof() noexcept; 75}; 76 77template <> struct char_traits<char>; 78template <> struct char_traits<wchar_t>; 79template <> struct char_traits<char8_t>; // C++20 80template <> struct char_traits<char16_t>; 81template <> struct char_traits<char32_t>; 82 83template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> > 84class basic_string 85{ 86public: 87// types: 88 typedef traits traits_type; 89 typedef typename traits_type::char_type value_type; 90 typedef Allocator allocator_type; 91 typedef typename allocator_type::size_type size_type; 92 typedef typename allocator_type::difference_type difference_type; 93 typedef typename allocator_type::reference reference; 94 typedef typename allocator_type::const_reference const_reference; 95 typedef typename allocator_type::pointer pointer; 96 typedef typename allocator_type::const_pointer const_pointer; 97 typedef implementation-defined iterator; 98 typedef implementation-defined const_iterator; 99 typedef std::reverse_iterator<iterator> reverse_iterator; 100 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 101 102 static const size_type npos = -1; 103 104 basic_string() 105 noexcept(is_nothrow_default_constructible<allocator_type>::value); // constexpr since C++20 106 explicit basic_string(const allocator_type& a); // constexpr since C++20 107 basic_string(const basic_string& str); // constexpr since C++20 108 basic_string(basic_string&& str) 109 noexcept(is_nothrow_move_constructible<allocator_type>::value); // constexpr since C++20 110 basic_string(const basic_string& str, size_type pos, 111 const allocator_type& a = allocator_type()); // constexpr since C++20 112 basic_string(const basic_string& str, size_type pos, size_type n, 113 const Allocator& a = Allocator()); // constexpr since C++20 114 constexpr basic_string( 115 basic_string&& str, size_type pos, const Allocator& a = Allocator()); // since C++23 116 constexpr basic_string( 117 basic_string&& str, size_type pos, size_type n, const Allocator& a = Allocator()); // since C++23 118 template<class T> 119 basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator()); // C++17, constexpr since C++20 120 template <class T> 121 explicit basic_string(const T& t, const Allocator& a = Allocator()); // C++17, constexpr since C++20 122 basic_string(const value_type* s, const allocator_type& a = allocator_type()); // constexpr since C++20 123 basic_string(const value_type* s, size_type n, const allocator_type& a = allocator_type()); // constexpr since C++20 124 basic_string(nullptr_t) = delete; // C++23 125 basic_string(size_type n, value_type c, const allocator_type& a = allocator_type()); // constexpr since C++20 126 template<class InputIterator> 127 basic_string(InputIterator begin, InputIterator end, 128 const allocator_type& a = allocator_type()); // constexpr since C++20 129 template<container-compatible-range<charT> R> 130 constexpr basic_string(from_range_t, R&& rg, const Allocator& a = Allocator()); // since C++23 131 basic_string(initializer_list<value_type>, const Allocator& = Allocator()); // constexpr since C++20 132 basic_string(const basic_string&, const Allocator&); // constexpr since C++20 133 basic_string(basic_string&&, const Allocator&); // constexpr since C++20 134 135 ~basic_string(); // constexpr since C++20 136 137 operator basic_string_view<charT, traits>() const noexcept; // constexpr since C++20 138 139 basic_string& operator=(const basic_string& str); // constexpr since C++20 140 template <class T> 141 basic_string& operator=(const T& t); // C++17, constexpr since C++20 142 basic_string& operator=(basic_string&& str) 143 noexcept( 144 allocator_type::propagate_on_container_move_assignment::value || 145 allocator_type::is_always_equal::value ); // C++17, constexpr since C++20 146 basic_string& operator=(const value_type* s); // constexpr since C++20 147 basic_string& operator=(nullptr_t) = delete; // C++23 148 basic_string& operator=(value_type c); // constexpr since C++20 149 basic_string& operator=(initializer_list<value_type>); // constexpr since C++20 150 151 iterator begin() noexcept; // constexpr since C++20 152 const_iterator begin() const noexcept; // constexpr since C++20 153 iterator end() noexcept; // constexpr since C++20 154 const_iterator end() const noexcept; // constexpr since C++20 155 156 reverse_iterator rbegin() noexcept; // constexpr since C++20 157 const_reverse_iterator rbegin() const noexcept; // constexpr since C++20 158 reverse_iterator rend() noexcept; // constexpr since C++20 159 const_reverse_iterator rend() const noexcept; // constexpr since C++20 160 161 const_iterator cbegin() const noexcept; // constexpr since C++20 162 const_iterator cend() const noexcept; // constexpr since C++20 163 const_reverse_iterator crbegin() const noexcept; // constexpr since C++20 164 const_reverse_iterator crend() const noexcept; // constexpr since C++20 165 166 size_type size() const noexcept; // constexpr since C++20 167 size_type length() const noexcept; // constexpr since C++20 168 size_type max_size() const noexcept; // constexpr since C++20 169 size_type capacity() const noexcept; // constexpr since C++20 170 171 void resize(size_type n, value_type c); // constexpr since C++20 172 void resize(size_type n); // constexpr since C++20 173 174 template<class Operation> 175 constexpr void resize_and_overwrite(size_type n, Operation op); // since C++23 176 177 void reserve(size_type res_arg); // constexpr since C++20 178 void reserve(); // deprecated in C++20, removed in C++26 179 void shrink_to_fit(); // constexpr since C++20 180 void clear() noexcept; // constexpr since C++20 181 bool empty() const noexcept; // constexpr since C++20 182 183 const_reference operator[](size_type pos) const; // constexpr since C++20 184 reference operator[](size_type pos); // constexpr since C++20 185 186 const_reference at(size_type n) const; // constexpr since C++20 187 reference at(size_type n); // constexpr since C++20 188 189 basic_string& operator+=(const basic_string& str); // constexpr since C++20 190 template <class T> 191 basic_string& operator+=(const T& t); // C++17, constexpr since C++20 192 basic_string& operator+=(const value_type* s); // constexpr since C++20 193 basic_string& operator+=(value_type c); // constexpr since C++20 194 basic_string& operator+=(initializer_list<value_type>); // constexpr since C++20 195 196 basic_string& append(const basic_string& str); // constexpr since C++20 197 template <class T> 198 basic_string& append(const T& t); // C++17, constexpr since C++20 199 basic_string& append(const basic_string& str, size_type pos, size_type n=npos); // C++14, constexpr since C++20 200 template <class T> 201 basic_string& append(const T& t, size_type pos, size_type n=npos); // C++17, constexpr since C++20 202 basic_string& append(const value_type* s, size_type n); // constexpr since C++20 203 basic_string& append(const value_type* s); // constexpr since C++20 204 basic_string& append(size_type n, value_type c); // constexpr since C++20 205 template<class InputIterator> 206 basic_string& append(InputIterator first, InputIterator last); // constexpr since C++20 207 template<container-compatible-range<charT> R> 208 constexpr basic_string& append_range(R&& rg); // C++23 209 basic_string& append(initializer_list<value_type>); // constexpr since C++20 210 211 void push_back(value_type c); // constexpr since C++20 212 void pop_back(); // constexpr since C++20 213 reference front(); // constexpr since C++20 214 const_reference front() const; // constexpr since C++20 215 reference back(); // constexpr since C++20 216 const_reference back() const; // constexpr since C++20 217 218 basic_string& assign(const basic_string& str); // constexpr since C++20 219 template <class T> 220 basic_string& assign(const T& t); // C++17, constexpr since C++20 221 basic_string& assign(basic_string&& str); // constexpr since C++20 222 basic_string& assign(const basic_string& str, size_type pos, size_type n=npos); // C++14, constexpr since C++20 223 template <class T> 224 basic_string& assign(const T& t, size_type pos, size_type n=npos); // C++17, constexpr since C++20 225 basic_string& assign(const value_type* s, size_type n); // constexpr since C++20 226 basic_string& assign(const value_type* s); // constexpr since C++20 227 basic_string& assign(size_type n, value_type c); // constexpr since C++20 228 template<class InputIterator> 229 basic_string& assign(InputIterator first, InputIterator last); // constexpr since C++20 230 template<container-compatible-range<charT> R> 231 constexpr basic_string& assign_range(R&& rg); // C++23 232 basic_string& assign(initializer_list<value_type>); // constexpr since C++20 233 234 basic_string& insert(size_type pos1, const basic_string& str); // constexpr since C++20 235 template <class T> 236 basic_string& insert(size_type pos1, const T& t); // constexpr since C++20 237 basic_string& insert(size_type pos1, const basic_string& str, 238 size_type pos2, size_type n); // constexpr since C++20 239 template <class T> 240 basic_string& insert(size_type pos1, const T& t, size_type pos2, size_type n); // C++17, constexpr since C++20 241 basic_string& insert(size_type pos, const value_type* s, size_type n=npos); // C++14, constexpr since C++20 242 basic_string& insert(size_type pos, const value_type* s); // constexpr since C++20 243 basic_string& insert(size_type pos, size_type n, value_type c); // constexpr since C++20 244 iterator insert(const_iterator p, value_type c); // constexpr since C++20 245 iterator insert(const_iterator p, size_type n, value_type c); // constexpr since C++20 246 template<class InputIterator> 247 iterator insert(const_iterator p, InputIterator first, InputIterator last); // constexpr since C++20 248 template<container-compatible-range<charT> R> 249 constexpr iterator insert_range(const_iterator p, R&& rg); // C++23 250 iterator insert(const_iterator p, initializer_list<value_type>); // constexpr since C++20 251 252 basic_string& erase(size_type pos = 0, size_type n = npos); // constexpr since C++20 253 iterator erase(const_iterator position); // constexpr since C++20 254 iterator erase(const_iterator first, const_iterator last); // constexpr since C++20 255 256 basic_string& replace(size_type pos1, size_type n1, const basic_string& str); // constexpr since C++20 257 template <class T> 258 basic_string& replace(size_type pos1, size_type n1, const T& t); // C++17, constexpr since C++20 259 basic_string& replace(size_type pos1, size_type n1, const basic_string& str, 260 size_type pos2, size_type n2=npos); // C++14, constexpr since C++20 261 template <class T> 262 basic_string& replace(size_type pos1, size_type n1, const T& t, 263 size_type pos2, size_type n); // C++17, constexpr since C++20 264 basic_string& replace(size_type pos, size_type n1, const value_type* s, size_type n2); // constexpr since C++20 265 basic_string& replace(size_type pos, size_type n1, const value_type* s); // constexpr since C++20 266 basic_string& replace(size_type pos, size_type n1, size_type n2, value_type c); // constexpr since C++20 267 basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str); // constexpr since C++20 268 template <class T> 269 basic_string& replace(const_iterator i1, const_iterator i2, const T& t); // C++17, constexpr since C++20 270 basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s, size_type n); // constexpr since C++20 271 basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s); // constexpr since C++20 272 basic_string& replace(const_iterator i1, const_iterator i2, size_type n, value_type c); // constexpr since C++20 273 template<class InputIterator> 274 basic_string& replace(const_iterator i1, const_iterator i2, InputIterator j1, InputIterator j2); // constexpr since C++20 275 template<container-compatible-range<charT> R> 276 constexpr basic_string& replace_with_range(const_iterator i1, const_iterator i2, R&& rg); // C++23 277 basic_string& replace(const_iterator i1, const_iterator i2, initializer_list<value_type>); // constexpr since C++20 278 279 size_type copy(value_type* s, size_type n, size_type pos = 0) const; // constexpr since C++20 280 basic_string substr(size_type pos = 0, size_type n = npos) const; // constexpr in C++20, removed in C++23 281 basic_string substr(size_type pos = 0, size_type n = npos) const&; // since C++23 282 constexpr basic_string substr(size_type pos = 0, size_type n = npos) &&; // since C++23 283 void swap(basic_string& str) 284 noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value || 285 allocator_traits<allocator_type>::is_always_equal::value); // C++17, constexpr since C++20 286 287 const value_type* c_str() const noexcept; // constexpr since C++20 288 const value_type* data() const noexcept; // constexpr since C++20 289 value_type* data() noexcept; // C++17, constexpr since C++20 290 291 allocator_type get_allocator() const noexcept; // constexpr since C++20 292 293 size_type find(const basic_string& str, size_type pos = 0) const noexcept; // constexpr since C++20 294 template <class T> 295 size_type find(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension, constexpr since C++20 296 size_type find(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20 297 size_type find(const value_type* s, size_type pos = 0) const noexcept; // constexpr since C++20 298 size_type find(value_type c, size_type pos = 0) const noexcept; // constexpr since C++20 299 300 size_type rfind(const basic_string& str, size_type pos = npos) const noexcept; // constexpr since C++20 301 template <class T> 302 size_type rfind(const T& t, size_type pos = npos) const noexcept; // C++17, noexcept as an extension, constexpr since C++20 303 size_type rfind(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20 304 size_type rfind(const value_type* s, size_type pos = npos) const noexcept; // constexpr since C++20 305 size_type rfind(value_type c, size_type pos = npos) const noexcept; // constexpr since C++20 306 307 size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept; // constexpr since C++20 308 template <class T> 309 size_type find_first_of(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension, constexpr since C++20 310 size_type find_first_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20 311 size_type find_first_of(const value_type* s, size_type pos = 0) const noexcept; // constexpr since C++20 312 size_type find_first_of(value_type c, size_type pos = 0) const noexcept; // constexpr since C++20 313 314 size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept; // constexpr since C++20 315 template <class T> 316 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 317 size_type find_last_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20 318 size_type find_last_of(const value_type* s, size_type pos = npos) const noexcept; // constexpr since C++20 319 size_type find_last_of(value_type c, size_type pos = npos) const noexcept; // constexpr since C++20 320 321 size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept; // constexpr since C++20 322 template <class T> 323 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 324 size_type find_first_not_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20 325 size_type find_first_not_of(const value_type* s, size_type pos = 0) const noexcept; // constexpr since C++20 326 size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept; // constexpr since C++20 327 328 size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept; // constexpr since C++20 329 template <class T> 330 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 331 size_type find_last_not_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20 332 size_type find_last_not_of(const value_type* s, size_type pos = npos) const noexcept; // constexpr since C++20 333 size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept; // constexpr since C++20 334 335 int compare(const basic_string& str) const noexcept; // constexpr since C++20 336 template <class T> 337 int compare(const T& t) const noexcept; // C++17, noexcept as an extension, constexpr since C++20 338 int compare(size_type pos1, size_type n1, const basic_string& str) const; // constexpr since C++20 339 template <class T> 340 int compare(size_type pos1, size_type n1, const T& t) const; // C++17, constexpr since C++20 341 int compare(size_type pos1, size_type n1, const basic_string& str, 342 size_type pos2, size_type n2=npos) const; // C++14, constexpr since C++20 343 template <class T> 344 int compare(size_type pos1, size_type n1, const T& t, 345 size_type pos2, size_type n2=npos) const; // C++17, constexpr since C++20 346 int compare(const value_type* s) const noexcept; // constexpr since C++20 347 int compare(size_type pos1, size_type n1, const value_type* s) const; // constexpr since C++20 348 int compare(size_type pos1, size_type n1, const value_type* s, size_type n2) const; // constexpr since C++20 349 350 constexpr bool starts_with(basic_string_view<charT, traits> sv) const noexcept; // C++20 351 constexpr bool starts_with(charT c) const noexcept; // C++20 352 constexpr bool starts_with(const charT* s) const; // C++20 353 constexpr bool ends_with(basic_string_view<charT, traits> sv) const noexcept; // C++20 354 constexpr bool ends_with(charT c) const noexcept; // C++20 355 constexpr bool ends_with(const charT* s) const; // C++20 356 357 constexpr bool contains(basic_string_view<charT, traits> sv) const noexcept; // C++23 358 constexpr bool contains(charT c) const noexcept; // C++23 359 constexpr bool contains(const charT* s) const; // C++23 360}; 361 362template<class InputIterator, 363 class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>> 364basic_string(InputIterator, InputIterator, Allocator = Allocator()) 365 -> basic_string<typename iterator_traits<InputIterator>::value_type, 366 char_traits<typename iterator_traits<InputIterator>::value_type>, 367 Allocator>; // C++17 368 369template<ranges::input_range R, 370 class Allocator = allocator<ranges::range_value_t<R>>> 371 basic_string(from_range_t, R&&, Allocator = Allocator()) 372 -> basic_string<ranges::range_value_t<R>, char_traits<ranges::range_value_t<R>>, 373 Allocator>; // C++23 374 375template<class charT, 376 class traits, 377 class Allocator = allocator<charT>> 378 explicit basic_string(basic_string_view<charT, traits>, const Allocator& = Allocator()) 379 -> basic_string<charT, traits, Allocator>; // C++17 380 381template<class charT, 382 class traits, 383 class Allocator = allocator<charT>> 384 basic_string(basic_string_view<charT, traits>, 385 typename see below::size_type, typename see below::size_type, 386 const Allocator& = Allocator()) 387 -> basic_string<charT, traits, Allocator>; // C++17 388 389template<class charT, class traits, class Allocator> 390basic_string<charT, traits, Allocator> 391operator+(const basic_string<charT, traits, Allocator>& lhs, 392 const basic_string<charT, traits, Allocator>& rhs); // constexpr since C++20 393 394template<class charT, class traits, class Allocator> 395basic_string<charT, traits, Allocator> 396operator+(const charT* lhs , const basic_string<charT,traits,Allocator>&rhs); // constexpr since C++20 397 398template<class charT, class traits, class Allocator> 399basic_string<charT, traits, Allocator> 400operator+(charT lhs, const basic_string<charT,traits,Allocator>& rhs); // constexpr since C++20 401 402template<class charT, class traits, class Allocator> 403basic_string<charT, traits, Allocator> 404operator+(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs); // constexpr since C++20 405 406template<class charT, class traits, class Allocator> 407basic_string<charT, traits, Allocator> 408operator+(const basic_string<charT, traits, Allocator>& lhs, charT rhs); // constexpr since C++20 409 410template<class charT, class traits, class Allocator> 411 constexpr basic_string<charT, traits, Allocator> 412 operator+(const basic_string<charT, traits, Allocator>& lhs, 413 type_identity_t<basic_string_view<charT, traits>> rhs); // Since C++26 414template<class charT, class traits, class Allocator> 415 constexpr basic_string<charT, traits, Allocator> 416 operator+(basic_string<charT, traits, Allocator>&& lhs, 417 type_identity_t<basic_string_view<charT, traits>> rhs); // Since C++26 418template<class charT, class traits, class Allocator> 419 constexpr basic_string<charT, traits, Allocator> 420 operator+(type_identity_t<basic_string_view<charT, traits>> lhs, 421 const basic_string<charT, traits, Allocator>& rhs); // Since C++26 422template<class charT, class traits, class Allocator> 423 constexpr basic_string<charT, traits, Allocator> 424 operator+(type_identity_t<basic_string_view<charT, traits>> lhs, 425 basic_string<charT, traits, Allocator>&& rhs); // Since C++26 426 427 428template<class charT, class traits, class Allocator> 429bool operator==(const basic_string<charT, traits, Allocator>& lhs, 430 const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20 431 432template<class charT, class traits, class Allocator> 433bool operator==(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 434 435template<class charT, class traits, class Allocator> 436bool operator==(const basic_string<charT,traits,Allocator>& lhs, const charT* rhs) noexcept; // constexpr since C++20 437 438template<class charT, class traits, class Allocator> 439bool operator!=(const basic_string<charT,traits,Allocator>& lhs, 440 const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 441 442template<class charT, class traits, class Allocator> 443bool operator!=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 444 445template<class charT, class traits, class Allocator> 446bool operator!=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // removed in C++20 447 448template<class charT, class traits, class Allocator> 449bool operator< (const basic_string<charT, traits, Allocator>& lhs, 450 const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 451 452template<class charT, class traits, class Allocator> 453bool operator< (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // removed in C++20 454 455template<class charT, class traits, class Allocator> 456bool operator< (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 457 458template<class charT, class traits, class Allocator> 459bool operator> (const basic_string<charT, traits, Allocator>& lhs, 460 const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 461 462template<class charT, class traits, class Allocator> 463bool operator> (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // removed in C++20 464 465template<class charT, class traits, class Allocator> 466bool operator> (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 467 468template<class charT, class traits, class Allocator> 469bool operator<=(const basic_string<charT, traits, Allocator>& lhs, 470 const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 471 472template<class charT, class traits, class Allocator> 473bool operator<=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // removed in C++20 474 475template<class charT, class traits, class Allocator> 476bool operator<=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 477 478template<class charT, class traits, class Allocator> 479bool operator>=(const basic_string<charT, traits, Allocator>& lhs, 480 const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 481 482template<class charT, class traits, class Allocator> 483bool operator>=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // removed in C++20 484 485template<class charT, class traits, class Allocator> 486bool operator>=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 487 488template<class charT, class traits, class Allocator> // since C++20 489constexpr see below operator<=>(const basic_string<charT, traits, Allocator>& lhs, 490 const basic_string<charT, traits, Allocator>& rhs) noexcept; 491 492template<class charT, class traits, class Allocator> // since C++20 493constexpr see below operator<=>(const basic_string<charT, traits, Allocator>& lhs, 494 const charT* rhs) noexcept; 495 496template<class charT, class traits, class Allocator> 497void swap(basic_string<charT, traits, Allocator>& lhs, 498 basic_string<charT, traits, Allocator>& rhs) 499 noexcept(noexcept(lhs.swap(rhs))); // constexpr since C++20 500 501template<class charT, class traits, class Allocator> 502basic_istream<charT, traits>& 503operator>>(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str); 504 505template<class charT, class traits, class Allocator> 506basic_ostream<charT, traits>& 507operator<<(basic_ostream<charT, traits>& os, const basic_string<charT, traits, Allocator>& str); 508 509template<class charT, class traits, class Allocator> 510basic_istream<charT, traits>& 511getline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str, 512 charT delim); 513 514template<class charT, class traits, class Allocator> 515basic_istream<charT, traits>& 516getline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str); 517 518template<class charT, class traits, class Allocator, class U> 519typename basic_string<charT, traits, Allocator>::size_type 520erase(basic_string<charT, traits, Allocator>& c, const U& value); // C++20 521template<class charT, class traits, class Allocator, class Predicate> 522typename basic_string<charT, traits, Allocator>::size_type 523erase_if(basic_string<charT, traits, Allocator>& c, Predicate pred); // C++20 524 525typedef basic_string<char> string; 526typedef basic_string<wchar_t> wstring; 527typedef basic_string<char8_t> u8string; // C++20 528typedef basic_string<char16_t> u16string; 529typedef basic_string<char32_t> u32string; 530 531int stoi (const string& str, size_t* idx = nullptr, int base = 10); 532long stol (const string& str, size_t* idx = nullptr, int base = 10); 533unsigned long stoul (const string& str, size_t* idx = nullptr, int base = 10); 534long long stoll (const string& str, size_t* idx = nullptr, int base = 10); 535unsigned long long stoull(const string& str, size_t* idx = nullptr, int base = 10); 536 537float stof (const string& str, size_t* idx = nullptr); 538double stod (const string& str, size_t* idx = nullptr); 539long double stold(const string& str, size_t* idx = nullptr); 540 541string to_string(int val); 542string to_string(unsigned val); 543string to_string(long val); 544string to_string(unsigned long val); 545string to_string(long long val); 546string to_string(unsigned long long val); 547string to_string(float val); 548string to_string(double val); 549string to_string(long double val); 550 551int stoi (const wstring& str, size_t* idx = nullptr, int base = 10); 552long stol (const wstring& str, size_t* idx = nullptr, int base = 10); 553unsigned long stoul (const wstring& str, size_t* idx = nullptr, int base = 10); 554long long stoll (const wstring& str, size_t* idx = nullptr, int base = 10); 555unsigned long long stoull(const wstring& str, size_t* idx = nullptr, int base = 10); 556 557float stof (const wstring& str, size_t* idx = nullptr); 558double stod (const wstring& str, size_t* idx = nullptr); 559long double stold(const wstring& str, size_t* idx = nullptr); 560 561wstring to_wstring(int val); 562wstring to_wstring(unsigned val); 563wstring to_wstring(long val); 564wstring to_wstring(unsigned long val); 565wstring to_wstring(long long val); 566wstring to_wstring(unsigned long long val); 567wstring to_wstring(float val); 568wstring to_wstring(double val); 569wstring to_wstring(long double val); 570 571template <> struct hash<string>; 572template <> struct hash<u8string>; // C++20 573template <> struct hash<u16string>; 574template <> struct hash<u32string>; 575template <> struct hash<wstring>; 576 577basic_string<char> operator""s( const char *str, size_t len ); // C++14, constexpr since C++20 578basic_string<wchar_t> operator""s( const wchar_t *str, size_t len ); // C++14, constexpr since C++20 579constexpr basic_string<char8_t> operator""s( const char8_t *str, size_t len ); // C++20 580basic_string<char16_t> operator""s( const char16_t *str, size_t len ); // C++14, constexpr since C++20 581basic_string<char32_t> operator""s( const char32_t *str, size_t len ); // C++14, constexpr since C++20 582 583} // std 584 585*/ 586 587// clang-format on 588 589#include <__cxx03/__algorithm/max.h> 590#include <__cxx03/__algorithm/min.h> 591#include <__cxx03/__algorithm/remove.h> 592#include <__cxx03/__algorithm/remove_if.h> 593#include <__cxx03/__assert> 594#include <__cxx03/__config> 595#include <__cxx03/__debug_utils/sanitizers.h> 596#include <__cxx03/__functional/hash.h> 597#include <__cxx03/__functional/unary_function.h> 598#include <__cxx03/__fwd/string.h> 599#include <__cxx03/__ios/fpos.h> 600#include <__cxx03/__iterator/bounded_iter.h> 601#include <__cxx03/__iterator/distance.h> 602#include <__cxx03/__iterator/iterator_traits.h> 603#include <__cxx03/__iterator/reverse_iterator.h> 604#include <__cxx03/__iterator/wrap_iter.h> 605#include <__cxx03/__memory/addressof.h> 606#include <__cxx03/__memory/allocate_at_least.h> 607#include <__cxx03/__memory/allocator.h> 608#include <__cxx03/__memory/allocator_traits.h> 609#include <__cxx03/__memory/compressed_pair.h> 610#include <__cxx03/__memory/construct_at.h> 611#include <__cxx03/__memory/pointer_traits.h> 612#include <__cxx03/__memory/swap_allocator.h> 613#include <__cxx03/__string/char_traits.h> 614#include <__cxx03/__string/extern_template_lists.h> 615#include <__cxx03/__type_traits/conditional.h> 616#include <__cxx03/__type_traits/is_allocator.h> 617#include <__cxx03/__type_traits/is_array.h> 618#include <__cxx03/__type_traits/is_convertible.h> 619#include <__cxx03/__type_traits/is_nothrow_assignable.h> 620#include <__cxx03/__type_traits/is_nothrow_constructible.h> 621#include <__cxx03/__type_traits/is_same.h> 622#include <__cxx03/__type_traits/is_standard_layout.h> 623#include <__cxx03/__type_traits/is_trivial.h> 624#include <__cxx03/__type_traits/is_trivially_relocatable.h> 625#include <__cxx03/__type_traits/noexcept_move_assign_container.h> 626#include <__cxx03/__type_traits/remove_cvref.h> 627#include <__cxx03/__type_traits/void_t.h> 628#include <__cxx03/__utility/auto_cast.h> 629#include <__cxx03/__utility/declval.h> 630#include <__cxx03/__utility/forward.h> 631#include <__cxx03/__utility/is_pointer_in_range.h> 632#include <__cxx03/__utility/move.h> 633#include <__cxx03/__utility/swap.h> 634#include <__cxx03/__utility/unreachable.h> 635#include <__cxx03/climits> 636#include <__cxx03/cstdio> // EOF 637#include <__cxx03/cstring> 638#include <__cxx03/limits> 639#include <__cxx03/stdexcept> 640#include <__cxx03/string_view> 641#include <__cxx03/version> 642 643#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 644# include <__cxx03/cwchar> 645#endif 646 647// standard-mandated includes 648 649// [iterator.range] 650#include <__cxx03/__iterator/access.h> 651 652#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 653# pragma GCC system_header 654#endif 655 656_LIBCPP_PUSH_MACROS 657#include <__cxx03/__undef_macros> 658 659#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN) 660# define _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS __attribute__((__no_sanitize__("address"))) 661// This macro disables AddressSanitizer (ASan) instrumentation for a specific function, 662// allowing memory accesses that would normally trigger ASan errors to proceed without crashing. 663// This is useful for accessing parts of objects memory, which should not be accessed, 664// such as unused bytes in short strings, that should never be accessed 665// by other parts of the program. 666#else 667# define _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS 668#endif 669 670_LIBCPP_BEGIN_NAMESPACE_STD 671 672// basic_string 673 674template <class _CharT, class _Traits, class _Allocator> 675basic_string<_CharT, _Traits, _Allocator> _LIBCPP_HIDE_FROM_ABI 676operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const basic_string<_CharT, _Traits, _Allocator>& __y); 677 678template <class _CharT, class _Traits, class _Allocator> 679_LIBCPP_HIDDEN basic_string<_CharT, _Traits, _Allocator> 680operator+(const _CharT* __x, const basic_string<_CharT, _Traits, _Allocator>& __y); 681 682template <class _CharT, class _Traits, class _Allocator> 683_LIBCPP_HIDE_FROM_ABI basic_string<_CharT, _Traits, _Allocator> 684operator+(_CharT __x, const basic_string<_CharT, _Traits, _Allocator>& __y); 685 686template <class _CharT, class _Traits, class _Allocator> 687inline _LIBCPP_HIDE_FROM_ABI basic_string<_CharT, _Traits, _Allocator> 688operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const _CharT* __y); 689 690template <class _CharT, class _Traits, class _Allocator> 691_LIBCPP_HIDE_FROM_ABI basic_string<_CharT, _Traits, _Allocator> 692operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y); 693 694extern template _LIBCPP_EXPORTED_FROM_ABI string operator+ 695 <char, char_traits<char>, allocator<char> >(char const*, string const&); 696 697template <class _Iter> 698struct __string_is_trivial_iterator : public false_type {}; 699 700template <class _Tp> 701struct __string_is_trivial_iterator<_Tp*> : public is_arithmetic<_Tp> {}; 702 703template <class _Iter> 704struct __string_is_trivial_iterator<__wrap_iter<_Iter> > : public __string_is_trivial_iterator<_Iter> {}; 705 706template <class _CharT, class _Traits, class _Tp> 707struct __can_be_converted_to_string_view 708 : public _BoolConstant< is_convertible<const _Tp&, basic_string_view<_CharT, _Traits> >::value && 709 !is_convertible<const _Tp&, const _CharT*>::value > {}; 710 711struct __uninitialized_size_tag {}; 712struct __init_with_sentinel_tag {}; 713 714template <class _CharT, class _Traits, class _Allocator> 715class basic_string { 716private: 717 using __default_allocator_type = allocator<_CharT>; 718 719public: 720 typedef basic_string __self; 721 typedef basic_string_view<_CharT, _Traits> __self_view; 722 typedef _Traits traits_type; 723 typedef _CharT value_type; 724 typedef _Allocator allocator_type; 725 typedef allocator_traits<allocator_type> __alloc_traits; 726 typedef typename __alloc_traits::size_type size_type; 727 typedef typename __alloc_traits::difference_type difference_type; 728 typedef value_type& reference; 729 typedef const value_type& const_reference; 730 typedef typename __alloc_traits::pointer pointer; 731 typedef typename __alloc_traits::const_pointer const_pointer; 732 733 // A basic_string contains the following members which may be trivially relocatable: 734 // - pointer: is currently assumed to be trivially relocatable, but is still checked in case that changes 735 // - size_type: is always trivially relocatable, since it has to be an integral type 736 // - value_type: is always trivially relocatable, since it has to be trivial 737 // - unsigned char: is a fundamental type, so it's trivially relocatable 738 // - allocator_type: may or may not be trivially relocatable, so it's checked 739 // 740 // This string implementation doesn't contain any references into itself. It only contains a bit that says whether 741 // it is in small or large string mode, so the entire structure is trivially relocatable if its members are. 742#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN) 743 // When compiling with AddressSanitizer (ASan), basic_string cannot be trivially 744 // relocatable. Because the object's memory might be poisoned when its content 745 // is kept inside objects memory (short string optimization), instead of in allocated 746 // external memory. In such cases, the destructor is responsible for unpoisoning 747 // the memory to avoid triggering false positives. 748 // Therefore it's crucial to ensure the destructor is called. 749 using __trivially_relocatable = void; 750#else 751 using __trivially_relocatable = __conditional_t< 752 __libcpp_is_trivially_relocatable<allocator_type>::value && __libcpp_is_trivially_relocatable<pointer>::value, 753 basic_string, 754 void>; 755#endif 756#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN) 757 _LIBCPP_HIDE_FROM_ABI pointer __asan_volatile_wrapper(pointer const& __ptr) const { 758 if (__libcpp_is_constant_evaluated()) 759 return __ptr; 760 761 pointer volatile __copy_ptr = __ptr; 762 763 return const_cast<pointer&>(__copy_ptr); 764 } 765 766 _LIBCPP_HIDE_FROM_ABI const_pointer __asan_volatile_wrapper(const_pointer const& __ptr) const { 767 if (__libcpp_is_constant_evaluated()) 768 return __ptr; 769 770 const_pointer volatile __copy_ptr = __ptr; 771 772 return const_cast<const_pointer&>(__copy_ptr); 773 } 774# define _LIBCPP_ASAN_VOLATILE_WRAPPER(PTR) __asan_volatile_wrapper(PTR) 775#else 776# define _LIBCPP_ASAN_VOLATILE_WRAPPER(PTR) PTR 777#endif 778 779 static_assert(!is_array<value_type>::value, "Character type of basic_string must not be an array"); 780 static_assert(is_standard_layout<value_type>::value, "Character type of basic_string must be standard-layout"); 781 static_assert(is_trivial<value_type>::value, "Character type of basic_string must be trivial"); 782 static_assert(is_same<_CharT, typename traits_type::char_type>::value, 783 "traits_type::char_type must be the same type as CharT"); 784 static_assert(is_same<typename allocator_type::value_type, value_type>::value, 785 "Allocator::value_type must be same type as value_type"); 786 static_assert(__check_valid_allocator<allocator_type>::value, ""); 787 788#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING 789 // Users might provide custom allocators, and prior to C++20 we have no existing way to detect whether the allocator's 790 // pointer type is contiguous (though it has to be by the Standard). Using the wrapper type ensures the iterator is 791 // considered contiguous. 792 typedef __bounded_iter<__wrap_iter<pointer>> iterator; 793 typedef __bounded_iter<__wrap_iter<const_pointer>> const_iterator; 794#else 795 typedef __wrap_iter<pointer> iterator; 796 typedef __wrap_iter<const_pointer> const_iterator; 797#endif 798 typedef std::reverse_iterator<iterator> reverse_iterator; 799 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 800 801private: 802 static_assert(CHAR_BIT == 8, "This implementation assumes that one byte contains 8 bits"); 803 804#ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT 805 806 struct __long { 807 pointer __data_; 808 size_type __size_; 809 size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1; 810 size_type __is_long_ : 1; 811 }; 812 813 enum { __min_cap = (sizeof(__long) - 1) / sizeof(value_type) > 2 ? (sizeof(__long) - 1) / sizeof(value_type) : 2 }; 814 815 struct __short { 816 value_type __data_[__min_cap]; 817 unsigned char __padding_[sizeof(value_type) - 1]; 818 unsigned char __size_ : 7; 819 unsigned char __is_long_ : 1; 820 }; 821 822 // The __endian_factor is required because the field we use to store the size 823 // has one fewer bit than it would if it were not a bitfield. 824 // 825 // If the LSB is used to store the short-flag in the short string representation, 826 // we have to multiply the size by two when it is stored and divide it by two when 827 // it is loaded to make sure that we always store an even number. In the long string 828 // representation, we can ignore this because we can assume that we always allocate 829 // an even amount of value_types. 830 // 831 // If the MSB is used for the short-flag, the max_size() is numeric_limits<size_type>::max() / 2. 832 // This does not impact the short string representation, since we never need the MSB 833 // for representing the size of a short string anyway. 834 835# ifdef _LIBCPP_BIG_ENDIAN 836 static const size_type __endian_factor = 2; 837# else 838 static const size_type __endian_factor = 1; 839# endif 840 841#else // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT 842 843# ifdef _LIBCPP_BIG_ENDIAN 844 static const size_type __endian_factor = 1; 845# else 846 static const size_type __endian_factor = 2; 847# endif 848 849 // Attribute 'packed' is used to keep the layout compatible with the 850 // previous definition that did not use bit fields. This is because on 851 // some platforms bit fields have a default size rather than the actual 852 // size used, e.g., it is 4 bytes on AIX. See D128285 for details. 853 struct __long { 854 struct _LIBCPP_PACKED { 855 size_type __is_long_ : 1; 856 size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1; 857 }; 858 size_type __size_; 859 pointer __data_; 860 }; 861 862 enum { __min_cap = (sizeof(__long) - 1) / sizeof(value_type) > 2 ? (sizeof(__long) - 1) / sizeof(value_type) : 2 }; 863 864 struct __short { 865 struct _LIBCPP_PACKED { 866 unsigned char __is_long_ : 1; 867 unsigned char __size_ : 7; 868 }; 869 char __padding_[sizeof(value_type) - 1]; 870 value_type __data_[__min_cap]; 871 }; 872 873#endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT 874 875 static_assert(sizeof(__short) == (sizeof(value_type) * (__min_cap + 1)), "__short has an unexpected size."); 876 877 union __rep { 878 __short __s; 879 __long __l; 880 }; 881 882 __compressed_pair<__rep, allocator_type> __r_; 883 884 // Construct a string with the given allocator and enough storage to hold `__size` characters, but 885 // don't initialize the characters. The contents of the string, including the null terminator, must be 886 // initialized separately. 887 _LIBCPP_HIDE_FROM_ABI explicit basic_string(__uninitialized_size_tag, size_type __size, const allocator_type& __a) 888 : __r_(__default_init_tag(), __a) { 889 if (__size > max_size()) 890 __throw_length_error(); 891 if (__fits_in_sso(__size)) { 892 __r_.first() = __rep(); 893 __set_short_size(__size); 894 } else { 895 auto __capacity = __recommend(__size) + 1; 896 auto __allocation = __alloc_traits::allocate(__alloc(), __capacity); 897 __begin_lifetime(__allocation, __capacity); 898 __set_long_cap(__capacity); 899 __set_long_pointer(__allocation); 900 __set_long_size(__size); 901 } 902 __annotate_new(__size); 903 } 904 905 template <class _Iter, class _Sent> 906 _LIBCPP_HIDE_FROM_ABI basic_string(__init_with_sentinel_tag, _Iter __first, _Sent __last, const allocator_type& __a) 907 : __r_(__default_init_tag(), __a) { 908 __init_with_sentinel(std::move(__first), std::move(__last)); 909 } 910 911 _LIBCPP_HIDE_FROM_ABI iterator __make_iterator(pointer __p) { 912#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING 913 // Bound the iterator according to the size (and not the capacity, unlike vector). 914 // 915 // By the Standard, string iterators are generally not guaranteed to stay valid when the container is modified, 916 // regardless of whether reallocation occurs. This allows us to check for out-of-bounds accesses using logical size, 917 // a stricter check, since correct code can never rely on being able to access newly-added elements via an existing 918 // iterator. 919 return std::__make_bounded_iter( 920 std::__wrap_iter<pointer>(__p), 921 std::__wrap_iter<pointer>(__get_pointer()), 922 std::__wrap_iter<pointer>(__get_pointer() + size())); 923#else 924 return iterator(__p); 925#endif // _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING 926 } 927 928 _LIBCPP_HIDE_FROM_ABI const_iterator __make_const_iterator(const_pointer __p) const { 929#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING 930 // Bound the iterator according to the size (and not the capacity, unlike vector). 931 return std::__make_bounded_iter( 932 std::__wrap_iter<const_pointer>(__p), 933 std::__wrap_iter<const_pointer>(__get_pointer()), 934 std::__wrap_iter<const_pointer>(__get_pointer() + size())); 935#else 936 return const_iterator(__p); 937#endif // _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING 938 } 939 940public: 941 _LIBCPP_TEMPLATE_DATA_VIS static const size_type npos = -1; 942 943 _LIBCPP_HIDE_FROM_ABI basic_string() : __r_(__value_init_tag(), __default_init_tag()) { __annotate_new(0); } 944 945 _LIBCPP_HIDE_FROM_ABI explicit basic_string(const allocator_type& __a) : __r_(__value_init_tag(), __a) { 946 __annotate_new(0); 947 } 948 949 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS basic_string(const basic_string& __str) 950 : __r_(__default_init_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc())) { 951 if (!__str.__is_long()) { 952 __r_.first() = __str.__r_.first(); 953 __annotate_new(__get_short_size()); 954 } else 955 __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); 956 } 957 958 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS 959 basic_string(const basic_string& __str, const allocator_type& __a) : __r_(__default_init_tag(), __a) { 960 if (!__str.__is_long()) { 961 __r_.first() = __str.__r_.first(); 962 __annotate_new(__get_short_size()); 963 } else 964 __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); 965 } 966 967 template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0> 968 _LIBCPP_HIDE_FROM_ABI basic_string(const _CharT* __s) : __r_(__default_init_tag(), __default_init_tag()) { 969 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "basic_string(const char*) detected nullptr"); 970 __init(__s, traits_type::length(__s)); 971 } 972 973 template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0> 974 _LIBCPP_HIDE_FROM_ABI basic_string(const _CharT* __s, const _Allocator& __a) : __r_(__default_init_tag(), __a) { 975 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "basic_string(const char*, allocator) detected nullptr"); 976 __init(__s, traits_type::length(__s)); 977 } 978 979 _LIBCPP_HIDE_FROM_ABI basic_string(const _CharT* __s, size_type __n) 980 : __r_(__default_init_tag(), __default_init_tag()) { 981 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr"); 982 __init(__s, __n); 983 } 984 985 _LIBCPP_HIDE_FROM_ABI basic_string(const _CharT* __s, size_type __n, const _Allocator& __a) 986 : __r_(__default_init_tag(), __a) { 987 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr"); 988 __init(__s, __n); 989 } 990 991 _LIBCPP_HIDE_FROM_ABI basic_string(size_type __n, _CharT __c) : __r_(__default_init_tag(), __default_init_tag()) { 992 __init(__n, __c); 993 } 994 995 template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0> 996 _LIBCPP_HIDE_FROM_ABI basic_string(size_type __n, _CharT __c, const _Allocator& __a) 997 : __r_(__default_init_tag(), __a) { 998 __init(__n, __c); 999 } 1000 1001 basic_string(const basic_string& __str, size_type __pos, size_type __n, const _Allocator& __a = _Allocator()) 1002 : __r_(__default_init_tag(), __a) { 1003 size_type __str_sz = __str.size(); 1004 if (__pos > __str_sz) 1005 __throw_out_of_range(); 1006 __init(__str.data() + __pos, std::min(__n, __str_sz - __pos)); 1007 } 1008 1009 _LIBCPP_HIDE_FROM_ABI basic_string(const basic_string& __str, size_type __pos, const _Allocator& __a = _Allocator()) 1010 : __r_(__default_init_tag(), __a) { 1011 size_type __str_sz = __str.size(); 1012 if (__pos > __str_sz) 1013 __throw_out_of_range(); 1014 __init(__str.data() + __pos, __str_sz - __pos); 1015 } 1016 1017 template <class _Tp, 1018 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 1019 !__is_same_uncvref<_Tp, basic_string>::value, 1020 int> = 0> 1021 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 1022 basic_string(const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a = allocator_type()) 1023 : __r_(__default_init_tag(), __a) { 1024 __self_view __sv0 = __t; 1025 __self_view __sv = __sv0.substr(__pos, __n); 1026 __init(__sv.data(), __sv.size()); 1027 } 1028 1029 template <class _Tp, 1030 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 1031 !__is_same_uncvref<_Tp, basic_string>::value, 1032 int> = 0> 1033 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS explicit basic_string(const _Tp& __t) 1034 : __r_(__default_init_tag(), __default_init_tag()) { 1035 __self_view __sv = __t; 1036 __init(__sv.data(), __sv.size()); 1037 } 1038 1039 template <class _Tp, 1040 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 1041 !__is_same_uncvref<_Tp, basic_string>::value, 1042 int> = 0> 1043 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS explicit basic_string(const _Tp& __t, const allocator_type& __a) 1044 : __r_(__default_init_tag(), __a) { 1045 __self_view __sv = __t; 1046 __init(__sv.data(), __sv.size()); 1047 } 1048 1049 template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0> 1050 _LIBCPP_HIDE_FROM_ABI basic_string(_InputIterator __first, _InputIterator __last) 1051 : __r_(__default_init_tag(), __default_init_tag()) { 1052 __init(__first, __last); 1053 } 1054 1055 template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0> 1056 _LIBCPP_HIDE_FROM_ABI basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a) 1057 : __r_(__default_init_tag(), __a) { 1058 __init(__first, __last); 1059 } 1060 1061 inline ~basic_string() { 1062 __annotate_delete(); 1063 if (__is_long()) 1064 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 1065 } 1066 1067 _LIBCPP_HIDE_FROM_ABI operator __self_view() const _NOEXCEPT { return __self_view(data(), size()); } 1068 1069 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS basic_string& operator=(const basic_string& __str); 1070 1071 template <class _Tp, 1072 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 1073 !__is_same_uncvref<_Tp, basic_string>::value, 1074 int> = 0> 1075 basic_string& operator=(const _Tp& __t) { 1076 __self_view __sv = __t; 1077 return assign(__sv); 1078 } 1079 1080 _LIBCPP_HIDE_FROM_ABI basic_string& operator=(const value_type* __s) { return assign(__s); } 1081 basic_string& operator=(value_type __c); 1082 1083 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __make_iterator(__get_pointer()); } 1084 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __make_const_iterator(__get_pointer()); } 1085 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __make_iterator(__get_pointer() + size()); } 1086 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __make_const_iterator(__get_pointer() + size()); } 1087 1088 _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); } 1089 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); } 1090 _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); } 1091 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); } 1092 1093 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); } 1094 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); } 1095 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return rbegin(); } 1096 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return rend(); } 1097 1098 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { 1099 return __is_long() ? __get_long_size() : __get_short_size(); 1100 } 1101 _LIBCPP_HIDE_FROM_ABI size_type length() const _NOEXCEPT { return size(); } 1102 1103 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { 1104 size_type __m = __alloc_traits::max_size(__alloc()); 1105 if (__m <= std::numeric_limits<size_type>::max() / 2) { 1106 return __m - __alignment; 1107 } else { 1108 bool __uses_lsb = __endian_factor == 2; 1109 return __uses_lsb ? __m - __alignment : (__m / 2) - __alignment; 1110 } 1111 } 1112 1113 _LIBCPP_HIDE_FROM_ABI size_type capacity() const _NOEXCEPT { 1114 return (__is_long() ? __get_long_cap() : static_cast<size_type>(__min_cap)) - 1; 1115 } 1116 1117 void resize(size_type __n, value_type __c); 1118 _LIBCPP_HIDE_FROM_ABI void resize(size_type __n) { resize(__n, value_type()); } 1119 1120 void reserve(size_type __requested_capacity); 1121 1122 _LIBCPP_HIDE_FROM_ABI void __resize_default_init(size_type __n); 1123 1124 _LIBCPP_HIDE_FROM_ABI void reserve() _NOEXCEPT { shrink_to_fit(); } 1125 _LIBCPP_HIDE_FROM_ABI void shrink_to_fit() _NOEXCEPT; 1126 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT; 1127 1128 _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return size() == 0; } 1129 1130 _LIBCPP_HIDE_FROM_ABI const_reference operator[](size_type __pos) const _NOEXCEPT { 1131 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos <= size(), "string index out of bounds"); 1132 if (__builtin_constant_p(__pos) && !__fits_in_sso(__pos)) { 1133 return *(__get_long_pointer() + __pos); 1134 } 1135 return *(data() + __pos); 1136 } 1137 1138 _LIBCPP_HIDE_FROM_ABI reference operator[](size_type __pos) _NOEXCEPT { 1139 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos <= size(), "string index out of bounds"); 1140 if (__builtin_constant_p(__pos) && !__fits_in_sso(__pos)) { 1141 return *(__get_long_pointer() + __pos); 1142 } 1143 return *(__get_pointer() + __pos); 1144 } 1145 1146 const_reference at(size_type __n) const; 1147 reference at(size_type __n); 1148 1149 _LIBCPP_HIDE_FROM_ABI basic_string& operator+=(const basic_string& __str) { return append(__str); } 1150 1151 template <class _Tp, 1152 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 1153 !__is_same_uncvref<_Tp, basic_string >::value, 1154 int> = 0> 1155 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string& operator+=(const _Tp& __t) { 1156 __self_view __sv = __t; 1157 return append(__sv); 1158 } 1159 1160 _LIBCPP_HIDE_FROM_ABI basic_string& operator+=(const value_type* __s) { return append(__s); } 1161 1162 _LIBCPP_HIDE_FROM_ABI basic_string& operator+=(value_type __c) { 1163 push_back(__c); 1164 return *this; 1165 } 1166 1167 _LIBCPP_HIDE_FROM_ABI basic_string& append(const basic_string& __str) { return append(__str.data(), __str.size()); } 1168 1169 template <class _Tp, 1170 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 1171 !__is_same_uncvref<_Tp, basic_string>::value, 1172 int> = 0> 1173 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string& append(const _Tp& __t) { 1174 __self_view __sv = __t; 1175 return append(__sv.data(), __sv.size()); 1176 } 1177 1178 basic_string& append(const basic_string& __str, size_type __pos, size_type __n = npos); 1179 1180 template <class _Tp, 1181 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 1182 !__is_same_uncvref<_Tp, basic_string>::value, 1183 int> = 0> 1184 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string& 1185 append(const _Tp& __t, size_type __pos, size_type __n = npos); 1186 1187 basic_string& append(const value_type* __s, size_type __n); 1188 basic_string& append(const value_type* __s); 1189 basic_string& append(size_type __n, value_type __c); 1190 1191 _LIBCPP_HIDE_FROM_ABI void __append_default_init(size_type __n); 1192 1193 template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0> 1194 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_HIDE_FROM_ABI basic_string& 1195 append(_InputIterator __first, _InputIterator __last) { 1196 const basic_string __temp(__first, __last, __alloc()); 1197 append(__temp.data(), __temp.size()); 1198 return *this; 1199 } 1200 1201 template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0> 1202 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_HIDE_FROM_ABI basic_string& 1203 append(_ForwardIterator __first, _ForwardIterator __last); 1204 1205 void push_back(value_type __c); 1206 _LIBCPP_HIDE_FROM_ABI void pop_back(); 1207 1208 _LIBCPP_HIDE_FROM_ABI reference front() _NOEXCEPT { 1209 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::front(): string is empty"); 1210 return *__get_pointer(); 1211 } 1212 1213 _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT { 1214 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::front(): string is empty"); 1215 return *data(); 1216 } 1217 1218 _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT { 1219 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::back(): string is empty"); 1220 return *(__get_pointer() + size() - 1); 1221 } 1222 1223 _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT { 1224 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::back(): string is empty"); 1225 return *(data() + size() - 1); 1226 } 1227 1228 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 1229 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string& assign(const _Tp& __t) { 1230 __self_view __sv = __t; 1231 return assign(__sv.data(), __sv.size()); 1232 } 1233 1234 _LIBCPP_HIDE_FROM_ABI basic_string& assign(const basic_string& __str) { return *this = __str; } 1235 1236 basic_string& assign(const basic_string& __str, size_type __pos, size_type __n = npos); 1237 1238 template <class _Tp, 1239 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 1240 !__is_same_uncvref<_Tp, basic_string>::value, 1241 int> = 0> 1242 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string& 1243 assign(const _Tp& __t, size_type __pos, size_type __n = npos); 1244 1245 basic_string& assign(const value_type* __s, size_type __n); 1246 basic_string& assign(const value_type* __s); 1247 basic_string& assign(size_type __n, value_type __c); 1248 template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0> 1249 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string& 1250 assign(_InputIterator __first, _InputIterator __last); 1251 1252 template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0> 1253 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string& 1254 assign(_ForwardIterator __first, _ForwardIterator __last); 1255 1256 _LIBCPP_HIDE_FROM_ABI basic_string& insert(size_type __pos1, const basic_string& __str) { 1257 return insert(__pos1, __str.data(), __str.size()); 1258 } 1259 1260 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 1261 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string& insert(size_type __pos1, const _Tp& __t) { 1262 __self_view __sv = __t; 1263 return insert(__pos1, __sv.data(), __sv.size()); 1264 } 1265 1266 template <class _Tp, 1267 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 1268 !__is_same_uncvref<_Tp, basic_string>::value, 1269 int> = 0> 1270 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string& 1271 insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n = npos); 1272 1273 basic_string& insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n = npos); 1274 basic_string& insert(size_type __pos, const value_type* __s, size_type __n); 1275 basic_string& insert(size_type __pos, const value_type* __s); 1276 basic_string& insert(size_type __pos, size_type __n, value_type __c); 1277 iterator insert(const_iterator __pos, value_type __c); 1278 1279 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __pos, size_type __n, value_type __c) { 1280 difference_type __p = __pos - begin(); 1281 insert(static_cast<size_type>(__p), __n, __c); 1282 return begin() + __p; 1283 } 1284 1285 template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0> 1286 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS iterator 1287 insert(const_iterator __pos, _InputIterator __first, _InputIterator __last); 1288 1289 template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0> 1290 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS iterator 1291 insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last); 1292 1293 basic_string& erase(size_type __pos = 0, size_type __n = npos); 1294 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __pos); 1295 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __first, const_iterator __last); 1296 1297 _LIBCPP_HIDE_FROM_ABI basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str) { 1298 return replace(__pos1, __n1, __str.data(), __str.size()); 1299 } 1300 1301 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 1302 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string& 1303 replace(size_type __pos1, size_type __n1, const _Tp& __t) { 1304 __self_view __sv = __t; 1305 return replace(__pos1, __n1, __sv.data(), __sv.size()); 1306 } 1307 1308 basic_string& 1309 replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2 = npos); 1310 1311 template <class _Tp, 1312 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 1313 !__is_same_uncvref<_Tp, basic_string>::value, 1314 int> = 0> 1315 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string& 1316 replace(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2 = npos); 1317 1318 basic_string& replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2); 1319 basic_string& replace(size_type __pos, size_type __n1, const value_type* __s); 1320 basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c); 1321 1322 _LIBCPP_HIDE_FROM_ABI basic_string& replace(const_iterator __i1, const_iterator __i2, const basic_string& __str) { 1323 return replace( 1324 static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __str.data(), __str.size()); 1325 } 1326 1327 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 1328 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string& 1329 replace(const_iterator __i1, const_iterator __i2, const _Tp& __t) { 1330 __self_view __sv = __t; 1331 return replace(__i1 - begin(), __i2 - __i1, __sv); 1332 } 1333 1334 _LIBCPP_HIDE_FROM_ABI basic_string& 1335 replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n) { 1336 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s, __n); 1337 } 1338 1339 _LIBCPP_HIDE_FROM_ABI basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s) { 1340 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s); 1341 } 1342 1343 _LIBCPP_HIDE_FROM_ABI basic_string& replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c) { 1344 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __n, __c); 1345 } 1346 1347 template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0> 1348 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string& 1349 replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2); 1350 1351 size_type copy(value_type* __s, size_type __n, size_type __pos = 0) const; 1352 1353 _LIBCPP_HIDE_FROM_ABI basic_string substr(size_type __pos = 0, size_type __n = npos) const { 1354 return basic_string(*this, __pos, __n); 1355 } 1356 1357 _LIBCPP_HIDE_FROM_ABI void swap(basic_string& __str); 1358 1359 _LIBCPP_HIDE_FROM_ABI const value_type* c_str() const _NOEXCEPT { return data(); } 1360 _LIBCPP_HIDE_FROM_ABI const value_type* data() const _NOEXCEPT { return std::__to_address(__get_pointer()); } 1361 1362 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT { return __alloc(); } 1363 1364 _LIBCPP_HIDE_FROM_ABI size_type find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; 1365 1366 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 1367 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS size_type 1368 find(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT; 1369 1370 size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; 1371 _LIBCPP_HIDE_FROM_ABI size_type find(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; 1372 size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT; 1373 1374 _LIBCPP_HIDE_FROM_ABI size_type rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; 1375 1376 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 1377 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS size_type 1378 rfind(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT; 1379 1380 size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; 1381 _LIBCPP_HIDE_FROM_ABI size_type rfind(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; 1382 size_type rfind(value_type __c, size_type __pos = npos) const _NOEXCEPT; 1383 1384 _LIBCPP_HIDE_FROM_ABI size_type find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; 1385 1386 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 1387 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS size_type 1388 find_first_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT; 1389 1390 size_type find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; 1391 _LIBCPP_HIDE_FROM_ABI size_type find_first_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; 1392 _LIBCPP_HIDE_FROM_ABI size_type find_first_of(value_type __c, size_type __pos = 0) const _NOEXCEPT; 1393 1394 _LIBCPP_HIDE_FROM_ABI size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; 1395 1396 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 1397 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS size_type 1398 find_last_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT; 1399 1400 size_type find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; 1401 _LIBCPP_HIDE_FROM_ABI size_type find_last_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; 1402 _LIBCPP_HIDE_FROM_ABI size_type find_last_of(value_type __c, size_type __pos = npos) const _NOEXCEPT; 1403 1404 _LIBCPP_HIDE_FROM_ABI size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; 1405 1406 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 1407 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS size_type 1408 find_first_not_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT; 1409 1410 size_type find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; 1411 _LIBCPP_HIDE_FROM_ABI size_type find_first_not_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; 1412 _LIBCPP_HIDE_FROM_ABI size_type find_first_not_of(value_type __c, size_type __pos = 0) const _NOEXCEPT; 1413 1414 _LIBCPP_HIDE_FROM_ABI size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; 1415 1416 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 1417 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS size_type 1418 find_last_not_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT; 1419 1420 size_type find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; 1421 _LIBCPP_HIDE_FROM_ABI size_type find_last_not_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; 1422 _LIBCPP_HIDE_FROM_ABI size_type find_last_not_of(value_type __c, size_type __pos = npos) const _NOEXCEPT; 1423 1424 _LIBCPP_HIDE_FROM_ABI int compare(const basic_string& __str) const _NOEXCEPT; 1425 1426 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 1427 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS int compare(const _Tp& __t) const _NOEXCEPT; 1428 1429 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 1430 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS int 1431 compare(size_type __pos1, size_type __n1, const _Tp& __t) const; 1432 1433 _LIBCPP_HIDE_FROM_ABI int compare(size_type __pos1, size_type __n1, const basic_string& __str) const; 1434 int compare( 1435 size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2 = npos) const; 1436 1437 template <class _Tp, 1438 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 1439 !__is_same_uncvref<_Tp, basic_string>::value, 1440 int> = 0> 1441 inline _LIBCPP_HIDE_FROM_ABI int 1442 compare(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2 = npos) const; 1443 1444 int compare(const value_type* __s) const _NOEXCEPT; 1445 int compare(size_type __pos1, size_type __n1, const value_type* __s) const; 1446 int compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const; 1447 1448 _LIBCPP_HIDE_FROM_ABI bool __invariants() const; 1449 1450 _LIBCPP_HIDE_FROM_ABI void __clear_and_shrink() _NOEXCEPT; 1451 1452private: 1453 template <class _Alloc> 1454 inline _LIBCPP_HIDE_FROM_ABI bool friend 1455 operator==(const basic_string<char, char_traits<char>, _Alloc>& __lhs, 1456 const basic_string<char, char_traits<char>, _Alloc>& __rhs) _NOEXCEPT; 1457 1458 _LIBCPP_HIDE_FROM_ABI void __shrink_or_extend(size_type __target_capacity); 1459 1460 _LIBCPP_HIDE_FROM_ABI _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS bool __is_long() const _NOEXCEPT { 1461 if (__libcpp_is_constant_evaluated() && __builtin_constant_p(__r_.first().__l.__is_long_)) { 1462 return __r_.first().__l.__is_long_; 1463 } 1464 return __r_.first().__s.__is_long_; 1465 } 1466 1467 static _LIBCPP_HIDE_FROM_ABI void __begin_lifetime(pointer __begin, size_type __n) { 1468 (void)__begin; 1469 (void)__n; 1470 } 1471 1472 _LIBCPP_HIDE_FROM_ABI static bool __fits_in_sso(size_type __sz) { return __sz < __min_cap; } 1473 1474 template <class _Iterator, class _Sentinel> 1475 _LIBCPP_HIDE_FROM_ABI void __assign_trivial(_Iterator __first, _Sentinel __last, size_type __n); 1476 1477 template <class _Iterator, class _Sentinel> 1478 _LIBCPP_HIDE_FROM_ABI void __assign_with_sentinel(_Iterator __first, _Sentinel __last); 1479 1480 // Copy [__first, __last) into [__dest, __dest + (__last - __first)). Assumes that the ranges don't overlap. 1481 template <class _ForwardIter, class _Sent> 1482 _LIBCPP_HIDE_FROM_ABI static value_type* 1483 __copy_non_overlapping_range(_ForwardIter __first, _Sent __last, value_type* __dest) { 1484 for (; __first != __last; ++__first) 1485 traits_type::assign(*__dest++, *__first); 1486 return __dest; 1487 } 1488 1489 template <class _ForwardIterator, class _Sentinel> 1490 _LIBCPP_HIDE_FROM_ABI iterator 1491 __insert_from_safe_copy(size_type __n, size_type __ip, _ForwardIterator __first, _Sentinel __last) { 1492 size_type __sz = size(); 1493 size_type __cap = capacity(); 1494 value_type* __p; 1495 if (__cap - __sz >= __n) { 1496 __annotate_increase(__n); 1497 __p = std::__to_address(__get_pointer()); 1498 size_type __n_move = __sz - __ip; 1499 if (__n_move != 0) 1500 traits_type::move(__p + __ip + __n, __p + __ip, __n_move); 1501 } else { 1502 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __ip, 0, __n); 1503 __p = std::__to_address(__get_long_pointer()); 1504 } 1505 __sz += __n; 1506 __set_size(__sz); 1507 traits_type::assign(__p[__sz], value_type()); 1508 __copy_non_overlapping_range(__first, __last, __p + __ip); 1509 1510 return begin() + __ip; 1511 } 1512 1513 template <class _Iterator, class _Sentinel> 1514 iterator __insert_with_size(const_iterator __pos, _Iterator __first, _Sentinel __last, size_type __n); 1515 1516 _LIBCPP_HIDE_FROM_ABI allocator_type& __alloc() _NOEXCEPT { return __r_.second(); } 1517 _LIBCPP_HIDE_FROM_ABI const allocator_type& __alloc() const _NOEXCEPT { return __r_.second(); } 1518 1519 _LIBCPP_HIDE_FROM_ABI _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS void __set_short_size(size_type __s) _NOEXCEPT { 1520 _LIBCPP_ASSERT_INTERNAL(__s < __min_cap, "__s should never be greater than or equal to the short string capacity"); 1521 __r_.first().__s.__size_ = __s; 1522 __r_.first().__s.__is_long_ = false; 1523 } 1524 1525 _LIBCPP_HIDE_FROM_ABI _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS size_type __get_short_size() const _NOEXCEPT { 1526 _LIBCPP_ASSERT_INTERNAL(!__r_.first().__s.__is_long_, "String has to be short when trying to get the short size"); 1527 return __r_.first().__s.__size_; 1528 } 1529 1530 _LIBCPP_HIDE_FROM_ABI void __set_long_size(size_type __s) _NOEXCEPT { __r_.first().__l.__size_ = __s; } 1531 _LIBCPP_HIDE_FROM_ABI size_type __get_long_size() const _NOEXCEPT { return __r_.first().__l.__size_; } 1532 _LIBCPP_HIDE_FROM_ABI void __set_size(size_type __s) _NOEXCEPT { 1533 if (__is_long()) 1534 __set_long_size(__s); 1535 else 1536 __set_short_size(__s); 1537 } 1538 1539 _LIBCPP_HIDE_FROM_ABI void __set_long_cap(size_type __s) _NOEXCEPT { 1540 __r_.first().__l.__cap_ = __s / __endian_factor; 1541 __r_.first().__l.__is_long_ = true; 1542 } 1543 1544 _LIBCPP_HIDE_FROM_ABI size_type __get_long_cap() const _NOEXCEPT { return __r_.first().__l.__cap_ * __endian_factor; } 1545 1546 _LIBCPP_HIDE_FROM_ABI void __set_long_pointer(pointer __p) _NOEXCEPT { __r_.first().__l.__data_ = __p; } 1547 _LIBCPP_HIDE_FROM_ABI pointer __get_long_pointer() _NOEXCEPT { 1548 return _LIBCPP_ASAN_VOLATILE_WRAPPER(__r_.first().__l.__data_); 1549 } 1550 _LIBCPP_HIDE_FROM_ABI const_pointer __get_long_pointer() const _NOEXCEPT { 1551 return _LIBCPP_ASAN_VOLATILE_WRAPPER(__r_.first().__l.__data_); 1552 } 1553 _LIBCPP_HIDE_FROM_ABI _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS pointer __get_short_pointer() _NOEXCEPT { 1554 return _LIBCPP_ASAN_VOLATILE_WRAPPER(pointer_traits<pointer>::pointer_to(__r_.first().__s.__data_[0])); 1555 } 1556 _LIBCPP_HIDE_FROM_ABI _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS const_pointer __get_short_pointer() const _NOEXCEPT { 1557 return _LIBCPP_ASAN_VOLATILE_WRAPPER(pointer_traits<const_pointer>::pointer_to(__r_.first().__s.__data_[0])); 1558 } 1559 _LIBCPP_HIDE_FROM_ABI pointer __get_pointer() _NOEXCEPT { 1560 return __is_long() ? __get_long_pointer() : __get_short_pointer(); 1561 } 1562 _LIBCPP_HIDE_FROM_ABI const_pointer __get_pointer() const _NOEXCEPT { 1563 return __is_long() ? __get_long_pointer() : __get_short_pointer(); 1564 } 1565 1566 // The following functions are no-ops outside of AddressSanitizer mode. 1567 _LIBCPP_HIDE_FROM_ABI void __annotate_contiguous_container(const void* __old_mid, const void* __new_mid) const { 1568 (void)__old_mid; 1569 (void)__new_mid; 1570#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN) 1571# if defined(__APPLE__) 1572 // TODO: remove after addressing issue #96099 (https://github.com/llvm/llvm-project/issues/96099) 1573 if (!__is_long()) 1574 return; 1575# endif 1576 std::__annotate_contiguous_container<_Allocator>(data(), data() + capacity() + 1, __old_mid, __new_mid); 1577#endif 1578 } 1579 1580 _LIBCPP_HIDE_FROM_ABI void __annotate_new(size_type __current_size) const _NOEXCEPT { 1581 (void)__current_size; 1582#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN) 1583 if (!__libcpp_is_constant_evaluated()) 1584 __annotate_contiguous_container(data() + capacity() + 1, data() + __current_size + 1); 1585#endif 1586 } 1587 1588 _LIBCPP_HIDE_FROM_ABI void __annotate_delete() const _NOEXCEPT { 1589#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN) 1590 if (!__libcpp_is_constant_evaluated()) 1591 __annotate_contiguous_container(data() + size() + 1, data() + capacity() + 1); 1592#endif 1593 } 1594 1595 _LIBCPP_HIDE_FROM_ABI void __annotate_increase(size_type __n) const _NOEXCEPT { 1596 (void)__n; 1597#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN) 1598 if (!__libcpp_is_constant_evaluated()) 1599 __annotate_contiguous_container(data() + size() + 1, data() + size() + 1 + __n); 1600#endif 1601 } 1602 1603 _LIBCPP_HIDE_FROM_ABI void __annotate_shrink(size_type __old_size) const _NOEXCEPT { 1604 (void)__old_size; 1605#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN) 1606 if (!__libcpp_is_constant_evaluated()) 1607 __annotate_contiguous_container(data() + __old_size + 1, data() + size() + 1); 1608#endif 1609 } 1610 1611 template <size_type __a> 1612 static _LIBCPP_HIDE_FROM_ABI size_type __align_it(size_type __s) _NOEXCEPT { 1613 return (__s + (__a - 1)) & ~(__a - 1); 1614 } 1615 enum { __alignment = 8 }; 1616 static _LIBCPP_HIDE_FROM_ABI size_type __recommend(size_type __s) _NOEXCEPT { 1617 if (__s < __min_cap) { 1618 return static_cast<size_type>(__min_cap) - 1; 1619 } 1620 const size_type __boundary = sizeof(value_type) < __alignment ? __alignment / sizeof(value_type) : __endian_factor; 1621 size_type __guess = __align_it<__boundary>(__s + 1) - 1; 1622 if (__guess == __min_cap) 1623 __guess += __endian_factor; 1624 return __guess; 1625 } 1626 1627 inline void __init(const value_type* __s, size_type __sz, size_type __reserve); 1628 inline void __init(const value_type* __s, size_type __sz); 1629 inline void __init(size_type __n, value_type __c); 1630 1631 // Slow path for the (inlined) copy constructor for 'long' strings. 1632 // Always externally instantiated and not inlined. 1633 // Requires that __s is zero terminated. 1634 // The main reason for this function to exist is because for unstable, we 1635 // want to allow inlining of the copy constructor. However, we don't want 1636 // to call the __init() functions as those are marked as inline which may 1637 // result in over-aggressive inlining by the compiler, where our aim is 1638 // to only inline the fast path code directly in the ctor. 1639 _LIBCPP_NOINLINE void __init_copy_ctor_external(const value_type* __s, size_type __sz); 1640 1641 template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0> 1642 inline void __init(_InputIterator __first, _InputIterator __last); 1643 1644 template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0> 1645 inline void __init(_ForwardIterator __first, _ForwardIterator __last); 1646 1647 template <class _InputIterator, class _Sentinel> 1648 _LIBCPP_HIDE_FROM_ABI void __init_with_sentinel(_InputIterator __first, _Sentinel __last); 1649 template <class _InputIterator, class _Sentinel> 1650 _LIBCPP_HIDE_FROM_ABI void __init_with_size(_InputIterator __first, _Sentinel __last, size_type __sz); 1651 1652#if _LIBCPP_ABI_VERSION >= 2 // We want to use the function in the dylib in ABIv1 1653 _LIBCPP_HIDE_FROM_ABI 1654#endif 1655 _LIBCPP_DEPRECATED_("use __grow_by_without_replace") void __grow_by( 1656 size_type __old_cap, 1657 size_type __delta_cap, 1658 size_type __old_sz, 1659 size_type __n_copy, 1660 size_type __n_del, 1661 size_type __n_add = 0); 1662 _LIBCPP_HIDE_FROM_ABI void __grow_by_without_replace( 1663 size_type __old_cap, 1664 size_type __delta_cap, 1665 size_type __old_sz, 1666 size_type __n_copy, 1667 size_type __n_del, 1668 size_type __n_add = 0); 1669 void __grow_by_and_replace( 1670 size_type __old_cap, 1671 size_type __delta_cap, 1672 size_type __old_sz, 1673 size_type __n_copy, 1674 size_type __n_del, 1675 size_type __n_add, 1676 const value_type* __p_new_stuff); 1677 1678 // __assign_no_alias is invoked for assignment operations where we 1679 // have proof that the input does not alias the current instance. 1680 // For example, operator=(basic_string) performs a 'self' check. 1681 template <bool __is_short> 1682 _LIBCPP_NOINLINE basic_string& __assign_no_alias(const value_type* __s, size_type __n); 1683 1684 _LIBCPP_HIDE_FROM_ABI void __erase_to_end(size_type __pos) { 1685 __null_terminate_at(std::__to_address(__get_pointer()), __pos); 1686 } 1687 1688 // __erase_external_with_move is invoked for erase() invocations where 1689 // `n ~= npos`, likely requiring memory moves on the string data. 1690 _LIBCPP_NOINLINE void __erase_external_with_move(size_type __pos, size_type __n); 1691 1692 _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const basic_string& __str) { 1693 __copy_assign_alloc( 1694 __str, integral_constant<bool, __alloc_traits::propagate_on_container_copy_assignment::value>()); 1695 } 1696 1697 _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const basic_string& __str, true_type) { 1698 if (__alloc() == __str.__alloc()) 1699 __alloc() = __str.__alloc(); 1700 else { 1701 if (!__str.__is_long()) { 1702 __clear_and_shrink(); 1703 __alloc() = __str.__alloc(); 1704 } else { 1705 __annotate_delete(); 1706 allocator_type __a = __str.__alloc(); 1707 auto __allocation = std::__allocate_at_least(__a, __str.__get_long_cap()); 1708 __begin_lifetime(__allocation.ptr, __allocation.count); 1709 if (__is_long()) 1710 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 1711 __alloc() = std::move(__a); 1712 __set_long_pointer(__allocation.ptr); 1713 __set_long_cap(__allocation.count); 1714 __set_long_size(__str.size()); 1715 __annotate_new(__get_long_size()); 1716 } 1717 } 1718 } 1719 1720 _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const basic_string&, false_type) _NOEXCEPT {} 1721 1722 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(basic_string& __str) { 1723 __move_assign_alloc( 1724 __str, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>()); 1725 } 1726 1727 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(basic_string& __c, true_type) { __alloc() = std::move(__c.__alloc()); } 1728 1729 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(basic_string&, false_type) _NOEXCEPT {} 1730 1731 _LIBCPP_NOINLINE basic_string& __assign_external(const value_type* __s); 1732 _LIBCPP_NOINLINE basic_string& __assign_external(const value_type* __s, size_type __n); 1733 1734 // Assigns the value in __s, guaranteed to be __n < __min_cap in length. 1735 inline basic_string& __assign_short(const value_type* __s, size_type __n) { 1736 size_type __old_size = size(); 1737 if (__n > __old_size) 1738 __annotate_increase(__n - __old_size); 1739 pointer __p = 1740 __is_long() ? (__set_long_size(__n), __get_long_pointer()) : (__set_short_size(__n), __get_short_pointer()); 1741 traits_type::move(std::__to_address(__p), __s, __n); 1742 traits_type::assign(__p[__n], value_type()); 1743 if (__old_size > __n) 1744 __annotate_shrink(__old_size); 1745 return *this; 1746 } 1747 1748 _LIBCPP_HIDE_FROM_ABI basic_string& __null_terminate_at(value_type* __p, size_type __newsz) { 1749 size_type __old_size = size(); 1750 if (__newsz > __old_size) 1751 __annotate_increase(__newsz - __old_size); 1752 __set_size(__newsz); 1753 traits_type::assign(__p[__newsz], value_type()); 1754 if (__old_size > __newsz) 1755 __annotate_shrink(__old_size); 1756 return *this; 1757 } 1758 1759 template <class _Tp> 1760 _LIBCPP_HIDE_FROM_ABI bool __addr_in_range(const _Tp& __v) const { 1761 return std::__is_pointer_in_range(data(), data() + size() + 1, std::addressof(__v)); 1762 } 1763 1764 _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void __throw_length_error() const { 1765 std::__throw_length_error("basic_string"); 1766 } 1767 1768 _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void __throw_out_of_range() const { 1769 std::__throw_out_of_range("basic_string"); 1770 } 1771 1772 friend basic_string operator+ <>(const basic_string&, const basic_string&); 1773 friend basic_string operator+ <>(const value_type*, const basic_string&); 1774 friend basic_string operator+ <>(value_type, const basic_string&); 1775 friend basic_string operator+ <>(const basic_string&, const value_type*); 1776 friend basic_string operator+ <>(const basic_string&, value_type); 1777}; 1778 1779// These declarations must appear before any functions are implicitly used 1780// so that they have the correct visibility specifier. 1781#define _LIBCPP_DECLARE(...) extern template __VA_ARGS__; 1782#ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION 1783_LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, char) 1784# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 1785_LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, wchar_t) 1786# endif 1787#else 1788_LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, char) 1789# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 1790_LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, wchar_t) 1791# endif 1792#endif 1793#undef _LIBCPP_DECLARE 1794 1795template <class _CharT, class _Traits, class _Allocator> 1796void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz, size_type __reserve) { 1797 if (__libcpp_is_constant_evaluated()) 1798 __r_.first() = __rep(); 1799 if (__reserve > max_size()) 1800 __throw_length_error(); 1801 pointer __p; 1802 if (__fits_in_sso(__reserve)) { 1803 __set_short_size(__sz); 1804 __p = __get_short_pointer(); 1805 } else { 1806 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__reserve) + 1); 1807 __p = __allocation.ptr; 1808 __begin_lifetime(__p, __allocation.count); 1809 __set_long_pointer(__p); 1810 __set_long_cap(__allocation.count); 1811 __set_long_size(__sz); 1812 } 1813 traits_type::copy(std::__to_address(__p), __s, __sz); 1814 traits_type::assign(__p[__sz], value_type()); 1815 __annotate_new(__sz); 1816} 1817 1818template <class _CharT, class _Traits, class _Allocator> 1819void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz) { 1820 if (__libcpp_is_constant_evaluated()) 1821 __r_.first() = __rep(); 1822 if (__sz > max_size()) 1823 __throw_length_error(); 1824 pointer __p; 1825 if (__fits_in_sso(__sz)) { 1826 __set_short_size(__sz); 1827 __p = __get_short_pointer(); 1828 } else { 1829 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1); 1830 __p = __allocation.ptr; 1831 __begin_lifetime(__p, __allocation.count); 1832 __set_long_pointer(__p); 1833 __set_long_cap(__allocation.count); 1834 __set_long_size(__sz); 1835 } 1836 traits_type::copy(std::__to_address(__p), __s, __sz); 1837 traits_type::assign(__p[__sz], value_type()); 1838 __annotate_new(__sz); 1839} 1840 1841template <class _CharT, class _Traits, class _Allocator> 1842_LIBCPP_NOINLINE void 1843basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external(const value_type* __s, size_type __sz) { 1844 if (__libcpp_is_constant_evaluated()) 1845 __r_.first() = __rep(); 1846 1847 pointer __p; 1848 if (__fits_in_sso(__sz)) { 1849 __p = __get_short_pointer(); 1850 __set_short_size(__sz); 1851 } else { 1852 if (__sz > max_size()) 1853 __throw_length_error(); 1854 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1); 1855 __p = __allocation.ptr; 1856 __begin_lifetime(__p, __allocation.count); 1857 __set_long_pointer(__p); 1858 __set_long_cap(__allocation.count); 1859 __set_long_size(__sz); 1860 } 1861 traits_type::copy(std::__to_address(__p), __s, __sz + 1); 1862 __annotate_new(__sz); 1863} 1864 1865template <class _CharT, class _Traits, class _Allocator> 1866void basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c) { 1867 if (__libcpp_is_constant_evaluated()) 1868 __r_.first() = __rep(); 1869 1870 if (__n > max_size()) 1871 __throw_length_error(); 1872 pointer __p; 1873 if (__fits_in_sso(__n)) { 1874 __set_short_size(__n); 1875 __p = __get_short_pointer(); 1876 } else { 1877 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__n) + 1); 1878 __p = __allocation.ptr; 1879 __begin_lifetime(__p, __allocation.count); 1880 __set_long_pointer(__p); 1881 __set_long_cap(__allocation.count); 1882 __set_long_size(__n); 1883 } 1884 traits_type::assign(std::__to_address(__p), __n, __c); 1885 traits_type::assign(__p[__n], value_type()); 1886 __annotate_new(__n); 1887} 1888 1889template <class _CharT, class _Traits, class _Allocator> 1890template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> > 1891void basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last) { 1892 __init_with_sentinel(std::move(__first), std::move(__last)); 1893} 1894 1895template <class _CharT, class _Traits, class _Allocator> 1896template <class _InputIterator, class _Sentinel> 1897_LIBCPP_HIDE_FROM_ABI void 1898basic_string<_CharT, _Traits, _Allocator>::__init_with_sentinel(_InputIterator __first, _Sentinel __last) { 1899 __r_.first() = __rep(); 1900 __annotate_new(0); 1901 1902#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 1903 try { 1904#endif // _LIBCPP_HAS_NO_EXCEPTIONS 1905 for (; __first != __last; ++__first) 1906 push_back(*__first); 1907#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 1908 } catch (...) { 1909 __annotate_delete(); 1910 if (__is_long()) 1911 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 1912 throw; 1913 } 1914#endif // _LIBCPP_HAS_NO_EXCEPTIONS 1915} 1916 1917template <class _CharT, class _Traits, class _Allocator> 1918template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> > 1919void basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last) { 1920 size_type __sz = static_cast<size_type>(std::distance(__first, __last)); 1921 __init_with_size(__first, __last, __sz); 1922} 1923 1924template <class _CharT, class _Traits, class _Allocator> 1925template <class _InputIterator, class _Sentinel> 1926_LIBCPP_HIDE_FROM_ABI void 1927basic_string<_CharT, _Traits, _Allocator>::__init_with_size(_InputIterator __first, _Sentinel __last, size_type __sz) { 1928 if (__libcpp_is_constant_evaluated()) 1929 __r_.first() = __rep(); 1930 1931 if (__sz > max_size()) 1932 __throw_length_error(); 1933 1934 pointer __p; 1935 if (__fits_in_sso(__sz)) { 1936 __set_short_size(__sz); 1937 __p = __get_short_pointer(); 1938 1939 } else { 1940 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1); 1941 __p = __allocation.ptr; 1942 __begin_lifetime(__p, __allocation.count); 1943 __set_long_pointer(__p); 1944 __set_long_cap(__allocation.count); 1945 __set_long_size(__sz); 1946 } 1947 1948#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 1949 try { 1950#endif // _LIBCPP_HAS_NO_EXCEPTIONS 1951 auto __end = __copy_non_overlapping_range(__first, __last, std::__to_address(__p)); 1952 traits_type::assign(*__end, value_type()); 1953#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 1954 } catch (...) { 1955 if (__is_long()) 1956 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 1957 throw; 1958 } 1959#endif // _LIBCPP_HAS_NO_EXCEPTIONS 1960 __annotate_new(__sz); 1961} 1962 1963template <class _CharT, class _Traits, class _Allocator> 1964void basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace( 1965 size_type __old_cap, 1966 size_type __delta_cap, 1967 size_type __old_sz, 1968 size_type __n_copy, 1969 size_type __n_del, 1970 size_type __n_add, 1971 const value_type* __p_new_stuff) { 1972 size_type __ms = max_size(); 1973 if (__delta_cap > __ms - __old_cap - 1) 1974 __throw_length_error(); 1975 pointer __old_p = __get_pointer(); 1976 size_type __cap = 1977 __old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms - 1; 1978 __annotate_delete(); 1979 auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1); 1980 pointer __p = __allocation.ptr; 1981 __begin_lifetime(__p, __allocation.count); 1982 if (__n_copy != 0) 1983 traits_type::copy(std::__to_address(__p), std::__to_address(__old_p), __n_copy); 1984 if (__n_add != 0) 1985 traits_type::copy(std::__to_address(__p) + __n_copy, __p_new_stuff, __n_add); 1986 size_type __sec_cp_sz = __old_sz - __n_del - __n_copy; 1987 if (__sec_cp_sz != 0) 1988 traits_type::copy( 1989 std::__to_address(__p) + __n_copy + __n_add, std::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz); 1990 if (__old_cap + 1 != __min_cap) 1991 __alloc_traits::deallocate(__alloc(), __old_p, __old_cap + 1); 1992 __set_long_pointer(__p); 1993 __set_long_cap(__allocation.count); 1994 __old_sz = __n_copy + __n_add + __sec_cp_sz; 1995 __set_long_size(__old_sz); 1996 traits_type::assign(__p[__old_sz], value_type()); 1997 __annotate_new(__old_sz); 1998} 1999 2000// __grow_by is deprecated because it does not set the size. It may not update the size when the size is changed, and it 2001// may also not set the size at all when the string was short initially. This leads to unpredictable size value. It is 2002// not removed or changed to avoid breaking the ABI. 2003template <class _CharT, class _Traits, class _Allocator> 2004void 2005#if _LIBCPP_ABI_VERSION >= 2 // We want to use the function in the dylib in ABIv1 2006 _LIBCPP_HIDE_FROM_ABI 2007#endif 2008 _LIBCPP_DEPRECATED_("use __grow_by_without_replace") basic_string<_CharT, _Traits, _Allocator>::__grow_by( 2009 size_type __old_cap, 2010 size_type __delta_cap, 2011 size_type __old_sz, 2012 size_type __n_copy, 2013 size_type __n_del, 2014 size_type __n_add) { 2015 size_type __ms = max_size(); 2016 if (__delta_cap > __ms - __old_cap) 2017 __throw_length_error(); 2018 pointer __old_p = __get_pointer(); 2019 size_type __cap = 2020 __old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms - 1; 2021 __annotate_delete(); 2022 auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1); 2023 pointer __p = __allocation.ptr; 2024 __begin_lifetime(__p, __allocation.count); 2025 if (__n_copy != 0) 2026 traits_type::copy(std::__to_address(__p), std::__to_address(__old_p), __n_copy); 2027 size_type __sec_cp_sz = __old_sz - __n_del - __n_copy; 2028 if (__sec_cp_sz != 0) 2029 traits_type::copy( 2030 std::__to_address(__p) + __n_copy + __n_add, std::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz); 2031 if (__old_cap + 1 != __min_cap) 2032 __alloc_traits::deallocate(__alloc(), __old_p, __old_cap + 1); 2033 __set_long_pointer(__p); 2034 __set_long_cap(__allocation.count); 2035} 2036 2037template <class _CharT, class _Traits, class _Allocator> 2038void _LIBCPP_HIDE_FROM_ABI basic_string<_CharT, _Traits, _Allocator>::__grow_by_without_replace( 2039 size_type __old_cap, 2040 size_type __delta_cap, 2041 size_type __old_sz, 2042 size_type __n_copy, 2043 size_type __n_del, 2044 size_type __n_add) { 2045 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 2046 __grow_by(__old_cap, __delta_cap, __old_sz, __n_copy, __n_del, __n_add); 2047 _LIBCPP_SUPPRESS_DEPRECATED_POP 2048 __set_long_size(__old_sz - __n_del + __n_add); 2049 __annotate_new(__old_sz - __n_del + __n_add); 2050} 2051 2052// assign 2053 2054template <class _CharT, class _Traits, class _Allocator> 2055template <bool __is_short> 2056_LIBCPP_NOINLINE basic_string<_CharT, _Traits, _Allocator>& 2057basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias(const value_type* __s, size_type __n) { 2058 size_type __cap = __is_short ? static_cast<size_type>(__min_cap) : __get_long_cap(); 2059 if (__n < __cap) { 2060 size_type __old_size = __is_short ? __get_short_size() : __get_long_size(); 2061 if (__n > __old_size) 2062 __annotate_increase(__n - __old_size); 2063 pointer __p = __is_short ? __get_short_pointer() : __get_long_pointer(); 2064 __is_short ? __set_short_size(__n) : __set_long_size(__n); 2065 traits_type::copy(std::__to_address(__p), __s, __n); 2066 traits_type::assign(__p[__n], value_type()); 2067 if (__old_size > __n) 2068 __annotate_shrink(__old_size); 2069 } else { 2070 size_type __sz = __is_short ? __get_short_size() : __get_long_size(); 2071 __grow_by_and_replace(__cap - 1, __n - __cap + 1, __sz, 0, __sz, __n, __s); 2072 } 2073 return *this; 2074} 2075 2076template <class _CharT, class _Traits, class _Allocator> 2077_LIBCPP_NOINLINE basic_string<_CharT, _Traits, _Allocator>& 2078basic_string<_CharT, _Traits, _Allocator>::__assign_external(const value_type* __s, size_type __n) { 2079 size_type __cap = capacity(); 2080 if (__cap >= __n) { 2081 size_type __old_size = size(); 2082 if (__n > __old_size) 2083 __annotate_increase(__n - __old_size); 2084 value_type* __p = std::__to_address(__get_pointer()); 2085 traits_type::move(__p, __s, __n); 2086 return __null_terminate_at(__p, __n); 2087 } else { 2088 size_type __sz = size(); 2089 __grow_by_and_replace(__cap, __n - __cap, __sz, 0, __sz, __n, __s); 2090 return *this; 2091 } 2092} 2093 2094template <class _CharT, class _Traits, class _Allocator> 2095basic_string<_CharT, _Traits, _Allocator>& 2096basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n) { 2097 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::assign received nullptr"); 2098 return (__builtin_constant_p(__n) && __fits_in_sso(__n)) ? __assign_short(__s, __n) : __assign_external(__s, __n); 2099} 2100 2101template <class _CharT, class _Traits, class _Allocator> 2102basic_string<_CharT, _Traits, _Allocator>& 2103basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c) { 2104 size_type __cap = capacity(); 2105 size_type __old_size = size(); 2106 if (__cap < __n) { 2107 size_type __sz = size(); 2108 __grow_by_without_replace(__cap, __n - __cap, __sz, 0, __sz); 2109 __annotate_increase(__n); 2110 } else if (__n > __old_size) 2111 __annotate_increase(__n - __old_size); 2112 value_type* __p = std::__to_address(__get_pointer()); 2113 traits_type::assign(__p, __n, __c); 2114 return __null_terminate_at(__p, __n); 2115} 2116 2117template <class _CharT, class _Traits, class _Allocator> 2118basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c) { 2119 pointer __p; 2120 size_type __old_size = size(); 2121 if (__old_size == 0) 2122 __annotate_increase(1); 2123 if (__is_long()) { 2124 __p = __get_long_pointer(); 2125 __set_long_size(1); 2126 } else { 2127 __p = __get_short_pointer(); 2128 __set_short_size(1); 2129 } 2130 traits_type::assign(*__p, __c); 2131 traits_type::assign(*++__p, value_type()); 2132 if (__old_size > 1) 2133 __annotate_shrink(__old_size); 2134 return *this; 2135} 2136 2137template <class _CharT, class _Traits, class _Allocator> 2138_LIBCPP_STRING_INTERNAL_MEMORY_ACCESS basic_string<_CharT, _Traits, _Allocator>& 2139basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str) { 2140 if (this != std::addressof(__str)) { 2141 __copy_assign_alloc(__str); 2142 if (!__is_long()) { 2143 if (!__str.__is_long()) { 2144 size_type __old_size = __get_short_size(); 2145 if (__get_short_size() < __str.__get_short_size()) 2146 __annotate_increase(__str.__get_short_size() - __get_short_size()); 2147 __r_.first() = __str.__r_.first(); 2148 if (__old_size > __get_short_size()) 2149 __annotate_shrink(__old_size); 2150 } else { 2151 return __assign_no_alias<true>(__str.data(), __str.size()); 2152 } 2153 } else { 2154 return __assign_no_alias<false>(__str.data(), __str.size()); 2155 } 2156 } 2157 return *this; 2158} 2159 2160template <class _CharT, class _Traits, class _Allocator> 2161template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> > 2162basic_string<_CharT, _Traits, _Allocator>& 2163basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last) { 2164 __assign_with_sentinel(__first, __last); 2165 return *this; 2166} 2167 2168template <class _CharT, class _Traits, class _Allocator> 2169template <class _InputIterator, class _Sentinel> 2170_LIBCPP_HIDE_FROM_ABI void 2171basic_string<_CharT, _Traits, _Allocator>::__assign_with_sentinel(_InputIterator __first, _Sentinel __last) { 2172 const basic_string __temp(__init_with_sentinel_tag(), std::move(__first), std::move(__last), __alloc()); 2173 assign(__temp.data(), __temp.size()); 2174} 2175 2176template <class _CharT, class _Traits, class _Allocator> 2177template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> > 2178basic_string<_CharT, _Traits, _Allocator>& 2179basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last) { 2180 if (__string_is_trivial_iterator<_ForwardIterator>::value) { 2181 size_type __n = static_cast<size_type>(std::distance(__first, __last)); 2182 __assign_trivial(__first, __last, __n); 2183 } else { 2184 __assign_with_sentinel(__first, __last); 2185 } 2186 2187 return *this; 2188} 2189 2190template <class _CharT, class _Traits, class _Allocator> 2191template <class _Iterator, class _Sentinel> 2192_LIBCPP_HIDE_FROM_ABI void 2193basic_string<_CharT, _Traits, _Allocator>::__assign_trivial(_Iterator __first, _Sentinel __last, size_type __n) { 2194 _LIBCPP_ASSERT_INTERNAL( 2195 __string_is_trivial_iterator<_Iterator>::value, "The iterator type given to `__assign_trivial` must be trivial"); 2196 2197 size_type __old_size = size(); 2198 size_type __cap = capacity(); 2199 if (__cap < __n) { 2200 // Unlike `append` functions, if the input range points into the string itself, there is no case that the input 2201 // range could get invalidated by reallocation: 2202 // 1. If the input range is a subset of the string itself, its size cannot exceed the capacity of the string, 2203 // thus no reallocation would happen. 2204 // 2. In the exotic case where the input range is the byte representation of the string itself, the string 2205 // object itself stays valid even if reallocation happens. 2206 size_type __sz = size(); 2207 __grow_by_without_replace(__cap, __n - __cap, __sz, 0, __sz); 2208 __annotate_increase(__n); 2209 } else if (__n > __old_size) 2210 __annotate_increase(__n - __old_size); 2211 pointer __p = __get_pointer(); 2212 for (; __first != __last; ++__p, (void)++__first) 2213 traits_type::assign(*__p, *__first); 2214 traits_type::assign(*__p, value_type()); 2215 __set_size(__n); 2216 if (__n < __old_size) 2217 __annotate_shrink(__old_size); 2218} 2219 2220template <class _CharT, class _Traits, class _Allocator> 2221basic_string<_CharT, _Traits, _Allocator>& 2222basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, size_type __pos, size_type __n) { 2223 size_type __sz = __str.size(); 2224 if (__pos > __sz) 2225 __throw_out_of_range(); 2226 return assign(__str.data() + __pos, std::min(__n, __sz - __pos)); 2227} 2228 2229template <class _CharT, class _Traits, class _Allocator> 2230template <class _Tp, 2231 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 2232 !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 2233 int> > 2234basic_string<_CharT, _Traits, _Allocator>& 2235basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp& __t, size_type __pos, size_type __n) { 2236 __self_view __sv = __t; 2237 size_type __sz = __sv.size(); 2238 if (__pos > __sz) 2239 __throw_out_of_range(); 2240 return assign(__sv.data() + __pos, std::min(__n, __sz - __pos)); 2241} 2242 2243template <class _CharT, class _Traits, class _Allocator> 2244_LIBCPP_NOINLINE basic_string<_CharT, _Traits, _Allocator>& 2245basic_string<_CharT, _Traits, _Allocator>::__assign_external(const value_type* __s) { 2246 return __assign_external(__s, traits_type::length(__s)); 2247} 2248 2249template <class _CharT, class _Traits, class _Allocator> 2250basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s) { 2251 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::assign received nullptr"); 2252 return __builtin_constant_p(*__s) 2253 ? (__fits_in_sso(traits_type::length(__s)) ? __assign_short(__s, traits_type::length(__s)) 2254 : __assign_external(__s, traits_type::length(__s))) 2255 : __assign_external(__s); 2256} 2257// append 2258 2259template <class _CharT, class _Traits, class _Allocator> 2260basic_string<_CharT, _Traits, _Allocator>& 2261basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n) { 2262 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::append received nullptr"); 2263 size_type __cap = capacity(); 2264 size_type __sz = size(); 2265 if (__cap - __sz >= __n) { 2266 if (__n) { 2267 __annotate_increase(__n); 2268 value_type* __p = std::__to_address(__get_pointer()); 2269 traits_type::copy(__p + __sz, __s, __n); 2270 __sz += __n; 2271 __set_size(__sz); 2272 traits_type::assign(__p[__sz], value_type()); 2273 } 2274 } else 2275 __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __sz, 0, __n, __s); 2276 return *this; 2277} 2278 2279template <class _CharT, class _Traits, class _Allocator> 2280basic_string<_CharT, _Traits, _Allocator>& 2281basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c) { 2282 if (__n) { 2283 size_type __cap = capacity(); 2284 size_type __sz = size(); 2285 if (__cap - __sz < __n) 2286 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0); 2287 __annotate_increase(__n); 2288 pointer __p = __get_pointer(); 2289 traits_type::assign(std::__to_address(__p) + __sz, __n, __c); 2290 __sz += __n; 2291 __set_size(__sz); 2292 traits_type::assign(__p[__sz], value_type()); 2293 } 2294 return *this; 2295} 2296 2297template <class _CharT, class _Traits, class _Allocator> 2298inline void basic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n) { 2299 if (__n) { 2300 size_type __cap = capacity(); 2301 size_type __sz = size(); 2302 if (__cap - __sz < __n) 2303 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0); 2304 __annotate_increase(__n); 2305 pointer __p = __get_pointer(); 2306 __sz += __n; 2307 __set_size(__sz); 2308 traits_type::assign(__p[__sz], value_type()); 2309 } 2310} 2311 2312template <class _CharT, class _Traits, class _Allocator> 2313void basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c) { 2314 bool __is_short = !__is_long(); 2315 size_type __cap; 2316 size_type __sz; 2317 if (__is_short) { 2318 __cap = __min_cap - 1; 2319 __sz = __get_short_size(); 2320 } else { 2321 __cap = __get_long_cap() - 1; 2322 __sz = __get_long_size(); 2323 } 2324 if (__sz == __cap) { 2325 __grow_by_without_replace(__cap, 1, __sz, __sz, 0); 2326 __annotate_increase(1); 2327 __is_short = false; // the string is always long after __grow_by 2328 } else 2329 __annotate_increase(1); 2330 pointer __p = __get_pointer(); 2331 if (__is_short) { 2332 __p = __get_short_pointer() + __sz; 2333 __set_short_size(__sz + 1); 2334 } else { 2335 __p = __get_long_pointer() + __sz; 2336 __set_long_size(__sz + 1); 2337 } 2338 traits_type::assign(*__p, __c); 2339 traits_type::assign(*++__p, value_type()); 2340} 2341 2342template <class _CharT, class _Traits, class _Allocator> 2343template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> > 2344basic_string<_CharT, _Traits, _Allocator>& 2345basic_string<_CharT, _Traits, _Allocator>::append(_ForwardIterator __first, _ForwardIterator __last) { 2346 size_type __sz = size(); 2347 size_type __cap = capacity(); 2348 size_type __n = static_cast<size_type>(std::distance(__first, __last)); 2349 if (__n) { 2350 if (__string_is_trivial_iterator<_ForwardIterator>::value && !__addr_in_range(*__first)) { 2351 if (__cap - __sz < __n) 2352 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0); 2353 __annotate_increase(__n); 2354 auto __end = __copy_non_overlapping_range(__first, __last, std::__to_address(__get_pointer() + __sz)); 2355 traits_type::assign(*__end, value_type()); 2356 __set_size(__sz + __n); 2357 } else { 2358 const basic_string __temp(__first, __last, __alloc()); 2359 append(__temp.data(), __temp.size()); 2360 } 2361 } 2362 return *this; 2363} 2364 2365template <class _CharT, class _Traits, class _Allocator> 2366basic_string<_CharT, _Traits, _Allocator>& 2367basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, size_type __pos, size_type __n) { 2368 size_type __sz = __str.size(); 2369 if (__pos > __sz) 2370 __throw_out_of_range(); 2371 return append(__str.data() + __pos, std::min(__n, __sz - __pos)); 2372} 2373 2374template <class _CharT, class _Traits, class _Allocator> 2375template <class _Tp, 2376 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 2377 !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 2378 int> > 2379basic_string<_CharT, _Traits, _Allocator>& 2380basic_string<_CharT, _Traits, _Allocator>::append(const _Tp& __t, size_type __pos, size_type __n) { 2381 __self_view __sv = __t; 2382 size_type __sz = __sv.size(); 2383 if (__pos > __sz) 2384 __throw_out_of_range(); 2385 return append(__sv.data() + __pos, std::min(__n, __sz - __pos)); 2386} 2387 2388template <class _CharT, class _Traits, class _Allocator> 2389basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s) { 2390 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::append received nullptr"); 2391 return append(__s, traits_type::length(__s)); 2392} 2393 2394// insert 2395 2396template <class _CharT, class _Traits, class _Allocator> 2397basic_string<_CharT, _Traits, _Allocator>& 2398basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n) { 2399 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::insert received nullptr"); 2400 size_type __sz = size(); 2401 if (__pos > __sz) 2402 __throw_out_of_range(); 2403 size_type __cap = capacity(); 2404 if (__cap - __sz >= __n) { 2405 if (__n) { 2406 __annotate_increase(__n); 2407 value_type* __p = std::__to_address(__get_pointer()); 2408 size_type __n_move = __sz - __pos; 2409 if (__n_move != 0) { 2410 if (std::__is_pointer_in_range(__p + __pos, __p + __sz, __s)) 2411 __s += __n; 2412 traits_type::move(__p + __pos + __n, __p + __pos, __n_move); 2413 } 2414 traits_type::move(__p + __pos, __s, __n); 2415 __sz += __n; 2416 __set_size(__sz); 2417 traits_type::assign(__p[__sz], value_type()); 2418 } 2419 } else 2420 __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s); 2421 return *this; 2422} 2423 2424template <class _CharT, class _Traits, class _Allocator> 2425basic_string<_CharT, _Traits, _Allocator>& 2426basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n, value_type __c) { 2427 size_type __sz = size(); 2428 if (__pos > __sz) 2429 __throw_out_of_range(); 2430 if (__n) { 2431 size_type __cap = capacity(); 2432 value_type* __p; 2433 if (__cap - __sz >= __n) { 2434 __annotate_increase(__n); 2435 __p = std::__to_address(__get_pointer()); 2436 size_type __n_move = __sz - __pos; 2437 if (__n_move != 0) 2438 traits_type::move(__p + __pos + __n, __p + __pos, __n_move); 2439 } else { 2440 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n); 2441 __p = std::__to_address(__get_long_pointer()); 2442 } 2443 traits_type::assign(__p + __pos, __n, __c); 2444 __sz += __n; 2445 __set_size(__sz); 2446 traits_type::assign(__p[__sz], value_type()); 2447 } 2448 return *this; 2449} 2450 2451template <class _CharT, class _Traits, class _Allocator> 2452template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> > 2453typename basic_string<_CharT, _Traits, _Allocator>::iterator 2454basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last) { 2455 const basic_string __temp(__first, __last, __alloc()); 2456 return insert(__pos, __temp.data(), __temp.data() + __temp.size()); 2457} 2458 2459template <class _CharT, class _Traits, class _Allocator> 2460template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> > 2461typename basic_string<_CharT, _Traits, _Allocator>::iterator basic_string<_CharT, _Traits, _Allocator>::insert( 2462 const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last) { 2463 auto __n = static_cast<size_type>(std::distance(__first, __last)); 2464 return __insert_with_size(__pos, __first, __last, __n); 2465} 2466 2467template <class _CharT, class _Traits, class _Allocator> 2468template <class _Iterator, class _Sentinel> 2469typename basic_string<_CharT, _Traits, _Allocator>::iterator 2470basic_string<_CharT, _Traits, _Allocator>::__insert_with_size( 2471 const_iterator __pos, _Iterator __first, _Sentinel __last, size_type __n) { 2472 size_type __ip = static_cast<size_type>(__pos - begin()); 2473 if (__n == 0) 2474 return begin() + __ip; 2475 2476 if (__string_is_trivial_iterator<_Iterator>::value && !__addr_in_range(*__first)) { 2477 return __insert_from_safe_copy(__n, __ip, __first, __last); 2478 } else { 2479 const basic_string __temp(__init_with_sentinel_tag(), __first, __last, __alloc()); 2480 return __insert_from_safe_copy(__n, __ip, __temp.begin(), __temp.end()); 2481 } 2482} 2483 2484template <class _CharT, class _Traits, class _Allocator> 2485basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::insert( 2486 size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n) { 2487 size_type __str_sz = __str.size(); 2488 if (__pos2 > __str_sz) 2489 __throw_out_of_range(); 2490 return insert(__pos1, __str.data() + __pos2, std::min(__n, __str_sz - __pos2)); 2491} 2492 2493template <class _CharT, class _Traits, class _Allocator> 2494template <class _Tp, 2495 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 2496 !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 2497 int> > 2498basic_string<_CharT, _Traits, _Allocator>& 2499basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n) { 2500 __self_view __sv = __t; 2501 size_type __str_sz = __sv.size(); 2502 if (__pos2 > __str_sz) 2503 __throw_out_of_range(); 2504 return insert(__pos1, __sv.data() + __pos2, std::min(__n, __str_sz - __pos2)); 2505} 2506 2507template <class _CharT, class _Traits, class _Allocator> 2508basic_string<_CharT, _Traits, _Allocator>& 2509basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s) { 2510 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::insert received nullptr"); 2511 return insert(__pos, __s, traits_type::length(__s)); 2512} 2513 2514template <class _CharT, class _Traits, class _Allocator> 2515typename basic_string<_CharT, _Traits, _Allocator>::iterator 2516basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c) { 2517 size_type __ip = static_cast<size_type>(__pos - begin()); 2518 size_type __sz = size(); 2519 size_type __cap = capacity(); 2520 value_type* __p; 2521 if (__cap == __sz) { 2522 __grow_by_without_replace(__cap, 1, __sz, __ip, 0, 1); 2523 __p = std::__to_address(__get_long_pointer()); 2524 } else { 2525 __annotate_increase(1); 2526 __p = std::__to_address(__get_pointer()); 2527 size_type __n_move = __sz - __ip; 2528 if (__n_move != 0) 2529 traits_type::move(__p + __ip + 1, __p + __ip, __n_move); 2530 } 2531 traits_type::assign(__p[__ip], __c); 2532 traits_type::assign(__p[++__sz], value_type()); 2533 __set_size(__sz); 2534 return begin() + static_cast<difference_type>(__ip); 2535} 2536 2537// replace 2538 2539template <class _CharT, class _Traits, class _Allocator> 2540basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace( 2541 size_type __pos, size_type __n1, const value_type* __s, size_type __n2) 2542 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK { 2543 _LIBCPP_ASSERT_NON_NULL(__n2 == 0 || __s != nullptr, "string::replace received nullptr"); 2544 size_type __sz = size(); 2545 if (__pos > __sz) 2546 __throw_out_of_range(); 2547 __n1 = std::min(__n1, __sz - __pos); 2548 size_type __cap = capacity(); 2549 if (__cap - __sz + __n1 >= __n2) { 2550 value_type* __p = std::__to_address(__get_pointer()); 2551 if (__n1 != __n2) { 2552 if (__n2 > __n1) 2553 __annotate_increase(__n2 - __n1); 2554 size_type __n_move = __sz - __pos - __n1; 2555 if (__n_move != 0) { 2556 if (__n1 > __n2) { 2557 traits_type::move(__p + __pos, __s, __n2); 2558 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move); 2559 return __null_terminate_at(__p, __sz + (__n2 - __n1)); 2560 } 2561 if (std::__is_pointer_in_range(__p + __pos + 1, __p + __sz, __s)) { 2562 if (__p + __pos + __n1 <= __s) 2563 __s += __n2 - __n1; 2564 else // __p + __pos < __s < __p + __pos + __n1 2565 { 2566 traits_type::move(__p + __pos, __s, __n1); 2567 __pos += __n1; 2568 __s += __n2; 2569 __n2 -= __n1; 2570 __n1 = 0; 2571 } 2572 } 2573 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move); 2574 } 2575 } 2576 traits_type::move(__p + __pos, __s, __n2); 2577 return __null_terminate_at(__p, __sz + (__n2 - __n1)); 2578 } else 2579 __grow_by_and_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2, __s); 2580 return *this; 2581} 2582 2583template <class _CharT, class _Traits, class _Allocator> 2584basic_string<_CharT, _Traits, _Allocator>& 2585basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, size_type __n2, value_type __c) { 2586 size_type __sz = size(); 2587 if (__pos > __sz) 2588 __throw_out_of_range(); 2589 __n1 = std::min(__n1, __sz - __pos); 2590 size_type __cap = capacity(); 2591 value_type* __p; 2592 if (__cap - __sz + __n1 >= __n2) { 2593 __p = std::__to_address(__get_pointer()); 2594 if (__n1 != __n2) { 2595 if (__n2 > __n1) 2596 __annotate_increase(__n2 - __n1); 2597 size_type __n_move = __sz - __pos - __n1; 2598 if (__n_move != 0) 2599 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move); 2600 } 2601 } else { 2602 __grow_by_without_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2); 2603 __p = std::__to_address(__get_long_pointer()); 2604 } 2605 traits_type::assign(__p + __pos, __n2, __c); 2606 return __null_terminate_at(__p, __sz - (__n1 - __n2)); 2607} 2608 2609template <class _CharT, class _Traits, class _Allocator> 2610template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> > 2611basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace( 2612 const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2) { 2613 const basic_string __temp(__j1, __j2, __alloc()); 2614 return replace(__i1, __i2, __temp); 2615} 2616 2617template <class _CharT, class _Traits, class _Allocator> 2618basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace( 2619 size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2) { 2620 size_type __str_sz = __str.size(); 2621 if (__pos2 > __str_sz) 2622 __throw_out_of_range(); 2623 return replace(__pos1, __n1, __str.data() + __pos2, std::min(__n2, __str_sz - __pos2)); 2624} 2625 2626template <class _CharT, class _Traits, class _Allocator> 2627template <class _Tp, 2628 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 2629 !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 2630 int> > 2631basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace( 2632 size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2) { 2633 __self_view __sv = __t; 2634 size_type __str_sz = __sv.size(); 2635 if (__pos2 > __str_sz) 2636 __throw_out_of_range(); 2637 return replace(__pos1, __n1, __sv.data() + __pos2, std::min(__n2, __str_sz - __pos2)); 2638} 2639 2640template <class _CharT, class _Traits, class _Allocator> 2641basic_string<_CharT, _Traits, _Allocator>& 2642basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s) { 2643 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::replace received nullptr"); 2644 return replace(__pos, __n1, __s, traits_type::length(__s)); 2645} 2646 2647// erase 2648 2649// 'externally instantiated' erase() implementation, called when __n != npos. 2650// Does not check __pos against size() 2651template <class _CharT, class _Traits, class _Allocator> 2652_LIBCPP_NOINLINE void 2653basic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move(size_type __pos, size_type __n) { 2654 if (__n) { 2655 size_type __sz = size(); 2656 value_type* __p = std::__to_address(__get_pointer()); 2657 __n = std::min(__n, __sz - __pos); 2658 size_type __n_move = __sz - __pos - __n; 2659 if (__n_move != 0) 2660 traits_type::move(__p + __pos, __p + __pos + __n, __n_move); 2661 __null_terminate_at(__p, __sz - __n); 2662 } 2663} 2664 2665template <class _CharT, class _Traits, class _Allocator> 2666basic_string<_CharT, _Traits, _Allocator>& 2667basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, size_type __n) { 2668 if (__pos > size()) 2669 __throw_out_of_range(); 2670 if (__n == npos) { 2671 __erase_to_end(__pos); 2672 } else { 2673 __erase_external_with_move(__pos, __n); 2674 } 2675 return *this; 2676} 2677 2678template <class _CharT, class _Traits, class _Allocator> 2679inline typename basic_string<_CharT, _Traits, _Allocator>::iterator 2680basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos) { 2681 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 2682 __pos != end(), "string::erase(iterator) called with a non-dereferenceable iterator"); 2683 iterator __b = begin(); 2684 size_type __r = static_cast<size_type>(__pos - __b); 2685 erase(__r, 1); 2686 return __b + static_cast<difference_type>(__r); 2687} 2688 2689template <class _CharT, class _Traits, class _Allocator> 2690inline typename basic_string<_CharT, _Traits, _Allocator>::iterator 2691basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last) { 2692 _LIBCPP_ASSERT_VALID_INPUT_RANGE(__first <= __last, "string::erase(first, last) called with invalid range"); 2693 iterator __b = begin(); 2694 size_type __r = static_cast<size_type>(__first - __b); 2695 erase(__r, static_cast<size_type>(__last - __first)); 2696 return __b + static_cast<difference_type>(__r); 2697} 2698 2699template <class _CharT, class _Traits, class _Allocator> 2700inline void basic_string<_CharT, _Traits, _Allocator>::pop_back() { 2701 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::pop_back(): string is already empty"); 2702 __erase_to_end(size() - 1); 2703} 2704 2705template <class _CharT, class _Traits, class _Allocator> 2706inline void basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT { 2707 size_type __old_size = size(); 2708 if (__is_long()) { 2709 traits_type::assign(*__get_long_pointer(), value_type()); 2710 __set_long_size(0); 2711 } else { 2712 traits_type::assign(*__get_short_pointer(), value_type()); 2713 __set_short_size(0); 2714 } 2715 __annotate_shrink(__old_size); 2716} 2717 2718template <class _CharT, class _Traits, class _Allocator> 2719void basic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c) { 2720 size_type __sz = size(); 2721 if (__n > __sz) 2722 append(__n - __sz, __c); 2723 else 2724 __erase_to_end(__n); 2725} 2726 2727template <class _CharT, class _Traits, class _Allocator> 2728inline void basic_string<_CharT, _Traits, _Allocator>::__resize_default_init(size_type __n) { 2729 size_type __sz = size(); 2730 if (__n > __sz) { 2731 __append_default_init(__n - __sz); 2732 } else 2733 __erase_to_end(__n); 2734} 2735 2736template <class _CharT, class _Traits, class _Allocator> 2737void basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacity) { 2738 if (__requested_capacity > max_size()) 2739 __throw_length_error(); 2740 2741 // Make sure reserve(n) never shrinks. This is technically only required in C++20 2742 // and later (since P0966R1), however we provide consistent behavior in all Standard 2743 // modes because this function is instantiated in the shared library. 2744 if (__requested_capacity <= capacity()) 2745 return; 2746 2747 size_type __target_capacity = std::max(__requested_capacity, size()); 2748 __target_capacity = __recommend(__target_capacity); 2749 if (__target_capacity == capacity()) 2750 return; 2751 2752 __shrink_or_extend(__target_capacity); 2753} 2754 2755template <class _CharT, class _Traits, class _Allocator> 2756inline void basic_string<_CharT, _Traits, _Allocator>::shrink_to_fit() _NOEXCEPT { 2757 size_type __target_capacity = __recommend(size()); 2758 if (__target_capacity == capacity()) 2759 return; 2760 2761 __shrink_or_extend(__target_capacity); 2762} 2763 2764template <class _CharT, class _Traits, class _Allocator> 2765inline void basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target_capacity) { 2766 __annotate_delete(); 2767 size_type __cap = capacity(); 2768 size_type __sz = size(); 2769 2770 pointer __new_data, __p; 2771 bool __was_long, __now_long; 2772 if (__fits_in_sso(__target_capacity)) { 2773 __was_long = true; 2774 __now_long = false; 2775 __new_data = __get_short_pointer(); 2776 __p = __get_long_pointer(); 2777 } else { 2778 if (__target_capacity > __cap) { 2779 // Extend 2780 // - called from reserve should propagate the exception thrown. 2781 auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1); 2782 __new_data = __allocation.ptr; 2783 __target_capacity = __allocation.count - 1; 2784 } else { 2785 // Shrink 2786 // - called from shrink_to_fit should not throw. 2787 // - called from reserve may throw but is not required to. 2788#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 2789 try { 2790#endif // _LIBCPP_HAS_NO_EXCEPTIONS 2791 auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1); 2792 2793 // The Standard mandates shrink_to_fit() does not increase the capacity. 2794 // With equal capacity keep the existing buffer. This avoids extra work 2795 // due to swapping the elements. 2796 if (__allocation.count - 1 > __target_capacity) { 2797 __alloc_traits::deallocate(__alloc(), __allocation.ptr, __allocation.count); 2798 __annotate_new(__sz); // Undoes the __annotate_delete() 2799 return; 2800 } 2801 __new_data = __allocation.ptr; 2802 __target_capacity = __allocation.count - 1; 2803#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 2804 } catch (...) { 2805 return; 2806 } 2807#endif // _LIBCPP_HAS_NO_EXCEPTIONS 2808 } 2809 __begin_lifetime(__new_data, __target_capacity + 1); 2810 __now_long = true; 2811 __was_long = __is_long(); 2812 __p = __get_pointer(); 2813 } 2814 traits_type::copy(std::__to_address(__new_data), std::__to_address(__p), size() + 1); 2815 if (__was_long) 2816 __alloc_traits::deallocate(__alloc(), __p, __cap + 1); 2817 if (__now_long) { 2818 __set_long_cap(__target_capacity + 1); 2819 __set_long_size(__sz); 2820 __set_long_pointer(__new_data); 2821 } else 2822 __set_short_size(__sz); 2823 __annotate_new(__sz); 2824} 2825 2826template <class _CharT, class _Traits, class _Allocator> 2827typename basic_string<_CharT, _Traits, _Allocator>::const_reference 2828basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const { 2829 if (__n >= size()) 2830 __throw_out_of_range(); 2831 return (*this)[__n]; 2832} 2833 2834template <class _CharT, class _Traits, class _Allocator> 2835typename basic_string<_CharT, _Traits, _Allocator>::reference 2836basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) { 2837 if (__n >= size()) 2838 __throw_out_of_range(); 2839 return (*this)[__n]; 2840} 2841 2842template <class _CharT, class _Traits, class _Allocator> 2843typename basic_string<_CharT, _Traits, _Allocator>::size_type 2844basic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n, size_type __pos) const { 2845 size_type __sz = size(); 2846 if (__pos > __sz) 2847 __throw_out_of_range(); 2848 size_type __rlen = std::min(__n, __sz - __pos); 2849 traits_type::copy(__s, data() + __pos, __rlen); 2850 return __rlen; 2851} 2852 2853template <class _CharT, class _Traits, class _Allocator> 2854inline void basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str) { 2855 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR( 2856 __alloc_traits::propagate_on_container_swap::value || __alloc_traits::is_always_equal::value || 2857 __alloc() == __str.__alloc(), 2858 "swapping non-equal allocators"); 2859 if (!__is_long()) 2860 __annotate_delete(); 2861 if (this != &__str && !__str.__is_long()) 2862 __str.__annotate_delete(); 2863 std::swap(__r_.first(), __str.__r_.first()); 2864 std::__swap_allocator(__alloc(), __str.__alloc()); 2865 if (!__is_long()) 2866 __annotate_new(__get_short_size()); 2867 if (this != &__str && !__str.__is_long()) 2868 __str.__annotate_new(__str.__get_short_size()); 2869} 2870 2871// find 2872 2873template <class _Traits> 2874struct _LIBCPP_HIDDEN __traits_eq { 2875 typedef typename _Traits::char_type char_type; 2876 _LIBCPP_HIDE_FROM_ABI bool operator()(const char_type& __x, const char_type& __y) _NOEXCEPT { 2877 return _Traits::eq(__x, __y); 2878 } 2879}; 2880 2881template <class _CharT, class _Traits, class _Allocator> 2882typename basic_string<_CharT, _Traits, _Allocator>::size_type 2883basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT { 2884 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find(): received nullptr"); 2885 return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); 2886} 2887 2888template <class _CharT, class _Traits, class _Allocator> 2889inline typename basic_string<_CharT, _Traits, _Allocator>::size_type 2890basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str, size_type __pos) const _NOEXCEPT { 2891 return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __str.data(), __pos, __str.size()); 2892} 2893 2894template <class _CharT, class _Traits, class _Allocator> 2895template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 2896typename basic_string<_CharT, _Traits, _Allocator>::size_type 2897basic_string<_CharT, _Traits, _Allocator>::find(const _Tp& __t, size_type __pos) const _NOEXCEPT { 2898 __self_view __sv = __t; 2899 return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __sv.data(), __pos, __sv.size()); 2900} 2901 2902template <class _CharT, class _Traits, class _Allocator> 2903inline typename basic_string<_CharT, _Traits, _Allocator>::size_type 2904basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, size_type __pos) const _NOEXCEPT { 2905 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find(): received nullptr"); 2906 return std::__str_find<value_type, size_type, traits_type, npos>( 2907 data(), size(), __s, __pos, traits_type::length(__s)); 2908} 2909 2910template <class _CharT, class _Traits, class _Allocator> 2911typename basic_string<_CharT, _Traits, _Allocator>::size_type 2912basic_string<_CharT, _Traits, _Allocator>::find(value_type __c, size_type __pos) const _NOEXCEPT { 2913 return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos); 2914} 2915 2916// rfind 2917 2918template <class _CharT, class _Traits, class _Allocator> 2919typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::rfind( 2920 const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT { 2921 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::rfind(): received nullptr"); 2922 return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); 2923} 2924 2925template <class _CharT, class _Traits, class _Allocator> 2926inline typename basic_string<_CharT, _Traits, _Allocator>::size_type 2927basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str, size_type __pos) const _NOEXCEPT { 2928 return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __str.data(), __pos, __str.size()); 2929} 2930 2931template <class _CharT, class _Traits, class _Allocator> 2932template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 2933typename basic_string<_CharT, _Traits, _Allocator>::size_type 2934basic_string<_CharT, _Traits, _Allocator>::rfind(const _Tp& __t, size_type __pos) const _NOEXCEPT { 2935 __self_view __sv = __t; 2936 return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __sv.data(), __pos, __sv.size()); 2937} 2938 2939template <class _CharT, class _Traits, class _Allocator> 2940inline typename basic_string<_CharT, _Traits, _Allocator>::size_type 2941basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, size_type __pos) const _NOEXCEPT { 2942 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::rfind(): received nullptr"); 2943 return std::__str_rfind<value_type, size_type, traits_type, npos>( 2944 data(), size(), __s, __pos, traits_type::length(__s)); 2945} 2946 2947template <class _CharT, class _Traits, class _Allocator> 2948typename basic_string<_CharT, _Traits, _Allocator>::size_type 2949basic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c, size_type __pos) const _NOEXCEPT { 2950 return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos); 2951} 2952 2953// find_first_of 2954 2955template <class _CharT, class _Traits, class _Allocator> 2956typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_first_of( 2957 const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT { 2958 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr"); 2959 return std::__str_find_first_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); 2960} 2961 2962template <class _CharT, class _Traits, class _Allocator> 2963inline typename basic_string<_CharT, _Traits, _Allocator>::size_type 2964basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str, size_type __pos) const _NOEXCEPT { 2965 return std::__str_find_first_of<value_type, size_type, traits_type, npos>( 2966 data(), size(), __str.data(), __pos, __str.size()); 2967} 2968 2969template <class _CharT, class _Traits, class _Allocator> 2970template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 2971typename basic_string<_CharT, _Traits, _Allocator>::size_type 2972basic_string<_CharT, _Traits, _Allocator>::find_first_of(const _Tp& __t, size_type __pos) const _NOEXCEPT { 2973 __self_view __sv = __t; 2974 return std::__str_find_first_of<value_type, size_type, traits_type, npos>( 2975 data(), size(), __sv.data(), __pos, __sv.size()); 2976} 2977 2978template <class _CharT, class _Traits, class _Allocator> 2979inline typename basic_string<_CharT, _Traits, _Allocator>::size_type 2980basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, size_type __pos) const _NOEXCEPT { 2981 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_first_of(): received nullptr"); 2982 return std::__str_find_first_of<value_type, size_type, traits_type, npos>( 2983 data(), size(), __s, __pos, traits_type::length(__s)); 2984} 2985 2986template <class _CharT, class _Traits, class _Allocator> 2987inline typename basic_string<_CharT, _Traits, _Allocator>::size_type 2988basic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c, size_type __pos) const _NOEXCEPT { 2989 return find(__c, __pos); 2990} 2991 2992// find_last_of 2993 2994template <class _CharT, class _Traits, class _Allocator> 2995inline typename basic_string<_CharT, _Traits, _Allocator>::size_type 2996basic_string<_CharT, _Traits, _Allocator>::find_last_of( 2997 const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT { 2998 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr"); 2999 return std::__str_find_last_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); 3000} 3001 3002template <class _CharT, class _Traits, class _Allocator> 3003inline typename basic_string<_CharT, _Traits, _Allocator>::size_type 3004basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str, size_type __pos) const _NOEXCEPT { 3005 return std::__str_find_last_of<value_type, size_type, traits_type, npos>( 3006 data(), size(), __str.data(), __pos, __str.size()); 3007} 3008 3009template <class _CharT, class _Traits, class _Allocator> 3010template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 3011typename basic_string<_CharT, _Traits, _Allocator>::size_type 3012basic_string<_CharT, _Traits, _Allocator>::find_last_of(const _Tp& __t, size_type __pos) const _NOEXCEPT { 3013 __self_view __sv = __t; 3014 return std::__str_find_last_of<value_type, size_type, traits_type, npos>( 3015 data(), size(), __sv.data(), __pos, __sv.size()); 3016} 3017 3018template <class _CharT, class _Traits, class _Allocator> 3019inline typename basic_string<_CharT, _Traits, _Allocator>::size_type 3020basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, size_type __pos) const _NOEXCEPT { 3021 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_last_of(): received nullptr"); 3022 return std::__str_find_last_of<value_type, size_type, traits_type, npos>( 3023 data(), size(), __s, __pos, traits_type::length(__s)); 3024} 3025 3026template <class _CharT, class _Traits, class _Allocator> 3027inline typename basic_string<_CharT, _Traits, _Allocator>::size_type 3028basic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c, size_type __pos) const _NOEXCEPT { 3029 return rfind(__c, __pos); 3030} 3031 3032// find_first_not_of 3033 3034template <class _CharT, class _Traits, class _Allocator> 3035typename basic_string<_CharT, _Traits, _Allocator>::size_type 3036basic_string<_CharT, _Traits, _Allocator>::find_first_not_of( 3037 const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT { 3038 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr"); 3039 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); 3040} 3041 3042template <class _CharT, class _Traits, class _Allocator> 3043inline typename basic_string<_CharT, _Traits, _Allocator>::size_type 3044basic_string<_CharT, _Traits, _Allocator>::find_first_not_of( 3045 const basic_string& __str, size_type __pos) const _NOEXCEPT { 3046 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>( 3047 data(), size(), __str.data(), __pos, __str.size()); 3048} 3049 3050template <class _CharT, class _Traits, class _Allocator> 3051template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 3052typename basic_string<_CharT, _Traits, _Allocator>::size_type 3053basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const _Tp& __t, size_type __pos) const _NOEXCEPT { 3054 __self_view __sv = __t; 3055 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>( 3056 data(), size(), __sv.data(), __pos, __sv.size()); 3057} 3058 3059template <class _CharT, class _Traits, class _Allocator> 3060inline typename basic_string<_CharT, _Traits, _Allocator>::size_type 3061basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s, size_type __pos) const _NOEXCEPT { 3062 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_first_not_of(): received nullptr"); 3063 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>( 3064 data(), size(), __s, __pos, traits_type::length(__s)); 3065} 3066 3067template <class _CharT, class _Traits, class _Allocator> 3068inline typename basic_string<_CharT, _Traits, _Allocator>::size_type 3069basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c, size_type __pos) const _NOEXCEPT { 3070 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos); 3071} 3072 3073// find_last_not_of 3074 3075template <class _CharT, class _Traits, class _Allocator> 3076typename basic_string<_CharT, _Traits, _Allocator>::size_type 3077basic_string<_CharT, _Traits, _Allocator>::find_last_not_of( 3078 const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT { 3079 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr"); 3080 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); 3081} 3082 3083template <class _CharT, class _Traits, class _Allocator> 3084inline typename basic_string<_CharT, _Traits, _Allocator>::size_type 3085basic_string<_CharT, _Traits, _Allocator>::find_last_not_of( 3086 const basic_string& __str, size_type __pos) const _NOEXCEPT { 3087 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>( 3088 data(), size(), __str.data(), __pos, __str.size()); 3089} 3090 3091template <class _CharT, class _Traits, class _Allocator> 3092template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 3093typename basic_string<_CharT, _Traits, _Allocator>::size_type 3094basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const _Tp& __t, size_type __pos) const _NOEXCEPT { 3095 __self_view __sv = __t; 3096 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>( 3097 data(), size(), __sv.data(), __pos, __sv.size()); 3098} 3099 3100template <class _CharT, class _Traits, class _Allocator> 3101inline typename basic_string<_CharT, _Traits, _Allocator>::size_type 3102basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s, size_type __pos) const _NOEXCEPT { 3103 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_last_not_of(): received nullptr"); 3104 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>( 3105 data(), size(), __s, __pos, traits_type::length(__s)); 3106} 3107 3108template <class _CharT, class _Traits, class _Allocator> 3109inline typename basic_string<_CharT, _Traits, _Allocator>::size_type 3110basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c, size_type __pos) const _NOEXCEPT { 3111 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos); 3112} 3113 3114// compare 3115 3116template <class _CharT, class _Traits, class _Allocator> 3117template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 3118int basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const _NOEXCEPT { 3119 __self_view __sv = __t; 3120 size_t __lhs_sz = size(); 3121 size_t __rhs_sz = __sv.size(); 3122 int __result = traits_type::compare(data(), __sv.data(), std::min(__lhs_sz, __rhs_sz)); 3123 if (__result != 0) 3124 return __result; 3125 if (__lhs_sz < __rhs_sz) 3126 return -1; 3127 if (__lhs_sz > __rhs_sz) 3128 return 1; 3129 return 0; 3130} 3131 3132template <class _CharT, class _Traits, class _Allocator> 3133inline int basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT { 3134 return compare(__self_view(__str)); 3135} 3136 3137template <class _CharT, class _Traits, class _Allocator> 3138inline int basic_string<_CharT, _Traits, _Allocator>::compare( 3139 size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const { 3140 _LIBCPP_ASSERT_NON_NULL(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr"); 3141 size_type __sz = size(); 3142 if (__pos1 > __sz || __n2 == npos) 3143 __throw_out_of_range(); 3144 size_type __rlen = std::min(__n1, __sz - __pos1); 3145 int __r = traits_type::compare(data() + __pos1, __s, std::min(__rlen, __n2)); 3146 if (__r == 0) { 3147 if (__rlen < __n2) 3148 __r = -1; 3149 else if (__rlen > __n2) 3150 __r = 1; 3151 } 3152 return __r; 3153} 3154 3155template <class _CharT, class _Traits, class _Allocator> 3156template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 3157int basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, const _Tp& __t) const { 3158 __self_view __sv = __t; 3159 return compare(__pos1, __n1, __sv.data(), __sv.size()); 3160} 3161 3162template <class _CharT, class _Traits, class _Allocator> 3163inline int 3164basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, const basic_string& __str) const { 3165 return compare(__pos1, __n1, __str.data(), __str.size()); 3166} 3167 3168template <class _CharT, class _Traits, class _Allocator> 3169template <class _Tp, 3170 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 3171 !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 3172 int> > 3173int basic_string<_CharT, _Traits, _Allocator>::compare( 3174 size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2) const { 3175 __self_view __sv = __t; 3176 return __self_view(*this).substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2)); 3177} 3178 3179template <class _CharT, class _Traits, class _Allocator> 3180int basic_string<_CharT, _Traits, _Allocator>::compare( 3181 size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2) const { 3182 return compare(__pos1, __n1, __self_view(__str), __pos2, __n2); 3183} 3184 3185template <class _CharT, class _Traits, class _Allocator> 3186int basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT { 3187 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::compare(): received nullptr"); 3188 return compare(0, npos, __s, traits_type::length(__s)); 3189} 3190 3191template <class _CharT, class _Traits, class _Allocator> 3192int basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, const value_type* __s) const { 3193 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::compare(): received nullptr"); 3194 return compare(__pos1, __n1, __s, traits_type::length(__s)); 3195} 3196 3197// __invariants 3198 3199template <class _CharT, class _Traits, class _Allocator> 3200inline bool basic_string<_CharT, _Traits, _Allocator>::__invariants() const { 3201 if (size() > capacity()) 3202 return false; 3203 if (capacity() < __min_cap - 1) 3204 return false; 3205 if (data() == nullptr) 3206 return false; 3207 if (!_Traits::eq(data()[size()], value_type())) 3208 return false; 3209 return true; 3210} 3211 3212// __clear_and_shrink 3213 3214template <class _CharT, class _Traits, class _Allocator> 3215inline void basic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT { 3216 clear(); 3217 if (__is_long()) { 3218 __annotate_delete(); 3219 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), capacity() + 1); 3220 __r_.first() = __rep(); 3221 } 3222} 3223 3224// operator== 3225 3226template <class _CharT, class _Traits, class _Allocator> 3227inline _LIBCPP_HIDE_FROM_ABI bool operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3228 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 3229 size_t __lhs_sz = __lhs.size(); 3230 return __lhs_sz == __rhs.size() && _Traits::compare(__lhs.data(), __rhs.data(), __lhs_sz) == 0; 3231} 3232 3233template <class _Allocator> 3234inline _LIBCPP_HIDE_FROM_ABI bool operator==(const basic_string<char, char_traits<char>, _Allocator>& __lhs, 3235 const basic_string<char, char_traits<char>, _Allocator>& __rhs) _NOEXCEPT { 3236 size_t __sz = __lhs.size(); 3237 if (__sz != __rhs.size()) 3238 return false; 3239 return char_traits<char>::compare(__lhs.data(), __rhs.data(), __sz) == 0; 3240} 3241 3242template <class _CharT, class _Traits, class _Allocator> 3243inline _LIBCPP_HIDE_FROM_ABI bool 3244operator==(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 3245 typedef basic_string<_CharT, _Traits, _Allocator> _String; 3246 _LIBCPP_ASSERT_NON_NULL(__lhs != nullptr, "operator==(char*, basic_string): received nullptr"); 3247 size_t __lhs_len = _Traits::length(__lhs); 3248 if (__lhs_len != __rhs.size()) 3249 return false; 3250 return __rhs.compare(0, _String::npos, __lhs, __lhs_len) == 0; 3251} 3252 3253template <class _CharT, class _Traits, class _Allocator> 3254inline _LIBCPP_HIDE_FROM_ABI bool 3255operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT { 3256 typedef basic_string<_CharT, _Traits, _Allocator> _String; 3257 _LIBCPP_ASSERT_NON_NULL(__rhs != nullptr, "operator==(basic_string, char*): received nullptr"); 3258 size_t __rhs_len = _Traits::length(__rhs); 3259 if (__rhs_len != __lhs.size()) 3260 return false; 3261 return __lhs.compare(0, _String::npos, __rhs, __rhs_len) == 0; 3262} 3263 3264template <class _CharT, class _Traits, class _Allocator> 3265inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3266 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 3267 return !(__lhs == __rhs); 3268} 3269 3270template <class _CharT, class _Traits, class _Allocator> 3271inline _LIBCPP_HIDE_FROM_ABI bool 3272operator!=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 3273 return !(__lhs == __rhs); 3274} 3275 3276template <class _CharT, class _Traits, class _Allocator> 3277inline _LIBCPP_HIDE_FROM_ABI bool 3278operator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT { 3279 return !(__lhs == __rhs); 3280} 3281 3282// operator< 3283 3284template <class _CharT, class _Traits, class _Allocator> 3285inline _LIBCPP_HIDE_FROM_ABI bool operator<(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3286 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 3287 return __lhs.compare(__rhs) < 0; 3288} 3289 3290template <class _CharT, class _Traits, class _Allocator> 3291inline _LIBCPP_HIDE_FROM_ABI bool 3292operator<(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT { 3293 return __lhs.compare(__rhs) < 0; 3294} 3295 3296template <class _CharT, class _Traits, class _Allocator> 3297inline _LIBCPP_HIDE_FROM_ABI bool 3298operator<(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 3299 return __rhs.compare(__lhs) > 0; 3300} 3301 3302// operator> 3303 3304template <class _CharT, class _Traits, class _Allocator> 3305inline _LIBCPP_HIDE_FROM_ABI bool operator>(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3306 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 3307 return __rhs < __lhs; 3308} 3309 3310template <class _CharT, class _Traits, class _Allocator> 3311inline _LIBCPP_HIDE_FROM_ABI bool 3312operator>(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT { 3313 return __rhs < __lhs; 3314} 3315 3316template <class _CharT, class _Traits, class _Allocator> 3317inline _LIBCPP_HIDE_FROM_ABI bool 3318operator>(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 3319 return __rhs < __lhs; 3320} 3321 3322// operator<= 3323 3324template <class _CharT, class _Traits, class _Allocator> 3325inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3326 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 3327 return !(__rhs < __lhs); 3328} 3329 3330template <class _CharT, class _Traits, class _Allocator> 3331inline _LIBCPP_HIDE_FROM_ABI bool 3332operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT { 3333 return !(__rhs < __lhs); 3334} 3335 3336template <class _CharT, class _Traits, class _Allocator> 3337inline _LIBCPP_HIDE_FROM_ABI bool 3338operator<=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 3339 return !(__rhs < __lhs); 3340} 3341 3342// operator>= 3343 3344template <class _CharT, class _Traits, class _Allocator> 3345inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3346 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 3347 return !(__lhs < __rhs); 3348} 3349 3350template <class _CharT, class _Traits, class _Allocator> 3351inline _LIBCPP_HIDE_FROM_ABI bool 3352operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT { 3353 return !(__lhs < __rhs); 3354} 3355 3356template <class _CharT, class _Traits, class _Allocator> 3357inline _LIBCPP_HIDE_FROM_ABI bool 3358operator>=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 3359 return !(__lhs < __rhs); 3360} 3361 3362// operator + 3363 3364template <class _CharT, class _Traits, class _Allocator> 3365_LIBCPP_HIDE_FROM_ABI basic_string<_CharT, _Traits, _Allocator> 3366operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3367 const basic_string<_CharT, _Traits, _Allocator>& __rhs) { 3368 using _String = basic_string<_CharT, _Traits, _Allocator>; 3369 auto __lhs_sz = __lhs.size(); 3370 auto __rhs_sz = __rhs.size(); 3371 _String __r(__uninitialized_size_tag(), 3372 __lhs_sz + __rhs_sz, 3373 _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator())); 3374 auto __ptr = std::__to_address(__r.__get_pointer()); 3375 _Traits::copy(__ptr, __lhs.data(), __lhs_sz); 3376 _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz); 3377 _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT()); 3378 return __r; 3379} 3380 3381template <class _CharT, class _Traits, class _Allocator> 3382_LIBCPP_HIDDEN basic_string<_CharT, _Traits, _Allocator> 3383operator+(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) { 3384 using _String = basic_string<_CharT, _Traits, _Allocator>; 3385 auto __lhs_sz = _Traits::length(__lhs); 3386 auto __rhs_sz = __rhs.size(); 3387 _String __r(__uninitialized_size_tag(), 3388 __lhs_sz + __rhs_sz, 3389 _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator())); 3390 auto __ptr = std::__to_address(__r.__get_pointer()); 3391 _Traits::copy(__ptr, __lhs, __lhs_sz); 3392 _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz); 3393 _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT()); 3394 return __r; 3395} 3396 3397template <class _CharT, class _Traits, class _Allocator> 3398_LIBCPP_HIDE_FROM_ABI basic_string<_CharT, _Traits, _Allocator> 3399operator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) { 3400 using _String = basic_string<_CharT, _Traits, _Allocator>; 3401 typename _String::size_type __rhs_sz = __rhs.size(); 3402 _String __r(__uninitialized_size_tag(), 3403 __rhs_sz + 1, 3404 _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator())); 3405 auto __ptr = std::__to_address(__r.__get_pointer()); 3406 _Traits::assign(__ptr, 1, __lhs); 3407 _Traits::copy(__ptr + 1, __rhs.data(), __rhs_sz); 3408 _Traits::assign(__ptr + 1 + __rhs_sz, 1, _CharT()); 3409 return __r; 3410} 3411 3412template <class _CharT, class _Traits, class _Allocator> 3413inline basic_string<_CharT, _Traits, _Allocator> 3414operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) { 3415 using _String = basic_string<_CharT, _Traits, _Allocator>; 3416 typename _String::size_type __lhs_sz = __lhs.size(); 3417 typename _String::size_type __rhs_sz = _Traits::length(__rhs); 3418 _String __r(__uninitialized_size_tag(), 3419 __lhs_sz + __rhs_sz, 3420 _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator())); 3421 auto __ptr = std::__to_address(__r.__get_pointer()); 3422 _Traits::copy(__ptr, __lhs.data(), __lhs_sz); 3423 _Traits::copy(__ptr + __lhs_sz, __rhs, __rhs_sz); 3424 _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT()); 3425 return __r; 3426} 3427 3428template <class _CharT, class _Traits, class _Allocator> 3429_LIBCPP_HIDE_FROM_ABI basic_string<_CharT, _Traits, _Allocator> 3430operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs) { 3431 using _String = basic_string<_CharT, _Traits, _Allocator>; 3432 typename _String::size_type __lhs_sz = __lhs.size(); 3433 _String __r(__uninitialized_size_tag(), 3434 __lhs_sz + 1, 3435 _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator())); 3436 auto __ptr = std::__to_address(__r.__get_pointer()); 3437 _Traits::copy(__ptr, __lhs.data(), __lhs_sz); 3438 _Traits::assign(__ptr + __lhs_sz, 1, __rhs); 3439 _Traits::assign(__ptr + 1 + __lhs_sz, 1, _CharT()); 3440 return __r; 3441} 3442 3443// swap 3444 3445template <class _CharT, class _Traits, class _Allocator> 3446inline _LIBCPP_HIDE_FROM_ABI void 3447swap(basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>& __rhs) { 3448 __lhs.swap(__rhs); 3449} 3450 3451_LIBCPP_EXPORTED_FROM_ABI int stoi(const string& __str, size_t* __idx = nullptr, int __base = 10); 3452_LIBCPP_EXPORTED_FROM_ABI long stol(const string& __str, size_t* __idx = nullptr, int __base = 10); 3453_LIBCPP_EXPORTED_FROM_ABI unsigned long stoul(const string& __str, size_t* __idx = nullptr, int __base = 10); 3454_LIBCPP_EXPORTED_FROM_ABI long long stoll(const string& __str, size_t* __idx = nullptr, int __base = 10); 3455_LIBCPP_EXPORTED_FROM_ABI unsigned long long stoull(const string& __str, size_t* __idx = nullptr, int __base = 10); 3456 3457_LIBCPP_EXPORTED_FROM_ABI float stof(const string& __str, size_t* __idx = nullptr); 3458_LIBCPP_EXPORTED_FROM_ABI double stod(const string& __str, size_t* __idx = nullptr); 3459_LIBCPP_EXPORTED_FROM_ABI long double stold(const string& __str, size_t* __idx = nullptr); 3460 3461_LIBCPP_EXPORTED_FROM_ABI string to_string(int __val); 3462_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned __val); 3463_LIBCPP_EXPORTED_FROM_ABI string to_string(long __val); 3464_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long __val); 3465_LIBCPP_EXPORTED_FROM_ABI string to_string(long long __val); 3466_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long long __val); 3467_LIBCPP_EXPORTED_FROM_ABI string to_string(float __val); 3468_LIBCPP_EXPORTED_FROM_ABI string to_string(double __val); 3469_LIBCPP_EXPORTED_FROM_ABI string to_string(long double __val); 3470 3471#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 3472_LIBCPP_EXPORTED_FROM_ABI int stoi(const wstring& __str, size_t* __idx = nullptr, int __base = 10); 3473_LIBCPP_EXPORTED_FROM_ABI long stol(const wstring& __str, size_t* __idx = nullptr, int __base = 10); 3474_LIBCPP_EXPORTED_FROM_ABI unsigned long stoul(const wstring& __str, size_t* __idx = nullptr, int __base = 10); 3475_LIBCPP_EXPORTED_FROM_ABI long long stoll(const wstring& __str, size_t* __idx = nullptr, int __base = 10); 3476_LIBCPP_EXPORTED_FROM_ABI unsigned long long stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10); 3477 3478_LIBCPP_EXPORTED_FROM_ABI float stof(const wstring& __str, size_t* __idx = nullptr); 3479_LIBCPP_EXPORTED_FROM_ABI double stod(const wstring& __str, size_t* __idx = nullptr); 3480_LIBCPP_EXPORTED_FROM_ABI long double stold(const wstring& __str, size_t* __idx = nullptr); 3481 3482_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(int __val); 3483_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned __val); 3484_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long __val); 3485_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long __val); 3486_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long long __val); 3487_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long long __val); 3488_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(float __val); 3489_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(double __val); 3490_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long double __val); 3491#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS 3492 3493template <class _CharT, class _Traits, class _Allocator> 3494_LIBCPP_TEMPLATE_DATA_VIS const typename basic_string<_CharT, _Traits, _Allocator>::size_type 3495 basic_string<_CharT, _Traits, _Allocator>::npos; 3496 3497template <class _CharT, class _Allocator> 3498struct __string_hash : public __unary_function<basic_string<_CharT, char_traits<_CharT>, _Allocator>, size_t> { 3499 _LIBCPP_HIDE_FROM_ABI size_t 3500 operator()(const basic_string<_CharT, char_traits<_CharT>, _Allocator>& __val) const _NOEXCEPT { 3501 return std::__do_string_hash(__val.data(), __val.data() + __val.size()); 3502 } 3503}; 3504 3505template <class _Allocator> 3506struct hash<basic_string<char, char_traits<char>, _Allocator> > : __string_hash<char, _Allocator> {}; 3507 3508#ifndef _LIBCPP_HAS_NO_CHAR8_T 3509template <class _Allocator> 3510struct hash<basic_string<char8_t, char_traits<char8_t>, _Allocator> > : __string_hash<char8_t, _Allocator> {}; 3511#endif 3512 3513template <class _Allocator> 3514struct hash<basic_string<char16_t, char_traits<char16_t>, _Allocator> > : __string_hash<char16_t, _Allocator> {}; 3515 3516template <class _Allocator> 3517struct hash<basic_string<char32_t, char_traits<char32_t>, _Allocator> > : __string_hash<char32_t, _Allocator> {}; 3518 3519#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 3520template <class _Allocator> 3521struct hash<basic_string<wchar_t, char_traits<wchar_t>, _Allocator> > : __string_hash<wchar_t, _Allocator> {}; 3522#endif 3523 3524template <class _CharT, class _Traits, class _Allocator> 3525_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& 3526operator<<(basic_ostream<_CharT, _Traits>& __os, const basic_string<_CharT, _Traits, _Allocator>& __str); 3527 3528template <class _CharT, class _Traits, class _Allocator> 3529_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& 3530operator>>(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Allocator>& __str); 3531 3532template <class _CharT, class _Traits, class _Allocator> 3533_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& 3534getline(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm); 3535 3536template <class _CharT, class _Traits, class _Allocator> 3537inline _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& 3538getline(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Allocator>& __str); 3539 3540template <class _CharT, class _Traits, class _Allocator> 3541inline _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& 3542getline(basic_istream<_CharT, _Traits>&& __is, basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm); 3543 3544template <class _CharT, class _Traits, class _Allocator> 3545inline _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& 3546getline(basic_istream<_CharT, _Traits>&& __is, basic_string<_CharT, _Traits, _Allocator>& __str); 3547 3548_LIBCPP_END_NAMESPACE_STD 3549 3550_LIBCPP_POP_MACROS 3551 3552#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) 3553# include <__cxx03/algorithm> 3554# include <__cxx03/cstdlib> 3555# include <__cxx03/iterator> 3556# include <__cxx03/new> 3557# include <__cxx03/type_traits> 3558# include <__cxx03/typeinfo> 3559# include <__cxx03/utility> 3560#endif 3561 3562#endif // _LIBCPP___CXX03_STRING 3563