10b57cec5SDimitry Andric// -*- C++ -*- 2349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 30b57cec5SDimitry Andric// 40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 70b57cec5SDimitry Andric// 80b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 90b57cec5SDimitry Andric 100b57cec5SDimitry Andric#ifndef _LIBCPP_STRING 110b57cec5SDimitry Andric#define _LIBCPP_STRING 120b57cec5SDimitry Andric 135f757f3fSDimitry Andric// clang-format off 145f757f3fSDimitry Andric 150b57cec5SDimitry Andric/* 160b57cec5SDimitry Andric string synopsis 170b57cec5SDimitry Andric 18bdd1243dSDimitry Andric#include <compare> 19bdd1243dSDimitry Andric#include <initializer_list> 20bdd1243dSDimitry Andric 210b57cec5SDimitry Andricnamespace std 220b57cec5SDimitry Andric{ 230b57cec5SDimitry Andric 240b57cec5SDimitry Andrictemplate <class stateT> 250b57cec5SDimitry Andricclass fpos 260b57cec5SDimitry Andric{ 270b57cec5SDimitry Andricprivate: 280b57cec5SDimitry Andric stateT st; 290b57cec5SDimitry Andricpublic: 300b57cec5SDimitry Andric fpos(streamoff = streamoff()); 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric operator streamoff() const; 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric stateT state() const; 350b57cec5SDimitry Andric void state(stateT); 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric fpos& operator+=(streamoff); 380b57cec5SDimitry Andric fpos operator+ (streamoff) const; 390b57cec5SDimitry Andric fpos& operator-=(streamoff); 400b57cec5SDimitry Andric fpos operator- (streamoff) const; 410b57cec5SDimitry Andric}; 420b57cec5SDimitry Andric 430b57cec5SDimitry Andrictemplate <class stateT> streamoff operator-(const fpos<stateT>& x, const fpos<stateT>& y); 440b57cec5SDimitry Andric 450b57cec5SDimitry Andrictemplate <class stateT> bool operator==(const fpos<stateT>& x, const fpos<stateT>& y); 460b57cec5SDimitry Andrictemplate <class stateT> bool operator!=(const fpos<stateT>& x, const fpos<stateT>& y); 470b57cec5SDimitry Andric 480b57cec5SDimitry Andrictemplate <class charT> 490b57cec5SDimitry Andricstruct char_traits 500b57cec5SDimitry Andric{ 51bdd1243dSDimitry Andric using char_type = charT; 52bdd1243dSDimitry Andric using int_type = ...; 53bdd1243dSDimitry Andric using off_type = streamoff; 54bdd1243dSDimitry Andric using pos_type = streampos; 55bdd1243dSDimitry Andric using state_type = mbstate_t; 56bdd1243dSDimitry Andric using comparison_category = strong_ordering; // Since C++20 only for the specializations 57bdd1243dSDimitry Andric // char, wchar_t, char8_t, char16_t, and char32_t. 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric static void assign(char_type& c1, const char_type& c2) noexcept; 600b57cec5SDimitry Andric static constexpr bool eq(char_type c1, char_type c2) noexcept; 610b57cec5SDimitry Andric static constexpr bool lt(char_type c1, char_type c2) noexcept; 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric static int compare(const char_type* s1, const char_type* s2, size_t n); 640b57cec5SDimitry Andric static size_t length(const char_type* s); 650b57cec5SDimitry Andric static const char_type* find(const char_type* s, size_t n, const char_type& a); 660b57cec5SDimitry Andric static char_type* move(char_type* s1, const char_type* s2, size_t n); 670b57cec5SDimitry Andric static char_type* copy(char_type* s1, const char_type* s2, size_t n); 680b57cec5SDimitry Andric static char_type* assign(char_type* s, size_t n, char_type a); 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric static constexpr int_type not_eof(int_type c) noexcept; 710b57cec5SDimitry Andric static constexpr char_type to_char_type(int_type c) noexcept; 720b57cec5SDimitry Andric static constexpr int_type to_int_type(char_type c) noexcept; 730b57cec5SDimitry Andric static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept; 740b57cec5SDimitry Andric static constexpr int_type eof() noexcept; 750b57cec5SDimitry Andric}; 760b57cec5SDimitry Andric 770b57cec5SDimitry Andrictemplate <> struct char_traits<char>; 780b57cec5SDimitry Andrictemplate <> struct char_traits<wchar_t>; 79fe6060f1SDimitry Andrictemplate <> struct char_traits<char8_t>; // C++20 80fe6060f1SDimitry Andrictemplate <> struct char_traits<char16_t>; 81fe6060f1SDimitry Andrictemplate <> struct char_traits<char32_t>; 820b57cec5SDimitry Andric 830b57cec5SDimitry Andrictemplate<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> > 840b57cec5SDimitry Andricclass basic_string 850b57cec5SDimitry Andric{ 860b57cec5SDimitry Andricpublic: 870b57cec5SDimitry Andric// types: 880b57cec5SDimitry Andric typedef traits traits_type; 890b57cec5SDimitry Andric typedef typename traits_type::char_type value_type; 900b57cec5SDimitry Andric typedef Allocator allocator_type; 910b57cec5SDimitry Andric typedef typename allocator_type::size_type size_type; 920b57cec5SDimitry Andric typedef typename allocator_type::difference_type difference_type; 930b57cec5SDimitry Andric typedef typename allocator_type::reference reference; 940b57cec5SDimitry Andric typedef typename allocator_type::const_reference const_reference; 950b57cec5SDimitry Andric typedef typename allocator_type::pointer pointer; 960b57cec5SDimitry Andric typedef typename allocator_type::const_pointer const_pointer; 970b57cec5SDimitry Andric typedef implementation-defined iterator; 980b57cec5SDimitry Andric typedef implementation-defined const_iterator; 990b57cec5SDimitry Andric typedef std::reverse_iterator<iterator> reverse_iterator; 1000b57cec5SDimitry Andric typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric static const size_type npos = -1; 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric basic_string() 10581ad6265SDimitry Andric noexcept(is_nothrow_default_constructible<allocator_type>::value); // constexpr since C++20 10681ad6265SDimitry Andric explicit basic_string(const allocator_type& a); // constexpr since C++20 10781ad6265SDimitry Andric basic_string(const basic_string& str); // constexpr since C++20 1080b57cec5SDimitry Andric basic_string(basic_string&& str) 10981ad6265SDimitry Andric noexcept(is_nothrow_move_constructible<allocator_type>::value); // constexpr since C++20 1100b57cec5SDimitry Andric basic_string(const basic_string& str, size_type pos, 11181ad6265SDimitry Andric const allocator_type& a = allocator_type()); // constexpr since C++20 1120b57cec5SDimitry Andric basic_string(const basic_string& str, size_type pos, size_type n, 11381ad6265SDimitry Andric const Allocator& a = Allocator()); // constexpr since C++20 114bdd1243dSDimitry Andric constexpr basic_string( 115bdd1243dSDimitry Andric basic_string&& str, size_type pos, const Allocator& a = Allocator()); // since C++23 116bdd1243dSDimitry Andric constexpr basic_string( 117bdd1243dSDimitry Andric basic_string&& str, size_type pos, size_type n, const Allocator& a = Allocator()); // since C++23 1180b57cec5SDimitry Andric template<class T> 11981ad6265SDimitry Andric basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator()); // C++17, constexpr since C++20 1200b57cec5SDimitry Andric template <class T> 12181ad6265SDimitry Andric explicit basic_string(const T& t, const Allocator& a = Allocator()); // C++17, constexpr since C++20 12281ad6265SDimitry Andric basic_string(const value_type* s, const allocator_type& a = allocator_type()); // constexpr since C++20 12381ad6265SDimitry Andric basic_string(const value_type* s, size_type n, const allocator_type& a = allocator_type()); // constexpr since C++20 12406c3fb27SDimitry Andric basic_string(nullptr_t) = delete; // C++23 12581ad6265SDimitry Andric basic_string(size_type n, value_type c, const allocator_type& a = allocator_type()); // constexpr since C++20 1260b57cec5SDimitry Andric template<class InputIterator> 1270b57cec5SDimitry Andric basic_string(InputIterator begin, InputIterator end, 12881ad6265SDimitry Andric const allocator_type& a = allocator_type()); // constexpr since C++20 12906c3fb27SDimitry Andric template<container-compatible-range<charT> R> 13006c3fb27SDimitry Andric constexpr basic_string(from_range_t, R&& rg, const Allocator& a = Allocator()); // since C++23 13181ad6265SDimitry Andric basic_string(initializer_list<value_type>, const Allocator& = Allocator()); // constexpr since C++20 13281ad6265SDimitry Andric basic_string(const basic_string&, const Allocator&); // constexpr since C++20 13381ad6265SDimitry Andric basic_string(basic_string&&, const Allocator&); // constexpr since C++20 1340b57cec5SDimitry Andric 13581ad6265SDimitry Andric ~basic_string(); // constexpr since C++20 1360b57cec5SDimitry Andric 13781ad6265SDimitry Andric operator basic_string_view<charT, traits>() const noexcept; // constexpr since C++20 1380b57cec5SDimitry Andric 13981ad6265SDimitry Andric basic_string& operator=(const basic_string& str); // constexpr since C++20 1400b57cec5SDimitry Andric template <class T> 14181ad6265SDimitry Andric basic_string& operator=(const T& t); // C++17, constexpr since C++20 1420b57cec5SDimitry Andric basic_string& operator=(basic_string&& str) 1430b57cec5SDimitry Andric noexcept( 1440b57cec5SDimitry Andric allocator_type::propagate_on_container_move_assignment::value || 14581ad6265SDimitry Andric allocator_type::is_always_equal::value ); // C++17, constexpr since C++20 14681ad6265SDimitry Andric basic_string& operator=(const value_type* s); // constexpr since C++20 14706c3fb27SDimitry Andric basic_string& operator=(nullptr_t) = delete; // C++23 14881ad6265SDimitry Andric basic_string& operator=(value_type c); // constexpr since C++20 14981ad6265SDimitry Andric basic_string& operator=(initializer_list<value_type>); // constexpr since C++20 1500b57cec5SDimitry Andric 15181ad6265SDimitry Andric iterator begin() noexcept; // constexpr since C++20 15281ad6265SDimitry Andric const_iterator begin() const noexcept; // constexpr since C++20 15381ad6265SDimitry Andric iterator end() noexcept; // constexpr since C++20 15481ad6265SDimitry Andric const_iterator end() const noexcept; // constexpr since C++20 1550b57cec5SDimitry Andric 15681ad6265SDimitry Andric reverse_iterator rbegin() noexcept; // constexpr since C++20 15781ad6265SDimitry Andric const_reverse_iterator rbegin() const noexcept; // constexpr since C++20 15881ad6265SDimitry Andric reverse_iterator rend() noexcept; // constexpr since C++20 15981ad6265SDimitry Andric const_reverse_iterator rend() const noexcept; // constexpr since C++20 1600b57cec5SDimitry Andric 16181ad6265SDimitry Andric const_iterator cbegin() const noexcept; // constexpr since C++20 16281ad6265SDimitry Andric const_iterator cend() const noexcept; // constexpr since C++20 16381ad6265SDimitry Andric const_reverse_iterator crbegin() const noexcept; // constexpr since C++20 16481ad6265SDimitry Andric const_reverse_iterator crend() const noexcept; // constexpr since C++20 1650b57cec5SDimitry Andric 16681ad6265SDimitry Andric size_type size() const noexcept; // constexpr since C++20 16781ad6265SDimitry Andric size_type length() const noexcept; // constexpr since C++20 16881ad6265SDimitry Andric size_type max_size() const noexcept; // constexpr since C++20 16981ad6265SDimitry Andric size_type capacity() const noexcept; // constexpr since C++20 1700b57cec5SDimitry Andric 17181ad6265SDimitry Andric void resize(size_type n, value_type c); // constexpr since C++20 17281ad6265SDimitry Andric void resize(size_type n); // constexpr since C++20 1730b57cec5SDimitry Andric 17404eeddc0SDimitry Andric template<class Operation> 17504eeddc0SDimitry Andric constexpr void resize_and_overwrite(size_type n, Operation op); // since C++23 17604eeddc0SDimitry Andric 17781ad6265SDimitry Andric void reserve(size_type res_arg); // constexpr since C++20 1785f757f3fSDimitry Andric void reserve(); // deprecated in C++20, removed in C++26 17981ad6265SDimitry Andric void shrink_to_fit(); // constexpr since C++20 18081ad6265SDimitry Andric void clear() noexcept; // constexpr since C++20 18181ad6265SDimitry Andric bool empty() const noexcept; // constexpr since C++20 1820b57cec5SDimitry Andric 18381ad6265SDimitry Andric const_reference operator[](size_type pos) const; // constexpr since C++20 18481ad6265SDimitry Andric reference operator[](size_type pos); // constexpr since C++20 1850b57cec5SDimitry Andric 18681ad6265SDimitry Andric const_reference at(size_type n) const; // constexpr since C++20 18781ad6265SDimitry Andric reference at(size_type n); // constexpr since C++20 1880b57cec5SDimitry Andric 18981ad6265SDimitry Andric basic_string& operator+=(const basic_string& str); // constexpr since C++20 1900b57cec5SDimitry Andric template <class T> 19181ad6265SDimitry Andric basic_string& operator+=(const T& t); // C++17, constexpr since C++20 19281ad6265SDimitry Andric basic_string& operator+=(const value_type* s); // constexpr since C++20 19381ad6265SDimitry Andric basic_string& operator+=(value_type c); // constexpr since C++20 19481ad6265SDimitry Andric basic_string& operator+=(initializer_list<value_type>); // constexpr since C++20 1950b57cec5SDimitry Andric 19681ad6265SDimitry Andric basic_string& append(const basic_string& str); // constexpr since C++20 1970b57cec5SDimitry Andric template <class T> 19881ad6265SDimitry Andric basic_string& append(const T& t); // C++17, constexpr since C++20 19981ad6265SDimitry Andric basic_string& append(const basic_string& str, size_type pos, size_type n=npos); // C++14, constexpr since C++20 2000b57cec5SDimitry Andric template <class T> 20181ad6265SDimitry Andric basic_string& append(const T& t, size_type pos, size_type n=npos); // C++17, constexpr since C++20 20281ad6265SDimitry Andric basic_string& append(const value_type* s, size_type n); // constexpr since C++20 20381ad6265SDimitry Andric basic_string& append(const value_type* s); // constexpr since C++20 20481ad6265SDimitry Andric basic_string& append(size_type n, value_type c); // constexpr since C++20 2050b57cec5SDimitry Andric template<class InputIterator> 20681ad6265SDimitry Andric basic_string& append(InputIterator first, InputIterator last); // constexpr since C++20 20706c3fb27SDimitry Andric template<container-compatible-range<charT> R> 20806c3fb27SDimitry Andric constexpr basic_string& append_range(R&& rg); // C++23 20981ad6265SDimitry Andric basic_string& append(initializer_list<value_type>); // constexpr since C++20 2100b57cec5SDimitry Andric 21181ad6265SDimitry Andric void push_back(value_type c); // constexpr since C++20 21281ad6265SDimitry Andric void pop_back(); // constexpr since C++20 21381ad6265SDimitry Andric reference front(); // constexpr since C++20 21481ad6265SDimitry Andric const_reference front() const; // constexpr since C++20 21581ad6265SDimitry Andric reference back(); // constexpr since C++20 21681ad6265SDimitry Andric const_reference back() const; // constexpr since C++20 2170b57cec5SDimitry Andric 21881ad6265SDimitry Andric basic_string& assign(const basic_string& str); // constexpr since C++20 2190b57cec5SDimitry Andric template <class T> 22081ad6265SDimitry Andric basic_string& assign(const T& t); // C++17, constexpr since C++20 22181ad6265SDimitry Andric basic_string& assign(basic_string&& str); // constexpr since C++20 22281ad6265SDimitry Andric basic_string& assign(const basic_string& str, size_type pos, size_type n=npos); // C++14, constexpr since C++20 2230b57cec5SDimitry Andric template <class T> 22481ad6265SDimitry Andric basic_string& assign(const T& t, size_type pos, size_type n=npos); // C++17, constexpr since C++20 22581ad6265SDimitry Andric basic_string& assign(const value_type* s, size_type n); // constexpr since C++20 22681ad6265SDimitry Andric basic_string& assign(const value_type* s); // constexpr since C++20 22781ad6265SDimitry Andric basic_string& assign(size_type n, value_type c); // constexpr since C++20 2280b57cec5SDimitry Andric template<class InputIterator> 22981ad6265SDimitry Andric basic_string& assign(InputIterator first, InputIterator last); // constexpr since C++20 23006c3fb27SDimitry Andric template<container-compatible-range<charT> R> 23106c3fb27SDimitry Andric constexpr basic_string& assign_range(R&& rg); // C++23 23281ad6265SDimitry Andric basic_string& assign(initializer_list<value_type>); // constexpr since C++20 2330b57cec5SDimitry Andric 23481ad6265SDimitry Andric basic_string& insert(size_type pos1, const basic_string& str); // constexpr since C++20 2350b57cec5SDimitry Andric template <class T> 23681ad6265SDimitry Andric basic_string& insert(size_type pos1, const T& t); // constexpr since C++20 2370b57cec5SDimitry Andric basic_string& insert(size_type pos1, const basic_string& str, 23881ad6265SDimitry Andric size_type pos2, size_type n); // constexpr since C++20 2390b57cec5SDimitry Andric template <class T> 24081ad6265SDimitry Andric basic_string& insert(size_type pos1, const T& t, size_type pos2, size_type n); // C++17, constexpr since C++20 24181ad6265SDimitry Andric basic_string& insert(size_type pos, const value_type* s, size_type n=npos); // C++14, constexpr since C++20 24281ad6265SDimitry Andric basic_string& insert(size_type pos, const value_type* s); // constexpr since C++20 24381ad6265SDimitry Andric basic_string& insert(size_type pos, size_type n, value_type c); // constexpr since C++20 24481ad6265SDimitry Andric iterator insert(const_iterator p, value_type c); // constexpr since C++20 24581ad6265SDimitry Andric iterator insert(const_iterator p, size_type n, value_type c); // constexpr since C++20 2460b57cec5SDimitry Andric template<class InputIterator> 24781ad6265SDimitry Andric iterator insert(const_iterator p, InputIterator first, InputIterator last); // constexpr since C++20 24806c3fb27SDimitry Andric template<container-compatible-range<charT> R> 24906c3fb27SDimitry Andric constexpr iterator insert_range(const_iterator p, R&& rg); // C++23 25081ad6265SDimitry Andric iterator insert(const_iterator p, initializer_list<value_type>); // constexpr since C++20 2510b57cec5SDimitry Andric 25281ad6265SDimitry Andric basic_string& erase(size_type pos = 0, size_type n = npos); // constexpr since C++20 25381ad6265SDimitry Andric iterator erase(const_iterator position); // constexpr since C++20 25481ad6265SDimitry Andric iterator erase(const_iterator first, const_iterator last); // constexpr since C++20 2550b57cec5SDimitry Andric 25681ad6265SDimitry Andric basic_string& replace(size_type pos1, size_type n1, const basic_string& str); // constexpr since C++20 2570b57cec5SDimitry Andric template <class T> 25881ad6265SDimitry Andric basic_string& replace(size_type pos1, size_type n1, const T& t); // C++17, constexpr since C++20 2590b57cec5SDimitry Andric basic_string& replace(size_type pos1, size_type n1, const basic_string& str, 26081ad6265SDimitry Andric size_type pos2, size_type n2=npos); // C++14, constexpr since C++20 2610b57cec5SDimitry Andric template <class T> 2620b57cec5SDimitry Andric basic_string& replace(size_type pos1, size_type n1, const T& t, 26381ad6265SDimitry Andric size_type pos2, size_type n); // C++17, constexpr since C++20 26481ad6265SDimitry Andric basic_string& replace(size_type pos, size_type n1, const value_type* s, size_type n2); // constexpr since C++20 26581ad6265SDimitry Andric basic_string& replace(size_type pos, size_type n1, const value_type* s); // constexpr since C++20 26681ad6265SDimitry Andric basic_string& replace(size_type pos, size_type n1, size_type n2, value_type c); // constexpr since C++20 26781ad6265SDimitry Andric basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str); // constexpr since C++20 2680b57cec5SDimitry Andric template <class T> 26981ad6265SDimitry Andric basic_string& replace(const_iterator i1, const_iterator i2, const T& t); // C++17, constexpr since C++20 27081ad6265SDimitry Andric basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s, size_type n); // constexpr since C++20 27181ad6265SDimitry Andric basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s); // constexpr since C++20 27281ad6265SDimitry Andric basic_string& replace(const_iterator i1, const_iterator i2, size_type n, value_type c); // constexpr since C++20 2730b57cec5SDimitry Andric template<class InputIterator> 27481ad6265SDimitry Andric basic_string& replace(const_iterator i1, const_iterator i2, InputIterator j1, InputIterator j2); // constexpr since C++20 27506c3fb27SDimitry Andric template<container-compatible-range<charT> R> 27606c3fb27SDimitry Andric constexpr basic_string& replace_with_range(const_iterator i1, const_iterator i2, R&& rg); // C++23 27781ad6265SDimitry Andric basic_string& replace(const_iterator i1, const_iterator i2, initializer_list<value_type>); // constexpr since C++20 2780b57cec5SDimitry Andric 27981ad6265SDimitry Andric size_type copy(value_type* s, size_type n, size_type pos = 0) const; // constexpr since C++20 280bdd1243dSDimitry Andric basic_string substr(size_type pos = 0, size_type n = npos) const; // constexpr in C++20, removed in C++23 281bdd1243dSDimitry Andric basic_string substr(size_type pos = 0, size_type n = npos) const&; // since C++23 282bdd1243dSDimitry Andric constexpr basic_string substr(size_type pos = 0, size_type n = npos) &&; // since C++23 2830b57cec5SDimitry Andric void swap(basic_string& str) 2840b57cec5SDimitry Andric noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value || 28581ad6265SDimitry Andric allocator_traits<allocator_type>::is_always_equal::value); // C++17, constexpr since C++20 2860b57cec5SDimitry Andric 28781ad6265SDimitry Andric const value_type* c_str() const noexcept; // constexpr since C++20 28881ad6265SDimitry Andric const value_type* data() const noexcept; // constexpr since C++20 28981ad6265SDimitry Andric value_type* data() noexcept; // C++17, constexpr since C++20 2900b57cec5SDimitry Andric 29181ad6265SDimitry Andric allocator_type get_allocator() const noexcept; // constexpr since C++20 2920b57cec5SDimitry Andric 29381ad6265SDimitry Andric size_type find(const basic_string& str, size_type pos = 0) const noexcept; // constexpr since C++20 2940b57cec5SDimitry Andric template <class T> 29581ad6265SDimitry Andric size_type find(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension, constexpr since C++20 29681ad6265SDimitry Andric size_type find(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20 29781ad6265SDimitry Andric size_type find(const value_type* s, size_type pos = 0) const noexcept; // constexpr since C++20 29881ad6265SDimitry Andric size_type find(value_type c, size_type pos = 0) const noexcept; // constexpr since C++20 2990b57cec5SDimitry Andric 30081ad6265SDimitry Andric size_type rfind(const basic_string& str, size_type pos = npos) const noexcept; // constexpr since C++20 3010b57cec5SDimitry Andric template <class T> 30281ad6265SDimitry Andric size_type rfind(const T& t, size_type pos = npos) const noexcept; // C++17, noexcept as an extension, constexpr since C++20 30381ad6265SDimitry Andric size_type rfind(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20 30481ad6265SDimitry Andric size_type rfind(const value_type* s, size_type pos = npos) const noexcept; // constexpr since C++20 30581ad6265SDimitry Andric size_type rfind(value_type c, size_type pos = npos) const noexcept; // constexpr since C++20 3060b57cec5SDimitry Andric 30781ad6265SDimitry Andric size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept; // constexpr since C++20 3080b57cec5SDimitry Andric template <class T> 30981ad6265SDimitry Andric size_type find_first_of(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension, constexpr since C++20 31081ad6265SDimitry Andric size_type find_first_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20 31181ad6265SDimitry Andric size_type find_first_of(const value_type* s, size_type pos = 0) const noexcept; // constexpr since C++20 31281ad6265SDimitry Andric size_type find_first_of(value_type c, size_type pos = 0) const noexcept; // constexpr since C++20 3130b57cec5SDimitry Andric 31481ad6265SDimitry Andric size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept; // constexpr since C++20 3150b57cec5SDimitry Andric template <class T> 31681ad6265SDimitry Andric size_type find_last_of(const T& t, size_type pos = npos) const noexcept noexcept; // C++17, noexcept as an extension, constexpr since C++20 31781ad6265SDimitry Andric size_type find_last_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20 31881ad6265SDimitry Andric size_type find_last_of(const value_type* s, size_type pos = npos) const noexcept; // constexpr since C++20 31981ad6265SDimitry Andric size_type find_last_of(value_type c, size_type pos = npos) const noexcept; // constexpr since C++20 3200b57cec5SDimitry Andric 32181ad6265SDimitry Andric size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept; // constexpr since C++20 3220b57cec5SDimitry Andric template <class T> 32381ad6265SDimitry Andric size_type find_first_not_of(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension, constexpr since C++20 32481ad6265SDimitry Andric size_type find_first_not_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20 32581ad6265SDimitry Andric size_type find_first_not_of(const value_type* s, size_type pos = 0) const noexcept; // constexpr since C++20 32681ad6265SDimitry Andric size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept; // constexpr since C++20 3270b57cec5SDimitry Andric 32881ad6265SDimitry Andric size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept; // constexpr since C++20 3290b57cec5SDimitry Andric template <class T> 33081ad6265SDimitry Andric size_type find_last_not_of(const T& t, size_type pos = npos) const noexcept; // C++17, noexcept as an extension, constexpr since C++20 33181ad6265SDimitry Andric size_type find_last_not_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20 33281ad6265SDimitry Andric size_type find_last_not_of(const value_type* s, size_type pos = npos) const noexcept; // constexpr since C++20 33381ad6265SDimitry Andric size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept; // constexpr since C++20 3340b57cec5SDimitry Andric 33581ad6265SDimitry Andric int compare(const basic_string& str) const noexcept; // constexpr since C++20 3360b57cec5SDimitry Andric template <class T> 33781ad6265SDimitry Andric int compare(const T& t) const noexcept; // C++17, noexcept as an extension, constexpr since C++20 33881ad6265SDimitry Andric int compare(size_type pos1, size_type n1, const basic_string& str) const; // constexpr since C++20 3390b57cec5SDimitry Andric template <class T> 34081ad6265SDimitry Andric int compare(size_type pos1, size_type n1, const T& t) const; // C++17, constexpr since C++20 3410b57cec5SDimitry Andric int compare(size_type pos1, size_type n1, const basic_string& str, 34281ad6265SDimitry Andric size_type pos2, size_type n2=npos) const; // C++14, constexpr since C++20 3430b57cec5SDimitry Andric template <class T> 3440b57cec5SDimitry Andric int compare(size_type pos1, size_type n1, const T& t, 34581ad6265SDimitry Andric size_type pos2, size_type n2=npos) const; // C++17, constexpr since C++20 34681ad6265SDimitry Andric int compare(const value_type* s) const noexcept; // constexpr since C++20 34781ad6265SDimitry Andric int compare(size_type pos1, size_type n1, const value_type* s) const; // constexpr since C++20 34881ad6265SDimitry Andric int compare(size_type pos1, size_type n1, const value_type* s, size_type n2) const; // constexpr since C++20 3490b57cec5SDimitry Andric 35081ad6265SDimitry Andric constexpr bool starts_with(basic_string_view<charT, traits> sv) const noexcept; // C++20 35181ad6265SDimitry Andric constexpr bool starts_with(charT c) const noexcept; // C++20 35281ad6265SDimitry Andric constexpr bool starts_with(const charT* s) const; // C++20 35381ad6265SDimitry Andric constexpr bool ends_with(basic_string_view<charT, traits> sv) const noexcept; // C++20 35481ad6265SDimitry Andric constexpr bool ends_with(charT c) const noexcept; // C++20 35581ad6265SDimitry Andric constexpr bool ends_with(const charT* s) const; // C++20 356e8d8bef9SDimitry Andric 35706c3fb27SDimitry Andric constexpr bool contains(basic_string_view<charT, traits> sv) const noexcept; // C++23 35806c3fb27SDimitry Andric constexpr bool contains(charT c) const noexcept; // C++23 35906c3fb27SDimitry Andric constexpr bool contains(const charT* s) const; // C++23 3600b57cec5SDimitry Andric}; 3610b57cec5SDimitry Andric 3620b57cec5SDimitry Andrictemplate<class InputIterator, 3630b57cec5SDimitry Andric class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>> 3640b57cec5SDimitry Andricbasic_string(InputIterator, InputIterator, Allocator = Allocator()) 3650b57cec5SDimitry Andric -> basic_string<typename iterator_traits<InputIterator>::value_type, 3660b57cec5SDimitry Andric char_traits<typename iterator_traits<InputIterator>::value_type>, 3670b57cec5SDimitry Andric Allocator>; // C++17 3680b57cec5SDimitry Andric 36906c3fb27SDimitry Andrictemplate<ranges::input_range R, 37006c3fb27SDimitry Andric class Allocator = allocator<ranges::range_value_t<R>>> 37106c3fb27SDimitry Andric basic_string(from_range_t, R&&, Allocator = Allocator()) 37206c3fb27SDimitry Andric -> basic_string<ranges::range_value_t<R>, char_traits<ranges::range_value_t<R>>, 37306c3fb27SDimitry Andric Allocator>; // C++23 37406c3fb27SDimitry Andric 37506c3fb27SDimitry Andrictemplate<class charT, 37606c3fb27SDimitry Andric class traits, 37706c3fb27SDimitry Andric class Allocator = allocator<charT>> 37806c3fb27SDimitry Andric explicit basic_string(basic_string_view<charT, traits>, const Allocator& = Allocator()) 37906c3fb27SDimitry Andric -> basic_string<charT, traits, Allocator>; // C++17 38006c3fb27SDimitry Andric 38106c3fb27SDimitry Andrictemplate<class charT, 38206c3fb27SDimitry Andric class traits, 38306c3fb27SDimitry Andric class Allocator = allocator<charT>> 38406c3fb27SDimitry Andric basic_string(basic_string_view<charT, traits>, 38506c3fb27SDimitry Andric typename see below::size_type, typename see below::size_type, 38606c3fb27SDimitry Andric const Allocator& = Allocator()) 38706c3fb27SDimitry Andric -> basic_string<charT, traits, Allocator>; // C++17 38806c3fb27SDimitry Andric 3890b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 3900b57cec5SDimitry Andricbasic_string<charT, traits, Allocator> 3910b57cec5SDimitry Andricoperator+(const basic_string<charT, traits, Allocator>& lhs, 39281ad6265SDimitry Andric const basic_string<charT, traits, Allocator>& rhs); // constexpr since C++20 3930b57cec5SDimitry Andric 3940b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 3950b57cec5SDimitry Andricbasic_string<charT, traits, Allocator> 39681ad6265SDimitry Andricoperator+(const charT* lhs , const basic_string<charT,traits,Allocator>&rhs); // constexpr since C++20 3970b57cec5SDimitry Andric 3980b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 3990b57cec5SDimitry Andricbasic_string<charT, traits, Allocator> 40081ad6265SDimitry Andricoperator+(charT lhs, const basic_string<charT,traits,Allocator>& rhs); // constexpr since C++20 4010b57cec5SDimitry Andric 4020b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 4030b57cec5SDimitry Andricbasic_string<charT, traits, Allocator> 40481ad6265SDimitry Andricoperator+(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs); // constexpr since C++20 4050b57cec5SDimitry Andric 4060b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 4070b57cec5SDimitry Andricbasic_string<charT, traits, Allocator> 40881ad6265SDimitry Andricoperator+(const basic_string<charT, traits, Allocator>& lhs, charT rhs); // constexpr since C++20 4090b57cec5SDimitry Andric 4100b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 4110fca6ea1SDimitry Andric constexpr basic_string<charT, traits, Allocator> 4120fca6ea1SDimitry Andric operator+(const basic_string<charT, traits, Allocator>& lhs, 4130fca6ea1SDimitry Andric type_identity_t<basic_string_view<charT, traits>> rhs); // Since C++26 4140fca6ea1SDimitry Andrictemplate<class charT, class traits, class Allocator> 4150fca6ea1SDimitry Andric constexpr basic_string<charT, traits, Allocator> 4160fca6ea1SDimitry Andric operator+(basic_string<charT, traits, Allocator>&& lhs, 4170fca6ea1SDimitry Andric type_identity_t<basic_string_view<charT, traits>> rhs); // Since C++26 4180fca6ea1SDimitry Andrictemplate<class charT, class traits, class Allocator> 4190fca6ea1SDimitry Andric constexpr basic_string<charT, traits, Allocator> 4200fca6ea1SDimitry Andric operator+(type_identity_t<basic_string_view<charT, traits>> lhs, 4210fca6ea1SDimitry Andric const basic_string<charT, traits, Allocator>& rhs); // Since C++26 4220fca6ea1SDimitry Andrictemplate<class charT, class traits, class Allocator> 4230fca6ea1SDimitry Andric constexpr basic_string<charT, traits, Allocator> 4240fca6ea1SDimitry Andric operator+(type_identity_t<basic_string_view<charT, traits>> lhs, 4250fca6ea1SDimitry Andric basic_string<charT, traits, Allocator>&& rhs); // Since C++26 4260fca6ea1SDimitry Andric 4270fca6ea1SDimitry Andric 4280fca6ea1SDimitry Andrictemplate<class charT, class traits, class Allocator> 4290b57cec5SDimitry Andricbool operator==(const basic_string<charT, traits, Allocator>& lhs, 43081ad6265SDimitry Andric const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20 4310b57cec5SDimitry Andric 4320b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 433bdd1243dSDimitry Andricbool operator==(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 4340b57cec5SDimitry Andric 4350b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 43681ad6265SDimitry Andricbool operator==(const basic_string<charT,traits,Allocator>& lhs, const charT* rhs) noexcept; // constexpr since C++20 4370b57cec5SDimitry Andric 4380b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 4390b57cec5SDimitry Andricbool operator!=(const basic_string<charT,traits,Allocator>& lhs, 440bdd1243dSDimitry Andric const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 4410b57cec5SDimitry Andric 4420b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 443bdd1243dSDimitry Andricbool operator!=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 4440b57cec5SDimitry Andric 4450b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 446bdd1243dSDimitry Andricbool operator!=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // removed in C++20 4470b57cec5SDimitry Andric 4480b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 4490b57cec5SDimitry Andricbool operator< (const basic_string<charT, traits, Allocator>& lhs, 450bdd1243dSDimitry Andric const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 4510b57cec5SDimitry Andric 4520b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 453bdd1243dSDimitry Andricbool operator< (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // removed in C++20 4540b57cec5SDimitry Andric 4550b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 456bdd1243dSDimitry Andricbool operator< (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 4570b57cec5SDimitry Andric 4580b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 4590b57cec5SDimitry Andricbool operator> (const basic_string<charT, traits, Allocator>& lhs, 460bdd1243dSDimitry Andric const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 4610b57cec5SDimitry Andric 4620b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 463bdd1243dSDimitry Andricbool operator> (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // removed in C++20 4640b57cec5SDimitry Andric 4650b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 466bdd1243dSDimitry Andricbool operator> (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 4670b57cec5SDimitry Andric 4680b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 4690b57cec5SDimitry Andricbool operator<=(const basic_string<charT, traits, Allocator>& lhs, 470bdd1243dSDimitry Andric const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 4710b57cec5SDimitry Andric 4720b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 473bdd1243dSDimitry Andricbool operator<=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // removed in C++20 4740b57cec5SDimitry Andric 4750b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 476bdd1243dSDimitry Andricbool operator<=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 4770b57cec5SDimitry Andric 4780b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 4790b57cec5SDimitry Andricbool operator>=(const basic_string<charT, traits, Allocator>& lhs, 480bdd1243dSDimitry Andric const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 4810b57cec5SDimitry Andric 4820b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 483bdd1243dSDimitry Andricbool operator>=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // removed in C++20 4840b57cec5SDimitry Andric 4850b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 486bdd1243dSDimitry Andricbool operator>=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 487bdd1243dSDimitry Andric 488bdd1243dSDimitry Andrictemplate<class charT, class traits, class Allocator> // since C++20 489bdd1243dSDimitry Andricconstexpr see below operator<=>(const basic_string<charT, traits, Allocator>& lhs, 490bdd1243dSDimitry Andric const basic_string<charT, traits, Allocator>& rhs) noexcept; 491bdd1243dSDimitry Andric 492bdd1243dSDimitry Andrictemplate<class charT, class traits, class Allocator> // since C++20 493bdd1243dSDimitry Andricconstexpr see below operator<=>(const basic_string<charT, traits, Allocator>& lhs, 494bdd1243dSDimitry Andric const charT* rhs) noexcept; 4950b57cec5SDimitry Andric 4960b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 4970b57cec5SDimitry Andricvoid swap(basic_string<charT, traits, Allocator>& lhs, 4980b57cec5SDimitry Andric basic_string<charT, traits, Allocator>& rhs) 49981ad6265SDimitry Andric noexcept(noexcept(lhs.swap(rhs))); // constexpr since C++20 5000b57cec5SDimitry Andric 5010b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 5020b57cec5SDimitry Andricbasic_istream<charT, traits>& 5030b57cec5SDimitry Andricoperator>>(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str); 5040b57cec5SDimitry Andric 5050b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 5060b57cec5SDimitry Andricbasic_ostream<charT, traits>& 5070b57cec5SDimitry Andricoperator<<(basic_ostream<charT, traits>& os, const basic_string<charT, traits, Allocator>& str); 5080b57cec5SDimitry Andric 5090b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 5100b57cec5SDimitry Andricbasic_istream<charT, traits>& 5110b57cec5SDimitry Andricgetline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str, 5120b57cec5SDimitry Andric charT delim); 5130b57cec5SDimitry Andric 5140b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 5150b57cec5SDimitry Andricbasic_istream<charT, traits>& 5160b57cec5SDimitry Andricgetline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str); 5170b57cec5SDimitry Andric 5180b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator, class U> 5195ffd83dbSDimitry Andrictypename basic_string<charT, traits, Allocator>::size_type 5205ffd83dbSDimitry Andricerase(basic_string<charT, traits, Allocator>& c, const U& value); // C++20 5210b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator, class Predicate> 5225ffd83dbSDimitry Andrictypename basic_string<charT, traits, Allocator>::size_type 5235ffd83dbSDimitry Andricerase_if(basic_string<charT, traits, Allocator>& c, Predicate pred); // C++20 5240b57cec5SDimitry Andric 5250b57cec5SDimitry Andrictypedef basic_string<char> string; 5260b57cec5SDimitry Andrictypedef basic_string<wchar_t> wstring; 527fe6060f1SDimitry Andrictypedef basic_string<char8_t> u8string; // C++20 5280b57cec5SDimitry Andrictypedef basic_string<char16_t> u16string; 5290b57cec5SDimitry Andrictypedef basic_string<char32_t> u32string; 5300b57cec5SDimitry Andric 531e8d8bef9SDimitry Andricint stoi (const string& str, size_t* idx = nullptr, int base = 10); 532e8d8bef9SDimitry Andriclong stol (const string& str, size_t* idx = nullptr, int base = 10); 533e8d8bef9SDimitry Andricunsigned long stoul (const string& str, size_t* idx = nullptr, int base = 10); 534e8d8bef9SDimitry Andriclong long stoll (const string& str, size_t* idx = nullptr, int base = 10); 535e8d8bef9SDimitry Andricunsigned long long stoull(const string& str, size_t* idx = nullptr, int base = 10); 5360b57cec5SDimitry Andric 537e8d8bef9SDimitry Andricfloat stof (const string& str, size_t* idx = nullptr); 538e8d8bef9SDimitry Andricdouble stod (const string& str, size_t* idx = nullptr); 539e8d8bef9SDimitry Andriclong double stold(const string& str, size_t* idx = nullptr); 5400b57cec5SDimitry Andric 5410b57cec5SDimitry Andricstring to_string(int val); 5420b57cec5SDimitry Andricstring to_string(unsigned val); 5430b57cec5SDimitry Andricstring to_string(long val); 5440b57cec5SDimitry Andricstring to_string(unsigned long val); 5450b57cec5SDimitry Andricstring to_string(long long val); 5460b57cec5SDimitry Andricstring to_string(unsigned long long val); 5470b57cec5SDimitry Andricstring to_string(float val); 5480b57cec5SDimitry Andricstring to_string(double val); 5490b57cec5SDimitry Andricstring to_string(long double val); 5500b57cec5SDimitry Andric 551e8d8bef9SDimitry Andricint stoi (const wstring& str, size_t* idx = nullptr, int base = 10); 552e8d8bef9SDimitry Andriclong stol (const wstring& str, size_t* idx = nullptr, int base = 10); 553e8d8bef9SDimitry Andricunsigned long stoul (const wstring& str, size_t* idx = nullptr, int base = 10); 554e8d8bef9SDimitry Andriclong long stoll (const wstring& str, size_t* idx = nullptr, int base = 10); 555e8d8bef9SDimitry Andricunsigned long long stoull(const wstring& str, size_t* idx = nullptr, int base = 10); 5560b57cec5SDimitry Andric 557e8d8bef9SDimitry Andricfloat stof (const wstring& str, size_t* idx = nullptr); 558e8d8bef9SDimitry Andricdouble stod (const wstring& str, size_t* idx = nullptr); 559e8d8bef9SDimitry Andriclong double stold(const wstring& str, size_t* idx = nullptr); 5600b57cec5SDimitry Andric 5610b57cec5SDimitry Andricwstring to_wstring(int val); 5620b57cec5SDimitry Andricwstring to_wstring(unsigned val); 5630b57cec5SDimitry Andricwstring to_wstring(long val); 5640b57cec5SDimitry Andricwstring to_wstring(unsigned long val); 5650b57cec5SDimitry Andricwstring to_wstring(long long val); 5660b57cec5SDimitry Andricwstring to_wstring(unsigned long long val); 5670b57cec5SDimitry Andricwstring to_wstring(float val); 5680b57cec5SDimitry Andricwstring to_wstring(double val); 5690b57cec5SDimitry Andricwstring to_wstring(long double val); 5700b57cec5SDimitry Andric 5710b57cec5SDimitry Andrictemplate <> struct hash<string>; 572fe6060f1SDimitry Andrictemplate <> struct hash<u8string>; // C++20 5730b57cec5SDimitry Andrictemplate <> struct hash<u16string>; 5740b57cec5SDimitry Andrictemplate <> struct hash<u32string>; 5750b57cec5SDimitry Andrictemplate <> struct hash<wstring>; 5760b57cec5SDimitry Andric 57781ad6265SDimitry Andricbasic_string<char> operator""s( const char *str, size_t len ); // C++14, constexpr since C++20 57881ad6265SDimitry Andricbasic_string<wchar_t> operator""s( const wchar_t *str, size_t len ); // C++14, constexpr since C++20 57981ad6265SDimitry Andricconstexpr basic_string<char8_t> operator""s( const char8_t *str, size_t len ); // C++20 58081ad6265SDimitry Andricbasic_string<char16_t> operator""s( const char16_t *str, size_t len ); // C++14, constexpr since C++20 58181ad6265SDimitry Andricbasic_string<char32_t> operator""s( const char32_t *str, size_t len ); // C++14, constexpr since C++20 5820b57cec5SDimitry Andric 5830b57cec5SDimitry Andric} // std 5840b57cec5SDimitry Andric 5850b57cec5SDimitry Andric*/ 5860b57cec5SDimitry Andric 5875f757f3fSDimitry Andric// clang-format on 5885f757f3fSDimitry Andric 58981ad6265SDimitry Andric#include <__algorithm/max.h> 59081ad6265SDimitry Andric#include <__algorithm/min.h> 59181ad6265SDimitry Andric#include <__algorithm/remove.h> 59281ad6265SDimitry Andric#include <__algorithm/remove_if.h> 5930fca6ea1SDimitry Andric#include <__assert> 5940b57cec5SDimitry Andric#include <__config> 5950fca6ea1SDimitry Andric#include <__debug_utils/sanitizers.h> 59681ad6265SDimitry Andric#include <__format/enable_insertable.h> 59781ad6265SDimitry Andric#include <__functional/hash.h> 59881ad6265SDimitry Andric#include <__functional/unary_function.h> 599bdd1243dSDimitry Andric#include <__fwd/string.h> 60081ad6265SDimitry Andric#include <__ios/fpos.h> 6010fca6ea1SDimitry Andric#include <__iterator/bounded_iter.h> 60281ad6265SDimitry Andric#include <__iterator/distance.h> 60381ad6265SDimitry Andric#include <__iterator/iterator_traits.h> 60481ad6265SDimitry Andric#include <__iterator/reverse_iterator.h> 605fe6060f1SDimitry Andric#include <__iterator/wrap_iter.h> 60606c3fb27SDimitry Andric#include <__memory/addressof.h> 60781ad6265SDimitry Andric#include <__memory/allocate_at_least.h> 608bdd1243dSDimitry Andric#include <__memory/allocator.h> 609bdd1243dSDimitry Andric#include <__memory/allocator_traits.h> 610bdd1243dSDimitry Andric#include <__memory/compressed_pair.h> 611bdd1243dSDimitry Andric#include <__memory/construct_at.h> 612bdd1243dSDimitry Andric#include <__memory/pointer_traits.h> 613972a253aSDimitry Andric#include <__memory/swap_allocator.h> 614bdd1243dSDimitry Andric#include <__memory_resource/polymorphic_allocator.h> 61506c3fb27SDimitry Andric#include <__ranges/access.h> 61606c3fb27SDimitry Andric#include <__ranges/concepts.h> 61706c3fb27SDimitry Andric#include <__ranges/container_compatible_range.h> 61806c3fb27SDimitry Andric#include <__ranges/from_range.h> 61906c3fb27SDimitry Andric#include <__ranges/size.h> 62081ad6265SDimitry Andric#include <__string/char_traits.h> 62181ad6265SDimitry Andric#include <__string/extern_template_lists.h> 6220fca6ea1SDimitry Andric#include <__type_traits/conditional.h> 623bdd1243dSDimitry Andric#include <__type_traits/is_allocator.h> 62406c3fb27SDimitry Andric#include <__type_traits/is_array.h> 62506c3fb27SDimitry Andric#include <__type_traits/is_convertible.h> 6260fca6ea1SDimitry Andric#include <__type_traits/is_nothrow_assignable.h> 6270fca6ea1SDimitry Andric#include <__type_traits/is_nothrow_constructible.h> 62806c3fb27SDimitry Andric#include <__type_traits/is_same.h> 62906c3fb27SDimitry Andric#include <__type_traits/is_standard_layout.h> 63006c3fb27SDimitry Andric#include <__type_traits/is_trivial.h> 6310fca6ea1SDimitry Andric#include <__type_traits/is_trivially_relocatable.h> 632bdd1243dSDimitry Andric#include <__type_traits/noexcept_move_assign_container.h> 63306c3fb27SDimitry Andric#include <__type_traits/remove_cvref.h> 63406c3fb27SDimitry Andric#include <__type_traits/void_t.h> 63581ad6265SDimitry Andric#include <__utility/auto_cast.h> 63606c3fb27SDimitry Andric#include <__utility/declval.h> 63706c3fb27SDimitry Andric#include <__utility/forward.h> 63806c3fb27SDimitry Andric#include <__utility/is_pointer_in_range.h> 63981ad6265SDimitry Andric#include <__utility/move.h> 64081ad6265SDimitry Andric#include <__utility/swap.h> 64181ad6265SDimitry Andric#include <__utility/unreachable.h> 64281ad6265SDimitry Andric#include <climits> 643fe6060f1SDimitry Andric#include <cstdio> // EOF 644fe6060f1SDimitry Andric#include <cstring> 64581ad6265SDimitry Andric#include <limits> 6460b57cec5SDimitry Andric#include <stdexcept> 647fe6060f1SDimitry Andric#include <string_view> 6480b57cec5SDimitry Andric#include <version> 649fe6060f1SDimitry Andric 650349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 651349cc55cSDimitry Andric# include <cwchar> 652349cc55cSDimitry Andric#endif 653349cc55cSDimitry Andric 65481ad6265SDimitry Andric// standard-mandated includes 65581ad6265SDimitry Andric 65681ad6265SDimitry Andric// [iterator.range] 65781ad6265SDimitry Andric#include <__iterator/access.h> 65881ad6265SDimitry Andric#include <__iterator/data.h> 65981ad6265SDimitry Andric#include <__iterator/empty.h> 66081ad6265SDimitry Andric#include <__iterator/reverse_access.h> 66181ad6265SDimitry Andric#include <__iterator/size.h> 66281ad6265SDimitry Andric 66381ad6265SDimitry Andric// [string.syn] 66481ad6265SDimitry Andric#include <compare> 66581ad6265SDimitry Andric#include <initializer_list> 66681ad6265SDimitry Andric 6670b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 6680b57cec5SDimitry Andric# pragma GCC system_header 6690b57cec5SDimitry Andric#endif 6700b57cec5SDimitry Andric 6710b57cec5SDimitry Andric_LIBCPP_PUSH_MACROS 6720b57cec5SDimitry Andric#include <__undef_macros> 6730b57cec5SDimitry Andric 6745f757f3fSDimitry Andric#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN) 6755f757f3fSDimitry Andric# define _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS __attribute__((__no_sanitize__("address"))) 6765f757f3fSDimitry Andric// This macro disables AddressSanitizer (ASan) instrumentation for a specific function, 6775f757f3fSDimitry Andric// allowing memory accesses that would normally trigger ASan errors to proceed without crashing. 6785f757f3fSDimitry Andric// This is useful for accessing parts of objects memory, which should not be accessed, 6795f757f3fSDimitry Andric// such as unused bytes in short strings, that should never be accessed 6805f757f3fSDimitry Andric// by other parts of the program. 6815f757f3fSDimitry Andric#else 6825f757f3fSDimitry Andric# define _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS 6835f757f3fSDimitry Andric#endif 6840b57cec5SDimitry Andric 6850b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 6860b57cec5SDimitry Andric 6870b57cec5SDimitry Andric// basic_string 6880b57cec5SDimitry Andric 6890b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 690cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 691cb14a3feSDimitry Andricoperator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const basic_string<_CharT, _Traits, _Allocator>& __y); 6920b57cec5SDimitry Andric 6930b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 694cb14a3feSDimitry Andric_LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 6950b57cec5SDimitry Andricoperator+(const _CharT* __x, const basic_string<_CharT, _Traits, _Allocator>& __y); 6960b57cec5SDimitry Andric 6970b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 698cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 6990b57cec5SDimitry Andricoperator+(_CharT __x, const basic_string<_CharT, _Traits, _Allocator>& __y); 7000b57cec5SDimitry Andric 7010b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 702cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 7030b57cec5SDimitry Andricoperator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const _CharT* __y); 7040b57cec5SDimitry Andric 7050b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 706cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 7070b57cec5SDimitry Andricoperator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y); 7080b57cec5SDimitry Andric 7090fca6ea1SDimitry Andric#if _LIBCPP_STD_VER >= 26 7100fca6ea1SDimitry Andric 7110fca6ea1SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 7120fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator> 7130fca6ea1SDimitry Andricoperator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 7140fca6ea1SDimitry Andric type_identity_t<basic_string_view<_CharT, _Traits>> __rhs); 7150fca6ea1SDimitry Andric 7160fca6ea1SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 7170fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator> 7180fca6ea1SDimitry Andricoperator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, type_identity_t<basic_string_view<_CharT, _Traits>> __rhs); 7190fca6ea1SDimitry Andric 7200fca6ea1SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 7210fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator> 7220fca6ea1SDimitry Andricoperator+(type_identity_t<basic_string_view<_CharT, _Traits>> __lhs, 7230fca6ea1SDimitry Andric const basic_string<_CharT, _Traits, _Allocator>& __rhs); 7240fca6ea1SDimitry Andric 7250fca6ea1SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 7260fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator> 7270fca6ea1SDimitry Andricoperator+(type_identity_t<basic_string_view<_CharT, _Traits>> __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs); 7280fca6ea1SDimitry Andric 7290fca6ea1SDimitry Andric#endif 7300fca6ea1SDimitry Andric 73106c3fb27SDimitry Andricextern template _LIBCPP_EXPORTED_FROM_ABI string operator+ 73206c3fb27SDimitry Andric <char, char_traits<char>, allocator<char> >(char const*, string const&); 7330b57cec5SDimitry Andric 7340b57cec5SDimitry Andrictemplate <class _Iter> 735fe6060f1SDimitry Andricstruct __string_is_trivial_iterator : public false_type {}; 736fe6060f1SDimitry Andric 737fe6060f1SDimitry Andrictemplate <class _Tp> 738cb14a3feSDimitry Andricstruct __string_is_trivial_iterator<_Tp*> : public is_arithmetic<_Tp> {}; 7390b57cec5SDimitry Andric 7400b57cec5SDimitry Andrictemplate <class _Iter> 741cb14a3feSDimitry Andricstruct __string_is_trivial_iterator<__wrap_iter<_Iter> > : public __string_is_trivial_iterator<_Iter> {}; 7420b57cec5SDimitry Andric 7430b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Tp> 744cb14a3feSDimitry Andricstruct __can_be_converted_to_string_view 745cb14a3feSDimitry Andric : public _BoolConstant< is_convertible<const _Tp&, basic_string_view<_CharT, _Traits> >::value && 746cb14a3feSDimitry Andric !is_convertible<const _Tp&, const _CharT*>::value > {}; 7470b57cec5SDimitry Andric 74881ad6265SDimitry Andricstruct __uninitialized_size_tag {}; 74906c3fb27SDimitry Andricstruct __init_with_sentinel_tag {}; 750e8d8bef9SDimitry Andric 7510b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 752cb14a3feSDimitry Andricclass basic_string { 7535f757f3fSDimitry Andricprivate: 7545f757f3fSDimitry Andric using __default_allocator_type = allocator<_CharT>; 7555f757f3fSDimitry Andric 7560b57cec5SDimitry Andricpublic: 7570b57cec5SDimitry Andric typedef basic_string __self; 7580b57cec5SDimitry Andric typedef basic_string_view<_CharT, _Traits> __self_view; 7590b57cec5SDimitry Andric typedef _Traits traits_type; 7600b57cec5SDimitry Andric typedef _CharT value_type; 7610b57cec5SDimitry Andric typedef _Allocator allocator_type; 7620b57cec5SDimitry Andric typedef allocator_traits<allocator_type> __alloc_traits; 7630b57cec5SDimitry Andric typedef typename __alloc_traits::size_type size_type; 7640b57cec5SDimitry Andric typedef typename __alloc_traits::difference_type difference_type; 7650b57cec5SDimitry Andric typedef value_type& reference; 7660b57cec5SDimitry Andric typedef const value_type& const_reference; 7670b57cec5SDimitry Andric typedef typename __alloc_traits::pointer pointer; 7680b57cec5SDimitry Andric typedef typename __alloc_traits::const_pointer const_pointer; 7690b57cec5SDimitry Andric 7700fca6ea1SDimitry Andric // A basic_string contains the following members which may be trivially relocatable: 7710fca6ea1SDimitry Andric // - pointer: is currently assumed to be trivially relocatable, but is still checked in case that changes 7720fca6ea1SDimitry Andric // - size_type: is always trivially relocatable, since it has to be an integral type 7730fca6ea1SDimitry Andric // - value_type: is always trivially relocatable, since it has to be trivial 7740fca6ea1SDimitry Andric // - unsigned char: is a fundamental type, so it's trivially relocatable 7750fca6ea1SDimitry Andric // - allocator_type: may or may not be trivially relocatable, so it's checked 7760fca6ea1SDimitry Andric // 7770fca6ea1SDimitry Andric // This string implementation doesn't contain any references into itself. It only contains a bit that says whether 7780fca6ea1SDimitry Andric // it is in small or large string mode, so the entire structure is trivially relocatable if its members are. 7790fca6ea1SDimitry Andric#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN) 7800fca6ea1SDimitry Andric // When compiling with AddressSanitizer (ASan), basic_string cannot be trivially 7810fca6ea1SDimitry Andric // relocatable. Because the object's memory might be poisoned when its content 7820fca6ea1SDimitry Andric // is kept inside objects memory (short string optimization), instead of in allocated 7830fca6ea1SDimitry Andric // external memory. In such cases, the destructor is responsible for unpoisoning 7840fca6ea1SDimitry Andric // the memory to avoid triggering false positives. 7850fca6ea1SDimitry Andric // Therefore it's crucial to ensure the destructor is called. 7860fca6ea1SDimitry Andric using __trivially_relocatable = void; 7870fca6ea1SDimitry Andric#else 7880fca6ea1SDimitry Andric using __trivially_relocatable = __conditional_t< 7890fca6ea1SDimitry Andric __libcpp_is_trivially_relocatable<allocator_type>::value && __libcpp_is_trivially_relocatable<pointer>::value, 7900fca6ea1SDimitry Andric basic_string, 7910fca6ea1SDimitry Andric void>; 7920fca6ea1SDimitry Andric#endif 7930fca6ea1SDimitry Andric#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN) 7940fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pointer __asan_volatile_wrapper(pointer const& __ptr) const { 7950fca6ea1SDimitry Andric if (__libcpp_is_constant_evaluated()) 7960fca6ea1SDimitry Andric return __ptr; 7970fca6ea1SDimitry Andric 7980fca6ea1SDimitry Andric pointer volatile __copy_ptr = __ptr; 7990fca6ea1SDimitry Andric 8000fca6ea1SDimitry Andric return const_cast<pointer&>(__copy_ptr); 8010fca6ea1SDimitry Andric } 8020fca6ea1SDimitry Andric 8030fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_pointer 8040fca6ea1SDimitry Andric __asan_volatile_wrapper(const_pointer const& __ptr) const { 8050fca6ea1SDimitry Andric if (__libcpp_is_constant_evaluated()) 8060fca6ea1SDimitry Andric return __ptr; 8070fca6ea1SDimitry Andric 8080fca6ea1SDimitry Andric const_pointer volatile __copy_ptr = __ptr; 8090fca6ea1SDimitry Andric 8100fca6ea1SDimitry Andric return const_cast<const_pointer&>(__copy_ptr); 8110fca6ea1SDimitry Andric } 8120fca6ea1SDimitry Andric# define _LIBCPP_ASAN_VOLATILE_WRAPPER(PTR) __asan_volatile_wrapper(PTR) 8130fca6ea1SDimitry Andric#else 8140fca6ea1SDimitry Andric# define _LIBCPP_ASAN_VOLATILE_WRAPPER(PTR) PTR 8150fca6ea1SDimitry Andric#endif 8160fca6ea1SDimitry Andric 8170fca6ea1SDimitry Andric static_assert(!is_array<value_type>::value, "Character type of basic_string must not be an array"); 8180fca6ea1SDimitry Andric static_assert(is_standard_layout<value_type>::value, "Character type of basic_string must be standard-layout"); 8190fca6ea1SDimitry Andric static_assert(is_trivial<value_type>::value, "Character type of basic_string must be trivial"); 8200fca6ea1SDimitry Andric static_assert(is_same<_CharT, typename traits_type::char_type>::value, 8210b57cec5SDimitry Andric "traits_type::char_type must be the same type as CharT"); 8220fca6ea1SDimitry Andric static_assert(is_same<typename allocator_type::value_type, value_type>::value, 8230b57cec5SDimitry Andric "Allocator::value_type must be same type as value_type"); 8240fca6ea1SDimitry Andric static_assert(__check_valid_allocator<allocator_type>::value, ""); 8250b57cec5SDimitry Andric 8260fca6ea1SDimitry Andric#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING 8270fca6ea1SDimitry Andric // Users might provide custom allocators, and prior to C++20 we have no existing way to detect whether the allocator's 8280fca6ea1SDimitry Andric // pointer type is contiguous (though it has to be by the Standard). Using the wrapper type ensures the iterator is 8290fca6ea1SDimitry Andric // considered contiguous. 8300fca6ea1SDimitry Andric typedef __bounded_iter<__wrap_iter<pointer>> iterator; 8310fca6ea1SDimitry Andric typedef __bounded_iter<__wrap_iter<const_pointer>> const_iterator; 8320fca6ea1SDimitry Andric#else 8330b57cec5SDimitry Andric typedef __wrap_iter<pointer> iterator; 8340b57cec5SDimitry Andric typedef __wrap_iter<const_pointer> const_iterator; 8350fca6ea1SDimitry Andric#endif 83681ad6265SDimitry Andric typedef std::reverse_iterator<iterator> reverse_iterator; 83781ad6265SDimitry Andric typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 8380b57cec5SDimitry Andric 8390b57cec5SDimitry Andricprivate: 84081ad6265SDimitry Andric static_assert(CHAR_BIT == 8, "This implementation assumes that one byte contains 8 bits"); 8410b57cec5SDimitry Andric 8420b57cec5SDimitry Andric#ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT 8430b57cec5SDimitry Andric 844cb14a3feSDimitry Andric struct __long { 8450b57cec5SDimitry Andric pointer __data_; 8460b57cec5SDimitry Andric size_type __size_; 84781ad6265SDimitry Andric size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1; 84881ad6265SDimitry Andric size_type __is_long_ : 1; 8490b57cec5SDimitry Andric }; 8500b57cec5SDimitry Andric 851cb14a3feSDimitry Andric enum { __min_cap = (sizeof(__long) - 1) / sizeof(value_type) > 2 ? (sizeof(__long) - 1) / sizeof(value_type) : 2 }; 8520b57cec5SDimitry Andric 853cb14a3feSDimitry Andric struct __short { 8540b57cec5SDimitry Andric value_type __data_[__min_cap]; 85581ad6265SDimitry Andric unsigned char __padding_[sizeof(value_type) - 1]; 85681ad6265SDimitry Andric unsigned char __size_ : 7; 85781ad6265SDimitry Andric unsigned char __is_long_ : 1; 8580b57cec5SDimitry Andric }; 8590b57cec5SDimitry Andric 86081ad6265SDimitry Andric // The __endian_factor is required because the field we use to store the size 86181ad6265SDimitry Andric // has one fewer bit than it would if it were not a bitfield. 86281ad6265SDimitry Andric // 86381ad6265SDimitry Andric // If the LSB is used to store the short-flag in the short string representation, 86481ad6265SDimitry Andric // we have to multiply the size by two when it is stored and divide it by two when 86581ad6265SDimitry Andric // it is loaded to make sure that we always store an even number. In the long string 86681ad6265SDimitry Andric // representation, we can ignore this because we can assume that we always allocate 86781ad6265SDimitry Andric // an even amount of value_types. 86881ad6265SDimitry Andric // 86981ad6265SDimitry Andric // If the MSB is used for the short-flag, the max_size() is numeric_limits<size_type>::max() / 2. 87081ad6265SDimitry Andric // This does not impact the short string representation, since we never need the MSB 87181ad6265SDimitry Andric // for representing the size of a short string anyway. 87281ad6265SDimitry Andric 87381ad6265SDimitry Andric# ifdef _LIBCPP_BIG_ENDIAN 87481ad6265SDimitry Andric static const size_type __endian_factor = 2; 8750b57cec5SDimitry Andric# else 87681ad6265SDimitry Andric static const size_type __endian_factor = 1; 87781ad6265SDimitry Andric# endif 8780b57cec5SDimitry Andric 87981ad6265SDimitry Andric#else // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT 88081ad6265SDimitry Andric 88181ad6265SDimitry Andric# ifdef _LIBCPP_BIG_ENDIAN 88281ad6265SDimitry Andric static const size_type __endian_factor = 1; 88381ad6265SDimitry Andric# else 88481ad6265SDimitry Andric static const size_type __endian_factor = 2; 88581ad6265SDimitry Andric# endif 88681ad6265SDimitry Andric 88781ad6265SDimitry Andric // Attribute 'packed' is used to keep the layout compatible with the 88881ad6265SDimitry Andric // previous definition that did not use bit fields. This is because on 88981ad6265SDimitry Andric // some platforms bit fields have a default size rather than the actual 89081ad6265SDimitry Andric // size used, e.g., it is 4 bytes on AIX. See D128285 for details. 891cb14a3feSDimitry Andric struct __long { 89281ad6265SDimitry Andric struct _LIBCPP_PACKED { 89381ad6265SDimitry Andric size_type __is_long_ : 1; 89481ad6265SDimitry Andric size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1; 89581ad6265SDimitry Andric }; 8960b57cec5SDimitry Andric size_type __size_; 8970b57cec5SDimitry Andric pointer __data_; 8980b57cec5SDimitry Andric }; 8990b57cec5SDimitry Andric 900cb14a3feSDimitry Andric enum { __min_cap = (sizeof(__long) - 1) / sizeof(value_type) > 2 ? (sizeof(__long) - 1) / sizeof(value_type) : 2 }; 9010b57cec5SDimitry Andric 902cb14a3feSDimitry Andric struct __short { 90381ad6265SDimitry Andric struct _LIBCPP_PACKED { 90481ad6265SDimitry Andric unsigned char __is_long_ : 1; 90581ad6265SDimitry Andric unsigned char __size_ : 7; 9060b57cec5SDimitry Andric }; 90781ad6265SDimitry Andric char __padding_[sizeof(value_type) - 1]; 9080b57cec5SDimitry Andric value_type __data_[__min_cap]; 9090b57cec5SDimitry Andric }; 9100b57cec5SDimitry Andric 9110b57cec5SDimitry Andric#endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT 9120b57cec5SDimitry Andric 91381ad6265SDimitry Andric static_assert(sizeof(__short) == (sizeof(value_type) * (__min_cap + 1)), "__short has an unexpected size."); 91481ad6265SDimitry Andric 9150fca6ea1SDimitry Andric union __rep { 9160b57cec5SDimitry Andric __short __s; 9175f757f3fSDimitry Andric __long __l; 9180b57cec5SDimitry Andric }; 9190b57cec5SDimitry Andric 9200b57cec5SDimitry Andric __compressed_pair<__rep, allocator_type> __r_; 9210b57cec5SDimitry Andric 92281ad6265SDimitry Andric // Construct a string with the given allocator and enough storage to hold `__size` characters, but 92381ad6265SDimitry Andric // don't initialize the characters. The contents of the string, including the null terminator, must be 92481ad6265SDimitry Andric // initialized separately. 925cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string( 926cb14a3feSDimitry Andric __uninitialized_size_tag, size_type __size, const allocator_type& __a) 92781ad6265SDimitry Andric : __r_(__default_init_tag(), __a) { 92881ad6265SDimitry Andric if (__size > max_size()) 92981ad6265SDimitry Andric __throw_length_error(); 93081ad6265SDimitry Andric if (__fits_in_sso(__size)) { 931bdd1243dSDimitry Andric __r_.first() = __rep(); 93281ad6265SDimitry Andric __set_short_size(__size); 93381ad6265SDimitry Andric } else { 93481ad6265SDimitry Andric auto __capacity = __recommend(__size) + 1; 93581ad6265SDimitry Andric auto __allocation = __alloc_traits::allocate(__alloc(), __capacity); 93681ad6265SDimitry Andric __begin_lifetime(__allocation, __capacity); 93781ad6265SDimitry Andric __set_long_cap(__capacity); 93881ad6265SDimitry Andric __set_long_pointer(__allocation); 93981ad6265SDimitry Andric __set_long_size(__size); 94081ad6265SDimitry Andric } 9415f757f3fSDimitry Andric __annotate_new(__size); 94206c3fb27SDimitry Andric } 94306c3fb27SDimitry Andric 94406c3fb27SDimitry Andric template <class _Iter, class _Sent> 94506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 94606c3fb27SDimitry Andric basic_string(__init_with_sentinel_tag, _Iter __first, _Sent __last, const allocator_type& __a) 94706c3fb27SDimitry Andric : __r_(__default_init_tag(), __a) { 94806c3fb27SDimitry Andric __init_with_sentinel(std::move(__first), std::move(__last)); 94981ad6265SDimitry Andric } 95081ad6265SDimitry Andric 9510fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator __make_iterator(pointer __p) { 9520fca6ea1SDimitry Andric#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING 9530fca6ea1SDimitry Andric // Bound the iterator according to the size (and not the capacity, unlike vector). 9540fca6ea1SDimitry Andric // 9550fca6ea1SDimitry Andric // By the Standard, string iterators are generally not guaranteed to stay valid when the container is modified, 9560fca6ea1SDimitry Andric // regardless of whether reallocation occurs. This allows us to check for out-of-bounds accesses using logical size, 9570fca6ea1SDimitry Andric // a stricter check, since correct code can never rely on being able to access newly-added elements via an existing 9580fca6ea1SDimitry Andric // iterator. 9590fca6ea1SDimitry Andric return std::__make_bounded_iter( 9600fca6ea1SDimitry Andric std::__wrap_iter<pointer>(__p), 9610fca6ea1SDimitry Andric std::__wrap_iter<pointer>(__get_pointer()), 9620fca6ea1SDimitry Andric std::__wrap_iter<pointer>(__get_pointer() + size())); 9630fca6ea1SDimitry Andric#else 9640fca6ea1SDimitry Andric return iterator(__p); 9650fca6ea1SDimitry Andric#endif // _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING 9660fca6ea1SDimitry Andric } 967bdd1243dSDimitry Andric 968bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator __make_const_iterator(const_pointer __p) const { 9690fca6ea1SDimitry Andric#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING 9700fca6ea1SDimitry Andric // Bound the iterator according to the size (and not the capacity, unlike vector). 9710fca6ea1SDimitry Andric return std::__make_bounded_iter( 9720fca6ea1SDimitry Andric std::__wrap_iter<const_pointer>(__p), 9730fca6ea1SDimitry Andric std::__wrap_iter<const_pointer>(__get_pointer()), 9740fca6ea1SDimitry Andric std::__wrap_iter<const_pointer>(__get_pointer() + size())); 9750fca6ea1SDimitry Andric#else 97606c3fb27SDimitry Andric return const_iterator(__p); 9770fca6ea1SDimitry Andric#endif // _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING 978bdd1243dSDimitry Andric } 979bdd1243dSDimitry Andric 9800b57cec5SDimitry Andricpublic: 981bdd1243dSDimitry Andric _LIBCPP_TEMPLATE_DATA_VIS static const size_type npos = -1; 9820b57cec5SDimitry Andric 983bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string() 984bdd1243dSDimitry Andric _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) 9855f757f3fSDimitry Andric : __r_(__value_init_tag(), __default_init_tag()) { 9865f757f3fSDimitry Andric __annotate_new(0); 987bdd1243dSDimitry Andric } 9880b57cec5SDimitry Andric 989bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(const allocator_type& __a) 9900b57cec5SDimitry Andric#if _LIBCPP_STD_VER <= 14 991bdd1243dSDimitry Andric _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value) 9920b57cec5SDimitry Andric#else 993bdd1243dSDimitry Andric _NOEXCEPT 9940b57cec5SDimitry Andric#endif 9955f757f3fSDimitry Andric : __r_(__value_init_tag(), __a) { 9965f757f3fSDimitry Andric __annotate_new(0); 997bdd1243dSDimitry Andric } 9980b57cec5SDimitry Andric 9995f757f3fSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS basic_string(const basic_string& __str) 100006c3fb27SDimitry Andric : __r_(__default_init_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc())) { 1001cb14a3feSDimitry Andric if (!__str.__is_long()) { 100206c3fb27SDimitry Andric __r_.first() = __str.__r_.first(); 10035f757f3fSDimitry Andric __annotate_new(__get_short_size()); 1004cb14a3feSDimitry Andric } else 100506c3fb27SDimitry Andric __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); 100606c3fb27SDimitry Andric } 100706c3fb27SDimitry Andric 1008cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS 1009cb14a3feSDimitry Andric basic_string(const basic_string& __str, const allocator_type& __a) 101006c3fb27SDimitry Andric : __r_(__default_init_tag(), __a) { 1011cb14a3feSDimitry Andric if (!__str.__is_long()) { 101206c3fb27SDimitry Andric __r_.first() = __str.__r_.first(); 10135f757f3fSDimitry Andric __annotate_new(__get_short_size()); 1014cb14a3feSDimitry Andric } else 101506c3fb27SDimitry Andric __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); 101606c3fb27SDimitry Andric } 10170b57cec5SDimitry Andric 10180b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 1019cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(basic_string&& __str) 10200b57cec5SDimitry Andric# if _LIBCPP_STD_VER <= 14 1021bdd1243dSDimitry Andric _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value) 10220b57cec5SDimitry Andric# else 1023bdd1243dSDimitry Andric _NOEXCEPT 10240b57cec5SDimitry Andric# endif 10255f757f3fSDimitry Andric // Turning off ASan instrumentation for variable initialization with _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS 10265f757f3fSDimitry Andric // does not work consistently during initialization of __r_, so we instead unpoison __str's memory manually first. 10275f757f3fSDimitry Andric // __str's memory needs to be unpoisoned only in the case where it's a short string. 10280fca6ea1SDimitry Andric : __r_([](basic_string& __s) -> decltype(__s.__r_)&& { 10290fca6ea1SDimitry Andric if (!__s.__is_long()) 10300fca6ea1SDimitry Andric __s.__annotate_delete(); 10310fca6ea1SDimitry Andric return std::move(__s.__r_); 10320fca6ea1SDimitry Andric }(__str)) { 10335f757f3fSDimitry Andric __str.__r_.first() = __rep(); 10345f757f3fSDimitry Andric __str.__annotate_new(0); 10355f757f3fSDimitry Andric if (!__is_long()) 10365f757f3fSDimitry Andric __annotate_new(size()); 1037bdd1243dSDimitry Andric } 10380b57cec5SDimitry Andric 1039cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(basic_string&& __str, const allocator_type& __a) 1040bdd1243dSDimitry Andric : __r_(__default_init_tag(), __a) { 1041bdd1243dSDimitry Andric if (__str.__is_long() && __a != __str.__alloc()) // copy, not move 1042bdd1243dSDimitry Andric __init(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); 1043bdd1243dSDimitry Andric else { 1044bdd1243dSDimitry Andric if (__libcpp_is_constant_evaluated()) 1045bdd1243dSDimitry Andric __r_.first() = __rep(); 10465f757f3fSDimitry Andric if (!__str.__is_long()) 10475f757f3fSDimitry Andric __str.__annotate_delete(); 1048bdd1243dSDimitry Andric __r_.first() = __str.__r_.first(); 10495f757f3fSDimitry Andric __str.__r_.first() = __rep(); 10505f757f3fSDimitry Andric __str.__annotate_new(0); 10515f757f3fSDimitry Andric if (!__is_long() && this != &__str) 10525f757f3fSDimitry Andric __annotate_new(size()); 1053bdd1243dSDimitry Andric } 1054bdd1243dSDimitry Andric } 10550b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 10560b57cec5SDimitry Andric 105706c3fb27SDimitry Andric template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0> 1058bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s) 1059bdd1243dSDimitry Andric : __r_(__default_init_tag(), __default_init_tag()) { 10605f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "basic_string(const char*) detected nullptr"); 10610b57cec5SDimitry Andric __init(__s, traits_type::length(__s)); 10620b57cec5SDimitry Andric } 10630b57cec5SDimitry Andric 106406c3fb27SDimitry Andric template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0> 106506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s, const _Allocator& __a) 106606c3fb27SDimitry Andric : __r_(__default_init_tag(), __a) { 10675f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "basic_string(const char*, allocator) detected nullptr"); 106806c3fb27SDimitry Andric __init(__s, traits_type::length(__s)); 106906c3fb27SDimitry Andric } 10700b57cec5SDimitry Andric 107106c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 1072fe6060f1SDimitry Andric basic_string(nullptr_t) = delete; 1073fe6060f1SDimitry Andric#endif 1074fe6060f1SDimitry Andric 1075bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s, size_type __n) 1076bdd1243dSDimitry Andric : __r_(__default_init_tag(), __default_init_tag()) { 10775f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr"); 1078bdd1243dSDimitry Andric __init(__s, __n); 1079bdd1243dSDimitry Andric } 1080bdd1243dSDimitry Andric 1081bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 1082bdd1243dSDimitry Andric basic_string(const _CharT* __s, size_type __n, const _Allocator& __a) 1083bdd1243dSDimitry Andric : __r_(__default_init_tag(), __a) { 10845f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr"); 1085bdd1243dSDimitry Andric __init(__s, __n); 1086bdd1243dSDimitry Andric } 1087bdd1243dSDimitry Andric 1088bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(size_type __n, _CharT __c) 1089bdd1243dSDimitry Andric : __r_(__default_init_tag(), __default_init_tag()) { 1090bdd1243dSDimitry Andric __init(__n, __c); 1091bdd1243dSDimitry Andric } 1092bdd1243dSDimitry Andric 109306c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 1094cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr basic_string( 1095cb14a3feSDimitry Andric basic_string&& __str, size_type __pos, const _Allocator& __alloc = _Allocator()) 1096bdd1243dSDimitry Andric : basic_string(std::move(__str), __pos, npos, __alloc) {} 1097bdd1243dSDimitry Andric 1098cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr basic_string( 1099cb14a3feSDimitry Andric basic_string&& __str, size_type __pos, size_type __n, const _Allocator& __alloc = _Allocator()) 1100bdd1243dSDimitry Andric : __r_(__default_init_tag(), __alloc) { 1101bdd1243dSDimitry Andric if (__pos > __str.size()) 1102bdd1243dSDimitry Andric __throw_out_of_range(); 1103bdd1243dSDimitry Andric 1104bdd1243dSDimitry Andric auto __len = std::min<size_type>(__n, __str.size() - __pos); 1105bdd1243dSDimitry Andric if (__alloc_traits::is_always_equal::value || __alloc == __str.__alloc()) { 11065f757f3fSDimitry Andric __move_assign(std::move(__str), __pos, __len); 1107bdd1243dSDimitry Andric } else { 1108bdd1243dSDimitry Andric // Perform a copy because the allocators are not compatible. 1109bdd1243dSDimitry Andric __init(__str.data() + __pos, __len); 1110bdd1243dSDimitry Andric } 1111bdd1243dSDimitry Andric } 1112bdd1243dSDimitry Andric#endif 11130b57cec5SDimitry Andric 111406c3fb27SDimitry Andric template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0> 111506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(size_type __n, _CharT __c, const _Allocator& __a) 111606c3fb27SDimitry Andric : __r_(__default_init_tag(), __a) { 111706c3fb27SDimitry Andric __init(__n, __c); 111806c3fb27SDimitry Andric } 11190b57cec5SDimitry Andric 1120bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 112106c3fb27SDimitry Andric basic_string(const basic_string& __str, size_type __pos, size_type __n, const _Allocator& __a = _Allocator()) 112206c3fb27SDimitry Andric : __r_(__default_init_tag(), __a) { 112306c3fb27SDimitry Andric size_type __str_sz = __str.size(); 112406c3fb27SDimitry Andric if (__pos > __str_sz) 112506c3fb27SDimitry Andric __throw_out_of_range(); 112606c3fb27SDimitry Andric __init(__str.data() + __pos, std::min(__n, __str_sz - __pos)); 112706c3fb27SDimitry Andric } 11280b57cec5SDimitry Andric 1129bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 1130bdd1243dSDimitry Andric basic_string(const basic_string& __str, size_type __pos, const _Allocator& __a = _Allocator()) 1131bdd1243dSDimitry Andric : __r_(__default_init_tag(), __a) { 1132bdd1243dSDimitry Andric size_type __str_sz = __str.size(); 1133bdd1243dSDimitry Andric if (__pos > __str_sz) 1134bdd1243dSDimitry Andric __throw_out_of_range(); 1135bdd1243dSDimitry Andric __init(__str.data() + __pos, __str_sz - __pos); 1136bdd1243dSDimitry Andric } 11370b57cec5SDimitry Andric 1138bdd1243dSDimitry Andric template <class _Tp, 113906c3fb27SDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 114006c3fb27SDimitry Andric !__is_same_uncvref<_Tp, basic_string>::value, 114106c3fb27SDimitry Andric int> = 0> 1142bdd1243dSDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 114306c3fb27SDimitry Andric basic_string(const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a = allocator_type()) 114406c3fb27SDimitry Andric : __r_(__default_init_tag(), __a) { 114506c3fb27SDimitry Andric __self_view __sv0 = __t; 114606c3fb27SDimitry Andric __self_view __sv = __sv0.substr(__pos, __n); 114706c3fb27SDimitry Andric __init(__sv.data(), __sv.size()); 114806c3fb27SDimitry Andric } 11490b57cec5SDimitry Andric 1150bdd1243dSDimitry Andric template <class _Tp, 115106c3fb27SDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 115206c3fb27SDimitry Andric !__is_same_uncvref<_Tp, basic_string>::value, 115306c3fb27SDimitry Andric int> = 0> 115406c3fb27SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(const _Tp& __t) 115506c3fb27SDimitry Andric : __r_(__default_init_tag(), __default_init_tag()) { 115606c3fb27SDimitry Andric __self_view __sv = __t; 115706c3fb27SDimitry Andric __init(__sv.data(), __sv.size()); 115806c3fb27SDimitry Andric } 1159bdd1243dSDimitry Andric 1160bdd1243dSDimitry Andric template <class _Tp, 116106c3fb27SDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 116206c3fb27SDimitry Andric !__is_same_uncvref<_Tp, basic_string>::value, 116306c3fb27SDimitry Andric int> = 0> 11640fca6ea1SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 11650fca6ea1SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(const _Tp& __t, const allocator_type& __a) 116606c3fb27SDimitry Andric : __r_(__default_init_tag(), __a) { 116706c3fb27SDimitry Andric __self_view __sv = __t; 116806c3fb27SDimitry Andric __init(__sv.data(), __sv.size()); 116906c3fb27SDimitry Andric } 11700b57cec5SDimitry Andric 117106c3fb27SDimitry Andric template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0> 1172bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(_InputIterator __first, _InputIterator __last) 1173bdd1243dSDimitry Andric : __r_(__default_init_tag(), __default_init_tag()) { 1174bdd1243dSDimitry Andric __init(__first, __last); 1175bdd1243dSDimitry Andric } 1176bdd1243dSDimitry Andric 117706c3fb27SDimitry Andric template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0> 1178bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 1179bdd1243dSDimitry Andric basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a) 1180bdd1243dSDimitry Andric : __r_(__default_init_tag(), __a) { 1181bdd1243dSDimitry Andric __init(__first, __last); 1182bdd1243dSDimitry Andric } 1183bdd1243dSDimitry Andric 118406c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 118506c3fb27SDimitry Andric template <_ContainerCompatibleRange<_CharT> _Range> 1186cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr basic_string( 1187cb14a3feSDimitry Andric from_range_t, _Range&& __range, const allocator_type& __a = allocator_type()) 118806c3fb27SDimitry Andric : __r_(__default_init_tag(), __a) { 118906c3fb27SDimitry Andric if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { 119006c3fb27SDimitry Andric __init_with_size(ranges::begin(__range), ranges::end(__range), ranges::distance(__range)); 119106c3fb27SDimitry Andric } else { 119206c3fb27SDimitry Andric __init_with_sentinel(ranges::begin(__range), ranges::end(__range)); 119306c3fb27SDimitry Andric } 119406c3fb27SDimitry Andric } 119506c3fb27SDimitry Andric#endif 119606c3fb27SDimitry Andric 11970b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 1198bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(initializer_list<_CharT> __il) 1199bdd1243dSDimitry Andric : __r_(__default_init_tag(), __default_init_tag()) { 1200bdd1243dSDimitry Andric __init(__il.begin(), __il.end()); 1201bdd1243dSDimitry Andric } 1202bdd1243dSDimitry Andric 1203bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(initializer_list<_CharT> __il, const _Allocator& __a) 1204bdd1243dSDimitry Andric : __r_(__default_init_tag(), __a) { 1205bdd1243dSDimitry Andric __init(__il.begin(), __il.end()); 1206bdd1243dSDimitry Andric } 12070b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 12080b57cec5SDimitry Andric 120906c3fb27SDimitry Andric inline _LIBCPP_CONSTEXPR_SINCE_CXX20 ~basic_string() { 12105f757f3fSDimitry Andric __annotate_delete(); 121106c3fb27SDimitry Andric if (__is_long()) 121206c3fb27SDimitry Andric __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 121306c3fb27SDimitry Andric } 12140b57cec5SDimitry Andric 1215cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 operator __self_view() const _NOEXCEPT { 1216cb14a3feSDimitry Andric return __self_view(data(), size()); 1217cb14a3feSDimitry Andric } 12180b57cec5SDimitry Andric 1219cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS basic_string& 1220cb14a3feSDimitry Andric operator=(const basic_string& __str); 12210b57cec5SDimitry Andric 1222cb14a3feSDimitry Andric template <class _Tp, 1223cb14a3feSDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 1224cb14a3feSDimitry Andric !__is_same_uncvref<_Tp, basic_string>::value, 1225cb14a3feSDimitry Andric int> = 0> 1226bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(const _Tp& __t) { 122781ad6265SDimitry Andric __self_view __sv = __t; 122881ad6265SDimitry Andric return assign(__sv); 122981ad6265SDimitry Andric } 12300b57cec5SDimitry Andric 12310b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 12320fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 12330fca6ea1SDimitry Andric operator=(basic_string&& __str) noexcept(__noexcept_move_assign_container<_Allocator, __alloc_traits>::value) { 1234bdd1243dSDimitry Andric __move_assign(__str, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>()); 1235bdd1243dSDimitry Andric return *this; 1236bdd1243dSDimitry Andric } 1237bdd1243dSDimitry Andric 1238cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(initializer_list<value_type> __il) { 1239cb14a3feSDimitry Andric return assign(__il.begin(), __il.size()); 1240cb14a3feSDimitry Andric } 12410b57cec5SDimitry Andric#endif 1242cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(const value_type* __s) { 1243cb14a3feSDimitry Andric return assign(__s); 1244cb14a3feSDimitry Andric } 124506c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 1246fe6060f1SDimitry Andric basic_string& operator=(nullptr_t) = delete; 1247fe6060f1SDimitry Andric#endif 12480fca6ea1SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(value_type __c); 12490b57cec5SDimitry Andric 1250cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator begin() _NOEXCEPT { 1251cb14a3feSDimitry Andric return __make_iterator(__get_pointer()); 1252cb14a3feSDimitry Andric } 1253cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator begin() const _NOEXCEPT { 1254cb14a3feSDimitry Andric return __make_const_iterator(__get_pointer()); 1255cb14a3feSDimitry Andric } 1256cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator end() _NOEXCEPT { 1257cb14a3feSDimitry Andric return __make_iterator(__get_pointer() + size()); 1258cb14a3feSDimitry Andric } 1259cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator end() const _NOEXCEPT { 1260cb14a3feSDimitry Andric return __make_const_iterator(__get_pointer() + size()); 1261cb14a3feSDimitry Andric } 126281ad6265SDimitry Andric 1263cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reverse_iterator rbegin() _NOEXCEPT { 1264cb14a3feSDimitry Andric return reverse_iterator(end()); 1265cb14a3feSDimitry Andric } 1266cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator rbegin() const _NOEXCEPT { 1267cb14a3feSDimitry Andric return const_reverse_iterator(end()); 1268cb14a3feSDimitry Andric } 1269cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reverse_iterator rend() _NOEXCEPT { 1270cb14a3feSDimitry Andric return reverse_iterator(begin()); 1271cb14a3feSDimitry Andric } 1272cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator rend() const _NOEXCEPT { 1273cb14a3feSDimitry Andric return const_reverse_iterator(begin()); 1274cb14a3feSDimitry Andric } 12750b57cec5SDimitry Andric 1276cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator cbegin() const _NOEXCEPT { return begin(); } 1277cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator cend() const _NOEXCEPT { return end(); } 1278cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator crbegin() const _NOEXCEPT { 1279cb14a3feSDimitry Andric return rbegin(); 1280cb14a3feSDimitry Andric } 1281cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator crend() const _NOEXCEPT { return rend(); } 12820b57cec5SDimitry Andric 1283cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type size() const _NOEXCEPT { 1284cb14a3feSDimitry Andric return __is_long() ? __get_long_size() : __get_short_size(); 1285cb14a3feSDimitry Andric } 1286bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type length() const _NOEXCEPT { return size(); } 1287bdd1243dSDimitry Andric 1288bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type max_size() const _NOEXCEPT { 1289bdd1243dSDimitry Andric size_type __m = __alloc_traits::max_size(__alloc()); 1290bdd1243dSDimitry Andric if (__m <= std::numeric_limits<size_type>::max() / 2) { 1291bdd1243dSDimitry Andric return __m - __alignment; 1292bdd1243dSDimitry Andric } else { 1293bdd1243dSDimitry Andric bool __uses_lsb = __endian_factor == 2; 1294bdd1243dSDimitry Andric return __uses_lsb ? __m - __alignment : (__m / 2) - __alignment; 1295bdd1243dSDimitry Andric } 1296bdd1243dSDimitry Andric } 1297bdd1243dSDimitry Andric 1298bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type capacity() const _NOEXCEPT { 129981ad6265SDimitry Andric return (__is_long() ? __get_long_cap() : static_cast<size_type>(__min_cap)) - 1; 130081ad6265SDimitry Andric } 13010b57cec5SDimitry Andric 1302bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 void resize(size_type __n, value_type __c); 1303bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void resize(size_type __n) { resize(__n, value_type()); } 13040b57cec5SDimitry Andric 1305bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 void reserve(size_type __requested_capacity); 130604eeddc0SDimitry Andric 130706c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 130804eeddc0SDimitry Andric template <class _Op> 1309cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr void resize_and_overwrite(size_type __n, _Op __op) { 131004eeddc0SDimitry Andric __resize_default_init(__n); 131181ad6265SDimitry Andric __erase_to_end(std::move(__op)(data(), _LIBCPP_AUTO_CAST(__n))); 131204eeddc0SDimitry Andric } 131304eeddc0SDimitry Andric#endif 131404eeddc0SDimitry Andric 1315bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __resize_default_init(size_type __n); 13160b57cec5SDimitry Andric 13175f757f3fSDimitry Andric#if _LIBCPP_STD_VER < 26 || defined(_LIBCPP_ENABLE_CXX26_REMOVED_STRING_RESERVE) 131881ad6265SDimitry Andric _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI void reserve() _NOEXCEPT { shrink_to_fit(); } 13195f757f3fSDimitry Andric#endif 1320bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void shrink_to_fit() _NOEXCEPT; 1321bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void clear() _NOEXCEPT; 132281ad6265SDimitry Andric 13230fca6ea1SDimitry Andric _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool empty() const _NOEXCEPT { 1324cb14a3feSDimitry Andric return size() == 0; 1325cb14a3feSDimitry Andric } 13260b57cec5SDimitry Andric 1327bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference operator[](size_type __pos) const _NOEXCEPT { 132806c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos <= size(), "string index out of bounds"); 13295f757f3fSDimitry Andric if (__builtin_constant_p(__pos) && !__fits_in_sso(__pos)) { 13305f757f3fSDimitry Andric return *(__get_long_pointer() + __pos); 13315f757f3fSDimitry Andric } 1332bdd1243dSDimitry Andric return *(data() + __pos); 1333bdd1243dSDimitry Andric } 13340b57cec5SDimitry Andric 1335bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](size_type __pos) _NOEXCEPT { 133606c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos <= size(), "string index out of bounds"); 13375f757f3fSDimitry Andric if (__builtin_constant_p(__pos) && !__fits_in_sso(__pos)) { 13385f757f3fSDimitry Andric return *(__get_long_pointer() + __pos); 13395f757f3fSDimitry Andric } 1340bdd1243dSDimitry Andric return *(__get_pointer() + __pos); 1341bdd1243dSDimitry Andric } 13420b57cec5SDimitry Andric 1343bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference at(size_type __n) const; 1344bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 reference at(size_type __n); 1345bdd1243dSDimitry Andric 1346bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator+=(const basic_string& __str) { 134781ad6265SDimitry Andric return append(__str); 134881ad6265SDimitry Andric } 13490b57cec5SDimitry Andric 135006c3fb27SDimitry Andric template <class _Tp, 135106c3fb27SDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 135206c3fb27SDimitry Andric !__is_same_uncvref<_Tp, basic_string >::value, 135306c3fb27SDimitry Andric int> = 0> 135406c3fb27SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 135581ad6265SDimitry Andric operator+=(const _Tp& __t) { 1356cb14a3feSDimitry Andric __self_view __sv = __t; 1357cb14a3feSDimitry Andric return append(__sv); 135881ad6265SDimitry Andric } 135981ad6265SDimitry Andric 1360bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator+=(const value_type* __s) { 136181ad6265SDimitry Andric return append(__s); 136281ad6265SDimitry Andric } 136381ad6265SDimitry Andric 1364bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator+=(value_type __c) { 136581ad6265SDimitry Andric push_back(__c); 136681ad6265SDimitry Andric return *this; 136781ad6265SDimitry Andric } 136881ad6265SDimitry Andric 13690b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 1370cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator+=(initializer_list<value_type> __il) { 1371cb14a3feSDimitry Andric return append(__il); 1372cb14a3feSDimitry Andric } 13730b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 13740b57cec5SDimitry Andric 1375bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const basic_string& __str) { 1376bdd1243dSDimitry Andric return append(__str.data(), __str.size()); 1377bdd1243dSDimitry Andric } 13780b57cec5SDimitry Andric 137906c3fb27SDimitry Andric template <class _Tp, 138006c3fb27SDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 138106c3fb27SDimitry Andric !__is_same_uncvref<_Tp, basic_string>::value, 138206c3fb27SDimitry Andric int> = 0> 138306c3fb27SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 138406c3fb27SDimitry Andric append(const _Tp& __t) { 138506c3fb27SDimitry Andric __self_view __sv = __t; 138606c3fb27SDimitry Andric return append(__sv.data(), __sv.size()); 138706c3fb27SDimitry Andric } 138806c3fb27SDimitry Andric 1389bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const basic_string& __str, size_type __pos, size_type __n = npos); 13900b57cec5SDimitry Andric 139106c3fb27SDimitry Andric template <class _Tp, 139206c3fb27SDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 139306c3fb27SDimitry Andric !__is_same_uncvref<_Tp, basic_string>::value, 139406c3fb27SDimitry Andric int> = 0> 1395bdd1243dSDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 139606c3fb27SDimitry Andric 13970b57cec5SDimitry Andric basic_string& 13980b57cec5SDimitry Andric append(const _Tp& __t, size_type __pos, size_type __n = npos); 139906c3fb27SDimitry Andric 1400bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const value_type* __s, size_type __n); 1401bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const value_type* __s); 1402bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(size_type __n, value_type __c); 14030b57cec5SDimitry Andric 1404cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __append_default_init(size_type __n); 14050b57cec5SDimitry Andric 140606c3fb27SDimitry Andric template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0> 140706c3fb27SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 14080b57cec5SDimitry Andric append(_InputIterator __first, _InputIterator __last) { 14090b57cec5SDimitry Andric const basic_string __temp(__first, __last, __alloc()); 14100b57cec5SDimitry Andric append(__temp.data(), __temp.size()); 14110b57cec5SDimitry Andric return *this; 14120b57cec5SDimitry Andric } 141306c3fb27SDimitry Andric 141406c3fb27SDimitry Andric template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0> 141506c3fb27SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 1416fe6060f1SDimitry Andric append(_ForwardIterator __first, _ForwardIterator __last); 14170b57cec5SDimitry Andric 141806c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 141906c3fb27SDimitry Andric template <_ContainerCompatibleRange<_CharT> _Range> 1420cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr basic_string& append_range(_Range&& __range) { 142106c3fb27SDimitry Andric insert_range(end(), std::forward<_Range>(__range)); 142206c3fb27SDimitry Andric return *this; 142306c3fb27SDimitry Andric } 142406c3fb27SDimitry Andric#endif 142506c3fb27SDimitry Andric 14260b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 1427cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(initializer_list<value_type> __il) { 1428cb14a3feSDimitry Andric return append(__il.begin(), __il.size()); 1429cb14a3feSDimitry Andric } 14300b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 14310b57cec5SDimitry Andric 1432bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 void push_back(value_type __c); 1433bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void pop_back(); 1434bdd1243dSDimitry Andric 1435bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference front() _NOEXCEPT { 143606c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::front(): string is empty"); 1437bdd1243dSDimitry Andric return *__get_pointer(); 1438bdd1243dSDimitry Andric } 1439bdd1243dSDimitry Andric 1440bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference front() const _NOEXCEPT { 144106c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::front(): string is empty"); 1442bdd1243dSDimitry Andric return *data(); 1443bdd1243dSDimitry Andric } 1444bdd1243dSDimitry Andric 1445bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference back() _NOEXCEPT { 144606c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::back(): string is empty"); 1447bdd1243dSDimitry Andric return *(__get_pointer() + size() - 1); 1448bdd1243dSDimitry Andric } 1449bdd1243dSDimitry Andric 1450bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference back() const _NOEXCEPT { 145106c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::back(): string is empty"); 1452bdd1243dSDimitry Andric return *(data() + size() - 1); 1453bdd1243dSDimitry Andric } 14540b57cec5SDimitry Andric 145506c3fb27SDimitry Andric template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 145606c3fb27SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 145706c3fb27SDimitry Andric assign(const _Tp& __t) { 145806c3fb27SDimitry Andric __self_view __sv = __t; 145906c3fb27SDimitry Andric return assign(__sv.data(), __sv.size()); 146006c3fb27SDimitry Andric } 146106c3fb27SDimitry Andric 14625f757f3fSDimitry Andric#if _LIBCPP_STD_VER >= 20 1463cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr void __move_assign(basic_string&& __str, size_type __pos, size_type __len) { 14645f757f3fSDimitry Andric // Pilfer the allocation from __str. 14655f757f3fSDimitry Andric _LIBCPP_ASSERT_INTERNAL(__alloc() == __str.__alloc(), "__move_assign called with wrong allocator"); 14665f757f3fSDimitry Andric size_type __old_sz = __str.size(); 14675f757f3fSDimitry Andric if (!__str.__is_long()) 14685f757f3fSDimitry Andric __str.__annotate_delete(); 14695f757f3fSDimitry Andric __r_.first() = __str.__r_.first(); 14705f757f3fSDimitry Andric __str.__r_.first() = __rep(); 14715f757f3fSDimitry Andric __str.__annotate_new(0); 14725f757f3fSDimitry Andric 14735f757f3fSDimitry Andric _Traits::move(data(), data() + __pos, __len); 14745f757f3fSDimitry Andric __set_size(__len); 14755f757f3fSDimitry Andric _Traits::assign(data()[__len], value_type()); 14765f757f3fSDimitry Andric 14775f757f3fSDimitry Andric if (!__is_long()) { 14785f757f3fSDimitry Andric __annotate_new(__len); 14795f757f3fSDimitry Andric } else if (__old_sz > __len) { 14805f757f3fSDimitry Andric __annotate_shrink(__old_sz); 14815f757f3fSDimitry Andric } 14825f757f3fSDimitry Andric } 14835f757f3fSDimitry Andric#endif 14845f757f3fSDimitry Andric 1485cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const basic_string& __str) { 1486cb14a3feSDimitry Andric return *this = __str; 1487cb14a3feSDimitry Andric } 14880b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 14890fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 14900fca6ea1SDimitry Andric assign(basic_string&& __str) noexcept(__noexcept_move_assign_container<_Allocator, __alloc_traits>::value) { 1491cb14a3feSDimitry Andric *this = std::move(__str); 1492cb14a3feSDimitry Andric return *this; 1493cb14a3feSDimitry Andric } 14940b57cec5SDimitry Andric#endif 1495bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const basic_string& __str, size_type __pos, size_type __n = npos); 149606c3fb27SDimitry Andric 149706c3fb27SDimitry Andric template <class _Tp, 149806c3fb27SDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 149906c3fb27SDimitry Andric !__is_same_uncvref<_Tp, basic_string>::value, 150006c3fb27SDimitry Andric int> = 0> 150106c3fb27SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 15020b57cec5SDimitry Andric assign(const _Tp& __t, size_type __pos, size_type __n = npos); 150306c3fb27SDimitry Andric 1504bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const value_type* __s, size_type __n); 1505bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const value_type* __s); 1506bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(size_type __n, value_type __c); 150706c3fb27SDimitry Andric template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0> 150806c3fb27SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 15090b57cec5SDimitry Andric assign(_InputIterator __first, _InputIterator __last); 151006c3fb27SDimitry Andric 151106c3fb27SDimitry Andric template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0> 151206c3fb27SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 15130b57cec5SDimitry Andric assign(_ForwardIterator __first, _ForwardIterator __last); 151406c3fb27SDimitry Andric 151506c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 151606c3fb27SDimitry Andric template <_ContainerCompatibleRange<_CharT> _Range> 1517cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr basic_string& assign_range(_Range&& __range) { 151806c3fb27SDimitry Andric if constexpr (__string_is_trivial_iterator<ranges::iterator_t<_Range>>::value && 151906c3fb27SDimitry Andric (ranges::forward_range<_Range> || ranges::sized_range<_Range>)) { 152006c3fb27SDimitry Andric size_type __n = static_cast<size_type>(ranges::distance(__range)); 152106c3fb27SDimitry Andric __assign_trivial(ranges::begin(__range), ranges::end(__range), __n); 152206c3fb27SDimitry Andric 152306c3fb27SDimitry Andric } else { 152406c3fb27SDimitry Andric __assign_with_sentinel(ranges::begin(__range), ranges::end(__range)); 152506c3fb27SDimitry Andric } 152606c3fb27SDimitry Andric 152706c3fb27SDimitry Andric return *this; 152806c3fb27SDimitry Andric } 152906c3fb27SDimitry Andric#endif 153006c3fb27SDimitry Andric 15310b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 1532cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(initializer_list<value_type> __il) { 1533cb14a3feSDimitry Andric return assign(__il.begin(), __il.size()); 1534cb14a3feSDimitry Andric } 15350b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 15360b57cec5SDimitry Andric 1537bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 1538bdd1243dSDimitry Andric insert(size_type __pos1, const basic_string& __str) { 1539bdd1243dSDimitry Andric return insert(__pos1, __str.data(), __str.size()); 1540bdd1243dSDimitry Andric } 15410b57cec5SDimitry Andric 154206c3fb27SDimitry Andric template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 154306c3fb27SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 154406c3fb27SDimitry Andric insert(size_type __pos1, const _Tp& __t) { 154506c3fb27SDimitry Andric __self_view __sv = __t; 154606c3fb27SDimitry Andric return insert(__pos1, __sv.data(), __sv.size()); 154706c3fb27SDimitry Andric } 15480b57cec5SDimitry Andric 154906c3fb27SDimitry Andric template <class _Tp, 155006c3fb27SDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 155106c3fb27SDimitry Andric !__is_same_uncvref<_Tp, basic_string>::value, 155206c3fb27SDimitry Andric int> = 0> 155306c3fb27SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 15540b57cec5SDimitry Andric insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n = npos); 155506c3fb27SDimitry Andric 155606c3fb27SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 155706c3fb27SDimitry Andric insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n = npos); 1558bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* __s, size_type __n); 1559bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* __s); 1560bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, size_type __n, value_type __c); 1561bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator insert(const_iterator __pos, value_type __c); 1562bdd1243dSDimitry Andric 156306c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 156406c3fb27SDimitry Andric template <_ContainerCompatibleRange<_CharT> _Range> 1565cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr iterator insert_range(const_iterator __position, _Range&& __range) { 156606c3fb27SDimitry Andric if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { 156706c3fb27SDimitry Andric auto __n = static_cast<size_type>(ranges::distance(__range)); 156806c3fb27SDimitry Andric return __insert_with_size(__position, ranges::begin(__range), ranges::end(__range), __n); 156906c3fb27SDimitry Andric 157006c3fb27SDimitry Andric } else { 157106c3fb27SDimitry Andric basic_string __temp(from_range, std::forward<_Range>(__range), __alloc()); 157206c3fb27SDimitry Andric return insert(__position, __temp.data(), __temp.data() + __temp.size()); 157306c3fb27SDimitry Andric } 157406c3fb27SDimitry Andric } 157506c3fb27SDimitry Andric#endif 157606c3fb27SDimitry Andric 1577bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator 1578bdd1243dSDimitry Andric insert(const_iterator __pos, size_type __n, value_type __c) { 1579bdd1243dSDimitry Andric difference_type __p = __pos - begin(); 1580bdd1243dSDimitry Andric insert(static_cast<size_type>(__p), __n, __c); 1581bdd1243dSDimitry Andric return begin() + __p; 1582bdd1243dSDimitry Andric } 1583bdd1243dSDimitry Andric 158406c3fb27SDimitry Andric template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0> 158506c3fb27SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator 15860b57cec5SDimitry Andric insert(const_iterator __pos, _InputIterator __first, _InputIterator __last); 158706c3fb27SDimitry Andric 158806c3fb27SDimitry Andric template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0> 158906c3fb27SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator 15900b57cec5SDimitry Andric insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last); 159106c3fb27SDimitry Andric 15920b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 1593cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator 1594cb14a3feSDimitry Andric insert(const_iterator __pos, initializer_list<value_type> __il) { 1595cb14a3feSDimitry Andric return insert(__pos, __il.begin(), __il.end()); 1596cb14a3feSDimitry Andric } 15970b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 15980b57cec5SDimitry Andric 1599bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& erase(size_type __pos = 0, size_type __n = npos); 1600cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator erase(const_iterator __pos); 1601cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator erase(const_iterator __first, const_iterator __last); 16020b57cec5SDimitry Andric 1603bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 1604bdd1243dSDimitry Andric replace(size_type __pos1, size_type __n1, const basic_string& __str) { 1605bdd1243dSDimitry Andric return replace(__pos1, __n1, __str.data(), __str.size()); 1606bdd1243dSDimitry Andric } 16070b57cec5SDimitry Andric 160806c3fb27SDimitry Andric template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 160906c3fb27SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 161006c3fb27SDimitry Andric replace(size_type __pos1, size_type __n1, const _Tp& __t) { 161106c3fb27SDimitry Andric __self_view __sv = __t; 161206c3fb27SDimitry Andric return replace(__pos1, __n1, __sv.data(), __sv.size()); 161306c3fb27SDimitry Andric } 161406c3fb27SDimitry Andric 161506c3fb27SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 161606c3fb27SDimitry Andric replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2 = npos); 161706c3fb27SDimitry Andric 161806c3fb27SDimitry Andric template <class _Tp, 161906c3fb27SDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 162006c3fb27SDimitry Andric !__is_same_uncvref<_Tp, basic_string>::value, 162106c3fb27SDimitry Andric int> = 0> 162206c3fb27SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 16230b57cec5SDimitry Andric replace(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2 = npos); 162406c3fb27SDimitry Andric 162506c3fb27SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 162606c3fb27SDimitry Andric replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2); 1627bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& replace(size_type __pos, size_type __n1, const value_type* __s); 1628bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c); 1629bdd1243dSDimitry Andric 1630bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 1631bdd1243dSDimitry Andric replace(const_iterator __i1, const_iterator __i2, const basic_string& __str) { 1632bdd1243dSDimitry Andric return replace( 1633bdd1243dSDimitry Andric static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __str.data(), __str.size()); 1634bdd1243dSDimitry Andric } 16350b57cec5SDimitry Andric 163606c3fb27SDimitry Andric template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 163706c3fb27SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 163806c3fb27SDimitry Andric replace(const_iterator __i1, const_iterator __i2, const _Tp& __t) { 163906c3fb27SDimitry Andric __self_view __sv = __t; 164006c3fb27SDimitry Andric return replace(__i1 - begin(), __i2 - __i1, __sv); 164106c3fb27SDimitry Andric } 16420b57cec5SDimitry Andric 1643bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 1644bdd1243dSDimitry Andric replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n) { 1645bdd1243dSDimitry Andric return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s, __n); 1646bdd1243dSDimitry Andric } 1647bdd1243dSDimitry Andric 1648bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 1649bdd1243dSDimitry Andric replace(const_iterator __i1, const_iterator __i2, const value_type* __s) { 1650bdd1243dSDimitry Andric return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s); 1651bdd1243dSDimitry Andric } 1652bdd1243dSDimitry Andric 1653bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 1654bdd1243dSDimitry Andric replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c) { 1655bdd1243dSDimitry Andric return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __n, __c); 1656bdd1243dSDimitry Andric } 1657bdd1243dSDimitry Andric 165806c3fb27SDimitry Andric template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0> 165906c3fb27SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 16600b57cec5SDimitry Andric replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2); 166106c3fb27SDimitry Andric 166206c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 166306c3fb27SDimitry Andric template <_ContainerCompatibleRange<_CharT> _Range> 1664cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr basic_string& 1665cb14a3feSDimitry Andric replace_with_range(const_iterator __i1, const_iterator __i2, _Range&& __range) { 166606c3fb27SDimitry Andric basic_string __temp(from_range, std::forward<_Range>(__range), __alloc()); 166706c3fb27SDimitry Andric return replace(__i1, __i2, __temp); 166806c3fb27SDimitry Andric } 166906c3fb27SDimitry Andric#endif 167006c3fb27SDimitry Andric 16710b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 1672cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 1673cb14a3feSDimitry Andric replace(const_iterator __i1, const_iterator __i2, initializer_list<value_type> __il) { 1674cb14a3feSDimitry Andric return replace(__i1, __i2, __il.begin(), __il.end()); 1675cb14a3feSDimitry Andric } 16760b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 16770b57cec5SDimitry Andric 1678bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type copy(value_type* __s, size_type __n, size_type __pos = 0) const; 16790b57cec5SDimitry Andric 1680bdd1243dSDimitry Andric#if _LIBCPP_STD_VER <= 20 1681cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string 1682cb14a3feSDimitry Andric substr(size_type __pos = 0, size_type __n = npos) const { 1683bdd1243dSDimitry Andric return basic_string(*this, __pos, __n); 1684bdd1243dSDimitry Andric } 1685bdd1243dSDimitry Andric#else 1686cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr basic_string substr(size_type __pos = 0, size_type __n = npos) const& { 1687bdd1243dSDimitry Andric return basic_string(*this, __pos, __n); 1688bdd1243dSDimitry Andric } 1689bdd1243dSDimitry Andric 1690cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr basic_string substr(size_type __pos = 0, size_type __n = npos) && { 1691bdd1243dSDimitry Andric return basic_string(std::move(*this), __pos, __n); 1692bdd1243dSDimitry Andric } 1693bdd1243dSDimitry Andric#endif 1694bdd1243dSDimitry Andric 1695cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(basic_string& __str) 16960b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14 16970b57cec5SDimitry Andric _NOEXCEPT; 16980b57cec5SDimitry Andric#else 16990fca6ea1SDimitry Andric _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>); 17000b57cec5SDimitry Andric#endif 17010b57cec5SDimitry Andric 1702cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const value_type* c_str() const _NOEXCEPT { return data(); } 1703cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const value_type* data() const _NOEXCEPT { 1704cb14a3feSDimitry Andric return std::__to_address(__get_pointer()); 1705cb14a3feSDimitry Andric } 170606c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17 1707cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 value_type* data() _NOEXCEPT { 1708cb14a3feSDimitry Andric return std::__to_address(__get_pointer()); 1709cb14a3feSDimitry Andric } 17100b57cec5SDimitry Andric#endif 17110b57cec5SDimitry Andric 1712cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 allocator_type get_allocator() const _NOEXCEPT { 1713cb14a3feSDimitry Andric return __alloc(); 1714cb14a3feSDimitry Andric } 17150b57cec5SDimitry Andric 1716cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1717cb14a3feSDimitry Andric find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; 17180b57cec5SDimitry Andric 171906c3fb27SDimitry Andric template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 172006c3fb27SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1721fe6060f1SDimitry Andric find(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT; 172206c3fb27SDimitry Andric 172306c3fb27SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; 1724cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1725cb14a3feSDimitry Andric find(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; 1726bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT; 17270b57cec5SDimitry Andric 1728cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1729cb14a3feSDimitry Andric rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; 17300b57cec5SDimitry Andric 173106c3fb27SDimitry Andric template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 173206c3fb27SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1733fe6060f1SDimitry Andric rfind(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT; 173406c3fb27SDimitry Andric 1735cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; 1736cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1737cb14a3feSDimitry Andric rfind(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; 1738bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type rfind(value_type __c, size_type __pos = npos) const _NOEXCEPT; 17390b57cec5SDimitry Andric 1740cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1741cb14a3feSDimitry Andric find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; 17420b57cec5SDimitry Andric 174306c3fb27SDimitry Andric template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 174406c3fb27SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1745fe6060f1SDimitry Andric find_first_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT; 174606c3fb27SDimitry Andric 1747cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1748cb14a3feSDimitry Andric find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; 1749cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1750cb14a3feSDimitry Andric find_first_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; 1751cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1752cb14a3feSDimitry Andric find_first_of(value_type __c, size_type __pos = 0) const _NOEXCEPT; 17530b57cec5SDimitry Andric 1754cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1755cb14a3feSDimitry Andric find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; 17560b57cec5SDimitry Andric 175706c3fb27SDimitry Andric template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 175806c3fb27SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1759fe6060f1SDimitry Andric find_last_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT; 176006c3fb27SDimitry Andric 1761cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1762cb14a3feSDimitry Andric find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; 1763cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1764cb14a3feSDimitry Andric find_last_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; 1765cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1766cb14a3feSDimitry Andric find_last_of(value_type __c, size_type __pos = npos) const _NOEXCEPT; 17670b57cec5SDimitry Andric 1768cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1769cb14a3feSDimitry Andric find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; 17700b57cec5SDimitry Andric 177106c3fb27SDimitry Andric template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 177206c3fb27SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1773fe6060f1SDimitry Andric find_first_not_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT; 177406c3fb27SDimitry Andric 1775cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1776cb14a3feSDimitry Andric find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; 1777cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1778cb14a3feSDimitry Andric find_first_not_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; 1779cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1780cb14a3feSDimitry Andric find_first_not_of(value_type __c, size_type __pos = 0) const _NOEXCEPT; 17810b57cec5SDimitry Andric 1782cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1783cb14a3feSDimitry Andric find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; 17840b57cec5SDimitry Andric 178506c3fb27SDimitry Andric template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 178606c3fb27SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1787fe6060f1SDimitry Andric find_last_not_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT; 178806c3fb27SDimitry Andric 1789cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1790cb14a3feSDimitry Andric find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; 1791cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1792cb14a3feSDimitry Andric find_last_not_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; 1793cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1794cb14a3feSDimitry Andric find_last_not_of(value_type __c, size_type __pos = npos) const _NOEXCEPT; 17950b57cec5SDimitry Andric 1796cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(const basic_string& __str) const _NOEXCEPT; 17970b57cec5SDimitry Andric 179806c3fb27SDimitry Andric template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 179906c3fb27SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 int 1800fe6060f1SDimitry Andric compare(const _Tp& __t) const _NOEXCEPT; 18010b57cec5SDimitry Andric 180206c3fb27SDimitry Andric template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 180306c3fb27SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 int 18040b57cec5SDimitry Andric compare(size_type __pos1, size_type __n1, const _Tp& __t) const; 18050b57cec5SDimitry Andric 1806cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int 1807cb14a3feSDimitry Andric compare(size_type __pos1, size_type __n1, const basic_string& __str) const; 1808cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 int 1809cb14a3feSDimitry Andric compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2 = npos) const; 18100b57cec5SDimitry Andric 181106c3fb27SDimitry Andric template <class _Tp, 181206c3fb27SDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 181306c3fb27SDimitry Andric !__is_same_uncvref<_Tp, basic_string>::value, 181406c3fb27SDimitry Andric int> = 0> 181506c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int 18160b57cec5SDimitry Andric compare(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2 = npos) const; 181706c3fb27SDimitry Andric 1818bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(const value_type* __s) const _NOEXCEPT; 1819bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(size_type __pos1, size_type __n1, const value_type* __s) const; 1820cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 int 1821cb14a3feSDimitry Andric compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const; 18220b57cec5SDimitry Andric 182306c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 20 1824cb14a3feSDimitry Andric constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(__self_view __sv) const noexcept { 1825cb14a3feSDimitry Andric return __self_view(data(), size()).starts_with(__sv); 1826cb14a3feSDimitry Andric } 18270b57cec5SDimitry Andric 1828cb14a3feSDimitry Andric constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(value_type __c) const noexcept { 1829cb14a3feSDimitry Andric return !empty() && _Traits::eq(front(), __c); 1830cb14a3feSDimitry Andric } 18310b57cec5SDimitry Andric 1832cb14a3feSDimitry Andric constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(const value_type* __s) const noexcept { 1833cb14a3feSDimitry Andric return starts_with(__self_view(__s)); 1834cb14a3feSDimitry Andric } 18350b57cec5SDimitry Andric 1836cb14a3feSDimitry Andric constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(__self_view __sv) const noexcept { 1837cb14a3feSDimitry Andric return __self_view(data(), size()).ends_with(__sv); 1838cb14a3feSDimitry Andric } 18390b57cec5SDimitry Andric 1840cb14a3feSDimitry Andric constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(value_type __c) const noexcept { 1841cb14a3feSDimitry Andric return !empty() && _Traits::eq(back(), __c); 1842cb14a3feSDimitry Andric } 18430b57cec5SDimitry Andric 1844cb14a3feSDimitry Andric constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(const value_type* __s) const noexcept { 1845cb14a3feSDimitry Andric return ends_with(__self_view(__s)); 1846cb14a3feSDimitry Andric } 18470b57cec5SDimitry Andric#endif 18480b57cec5SDimitry Andric 184906c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 1850cb14a3feSDimitry Andric constexpr _LIBCPP_HIDE_FROM_ABI bool contains(__self_view __sv) const noexcept { 1851cb14a3feSDimitry Andric return __self_view(data(), size()).contains(__sv); 1852cb14a3feSDimitry Andric } 1853e8d8bef9SDimitry Andric 1854cb14a3feSDimitry Andric constexpr _LIBCPP_HIDE_FROM_ABI bool contains(value_type __c) const noexcept { 1855cb14a3feSDimitry Andric return __self_view(data(), size()).contains(__c); 1856cb14a3feSDimitry Andric } 1857e8d8bef9SDimitry Andric 1858cb14a3feSDimitry Andric constexpr _LIBCPP_HIDE_FROM_ABI bool contains(const value_type* __s) const { 1859cb14a3feSDimitry Andric return __self_view(data(), size()).contains(__s); 1860cb14a3feSDimitry Andric } 1861e8d8bef9SDimitry Andric#endif 1862e8d8bef9SDimitry Andric 1863bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __invariants() const; 18640b57cec5SDimitry Andric 1865bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __clear_and_shrink() _NOEXCEPT; 18660b57cec5SDimitry Andric 18670b57cec5SDimitry Andricprivate: 186881ad6265SDimitry Andric template <class _Alloc> 1869cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool friend 1870cb14a3feSDimitry Andric operator==(const basic_string<char, char_traits<char>, _Alloc>& __lhs, 187181ad6265SDimitry Andric const basic_string<char, char_traits<char>, _Alloc>& __rhs) _NOEXCEPT; 187281ad6265SDimitry Andric 1873bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __shrink_or_extend(size_type __target_capacity); 187481ad6265SDimitry Andric 1875cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS bool 1876cb14a3feSDimitry Andric __is_long() const _NOEXCEPT { 18775f757f3fSDimitry Andric if (__libcpp_is_constant_evaluated() && __builtin_constant_p(__r_.first().__l.__is_long_)) { 18785f757f3fSDimitry Andric return __r_.first().__l.__is_long_; 18795f757f3fSDimitry Andric } 188081ad6265SDimitry Andric return __r_.first().__s.__is_long_; 188181ad6265SDimitry Andric } 188281ad6265SDimitry Andric 1883bdd1243dSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __begin_lifetime(pointer __begin, size_type __n) { 188406c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 20 188581ad6265SDimitry Andric if (__libcpp_is_constant_evaluated()) { 188681ad6265SDimitry Andric for (size_type __i = 0; __i != __n; ++__i) 188781ad6265SDimitry Andric std::construct_at(std::addressof(__begin[__i])); 188881ad6265SDimitry Andric } 188981ad6265SDimitry Andric#else 189081ad6265SDimitry Andric (void)__begin; 189181ad6265SDimitry Andric (void)__n; 189206c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 20 189381ad6265SDimitry Andric } 189481ad6265SDimitry Andric 1895cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI static bool __fits_in_sso(size_type __sz) { return __sz < __min_cap; } 189604eeddc0SDimitry Andric 189706c3fb27SDimitry Andric template <class _Iterator, class _Sentinel> 1898cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void 1899cb14a3feSDimitry Andric __assign_trivial(_Iterator __first, _Sentinel __last, size_type __n); 190006c3fb27SDimitry Andric 190106c3fb27SDimitry Andric template <class _Iterator, class _Sentinel> 1902cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __assign_with_sentinel(_Iterator __first, _Sentinel __last); 190306c3fb27SDimitry Andric 19040fca6ea1SDimitry Andric // Copy [__first, __last) into [__dest, __dest + (__last - __first)). Assumes that the ranges don't overlap. 19050fca6ea1SDimitry Andric template <class _ForwardIter, class _Sent> 19060fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static value_type* 19070fca6ea1SDimitry Andric __copy_non_overlapping_range(_ForwardIter __first, _Sent __last, value_type* __dest) { 19080fca6ea1SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 19090fca6ea1SDimitry Andric if constexpr (__libcpp_is_contiguous_iterator<_ForwardIter>::value && 19100fca6ea1SDimitry Andric is_same<value_type, __iter_value_type<_ForwardIter>>::value && is_same<_ForwardIter, _Sent>::value) { 19110fca6ea1SDimitry Andric traits_type::copy(__dest, std::__to_address(__first), __last - __first); 19120fca6ea1SDimitry Andric return __dest + (__last - __first); 19130fca6ea1SDimitry Andric } 19140fca6ea1SDimitry Andric#endif 19150fca6ea1SDimitry Andric 19160fca6ea1SDimitry Andric for (; __first != __last; ++__first) 19170fca6ea1SDimitry Andric traits_type::assign(*__dest++, *__first); 19180fca6ea1SDimitry Andric return __dest; 19190fca6ea1SDimitry Andric } 19200fca6ea1SDimitry Andric 192106c3fb27SDimitry Andric template <class _ForwardIterator, class _Sentinel> 1922cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 iterator 1923cb14a3feSDimitry Andric __insert_from_safe_copy(size_type __n, size_type __ip, _ForwardIterator __first, _Sentinel __last) { 192481ad6265SDimitry Andric size_type __sz = size(); 192581ad6265SDimitry Andric size_type __cap = capacity(); 192681ad6265SDimitry Andric value_type* __p; 1927cb14a3feSDimitry Andric if (__cap - __sz >= __n) { 19285f757f3fSDimitry Andric __annotate_increase(__n); 192981ad6265SDimitry Andric __p = std::__to_address(__get_pointer()); 193081ad6265SDimitry Andric size_type __n_move = __sz - __ip; 193181ad6265SDimitry Andric if (__n_move != 0) 193281ad6265SDimitry Andric traits_type::move(__p + __ip + __n, __p + __ip, __n_move); 1933cb14a3feSDimitry Andric } else { 193406c3fb27SDimitry Andric __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __ip, 0, __n); 193581ad6265SDimitry Andric __p = std::__to_address(__get_long_pointer()); 193681ad6265SDimitry Andric } 193781ad6265SDimitry Andric __sz += __n; 193881ad6265SDimitry Andric __set_size(__sz); 193981ad6265SDimitry Andric traits_type::assign(__p[__sz], value_type()); 19400fca6ea1SDimitry Andric __copy_non_overlapping_range(__first, __last, __p + __ip); 19410b57cec5SDimitry Andric 194281ad6265SDimitry Andric return begin() + __ip; 194381ad6265SDimitry Andric } 19440b57cec5SDimitry Andric 194506c3fb27SDimitry Andric template <class _Iterator, class _Sentinel> 1946cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator 1947cb14a3feSDimitry Andric __insert_with_size(const_iterator __pos, _Iterator __first, _Sentinel __last, size_type __n); 194806c3fb27SDimitry Andric 1949bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 allocator_type& __alloc() _NOEXCEPT { return __r_.second(); } 195081ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const allocator_type& __alloc() const _NOEXCEPT { return __r_.second(); } 19510b57cec5SDimitry Andric 1952cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS void 1953cb14a3feSDimitry Andric __set_short_size(size_type __s) _NOEXCEPT { 1954cb14a3feSDimitry Andric _LIBCPP_ASSERT_INTERNAL(__s < __min_cap, "__s should never be greater than or equal to the short string capacity"); 195581ad6265SDimitry Andric __r_.first().__s.__size_ = __s; 195681ad6265SDimitry Andric __r_.first().__s.__is_long_ = false; 195781ad6265SDimitry Andric } 19580b57cec5SDimitry Andric 1959cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS size_type 1960cb14a3feSDimitry Andric __get_short_size() const _NOEXCEPT { 1961cb14a3feSDimitry Andric _LIBCPP_ASSERT_INTERNAL(!__r_.first().__s.__is_long_, "String has to be short when trying to get the short size"); 196281ad6265SDimitry Andric return __r_.first().__s.__size_; 196381ad6265SDimitry Andric } 19640b57cec5SDimitry Andric 1965cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __set_long_size(size_type __s) _NOEXCEPT { 1966cb14a3feSDimitry Andric __r_.first().__l.__size_ = __s; 1967cb14a3feSDimitry Andric } 1968cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __get_long_size() const _NOEXCEPT { 1969cb14a3feSDimitry Andric return __r_.first().__l.__size_; 1970cb14a3feSDimitry Andric } 1971cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __set_size(size_type __s) _NOEXCEPT { 1972cb14a3feSDimitry Andric if (__is_long()) 1973cb14a3feSDimitry Andric __set_long_size(__s); 1974cb14a3feSDimitry Andric else 1975cb14a3feSDimitry Andric __set_short_size(__s); 1976cb14a3feSDimitry Andric } 19770b57cec5SDimitry Andric 1978cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __set_long_cap(size_type __s) _NOEXCEPT { 197981ad6265SDimitry Andric __r_.first().__l.__cap_ = __s / __endian_factor; 198081ad6265SDimitry Andric __r_.first().__l.__is_long_ = true; 198181ad6265SDimitry Andric } 19820b57cec5SDimitry Andric 1983cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __get_long_cap() const _NOEXCEPT { 198481ad6265SDimitry Andric return __r_.first().__l.__cap_ * __endian_factor; 198581ad6265SDimitry Andric } 198681ad6265SDimitry Andric 1987cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __set_long_pointer(pointer __p) _NOEXCEPT { 1988cb14a3feSDimitry Andric __r_.first().__l.__data_ = __p; 1989cb14a3feSDimitry Andric } 1990cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pointer __get_long_pointer() _NOEXCEPT { 19910fca6ea1SDimitry Andric return _LIBCPP_ASAN_VOLATILE_WRAPPER(__r_.first().__l.__data_); 1992cb14a3feSDimitry Andric } 1993cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_pointer __get_long_pointer() const _NOEXCEPT { 19940fca6ea1SDimitry Andric return _LIBCPP_ASAN_VOLATILE_WRAPPER(__r_.first().__l.__data_); 1995cb14a3feSDimitry Andric } 19960fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS pointer 19970fca6ea1SDimitry Andric __get_short_pointer() _NOEXCEPT { 19980fca6ea1SDimitry Andric return _LIBCPP_ASAN_VOLATILE_WRAPPER(pointer_traits<pointer>::pointer_to(__r_.first().__s.__data_[0])); 1999cb14a3feSDimitry Andric } 20000fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS const_pointer 20010fca6ea1SDimitry Andric __get_short_pointer() const _NOEXCEPT { 20020fca6ea1SDimitry Andric return _LIBCPP_ASAN_VOLATILE_WRAPPER(pointer_traits<const_pointer>::pointer_to(__r_.first().__s.__data_[0])); 2003cb14a3feSDimitry Andric } 2004cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pointer __get_pointer() _NOEXCEPT { 2005cb14a3feSDimitry Andric return __is_long() ? __get_long_pointer() : __get_short_pointer(); 2006cb14a3feSDimitry Andric } 2007cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_pointer __get_pointer() const _NOEXCEPT { 2008cb14a3feSDimitry Andric return __is_long() ? __get_long_pointer() : __get_short_pointer(); 2009cb14a3feSDimitry Andric } 20100b57cec5SDimitry Andric 20115f757f3fSDimitry Andric // The following functions are no-ops outside of AddressSanitizer mode. 2012cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 2013cb14a3feSDimitry Andric __annotate_contiguous_container(const void* __old_mid, const void* __new_mid) const { 20145f757f3fSDimitry Andric (void)__old_mid; 20155f757f3fSDimitry Andric (void)__new_mid; 20165f757f3fSDimitry Andric#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN) 20170fca6ea1SDimitry Andric #if defined(__APPLE__) 20180fca6ea1SDimitry Andric // TODO: remove after addressing issue #96099 (https://github.com/llvm/llvm-project/issues/96099) 20190fca6ea1SDimitry Andric if(!__is_long()) 20200fca6ea1SDimitry Andric return; 20215f757f3fSDimitry Andric #endif 20220fca6ea1SDimitry Andric std::__annotate_contiguous_container<_Allocator>(data(), data() + capacity() + 1, __old_mid, __new_mid); 20230fca6ea1SDimitry Andric#endif 20245f757f3fSDimitry Andric } 20255f757f3fSDimitry Andric 20265f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __annotate_new(size_type __current_size) const _NOEXCEPT { 2027cb14a3feSDimitry Andric (void)__current_size; 2028cb14a3feSDimitry Andric#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN) 20290fca6ea1SDimitry Andric if (!__libcpp_is_constant_evaluated()) 20305f757f3fSDimitry Andric __annotate_contiguous_container(data() + capacity() + 1, data() + __current_size + 1); 2031cb14a3feSDimitry Andric#endif 20325f757f3fSDimitry Andric } 20335f757f3fSDimitry Andric 20345f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __annotate_delete() const _NOEXCEPT { 2035cb14a3feSDimitry Andric#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN) 20360fca6ea1SDimitry Andric if (!__libcpp_is_constant_evaluated()) 20375f757f3fSDimitry Andric __annotate_contiguous_container(data() + size() + 1, data() + capacity() + 1); 2038cb14a3feSDimitry Andric#endif 20395f757f3fSDimitry Andric } 20405f757f3fSDimitry Andric 20415f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __annotate_increase(size_type __n) const _NOEXCEPT { 2042cb14a3feSDimitry Andric (void)__n; 2043cb14a3feSDimitry Andric#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN) 20440fca6ea1SDimitry Andric if (!__libcpp_is_constant_evaluated()) 20455f757f3fSDimitry Andric __annotate_contiguous_container(data() + size() + 1, data() + size() + 1 + __n); 2046cb14a3feSDimitry Andric#endif 20475f757f3fSDimitry Andric } 20485f757f3fSDimitry Andric 20495f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __annotate_shrink(size_type __old_size) const _NOEXCEPT { 2050cb14a3feSDimitry Andric (void)__old_size; 2051cb14a3feSDimitry Andric#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN) 20520fca6ea1SDimitry Andric if (!__libcpp_is_constant_evaluated()) 20535f757f3fSDimitry Andric __annotate_contiguous_container(data() + __old_size + 1, data() + size() + 1); 2054cb14a3feSDimitry Andric#endif 20555f757f3fSDimitry Andric } 20565f757f3fSDimitry Andric 2057cb14a3feSDimitry Andric template <size_type __a> 2058cb14a3feSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __align_it(size_type __s) _NOEXCEPT { 2059cb14a3feSDimitry Andric return (__s + (__a - 1)) & ~(__a - 1); 2060cb14a3feSDimitry Andric } 20610fca6ea1SDimitry Andric enum { __alignment = 8 }; 2062cb14a3feSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __recommend(size_type __s) _NOEXCEPT { 206381ad6265SDimitry Andric if (__s < __min_cap) { 206481ad6265SDimitry Andric return static_cast<size_type>(__min_cap) - 1; 206581ad6265SDimitry Andric } 2066ead8e4c0SDimitry Andric const size_type __boundary = sizeof(value_type) < __alignment ? __alignment / sizeof(value_type) : __endian_factor; 2067ead8e4c0SDimitry Andric size_type __guess = __align_it<__boundary>(__s + 1) - 1; 2068cb14a3feSDimitry Andric if (__guess == __min_cap) 2069ead8e4c0SDimitry Andric __guess += __endian_factor; 20700b57cec5SDimitry Andric return __guess; 20710b57cec5SDimitry Andric } 20720b57cec5SDimitry Andric 2073cb14a3feSDimitry Andric inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init(const value_type* __s, size_type __sz, size_type __reserve); 2074cb14a3feSDimitry Andric inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init(const value_type* __s, size_type __sz); 2075cb14a3feSDimitry Andric inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init(size_type __n, value_type __c); 20760b57cec5SDimitry Andric 20775ffd83dbSDimitry Andric // Slow path for the (inlined) copy constructor for 'long' strings. 20785ffd83dbSDimitry Andric // Always externally instantiated and not inlined. 20795ffd83dbSDimitry Andric // Requires that __s is zero terminated. 20805ffd83dbSDimitry Andric // The main reason for this function to exist is because for unstable, we 20815ffd83dbSDimitry Andric // want to allow inlining of the copy constructor. However, we don't want 20825ffd83dbSDimitry Andric // to call the __init() functions as those are marked as inline which may 20835ffd83dbSDimitry Andric // result in over-aggressive inlining by the compiler, where our aim is 20845ffd83dbSDimitry Andric // to only inline the fast path code directly in the ctor. 20855f757f3fSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE void __init_copy_ctor_external(const value_type* __s, size_type __sz); 20865ffd83dbSDimitry Andric 208706c3fb27SDimitry Andric template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0> 208806c3fb27SDimitry Andric inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init(_InputIterator __first, _InputIterator __last); 20890b57cec5SDimitry Andric 209006c3fb27SDimitry Andric template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0> 209106c3fb27SDimitry Andric inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init(_ForwardIterator __first, _ForwardIterator __last); 209206c3fb27SDimitry Andric 209306c3fb27SDimitry Andric template <class _InputIterator, class _Sentinel> 2094cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 2095cb14a3feSDimitry Andric __init_with_sentinel(_InputIterator __first, _Sentinel __last); 209606c3fb27SDimitry Andric template <class _InputIterator, class _Sentinel> 2097cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 2098cb14a3feSDimitry Andric __init_with_size(_InputIterator __first, _Sentinel __last, size_type __sz); 20990b57cec5SDimitry Andric 2100bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 210106c3fb27SDimitry Andric#if _LIBCPP_ABI_VERSION >= 2 // We want to use the function in the dylib in ABIv1 210206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 210306c3fb27SDimitry Andric#endif 2104cb14a3feSDimitry Andric _LIBCPP_DEPRECATED_("use __grow_by_without_replace") void __grow_by( 2105cb14a3feSDimitry Andric size_type __old_cap, 2106cb14a3feSDimitry Andric size_type __delta_cap, 2107cb14a3feSDimitry Andric size_type __old_sz, 2108cb14a3feSDimitry Andric size_type __n_copy, 2109cb14a3feSDimitry Andric size_type __n_del, 2110cb14a3feSDimitry Andric size_type __n_add = 0); 2111cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __grow_by_without_replace( 2112cb14a3feSDimitry Andric size_type __old_cap, 2113cb14a3feSDimitry Andric size_type __delta_cap, 2114cb14a3feSDimitry Andric size_type __old_sz, 2115cb14a3feSDimitry Andric size_type __n_copy, 2116cb14a3feSDimitry Andric size_type __n_del, 2117cb14a3feSDimitry Andric size_type __n_add = 0); 2118cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 void __grow_by_and_replace( 2119cb14a3feSDimitry Andric size_type __old_cap, 2120cb14a3feSDimitry Andric size_type __delta_cap, 2121cb14a3feSDimitry Andric size_type __old_sz, 2122cb14a3feSDimitry Andric size_type __n_copy, 2123cb14a3feSDimitry Andric size_type __n_del, 2124cb14a3feSDimitry Andric size_type __n_add, 2125cb14a3feSDimitry Andric const value_type* __p_new_stuff); 21260b57cec5SDimitry Andric 21275ffd83dbSDimitry Andric // __assign_no_alias is invoked for assignment operations where we 21285ffd83dbSDimitry Andric // have proof that the input does not alias the current instance. 21295ffd83dbSDimitry Andric // For example, operator=(basic_string) performs a 'self' check. 21305ffd83dbSDimitry Andric template <bool __is_short> 21315f757f3fSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE basic_string& __assign_no_alias(const value_type* __s, size_type __n); 21325ffd83dbSDimitry Andric 2133bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __erase_to_end(size_type __pos) { 2134bdd1243dSDimitry Andric __null_terminate_at(std::__to_address(__get_pointer()), __pos); 2135bdd1243dSDimitry Andric } 21360b57cec5SDimitry Andric 21375ffd83dbSDimitry Andric // __erase_external_with_move is invoked for erase() invocations where 21385ffd83dbSDimitry Andric // `n ~= npos`, likely requiring memory moves on the string data. 21395f757f3fSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE void __erase_external_with_move(size_type __pos, size_type __n); 21405ffd83dbSDimitry Andric 2141cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __copy_assign_alloc(const basic_string& __str) { 2142cb14a3feSDimitry Andric __copy_assign_alloc( 2143cb14a3feSDimitry Andric __str, integral_constant<bool, __alloc_traits::propagate_on_container_copy_assignment::value>()); 2144cb14a3feSDimitry Andric } 21450b57cec5SDimitry Andric 2146cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __copy_assign_alloc(const basic_string& __str, true_type) { 21470b57cec5SDimitry Andric if (__alloc() == __str.__alloc()) 21480b57cec5SDimitry Andric __alloc() = __str.__alloc(); 2149cb14a3feSDimitry Andric else { 2150cb14a3feSDimitry Andric if (!__str.__is_long()) { 21510b57cec5SDimitry Andric __clear_and_shrink(); 21520b57cec5SDimitry Andric __alloc() = __str.__alloc(); 2153cb14a3feSDimitry Andric } else { 21545f757f3fSDimitry Andric __annotate_delete(); 21550b57cec5SDimitry Andric allocator_type __a = __str.__alloc(); 215681ad6265SDimitry Andric auto __allocation = std::__allocate_at_least(__a, __str.__get_long_cap()); 215781ad6265SDimitry Andric __begin_lifetime(__allocation.ptr, __allocation.count); 21585f757f3fSDimitry Andric if (__is_long()) 2159bdd1243dSDimitry Andric __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 216081ad6265SDimitry Andric __alloc() = std::move(__a); 216181ad6265SDimitry Andric __set_long_pointer(__allocation.ptr); 216281ad6265SDimitry Andric __set_long_cap(__allocation.count); 21630b57cec5SDimitry Andric __set_long_size(__str.size()); 21645f757f3fSDimitry Andric __annotate_new(__get_long_size()); 21650b57cec5SDimitry Andric } 21660b57cec5SDimitry Andric } 21670b57cec5SDimitry Andric } 21680b57cec5SDimitry Andric 2169cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 2170cb14a3feSDimitry Andric __copy_assign_alloc(const basic_string&, false_type) _NOEXCEPT {} 21710b57cec5SDimitry Andric 21720b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 21730fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 21740fca6ea1SDimitry Andric __move_assign(basic_string& __str, false_type) noexcept(__alloc_traits::is_always_equal::value); 2175cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS void 2176cb14a3feSDimitry Andric __move_assign(basic_string& __str, true_type) 217706c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 17 21780fca6ea1SDimitry Andric noexcept; 21790b57cec5SDimitry Andric# else 21800fca6ea1SDimitry Andric noexcept(is_nothrow_move_assignable<allocator_type>::value); 21810b57cec5SDimitry Andric# endif 21820b57cec5SDimitry Andric#endif 21830b57cec5SDimitry Andric 2184cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign_alloc(basic_string& __str) 2185cb14a3feSDimitry Andric _NOEXCEPT_(!__alloc_traits::propagate_on_container_move_assignment::value || 2186cb14a3feSDimitry Andric is_nothrow_move_assignable<allocator_type>::value) { 2187cb14a3feSDimitry Andric __move_assign_alloc( 2188cb14a3feSDimitry Andric __str, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>()); 2189cb14a3feSDimitry Andric } 21900b57cec5SDimitry Andric 2191cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign_alloc(basic_string& __c, true_type) 2192cb14a3feSDimitry Andric _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) { 219381ad6265SDimitry Andric __alloc() = std::move(__c.__alloc()); 21940b57cec5SDimitry Andric } 21950b57cec5SDimitry Andric 2196cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign_alloc(basic_string&, false_type) _NOEXCEPT {} 21970b57cec5SDimitry Andric 21985f757f3fSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE basic_string& __assign_external(const value_type* __s); 21995f757f3fSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE basic_string& __assign_external(const value_type* __s, size_type __n); 22005ffd83dbSDimitry Andric 22015ffd83dbSDimitry Andric // Assigns the value in __s, guaranteed to be __n < __min_cap in length. 22025f757f3fSDimitry Andric inline _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& __assign_short(const value_type* __s, size_type __n) { 22035f757f3fSDimitry Andric size_type __old_size = size(); 22045f757f3fSDimitry Andric if (__n > __old_size) 22055f757f3fSDimitry Andric __annotate_increase(__n - __old_size); 2206cb14a3feSDimitry Andric pointer __p = 2207cb14a3feSDimitry Andric __is_long() ? (__set_long_size(__n), __get_long_pointer()) : (__set_short_size(__n), __get_short_pointer()); 220881ad6265SDimitry Andric traits_type::move(std::__to_address(__p), __s, __n); 22095ffd83dbSDimitry Andric traits_type::assign(__p[__n], value_type()); 22105f757f3fSDimitry Andric if (__old_size > __n) 22115f757f3fSDimitry Andric __annotate_shrink(__old_size); 22125ffd83dbSDimitry Andric return *this; 22135ffd83dbSDimitry Andric } 22145ffd83dbSDimitry Andric 2215cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 2216cb14a3feSDimitry Andric __null_terminate_at(value_type* __p, size_type __newsz) { 22175f757f3fSDimitry Andric size_type __old_size = size(); 22185f757f3fSDimitry Andric if (__newsz > __old_size) 22195f757f3fSDimitry Andric __annotate_increase(__newsz - __old_size); 22200eae32dcSDimitry Andric __set_size(__newsz); 22210eae32dcSDimitry Andric traits_type::assign(__p[__newsz], value_type()); 22225f757f3fSDimitry Andric if (__old_size > __newsz) 22235f757f3fSDimitry Andric __annotate_shrink(__old_size); 22240eae32dcSDimitry Andric return *this; 22250eae32dcSDimitry Andric } 22260eae32dcSDimitry Andric 2227fe6060f1SDimitry Andric template <class _Tp> 222806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __addr_in_range(const _Tp& __v) const { 222906c3fb27SDimitry Andric return std::__is_pointer_in_range(data(), data() + size() + 1, std::addressof(__v)); 2230fe6060f1SDimitry Andric } 2231fe6060f1SDimitry Andric 2232cb14a3feSDimitry Andric _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void __throw_length_error() const { 223381ad6265SDimitry Andric std::__throw_length_error("basic_string"); 223469ade1e0SDimitry Andric } 223569ade1e0SDimitry Andric 2236cb14a3feSDimitry Andric _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void __throw_out_of_range() const { 223781ad6265SDimitry Andric std::__throw_out_of_range("basic_string"); 223869ade1e0SDimitry Andric } 223969ade1e0SDimitry Andric 2240bdd1243dSDimitry Andric friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+ <>(const basic_string&, const basic_string&); 2241bdd1243dSDimitry Andric friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+ <>(const value_type*, const basic_string&); 2242bdd1243dSDimitry Andric friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+ <>(value_type, const basic_string&); 2243bdd1243dSDimitry Andric friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+ <>(const basic_string&, const value_type*); 2244bdd1243dSDimitry Andric friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+ <>(const basic_string&, value_type); 22450fca6ea1SDimitry Andric#if _LIBCPP_STD_VER >= 26 22460fca6ea1SDimitry Andric friend constexpr basic_string operator+ <>(const basic_string&, type_identity_t<__self_view>); 22470fca6ea1SDimitry Andric friend constexpr basic_string operator+ <>(type_identity_t<__self_view>, const basic_string&); 22480fca6ea1SDimitry Andric#endif 22490b57cec5SDimitry Andric}; 22500b57cec5SDimitry Andric 22515ffd83dbSDimitry Andric// These declarations must appear before any functions are implicitly used 22525ffd83dbSDimitry Andric// so that they have the correct visibility specifier. 225381ad6265SDimitry Andric#define _LIBCPP_DECLARE(...) extern template __VA_ARGS__; 22545ffd83dbSDimitry Andric#ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION 225581ad6265SDimitry Andric_LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, char) 2256349cc55cSDimitry Andric# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 225781ad6265SDimitry Andric_LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, wchar_t) 2258349cc55cSDimitry Andric# endif 22595ffd83dbSDimitry Andric#else 226081ad6265SDimitry Andric_LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, char) 2261349cc55cSDimitry Andric# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 226281ad6265SDimitry Andric_LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, wchar_t) 22635ffd83dbSDimitry Andric# endif 2264349cc55cSDimitry Andric#endif 226581ad6265SDimitry Andric#undef _LIBCPP_DECLARE 22665ffd83dbSDimitry Andric 2267349cc55cSDimitry Andric#if _LIBCPP_STD_VER >= 17 22680b57cec5SDimitry Andrictemplate <class _InputIterator, 2269fe6060f1SDimitry Andric class _CharT = __iter_value_type<_InputIterator>, 22700b57cec5SDimitry Andric class _Allocator = allocator<_CharT>, 227106c3fb27SDimitry Andric class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, 2272cb14a3feSDimitry Andric class = enable_if_t<__is_allocator<_Allocator>::value> > 22730b57cec5SDimitry Andricbasic_string(_InputIterator, _InputIterator, _Allocator = _Allocator()) 22740b57cec5SDimitry Andric -> basic_string<_CharT, char_traits<_CharT>, _Allocator>; 22750b57cec5SDimitry Andric 22760b57cec5SDimitry Andrictemplate <class _CharT, 22770b57cec5SDimitry Andric class _Traits, 22780b57cec5SDimitry Andric class _Allocator = allocator<_CharT>, 2279cb14a3feSDimitry Andric class = enable_if_t<__is_allocator<_Allocator>::value> > 22800fca6ea1SDimitry Andricexplicit basic_string(basic_string_view<_CharT, _Traits>, 22810fca6ea1SDimitry Andric const _Allocator& = _Allocator()) -> basic_string<_CharT, _Traits, _Allocator>; 22820b57cec5SDimitry Andric 22830b57cec5SDimitry Andrictemplate <class _CharT, 22840b57cec5SDimitry Andric class _Traits, 22850b57cec5SDimitry Andric class _Allocator = allocator<_CharT>, 2286349cc55cSDimitry Andric class = enable_if_t<__is_allocator<_Allocator>::value>, 2287cb14a3feSDimitry Andric class _Sz = typename allocator_traits<_Allocator>::size_type > 22880b57cec5SDimitry Andricbasic_string(basic_string_view<_CharT, _Traits>, _Sz, _Sz, const _Allocator& = _Allocator()) 22890b57cec5SDimitry Andric -> basic_string<_CharT, _Traits, _Allocator>; 22900b57cec5SDimitry Andric#endif 22910b57cec5SDimitry Andric 229206c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 229306c3fb27SDimitry Andrictemplate <ranges::input_range _Range, 229406c3fb27SDimitry Andric class _Allocator = allocator<ranges::range_value_t<_Range>>, 2295cb14a3feSDimitry Andric class = enable_if_t<__is_allocator<_Allocator>::value> > 229606c3fb27SDimitry Andricbasic_string(from_range_t, _Range&&, _Allocator = _Allocator()) 229706c3fb27SDimitry Andric -> basic_string<ranges::range_value_t<_Range>, char_traits<ranges::range_value_t<_Range>>, _Allocator>; 229806c3fb27SDimitry Andric#endif 22990b57cec5SDimitry Andric 23000b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2301cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void 2302cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz, size_type __reserve) { 230381ad6265SDimitry Andric if (__libcpp_is_constant_evaluated()) 2304bdd1243dSDimitry Andric __r_.first() = __rep(); 23050b57cec5SDimitry Andric if (__reserve > max_size()) 230604eeddc0SDimitry Andric __throw_length_error(); 23070b57cec5SDimitry Andric pointer __p; 2308cb14a3feSDimitry Andric if (__fits_in_sso(__reserve)) { 23090b57cec5SDimitry Andric __set_short_size(__sz); 23100b57cec5SDimitry Andric __p = __get_short_pointer(); 2311cb14a3feSDimitry Andric } else { 231281ad6265SDimitry Andric auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__reserve) + 1); 231381ad6265SDimitry Andric __p = __allocation.ptr; 231481ad6265SDimitry Andric __begin_lifetime(__p, __allocation.count); 23150b57cec5SDimitry Andric __set_long_pointer(__p); 231681ad6265SDimitry Andric __set_long_cap(__allocation.count); 23170b57cec5SDimitry Andric __set_long_size(__sz); 23180b57cec5SDimitry Andric } 231981ad6265SDimitry Andric traits_type::copy(std::__to_address(__p), __s, __sz); 23200b57cec5SDimitry Andric traits_type::assign(__p[__sz], value_type()); 23215f757f3fSDimitry Andric __annotate_new(__sz); 23220b57cec5SDimitry Andric} 23230b57cec5SDimitry Andric 23240b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2325cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void 2326cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz) { 232781ad6265SDimitry Andric if (__libcpp_is_constant_evaluated()) 2328bdd1243dSDimitry Andric __r_.first() = __rep(); 23290b57cec5SDimitry Andric if (__sz > max_size()) 233004eeddc0SDimitry Andric __throw_length_error(); 23310b57cec5SDimitry Andric pointer __p; 2332cb14a3feSDimitry Andric if (__fits_in_sso(__sz)) { 23330b57cec5SDimitry Andric __set_short_size(__sz); 23340b57cec5SDimitry Andric __p = __get_short_pointer(); 2335cb14a3feSDimitry Andric } else { 233681ad6265SDimitry Andric auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1); 233781ad6265SDimitry Andric __p = __allocation.ptr; 233881ad6265SDimitry Andric __begin_lifetime(__p, __allocation.count); 23390b57cec5SDimitry Andric __set_long_pointer(__p); 234081ad6265SDimitry Andric __set_long_cap(__allocation.count); 23410b57cec5SDimitry Andric __set_long_size(__sz); 23420b57cec5SDimitry Andric } 234381ad6265SDimitry Andric traits_type::copy(std::__to_address(__p), __s, __sz); 23440b57cec5SDimitry Andric traits_type::assign(__p[__sz], value_type()); 23455f757f3fSDimitry Andric __annotate_new(__sz); 23460b57cec5SDimitry Andric} 23470b57cec5SDimitry Andric 23480b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2349cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE void 2350cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external(const value_type* __s, size_type __sz) { 235181ad6265SDimitry Andric if (__libcpp_is_constant_evaluated()) 2352bdd1243dSDimitry Andric __r_.first() = __rep(); 2353bdd1243dSDimitry Andric 23545ffd83dbSDimitry Andric pointer __p; 235504eeddc0SDimitry Andric if (__fits_in_sso(__sz)) { 23565ffd83dbSDimitry Andric __p = __get_short_pointer(); 23575ffd83dbSDimitry Andric __set_short_size(__sz); 23585ffd83dbSDimitry Andric } else { 23595ffd83dbSDimitry Andric if (__sz > max_size()) 236004eeddc0SDimitry Andric __throw_length_error(); 236181ad6265SDimitry Andric auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1); 236281ad6265SDimitry Andric __p = __allocation.ptr; 236381ad6265SDimitry Andric __begin_lifetime(__p, __allocation.count); 23645ffd83dbSDimitry Andric __set_long_pointer(__p); 236581ad6265SDimitry Andric __set_long_cap(__allocation.count); 23665ffd83dbSDimitry Andric __set_long_size(__sz); 23675ffd83dbSDimitry Andric } 236881ad6265SDimitry Andric traits_type::copy(std::__to_address(__p), __s, __sz + 1); 23695f757f3fSDimitry Andric __annotate_new(__sz); 23705ffd83dbSDimitry Andric} 23715ffd83dbSDimitry Andric 23720b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2373cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c) { 237481ad6265SDimitry Andric if (__libcpp_is_constant_evaluated()) 2375bdd1243dSDimitry Andric __r_.first() = __rep(); 2376bdd1243dSDimitry Andric 23770b57cec5SDimitry Andric if (__n > max_size()) 237804eeddc0SDimitry Andric __throw_length_error(); 23790b57cec5SDimitry Andric pointer __p; 2380cb14a3feSDimitry Andric if (__fits_in_sso(__n)) { 23810b57cec5SDimitry Andric __set_short_size(__n); 23820b57cec5SDimitry Andric __p = __get_short_pointer(); 2383cb14a3feSDimitry Andric } else { 238481ad6265SDimitry Andric auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__n) + 1); 238581ad6265SDimitry Andric __p = __allocation.ptr; 238681ad6265SDimitry Andric __begin_lifetime(__p, __allocation.count); 23870b57cec5SDimitry Andric __set_long_pointer(__p); 238881ad6265SDimitry Andric __set_long_cap(__allocation.count); 23890b57cec5SDimitry Andric __set_long_size(__n); 23900b57cec5SDimitry Andric } 239181ad6265SDimitry Andric traits_type::assign(std::__to_address(__p), __n, __c); 23920b57cec5SDimitry Andric traits_type::assign(__p[__n], value_type()); 23935f757f3fSDimitry Andric __annotate_new(__n); 23940b57cec5SDimitry Andric} 23950b57cec5SDimitry Andric 23960b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 239706c3fb27SDimitry Andrictemplate <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> > 2398cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void 2399cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last) { 240006c3fb27SDimitry Andric __init_with_sentinel(std::move(__first), std::move(__last)); 24010b57cec5SDimitry Andric} 24020b57cec5SDimitry Andric 24030b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 240406c3fb27SDimitry Andrictemplate <class _InputIterator, class _Sentinel> 2405cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 2406cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__init_with_sentinel(_InputIterator __first, _Sentinel __last) { 24075f757f3fSDimitry Andric __r_.first() = __rep(); 24085f757f3fSDimitry Andric __annotate_new(0); 240906c3fb27SDimitry Andric 241006c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 2411cb14a3feSDimitry Andric try { 241206c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 24130b57cec5SDimitry Andric for (; __first != __last; ++__first) 24140b57cec5SDimitry Andric push_back(*__first); 241506c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 2416cb14a3feSDimitry Andric } catch (...) { 24175f757f3fSDimitry Andric __annotate_delete(); 24180b57cec5SDimitry Andric if (__is_long()) 24190b57cec5SDimitry Andric __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 24200b57cec5SDimitry Andric throw; 24210b57cec5SDimitry Andric } 242206c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 24230b57cec5SDimitry Andric} 24240b57cec5SDimitry Andric 24250b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 242606c3fb27SDimitry Andrictemplate <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> > 242706c3fb27SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void 2428cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last) { 242906c3fb27SDimitry Andric size_type __sz = static_cast<size_type>(std::distance(__first, __last)); 243006c3fb27SDimitry Andric __init_with_size(__first, __last, __sz); 243106c3fb27SDimitry Andric} 243206c3fb27SDimitry Andric 243306c3fb27SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 243406c3fb27SDimitry Andrictemplate <class _InputIterator, class _Sentinel> 2435cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 2436cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__init_with_size(_InputIterator __first, _Sentinel __last, size_type __sz) { 243781ad6265SDimitry Andric if (__libcpp_is_constant_evaluated()) 2438bdd1243dSDimitry Andric __r_.first() = __rep(); 243906c3fb27SDimitry Andric 24400b57cec5SDimitry Andric if (__sz > max_size()) 244104eeddc0SDimitry Andric __throw_length_error(); 244206c3fb27SDimitry Andric 24430b57cec5SDimitry Andric pointer __p; 2444cb14a3feSDimitry Andric if (__fits_in_sso(__sz)) { 24450b57cec5SDimitry Andric __set_short_size(__sz); 24460b57cec5SDimitry Andric __p = __get_short_pointer(); 244706c3fb27SDimitry Andric 2448cb14a3feSDimitry Andric } else { 244981ad6265SDimitry Andric auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1); 245081ad6265SDimitry Andric __p = __allocation.ptr; 245181ad6265SDimitry Andric __begin_lifetime(__p, __allocation.count); 24520b57cec5SDimitry Andric __set_long_pointer(__p); 245381ad6265SDimitry Andric __set_long_cap(__allocation.count); 24540b57cec5SDimitry Andric __set_long_size(__sz); 24550b57cec5SDimitry Andric } 2456fe6060f1SDimitry Andric 245706c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 2458cb14a3feSDimitry Andric try { 245906c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 24600fca6ea1SDimitry Andric auto __end = __copy_non_overlapping_range(__first, __last, std::__to_address(__p)); 24610fca6ea1SDimitry Andric traits_type::assign(*__end, value_type()); 246206c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 2463cb14a3feSDimitry Andric } catch (...) { 2464fe6060f1SDimitry Andric if (__is_long()) 2465fe6060f1SDimitry Andric __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 2466fe6060f1SDimitry Andric throw; 2467fe6060f1SDimitry Andric } 246806c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 24695f757f3fSDimitry Andric __annotate_new(__sz); 24700b57cec5SDimitry Andric} 24710b57cec5SDimitry Andric 24720b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2473cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace( 2474cb14a3feSDimitry Andric size_type __old_cap, 2475cb14a3feSDimitry Andric size_type __delta_cap, 2476cb14a3feSDimitry Andric size_type __old_sz, 2477cb14a3feSDimitry Andric size_type __n_copy, 2478cb14a3feSDimitry Andric size_type __n_del, 2479cb14a3feSDimitry Andric size_type __n_add, 2480cb14a3feSDimitry Andric const value_type* __p_new_stuff) { 24810b57cec5SDimitry Andric size_type __ms = max_size(); 24820b57cec5SDimitry Andric if (__delta_cap > __ms - __old_cap - 1) 248304eeddc0SDimitry Andric __throw_length_error(); 24840b57cec5SDimitry Andric pointer __old_p = __get_pointer(); 2485cb14a3feSDimitry Andric size_type __cap = 2486cb14a3feSDimitry Andric __old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms - 1; 24875f757f3fSDimitry Andric __annotate_delete(); 248881ad6265SDimitry Andric auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1); 248981ad6265SDimitry Andric pointer __p = __allocation.ptr; 249081ad6265SDimitry Andric __begin_lifetime(__p, __allocation.count); 24910b57cec5SDimitry Andric if (__n_copy != 0) 2492cb14a3feSDimitry Andric traits_type::copy(std::__to_address(__p), std::__to_address(__old_p), __n_copy); 24930b57cec5SDimitry Andric if (__n_add != 0) 249481ad6265SDimitry Andric traits_type::copy(std::__to_address(__p) + __n_copy, __p_new_stuff, __n_add); 24950b57cec5SDimitry Andric size_type __sec_cp_sz = __old_sz - __n_del - __n_copy; 24960b57cec5SDimitry Andric if (__sec_cp_sz != 0) 2497cb14a3feSDimitry Andric traits_type::copy( 2498cb14a3feSDimitry Andric std::__to_address(__p) + __n_copy + __n_add, std::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz); 24995f757f3fSDimitry Andric if (__old_cap + 1 != __min_cap) 25000b57cec5SDimitry Andric __alloc_traits::deallocate(__alloc(), __old_p, __old_cap + 1); 25010b57cec5SDimitry Andric __set_long_pointer(__p); 250281ad6265SDimitry Andric __set_long_cap(__allocation.count); 25030b57cec5SDimitry Andric __old_sz = __n_copy + __n_add + __sec_cp_sz; 25040b57cec5SDimitry Andric __set_long_size(__old_sz); 25050b57cec5SDimitry Andric traits_type::assign(__p[__old_sz], value_type()); 25060fca6ea1SDimitry Andric __annotate_new(__old_sz); 25070b57cec5SDimitry Andric} 25080b57cec5SDimitry Andric 250906c3fb27SDimitry Andric// __grow_by is deprecated because it does not set the size. It may not update the size when the size is changed, and it 251006c3fb27SDimitry Andric// may also not set the size at all when the string was short initially. This leads to unpredictable size value. It is 251106c3fb27SDimitry Andric// not removed or changed to avoid breaking the ABI. 25120b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2513cb14a3feSDimitry Andricvoid _LIBCPP_CONSTEXPR_SINCE_CXX20 251406c3fb27SDimitry Andric#if _LIBCPP_ABI_VERSION >= 2 // We want to use the function in the dylib in ABIv1 251506c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI 251606c3fb27SDimitry Andric#endif 2517cb14a3feSDimitry Andric_LIBCPP_DEPRECATED_("use __grow_by_without_replace") basic_string<_CharT, _Traits, _Allocator>::__grow_by( 2518cb14a3feSDimitry Andric size_type __old_cap, 2519cb14a3feSDimitry Andric size_type __delta_cap, 2520cb14a3feSDimitry Andric size_type __old_sz, 2521cb14a3feSDimitry Andric size_type __n_copy, 2522cb14a3feSDimitry Andric size_type __n_del, 2523cb14a3feSDimitry Andric size_type __n_add) { 25240b57cec5SDimitry Andric size_type __ms = max_size(); 25250b57cec5SDimitry Andric if (__delta_cap > __ms - __old_cap) 252604eeddc0SDimitry Andric __throw_length_error(); 25270b57cec5SDimitry Andric pointer __old_p = __get_pointer(); 2528cb14a3feSDimitry Andric size_type __cap = 2529cb14a3feSDimitry Andric __old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms - 1; 25305f757f3fSDimitry Andric __annotate_delete(); 253181ad6265SDimitry Andric auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1); 253281ad6265SDimitry Andric pointer __p = __allocation.ptr; 253381ad6265SDimitry Andric __begin_lifetime(__p, __allocation.count); 25340b57cec5SDimitry Andric if (__n_copy != 0) 2535cb14a3feSDimitry Andric traits_type::copy(std::__to_address(__p), std::__to_address(__old_p), __n_copy); 25360b57cec5SDimitry Andric size_type __sec_cp_sz = __old_sz - __n_del - __n_copy; 25370b57cec5SDimitry Andric if (__sec_cp_sz != 0) 2538cb14a3feSDimitry Andric traits_type::copy( 2539cb14a3feSDimitry Andric std::__to_address(__p) + __n_copy + __n_add, std::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz); 25405f757f3fSDimitry Andric if (__old_cap + 1 != __min_cap) 25410b57cec5SDimitry Andric __alloc_traits::deallocate(__alloc(), __old_p, __old_cap + 1); 25420b57cec5SDimitry Andric __set_long_pointer(__p); 254381ad6265SDimitry Andric __set_long_cap(__allocation.count); 25440b57cec5SDimitry Andric} 25450b57cec5SDimitry Andric 254606c3fb27SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 254706c3fb27SDimitry Andricvoid _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI 254806c3fb27SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__grow_by_without_replace( 254906c3fb27SDimitry Andric size_type __old_cap, 255006c3fb27SDimitry Andric size_type __delta_cap, 255106c3fb27SDimitry Andric size_type __old_sz, 255206c3fb27SDimitry Andric size_type __n_copy, 255306c3fb27SDimitry Andric size_type __n_del, 255406c3fb27SDimitry Andric size_type __n_add) { 255506c3fb27SDimitry Andric _LIBCPP_SUPPRESS_DEPRECATED_PUSH 255606c3fb27SDimitry Andric __grow_by(__old_cap, __delta_cap, __old_sz, __n_copy, __n_del, __n_add); 255706c3fb27SDimitry Andric _LIBCPP_SUPPRESS_DEPRECATED_POP 255806c3fb27SDimitry Andric __set_long_size(__old_sz - __n_del + __n_add); 25595f757f3fSDimitry Andric __annotate_new(__old_sz - __n_del + __n_add); 256006c3fb27SDimitry Andric} 256106c3fb27SDimitry Andric 25620b57cec5SDimitry Andric// assign 25630b57cec5SDimitry Andric 25640b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 25655ffd83dbSDimitry Andrictemplate <bool __is_short> 2566cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE basic_string<_CharT, _Traits, _Allocator>& 2567cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__assign_no_alias(const value_type* __s, size_type __n) { 256881ad6265SDimitry Andric size_type __cap = __is_short ? static_cast<size_type>(__min_cap) : __get_long_cap(); 25695ffd83dbSDimitry Andric if (__n < __cap) { 25705f757f3fSDimitry Andric size_type __old_size = __is_short ? __get_short_size() : __get_long_size(); 25715f757f3fSDimitry Andric if (__n > __old_size) 25725f757f3fSDimitry Andric __annotate_increase(__n - __old_size); 25735ffd83dbSDimitry Andric pointer __p = __is_short ? __get_short_pointer() : __get_long_pointer(); 25745ffd83dbSDimitry Andric __is_short ? __set_short_size(__n) : __set_long_size(__n); 257581ad6265SDimitry Andric traits_type::copy(std::__to_address(__p), __s, __n); 25765ffd83dbSDimitry Andric traits_type::assign(__p[__n], value_type()); 25775f757f3fSDimitry Andric if (__old_size > __n) 25785f757f3fSDimitry Andric __annotate_shrink(__old_size); 25795ffd83dbSDimitry Andric } else { 25805ffd83dbSDimitry Andric size_type __sz = __is_short ? __get_short_size() : __get_long_size(); 25815ffd83dbSDimitry Andric __grow_by_and_replace(__cap - 1, __n - __cap + 1, __sz, 0, __sz, __n, __s); 25825ffd83dbSDimitry Andric } 25835ffd83dbSDimitry Andric return *this; 25845ffd83dbSDimitry Andric} 25855ffd83dbSDimitry Andric 25865ffd83dbSDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2587cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE basic_string<_CharT, _Traits, _Allocator>& 2588cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__assign_external(const value_type* __s, size_type __n) { 25890b57cec5SDimitry Andric size_type __cap = capacity(); 25905ffd83dbSDimitry Andric if (__cap >= __n) { 25915f757f3fSDimitry Andric size_type __old_size = size(); 25925f757f3fSDimitry Andric if (__n > __old_size) 25935f757f3fSDimitry Andric __annotate_increase(__n - __old_size); 259481ad6265SDimitry Andric value_type* __p = std::__to_address(__get_pointer()); 25950b57cec5SDimitry Andric traits_type::move(__p, __s, __n); 25960eae32dcSDimitry Andric return __null_terminate_at(__p, __n); 25975ffd83dbSDimitry Andric } else { 25980b57cec5SDimitry Andric size_type __sz = size(); 25990b57cec5SDimitry Andric __grow_by_and_replace(__cap, __n - __cap, __sz, 0, __sz, __n, __s); 26000b57cec5SDimitry Andric return *this; 26010b57cec5SDimitry Andric } 26020eae32dcSDimitry Andric} 26030b57cec5SDimitry Andric 26040b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2605cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2606cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n) { 26075f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::assign received nullptr"); 2608cb14a3feSDimitry Andric return (__builtin_constant_p(__n) && __fits_in_sso(__n)) ? __assign_short(__s, __n) : __assign_external(__s, __n); 26095ffd83dbSDimitry Andric} 26105ffd83dbSDimitry Andric 26115ffd83dbSDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2612cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2613cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c) { 26140b57cec5SDimitry Andric size_type __cap = capacity(); 26155f757f3fSDimitry Andric size_type __old_size = size(); 2616cb14a3feSDimitry Andric if (__cap < __n) { 26170b57cec5SDimitry Andric size_type __sz = size(); 261806c3fb27SDimitry Andric __grow_by_without_replace(__cap, __n - __cap, __sz, 0, __sz); 26195f757f3fSDimitry Andric __annotate_increase(__n); 2620cb14a3feSDimitry Andric } else if (__n > __old_size) 26215f757f3fSDimitry Andric __annotate_increase(__n - __old_size); 262281ad6265SDimitry Andric value_type* __p = std::__to_address(__get_pointer()); 26230b57cec5SDimitry Andric traits_type::assign(__p, __n, __c); 26240eae32dcSDimitry Andric return __null_terminate_at(__p, __n); 26250b57cec5SDimitry Andric} 26260b57cec5SDimitry Andric 26270b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2628cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2629cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c) { 26300b57cec5SDimitry Andric pointer __p; 26315f757f3fSDimitry Andric size_type __old_size = size(); 26325f757f3fSDimitry Andric if (__old_size == 0) 26335f757f3fSDimitry Andric __annotate_increase(1); 26345f757f3fSDimitry Andric if (__is_long()) { 26350b57cec5SDimitry Andric __p = __get_long_pointer(); 26360b57cec5SDimitry Andric __set_long_size(1); 26375f757f3fSDimitry Andric } else { 26380b57cec5SDimitry Andric __p = __get_short_pointer(); 26390b57cec5SDimitry Andric __set_short_size(1); 26400b57cec5SDimitry Andric } 26410b57cec5SDimitry Andric traits_type::assign(*__p, __c); 26420b57cec5SDimitry Andric traits_type::assign(*++__p, value_type()); 26435f757f3fSDimitry Andric if (__old_size > 1) 26445f757f3fSDimitry Andric __annotate_shrink(__old_size); 26450b57cec5SDimitry Andric return *this; 26460b57cec5SDimitry Andric} 26470b57cec5SDimitry Andric 26480b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2649cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS basic_string<_CharT, _Traits, _Allocator>& 2650cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str) { 265106c3fb27SDimitry Andric if (this != std::addressof(__str)) { 26520b57cec5SDimitry Andric __copy_assign_alloc(__str); 26535ffd83dbSDimitry Andric if (!__is_long()) { 26545ffd83dbSDimitry Andric if (!__str.__is_long()) { 26555f757f3fSDimitry Andric size_type __old_size = __get_short_size(); 26565f757f3fSDimitry Andric if (__get_short_size() < __str.__get_short_size()) 26575f757f3fSDimitry Andric __annotate_increase(__str.__get_short_size() - __get_short_size()); 2658bdd1243dSDimitry Andric __r_.first() = __str.__r_.first(); 26595f757f3fSDimitry Andric if (__old_size > __get_short_size()) 26605f757f3fSDimitry Andric __annotate_shrink(__old_size); 26615ffd83dbSDimitry Andric } else { 26625ffd83dbSDimitry Andric return __assign_no_alias<true>(__str.data(), __str.size()); 26635ffd83dbSDimitry Andric } 26645ffd83dbSDimitry Andric } else { 26655ffd83dbSDimitry Andric return __assign_no_alias<false>(__str.data(), __str.size()); 26665ffd83dbSDimitry Andric } 26670b57cec5SDimitry Andric } 26680b57cec5SDimitry Andric return *this; 26690b57cec5SDimitry Andric} 26700b57cec5SDimitry Andric 26710b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 26720b57cec5SDimitry Andric 26730b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 26740fca6ea1SDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__move_assign( 26750fca6ea1SDimitry Andric basic_string& __str, false_type) noexcept(__alloc_traits::is_always_equal::value) { 26760b57cec5SDimitry Andric if (__alloc() != __str.__alloc()) 26770b57cec5SDimitry Andric assign(__str); 26780b57cec5SDimitry Andric else 26790b57cec5SDimitry Andric __move_assign(__str, true_type()); 26800b57cec5SDimitry Andric} 26810b57cec5SDimitry Andric 26820b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2683cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS void 26840b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type) 268506c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 17 26860fca6ea1SDimitry Andric noexcept 26870b57cec5SDimitry Andric# else 26880fca6ea1SDimitry Andric noexcept(is_nothrow_move_assignable<allocator_type>::value) 26890b57cec5SDimitry Andric# endif 26900b57cec5SDimitry Andric{ 26915f757f3fSDimitry Andric __annotate_delete(); 2692480093f4SDimitry Andric if (__is_long()) { 2693cb14a3feSDimitry Andric __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 2694480093f4SDimitry Andric# if _LIBCPP_STD_VER <= 14 2695480093f4SDimitry Andric if (!is_nothrow_move_assignable<allocator_type>::value) { 2696480093f4SDimitry Andric __set_short_size(0); 2697480093f4SDimitry Andric traits_type::assign(__get_short_pointer()[0], value_type()); 26985f757f3fSDimitry Andric __annotate_new(0); 2699480093f4SDimitry Andric } 2700480093f4SDimitry Andric# endif 2701480093f4SDimitry Andric } 27025f757f3fSDimitry Andric size_type __str_old_size = __str.size(); 27035f757f3fSDimitry Andric bool __str_was_short = !__str.__is_long(); 27045f757f3fSDimitry Andric 27050b57cec5SDimitry Andric __move_assign_alloc(__str); 2706480093f4SDimitry Andric __r_.first() = __str.__r_.first(); 2707480093f4SDimitry Andric __str.__set_short_size(0); 2708480093f4SDimitry Andric traits_type::assign(__str.__get_short_pointer()[0], value_type()); 27095f757f3fSDimitry Andric 27105f757f3fSDimitry Andric if (__str_was_short && this != &__str) 27115f757f3fSDimitry Andric __str.__annotate_shrink(__str_old_size); 27125f757f3fSDimitry Andric else 27135f757f3fSDimitry Andric // ASan annotations: was long, so object memory is unpoisoned as new. 27145f757f3fSDimitry Andric // Or is same as *this, and __annotate_delete() was called. 27155f757f3fSDimitry Andric __str.__annotate_new(0); 27165f757f3fSDimitry Andric 27175f757f3fSDimitry Andric // ASan annotations: Guard against `std::string s; s = std::move(s);` 27185f757f3fSDimitry Andric // You can find more here: https://en.cppreference.com/w/cpp/utility/move 27195f757f3fSDimitry Andric // Quote: "Unless otherwise specified, all standard library objects that have been moved 27205f757f3fSDimitry Andric // from are placed in a "valid but unspecified state", meaning the object's class 27215f757f3fSDimitry Andric // invariants hold (so functions without preconditions, such as the assignment operator, 27225f757f3fSDimitry Andric // can be safely used on the object after it was moved from):" 27235f757f3fSDimitry Andric // Quote: "v = std::move(v); // the value of v is unspecified" 27245f757f3fSDimitry Andric if (!__is_long() && &__str != this) 27255f757f3fSDimitry Andric // If it is long string, delete was never called on original __str's buffer. 27265f757f3fSDimitry Andric __annotate_new(__get_short_size()); 272781ad6265SDimitry Andric} 27280b57cec5SDimitry Andric 27290b57cec5SDimitry Andric#endif 27300b57cec5SDimitry Andric 27310b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 273206c3fb27SDimitry Andrictemplate <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> > 273306c3fb27SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2734cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last) { 273506c3fb27SDimitry Andric __assign_with_sentinel(__first, __last); 27360b57cec5SDimitry Andric return *this; 27370b57cec5SDimitry Andric} 27380b57cec5SDimitry Andric 27390b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 274006c3fb27SDimitry Andrictemplate <class _InputIterator, class _Sentinel> 2741cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 274206c3fb27SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__assign_with_sentinel(_InputIterator __first, _Sentinel __last) { 274306c3fb27SDimitry Andric const basic_string __temp(__init_with_sentinel_tag(), std::move(__first), std::move(__last), __alloc()); 274406c3fb27SDimitry Andric assign(__temp.data(), __temp.size()); 274506c3fb27SDimitry Andric} 274606c3fb27SDimitry Andric 274706c3fb27SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 274806c3fb27SDimitry Andrictemplate <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> > 274906c3fb27SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2750cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last) { 275106c3fb27SDimitry Andric if (__string_is_trivial_iterator<_ForwardIterator>::value) { 275206c3fb27SDimitry Andric size_type __n = static_cast<size_type>(std::distance(__first, __last)); 275306c3fb27SDimitry Andric __assign_trivial(__first, __last, __n); 275406c3fb27SDimitry Andric } else { 275506c3fb27SDimitry Andric __assign_with_sentinel(__first, __last); 275606c3fb27SDimitry Andric } 2757fe6060f1SDimitry Andric 275806c3fb27SDimitry Andric return *this; 275906c3fb27SDimitry Andric} 276006c3fb27SDimitry Andric 276106c3fb27SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 276206c3fb27SDimitry Andrictemplate <class _Iterator, class _Sentinel> 2763cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void 276406c3fb27SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__assign_trivial(_Iterator __first, _Sentinel __last, size_type __n) { 276506c3fb27SDimitry Andric _LIBCPP_ASSERT_INTERNAL( 276606c3fb27SDimitry Andric __string_is_trivial_iterator<_Iterator>::value, "The iterator type given to `__assign_trivial` must be trivial"); 276706c3fb27SDimitry Andric 27685f757f3fSDimitry Andric size_type __old_size = size(); 276906c3fb27SDimitry Andric size_type __cap = capacity(); 277006c3fb27SDimitry Andric if (__cap < __n) { 277106c3fb27SDimitry Andric // Unlike `append` functions, if the input range points into the string itself, there is no case that the input 277206c3fb27SDimitry Andric // range could get invalidated by reallocation: 277306c3fb27SDimitry Andric // 1. If the input range is a subset of the string itself, its size cannot exceed the capacity of the string, 277406c3fb27SDimitry Andric // thus no reallocation would happen. 277506c3fb27SDimitry Andric // 2. In the exotic case where the input range is the byte representation of the string itself, the string 277606c3fb27SDimitry Andric // object itself stays valid even if reallocation happens. 27770b57cec5SDimitry Andric size_type __sz = size(); 277806c3fb27SDimitry Andric __grow_by_without_replace(__cap, __n - __cap, __sz, 0, __sz); 27795f757f3fSDimitry Andric __annotate_increase(__n); 2780cb14a3feSDimitry Andric } else if (__n > __old_size) 27815f757f3fSDimitry Andric __annotate_increase(__n - __old_size); 27820b57cec5SDimitry Andric pointer __p = __get_pointer(); 2783349cc55cSDimitry Andric for (; __first != __last; ++__p, (void)++__first) 27840b57cec5SDimitry Andric traits_type::assign(*__p, *__first); 27850b57cec5SDimitry Andric traits_type::assign(*__p, value_type()); 27860b57cec5SDimitry Andric __set_size(__n); 27875f757f3fSDimitry Andric if (__n < __old_size) 27885f757f3fSDimitry Andric __annotate_shrink(__old_size); 27890b57cec5SDimitry Andric} 27900b57cec5SDimitry Andric 27910b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2792cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2793cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, size_type __pos, size_type __n) { 27940b57cec5SDimitry Andric size_type __sz = __str.size(); 27950b57cec5SDimitry Andric if (__pos > __sz) 279604eeddc0SDimitry Andric __throw_out_of_range(); 279781ad6265SDimitry Andric return assign(__str.data() + __pos, std::min(__n, __sz - __pos)); 27980b57cec5SDimitry Andric} 27990b57cec5SDimitry Andric 28000b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 280106c3fb27SDimitry Andrictemplate <class _Tp, 280206c3fb27SDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 280306c3fb27SDimitry Andric !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 280406c3fb27SDimitry Andric int> > 280506c3fb27SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 280606c3fb27SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::assign(const _Tp& __t, size_type __pos, size_type __n) { 28070b57cec5SDimitry Andric __self_view __sv = __t; 28080b57cec5SDimitry Andric size_type __sz = __sv.size(); 28090b57cec5SDimitry Andric if (__pos > __sz) 281004eeddc0SDimitry Andric __throw_out_of_range(); 281181ad6265SDimitry Andric return assign(__sv.data() + __pos, std::min(__n, __sz - __pos)); 28120b57cec5SDimitry Andric} 28130b57cec5SDimitry Andric 28140b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2815cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE basic_string<_CharT, _Traits, _Allocator>& 28165ffd83dbSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__assign_external(const value_type* __s) { 28175ffd83dbSDimitry Andric return __assign_external(__s, traits_type::length(__s)); 28185ffd83dbSDimitry Andric} 28195ffd83dbSDimitry Andric 28205ffd83dbSDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2821cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2822cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s) { 28235f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::assign received nullptr"); 2824349cc55cSDimitry Andric return __builtin_constant_p(*__s) 2825cb14a3feSDimitry Andric ? (__fits_in_sso(traits_type::length(__s)) ? __assign_short(__s, traits_type::length(__s)) 28265ffd83dbSDimitry Andric : __assign_external(__s, traits_type::length(__s))) 28275ffd83dbSDimitry Andric : __assign_external(__s); 28280b57cec5SDimitry Andric} 28290b57cec5SDimitry Andric// append 28300b57cec5SDimitry Andric 28310b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2832cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2833cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n) { 28345f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::append received nullptr"); 28350b57cec5SDimitry Andric size_type __cap = capacity(); 28360b57cec5SDimitry Andric size_type __sz = size(); 2837cb14a3feSDimitry Andric if (__cap - __sz >= __n) { 2838cb14a3feSDimitry Andric if (__n) { 28395f757f3fSDimitry Andric __annotate_increase(__n); 284081ad6265SDimitry Andric value_type* __p = std::__to_address(__get_pointer()); 28410b57cec5SDimitry Andric traits_type::copy(__p + __sz, __s, __n); 28420b57cec5SDimitry Andric __sz += __n; 28430b57cec5SDimitry Andric __set_size(__sz); 28440b57cec5SDimitry Andric traits_type::assign(__p[__sz], value_type()); 28450b57cec5SDimitry Andric } 2846cb14a3feSDimitry Andric } else 28470b57cec5SDimitry Andric __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __sz, 0, __n, __s); 28480b57cec5SDimitry Andric return *this; 28490b57cec5SDimitry Andric} 28500b57cec5SDimitry Andric 28510b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2852cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2853cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c) { 2854cb14a3feSDimitry Andric if (__n) { 28550b57cec5SDimitry Andric size_type __cap = capacity(); 28560b57cec5SDimitry Andric size_type __sz = size(); 28570b57cec5SDimitry Andric if (__cap - __sz < __n) 285806c3fb27SDimitry Andric __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0); 28595f757f3fSDimitry Andric __annotate_increase(__n); 28600b57cec5SDimitry Andric pointer __p = __get_pointer(); 286181ad6265SDimitry Andric traits_type::assign(std::__to_address(__p) + __sz, __n, __c); 28620b57cec5SDimitry Andric __sz += __n; 28630b57cec5SDimitry Andric __set_size(__sz); 28640b57cec5SDimitry Andric traits_type::assign(__p[__sz], value_type()); 28650b57cec5SDimitry Andric } 28660b57cec5SDimitry Andric return *this; 28670b57cec5SDimitry Andric} 28680b57cec5SDimitry Andric 28690b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2870bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 inline void 2871cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n) { 2872cb14a3feSDimitry Andric if (__n) { 28730b57cec5SDimitry Andric size_type __cap = capacity(); 28740b57cec5SDimitry Andric size_type __sz = size(); 28750b57cec5SDimitry Andric if (__cap - __sz < __n) 287606c3fb27SDimitry Andric __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0); 28775f757f3fSDimitry Andric __annotate_increase(__n); 28780b57cec5SDimitry Andric pointer __p = __get_pointer(); 28790b57cec5SDimitry Andric __sz += __n; 28800b57cec5SDimitry Andric __set_size(__sz); 28810b57cec5SDimitry Andric traits_type::assign(__p[__sz], value_type()); 28820b57cec5SDimitry Andric } 28830b57cec5SDimitry Andric} 28840b57cec5SDimitry Andric 28850b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2886cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c) { 28870b57cec5SDimitry Andric bool __is_short = !__is_long(); 28880b57cec5SDimitry Andric size_type __cap; 28890b57cec5SDimitry Andric size_type __sz; 2890cb14a3feSDimitry Andric if (__is_short) { 28910b57cec5SDimitry Andric __cap = __min_cap - 1; 28920b57cec5SDimitry Andric __sz = __get_short_size(); 2893cb14a3feSDimitry Andric } else { 28940b57cec5SDimitry Andric __cap = __get_long_cap() - 1; 28950b57cec5SDimitry Andric __sz = __get_long_size(); 28960b57cec5SDimitry Andric } 2897cb14a3feSDimitry Andric if (__sz == __cap) { 289806c3fb27SDimitry Andric __grow_by_without_replace(__cap, 1, __sz, __sz, 0); 28995f757f3fSDimitry Andric __annotate_increase(1); 2900349cc55cSDimitry Andric __is_short = false; // the string is always long after __grow_by 29015f757f3fSDimitry Andric } else 29025f757f3fSDimitry Andric __annotate_increase(1); 290381ad6265SDimitry Andric pointer __p = __get_pointer(); 2904cb14a3feSDimitry Andric if (__is_short) { 29050b57cec5SDimitry Andric __p = __get_short_pointer() + __sz; 29060b57cec5SDimitry Andric __set_short_size(__sz + 1); 2907cb14a3feSDimitry Andric } else { 29080b57cec5SDimitry Andric __p = __get_long_pointer() + __sz; 29090b57cec5SDimitry Andric __set_long_size(__sz + 1); 29100b57cec5SDimitry Andric } 29110b57cec5SDimitry Andric traits_type::assign(*__p, __c); 29120b57cec5SDimitry Andric traits_type::assign(*++__p, value_type()); 29130b57cec5SDimitry Andric} 29140b57cec5SDimitry Andric 29150b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 291606c3fb27SDimitry Andrictemplate <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> > 291706c3fb27SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2918cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::append(_ForwardIterator __first, _ForwardIterator __last) { 29190b57cec5SDimitry Andric size_type __sz = size(); 29200b57cec5SDimitry Andric size_type __cap = capacity(); 292181ad6265SDimitry Andric size_type __n = static_cast<size_type>(std::distance(__first, __last)); 2922cb14a3feSDimitry Andric if (__n) { 2923cb14a3feSDimitry Andric if (__string_is_trivial_iterator<_ForwardIterator>::value && !__addr_in_range(*__first)) { 29240b57cec5SDimitry Andric if (__cap - __sz < __n) 292506c3fb27SDimitry Andric __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0); 29265f757f3fSDimitry Andric __annotate_increase(__n); 29270fca6ea1SDimitry Andric auto __end = __copy_non_overlapping_range(__first, __last, std::__to_address(__get_pointer() + __sz)); 29280fca6ea1SDimitry Andric traits_type::assign(*__end, value_type()); 29290b57cec5SDimitry Andric __set_size(__sz + __n); 2930cb14a3feSDimitry Andric } else { 2931fe6060f1SDimitry Andric const basic_string __temp(__first, __last, __alloc()); 2932fe6060f1SDimitry Andric append(__temp.data(), __temp.size()); 2933fe6060f1SDimitry Andric } 29340b57cec5SDimitry Andric } 29350b57cec5SDimitry Andric return *this; 29360b57cec5SDimitry Andric} 29370b57cec5SDimitry Andric 29380b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2939cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2940cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, size_type __pos, size_type __n) { 29410b57cec5SDimitry Andric size_type __sz = __str.size(); 29420b57cec5SDimitry Andric if (__pos > __sz) 294304eeddc0SDimitry Andric __throw_out_of_range(); 294481ad6265SDimitry Andric return append(__str.data() + __pos, std::min(__n, __sz - __pos)); 29450b57cec5SDimitry Andric} 29460b57cec5SDimitry Andric 29470b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 294806c3fb27SDimitry Andrictemplate <class _Tp, 294906c3fb27SDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 295006c3fb27SDimitry Andric !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 295106c3fb27SDimitry Andric int> > 295206c3fb27SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 295306c3fb27SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::append(const _Tp& __t, size_type __pos, size_type __n) { 29540b57cec5SDimitry Andric __self_view __sv = __t; 29550b57cec5SDimitry Andric size_type __sz = __sv.size(); 29560b57cec5SDimitry Andric if (__pos > __sz) 295704eeddc0SDimitry Andric __throw_out_of_range(); 295881ad6265SDimitry Andric return append(__sv.data() + __pos, std::min(__n, __sz - __pos)); 29590b57cec5SDimitry Andric} 29600b57cec5SDimitry Andric 29610b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2962cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2963cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s) { 29645f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::append received nullptr"); 29650b57cec5SDimitry Andric return append(__s, traits_type::length(__s)); 29660b57cec5SDimitry Andric} 29670b57cec5SDimitry Andric 29680b57cec5SDimitry Andric// insert 29690b57cec5SDimitry Andric 29700b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2971cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2972cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n) { 29735f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::insert received nullptr"); 29740b57cec5SDimitry Andric size_type __sz = size(); 29750b57cec5SDimitry Andric if (__pos > __sz) 297604eeddc0SDimitry Andric __throw_out_of_range(); 29770b57cec5SDimitry Andric size_type __cap = capacity(); 2978cb14a3feSDimitry Andric if (__cap - __sz >= __n) { 2979cb14a3feSDimitry Andric if (__n) { 29805f757f3fSDimitry Andric __annotate_increase(__n); 298181ad6265SDimitry Andric value_type* __p = std::__to_address(__get_pointer()); 29820b57cec5SDimitry Andric size_type __n_move = __sz - __pos; 2983cb14a3feSDimitry Andric if (__n_move != 0) { 29845f757f3fSDimitry Andric if (std::__is_pointer_in_range(__p + __pos, __p + __sz, __s)) 29850b57cec5SDimitry Andric __s += __n; 29860b57cec5SDimitry Andric traits_type::move(__p + __pos + __n, __p + __pos, __n_move); 29870b57cec5SDimitry Andric } 29880b57cec5SDimitry Andric traits_type::move(__p + __pos, __s, __n); 29890b57cec5SDimitry Andric __sz += __n; 29900b57cec5SDimitry Andric __set_size(__sz); 29910b57cec5SDimitry Andric traits_type::assign(__p[__sz], value_type()); 29920b57cec5SDimitry Andric } 2993cb14a3feSDimitry Andric } else 29940b57cec5SDimitry Andric __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s); 29950b57cec5SDimitry Andric return *this; 29960b57cec5SDimitry Andric} 29970b57cec5SDimitry Andric 29980b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2999cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 3000cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n, value_type __c) { 30010b57cec5SDimitry Andric size_type __sz = size(); 30020b57cec5SDimitry Andric if (__pos > __sz) 300304eeddc0SDimitry Andric __throw_out_of_range(); 3004cb14a3feSDimitry Andric if (__n) { 30050b57cec5SDimitry Andric size_type __cap = capacity(); 30060b57cec5SDimitry Andric value_type* __p; 3007cb14a3feSDimitry Andric if (__cap - __sz >= __n) { 30085f757f3fSDimitry Andric __annotate_increase(__n); 300981ad6265SDimitry Andric __p = std::__to_address(__get_pointer()); 30100b57cec5SDimitry Andric size_type __n_move = __sz - __pos; 30110b57cec5SDimitry Andric if (__n_move != 0) 30120b57cec5SDimitry Andric traits_type::move(__p + __pos + __n, __p + __pos, __n_move); 3013cb14a3feSDimitry Andric } else { 301406c3fb27SDimitry Andric __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n); 301581ad6265SDimitry Andric __p = std::__to_address(__get_long_pointer()); 30160b57cec5SDimitry Andric } 30170b57cec5SDimitry Andric traits_type::assign(__p + __pos, __n, __c); 30180b57cec5SDimitry Andric __sz += __n; 30190b57cec5SDimitry Andric __set_size(__sz); 30200b57cec5SDimitry Andric traits_type::assign(__p[__sz], value_type()); 30210b57cec5SDimitry Andric } 30220b57cec5SDimitry Andric return *this; 30230b57cec5SDimitry Andric} 30240b57cec5SDimitry Andric 30250b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 302606c3fb27SDimitry Andrictemplate <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> > 302706c3fb27SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator 3028cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last) { 30290b57cec5SDimitry Andric const basic_string __temp(__first, __last, __alloc()); 30300b57cec5SDimitry Andric return insert(__pos, __temp.data(), __temp.data() + __temp.size()); 30310b57cec5SDimitry Andric} 30320b57cec5SDimitry Andric 30330b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 303406c3fb27SDimitry Andrictemplate <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> > 303506c3fb27SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator 3036cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::insert( 3037cb14a3feSDimitry Andric const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last) { 303806c3fb27SDimitry Andric auto __n = static_cast<size_type>(std::distance(__first, __last)); 303906c3fb27SDimitry Andric return __insert_with_size(__pos, __first, __last, __n); 304006c3fb27SDimitry Andric} 30410eae32dcSDimitry Andric 304206c3fb27SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 304306c3fb27SDimitry Andrictemplate <class _Iterator, class _Sentinel> 3044cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator 304506c3fb27SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__insert_with_size( 304606c3fb27SDimitry Andric const_iterator __pos, _Iterator __first, _Sentinel __last, size_type __n) { 30470b57cec5SDimitry Andric size_type __ip = static_cast<size_type>(__pos - begin()); 304881ad6265SDimitry Andric if (__n == 0) 304981ad6265SDimitry Andric return begin() + __ip; 305081ad6265SDimitry Andric 3051cb14a3feSDimitry Andric if (__string_is_trivial_iterator<_Iterator>::value && !__addr_in_range(*__first)) { 305281ad6265SDimitry Andric return __insert_from_safe_copy(__n, __ip, __first, __last); 3053cb14a3feSDimitry Andric } else { 305406c3fb27SDimitry Andric const basic_string __temp(__init_with_sentinel_tag(), __first, __last, __alloc()); 305581ad6265SDimitry Andric return __insert_from_safe_copy(__n, __ip, __temp.begin(), __temp.end()); 3056fe6060f1SDimitry Andric } 3057fe6060f1SDimitry Andric} 30580b57cec5SDimitry Andric 30590b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3060cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 3061cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::insert( 3062cb14a3feSDimitry Andric size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n) { 30630b57cec5SDimitry Andric size_type __str_sz = __str.size(); 30640b57cec5SDimitry Andric if (__pos2 > __str_sz) 306504eeddc0SDimitry Andric __throw_out_of_range(); 306681ad6265SDimitry Andric return insert(__pos1, __str.data() + __pos2, std::min(__n, __str_sz - __pos2)); 30670b57cec5SDimitry Andric} 30680b57cec5SDimitry Andric 30690b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 307006c3fb27SDimitry Andrictemplate <class _Tp, 307106c3fb27SDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 307206c3fb27SDimitry Andric !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 307306c3fb27SDimitry Andric int> > 307406c3fb27SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 307506c3fb27SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n) { 30760b57cec5SDimitry Andric __self_view __sv = __t; 30770b57cec5SDimitry Andric size_type __str_sz = __sv.size(); 30780b57cec5SDimitry Andric if (__pos2 > __str_sz) 307904eeddc0SDimitry Andric __throw_out_of_range(); 308081ad6265SDimitry Andric return insert(__pos1, __sv.data() + __pos2, std::min(__n, __str_sz - __pos2)); 30810b57cec5SDimitry Andric} 30820b57cec5SDimitry Andric 30830b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3084cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 3085cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s) { 30865f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::insert received nullptr"); 30870b57cec5SDimitry Andric return insert(__pos, __s, traits_type::length(__s)); 30880b57cec5SDimitry Andric} 30890b57cec5SDimitry Andric 30900b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3091cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator 3092cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c) { 30930b57cec5SDimitry Andric size_type __ip = static_cast<size_type>(__pos - begin()); 30940b57cec5SDimitry Andric size_type __sz = size(); 30950b57cec5SDimitry Andric size_type __cap = capacity(); 30960b57cec5SDimitry Andric value_type* __p; 3097cb14a3feSDimitry Andric if (__cap == __sz) { 309806c3fb27SDimitry Andric __grow_by_without_replace(__cap, 1, __sz, __ip, 0, 1); 309981ad6265SDimitry Andric __p = std::__to_address(__get_long_pointer()); 3100cb14a3feSDimitry Andric } else { 31015f757f3fSDimitry Andric __annotate_increase(1); 310281ad6265SDimitry Andric __p = std::__to_address(__get_pointer()); 31030b57cec5SDimitry Andric size_type __n_move = __sz - __ip; 31040b57cec5SDimitry Andric if (__n_move != 0) 31050b57cec5SDimitry Andric traits_type::move(__p + __ip + 1, __p + __ip, __n_move); 31060b57cec5SDimitry Andric } 31070b57cec5SDimitry Andric traits_type::assign(__p[__ip], __c); 31080b57cec5SDimitry Andric traits_type::assign(__p[++__sz], value_type()); 31090b57cec5SDimitry Andric __set_size(__sz); 31100b57cec5SDimitry Andric return begin() + static_cast<difference_type>(__ip); 31110b57cec5SDimitry Andric} 31120b57cec5SDimitry Andric 31130b57cec5SDimitry Andric// replace 31140b57cec5SDimitry Andric 31150b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3116cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 3117cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::replace( 3118cb14a3feSDimitry Andric size_type __pos, size_type __n1, const value_type* __s, size_type __n2) 3119cb14a3feSDimitry Andric _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK { 31205f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__n2 == 0 || __s != nullptr, "string::replace received nullptr"); 31210b57cec5SDimitry Andric size_type __sz = size(); 31220b57cec5SDimitry Andric if (__pos > __sz) 312304eeddc0SDimitry Andric __throw_out_of_range(); 312481ad6265SDimitry Andric __n1 = std::min(__n1, __sz - __pos); 31250b57cec5SDimitry Andric size_type __cap = capacity(); 3126cb14a3feSDimitry Andric if (__cap - __sz + __n1 >= __n2) { 312781ad6265SDimitry Andric value_type* __p = std::__to_address(__get_pointer()); 3128cb14a3feSDimitry Andric if (__n1 != __n2) { 31295f757f3fSDimitry Andric if (__n2 > __n1) 31305f757f3fSDimitry Andric __annotate_increase(__n2 - __n1); 31310b57cec5SDimitry Andric size_type __n_move = __sz - __pos - __n1; 3132cb14a3feSDimitry Andric if (__n_move != 0) { 3133cb14a3feSDimitry Andric if (__n1 > __n2) { 31340b57cec5SDimitry Andric traits_type::move(__p + __pos, __s, __n2); 31350b57cec5SDimitry Andric traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move); 31360eae32dcSDimitry Andric return __null_terminate_at(__p, __sz + (__n2 - __n1)); 31370b57cec5SDimitry Andric } 3138cb14a3feSDimitry Andric if (std::__is_pointer_in_range(__p + __pos + 1, __p + __sz, __s)) { 31390b57cec5SDimitry Andric if (__p + __pos + __n1 <= __s) 31400b57cec5SDimitry Andric __s += __n2 - __n1; 31410b57cec5SDimitry Andric else // __p + __pos < __s < __p + __pos + __n1 31420b57cec5SDimitry Andric { 31430b57cec5SDimitry Andric traits_type::move(__p + __pos, __s, __n1); 31440b57cec5SDimitry Andric __pos += __n1; 31450b57cec5SDimitry Andric __s += __n2; 31460b57cec5SDimitry Andric __n2 -= __n1; 31470b57cec5SDimitry Andric __n1 = 0; 31480b57cec5SDimitry Andric } 31490b57cec5SDimitry Andric } 31500b57cec5SDimitry Andric traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move); 31510b57cec5SDimitry Andric } 31520b57cec5SDimitry Andric } 31530b57cec5SDimitry Andric traits_type::move(__p + __pos, __s, __n2); 31540eae32dcSDimitry Andric return __null_terminate_at(__p, __sz + (__n2 - __n1)); 3155cb14a3feSDimitry Andric } else 31560b57cec5SDimitry Andric __grow_by_and_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2, __s); 31570b57cec5SDimitry Andric return *this; 31580b57cec5SDimitry Andric} 31590b57cec5SDimitry Andric 31600b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3161cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 3162cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, size_type __n2, value_type __c) { 31630b57cec5SDimitry Andric size_type __sz = size(); 31640b57cec5SDimitry Andric if (__pos > __sz) 316504eeddc0SDimitry Andric __throw_out_of_range(); 316681ad6265SDimitry Andric __n1 = std::min(__n1, __sz - __pos); 31670b57cec5SDimitry Andric size_type __cap = capacity(); 31680b57cec5SDimitry Andric value_type* __p; 31695f757f3fSDimitry Andric if (__cap - __sz + __n1 >= __n2) { 317081ad6265SDimitry Andric __p = std::__to_address(__get_pointer()); 31715f757f3fSDimitry Andric if (__n1 != __n2) { 31725f757f3fSDimitry Andric if (__n2 > __n1) 31735f757f3fSDimitry Andric __annotate_increase(__n2 - __n1); 31740b57cec5SDimitry Andric size_type __n_move = __sz - __pos - __n1; 31750b57cec5SDimitry Andric if (__n_move != 0) 31760b57cec5SDimitry Andric traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move); 31770b57cec5SDimitry Andric } 31785f757f3fSDimitry Andric } else { 317906c3fb27SDimitry Andric __grow_by_without_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2); 318081ad6265SDimitry Andric __p = std::__to_address(__get_long_pointer()); 31810b57cec5SDimitry Andric } 31820b57cec5SDimitry Andric traits_type::assign(__p + __pos, __n2, __c); 31830eae32dcSDimitry Andric return __null_terminate_at(__p, __sz - (__n1 - __n2)); 31840b57cec5SDimitry Andric} 31850b57cec5SDimitry Andric 31860b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 318706c3fb27SDimitry Andrictemplate <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> > 318806c3fb27SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 3189cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::replace( 3190cb14a3feSDimitry Andric const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2) { 31910b57cec5SDimitry Andric const basic_string __temp(__j1, __j2, __alloc()); 319204eeddc0SDimitry Andric return replace(__i1, __i2, __temp); 31930b57cec5SDimitry Andric} 31940b57cec5SDimitry Andric 31950b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3196cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 3197cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::replace( 3198cb14a3feSDimitry Andric size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2) { 31990b57cec5SDimitry Andric size_type __str_sz = __str.size(); 32000b57cec5SDimitry Andric if (__pos2 > __str_sz) 320104eeddc0SDimitry Andric __throw_out_of_range(); 320281ad6265SDimitry Andric return replace(__pos1, __n1, __str.data() + __pos2, std::min(__n2, __str_sz - __pos2)); 32030b57cec5SDimitry Andric} 32040b57cec5SDimitry Andric 32050b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 320606c3fb27SDimitry Andrictemplate <class _Tp, 320706c3fb27SDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 320806c3fb27SDimitry Andric !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 320906c3fb27SDimitry Andric int> > 321006c3fb27SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 321106c3fb27SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::replace( 321206c3fb27SDimitry Andric size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2) { 32130b57cec5SDimitry Andric __self_view __sv = __t; 32140b57cec5SDimitry Andric size_type __str_sz = __sv.size(); 32150b57cec5SDimitry Andric if (__pos2 > __str_sz) 321604eeddc0SDimitry Andric __throw_out_of_range(); 321781ad6265SDimitry Andric return replace(__pos1, __n1, __sv.data() + __pos2, std::min(__n2, __str_sz - __pos2)); 32180b57cec5SDimitry Andric} 32190b57cec5SDimitry Andric 32200b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3221cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 3222cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s) { 32235f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::replace received nullptr"); 32240b57cec5SDimitry Andric return replace(__pos, __n1, __s, traits_type::length(__s)); 32250b57cec5SDimitry Andric} 32260b57cec5SDimitry Andric 32270b57cec5SDimitry Andric// erase 32280b57cec5SDimitry Andric 32295ffd83dbSDimitry Andric// 'externally instantiated' erase() implementation, called when __n != npos. 32305ffd83dbSDimitry Andric// Does not check __pos against size() 32310b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3232cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE void 3233cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move(size_type __pos, size_type __n) { 3234cb14a3feSDimitry Andric if (__n) { 32355ffd83dbSDimitry Andric size_type __sz = size(); 323681ad6265SDimitry Andric value_type* __p = std::__to_address(__get_pointer()); 323781ad6265SDimitry Andric __n = std::min(__n, __sz - __pos); 32380b57cec5SDimitry Andric size_type __n_move = __sz - __pos - __n; 32390b57cec5SDimitry Andric if (__n_move != 0) 32400b57cec5SDimitry Andric traits_type::move(__p + __pos, __p + __pos + __n, __n_move); 32410eae32dcSDimitry Andric __null_terminate_at(__p, __sz - __n); 32420b57cec5SDimitry Andric } 32435ffd83dbSDimitry Andric} 32445ffd83dbSDimitry Andric 32455ffd83dbSDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3246cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 3247cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, size_type __n) { 324804eeddc0SDimitry Andric if (__pos > size()) 324904eeddc0SDimitry Andric __throw_out_of_range(); 32505ffd83dbSDimitry Andric if (__n == npos) { 32515ffd83dbSDimitry Andric __erase_to_end(__pos); 32525ffd83dbSDimitry Andric } else { 32535ffd83dbSDimitry Andric __erase_external_with_move(__pos, __n); 32545ffd83dbSDimitry Andric } 32550b57cec5SDimitry Andric return *this; 32560b57cec5SDimitry Andric} 32570b57cec5SDimitry Andric 32580b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3259cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator 3260cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos) { 326106c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 326206c3fb27SDimitry Andric __pos != end(), "string::erase(iterator) called with a non-dereferenceable iterator"); 32630b57cec5SDimitry Andric iterator __b = begin(); 32640b57cec5SDimitry Andric size_type __r = static_cast<size_type>(__pos - __b); 32650b57cec5SDimitry Andric erase(__r, 1); 32660b57cec5SDimitry Andric return __b + static_cast<difference_type>(__r); 32670b57cec5SDimitry Andric} 32680b57cec5SDimitry Andric 32690b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3270cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator 3271cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last) { 327206c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE(__first <= __last, "string::erase(first, last) called with invalid range"); 32730b57cec5SDimitry Andric iterator __b = begin(); 32740b57cec5SDimitry Andric size_type __r = static_cast<size_type>(__first - __b); 32750b57cec5SDimitry Andric erase(__r, static_cast<size_type>(__last - __first)); 32760b57cec5SDimitry Andric return __b + static_cast<difference_type>(__r); 32770b57cec5SDimitry Andric} 32780b57cec5SDimitry Andric 32790b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3280cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::pop_back() { 328106c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::pop_back(): string is already empty"); 32820eae32dcSDimitry Andric __erase_to_end(size() - 1); 32830b57cec5SDimitry Andric} 32840b57cec5SDimitry Andric 32850b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3286cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT { 32875f757f3fSDimitry Andric size_type __old_size = size(); 3288cb14a3feSDimitry Andric if (__is_long()) { 32890b57cec5SDimitry Andric traits_type::assign(*__get_long_pointer(), value_type()); 32900b57cec5SDimitry Andric __set_long_size(0); 3291cb14a3feSDimitry Andric } else { 32920b57cec5SDimitry Andric traits_type::assign(*__get_short_pointer(), value_type()); 32930b57cec5SDimitry Andric __set_short_size(0); 32940b57cec5SDimitry Andric } 32955f757f3fSDimitry Andric __annotate_shrink(__old_size); 32960b57cec5SDimitry Andric} 32970b57cec5SDimitry Andric 32980b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3299cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c) { 33000b57cec5SDimitry Andric size_type __sz = size(); 33010b57cec5SDimitry Andric if (__n > __sz) 33020b57cec5SDimitry Andric append(__n - __sz, __c); 33030b57cec5SDimitry Andric else 33040b57cec5SDimitry Andric __erase_to_end(__n); 33050b57cec5SDimitry Andric} 33060b57cec5SDimitry Andric 33070b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3308bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 inline void 3309cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__resize_default_init(size_type __n) { 33100b57cec5SDimitry Andric size_type __sz = size(); 33110b57cec5SDimitry Andric if (__n > __sz) { 33120b57cec5SDimitry Andric __append_default_init(__n - __sz); 33130b57cec5SDimitry Andric } else 33140b57cec5SDimitry Andric __erase_to_end(__n); 33150b57cec5SDimitry Andric} 33160b57cec5SDimitry Andric 33170b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3318cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacity) { 3319e8d8bef9SDimitry Andric if (__requested_capacity > max_size()) 332004eeddc0SDimitry Andric __throw_length_error(); 3321e8d8bef9SDimitry Andric 332204eeddc0SDimitry Andric // Make sure reserve(n) never shrinks. This is technically only required in C++20 332304eeddc0SDimitry Andric // and later (since P0966R1), however we provide consistent behavior in all Standard 332404eeddc0SDimitry Andric // modes because this function is instantiated in the shared library. 332504eeddc0SDimitry Andric if (__requested_capacity <= capacity()) 332604eeddc0SDimitry Andric return; 3327e8d8bef9SDimitry Andric 332881ad6265SDimitry Andric size_type __target_capacity = std::max(__requested_capacity, size()); 3329e8d8bef9SDimitry Andric __target_capacity = __recommend(__target_capacity); 3330cb14a3feSDimitry Andric if (__target_capacity == capacity()) 3331cb14a3feSDimitry Andric return; 3332e8d8bef9SDimitry Andric 3333e8d8bef9SDimitry Andric __shrink_or_extend(__target_capacity); 3334e8d8bef9SDimitry Andric} 3335e8d8bef9SDimitry Andric 3336e8d8bef9SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3337cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::shrink_to_fit() _NOEXCEPT { 3338e8d8bef9SDimitry Andric size_type __target_capacity = __recommend(size()); 3339cb14a3feSDimitry Andric if (__target_capacity == capacity()) 3340cb14a3feSDimitry Andric return; 3341e8d8bef9SDimitry Andric 3342e8d8bef9SDimitry Andric __shrink_or_extend(__target_capacity); 3343e8d8bef9SDimitry Andric} 3344e8d8bef9SDimitry Andric 3345e8d8bef9SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3346cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 void 3347cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target_capacity) { 33485f757f3fSDimitry Andric __annotate_delete(); 33490b57cec5SDimitry Andric size_type __cap = capacity(); 33500b57cec5SDimitry Andric size_type __sz = size(); 3351e8d8bef9SDimitry Andric 33520b57cec5SDimitry Andric pointer __new_data, __p; 33530b57cec5SDimitry Andric bool __was_long, __now_long; 3354cb14a3feSDimitry Andric if (__fits_in_sso(__target_capacity)) { 33550b57cec5SDimitry Andric __was_long = true; 33560b57cec5SDimitry Andric __now_long = false; 33570b57cec5SDimitry Andric __new_data = __get_short_pointer(); 33580b57cec5SDimitry Andric __p = __get_long_pointer(); 3359cb14a3feSDimitry Andric } else { 336081ad6265SDimitry Andric if (__target_capacity > __cap) { 3361*36b606aeSDimitry Andric // Extend 3362*36b606aeSDimitry Andric // - called from reserve should propagate the exception thrown. 336381ad6265SDimitry Andric auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1); 336481ad6265SDimitry Andric __new_data = __allocation.ptr; 336581ad6265SDimitry Andric __target_capacity = __allocation.count - 1; 3366cb14a3feSDimitry Andric } else { 3367*36b606aeSDimitry Andric // Shrink 3368*36b606aeSDimitry Andric // - called from shrink_to_fit should not throw. 3369*36b606aeSDimitry Andric // - called from reserve may throw but is not required to. 337006c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 3371cb14a3feSDimitry Andric try { 337206c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 337381ad6265SDimitry Andric auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1); 3374*36b606aeSDimitry Andric 3375*36b606aeSDimitry Andric // The Standard mandates shrink_to_fit() does not increase the capacity. 3376*36b606aeSDimitry Andric // With equal capacity keep the existing buffer. This avoids extra work 3377*36b606aeSDimitry Andric // due to swapping the elements. 3378*36b606aeSDimitry Andric if (__allocation.count - 1 > __target_capacity) { 3379*36b606aeSDimitry Andric __alloc_traits::deallocate(__alloc(), __allocation.ptr, __allocation.count); 3380*36b606aeSDimitry Andric __annotate_new(__sz); // Undoes the __annotate_delete() 3381*36b606aeSDimitry Andric return; 3382*36b606aeSDimitry Andric } 338381ad6265SDimitry Andric __new_data = __allocation.ptr; 338481ad6265SDimitry Andric __target_capacity = __allocation.count - 1; 338506c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 3386cb14a3feSDimitry Andric } catch (...) { 33870b57cec5SDimitry Andric return; 33880b57cec5SDimitry Andric } 338906c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 33900b57cec5SDimitry Andric } 339181ad6265SDimitry Andric __begin_lifetime(__new_data, __target_capacity + 1); 33920b57cec5SDimitry Andric __now_long = true; 33930b57cec5SDimitry Andric __was_long = __is_long(); 33940b57cec5SDimitry Andric __p = __get_pointer(); 33950b57cec5SDimitry Andric } 3396cb14a3feSDimitry Andric traits_type::copy(std::__to_address(__new_data), std::__to_address(__p), size() + 1); 33970b57cec5SDimitry Andric if (__was_long) 33980b57cec5SDimitry Andric __alloc_traits::deallocate(__alloc(), __p, __cap + 1); 3399cb14a3feSDimitry Andric if (__now_long) { 3400e8d8bef9SDimitry Andric __set_long_cap(__target_capacity + 1); 34010b57cec5SDimitry Andric __set_long_size(__sz); 34020b57cec5SDimitry Andric __set_long_pointer(__new_data); 3403cb14a3feSDimitry Andric } else 34040b57cec5SDimitry Andric __set_short_size(__sz); 34055f757f3fSDimitry Andric __annotate_new(__sz); 34060b57cec5SDimitry Andric} 34070b57cec5SDimitry Andric 34080b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3409cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::const_reference 3410cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const { 34110b57cec5SDimitry Andric if (__n >= size()) 341204eeddc0SDimitry Andric __throw_out_of_range(); 34130b57cec5SDimitry Andric return (*this)[__n]; 34140b57cec5SDimitry Andric} 34150b57cec5SDimitry Andric 34160b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3417cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::reference 3418cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::at(size_type __n) { 34190b57cec5SDimitry Andric if (__n >= size()) 342004eeddc0SDimitry Andric __throw_out_of_range(); 34210b57cec5SDimitry Andric return (*this)[__n]; 34220b57cec5SDimitry Andric} 34230b57cec5SDimitry Andric 34240b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3425cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3426cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n, size_type __pos) const { 34270b57cec5SDimitry Andric size_type __sz = size(); 34280b57cec5SDimitry Andric if (__pos > __sz) 342904eeddc0SDimitry Andric __throw_out_of_range(); 343081ad6265SDimitry Andric size_type __rlen = std::min(__n, __sz - __pos); 34310b57cec5SDimitry Andric traits_type::copy(__s, data() + __pos, __rlen); 34320b57cec5SDimitry Andric return __rlen; 34330b57cec5SDimitry Andric} 34340b57cec5SDimitry Andric 34350b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3436cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str) 34370b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14 34380b57cec5SDimitry Andric _NOEXCEPT 34390b57cec5SDimitry Andric#else 34400fca6ea1SDimitry Andric _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>) 34410b57cec5SDimitry Andric#endif 34420b57cec5SDimitry Andric{ 344306c3fb27SDimitry Andric _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR( 3444cb14a3feSDimitry Andric __alloc_traits::propagate_on_container_swap::value || __alloc_traits::is_always_equal::value || 3445cb14a3feSDimitry Andric __alloc() == __str.__alloc(), 3446cb14a3feSDimitry Andric "swapping non-equal allocators"); 34475f757f3fSDimitry Andric if (!__is_long()) 34485f757f3fSDimitry Andric __annotate_delete(); 34495f757f3fSDimitry Andric if (this != &__str && !__str.__is_long()) 34505f757f3fSDimitry Andric __str.__annotate_delete(); 345181ad6265SDimitry Andric std::swap(__r_.first(), __str.__r_.first()); 345281ad6265SDimitry Andric std::__swap_allocator(__alloc(), __str.__alloc()); 34535f757f3fSDimitry Andric if (!__is_long()) 34545f757f3fSDimitry Andric __annotate_new(__get_short_size()); 34555f757f3fSDimitry Andric if (this != &__str && !__str.__is_long()) 34565f757f3fSDimitry Andric __str.__annotate_new(__str.__get_short_size()); 34570b57cec5SDimitry Andric} 34580b57cec5SDimitry Andric 34590b57cec5SDimitry Andric// find 34600b57cec5SDimitry Andric 34610b57cec5SDimitry Andrictemplate <class _Traits> 3462cb14a3feSDimitry Andricstruct _LIBCPP_HIDDEN __traits_eq { 34630b57cec5SDimitry Andric typedef typename _Traits::char_type char_type; 3464cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool operator()(const char_type& __x, const char_type& __y) _NOEXCEPT { 3465cb14a3feSDimitry Andric return _Traits::eq(__x, __y); 3466cb14a3feSDimitry Andric } 34670b57cec5SDimitry Andric}; 34680b57cec5SDimitry Andric 34690b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3470cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3471cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT { 34725f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find(): received nullptr"); 3473cb14a3feSDimitry Andric return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); 34740b57cec5SDimitry Andric} 34750b57cec5SDimitry Andric 34760b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3477cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3478cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str, size_type __pos) const _NOEXCEPT { 3479cb14a3feSDimitry Andric return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __str.data(), __pos, __str.size()); 34800b57cec5SDimitry Andric} 34810b57cec5SDimitry Andric 34820b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 348306c3fb27SDimitry Andrictemplate <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 348406c3fb27SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3485cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find(const _Tp& __t, size_type __pos) const _NOEXCEPT { 34860b57cec5SDimitry Andric __self_view __sv = __t; 3487cb14a3feSDimitry Andric return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __sv.data(), __pos, __sv.size()); 34880b57cec5SDimitry Andric} 34890b57cec5SDimitry Andric 34900b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3491cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3492cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, size_type __pos) const _NOEXCEPT { 34935f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find(): received nullptr"); 3494cb14a3feSDimitry Andric return std::__str_find<value_type, size_type, traits_type, npos>( 3495cb14a3feSDimitry Andric data(), size(), __s, __pos, traits_type::length(__s)); 34960b57cec5SDimitry Andric} 34970b57cec5SDimitry Andric 34980b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3499cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3500cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find(value_type __c, size_type __pos) const _NOEXCEPT { 3501cb14a3feSDimitry Andric return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos); 35020b57cec5SDimitry Andric} 35030b57cec5SDimitry Andric 35040b57cec5SDimitry Andric// rfind 35050b57cec5SDimitry Andric 35060b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3507cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3508cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::rfind( 3509cb14a3feSDimitry Andric const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT { 35105f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::rfind(): received nullptr"); 3511cb14a3feSDimitry Andric return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); 35120b57cec5SDimitry Andric} 35130b57cec5SDimitry Andric 35140b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3515cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3516cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str, size_type __pos) const _NOEXCEPT { 3517cb14a3feSDimitry Andric return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __str.data(), __pos, __str.size()); 35180b57cec5SDimitry Andric} 35190b57cec5SDimitry Andric 35200b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 352106c3fb27SDimitry Andrictemplate <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 352206c3fb27SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3523cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::rfind(const _Tp& __t, size_type __pos) const _NOEXCEPT { 35240b57cec5SDimitry Andric __self_view __sv = __t; 3525cb14a3feSDimitry Andric return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __sv.data(), __pos, __sv.size()); 35260b57cec5SDimitry Andric} 35270b57cec5SDimitry Andric 35280b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3529cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3530cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, size_type __pos) const _NOEXCEPT { 35315f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::rfind(): received nullptr"); 3532cb14a3feSDimitry Andric return std::__str_rfind<value_type, size_type, traits_type, npos>( 3533cb14a3feSDimitry Andric data(), size(), __s, __pos, traits_type::length(__s)); 35340b57cec5SDimitry Andric} 35350b57cec5SDimitry Andric 35360b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3537cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3538cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c, size_type __pos) const _NOEXCEPT { 3539cb14a3feSDimitry Andric return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos); 35400b57cec5SDimitry Andric} 35410b57cec5SDimitry Andric 35420b57cec5SDimitry Andric// find_first_of 35430b57cec5SDimitry Andric 35440b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3545cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3546cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_first_of( 3547cb14a3feSDimitry Andric const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT { 35485f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr"); 3549cb14a3feSDimitry Andric return std::__str_find_first_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); 35500b57cec5SDimitry Andric} 35510b57cec5SDimitry Andric 35520b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3553cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3554cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str, size_type __pos) const _NOEXCEPT { 3555cb14a3feSDimitry Andric return std::__str_find_first_of<value_type, size_type, traits_type, npos>( 3556cb14a3feSDimitry Andric data(), size(), __str.data(), __pos, __str.size()); 35570b57cec5SDimitry Andric} 35580b57cec5SDimitry Andric 35590b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 356006c3fb27SDimitry Andrictemplate <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 356106c3fb27SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3562cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_first_of(const _Tp& __t, size_type __pos) const _NOEXCEPT { 35630b57cec5SDimitry Andric __self_view __sv = __t; 3564cb14a3feSDimitry Andric return std::__str_find_first_of<value_type, size_type, traits_type, npos>( 3565cb14a3feSDimitry Andric data(), size(), __sv.data(), __pos, __sv.size()); 35660b57cec5SDimitry Andric} 35670b57cec5SDimitry Andric 35680b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3569cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3570cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, size_type __pos) const _NOEXCEPT { 35715f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_first_of(): received nullptr"); 3572cb14a3feSDimitry Andric return std::__str_find_first_of<value_type, size_type, traits_type, npos>( 3573cb14a3feSDimitry Andric data(), size(), __s, __pos, traits_type::length(__s)); 35740b57cec5SDimitry Andric} 35750b57cec5SDimitry Andric 35760b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3577cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3578cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c, size_type __pos) const _NOEXCEPT { 35790b57cec5SDimitry Andric return find(__c, __pos); 35800b57cec5SDimitry Andric} 35810b57cec5SDimitry Andric 35820b57cec5SDimitry Andric// find_last_of 35830b57cec5SDimitry Andric 35840b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3585cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3586cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_last_of( 3587cb14a3feSDimitry Andric const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT { 35885f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr"); 3589cb14a3feSDimitry Andric return std::__str_find_last_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); 35900b57cec5SDimitry Andric} 35910b57cec5SDimitry Andric 35920b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3593cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3594cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str, size_type __pos) const _NOEXCEPT { 3595cb14a3feSDimitry Andric return std::__str_find_last_of<value_type, size_type, traits_type, npos>( 3596cb14a3feSDimitry Andric data(), size(), __str.data(), __pos, __str.size()); 35970b57cec5SDimitry Andric} 35980b57cec5SDimitry Andric 35990b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 360006c3fb27SDimitry Andrictemplate <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 360106c3fb27SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3602cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_last_of(const _Tp& __t, size_type __pos) const _NOEXCEPT { 36030b57cec5SDimitry Andric __self_view __sv = __t; 3604cb14a3feSDimitry Andric return std::__str_find_last_of<value_type, size_type, traits_type, npos>( 3605cb14a3feSDimitry Andric data(), size(), __sv.data(), __pos, __sv.size()); 36060b57cec5SDimitry Andric} 36070b57cec5SDimitry Andric 36080b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3609cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3610cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, size_type __pos) const _NOEXCEPT { 36115f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_last_of(): received nullptr"); 3612cb14a3feSDimitry Andric return std::__str_find_last_of<value_type, size_type, traits_type, npos>( 3613cb14a3feSDimitry Andric data(), size(), __s, __pos, traits_type::length(__s)); 36140b57cec5SDimitry Andric} 36150b57cec5SDimitry Andric 36160b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3617cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3618cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c, size_type __pos) const _NOEXCEPT { 36190b57cec5SDimitry Andric return rfind(__c, __pos); 36200b57cec5SDimitry Andric} 36210b57cec5SDimitry Andric 36220b57cec5SDimitry Andric// find_first_not_of 36230b57cec5SDimitry Andric 36240b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3625cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3626cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_first_not_of( 3627cb14a3feSDimitry Andric const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT { 36285f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr"); 3629cb14a3feSDimitry Andric return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); 36300b57cec5SDimitry Andric} 36310b57cec5SDimitry Andric 36320b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3633cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3634cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_first_not_of( 3635cb14a3feSDimitry Andric const basic_string& __str, size_type __pos) const _NOEXCEPT { 3636cb14a3feSDimitry Andric return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>( 3637cb14a3feSDimitry Andric data(), size(), __str.data(), __pos, __str.size()); 36380b57cec5SDimitry Andric} 36390b57cec5SDimitry Andric 36400b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 364106c3fb27SDimitry Andrictemplate <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 364206c3fb27SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3643cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const _Tp& __t, size_type __pos) const _NOEXCEPT { 36440b57cec5SDimitry Andric __self_view __sv = __t; 3645cb14a3feSDimitry Andric return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>( 3646cb14a3feSDimitry Andric data(), size(), __sv.data(), __pos, __sv.size()); 36470b57cec5SDimitry Andric} 36480b57cec5SDimitry Andric 36490b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3650cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3651cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s, size_type __pos) const _NOEXCEPT { 36525f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_first_not_of(): received nullptr"); 3653cb14a3feSDimitry Andric return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>( 3654cb14a3feSDimitry Andric data(), size(), __s, __pos, traits_type::length(__s)); 36550b57cec5SDimitry Andric} 36560b57cec5SDimitry Andric 36570b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3658cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3659cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c, size_type __pos) const _NOEXCEPT { 3660cb14a3feSDimitry Andric return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos); 36610b57cec5SDimitry Andric} 36620b57cec5SDimitry Andric 36630b57cec5SDimitry Andric// find_last_not_of 36640b57cec5SDimitry Andric 36650b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3666cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3667cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_last_not_of( 3668cb14a3feSDimitry Andric const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT { 36695f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr"); 3670cb14a3feSDimitry Andric return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); 36710b57cec5SDimitry Andric} 36720b57cec5SDimitry Andric 36730b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3674cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3675cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_last_not_of( 3676cb14a3feSDimitry Andric const basic_string& __str, size_type __pos) const _NOEXCEPT { 3677cb14a3feSDimitry Andric return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>( 3678cb14a3feSDimitry Andric data(), size(), __str.data(), __pos, __str.size()); 36790b57cec5SDimitry Andric} 36800b57cec5SDimitry Andric 36810b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 368206c3fb27SDimitry Andrictemplate <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 368306c3fb27SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3684cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const _Tp& __t, size_type __pos) const _NOEXCEPT { 36850b57cec5SDimitry Andric __self_view __sv = __t; 3686cb14a3feSDimitry Andric return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>( 3687cb14a3feSDimitry Andric data(), size(), __sv.data(), __pos, __sv.size()); 36880b57cec5SDimitry Andric} 36890b57cec5SDimitry Andric 36900b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3691cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3692cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s, size_type __pos) const _NOEXCEPT { 36935f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_last_not_of(): received nullptr"); 3694cb14a3feSDimitry Andric return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>( 3695cb14a3feSDimitry Andric data(), size(), __s, __pos, traits_type::length(__s)); 36960b57cec5SDimitry Andric} 36970b57cec5SDimitry Andric 36980b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3699cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3700cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c, size_type __pos) const _NOEXCEPT { 3701cb14a3feSDimitry Andric return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos); 37020b57cec5SDimitry Andric} 37030b57cec5SDimitry Andric 37040b57cec5SDimitry Andric// compare 37050b57cec5SDimitry Andric 37060b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 370706c3fb27SDimitry Andrictemplate <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 3708cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 int basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const _NOEXCEPT { 37090b57cec5SDimitry Andric __self_view __sv = __t; 37100b57cec5SDimitry Andric size_t __lhs_sz = size(); 37110b57cec5SDimitry Andric size_t __rhs_sz = __sv.size(); 3712cb14a3feSDimitry Andric int __result = traits_type::compare(data(), __sv.data(), std::min(__lhs_sz, __rhs_sz)); 37130b57cec5SDimitry Andric if (__result != 0) 37140b57cec5SDimitry Andric return __result; 37150b57cec5SDimitry Andric if (__lhs_sz < __rhs_sz) 37160b57cec5SDimitry Andric return -1; 37170b57cec5SDimitry Andric if (__lhs_sz > __rhs_sz) 37180b57cec5SDimitry Andric return 1; 37190b57cec5SDimitry Andric return 0; 37200b57cec5SDimitry Andric} 37210b57cec5SDimitry Andric 37220b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3723cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 int 3724cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT { 37250b57cec5SDimitry Andric return compare(__self_view(__str)); 37260b57cec5SDimitry Andric} 37270b57cec5SDimitry Andric 37280b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3729cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 int basic_string<_CharT, _Traits, _Allocator>::compare( 3730cb14a3feSDimitry Andric size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const { 37315f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr"); 37320b57cec5SDimitry Andric size_type __sz = size(); 37330b57cec5SDimitry Andric if (__pos1 > __sz || __n2 == npos) 373404eeddc0SDimitry Andric __throw_out_of_range(); 373581ad6265SDimitry Andric size_type __rlen = std::min(__n1, __sz - __pos1); 373681ad6265SDimitry Andric int __r = traits_type::compare(data() + __pos1, __s, std::min(__rlen, __n2)); 3737cb14a3feSDimitry Andric if (__r == 0) { 37380b57cec5SDimitry Andric if (__rlen < __n2) 37390b57cec5SDimitry Andric __r = -1; 37400b57cec5SDimitry Andric else if (__rlen > __n2) 37410b57cec5SDimitry Andric __r = 1; 37420b57cec5SDimitry Andric } 37430b57cec5SDimitry Andric return __r; 37440b57cec5SDimitry Andric} 37450b57cec5SDimitry Andric 37460b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 374706c3fb27SDimitry Andrictemplate <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 374806c3fb27SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 int 3749cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, const _Tp& __t) const { 37500b57cec5SDimitry Andric __self_view __sv = __t; 37510b57cec5SDimitry Andric return compare(__pos1, __n1, __sv.data(), __sv.size()); 37520b57cec5SDimitry Andric} 37530b57cec5SDimitry Andric 37540b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3755cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 int 3756cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, const basic_string& __str) const { 37570b57cec5SDimitry Andric return compare(__pos1, __n1, __str.data(), __str.size()); 37580b57cec5SDimitry Andric} 37590b57cec5SDimitry Andric 37600b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 376106c3fb27SDimitry Andrictemplate <class _Tp, 376206c3fb27SDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 376306c3fb27SDimitry Andric !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 376406c3fb27SDimitry Andric int> > 376506c3fb27SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 int basic_string<_CharT, _Traits, _Allocator>::compare( 376606c3fb27SDimitry Andric size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2) const { 37670b57cec5SDimitry Andric __self_view __sv = __t; 37680b57cec5SDimitry Andric return __self_view(*this).substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2)); 37690b57cec5SDimitry Andric} 37700b57cec5SDimitry Andric 37710b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3772cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 int basic_string<_CharT, _Traits, _Allocator>::compare( 3773cb14a3feSDimitry Andric size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2) const { 37740b57cec5SDimitry Andric return compare(__pos1, __n1, __self_view(__str), __pos2, __n2); 37750b57cec5SDimitry Andric} 37760b57cec5SDimitry Andric 37770b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3778cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 int 3779cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT { 37805f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::compare(): received nullptr"); 37810b57cec5SDimitry Andric return compare(0, npos, __s, traits_type::length(__s)); 37820b57cec5SDimitry Andric} 37830b57cec5SDimitry Andric 37840b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3785cb14a3feSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 int 3786cb14a3feSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, const value_type* __s) const { 37875f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::compare(): received nullptr"); 37880b57cec5SDimitry Andric return compare(__pos1, __n1, __s, traits_type::length(__s)); 37890b57cec5SDimitry Andric} 37900b57cec5SDimitry Andric 37910b57cec5SDimitry Andric// __invariants 37920b57cec5SDimitry Andric 37930b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3794cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 bool basic_string<_CharT, _Traits, _Allocator>::__invariants() const { 37950b57cec5SDimitry Andric if (size() > capacity()) 37960b57cec5SDimitry Andric return false; 37970b57cec5SDimitry Andric if (capacity() < __min_cap - 1) 37980b57cec5SDimitry Andric return false; 3799e8d8bef9SDimitry Andric if (data() == nullptr) 38000b57cec5SDimitry Andric return false; 380106c3fb27SDimitry Andric if (!_Traits::eq(data()[size()], value_type())) 38020b57cec5SDimitry Andric return false; 38030b57cec5SDimitry Andric return true; 38040b57cec5SDimitry Andric} 38050b57cec5SDimitry Andric 38060b57cec5SDimitry Andric// __clear_and_shrink 38070b57cec5SDimitry Andric 38080b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3809cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT { 38100b57cec5SDimitry Andric clear(); 38115f757f3fSDimitry Andric if (__is_long()) { 38125f757f3fSDimitry Andric __annotate_delete(); 38130b57cec5SDimitry Andric __alloc_traits::deallocate(__alloc(), __get_long_pointer(), capacity() + 1); 38145f757f3fSDimitry Andric __r_.first() = __rep(); 38150b57cec5SDimitry Andric } 38160b57cec5SDimitry Andric} 38170b57cec5SDimitry Andric 38180b57cec5SDimitry Andric// operator== 38190b57cec5SDimitry Andric 38200b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3821cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool 38220b57cec5SDimitry Andricoperator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3823cb14a3feSDimitry Andric const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 382406c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 20 3825bdd1243dSDimitry Andric return basic_string_view<_CharT, _Traits>(__lhs) == basic_string_view<_CharT, _Traits>(__rhs); 3826bdd1243dSDimitry Andric#else 38270b57cec5SDimitry Andric size_t __lhs_sz = __lhs.size(); 3828cb14a3feSDimitry Andric return __lhs_sz == __rhs.size() && _Traits::compare(__lhs.data(), __rhs.data(), __lhs_sz) == 0; 3829bdd1243dSDimitry Andric#endif 38300b57cec5SDimitry Andric} 38310b57cec5SDimitry Andric 38320b57cec5SDimitry Andrictemplate <class _Allocator> 3833cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool 38340b57cec5SDimitry Andricoperator==(const basic_string<char, char_traits<char>, _Allocator>& __lhs, 3835cb14a3feSDimitry Andric const basic_string<char, char_traits<char>, _Allocator>& __rhs) _NOEXCEPT { 38360fca6ea1SDimitry Andric size_t __sz = __lhs.size(); 38370fca6ea1SDimitry Andric if (__sz != __rhs.size()) 38380b57cec5SDimitry Andric return false; 38390fca6ea1SDimitry Andric return char_traits<char>::compare(__lhs.data(), __rhs.data(), __sz) == 0; 38400b57cec5SDimitry Andric} 38410b57cec5SDimitry Andric 3842bdd1243dSDimitry Andric#if _LIBCPP_STD_VER <= 17 38430b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3844cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool 3845cb14a3feSDimitry Andricoperator==(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 38460b57cec5SDimitry Andric typedef basic_string<_CharT, _Traits, _Allocator> _String; 38475f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__lhs != nullptr, "operator==(char*, basic_string): received nullptr"); 38480b57cec5SDimitry Andric size_t __lhs_len = _Traits::length(__lhs); 3849cb14a3feSDimitry Andric if (__lhs_len != __rhs.size()) 3850cb14a3feSDimitry Andric return false; 38510b57cec5SDimitry Andric return __rhs.compare(0, _String::npos, __lhs, __lhs_len) == 0; 38520b57cec5SDimitry Andric} 3853bdd1243dSDimitry Andric#endif // _LIBCPP_STD_VER <= 17 38540b57cec5SDimitry Andric 38550b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3856cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool 3857cb14a3feSDimitry Andricoperator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT { 385806c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 20 3859bdd1243dSDimitry Andric return basic_string_view<_CharT, _Traits>(__lhs) == basic_string_view<_CharT, _Traits>(__rhs); 3860bdd1243dSDimitry Andric#else 38610b57cec5SDimitry Andric typedef basic_string<_CharT, _Traits, _Allocator> _String; 38625f757f3fSDimitry Andric _LIBCPP_ASSERT_NON_NULL(__rhs != nullptr, "operator==(basic_string, char*): received nullptr"); 38630b57cec5SDimitry Andric size_t __rhs_len = _Traits::length(__rhs); 3864cb14a3feSDimitry Andric if (__rhs_len != __lhs.size()) 3865cb14a3feSDimitry Andric return false; 38660b57cec5SDimitry Andric return __lhs.compare(0, _String::npos, __rhs, __rhs_len) == 0; 3867bdd1243dSDimitry Andric#endif 3868bdd1243dSDimitry Andric} 3869bdd1243dSDimitry Andric 387006c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 20 3871bdd1243dSDimitry Andric 3872bdd1243dSDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3873cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr auto operator<=>(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3874bdd1243dSDimitry Andric const basic_string<_CharT, _Traits, _Allocator>& __rhs) noexcept { 3875bdd1243dSDimitry Andric return basic_string_view<_CharT, _Traits>(__lhs) <=> basic_string_view<_CharT, _Traits>(__rhs); 38760b57cec5SDimitry Andric} 38770b57cec5SDimitry Andric 38780b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3879bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr auto 3880bdd1243dSDimitry Andricoperator<=>(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) { 3881bdd1243dSDimitry Andric return basic_string_view<_CharT, _Traits>(__lhs) <=> basic_string_view<_CharT, _Traits>(__rhs); 3882bdd1243dSDimitry Andric} 3883bdd1243dSDimitry Andric 388406c3fb27SDimitry Andric#else // _LIBCPP_STD_VER >= 20 3885bdd1243dSDimitry Andric 3886bdd1243dSDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3887cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3888cb14a3feSDimitry Andric const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 38890b57cec5SDimitry Andric return !(__lhs == __rhs); 38900b57cec5SDimitry Andric} 38910b57cec5SDimitry Andric 38920b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3893cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool 3894cb14a3feSDimitry Andricoperator!=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 38950b57cec5SDimitry Andric return !(__lhs == __rhs); 38960b57cec5SDimitry Andric} 38970b57cec5SDimitry Andric 38980b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3899cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool 3900cb14a3feSDimitry Andricoperator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT { 39010b57cec5SDimitry Andric return !(__lhs == __rhs); 39020b57cec5SDimitry Andric} 39030b57cec5SDimitry Andric 39040b57cec5SDimitry Andric// operator< 39050b57cec5SDimitry Andric 39060b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3907cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator<(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3908cb14a3feSDimitry Andric const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 39090b57cec5SDimitry Andric return __lhs.compare(__rhs) < 0; 39100b57cec5SDimitry Andric} 39110b57cec5SDimitry Andric 39120b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3913cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool 3914cb14a3feSDimitry Andricoperator<(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT { 39150b57cec5SDimitry Andric return __lhs.compare(__rhs) < 0; 39160b57cec5SDimitry Andric} 39170b57cec5SDimitry Andric 39180b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3919cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool 3920cb14a3feSDimitry Andricoperator<(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 39210b57cec5SDimitry Andric return __rhs.compare(__lhs) > 0; 39220b57cec5SDimitry Andric} 39230b57cec5SDimitry Andric 39240b57cec5SDimitry Andric// operator> 39250b57cec5SDimitry Andric 39260b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3927cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator>(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3928cb14a3feSDimitry Andric const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 39290b57cec5SDimitry Andric return __rhs < __lhs; 39300b57cec5SDimitry Andric} 39310b57cec5SDimitry Andric 39320b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3933cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool 3934cb14a3feSDimitry Andricoperator>(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT { 39350b57cec5SDimitry Andric return __rhs < __lhs; 39360b57cec5SDimitry Andric} 39370b57cec5SDimitry Andric 39380b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3939cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool 3940cb14a3feSDimitry Andricoperator>(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 39410b57cec5SDimitry Andric return __rhs < __lhs; 39420b57cec5SDimitry Andric} 39430b57cec5SDimitry Andric 39440b57cec5SDimitry Andric// operator<= 39450b57cec5SDimitry Andric 39460b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3947cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3948cb14a3feSDimitry Andric const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 39490b57cec5SDimitry Andric return !(__rhs < __lhs); 39500b57cec5SDimitry Andric} 39510b57cec5SDimitry Andric 39520b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3953cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool 3954cb14a3feSDimitry Andricoperator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT { 39550b57cec5SDimitry Andric return !(__rhs < __lhs); 39560b57cec5SDimitry Andric} 39570b57cec5SDimitry Andric 39580b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3959cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool 3960cb14a3feSDimitry Andricoperator<=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 39610b57cec5SDimitry Andric return !(__rhs < __lhs); 39620b57cec5SDimitry Andric} 39630b57cec5SDimitry Andric 39640b57cec5SDimitry Andric// operator>= 39650b57cec5SDimitry Andric 39660b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3967cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3968cb14a3feSDimitry Andric const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 39690b57cec5SDimitry Andric return !(__lhs < __rhs); 39700b57cec5SDimitry Andric} 39710b57cec5SDimitry Andric 39720b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3973cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool 3974cb14a3feSDimitry Andricoperator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT { 39750b57cec5SDimitry Andric return !(__lhs < __rhs); 39760b57cec5SDimitry Andric} 39770b57cec5SDimitry Andric 39780b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3979cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool 3980cb14a3feSDimitry Andricoperator>=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 39810b57cec5SDimitry Andric return !(__lhs < __rhs); 39820b57cec5SDimitry Andric} 398306c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 20 39840b57cec5SDimitry Andric 39850b57cec5SDimitry Andric// operator + 39860b57cec5SDimitry Andric 39870b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3988cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 39890b57cec5SDimitry Andricoperator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3990cb14a3feSDimitry Andric const basic_string<_CharT, _Traits, _Allocator>& __rhs) { 399181ad6265SDimitry Andric using _String = basic_string<_CharT, _Traits, _Allocator>; 399281ad6265SDimitry Andric auto __lhs_sz = __lhs.size(); 399381ad6265SDimitry Andric auto __rhs_sz = __rhs.size(); 399481ad6265SDimitry Andric _String __r(__uninitialized_size_tag(), 399581ad6265SDimitry Andric __lhs_sz + __rhs_sz, 399681ad6265SDimitry Andric _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator())); 399781ad6265SDimitry Andric auto __ptr = std::__to_address(__r.__get_pointer()); 399881ad6265SDimitry Andric _Traits::copy(__ptr, __lhs.data(), __lhs_sz); 399981ad6265SDimitry Andric _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz); 400081ad6265SDimitry Andric _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT()); 40010b57cec5SDimitry Andric return __r; 40020b57cec5SDimitry Andric} 40030b57cec5SDimitry Andric 40040b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 4005cb14a3feSDimitry Andric_LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 4006cb14a3feSDimitry Andricoperator+(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) { 400781ad6265SDimitry Andric using _String = basic_string<_CharT, _Traits, _Allocator>; 400881ad6265SDimitry Andric auto __lhs_sz = _Traits::length(__lhs); 400981ad6265SDimitry Andric auto __rhs_sz = __rhs.size(); 401081ad6265SDimitry Andric _String __r(__uninitialized_size_tag(), 401181ad6265SDimitry Andric __lhs_sz + __rhs_sz, 401281ad6265SDimitry Andric _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator())); 401381ad6265SDimitry Andric auto __ptr = std::__to_address(__r.__get_pointer()); 401481ad6265SDimitry Andric _Traits::copy(__ptr, __lhs, __lhs_sz); 401581ad6265SDimitry Andric _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz); 401681ad6265SDimitry Andric _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT()); 40170b57cec5SDimitry Andric return __r; 40180b57cec5SDimitry Andric} 40190b57cec5SDimitry Andric 40200b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 4021cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 4022cb14a3feSDimitry Andricoperator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) { 402381ad6265SDimitry Andric using _String = basic_string<_CharT, _Traits, _Allocator>; 402481ad6265SDimitry Andric typename _String::size_type __rhs_sz = __rhs.size(); 402581ad6265SDimitry Andric _String __r(__uninitialized_size_tag(), 402681ad6265SDimitry Andric __rhs_sz + 1, 402781ad6265SDimitry Andric _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator())); 402881ad6265SDimitry Andric auto __ptr = std::__to_address(__r.__get_pointer()); 402981ad6265SDimitry Andric _Traits::assign(__ptr, 1, __lhs); 403081ad6265SDimitry Andric _Traits::copy(__ptr + 1, __rhs.data(), __rhs_sz); 403181ad6265SDimitry Andric _Traits::assign(__ptr + 1 + __rhs_sz, 1, _CharT()); 40320b57cec5SDimitry Andric return __r; 40330b57cec5SDimitry Andric} 40340b57cec5SDimitry Andric 40350b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 4036cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 4037cb14a3feSDimitry Andricoperator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) { 403881ad6265SDimitry Andric using _String = basic_string<_CharT, _Traits, _Allocator>; 403981ad6265SDimitry Andric typename _String::size_type __lhs_sz = __lhs.size(); 404081ad6265SDimitry Andric typename _String::size_type __rhs_sz = _Traits::length(__rhs); 404181ad6265SDimitry Andric _String __r(__uninitialized_size_tag(), 404281ad6265SDimitry Andric __lhs_sz + __rhs_sz, 404381ad6265SDimitry Andric _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator())); 404481ad6265SDimitry Andric auto __ptr = std::__to_address(__r.__get_pointer()); 404581ad6265SDimitry Andric _Traits::copy(__ptr, __lhs.data(), __lhs_sz); 404681ad6265SDimitry Andric _Traits::copy(__ptr + __lhs_sz, __rhs, __rhs_sz); 404781ad6265SDimitry Andric _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT()); 40480b57cec5SDimitry Andric return __r; 40490b57cec5SDimitry Andric} 40500b57cec5SDimitry Andric 40510b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 4052cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 4053cb14a3feSDimitry Andricoperator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs) { 405481ad6265SDimitry Andric using _String = basic_string<_CharT, _Traits, _Allocator>; 405581ad6265SDimitry Andric typename _String::size_type __lhs_sz = __lhs.size(); 405681ad6265SDimitry Andric _String __r(__uninitialized_size_tag(), 405781ad6265SDimitry Andric __lhs_sz + 1, 405881ad6265SDimitry Andric _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator())); 405981ad6265SDimitry Andric auto __ptr = std::__to_address(__r.__get_pointer()); 406081ad6265SDimitry Andric _Traits::copy(__ptr, __lhs.data(), __lhs_sz); 406181ad6265SDimitry Andric _Traits::assign(__ptr + __lhs_sz, 1, __rhs); 406281ad6265SDimitry Andric _Traits::assign(__ptr + 1 + __lhs_sz, 1, _CharT()); 40630b57cec5SDimitry Andric return __r; 40640b57cec5SDimitry Andric} 40650b57cec5SDimitry Andric 40660b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 40670b57cec5SDimitry Andric 40680b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 4069cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 4070cb14a3feSDimitry Andricoperator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) { 407181ad6265SDimitry Andric return std::move(__lhs.append(__rhs)); 40720b57cec5SDimitry Andric} 40730b57cec5SDimitry Andric 40740b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 4075cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 4076cb14a3feSDimitry Andricoperator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs) { 407781ad6265SDimitry Andric return std::move(__rhs.insert(0, __lhs)); 40780b57cec5SDimitry Andric} 40790b57cec5SDimitry Andric 40800b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 4081cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 4082cb14a3feSDimitry Andricoperator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs) { 408381ad6265SDimitry Andric return std::move(__lhs.append(__rhs)); 40840b57cec5SDimitry Andric} 40850b57cec5SDimitry Andric 40860b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 4087cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 4088cb14a3feSDimitry Andricoperator+(const _CharT* __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs) { 408981ad6265SDimitry Andric return std::move(__rhs.insert(0, __lhs)); 40900b57cec5SDimitry Andric} 40910b57cec5SDimitry Andric 40920b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 4093cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 4094cb14a3feSDimitry Andricoperator+(_CharT __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs) { 40950b57cec5SDimitry Andric __rhs.insert(__rhs.begin(), __lhs); 409681ad6265SDimitry Andric return std::move(__rhs); 40970b57cec5SDimitry Andric} 40980b57cec5SDimitry Andric 40990b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 4100cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 4101cb14a3feSDimitry Andricoperator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const _CharT* __rhs) { 410281ad6265SDimitry Andric return std::move(__lhs.append(__rhs)); 41030b57cec5SDimitry Andric} 41040b57cec5SDimitry Andric 41050b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 4106cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 4107cb14a3feSDimitry Andricoperator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT __rhs) { 41080b57cec5SDimitry Andric __lhs.push_back(__rhs); 410981ad6265SDimitry Andric return std::move(__lhs); 41100b57cec5SDimitry Andric} 41110b57cec5SDimitry Andric 41120b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 41130b57cec5SDimitry Andric 41140fca6ea1SDimitry Andric#if _LIBCPP_STD_VER >= 26 41150fca6ea1SDimitry Andric 41160fca6ea1SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 41170fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator> 41180fca6ea1SDimitry Andricoperator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 41190fca6ea1SDimitry Andric type_identity_t<basic_string_view<_CharT, _Traits>> __rhs) { 41200fca6ea1SDimitry Andric using _String = basic_string<_CharT, _Traits, _Allocator>; 41210fca6ea1SDimitry Andric typename _String::size_type __lhs_sz = __lhs.size(); 41220fca6ea1SDimitry Andric typename _String::size_type __rhs_sz = __rhs.size(); 41230fca6ea1SDimitry Andric _String __r(__uninitialized_size_tag(), 41240fca6ea1SDimitry Andric __lhs_sz + __rhs_sz, 41250fca6ea1SDimitry Andric _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator())); 41260fca6ea1SDimitry Andric auto __ptr = std::__to_address(__r.__get_pointer()); 41270fca6ea1SDimitry Andric _Traits::copy(__ptr, __lhs.data(), __lhs_sz); 41280fca6ea1SDimitry Andric _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz); 41290fca6ea1SDimitry Andric _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT()); 41300fca6ea1SDimitry Andric return __r; 41310fca6ea1SDimitry Andric} 41320fca6ea1SDimitry Andric 41330fca6ea1SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 41340fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator> 41350fca6ea1SDimitry Andricoperator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, 41360fca6ea1SDimitry Andric type_identity_t<basic_string_view<_CharT, _Traits>> __rhs) { 41370fca6ea1SDimitry Andric __lhs.append(__rhs); 41380fca6ea1SDimitry Andric return std::move(__lhs); 41390fca6ea1SDimitry Andric} 41400fca6ea1SDimitry Andric 41410fca6ea1SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 41420fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator> 41430fca6ea1SDimitry Andricoperator+(type_identity_t<basic_string_view<_CharT, _Traits>> __lhs, 41440fca6ea1SDimitry Andric const basic_string<_CharT, _Traits, _Allocator>& __rhs) { 41450fca6ea1SDimitry Andric using _String = basic_string<_CharT, _Traits, _Allocator>; 41460fca6ea1SDimitry Andric typename _String::size_type __lhs_sz = __lhs.size(); 41470fca6ea1SDimitry Andric typename _String::size_type __rhs_sz = __rhs.size(); 41480fca6ea1SDimitry Andric _String __r(__uninitialized_size_tag(), 41490fca6ea1SDimitry Andric __lhs_sz + __rhs_sz, 41500fca6ea1SDimitry Andric _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator())); 41510fca6ea1SDimitry Andric auto __ptr = std::__to_address(__r.__get_pointer()); 41520fca6ea1SDimitry Andric _Traits::copy(__ptr, __lhs.data(), __lhs_sz); 41530fca6ea1SDimitry Andric _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz); 41540fca6ea1SDimitry Andric _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT()); 41550fca6ea1SDimitry Andric return __r; 41560fca6ea1SDimitry Andric} 41570fca6ea1SDimitry Andric 41580fca6ea1SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 41590fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr basic_string<_CharT, _Traits, _Allocator> 41600fca6ea1SDimitry Andricoperator+(type_identity_t<basic_string_view<_CharT, _Traits>> __lhs, 41610fca6ea1SDimitry Andric basic_string<_CharT, _Traits, _Allocator>&& __rhs) { 41620fca6ea1SDimitry Andric __rhs.insert(0, __lhs); 41630fca6ea1SDimitry Andric return std::move(__rhs); 41640fca6ea1SDimitry Andric} 41650fca6ea1SDimitry Andric 41660fca6ea1SDimitry Andric#endif // _LIBCPP_STD_VER >= 26 41670fca6ea1SDimitry Andric 41680b57cec5SDimitry Andric// swap 41690b57cec5SDimitry Andric 41700b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 4171cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 4172cb14a3feSDimitry Andricswap(basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>& __rhs) 4173cb14a3feSDimitry Andric _NOEXCEPT_(_NOEXCEPT_(__lhs.swap(__rhs))) { 41740b57cec5SDimitry Andric __lhs.swap(__rhs); 41750b57cec5SDimitry Andric} 41760b57cec5SDimitry Andric 417706c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI int stoi(const string& __str, size_t* __idx = nullptr, int __base = 10); 417806c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI long stol(const string& __str, size_t* __idx = nullptr, int __base = 10); 417906c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI unsigned long stoul(const string& __str, size_t* __idx = nullptr, int __base = 10); 418006c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI long long stoll(const string& __str, size_t* __idx = nullptr, int __base = 10); 418106c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI unsigned long long stoull(const string& __str, size_t* __idx = nullptr, int __base = 10); 41820b57cec5SDimitry Andric 418306c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI float stof(const string& __str, size_t* __idx = nullptr); 418406c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI double stod(const string& __str, size_t* __idx = nullptr); 418506c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI long double stold(const string& __str, size_t* __idx = nullptr); 41860b57cec5SDimitry Andric 418706c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI string to_string(int __val); 418806c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned __val); 418906c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI string to_string(long __val); 419006c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long __val); 419106c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI string to_string(long long __val); 419206c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long long __val); 419306c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI string to_string(float __val); 419406c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI string to_string(double __val); 419506c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI string to_string(long double __val); 41960b57cec5SDimitry Andric 4197349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 419806c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI int stoi(const wstring& __str, size_t* __idx = nullptr, int __base = 10); 419906c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI long stol(const wstring& __str, size_t* __idx = nullptr, int __base = 10); 420006c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI unsigned long stoul(const wstring& __str, size_t* __idx = nullptr, int __base = 10); 420106c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI long long stoll(const wstring& __str, size_t* __idx = nullptr, int __base = 10); 420206c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI unsigned long long stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10); 42030b57cec5SDimitry Andric 420406c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI float stof(const wstring& __str, size_t* __idx = nullptr); 420506c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI double stod(const wstring& __str, size_t* __idx = nullptr); 420606c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI long double stold(const wstring& __str, size_t* __idx = nullptr); 42070b57cec5SDimitry Andric 420806c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(int __val); 420906c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned __val); 421006c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long __val); 421106c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long __val); 421206c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long long __val); 421306c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long long __val); 421406c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(float __val); 421506c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(double __val); 421606c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long double __val); 4217349cc55cSDimitry Andric#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS 42180b57cec5SDimitry Andric 42190b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 4220cb14a3feSDimitry Andric_LIBCPP_TEMPLATE_DATA_VIS const typename basic_string<_CharT, _Traits, _Allocator>::size_type 42210b57cec5SDimitry Andric basic_string<_CharT, _Traits, _Allocator>::npos; 42220b57cec5SDimitry Andric 42230b57cec5SDimitry Andrictemplate <class _CharT, class _Allocator> 422406c3fb27SDimitry Andricstruct __string_hash : public __unary_function<basic_string<_CharT, char_traits<_CharT>, _Allocator>, size_t> { 422506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t 422606c3fb27SDimitry Andric operator()(const basic_string<_CharT, char_traits<_CharT>, _Allocator>& __val) const _NOEXCEPT { 422706c3fb27SDimitry Andric return std::__do_string_hash(__val.data(), __val.data() + __val.size()); 422806c3fb27SDimitry Andric } 42290b57cec5SDimitry Andric}; 42300b57cec5SDimitry Andric 4231bdd1243dSDimitry Andrictemplate <class _Allocator> 4232bdd1243dSDimitry Andricstruct hash<basic_string<char, char_traits<char>, _Allocator> > : __string_hash<char, _Allocator> {}; 4233bdd1243dSDimitry Andric 4234bdd1243dSDimitry Andric#ifndef _LIBCPP_HAS_NO_CHAR8_T 4235bdd1243dSDimitry Andrictemplate <class _Allocator> 4236bdd1243dSDimitry Andricstruct hash<basic_string<char8_t, char_traits<char8_t>, _Allocator> > : __string_hash<char8_t, _Allocator> {}; 4237bdd1243dSDimitry Andric#endif 4238bdd1243dSDimitry Andric 4239bdd1243dSDimitry Andrictemplate <class _Allocator> 4240bdd1243dSDimitry Andricstruct hash<basic_string<char16_t, char_traits<char16_t>, _Allocator> > : __string_hash<char16_t, _Allocator> {}; 4241bdd1243dSDimitry Andric 4242bdd1243dSDimitry Andrictemplate <class _Allocator> 4243bdd1243dSDimitry Andricstruct hash<basic_string<char32_t, char_traits<char32_t>, _Allocator> > : __string_hash<char32_t, _Allocator> {}; 4244bdd1243dSDimitry Andric 4245bdd1243dSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 4246bdd1243dSDimitry Andrictemplate <class _Allocator> 4247bdd1243dSDimitry Andricstruct hash<basic_string<wchar_t, char_traits<wchar_t>, _Allocator> > : __string_hash<wchar_t, _Allocator> {}; 4248bdd1243dSDimitry Andric#endif 4249bdd1243dSDimitry Andric 42500b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 4251bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& 4252cb14a3feSDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os, const basic_string<_CharT, _Traits, _Allocator>& __str); 42530b57cec5SDimitry Andric 42540b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 4255bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& 4256cb14a3feSDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Allocator>& __str); 42570b57cec5SDimitry Andric 42580b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 4259bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& 4260cb14a3feSDimitry Andricgetline(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm); 42610b57cec5SDimitry Andric 42620b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 4263cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& 4264cb14a3feSDimitry Andricgetline(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Allocator>& __str); 42650b57cec5SDimitry Andric 42660b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 4267cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& 4268cb14a3feSDimitry Andricgetline(basic_istream<_CharT, _Traits>&& __is, basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm); 42690b57cec5SDimitry Andric 42700b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 4271cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& 4272cb14a3feSDimitry Andricgetline(basic_istream<_CharT, _Traits>&& __is, basic_string<_CharT, _Traits, _Allocator>& __str); 42730b57cec5SDimitry Andric 427406c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 20 42750b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator, class _Up> 4276cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename basic_string<_CharT, _Traits, _Allocator>::size_type 42775ffd83dbSDimitry Andricerase(basic_string<_CharT, _Traits, _Allocator>& __str, const _Up& __v) { 42785ffd83dbSDimitry Andric auto __old_size = __str.size(); 427981ad6265SDimitry Andric __str.erase(std::remove(__str.begin(), __str.end(), __v), __str.end()); 42805ffd83dbSDimitry Andric return __old_size - __str.size(); 42815ffd83dbSDimitry Andric} 42820b57cec5SDimitry Andric 42830b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator, class _Predicate> 4284cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename basic_string<_CharT, _Traits, _Allocator>::size_type 4285cb14a3feSDimitry Andricerase_if(basic_string<_CharT, _Traits, _Allocator>& __str, _Predicate __pred) { 42865ffd83dbSDimitry Andric auto __old_size = __str.size(); 4287cb14a3feSDimitry Andric __str.erase(std::remove_if(__str.begin(), __str.end(), __pred), __str.end()); 42885ffd83dbSDimitry Andric return __old_size - __str.size(); 42895ffd83dbSDimitry Andric} 42900b57cec5SDimitry Andric#endif 42910b57cec5SDimitry Andric 429206c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14 42930b57cec5SDimitry Andric// Literal suffixes for basic_string [basic.string.literals] 4294cb14a3feSDimitry Andricinline namespace literals { 4295cb14a3feSDimitry Andricinline namespace string_literals { 4296cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<char> 4297cb14a3feSDimitry Andricoperator""s(const char* __str, size_t __len) { 42980b57cec5SDimitry Andric return basic_string<char>(__str, __len); 42990b57cec5SDimitry Andric} 43000b57cec5SDimitry Andric 4301349cc55cSDimitry Andric# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 4302cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<wchar_t> 4303cb14a3feSDimitry Andricoperator""s(const wchar_t* __str, size_t __len) { 43040b57cec5SDimitry Andric return basic_string<wchar_t>(__str, __len); 43050b57cec5SDimitry Andric} 4306349cc55cSDimitry Andric# endif 43070b57cec5SDimitry Andric 4308fe6060f1SDimitry Andric# ifndef _LIBCPP_HAS_NO_CHAR8_T 4309cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI constexpr basic_string<char8_t> operator""s(const char8_t* __str, size_t __len) { 43100b57cec5SDimitry Andric return basic_string<char8_t>(__str, __len); 43110b57cec5SDimitry Andric} 43120b57cec5SDimitry Andric# endif 43130b57cec5SDimitry Andric 4314cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<char16_t> 4315cb14a3feSDimitry Andricoperator""s(const char16_t* __str, size_t __len) { 43160b57cec5SDimitry Andric return basic_string<char16_t>(__str, __len); 43170b57cec5SDimitry Andric} 43180b57cec5SDimitry Andric 4319cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<char32_t> 4320cb14a3feSDimitry Andricoperator""s(const char32_t* __str, size_t __len) { 43210b57cec5SDimitry Andric return basic_string<char32_t>(__str, __len); 43220b57cec5SDimitry Andric} 43230eae32dcSDimitry Andric} // namespace string_literals 43240eae32dcSDimitry Andric} // namespace literals 432581ad6265SDimitry Andric 432606c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 20 432781ad6265SDimitry Andrictemplate <> 432881ad6265SDimitry Andricinline constexpr bool __format::__enable_insertable<std::basic_string<char>> = true; 432981ad6265SDimitry Andric# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 433081ad6265SDimitry Andrictemplate <> 433181ad6265SDimitry Andricinline constexpr bool __format::__enable_insertable<std::basic_string<wchar_t>> = true; 433281ad6265SDimitry Andric# endif 433381ad6265SDimitry Andric# endif 433481ad6265SDimitry Andric 43350b57cec5SDimitry Andric#endif 43360b57cec5SDimitry Andric 43370b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 43380b57cec5SDimitry Andric 43390b57cec5SDimitry Andric_LIBCPP_POP_MACROS 43400b57cec5SDimitry Andric 4341bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 4342bdd1243dSDimitry Andric# include <algorithm> 4343bdd1243dSDimitry Andric# include <concepts> 434406c3fb27SDimitry Andric# include <cstdlib> 4345bdd1243dSDimitry Andric# include <iterator> 4346bdd1243dSDimitry Andric# include <new> 434706c3fb27SDimitry Andric# include <type_traits> 4348bdd1243dSDimitry Andric# include <typeinfo> 4349bdd1243dSDimitry Andric# include <utility> 4350bdd1243dSDimitry Andric#endif 4351bdd1243dSDimitry Andric 43520b57cec5SDimitry Andric#endif // _LIBCPP_STRING 4353