xref: /freebsd/contrib/llvm-project/libcxx/include/__cxx03/string (revision 700637cbb5e582861067a11aaca4d053546871d2)
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