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 13c9157d92SDimitry Andric// clang-format off 14c9157d92SDimitry 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 124fe013be4SDimitry 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 129fe013be4SDimitry Andric template<container-compatible-range<charT> R> 130fe013be4SDimitry 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 147fe013be4SDimitry 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 178c9157d92SDimitry 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 207fe013be4SDimitry Andric template<container-compatible-range<charT> R> 208fe013be4SDimitry 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 230fe013be4SDimitry Andric template<container-compatible-range<charT> R> 231fe013be4SDimitry 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 248fe013be4SDimitry Andric template<container-compatible-range<charT> R> 249fe013be4SDimitry 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 275fe013be4SDimitry Andric template<container-compatible-range<charT> R> 276fe013be4SDimitry 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 357fe013be4SDimitry Andric constexpr bool contains(basic_string_view<charT, traits> sv) const noexcept; // C++23 358fe013be4SDimitry Andric constexpr bool contains(charT c) const noexcept; // C++23 359fe013be4SDimitry 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 369fe013be4SDimitry Andrictemplate<ranges::input_range R, 370fe013be4SDimitry Andric class Allocator = allocator<ranges::range_value_t<R>>> 371fe013be4SDimitry Andric basic_string(from_range_t, R&&, Allocator = Allocator()) 372fe013be4SDimitry Andric -> basic_string<ranges::range_value_t<R>, char_traits<ranges::range_value_t<R>>, 373fe013be4SDimitry Andric Allocator>; // C++23 374fe013be4SDimitry Andric 375fe013be4SDimitry Andrictemplate<class charT, 376fe013be4SDimitry Andric class traits, 377fe013be4SDimitry Andric class Allocator = allocator<charT>> 378fe013be4SDimitry Andric explicit basic_string(basic_string_view<charT, traits>, const Allocator& = Allocator()) 379fe013be4SDimitry Andric -> basic_string<charT, traits, Allocator>; // C++17 380fe013be4SDimitry Andric 381fe013be4SDimitry Andrictemplate<class charT, 382fe013be4SDimitry Andric class traits, 383fe013be4SDimitry Andric class Allocator = allocator<charT>> 384fe013be4SDimitry Andric basic_string(basic_string_view<charT, traits>, 385fe013be4SDimitry Andric typename see below::size_type, typename see below::size_type, 386fe013be4SDimitry Andric const Allocator& = Allocator()) 387fe013be4SDimitry Andric -> basic_string<charT, traits, Allocator>; // C++17 388fe013be4SDimitry 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> 4110b57cec5SDimitry Andricbool operator==(const basic_string<charT, traits, Allocator>& lhs, 41281ad6265SDimitry Andric const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20 4130b57cec5SDimitry Andric 4140b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 415bdd1243dSDimitry Andricbool operator==(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 4160b57cec5SDimitry Andric 4170b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 41881ad6265SDimitry Andricbool operator==(const basic_string<charT,traits,Allocator>& lhs, const charT* rhs) noexcept; // constexpr since C++20 4190b57cec5SDimitry Andric 4200b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 4210b57cec5SDimitry Andricbool operator!=(const basic_string<charT,traits,Allocator>& lhs, 422bdd1243dSDimitry Andric const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 4230b57cec5SDimitry Andric 4240b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 425bdd1243dSDimitry Andricbool operator!=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 4260b57cec5SDimitry Andric 4270b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 428bdd1243dSDimitry Andricbool operator!=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // removed in C++20 4290b57cec5SDimitry Andric 4300b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 4310b57cec5SDimitry Andricbool operator< (const basic_string<charT, traits, Allocator>& lhs, 432bdd1243dSDimitry Andric const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 4330b57cec5SDimitry Andric 4340b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 435bdd1243dSDimitry Andricbool operator< (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // removed in C++20 4360b57cec5SDimitry Andric 4370b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 438bdd1243dSDimitry Andricbool operator< (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 4390b57cec5SDimitry Andric 4400b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 4410b57cec5SDimitry Andricbool operator> (const basic_string<charT, traits, Allocator>& lhs, 442bdd1243dSDimitry Andric const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 4430b57cec5SDimitry Andric 4440b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 445bdd1243dSDimitry Andricbool operator> (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // removed in C++20 4460b57cec5SDimitry Andric 4470b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 448bdd1243dSDimitry Andricbool operator> (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 4490b57cec5SDimitry Andric 4500b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 4510b57cec5SDimitry Andricbool operator<=(const basic_string<charT, traits, Allocator>& lhs, 452bdd1243dSDimitry Andric const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 4530b57cec5SDimitry Andric 4540b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 455bdd1243dSDimitry Andricbool operator<=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // removed in C++20 4560b57cec5SDimitry Andric 4570b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 458bdd1243dSDimitry Andricbool operator<=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 4590b57cec5SDimitry Andric 4600b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 4610b57cec5SDimitry Andricbool operator>=(const basic_string<charT, traits, Allocator>& lhs, 462bdd1243dSDimitry Andric const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 4630b57cec5SDimitry Andric 4640b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 465bdd1243dSDimitry Andricbool operator>=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // removed in C++20 4660b57cec5SDimitry Andric 4670b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 468bdd1243dSDimitry Andricbool operator>=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // removed in C++20 469bdd1243dSDimitry Andric 470bdd1243dSDimitry Andrictemplate<class charT, class traits, class Allocator> // since C++20 471bdd1243dSDimitry Andricconstexpr see below operator<=>(const basic_string<charT, traits, Allocator>& lhs, 472bdd1243dSDimitry Andric const basic_string<charT, traits, Allocator>& rhs) noexcept; 473bdd1243dSDimitry Andric 474bdd1243dSDimitry Andrictemplate<class charT, class traits, class Allocator> // since C++20 475bdd1243dSDimitry Andricconstexpr see below operator<=>(const basic_string<charT, traits, Allocator>& lhs, 476bdd1243dSDimitry Andric const charT* rhs) noexcept; 4770b57cec5SDimitry Andric 4780b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 4790b57cec5SDimitry Andricvoid swap(basic_string<charT, traits, Allocator>& lhs, 4800b57cec5SDimitry Andric basic_string<charT, traits, Allocator>& rhs) 48181ad6265SDimitry Andric noexcept(noexcept(lhs.swap(rhs))); // constexpr since C++20 4820b57cec5SDimitry Andric 4830b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 4840b57cec5SDimitry Andricbasic_istream<charT, traits>& 4850b57cec5SDimitry Andricoperator>>(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str); 4860b57cec5SDimitry Andric 4870b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 4880b57cec5SDimitry Andricbasic_ostream<charT, traits>& 4890b57cec5SDimitry Andricoperator<<(basic_ostream<charT, traits>& os, const basic_string<charT, traits, Allocator>& str); 4900b57cec5SDimitry Andric 4910b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 4920b57cec5SDimitry Andricbasic_istream<charT, traits>& 4930b57cec5SDimitry Andricgetline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str, 4940b57cec5SDimitry Andric charT delim); 4950b57cec5SDimitry Andric 4960b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator> 4970b57cec5SDimitry Andricbasic_istream<charT, traits>& 4980b57cec5SDimitry Andricgetline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str); 4990b57cec5SDimitry Andric 5000b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator, class U> 5015ffd83dbSDimitry Andrictypename basic_string<charT, traits, Allocator>::size_type 5025ffd83dbSDimitry Andricerase(basic_string<charT, traits, Allocator>& c, const U& value); // C++20 5030b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator, class Predicate> 5045ffd83dbSDimitry Andrictypename basic_string<charT, traits, Allocator>::size_type 5055ffd83dbSDimitry Andricerase_if(basic_string<charT, traits, Allocator>& c, Predicate pred); // C++20 5060b57cec5SDimitry Andric 5070b57cec5SDimitry Andrictypedef basic_string<char> string; 5080b57cec5SDimitry Andrictypedef basic_string<wchar_t> wstring; 509fe6060f1SDimitry Andrictypedef basic_string<char8_t> u8string; // C++20 5100b57cec5SDimitry Andrictypedef basic_string<char16_t> u16string; 5110b57cec5SDimitry Andrictypedef basic_string<char32_t> u32string; 5120b57cec5SDimitry Andric 513e8d8bef9SDimitry Andricint stoi (const string& str, size_t* idx = nullptr, int base = 10); 514e8d8bef9SDimitry Andriclong stol (const string& str, size_t* idx = nullptr, int base = 10); 515e8d8bef9SDimitry Andricunsigned long stoul (const string& str, size_t* idx = nullptr, int base = 10); 516e8d8bef9SDimitry Andriclong long stoll (const string& str, size_t* idx = nullptr, int base = 10); 517e8d8bef9SDimitry Andricunsigned long long stoull(const string& str, size_t* idx = nullptr, int base = 10); 5180b57cec5SDimitry Andric 519e8d8bef9SDimitry Andricfloat stof (const string& str, size_t* idx = nullptr); 520e8d8bef9SDimitry Andricdouble stod (const string& str, size_t* idx = nullptr); 521e8d8bef9SDimitry Andriclong double stold(const string& str, size_t* idx = nullptr); 5220b57cec5SDimitry Andric 5230b57cec5SDimitry Andricstring to_string(int val); 5240b57cec5SDimitry Andricstring to_string(unsigned val); 5250b57cec5SDimitry Andricstring to_string(long val); 5260b57cec5SDimitry Andricstring to_string(unsigned long val); 5270b57cec5SDimitry Andricstring to_string(long long val); 5280b57cec5SDimitry Andricstring to_string(unsigned long long val); 5290b57cec5SDimitry Andricstring to_string(float val); 5300b57cec5SDimitry Andricstring to_string(double val); 5310b57cec5SDimitry Andricstring to_string(long double val); 5320b57cec5SDimitry Andric 533e8d8bef9SDimitry Andricint stoi (const wstring& str, size_t* idx = nullptr, int base = 10); 534e8d8bef9SDimitry Andriclong stol (const wstring& str, size_t* idx = nullptr, int base = 10); 535e8d8bef9SDimitry Andricunsigned long stoul (const wstring& str, size_t* idx = nullptr, int base = 10); 536e8d8bef9SDimitry Andriclong long stoll (const wstring& str, size_t* idx = nullptr, int base = 10); 537e8d8bef9SDimitry Andricunsigned long long stoull(const wstring& str, size_t* idx = nullptr, int base = 10); 5380b57cec5SDimitry Andric 539e8d8bef9SDimitry Andricfloat stof (const wstring& str, size_t* idx = nullptr); 540e8d8bef9SDimitry Andricdouble stod (const wstring& str, size_t* idx = nullptr); 541e8d8bef9SDimitry Andriclong double stold(const wstring& str, size_t* idx = nullptr); 5420b57cec5SDimitry Andric 5430b57cec5SDimitry Andricwstring to_wstring(int val); 5440b57cec5SDimitry Andricwstring to_wstring(unsigned val); 5450b57cec5SDimitry Andricwstring to_wstring(long val); 5460b57cec5SDimitry Andricwstring to_wstring(unsigned long val); 5470b57cec5SDimitry Andricwstring to_wstring(long long val); 5480b57cec5SDimitry Andricwstring to_wstring(unsigned long long val); 5490b57cec5SDimitry Andricwstring to_wstring(float val); 5500b57cec5SDimitry Andricwstring to_wstring(double val); 5510b57cec5SDimitry Andricwstring to_wstring(long double val); 5520b57cec5SDimitry Andric 5530b57cec5SDimitry Andrictemplate <> struct hash<string>; 554fe6060f1SDimitry Andrictemplate <> struct hash<u8string>; // C++20 5550b57cec5SDimitry Andrictemplate <> struct hash<u16string>; 5560b57cec5SDimitry Andrictemplate <> struct hash<u32string>; 5570b57cec5SDimitry Andrictemplate <> struct hash<wstring>; 5580b57cec5SDimitry Andric 55981ad6265SDimitry Andricbasic_string<char> operator""s( const char *str, size_t len ); // C++14, constexpr since C++20 56081ad6265SDimitry Andricbasic_string<wchar_t> operator""s( const wchar_t *str, size_t len ); // C++14, constexpr since C++20 56181ad6265SDimitry Andricconstexpr basic_string<char8_t> operator""s( const char8_t *str, size_t len ); // C++20 56281ad6265SDimitry Andricbasic_string<char16_t> operator""s( const char16_t *str, size_t len ); // C++14, constexpr since C++20 56381ad6265SDimitry Andricbasic_string<char32_t> operator""s( const char32_t *str, size_t len ); // C++14, constexpr since C++20 5640b57cec5SDimitry Andric 5650b57cec5SDimitry Andric} // std 5660b57cec5SDimitry Andric 5670b57cec5SDimitry Andric*/ 5680b57cec5SDimitry Andric 569c9157d92SDimitry Andric// clang-format on 570c9157d92SDimitry Andric 57181ad6265SDimitry Andric#include <__algorithm/max.h> 57281ad6265SDimitry Andric#include <__algorithm/min.h> 57381ad6265SDimitry Andric#include <__algorithm/remove.h> 57481ad6265SDimitry Andric#include <__algorithm/remove_if.h> 57581ad6265SDimitry Andric#include <__assert> // all public C++ headers provide the assertion handler 5760b57cec5SDimitry Andric#include <__config> 57781ad6265SDimitry Andric#include <__format/enable_insertable.h> 57881ad6265SDimitry Andric#include <__functional/hash.h> 57981ad6265SDimitry Andric#include <__functional/unary_function.h> 580bdd1243dSDimitry Andric#include <__fwd/string.h> 58181ad6265SDimitry Andric#include <__ios/fpos.h> 58281ad6265SDimitry Andric#include <__iterator/distance.h> 58381ad6265SDimitry Andric#include <__iterator/iterator_traits.h> 58481ad6265SDimitry Andric#include <__iterator/reverse_iterator.h> 585fe6060f1SDimitry Andric#include <__iterator/wrap_iter.h> 586fe013be4SDimitry Andric#include <__memory/addressof.h> 58781ad6265SDimitry Andric#include <__memory/allocate_at_least.h> 588bdd1243dSDimitry Andric#include <__memory/allocator.h> 589bdd1243dSDimitry Andric#include <__memory/allocator_traits.h> 590bdd1243dSDimitry Andric#include <__memory/compressed_pair.h> 591bdd1243dSDimitry Andric#include <__memory/construct_at.h> 592bdd1243dSDimitry Andric#include <__memory/pointer_traits.h> 593972a253aSDimitry Andric#include <__memory/swap_allocator.h> 594bdd1243dSDimitry Andric#include <__memory_resource/polymorphic_allocator.h> 595fe013be4SDimitry Andric#include <__ranges/access.h> 596fe013be4SDimitry Andric#include <__ranges/concepts.h> 597fe013be4SDimitry Andric#include <__ranges/container_compatible_range.h> 598fe013be4SDimitry Andric#include <__ranges/from_range.h> 599fe013be4SDimitry Andric#include <__ranges/size.h> 60081ad6265SDimitry Andric#include <__string/char_traits.h> 60181ad6265SDimitry Andric#include <__string/extern_template_lists.h> 602bdd1243dSDimitry Andric#include <__type_traits/is_allocator.h> 603fe013be4SDimitry Andric#include <__type_traits/is_array.h> 604fe013be4SDimitry Andric#include <__type_traits/is_convertible.h> 605fe013be4SDimitry Andric#include <__type_traits/is_nothrow_default_constructible.h> 606fe013be4SDimitry Andric#include <__type_traits/is_nothrow_move_assignable.h> 607fe013be4SDimitry Andric#include <__type_traits/is_same.h> 608fe013be4SDimitry Andric#include <__type_traits/is_standard_layout.h> 609fe013be4SDimitry Andric#include <__type_traits/is_trivial.h> 610bdd1243dSDimitry Andric#include <__type_traits/noexcept_move_assign_container.h> 611fe013be4SDimitry Andric#include <__type_traits/remove_cvref.h> 612fe013be4SDimitry Andric#include <__type_traits/void_t.h> 61381ad6265SDimitry Andric#include <__utility/auto_cast.h> 614fe013be4SDimitry Andric#include <__utility/declval.h> 615fe013be4SDimitry Andric#include <__utility/forward.h> 616fe013be4SDimitry Andric#include <__utility/is_pointer_in_range.h> 61781ad6265SDimitry Andric#include <__utility/move.h> 61881ad6265SDimitry Andric#include <__utility/swap.h> 61981ad6265SDimitry Andric#include <__utility/unreachable.h> 62081ad6265SDimitry Andric#include <climits> 621fe6060f1SDimitry Andric#include <cstdio> // EOF 622fe6060f1SDimitry Andric#include <cstring> 62381ad6265SDimitry Andric#include <limits> 6240b57cec5SDimitry Andric#include <stdexcept> 625fe6060f1SDimitry Andric#include <string_view> 6260b57cec5SDimitry Andric#include <version> 627fe6060f1SDimitry Andric 628349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 629349cc55cSDimitry Andric# include <cwchar> 630349cc55cSDimitry Andric#endif 631349cc55cSDimitry Andric 63281ad6265SDimitry Andric// standard-mandated includes 63381ad6265SDimitry Andric 63481ad6265SDimitry Andric// [iterator.range] 63581ad6265SDimitry Andric#include <__iterator/access.h> 63681ad6265SDimitry Andric#include <__iterator/data.h> 63781ad6265SDimitry Andric#include <__iterator/empty.h> 63881ad6265SDimitry Andric#include <__iterator/reverse_access.h> 63981ad6265SDimitry Andric#include <__iterator/size.h> 64081ad6265SDimitry Andric 64181ad6265SDimitry Andric// [string.syn] 64281ad6265SDimitry Andric#include <compare> 64381ad6265SDimitry Andric#include <initializer_list> 64481ad6265SDimitry Andric 6450b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 6460b57cec5SDimitry Andric# pragma GCC system_header 6470b57cec5SDimitry Andric#endif 6480b57cec5SDimitry Andric 6490b57cec5SDimitry Andric_LIBCPP_PUSH_MACROS 6500b57cec5SDimitry Andric#include <__undef_macros> 6510b57cec5SDimitry Andric 652c9157d92SDimitry Andric#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN) 653c9157d92SDimitry Andric# define _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS __attribute__((__no_sanitize__("address"))) 654c9157d92SDimitry Andric// This macro disables AddressSanitizer (ASan) instrumentation for a specific function, 655c9157d92SDimitry Andric// allowing memory accesses that would normally trigger ASan errors to proceed without crashing. 656c9157d92SDimitry Andric// This is useful for accessing parts of objects memory, which should not be accessed, 657c9157d92SDimitry Andric// such as unused bytes in short strings, that should never be accessed 658c9157d92SDimitry Andric// by other parts of the program. 659c9157d92SDimitry Andric#else 660c9157d92SDimitry Andric# define _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS 661c9157d92SDimitry Andric#endif 662c9157d92SDimitry Andric#define _LIBCPP_SHORT_STRING_ANNOTATIONS_ALLOWED false 6630b57cec5SDimitry Andric 6640b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 6650b57cec5SDimitry Andric 6660b57cec5SDimitry Andric// basic_string 6670b57cec5SDimitry Andric 6680b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 669e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 670e710425bSDimitry Andricoperator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const basic_string<_CharT, _Traits, _Allocator>& __y); 6710b57cec5SDimitry Andric 6720b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 673e710425bSDimitry Andric_LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 6740b57cec5SDimitry Andricoperator+(const _CharT* __x, const basic_string<_CharT, _Traits, _Allocator>& __y); 6750b57cec5SDimitry Andric 6760b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 677e710425bSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 6780b57cec5SDimitry Andricoperator+(_CharT __x, const basic_string<_CharT, _Traits, _Allocator>& __y); 6790b57cec5SDimitry Andric 6800b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 681e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 6820b57cec5SDimitry Andricoperator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const _CharT* __y); 6830b57cec5SDimitry Andric 6840b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 685e710425bSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 6860b57cec5SDimitry Andricoperator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y); 6870b57cec5SDimitry Andric 688fe013be4SDimitry Andricextern template _LIBCPP_EXPORTED_FROM_ABI string operator+ 689fe013be4SDimitry Andric <char, char_traits<char>, allocator<char> >(char const*, string const&); 6900b57cec5SDimitry Andric 6910b57cec5SDimitry Andrictemplate <class _Iter> 692fe6060f1SDimitry Andricstruct __string_is_trivial_iterator : public false_type {}; 693fe6060f1SDimitry Andric 694fe6060f1SDimitry Andrictemplate <class _Tp> 695e710425bSDimitry Andricstruct __string_is_trivial_iterator<_Tp*> : public is_arithmetic<_Tp> {}; 6960b57cec5SDimitry Andric 6970b57cec5SDimitry Andrictemplate <class _Iter> 698e710425bSDimitry Andricstruct __string_is_trivial_iterator<__wrap_iter<_Iter> > : public __string_is_trivial_iterator<_Iter> {}; 6990b57cec5SDimitry Andric 7000b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Tp> 701e710425bSDimitry Andricstruct __can_be_converted_to_string_view 702e710425bSDimitry Andric : public _BoolConstant< is_convertible<const _Tp&, basic_string_view<_CharT, _Traits> >::value && 703e710425bSDimitry Andric !is_convertible<const _Tp&, const _CharT*>::value > {}; 7040b57cec5SDimitry Andric 70581ad6265SDimitry Andricstruct __uninitialized_size_tag {}; 706fe013be4SDimitry Andricstruct __init_with_sentinel_tag {}; 707e8d8bef9SDimitry Andric 7080b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 709e710425bSDimitry Andricclass basic_string { 710c9157d92SDimitry Andricprivate: 711c9157d92SDimitry Andric using __default_allocator_type = allocator<_CharT>; 712c9157d92SDimitry Andric 7130b57cec5SDimitry Andricpublic: 7140b57cec5SDimitry Andric typedef basic_string __self; 7150b57cec5SDimitry Andric typedef basic_string_view<_CharT, _Traits> __self_view; 7160b57cec5SDimitry Andric typedef _Traits traits_type; 7170b57cec5SDimitry Andric typedef _CharT value_type; 7180b57cec5SDimitry Andric typedef _Allocator allocator_type; 7190b57cec5SDimitry Andric typedef allocator_traits<allocator_type> __alloc_traits; 7200b57cec5SDimitry Andric typedef typename __alloc_traits::size_type size_type; 7210b57cec5SDimitry Andric typedef typename __alloc_traits::difference_type difference_type; 7220b57cec5SDimitry Andric typedef value_type& reference; 7230b57cec5SDimitry Andric typedef const value_type& const_reference; 7240b57cec5SDimitry Andric typedef typename __alloc_traits::pointer pointer; 7250b57cec5SDimitry Andric typedef typename __alloc_traits::const_pointer const_pointer; 7260b57cec5SDimitry Andric 7270b57cec5SDimitry Andric static_assert((!is_array<value_type>::value), "Character type of basic_string must not be an array"); 7280b57cec5SDimitry Andric static_assert((is_standard_layout<value_type>::value), "Character type of basic_string must be standard-layout"); 7290b57cec5SDimitry Andric static_assert((is_trivial<value_type>::value), "Character type of basic_string must be trivial"); 7300b57cec5SDimitry Andric static_assert((is_same<_CharT, typename traits_type::char_type>::value), 7310b57cec5SDimitry Andric "traits_type::char_type must be the same type as CharT"); 7320b57cec5SDimitry Andric static_assert((is_same<typename allocator_type::value_type, value_type>::value), 7330b57cec5SDimitry Andric "Allocator::value_type must be same type as value_type"); 7340b57cec5SDimitry Andric 735bdd1243dSDimitry Andric static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value, 736bdd1243dSDimitry Andric "[allocator.requirements] states that rebinding an allocator to the same type should result in the " 737bdd1243dSDimitry Andric "original allocator"); 738bdd1243dSDimitry Andric 739bdd1243dSDimitry Andric // TODO: Implement iterator bounds checking without requiring the global database. 7400b57cec5SDimitry Andric typedef __wrap_iter<pointer> iterator; 7410b57cec5SDimitry Andric typedef __wrap_iter<const_pointer> const_iterator; 74281ad6265SDimitry Andric typedef std::reverse_iterator<iterator> reverse_iterator; 74381ad6265SDimitry Andric typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 7440b57cec5SDimitry Andric 7450b57cec5SDimitry Andricprivate: 74681ad6265SDimitry Andric static_assert(CHAR_BIT == 8, "This implementation assumes that one byte contains 8 bits"); 7470b57cec5SDimitry Andric 7480b57cec5SDimitry Andric#ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT 7490b57cec5SDimitry Andric 750e710425bSDimitry Andric struct __long { 7510b57cec5SDimitry Andric pointer __data_; 7520b57cec5SDimitry Andric size_type __size_; 75381ad6265SDimitry Andric size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1; 75481ad6265SDimitry Andric size_type __is_long_ : 1; 7550b57cec5SDimitry Andric }; 7560b57cec5SDimitry Andric 757e710425bSDimitry Andric enum { __min_cap = (sizeof(__long) - 1) / sizeof(value_type) > 2 ? (sizeof(__long) - 1) / sizeof(value_type) : 2 }; 7580b57cec5SDimitry Andric 759e710425bSDimitry Andric struct __short { 7600b57cec5SDimitry Andric value_type __data_[__min_cap]; 76181ad6265SDimitry Andric unsigned char __padding_[sizeof(value_type) - 1]; 76281ad6265SDimitry Andric unsigned char __size_ : 7; 76381ad6265SDimitry Andric unsigned char __is_long_ : 1; 7640b57cec5SDimitry Andric }; 7650b57cec5SDimitry Andric 76681ad6265SDimitry Andric // The __endian_factor is required because the field we use to store the size 76781ad6265SDimitry Andric // has one fewer bit than it would if it were not a bitfield. 76881ad6265SDimitry Andric // 76981ad6265SDimitry Andric // If the LSB is used to store the short-flag in the short string representation, 77081ad6265SDimitry Andric // we have to multiply the size by two when it is stored and divide it by two when 77181ad6265SDimitry Andric // it is loaded to make sure that we always store an even number. In the long string 77281ad6265SDimitry Andric // representation, we can ignore this because we can assume that we always allocate 77381ad6265SDimitry Andric // an even amount of value_types. 77481ad6265SDimitry Andric // 77581ad6265SDimitry Andric // If the MSB is used for the short-flag, the max_size() is numeric_limits<size_type>::max() / 2. 77681ad6265SDimitry Andric // This does not impact the short string representation, since we never need the MSB 77781ad6265SDimitry Andric // for representing the size of a short string anyway. 77881ad6265SDimitry Andric 77981ad6265SDimitry Andric# ifdef _LIBCPP_BIG_ENDIAN 78081ad6265SDimitry Andric static const size_type __endian_factor = 2; 7810b57cec5SDimitry Andric# else 78281ad6265SDimitry Andric static const size_type __endian_factor = 1; 78381ad6265SDimitry Andric# endif 7840b57cec5SDimitry Andric 78581ad6265SDimitry Andric#else // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT 78681ad6265SDimitry Andric 78781ad6265SDimitry Andric# ifdef _LIBCPP_BIG_ENDIAN 78881ad6265SDimitry Andric static const size_type __endian_factor = 1; 78981ad6265SDimitry Andric# else 79081ad6265SDimitry Andric static const size_type __endian_factor = 2; 79181ad6265SDimitry Andric# endif 79281ad6265SDimitry Andric 79381ad6265SDimitry Andric // Attribute 'packed' is used to keep the layout compatible with the 79481ad6265SDimitry Andric // previous definition that did not use bit fields. This is because on 79581ad6265SDimitry Andric // some platforms bit fields have a default size rather than the actual 79681ad6265SDimitry Andric // size used, e.g., it is 4 bytes on AIX. See D128285 for details. 797e710425bSDimitry Andric struct __long { 79881ad6265SDimitry Andric struct _LIBCPP_PACKED { 79981ad6265SDimitry Andric size_type __is_long_ : 1; 80081ad6265SDimitry Andric size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1; 80181ad6265SDimitry Andric }; 8020b57cec5SDimitry Andric size_type __size_; 8030b57cec5SDimitry Andric pointer __data_; 8040b57cec5SDimitry Andric }; 8050b57cec5SDimitry Andric 806e710425bSDimitry Andric enum { __min_cap = (sizeof(__long) - 1) / sizeof(value_type) > 2 ? (sizeof(__long) - 1) / sizeof(value_type) : 2 }; 8070b57cec5SDimitry Andric 808e710425bSDimitry Andric struct __short { 80981ad6265SDimitry Andric struct _LIBCPP_PACKED { 81081ad6265SDimitry Andric unsigned char __is_long_ : 1; 81181ad6265SDimitry Andric unsigned char __size_ : 7; 8120b57cec5SDimitry Andric }; 81381ad6265SDimitry Andric char __padding_[sizeof(value_type) - 1]; 8140b57cec5SDimitry Andric value_type __data_[__min_cap]; 8150b57cec5SDimitry Andric }; 8160b57cec5SDimitry Andric 8170b57cec5SDimitry Andric#endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT 8180b57cec5SDimitry Andric 81981ad6265SDimitry Andric static_assert(sizeof(__short) == (sizeof(value_type) * (__min_cap + 1)), "__short has an unexpected size."); 82081ad6265SDimitry Andric 821e710425bSDimitry Andric union __ulx { 822e710425bSDimitry Andric __long __lx; 823e710425bSDimitry Andric __short __lxx; 824e710425bSDimitry Andric }; 8250b57cec5SDimitry Andric 8260b57cec5SDimitry Andric enum { __n_words = sizeof(__ulx) / sizeof(size_type) }; 8270b57cec5SDimitry Andric 828e710425bSDimitry Andric struct __raw { 8290b57cec5SDimitry Andric size_type __words[__n_words]; 8300b57cec5SDimitry Andric }; 8310b57cec5SDimitry Andric 832e710425bSDimitry Andric struct __rep { 833e710425bSDimitry Andric union { 8340b57cec5SDimitry Andric __short __s; 835c9157d92SDimitry Andric __long __l; 8360b57cec5SDimitry Andric __raw __r; 8370b57cec5SDimitry Andric }; 8380b57cec5SDimitry Andric }; 8390b57cec5SDimitry Andric 8400b57cec5SDimitry Andric __compressed_pair<__rep, allocator_type> __r_; 8410b57cec5SDimitry Andric 84281ad6265SDimitry Andric // Construct a string with the given allocator and enough storage to hold `__size` characters, but 84381ad6265SDimitry Andric // don't initialize the characters. The contents of the string, including the null terminator, must be 84481ad6265SDimitry Andric // initialized separately. 845e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string( 846e710425bSDimitry Andric __uninitialized_size_tag, size_type __size, const allocator_type& __a) 84781ad6265SDimitry Andric : __r_(__default_init_tag(), __a) { 84881ad6265SDimitry Andric if (__size > max_size()) 84981ad6265SDimitry Andric __throw_length_error(); 85081ad6265SDimitry Andric if (__fits_in_sso(__size)) { 851bdd1243dSDimitry Andric __r_.first() = __rep(); 85281ad6265SDimitry Andric __set_short_size(__size); 85381ad6265SDimitry Andric } else { 85481ad6265SDimitry Andric auto __capacity = __recommend(__size) + 1; 85581ad6265SDimitry Andric auto __allocation = __alloc_traits::allocate(__alloc(), __capacity); 85681ad6265SDimitry Andric __begin_lifetime(__allocation, __capacity); 85781ad6265SDimitry Andric __set_long_cap(__capacity); 85881ad6265SDimitry Andric __set_long_pointer(__allocation); 85981ad6265SDimitry Andric __set_long_size(__size); 86081ad6265SDimitry Andric } 861c9157d92SDimitry Andric __annotate_new(__size); 862fe013be4SDimitry Andric } 863fe013be4SDimitry Andric 864fe013be4SDimitry Andric template <class _Iter, class _Sent> 865fe013be4SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 866fe013be4SDimitry Andric basic_string(__init_with_sentinel_tag, _Iter __first, _Sent __last, const allocator_type& __a) 867fe013be4SDimitry Andric : __r_(__default_init_tag(), __a) { 868fe013be4SDimitry Andric __init_with_sentinel(std::move(__first), std::move(__last)); 86981ad6265SDimitry Andric } 87081ad6265SDimitry Andric 871e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator __make_iterator(pointer __p) { return iterator(__p); } 872bdd1243dSDimitry Andric 873bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator __make_const_iterator(const_pointer __p) const { 874fe013be4SDimitry Andric return const_iterator(__p); 875bdd1243dSDimitry Andric } 876bdd1243dSDimitry Andric 8770b57cec5SDimitry Andricpublic: 878bdd1243dSDimitry Andric _LIBCPP_TEMPLATE_DATA_VIS static const size_type npos = -1; 8790b57cec5SDimitry Andric 880bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string() 881bdd1243dSDimitry Andric _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) 882c9157d92SDimitry Andric : __r_(__value_init_tag(), __default_init_tag()) { 883c9157d92SDimitry Andric __annotate_new(0); 884bdd1243dSDimitry Andric } 8850b57cec5SDimitry Andric 886bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(const allocator_type& __a) 8870b57cec5SDimitry Andric#if _LIBCPP_STD_VER <= 14 888bdd1243dSDimitry Andric _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value) 8890b57cec5SDimitry Andric#else 890bdd1243dSDimitry Andric _NOEXCEPT 8910b57cec5SDimitry Andric#endif 892c9157d92SDimitry Andric : __r_(__value_init_tag(), __a) { 893c9157d92SDimitry Andric __annotate_new(0); 894bdd1243dSDimitry Andric } 8950b57cec5SDimitry Andric 896c9157d92SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS basic_string(const basic_string& __str) 897fe013be4SDimitry Andric : __r_(__default_init_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc())) { 898e710425bSDimitry Andric if (!__str.__is_long()) { 899fe013be4SDimitry Andric __r_.first() = __str.__r_.first(); 900c9157d92SDimitry Andric __annotate_new(__get_short_size()); 901e710425bSDimitry Andric } else 902fe013be4SDimitry Andric __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); 903fe013be4SDimitry Andric } 904fe013be4SDimitry Andric 905e710425bSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS 906e710425bSDimitry Andric basic_string(const basic_string& __str, const allocator_type& __a) 907fe013be4SDimitry Andric : __r_(__default_init_tag(), __a) { 908e710425bSDimitry Andric if (!__str.__is_long()) { 909fe013be4SDimitry Andric __r_.first() = __str.__r_.first(); 910c9157d92SDimitry Andric __annotate_new(__get_short_size()); 911e710425bSDimitry Andric } else 912fe013be4SDimitry Andric __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); 913fe013be4SDimitry Andric } 9140b57cec5SDimitry Andric 9150b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 916e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(basic_string&& __str) 9170b57cec5SDimitry Andric# if _LIBCPP_STD_VER <= 14 918bdd1243dSDimitry Andric _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value) 9190b57cec5SDimitry Andric# else 920bdd1243dSDimitry Andric _NOEXCEPT 9210b57cec5SDimitry Andric# endif 922c9157d92SDimitry Andric // Turning off ASan instrumentation for variable initialization with _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS 923c9157d92SDimitry Andric // does not work consistently during initialization of __r_, so we instead unpoison __str's memory manually first. 924c9157d92SDimitry Andric // __str's memory needs to be unpoisoned only in the case where it's a short string. 925a58f00eaSDimitry Andric : __r_([](basic_string &__s) -> decltype(__s.__r_)&& { if(!__s.__is_long()) __s.__annotate_delete(); return std::move(__s.__r_); }(__str)) { 926c9157d92SDimitry Andric __str.__r_.first() = __rep(); 927c9157d92SDimitry Andric __str.__annotate_new(0); 928c9157d92SDimitry Andric if (!__is_long()) 929c9157d92SDimitry Andric __annotate_new(size()); 930bdd1243dSDimitry Andric } 9310b57cec5SDimitry Andric 932e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(basic_string&& __str, const allocator_type& __a) 933bdd1243dSDimitry Andric : __r_(__default_init_tag(), __a) { 934bdd1243dSDimitry Andric if (__str.__is_long() && __a != __str.__alloc()) // copy, not move 935bdd1243dSDimitry Andric __init(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); 936bdd1243dSDimitry Andric else { 937bdd1243dSDimitry Andric if (__libcpp_is_constant_evaluated()) 938bdd1243dSDimitry Andric __r_.first() = __rep(); 939c9157d92SDimitry Andric if (!__str.__is_long()) 940c9157d92SDimitry Andric __str.__annotate_delete(); 941bdd1243dSDimitry Andric __r_.first() = __str.__r_.first(); 942c9157d92SDimitry Andric __str.__r_.first() = __rep(); 943c9157d92SDimitry Andric __str.__annotate_new(0); 944c9157d92SDimitry Andric if (!__is_long() && this != &__str) 945c9157d92SDimitry Andric __annotate_new(size()); 946bdd1243dSDimitry Andric } 947bdd1243dSDimitry Andric } 9480b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 9490b57cec5SDimitry Andric 950fe013be4SDimitry Andric template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0> 951bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s) 952bdd1243dSDimitry Andric : __r_(__default_init_tag(), __default_init_tag()) { 953c9157d92SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "basic_string(const char*) detected nullptr"); 9540b57cec5SDimitry Andric __init(__s, traits_type::length(__s)); 9550b57cec5SDimitry Andric } 9560b57cec5SDimitry Andric 957fe013be4SDimitry Andric template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0> 958fe013be4SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s, const _Allocator& __a) 959fe013be4SDimitry Andric : __r_(__default_init_tag(), __a) { 960c9157d92SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "basic_string(const char*, allocator) detected nullptr"); 961fe013be4SDimitry Andric __init(__s, traits_type::length(__s)); 962fe013be4SDimitry Andric } 9630b57cec5SDimitry Andric 964fe013be4SDimitry Andric#if _LIBCPP_STD_VER >= 23 965fe6060f1SDimitry Andric basic_string(nullptr_t) = delete; 966fe6060f1SDimitry Andric#endif 967fe6060f1SDimitry Andric 968bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s, size_type __n) 969bdd1243dSDimitry Andric : __r_(__default_init_tag(), __default_init_tag()) { 970c9157d92SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr"); 971bdd1243dSDimitry Andric __init(__s, __n); 972bdd1243dSDimitry Andric } 973bdd1243dSDimitry Andric 974bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 975bdd1243dSDimitry Andric basic_string(const _CharT* __s, size_type __n, const _Allocator& __a) 976bdd1243dSDimitry Andric : __r_(__default_init_tag(), __a) { 977c9157d92SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr"); 978bdd1243dSDimitry Andric __init(__s, __n); 979bdd1243dSDimitry Andric } 980bdd1243dSDimitry Andric 981bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(size_type __n, _CharT __c) 982bdd1243dSDimitry Andric : __r_(__default_init_tag(), __default_init_tag()) { 983bdd1243dSDimitry Andric __init(__n, __c); 984bdd1243dSDimitry Andric } 985bdd1243dSDimitry Andric 986fe013be4SDimitry Andric#if _LIBCPP_STD_VER >= 23 987e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr basic_string( 988e710425bSDimitry Andric basic_string&& __str, size_type __pos, const _Allocator& __alloc = _Allocator()) 989bdd1243dSDimitry Andric : basic_string(std::move(__str), __pos, npos, __alloc) {} 990bdd1243dSDimitry Andric 991e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr basic_string( 992e710425bSDimitry Andric basic_string&& __str, size_type __pos, size_type __n, const _Allocator& __alloc = _Allocator()) 993bdd1243dSDimitry Andric : __r_(__default_init_tag(), __alloc) { 994bdd1243dSDimitry Andric if (__pos > __str.size()) 995bdd1243dSDimitry Andric __throw_out_of_range(); 996bdd1243dSDimitry Andric 997bdd1243dSDimitry Andric auto __len = std::min<size_type>(__n, __str.size() - __pos); 998bdd1243dSDimitry Andric if (__alloc_traits::is_always_equal::value || __alloc == __str.__alloc()) { 999c9157d92SDimitry Andric __move_assign(std::move(__str), __pos, __len); 1000bdd1243dSDimitry Andric } else { 1001bdd1243dSDimitry Andric // Perform a copy because the allocators are not compatible. 1002bdd1243dSDimitry Andric __init(__str.data() + __pos, __len); 1003bdd1243dSDimitry Andric } 1004bdd1243dSDimitry Andric } 1005bdd1243dSDimitry Andric#endif 10060b57cec5SDimitry Andric 1007fe013be4SDimitry Andric template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0> 1008fe013be4SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(size_type __n, _CharT __c, const _Allocator& __a) 1009fe013be4SDimitry Andric : __r_(__default_init_tag(), __a) { 1010fe013be4SDimitry Andric __init(__n, __c); 1011fe013be4SDimitry Andric } 10120b57cec5SDimitry Andric 1013bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 1014fe013be4SDimitry Andric basic_string(const basic_string& __str, size_type __pos, size_type __n, const _Allocator& __a = _Allocator()) 1015fe013be4SDimitry Andric : __r_(__default_init_tag(), __a) { 1016fe013be4SDimitry Andric size_type __str_sz = __str.size(); 1017fe013be4SDimitry Andric if (__pos > __str_sz) 1018fe013be4SDimitry Andric __throw_out_of_range(); 1019fe013be4SDimitry Andric __init(__str.data() + __pos, std::min(__n, __str_sz - __pos)); 1020fe013be4SDimitry Andric } 10210b57cec5SDimitry Andric 1022bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 1023bdd1243dSDimitry Andric basic_string(const basic_string& __str, size_type __pos, const _Allocator& __a = _Allocator()) 1024bdd1243dSDimitry Andric : __r_(__default_init_tag(), __a) { 1025bdd1243dSDimitry Andric size_type __str_sz = __str.size(); 1026bdd1243dSDimitry Andric if (__pos > __str_sz) 1027bdd1243dSDimitry Andric __throw_out_of_range(); 1028bdd1243dSDimitry Andric __init(__str.data() + __pos, __str_sz - __pos); 1029bdd1243dSDimitry Andric } 10300b57cec5SDimitry Andric 1031bdd1243dSDimitry Andric template <class _Tp, 1032fe013be4SDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 1033fe013be4SDimitry Andric !__is_same_uncvref<_Tp, basic_string>::value, 1034fe013be4SDimitry Andric int> = 0> 1035bdd1243dSDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 1036fe013be4SDimitry Andric basic_string(const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a = allocator_type()) 1037fe013be4SDimitry Andric : __r_(__default_init_tag(), __a) { 1038fe013be4SDimitry Andric __self_view __sv0 = __t; 1039fe013be4SDimitry Andric __self_view __sv = __sv0.substr(__pos, __n); 1040fe013be4SDimitry Andric __init(__sv.data(), __sv.size()); 1041fe013be4SDimitry Andric } 10420b57cec5SDimitry Andric 1043bdd1243dSDimitry Andric template <class _Tp, 1044fe013be4SDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 1045fe013be4SDimitry Andric !__is_same_uncvref<_Tp, basic_string>::value, 1046fe013be4SDimitry Andric int> = 0> 1047fe013be4SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(const _Tp& __t) 1048fe013be4SDimitry Andric : __r_(__default_init_tag(), __default_init_tag()) { 1049fe013be4SDimitry Andric __self_view __sv = __t; 1050fe013be4SDimitry Andric __init(__sv.data(), __sv.size()); 1051fe013be4SDimitry Andric } 1052bdd1243dSDimitry Andric 1053bdd1243dSDimitry Andric template <class _Tp, 1054fe013be4SDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 1055fe013be4SDimitry Andric !__is_same_uncvref<_Tp, basic_string>::value, 1056fe013be4SDimitry Andric int> = 0> 1057bdd1243dSDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string( 1058fe013be4SDimitry Andric const _Tp& __t, const allocator_type& __a) 1059fe013be4SDimitry Andric : __r_(__default_init_tag(), __a) { 1060fe013be4SDimitry Andric __self_view __sv = __t; 1061fe013be4SDimitry Andric __init(__sv.data(), __sv.size()); 1062fe013be4SDimitry Andric } 10630b57cec5SDimitry Andric 1064fe013be4SDimitry Andric template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0> 1065bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(_InputIterator __first, _InputIterator __last) 1066bdd1243dSDimitry Andric : __r_(__default_init_tag(), __default_init_tag()) { 1067bdd1243dSDimitry Andric __init(__first, __last); 1068bdd1243dSDimitry Andric } 1069bdd1243dSDimitry Andric 1070fe013be4SDimitry Andric template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0> 1071bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 1072bdd1243dSDimitry Andric basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a) 1073bdd1243dSDimitry Andric : __r_(__default_init_tag(), __a) { 1074bdd1243dSDimitry Andric __init(__first, __last); 1075bdd1243dSDimitry Andric } 1076bdd1243dSDimitry Andric 1077fe013be4SDimitry Andric#if _LIBCPP_STD_VER >= 23 1078fe013be4SDimitry Andric template <_ContainerCompatibleRange<_CharT> _Range> 1079e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr basic_string( 1080e710425bSDimitry Andric from_range_t, _Range&& __range, const allocator_type& __a = allocator_type()) 1081fe013be4SDimitry Andric : __r_(__default_init_tag(), __a) { 1082fe013be4SDimitry Andric if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { 1083fe013be4SDimitry Andric __init_with_size(ranges::begin(__range), ranges::end(__range), ranges::distance(__range)); 1084fe013be4SDimitry Andric } else { 1085fe013be4SDimitry Andric __init_with_sentinel(ranges::begin(__range), ranges::end(__range)); 1086fe013be4SDimitry Andric } 1087fe013be4SDimitry Andric } 1088fe013be4SDimitry Andric#endif 1089fe013be4SDimitry Andric 10900b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 1091bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(initializer_list<_CharT> __il) 1092bdd1243dSDimitry Andric : __r_(__default_init_tag(), __default_init_tag()) { 1093bdd1243dSDimitry Andric __init(__il.begin(), __il.end()); 1094bdd1243dSDimitry Andric } 1095bdd1243dSDimitry Andric 1096bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(initializer_list<_CharT> __il, const _Allocator& __a) 1097bdd1243dSDimitry Andric : __r_(__default_init_tag(), __a) { 1098bdd1243dSDimitry Andric __init(__il.begin(), __il.end()); 1099bdd1243dSDimitry Andric } 11000b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 11010b57cec5SDimitry Andric 1102fe013be4SDimitry Andric inline _LIBCPP_CONSTEXPR_SINCE_CXX20 ~basic_string() { 1103c9157d92SDimitry Andric __annotate_delete(); 1104fe013be4SDimitry Andric if (__is_long()) 1105fe013be4SDimitry Andric __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 1106fe013be4SDimitry Andric } 11070b57cec5SDimitry Andric 1108e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 operator __self_view() const _NOEXCEPT { 1109e710425bSDimitry Andric return __self_view(data(), size()); 1110e710425bSDimitry Andric } 11110b57cec5SDimitry Andric 1112e710425bSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS basic_string& 1113e710425bSDimitry Andric operator=(const basic_string& __str); 11140b57cec5SDimitry Andric 1115e710425bSDimitry Andric template <class _Tp, 1116e710425bSDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 1117e710425bSDimitry Andric !__is_same_uncvref<_Tp, basic_string>::value, 1118e710425bSDimitry Andric int> = 0> 1119bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(const _Tp& __t) { 112081ad6265SDimitry Andric __self_view __sv = __t; 112181ad6265SDimitry Andric return assign(__sv); 112281ad6265SDimitry Andric } 11230b57cec5SDimitry Andric 11240b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 1125e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(basic_string&& __str) 1126e710425bSDimitry Andric _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value)) { 1127bdd1243dSDimitry Andric __move_assign(__str, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>()); 1128bdd1243dSDimitry Andric return *this; 1129bdd1243dSDimitry Andric } 1130bdd1243dSDimitry Andric 1131e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(initializer_list<value_type> __il) { 1132e710425bSDimitry Andric return assign(__il.begin(), __il.size()); 1133e710425bSDimitry Andric } 11340b57cec5SDimitry Andric#endif 1135e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(const value_type* __s) { 1136e710425bSDimitry Andric return assign(__s); 1137e710425bSDimitry Andric } 1138fe013be4SDimitry Andric#if _LIBCPP_STD_VER >= 23 1139fe6060f1SDimitry Andric basic_string& operator=(nullptr_t) = delete; 1140fe6060f1SDimitry Andric#endif 1141c9157d92SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS basic_string& operator=(value_type __c); 11420b57cec5SDimitry Andric 1143e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator begin() _NOEXCEPT { 1144e710425bSDimitry Andric return __make_iterator(__get_pointer()); 1145e710425bSDimitry Andric } 1146e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator begin() const _NOEXCEPT { 1147e710425bSDimitry Andric return __make_const_iterator(__get_pointer()); 1148e710425bSDimitry Andric } 1149e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator end() _NOEXCEPT { 1150e710425bSDimitry Andric return __make_iterator(__get_pointer() + size()); 1151e710425bSDimitry Andric } 1152e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator end() const _NOEXCEPT { 1153e710425bSDimitry Andric return __make_const_iterator(__get_pointer() + size()); 1154e710425bSDimitry Andric } 115581ad6265SDimitry Andric 1156e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reverse_iterator rbegin() _NOEXCEPT { 1157e710425bSDimitry Andric return reverse_iterator(end()); 1158e710425bSDimitry Andric } 1159e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator rbegin() const _NOEXCEPT { 1160e710425bSDimitry Andric return const_reverse_iterator(end()); 1161e710425bSDimitry Andric } 1162e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reverse_iterator rend() _NOEXCEPT { 1163e710425bSDimitry Andric return reverse_iterator(begin()); 1164e710425bSDimitry Andric } 1165e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator rend() const _NOEXCEPT { 1166e710425bSDimitry Andric return const_reverse_iterator(begin()); 1167e710425bSDimitry Andric } 11680b57cec5SDimitry Andric 1169e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator cbegin() const _NOEXCEPT { return begin(); } 1170e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator cend() const _NOEXCEPT { return end(); } 1171e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator crbegin() const _NOEXCEPT { 1172e710425bSDimitry Andric return rbegin(); 1173e710425bSDimitry Andric } 1174e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator crend() const _NOEXCEPT { return rend(); } 11750b57cec5SDimitry Andric 1176e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type size() const _NOEXCEPT { 1177e710425bSDimitry Andric return __is_long() ? __get_long_size() : __get_short_size(); 1178e710425bSDimitry Andric } 1179bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type length() const _NOEXCEPT { return size(); } 1180bdd1243dSDimitry Andric 1181bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type max_size() const _NOEXCEPT { 1182bdd1243dSDimitry Andric size_type __m = __alloc_traits::max_size(__alloc()); 1183bdd1243dSDimitry Andric if (__m <= std::numeric_limits<size_type>::max() / 2) { 1184bdd1243dSDimitry Andric return __m - __alignment; 1185bdd1243dSDimitry Andric } else { 1186bdd1243dSDimitry Andric bool __uses_lsb = __endian_factor == 2; 1187bdd1243dSDimitry Andric return __uses_lsb ? __m - __alignment : (__m / 2) - __alignment; 1188bdd1243dSDimitry Andric } 1189bdd1243dSDimitry Andric } 1190bdd1243dSDimitry Andric 1191bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type capacity() const _NOEXCEPT { 119281ad6265SDimitry Andric return (__is_long() ? __get_long_cap() : static_cast<size_type>(__min_cap)) - 1; 119381ad6265SDimitry Andric } 11940b57cec5SDimitry Andric 1195bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 void resize(size_type __n, value_type __c); 1196bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void resize(size_type __n) { resize(__n, value_type()); } 11970b57cec5SDimitry Andric 1198bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 void reserve(size_type __requested_capacity); 119904eeddc0SDimitry Andric 1200fe013be4SDimitry Andric#if _LIBCPP_STD_VER >= 23 120104eeddc0SDimitry Andric template <class _Op> 1202e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr void resize_and_overwrite(size_type __n, _Op __op) { 120304eeddc0SDimitry Andric __resize_default_init(__n); 120481ad6265SDimitry Andric __erase_to_end(std::move(__op)(data(), _LIBCPP_AUTO_CAST(__n))); 120504eeddc0SDimitry Andric } 120604eeddc0SDimitry Andric#endif 120704eeddc0SDimitry Andric 1208bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __resize_default_init(size_type __n); 12090b57cec5SDimitry Andric 1210c9157d92SDimitry Andric#if _LIBCPP_STD_VER < 26 || defined(_LIBCPP_ENABLE_CXX26_REMOVED_STRING_RESERVE) 121181ad6265SDimitry Andric _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI void reserve() _NOEXCEPT { shrink_to_fit(); } 1212c9157d92SDimitry Andric#endif 1213bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void shrink_to_fit() _NOEXCEPT; 1214bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void clear() _NOEXCEPT; 121581ad6265SDimitry Andric 1216e710425bSDimitry Andric _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool empty() const _NOEXCEPT { 1217e710425bSDimitry Andric return size() == 0; 1218e710425bSDimitry Andric } 12190b57cec5SDimitry Andric 1220bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference operator[](size_type __pos) const _NOEXCEPT { 1221fe013be4SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos <= size(), "string index out of bounds"); 1222c9157d92SDimitry Andric if (__builtin_constant_p(__pos) && !__fits_in_sso(__pos)) { 1223c9157d92SDimitry Andric return *(__get_long_pointer() + __pos); 1224c9157d92SDimitry Andric } 1225bdd1243dSDimitry Andric return *(data() + __pos); 1226bdd1243dSDimitry Andric } 12270b57cec5SDimitry Andric 1228bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](size_type __pos) _NOEXCEPT { 1229fe013be4SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos <= size(), "string index out of bounds"); 1230c9157d92SDimitry Andric if (__builtin_constant_p(__pos) && !__fits_in_sso(__pos)) { 1231c9157d92SDimitry Andric return *(__get_long_pointer() + __pos); 1232c9157d92SDimitry Andric } 1233bdd1243dSDimitry Andric return *(__get_pointer() + __pos); 1234bdd1243dSDimitry Andric } 12350b57cec5SDimitry Andric 1236bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference at(size_type __n) const; 1237bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 reference at(size_type __n); 1238bdd1243dSDimitry Andric 1239bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator+=(const basic_string& __str) { 124081ad6265SDimitry Andric return append(__str); 124181ad6265SDimitry Andric } 12420b57cec5SDimitry Andric 1243fe013be4SDimitry Andric template <class _Tp, 1244fe013be4SDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 1245fe013be4SDimitry Andric !__is_same_uncvref<_Tp, basic_string >::value, 1246fe013be4SDimitry Andric int> = 0> 1247fe013be4SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 124881ad6265SDimitry Andric operator+=(const _Tp& __t) { 1249e710425bSDimitry Andric __self_view __sv = __t; 1250e710425bSDimitry Andric return append(__sv); 125181ad6265SDimitry Andric } 125281ad6265SDimitry Andric 1253bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator+=(const value_type* __s) { 125481ad6265SDimitry Andric return append(__s); 125581ad6265SDimitry Andric } 125681ad6265SDimitry Andric 1257bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator+=(value_type __c) { 125881ad6265SDimitry Andric push_back(__c); 125981ad6265SDimitry Andric return *this; 126081ad6265SDimitry Andric } 126181ad6265SDimitry Andric 12620b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 1263e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator+=(initializer_list<value_type> __il) { 1264e710425bSDimitry Andric return append(__il); 1265e710425bSDimitry Andric } 12660b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 12670b57cec5SDimitry Andric 1268bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const basic_string& __str) { 1269bdd1243dSDimitry Andric return append(__str.data(), __str.size()); 1270bdd1243dSDimitry Andric } 12710b57cec5SDimitry Andric 1272fe013be4SDimitry Andric template <class _Tp, 1273fe013be4SDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 1274fe013be4SDimitry Andric !__is_same_uncvref<_Tp, basic_string>::value, 1275fe013be4SDimitry Andric int> = 0> 1276fe013be4SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 1277fe013be4SDimitry Andric append(const _Tp& __t) { 1278fe013be4SDimitry Andric __self_view __sv = __t; 1279fe013be4SDimitry Andric return append(__sv.data(), __sv.size()); 1280fe013be4SDimitry Andric } 1281fe013be4SDimitry Andric 1282bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const basic_string& __str, size_type __pos, size_type __n = npos); 12830b57cec5SDimitry Andric 1284fe013be4SDimitry Andric template <class _Tp, 1285fe013be4SDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 1286fe013be4SDimitry Andric !__is_same_uncvref<_Tp, basic_string>::value, 1287fe013be4SDimitry Andric int> = 0> 1288bdd1243dSDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 1289fe013be4SDimitry Andric 12900b57cec5SDimitry Andric basic_string& 12910b57cec5SDimitry Andric append(const _Tp& __t, size_type __pos, size_type __n = npos); 1292fe013be4SDimitry Andric 1293bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const value_type* __s, size_type __n); 1294bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const value_type* __s); 1295bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(size_type __n, value_type __c); 12960b57cec5SDimitry Andric 1297e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __append_default_init(size_type __n); 12980b57cec5SDimitry Andric 1299fe013be4SDimitry Andric template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0> 1300fe013be4SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 13010b57cec5SDimitry Andric append(_InputIterator __first, _InputIterator __last) { 13020b57cec5SDimitry Andric const basic_string __temp(__first, __last, __alloc()); 13030b57cec5SDimitry Andric append(__temp.data(), __temp.size()); 13040b57cec5SDimitry Andric return *this; 13050b57cec5SDimitry Andric } 1306fe013be4SDimitry Andric 1307fe013be4SDimitry Andric template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0> 1308fe013be4SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 1309fe6060f1SDimitry Andric append(_ForwardIterator __first, _ForwardIterator __last); 13100b57cec5SDimitry Andric 1311fe013be4SDimitry Andric#if _LIBCPP_STD_VER >= 23 1312fe013be4SDimitry Andric template <_ContainerCompatibleRange<_CharT> _Range> 1313e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr basic_string& append_range(_Range&& __range) { 1314fe013be4SDimitry Andric insert_range(end(), std::forward<_Range>(__range)); 1315fe013be4SDimitry Andric return *this; 1316fe013be4SDimitry Andric } 1317fe013be4SDimitry Andric#endif 1318fe013be4SDimitry Andric 13190b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 1320e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(initializer_list<value_type> __il) { 1321e710425bSDimitry Andric return append(__il.begin(), __il.size()); 1322e710425bSDimitry Andric } 13230b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 13240b57cec5SDimitry Andric 1325bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 void push_back(value_type __c); 1326bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void pop_back(); 1327bdd1243dSDimitry Andric 1328bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference front() _NOEXCEPT { 1329fe013be4SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::front(): string is empty"); 1330bdd1243dSDimitry Andric return *__get_pointer(); 1331bdd1243dSDimitry Andric } 1332bdd1243dSDimitry Andric 1333bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference front() const _NOEXCEPT { 1334fe013be4SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::front(): string is empty"); 1335bdd1243dSDimitry Andric return *data(); 1336bdd1243dSDimitry Andric } 1337bdd1243dSDimitry Andric 1338bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference back() _NOEXCEPT { 1339fe013be4SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::back(): string is empty"); 1340bdd1243dSDimitry Andric return *(__get_pointer() + size() - 1); 1341bdd1243dSDimitry Andric } 1342bdd1243dSDimitry Andric 1343bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference back() const _NOEXCEPT { 1344fe013be4SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::back(): string is empty"); 1345bdd1243dSDimitry Andric return *(data() + size() - 1); 1346bdd1243dSDimitry Andric } 13470b57cec5SDimitry Andric 1348fe013be4SDimitry Andric template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 1349fe013be4SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 1350fe013be4SDimitry Andric assign(const _Tp& __t) { 1351fe013be4SDimitry Andric __self_view __sv = __t; 1352fe013be4SDimitry Andric return assign(__sv.data(), __sv.size()); 1353fe013be4SDimitry Andric } 1354fe013be4SDimitry Andric 1355c9157d92SDimitry Andric#if _LIBCPP_STD_VER >= 20 1356e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr void __move_assign(basic_string&& __str, size_type __pos, size_type __len) { 1357c9157d92SDimitry Andric // Pilfer the allocation from __str. 1358c9157d92SDimitry Andric _LIBCPP_ASSERT_INTERNAL(__alloc() == __str.__alloc(), "__move_assign called with wrong allocator"); 1359c9157d92SDimitry Andric size_type __old_sz = __str.size(); 1360c9157d92SDimitry Andric if (!__str.__is_long()) 1361c9157d92SDimitry Andric __str.__annotate_delete(); 1362c9157d92SDimitry Andric __r_.first() = __str.__r_.first(); 1363c9157d92SDimitry Andric __str.__r_.first() = __rep(); 1364c9157d92SDimitry Andric __str.__annotate_new(0); 1365c9157d92SDimitry Andric 1366c9157d92SDimitry Andric _Traits::move(data(), data() + __pos, __len); 1367c9157d92SDimitry Andric __set_size(__len); 1368c9157d92SDimitry Andric _Traits::assign(data()[__len], value_type()); 1369c9157d92SDimitry Andric 1370c9157d92SDimitry Andric if (!__is_long()) { 1371c9157d92SDimitry Andric __annotate_new(__len); 1372c9157d92SDimitry Andric } else if (__old_sz > __len) { 1373c9157d92SDimitry Andric __annotate_shrink(__old_sz); 1374c9157d92SDimitry Andric } 1375c9157d92SDimitry Andric } 1376c9157d92SDimitry Andric#endif 1377c9157d92SDimitry Andric 1378e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const basic_string& __str) { 1379e710425bSDimitry Andric return *this = __str; 1380e710425bSDimitry Andric } 13810b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 1382e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(basic_string&& __str) 1383e710425bSDimitry Andric _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value)) { 1384e710425bSDimitry Andric *this = std::move(__str); 1385e710425bSDimitry Andric return *this; 1386e710425bSDimitry Andric } 13870b57cec5SDimitry Andric#endif 1388bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const basic_string& __str, size_type __pos, size_type __n = npos); 1389fe013be4SDimitry Andric 1390fe013be4SDimitry Andric template <class _Tp, 1391fe013be4SDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 1392fe013be4SDimitry Andric !__is_same_uncvref<_Tp, basic_string>::value, 1393fe013be4SDimitry Andric int> = 0> 1394fe013be4SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 13950b57cec5SDimitry Andric assign(const _Tp& __t, size_type __pos, size_type __n = npos); 1396fe013be4SDimitry Andric 1397bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const value_type* __s, size_type __n); 1398bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const value_type* __s); 1399bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(size_type __n, value_type __c); 1400fe013be4SDimitry Andric template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0> 1401fe013be4SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 14020b57cec5SDimitry Andric assign(_InputIterator __first, _InputIterator __last); 1403fe013be4SDimitry Andric 1404fe013be4SDimitry Andric template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0> 1405fe013be4SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 14060b57cec5SDimitry Andric assign(_ForwardIterator __first, _ForwardIterator __last); 1407fe013be4SDimitry Andric 1408fe013be4SDimitry Andric#if _LIBCPP_STD_VER >= 23 1409fe013be4SDimitry Andric template <_ContainerCompatibleRange<_CharT> _Range> 1410e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr basic_string& assign_range(_Range&& __range) { 1411fe013be4SDimitry Andric if constexpr (__string_is_trivial_iterator<ranges::iterator_t<_Range>>::value && 1412fe013be4SDimitry Andric (ranges::forward_range<_Range> || ranges::sized_range<_Range>)) { 1413fe013be4SDimitry Andric size_type __n = static_cast<size_type>(ranges::distance(__range)); 1414fe013be4SDimitry Andric __assign_trivial(ranges::begin(__range), ranges::end(__range), __n); 1415fe013be4SDimitry Andric 1416fe013be4SDimitry Andric } else { 1417fe013be4SDimitry Andric __assign_with_sentinel(ranges::begin(__range), ranges::end(__range)); 1418fe013be4SDimitry Andric } 1419fe013be4SDimitry Andric 1420fe013be4SDimitry Andric return *this; 1421fe013be4SDimitry Andric } 1422fe013be4SDimitry Andric#endif 1423fe013be4SDimitry Andric 14240b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 1425e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(initializer_list<value_type> __il) { 1426e710425bSDimitry Andric return assign(__il.begin(), __il.size()); 1427e710425bSDimitry Andric } 14280b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 14290b57cec5SDimitry Andric 1430bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 1431bdd1243dSDimitry Andric insert(size_type __pos1, const basic_string& __str) { 1432bdd1243dSDimitry Andric return insert(__pos1, __str.data(), __str.size()); 1433bdd1243dSDimitry Andric } 14340b57cec5SDimitry Andric 1435fe013be4SDimitry Andric template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 1436fe013be4SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 1437fe013be4SDimitry Andric insert(size_type __pos1, const _Tp& __t) { 1438fe013be4SDimitry Andric __self_view __sv = __t; 1439fe013be4SDimitry Andric return insert(__pos1, __sv.data(), __sv.size()); 1440fe013be4SDimitry Andric } 14410b57cec5SDimitry Andric 1442fe013be4SDimitry Andric template <class _Tp, 1443fe013be4SDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 1444fe013be4SDimitry Andric !__is_same_uncvref<_Tp, basic_string>::value, 1445fe013be4SDimitry Andric int> = 0> 1446fe013be4SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 14470b57cec5SDimitry Andric insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n = npos); 1448fe013be4SDimitry Andric 1449fe013be4SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 1450fe013be4SDimitry Andric insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n = npos); 1451bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* __s, size_type __n); 1452bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* __s); 1453bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, size_type __n, value_type __c); 1454bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator insert(const_iterator __pos, value_type __c); 1455bdd1243dSDimitry Andric 1456fe013be4SDimitry Andric#if _LIBCPP_STD_VER >= 23 1457fe013be4SDimitry Andric template <_ContainerCompatibleRange<_CharT> _Range> 1458e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr iterator insert_range(const_iterator __position, _Range&& __range) { 1459fe013be4SDimitry Andric if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { 1460fe013be4SDimitry Andric auto __n = static_cast<size_type>(ranges::distance(__range)); 1461fe013be4SDimitry Andric return __insert_with_size(__position, ranges::begin(__range), ranges::end(__range), __n); 1462fe013be4SDimitry Andric 1463fe013be4SDimitry Andric } else { 1464fe013be4SDimitry Andric basic_string __temp(from_range, std::forward<_Range>(__range), __alloc()); 1465fe013be4SDimitry Andric return insert(__position, __temp.data(), __temp.data() + __temp.size()); 1466fe013be4SDimitry Andric } 1467fe013be4SDimitry Andric } 1468fe013be4SDimitry Andric#endif 1469fe013be4SDimitry Andric 1470bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator 1471bdd1243dSDimitry Andric insert(const_iterator __pos, size_type __n, value_type __c) { 1472bdd1243dSDimitry Andric difference_type __p = __pos - begin(); 1473bdd1243dSDimitry Andric insert(static_cast<size_type>(__p), __n, __c); 1474bdd1243dSDimitry Andric return begin() + __p; 1475bdd1243dSDimitry Andric } 1476bdd1243dSDimitry Andric 1477fe013be4SDimitry Andric template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0> 1478fe013be4SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator 14790b57cec5SDimitry Andric insert(const_iterator __pos, _InputIterator __first, _InputIterator __last); 1480fe013be4SDimitry Andric 1481fe013be4SDimitry Andric template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0> 1482fe013be4SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator 14830b57cec5SDimitry Andric insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last); 1484fe013be4SDimitry Andric 14850b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 1486e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator 1487e710425bSDimitry Andric insert(const_iterator __pos, initializer_list<value_type> __il) { 1488e710425bSDimitry Andric return insert(__pos, __il.begin(), __il.end()); 1489e710425bSDimitry Andric } 14900b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 14910b57cec5SDimitry Andric 1492bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& erase(size_type __pos = 0, size_type __n = npos); 1493e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator erase(const_iterator __pos); 1494e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator erase(const_iterator __first, const_iterator __last); 14950b57cec5SDimitry Andric 1496bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 1497bdd1243dSDimitry Andric replace(size_type __pos1, size_type __n1, const basic_string& __str) { 1498bdd1243dSDimitry Andric return replace(__pos1, __n1, __str.data(), __str.size()); 1499bdd1243dSDimitry Andric } 15000b57cec5SDimitry Andric 1501fe013be4SDimitry Andric template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 1502fe013be4SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 1503fe013be4SDimitry Andric replace(size_type __pos1, size_type __n1, const _Tp& __t) { 1504fe013be4SDimitry Andric __self_view __sv = __t; 1505fe013be4SDimitry Andric return replace(__pos1, __n1, __sv.data(), __sv.size()); 1506fe013be4SDimitry Andric } 1507fe013be4SDimitry Andric 1508fe013be4SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 1509fe013be4SDimitry Andric replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2 = npos); 1510fe013be4SDimitry Andric 1511fe013be4SDimitry Andric template <class _Tp, 1512fe013be4SDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 1513fe013be4SDimitry Andric !__is_same_uncvref<_Tp, basic_string>::value, 1514fe013be4SDimitry Andric int> = 0> 1515fe013be4SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 15160b57cec5SDimitry Andric replace(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2 = npos); 1517fe013be4SDimitry Andric 1518fe013be4SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 1519fe013be4SDimitry Andric replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2); 1520bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& replace(size_type __pos, size_type __n1, const value_type* __s); 1521bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c); 1522bdd1243dSDimitry Andric 1523bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 1524bdd1243dSDimitry Andric replace(const_iterator __i1, const_iterator __i2, const basic_string& __str) { 1525bdd1243dSDimitry Andric return replace( 1526bdd1243dSDimitry Andric static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __str.data(), __str.size()); 1527bdd1243dSDimitry Andric } 15280b57cec5SDimitry Andric 1529fe013be4SDimitry Andric template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 1530fe013be4SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 1531fe013be4SDimitry Andric replace(const_iterator __i1, const_iterator __i2, const _Tp& __t) { 1532fe013be4SDimitry Andric __self_view __sv = __t; 1533fe013be4SDimitry Andric return replace(__i1 - begin(), __i2 - __i1, __sv); 1534fe013be4SDimitry Andric } 15350b57cec5SDimitry Andric 1536bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 1537bdd1243dSDimitry Andric replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n) { 1538bdd1243dSDimitry Andric return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s, __n); 1539bdd1243dSDimitry Andric } 1540bdd1243dSDimitry Andric 1541bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 1542bdd1243dSDimitry Andric replace(const_iterator __i1, const_iterator __i2, const value_type* __s) { 1543bdd1243dSDimitry Andric return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s); 1544bdd1243dSDimitry Andric } 1545bdd1243dSDimitry Andric 1546bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 1547bdd1243dSDimitry Andric replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c) { 1548bdd1243dSDimitry Andric return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __n, __c); 1549bdd1243dSDimitry Andric } 1550bdd1243dSDimitry Andric 1551fe013be4SDimitry Andric template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0> 1552fe013be4SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 15530b57cec5SDimitry Andric replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2); 1554fe013be4SDimitry Andric 1555fe013be4SDimitry Andric#if _LIBCPP_STD_VER >= 23 1556fe013be4SDimitry Andric template <_ContainerCompatibleRange<_CharT> _Range> 1557e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr basic_string& 1558e710425bSDimitry Andric replace_with_range(const_iterator __i1, const_iterator __i2, _Range&& __range) { 1559fe013be4SDimitry Andric basic_string __temp(from_range, std::forward<_Range>(__range), __alloc()); 1560fe013be4SDimitry Andric return replace(__i1, __i2, __temp); 1561fe013be4SDimitry Andric } 1562fe013be4SDimitry Andric#endif 1563fe013be4SDimitry Andric 15640b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 1565e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 1566e710425bSDimitry Andric replace(const_iterator __i1, const_iterator __i2, initializer_list<value_type> __il) { 1567e710425bSDimitry Andric return replace(__i1, __i2, __il.begin(), __il.end()); 1568e710425bSDimitry Andric } 15690b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 15700b57cec5SDimitry Andric 1571bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type copy(value_type* __s, size_type __n, size_type __pos = 0) const; 15720b57cec5SDimitry Andric 1573bdd1243dSDimitry Andric#if _LIBCPP_STD_VER <= 20 1574e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string 1575e710425bSDimitry Andric substr(size_type __pos = 0, size_type __n = npos) const { 1576bdd1243dSDimitry Andric return basic_string(*this, __pos, __n); 1577bdd1243dSDimitry Andric } 1578bdd1243dSDimitry Andric#else 1579e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr basic_string substr(size_type __pos = 0, size_type __n = npos) const& { 1580bdd1243dSDimitry Andric return basic_string(*this, __pos, __n); 1581bdd1243dSDimitry Andric } 1582bdd1243dSDimitry Andric 1583e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr basic_string substr(size_type __pos = 0, size_type __n = npos) && { 1584bdd1243dSDimitry Andric return basic_string(std::move(*this), __pos, __n); 1585bdd1243dSDimitry Andric } 1586bdd1243dSDimitry Andric#endif 1587bdd1243dSDimitry Andric 1588e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(basic_string& __str) 15890b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14 15900b57cec5SDimitry Andric _NOEXCEPT; 15910b57cec5SDimitry Andric#else 1592e710425bSDimitry Andric _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<allocator_type>::value); 15930b57cec5SDimitry Andric#endif 15940b57cec5SDimitry Andric 1595e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const value_type* c_str() const _NOEXCEPT { return data(); } 1596e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const value_type* data() const _NOEXCEPT { 1597e710425bSDimitry Andric return std::__to_address(__get_pointer()); 1598e710425bSDimitry Andric } 1599fe013be4SDimitry Andric#if _LIBCPP_STD_VER >= 17 1600e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 value_type* data() _NOEXCEPT { 1601e710425bSDimitry Andric return std::__to_address(__get_pointer()); 1602e710425bSDimitry Andric } 16030b57cec5SDimitry Andric#endif 16040b57cec5SDimitry Andric 1605e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 allocator_type get_allocator() const _NOEXCEPT { 1606e710425bSDimitry Andric return __alloc(); 1607e710425bSDimitry Andric } 16080b57cec5SDimitry Andric 1609e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1610e710425bSDimitry Andric find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; 16110b57cec5SDimitry Andric 1612fe013be4SDimitry Andric template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 1613fe013be4SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1614fe6060f1SDimitry Andric find(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT; 1615fe013be4SDimitry Andric 1616fe013be4SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; 1617e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1618e710425bSDimitry Andric find(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; 1619bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT; 16200b57cec5SDimitry Andric 1621e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1622e710425bSDimitry Andric rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; 16230b57cec5SDimitry Andric 1624fe013be4SDimitry Andric template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 1625fe013be4SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1626fe6060f1SDimitry Andric rfind(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT; 1627fe013be4SDimitry Andric 1628e710425bSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; 1629e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1630e710425bSDimitry Andric rfind(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; 1631bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type rfind(value_type __c, size_type __pos = npos) const _NOEXCEPT; 16320b57cec5SDimitry Andric 1633e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1634e710425bSDimitry Andric find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; 16350b57cec5SDimitry Andric 1636fe013be4SDimitry Andric template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 1637fe013be4SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1638fe6060f1SDimitry Andric find_first_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT; 1639fe013be4SDimitry Andric 1640e710425bSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1641e710425bSDimitry Andric find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; 1642e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1643e710425bSDimitry Andric find_first_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; 1644e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1645e710425bSDimitry Andric find_first_of(value_type __c, size_type __pos = 0) const _NOEXCEPT; 16460b57cec5SDimitry Andric 1647e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1648e710425bSDimitry Andric find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; 16490b57cec5SDimitry Andric 1650fe013be4SDimitry Andric template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 1651fe013be4SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1652fe6060f1SDimitry Andric find_last_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT; 1653fe013be4SDimitry Andric 1654e710425bSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1655e710425bSDimitry Andric find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; 1656e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1657e710425bSDimitry Andric find_last_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; 1658e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1659e710425bSDimitry Andric find_last_of(value_type __c, size_type __pos = npos) const _NOEXCEPT; 16600b57cec5SDimitry Andric 1661e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1662e710425bSDimitry Andric find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; 16630b57cec5SDimitry Andric 1664fe013be4SDimitry Andric template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 1665fe013be4SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1666fe6060f1SDimitry Andric find_first_not_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT; 1667fe013be4SDimitry Andric 1668e710425bSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1669e710425bSDimitry Andric find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; 1670e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1671e710425bSDimitry Andric find_first_not_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; 1672e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1673e710425bSDimitry Andric find_first_not_of(value_type __c, size_type __pos = 0) const _NOEXCEPT; 16740b57cec5SDimitry Andric 1675e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1676e710425bSDimitry Andric find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; 16770b57cec5SDimitry Andric 1678fe013be4SDimitry Andric template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 1679fe013be4SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1680fe6060f1SDimitry Andric find_last_not_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT; 1681fe013be4SDimitry Andric 1682e710425bSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1683e710425bSDimitry Andric find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; 1684e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1685e710425bSDimitry Andric find_last_not_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; 1686e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type 1687e710425bSDimitry Andric find_last_not_of(value_type __c, size_type __pos = npos) const _NOEXCEPT; 16880b57cec5SDimitry Andric 1689e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(const basic_string& __str) const _NOEXCEPT; 16900b57cec5SDimitry Andric 1691fe013be4SDimitry Andric template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 1692fe013be4SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 int 1693fe6060f1SDimitry Andric compare(const _Tp& __t) const _NOEXCEPT; 16940b57cec5SDimitry Andric 1695fe013be4SDimitry Andric template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> 1696fe013be4SDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 int 16970b57cec5SDimitry Andric compare(size_type __pos1, size_type __n1, const _Tp& __t) const; 16980b57cec5SDimitry Andric 1699e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int 1700e710425bSDimitry Andric compare(size_type __pos1, size_type __n1, const basic_string& __str) const; 1701e710425bSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 int 1702e710425bSDimitry Andric compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2 = npos) const; 17030b57cec5SDimitry Andric 1704fe013be4SDimitry Andric template <class _Tp, 1705fe013be4SDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 1706fe013be4SDimitry Andric !__is_same_uncvref<_Tp, basic_string>::value, 1707fe013be4SDimitry Andric int> = 0> 1708fe013be4SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int 17090b57cec5SDimitry Andric compare(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2 = npos) const; 1710fe013be4SDimitry Andric 1711bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(const value_type* __s) const _NOEXCEPT; 1712bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(size_type __pos1, size_type __n1, const value_type* __s) const; 1713e710425bSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 int 1714e710425bSDimitry Andric compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const; 17150b57cec5SDimitry Andric 1716fe013be4SDimitry Andric#if _LIBCPP_STD_VER >= 20 1717e710425bSDimitry Andric constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(__self_view __sv) const noexcept { 1718e710425bSDimitry Andric return __self_view(data(), size()).starts_with(__sv); 1719e710425bSDimitry Andric } 17200b57cec5SDimitry Andric 1721e710425bSDimitry Andric constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(value_type __c) const noexcept { 1722e710425bSDimitry Andric return !empty() && _Traits::eq(front(), __c); 1723e710425bSDimitry Andric } 17240b57cec5SDimitry Andric 1725e710425bSDimitry Andric constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(const value_type* __s) const noexcept { 1726e710425bSDimitry Andric return starts_with(__self_view(__s)); 1727e710425bSDimitry Andric } 17280b57cec5SDimitry Andric 1729e710425bSDimitry Andric constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(__self_view __sv) const noexcept { 1730e710425bSDimitry Andric return __self_view(data(), size()).ends_with(__sv); 1731e710425bSDimitry Andric } 17320b57cec5SDimitry Andric 1733e710425bSDimitry Andric constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(value_type __c) const noexcept { 1734e710425bSDimitry Andric return !empty() && _Traits::eq(back(), __c); 1735e710425bSDimitry Andric } 17360b57cec5SDimitry Andric 1737e710425bSDimitry Andric constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(const value_type* __s) const noexcept { 1738e710425bSDimitry Andric return ends_with(__self_view(__s)); 1739e710425bSDimitry Andric } 17400b57cec5SDimitry Andric#endif 17410b57cec5SDimitry Andric 1742fe013be4SDimitry Andric#if _LIBCPP_STD_VER >= 23 1743e710425bSDimitry Andric constexpr _LIBCPP_HIDE_FROM_ABI bool contains(__self_view __sv) const noexcept { 1744e710425bSDimitry Andric return __self_view(data(), size()).contains(__sv); 1745e710425bSDimitry Andric } 1746e8d8bef9SDimitry Andric 1747e710425bSDimitry Andric constexpr _LIBCPP_HIDE_FROM_ABI bool contains(value_type __c) const noexcept { 1748e710425bSDimitry Andric return __self_view(data(), size()).contains(__c); 1749e710425bSDimitry Andric } 1750e8d8bef9SDimitry Andric 1751e710425bSDimitry Andric constexpr _LIBCPP_HIDE_FROM_ABI bool contains(const value_type* __s) const { 1752e710425bSDimitry Andric return __self_view(data(), size()).contains(__s); 1753e710425bSDimitry Andric } 1754e8d8bef9SDimitry Andric#endif 1755e8d8bef9SDimitry Andric 1756bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __invariants() const; 17570b57cec5SDimitry Andric 1758bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __clear_and_shrink() _NOEXCEPT; 17590b57cec5SDimitry Andric 17600b57cec5SDimitry Andricprivate: 176181ad6265SDimitry Andric template <class _Alloc> 1762e710425bSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool friend 1763e710425bSDimitry Andric operator==(const basic_string<char, char_traits<char>, _Alloc>& __lhs, 176481ad6265SDimitry Andric const basic_string<char, char_traits<char>, _Alloc>& __rhs) _NOEXCEPT; 176581ad6265SDimitry Andric 1766bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __shrink_or_extend(size_type __target_capacity); 176781ad6265SDimitry Andric 1768e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS bool 1769e710425bSDimitry Andric __is_long() const _NOEXCEPT { 1770c9157d92SDimitry Andric if (__libcpp_is_constant_evaluated() && __builtin_constant_p(__r_.first().__l.__is_long_)) { 1771c9157d92SDimitry Andric return __r_.first().__l.__is_long_; 1772c9157d92SDimitry Andric } 177381ad6265SDimitry Andric return __r_.first().__s.__is_long_; 177481ad6265SDimitry Andric } 177581ad6265SDimitry Andric 1776bdd1243dSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __begin_lifetime(pointer __begin, size_type __n) { 1777fe013be4SDimitry Andric#if _LIBCPP_STD_VER >= 20 177881ad6265SDimitry Andric if (__libcpp_is_constant_evaluated()) { 177981ad6265SDimitry Andric for (size_type __i = 0; __i != __n; ++__i) 178081ad6265SDimitry Andric std::construct_at(std::addressof(__begin[__i])); 178181ad6265SDimitry Andric } 178281ad6265SDimitry Andric#else 178381ad6265SDimitry Andric (void)__begin; 178481ad6265SDimitry Andric (void)__n; 1785fe013be4SDimitry Andric#endif // _LIBCPP_STD_VER >= 20 178681ad6265SDimitry Andric } 178781ad6265SDimitry Andric 1788e710425bSDimitry Andric _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI static bool __fits_in_sso(size_type __sz) { return __sz < __min_cap; } 178904eeddc0SDimitry Andric 1790fe013be4SDimitry Andric template <class _Iterator, class _Sentinel> 1791e710425bSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void 1792e710425bSDimitry Andric __assign_trivial(_Iterator __first, _Sentinel __last, size_type __n); 1793fe013be4SDimitry Andric 1794fe013be4SDimitry Andric template <class _Iterator, class _Sentinel> 1795e710425bSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __assign_with_sentinel(_Iterator __first, _Sentinel __last); 1796fe013be4SDimitry Andric 1797fe013be4SDimitry Andric template <class _ForwardIterator, class _Sentinel> 1798e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 iterator 1799e710425bSDimitry Andric __insert_from_safe_copy(size_type __n, size_type __ip, _ForwardIterator __first, _Sentinel __last) { 180081ad6265SDimitry Andric size_type __sz = size(); 180181ad6265SDimitry Andric size_type __cap = capacity(); 180281ad6265SDimitry Andric value_type* __p; 1803e710425bSDimitry Andric if (__cap - __sz >= __n) { 1804c9157d92SDimitry Andric __annotate_increase(__n); 180581ad6265SDimitry Andric __p = std::__to_address(__get_pointer()); 180681ad6265SDimitry Andric size_type __n_move = __sz - __ip; 180781ad6265SDimitry Andric if (__n_move != 0) 180881ad6265SDimitry Andric traits_type::move(__p + __ip + __n, __p + __ip, __n_move); 1809e710425bSDimitry Andric } else { 1810fe013be4SDimitry Andric __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __ip, 0, __n); 181181ad6265SDimitry Andric __p = std::__to_address(__get_long_pointer()); 181281ad6265SDimitry Andric } 181381ad6265SDimitry Andric __sz += __n; 181481ad6265SDimitry Andric __set_size(__sz); 181581ad6265SDimitry Andric traits_type::assign(__p[__sz], value_type()); 181681ad6265SDimitry Andric for (__p += __ip; __first != __last; ++__p, ++__first) 181781ad6265SDimitry Andric traits_type::assign(*__p, *__first); 18180b57cec5SDimitry Andric 181981ad6265SDimitry Andric return begin() + __ip; 182081ad6265SDimitry Andric } 18210b57cec5SDimitry Andric 1822fe013be4SDimitry Andric template <class _Iterator, class _Sentinel> 1823e710425bSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator 1824e710425bSDimitry Andric __insert_with_size(const_iterator __pos, _Iterator __first, _Sentinel __last, size_type __n); 1825fe013be4SDimitry Andric 1826bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 allocator_type& __alloc() _NOEXCEPT { return __r_.second(); } 182781ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const allocator_type& __alloc() const _NOEXCEPT { return __r_.second(); } 18280b57cec5SDimitry Andric 1829e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS void 1830e710425bSDimitry Andric __set_short_size(size_type __s) _NOEXCEPT { 1831e710425bSDimitry Andric _LIBCPP_ASSERT_INTERNAL(__s < __min_cap, "__s should never be greater than or equal to the short string capacity"); 183281ad6265SDimitry Andric __r_.first().__s.__size_ = __s; 183381ad6265SDimitry Andric __r_.first().__s.__is_long_ = false; 183481ad6265SDimitry Andric } 18350b57cec5SDimitry Andric 1836e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS size_type 1837e710425bSDimitry Andric __get_short_size() const _NOEXCEPT { 1838e710425bSDimitry Andric _LIBCPP_ASSERT_INTERNAL(!__r_.first().__s.__is_long_, "String has to be short when trying to get the short size"); 183981ad6265SDimitry Andric return __r_.first().__s.__size_; 184081ad6265SDimitry Andric } 18410b57cec5SDimitry Andric 1842e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __set_long_size(size_type __s) _NOEXCEPT { 1843e710425bSDimitry Andric __r_.first().__l.__size_ = __s; 1844e710425bSDimitry Andric } 1845e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __get_long_size() const _NOEXCEPT { 1846e710425bSDimitry Andric return __r_.first().__l.__size_; 1847e710425bSDimitry Andric } 1848e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __set_size(size_type __s) _NOEXCEPT { 1849e710425bSDimitry Andric if (__is_long()) 1850e710425bSDimitry Andric __set_long_size(__s); 1851e710425bSDimitry Andric else 1852e710425bSDimitry Andric __set_short_size(__s); 1853e710425bSDimitry Andric } 18540b57cec5SDimitry Andric 1855e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __set_long_cap(size_type __s) _NOEXCEPT { 185681ad6265SDimitry Andric __r_.first().__l.__cap_ = __s / __endian_factor; 185781ad6265SDimitry Andric __r_.first().__l.__is_long_ = true; 185881ad6265SDimitry Andric } 18590b57cec5SDimitry Andric 1860e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __get_long_cap() const _NOEXCEPT { 186181ad6265SDimitry Andric return __r_.first().__l.__cap_ * __endian_factor; 186281ad6265SDimitry Andric } 186381ad6265SDimitry Andric 1864e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __set_long_pointer(pointer __p) _NOEXCEPT { 1865e710425bSDimitry Andric __r_.first().__l.__data_ = __p; 1866e710425bSDimitry Andric } 1867e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pointer __get_long_pointer() _NOEXCEPT { 1868e710425bSDimitry Andric return __r_.first().__l.__data_; 1869e710425bSDimitry Andric } 1870e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_pointer __get_long_pointer() const _NOEXCEPT { 1871e710425bSDimitry Andric return __r_.first().__l.__data_; 1872e710425bSDimitry Andric } 1873e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pointer __get_short_pointer() _NOEXCEPT { 1874e710425bSDimitry Andric return pointer_traits<pointer>::pointer_to(__r_.first().__s.__data_[0]); 1875e710425bSDimitry Andric } 1876e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_pointer __get_short_pointer() const _NOEXCEPT { 1877e710425bSDimitry Andric return pointer_traits<const_pointer>::pointer_to(__r_.first().__s.__data_[0]); 1878e710425bSDimitry Andric } 1879e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pointer __get_pointer() _NOEXCEPT { 1880e710425bSDimitry Andric return __is_long() ? __get_long_pointer() : __get_short_pointer(); 1881e710425bSDimitry Andric } 1882e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_pointer __get_pointer() const _NOEXCEPT { 1883e710425bSDimitry Andric return __is_long() ? __get_long_pointer() : __get_short_pointer(); 1884e710425bSDimitry Andric } 18850b57cec5SDimitry Andric 1886c9157d92SDimitry Andric // The following functions are no-ops outside of AddressSanitizer mode. 1887e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 1888e710425bSDimitry Andric __annotate_contiguous_container(const void* __old_mid, const void* __new_mid) const { 1889c9157d92SDimitry Andric (void)__old_mid; 1890c9157d92SDimitry Andric (void)__new_mid; 1891c9157d92SDimitry Andric#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN) 1892c9157d92SDimitry Andric const void* __begin = data(); 1893c9157d92SDimitry Andric const void* __end = data() + capacity() + 1; 1894a58f00eaSDimitry Andric if (__asan_annotate_container_with_allocator<allocator_type>::value && !__libcpp_is_constant_evaluated()) 1895c9157d92SDimitry Andric __sanitizer_annotate_contiguous_container(__begin, __end, __old_mid, __new_mid); 1896c9157d92SDimitry Andric#endif 1897c9157d92SDimitry Andric } 1898c9157d92SDimitry Andric 1899c9157d92SDimitry Andric // ASan: short string is poisoned if and only if this function returns true. 1900c9157d92SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __asan_short_string_is_annotated() const _NOEXCEPT { 1901c9157d92SDimitry Andric return _LIBCPP_SHORT_STRING_ANNOTATIONS_ALLOWED && !__libcpp_is_constant_evaluated(); 1902c9157d92SDimitry Andric } 1903c9157d92SDimitry Andric 1904c9157d92SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __annotate_new(size_type __current_size) const _NOEXCEPT { 1905e710425bSDimitry Andric (void) __current_size; 1906e710425bSDimitry Andric#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN) 1907c9157d92SDimitry Andric if (!__libcpp_is_constant_evaluated() && (__asan_short_string_is_annotated() || __is_long())) 1908c9157d92SDimitry Andric __annotate_contiguous_container(data() + capacity() + 1, data() + __current_size + 1); 1909e710425bSDimitry Andric#endif 1910c9157d92SDimitry Andric } 1911c9157d92SDimitry Andric 1912c9157d92SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __annotate_delete() const _NOEXCEPT { 1913e710425bSDimitry Andric#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN) 1914c9157d92SDimitry Andric if (!__libcpp_is_constant_evaluated() && (__asan_short_string_is_annotated() || __is_long())) 1915c9157d92SDimitry Andric __annotate_contiguous_container(data() + size() + 1, data() + capacity() + 1); 1916e710425bSDimitry Andric#endif 1917c9157d92SDimitry Andric } 1918c9157d92SDimitry Andric 1919c9157d92SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __annotate_increase(size_type __n) const _NOEXCEPT { 1920e710425bSDimitry Andric (void) __n; 1921e710425bSDimitry Andric#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN) 1922c9157d92SDimitry Andric if (!__libcpp_is_constant_evaluated() && (__asan_short_string_is_annotated() || __is_long())) 1923c9157d92SDimitry Andric __annotate_contiguous_container(data() + size() + 1, data() + size() + 1 + __n); 1924e710425bSDimitry Andric#endif 1925c9157d92SDimitry Andric } 1926c9157d92SDimitry Andric 1927c9157d92SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __annotate_shrink(size_type __old_size) const _NOEXCEPT { 1928e710425bSDimitry Andric (void) __old_size; 1929e710425bSDimitry Andric#if !defined(_LIBCPP_HAS_NO_ASAN) && defined(_LIBCPP_INSTRUMENTED_WITH_ASAN) 1930c9157d92SDimitry Andric if (!__libcpp_is_constant_evaluated() && (__asan_short_string_is_annotated() || __is_long())) 1931c9157d92SDimitry Andric __annotate_contiguous_container(data() + __old_size + 1, data() + size() + 1); 1932e710425bSDimitry Andric#endif 1933c9157d92SDimitry Andric } 1934c9157d92SDimitry Andric 1935e710425bSDimitry Andric template <size_type __a> 1936e710425bSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __align_it(size_type __s) _NOEXCEPT { 1937e710425bSDimitry Andric return (__s + (__a - 1)) & ~(__a - 1); 1938e710425bSDimitry Andric } 1939c9157d92SDimitry Andric enum { 1940b9d9368bSDimitry Andric __alignment = 8 1941c9157d92SDimitry Andric }; 1942e710425bSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __recommend(size_type __s) _NOEXCEPT { 194381ad6265SDimitry Andric if (__s < __min_cap) { 194481ad6265SDimitry Andric return static_cast<size_type>(__min_cap) - 1; 194581ad6265SDimitry Andric } 1946*55c5dad2SDimitry Andric const size_type __boundary = sizeof(value_type) < __alignment ? __alignment / sizeof(value_type) : __endian_factor; 1947*55c5dad2SDimitry Andric size_type __guess = __align_it<__boundary>(__s + 1) - 1; 1948e710425bSDimitry Andric if (__guess == __min_cap) 1949*55c5dad2SDimitry Andric __guess += __endian_factor; 19500b57cec5SDimitry Andric return __guess; 19510b57cec5SDimitry Andric } 19520b57cec5SDimitry Andric 1953e710425bSDimitry Andric inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init(const value_type* __s, size_type __sz, size_type __reserve); 1954e710425bSDimitry Andric inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init(const value_type* __s, size_type __sz); 1955e710425bSDimitry Andric inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init(size_type __n, value_type __c); 19560b57cec5SDimitry Andric 19575ffd83dbSDimitry Andric // Slow path for the (inlined) copy constructor for 'long' strings. 19585ffd83dbSDimitry Andric // Always externally instantiated and not inlined. 19595ffd83dbSDimitry Andric // Requires that __s is zero terminated. 19605ffd83dbSDimitry Andric // The main reason for this function to exist is because for unstable, we 19615ffd83dbSDimitry Andric // want to allow inlining of the copy constructor. However, we don't want 19625ffd83dbSDimitry Andric // to call the __init() functions as those are marked as inline which may 19635ffd83dbSDimitry Andric // result in over-aggressive inlining by the compiler, where our aim is 19645ffd83dbSDimitry Andric // to only inline the fast path code directly in the ctor. 1965c9157d92SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE void __init_copy_ctor_external(const value_type* __s, size_type __sz); 19665ffd83dbSDimitry Andric 1967fe013be4SDimitry Andric template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0> 1968fe013be4SDimitry Andric inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init(_InputIterator __first, _InputIterator __last); 19690b57cec5SDimitry Andric 1970fe013be4SDimitry Andric template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0> 1971fe013be4SDimitry Andric inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init(_ForwardIterator __first, _ForwardIterator __last); 1972fe013be4SDimitry Andric 1973fe013be4SDimitry Andric template <class _InputIterator, class _Sentinel> 1974e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 1975e710425bSDimitry Andric __init_with_sentinel(_InputIterator __first, _Sentinel __last); 1976fe013be4SDimitry Andric template <class _InputIterator, class _Sentinel> 1977e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 1978e710425bSDimitry Andric __init_with_size(_InputIterator __first, _Sentinel __last, size_type __sz); 19790b57cec5SDimitry Andric 1980bdd1243dSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 1981fe013be4SDimitry Andric#if _LIBCPP_ABI_VERSION >= 2 // We want to use the function in the dylib in ABIv1 1982fe013be4SDimitry Andric _LIBCPP_HIDE_FROM_ABI 1983fe013be4SDimitry Andric#endif 1984e710425bSDimitry Andric _LIBCPP_DEPRECATED_("use __grow_by_without_replace") void __grow_by( 1985e710425bSDimitry Andric size_type __old_cap, 1986e710425bSDimitry Andric size_type __delta_cap, 1987e710425bSDimitry Andric size_type __old_sz, 1988e710425bSDimitry Andric size_type __n_copy, 1989e710425bSDimitry Andric size_type __n_del, 1990e710425bSDimitry Andric size_type __n_add = 0); 1991e710425bSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __grow_by_without_replace( 1992e710425bSDimitry Andric size_type __old_cap, 1993e710425bSDimitry Andric size_type __delta_cap, 1994e710425bSDimitry Andric size_type __old_sz, 1995e710425bSDimitry Andric size_type __n_copy, 1996e710425bSDimitry Andric size_type __n_del, 1997e710425bSDimitry Andric size_type __n_add = 0); 1998e710425bSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 void __grow_by_and_replace( 1999e710425bSDimitry Andric size_type __old_cap, 2000e710425bSDimitry Andric size_type __delta_cap, 2001e710425bSDimitry Andric size_type __old_sz, 2002e710425bSDimitry Andric size_type __n_copy, 2003e710425bSDimitry Andric size_type __n_del, 2004e710425bSDimitry Andric size_type __n_add, 2005e710425bSDimitry Andric const value_type* __p_new_stuff); 20060b57cec5SDimitry Andric 20075ffd83dbSDimitry Andric // __assign_no_alias is invoked for assignment operations where we 20085ffd83dbSDimitry Andric // have proof that the input does not alias the current instance. 20095ffd83dbSDimitry Andric // For example, operator=(basic_string) performs a 'self' check. 20105ffd83dbSDimitry Andric template <bool __is_short> 2011c9157d92SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE basic_string& __assign_no_alias(const value_type* __s, size_type __n); 20125ffd83dbSDimitry Andric 2013bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __erase_to_end(size_type __pos) { 2014bdd1243dSDimitry Andric __null_terminate_at(std::__to_address(__get_pointer()), __pos); 2015bdd1243dSDimitry Andric } 20160b57cec5SDimitry Andric 20175ffd83dbSDimitry Andric // __erase_external_with_move is invoked for erase() invocations where 20185ffd83dbSDimitry Andric // `n ~= npos`, likely requiring memory moves on the string data. 2019c9157d92SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE void __erase_external_with_move(size_type __pos, size_type __n); 20205ffd83dbSDimitry Andric 2021e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __copy_assign_alloc(const basic_string& __str) { 2022e710425bSDimitry Andric __copy_assign_alloc( 2023e710425bSDimitry Andric __str, integral_constant<bool, __alloc_traits::propagate_on_container_copy_assignment::value>()); 2024e710425bSDimitry Andric } 20250b57cec5SDimitry Andric 2026e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __copy_assign_alloc(const basic_string& __str, true_type) { 20270b57cec5SDimitry Andric if (__alloc() == __str.__alloc()) 20280b57cec5SDimitry Andric __alloc() = __str.__alloc(); 2029e710425bSDimitry Andric else { 2030e710425bSDimitry Andric if (!__str.__is_long()) { 20310b57cec5SDimitry Andric __clear_and_shrink(); 20320b57cec5SDimitry Andric __alloc() = __str.__alloc(); 2033e710425bSDimitry Andric } else { 2034c9157d92SDimitry Andric __annotate_delete(); 20350b57cec5SDimitry Andric allocator_type __a = __str.__alloc(); 203681ad6265SDimitry Andric auto __allocation = std::__allocate_at_least(__a, __str.__get_long_cap()); 203781ad6265SDimitry Andric __begin_lifetime(__allocation.ptr, __allocation.count); 2038c9157d92SDimitry Andric if (__is_long()) 2039bdd1243dSDimitry Andric __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 204081ad6265SDimitry Andric __alloc() = std::move(__a); 204181ad6265SDimitry Andric __set_long_pointer(__allocation.ptr); 204281ad6265SDimitry Andric __set_long_cap(__allocation.count); 20430b57cec5SDimitry Andric __set_long_size(__str.size()); 2044c9157d92SDimitry Andric __annotate_new(__get_long_size()); 20450b57cec5SDimitry Andric } 20460b57cec5SDimitry Andric } 20470b57cec5SDimitry Andric } 20480b57cec5SDimitry Andric 2049e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 2050e710425bSDimitry Andric __copy_assign_alloc(const basic_string&, false_type) _NOEXCEPT {} 20510b57cec5SDimitry Andric 20520b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 2053e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign(basic_string& __str, false_type) 20540b57cec5SDimitry Andric _NOEXCEPT_(__alloc_traits::is_always_equal::value); 2055e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS void 2056e710425bSDimitry Andric __move_assign(basic_string& __str, true_type) 2057fe013be4SDimitry Andric# if _LIBCPP_STD_VER >= 17 20580b57cec5SDimitry Andric _NOEXCEPT; 20590b57cec5SDimitry Andric# else 20600b57cec5SDimitry Andric _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value); 20610b57cec5SDimitry Andric# endif 20620b57cec5SDimitry Andric#endif 20630b57cec5SDimitry Andric 2064e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign_alloc(basic_string& __str) 2065e710425bSDimitry Andric _NOEXCEPT_(!__alloc_traits::propagate_on_container_move_assignment::value || 2066e710425bSDimitry Andric is_nothrow_move_assignable<allocator_type>::value) { 2067e710425bSDimitry Andric __move_assign_alloc( 2068e710425bSDimitry Andric __str, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>()); 2069e710425bSDimitry Andric } 20700b57cec5SDimitry Andric 2071e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign_alloc(basic_string& __c, true_type) 2072e710425bSDimitry Andric _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) { 207381ad6265SDimitry Andric __alloc() = std::move(__c.__alloc()); 20740b57cec5SDimitry Andric } 20750b57cec5SDimitry Andric 2076e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign_alloc(basic_string&, false_type) _NOEXCEPT {} 20770b57cec5SDimitry Andric 2078c9157d92SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE basic_string& __assign_external(const value_type* __s); 2079c9157d92SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE basic_string& __assign_external(const value_type* __s, size_type __n); 20805ffd83dbSDimitry Andric 20815ffd83dbSDimitry Andric // Assigns the value in __s, guaranteed to be __n < __min_cap in length. 2082c9157d92SDimitry Andric inline _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& __assign_short(const value_type* __s, size_type __n) { 2083c9157d92SDimitry Andric size_type __old_size = size(); 2084c9157d92SDimitry Andric if (__n > __old_size) 2085c9157d92SDimitry Andric __annotate_increase(__n - __old_size); 2086e710425bSDimitry Andric pointer __p = 2087e710425bSDimitry Andric __is_long() ? (__set_long_size(__n), __get_long_pointer()) : (__set_short_size(__n), __get_short_pointer()); 208881ad6265SDimitry Andric traits_type::move(std::__to_address(__p), __s, __n); 20895ffd83dbSDimitry Andric traits_type::assign(__p[__n], value_type()); 2090c9157d92SDimitry Andric if (__old_size > __n) 2091c9157d92SDimitry Andric __annotate_shrink(__old_size); 20925ffd83dbSDimitry Andric return *this; 20935ffd83dbSDimitry Andric } 20945ffd83dbSDimitry Andric 2095e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& 2096e710425bSDimitry Andric __null_terminate_at(value_type* __p, size_type __newsz) { 2097c9157d92SDimitry Andric size_type __old_size = size(); 2098c9157d92SDimitry Andric if (__newsz > __old_size) 2099c9157d92SDimitry Andric __annotate_increase(__newsz - __old_size); 21000eae32dcSDimitry Andric __set_size(__newsz); 21010eae32dcSDimitry Andric traits_type::assign(__p[__newsz], value_type()); 2102c9157d92SDimitry Andric if (__old_size > __newsz) 2103c9157d92SDimitry Andric __annotate_shrink(__old_size); 21040eae32dcSDimitry Andric return *this; 21050eae32dcSDimitry Andric } 21060eae32dcSDimitry Andric 2107fe6060f1SDimitry Andric template <class _Tp> 2108fe013be4SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __addr_in_range(const _Tp& __v) const { 2109fe013be4SDimitry Andric return std::__is_pointer_in_range(data(), data() + size() + 1, std::addressof(__v)); 2110fe6060f1SDimitry Andric } 2111fe6060f1SDimitry Andric 2112e710425bSDimitry Andric _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void __throw_length_error() const { 211381ad6265SDimitry Andric std::__throw_length_error("basic_string"); 211469ade1e0SDimitry Andric } 211569ade1e0SDimitry Andric 2116e710425bSDimitry Andric _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void __throw_out_of_range() const { 211781ad6265SDimitry Andric std::__throw_out_of_range("basic_string"); 211869ade1e0SDimitry Andric } 211969ade1e0SDimitry Andric 2120bdd1243dSDimitry Andric friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+ <>(const basic_string&, const basic_string&); 2121bdd1243dSDimitry Andric friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+ <>(const value_type*, const basic_string&); 2122bdd1243dSDimitry Andric friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+ <>(value_type, const basic_string&); 2123bdd1243dSDimitry Andric friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+ <>(const basic_string&, const value_type*); 2124bdd1243dSDimitry Andric friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+ <>(const basic_string&, value_type); 21250b57cec5SDimitry Andric}; 21260b57cec5SDimitry Andric 21275ffd83dbSDimitry Andric// These declarations must appear before any functions are implicitly used 21285ffd83dbSDimitry Andric// so that they have the correct visibility specifier. 212981ad6265SDimitry Andric#define _LIBCPP_DECLARE(...) extern template __VA_ARGS__; 21305ffd83dbSDimitry Andric#ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION 213181ad6265SDimitry Andric_LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, char) 2132349cc55cSDimitry Andric# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 213381ad6265SDimitry Andric_LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, wchar_t) 2134349cc55cSDimitry Andric# endif 21355ffd83dbSDimitry Andric#else 213681ad6265SDimitry Andric_LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, char) 2137349cc55cSDimitry Andric# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 213881ad6265SDimitry Andric_LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, wchar_t) 21395ffd83dbSDimitry Andric# endif 2140349cc55cSDimitry Andric#endif 214181ad6265SDimitry Andric#undef _LIBCPP_DECLARE 21425ffd83dbSDimitry Andric 2143349cc55cSDimitry Andric#if _LIBCPP_STD_VER >= 17 21440b57cec5SDimitry Andrictemplate <class _InputIterator, 2145fe6060f1SDimitry Andric class _CharT = __iter_value_type<_InputIterator>, 21460b57cec5SDimitry Andric class _Allocator = allocator<_CharT>, 2147fe013be4SDimitry Andric class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, 2148e710425bSDimitry Andric class = enable_if_t<__is_allocator<_Allocator>::value> > 21490b57cec5SDimitry Andricbasic_string(_InputIterator, _InputIterator, _Allocator = _Allocator()) 21500b57cec5SDimitry Andric -> basic_string<_CharT, char_traits<_CharT>, _Allocator>; 21510b57cec5SDimitry Andric 21520b57cec5SDimitry Andrictemplate <class _CharT, 21530b57cec5SDimitry Andric class _Traits, 21540b57cec5SDimitry Andric class _Allocator = allocator<_CharT>, 2155e710425bSDimitry Andric class = enable_if_t<__is_allocator<_Allocator>::value> > 21560b57cec5SDimitry Andricexplicit basic_string(basic_string_view<_CharT, _Traits>, const _Allocator& = _Allocator()) 21570b57cec5SDimitry Andric -> basic_string<_CharT, _Traits, _Allocator>; 21580b57cec5SDimitry Andric 21590b57cec5SDimitry Andrictemplate <class _CharT, 21600b57cec5SDimitry Andric class _Traits, 21610b57cec5SDimitry Andric class _Allocator = allocator<_CharT>, 2162349cc55cSDimitry Andric class = enable_if_t<__is_allocator<_Allocator>::value>, 2163e710425bSDimitry Andric class _Sz = typename allocator_traits<_Allocator>::size_type > 21640b57cec5SDimitry Andricbasic_string(basic_string_view<_CharT, _Traits>, _Sz, _Sz, const _Allocator& = _Allocator()) 21650b57cec5SDimitry Andric -> basic_string<_CharT, _Traits, _Allocator>; 21660b57cec5SDimitry Andric#endif 21670b57cec5SDimitry Andric 2168fe013be4SDimitry Andric#if _LIBCPP_STD_VER >= 23 2169fe013be4SDimitry Andrictemplate <ranges::input_range _Range, 2170fe013be4SDimitry Andric class _Allocator = allocator<ranges::range_value_t<_Range>>, 2171e710425bSDimitry Andric class = enable_if_t<__is_allocator<_Allocator>::value> > 2172fe013be4SDimitry Andricbasic_string(from_range_t, _Range&&, _Allocator = _Allocator()) 2173fe013be4SDimitry Andric -> basic_string<ranges::range_value_t<_Range>, char_traits<ranges::range_value_t<_Range>>, _Allocator>; 2174fe013be4SDimitry Andric#endif 21750b57cec5SDimitry Andric 21760b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2177e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void 2178e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz, size_type __reserve) { 217981ad6265SDimitry Andric if (__libcpp_is_constant_evaluated()) 2180bdd1243dSDimitry Andric __r_.first() = __rep(); 21810b57cec5SDimitry Andric if (__reserve > max_size()) 218204eeddc0SDimitry Andric __throw_length_error(); 21830b57cec5SDimitry Andric pointer __p; 2184e710425bSDimitry Andric if (__fits_in_sso(__reserve)) { 21850b57cec5SDimitry Andric __set_short_size(__sz); 21860b57cec5SDimitry Andric __p = __get_short_pointer(); 2187e710425bSDimitry Andric } else { 218881ad6265SDimitry Andric auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__reserve) + 1); 218981ad6265SDimitry Andric __p = __allocation.ptr; 219081ad6265SDimitry Andric __begin_lifetime(__p, __allocation.count); 21910b57cec5SDimitry Andric __set_long_pointer(__p); 219281ad6265SDimitry Andric __set_long_cap(__allocation.count); 21930b57cec5SDimitry Andric __set_long_size(__sz); 21940b57cec5SDimitry Andric } 219581ad6265SDimitry Andric traits_type::copy(std::__to_address(__p), __s, __sz); 21960b57cec5SDimitry Andric traits_type::assign(__p[__sz], value_type()); 2197c9157d92SDimitry Andric __annotate_new(__sz); 21980b57cec5SDimitry Andric} 21990b57cec5SDimitry Andric 22000b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2201e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void 2202e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz) { 220381ad6265SDimitry Andric if (__libcpp_is_constant_evaluated()) 2204bdd1243dSDimitry Andric __r_.first() = __rep(); 22050b57cec5SDimitry Andric if (__sz > max_size()) 220604eeddc0SDimitry Andric __throw_length_error(); 22070b57cec5SDimitry Andric pointer __p; 2208e710425bSDimitry Andric if (__fits_in_sso(__sz)) { 22090b57cec5SDimitry Andric __set_short_size(__sz); 22100b57cec5SDimitry Andric __p = __get_short_pointer(); 2211e710425bSDimitry Andric } else { 221281ad6265SDimitry Andric auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1); 221381ad6265SDimitry Andric __p = __allocation.ptr; 221481ad6265SDimitry Andric __begin_lifetime(__p, __allocation.count); 22150b57cec5SDimitry Andric __set_long_pointer(__p); 221681ad6265SDimitry Andric __set_long_cap(__allocation.count); 22170b57cec5SDimitry Andric __set_long_size(__sz); 22180b57cec5SDimitry Andric } 221981ad6265SDimitry Andric traits_type::copy(std::__to_address(__p), __s, __sz); 22200b57cec5SDimitry Andric traits_type::assign(__p[__sz], value_type()); 2221c9157d92SDimitry Andric __annotate_new(__sz); 22220b57cec5SDimitry Andric} 22230b57cec5SDimitry Andric 22240b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2225e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE void 2226e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external(const value_type* __s, size_type __sz) { 222781ad6265SDimitry Andric if (__libcpp_is_constant_evaluated()) 2228bdd1243dSDimitry Andric __r_.first() = __rep(); 2229bdd1243dSDimitry Andric 22305ffd83dbSDimitry Andric pointer __p; 223104eeddc0SDimitry Andric if (__fits_in_sso(__sz)) { 22325ffd83dbSDimitry Andric __p = __get_short_pointer(); 22335ffd83dbSDimitry Andric __set_short_size(__sz); 22345ffd83dbSDimitry Andric } else { 22355ffd83dbSDimitry Andric if (__sz > max_size()) 223604eeddc0SDimitry Andric __throw_length_error(); 223781ad6265SDimitry Andric auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1); 223881ad6265SDimitry Andric __p = __allocation.ptr; 223981ad6265SDimitry Andric __begin_lifetime(__p, __allocation.count); 22405ffd83dbSDimitry Andric __set_long_pointer(__p); 224181ad6265SDimitry Andric __set_long_cap(__allocation.count); 22425ffd83dbSDimitry Andric __set_long_size(__sz); 22435ffd83dbSDimitry Andric } 224481ad6265SDimitry Andric traits_type::copy(std::__to_address(__p), __s, __sz + 1); 2245c9157d92SDimitry Andric __annotate_new(__sz); 22465ffd83dbSDimitry Andric} 22475ffd83dbSDimitry Andric 22480b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2249e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c) { 225081ad6265SDimitry Andric if (__libcpp_is_constant_evaluated()) 2251bdd1243dSDimitry Andric __r_.first() = __rep(); 2252bdd1243dSDimitry Andric 22530b57cec5SDimitry Andric if (__n > max_size()) 225404eeddc0SDimitry Andric __throw_length_error(); 22550b57cec5SDimitry Andric pointer __p; 2256e710425bSDimitry Andric if (__fits_in_sso(__n)) { 22570b57cec5SDimitry Andric __set_short_size(__n); 22580b57cec5SDimitry Andric __p = __get_short_pointer(); 2259e710425bSDimitry Andric } else { 226081ad6265SDimitry Andric auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__n) + 1); 226181ad6265SDimitry Andric __p = __allocation.ptr; 226281ad6265SDimitry Andric __begin_lifetime(__p, __allocation.count); 22630b57cec5SDimitry Andric __set_long_pointer(__p); 226481ad6265SDimitry Andric __set_long_cap(__allocation.count); 22650b57cec5SDimitry Andric __set_long_size(__n); 22660b57cec5SDimitry Andric } 226781ad6265SDimitry Andric traits_type::assign(std::__to_address(__p), __n, __c); 22680b57cec5SDimitry Andric traits_type::assign(__p[__n], value_type()); 2269c9157d92SDimitry Andric __annotate_new(__n); 22700b57cec5SDimitry Andric} 22710b57cec5SDimitry Andric 22720b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2273fe013be4SDimitry Andrictemplate <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> > 2274e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void 2275e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last) { 2276fe013be4SDimitry Andric __init_with_sentinel(std::move(__first), std::move(__last)); 22770b57cec5SDimitry Andric} 22780b57cec5SDimitry Andric 22790b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2280fe013be4SDimitry Andrictemplate <class _InputIterator, class _Sentinel> 2281e710425bSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 2282e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__init_with_sentinel(_InputIterator __first, _Sentinel __last) { 2283c9157d92SDimitry Andric __r_.first() = __rep(); 2284c9157d92SDimitry Andric __annotate_new(0); 2285fe013be4SDimitry Andric 2286fe013be4SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 2287e710425bSDimitry Andric try { 2288fe013be4SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 22890b57cec5SDimitry Andric for (; __first != __last; ++__first) 22900b57cec5SDimitry Andric push_back(*__first); 2291fe013be4SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 2292e710425bSDimitry Andric } catch (...) { 2293c9157d92SDimitry Andric __annotate_delete(); 22940b57cec5SDimitry Andric if (__is_long()) 22950b57cec5SDimitry Andric __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 22960b57cec5SDimitry Andric throw; 22970b57cec5SDimitry Andric } 2298fe013be4SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 22990b57cec5SDimitry Andric} 23000b57cec5SDimitry Andric 23010b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2302fe013be4SDimitry Andrictemplate <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> > 2303fe013be4SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void 2304e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last) { 2305fe013be4SDimitry Andric size_type __sz = static_cast<size_type>(std::distance(__first, __last)); 2306fe013be4SDimitry Andric __init_with_size(__first, __last, __sz); 2307fe013be4SDimitry Andric} 2308fe013be4SDimitry Andric 2309fe013be4SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2310fe013be4SDimitry Andrictemplate <class _InputIterator, class _Sentinel> 2311e710425bSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 2312e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__init_with_size(_InputIterator __first, _Sentinel __last, size_type __sz) { 231381ad6265SDimitry Andric if (__libcpp_is_constant_evaluated()) 2314bdd1243dSDimitry Andric __r_.first() = __rep(); 2315fe013be4SDimitry Andric 23160b57cec5SDimitry Andric if (__sz > max_size()) 231704eeddc0SDimitry Andric __throw_length_error(); 2318fe013be4SDimitry Andric 23190b57cec5SDimitry Andric pointer __p; 2320e710425bSDimitry Andric if (__fits_in_sso(__sz)) { 23210b57cec5SDimitry Andric __set_short_size(__sz); 23220b57cec5SDimitry Andric __p = __get_short_pointer(); 2323fe013be4SDimitry Andric 2324e710425bSDimitry Andric } else { 232581ad6265SDimitry Andric auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1); 232681ad6265SDimitry Andric __p = __allocation.ptr; 232781ad6265SDimitry Andric __begin_lifetime(__p, __allocation.count); 23280b57cec5SDimitry Andric __set_long_pointer(__p); 232981ad6265SDimitry Andric __set_long_cap(__allocation.count); 23300b57cec5SDimitry Andric __set_long_size(__sz); 23310b57cec5SDimitry Andric } 2332fe6060f1SDimitry Andric 2333fe013be4SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 2334e710425bSDimitry Andric try { 2335fe013be4SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 23360b57cec5SDimitry Andric for (; __first != __last; ++__first, (void)++__p) 23370b57cec5SDimitry Andric traits_type::assign(*__p, *__first); 23380b57cec5SDimitry Andric traits_type::assign(*__p, value_type()); 2339fe013be4SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 2340e710425bSDimitry Andric } catch (...) { 2341fe6060f1SDimitry Andric if (__is_long()) 2342fe6060f1SDimitry Andric __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 2343fe6060f1SDimitry Andric throw; 2344fe6060f1SDimitry Andric } 2345fe013be4SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 2346c9157d92SDimitry Andric __annotate_new(__sz); 23470b57cec5SDimitry Andric} 23480b57cec5SDimitry Andric 23490b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2350e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace( 2351e710425bSDimitry Andric size_type __old_cap, 2352e710425bSDimitry Andric size_type __delta_cap, 2353e710425bSDimitry Andric size_type __old_sz, 2354e710425bSDimitry Andric size_type __n_copy, 2355e710425bSDimitry Andric size_type __n_del, 2356e710425bSDimitry Andric size_type __n_add, 2357e710425bSDimitry Andric const value_type* __p_new_stuff) { 23580b57cec5SDimitry Andric size_type __ms = max_size(); 23590b57cec5SDimitry Andric if (__delta_cap > __ms - __old_cap - 1) 236004eeddc0SDimitry Andric __throw_length_error(); 23610b57cec5SDimitry Andric pointer __old_p = __get_pointer(); 2362e710425bSDimitry Andric size_type __cap = 2363e710425bSDimitry Andric __old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms - 1; 2364c9157d92SDimitry Andric __annotate_delete(); 236581ad6265SDimitry Andric auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1); 236681ad6265SDimitry Andric pointer __p = __allocation.ptr; 236781ad6265SDimitry Andric __begin_lifetime(__p, __allocation.count); 23680b57cec5SDimitry Andric if (__n_copy != 0) 2369e710425bSDimitry Andric traits_type::copy(std::__to_address(__p), std::__to_address(__old_p), __n_copy); 23700b57cec5SDimitry Andric if (__n_add != 0) 237181ad6265SDimitry Andric traits_type::copy(std::__to_address(__p) + __n_copy, __p_new_stuff, __n_add); 23720b57cec5SDimitry Andric size_type __sec_cp_sz = __old_sz - __n_del - __n_copy; 23730b57cec5SDimitry Andric if (__sec_cp_sz != 0) 2374e710425bSDimitry Andric traits_type::copy( 2375e710425bSDimitry Andric std::__to_address(__p) + __n_copy + __n_add, std::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz); 2376c9157d92SDimitry Andric if (__old_cap + 1 != __min_cap) 23770b57cec5SDimitry Andric __alloc_traits::deallocate(__alloc(), __old_p, __old_cap + 1); 23780b57cec5SDimitry Andric __set_long_pointer(__p); 237981ad6265SDimitry Andric __set_long_cap(__allocation.count); 23800b57cec5SDimitry Andric __old_sz = __n_copy + __n_add + __sec_cp_sz; 23810b57cec5SDimitry Andric __set_long_size(__old_sz); 23820b57cec5SDimitry Andric traits_type::assign(__p[__old_sz], value_type()); 2383c9157d92SDimitry Andric __annotate_new(__old_cap + __delta_cap); 23840b57cec5SDimitry Andric} 23850b57cec5SDimitry Andric 2386fe013be4SDimitry 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 2387fe013be4SDimitry Andric// may also not set the size at all when the string was short initially. This leads to unpredictable size value. It is 2388fe013be4SDimitry Andric// not removed or changed to avoid breaking the ABI. 23890b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2390e710425bSDimitry Andricvoid _LIBCPP_CONSTEXPR_SINCE_CXX20 2391fe013be4SDimitry Andric#if _LIBCPP_ABI_VERSION >= 2 // We want to use the function in the dylib in ABIv1 2392fe013be4SDimitry Andric _LIBCPP_HIDE_FROM_ABI 2393fe013be4SDimitry Andric#endif 2394e710425bSDimitry Andric _LIBCPP_DEPRECATED_("use __grow_by_without_replace") basic_string<_CharT, _Traits, _Allocator>::__grow_by( 2395e710425bSDimitry Andric size_type __old_cap, 2396e710425bSDimitry Andric size_type __delta_cap, 2397e710425bSDimitry Andric size_type __old_sz, 2398e710425bSDimitry Andric size_type __n_copy, 2399e710425bSDimitry Andric size_type __n_del, 2400e710425bSDimitry Andric size_type __n_add) { 24010b57cec5SDimitry Andric size_type __ms = max_size(); 24020b57cec5SDimitry Andric if (__delta_cap > __ms - __old_cap) 240304eeddc0SDimitry Andric __throw_length_error(); 24040b57cec5SDimitry Andric pointer __old_p = __get_pointer(); 2405e710425bSDimitry Andric size_type __cap = 2406e710425bSDimitry Andric __old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms - 1; 2407c9157d92SDimitry Andric __annotate_delete(); 240881ad6265SDimitry Andric auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1); 240981ad6265SDimitry Andric pointer __p = __allocation.ptr; 241081ad6265SDimitry Andric __begin_lifetime(__p, __allocation.count); 24110b57cec5SDimitry Andric if (__n_copy != 0) 2412e710425bSDimitry Andric traits_type::copy(std::__to_address(__p), std::__to_address(__old_p), __n_copy); 24130b57cec5SDimitry Andric size_type __sec_cp_sz = __old_sz - __n_del - __n_copy; 24140b57cec5SDimitry Andric if (__sec_cp_sz != 0) 2415e710425bSDimitry Andric traits_type::copy( 2416e710425bSDimitry Andric std::__to_address(__p) + __n_copy + __n_add, std::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz); 2417c9157d92SDimitry Andric if (__old_cap + 1 != __min_cap) 24180b57cec5SDimitry Andric __alloc_traits::deallocate(__alloc(), __old_p, __old_cap + 1); 24190b57cec5SDimitry Andric __set_long_pointer(__p); 242081ad6265SDimitry Andric __set_long_cap(__allocation.count); 24210b57cec5SDimitry Andric} 24220b57cec5SDimitry Andric 2423fe013be4SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2424fe013be4SDimitry Andricvoid _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI 2425fe013be4SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__grow_by_without_replace( 2426fe013be4SDimitry Andric size_type __old_cap, 2427fe013be4SDimitry Andric size_type __delta_cap, 2428fe013be4SDimitry Andric size_type __old_sz, 2429fe013be4SDimitry Andric size_type __n_copy, 2430fe013be4SDimitry Andric size_type __n_del, 2431fe013be4SDimitry Andric size_type __n_add) { 2432fe013be4SDimitry Andric _LIBCPP_SUPPRESS_DEPRECATED_PUSH 2433fe013be4SDimitry Andric __grow_by(__old_cap, __delta_cap, __old_sz, __n_copy, __n_del, __n_add); 2434fe013be4SDimitry Andric _LIBCPP_SUPPRESS_DEPRECATED_POP 2435fe013be4SDimitry Andric __set_long_size(__old_sz - __n_del + __n_add); 2436c9157d92SDimitry Andric __annotate_new(__old_sz - __n_del + __n_add); 2437fe013be4SDimitry Andric} 2438fe013be4SDimitry Andric 24390b57cec5SDimitry Andric// assign 24400b57cec5SDimitry Andric 24410b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 24425ffd83dbSDimitry Andrictemplate <bool __is_short> 2443e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE basic_string<_CharT, _Traits, _Allocator>& 2444e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__assign_no_alias(const value_type* __s, size_type __n) { 244581ad6265SDimitry Andric size_type __cap = __is_short ? static_cast<size_type>(__min_cap) : __get_long_cap(); 24465ffd83dbSDimitry Andric if (__n < __cap) { 2447c9157d92SDimitry Andric size_type __old_size = __is_short ? __get_short_size() : __get_long_size(); 2448c9157d92SDimitry Andric if (__n > __old_size) 2449c9157d92SDimitry Andric __annotate_increase(__n - __old_size); 24505ffd83dbSDimitry Andric pointer __p = __is_short ? __get_short_pointer() : __get_long_pointer(); 24515ffd83dbSDimitry Andric __is_short ? __set_short_size(__n) : __set_long_size(__n); 245281ad6265SDimitry Andric traits_type::copy(std::__to_address(__p), __s, __n); 24535ffd83dbSDimitry Andric traits_type::assign(__p[__n], value_type()); 2454c9157d92SDimitry Andric if (__old_size > __n) 2455c9157d92SDimitry Andric __annotate_shrink(__old_size); 24565ffd83dbSDimitry Andric } else { 24575ffd83dbSDimitry Andric size_type __sz = __is_short ? __get_short_size() : __get_long_size(); 24585ffd83dbSDimitry Andric __grow_by_and_replace(__cap - 1, __n - __cap + 1, __sz, 0, __sz, __n, __s); 24595ffd83dbSDimitry Andric } 24605ffd83dbSDimitry Andric return *this; 24615ffd83dbSDimitry Andric} 24625ffd83dbSDimitry Andric 24635ffd83dbSDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2464e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE basic_string<_CharT, _Traits, _Allocator>& 2465e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__assign_external(const value_type* __s, size_type __n) { 24660b57cec5SDimitry Andric size_type __cap = capacity(); 24675ffd83dbSDimitry Andric if (__cap >= __n) { 2468c9157d92SDimitry Andric size_type __old_size = size(); 2469c9157d92SDimitry Andric if (__n > __old_size) 2470c9157d92SDimitry Andric __annotate_increase(__n - __old_size); 247181ad6265SDimitry Andric value_type* __p = std::__to_address(__get_pointer()); 24720b57cec5SDimitry Andric traits_type::move(__p, __s, __n); 24730eae32dcSDimitry Andric return __null_terminate_at(__p, __n); 24745ffd83dbSDimitry Andric } else { 24750b57cec5SDimitry Andric size_type __sz = size(); 24760b57cec5SDimitry Andric __grow_by_and_replace(__cap, __n - __cap, __sz, 0, __sz, __n, __s); 24770b57cec5SDimitry Andric return *this; 24780b57cec5SDimitry Andric } 24790eae32dcSDimitry Andric} 24800b57cec5SDimitry Andric 24810b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2482e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2483e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n) { 2484c9157d92SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::assign received nullptr"); 2485e710425bSDimitry Andric return (__builtin_constant_p(__n) && __fits_in_sso(__n)) ? __assign_short(__s, __n) : __assign_external(__s, __n); 24865ffd83dbSDimitry Andric} 24875ffd83dbSDimitry Andric 24885ffd83dbSDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2489e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2490e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c) { 24910b57cec5SDimitry Andric size_type __cap = capacity(); 2492c9157d92SDimitry Andric size_type __old_size = size(); 2493e710425bSDimitry Andric if (__cap < __n) { 24940b57cec5SDimitry Andric size_type __sz = size(); 2495fe013be4SDimitry Andric __grow_by_without_replace(__cap, __n - __cap, __sz, 0, __sz); 2496c9157d92SDimitry Andric __annotate_increase(__n); 2497e710425bSDimitry Andric } else if (__n > __old_size) 2498c9157d92SDimitry Andric __annotate_increase(__n - __old_size); 249981ad6265SDimitry Andric value_type* __p = std::__to_address(__get_pointer()); 25000b57cec5SDimitry Andric traits_type::assign(__p, __n, __c); 25010eae32dcSDimitry Andric return __null_terminate_at(__p, __n); 25020b57cec5SDimitry Andric} 25030b57cec5SDimitry Andric 25040b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2505e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2506e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c) { 25070b57cec5SDimitry Andric pointer __p; 2508c9157d92SDimitry Andric size_type __old_size = size(); 2509c9157d92SDimitry Andric if (__old_size == 0) 2510c9157d92SDimitry Andric __annotate_increase(1); 2511c9157d92SDimitry Andric if (__is_long()) { 25120b57cec5SDimitry Andric __p = __get_long_pointer(); 25130b57cec5SDimitry Andric __set_long_size(1); 2514c9157d92SDimitry Andric } else { 25150b57cec5SDimitry Andric __p = __get_short_pointer(); 25160b57cec5SDimitry Andric __set_short_size(1); 25170b57cec5SDimitry Andric } 25180b57cec5SDimitry Andric traits_type::assign(*__p, __c); 25190b57cec5SDimitry Andric traits_type::assign(*++__p, value_type()); 2520c9157d92SDimitry Andric if (__old_size > 1) 2521c9157d92SDimitry Andric __annotate_shrink(__old_size); 25220b57cec5SDimitry Andric return *this; 25230b57cec5SDimitry Andric} 25240b57cec5SDimitry Andric 25250b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2526e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS basic_string<_CharT, _Traits, _Allocator>& 2527e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str) { 2528fe013be4SDimitry Andric if (this != std::addressof(__str)) { 25290b57cec5SDimitry Andric __copy_assign_alloc(__str); 25305ffd83dbSDimitry Andric if (!__is_long()) { 25315ffd83dbSDimitry Andric if (!__str.__is_long()) { 2532c9157d92SDimitry Andric size_type __old_size = __get_short_size(); 2533c9157d92SDimitry Andric if (__get_short_size() < __str.__get_short_size()) 2534c9157d92SDimitry Andric __annotate_increase(__str.__get_short_size() - __get_short_size()); 2535bdd1243dSDimitry Andric __r_.first() = __str.__r_.first(); 2536c9157d92SDimitry Andric if (__old_size > __get_short_size()) 2537c9157d92SDimitry Andric __annotate_shrink(__old_size); 25385ffd83dbSDimitry Andric } else { 25395ffd83dbSDimitry Andric return __assign_no_alias<true>(__str.data(), __str.size()); 25405ffd83dbSDimitry Andric } 25415ffd83dbSDimitry Andric } else { 25425ffd83dbSDimitry Andric return __assign_no_alias<false>(__str.data(), __str.size()); 25435ffd83dbSDimitry Andric } 25440b57cec5SDimitry Andric } 25450b57cec5SDimitry Andric return *this; 25460b57cec5SDimitry Andric} 25470b57cec5SDimitry Andric 25480b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 25490b57cec5SDimitry Andric 25500b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2551e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 void 25520b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, false_type) 2553e710425bSDimitry Andric _NOEXCEPT_(__alloc_traits::is_always_equal::value) { 25540b57cec5SDimitry Andric if (__alloc() != __str.__alloc()) 25550b57cec5SDimitry Andric assign(__str); 25560b57cec5SDimitry Andric else 25570b57cec5SDimitry Andric __move_assign(__str, true_type()); 25580b57cec5SDimitry Andric} 25590b57cec5SDimitry Andric 25600b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2561e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS void 25620b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type) 2563fe013be4SDimitry Andric# if _LIBCPP_STD_VER >= 17 25640b57cec5SDimitry Andric _NOEXCEPT 25650b57cec5SDimitry Andric# else 25660b57cec5SDimitry Andric _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) 25670b57cec5SDimitry Andric# endif 25680b57cec5SDimitry Andric{ 2569c9157d92SDimitry Andric __annotate_delete(); 2570480093f4SDimitry Andric if (__is_long()) { 2571e710425bSDimitry Andric __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); 2572480093f4SDimitry Andric# if _LIBCPP_STD_VER <= 14 2573480093f4SDimitry Andric if (!is_nothrow_move_assignable<allocator_type>::value) { 2574480093f4SDimitry Andric __set_short_size(0); 2575480093f4SDimitry Andric traits_type::assign(__get_short_pointer()[0], value_type()); 2576c9157d92SDimitry Andric __annotate_new(0); 2577480093f4SDimitry Andric } 2578480093f4SDimitry Andric# endif 2579480093f4SDimitry Andric } 2580c9157d92SDimitry Andric size_type __str_old_size = __str.size(); 2581c9157d92SDimitry Andric bool __str_was_short = !__str.__is_long(); 2582c9157d92SDimitry Andric 25830b57cec5SDimitry Andric __move_assign_alloc(__str); 2584480093f4SDimitry Andric __r_.first() = __str.__r_.first(); 2585480093f4SDimitry Andric __str.__set_short_size(0); 2586480093f4SDimitry Andric traits_type::assign(__str.__get_short_pointer()[0], value_type()); 2587c9157d92SDimitry Andric 2588c9157d92SDimitry Andric if (__str_was_short && this != &__str) 2589c9157d92SDimitry Andric __str.__annotate_shrink(__str_old_size); 2590c9157d92SDimitry Andric else 2591c9157d92SDimitry Andric // ASan annotations: was long, so object memory is unpoisoned as new. 2592c9157d92SDimitry Andric // Or is same as *this, and __annotate_delete() was called. 2593c9157d92SDimitry Andric __str.__annotate_new(0); 2594c9157d92SDimitry Andric 2595c9157d92SDimitry Andric // ASan annotations: Guard against `std::string s; s = std::move(s);` 2596c9157d92SDimitry Andric // You can find more here: https://en.cppreference.com/w/cpp/utility/move 2597c9157d92SDimitry Andric // Quote: "Unless otherwise specified, all standard library objects that have been moved 2598c9157d92SDimitry Andric // from are placed in a "valid but unspecified state", meaning the object's class 2599c9157d92SDimitry Andric // invariants hold (so functions without preconditions, such as the assignment operator, 2600c9157d92SDimitry Andric // can be safely used on the object after it was moved from):" 2601c9157d92SDimitry Andric // Quote: "v = std::move(v); // the value of v is unspecified" 2602c9157d92SDimitry Andric if (!__is_long() && &__str != this) 2603c9157d92SDimitry Andric // If it is long string, delete was never called on original __str's buffer. 2604c9157d92SDimitry Andric __annotate_new(__get_short_size()); 260581ad6265SDimitry Andric} 26060b57cec5SDimitry Andric 26070b57cec5SDimitry Andric#endif 26080b57cec5SDimitry Andric 26090b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2610fe013be4SDimitry Andrictemplate <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> > 2611fe013be4SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2612e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last) { 2613fe013be4SDimitry Andric __assign_with_sentinel(__first, __last); 26140b57cec5SDimitry Andric return *this; 26150b57cec5SDimitry Andric} 26160b57cec5SDimitry Andric 26170b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2618fe013be4SDimitry Andrictemplate <class _InputIterator, class _Sentinel> 2619e710425bSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 2620fe013be4SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__assign_with_sentinel(_InputIterator __first, _Sentinel __last) { 2621fe013be4SDimitry Andric const basic_string __temp(__init_with_sentinel_tag(), std::move(__first), std::move(__last), __alloc()); 2622fe013be4SDimitry Andric assign(__temp.data(), __temp.size()); 2623fe013be4SDimitry Andric} 2624fe013be4SDimitry Andric 2625fe013be4SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2626fe013be4SDimitry Andrictemplate <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> > 2627fe013be4SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2628e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last) { 2629fe013be4SDimitry Andric if (__string_is_trivial_iterator<_ForwardIterator>::value) { 2630fe013be4SDimitry Andric size_type __n = static_cast<size_type>(std::distance(__first, __last)); 2631fe013be4SDimitry Andric __assign_trivial(__first, __last, __n); 2632fe013be4SDimitry Andric } else { 2633fe013be4SDimitry Andric __assign_with_sentinel(__first, __last); 2634fe013be4SDimitry Andric } 2635fe6060f1SDimitry Andric 2636fe013be4SDimitry Andric return *this; 2637fe013be4SDimitry Andric} 2638fe013be4SDimitry Andric 2639fe013be4SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2640fe013be4SDimitry Andrictemplate <class _Iterator, class _Sentinel> 2641e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void 2642fe013be4SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__assign_trivial(_Iterator __first, _Sentinel __last, size_type __n) { 2643fe013be4SDimitry Andric _LIBCPP_ASSERT_INTERNAL( 2644fe013be4SDimitry Andric __string_is_trivial_iterator<_Iterator>::value, "The iterator type given to `__assign_trivial` must be trivial"); 2645fe013be4SDimitry Andric 2646c9157d92SDimitry Andric size_type __old_size = size(); 2647fe013be4SDimitry Andric size_type __cap = capacity(); 2648fe013be4SDimitry Andric if (__cap < __n) { 2649fe013be4SDimitry Andric // Unlike `append` functions, if the input range points into the string itself, there is no case that the input 2650fe013be4SDimitry Andric // range could get invalidated by reallocation: 2651fe013be4SDimitry Andric // 1. If the input range is a subset of the string itself, its size cannot exceed the capacity of the string, 2652fe013be4SDimitry Andric // thus no reallocation would happen. 2653fe013be4SDimitry Andric // 2. In the exotic case where the input range is the byte representation of the string itself, the string 2654fe013be4SDimitry Andric // object itself stays valid even if reallocation happens. 26550b57cec5SDimitry Andric size_type __sz = size(); 2656fe013be4SDimitry Andric __grow_by_without_replace(__cap, __n - __cap, __sz, 0, __sz); 2657c9157d92SDimitry Andric __annotate_increase(__n); 2658e710425bSDimitry Andric } else if (__n > __old_size) 2659c9157d92SDimitry Andric __annotate_increase(__n - __old_size); 26600b57cec5SDimitry Andric pointer __p = __get_pointer(); 2661349cc55cSDimitry Andric for (; __first != __last; ++__p, (void)++__first) 26620b57cec5SDimitry Andric traits_type::assign(*__p, *__first); 26630b57cec5SDimitry Andric traits_type::assign(*__p, value_type()); 26640b57cec5SDimitry Andric __set_size(__n); 2665c9157d92SDimitry Andric if (__n < __old_size) 2666c9157d92SDimitry Andric __annotate_shrink(__old_size); 26670b57cec5SDimitry Andric} 26680b57cec5SDimitry Andric 26690b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2670e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2671e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, size_type __pos, size_type __n) { 26720b57cec5SDimitry Andric size_type __sz = __str.size(); 26730b57cec5SDimitry Andric if (__pos > __sz) 267404eeddc0SDimitry Andric __throw_out_of_range(); 267581ad6265SDimitry Andric return assign(__str.data() + __pos, std::min(__n, __sz - __pos)); 26760b57cec5SDimitry Andric} 26770b57cec5SDimitry Andric 26780b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2679fe013be4SDimitry Andrictemplate <class _Tp, 2680fe013be4SDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 2681fe013be4SDimitry Andric !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 2682fe013be4SDimitry Andric int> > 2683fe013be4SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2684fe013be4SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::assign(const _Tp& __t, size_type __pos, size_type __n) { 26850b57cec5SDimitry Andric __self_view __sv = __t; 26860b57cec5SDimitry Andric size_type __sz = __sv.size(); 26870b57cec5SDimitry Andric if (__pos > __sz) 268804eeddc0SDimitry Andric __throw_out_of_range(); 268981ad6265SDimitry Andric return assign(__sv.data() + __pos, std::min(__n, __sz - __pos)); 26900b57cec5SDimitry Andric} 26910b57cec5SDimitry Andric 26920b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2693e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE basic_string<_CharT, _Traits, _Allocator>& 26945ffd83dbSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__assign_external(const value_type* __s) { 26955ffd83dbSDimitry Andric return __assign_external(__s, traits_type::length(__s)); 26965ffd83dbSDimitry Andric} 26975ffd83dbSDimitry Andric 26985ffd83dbSDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2699e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2700e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s) { 2701c9157d92SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::assign received nullptr"); 2702349cc55cSDimitry Andric return __builtin_constant_p(*__s) 2703e710425bSDimitry Andric ? (__fits_in_sso(traits_type::length(__s)) ? __assign_short(__s, traits_type::length(__s)) 27045ffd83dbSDimitry Andric : __assign_external(__s, traits_type::length(__s))) 27055ffd83dbSDimitry Andric : __assign_external(__s); 27060b57cec5SDimitry Andric} 27070b57cec5SDimitry Andric// append 27080b57cec5SDimitry Andric 27090b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2710e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2711e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n) { 2712c9157d92SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::append received nullptr"); 27130b57cec5SDimitry Andric size_type __cap = capacity(); 27140b57cec5SDimitry Andric size_type __sz = size(); 2715e710425bSDimitry Andric if (__cap - __sz >= __n) { 2716e710425bSDimitry Andric if (__n) { 2717c9157d92SDimitry Andric __annotate_increase(__n); 271881ad6265SDimitry Andric value_type* __p = std::__to_address(__get_pointer()); 27190b57cec5SDimitry Andric traits_type::copy(__p + __sz, __s, __n); 27200b57cec5SDimitry Andric __sz += __n; 27210b57cec5SDimitry Andric __set_size(__sz); 27220b57cec5SDimitry Andric traits_type::assign(__p[__sz], value_type()); 27230b57cec5SDimitry Andric } 2724e710425bSDimitry Andric } else 27250b57cec5SDimitry Andric __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __sz, 0, __n, __s); 27260b57cec5SDimitry Andric return *this; 27270b57cec5SDimitry Andric} 27280b57cec5SDimitry Andric 27290b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2730e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2731e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c) { 2732e710425bSDimitry Andric if (__n) { 27330b57cec5SDimitry Andric size_type __cap = capacity(); 27340b57cec5SDimitry Andric size_type __sz = size(); 27350b57cec5SDimitry Andric if (__cap - __sz < __n) 2736fe013be4SDimitry Andric __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0); 2737c9157d92SDimitry Andric __annotate_increase(__n); 27380b57cec5SDimitry Andric pointer __p = __get_pointer(); 273981ad6265SDimitry Andric traits_type::assign(std::__to_address(__p) + __sz, __n, __c); 27400b57cec5SDimitry Andric __sz += __n; 27410b57cec5SDimitry Andric __set_size(__sz); 27420b57cec5SDimitry Andric traits_type::assign(__p[__sz], value_type()); 27430b57cec5SDimitry Andric } 27440b57cec5SDimitry Andric return *this; 27450b57cec5SDimitry Andric} 27460b57cec5SDimitry Andric 27470b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2748bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 inline void 2749e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n) { 2750e710425bSDimitry Andric if (__n) { 27510b57cec5SDimitry Andric size_type __cap = capacity(); 27520b57cec5SDimitry Andric size_type __sz = size(); 27530b57cec5SDimitry Andric if (__cap - __sz < __n) 2754fe013be4SDimitry Andric __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0); 2755c9157d92SDimitry Andric __annotate_increase(__n); 27560b57cec5SDimitry Andric pointer __p = __get_pointer(); 27570b57cec5SDimitry Andric __sz += __n; 27580b57cec5SDimitry Andric __set_size(__sz); 27590b57cec5SDimitry Andric traits_type::assign(__p[__sz], value_type()); 27600b57cec5SDimitry Andric } 27610b57cec5SDimitry Andric} 27620b57cec5SDimitry Andric 27630b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2764e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c) { 27650b57cec5SDimitry Andric bool __is_short = !__is_long(); 27660b57cec5SDimitry Andric size_type __cap; 27670b57cec5SDimitry Andric size_type __sz; 2768e710425bSDimitry Andric if (__is_short) { 27690b57cec5SDimitry Andric __cap = __min_cap - 1; 27700b57cec5SDimitry Andric __sz = __get_short_size(); 2771e710425bSDimitry Andric } else { 27720b57cec5SDimitry Andric __cap = __get_long_cap() - 1; 27730b57cec5SDimitry Andric __sz = __get_long_size(); 27740b57cec5SDimitry Andric } 2775e710425bSDimitry Andric if (__sz == __cap) { 2776fe013be4SDimitry Andric __grow_by_without_replace(__cap, 1, __sz, __sz, 0); 2777c9157d92SDimitry Andric __annotate_increase(1); 2778349cc55cSDimitry Andric __is_short = false; // the string is always long after __grow_by 2779c9157d92SDimitry Andric } else 2780c9157d92SDimitry Andric __annotate_increase(1); 278181ad6265SDimitry Andric pointer __p = __get_pointer(); 2782e710425bSDimitry Andric if (__is_short) { 27830b57cec5SDimitry Andric __p = __get_short_pointer() + __sz; 27840b57cec5SDimitry Andric __set_short_size(__sz + 1); 2785e710425bSDimitry Andric } else { 27860b57cec5SDimitry Andric __p = __get_long_pointer() + __sz; 27870b57cec5SDimitry Andric __set_long_size(__sz + 1); 27880b57cec5SDimitry Andric } 27890b57cec5SDimitry Andric traits_type::assign(*__p, __c); 27900b57cec5SDimitry Andric traits_type::assign(*++__p, value_type()); 27910b57cec5SDimitry Andric} 27920b57cec5SDimitry Andric 27930b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2794fe013be4SDimitry Andrictemplate <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> > 2795fe013be4SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2796e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::append(_ForwardIterator __first, _ForwardIterator __last) { 27970b57cec5SDimitry Andric size_type __sz = size(); 27980b57cec5SDimitry Andric size_type __cap = capacity(); 279981ad6265SDimitry Andric size_type __n = static_cast<size_type>(std::distance(__first, __last)); 2800e710425bSDimitry Andric if (__n) { 2801e710425bSDimitry Andric if (__string_is_trivial_iterator<_ForwardIterator>::value && !__addr_in_range(*__first)) { 28020b57cec5SDimitry Andric if (__cap - __sz < __n) 2803fe013be4SDimitry Andric __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0); 2804c9157d92SDimitry Andric __annotate_increase(__n); 28050b57cec5SDimitry Andric pointer __p = __get_pointer() + __sz; 2806349cc55cSDimitry Andric for (; __first != __last; ++__p, (void)++__first) 28070b57cec5SDimitry Andric traits_type::assign(*__p, *__first); 28080b57cec5SDimitry Andric traits_type::assign(*__p, value_type()); 28090b57cec5SDimitry Andric __set_size(__sz + __n); 2810e710425bSDimitry Andric } else { 2811fe6060f1SDimitry Andric const basic_string __temp(__first, __last, __alloc()); 2812fe6060f1SDimitry Andric append(__temp.data(), __temp.size()); 2813fe6060f1SDimitry Andric } 28140b57cec5SDimitry Andric } 28150b57cec5SDimitry Andric return *this; 28160b57cec5SDimitry Andric} 28170b57cec5SDimitry Andric 28180b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2819e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2820e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, size_type __pos, size_type __n) { 28210b57cec5SDimitry Andric size_type __sz = __str.size(); 28220b57cec5SDimitry Andric if (__pos > __sz) 282304eeddc0SDimitry Andric __throw_out_of_range(); 282481ad6265SDimitry Andric return append(__str.data() + __pos, std::min(__n, __sz - __pos)); 28250b57cec5SDimitry Andric} 28260b57cec5SDimitry Andric 28270b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2828fe013be4SDimitry Andrictemplate <class _Tp, 2829fe013be4SDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 2830fe013be4SDimitry Andric !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 2831fe013be4SDimitry Andric int> > 2832fe013be4SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2833fe013be4SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::append(const _Tp& __t, size_type __pos, size_type __n) { 28340b57cec5SDimitry Andric __self_view __sv = __t; 28350b57cec5SDimitry Andric size_type __sz = __sv.size(); 28360b57cec5SDimitry Andric if (__pos > __sz) 283704eeddc0SDimitry Andric __throw_out_of_range(); 283881ad6265SDimitry Andric return append(__sv.data() + __pos, std::min(__n, __sz - __pos)); 28390b57cec5SDimitry Andric} 28400b57cec5SDimitry Andric 28410b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2842e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2843e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s) { 2844c9157d92SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::append received nullptr"); 28450b57cec5SDimitry Andric return append(__s, traits_type::length(__s)); 28460b57cec5SDimitry Andric} 28470b57cec5SDimitry Andric 28480b57cec5SDimitry Andric// insert 28490b57cec5SDimitry Andric 28500b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2851e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2852e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n) { 2853c9157d92SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::insert received nullptr"); 28540b57cec5SDimitry Andric size_type __sz = size(); 28550b57cec5SDimitry Andric if (__pos > __sz) 285604eeddc0SDimitry Andric __throw_out_of_range(); 28570b57cec5SDimitry Andric size_type __cap = capacity(); 2858e710425bSDimitry Andric if (__cap - __sz >= __n) { 2859e710425bSDimitry Andric if (__n) { 2860c9157d92SDimitry Andric __annotate_increase(__n); 286181ad6265SDimitry Andric value_type* __p = std::__to_address(__get_pointer()); 28620b57cec5SDimitry Andric size_type __n_move = __sz - __pos; 2863e710425bSDimitry Andric if (__n_move != 0) { 2864c9157d92SDimitry Andric if (std::__is_pointer_in_range(__p + __pos, __p + __sz, __s)) 28650b57cec5SDimitry Andric __s += __n; 28660b57cec5SDimitry Andric traits_type::move(__p + __pos + __n, __p + __pos, __n_move); 28670b57cec5SDimitry Andric } 28680b57cec5SDimitry Andric traits_type::move(__p + __pos, __s, __n); 28690b57cec5SDimitry Andric __sz += __n; 28700b57cec5SDimitry Andric __set_size(__sz); 28710b57cec5SDimitry Andric traits_type::assign(__p[__sz], value_type()); 28720b57cec5SDimitry Andric } 2873e710425bSDimitry Andric } else 28740b57cec5SDimitry Andric __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s); 28750b57cec5SDimitry Andric return *this; 28760b57cec5SDimitry Andric} 28770b57cec5SDimitry Andric 28780b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2879e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2880e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n, value_type __c) { 28810b57cec5SDimitry Andric size_type __sz = size(); 28820b57cec5SDimitry Andric if (__pos > __sz) 288304eeddc0SDimitry Andric __throw_out_of_range(); 2884e710425bSDimitry Andric if (__n) { 28850b57cec5SDimitry Andric size_type __cap = capacity(); 28860b57cec5SDimitry Andric value_type* __p; 2887e710425bSDimitry Andric if (__cap - __sz >= __n) { 2888c9157d92SDimitry Andric __annotate_increase(__n); 288981ad6265SDimitry Andric __p = std::__to_address(__get_pointer()); 28900b57cec5SDimitry Andric size_type __n_move = __sz - __pos; 28910b57cec5SDimitry Andric if (__n_move != 0) 28920b57cec5SDimitry Andric traits_type::move(__p + __pos + __n, __p + __pos, __n_move); 2893e710425bSDimitry Andric } else { 2894fe013be4SDimitry Andric __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n); 289581ad6265SDimitry Andric __p = std::__to_address(__get_long_pointer()); 28960b57cec5SDimitry Andric } 28970b57cec5SDimitry Andric traits_type::assign(__p + __pos, __n, __c); 28980b57cec5SDimitry Andric __sz += __n; 28990b57cec5SDimitry Andric __set_size(__sz); 29000b57cec5SDimitry Andric traits_type::assign(__p[__sz], value_type()); 29010b57cec5SDimitry Andric } 29020b57cec5SDimitry Andric return *this; 29030b57cec5SDimitry Andric} 29040b57cec5SDimitry Andric 29050b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2906fe013be4SDimitry Andrictemplate <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> > 2907fe013be4SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator 2908e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last) { 29090b57cec5SDimitry Andric const basic_string __temp(__first, __last, __alloc()); 29100b57cec5SDimitry Andric return insert(__pos, __temp.data(), __temp.data() + __temp.size()); 29110b57cec5SDimitry Andric} 29120b57cec5SDimitry Andric 29130b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2914fe013be4SDimitry Andrictemplate <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> > 2915fe013be4SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator 2916e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::insert( 2917e710425bSDimitry Andric const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last) { 2918fe013be4SDimitry Andric auto __n = static_cast<size_type>(std::distance(__first, __last)); 2919fe013be4SDimitry Andric return __insert_with_size(__pos, __first, __last, __n); 2920fe013be4SDimitry Andric} 29210eae32dcSDimitry Andric 2922fe013be4SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2923fe013be4SDimitry Andrictemplate <class _Iterator, class _Sentinel> 2924e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator 2925fe013be4SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__insert_with_size( 2926fe013be4SDimitry Andric const_iterator __pos, _Iterator __first, _Sentinel __last, size_type __n) { 29270b57cec5SDimitry Andric size_type __ip = static_cast<size_type>(__pos - begin()); 292881ad6265SDimitry Andric if (__n == 0) 292981ad6265SDimitry Andric return begin() + __ip; 293081ad6265SDimitry Andric 2931e710425bSDimitry Andric if (__string_is_trivial_iterator<_Iterator>::value && !__addr_in_range(*__first)) { 293281ad6265SDimitry Andric return __insert_from_safe_copy(__n, __ip, __first, __last); 2933e710425bSDimitry Andric } else { 2934fe013be4SDimitry Andric const basic_string __temp(__init_with_sentinel_tag(), __first, __last, __alloc()); 293581ad6265SDimitry Andric return __insert_from_safe_copy(__n, __ip, __temp.begin(), __temp.end()); 2936fe6060f1SDimitry Andric } 2937fe6060f1SDimitry Andric} 29380b57cec5SDimitry Andric 29390b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2940e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2941e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::insert( 2942e710425bSDimitry Andric size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n) { 29430b57cec5SDimitry Andric size_type __str_sz = __str.size(); 29440b57cec5SDimitry Andric if (__pos2 > __str_sz) 294504eeddc0SDimitry Andric __throw_out_of_range(); 294681ad6265SDimitry Andric return insert(__pos1, __str.data() + __pos2, std::min(__n, __str_sz - __pos2)); 29470b57cec5SDimitry Andric} 29480b57cec5SDimitry Andric 29490b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2950fe013be4SDimitry Andrictemplate <class _Tp, 2951fe013be4SDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 2952fe013be4SDimitry Andric !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 2953fe013be4SDimitry Andric int> > 2954fe013be4SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2955fe013be4SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n) { 29560b57cec5SDimitry Andric __self_view __sv = __t; 29570b57cec5SDimitry Andric size_type __str_sz = __sv.size(); 29580b57cec5SDimitry Andric if (__pos2 > __str_sz) 295904eeddc0SDimitry Andric __throw_out_of_range(); 296081ad6265SDimitry Andric return insert(__pos1, __sv.data() + __pos2, std::min(__n, __str_sz - __pos2)); 29610b57cec5SDimitry Andric} 29620b57cec5SDimitry Andric 29630b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2964e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2965e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s) { 2966c9157d92SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::insert received nullptr"); 29670b57cec5SDimitry Andric return insert(__pos, __s, traits_type::length(__s)); 29680b57cec5SDimitry Andric} 29690b57cec5SDimitry Andric 29700b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2971e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator 2972e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c) { 29730b57cec5SDimitry Andric size_type __ip = static_cast<size_type>(__pos - begin()); 29740b57cec5SDimitry Andric size_type __sz = size(); 29750b57cec5SDimitry Andric size_type __cap = capacity(); 29760b57cec5SDimitry Andric value_type* __p; 2977e710425bSDimitry Andric if (__cap == __sz) { 2978fe013be4SDimitry Andric __grow_by_without_replace(__cap, 1, __sz, __ip, 0, 1); 297981ad6265SDimitry Andric __p = std::__to_address(__get_long_pointer()); 2980e710425bSDimitry Andric } else { 2981c9157d92SDimitry Andric __annotate_increase(1); 298281ad6265SDimitry Andric __p = std::__to_address(__get_pointer()); 29830b57cec5SDimitry Andric size_type __n_move = __sz - __ip; 29840b57cec5SDimitry Andric if (__n_move != 0) 29850b57cec5SDimitry Andric traits_type::move(__p + __ip + 1, __p + __ip, __n_move); 29860b57cec5SDimitry Andric } 29870b57cec5SDimitry Andric traits_type::assign(__p[__ip], __c); 29880b57cec5SDimitry Andric traits_type::assign(__p[++__sz], value_type()); 29890b57cec5SDimitry Andric __set_size(__sz); 29900b57cec5SDimitry Andric return begin() + static_cast<difference_type>(__ip); 29910b57cec5SDimitry Andric} 29920b57cec5SDimitry Andric 29930b57cec5SDimitry Andric// replace 29940b57cec5SDimitry Andric 29950b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 2996e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 2997e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::replace( 2998e710425bSDimitry Andric size_type __pos, size_type __n1, const value_type* __s, size_type __n2) 2999e710425bSDimitry Andric _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK { 3000c9157d92SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__n2 == 0 || __s != nullptr, "string::replace received nullptr"); 30010b57cec5SDimitry Andric size_type __sz = size(); 30020b57cec5SDimitry Andric if (__pos > __sz) 300304eeddc0SDimitry Andric __throw_out_of_range(); 300481ad6265SDimitry Andric __n1 = std::min(__n1, __sz - __pos); 30050b57cec5SDimitry Andric size_type __cap = capacity(); 3006e710425bSDimitry Andric if (__cap - __sz + __n1 >= __n2) { 300781ad6265SDimitry Andric value_type* __p = std::__to_address(__get_pointer()); 3008e710425bSDimitry Andric if (__n1 != __n2) { 3009c9157d92SDimitry Andric if (__n2 > __n1) 3010c9157d92SDimitry Andric __annotate_increase(__n2 - __n1); 30110b57cec5SDimitry Andric size_type __n_move = __sz - __pos - __n1; 3012e710425bSDimitry Andric if (__n_move != 0) { 3013e710425bSDimitry Andric if (__n1 > __n2) { 30140b57cec5SDimitry Andric traits_type::move(__p + __pos, __s, __n2); 30150b57cec5SDimitry Andric traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move); 30160eae32dcSDimitry Andric return __null_terminate_at(__p, __sz + (__n2 - __n1)); 30170b57cec5SDimitry Andric } 3018e710425bSDimitry Andric if (std::__is_pointer_in_range(__p + __pos + 1, __p + __sz, __s)) { 30190b57cec5SDimitry Andric if (__p + __pos + __n1 <= __s) 30200b57cec5SDimitry Andric __s += __n2 - __n1; 30210b57cec5SDimitry Andric else // __p + __pos < __s < __p + __pos + __n1 30220b57cec5SDimitry Andric { 30230b57cec5SDimitry Andric traits_type::move(__p + __pos, __s, __n1); 30240b57cec5SDimitry Andric __pos += __n1; 30250b57cec5SDimitry Andric __s += __n2; 30260b57cec5SDimitry Andric __n2 -= __n1; 30270b57cec5SDimitry Andric __n1 = 0; 30280b57cec5SDimitry Andric } 30290b57cec5SDimitry Andric } 30300b57cec5SDimitry Andric traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move); 30310b57cec5SDimitry Andric } 30320b57cec5SDimitry Andric } 30330b57cec5SDimitry Andric traits_type::move(__p + __pos, __s, __n2); 30340eae32dcSDimitry Andric return __null_terminate_at(__p, __sz + (__n2 - __n1)); 3035e710425bSDimitry Andric } else 30360b57cec5SDimitry Andric __grow_by_and_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2, __s); 30370b57cec5SDimitry Andric return *this; 30380b57cec5SDimitry Andric} 30390b57cec5SDimitry Andric 30400b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3041e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 3042e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, size_type __n2, value_type __c) { 30430b57cec5SDimitry Andric size_type __sz = size(); 30440b57cec5SDimitry Andric if (__pos > __sz) 304504eeddc0SDimitry Andric __throw_out_of_range(); 304681ad6265SDimitry Andric __n1 = std::min(__n1, __sz - __pos); 30470b57cec5SDimitry Andric size_type __cap = capacity(); 30480b57cec5SDimitry Andric value_type* __p; 3049c9157d92SDimitry Andric if (__cap - __sz + __n1 >= __n2) { 305081ad6265SDimitry Andric __p = std::__to_address(__get_pointer()); 3051c9157d92SDimitry Andric if (__n1 != __n2) { 3052c9157d92SDimitry Andric if (__n2 > __n1) 3053c9157d92SDimitry Andric __annotate_increase(__n2 - __n1); 30540b57cec5SDimitry Andric size_type __n_move = __sz - __pos - __n1; 30550b57cec5SDimitry Andric if (__n_move != 0) 30560b57cec5SDimitry Andric traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move); 30570b57cec5SDimitry Andric } 3058c9157d92SDimitry Andric } else { 3059fe013be4SDimitry Andric __grow_by_without_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2); 306081ad6265SDimitry Andric __p = std::__to_address(__get_long_pointer()); 30610b57cec5SDimitry Andric } 30620b57cec5SDimitry Andric traits_type::assign(__p + __pos, __n2, __c); 30630eae32dcSDimitry Andric return __null_terminate_at(__p, __sz - (__n1 - __n2)); 30640b57cec5SDimitry Andric} 30650b57cec5SDimitry Andric 30660b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3067fe013be4SDimitry Andrictemplate <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> > 3068fe013be4SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 3069e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::replace( 3070e710425bSDimitry Andric const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2) { 30710b57cec5SDimitry Andric const basic_string __temp(__j1, __j2, __alloc()); 307204eeddc0SDimitry Andric return replace(__i1, __i2, __temp); 30730b57cec5SDimitry Andric} 30740b57cec5SDimitry Andric 30750b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3076e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 3077e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::replace( 3078e710425bSDimitry Andric size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2) { 30790b57cec5SDimitry Andric size_type __str_sz = __str.size(); 30800b57cec5SDimitry Andric if (__pos2 > __str_sz) 308104eeddc0SDimitry Andric __throw_out_of_range(); 308281ad6265SDimitry Andric return replace(__pos1, __n1, __str.data() + __pos2, std::min(__n2, __str_sz - __pos2)); 30830b57cec5SDimitry Andric} 30840b57cec5SDimitry Andric 30850b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3086fe013be4SDimitry Andrictemplate <class _Tp, 3087fe013be4SDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 3088fe013be4SDimitry Andric !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 3089fe013be4SDimitry Andric int> > 3090fe013be4SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 3091fe013be4SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::replace( 3092fe013be4SDimitry Andric size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2) { 30930b57cec5SDimitry Andric __self_view __sv = __t; 30940b57cec5SDimitry Andric size_type __str_sz = __sv.size(); 30950b57cec5SDimitry Andric if (__pos2 > __str_sz) 309604eeddc0SDimitry Andric __throw_out_of_range(); 309781ad6265SDimitry Andric return replace(__pos1, __n1, __sv.data() + __pos2, std::min(__n2, __str_sz - __pos2)); 30980b57cec5SDimitry Andric} 30990b57cec5SDimitry Andric 31000b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3101e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 3102e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s) { 3103c9157d92SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::replace received nullptr"); 31040b57cec5SDimitry Andric return replace(__pos, __n1, __s, traits_type::length(__s)); 31050b57cec5SDimitry Andric} 31060b57cec5SDimitry Andric 31070b57cec5SDimitry Andric// erase 31080b57cec5SDimitry Andric 31095ffd83dbSDimitry Andric// 'externally instantiated' erase() implementation, called when __n != npos. 31105ffd83dbSDimitry Andric// Does not check __pos against size() 31110b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3112e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE void 3113e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move(size_type __pos, size_type __n) { 3114e710425bSDimitry Andric if (__n) { 31155ffd83dbSDimitry Andric size_type __sz = size(); 311681ad6265SDimitry Andric value_type* __p = std::__to_address(__get_pointer()); 311781ad6265SDimitry Andric __n = std::min(__n, __sz - __pos); 31180b57cec5SDimitry Andric size_type __n_move = __sz - __pos - __n; 31190b57cec5SDimitry Andric if (__n_move != 0) 31200b57cec5SDimitry Andric traits_type::move(__p + __pos, __p + __pos + __n, __n_move); 31210eae32dcSDimitry Andric __null_terminate_at(__p, __sz - __n); 31220b57cec5SDimitry Andric } 31235ffd83dbSDimitry Andric} 31245ffd83dbSDimitry Andric 31255ffd83dbSDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3126e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& 3127e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, size_type __n) { 312804eeddc0SDimitry Andric if (__pos > size()) 312904eeddc0SDimitry Andric __throw_out_of_range(); 31305ffd83dbSDimitry Andric if (__n == npos) { 31315ffd83dbSDimitry Andric __erase_to_end(__pos); 31325ffd83dbSDimitry Andric } else { 31335ffd83dbSDimitry Andric __erase_external_with_move(__pos, __n); 31345ffd83dbSDimitry Andric } 31350b57cec5SDimitry Andric return *this; 31360b57cec5SDimitry Andric} 31370b57cec5SDimitry Andric 31380b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3139e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator 3140e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos) { 3141fe013be4SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 3142fe013be4SDimitry Andric __pos != end(), "string::erase(iterator) called with a non-dereferenceable iterator"); 31430b57cec5SDimitry Andric iterator __b = begin(); 31440b57cec5SDimitry Andric size_type __r = static_cast<size_type>(__pos - __b); 31450b57cec5SDimitry Andric erase(__r, 1); 31460b57cec5SDimitry Andric return __b + static_cast<difference_type>(__r); 31470b57cec5SDimitry Andric} 31480b57cec5SDimitry Andric 31490b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3150e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator 3151e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last) { 3152fe013be4SDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE(__first <= __last, "string::erase(first, last) called with invalid range"); 31530b57cec5SDimitry Andric iterator __b = begin(); 31540b57cec5SDimitry Andric size_type __r = static_cast<size_type>(__first - __b); 31550b57cec5SDimitry Andric erase(__r, static_cast<size_type>(__last - __first)); 31560b57cec5SDimitry Andric return __b + static_cast<difference_type>(__r); 31570b57cec5SDimitry Andric} 31580b57cec5SDimitry Andric 31590b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3160e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::pop_back() { 3161fe013be4SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::pop_back(): string is already empty"); 31620eae32dcSDimitry Andric __erase_to_end(size() - 1); 31630b57cec5SDimitry Andric} 31640b57cec5SDimitry Andric 31650b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3166e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT { 3167c9157d92SDimitry Andric size_type __old_size = size(); 3168e710425bSDimitry Andric if (__is_long()) { 31690b57cec5SDimitry Andric traits_type::assign(*__get_long_pointer(), value_type()); 31700b57cec5SDimitry Andric __set_long_size(0); 3171e710425bSDimitry Andric } else { 31720b57cec5SDimitry Andric traits_type::assign(*__get_short_pointer(), value_type()); 31730b57cec5SDimitry Andric __set_short_size(0); 31740b57cec5SDimitry Andric } 3175c9157d92SDimitry Andric __annotate_shrink(__old_size); 31760b57cec5SDimitry Andric} 31770b57cec5SDimitry Andric 31780b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3179e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c) { 31800b57cec5SDimitry Andric size_type __sz = size(); 31810b57cec5SDimitry Andric if (__n > __sz) 31820b57cec5SDimitry Andric append(__n - __sz, __c); 31830b57cec5SDimitry Andric else 31840b57cec5SDimitry Andric __erase_to_end(__n); 31850b57cec5SDimitry Andric} 31860b57cec5SDimitry Andric 31870b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3188bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 inline void 3189e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__resize_default_init(size_type __n) { 31900b57cec5SDimitry Andric size_type __sz = size(); 31910b57cec5SDimitry Andric if (__n > __sz) { 31920b57cec5SDimitry Andric __append_default_init(__n - __sz); 31930b57cec5SDimitry Andric } else 31940b57cec5SDimitry Andric __erase_to_end(__n); 31950b57cec5SDimitry Andric} 31960b57cec5SDimitry Andric 31970b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3198e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacity) { 3199e8d8bef9SDimitry Andric if (__requested_capacity > max_size()) 320004eeddc0SDimitry Andric __throw_length_error(); 3201e8d8bef9SDimitry Andric 320204eeddc0SDimitry Andric // Make sure reserve(n) never shrinks. This is technically only required in C++20 320304eeddc0SDimitry Andric // and later (since P0966R1), however we provide consistent behavior in all Standard 320404eeddc0SDimitry Andric // modes because this function is instantiated in the shared library. 320504eeddc0SDimitry Andric if (__requested_capacity <= capacity()) 320604eeddc0SDimitry Andric return; 3207e8d8bef9SDimitry Andric 320881ad6265SDimitry Andric size_type __target_capacity = std::max(__requested_capacity, size()); 3209e8d8bef9SDimitry Andric __target_capacity = __recommend(__target_capacity); 3210e710425bSDimitry Andric if (__target_capacity == capacity()) 3211e710425bSDimitry Andric return; 3212e8d8bef9SDimitry Andric 3213e8d8bef9SDimitry Andric __shrink_or_extend(__target_capacity); 3214e8d8bef9SDimitry Andric} 3215e8d8bef9SDimitry Andric 3216e8d8bef9SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3217e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::shrink_to_fit() _NOEXCEPT { 3218e8d8bef9SDimitry Andric size_type __target_capacity = __recommend(size()); 3219e710425bSDimitry Andric if (__target_capacity == capacity()) 3220e710425bSDimitry Andric return; 3221e8d8bef9SDimitry Andric 3222e8d8bef9SDimitry Andric __shrink_or_extend(__target_capacity); 3223e8d8bef9SDimitry Andric} 3224e8d8bef9SDimitry Andric 3225e8d8bef9SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3226e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 void 3227e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target_capacity) { 3228c9157d92SDimitry Andric __annotate_delete(); 32290b57cec5SDimitry Andric size_type __cap = capacity(); 32300b57cec5SDimitry Andric size_type __sz = size(); 3231e8d8bef9SDimitry Andric 32320b57cec5SDimitry Andric pointer __new_data, __p; 32330b57cec5SDimitry Andric bool __was_long, __now_long; 3234e710425bSDimitry Andric if (__fits_in_sso(__target_capacity)) { 32350b57cec5SDimitry Andric __was_long = true; 32360b57cec5SDimitry Andric __now_long = false; 32370b57cec5SDimitry Andric __new_data = __get_short_pointer(); 32380b57cec5SDimitry Andric __p = __get_long_pointer(); 3239e710425bSDimitry Andric } else { 324081ad6265SDimitry Andric if (__target_capacity > __cap) { 324181ad6265SDimitry Andric auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1); 324281ad6265SDimitry Andric __new_data = __allocation.ptr; 324381ad6265SDimitry Andric __target_capacity = __allocation.count - 1; 3244e710425bSDimitry Andric } else { 3245fe013be4SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 3246e710425bSDimitry Andric try { 3247fe013be4SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 324881ad6265SDimitry Andric auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1); 324981ad6265SDimitry Andric __new_data = __allocation.ptr; 325081ad6265SDimitry Andric __target_capacity = __allocation.count - 1; 3251fe013be4SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 3252e710425bSDimitry Andric } catch (...) { 32530b57cec5SDimitry Andric return; 32540b57cec5SDimitry Andric } 3255fe013be4SDimitry Andric#else // _LIBCPP_HAS_NO_EXCEPTIONS 32560b57cec5SDimitry Andric if (__new_data == nullptr) 32570b57cec5SDimitry Andric return; 3258fe013be4SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS 32590b57cec5SDimitry Andric } 326081ad6265SDimitry Andric __begin_lifetime(__new_data, __target_capacity + 1); 32610b57cec5SDimitry Andric __now_long = true; 32620b57cec5SDimitry Andric __was_long = __is_long(); 32630b57cec5SDimitry Andric __p = __get_pointer(); 32640b57cec5SDimitry Andric } 3265e710425bSDimitry Andric traits_type::copy(std::__to_address(__new_data), std::__to_address(__p), size() + 1); 32660b57cec5SDimitry Andric if (__was_long) 32670b57cec5SDimitry Andric __alloc_traits::deallocate(__alloc(), __p, __cap + 1); 3268e710425bSDimitry Andric if (__now_long) { 3269e8d8bef9SDimitry Andric __set_long_cap(__target_capacity + 1); 32700b57cec5SDimitry Andric __set_long_size(__sz); 32710b57cec5SDimitry Andric __set_long_pointer(__new_data); 3272e710425bSDimitry Andric } else 32730b57cec5SDimitry Andric __set_short_size(__sz); 3274c9157d92SDimitry Andric __annotate_new(__sz); 32750b57cec5SDimitry Andric} 32760b57cec5SDimitry Andric 32770b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3278e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::const_reference 3279e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const { 32800b57cec5SDimitry Andric if (__n >= size()) 328104eeddc0SDimitry Andric __throw_out_of_range(); 32820b57cec5SDimitry Andric return (*this)[__n]; 32830b57cec5SDimitry Andric} 32840b57cec5SDimitry Andric 32850b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3286e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::reference 3287e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::at(size_type __n) { 32880b57cec5SDimitry Andric if (__n >= size()) 328904eeddc0SDimitry Andric __throw_out_of_range(); 32900b57cec5SDimitry Andric return (*this)[__n]; 32910b57cec5SDimitry Andric} 32920b57cec5SDimitry Andric 32930b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3294e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3295e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n, size_type __pos) const { 32960b57cec5SDimitry Andric size_type __sz = size(); 32970b57cec5SDimitry Andric if (__pos > __sz) 329804eeddc0SDimitry Andric __throw_out_of_range(); 329981ad6265SDimitry Andric size_type __rlen = std::min(__n, __sz - __pos); 33000b57cec5SDimitry Andric traits_type::copy(__s, data() + __pos, __rlen); 33010b57cec5SDimitry Andric return __rlen; 33020b57cec5SDimitry Andric} 33030b57cec5SDimitry Andric 33040b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3305e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str) 33060b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14 33070b57cec5SDimitry Andric _NOEXCEPT 33080b57cec5SDimitry Andric#else 3309e710425bSDimitry Andric _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<allocator_type>::value) 33100b57cec5SDimitry Andric#endif 33110b57cec5SDimitry Andric{ 3312fe013be4SDimitry Andric _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR( 3313e710425bSDimitry Andric __alloc_traits::propagate_on_container_swap::value || __alloc_traits::is_always_equal::value || 3314e710425bSDimitry Andric __alloc() == __str.__alloc(), 3315e710425bSDimitry Andric "swapping non-equal allocators"); 3316c9157d92SDimitry Andric if (!__is_long()) 3317c9157d92SDimitry Andric __annotate_delete(); 3318c9157d92SDimitry Andric if (this != &__str && !__str.__is_long()) 3319c9157d92SDimitry Andric __str.__annotate_delete(); 332081ad6265SDimitry Andric std::swap(__r_.first(), __str.__r_.first()); 332181ad6265SDimitry Andric std::__swap_allocator(__alloc(), __str.__alloc()); 3322c9157d92SDimitry Andric if (!__is_long()) 3323c9157d92SDimitry Andric __annotate_new(__get_short_size()); 3324c9157d92SDimitry Andric if (this != &__str && !__str.__is_long()) 3325c9157d92SDimitry Andric __str.__annotate_new(__str.__get_short_size()); 33260b57cec5SDimitry Andric} 33270b57cec5SDimitry Andric 33280b57cec5SDimitry Andric// find 33290b57cec5SDimitry Andric 33300b57cec5SDimitry Andrictemplate <class _Traits> 3331e710425bSDimitry Andricstruct _LIBCPP_HIDDEN __traits_eq { 33320b57cec5SDimitry Andric typedef typename _Traits::char_type char_type; 3333e710425bSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool operator()(const char_type& __x, const char_type& __y) _NOEXCEPT { 3334e710425bSDimitry Andric return _Traits::eq(__x, __y); 3335e710425bSDimitry Andric } 33360b57cec5SDimitry Andric}; 33370b57cec5SDimitry Andric 33380b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3339e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3340e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT { 3341c9157d92SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find(): received nullptr"); 3342e710425bSDimitry Andric return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); 33430b57cec5SDimitry Andric} 33440b57cec5SDimitry Andric 33450b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3346e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3347e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str, size_type __pos) const _NOEXCEPT { 3348e710425bSDimitry Andric return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __str.data(), __pos, __str.size()); 33490b57cec5SDimitry Andric} 33500b57cec5SDimitry Andric 33510b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3352fe013be4SDimitry Andrictemplate <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 3353fe013be4SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3354e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find(const _Tp& __t, size_type __pos) const _NOEXCEPT { 33550b57cec5SDimitry Andric __self_view __sv = __t; 3356e710425bSDimitry Andric return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __sv.data(), __pos, __sv.size()); 33570b57cec5SDimitry Andric} 33580b57cec5SDimitry Andric 33590b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3360e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3361e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, size_type __pos) const _NOEXCEPT { 3362c9157d92SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find(): received nullptr"); 3363e710425bSDimitry Andric return std::__str_find<value_type, size_type, traits_type, npos>( 3364e710425bSDimitry Andric data(), size(), __s, __pos, traits_type::length(__s)); 33650b57cec5SDimitry Andric} 33660b57cec5SDimitry Andric 33670b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3368e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3369e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find(value_type __c, size_type __pos) const _NOEXCEPT { 3370e710425bSDimitry Andric return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos); 33710b57cec5SDimitry Andric} 33720b57cec5SDimitry Andric 33730b57cec5SDimitry Andric// rfind 33740b57cec5SDimitry Andric 33750b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3376e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3377e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::rfind( 3378e710425bSDimitry Andric const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT { 3379c9157d92SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::rfind(): received nullptr"); 3380e710425bSDimitry Andric return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); 33810b57cec5SDimitry Andric} 33820b57cec5SDimitry Andric 33830b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3384e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3385e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str, size_type __pos) const _NOEXCEPT { 3386e710425bSDimitry Andric return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __str.data(), __pos, __str.size()); 33870b57cec5SDimitry Andric} 33880b57cec5SDimitry Andric 33890b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3390fe013be4SDimitry Andrictemplate <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 3391fe013be4SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3392e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::rfind(const _Tp& __t, size_type __pos) const _NOEXCEPT { 33930b57cec5SDimitry Andric __self_view __sv = __t; 3394e710425bSDimitry Andric return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __sv.data(), __pos, __sv.size()); 33950b57cec5SDimitry Andric} 33960b57cec5SDimitry Andric 33970b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3398e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3399e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, size_type __pos) const _NOEXCEPT { 3400c9157d92SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::rfind(): received nullptr"); 3401e710425bSDimitry Andric return std::__str_rfind<value_type, size_type, traits_type, npos>( 3402e710425bSDimitry Andric data(), size(), __s, __pos, traits_type::length(__s)); 34030b57cec5SDimitry Andric} 34040b57cec5SDimitry Andric 34050b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3406e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3407e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c, size_type __pos) const _NOEXCEPT { 3408e710425bSDimitry Andric return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos); 34090b57cec5SDimitry Andric} 34100b57cec5SDimitry Andric 34110b57cec5SDimitry Andric// find_first_of 34120b57cec5SDimitry Andric 34130b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3414e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3415e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_first_of( 3416e710425bSDimitry Andric const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT { 3417c9157d92SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr"); 3418e710425bSDimitry Andric return std::__str_find_first_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); 34190b57cec5SDimitry Andric} 34200b57cec5SDimitry Andric 34210b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3422e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3423e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str, size_type __pos) const _NOEXCEPT { 3424e710425bSDimitry Andric return std::__str_find_first_of<value_type, size_type, traits_type, npos>( 3425e710425bSDimitry Andric data(), size(), __str.data(), __pos, __str.size()); 34260b57cec5SDimitry Andric} 34270b57cec5SDimitry Andric 34280b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3429fe013be4SDimitry Andrictemplate <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 3430fe013be4SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3431e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_first_of(const _Tp& __t, size_type __pos) const _NOEXCEPT { 34320b57cec5SDimitry Andric __self_view __sv = __t; 3433e710425bSDimitry Andric return std::__str_find_first_of<value_type, size_type, traits_type, npos>( 3434e710425bSDimitry Andric data(), size(), __sv.data(), __pos, __sv.size()); 34350b57cec5SDimitry Andric} 34360b57cec5SDimitry Andric 34370b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3438e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3439e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, size_type __pos) const _NOEXCEPT { 3440c9157d92SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_first_of(): received nullptr"); 3441e710425bSDimitry Andric return std::__str_find_first_of<value_type, size_type, traits_type, npos>( 3442e710425bSDimitry Andric data(), size(), __s, __pos, traits_type::length(__s)); 34430b57cec5SDimitry Andric} 34440b57cec5SDimitry Andric 34450b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3446e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3447e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c, size_type __pos) const _NOEXCEPT { 34480b57cec5SDimitry Andric return find(__c, __pos); 34490b57cec5SDimitry Andric} 34500b57cec5SDimitry Andric 34510b57cec5SDimitry Andric// find_last_of 34520b57cec5SDimitry Andric 34530b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3454e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3455e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_last_of( 3456e710425bSDimitry Andric const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT { 3457c9157d92SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr"); 3458e710425bSDimitry Andric return std::__str_find_last_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); 34590b57cec5SDimitry Andric} 34600b57cec5SDimitry Andric 34610b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3462e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3463e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str, size_type __pos) const _NOEXCEPT { 3464e710425bSDimitry Andric return std::__str_find_last_of<value_type, size_type, traits_type, npos>( 3465e710425bSDimitry Andric data(), size(), __str.data(), __pos, __str.size()); 34660b57cec5SDimitry Andric} 34670b57cec5SDimitry Andric 34680b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3469fe013be4SDimitry Andrictemplate <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 3470fe013be4SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3471e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_last_of(const _Tp& __t, size_type __pos) const _NOEXCEPT { 34720b57cec5SDimitry Andric __self_view __sv = __t; 3473e710425bSDimitry Andric return std::__str_find_last_of<value_type, size_type, traits_type, npos>( 3474e710425bSDimitry Andric data(), size(), __sv.data(), __pos, __sv.size()); 34750b57cec5SDimitry Andric} 34760b57cec5SDimitry Andric 34770b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3478e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3479e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, size_type __pos) const _NOEXCEPT { 3480c9157d92SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_last_of(): received nullptr"); 3481e710425bSDimitry Andric return std::__str_find_last_of<value_type, size_type, traits_type, npos>( 3482e710425bSDimitry Andric data(), size(), __s, __pos, traits_type::length(__s)); 34830b57cec5SDimitry Andric} 34840b57cec5SDimitry Andric 34850b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3486e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3487e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c, size_type __pos) const _NOEXCEPT { 34880b57cec5SDimitry Andric return rfind(__c, __pos); 34890b57cec5SDimitry Andric} 34900b57cec5SDimitry Andric 34910b57cec5SDimitry Andric// find_first_not_of 34920b57cec5SDimitry Andric 34930b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3494e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3495e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_first_not_of( 3496e710425bSDimitry Andric const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT { 3497c9157d92SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr"); 3498e710425bSDimitry Andric return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); 34990b57cec5SDimitry Andric} 35000b57cec5SDimitry Andric 35010b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3502e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3503e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_first_not_of( 3504e710425bSDimitry Andric const basic_string& __str, size_type __pos) const _NOEXCEPT { 3505e710425bSDimitry Andric return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>( 3506e710425bSDimitry Andric data(), size(), __str.data(), __pos, __str.size()); 35070b57cec5SDimitry Andric} 35080b57cec5SDimitry Andric 35090b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3510fe013be4SDimitry Andrictemplate <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 3511fe013be4SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3512e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const _Tp& __t, size_type __pos) const _NOEXCEPT { 35130b57cec5SDimitry Andric __self_view __sv = __t; 3514e710425bSDimitry Andric return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>( 3515e710425bSDimitry Andric data(), size(), __sv.data(), __pos, __sv.size()); 35160b57cec5SDimitry Andric} 35170b57cec5SDimitry Andric 35180b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3519e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3520e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s, size_type __pos) const _NOEXCEPT { 3521c9157d92SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_first_not_of(): received nullptr"); 3522e710425bSDimitry Andric return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>( 3523e710425bSDimitry Andric data(), size(), __s, __pos, traits_type::length(__s)); 35240b57cec5SDimitry Andric} 35250b57cec5SDimitry Andric 35260b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3527e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3528e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c, size_type __pos) const _NOEXCEPT { 3529e710425bSDimitry Andric return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos); 35300b57cec5SDimitry Andric} 35310b57cec5SDimitry Andric 35320b57cec5SDimitry Andric// find_last_not_of 35330b57cec5SDimitry Andric 35340b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3535e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3536e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_last_not_of( 3537e710425bSDimitry Andric const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT { 3538c9157d92SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr"); 3539e710425bSDimitry Andric return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); 35400b57cec5SDimitry Andric} 35410b57cec5SDimitry Andric 35420b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3543e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3544e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_last_not_of( 3545e710425bSDimitry Andric const basic_string& __str, size_type __pos) const _NOEXCEPT { 3546e710425bSDimitry Andric return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>( 3547e710425bSDimitry Andric data(), size(), __str.data(), __pos, __str.size()); 35480b57cec5SDimitry Andric} 35490b57cec5SDimitry Andric 35500b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3551fe013be4SDimitry Andrictemplate <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 3552fe013be4SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3553e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const _Tp& __t, size_type __pos) const _NOEXCEPT { 35540b57cec5SDimitry Andric __self_view __sv = __t; 3555e710425bSDimitry Andric return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>( 3556e710425bSDimitry Andric data(), size(), __sv.data(), __pos, __sv.size()); 35570b57cec5SDimitry Andric} 35580b57cec5SDimitry Andric 35590b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3560e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3561e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s, size_type __pos) const _NOEXCEPT { 3562c9157d92SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_last_not_of(): received nullptr"); 3563e710425bSDimitry Andric return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>( 3564e710425bSDimitry Andric data(), size(), __s, __pos, traits_type::length(__s)); 35650b57cec5SDimitry Andric} 35660b57cec5SDimitry Andric 35670b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3568e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type 3569e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c, size_type __pos) const _NOEXCEPT { 3570e710425bSDimitry Andric return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos); 35710b57cec5SDimitry Andric} 35720b57cec5SDimitry Andric 35730b57cec5SDimitry Andric// compare 35740b57cec5SDimitry Andric 35750b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3576fe013be4SDimitry Andrictemplate <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 3577e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 int basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const _NOEXCEPT { 35780b57cec5SDimitry Andric __self_view __sv = __t; 35790b57cec5SDimitry Andric size_t __lhs_sz = size(); 35800b57cec5SDimitry Andric size_t __rhs_sz = __sv.size(); 3581e710425bSDimitry Andric int __result = traits_type::compare(data(), __sv.data(), std::min(__lhs_sz, __rhs_sz)); 35820b57cec5SDimitry Andric if (__result != 0) 35830b57cec5SDimitry Andric return __result; 35840b57cec5SDimitry Andric if (__lhs_sz < __rhs_sz) 35850b57cec5SDimitry Andric return -1; 35860b57cec5SDimitry Andric if (__lhs_sz > __rhs_sz) 35870b57cec5SDimitry Andric return 1; 35880b57cec5SDimitry Andric return 0; 35890b57cec5SDimitry Andric} 35900b57cec5SDimitry Andric 35910b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3592e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 int 3593e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT { 35940b57cec5SDimitry Andric return compare(__self_view(__str)); 35950b57cec5SDimitry Andric} 35960b57cec5SDimitry Andric 35970b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3598e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 int basic_string<_CharT, _Traits, _Allocator>::compare( 3599e710425bSDimitry Andric size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const { 3600c9157d92SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr"); 36010b57cec5SDimitry Andric size_type __sz = size(); 36020b57cec5SDimitry Andric if (__pos1 > __sz || __n2 == npos) 360304eeddc0SDimitry Andric __throw_out_of_range(); 360481ad6265SDimitry Andric size_type __rlen = std::min(__n1, __sz - __pos1); 360581ad6265SDimitry Andric int __r = traits_type::compare(data() + __pos1, __s, std::min(__rlen, __n2)); 3606e710425bSDimitry Andric if (__r == 0) { 36070b57cec5SDimitry Andric if (__rlen < __n2) 36080b57cec5SDimitry Andric __r = -1; 36090b57cec5SDimitry Andric else if (__rlen > __n2) 36100b57cec5SDimitry Andric __r = 1; 36110b57cec5SDimitry Andric } 36120b57cec5SDimitry Andric return __r; 36130b57cec5SDimitry Andric} 36140b57cec5SDimitry Andric 36150b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3616fe013be4SDimitry Andrictemplate <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > 3617fe013be4SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 int 3618e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, const _Tp& __t) const { 36190b57cec5SDimitry Andric __self_view __sv = __t; 36200b57cec5SDimitry Andric return compare(__pos1, __n1, __sv.data(), __sv.size()); 36210b57cec5SDimitry Andric} 36220b57cec5SDimitry Andric 36230b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3624e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 int 3625e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, const basic_string& __str) const { 36260b57cec5SDimitry Andric return compare(__pos1, __n1, __str.data(), __str.size()); 36270b57cec5SDimitry Andric} 36280b57cec5SDimitry Andric 36290b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3630fe013be4SDimitry Andrictemplate <class _Tp, 3631fe013be4SDimitry Andric __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && 3632fe013be4SDimitry Andric !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, 3633fe013be4SDimitry Andric int> > 3634fe013be4SDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 int basic_string<_CharT, _Traits, _Allocator>::compare( 3635fe013be4SDimitry Andric size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2) const { 36360b57cec5SDimitry Andric __self_view __sv = __t; 36370b57cec5SDimitry Andric return __self_view(*this).substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2)); 36380b57cec5SDimitry Andric} 36390b57cec5SDimitry Andric 36400b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3641e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 int basic_string<_CharT, _Traits, _Allocator>::compare( 3642e710425bSDimitry Andric size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2) const { 36430b57cec5SDimitry Andric return compare(__pos1, __n1, __self_view(__str), __pos2, __n2); 36440b57cec5SDimitry Andric} 36450b57cec5SDimitry Andric 36460b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3647e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 int 3648e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT { 3649c9157d92SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::compare(): received nullptr"); 36500b57cec5SDimitry Andric return compare(0, npos, __s, traits_type::length(__s)); 36510b57cec5SDimitry Andric} 36520b57cec5SDimitry Andric 36530b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3654e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 int 3655e710425bSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, const value_type* __s) const { 3656c9157d92SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::compare(): received nullptr"); 36570b57cec5SDimitry Andric return compare(__pos1, __n1, __s, traits_type::length(__s)); 36580b57cec5SDimitry Andric} 36590b57cec5SDimitry Andric 36600b57cec5SDimitry Andric// __invariants 36610b57cec5SDimitry Andric 36620b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3663e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 bool basic_string<_CharT, _Traits, _Allocator>::__invariants() const { 36640b57cec5SDimitry Andric if (size() > capacity()) 36650b57cec5SDimitry Andric return false; 36660b57cec5SDimitry Andric if (capacity() < __min_cap - 1) 36670b57cec5SDimitry Andric return false; 3668e8d8bef9SDimitry Andric if (data() == nullptr) 36690b57cec5SDimitry Andric return false; 3670fe013be4SDimitry Andric if (!_Traits::eq(data()[size()], value_type())) 36710b57cec5SDimitry Andric return false; 36720b57cec5SDimitry Andric return true; 36730b57cec5SDimitry Andric} 36740b57cec5SDimitry Andric 36750b57cec5SDimitry Andric// __clear_and_shrink 36760b57cec5SDimitry Andric 36770b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3678e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT { 36790b57cec5SDimitry Andric clear(); 3680c9157d92SDimitry Andric if (__is_long()) { 3681c9157d92SDimitry Andric __annotate_delete(); 36820b57cec5SDimitry Andric __alloc_traits::deallocate(__alloc(), __get_long_pointer(), capacity() + 1); 3683c9157d92SDimitry Andric __r_.first() = __rep(); 36840b57cec5SDimitry Andric } 36850b57cec5SDimitry Andric} 36860b57cec5SDimitry Andric 36870b57cec5SDimitry Andric// operator== 36880b57cec5SDimitry Andric 36890b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3690e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool 36910b57cec5SDimitry Andricoperator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3692e710425bSDimitry Andric const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 3693fe013be4SDimitry Andric#if _LIBCPP_STD_VER >= 20 3694bdd1243dSDimitry Andric return basic_string_view<_CharT, _Traits>(__lhs) == basic_string_view<_CharT, _Traits>(__rhs); 3695bdd1243dSDimitry Andric#else 36960b57cec5SDimitry Andric size_t __lhs_sz = __lhs.size(); 3697e710425bSDimitry Andric return __lhs_sz == __rhs.size() && _Traits::compare(__lhs.data(), __rhs.data(), __lhs_sz) == 0; 3698bdd1243dSDimitry Andric#endif 36990b57cec5SDimitry Andric} 37000b57cec5SDimitry Andric 37010b57cec5SDimitry Andrictemplate <class _Allocator> 3702e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool 37030b57cec5SDimitry Andricoperator==(const basic_string<char, char_traits<char>, _Allocator>& __lhs, 3704e710425bSDimitry Andric const basic_string<char, char_traits<char>, _Allocator>& __rhs) _NOEXCEPT { 37050b57cec5SDimitry Andric size_t __lhs_sz = __lhs.size(); 37060b57cec5SDimitry Andric if (__lhs_sz != __rhs.size()) 37070b57cec5SDimitry Andric return false; 37080b57cec5SDimitry Andric const char* __lp = __lhs.data(); 37090b57cec5SDimitry Andric const char* __rp = __rhs.data(); 37100b57cec5SDimitry Andric if (__lhs.__is_long()) 37110b57cec5SDimitry Andric return char_traits<char>::compare(__lp, __rp, __lhs_sz) == 0; 37120b57cec5SDimitry Andric for (; __lhs_sz != 0; --__lhs_sz, ++__lp, ++__rp) 37130b57cec5SDimitry Andric if (*__lp != *__rp) 37140b57cec5SDimitry Andric return false; 37150b57cec5SDimitry Andric return true; 37160b57cec5SDimitry Andric} 37170b57cec5SDimitry Andric 3718bdd1243dSDimitry Andric#if _LIBCPP_STD_VER <= 17 37190b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3720e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool 3721e710425bSDimitry Andricoperator==(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 37220b57cec5SDimitry Andric typedef basic_string<_CharT, _Traits, _Allocator> _String; 3723c9157d92SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__lhs != nullptr, "operator==(char*, basic_string): received nullptr"); 37240b57cec5SDimitry Andric size_t __lhs_len = _Traits::length(__lhs); 3725e710425bSDimitry Andric if (__lhs_len != __rhs.size()) 3726e710425bSDimitry Andric return false; 37270b57cec5SDimitry Andric return __rhs.compare(0, _String::npos, __lhs, __lhs_len) == 0; 37280b57cec5SDimitry Andric} 3729bdd1243dSDimitry Andric#endif // _LIBCPP_STD_VER <= 17 37300b57cec5SDimitry Andric 37310b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3732e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool 3733e710425bSDimitry Andricoperator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT { 3734fe013be4SDimitry Andric#if _LIBCPP_STD_VER >= 20 3735bdd1243dSDimitry Andric return basic_string_view<_CharT, _Traits>(__lhs) == basic_string_view<_CharT, _Traits>(__rhs); 3736bdd1243dSDimitry Andric#else 37370b57cec5SDimitry Andric typedef basic_string<_CharT, _Traits, _Allocator> _String; 3738c9157d92SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__rhs != nullptr, "operator==(basic_string, char*): received nullptr"); 37390b57cec5SDimitry Andric size_t __rhs_len = _Traits::length(__rhs); 3740e710425bSDimitry Andric if (__rhs_len != __lhs.size()) 3741e710425bSDimitry Andric return false; 37420b57cec5SDimitry Andric return __lhs.compare(0, _String::npos, __rhs, __rhs_len) == 0; 3743bdd1243dSDimitry Andric#endif 3744bdd1243dSDimitry Andric} 3745bdd1243dSDimitry Andric 3746fe013be4SDimitry Andric#if _LIBCPP_STD_VER >= 20 3747bdd1243dSDimitry Andric 3748bdd1243dSDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3749e710425bSDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr auto operator<=>(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3750bdd1243dSDimitry Andric const basic_string<_CharT, _Traits, _Allocator>& __rhs) noexcept { 3751bdd1243dSDimitry Andric return basic_string_view<_CharT, _Traits>(__lhs) <=> basic_string_view<_CharT, _Traits>(__rhs); 37520b57cec5SDimitry Andric} 37530b57cec5SDimitry Andric 37540b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3755bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr auto 3756bdd1243dSDimitry Andricoperator<=>(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) { 3757bdd1243dSDimitry Andric return basic_string_view<_CharT, _Traits>(__lhs) <=> basic_string_view<_CharT, _Traits>(__rhs); 3758bdd1243dSDimitry Andric} 3759bdd1243dSDimitry Andric 3760fe013be4SDimitry Andric#else // _LIBCPP_STD_VER >= 20 3761bdd1243dSDimitry Andric 3762bdd1243dSDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3763e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3764e710425bSDimitry Andric const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 37650b57cec5SDimitry Andric return !(__lhs == __rhs); 37660b57cec5SDimitry Andric} 37670b57cec5SDimitry Andric 37680b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3769e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool 3770e710425bSDimitry Andricoperator!=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 37710b57cec5SDimitry Andric return !(__lhs == __rhs); 37720b57cec5SDimitry Andric} 37730b57cec5SDimitry Andric 37740b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3775e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool 3776e710425bSDimitry Andricoperator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT { 37770b57cec5SDimitry Andric return !(__lhs == __rhs); 37780b57cec5SDimitry Andric} 37790b57cec5SDimitry Andric 37800b57cec5SDimitry Andric// operator< 37810b57cec5SDimitry Andric 37820b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3783e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator<(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3784e710425bSDimitry Andric const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 37850b57cec5SDimitry Andric return __lhs.compare(__rhs) < 0; 37860b57cec5SDimitry Andric} 37870b57cec5SDimitry Andric 37880b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3789e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool 3790e710425bSDimitry Andricoperator<(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT { 37910b57cec5SDimitry Andric return __lhs.compare(__rhs) < 0; 37920b57cec5SDimitry Andric} 37930b57cec5SDimitry Andric 37940b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3795e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool 3796e710425bSDimitry Andricoperator<(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 37970b57cec5SDimitry Andric return __rhs.compare(__lhs) > 0; 37980b57cec5SDimitry Andric} 37990b57cec5SDimitry Andric 38000b57cec5SDimitry Andric// operator> 38010b57cec5SDimitry Andric 38020b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3803e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator>(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3804e710425bSDimitry Andric const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 38050b57cec5SDimitry Andric return __rhs < __lhs; 38060b57cec5SDimitry Andric} 38070b57cec5SDimitry Andric 38080b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3809e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool 3810e710425bSDimitry Andricoperator>(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT { 38110b57cec5SDimitry Andric return __rhs < __lhs; 38120b57cec5SDimitry Andric} 38130b57cec5SDimitry Andric 38140b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3815e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool 3816e710425bSDimitry Andricoperator>(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 38170b57cec5SDimitry Andric return __rhs < __lhs; 38180b57cec5SDimitry Andric} 38190b57cec5SDimitry Andric 38200b57cec5SDimitry Andric// operator<= 38210b57cec5SDimitry Andric 38220b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3823e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3824e710425bSDimitry Andric const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 38250b57cec5SDimitry Andric return !(__rhs < __lhs); 38260b57cec5SDimitry Andric} 38270b57cec5SDimitry Andric 38280b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3829e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool 3830e710425bSDimitry Andricoperator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT { 38310b57cec5SDimitry Andric return !(__rhs < __lhs); 38320b57cec5SDimitry Andric} 38330b57cec5SDimitry Andric 38340b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3835e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool 3836e710425bSDimitry Andricoperator<=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 38370b57cec5SDimitry Andric return !(__rhs < __lhs); 38380b57cec5SDimitry Andric} 38390b57cec5SDimitry Andric 38400b57cec5SDimitry Andric// operator>= 38410b57cec5SDimitry Andric 38420b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3843e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3844e710425bSDimitry Andric const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 38450b57cec5SDimitry Andric return !(__lhs < __rhs); 38460b57cec5SDimitry Andric} 38470b57cec5SDimitry Andric 38480b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3849e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool 3850e710425bSDimitry Andricoperator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT { 38510b57cec5SDimitry Andric return !(__lhs < __rhs); 38520b57cec5SDimitry Andric} 38530b57cec5SDimitry Andric 38540b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3855e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool 3856e710425bSDimitry Andricoperator>=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT { 38570b57cec5SDimitry Andric return !(__lhs < __rhs); 38580b57cec5SDimitry Andric} 3859fe013be4SDimitry Andric#endif // _LIBCPP_STD_VER >= 20 38600b57cec5SDimitry Andric 38610b57cec5SDimitry Andric// operator + 38620b57cec5SDimitry Andric 38630b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3864e710425bSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 38650b57cec5SDimitry Andricoperator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 3866e710425bSDimitry Andric const basic_string<_CharT, _Traits, _Allocator>& __rhs) { 386781ad6265SDimitry Andric using _String = basic_string<_CharT, _Traits, _Allocator>; 386881ad6265SDimitry Andric auto __lhs_sz = __lhs.size(); 386981ad6265SDimitry Andric auto __rhs_sz = __rhs.size(); 387081ad6265SDimitry Andric _String __r(__uninitialized_size_tag(), 387181ad6265SDimitry Andric __lhs_sz + __rhs_sz, 387281ad6265SDimitry Andric _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator())); 387381ad6265SDimitry Andric auto __ptr = std::__to_address(__r.__get_pointer()); 387481ad6265SDimitry Andric _Traits::copy(__ptr, __lhs.data(), __lhs_sz); 387581ad6265SDimitry Andric _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz); 387681ad6265SDimitry Andric _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT()); 38770b57cec5SDimitry Andric return __r; 38780b57cec5SDimitry Andric} 38790b57cec5SDimitry Andric 38800b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3881e710425bSDimitry Andric_LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 3882e710425bSDimitry Andricoperator+(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) { 388381ad6265SDimitry Andric using _String = basic_string<_CharT, _Traits, _Allocator>; 388481ad6265SDimitry Andric auto __lhs_sz = _Traits::length(__lhs); 388581ad6265SDimitry Andric auto __rhs_sz = __rhs.size(); 388681ad6265SDimitry Andric _String __r(__uninitialized_size_tag(), 388781ad6265SDimitry Andric __lhs_sz + __rhs_sz, 388881ad6265SDimitry Andric _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator())); 388981ad6265SDimitry Andric auto __ptr = std::__to_address(__r.__get_pointer()); 389081ad6265SDimitry Andric _Traits::copy(__ptr, __lhs, __lhs_sz); 389181ad6265SDimitry Andric _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz); 389281ad6265SDimitry Andric _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT()); 38930b57cec5SDimitry Andric return __r; 38940b57cec5SDimitry Andric} 38950b57cec5SDimitry Andric 38960b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3897e710425bSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 3898e710425bSDimitry Andricoperator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) { 389981ad6265SDimitry Andric using _String = basic_string<_CharT, _Traits, _Allocator>; 390081ad6265SDimitry Andric typename _String::size_type __rhs_sz = __rhs.size(); 390181ad6265SDimitry Andric _String __r(__uninitialized_size_tag(), 390281ad6265SDimitry Andric __rhs_sz + 1, 390381ad6265SDimitry Andric _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator())); 390481ad6265SDimitry Andric auto __ptr = std::__to_address(__r.__get_pointer()); 390581ad6265SDimitry Andric _Traits::assign(__ptr, 1, __lhs); 390681ad6265SDimitry Andric _Traits::copy(__ptr + 1, __rhs.data(), __rhs_sz); 390781ad6265SDimitry Andric _Traits::assign(__ptr + 1 + __rhs_sz, 1, _CharT()); 39080b57cec5SDimitry Andric return __r; 39090b57cec5SDimitry Andric} 39100b57cec5SDimitry Andric 39110b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3912e710425bSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 3913e710425bSDimitry Andricoperator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) { 391481ad6265SDimitry Andric using _String = basic_string<_CharT, _Traits, _Allocator>; 391581ad6265SDimitry Andric typename _String::size_type __lhs_sz = __lhs.size(); 391681ad6265SDimitry Andric typename _String::size_type __rhs_sz = _Traits::length(__rhs); 391781ad6265SDimitry Andric _String __r(__uninitialized_size_tag(), 391881ad6265SDimitry Andric __lhs_sz + __rhs_sz, 391981ad6265SDimitry Andric _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator())); 392081ad6265SDimitry Andric auto __ptr = std::__to_address(__r.__get_pointer()); 392181ad6265SDimitry Andric _Traits::copy(__ptr, __lhs.data(), __lhs_sz); 392281ad6265SDimitry Andric _Traits::copy(__ptr + __lhs_sz, __rhs, __rhs_sz); 392381ad6265SDimitry Andric _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT()); 39240b57cec5SDimitry Andric return __r; 39250b57cec5SDimitry Andric} 39260b57cec5SDimitry Andric 39270b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3928e710425bSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 3929e710425bSDimitry Andricoperator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs) { 393081ad6265SDimitry Andric using _String = basic_string<_CharT, _Traits, _Allocator>; 393181ad6265SDimitry Andric typename _String::size_type __lhs_sz = __lhs.size(); 393281ad6265SDimitry Andric _String __r(__uninitialized_size_tag(), 393381ad6265SDimitry Andric __lhs_sz + 1, 393481ad6265SDimitry Andric _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator())); 393581ad6265SDimitry Andric auto __ptr = std::__to_address(__r.__get_pointer()); 393681ad6265SDimitry Andric _Traits::copy(__ptr, __lhs.data(), __lhs_sz); 393781ad6265SDimitry Andric _Traits::assign(__ptr + __lhs_sz, 1, __rhs); 393881ad6265SDimitry Andric _Traits::assign(__ptr + 1 + __lhs_sz, 1, _CharT()); 39390b57cec5SDimitry Andric return __r; 39400b57cec5SDimitry Andric} 39410b57cec5SDimitry Andric 39420b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 39430b57cec5SDimitry Andric 39440b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3945e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 3946e710425bSDimitry Andricoperator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) { 394781ad6265SDimitry Andric return std::move(__lhs.append(__rhs)); 39480b57cec5SDimitry Andric} 39490b57cec5SDimitry Andric 39500b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3951e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 3952e710425bSDimitry Andricoperator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs) { 395381ad6265SDimitry Andric return std::move(__rhs.insert(0, __lhs)); 39540b57cec5SDimitry Andric} 39550b57cec5SDimitry Andric 39560b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3957e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 3958e710425bSDimitry Andricoperator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs) { 395981ad6265SDimitry Andric return std::move(__lhs.append(__rhs)); 39600b57cec5SDimitry Andric} 39610b57cec5SDimitry Andric 39620b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3963e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 3964e710425bSDimitry Andricoperator+(const _CharT* __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs) { 396581ad6265SDimitry Andric return std::move(__rhs.insert(0, __lhs)); 39660b57cec5SDimitry Andric} 39670b57cec5SDimitry Andric 39680b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3969e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 3970e710425bSDimitry Andricoperator+(_CharT __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs) { 39710b57cec5SDimitry Andric __rhs.insert(__rhs.begin(), __lhs); 397281ad6265SDimitry Andric return std::move(__rhs); 39730b57cec5SDimitry Andric} 39740b57cec5SDimitry Andric 39750b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3976e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 3977e710425bSDimitry Andricoperator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const _CharT* __rhs) { 397881ad6265SDimitry Andric return std::move(__lhs.append(__rhs)); 39790b57cec5SDimitry Andric} 39800b57cec5SDimitry Andric 39810b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3982e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator> 3983e710425bSDimitry Andricoperator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT __rhs) { 39840b57cec5SDimitry Andric __lhs.push_back(__rhs); 398581ad6265SDimitry Andric return std::move(__lhs); 39860b57cec5SDimitry Andric} 39870b57cec5SDimitry Andric 39880b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 39890b57cec5SDimitry Andric 39900b57cec5SDimitry Andric// swap 39910b57cec5SDimitry Andric 39920b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 3993e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 3994e710425bSDimitry Andricswap(basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>& __rhs) 3995e710425bSDimitry Andric _NOEXCEPT_(_NOEXCEPT_(__lhs.swap(__rhs))) { 39960b57cec5SDimitry Andric __lhs.swap(__rhs); 39970b57cec5SDimitry Andric} 39980b57cec5SDimitry Andric 3999fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI int stoi(const string& __str, size_t* __idx = nullptr, int __base = 10); 4000fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI long stol(const string& __str, size_t* __idx = nullptr, int __base = 10); 4001fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI unsigned long stoul(const string& __str, size_t* __idx = nullptr, int __base = 10); 4002fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI long long stoll(const string& __str, size_t* __idx = nullptr, int __base = 10); 4003fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI unsigned long long stoull(const string& __str, size_t* __idx = nullptr, int __base = 10); 40040b57cec5SDimitry Andric 4005fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI float stof(const string& __str, size_t* __idx = nullptr); 4006fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI double stod(const string& __str, size_t* __idx = nullptr); 4007fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI long double stold(const string& __str, size_t* __idx = nullptr); 40080b57cec5SDimitry Andric 4009fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI string to_string(int __val); 4010fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned __val); 4011fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI string to_string(long __val); 4012fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long __val); 4013fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI string to_string(long long __val); 4014fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long long __val); 4015fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI string to_string(float __val); 4016fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI string to_string(double __val); 4017fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI string to_string(long double __val); 40180b57cec5SDimitry Andric 4019349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 4020fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI int stoi(const wstring& __str, size_t* __idx = nullptr, int __base = 10); 4021fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI long stol(const wstring& __str, size_t* __idx = nullptr, int __base = 10); 4022fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI unsigned long stoul(const wstring& __str, size_t* __idx = nullptr, int __base = 10); 4023fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI long long stoll(const wstring& __str, size_t* __idx = nullptr, int __base = 10); 4024fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI unsigned long long stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10); 40250b57cec5SDimitry Andric 4026fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI float stof(const wstring& __str, size_t* __idx = nullptr); 4027fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI double stod(const wstring& __str, size_t* __idx = nullptr); 4028fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI long double stold(const wstring& __str, size_t* __idx = nullptr); 40290b57cec5SDimitry Andric 4030fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(int __val); 4031fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned __val); 4032fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long __val); 4033fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long __val); 4034fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long long __val); 4035fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long long __val); 4036fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(float __val); 4037fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(double __val); 4038fe013be4SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long double __val); 4039349cc55cSDimitry Andric#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS 40400b57cec5SDimitry Andric 40410b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 4042e710425bSDimitry Andric_LIBCPP_TEMPLATE_DATA_VIS const typename basic_string<_CharT, _Traits, _Allocator>::size_type 40430b57cec5SDimitry Andric basic_string<_CharT, _Traits, _Allocator>::npos; 40440b57cec5SDimitry Andric 40450b57cec5SDimitry Andrictemplate <class _CharT, class _Allocator> 4046fe013be4SDimitry Andricstruct __string_hash : public __unary_function<basic_string<_CharT, char_traits<_CharT>, _Allocator>, size_t> { 4047fe013be4SDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t 4048fe013be4SDimitry Andric operator()(const basic_string<_CharT, char_traits<_CharT>, _Allocator>& __val) const _NOEXCEPT { 4049fe013be4SDimitry Andric return std::__do_string_hash(__val.data(), __val.data() + __val.size()); 4050fe013be4SDimitry Andric } 40510b57cec5SDimitry Andric}; 40520b57cec5SDimitry Andric 4053bdd1243dSDimitry Andrictemplate <class _Allocator> 4054bdd1243dSDimitry Andricstruct hash<basic_string<char, char_traits<char>, _Allocator> > : __string_hash<char, _Allocator> {}; 4055bdd1243dSDimitry Andric 4056bdd1243dSDimitry Andric#ifndef _LIBCPP_HAS_NO_CHAR8_T 4057bdd1243dSDimitry Andrictemplate <class _Allocator> 4058bdd1243dSDimitry Andricstruct hash<basic_string<char8_t, char_traits<char8_t>, _Allocator> > : __string_hash<char8_t, _Allocator> {}; 4059bdd1243dSDimitry Andric#endif 4060bdd1243dSDimitry Andric 4061bdd1243dSDimitry Andrictemplate <class _Allocator> 4062bdd1243dSDimitry Andricstruct hash<basic_string<char16_t, char_traits<char16_t>, _Allocator> > : __string_hash<char16_t, _Allocator> {}; 4063bdd1243dSDimitry Andric 4064bdd1243dSDimitry Andrictemplate <class _Allocator> 4065bdd1243dSDimitry Andricstruct hash<basic_string<char32_t, char_traits<char32_t>, _Allocator> > : __string_hash<char32_t, _Allocator> {}; 4066bdd1243dSDimitry Andric 4067bdd1243dSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 4068bdd1243dSDimitry Andrictemplate <class _Allocator> 4069bdd1243dSDimitry Andricstruct hash<basic_string<wchar_t, char_traits<wchar_t>, _Allocator> > : __string_hash<wchar_t, _Allocator> {}; 4070bdd1243dSDimitry Andric#endif 4071bdd1243dSDimitry Andric 40720b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 4073bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& 4074e710425bSDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os, const basic_string<_CharT, _Traits, _Allocator>& __str); 40750b57cec5SDimitry Andric 40760b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 4077bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& 4078e710425bSDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Allocator>& __str); 40790b57cec5SDimitry Andric 40800b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 4081bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& 4082e710425bSDimitry Andricgetline(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm); 40830b57cec5SDimitry Andric 40840b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 4085e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& 4086e710425bSDimitry Andricgetline(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Allocator>& __str); 40870b57cec5SDimitry Andric 40880b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 4089e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& 4090e710425bSDimitry Andricgetline(basic_istream<_CharT, _Traits>&& __is, basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm); 40910b57cec5SDimitry Andric 40920b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator> 4093e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& 4094e710425bSDimitry Andricgetline(basic_istream<_CharT, _Traits>&& __is, basic_string<_CharT, _Traits, _Allocator>& __str); 40950b57cec5SDimitry Andric 4096fe013be4SDimitry Andric#if _LIBCPP_STD_VER >= 20 40970b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator, class _Up> 4098e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename basic_string<_CharT, _Traits, _Allocator>::size_type 40995ffd83dbSDimitry Andricerase(basic_string<_CharT, _Traits, _Allocator>& __str, const _Up& __v) { 41005ffd83dbSDimitry Andric auto __old_size = __str.size(); 410181ad6265SDimitry Andric __str.erase(std::remove(__str.begin(), __str.end(), __v), __str.end()); 41025ffd83dbSDimitry Andric return __old_size - __str.size(); 41035ffd83dbSDimitry Andric} 41040b57cec5SDimitry Andric 41050b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator, class _Predicate> 4106e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename basic_string<_CharT, _Traits, _Allocator>::size_type 4107e710425bSDimitry Andricerase_if(basic_string<_CharT, _Traits, _Allocator>& __str, _Predicate __pred) { 41085ffd83dbSDimitry Andric auto __old_size = __str.size(); 4109e710425bSDimitry Andric __str.erase(std::remove_if(__str.begin(), __str.end(), __pred), __str.end()); 41105ffd83dbSDimitry Andric return __old_size - __str.size(); 41115ffd83dbSDimitry Andric} 41120b57cec5SDimitry Andric#endif 41130b57cec5SDimitry Andric 4114fe013be4SDimitry Andric#if _LIBCPP_STD_VER >= 14 41150b57cec5SDimitry Andric// Literal suffixes for basic_string [basic.string.literals] 4116e710425bSDimitry Andricinline namespace literals { 4117e710425bSDimitry Andricinline namespace string_literals { 4118e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<char> 4119e710425bSDimitry Andricoperator""s(const char* __str, size_t __len) { 41200b57cec5SDimitry Andric return basic_string<char>(__str, __len); 41210b57cec5SDimitry Andric} 41220b57cec5SDimitry Andric 4123349cc55cSDimitry Andric# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 4124e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<wchar_t> 4125e710425bSDimitry Andricoperator""s(const wchar_t* __str, size_t __len) { 41260b57cec5SDimitry Andric return basic_string<wchar_t>(__str, __len); 41270b57cec5SDimitry Andric} 4128349cc55cSDimitry Andric# endif 41290b57cec5SDimitry Andric 4130fe6060f1SDimitry Andric# ifndef _LIBCPP_HAS_NO_CHAR8_T 4131e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI constexpr basic_string<char8_t> operator""s(const char8_t* __str, size_t __len) { 41320b57cec5SDimitry Andric return basic_string<char8_t>(__str, __len); 41330b57cec5SDimitry Andric} 41340b57cec5SDimitry Andric# endif 41350b57cec5SDimitry Andric 4136e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<char16_t> 4137e710425bSDimitry Andricoperator""s(const char16_t* __str, size_t __len) { 41380b57cec5SDimitry Andric return basic_string<char16_t>(__str, __len); 41390b57cec5SDimitry Andric} 41400b57cec5SDimitry Andric 4141e710425bSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<char32_t> 4142e710425bSDimitry Andricoperator""s(const char32_t* __str, size_t __len) { 41430b57cec5SDimitry Andric return basic_string<char32_t>(__str, __len); 41440b57cec5SDimitry Andric} 41450eae32dcSDimitry Andric} // namespace string_literals 41460eae32dcSDimitry Andric} // namespace literals 414781ad6265SDimitry Andric 4148fe013be4SDimitry Andric# if _LIBCPP_STD_VER >= 20 414981ad6265SDimitry Andrictemplate <> 415081ad6265SDimitry Andricinline constexpr bool __format::__enable_insertable<std::basic_string<char>> = true; 415181ad6265SDimitry Andric# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 415281ad6265SDimitry Andrictemplate <> 415381ad6265SDimitry Andricinline constexpr bool __format::__enable_insertable<std::basic_string<wchar_t>> = true; 415481ad6265SDimitry Andric# endif 415581ad6265SDimitry Andric# endif 415681ad6265SDimitry Andric 41570b57cec5SDimitry Andric#endif 41580b57cec5SDimitry Andric 41590b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 41600b57cec5SDimitry Andric 41610b57cec5SDimitry Andric_LIBCPP_POP_MACROS 41620b57cec5SDimitry Andric 4163bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 4164bdd1243dSDimitry Andric# include <algorithm> 4165bdd1243dSDimitry Andric# include <concepts> 4166fe013be4SDimitry Andric# include <cstdlib> 4167bdd1243dSDimitry Andric# include <iterator> 4168bdd1243dSDimitry Andric# include <new> 4169fe013be4SDimitry Andric# include <type_traits> 4170bdd1243dSDimitry Andric# include <typeinfo> 4171bdd1243dSDimitry Andric# include <utility> 4172bdd1243dSDimitry Andric#endif 4173bdd1243dSDimitry Andric 41740b57cec5SDimitry Andric#endif // _LIBCPP_STRING 4175