3571 lines · plain
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-exception7//8//===----------------------------------------------------------------------===//9 10#ifndef _LIBCPP___CXX03_STRING11#define _LIBCPP___CXX03_STRING12 13// clang-format off14 15/*16 string synopsis17 18#include <__cxx03/compare>19#include <__cxx03/initializer_list>20 21namespace std22{23 24template <class stateT>25class fpos26{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_traits50{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 specializations57 // 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++2080template <> 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_string85{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++20106 explicit basic_string(const allocator_type& a); // constexpr since C++20107 basic_string(const basic_string& str); // constexpr since C++20108 basic_string(basic_string&& str)109 noexcept(is_nothrow_move_constructible<allocator_type>::value); // constexpr since C++20110 basic_string(const basic_string& str, size_type pos,111 const allocator_type& a = allocator_type()); // constexpr since C++20112 basic_string(const basic_string& str, size_type pos, size_type n,113 const Allocator& a = Allocator()); // constexpr since C++20114 constexpr basic_string(115 basic_string&& str, size_type pos, const Allocator& a = Allocator()); // since C++23116 constexpr basic_string(117 basic_string&& str, size_type pos, size_type n, const Allocator& a = Allocator()); // since C++23118 template<class T>119 basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator()); // C++17, constexpr since C++20120 template <class T>121 explicit basic_string(const T& t, const Allocator& a = Allocator()); // C++17, constexpr since C++20122 basic_string(const value_type* s, const allocator_type& a = allocator_type()); // constexpr since C++20123 basic_string(const value_type* s, size_type n, const allocator_type& a = allocator_type()); // constexpr since C++20124 basic_string(nullptr_t) = delete; // C++23125 basic_string(size_type n, value_type c, const allocator_type& a = allocator_type()); // constexpr since C++20126 template<class InputIterator>127 basic_string(InputIterator begin, InputIterator end,128 const allocator_type& a = allocator_type()); // constexpr since C++20129 template<container-compatible-range<charT> R>130 constexpr basic_string(from_range_t, R&& rg, const Allocator& a = Allocator()); // since C++23131 basic_string(initializer_list<value_type>, const Allocator& = Allocator()); // constexpr since C++20132 basic_string(const basic_string&, const Allocator&); // constexpr since C++20133 basic_string(basic_string&&, const Allocator&); // constexpr since C++20134 135 ~basic_string(); // constexpr since C++20136 137 operator basic_string_view<charT, traits>() const noexcept; // constexpr since C++20138 139 basic_string& operator=(const basic_string& str); // constexpr since C++20140 template <class T>141 basic_string& operator=(const T& t); // C++17, constexpr since C++20142 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++20146 basic_string& operator=(const value_type* s); // constexpr since C++20147 basic_string& operator=(nullptr_t) = delete; // C++23148 basic_string& operator=(value_type c); // constexpr since C++20149 basic_string& operator=(initializer_list<value_type>); // constexpr since C++20150 151 iterator begin() noexcept; // constexpr since C++20152 const_iterator begin() const noexcept; // constexpr since C++20153 iterator end() noexcept; // constexpr since C++20154 const_iterator end() const noexcept; // constexpr since C++20155 156 reverse_iterator rbegin() noexcept; // constexpr since C++20157 const_reverse_iterator rbegin() const noexcept; // constexpr since C++20158 reverse_iterator rend() noexcept; // constexpr since C++20159 const_reverse_iterator rend() const noexcept; // constexpr since C++20160 161 const_iterator cbegin() const noexcept; // constexpr since C++20162 const_iterator cend() const noexcept; // constexpr since C++20163 const_reverse_iterator crbegin() const noexcept; // constexpr since C++20164 const_reverse_iterator crend() const noexcept; // constexpr since C++20165 166 size_type size() const noexcept; // constexpr since C++20167 size_type length() const noexcept; // constexpr since C++20168 size_type max_size() const noexcept; // constexpr since C++20169 size_type capacity() const noexcept; // constexpr since C++20170 171 void resize(size_type n, value_type c); // constexpr since C++20172 void resize(size_type n); // constexpr since C++20173 174 template<class Operation>175 constexpr void resize_and_overwrite(size_type n, Operation op); // since C++23176 177 void reserve(size_type res_arg); // constexpr since C++20178 void reserve(); // deprecated in C++20, removed in C++26179 void shrink_to_fit(); // constexpr since C++20180 void clear() noexcept; // constexpr since C++20181 bool empty() const noexcept; // constexpr since C++20182 183 const_reference operator[](size_type pos) const; // constexpr since C++20184 reference operator[](size_type pos); // constexpr since C++20185 186 const_reference at(size_type n) const; // constexpr since C++20187 reference at(size_type n); // constexpr since C++20188 189 basic_string& operator+=(const basic_string& str); // constexpr since C++20190 template <class T>191 basic_string& operator+=(const T& t); // C++17, constexpr since C++20192 basic_string& operator+=(const value_type* s); // constexpr since C++20193 basic_string& operator+=(value_type c); // constexpr since C++20194 basic_string& operator+=(initializer_list<value_type>); // constexpr since C++20195 196 basic_string& append(const basic_string& str); // constexpr since C++20197 template <class T>198 basic_string& append(const T& t); // C++17, constexpr since C++20199 basic_string& append(const basic_string& str, size_type pos, size_type n=npos); // C++14, constexpr since C++20200 template <class T>201 basic_string& append(const T& t, size_type pos, size_type n=npos); // C++17, constexpr since C++20202 basic_string& append(const value_type* s, size_type n); // constexpr since C++20203 basic_string& append(const value_type* s); // constexpr since C++20204 basic_string& append(size_type n, value_type c); // constexpr since C++20205 template<class InputIterator>206 basic_string& append(InputIterator first, InputIterator last); // constexpr since C++20207 template<container-compatible-range<charT> R>208 constexpr basic_string& append_range(R&& rg); // C++23209 basic_string& append(initializer_list<value_type>); // constexpr since C++20210 211 void push_back(value_type c); // constexpr since C++20212 void pop_back(); // constexpr since C++20213 reference front(); // constexpr since C++20214 const_reference front() const; // constexpr since C++20215 reference back(); // constexpr since C++20216 const_reference back() const; // constexpr since C++20217 218 basic_string& assign(const basic_string& str); // constexpr since C++20219 template <class T>220 basic_string& assign(const T& t); // C++17, constexpr since C++20221 basic_string& assign(basic_string&& str); // constexpr since C++20222 basic_string& assign(const basic_string& str, size_type pos, size_type n=npos); // C++14, constexpr since C++20223 template <class T>224 basic_string& assign(const T& t, size_type pos, size_type n=npos); // C++17, constexpr since C++20225 basic_string& assign(const value_type* s, size_type n); // constexpr since C++20226 basic_string& assign(const value_type* s); // constexpr since C++20227 basic_string& assign(size_type n, value_type c); // constexpr since C++20228 template<class InputIterator>229 basic_string& assign(InputIterator first, InputIterator last); // constexpr since C++20230 template<container-compatible-range<charT> R>231 constexpr basic_string& assign_range(R&& rg); // C++23232 basic_string& assign(initializer_list<value_type>); // constexpr since C++20233 234 basic_string& insert(size_type pos1, const basic_string& str); // constexpr since C++20235 template <class T>236 basic_string& insert(size_type pos1, const T& t); // constexpr since C++20237 basic_string& insert(size_type pos1, const basic_string& str,238 size_type pos2, size_type n); // constexpr since C++20239 template <class T>240 basic_string& insert(size_type pos1, const T& t, size_type pos2, size_type n); // C++17, constexpr since C++20241 basic_string& insert(size_type pos, const value_type* s, size_type n=npos); // C++14, constexpr since C++20242 basic_string& insert(size_type pos, const value_type* s); // constexpr since C++20243 basic_string& insert(size_type pos, size_type n, value_type c); // constexpr since C++20244 iterator insert(const_iterator p, value_type c); // constexpr since C++20245 iterator insert(const_iterator p, size_type n, value_type c); // constexpr since C++20246 template<class InputIterator>247 iterator insert(const_iterator p, InputIterator first, InputIterator last); // constexpr since C++20248 template<container-compatible-range<charT> R>249 constexpr iterator insert_range(const_iterator p, R&& rg); // C++23250 iterator insert(const_iterator p, initializer_list<value_type>); // constexpr since C++20251 252 basic_string& erase(size_type pos = 0, size_type n = npos); // constexpr since C++20253 iterator erase(const_iterator position); // constexpr since C++20254 iterator erase(const_iterator first, const_iterator last); // constexpr since C++20255 256 basic_string& replace(size_type pos1, size_type n1, const basic_string& str); // constexpr since C++20257 template <class T>258 basic_string& replace(size_type pos1, size_type n1, const T& t); // C++17, constexpr since C++20259 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++20261 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++20264 basic_string& replace(size_type pos, size_type n1, const value_type* s, size_type n2); // constexpr since C++20265 basic_string& replace(size_type pos, size_type n1, const value_type* s); // constexpr since C++20266 basic_string& replace(size_type pos, size_type n1, size_type n2, value_type c); // constexpr since C++20267 basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str); // constexpr since C++20268 template <class T>269 basic_string& replace(const_iterator i1, const_iterator i2, const T& t); // C++17, constexpr since C++20270 basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s, size_type n); // constexpr since C++20271 basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s); // constexpr since C++20272 basic_string& replace(const_iterator i1, const_iterator i2, size_type n, value_type c); // constexpr since C++20273 template<class InputIterator>274 basic_string& replace(const_iterator i1, const_iterator i2, InputIterator j1, InputIterator j2); // constexpr since C++20275 template<container-compatible-range<charT> R>276 constexpr basic_string& replace_with_range(const_iterator i1, const_iterator i2, R&& rg); // C++23277 basic_string& replace(const_iterator i1, const_iterator i2, initializer_list<value_type>); // constexpr since C++20278 279 size_type copy(value_type* s, size_type n, size_type pos = 0) const; // constexpr since C++20280 basic_string substr(size_type pos = 0, size_type n = npos) const; // constexpr in C++20, removed in C++23281 basic_string substr(size_type pos = 0, size_type n = npos) const&; // since C++23282 constexpr basic_string substr(size_type pos = 0, size_type n = npos) &&; // since C++23283 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++20286 287 const value_type* c_str() const noexcept; // constexpr since C++20288 const value_type* data() const noexcept; // constexpr since C++20289 value_type* data() noexcept; // C++17, constexpr since C++20290 291 allocator_type get_allocator() const noexcept; // constexpr since C++20292 293 size_type find(const basic_string& str, size_type pos = 0) const noexcept; // constexpr since C++20294 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++20296 size_type find(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20297 size_type find(const value_type* s, size_type pos = 0) const noexcept; // constexpr since C++20298 size_type find(value_type c, size_type pos = 0) const noexcept; // constexpr since C++20299 300 size_type rfind(const basic_string& str, size_type pos = npos) const noexcept; // constexpr since C++20301 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++20303 size_type rfind(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20304 size_type rfind(const value_type* s, size_type pos = npos) const noexcept; // constexpr since C++20305 size_type rfind(value_type c, size_type pos = npos) const noexcept; // constexpr since C++20306 307 size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept; // constexpr since C++20308 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++20310 size_type find_first_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20311 size_type find_first_of(const value_type* s, size_type pos = 0) const noexcept; // constexpr since C++20312 size_type find_first_of(value_type c, size_type pos = 0) const noexcept; // constexpr since C++20313 314 size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept; // constexpr since C++20315 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++20317 size_type find_last_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20318 size_type find_last_of(const value_type* s, size_type pos = npos) const noexcept; // constexpr since C++20319 size_type find_last_of(value_type c, size_type pos = npos) const noexcept; // constexpr since C++20320 321 size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept; // constexpr since C++20322 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++20324 size_type find_first_not_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20325 size_type find_first_not_of(const value_type* s, size_type pos = 0) const noexcept; // constexpr since C++20326 size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept; // constexpr since C++20327 328 size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept; // constexpr since C++20329 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++20331 size_type find_last_not_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20332 size_type find_last_not_of(const value_type* s, size_type pos = npos) const noexcept; // constexpr since C++20333 size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept; // constexpr since C++20334 335 int compare(const basic_string& str) const noexcept; // constexpr since C++20336 template <class T>337 int compare(const T& t) const noexcept; // C++17, noexcept as an extension, constexpr since C++20338 int compare(size_type pos1, size_type n1, const basic_string& str) const; // constexpr since C++20339 template <class T>340 int compare(size_type pos1, size_type n1, const T& t) const; // C++17, constexpr since C++20341 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++20343 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++20346 int compare(const value_type* s) const noexcept; // constexpr since C++20347 int compare(size_type pos1, size_type n1, const value_type* s) const; // constexpr since C++20348 int compare(size_type pos1, size_type n1, const value_type* s, size_type n2) const; // constexpr since C++20349 350 constexpr bool starts_with(basic_string_view<charT, traits> sv) const noexcept; // C++20351 constexpr bool starts_with(charT c) const noexcept; // C++20352 constexpr bool starts_with(const charT* s) const; // C++20353 constexpr bool ends_with(basic_string_view<charT, traits> sv) const noexcept; // C++20354 constexpr bool ends_with(charT c) const noexcept; // C++20355 constexpr bool ends_with(const charT* s) const; // C++20356 357 constexpr bool contains(basic_string_view<charT, traits> sv) const noexcept; // C++23358 constexpr bool contains(charT c) const noexcept; // C++23359 constexpr bool contains(const charT* s) const; // C++23360};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++17368 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++23374 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++17380 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++17388 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++20393 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++20397 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++20401 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++20405 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++20409 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++26414template<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++26418template<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++26422template<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++26426 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++20431 432template<class charT, class traits, class Allocator>433bool operator==(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20434 435template<class charT, class traits, class Allocator>436bool operator==(const basic_string<charT,traits,Allocator>& lhs, const charT* rhs) noexcept; // constexpr since C++20437 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++20441 442template<class charT, class traits, class Allocator>443bool operator!=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20444 445template<class charT, class traits, class Allocator>446bool operator!=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // removed in C++20447 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++20451 452template<class charT, class traits, class Allocator>453bool operator< (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // removed in C++20454 455template<class charT, class traits, class Allocator>456bool operator< (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20457 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++20461 462template<class charT, class traits, class Allocator>463bool operator> (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // removed in C++20464 465template<class charT, class traits, class Allocator>466bool operator> (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20467 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++20471 472template<class charT, class traits, class Allocator>473bool operator<=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // removed in C++20474 475template<class charT, class traits, class Allocator>476bool operator<=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20477 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++20481 482template<class charT, class traits, class Allocator>483bool operator>=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // removed in C++20484 485template<class charT, class traits, class Allocator>486bool operator>=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20487 488template<class charT, class traits, class Allocator> // since C++20489constexpr 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++20493constexpr 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++20500 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_type520erase(basic_string<charT, traits, Allocator>& c, const U& value); // C++20521template<class charT, class traits, class Allocator, class Predicate>522typename basic_string<charT, traits, Allocator>::size_type523erase_if(basic_string<charT, traits, Allocator>& c, Predicate pred); // C++20524 525typedef basic_string<char> string;526typedef basic_string<wchar_t> wstring;527typedef basic_string<char8_t> u8string; // C++20528typedef 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++20573template <> 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++20578basic_string<wchar_t> operator""s( const wchar_t *str, size_t len ); // C++14, constexpr since C++20579constexpr basic_string<char8_t> operator""s( const char8_t *str, size_t len ); // C++20580basic_string<char16_t> operator""s( const char16_t *str, size_t len ); // C++14, constexpr since C++20581basic_string<char32_t> operator""s( const char32_t *str, size_t len ); // C++14, constexpr since C++20582 583} // std584 585*/586 587// clang-format on588 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> // EOF637#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_CHARACTERS644# include <__cxx03/cwchar>645#endif646 647// standard-mandated includes648 649// [iterator.range]650#include <__cxx03/__iterator/access.h>651 652#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)653# pragma GCC system_header654#endif655 656_LIBCPP_PUSH_MACROS657#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 accessed665// by other parts of the program.666#else667# define _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS668#endif669 670_LIBCPP_BEGIN_NAMESPACE_STD671 672// basic_string673 674template <class _CharT, class _Traits, class _Allocator>675basic_string<_CharT, _Traits, _Allocator> _LIBCPP_HIDE_FROM_ABI676operator+(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_view708 : 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 changes735 // - size_type: is always trivially relocatable, since it has to be an integral type736 // - value_type: is always trivially relocatable, since it has to be trivial737 // - unsigned char: is a fundamental type, so it's trivially relocatable738 // - allocator_type: may or may not be trivially relocatable, so it's checked739 //740 // This string implementation doesn't contain any references into itself. It only contains a bit that says whether741 // 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 trivially744 // relocatable. Because the object's memory might be poisoned when its content745 // is kept inside objects memory (short string optimization), instead of in allocated746 // external memory. In such cases, the destructor is responsible for unpoisoning747 // the memory to avoid triggering false positives.748 // Therefore it's crucial to ensure the destructor is called.749 using __trivially_relocatable = void;750#else751 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#endif756#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#else776# define _LIBCPP_ASAN_VOLATILE_WRAPPER(PTR) PTR777#endif778 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_STRING789 // Users might provide custom allocators, and prior to C++20 we have no existing way to detect whether the allocator's790 // pointer type is contiguous (though it has to be by the Standard). Using the wrapper type ensures the iterator is791 // considered contiguous.792 typedef __bounded_iter<__wrap_iter<pointer>> iterator;793 typedef __bounded_iter<__wrap_iter<const_pointer>> const_iterator;794#else795 typedef __wrap_iter<pointer> iterator;796 typedef __wrap_iter<const_pointer> const_iterator;797#endif798 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_LAYOUT805 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 size823 // 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 when827 // it is loaded to make sure that we always store an even number. In the long string828 // representation, we can ignore this because we can assume that we always allocate829 // 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 MSB833 // for representing the size of a short string anyway.834 835# ifdef _LIBCPP_BIG_ENDIAN836 static const size_type __endian_factor = 2;837# else838 static const size_type __endian_factor = 1;839# endif840 841#else // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT842 843# ifdef _LIBCPP_BIG_ENDIAN844 static const size_type __endian_factor = 1;845# else846 static const size_type __endian_factor = 2;847# endif848 849 // Attribute 'packed' is used to keep the layout compatible with the850 // previous definition that did not use bit fields. This is because on851 // some platforms bit fields have a default size rather than the actual852 // 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_LAYOUT874 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, but885 // don't initialize the characters. The contents of the string, including the null terminator, must be886 // 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_STRING913 // 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 existing918 // 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#else924 return iterator(__p);925#endif // _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING926 }927 928 _LIBCPP_HIDE_FROM_ABI const_iterator __make_const_iterator(const_pointer __p) const {929#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING930 // 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#else936 return const_iterator(__p);937#endif // _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING938 }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 } else955 __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size());956 }957 958 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS959 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 } else964 __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_VIS1022 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 if (size_type __m = __alloc_traits::max_size(__alloc()); __m <= std::numeric_limits<size_type>::max() / 2) {1105 size_type __res = __m - __alignment;1106 1107 // When the __endian_factor == 2, our string representation assumes that the capacity1108 // (including the null terminator) is always even, so we have to make sure the lowest bit isn't set when the1109 // string grows to max_size()1110 if (__endian_factor == 2)1111 __res &= ~size_type(1);1112 1113 // We have to allocate space for the null terminator, but max_size() doesn't include it.1114 return __res - 1;1115 } else {1116 bool __uses_lsb = __endian_factor == 2;1117 return __uses_lsb ? __m - __alignment - 1 : (__m / 2) - __alignment - 1;1118 }1119 }1120 1121 _LIBCPP_HIDE_FROM_ABI size_type capacity() const _NOEXCEPT {1122 return (__is_long() ? __get_long_cap() : static_cast<size_type>(__min_cap)) - 1;1123 }1124 1125 void resize(size_type __n, value_type __c);1126 _LIBCPP_HIDE_FROM_ABI void resize(size_type __n) { resize(__n, value_type()); }1127 1128 void reserve(size_type __requested_capacity);1129 1130 _LIBCPP_HIDE_FROM_ABI void __resize_default_init(size_type __n);1131 1132 _LIBCPP_HIDE_FROM_ABI void reserve() _NOEXCEPT { shrink_to_fit(); }1133 _LIBCPP_HIDE_FROM_ABI void shrink_to_fit() _NOEXCEPT;1134 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT;1135 1136 _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return size() == 0; }1137 1138 _LIBCPP_HIDE_FROM_ABI const_reference operator[](size_type __pos) const _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 *(data() + __pos);1144 }1145 1146 _LIBCPP_HIDE_FROM_ABI reference operator[](size_type __pos) _NOEXCEPT {1147 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos <= size(), "string index out of bounds");1148 if (__builtin_constant_p(__pos) && !__fits_in_sso(__pos)) {1149 return *(__get_long_pointer() + __pos);1150 }1151 return *(__get_pointer() + __pos);1152 }1153 1154 const_reference at(size_type __n) const;1155 reference at(size_type __n);1156 1157 _LIBCPP_HIDE_FROM_ABI basic_string& operator+=(const basic_string& __str) { return append(__str); }1158 1159 template <class _Tp,1160 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&1161 !__is_same_uncvref<_Tp, basic_string >::value,1162 int> = 0>1163 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string& operator+=(const _Tp& __t) {1164 __self_view __sv = __t;1165 return append(__sv);1166 }1167 1168 _LIBCPP_HIDE_FROM_ABI basic_string& operator+=(const value_type* __s) { return append(__s); }1169 1170 _LIBCPP_HIDE_FROM_ABI basic_string& operator+=(value_type __c) {1171 push_back(__c);1172 return *this;1173 }1174 1175 _LIBCPP_HIDE_FROM_ABI basic_string& append(const basic_string& __str) { return append(__str.data(), __str.size()); }1176 1177 template <class _Tp,1178 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&1179 !__is_same_uncvref<_Tp, basic_string>::value,1180 int> = 0>1181 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string& append(const _Tp& __t) {1182 __self_view __sv = __t;1183 return append(__sv.data(), __sv.size());1184 }1185 1186 basic_string& append(const basic_string& __str, size_type __pos, size_type __n = npos);1187 1188 template <class _Tp,1189 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&1190 !__is_same_uncvref<_Tp, basic_string>::value,1191 int> = 0>1192 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string&1193 append(const _Tp& __t, size_type __pos, size_type __n = npos);1194 1195 basic_string& append(const value_type* __s, size_type __n);1196 basic_string& append(const value_type* __s);1197 basic_string& append(size_type __n, value_type __c);1198 1199 _LIBCPP_HIDE_FROM_ABI void __append_default_init(size_type __n);1200 1201 template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>1202 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_HIDE_FROM_ABI basic_string&1203 append(_InputIterator __first, _InputIterator __last) {1204 const basic_string __temp(__first, __last, __alloc());1205 append(__temp.data(), __temp.size());1206 return *this;1207 }1208 1209 template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>1210 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_HIDE_FROM_ABI basic_string&1211 append(_ForwardIterator __first, _ForwardIterator __last);1212 1213 void push_back(value_type __c);1214 _LIBCPP_HIDE_FROM_ABI void pop_back();1215 1216 _LIBCPP_HIDE_FROM_ABI reference front() _NOEXCEPT {1217 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::front(): string is empty");1218 return *__get_pointer();1219 }1220 1221 _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT {1222 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::front(): string is empty");1223 return *data();1224 }1225 1226 _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT {1227 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::back(): string is empty");1228 return *(__get_pointer() + size() - 1);1229 }1230 1231 _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT {1232 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::back(): string is empty");1233 return *(data() + size() - 1);1234 }1235 1236 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>1237 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string& assign(const _Tp& __t) {1238 __self_view __sv = __t;1239 return assign(__sv.data(), __sv.size());1240 }1241 1242 _LIBCPP_HIDE_FROM_ABI basic_string& assign(const basic_string& __str) { return *this = __str; }1243 1244 basic_string& assign(const basic_string& __str, size_type __pos, size_type __n = npos);1245 1246 template <class _Tp,1247 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&1248 !__is_same_uncvref<_Tp, basic_string>::value,1249 int> = 0>1250 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string&1251 assign(const _Tp& __t, size_type __pos, size_type __n = npos);1252 1253 basic_string& assign(const value_type* __s, size_type __n);1254 basic_string& assign(const value_type* __s);1255 basic_string& assign(size_type __n, value_type __c);1256 template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>1257 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string&1258 assign(_InputIterator __first, _InputIterator __last);1259 1260 template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>1261 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string&1262 assign(_ForwardIterator __first, _ForwardIterator __last);1263 1264 _LIBCPP_HIDE_FROM_ABI basic_string& insert(size_type __pos1, const basic_string& __str) {1265 return insert(__pos1, __str.data(), __str.size());1266 }1267 1268 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>1269 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string& insert(size_type __pos1, const _Tp& __t) {1270 __self_view __sv = __t;1271 return insert(__pos1, __sv.data(), __sv.size());1272 }1273 1274 template <class _Tp,1275 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&1276 !__is_same_uncvref<_Tp, basic_string>::value,1277 int> = 0>1278 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string&1279 insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n = npos);1280 1281 basic_string& insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n = npos);1282 basic_string& insert(size_type __pos, const value_type* __s, size_type __n);1283 basic_string& insert(size_type __pos, const value_type* __s);1284 basic_string& insert(size_type __pos, size_type __n, value_type __c);1285 iterator insert(const_iterator __pos, value_type __c);1286 1287 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __pos, size_type __n, value_type __c) {1288 difference_type __p = __pos - begin();1289 insert(static_cast<size_type>(__p), __n, __c);1290 return begin() + __p;1291 }1292 1293 template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>1294 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS iterator1295 insert(const_iterator __pos, _InputIterator __first, _InputIterator __last);1296 1297 template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>1298 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS iterator1299 insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last);1300 1301 basic_string& erase(size_type __pos = 0, size_type __n = npos);1302 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __pos);1303 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __first, const_iterator __last);1304 1305 _LIBCPP_HIDE_FROM_ABI basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str) {1306 return replace(__pos1, __n1, __str.data(), __str.size());1307 }1308 1309 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>1310 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string&1311 replace(size_type __pos1, size_type __n1, const _Tp& __t) {1312 __self_view __sv = __t;1313 return replace(__pos1, __n1, __sv.data(), __sv.size());1314 }1315 1316 basic_string&1317 replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2 = npos);1318 1319 template <class _Tp,1320 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&1321 !__is_same_uncvref<_Tp, basic_string>::value,1322 int> = 0>1323 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string&1324 replace(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2 = npos);1325 1326 basic_string& replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2);1327 basic_string& replace(size_type __pos, size_type __n1, const value_type* __s);1328 basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c);1329 1330 _LIBCPP_HIDE_FROM_ABI basic_string& replace(const_iterator __i1, const_iterator __i2, const basic_string& __str) {1331 return replace(1332 static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __str.data(), __str.size());1333 }1334 1335 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>1336 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string&1337 replace(const_iterator __i1, const_iterator __i2, const _Tp& __t) {1338 __self_view __sv = __t;1339 return replace(__i1 - begin(), __i2 - __i1, __sv);1340 }1341 1342 _LIBCPP_HIDE_FROM_ABI basic_string&1343 replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n) {1344 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s, __n);1345 }1346 1347 _LIBCPP_HIDE_FROM_ABI basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s) {1348 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s);1349 }1350 1351 _LIBCPP_HIDE_FROM_ABI basic_string& replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c) {1352 return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __n, __c);1353 }1354 1355 template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0>1356 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string&1357 replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2);1358 1359 size_type copy(value_type* __s, size_type __n, size_type __pos = 0) const;1360 1361 _LIBCPP_HIDE_FROM_ABI basic_string substr(size_type __pos = 0, size_type __n = npos) const {1362 return basic_string(*this, __pos, __n);1363 }1364 1365 _LIBCPP_HIDE_FROM_ABI void swap(basic_string& __str);1366 1367 _LIBCPP_HIDE_FROM_ABI const value_type* c_str() const _NOEXCEPT { return data(); }1368 _LIBCPP_HIDE_FROM_ABI const value_type* data() const _NOEXCEPT { return std::__to_address(__get_pointer()); }1369 1370 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT { return __alloc(); }1371 1372 _LIBCPP_HIDE_FROM_ABI size_type find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;1373 1374 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>1375 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS size_type1376 find(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;1377 1378 size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;1379 _LIBCPP_HIDE_FROM_ABI size_type find(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;1380 size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT;1381 1382 _LIBCPP_HIDE_FROM_ABI size_type rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;1383 1384 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>1385 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS size_type1386 rfind(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;1387 1388 size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;1389 _LIBCPP_HIDE_FROM_ABI size_type rfind(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;1390 size_type rfind(value_type __c, size_type __pos = npos) const _NOEXCEPT;1391 1392 _LIBCPP_HIDE_FROM_ABI size_type find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;1393 1394 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>1395 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS size_type1396 find_first_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;1397 1398 size_type find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;1399 _LIBCPP_HIDE_FROM_ABI size_type find_first_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;1400 _LIBCPP_HIDE_FROM_ABI size_type find_first_of(value_type __c, size_type __pos = 0) const _NOEXCEPT;1401 1402 _LIBCPP_HIDE_FROM_ABI size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;1403 1404 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>1405 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS size_type1406 find_last_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;1407 1408 size_type find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;1409 _LIBCPP_HIDE_FROM_ABI size_type find_last_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;1410 _LIBCPP_HIDE_FROM_ABI size_type find_last_of(value_type __c, size_type __pos = npos) const _NOEXCEPT;1411 1412 _LIBCPP_HIDE_FROM_ABI size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;1413 1414 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>1415 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS size_type1416 find_first_not_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;1417 1418 size_type find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;1419 _LIBCPP_HIDE_FROM_ABI size_type find_first_not_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;1420 _LIBCPP_HIDE_FROM_ABI size_type find_first_not_of(value_type __c, size_type __pos = 0) const _NOEXCEPT;1421 1422 _LIBCPP_HIDE_FROM_ABI size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;1423 1424 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>1425 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS size_type1426 find_last_not_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;1427 1428 size_type find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;1429 _LIBCPP_HIDE_FROM_ABI size_type find_last_not_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;1430 _LIBCPP_HIDE_FROM_ABI size_type find_last_not_of(value_type __c, size_type __pos = npos) const _NOEXCEPT;1431 1432 _LIBCPP_HIDE_FROM_ABI int compare(const basic_string& __str) const _NOEXCEPT;1433 1434 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>1435 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS int compare(const _Tp& __t) const _NOEXCEPT;1436 1437 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>1438 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS int1439 compare(size_type __pos1, size_type __n1, const _Tp& __t) const;1440 1441 _LIBCPP_HIDE_FROM_ABI int compare(size_type __pos1, size_type __n1, const basic_string& __str) const;1442 int compare(1443 size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2 = npos) const;1444 1445 template <class _Tp,1446 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&1447 !__is_same_uncvref<_Tp, basic_string>::value,1448 int> = 0>1449 inline _LIBCPP_HIDE_FROM_ABI int1450 compare(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2 = npos) const;1451 1452 int compare(const value_type* __s) const _NOEXCEPT;1453 int compare(size_type __pos1, size_type __n1, const value_type* __s) const;1454 int compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const;1455 1456 _LIBCPP_HIDE_FROM_ABI bool __invariants() const;1457 1458 _LIBCPP_HIDE_FROM_ABI void __clear_and_shrink() _NOEXCEPT;1459 1460private:1461 template <class _Alloc>1462 inline _LIBCPP_HIDE_FROM_ABI bool friend1463 operator==(const basic_string<char, char_traits<char>, _Alloc>& __lhs,1464 const basic_string<char, char_traits<char>, _Alloc>& __rhs) _NOEXCEPT;1465 1466 _LIBCPP_HIDE_FROM_ABI void __shrink_or_extend(size_type __target_capacity);1467 1468 _LIBCPP_HIDE_FROM_ABI _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS bool __is_long() const _NOEXCEPT {1469 if (__libcpp_is_constant_evaluated() && __builtin_constant_p(__r_.first().__l.__is_long_)) {1470 return __r_.first().__l.__is_long_;1471 }1472 return __r_.first().__s.__is_long_;1473 }1474 1475 static _LIBCPP_HIDE_FROM_ABI void __begin_lifetime(pointer __begin, size_type __n) {1476 (void)__begin;1477 (void)__n;1478 }1479 1480 _LIBCPP_HIDE_FROM_ABI static bool __fits_in_sso(size_type __sz) { return __sz < __min_cap; }1481 1482 template <class _Iterator, class _Sentinel>1483 _LIBCPP_HIDE_FROM_ABI void __assign_trivial(_Iterator __first, _Sentinel __last, size_type __n);1484 1485 template <class _Iterator, class _Sentinel>1486 _LIBCPP_HIDE_FROM_ABI void __assign_with_sentinel(_Iterator __first, _Sentinel __last);1487 1488 // Copy [__first, __last) into [__dest, __dest + (__last - __first)). Assumes that the ranges don't overlap.1489 template <class _ForwardIter, class _Sent>1490 _LIBCPP_HIDE_FROM_ABI static value_type*1491 __copy_non_overlapping_range(_ForwardIter __first, _Sent __last, value_type* __dest) {1492 for (; __first != __last; ++__first)1493 traits_type::assign(*__dest++, *__first);1494 return __dest;1495 }1496 1497 template <class _ForwardIterator, class _Sentinel>1498 _LIBCPP_HIDE_FROM_ABI iterator1499 __insert_from_safe_copy(size_type __n, size_type __ip, _ForwardIterator __first, _Sentinel __last) {1500 size_type __sz = size();1501 size_type __cap = capacity();1502 value_type* __p;1503 if (__cap - __sz >= __n) {1504 __annotate_increase(__n);1505 __p = std::__to_address(__get_pointer());1506 size_type __n_move = __sz - __ip;1507 if (__n_move != 0)1508 traits_type::move(__p + __ip + __n, __p + __ip, __n_move);1509 } else {1510 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __ip, 0, __n);1511 __p = std::__to_address(__get_long_pointer());1512 }1513 __sz += __n;1514 __set_size(__sz);1515 traits_type::assign(__p[__sz], value_type());1516 __copy_non_overlapping_range(__first, __last, __p + __ip);1517 1518 return begin() + __ip;1519 }1520 1521 template <class _Iterator, class _Sentinel>1522 iterator __insert_with_size(const_iterator __pos, _Iterator __first, _Sentinel __last, size_type __n);1523 1524 _LIBCPP_HIDE_FROM_ABI allocator_type& __alloc() _NOEXCEPT { return __r_.second(); }1525 _LIBCPP_HIDE_FROM_ABI const allocator_type& __alloc() const _NOEXCEPT { return __r_.second(); }1526 1527 _LIBCPP_HIDE_FROM_ABI _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS void __set_short_size(size_type __s) _NOEXCEPT {1528 _LIBCPP_ASSERT_INTERNAL(__s < __min_cap, "__s should never be greater than or equal to the short string capacity");1529 __r_.first().__s.__size_ = __s;1530 __r_.first().__s.__is_long_ = false;1531 }1532 1533 _LIBCPP_HIDE_FROM_ABI _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS size_type __get_short_size() const _NOEXCEPT {1534 _LIBCPP_ASSERT_INTERNAL(!__r_.first().__s.__is_long_, "String has to be short when trying to get the short size");1535 return __r_.first().__s.__size_;1536 }1537 1538 _LIBCPP_HIDE_FROM_ABI void __set_long_size(size_type __s) _NOEXCEPT { __r_.first().__l.__size_ = __s; }1539 _LIBCPP_HIDE_FROM_ABI size_type __get_long_size() const _NOEXCEPT { return __r_.first().__l.__size_; }1540 _LIBCPP_HIDE_FROM_ABI void __set_size(size_type __s) _NOEXCEPT {1541 if (__is_long())1542 __set_long_size(__s);1543 else1544 __set_short_size(__s);1545 }1546 1547 _LIBCPP_HIDE_FROM_ABI void __set_long_cap(size_type __s) _NOEXCEPT {1548 __r_.first().__l.__cap_ = __s / __endian_factor;1549 __r_.first().__l.__is_long_ = true;1550 }1551 1552 _LIBCPP_HIDE_FROM_ABI size_type __get_long_cap() const _NOEXCEPT { return __r_.first().__l.__cap_ * __endian_factor; }1553 1554 _LIBCPP_HIDE_FROM_ABI void __set_long_pointer(pointer __p) _NOEXCEPT { __r_.first().__l.__data_ = __p; }1555 _LIBCPP_HIDE_FROM_ABI pointer __get_long_pointer() _NOEXCEPT {1556 return _LIBCPP_ASAN_VOLATILE_WRAPPER(__r_.first().__l.__data_);1557 }1558 _LIBCPP_HIDE_FROM_ABI const_pointer __get_long_pointer() const _NOEXCEPT {1559 return _LIBCPP_ASAN_VOLATILE_WRAPPER(__r_.first().__l.__data_);1560 }1561 _LIBCPP_HIDE_FROM_ABI _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS pointer __get_short_pointer() _NOEXCEPT {1562 return _LIBCPP_ASAN_VOLATILE_WRAPPER(pointer_traits<pointer>::pointer_to(__r_.first().__s.__data_[0]));1563 }1564 _LIBCPP_HIDE_FROM_ABI _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS const_pointer __get_short_pointer() const _NOEXCEPT {1565 return _LIBCPP_ASAN_VOLATILE_WRAPPER(pointer_traits<const_pointer>::pointer_to(__r_.first().__s.__data_[0]));1566 }1567 _LIBCPP_HIDE_FROM_ABI pointer __get_pointer() _NOEXCEPT {1568 return __is_long() ? __get_long_pointer() : __get_short_pointer();1569 }1570 _LIBCPP_HIDE_FROM_ABI const_pointer __get_pointer() const _NOEXCEPT {1571 return __is_long() ? __get_long_pointer() : __get_short_pointer();1572 }1573 1574 // The following functions are no-ops outside of AddressSanitizer mode.1575 _LIBCPP_HIDE_FROM_ABI void __annotate_contiguous_container(const void* __old_mid, const void* __new_mid) const {1576 (void)__old_mid;1577 (void)__new_mid;1578#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN)1579# if defined(__APPLE__)1580 // TODO: remove after addressing issue #96099 (https://github.com/llvm/llvm-project/issues/96099)1581 if (!__is_long())1582 return;1583# endif1584 std::__annotate_contiguous_container<_Allocator>(data(), data() + capacity() + 1, __old_mid, __new_mid);1585#endif1586 }1587 1588 _LIBCPP_HIDE_FROM_ABI void __annotate_new(size_type __current_size) const _NOEXCEPT {1589 (void)__current_size;1590#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN)1591 if (!__libcpp_is_constant_evaluated())1592 __annotate_contiguous_container(data() + capacity() + 1, data() + __current_size + 1);1593#endif1594 }1595 1596 _LIBCPP_HIDE_FROM_ABI void __annotate_delete() const _NOEXCEPT {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() + capacity() + 1);1600#endif1601 }1602 1603 _LIBCPP_HIDE_FROM_ABI void __annotate_increase(size_type __n) const _NOEXCEPT {1604 (void)__n;1605#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN)1606 if (!__libcpp_is_constant_evaluated())1607 __annotate_contiguous_container(data() + size() + 1, data() + size() + 1 + __n);1608#endif1609 }1610 1611 _LIBCPP_HIDE_FROM_ABI void __annotate_shrink(size_type __old_size) const _NOEXCEPT {1612 (void)__old_size;1613#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN)1614 if (!__libcpp_is_constant_evaluated())1615 __annotate_contiguous_container(data() + __old_size + 1, data() + size() + 1);1616#endif1617 }1618 1619 template <size_type __a>1620 static _LIBCPP_HIDE_FROM_ABI size_type __align_it(size_type __s) _NOEXCEPT {1621 return (__s + (__a - 1)) & ~(__a - 1);1622 }1623 enum { __alignment = 8 };1624 static _LIBCPP_HIDE_FROM_ABI size_type __recommend(size_type __s) _NOEXCEPT {1625 if (__s < __min_cap) {1626 return static_cast<size_type>(__min_cap) - 1;1627 }1628 const size_type __boundary = sizeof(value_type) < __alignment ? __alignment / sizeof(value_type) : __endian_factor;1629 size_type __guess = __align_it<__boundary>(__s + 1) - 1;1630 if (__guess == __min_cap)1631 __guess += __endian_factor;1632 return __guess;1633 }1634 1635 inline void __init(const value_type* __s, size_type __sz, size_type __reserve);1636 inline void __init(const value_type* __s, size_type __sz);1637 inline void __init(size_type __n, value_type __c);1638 1639 // Slow path for the (inlined) copy constructor for 'long' strings.1640 // Always externally instantiated and not inlined.1641 // Requires that __s is zero terminated.1642 // The main reason for this function to exist is because for unstable, we1643 // want to allow inlining of the copy constructor. However, we don't want1644 // to call the __init() functions as those are marked as inline which may1645 // result in over-aggressive inlining by the compiler, where our aim is1646 // to only inline the fast path code directly in the ctor.1647 _LIBCPP_NOINLINE void __init_copy_ctor_external(const value_type* __s, size_type __sz);1648 1649 template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>1650 inline void __init(_InputIterator __first, _InputIterator __last);1651 1652 template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>1653 inline void __init(_ForwardIterator __first, _ForwardIterator __last);1654 1655 template <class _InputIterator, class _Sentinel>1656 _LIBCPP_HIDE_FROM_ABI void __init_with_sentinel(_InputIterator __first, _Sentinel __last);1657 template <class _InputIterator, class _Sentinel>1658 _LIBCPP_HIDE_FROM_ABI void __init_with_size(_InputIterator __first, _Sentinel __last, size_type __sz);1659 1660#if _LIBCPP_ABI_VERSION >= 2 // We want to use the function in the dylib in ABIv11661 _LIBCPP_HIDE_FROM_ABI1662#endif1663 _LIBCPP_DEPRECATED_("use __grow_by_without_replace") void __grow_by(1664 size_type __old_cap,1665 size_type __delta_cap,1666 size_type __old_sz,1667 size_type __n_copy,1668 size_type __n_del,1669 size_type __n_add = 0);1670 _LIBCPP_HIDE_FROM_ABI void __grow_by_without_replace(1671 size_type __old_cap,1672 size_type __delta_cap,1673 size_type __old_sz,1674 size_type __n_copy,1675 size_type __n_del,1676 size_type __n_add = 0);1677 void __grow_by_and_replace(1678 size_type __old_cap,1679 size_type __delta_cap,1680 size_type __old_sz,1681 size_type __n_copy,1682 size_type __n_del,1683 size_type __n_add,1684 const value_type* __p_new_stuff);1685 1686 // __assign_no_alias is invoked for assignment operations where we1687 // have proof that the input does not alias the current instance.1688 // For example, operator=(basic_string) performs a 'self' check.1689 template <bool __is_short>1690 _LIBCPP_NOINLINE basic_string& __assign_no_alias(const value_type* __s, size_type __n);1691 1692 _LIBCPP_HIDE_FROM_ABI void __erase_to_end(size_type __pos) {1693 __null_terminate_at(std::__to_address(__get_pointer()), __pos);1694 }1695 1696 // __erase_external_with_move is invoked for erase() invocations where1697 // `n ~= npos`, likely requiring memory moves on the string data.1698 _LIBCPP_NOINLINE void __erase_external_with_move(size_type __pos, size_type __n);1699 1700 _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const basic_string& __str) {1701 __copy_assign_alloc(1702 __str, integral_constant<bool, __alloc_traits::propagate_on_container_copy_assignment::value>());1703 }1704 1705 _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const basic_string& __str, true_type) {1706 if (__alloc() == __str.__alloc())1707 __alloc() = __str.__alloc();1708 else {1709 if (!__str.__is_long()) {1710 __clear_and_shrink();1711 __alloc() = __str.__alloc();1712 } else {1713 __annotate_delete();1714 allocator_type __a = __str.__alloc();1715 auto __allocation = std::__allocate_at_least(__a, __str.__get_long_cap());1716 __begin_lifetime(__allocation.ptr, __allocation.count);1717 if (__is_long())1718 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());1719 __alloc() = std::move(__a);1720 __set_long_pointer(__allocation.ptr);1721 __set_long_cap(__allocation.count);1722 __set_long_size(__str.size());1723 __annotate_new(__get_long_size());1724 }1725 }1726 }1727 1728 _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const basic_string&, false_type) _NOEXCEPT {}1729 1730 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(basic_string& __str) {1731 __move_assign_alloc(1732 __str, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>());1733 }1734 1735 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(basic_string& __c, true_type) { __alloc() = std::move(__c.__alloc()); }1736 1737 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(basic_string&, false_type) _NOEXCEPT {}1738 1739 _LIBCPP_NOINLINE basic_string& __assign_external(const value_type* __s);1740 _LIBCPP_NOINLINE basic_string& __assign_external(const value_type* __s, size_type __n);1741 1742 // Assigns the value in __s, guaranteed to be __n < __min_cap in length.1743 inline basic_string& __assign_short(const value_type* __s, size_type __n) {1744 size_type __old_size = size();1745 if (__n > __old_size)1746 __annotate_increase(__n - __old_size);1747 pointer __p =1748 __is_long() ? (__set_long_size(__n), __get_long_pointer()) : (__set_short_size(__n), __get_short_pointer());1749 traits_type::move(std::__to_address(__p), __s, __n);1750 traits_type::assign(__p[__n], value_type());1751 if (__old_size > __n)1752 __annotate_shrink(__old_size);1753 return *this;1754 }1755 1756 _LIBCPP_HIDE_FROM_ABI basic_string& __null_terminate_at(value_type* __p, size_type __newsz) {1757 size_type __old_size = size();1758 if (__newsz > __old_size)1759 __annotate_increase(__newsz - __old_size);1760 __set_size(__newsz);1761 traits_type::assign(__p[__newsz], value_type());1762 if (__old_size > __newsz)1763 __annotate_shrink(__old_size);1764 return *this;1765 }1766 1767 template <class _Tp>1768 _LIBCPP_HIDE_FROM_ABI bool __addr_in_range(const _Tp& __v) const {1769 return std::__is_pointer_in_range(data(), data() + size() + 1, std::addressof(__v));1770 }1771 1772 _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void __throw_length_error() const {1773 std::__throw_length_error("basic_string");1774 }1775 1776 _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void __throw_out_of_range() const {1777 std::__throw_out_of_range("basic_string");1778 }1779 1780 friend basic_string operator+ <>(const basic_string&, const basic_string&);1781 friend basic_string operator+ <>(const value_type*, const basic_string&);1782 friend basic_string operator+ <>(value_type, const basic_string&);1783 friend basic_string operator+ <>(const basic_string&, const value_type*);1784 friend basic_string operator+ <>(const basic_string&, value_type);1785};1786 1787// These declarations must appear before any functions are implicitly used1788// so that they have the correct visibility specifier.1789#define _LIBCPP_DECLARE(...) extern template __VA_ARGS__;1790#ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION1791_LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, char)1792# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS1793_LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, wchar_t)1794# endif1795#else1796_LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, char)1797# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS1798_LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, wchar_t)1799# endif1800#endif1801#undef _LIBCPP_DECLARE1802 1803template <class _CharT, class _Traits, class _Allocator>1804void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz, size_type __reserve) {1805 if (__libcpp_is_constant_evaluated())1806 __r_.first() = __rep();1807 if (__reserve > max_size())1808 __throw_length_error();1809 pointer __p;1810 if (__fits_in_sso(__reserve)) {1811 __set_short_size(__sz);1812 __p = __get_short_pointer();1813 } else {1814 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__reserve) + 1);1815 __p = __allocation.ptr;1816 __begin_lifetime(__p, __allocation.count);1817 __set_long_pointer(__p);1818 __set_long_cap(__allocation.count);1819 __set_long_size(__sz);1820 }1821 traits_type::copy(std::__to_address(__p), __s, __sz);1822 traits_type::assign(__p[__sz], value_type());1823 __annotate_new(__sz);1824}1825 1826template <class _CharT, class _Traits, class _Allocator>1827void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz) {1828 if (__libcpp_is_constant_evaluated())1829 __r_.first() = __rep();1830 if (__sz > max_size())1831 __throw_length_error();1832 pointer __p;1833 if (__fits_in_sso(__sz)) {1834 __set_short_size(__sz);1835 __p = __get_short_pointer();1836 } else {1837 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1);1838 __p = __allocation.ptr;1839 __begin_lifetime(__p, __allocation.count);1840 __set_long_pointer(__p);1841 __set_long_cap(__allocation.count);1842 __set_long_size(__sz);1843 }1844 traits_type::copy(std::__to_address(__p), __s, __sz);1845 traits_type::assign(__p[__sz], value_type());1846 __annotate_new(__sz);1847}1848 1849template <class _CharT, class _Traits, class _Allocator>1850_LIBCPP_NOINLINE void1851basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external(const value_type* __s, size_type __sz) {1852 if (__libcpp_is_constant_evaluated())1853 __r_.first() = __rep();1854 1855 pointer __p;1856 if (__fits_in_sso(__sz)) {1857 __p = __get_short_pointer();1858 __set_short_size(__sz);1859 } else {1860 if (__sz > max_size())1861 __throw_length_error();1862 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1);1863 __p = __allocation.ptr;1864 __begin_lifetime(__p, __allocation.count);1865 __set_long_pointer(__p);1866 __set_long_cap(__allocation.count);1867 __set_long_size(__sz);1868 }1869 traits_type::copy(std::__to_address(__p), __s, __sz + 1);1870 __annotate_new(__sz);1871}1872 1873template <class _CharT, class _Traits, class _Allocator>1874void basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c) {1875 if (__libcpp_is_constant_evaluated())1876 __r_.first() = __rep();1877 1878 if (__n > max_size())1879 __throw_length_error();1880 pointer __p;1881 if (__fits_in_sso(__n)) {1882 __set_short_size(__n);1883 __p = __get_short_pointer();1884 } else {1885 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__n) + 1);1886 __p = __allocation.ptr;1887 __begin_lifetime(__p, __allocation.count);1888 __set_long_pointer(__p);1889 __set_long_cap(__allocation.count);1890 __set_long_size(__n);1891 }1892 traits_type::assign(std::__to_address(__p), __n, __c);1893 traits_type::assign(__p[__n], value_type());1894 __annotate_new(__n);1895}1896 1897template <class _CharT, class _Traits, class _Allocator>1898template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> >1899void basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last) {1900 __init_with_sentinel(std::move(__first), std::move(__last));1901}1902 1903template <class _CharT, class _Traits, class _Allocator>1904template <class _InputIterator, class _Sentinel>1905_LIBCPP_HIDE_FROM_ABI void1906basic_string<_CharT, _Traits, _Allocator>::__init_with_sentinel(_InputIterator __first, _Sentinel __last) {1907 __r_.first() = __rep();1908 __annotate_new(0);1909 1910#ifndef _LIBCPP_HAS_NO_EXCEPTIONS1911 try {1912#endif // _LIBCPP_HAS_NO_EXCEPTIONS1913 for (; __first != __last; ++__first)1914 push_back(*__first);1915#ifndef _LIBCPP_HAS_NO_EXCEPTIONS1916 } catch (...) {1917 __annotate_delete();1918 if (__is_long())1919 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());1920 throw;1921 }1922#endif // _LIBCPP_HAS_NO_EXCEPTIONS1923}1924 1925template <class _CharT, class _Traits, class _Allocator>1926template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> >1927void basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last) {1928 size_type __sz = static_cast<size_type>(std::distance(__first, __last));1929 __init_with_size(__first, __last, __sz);1930}1931 1932template <class _CharT, class _Traits, class _Allocator>1933template <class _InputIterator, class _Sentinel>1934_LIBCPP_HIDE_FROM_ABI void1935basic_string<_CharT, _Traits, _Allocator>::__init_with_size(_InputIterator __first, _Sentinel __last, size_type __sz) {1936 if (__libcpp_is_constant_evaluated())1937 __r_.first() = __rep();1938 1939 if (__sz > max_size())1940 __throw_length_error();1941 1942 pointer __p;1943 if (__fits_in_sso(__sz)) {1944 __set_short_size(__sz);1945 __p = __get_short_pointer();1946 1947 } else {1948 auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1);1949 __p = __allocation.ptr;1950 __begin_lifetime(__p, __allocation.count);1951 __set_long_pointer(__p);1952 __set_long_cap(__allocation.count);1953 __set_long_size(__sz);1954 }1955 1956#ifndef _LIBCPP_HAS_NO_EXCEPTIONS1957 try {1958#endif // _LIBCPP_HAS_NO_EXCEPTIONS1959 auto __end = __copy_non_overlapping_range(__first, __last, std::__to_address(__p));1960 traits_type::assign(*__end, value_type());1961#ifndef _LIBCPP_HAS_NO_EXCEPTIONS1962 } catch (...) {1963 if (__is_long())1964 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());1965 throw;1966 }1967#endif // _LIBCPP_HAS_NO_EXCEPTIONS1968 __annotate_new(__sz);1969}1970 1971template <class _CharT, class _Traits, class _Allocator>1972void basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace(1973 size_type __old_cap,1974 size_type __delta_cap,1975 size_type __old_sz,1976 size_type __n_copy,1977 size_type __n_del,1978 size_type __n_add,1979 const value_type* __p_new_stuff) {1980 size_type __ms = max_size();1981 if (__delta_cap > __ms - __old_cap)1982 __throw_length_error();1983 pointer __old_p = __get_pointer();1984 size_type __cap =1985 __old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms;1986 __annotate_delete();1987 auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1);1988 pointer __p = __allocation.ptr;1989 __begin_lifetime(__p, __allocation.count);1990 if (__n_copy != 0)1991 traits_type::copy(std::__to_address(__p), std::__to_address(__old_p), __n_copy);1992 if (__n_add != 0)1993 traits_type::copy(std::__to_address(__p) + __n_copy, __p_new_stuff, __n_add);1994 size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;1995 if (__sec_cp_sz != 0)1996 traits_type::copy(1997 std::__to_address(__p) + __n_copy + __n_add, std::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz);1998 if (__old_cap + 1 != __min_cap)1999 __alloc_traits::deallocate(__alloc(), __old_p, __old_cap + 1);2000 __set_long_pointer(__p);2001 __set_long_cap(__allocation.count);2002 __old_sz = __n_copy + __n_add + __sec_cp_sz;2003 __set_long_size(__old_sz);2004 traits_type::assign(__p[__old_sz], value_type());2005 __annotate_new(__old_sz);2006}2007 2008// __grow_by is deprecated because it does not set the size. It may not update the size when the size is changed, and it2009// may also not set the size at all when the string was short initially. This leads to unpredictable size value. It is2010// not removed or changed to avoid breaking the ABI.2011template <class _CharT, class _Traits, class _Allocator>2012void2013#if _LIBCPP_ABI_VERSION >= 2 // We want to use the function in the dylib in ABIv12014 _LIBCPP_HIDE_FROM_ABI2015#endif2016 _LIBCPP_DEPRECATED_("use __grow_by_without_replace") basic_string<_CharT, _Traits, _Allocator>::__grow_by(2017 size_type __old_cap,2018 size_type __delta_cap,2019 size_type __old_sz,2020 size_type __n_copy,2021 size_type __n_del,2022 size_type __n_add) {2023 size_type __ms = max_size();2024 if (__delta_cap > __ms - __old_cap)2025 __throw_length_error();2026 pointer __old_p = __get_pointer();2027 size_type __cap =2028 __old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms;2029 __annotate_delete();2030 auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1);2031 pointer __p = __allocation.ptr;2032 __begin_lifetime(__p, __allocation.count);2033 if (__n_copy != 0)2034 traits_type::copy(std::__to_address(__p), std::__to_address(__old_p), __n_copy);2035 size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;2036 if (__sec_cp_sz != 0)2037 traits_type::copy(2038 std::__to_address(__p) + __n_copy + __n_add, std::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz);2039 if (__old_cap + 1 != __min_cap)2040 __alloc_traits::deallocate(__alloc(), __old_p, __old_cap + 1);2041 __set_long_pointer(__p);2042 __set_long_cap(__allocation.count);2043}2044 2045template <class _CharT, class _Traits, class _Allocator>2046void _LIBCPP_HIDE_FROM_ABI basic_string<_CharT, _Traits, _Allocator>::__grow_by_without_replace(2047 size_type __old_cap,2048 size_type __delta_cap,2049 size_type __old_sz,2050 size_type __n_copy,2051 size_type __n_del,2052 size_type __n_add) {2053 _LIBCPP_SUPPRESS_DEPRECATED_PUSH2054 __grow_by(__old_cap, __delta_cap, __old_sz, __n_copy, __n_del, __n_add);2055 _LIBCPP_SUPPRESS_DEPRECATED_POP2056 __set_long_size(__old_sz - __n_del + __n_add);2057 __annotate_new(__old_sz - __n_del + __n_add);2058}2059 2060// assign2061 2062template <class _CharT, class _Traits, class _Allocator>2063template <bool __is_short>2064_LIBCPP_NOINLINE basic_string<_CharT, _Traits, _Allocator>&2065basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias(const value_type* __s, size_type __n) {2066 size_type __cap = __is_short ? static_cast<size_type>(__min_cap) : __get_long_cap();2067 if (__n < __cap) {2068 size_type __old_size = __is_short ? __get_short_size() : __get_long_size();2069 if (__n > __old_size)2070 __annotate_increase(__n - __old_size);2071 pointer __p = __is_short ? __get_short_pointer() : __get_long_pointer();2072 __is_short ? __set_short_size(__n) : __set_long_size(__n);2073 traits_type::copy(std::__to_address(__p), __s, __n);2074 traits_type::assign(__p[__n], value_type());2075 if (__old_size > __n)2076 __annotate_shrink(__old_size);2077 } else {2078 size_type __sz = __is_short ? __get_short_size() : __get_long_size();2079 __grow_by_and_replace(__cap - 1, __n - __cap + 1, __sz, 0, __sz, __n, __s);2080 }2081 return *this;2082}2083 2084template <class _CharT, class _Traits, class _Allocator>2085_LIBCPP_NOINLINE basic_string<_CharT, _Traits, _Allocator>&2086basic_string<_CharT, _Traits, _Allocator>::__assign_external(const value_type* __s, size_type __n) {2087 size_type __cap = capacity();2088 if (__cap >= __n) {2089 size_type __old_size = size();2090 if (__n > __old_size)2091 __annotate_increase(__n - __old_size);2092 value_type* __p = std::__to_address(__get_pointer());2093 traits_type::move(__p, __s, __n);2094 return __null_terminate_at(__p, __n);2095 } else {2096 size_type __sz = size();2097 __grow_by_and_replace(__cap, __n - __cap, __sz, 0, __sz, __n, __s);2098 return *this;2099 }2100}2101 2102template <class _CharT, class _Traits, class _Allocator>2103basic_string<_CharT, _Traits, _Allocator>&2104basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n) {2105 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::assign received nullptr");2106 return (__builtin_constant_p(__n) && __fits_in_sso(__n)) ? __assign_short(__s, __n) : __assign_external(__s, __n);2107}2108 2109template <class _CharT, class _Traits, class _Allocator>2110basic_string<_CharT, _Traits, _Allocator>&2111basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c) {2112 size_type __cap = capacity();2113 size_type __old_size = size();2114 if (__cap < __n) {2115 size_type __sz = size();2116 __grow_by_without_replace(__cap, __n - __cap, __sz, 0, __sz);2117 __annotate_increase(__n);2118 } else if (__n > __old_size)2119 __annotate_increase(__n - __old_size);2120 value_type* __p = std::__to_address(__get_pointer());2121 traits_type::assign(__p, __n, __c);2122 return __null_terminate_at(__p, __n);2123}2124 2125template <class _CharT, class _Traits, class _Allocator>2126basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c) {2127 pointer __p;2128 size_type __old_size = size();2129 if (__old_size == 0)2130 __annotate_increase(1);2131 if (__is_long()) {2132 __p = __get_long_pointer();2133 __set_long_size(1);2134 } else {2135 __p = __get_short_pointer();2136 __set_short_size(1);2137 }2138 traits_type::assign(*__p, __c);2139 traits_type::assign(*++__p, value_type());2140 if (__old_size > 1)2141 __annotate_shrink(__old_size);2142 return *this;2143}2144 2145template <class _CharT, class _Traits, class _Allocator>2146_LIBCPP_STRING_INTERNAL_MEMORY_ACCESS basic_string<_CharT, _Traits, _Allocator>&2147basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str) {2148 if (this != std::addressof(__str)) {2149 __copy_assign_alloc(__str);2150 if (!__is_long()) {2151 if (!__str.__is_long()) {2152 size_type __old_size = __get_short_size();2153 if (__get_short_size() < __str.__get_short_size())2154 __annotate_increase(__str.__get_short_size() - __get_short_size());2155 __r_.first() = __str.__r_.first();2156 if (__old_size > __get_short_size())2157 __annotate_shrink(__old_size);2158 } else {2159 return __assign_no_alias<true>(__str.data(), __str.size());2160 }2161 } else {2162 return __assign_no_alias<false>(__str.data(), __str.size());2163 }2164 }2165 return *this;2166}2167 2168template <class _CharT, class _Traits, class _Allocator>2169template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> >2170basic_string<_CharT, _Traits, _Allocator>&2171basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last) {2172 __assign_with_sentinel(__first, __last);2173 return *this;2174}2175 2176template <class _CharT, class _Traits, class _Allocator>2177template <class _InputIterator, class _Sentinel>2178_LIBCPP_HIDE_FROM_ABI void2179basic_string<_CharT, _Traits, _Allocator>::__assign_with_sentinel(_InputIterator __first, _Sentinel __last) {2180 const basic_string __temp(__init_with_sentinel_tag(), std::move(__first), std::move(__last), __alloc());2181 assign(__temp.data(), __temp.size());2182}2183 2184template <class _CharT, class _Traits, class _Allocator>2185template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> >2186basic_string<_CharT, _Traits, _Allocator>&2187basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last) {2188 if (__string_is_trivial_iterator<_ForwardIterator>::value) {2189 size_type __n = static_cast<size_type>(std::distance(__first, __last));2190 __assign_trivial(__first, __last, __n);2191 } else {2192 __assign_with_sentinel(__first, __last);2193 }2194 2195 return *this;2196}2197 2198template <class _CharT, class _Traits, class _Allocator>2199template <class _Iterator, class _Sentinel>2200_LIBCPP_HIDE_FROM_ABI void2201basic_string<_CharT, _Traits, _Allocator>::__assign_trivial(_Iterator __first, _Sentinel __last, size_type __n) {2202 _LIBCPP_ASSERT_INTERNAL(2203 __string_is_trivial_iterator<_Iterator>::value, "The iterator type given to `__assign_trivial` must be trivial");2204 2205 size_type __old_size = size();2206 size_type __cap = capacity();2207 if (__cap < __n) {2208 // Unlike `append` functions, if the input range points into the string itself, there is no case that the input2209 // range could get invalidated by reallocation:2210 // 1. If the input range is a subset of the string itself, its size cannot exceed the capacity of the string,2211 // thus no reallocation would happen.2212 // 2. In the exotic case where the input range is the byte representation of the string itself, the string2213 // object itself stays valid even if reallocation happens.2214 size_type __sz = size();2215 __grow_by_without_replace(__cap, __n - __cap, __sz, 0, __sz);2216 __annotate_increase(__n);2217 } else if (__n > __old_size)2218 __annotate_increase(__n - __old_size);2219 pointer __p = __get_pointer();2220 for (; __first != __last; ++__p, (void)++__first)2221 traits_type::assign(*__p, *__first);2222 traits_type::assign(*__p, value_type());2223 __set_size(__n);2224 if (__n < __old_size)2225 __annotate_shrink(__old_size);2226}2227 2228template <class _CharT, class _Traits, class _Allocator>2229basic_string<_CharT, _Traits, _Allocator>&2230basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, size_type __pos, size_type __n) {2231 size_type __sz = __str.size();2232 if (__pos > __sz)2233 __throw_out_of_range();2234 return assign(__str.data() + __pos, std::min(__n, __sz - __pos));2235}2236 2237template <class _CharT, class _Traits, class _Allocator>2238template <class _Tp,2239 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&2240 !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,2241 int> >2242basic_string<_CharT, _Traits, _Allocator>&2243basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp& __t, size_type __pos, size_type __n) {2244 __self_view __sv = __t;2245 size_type __sz = __sv.size();2246 if (__pos > __sz)2247 __throw_out_of_range();2248 return assign(__sv.data() + __pos, std::min(__n, __sz - __pos));2249}2250 2251template <class _CharT, class _Traits, class _Allocator>2252_LIBCPP_NOINLINE basic_string<_CharT, _Traits, _Allocator>&2253basic_string<_CharT, _Traits, _Allocator>::__assign_external(const value_type* __s) {2254 return __assign_external(__s, traits_type::length(__s));2255}2256 2257template <class _CharT, class _Traits, class _Allocator>2258basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s) {2259 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::assign received nullptr");2260 return __builtin_constant_p(*__s)2261 ? (__fits_in_sso(traits_type::length(__s)) ? __assign_short(__s, traits_type::length(__s))2262 : __assign_external(__s, traits_type::length(__s)))2263 : __assign_external(__s);2264}2265// append2266 2267template <class _CharT, class _Traits, class _Allocator>2268basic_string<_CharT, _Traits, _Allocator>&2269basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n) {2270 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::append received nullptr");2271 size_type __cap = capacity();2272 size_type __sz = size();2273 if (__cap - __sz >= __n) {2274 if (__n) {2275 __annotate_increase(__n);2276 value_type* __p = std::__to_address(__get_pointer());2277 traits_type::copy(__p + __sz, __s, __n);2278 __sz += __n;2279 __set_size(__sz);2280 traits_type::assign(__p[__sz], value_type());2281 }2282 } else2283 __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __sz, 0, __n, __s);2284 return *this;2285}2286 2287template <class _CharT, class _Traits, class _Allocator>2288basic_string<_CharT, _Traits, _Allocator>&2289basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c) {2290 if (__n) {2291 size_type __cap = capacity();2292 size_type __sz = size();2293 if (__cap - __sz < __n)2294 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);2295 __annotate_increase(__n);2296 pointer __p = __get_pointer();2297 traits_type::assign(std::__to_address(__p) + __sz, __n, __c);2298 __sz += __n;2299 __set_size(__sz);2300 traits_type::assign(__p[__sz], value_type());2301 }2302 return *this;2303}2304 2305template <class _CharT, class _Traits, class _Allocator>2306inline void basic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n) {2307 if (__n) {2308 size_type __cap = capacity();2309 size_type __sz = size();2310 if (__cap - __sz < __n)2311 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);2312 __annotate_increase(__n);2313 pointer __p = __get_pointer();2314 __sz += __n;2315 __set_size(__sz);2316 traits_type::assign(__p[__sz], value_type());2317 }2318}2319 2320template <class _CharT, class _Traits, class _Allocator>2321void basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c) {2322 bool __is_short = !__is_long();2323 size_type __cap;2324 size_type __sz;2325 if (__is_short) {2326 __cap = __min_cap - 1;2327 __sz = __get_short_size();2328 } else {2329 __cap = __get_long_cap() - 1;2330 __sz = __get_long_size();2331 }2332 if (__sz == __cap) {2333 __grow_by_without_replace(__cap, 1, __sz, __sz, 0);2334 __annotate_increase(1);2335 __is_short = false; // the string is always long after __grow_by2336 } else2337 __annotate_increase(1);2338 pointer __p = __get_pointer();2339 if (__is_short) {2340 __p = __get_short_pointer() + __sz;2341 __set_short_size(__sz + 1);2342 } else {2343 __p = __get_long_pointer() + __sz;2344 __set_long_size(__sz + 1);2345 }2346 traits_type::assign(*__p, __c);2347 traits_type::assign(*++__p, value_type());2348}2349 2350template <class _CharT, class _Traits, class _Allocator>2351template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> >2352basic_string<_CharT, _Traits, _Allocator>&2353basic_string<_CharT, _Traits, _Allocator>::append(_ForwardIterator __first, _ForwardIterator __last) {2354 size_type __sz = size();2355 size_type __cap = capacity();2356 size_type __n = static_cast<size_type>(std::distance(__first, __last));2357 if (__n) {2358 if (__string_is_trivial_iterator<_ForwardIterator>::value && !__addr_in_range(*__first)) {2359 if (__cap - __sz < __n)2360 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);2361 __annotate_increase(__n);2362 auto __end = __copy_non_overlapping_range(__first, __last, std::__to_address(__get_pointer() + __sz));2363 traits_type::assign(*__end, value_type());2364 __set_size(__sz + __n);2365 } else {2366 const basic_string __temp(__first, __last, __alloc());2367 append(__temp.data(), __temp.size());2368 }2369 }2370 return *this;2371}2372 2373template <class _CharT, class _Traits, class _Allocator>2374basic_string<_CharT, _Traits, _Allocator>&2375basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, size_type __pos, size_type __n) {2376 size_type __sz = __str.size();2377 if (__pos > __sz)2378 __throw_out_of_range();2379 return append(__str.data() + __pos, std::min(__n, __sz - __pos));2380}2381 2382template <class _CharT, class _Traits, class _Allocator>2383template <class _Tp,2384 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&2385 !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,2386 int> >2387basic_string<_CharT, _Traits, _Allocator>&2388basic_string<_CharT, _Traits, _Allocator>::append(const _Tp& __t, size_type __pos, size_type __n) {2389 __self_view __sv = __t;2390 size_type __sz = __sv.size();2391 if (__pos > __sz)2392 __throw_out_of_range();2393 return append(__sv.data() + __pos, std::min(__n, __sz - __pos));2394}2395 2396template <class _CharT, class _Traits, class _Allocator>2397basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s) {2398 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::append received nullptr");2399 return append(__s, traits_type::length(__s));2400}2401 2402// insert2403 2404template <class _CharT, class _Traits, class _Allocator>2405basic_string<_CharT, _Traits, _Allocator>&2406basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n) {2407 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::insert received nullptr");2408 size_type __sz = size();2409 if (__pos > __sz)2410 __throw_out_of_range();2411 size_type __cap = capacity();2412 if (__cap - __sz >= __n) {2413 if (__n) {2414 __annotate_increase(__n);2415 value_type* __p = std::__to_address(__get_pointer());2416 size_type __n_move = __sz - __pos;2417 if (__n_move != 0) {2418 if (std::__is_pointer_in_range(__p + __pos, __p + __sz, __s))2419 __s += __n;2420 traits_type::move(__p + __pos + __n, __p + __pos, __n_move);2421 }2422 traits_type::move(__p + __pos, __s, __n);2423 __sz += __n;2424 __set_size(__sz);2425 traits_type::assign(__p[__sz], value_type());2426 }2427 } else2428 __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s);2429 return *this;2430}2431 2432template <class _CharT, class _Traits, class _Allocator>2433basic_string<_CharT, _Traits, _Allocator>&2434basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n, value_type __c) {2435 size_type __sz = size();2436 if (__pos > __sz)2437 __throw_out_of_range();2438 if (__n) {2439 size_type __cap = capacity();2440 value_type* __p;2441 if (__cap - __sz >= __n) {2442 __annotate_increase(__n);2443 __p = std::__to_address(__get_pointer());2444 size_type __n_move = __sz - __pos;2445 if (__n_move != 0)2446 traits_type::move(__p + __pos + __n, __p + __pos, __n_move);2447 } else {2448 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n);2449 __p = std::__to_address(__get_long_pointer());2450 }2451 traits_type::assign(__p + __pos, __n, __c);2452 __sz += __n;2453 __set_size(__sz);2454 traits_type::assign(__p[__sz], value_type());2455 }2456 return *this;2457}2458 2459template <class _CharT, class _Traits, class _Allocator>2460template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> >2461typename basic_string<_CharT, _Traits, _Allocator>::iterator2462basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last) {2463 const basic_string __temp(__first, __last, __alloc());2464 return insert(__pos, __temp.data(), __temp.data() + __temp.size());2465}2466 2467template <class _CharT, class _Traits, class _Allocator>2468template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> >2469typename basic_string<_CharT, _Traits, _Allocator>::iterator basic_string<_CharT, _Traits, _Allocator>::insert(2470 const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last) {2471 auto __n = static_cast<size_type>(std::distance(__first, __last));2472 return __insert_with_size(__pos, __first, __last, __n);2473}2474 2475template <class _CharT, class _Traits, class _Allocator>2476template <class _Iterator, class _Sentinel>2477typename basic_string<_CharT, _Traits, _Allocator>::iterator2478basic_string<_CharT, _Traits, _Allocator>::__insert_with_size(2479 const_iterator __pos, _Iterator __first, _Sentinel __last, size_type __n) {2480 size_type __ip = static_cast<size_type>(__pos - begin());2481 if (__n == 0)2482 return begin() + __ip;2483 2484 if (__string_is_trivial_iterator<_Iterator>::value && !__addr_in_range(*__first)) {2485 return __insert_from_safe_copy(__n, __ip, __first, __last);2486 } else {2487 const basic_string __temp(__init_with_sentinel_tag(), __first, __last, __alloc());2488 return __insert_from_safe_copy(__n, __ip, __temp.begin(), __temp.end());2489 }2490}2491 2492template <class _CharT, class _Traits, class _Allocator>2493basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::insert(2494 size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n) {2495 size_type __str_sz = __str.size();2496 if (__pos2 > __str_sz)2497 __throw_out_of_range();2498 return insert(__pos1, __str.data() + __pos2, std::min(__n, __str_sz - __pos2));2499}2500 2501template <class _CharT, class _Traits, class _Allocator>2502template <class _Tp,2503 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&2504 !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,2505 int> >2506basic_string<_CharT, _Traits, _Allocator>&2507basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n) {2508 __self_view __sv = __t;2509 size_type __str_sz = __sv.size();2510 if (__pos2 > __str_sz)2511 __throw_out_of_range();2512 return insert(__pos1, __sv.data() + __pos2, std::min(__n, __str_sz - __pos2));2513}2514 2515template <class _CharT, class _Traits, class _Allocator>2516basic_string<_CharT, _Traits, _Allocator>&2517basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s) {2518 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::insert received nullptr");2519 return insert(__pos, __s, traits_type::length(__s));2520}2521 2522template <class _CharT, class _Traits, class _Allocator>2523typename basic_string<_CharT, _Traits, _Allocator>::iterator2524basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c) {2525 size_type __ip = static_cast<size_type>(__pos - begin());2526 size_type __sz = size();2527 size_type __cap = capacity();2528 value_type* __p;2529 if (__cap == __sz) {2530 __grow_by_without_replace(__cap, 1, __sz, __ip, 0, 1);2531 __p = std::__to_address(__get_long_pointer());2532 } else {2533 __annotate_increase(1);2534 __p = std::__to_address(__get_pointer());2535 size_type __n_move = __sz - __ip;2536 if (__n_move != 0)2537 traits_type::move(__p + __ip + 1, __p + __ip, __n_move);2538 }2539 traits_type::assign(__p[__ip], __c);2540 traits_type::assign(__p[++__sz], value_type());2541 __set_size(__sz);2542 return begin() + static_cast<difference_type>(__ip);2543}2544 2545// replace2546 2547template <class _CharT, class _Traits, class _Allocator>2548basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(2549 size_type __pos, size_type __n1, const value_type* __s, size_type __n2)2550 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK {2551 _LIBCPP_ASSERT_NON_NULL(__n2 == 0 || __s != nullptr, "string::replace received nullptr");2552 size_type __sz = size();2553 if (__pos > __sz)2554 __throw_out_of_range();2555 __n1 = std::min(__n1, __sz - __pos);2556 size_type __cap = capacity();2557 if (__cap - __sz + __n1 >= __n2) {2558 value_type* __p = std::__to_address(__get_pointer());2559 if (__n1 != __n2) {2560 if (__n2 > __n1)2561 __annotate_increase(__n2 - __n1);2562 size_type __n_move = __sz - __pos - __n1;2563 if (__n_move != 0) {2564 if (__n1 > __n2) {2565 traits_type::move(__p + __pos, __s, __n2);2566 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);2567 return __null_terminate_at(__p, __sz + (__n2 - __n1));2568 }2569 if (std::__is_pointer_in_range(__p + __pos + 1, __p + __sz, __s)) {2570 if (__p + __pos + __n1 <= __s)2571 __s += __n2 - __n1;2572 else // __p + __pos < __s < __p + __pos + __n12573 {2574 traits_type::move(__p + __pos, __s, __n1);2575 __pos += __n1;2576 __s += __n2;2577 __n2 -= __n1;2578 __n1 = 0;2579 }2580 }2581 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);2582 }2583 }2584 traits_type::move(__p + __pos, __s, __n2);2585 return __null_terminate_at(__p, __sz + (__n2 - __n1));2586 } else2587 __grow_by_and_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2, __s);2588 return *this;2589}2590 2591template <class _CharT, class _Traits, class _Allocator>2592basic_string<_CharT, _Traits, _Allocator>&2593basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, size_type __n2, value_type __c) {2594 size_type __sz = size();2595 if (__pos > __sz)2596 __throw_out_of_range();2597 __n1 = std::min(__n1, __sz - __pos);2598 size_type __cap = capacity();2599 value_type* __p;2600 if (__cap - __sz + __n1 >= __n2) {2601 __p = std::__to_address(__get_pointer());2602 if (__n1 != __n2) {2603 if (__n2 > __n1)2604 __annotate_increase(__n2 - __n1);2605 size_type __n_move = __sz - __pos - __n1;2606 if (__n_move != 0)2607 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);2608 }2609 } else {2610 __grow_by_without_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2);2611 __p = std::__to_address(__get_long_pointer());2612 }2613 traits_type::assign(__p + __pos, __n2, __c);2614 return __null_terminate_at(__p, __sz - (__n1 - __n2));2615}2616 2617template <class _CharT, class _Traits, class _Allocator>2618template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> >2619basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(2620 const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2) {2621 const basic_string __temp(__j1, __j2, __alloc());2622 return replace(__i1, __i2, __temp);2623}2624 2625template <class _CharT, class _Traits, class _Allocator>2626basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(2627 size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2) {2628 size_type __str_sz = __str.size();2629 if (__pos2 > __str_sz)2630 __throw_out_of_range();2631 return replace(__pos1, __n1, __str.data() + __pos2, std::min(__n2, __str_sz - __pos2));2632}2633 2634template <class _CharT, class _Traits, class _Allocator>2635template <class _Tp,2636 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&2637 !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,2638 int> >2639basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(2640 size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2) {2641 __self_view __sv = __t;2642 size_type __str_sz = __sv.size();2643 if (__pos2 > __str_sz)2644 __throw_out_of_range();2645 return replace(__pos1, __n1, __sv.data() + __pos2, std::min(__n2, __str_sz - __pos2));2646}2647 2648template <class _CharT, class _Traits, class _Allocator>2649basic_string<_CharT, _Traits, _Allocator>&2650basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s) {2651 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::replace received nullptr");2652 return replace(__pos, __n1, __s, traits_type::length(__s));2653}2654 2655// erase2656 2657// 'externally instantiated' erase() implementation, called when __n != npos.2658// Does not check __pos against size()2659template <class _CharT, class _Traits, class _Allocator>2660_LIBCPP_NOINLINE void2661basic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move(size_type __pos, size_type __n) {2662 if (__n) {2663 size_type __sz = size();2664 value_type* __p = std::__to_address(__get_pointer());2665 __n = std::min(__n, __sz - __pos);2666 size_type __n_move = __sz - __pos - __n;2667 if (__n_move != 0)2668 traits_type::move(__p + __pos, __p + __pos + __n, __n_move);2669 __null_terminate_at(__p, __sz - __n);2670 }2671}2672 2673template <class _CharT, class _Traits, class _Allocator>2674basic_string<_CharT, _Traits, _Allocator>&2675basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, size_type __n) {2676 if (__pos > size())2677 __throw_out_of_range();2678 if (__n == npos) {2679 __erase_to_end(__pos);2680 } else {2681 __erase_external_with_move(__pos, __n);2682 }2683 return *this;2684}2685 2686template <class _CharT, class _Traits, class _Allocator>2687inline typename basic_string<_CharT, _Traits, _Allocator>::iterator2688basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos) {2689 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(2690 __pos != end(), "string::erase(iterator) called with a non-dereferenceable iterator");2691 iterator __b = begin();2692 size_type __r = static_cast<size_type>(__pos - __b);2693 erase(__r, 1);2694 return __b + static_cast<difference_type>(__r);2695}2696 2697template <class _CharT, class _Traits, class _Allocator>2698inline typename basic_string<_CharT, _Traits, _Allocator>::iterator2699basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last) {2700 _LIBCPP_ASSERT_VALID_INPUT_RANGE(__first <= __last, "string::erase(first, last) called with invalid range");2701 iterator __b = begin();2702 size_type __r = static_cast<size_type>(__first - __b);2703 erase(__r, static_cast<size_type>(__last - __first));2704 return __b + static_cast<difference_type>(__r);2705}2706 2707template <class _CharT, class _Traits, class _Allocator>2708inline void basic_string<_CharT, _Traits, _Allocator>::pop_back() {2709 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::pop_back(): string is already empty");2710 __erase_to_end(size() - 1);2711}2712 2713template <class _CharT, class _Traits, class _Allocator>2714inline void basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT {2715 size_type __old_size = size();2716 if (__is_long()) {2717 traits_type::assign(*__get_long_pointer(), value_type());2718 __set_long_size(0);2719 } else {2720 traits_type::assign(*__get_short_pointer(), value_type());2721 __set_short_size(0);2722 }2723 __annotate_shrink(__old_size);2724}2725 2726template <class _CharT, class _Traits, class _Allocator>2727void basic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c) {2728 size_type __sz = size();2729 if (__n > __sz)2730 append(__n - __sz, __c);2731 else2732 __erase_to_end(__n);2733}2734 2735template <class _CharT, class _Traits, class _Allocator>2736inline void basic_string<_CharT, _Traits, _Allocator>::__resize_default_init(size_type __n) {2737 size_type __sz = size();2738 if (__n > __sz) {2739 __append_default_init(__n - __sz);2740 } else2741 __erase_to_end(__n);2742}2743 2744template <class _CharT, class _Traits, class _Allocator>2745void basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacity) {2746 if (__requested_capacity > max_size())2747 __throw_length_error();2748 2749 // Make sure reserve(n) never shrinks. This is technically only required in C++202750 // and later (since P0966R1), however we provide consistent behavior in all Standard2751 // modes because this function is instantiated in the shared library.2752 if (__requested_capacity <= capacity())2753 return;2754 2755 size_type __target_capacity = std::max(__requested_capacity, size());2756 __target_capacity = __recommend(__target_capacity);2757 if (__target_capacity == capacity())2758 return;2759 2760 __shrink_or_extend(__target_capacity);2761}2762 2763template <class _CharT, class _Traits, class _Allocator>2764inline void basic_string<_CharT, _Traits, _Allocator>::shrink_to_fit() _NOEXCEPT {2765 size_type __target_capacity = __recommend(size());2766 if (__target_capacity == capacity())2767 return;2768 2769 __shrink_or_extend(__target_capacity);2770}2771 2772template <class _CharT, class _Traits, class _Allocator>2773inline void basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target_capacity) {2774 __annotate_delete();2775 size_type __cap = capacity();2776 size_type __sz = size();2777 2778 pointer __new_data, __p;2779 bool __was_long, __now_long;2780 if (__fits_in_sso(__target_capacity)) {2781 __was_long = true;2782 __now_long = false;2783 __new_data = __get_short_pointer();2784 __p = __get_long_pointer();2785 } else {2786 if (__target_capacity > __cap) {2787 // Extend2788 // - called from reserve should propagate the exception thrown.2789 auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1);2790 __new_data = __allocation.ptr;2791 __target_capacity = __allocation.count - 1;2792 } else {2793 // Shrink2794 // - called from shrink_to_fit should not throw.2795 // - called from reserve may throw but is not required to.2796#ifndef _LIBCPP_HAS_NO_EXCEPTIONS2797 try {2798#endif // _LIBCPP_HAS_NO_EXCEPTIONS2799 auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1);2800 2801 // The Standard mandates shrink_to_fit() does not increase the capacity.2802 // With equal capacity keep the existing buffer. This avoids extra work2803 // due to swapping the elements.2804 if (__allocation.count - 1 > __target_capacity) {2805 __alloc_traits::deallocate(__alloc(), __allocation.ptr, __allocation.count);2806 __annotate_new(__sz); // Undoes the __annotate_delete()2807 return;2808 }2809 __new_data = __allocation.ptr;2810 __target_capacity = __allocation.count - 1;2811#ifndef _LIBCPP_HAS_NO_EXCEPTIONS2812 } catch (...) {2813 return;2814 }2815#endif // _LIBCPP_HAS_NO_EXCEPTIONS2816 }2817 __begin_lifetime(__new_data, __target_capacity + 1);2818 __now_long = true;2819 __was_long = __is_long();2820 __p = __get_pointer();2821 }2822 traits_type::copy(std::__to_address(__new_data), std::__to_address(__p), size() + 1);2823 if (__was_long)2824 __alloc_traits::deallocate(__alloc(), __p, __cap + 1);2825 if (__now_long) {2826 __set_long_cap(__target_capacity + 1);2827 __set_long_size(__sz);2828 __set_long_pointer(__new_data);2829 } else2830 __set_short_size(__sz);2831 __annotate_new(__sz);2832}2833 2834template <class _CharT, class _Traits, class _Allocator>2835typename basic_string<_CharT, _Traits, _Allocator>::const_reference2836basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const {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>::reference2844basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) {2845 if (__n >= size())2846 __throw_out_of_range();2847 return (*this)[__n];2848}2849 2850template <class _CharT, class _Traits, class _Allocator>2851typename basic_string<_CharT, _Traits, _Allocator>::size_type2852basic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n, size_type __pos) const {2853 size_type __sz = size();2854 if (__pos > __sz)2855 __throw_out_of_range();2856 size_type __rlen = std::min(__n, __sz - __pos);2857 traits_type::copy(__s, data() + __pos, __rlen);2858 return __rlen;2859}2860 2861template <class _CharT, class _Traits, class _Allocator>2862inline void basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str) {2863 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(2864 __alloc_traits::propagate_on_container_swap::value || __alloc_traits::is_always_equal::value ||2865 __alloc() == __str.__alloc(),2866 "swapping non-equal allocators");2867 if (!__is_long())2868 __annotate_delete();2869 if (this != std::addressof(__str) && !__str.__is_long())2870 __str.__annotate_delete();2871 std::swap(__r_.first(), __str.__r_.first());2872 std::__swap_allocator(__alloc(), __str.__alloc());2873 if (!__is_long())2874 __annotate_new(__get_short_size());2875 if (this != std::addressof(__str) && !__str.__is_long())2876 __str.__annotate_new(__str.__get_short_size());2877}2878 2879// find2880 2881template <class _Traits>2882struct _LIBCPP_HIDDEN __traits_eq {2883 typedef typename _Traits::char_type char_type;2884 _LIBCPP_HIDE_FROM_ABI bool operator()(const char_type& __x, const char_type& __y) _NOEXCEPT {2885 return _Traits::eq(__x, __y);2886 }2887};2888 2889template <class _CharT, class _Traits, class _Allocator>2890typename basic_string<_CharT, _Traits, _Allocator>::size_type2891basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT {2892 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find(): received nullptr");2893 return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);2894}2895 2896template <class _CharT, class _Traits, class _Allocator>2897inline typename basic_string<_CharT, _Traits, _Allocator>::size_type2898basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str, size_type __pos) const _NOEXCEPT {2899 return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __str.data(), __pos, __str.size());2900}2901 2902template <class _CharT, class _Traits, class _Allocator>2903template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >2904typename basic_string<_CharT, _Traits, _Allocator>::size_type2905basic_string<_CharT, _Traits, _Allocator>::find(const _Tp& __t, size_type __pos) const _NOEXCEPT {2906 __self_view __sv = __t;2907 return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __sv.data(), __pos, __sv.size());2908}2909 2910template <class _CharT, class _Traits, class _Allocator>2911inline typename basic_string<_CharT, _Traits, _Allocator>::size_type2912basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, size_type __pos) const _NOEXCEPT {2913 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find(): received nullptr");2914 return std::__str_find<value_type, size_type, traits_type, npos>(2915 data(), size(), __s, __pos, traits_type::length(__s));2916}2917 2918template <class _CharT, class _Traits, class _Allocator>2919typename basic_string<_CharT, _Traits, _Allocator>::size_type2920basic_string<_CharT, _Traits, _Allocator>::find(value_type __c, size_type __pos) const _NOEXCEPT {2921 return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);2922}2923 2924// rfind2925 2926template <class _CharT, class _Traits, class _Allocator>2927typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::rfind(2928 const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT {2929 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::rfind(): received nullptr");2930 return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);2931}2932 2933template <class _CharT, class _Traits, class _Allocator>2934inline typename basic_string<_CharT, _Traits, _Allocator>::size_type2935basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str, size_type __pos) const _NOEXCEPT {2936 return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __str.data(), __pos, __str.size());2937}2938 2939template <class _CharT, class _Traits, class _Allocator>2940template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >2941typename basic_string<_CharT, _Traits, _Allocator>::size_type2942basic_string<_CharT, _Traits, _Allocator>::rfind(const _Tp& __t, size_type __pos) const _NOEXCEPT {2943 __self_view __sv = __t;2944 return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __sv.data(), __pos, __sv.size());2945}2946 2947template <class _CharT, class _Traits, class _Allocator>2948inline typename basic_string<_CharT, _Traits, _Allocator>::size_type2949basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, size_type __pos) const _NOEXCEPT {2950 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::rfind(): received nullptr");2951 return std::__str_rfind<value_type, size_type, traits_type, npos>(2952 data(), size(), __s, __pos, traits_type::length(__s));2953}2954 2955template <class _CharT, class _Traits, class _Allocator>2956typename basic_string<_CharT, _Traits, _Allocator>::size_type2957basic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c, size_type __pos) const _NOEXCEPT {2958 return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);2959}2960 2961// find_first_of2962 2963template <class _CharT, class _Traits, class _Allocator>2964typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_first_of(2965 const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT {2966 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr");2967 return std::__str_find_first_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);2968}2969 2970template <class _CharT, class _Traits, class _Allocator>2971inline typename basic_string<_CharT, _Traits, _Allocator>::size_type2972basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str, size_type __pos) const _NOEXCEPT {2973 return std::__str_find_first_of<value_type, size_type, traits_type, npos>(2974 data(), size(), __str.data(), __pos, __str.size());2975}2976 2977template <class _CharT, class _Traits, class _Allocator>2978template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >2979typename basic_string<_CharT, _Traits, _Allocator>::size_type2980basic_string<_CharT, _Traits, _Allocator>::find_first_of(const _Tp& __t, size_type __pos) const _NOEXCEPT {2981 __self_view __sv = __t;2982 return std::__str_find_first_of<value_type, size_type, traits_type, npos>(2983 data(), size(), __sv.data(), __pos, __sv.size());2984}2985 2986template <class _CharT, class _Traits, class _Allocator>2987inline typename basic_string<_CharT, _Traits, _Allocator>::size_type2988basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, size_type __pos) const _NOEXCEPT {2989 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_first_of(): received nullptr");2990 return std::__str_find_first_of<value_type, size_type, traits_type, npos>(2991 data(), size(), __s, __pos, traits_type::length(__s));2992}2993 2994template <class _CharT, class _Traits, class _Allocator>2995inline typename basic_string<_CharT, _Traits, _Allocator>::size_type2996basic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c, size_type __pos) const _NOEXCEPT {2997 return find(__c, __pos);2998}2999 3000// find_last_of3001 3002template <class _CharT, class _Traits, class _Allocator>3003inline typename basic_string<_CharT, _Traits, _Allocator>::size_type3004basic_string<_CharT, _Traits, _Allocator>::find_last_of(3005 const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT {3006 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr");3007 return std::__str_find_last_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);3008}3009 3010template <class _CharT, class _Traits, class _Allocator>3011inline typename basic_string<_CharT, _Traits, _Allocator>::size_type3012basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str, size_type __pos) const _NOEXCEPT {3013 return std::__str_find_last_of<value_type, size_type, traits_type, npos>(3014 data(), size(), __str.data(), __pos, __str.size());3015}3016 3017template <class _CharT, class _Traits, class _Allocator>3018template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >3019typename basic_string<_CharT, _Traits, _Allocator>::size_type3020basic_string<_CharT, _Traits, _Allocator>::find_last_of(const _Tp& __t, size_type __pos) const _NOEXCEPT {3021 __self_view __sv = __t;3022 return std::__str_find_last_of<value_type, size_type, traits_type, npos>(3023 data(), size(), __sv.data(), __pos, __sv.size());3024}3025 3026template <class _CharT, class _Traits, class _Allocator>3027inline typename basic_string<_CharT, _Traits, _Allocator>::size_type3028basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, size_type __pos) const _NOEXCEPT {3029 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_last_of(): received nullptr");3030 return std::__str_find_last_of<value_type, size_type, traits_type, npos>(3031 data(), size(), __s, __pos, traits_type::length(__s));3032}3033 3034template <class _CharT, class _Traits, class _Allocator>3035inline typename basic_string<_CharT, _Traits, _Allocator>::size_type3036basic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c, size_type __pos) const _NOEXCEPT {3037 return rfind(__c, __pos);3038}3039 3040// find_first_not_of3041 3042template <class _CharT, class _Traits, class _Allocator>3043typename basic_string<_CharT, _Traits, _Allocator>::size_type3044basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(3045 const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT {3046 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr");3047 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);3048}3049 3050template <class _CharT, class _Traits, class _Allocator>3051inline typename basic_string<_CharT, _Traits, _Allocator>::size_type3052basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(3053 const basic_string& __str, size_type __pos) const _NOEXCEPT {3054 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(3055 data(), size(), __str.data(), __pos, __str.size());3056}3057 3058template <class _CharT, class _Traits, class _Allocator>3059template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >3060typename basic_string<_CharT, _Traits, _Allocator>::size_type3061basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const _Tp& __t, size_type __pos) const _NOEXCEPT {3062 __self_view __sv = __t;3063 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(3064 data(), size(), __sv.data(), __pos, __sv.size());3065}3066 3067template <class _CharT, class _Traits, class _Allocator>3068inline typename basic_string<_CharT, _Traits, _Allocator>::size_type3069basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s, size_type __pos) const _NOEXCEPT {3070 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_first_not_of(): received nullptr");3071 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(3072 data(), size(), __s, __pos, traits_type::length(__s));3073}3074 3075template <class _CharT, class _Traits, class _Allocator>3076inline typename basic_string<_CharT, _Traits, _Allocator>::size_type3077basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c, size_type __pos) const _NOEXCEPT {3078 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);3079}3080 3081// find_last_not_of3082 3083template <class _CharT, class _Traits, class _Allocator>3084typename basic_string<_CharT, _Traits, _Allocator>::size_type3085basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(3086 const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT {3087 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr");3088 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);3089}3090 3091template <class _CharT, class _Traits, class _Allocator>3092inline typename basic_string<_CharT, _Traits, _Allocator>::size_type3093basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(3094 const basic_string& __str, size_type __pos) const _NOEXCEPT {3095 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(3096 data(), size(), __str.data(), __pos, __str.size());3097}3098 3099template <class _CharT, class _Traits, class _Allocator>3100template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >3101typename basic_string<_CharT, _Traits, _Allocator>::size_type3102basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const _Tp& __t, size_type __pos) const _NOEXCEPT {3103 __self_view __sv = __t;3104 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(3105 data(), size(), __sv.data(), __pos, __sv.size());3106}3107 3108template <class _CharT, class _Traits, class _Allocator>3109inline typename basic_string<_CharT, _Traits, _Allocator>::size_type3110basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s, size_type __pos) const _NOEXCEPT {3111 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_last_not_of(): received nullptr");3112 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(3113 data(), size(), __s, __pos, traits_type::length(__s));3114}3115 3116template <class _CharT, class _Traits, class _Allocator>3117inline typename basic_string<_CharT, _Traits, _Allocator>::size_type3118basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c, size_type __pos) const _NOEXCEPT {3119 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);3120}3121 3122// compare3123 3124template <class _CharT, class _Traits, class _Allocator>3125template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >3126int basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const _NOEXCEPT {3127 __self_view __sv = __t;3128 size_t __lhs_sz = size();3129 size_t __rhs_sz = __sv.size();3130 int __result = traits_type::compare(data(), __sv.data(), std::min(__lhs_sz, __rhs_sz));3131 if (__result != 0)3132 return __result;3133 if (__lhs_sz < __rhs_sz)3134 return -1;3135 if (__lhs_sz > __rhs_sz)3136 return 1;3137 return 0;3138}3139 3140template <class _CharT, class _Traits, class _Allocator>3141inline int basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT {3142 return compare(__self_view(__str));3143}3144 3145template <class _CharT, class _Traits, class _Allocator>3146inline int basic_string<_CharT, _Traits, _Allocator>::compare(3147 size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const {3148 _LIBCPP_ASSERT_NON_NULL(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr");3149 size_type __sz = size();3150 if (__pos1 > __sz || __n2 == npos)3151 __throw_out_of_range();3152 size_type __rlen = std::min(__n1, __sz - __pos1);3153 int __r = traits_type::compare(data() + __pos1, __s, std::min(__rlen, __n2));3154 if (__r == 0) {3155 if (__rlen < __n2)3156 __r = -1;3157 else if (__rlen > __n2)3158 __r = 1;3159 }3160 return __r;3161}3162 3163template <class _CharT, class _Traits, class _Allocator>3164template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >3165int basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, const _Tp& __t) const {3166 __self_view __sv = __t;3167 return compare(__pos1, __n1, __sv.data(), __sv.size());3168}3169 3170template <class _CharT, class _Traits, class _Allocator>3171inline int3172basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, const basic_string& __str) const {3173 return compare(__pos1, __n1, __str.data(), __str.size());3174}3175 3176template <class _CharT, class _Traits, class _Allocator>3177template <class _Tp,3178 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&3179 !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,3180 int> >3181int basic_string<_CharT, _Traits, _Allocator>::compare(3182 size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2) const {3183 __self_view __sv = __t;3184 return __self_view(*this).substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));3185}3186 3187template <class _CharT, class _Traits, class _Allocator>3188int basic_string<_CharT, _Traits, _Allocator>::compare(3189 size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2) const {3190 return compare(__pos1, __n1, __self_view(__str), __pos2, __n2);3191}3192 3193template <class _CharT, class _Traits, class _Allocator>3194int basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT {3195 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::compare(): received nullptr");3196 return compare(0, npos, __s, traits_type::length(__s));3197}3198 3199template <class _CharT, class _Traits, class _Allocator>3200int basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, const value_type* __s) const {3201 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::compare(): received nullptr");3202 return compare(__pos1, __n1, __s, traits_type::length(__s));3203}3204 3205// __invariants3206 3207template <class _CharT, class _Traits, class _Allocator>3208inline bool basic_string<_CharT, _Traits, _Allocator>::__invariants() const {3209 if (size() > capacity())3210 return false;3211 if (capacity() < __min_cap - 1)3212 return false;3213 if (data() == nullptr)3214 return false;3215 if (!_Traits::eq(data()[size()], value_type()))3216 return false;3217 return true;3218}3219 3220// __clear_and_shrink3221 3222template <class _CharT, class _Traits, class _Allocator>3223inline void basic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT {3224 clear();3225 if (__is_long()) {3226 __annotate_delete();3227 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), capacity() + 1);3228 __r_.first() = __rep();3229 }3230}3231 3232// operator==3233 3234template <class _CharT, class _Traits, class _Allocator>3235inline _LIBCPP_HIDE_FROM_ABI bool operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs,3236 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT {3237 size_t __lhs_sz = __lhs.size();3238 return __lhs_sz == __rhs.size() && _Traits::compare(__lhs.data(), __rhs.data(), __lhs_sz) == 0;3239}3240 3241template <class _Allocator>3242inline _LIBCPP_HIDE_FROM_ABI bool operator==(const basic_string<char, char_traits<char>, _Allocator>& __lhs,3243 const basic_string<char, char_traits<char>, _Allocator>& __rhs) _NOEXCEPT {3244 size_t __sz = __lhs.size();3245 if (__sz != __rhs.size())3246 return false;3247 return char_traits<char>::compare(__lhs.data(), __rhs.data(), __sz) == 0;3248}3249 3250template <class _CharT, class _Traits, class _Allocator>3251inline _LIBCPP_HIDE_FROM_ABI bool3252operator==(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT {3253 typedef basic_string<_CharT, _Traits, _Allocator> _String;3254 _LIBCPP_ASSERT_NON_NULL(__lhs != nullptr, "operator==(char*, basic_string): received nullptr");3255 size_t __lhs_len = _Traits::length(__lhs);3256 if (__lhs_len != __rhs.size())3257 return false;3258 return __rhs.compare(0, _String::npos, __lhs, __lhs_len) == 0;3259}3260 3261template <class _CharT, class _Traits, class _Allocator>3262inline _LIBCPP_HIDE_FROM_ABI bool3263operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT {3264 typedef basic_string<_CharT, _Traits, _Allocator> _String;3265 _LIBCPP_ASSERT_NON_NULL(__rhs != nullptr, "operator==(basic_string, char*): received nullptr");3266 size_t __rhs_len = _Traits::length(__rhs);3267 if (__rhs_len != __lhs.size())3268 return false;3269 return __lhs.compare(0, _String::npos, __rhs, __rhs_len) == 0;3270}3271 3272template <class _CharT, class _Traits, class _Allocator>3273inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,3274 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT {3275 return !(__lhs == __rhs);3276}3277 3278template <class _CharT, class _Traits, class _Allocator>3279inline _LIBCPP_HIDE_FROM_ABI bool3280operator!=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT {3281 return !(__lhs == __rhs);3282}3283 3284template <class _CharT, class _Traits, class _Allocator>3285inline _LIBCPP_HIDE_FROM_ABI bool3286operator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT {3287 return !(__lhs == __rhs);3288}3289 3290// operator<3291 3292template <class _CharT, class _Traits, class _Allocator>3293inline _LIBCPP_HIDE_FROM_ABI bool operator<(const basic_string<_CharT, _Traits, _Allocator>& __lhs,3294 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT {3295 return __lhs.compare(__rhs) < 0;3296}3297 3298template <class _CharT, class _Traits, class _Allocator>3299inline _LIBCPP_HIDE_FROM_ABI bool3300operator<(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT {3301 return __lhs.compare(__rhs) < 0;3302}3303 3304template <class _CharT, class _Traits, class _Allocator>3305inline _LIBCPP_HIDE_FROM_ABI bool3306operator<(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT {3307 return __rhs.compare(__lhs) > 0;3308}3309 3310// operator>3311 3312template <class _CharT, class _Traits, class _Allocator>3313inline _LIBCPP_HIDE_FROM_ABI bool operator>(const basic_string<_CharT, _Traits, _Allocator>& __lhs,3314 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT {3315 return __rhs < __lhs;3316}3317 3318template <class _CharT, class _Traits, class _Allocator>3319inline _LIBCPP_HIDE_FROM_ABI bool3320operator>(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT {3321 return __rhs < __lhs;3322}3323 3324template <class _CharT, class _Traits, class _Allocator>3325inline _LIBCPP_HIDE_FROM_ABI bool3326operator>(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT {3327 return __rhs < __lhs;3328}3329 3330// operator<=3331 3332template <class _CharT, class _Traits, class _Allocator>3333inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,3334 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT {3335 return !(__rhs < __lhs);3336}3337 3338template <class _CharT, class _Traits, class _Allocator>3339inline _LIBCPP_HIDE_FROM_ABI bool3340operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT {3341 return !(__rhs < __lhs);3342}3343 3344template <class _CharT, class _Traits, class _Allocator>3345inline _LIBCPP_HIDE_FROM_ABI bool3346operator<=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT {3347 return !(__rhs < __lhs);3348}3349 3350// operator>=3351 3352template <class _CharT, class _Traits, class _Allocator>3353inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,3354 const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT {3355 return !(__lhs < __rhs);3356}3357 3358template <class _CharT, class _Traits, class _Allocator>3359inline _LIBCPP_HIDE_FROM_ABI bool3360operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT {3361 return !(__lhs < __rhs);3362}3363 3364template <class _CharT, class _Traits, class _Allocator>3365inline _LIBCPP_HIDE_FROM_ABI bool3366operator>=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT {3367 return !(__lhs < __rhs);3368}3369 3370// operator +3371 3372template <class _CharT, class _Traits, class _Allocator>3373_LIBCPP_HIDE_FROM_ABI basic_string<_CharT, _Traits, _Allocator>3374operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs,3375 const basic_string<_CharT, _Traits, _Allocator>& __rhs) {3376 using _String = basic_string<_CharT, _Traits, _Allocator>;3377 auto __lhs_sz = __lhs.size();3378 auto __rhs_sz = __rhs.size();3379 _String __r(__uninitialized_size_tag(),3380 __lhs_sz + __rhs_sz,3381 _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator()));3382 auto __ptr = std::__to_address(__r.__get_pointer());3383 _Traits::copy(__ptr, __lhs.data(), __lhs_sz);3384 _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz);3385 _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());3386 return __r;3387}3388 3389template <class _CharT, class _Traits, class _Allocator>3390_LIBCPP_HIDDEN basic_string<_CharT, _Traits, _Allocator>3391operator+(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) {3392 using _String = basic_string<_CharT, _Traits, _Allocator>;3393 auto __lhs_sz = _Traits::length(__lhs);3394 auto __rhs_sz = __rhs.size();3395 _String __r(__uninitialized_size_tag(),3396 __lhs_sz + __rhs_sz,3397 _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator()));3398 auto __ptr = std::__to_address(__r.__get_pointer());3399 _Traits::copy(__ptr, __lhs, __lhs_sz);3400 _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz);3401 _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());3402 return __r;3403}3404 3405template <class _CharT, class _Traits, class _Allocator>3406_LIBCPP_HIDE_FROM_ABI basic_string<_CharT, _Traits, _Allocator>3407operator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) {3408 using _String = basic_string<_CharT, _Traits, _Allocator>;3409 typename _String::size_type __rhs_sz = __rhs.size();3410 _String __r(__uninitialized_size_tag(),3411 __rhs_sz + 1,3412 _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator()));3413 auto __ptr = std::__to_address(__r.__get_pointer());3414 _Traits::assign(__ptr, 1, __lhs);3415 _Traits::copy(__ptr + 1, __rhs.data(), __rhs_sz);3416 _Traits::assign(__ptr + 1 + __rhs_sz, 1, _CharT());3417 return __r;3418}3419 3420template <class _CharT, class _Traits, class _Allocator>3421inline basic_string<_CharT, _Traits, _Allocator>3422operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) {3423 using _String = basic_string<_CharT, _Traits, _Allocator>;3424 typename _String::size_type __lhs_sz = __lhs.size();3425 typename _String::size_type __rhs_sz = _Traits::length(__rhs);3426 _String __r(__uninitialized_size_tag(),3427 __lhs_sz + __rhs_sz,3428 _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator()));3429 auto __ptr = std::__to_address(__r.__get_pointer());3430 _Traits::copy(__ptr, __lhs.data(), __lhs_sz);3431 _Traits::copy(__ptr + __lhs_sz, __rhs, __rhs_sz);3432 _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());3433 return __r;3434}3435 3436template <class _CharT, class _Traits, class _Allocator>3437_LIBCPP_HIDE_FROM_ABI basic_string<_CharT, _Traits, _Allocator>3438operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs) {3439 using _String = basic_string<_CharT, _Traits, _Allocator>;3440 typename _String::size_type __lhs_sz = __lhs.size();3441 _String __r(__uninitialized_size_tag(),3442 __lhs_sz + 1,3443 _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator()));3444 auto __ptr = std::__to_address(__r.__get_pointer());3445 _Traits::copy(__ptr, __lhs.data(), __lhs_sz);3446 _Traits::assign(__ptr + __lhs_sz, 1, __rhs);3447 _Traits::assign(__ptr + 1 + __lhs_sz, 1, _CharT());3448 return __r;3449}3450 3451// swap3452 3453template <class _CharT, class _Traits, class _Allocator>3454inline _LIBCPP_HIDE_FROM_ABI void3455swap(basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>& __rhs) {3456 __lhs.swap(__rhs);3457}3458 3459_LIBCPP_EXPORTED_FROM_ABI int stoi(const string& __str, size_t* __idx = nullptr, int __base = 10);3460_LIBCPP_EXPORTED_FROM_ABI long stol(const string& __str, size_t* __idx = nullptr, int __base = 10);3461_LIBCPP_EXPORTED_FROM_ABI unsigned long stoul(const string& __str, size_t* __idx = nullptr, int __base = 10);3462_LIBCPP_EXPORTED_FROM_ABI long long stoll(const string& __str, size_t* __idx = nullptr, int __base = 10);3463_LIBCPP_EXPORTED_FROM_ABI unsigned long long stoull(const string& __str, size_t* __idx = nullptr, int __base = 10);3464 3465_LIBCPP_EXPORTED_FROM_ABI float stof(const string& __str, size_t* __idx = nullptr);3466_LIBCPP_EXPORTED_FROM_ABI double stod(const string& __str, size_t* __idx = nullptr);3467_LIBCPP_EXPORTED_FROM_ABI long double stold(const string& __str, size_t* __idx = nullptr);3468 3469_LIBCPP_EXPORTED_FROM_ABI string to_string(int __val);3470_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned __val);3471_LIBCPP_EXPORTED_FROM_ABI string to_string(long __val);3472_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long __val);3473_LIBCPP_EXPORTED_FROM_ABI string to_string(long long __val);3474_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long long __val);3475_LIBCPP_EXPORTED_FROM_ABI string to_string(float __val);3476_LIBCPP_EXPORTED_FROM_ABI string to_string(double __val);3477_LIBCPP_EXPORTED_FROM_ABI string to_string(long double __val);3478 3479#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS3480_LIBCPP_EXPORTED_FROM_ABI int stoi(const wstring& __str, size_t* __idx = nullptr, int __base = 10);3481_LIBCPP_EXPORTED_FROM_ABI long stol(const wstring& __str, size_t* __idx = nullptr, int __base = 10);3482_LIBCPP_EXPORTED_FROM_ABI unsigned long stoul(const wstring& __str, size_t* __idx = nullptr, int __base = 10);3483_LIBCPP_EXPORTED_FROM_ABI long long stoll(const wstring& __str, size_t* __idx = nullptr, int __base = 10);3484_LIBCPP_EXPORTED_FROM_ABI unsigned long long stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10);3485 3486_LIBCPP_EXPORTED_FROM_ABI float stof(const wstring& __str, size_t* __idx = nullptr);3487_LIBCPP_EXPORTED_FROM_ABI double stod(const wstring& __str, size_t* __idx = nullptr);3488_LIBCPP_EXPORTED_FROM_ABI long double stold(const wstring& __str, size_t* __idx = nullptr);3489 3490_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(int __val);3491_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned __val);3492_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long __val);3493_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long __val);3494_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long long __val);3495_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long long __val);3496_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(float __val);3497_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(double __val);3498_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long double __val);3499#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS3500 3501template <class _CharT, class _Traits, class _Allocator>3502_LIBCPP_TEMPLATE_DATA_VIS const typename basic_string<_CharT, _Traits, _Allocator>::size_type3503 basic_string<_CharT, _Traits, _Allocator>::npos;3504 3505template <class _CharT, class _Allocator>3506struct __string_hash : public __unary_function<basic_string<_CharT, char_traits<_CharT>, _Allocator>, size_t> {3507 _LIBCPP_HIDE_FROM_ABI size_t3508 operator()(const basic_string<_CharT, char_traits<_CharT>, _Allocator>& __val) const _NOEXCEPT {3509 return std::__do_string_hash(__val.data(), __val.data() + __val.size());3510 }3511};3512 3513template <class _Allocator>3514struct hash<basic_string<char, char_traits<char>, _Allocator> > : __string_hash<char, _Allocator> {};3515 3516#ifndef _LIBCPP_HAS_NO_CHAR8_T3517template <class _Allocator>3518struct hash<basic_string<char8_t, char_traits<char8_t>, _Allocator> > : __string_hash<char8_t, _Allocator> {};3519#endif3520 3521template <class _Allocator>3522struct hash<basic_string<char16_t, char_traits<char16_t>, _Allocator> > : __string_hash<char16_t, _Allocator> {};3523 3524template <class _Allocator>3525struct hash<basic_string<char32_t, char_traits<char32_t>, _Allocator> > : __string_hash<char32_t, _Allocator> {};3526 3527#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS3528template <class _Allocator>3529struct hash<basic_string<wchar_t, char_traits<wchar_t>, _Allocator> > : __string_hash<wchar_t, _Allocator> {};3530#endif3531 3532template <class _CharT, class _Traits, class _Allocator>3533_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&3534operator<<(basic_ostream<_CharT, _Traits>& __os, const basic_string<_CharT, _Traits, _Allocator>& __str);3535 3536template <class _CharT, class _Traits, class _Allocator>3537_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&3538operator>>(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Allocator>& __str);3539 3540template <class _CharT, class _Traits, class _Allocator>3541_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 3548template <class _CharT, class _Traits, class _Allocator>3549inline _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&3550getline(basic_istream<_CharT, _Traits>&& __is, basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm);3551 3552template <class _CharT, class _Traits, class _Allocator>3553inline _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&3554getline(basic_istream<_CharT, _Traits>&& __is, basic_string<_CharT, _Traits, _Allocator>& __str);3555 3556_LIBCPP_END_NAMESPACE_STD3557 3558_LIBCPP_POP_MACROS3559 3560#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES)3561# include <__cxx03/algorithm>3562# include <__cxx03/cstdlib>3563# include <__cxx03/iterator>3564# include <__cxx03/new>3565# include <__cxx03/type_traits>3566# include <__cxx03/typeinfo>3567# include <__cxx03/utility>3568#endif3569 3570#endif // _LIBCPP___CXX03_STRING3571