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