xref: /openbsd-src/gnu/llvm/libcxx/include/string (revision 4bdff4bed0e3d54e55670334c7d0077db4170f86)
146035553Spatrick// -*- C++ -*-
2*4bdff4beSrobert//===----------------------------------------------------------------------===//
346035553Spatrick//
446035553Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
546035553Spatrick// See https://llvm.org/LICENSE.txt for license information.
646035553Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
746035553Spatrick//
846035553Spatrick//===----------------------------------------------------------------------===//
946035553Spatrick
1046035553Spatrick#ifndef _LIBCPP_STRING
1146035553Spatrick#define _LIBCPP_STRING
1246035553Spatrick
1346035553Spatrick/*
1446035553Spatrick    string synopsis
1546035553Spatrick
16*4bdff4beSrobert#include <compare>
17*4bdff4beSrobert#include <initializer_list>
18*4bdff4beSrobert
1946035553Spatricknamespace std
2046035553Spatrick{
2146035553Spatrick
2246035553Spatricktemplate <class stateT>
2346035553Spatrickclass fpos
2446035553Spatrick{
2546035553Spatrickprivate:
2646035553Spatrick    stateT st;
2746035553Spatrickpublic:
2846035553Spatrick    fpos(streamoff = streamoff());
2946035553Spatrick
3046035553Spatrick    operator streamoff() const;
3146035553Spatrick
3246035553Spatrick    stateT state() const;
3346035553Spatrick    void state(stateT);
3446035553Spatrick
3546035553Spatrick    fpos& operator+=(streamoff);
3646035553Spatrick    fpos  operator+ (streamoff) const;
3746035553Spatrick    fpos& operator-=(streamoff);
3846035553Spatrick    fpos  operator- (streamoff) const;
3946035553Spatrick};
4046035553Spatrick
4146035553Spatricktemplate <class stateT> streamoff operator-(const fpos<stateT>& x, const fpos<stateT>& y);
4246035553Spatrick
4346035553Spatricktemplate <class stateT> bool operator==(const fpos<stateT>& x, const fpos<stateT>& y);
4446035553Spatricktemplate <class stateT> bool operator!=(const fpos<stateT>& x, const fpos<stateT>& y);
4546035553Spatrick
4646035553Spatricktemplate <class charT>
4746035553Spatrickstruct char_traits
4846035553Spatrick{
49*4bdff4beSrobert    using char_type           = charT;
50*4bdff4beSrobert    using int_type            = ...;
51*4bdff4beSrobert    using off_type            = streamoff;
52*4bdff4beSrobert    using pos_type            = streampos;
53*4bdff4beSrobert    using state_type          = mbstate_t;
54*4bdff4beSrobert    using comparison_category = strong_ordering; // Since C++20 only for the specializations
55*4bdff4beSrobert                                                 // char, wchar_t, char8_t, char16_t, and char32_t.
5646035553Spatrick
5746035553Spatrick    static void assign(char_type& c1, const char_type& c2) noexcept;
5846035553Spatrick    static constexpr bool eq(char_type c1, char_type c2) noexcept;
5946035553Spatrick    static constexpr bool lt(char_type c1, char_type c2) noexcept;
6046035553Spatrick
6146035553Spatrick    static int              compare(const char_type* s1, const char_type* s2, size_t n);
6246035553Spatrick    static size_t           length(const char_type* s);
6346035553Spatrick    static const char_type* find(const char_type* s, size_t n, const char_type& a);
6446035553Spatrick    static char_type*       move(char_type* s1, const char_type* s2, size_t n);
6546035553Spatrick    static char_type*       copy(char_type* s1, const char_type* s2, size_t n);
6646035553Spatrick    static char_type*       assign(char_type* s, size_t n, char_type a);
6746035553Spatrick
6846035553Spatrick    static constexpr int_type  not_eof(int_type c) noexcept;
6946035553Spatrick    static constexpr char_type to_char_type(int_type c) noexcept;
7046035553Spatrick    static constexpr int_type  to_int_type(char_type c) noexcept;
7146035553Spatrick    static constexpr bool      eq_int_type(int_type c1, int_type c2) noexcept;
7246035553Spatrick    static constexpr int_type  eof() noexcept;
7346035553Spatrick};
7446035553Spatrick
7546035553Spatricktemplate <> struct char_traits<char>;
7646035553Spatricktemplate <> struct char_traits<wchar_t>;
7776d0caaeSpatricktemplate <> struct char_traits<char8_t>;  // C++20
7876d0caaeSpatricktemplate <> struct char_traits<char16_t>;
7976d0caaeSpatricktemplate <> struct char_traits<char32_t>;
8046035553Spatrick
8146035553Spatricktemplate<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
8246035553Spatrickclass basic_string
8346035553Spatrick{
8446035553Spatrickpublic:
8546035553Spatrick// types:
8646035553Spatrick    typedef traits traits_type;
8746035553Spatrick    typedef typename traits_type::char_type value_type;
8846035553Spatrick    typedef Allocator allocator_type;
8946035553Spatrick    typedef typename allocator_type::size_type size_type;
9046035553Spatrick    typedef typename allocator_type::difference_type difference_type;
9146035553Spatrick    typedef typename allocator_type::reference reference;
9246035553Spatrick    typedef typename allocator_type::const_reference const_reference;
9346035553Spatrick    typedef typename allocator_type::pointer pointer;
9446035553Spatrick    typedef typename allocator_type::const_pointer const_pointer;
9546035553Spatrick    typedef implementation-defined iterator;
9646035553Spatrick    typedef implementation-defined const_iterator;
9746035553Spatrick    typedef std::reverse_iterator<iterator> reverse_iterator;
9846035553Spatrick    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
9946035553Spatrick
10046035553Spatrick    static const size_type npos = -1;
10146035553Spatrick
10246035553Spatrick    basic_string()
103*4bdff4beSrobert        noexcept(is_nothrow_default_constructible<allocator_type>::value);                      // constexpr since C++20
104*4bdff4beSrobert    explicit basic_string(const allocator_type& a);                                             // constexpr since C++20
105*4bdff4beSrobert    basic_string(const basic_string& str);                                                      // constexpr since C++20
10646035553Spatrick    basic_string(basic_string&& str)
107*4bdff4beSrobert        noexcept(is_nothrow_move_constructible<allocator_type>::value);                         // constexpr since C++20
10846035553Spatrick    basic_string(const basic_string& str, size_type pos,
109*4bdff4beSrobert                 const allocator_type& a = allocator_type());                                   // constexpr since C++20
11046035553Spatrick    basic_string(const basic_string& str, size_type pos, size_type n,
111*4bdff4beSrobert                 const Allocator& a = Allocator());                                             // constexpr since C++20
112*4bdff4beSrobert    constexpr basic_string(
113*4bdff4beSrobert        basic_string&& str, size_type pos, const Allocator& a = Allocator());                   // since C++23
114*4bdff4beSrobert    constexpr basic_string(
115*4bdff4beSrobert        basic_string&& str, size_type pos, size_type n, const Allocator& a = Allocator());      // since C++23
11646035553Spatrick    template<class T>
117*4bdff4beSrobert        basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator()); // C++17, constexpr since C++20
11846035553Spatrick    template <class T>
119*4bdff4beSrobert        explicit basic_string(const T& t, const Allocator& a = Allocator());                    // C++17, constexpr since C++20
120*4bdff4beSrobert    basic_string(const value_type* s, const allocator_type& a = allocator_type());              // constexpr since C++20
121*4bdff4beSrobert    basic_string(const value_type* s, size_type n, const allocator_type& a = allocator_type()); // constexpr since C++20
12276d0caaeSpatrick    basic_string(nullptr_t) = delete; // C++2b
123*4bdff4beSrobert    basic_string(size_type n, value_type c, const allocator_type& a = allocator_type());        // constexpr since C++20
12446035553Spatrick    template<class InputIterator>
12546035553Spatrick        basic_string(InputIterator begin, InputIterator end,
126*4bdff4beSrobert                     const allocator_type& a = allocator_type());                               // constexpr since C++20
127*4bdff4beSrobert    basic_string(initializer_list<value_type>, const Allocator& = Allocator());                 // constexpr since C++20
128*4bdff4beSrobert    basic_string(const basic_string&, const Allocator&);                                        // constexpr since C++20
129*4bdff4beSrobert    basic_string(basic_string&&, const Allocator&);                                             // constexpr since C++20
13046035553Spatrick
131*4bdff4beSrobert    ~basic_string();                                                                            // constexpr since C++20
13246035553Spatrick
133*4bdff4beSrobert    operator basic_string_view<charT, traits>() const noexcept;                                 // constexpr since C++20
13446035553Spatrick
135*4bdff4beSrobert    basic_string& operator=(const basic_string& str);                                           // constexpr since C++20
13646035553Spatrick    template <class T>
137*4bdff4beSrobert        basic_string& operator=(const T& t);                                                    // C++17, constexpr since C++20
13846035553Spatrick    basic_string& operator=(basic_string&& str)
13946035553Spatrick        noexcept(
14046035553Spatrick             allocator_type::propagate_on_container_move_assignment::value ||
141*4bdff4beSrobert             allocator_type::is_always_equal::value );                                          // C++17, constexpr since C++20
142*4bdff4beSrobert    basic_string& operator=(const value_type* s);                                               // constexpr since C++20
14376d0caaeSpatrick    basic_string& operator=(nullptr_t) = delete; // C++2b
144*4bdff4beSrobert    basic_string& operator=(value_type c);                                                      // constexpr since C++20
145*4bdff4beSrobert    basic_string& operator=(initializer_list<value_type>);                                      // constexpr since C++20
14646035553Spatrick
147*4bdff4beSrobert    iterator       begin() noexcept;                                                            // constexpr since C++20
148*4bdff4beSrobert    const_iterator begin() const noexcept;                                                      // constexpr since C++20
149*4bdff4beSrobert    iterator       end() noexcept;                                                              // constexpr since C++20
150*4bdff4beSrobert    const_iterator end() const noexcept;                                                        // constexpr since C++20
15146035553Spatrick
152*4bdff4beSrobert    reverse_iterator       rbegin() noexcept;                                                   // constexpr since C++20
153*4bdff4beSrobert    const_reverse_iterator rbegin() const noexcept;                                             // constexpr since C++20
154*4bdff4beSrobert    reverse_iterator       rend() noexcept;                                                     // constexpr since C++20
155*4bdff4beSrobert    const_reverse_iterator rend() const noexcept;                                               // constexpr since C++20
15646035553Spatrick
157*4bdff4beSrobert    const_iterator         cbegin() const noexcept;                                             // constexpr since C++20
158*4bdff4beSrobert    const_iterator         cend() const noexcept;                                               // constexpr since C++20
159*4bdff4beSrobert    const_reverse_iterator crbegin() const noexcept;                                            // constexpr since C++20
160*4bdff4beSrobert    const_reverse_iterator crend() const noexcept;                                              // constexpr since C++20
16146035553Spatrick
162*4bdff4beSrobert    size_type size() const noexcept;                                                            // constexpr since C++20
163*4bdff4beSrobert    size_type length() const noexcept;                                                          // constexpr since C++20
164*4bdff4beSrobert    size_type max_size() const noexcept;                                                        // constexpr since C++20
165*4bdff4beSrobert    size_type capacity() const noexcept;                                                        // constexpr since C++20
16646035553Spatrick
167*4bdff4beSrobert    void resize(size_type n, value_type c);                                                     // constexpr since C++20
168*4bdff4beSrobert    void resize(size_type n);                                                                   // constexpr since C++20
16946035553Spatrick
170*4bdff4beSrobert    template<class Operation>
171*4bdff4beSrobert    constexpr void resize_and_overwrite(size_type n, Operation op); // since C++23
172*4bdff4beSrobert
173*4bdff4beSrobert    void reserve(size_type res_arg);                                                            // constexpr since C++20
17476d0caaeSpatrick    void reserve(); // deprecated in C++20
175*4bdff4beSrobert    void shrink_to_fit();                                                                       // constexpr since C++20
176*4bdff4beSrobert    void clear() noexcept;                                                                      // constexpr since C++20
177*4bdff4beSrobert    bool empty() const noexcept;                                                                // constexpr since C++20
17846035553Spatrick
179*4bdff4beSrobert    const_reference operator[](size_type pos) const;                                            // constexpr since C++20
180*4bdff4beSrobert    reference       operator[](size_type pos);                                                  // constexpr since C++20
18146035553Spatrick
182*4bdff4beSrobert    const_reference at(size_type n) const;                                                      // constexpr since C++20
183*4bdff4beSrobert    reference       at(size_type n);                                                            // constexpr since C++20
18446035553Spatrick
185*4bdff4beSrobert    basic_string& operator+=(const basic_string& str);                                          // constexpr since C++20
18646035553Spatrick    template <class T>
187*4bdff4beSrobert        basic_string& operator+=(const T& t);                                                   // C++17, constexpr since C++20
188*4bdff4beSrobert    basic_string& operator+=(const value_type* s);                                              // constexpr since C++20
189*4bdff4beSrobert    basic_string& operator+=(value_type c);                                                     // constexpr since C++20
190*4bdff4beSrobert    basic_string& operator+=(initializer_list<value_type>);                                     // constexpr since C++20
19146035553Spatrick
192*4bdff4beSrobert    basic_string& append(const basic_string& str);                                              // constexpr since C++20
19346035553Spatrick    template <class T>
194*4bdff4beSrobert        basic_string& append(const T& t);                                                       // C++17, constexpr since C++20
195*4bdff4beSrobert    basic_string& append(const basic_string& str, size_type pos, size_type n=npos);             // C++14, constexpr since C++20
19646035553Spatrick    template <class T>
197*4bdff4beSrobert        basic_string& append(const T& t, size_type pos, size_type n=npos);                      // C++17, constexpr since C++20
198*4bdff4beSrobert    basic_string& append(const value_type* s, size_type n);                                     // constexpr since C++20
199*4bdff4beSrobert    basic_string& append(const value_type* s);                                                  // constexpr since C++20
200*4bdff4beSrobert    basic_string& append(size_type n, value_type c);                                            // constexpr since C++20
20146035553Spatrick    template<class InputIterator>
202*4bdff4beSrobert        basic_string& append(InputIterator first, InputIterator last);                          // constexpr since C++20
203*4bdff4beSrobert    basic_string& append(initializer_list<value_type>);                                         // constexpr since C++20
20446035553Spatrick
205*4bdff4beSrobert    void push_back(value_type c);                                                               // constexpr since C++20
206*4bdff4beSrobert    void pop_back();                                                                            // constexpr since C++20
207*4bdff4beSrobert    reference       front();                                                                    // constexpr since C++20
208*4bdff4beSrobert    const_reference front() const;                                                              // constexpr since C++20
209*4bdff4beSrobert    reference       back();                                                                     // constexpr since C++20
210*4bdff4beSrobert    const_reference back() const;                                                               // constexpr since C++20
21146035553Spatrick
212*4bdff4beSrobert    basic_string& assign(const basic_string& str);                                              // constexpr since C++20
21346035553Spatrick    template <class T>
214*4bdff4beSrobert        basic_string& assign(const T& t);                                                       // C++17, constexpr since C++20
215*4bdff4beSrobert    basic_string& assign(basic_string&& str);                                                   // constexpr since C++20
216*4bdff4beSrobert    basic_string& assign(const basic_string& str, size_type pos, size_type n=npos);             // C++14, constexpr since C++20
21746035553Spatrick    template <class T>
218*4bdff4beSrobert        basic_string& assign(const T& t, size_type pos, size_type n=npos);                      // C++17, constexpr since C++20
219*4bdff4beSrobert    basic_string& assign(const value_type* s, size_type n);                                     // constexpr since C++20
220*4bdff4beSrobert    basic_string& assign(const value_type* s);                                                  // constexpr since C++20
221*4bdff4beSrobert    basic_string& assign(size_type n, value_type c);                                            // constexpr since C++20
22246035553Spatrick    template<class InputIterator>
223*4bdff4beSrobert        basic_string& assign(InputIterator first, InputIterator last);                          // constexpr since C++20
224*4bdff4beSrobert    basic_string& assign(initializer_list<value_type>);                                         // constexpr since C++20
22546035553Spatrick
226*4bdff4beSrobert    basic_string& insert(size_type pos1, const basic_string& str);                              // constexpr since C++20
22746035553Spatrick    template <class T>
228*4bdff4beSrobert        basic_string& insert(size_type pos1, const T& t);                                       // constexpr since C++20
22946035553Spatrick    basic_string& insert(size_type pos1, const basic_string& str,
230*4bdff4beSrobert                         size_type pos2, size_type n);                                          // constexpr since C++20
23146035553Spatrick    template <class T>
232*4bdff4beSrobert        basic_string& insert(size_type pos1, const T& t, size_type pos2, size_type n);          // C++17, constexpr since C++20
233*4bdff4beSrobert    basic_string& insert(size_type pos, const value_type* s, size_type n=npos);                 // C++14, constexpr since C++20
234*4bdff4beSrobert    basic_string& insert(size_type pos, const value_type* s);                                   // constexpr since C++20
235*4bdff4beSrobert    basic_string& insert(size_type pos, size_type n, value_type c);                             // constexpr since C++20
236*4bdff4beSrobert    iterator      insert(const_iterator p, value_type c);                                       // constexpr since C++20
237*4bdff4beSrobert    iterator      insert(const_iterator p, size_type n, value_type c);                          // constexpr since C++20
23846035553Spatrick    template<class InputIterator>
239*4bdff4beSrobert        iterator insert(const_iterator p, InputIterator first, InputIterator last);             // constexpr since C++20
240*4bdff4beSrobert    iterator      insert(const_iterator p, initializer_list<value_type>);                       // constexpr since C++20
24146035553Spatrick
242*4bdff4beSrobert    basic_string& erase(size_type pos = 0, size_type n = npos);                                 // constexpr since C++20
243*4bdff4beSrobert    iterator      erase(const_iterator position);                                               // constexpr since C++20
244*4bdff4beSrobert    iterator      erase(const_iterator first, const_iterator last);                             // constexpr since C++20
24546035553Spatrick
246*4bdff4beSrobert    basic_string& replace(size_type pos1, size_type n1, const basic_string& str);               // constexpr since C++20
24746035553Spatrick    template <class T>
248*4bdff4beSrobert    basic_string& replace(size_type pos1, size_type n1, const T& t);                            // C++17, constexpr since C++20
24946035553Spatrick    basic_string& replace(size_type pos1, size_type n1, const basic_string& str,
250*4bdff4beSrobert                          size_type pos2, size_type n2=npos);                                   // C++14, constexpr since C++20
25146035553Spatrick    template <class T>
25246035553Spatrick        basic_string& replace(size_type pos1, size_type n1, const T& t,
253*4bdff4beSrobert                              size_type pos2, size_type n);                                     // C++17, constexpr since C++20
254*4bdff4beSrobert    basic_string& replace(size_type pos, size_type n1, const value_type* s, size_type n2);      // constexpr since C++20
255*4bdff4beSrobert    basic_string& replace(size_type pos, size_type n1, const value_type* s);                    // constexpr since C++20
256*4bdff4beSrobert    basic_string& replace(size_type pos, size_type n1, size_type n2, value_type c);             // constexpr since C++20
257*4bdff4beSrobert    basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str);       // constexpr since C++20
25846035553Spatrick    template <class T>
259*4bdff4beSrobert        basic_string& replace(const_iterator i1, const_iterator i2, const T& t);                // C++17, constexpr since C++20
260*4bdff4beSrobert    basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s, size_type n); // constexpr since C++20
261*4bdff4beSrobert    basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s);           // constexpr since C++20
262*4bdff4beSrobert    basic_string& replace(const_iterator i1, const_iterator i2, size_type n, value_type c);     // constexpr since C++20
26346035553Spatrick    template<class InputIterator>
264*4bdff4beSrobert        basic_string& replace(const_iterator i1, const_iterator i2, InputIterator j1, InputIterator j2); // constexpr since C++20
265*4bdff4beSrobert    basic_string& replace(const_iterator i1, const_iterator i2, initializer_list<value_type>);  // constexpr since C++20
26646035553Spatrick
267*4bdff4beSrobert    size_type copy(value_type* s, size_type n, size_type pos = 0) const;                        // constexpr since C++20
268*4bdff4beSrobert    basic_string substr(size_type pos = 0, size_type n = npos) const;                           // constexpr in C++20, removed in C++23
269*4bdff4beSrobert    basic_string substr(size_type pos = 0, size_type n = npos) const&;                          // since C++23
270*4bdff4beSrobert    constexpr basic_string substr(size_type pos = 0, size_type n = npos) &&;                    // since C++23
27146035553Spatrick    void swap(basic_string& str)
27246035553Spatrick        noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
273*4bdff4beSrobert                 allocator_traits<allocator_type>::is_always_equal::value);                     // C++17, constexpr since C++20
27446035553Spatrick
275*4bdff4beSrobert    const value_type* c_str() const noexcept;                                                   // constexpr since C++20
276*4bdff4beSrobert    const value_type* data() const noexcept;                                                    // constexpr since C++20
277*4bdff4beSrobert          value_type* data()       noexcept;                                                    // C++17, constexpr since C++20
27846035553Spatrick
279*4bdff4beSrobert    allocator_type get_allocator() const noexcept;                                              // constexpr since C++20
28046035553Spatrick
281*4bdff4beSrobert    size_type find(const basic_string& str, size_type pos = 0) const noexcept;                  // constexpr since C++20
28246035553Spatrick    template <class T>
283*4bdff4beSrobert        size_type find(const T& t, size_type pos = 0) const noexcept;                           // C++17, noexcept as an extension, constexpr since C++20
284*4bdff4beSrobert    size_type find(const value_type* s, size_type pos, size_type n) const noexcept;             // constexpr since C++20
285*4bdff4beSrobert    size_type find(const value_type* s, size_type pos = 0) const noexcept;                      // constexpr since C++20
286*4bdff4beSrobert    size_type find(value_type c, size_type pos = 0) const noexcept;                             // constexpr since C++20
28746035553Spatrick
288*4bdff4beSrobert    size_type rfind(const basic_string& str, size_type pos = npos) const noexcept;              // constexpr since C++20
28946035553Spatrick    template <class T>
290*4bdff4beSrobert        size_type rfind(const T& t, size_type pos = npos) const noexcept;                       // C++17, noexcept as an extension, constexpr since C++20
291*4bdff4beSrobert    size_type rfind(const value_type* s, size_type pos, size_type n) const noexcept;            // constexpr since C++20
292*4bdff4beSrobert    size_type rfind(const value_type* s, size_type pos = npos) const noexcept;                  // constexpr since C++20
293*4bdff4beSrobert    size_type rfind(value_type c, size_type pos = npos) const noexcept;                         // constexpr since C++20
29446035553Spatrick
295*4bdff4beSrobert    size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept;         // constexpr since C++20
29646035553Spatrick    template <class T>
297*4bdff4beSrobert        size_type find_first_of(const T& t, size_type pos = 0) const noexcept;                  // C++17, noexcept as an extension, constexpr since C++20
298*4bdff4beSrobert    size_type find_first_of(const value_type* s, size_type pos, size_type n) const noexcept;    // constexpr since C++20
299*4bdff4beSrobert    size_type find_first_of(const value_type* s, size_type pos = 0) const noexcept;             // constexpr since C++20
300*4bdff4beSrobert    size_type find_first_of(value_type c, size_type pos = 0) const noexcept;                    // constexpr since C++20
30146035553Spatrick
302*4bdff4beSrobert    size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept;       // constexpr since C++20
30346035553Spatrick    template <class T>
304*4bdff4beSrobert        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
305*4bdff4beSrobert    size_type find_last_of(const value_type* s, size_type pos, size_type n) const noexcept;     // constexpr since C++20
306*4bdff4beSrobert    size_type find_last_of(const value_type* s, size_type pos = npos) const noexcept;           // constexpr since C++20
307*4bdff4beSrobert    size_type find_last_of(value_type c, size_type pos = npos) const noexcept;                  // constexpr since C++20
30846035553Spatrick
309*4bdff4beSrobert    size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept;     // constexpr since C++20
31046035553Spatrick    template <class T>
311*4bdff4beSrobert        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
312*4bdff4beSrobert    size_type find_first_not_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20
313*4bdff4beSrobert    size_type find_first_not_of(const value_type* s, size_type pos = 0) const noexcept;         // constexpr since C++20
314*4bdff4beSrobert    size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept;                // constexpr since C++20
31546035553Spatrick
316*4bdff4beSrobert    size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept;   // constexpr since C++20
31746035553Spatrick    template <class T>
318*4bdff4beSrobert        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
319*4bdff4beSrobert    size_type find_last_not_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20
320*4bdff4beSrobert    size_type find_last_not_of(const value_type* s, size_type pos = npos) const noexcept;       // constexpr since C++20
321*4bdff4beSrobert    size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept;              // constexpr since C++20
32246035553Spatrick
323*4bdff4beSrobert    int compare(const basic_string& str) const noexcept;                                        // constexpr since C++20
32446035553Spatrick    template <class T>
325*4bdff4beSrobert        int compare(const T& t) const noexcept;                                                 // C++17, noexcept as an extension, constexpr since C++20
326*4bdff4beSrobert    int compare(size_type pos1, size_type n1, const basic_string& str) const;                   // constexpr since C++20
32746035553Spatrick    template <class T>
328*4bdff4beSrobert        int compare(size_type pos1, size_type n1, const T& t) const;                            // C++17, constexpr since C++20
32946035553Spatrick    int compare(size_type pos1, size_type n1, const basic_string& str,
330*4bdff4beSrobert                size_type pos2, size_type n2=npos) const;                                       // C++14, constexpr since C++20
33146035553Spatrick    template <class T>
33246035553Spatrick        int compare(size_type pos1, size_type n1, const T& t,
333*4bdff4beSrobert                    size_type pos2, size_type n2=npos) const;                                   // C++17, constexpr since C++20
334*4bdff4beSrobert    int compare(const value_type* s) const noexcept;                                            // constexpr since C++20
335*4bdff4beSrobert    int compare(size_type pos1, size_type n1, const value_type* s) const;                       // constexpr since C++20
336*4bdff4beSrobert    int compare(size_type pos1, size_type n1, const value_type* s, size_type n2) const;         // constexpr since C++20
33746035553Spatrick
338*4bdff4beSrobert    constexpr bool starts_with(basic_string_view<charT, traits> sv) const noexcept;             // C++20
339*4bdff4beSrobert    constexpr bool starts_with(charT c) const noexcept;                                         // C++20
340*4bdff4beSrobert    constexpr bool starts_with(const charT* s) const;                                           // C++20
341*4bdff4beSrobert    constexpr bool ends_with(basic_string_view<charT, traits> sv) const noexcept;               // C++20
342*4bdff4beSrobert    constexpr bool ends_with(charT c) const noexcept;                                           // C++20
343*4bdff4beSrobert    constexpr bool ends_with(const charT* s) const;                                             // C++20
34476d0caaeSpatrick
34576d0caaeSpatrick    constexpr bool contains(basic_string_view<charT, traits> sv) const noexcept;                // C++2b
34676d0caaeSpatrick    constexpr bool contains(charT c) const noexcept;                                            // C++2b
34776d0caaeSpatrick    constexpr bool contains(const charT* s) const;                                              // C++2b
34846035553Spatrick};
34946035553Spatrick
35046035553Spatricktemplate<class InputIterator,
35146035553Spatrick         class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
35246035553Spatrickbasic_string(InputIterator, InputIterator, Allocator = Allocator())
35346035553Spatrick   -> basic_string<typename iterator_traits<InputIterator>::value_type,
35446035553Spatrick                  char_traits<typename iterator_traits<InputIterator>::value_type>,
35546035553Spatrick                  Allocator>;   // C++17
35646035553Spatrick
35746035553Spatricktemplate<class charT, class traits, class Allocator>
35846035553Spatrickbasic_string<charT, traits, Allocator>
35946035553Spatrickoperator+(const basic_string<charT, traits, Allocator>& lhs,
360*4bdff4beSrobert          const basic_string<charT, traits, Allocator>& rhs);                                   // constexpr since C++20
36146035553Spatrick
36246035553Spatricktemplate<class charT, class traits, class Allocator>
36346035553Spatrickbasic_string<charT, traits, Allocator>
364*4bdff4beSrobertoperator+(const charT* lhs , const basic_string<charT,traits,Allocator>&rhs);                   // constexpr since C++20
36546035553Spatrick
36646035553Spatricktemplate<class charT, class traits, class Allocator>
36746035553Spatrickbasic_string<charT, traits, Allocator>
368*4bdff4beSrobertoperator+(charT lhs, const basic_string<charT,traits,Allocator>& rhs);                          // constexpr since C++20
36946035553Spatrick
37046035553Spatricktemplate<class charT, class traits, class Allocator>
37146035553Spatrickbasic_string<charT, traits, Allocator>
372*4bdff4beSrobertoperator+(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs);                 // constexpr since C++20
37346035553Spatrick
37446035553Spatricktemplate<class charT, class traits, class Allocator>
37546035553Spatrickbasic_string<charT, traits, Allocator>
376*4bdff4beSrobertoperator+(const basic_string<charT, traits, Allocator>& lhs, charT rhs);                        // constexpr since C++20
37746035553Spatrick
37846035553Spatricktemplate<class charT, class traits, class Allocator>
37946035553Spatrickbool operator==(const basic_string<charT, traits, Allocator>& lhs,
380*4bdff4beSrobert                const basic_string<charT, traits, Allocator>& rhs) noexcept;                    // constexpr since C++20
38146035553Spatrick
38246035553Spatricktemplate<class charT, class traits, class Allocator>
383*4bdff4beSrobertbool operator==(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;  // removed in C++20
38446035553Spatrick
38546035553Spatricktemplate<class charT, class traits, class Allocator>
386*4bdff4beSrobertbool operator==(const basic_string<charT,traits,Allocator>& lhs, const charT* rhs) noexcept;    // constexpr since C++20
38746035553Spatrick
38846035553Spatricktemplate<class charT, class traits, class Allocator>
38946035553Spatrickbool operator!=(const basic_string<charT,traits,Allocator>& lhs,
390*4bdff4beSrobert                const basic_string<charT, traits, Allocator>& rhs) noexcept;                    // removed in C++20
39146035553Spatrick
39246035553Spatricktemplate<class charT, class traits, class Allocator>
393*4bdff4beSrobertbool operator!=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;  // removed in C++20
39446035553Spatrick
39546035553Spatricktemplate<class charT, class traits, class Allocator>
396*4bdff4beSrobertbool operator!=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;  // removed in C++20
39746035553Spatrick
39846035553Spatricktemplate<class charT, class traits, class Allocator>
39946035553Spatrickbool operator< (const basic_string<charT, traits, Allocator>& lhs,
400*4bdff4beSrobert                const basic_string<charT, traits, Allocator>& rhs) noexcept;                    // removed in C++20
40146035553Spatrick
40246035553Spatricktemplate<class charT, class traits, class Allocator>
403*4bdff4beSrobertbool operator< (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;  // removed in C++20
40446035553Spatrick
40546035553Spatricktemplate<class charT, class traits, class Allocator>
406*4bdff4beSrobertbool operator< (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;  // removed in C++20
40746035553Spatrick
40846035553Spatricktemplate<class charT, class traits, class Allocator>
40946035553Spatrickbool operator> (const basic_string<charT, traits, Allocator>& lhs,
410*4bdff4beSrobert                const basic_string<charT, traits, Allocator>& rhs) noexcept;                    // removed in C++20
41146035553Spatrick
41246035553Spatricktemplate<class charT, class traits, class Allocator>
413*4bdff4beSrobertbool operator> (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;  // removed in C++20
41446035553Spatrick
41546035553Spatricktemplate<class charT, class traits, class Allocator>
416*4bdff4beSrobertbool operator> (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;  // removed in C++20
41746035553Spatrick
41846035553Spatricktemplate<class charT, class traits, class Allocator>
41946035553Spatrickbool operator<=(const basic_string<charT, traits, Allocator>& lhs,
420*4bdff4beSrobert                const basic_string<charT, traits, Allocator>& rhs) noexcept;                    // removed in C++20
42146035553Spatrick
42246035553Spatricktemplate<class charT, class traits, class Allocator>
423*4bdff4beSrobertbool operator<=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;  // removed in C++20
42446035553Spatrick
42546035553Spatricktemplate<class charT, class traits, class Allocator>
426*4bdff4beSrobertbool operator<=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;  // removed in C++20
42746035553Spatrick
42846035553Spatricktemplate<class charT, class traits, class Allocator>
42946035553Spatrickbool operator>=(const basic_string<charT, traits, Allocator>& lhs,
430*4bdff4beSrobert                const basic_string<charT, traits, Allocator>& rhs) noexcept;                    // removed in C++20
431*4bdff4beSrobert
432*4bdff4beSroberttemplate<class charT, class traits, class Allocator>
433*4bdff4beSrobertbool operator>=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;  // removed in C++20
434*4bdff4beSrobert
435*4bdff4beSroberttemplate<class charT, class traits, class Allocator>
436*4bdff4beSrobertbool operator>=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;  // removed in C++20
437*4bdff4beSrobert
438*4bdff4beSroberttemplate<class charT, class traits, class Allocator>                                            // since C++20
439*4bdff4beSrobertconstexpr see below operator<=>(const basic_string<charT, traits, Allocator>& lhs,
44046035553Spatrick                                const basic_string<charT, traits, Allocator>& rhs) noexcept;
44146035553Spatrick
442*4bdff4beSroberttemplate<class charT, class traits, class Allocator>                                            // since C++20
443*4bdff4beSrobertconstexpr see below operator<=>(const basic_string<charT, traits, Allocator>& lhs,
444*4bdff4beSrobert                                const charT* rhs) noexcept;
44546035553Spatrick
44646035553Spatricktemplate<class charT, class traits, class Allocator>
44746035553Spatrickvoid swap(basic_string<charT, traits, Allocator>& lhs,
44846035553Spatrick          basic_string<charT, traits, Allocator>& rhs)
449*4bdff4beSrobert            noexcept(noexcept(lhs.swap(rhs)));                                                  // constexpr since C++20
45046035553Spatrick
45146035553Spatricktemplate<class charT, class traits, class Allocator>
45246035553Spatrickbasic_istream<charT, traits>&
45346035553Spatrickoperator>>(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str);
45446035553Spatrick
45546035553Spatricktemplate<class charT, class traits, class Allocator>
45646035553Spatrickbasic_ostream<charT, traits>&
45746035553Spatrickoperator<<(basic_ostream<charT, traits>& os, const basic_string<charT, traits, Allocator>& str);
45846035553Spatrick
45946035553Spatricktemplate<class charT, class traits, class Allocator>
46046035553Spatrickbasic_istream<charT, traits>&
46146035553Spatrickgetline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str,
46246035553Spatrick        charT delim);
46346035553Spatrick
46446035553Spatricktemplate<class charT, class traits, class Allocator>
46546035553Spatrickbasic_istream<charT, traits>&
46646035553Spatrickgetline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str);
46746035553Spatrick
46846035553Spatricktemplate<class charT, class traits, class Allocator, class U>
469037e7968Spatricktypename basic_string<charT, traits, Allocator>::size_type
470037e7968Spatrickerase(basic_string<charT, traits, Allocator>& c, const U& value);    // C++20
47146035553Spatricktemplate<class charT, class traits, class Allocator, class Predicate>
472037e7968Spatricktypename basic_string<charT, traits, Allocator>::size_type
473037e7968Spatrickerase_if(basic_string<charT, traits, Allocator>& c, Predicate pred); // C++20
47446035553Spatrick
47546035553Spatricktypedef basic_string<char>    string;
47646035553Spatricktypedef basic_string<wchar_t> wstring;
47776d0caaeSpatricktypedef basic_string<char8_t> u8string; // C++20
47846035553Spatricktypedef basic_string<char16_t> u16string;
47946035553Spatricktypedef basic_string<char32_t> u32string;
48046035553Spatrick
48176d0caaeSpatrickint                stoi  (const string& str, size_t* idx = nullptr, int base = 10);
48276d0caaeSpatricklong               stol  (const string& str, size_t* idx = nullptr, int base = 10);
48376d0caaeSpatrickunsigned long      stoul (const string& str, size_t* idx = nullptr, int base = 10);
48476d0caaeSpatricklong long          stoll (const string& str, size_t* idx = nullptr, int base = 10);
48576d0caaeSpatrickunsigned long long stoull(const string& str, size_t* idx = nullptr, int base = 10);
48646035553Spatrick
48776d0caaeSpatrickfloat       stof (const string& str, size_t* idx = nullptr);
48876d0caaeSpatrickdouble      stod (const string& str, size_t* idx = nullptr);
48976d0caaeSpatricklong double stold(const string& str, size_t* idx = nullptr);
49046035553Spatrick
49146035553Spatrickstring to_string(int val);
49246035553Spatrickstring to_string(unsigned val);
49346035553Spatrickstring to_string(long val);
49446035553Spatrickstring to_string(unsigned long val);
49546035553Spatrickstring to_string(long long val);
49646035553Spatrickstring to_string(unsigned long long val);
49746035553Spatrickstring to_string(float val);
49846035553Spatrickstring to_string(double val);
49946035553Spatrickstring to_string(long double val);
50046035553Spatrick
50176d0caaeSpatrickint                stoi  (const wstring& str, size_t* idx = nullptr, int base = 10);
50276d0caaeSpatricklong               stol  (const wstring& str, size_t* idx = nullptr, int base = 10);
50376d0caaeSpatrickunsigned long      stoul (const wstring& str, size_t* idx = nullptr, int base = 10);
50476d0caaeSpatricklong long          stoll (const wstring& str, size_t* idx = nullptr, int base = 10);
50576d0caaeSpatrickunsigned long long stoull(const wstring& str, size_t* idx = nullptr, int base = 10);
50646035553Spatrick
50776d0caaeSpatrickfloat       stof (const wstring& str, size_t* idx = nullptr);
50876d0caaeSpatrickdouble      stod (const wstring& str, size_t* idx = nullptr);
50976d0caaeSpatricklong double stold(const wstring& str, size_t* idx = nullptr);
51046035553Spatrick
51146035553Spatrickwstring to_wstring(int val);
51246035553Spatrickwstring to_wstring(unsigned val);
51346035553Spatrickwstring to_wstring(long val);
51446035553Spatrickwstring to_wstring(unsigned long val);
51546035553Spatrickwstring to_wstring(long long val);
51646035553Spatrickwstring to_wstring(unsigned long long val);
51746035553Spatrickwstring to_wstring(float val);
51846035553Spatrickwstring to_wstring(double val);
51946035553Spatrickwstring to_wstring(long double val);
52046035553Spatrick
52146035553Spatricktemplate <> struct hash<string>;
52276d0caaeSpatricktemplate <> struct hash<u8string>; // C++20
52346035553Spatricktemplate <> struct hash<u16string>;
52446035553Spatricktemplate <> struct hash<u32string>;
52546035553Spatricktemplate <> struct hash<wstring>;
52646035553Spatrick
527*4bdff4beSrobertbasic_string<char>     operator "" s( const char *str,     size_t len );           // C++14, constexpr since C++20
528*4bdff4beSrobertbasic_string<wchar_t>  operator "" s( const wchar_t *str,  size_t len );           // C++14, constexpr since C++20
529*4bdff4beSrobertconstexpr basic_string<char8_t>  operator "" s( const char8_t *str,  size_t len ); // C++20
530*4bdff4beSrobertbasic_string<char16_t> operator "" s( const char16_t *str, size_t len );           // C++14, constexpr since C++20
531*4bdff4beSrobertbasic_string<char32_t> operator "" s( const char32_t *str, size_t len );           // C++14, constexpr since C++20
53246035553Spatrick
53346035553Spatrick}  // std
53446035553Spatrick
53546035553Spatrick*/
53646035553Spatrick
537*4bdff4beSrobert#include <__algorithm/max.h>
538*4bdff4beSrobert#include <__algorithm/min.h>
539*4bdff4beSrobert#include <__algorithm/remove.h>
540*4bdff4beSrobert#include <__algorithm/remove_if.h>
541*4bdff4beSrobert#include <__assert> // all public C++ headers provide the assertion handler
54246035553Spatrick#include <__config>
54376d0caaeSpatrick#include <__debug>
544*4bdff4beSrobert#include <__format/enable_insertable.h>
545*4bdff4beSrobert#include <__functional/hash.h>
546*4bdff4beSrobert#include <__functional/unary_function.h>
547*4bdff4beSrobert#include <__fwd/string.h>
548*4bdff4beSrobert#include <__ios/fpos.h>
549*4bdff4beSrobert#include <__iterator/distance.h>
550*4bdff4beSrobert#include <__iterator/iterator_traits.h>
551*4bdff4beSrobert#include <__iterator/reverse_iterator.h>
55276d0caaeSpatrick#include <__iterator/wrap_iter.h>
553*4bdff4beSrobert#include <__memory/allocate_at_least.h>
554*4bdff4beSrobert#include <__memory/allocator.h>
555*4bdff4beSrobert#include <__memory/allocator_traits.h>
556*4bdff4beSrobert#include <__memory/compressed_pair.h>
557*4bdff4beSrobert#include <__memory/construct_at.h>
558*4bdff4beSrobert#include <__memory/pointer_traits.h>
559*4bdff4beSrobert#include <__memory/swap_allocator.h>
560*4bdff4beSrobert#include <__memory_resource/polymorphic_allocator.h>
561*4bdff4beSrobert#include <__string/char_traits.h>
562*4bdff4beSrobert#include <__string/extern_template_lists.h>
563*4bdff4beSrobert#include <__type_traits/is_allocator.h>
564*4bdff4beSrobert#include <__type_traits/noexcept_move_assign_container.h>
565*4bdff4beSrobert#include <__utility/auto_cast.h>
566*4bdff4beSrobert#include <__utility/move.h>
567*4bdff4beSrobert#include <__utility/swap.h>
568*4bdff4beSrobert#include <__utility/unreachable.h>
569*4bdff4beSrobert#include <climits>
570*4bdff4beSrobert#include <cstdint>
57176d0caaeSpatrick#include <cstdio>  // EOF
57276d0caaeSpatrick#include <cstdlib>
57376d0caaeSpatrick#include <cstring>
574*4bdff4beSrobert#include <limits>
57546035553Spatrick#include <stdexcept>
57676d0caaeSpatrick#include <string_view>
57746035553Spatrick#include <type_traits>
57846035553Spatrick#include <version>
57976d0caaeSpatrick
580*4bdff4beSrobert#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
581*4bdff4beSrobert#  include <cwchar>
58246035553Spatrick#endif
58346035553Spatrick
584*4bdff4beSrobert// standard-mandated includes
585*4bdff4beSrobert
586*4bdff4beSrobert// [iterator.range]
587*4bdff4beSrobert#include <__iterator/access.h>
588*4bdff4beSrobert#include <__iterator/data.h>
589*4bdff4beSrobert#include <__iterator/empty.h>
590*4bdff4beSrobert#include <__iterator/reverse_access.h>
591*4bdff4beSrobert#include <__iterator/size.h>
592*4bdff4beSrobert
593*4bdff4beSrobert// [string.syn]
594*4bdff4beSrobert#include <compare>
595*4bdff4beSrobert#include <initializer_list>
596*4bdff4beSrobert
59746035553Spatrick#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
59846035553Spatrick#  pragma GCC system_header
59946035553Spatrick#endif
60046035553Spatrick
60146035553Spatrick_LIBCPP_PUSH_MACROS
60246035553Spatrick#include <__undef_macros>
60346035553Spatrick
60446035553Spatrick
60546035553Spatrick_LIBCPP_BEGIN_NAMESPACE_STD
60646035553Spatrick
60746035553Spatrick// basic_string
60846035553Spatrick
60946035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
61046035553Spatrickbasic_string<_CharT, _Traits, _Allocator>
611*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
61246035553Spatrickoperator+(const basic_string<_CharT, _Traits, _Allocator>& __x,
61346035553Spatrick          const basic_string<_CharT, _Traits, _Allocator>& __y);
61446035553Spatrick
61546035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
616*4bdff4beSrobert_LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX20
61746035553Spatrickbasic_string<_CharT, _Traits, _Allocator>
61846035553Spatrickoperator+(const _CharT* __x, const basic_string<_CharT,_Traits,_Allocator>& __y);
61946035553Spatrick
62046035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
621*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
62246035553Spatrickbasic_string<_CharT, _Traits, _Allocator>
62346035553Spatrickoperator+(_CharT __x, const basic_string<_CharT,_Traits,_Allocator>& __y);
62446035553Spatrick
62546035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
626*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
62746035553Spatrickbasic_string<_CharT, _Traits, _Allocator>
62846035553Spatrickoperator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const _CharT* __y);
62946035553Spatrick
63046035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
631*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
63246035553Spatrickbasic_string<_CharT, _Traits, _Allocator>
63346035553Spatrickoperator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y);
63446035553Spatrick
635*4bdff4beSrobertextern template _LIBCPP_FUNC_VIS string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
63646035553Spatrick
63746035553Spatricktemplate <class _Iter>
63876d0caaeSpatrickstruct __string_is_trivial_iterator : public false_type {};
63976d0caaeSpatrick
64076d0caaeSpatricktemplate <class _Tp>
64176d0caaeSpatrickstruct __string_is_trivial_iterator<_Tp*>
64276d0caaeSpatrick    : public is_arithmetic<_Tp> {};
64346035553Spatrick
64446035553Spatricktemplate <class _Iter>
64576d0caaeSpatrickstruct __string_is_trivial_iterator<__wrap_iter<_Iter> >
64676d0caaeSpatrick    : public __string_is_trivial_iterator<_Iter> {};
64746035553Spatrick
64846035553Spatricktemplate <class _CharT, class _Traits, class _Tp>
649037e7968Spatrickstruct __can_be_converted_to_string_view : public _BoolConstant<
650037e7968Spatrick      is_convertible<const _Tp&, basic_string_view<_CharT, _Traits> >::value &&
651037e7968Spatrick     !is_convertible<const _Tp&, const _CharT*>::value
652037e7968Spatrick    > {};
65346035553Spatrick
654*4bdff4beSrobertstruct __uninitialized_size_tag {};
65576d0caaeSpatrick
65646035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
657*4bdff4beSrobertclass basic_string
65846035553Spatrick{
65946035553Spatrickpublic:
66046035553Spatrick    typedef basic_string                                 __self;
66146035553Spatrick    typedef basic_string_view<_CharT, _Traits>           __self_view;
66246035553Spatrick    typedef _Traits                                      traits_type;
66346035553Spatrick    typedef _CharT                                       value_type;
66446035553Spatrick    typedef _Allocator                                   allocator_type;
66546035553Spatrick    typedef allocator_traits<allocator_type>             __alloc_traits;
66646035553Spatrick    typedef typename __alloc_traits::size_type           size_type;
66746035553Spatrick    typedef typename __alloc_traits::difference_type     difference_type;
66846035553Spatrick    typedef value_type&                                  reference;
66946035553Spatrick    typedef const value_type&                            const_reference;
67046035553Spatrick    typedef typename __alloc_traits::pointer             pointer;
67146035553Spatrick    typedef typename __alloc_traits::const_pointer       const_pointer;
67246035553Spatrick
67346035553Spatrick    static_assert((!is_array<value_type>::value), "Character type of basic_string must not be an array");
67446035553Spatrick    static_assert(( is_standard_layout<value_type>::value), "Character type of basic_string must be standard-layout");
67546035553Spatrick    static_assert(( is_trivial<value_type>::value), "Character type of basic_string must be trivial");
67646035553Spatrick    static_assert(( is_same<_CharT, typename traits_type::char_type>::value),
67746035553Spatrick                  "traits_type::char_type must be the same type as CharT");
67846035553Spatrick    static_assert(( is_same<typename allocator_type::value_type, value_type>::value),
67946035553Spatrick                  "Allocator::value_type must be same type as value_type");
68046035553Spatrick
681*4bdff4beSrobert    static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value,
682*4bdff4beSrobert                  "[allocator.requirements] states that rebinding an allocator to the same type should result in the "
683*4bdff4beSrobert                  "original allocator");
684*4bdff4beSrobert
685*4bdff4beSrobert    // TODO: Implement iterator bounds checking without requiring the global database.
68646035553Spatrick    typedef __wrap_iter<pointer>                         iterator;
68746035553Spatrick    typedef __wrap_iter<const_pointer>                   const_iterator;
688*4bdff4beSrobert    typedef std::reverse_iterator<iterator>              reverse_iterator;
689*4bdff4beSrobert    typedef std::reverse_iterator<const_iterator>        const_reverse_iterator;
69046035553Spatrick
69146035553Spatrickprivate:
692*4bdff4beSrobert    static_assert(CHAR_BIT == 8, "This implementation assumes that one byte contains 8 bits");
69346035553Spatrick
69446035553Spatrick#ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
69546035553Spatrick
69646035553Spatrick    struct __long
69746035553Spatrick    {
69846035553Spatrick        pointer   __data_;
69946035553Spatrick        size_type __size_;
700*4bdff4beSrobert        size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1;
701*4bdff4beSrobert        size_type __is_long_ : 1;
70246035553Spatrick    };
70346035553Spatrick
70446035553Spatrick    enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ?
70546035553Spatrick                      (sizeof(__long) - 1)/sizeof(value_type) : 2};
70646035553Spatrick
70746035553Spatrick    struct __short
70846035553Spatrick    {
70946035553Spatrick        value_type __data_[__min_cap];
710*4bdff4beSrobert        unsigned char __padding_[sizeof(value_type) - 1];
711*4bdff4beSrobert        unsigned char __size_ : 7;
712*4bdff4beSrobert        unsigned char __is_long_ : 1;
71346035553Spatrick    };
71446035553Spatrick
715*4bdff4beSrobert// The __endian_factor is required because the field we use to store the size
716*4bdff4beSrobert// has one fewer bit than it would if it were not a bitfield.
717*4bdff4beSrobert//
718*4bdff4beSrobert// If the LSB is used to store the short-flag in the short string representation,
719*4bdff4beSrobert// we have to multiply the size by two when it is stored and divide it by two when
720*4bdff4beSrobert// it is loaded to make sure that we always store an even number. In the long string
721*4bdff4beSrobert// representation, we can ignore this because we can assume that we always allocate
722*4bdff4beSrobert// an even amount of value_types.
723*4bdff4beSrobert//
724*4bdff4beSrobert// If the MSB is used for the short-flag, the max_size() is numeric_limits<size_type>::max() / 2.
725*4bdff4beSrobert// This does not impact the short string representation, since we never need the MSB
726*4bdff4beSrobert// for representing the size of a short string anyway.
727*4bdff4beSrobert
728*4bdff4beSrobert#ifdef _LIBCPP_BIG_ENDIAN
729*4bdff4beSrobert    static const size_type __endian_factor = 2;
73046035553Spatrick#else
731*4bdff4beSrobert    static const size_type __endian_factor = 1;
732*4bdff4beSrobert#endif
73346035553Spatrick
734*4bdff4beSrobert#else // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
735*4bdff4beSrobert
736*4bdff4beSrobert#ifdef _LIBCPP_BIG_ENDIAN
737*4bdff4beSrobert    static const size_type __endian_factor = 1;
738*4bdff4beSrobert#else
739*4bdff4beSrobert    static const size_type __endian_factor = 2;
740*4bdff4beSrobert#endif
741*4bdff4beSrobert
742*4bdff4beSrobert    // Attribute 'packed' is used to keep the layout compatible with the
743*4bdff4beSrobert    // previous definition that did not use bit fields. This is because on
744*4bdff4beSrobert    // some platforms bit fields have a default size rather than the actual
745*4bdff4beSrobert    // size used, e.g., it is 4 bytes on AIX. See D128285 for details.
74646035553Spatrick    struct __long
74746035553Spatrick    {
748*4bdff4beSrobert        struct _LIBCPP_PACKED {
749*4bdff4beSrobert            size_type __is_long_ : 1;
750*4bdff4beSrobert            size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1;
751*4bdff4beSrobert        };
75246035553Spatrick        size_type __size_;
75346035553Spatrick        pointer   __data_;
75446035553Spatrick    };
75546035553Spatrick
75646035553Spatrick    enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ?
75746035553Spatrick                      (sizeof(__long) - 1)/sizeof(value_type) : 2};
75846035553Spatrick
75946035553Spatrick    struct __short
76046035553Spatrick    {
761*4bdff4beSrobert        struct _LIBCPP_PACKED {
762*4bdff4beSrobert            unsigned char __is_long_ : 1;
763*4bdff4beSrobert            unsigned char __size_ : 7;
76446035553Spatrick        };
765*4bdff4beSrobert        char __padding_[sizeof(value_type) - 1];
76646035553Spatrick        value_type __data_[__min_cap];
76746035553Spatrick    };
76846035553Spatrick
76946035553Spatrick#endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
77046035553Spatrick
771*4bdff4beSrobert    static_assert(sizeof(__short) == (sizeof(value_type) * (__min_cap + 1)), "__short has an unexpected size.");
772*4bdff4beSrobert
77346035553Spatrick    union __ulx{__long __lx; __short __lxx;};
77446035553Spatrick
77546035553Spatrick    enum {__n_words = sizeof(__ulx) / sizeof(size_type)};
77646035553Spatrick
77746035553Spatrick    struct __raw
77846035553Spatrick    {
77946035553Spatrick        size_type __words[__n_words];
78046035553Spatrick    };
78146035553Spatrick
78246035553Spatrick    struct __rep
78346035553Spatrick    {
78446035553Spatrick        union
78546035553Spatrick        {
78646035553Spatrick            __long  __l;
78746035553Spatrick            __short __s;
78846035553Spatrick            __raw   __r;
78946035553Spatrick        };
79046035553Spatrick    };
79146035553Spatrick
79246035553Spatrick    __compressed_pair<__rep, allocator_type> __r_;
79346035553Spatrick
794*4bdff4beSrobert    // Construct a string with the given allocator and enough storage to hold `__size` characters, but
795*4bdff4beSrobert    // don't initialize the characters. The contents of the string, including the null terminator, must be
796*4bdff4beSrobert    // initialized separately.
797*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
798*4bdff4beSrobert    explicit basic_string(__uninitialized_size_tag, size_type __size, const allocator_type& __a)
799*4bdff4beSrobert            : __r_(__default_init_tag(), __a) {
800*4bdff4beSrobert        if (__size > max_size())
801*4bdff4beSrobert            __throw_length_error();
802*4bdff4beSrobert        if (__fits_in_sso(__size)) {
803*4bdff4beSrobert            __r_.first() = __rep();
804*4bdff4beSrobert            __set_short_size(__size);
805*4bdff4beSrobert        } else {
806*4bdff4beSrobert            auto __capacity = __recommend(__size) + 1;
807*4bdff4beSrobert            auto __allocation = __alloc_traits::allocate(__alloc(), __capacity);
808*4bdff4beSrobert            __begin_lifetime(__allocation, __capacity);
809*4bdff4beSrobert            __set_long_cap(__capacity);
810*4bdff4beSrobert            __set_long_pointer(__allocation);
811*4bdff4beSrobert            __set_long_size(__size);
812*4bdff4beSrobert        }
813*4bdff4beSrobert        std::__debug_db_insert_c(this);
81446035553Spatrick    }
81546035553Spatrick
816*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator __make_iterator(pointer __p) {
817*4bdff4beSrobert        return iterator(this, __p);
818*4bdff4beSrobert    }
819*4bdff4beSrobert
820*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator __make_const_iterator(const_pointer __p) const {
821*4bdff4beSrobert        return const_iterator(this, __p);
822*4bdff4beSrobert    }
823*4bdff4beSrobert
824*4bdff4beSrobertpublic:
825*4bdff4beSrobert  _LIBCPP_TEMPLATE_DATA_VIS static const size_type npos = -1;
826*4bdff4beSrobert
827*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string()
828*4bdff4beSrobert      _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
829*4bdff4beSrobert      : __r_(__default_init_tag(), __default_init_tag()) {
830*4bdff4beSrobert    std::__debug_db_insert_c(this);
831*4bdff4beSrobert    __default_init();
832*4bdff4beSrobert  }
833*4bdff4beSrobert
834*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(const allocator_type& __a)
835*4bdff4beSrobert#if _LIBCPP_STD_VER <= 14
836*4bdff4beSrobert      _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
837*4bdff4beSrobert#else
838*4bdff4beSrobert      _NOEXCEPT
839*4bdff4beSrobert#endif
840*4bdff4beSrobert      : __r_(__default_init_tag(), __a) {
841*4bdff4beSrobert    std::__debug_db_insert_c(this);
842*4bdff4beSrobert    __default_init();
843*4bdff4beSrobert  }
844*4bdff4beSrobert
845*4bdff4beSrobert  _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const basic_string& __str);
846*4bdff4beSrobert  _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const basic_string& __str, const allocator_type& __a);
847*4bdff4beSrobert
848*4bdff4beSrobert#ifndef _LIBCPP_CXX03_LANG
849*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(basic_string&& __str)
850*4bdff4beSrobert#  if _LIBCPP_STD_VER <= 14
851*4bdff4beSrobert      _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
852*4bdff4beSrobert#  else
853*4bdff4beSrobert      _NOEXCEPT
854*4bdff4beSrobert#  endif
855*4bdff4beSrobert      : __r_(std::move(__str.__r_)) {
856*4bdff4beSrobert    __str.__default_init();
857*4bdff4beSrobert    std::__debug_db_insert_c(this);
858*4bdff4beSrobert    if (__is_long())
859*4bdff4beSrobert      std::__debug_db_swap(this, &__str);
860*4bdff4beSrobert  }
861*4bdff4beSrobert
862*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(basic_string&& __str, const allocator_type& __a)
863*4bdff4beSrobert      : __r_(__default_init_tag(), __a) {
864*4bdff4beSrobert    if (__str.__is_long() && __a != __str.__alloc()) // copy, not move
865*4bdff4beSrobert      __init(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size());
866*4bdff4beSrobert    else {
867*4bdff4beSrobert      if (__libcpp_is_constant_evaluated())
868*4bdff4beSrobert        __r_.first() = __rep();
869*4bdff4beSrobert      __r_.first() = __str.__r_.first();
870*4bdff4beSrobert      __str.__default_init();
871*4bdff4beSrobert    }
872*4bdff4beSrobert    std::__debug_db_insert_c(this);
873*4bdff4beSrobert    if (__is_long())
874*4bdff4beSrobert      std::__debug_db_swap(this, &__str);
875*4bdff4beSrobert  }
876*4bdff4beSrobert#endif // _LIBCPP_CXX03_LANG
877*4bdff4beSrobert
878*4bdff4beSrobert  template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> >
879*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s)
880*4bdff4beSrobert      : __r_(__default_init_tag(), __default_init_tag()) {
881*4bdff4beSrobert    _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr");
882*4bdff4beSrobert    __init(__s, traits_type::length(__s));
883*4bdff4beSrobert    std::__debug_db_insert_c(this);
884*4bdff4beSrobert  }
885*4bdff4beSrobert
886*4bdff4beSrobert  template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> >
887*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s, const _Allocator& __a);
88846035553Spatrick
88976d0caaeSpatrick#if _LIBCPP_STD_VER > 20
89076d0caaeSpatrick  basic_string(nullptr_t) = delete;
89176d0caaeSpatrick#endif
89276d0caaeSpatrick
893*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s, size_type __n)
894*4bdff4beSrobert      : __r_(__default_init_tag(), __default_init_tag()) {
895*4bdff4beSrobert    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr");
896*4bdff4beSrobert    __init(__s, __n);
897*4bdff4beSrobert    std::__debug_db_insert_c(this);
898*4bdff4beSrobert  }
89946035553Spatrick
900*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
901*4bdff4beSrobert  basic_string(const _CharT* __s, size_type __n, const _Allocator& __a)
902*4bdff4beSrobert      : __r_(__default_init_tag(), __a) {
903*4bdff4beSrobert    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr");
904*4bdff4beSrobert    __init(__s, __n);
905*4bdff4beSrobert    std::__debug_db_insert_c(this);
906*4bdff4beSrobert  }
90746035553Spatrick
908*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(size_type __n, _CharT __c)
909*4bdff4beSrobert      : __r_(__default_init_tag(), __default_init_tag()) {
910*4bdff4beSrobert    __init(__n, __c);
911*4bdff4beSrobert    std::__debug_db_insert_c(this);
912*4bdff4beSrobert  }
91346035553Spatrick
914*4bdff4beSrobert#if _LIBCPP_STD_VER > 20
915*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI constexpr
916*4bdff4beSrobert  basic_string(basic_string&& __str, size_type __pos, const _Allocator& __alloc = _Allocator())
917*4bdff4beSrobert      : basic_string(std::move(__str), __pos, npos, __alloc) {}
91846035553Spatrick
919*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI constexpr
920*4bdff4beSrobert  basic_string(basic_string&& __str, size_type __pos, size_type __n, const _Allocator& __alloc = _Allocator())
921*4bdff4beSrobert      : __r_(__default_init_tag(), __alloc) {
922*4bdff4beSrobert    if (__pos > __str.size())
923*4bdff4beSrobert      __throw_out_of_range();
924*4bdff4beSrobert
925*4bdff4beSrobert    auto __len = std::min<size_type>(__n, __str.size() - __pos);
926*4bdff4beSrobert    if (__alloc_traits::is_always_equal::value || __alloc == __str.__alloc()) {
927*4bdff4beSrobert      __r_.first() = __str.__r_.first();
928*4bdff4beSrobert      __str.__default_init();
929*4bdff4beSrobert
930*4bdff4beSrobert      _Traits::move(data(), data() + __pos, __len);
931*4bdff4beSrobert      __set_size(__len);
932*4bdff4beSrobert      _Traits::assign(data()[__len], value_type());
933*4bdff4beSrobert    } else {
934*4bdff4beSrobert      // Perform a copy because the allocators are not compatible.
935*4bdff4beSrobert      __init(__str.data() + __pos, __len);
936*4bdff4beSrobert    }
937*4bdff4beSrobert
938*4bdff4beSrobert    std::__debug_db_insert_c(this);
939*4bdff4beSrobert    if (__is_long())
940*4bdff4beSrobert      std::__debug_db_swap(this, &__str);
941*4bdff4beSrobert  }
942*4bdff4beSrobert#endif
943*4bdff4beSrobert
944*4bdff4beSrobert  template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> >
945*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(size_type __n, _CharT __c, const _Allocator& __a);
946*4bdff4beSrobert
947*4bdff4beSrobert  _LIBCPP_CONSTEXPR_SINCE_CXX20
948*4bdff4beSrobert  basic_string(const basic_string& __str, size_type __pos, size_type __n, const _Allocator& __a = _Allocator());
949*4bdff4beSrobert
950*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
951*4bdff4beSrobert  basic_string(const basic_string& __str, size_type __pos, const _Allocator& __a = _Allocator())
952*4bdff4beSrobert      : __r_(__default_init_tag(), __a) {
953*4bdff4beSrobert    size_type __str_sz = __str.size();
954*4bdff4beSrobert    if (__pos > __str_sz)
955*4bdff4beSrobert      __throw_out_of_range();
956*4bdff4beSrobert    __init(__str.data() + __pos, __str_sz - __pos);
957*4bdff4beSrobert    std::__debug_db_insert_c(this);
958*4bdff4beSrobert  }
959*4bdff4beSrobert
960*4bdff4beSrobert  template <class _Tp,
961*4bdff4beSrobert            class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
962037e7968Spatrick                                  !__is_same_uncvref<_Tp, basic_string>::value> >
963*4bdff4beSrobert  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
964*4bdff4beSrobert  basic_string(const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a = allocator_type());
96546035553Spatrick
966*4bdff4beSrobert  template <class _Tp,
967*4bdff4beSrobert            class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
968*4bdff4beSrobert                                  !__is_same_uncvref<_Tp, basic_string>::value> >
969*4bdff4beSrobert  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(
970*4bdff4beSrobert      const _Tp& __t);
97146035553Spatrick
972*4bdff4beSrobert  template <class _Tp,
973*4bdff4beSrobert            class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
974*4bdff4beSrobert                                  !__is_same_uncvref<_Tp, basic_string>::value> >
975*4bdff4beSrobert  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(
976*4bdff4beSrobert      const _Tp& __t, const allocator_type& __a);
977*4bdff4beSrobert
978*4bdff4beSrobert  template <class _InputIterator, class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value> >
979*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(_InputIterator __first, _InputIterator __last)
980*4bdff4beSrobert      : __r_(__default_init_tag(), __default_init_tag()) {
981*4bdff4beSrobert    __init(__first, __last);
982*4bdff4beSrobert    std::__debug_db_insert_c(this);
983*4bdff4beSrobert  }
984*4bdff4beSrobert
985*4bdff4beSrobert  template <class _InputIterator, class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value> >
986*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
987*4bdff4beSrobert  basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a)
988*4bdff4beSrobert      : __r_(__default_init_tag(), __a) {
989*4bdff4beSrobert    __init(__first, __last);
990*4bdff4beSrobert    std::__debug_db_insert_c(this);
991*4bdff4beSrobert  }
992*4bdff4beSrobert
99346035553Spatrick#ifndef _LIBCPP_CXX03_LANG
994*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(initializer_list<_CharT> __il)
995*4bdff4beSrobert      : __r_(__default_init_tag(), __default_init_tag()) {
996*4bdff4beSrobert    __init(__il.begin(), __il.end());
997*4bdff4beSrobert    std::__debug_db_insert_c(this);
998*4bdff4beSrobert  }
999*4bdff4beSrobert
1000*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(initializer_list<_CharT> __il, const _Allocator& __a)
1001*4bdff4beSrobert      : __r_(__default_init_tag(), __a) {
1002*4bdff4beSrobert    __init(__il.begin(), __il.end());
1003*4bdff4beSrobert    std::__debug_db_insert_c(this);
1004*4bdff4beSrobert  }
100546035553Spatrick#endif // _LIBCPP_CXX03_LANG
100646035553Spatrick
1007*4bdff4beSrobert    inline _LIBCPP_CONSTEXPR_SINCE_CXX20 ~basic_string();
100846035553Spatrick
1009*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
101046035553Spatrick    operator __self_view() const _NOEXCEPT { return __self_view(data(), size()); }
101146035553Spatrick
1012*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(const basic_string& __str);
101346035553Spatrick
1014*4bdff4beSrobert    template <class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1015*4bdff4beSrobert                                               !__is_same_uncvref<_Tp, basic_string>::value> >
1016*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(const _Tp& __t) {
1017*4bdff4beSrobert      __self_view __sv = __t;
1018*4bdff4beSrobert      return assign(__sv);
1019*4bdff4beSrobert    }
102046035553Spatrick
102146035553Spatrick#ifndef _LIBCPP_CXX03_LANG
1022*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(basic_string&& __str)
1023*4bdff4beSrobert      _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value)) {
1024*4bdff4beSrobert    __move_assign(__str, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>());
1025*4bdff4beSrobert    return *this;
1026*4bdff4beSrobert  }
1027*4bdff4beSrobert
1028*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
102946035553Spatrick    basic_string& operator=(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}
103046035553Spatrick#endif
1031*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1032*4bdff4beSrobert    basic_string& operator=(const value_type* __s) {return assign(__s);}
103376d0caaeSpatrick#if _LIBCPP_STD_VER > 20
103476d0caaeSpatrick    basic_string& operator=(nullptr_t) = delete;
103576d0caaeSpatrick#endif
1036*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(value_type __c);
103746035553Spatrick
1038*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
103946035553Spatrick    iterator begin() _NOEXCEPT
1040*4bdff4beSrobert        {return __make_iterator(__get_pointer());}
1041*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
104246035553Spatrick    const_iterator begin() const _NOEXCEPT
1043*4bdff4beSrobert        {return __make_const_iterator(__get_pointer());}
1044*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
104546035553Spatrick    iterator end() _NOEXCEPT
1046*4bdff4beSrobert        {return __make_iterator(__get_pointer() + size());}
1047*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
104846035553Spatrick    const_iterator end() const _NOEXCEPT
1049*4bdff4beSrobert        {return __make_const_iterator(__get_pointer() + size());}
1050*4bdff4beSrobert
1051*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
105246035553Spatrick    reverse_iterator rbegin() _NOEXCEPT
105346035553Spatrick        {return reverse_iterator(end());}
1054*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
105546035553Spatrick    const_reverse_iterator rbegin() const _NOEXCEPT
105646035553Spatrick        {return const_reverse_iterator(end());}
1057*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
105846035553Spatrick    reverse_iterator rend() _NOEXCEPT
105946035553Spatrick        {return reverse_iterator(begin());}
1060*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
106146035553Spatrick    const_reverse_iterator rend() const _NOEXCEPT
106246035553Spatrick        {return const_reverse_iterator(begin());}
106346035553Spatrick
1064*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
106546035553Spatrick    const_iterator cbegin() const _NOEXCEPT
106646035553Spatrick        {return begin();}
1067*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
106846035553Spatrick    const_iterator cend() const _NOEXCEPT
106946035553Spatrick        {return end();}
1070*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
107146035553Spatrick    const_reverse_iterator crbegin() const _NOEXCEPT
107246035553Spatrick        {return rbegin();}
1073*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
107446035553Spatrick    const_reverse_iterator crend() const _NOEXCEPT
107546035553Spatrick        {return rend();}
107646035553Spatrick
1077*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type size() const _NOEXCEPT
107846035553Spatrick        {return __is_long() ? __get_long_size() : __get_short_size();}
1079*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type length() const _NOEXCEPT {return size();}
108046035553Spatrick
1081*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type max_size() const _NOEXCEPT {
1082*4bdff4beSrobert    size_type __m = __alloc_traits::max_size(__alloc());
1083*4bdff4beSrobert    if (__m <= std::numeric_limits<size_type>::max() / 2) {
1084*4bdff4beSrobert      return __m - __alignment;
1085*4bdff4beSrobert    } else {
1086*4bdff4beSrobert    bool __uses_lsb = __endian_factor == 2;
1087*4bdff4beSrobert      return __uses_lsb ? __m - __alignment : (__m / 2) - __alignment;
1088*4bdff4beSrobert    }
1089*4bdff4beSrobert  }
109046035553Spatrick
1091*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type capacity() const _NOEXCEPT {
1092*4bdff4beSrobert        return (__is_long() ? __get_long_cap() : static_cast<size_type>(__min_cap)) - 1;
1093*4bdff4beSrobert    }
109446035553Spatrick
1095*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 void resize(size_type __n, value_type __c);
1096*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void resize(size_type __n) { resize(__n, value_type()); }
1097*4bdff4beSrobert
1098*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 void reserve(size_type __requested_capacity);
1099*4bdff4beSrobert
1100*4bdff4beSrobert#if _LIBCPP_STD_VER > 20
1101*4bdff4beSrobert    template <class _Op>
1102*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI constexpr
1103*4bdff4beSrobert    void resize_and_overwrite(size_type __n, _Op __op) {
1104*4bdff4beSrobert      __resize_default_init(__n);
1105*4bdff4beSrobert      __erase_to_end(std::move(__op)(data(), _LIBCPP_AUTO_CAST(__n)));
1106*4bdff4beSrobert    }
1107*4bdff4beSrobert#endif
1108*4bdff4beSrobert
1109*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __resize_default_init(size_type __n);
1110*4bdff4beSrobert
1111*4bdff4beSrobert    _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI void reserve() _NOEXCEPT { shrink_to_fit(); }
1112*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void shrink_to_fit() _NOEXCEPT;
1113*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void clear() _NOEXCEPT;
1114*4bdff4beSrobert
1115*4bdff4beSrobert    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
111646035553Spatrick    bool empty() const _NOEXCEPT {return size() == 0;}
111746035553Spatrick
1118*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference operator[](size_type __pos) const _NOEXCEPT {
1119*4bdff4beSrobert    _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
1120*4bdff4beSrobert    return *(data() + __pos);
1121*4bdff4beSrobert  }
112246035553Spatrick
1123*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](size_type __pos) _NOEXCEPT {
1124*4bdff4beSrobert    _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
1125*4bdff4beSrobert    return *(__get_pointer() + __pos);
1126*4bdff4beSrobert  }
112746035553Spatrick
1128*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference at(size_type __n) const;
1129*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 reference       at(size_type __n);
1130*4bdff4beSrobert
1131*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator+=(const basic_string& __str) {
1132*4bdff4beSrobert        return append(__str);
1133*4bdff4beSrobert    }
113446035553Spatrick
113546035553Spatrick    template <class _Tp>
1136*4bdff4beSrobert    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1137*4bdff4beSrobert    __enable_if_t
113846035553Spatrick        <
1139037e7968Spatrick            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
1140037e7968Spatrick            && !__is_same_uncvref<_Tp, basic_string >::value,
114146035553Spatrick            basic_string&
1142037e7968Spatrick        >
1143*4bdff4beSrobert    operator+=(const _Tp& __t) {
1144*4bdff4beSrobert        __self_view __sv = __t; return append(__sv);
1145*4bdff4beSrobert    }
1146*4bdff4beSrobert
1147*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator+=(const value_type* __s) {
1148*4bdff4beSrobert        return append(__s);
1149*4bdff4beSrobert    }
1150*4bdff4beSrobert
1151*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator+=(value_type __c) {
1152*4bdff4beSrobert        push_back(__c);
1153*4bdff4beSrobert        return *this;
1154*4bdff4beSrobert    }
1155*4bdff4beSrobert
115646035553Spatrick#ifndef _LIBCPP_CXX03_LANG
1157*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1158*4bdff4beSrobert    basic_string& operator+=(initializer_list<value_type> __il) { return append(__il); }
115946035553Spatrick#endif // _LIBCPP_CXX03_LANG
116046035553Spatrick
1161*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const basic_string& __str) {
1162*4bdff4beSrobert        return append(__str.data(), __str.size());
1163*4bdff4beSrobert  }
116446035553Spatrick
116546035553Spatrick    template <class _Tp>
1166*4bdff4beSrobert    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1167*4bdff4beSrobert    __enable_if_t<
1168037e7968Spatrick            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
1169037e7968Spatrick            && !__is_same_uncvref<_Tp, basic_string>::value,
117046035553Spatrick            basic_string&
1171037e7968Spatrick        >
117246035553Spatrick                  append(const _Tp& __t) { __self_view __sv = __t; return append(__sv.data(), __sv.size()); }
1173*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos);
117446035553Spatrick
117546035553Spatrick    template <class _Tp>
1176*4bdff4beSrobert    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1177*4bdff4beSrobert    __enable_if_t
117846035553Spatrick        <
1179037e7968Spatrick            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
1180037e7968Spatrick            && !__is_same_uncvref<_Tp, basic_string>::value,
118146035553Spatrick            basic_string&
1182037e7968Spatrick        >
118346035553Spatrick                  append(const _Tp& __t, size_type __pos, size_type __n=npos);
1184*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const value_type* __s, size_type __n);
1185*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const value_type* __s);
1186*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(size_type __n, value_type __c);
118746035553Spatrick
1188*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
118946035553Spatrick    void __append_default_init(size_type __n);
119046035553Spatrick
119146035553Spatrick    template<class _InputIterator>
119246035553Spatrick    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
1193*4bdff4beSrobert    __enable_if_t
119446035553Spatrick        <
119576d0caaeSpatrick            __is_exactly_cpp17_input_iterator<_InputIterator>::value,
119646035553Spatrick            basic_string&
1197037e7968Spatrick        >
1198*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
119946035553Spatrick    append(_InputIterator __first, _InputIterator __last) {
120046035553Spatrick      const basic_string __temp(__first, __last, __alloc());
120146035553Spatrick      append(__temp.data(), __temp.size());
120246035553Spatrick      return *this;
120346035553Spatrick    }
120446035553Spatrick    template<class _ForwardIterator>
120546035553Spatrick    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
1206*4bdff4beSrobert    __enable_if_t
120746035553Spatrick        <
120876d0caaeSpatrick            __is_cpp17_forward_iterator<_ForwardIterator>::value,
120946035553Spatrick            basic_string&
1210037e7968Spatrick        >
1211*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
121276d0caaeSpatrick    append(_ForwardIterator __first, _ForwardIterator __last);
121346035553Spatrick
121446035553Spatrick#ifndef _LIBCPP_CXX03_LANG
1215*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
121646035553Spatrick    basic_string& append(initializer_list<value_type> __il) {return append(__il.begin(), __il.size());}
121746035553Spatrick#endif // _LIBCPP_CXX03_LANG
121846035553Spatrick
1219*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 void push_back(value_type __c);
1220*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void pop_back();
1221*4bdff4beSrobert
1222*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference front() _NOEXCEPT {
1223*4bdff4beSrobert    _LIBCPP_ASSERT(!empty(), "string::front(): string is empty");
1224*4bdff4beSrobert    return *__get_pointer();
1225*4bdff4beSrobert  }
1226*4bdff4beSrobert
1227*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference front() const _NOEXCEPT {
1228*4bdff4beSrobert    _LIBCPP_ASSERT(!empty(), "string::front(): string is empty");
1229*4bdff4beSrobert    return *data();
1230*4bdff4beSrobert  }
1231*4bdff4beSrobert
1232*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference back() _NOEXCEPT {
1233*4bdff4beSrobert    _LIBCPP_ASSERT(!empty(), "string::back(): string is empty");
1234*4bdff4beSrobert    return *(__get_pointer() + size() - 1);
1235*4bdff4beSrobert  }
1236*4bdff4beSrobert
1237*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference back() const _NOEXCEPT {
1238*4bdff4beSrobert    _LIBCPP_ASSERT(!empty(), "string::back(): string is empty");
1239*4bdff4beSrobert    return *(data() + size() - 1);
1240*4bdff4beSrobert  }
124146035553Spatrick
124246035553Spatrick    template <class _Tp>
1243*4bdff4beSrobert    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1244*4bdff4beSrobert    __enable_if_t
124546035553Spatrick        <
124646035553Spatrick            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
124746035553Spatrick            basic_string&
1248037e7968Spatrick        >
124946035553Spatrick                 assign(const _Tp & __t) { __self_view __sv = __t; return assign(__sv.data(), __sv.size()); }
1250*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
125146035553Spatrick    basic_string& assign(const basic_string& __str) { return *this = __str; }
125246035553Spatrick#ifndef _LIBCPP_CXX03_LANG
1253*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
125446035553Spatrick    basic_string& assign(basic_string&& __str)
125546035553Spatrick        _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value))
1256*4bdff4beSrobert        {*this = std::move(__str); return *this;}
125746035553Spatrick#endif
1258*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos);
125946035553Spatrick    template <class _Tp>
1260*4bdff4beSrobert    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1261*4bdff4beSrobert    __enable_if_t
126246035553Spatrick        <
1263037e7968Spatrick            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
1264037e7968Spatrick            && !__is_same_uncvref<_Tp, basic_string>::value,
126546035553Spatrick            basic_string&
1266037e7968Spatrick        >
126746035553Spatrick                  assign(const _Tp & __t, size_type __pos, size_type __n=npos);
1268*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const value_type* __s, size_type __n);
1269*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const value_type* __s);
1270*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(size_type __n, value_type __c);
127146035553Spatrick    template<class _InputIterator>
1272*4bdff4beSrobert    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1273*4bdff4beSrobert    __enable_if_t
127446035553Spatrick        <
127576d0caaeSpatrick            __is_exactly_cpp17_input_iterator<_InputIterator>::value,
127646035553Spatrick            basic_string&
1277037e7968Spatrick        >
127846035553Spatrick        assign(_InputIterator __first, _InputIterator __last);
127946035553Spatrick    template<class _ForwardIterator>
1280*4bdff4beSrobert    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1281*4bdff4beSrobert    __enable_if_t
128246035553Spatrick        <
128376d0caaeSpatrick            __is_cpp17_forward_iterator<_ForwardIterator>::value,
128446035553Spatrick            basic_string&
1285037e7968Spatrick        >
128646035553Spatrick        assign(_ForwardIterator __first, _ForwardIterator __last);
128746035553Spatrick#ifndef _LIBCPP_CXX03_LANG
1288*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
128946035553Spatrick    basic_string& assign(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}
129046035553Spatrick#endif // _LIBCPP_CXX03_LANG
129146035553Spatrick
1292*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1293*4bdff4beSrobert  insert(size_type __pos1, const basic_string& __str) {
1294*4bdff4beSrobert    return insert(__pos1, __str.data(), __str.size());
1295*4bdff4beSrobert  }
129646035553Spatrick
129746035553Spatrick    template <class _Tp>
1298*4bdff4beSrobert    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1299*4bdff4beSrobert    __enable_if_t
130046035553Spatrick        <
130146035553Spatrick            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
130246035553Spatrick            basic_string&
1303037e7968Spatrick        >
130446035553Spatrick                 insert(size_type __pos1, const _Tp& __t)
130546035553Spatrick    { __self_view __sv = __t; return insert(__pos1, __sv.data(), __sv.size()); }
130646035553Spatrick
130746035553Spatrick    template <class _Tp>
1308*4bdff4beSrobert    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1309*4bdff4beSrobert    __enable_if_t
131046035553Spatrick        <
1311037e7968Spatrick            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value,
131246035553Spatrick            basic_string&
1313037e7968Spatrick        >
131446035553Spatrick                  insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n=npos);
1315*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20
131646035553Spatrick    basic_string& insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n=npos);
1317*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* __s, size_type __n);
1318*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* __s);
1319*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, size_type __n, value_type __c);
1320*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator      insert(const_iterator __pos, value_type __c);
1321*4bdff4beSrobert
1322*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator
1323*4bdff4beSrobert  insert(const_iterator __pos, size_type __n, value_type __c) {
1324*4bdff4beSrobert    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
1325*4bdff4beSrobert                         "string::insert(iterator, n, value) called with an iterator not referring to this string");
1326*4bdff4beSrobert    difference_type __p = __pos - begin();
1327*4bdff4beSrobert    insert(static_cast<size_type>(__p), __n, __c);
1328*4bdff4beSrobert    return begin() + __p;
1329*4bdff4beSrobert  }
1330*4bdff4beSrobert
133146035553Spatrick    template<class _InputIterator>
1332*4bdff4beSrobert    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1333*4bdff4beSrobert    __enable_if_t
133446035553Spatrick        <
133576d0caaeSpatrick            __is_exactly_cpp17_input_iterator<_InputIterator>::value,
133646035553Spatrick            iterator
1337037e7968Spatrick        >
133846035553Spatrick        insert(const_iterator __pos, _InputIterator __first, _InputIterator __last);
133946035553Spatrick    template<class _ForwardIterator>
1340*4bdff4beSrobert    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1341*4bdff4beSrobert    __enable_if_t
134246035553Spatrick        <
134376d0caaeSpatrick            __is_cpp17_forward_iterator<_ForwardIterator>::value,
134446035553Spatrick            iterator
1345037e7968Spatrick        >
134646035553Spatrick        insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last);
134746035553Spatrick#ifndef _LIBCPP_CXX03_LANG
1348*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
134946035553Spatrick    iterator insert(const_iterator __pos, initializer_list<value_type> __il)
135046035553Spatrick                    {return insert(__pos, __il.begin(), __il.end());}
135146035553Spatrick#endif // _LIBCPP_CXX03_LANG
135246035553Spatrick
1353*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& erase(size_type __pos = 0, size_type __n = npos);
1354*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
135546035553Spatrick    iterator      erase(const_iterator __pos);
1356*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
135746035553Spatrick    iterator      erase(const_iterator __first, const_iterator __last);
135846035553Spatrick
1359*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1360*4bdff4beSrobert  replace(size_type __pos1, size_type __n1, const basic_string& __str) {
1361*4bdff4beSrobert    return replace(__pos1, __n1, __str.data(), __str.size());
1362*4bdff4beSrobert  }
136346035553Spatrick
136446035553Spatrick    template <class _Tp>
1365*4bdff4beSrobert    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1366*4bdff4beSrobert    __enable_if_t
136746035553Spatrick        <
136846035553Spatrick            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
136946035553Spatrick            basic_string&
1370037e7968Spatrick        >
137146035553Spatrick                  replace(size_type __pos1, size_type __n1, const _Tp& __t) { __self_view __sv = __t; return replace(__pos1, __n1, __sv.data(), __sv.size()); }
1372*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20
137346035553Spatrick    basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos);
137446035553Spatrick    template <class _Tp>
1375*4bdff4beSrobert    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1376*4bdff4beSrobert    __enable_if_t
137746035553Spatrick        <
1378037e7968Spatrick            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value  && !__is_same_uncvref<_Tp, basic_string>::value,
137946035553Spatrick            basic_string&
1380037e7968Spatrick        >
138146035553Spatrick                  replace(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos);
1382*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20
138346035553Spatrick    basic_string& replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2);
1384*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& replace(size_type __pos, size_type __n1, const value_type* __s);
1385*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c);
1386*4bdff4beSrobert
1387*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1388*4bdff4beSrobert  replace(const_iterator __i1, const_iterator __i2, const basic_string& __str) {
1389*4bdff4beSrobert    return replace(
1390*4bdff4beSrobert        static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __str.data(), __str.size());
1391*4bdff4beSrobert  }
139246035553Spatrick
139346035553Spatrick    template <class _Tp>
1394*4bdff4beSrobert    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1395*4bdff4beSrobert    __enable_if_t
139646035553Spatrick        <
139746035553Spatrick            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
139846035553Spatrick            basic_string&
1399037e7968Spatrick        >
140046035553Spatrick                  replace(const_iterator __i1, const_iterator __i2, const _Tp& __t) { __self_view __sv = __t; return replace(__i1 - begin(), __i2 - __i1, __sv); }
140146035553Spatrick
1402*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1403*4bdff4beSrobert  replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n) {
1404*4bdff4beSrobert    return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s, __n);
1405*4bdff4beSrobert  }
1406*4bdff4beSrobert
1407*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1408*4bdff4beSrobert  replace(const_iterator __i1, const_iterator __i2, const value_type* __s) {
1409*4bdff4beSrobert    return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s);
1410*4bdff4beSrobert  }
1411*4bdff4beSrobert
1412*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1413*4bdff4beSrobert  replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c) {
1414*4bdff4beSrobert    return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __n, __c);
1415*4bdff4beSrobert  }
1416*4bdff4beSrobert
141746035553Spatrick    template<class _InputIterator>
1418*4bdff4beSrobert    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1419*4bdff4beSrobert    __enable_if_t
142046035553Spatrick        <
142146035553Spatrick            __is_cpp17_input_iterator<_InputIterator>::value,
142246035553Spatrick            basic_string&
1423037e7968Spatrick        >
142446035553Spatrick        replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2);
142546035553Spatrick#ifndef _LIBCPP_CXX03_LANG
1426*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
142746035553Spatrick    basic_string& replace(const_iterator __i1, const_iterator __i2, initializer_list<value_type> __il)
142846035553Spatrick        {return replace(__i1, __i2, __il.begin(), __il.end());}
142946035553Spatrick#endif // _LIBCPP_CXX03_LANG
143046035553Spatrick
1431*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type copy(value_type* __s, size_type __n, size_type __pos = 0) const;
143246035553Spatrick
1433*4bdff4beSrobert#if _LIBCPP_STD_VER <= 20
1434*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1435*4bdff4beSrobert    basic_string substr(size_type __pos = 0, size_type __n = npos) const {
1436*4bdff4beSrobert      return basic_string(*this, __pos, __n);
1437*4bdff4beSrobert    }
1438*4bdff4beSrobert#else
1439*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI constexpr
1440*4bdff4beSrobert    basic_string substr(size_type __pos = 0, size_type __n = npos) const& {
1441*4bdff4beSrobert      return basic_string(*this, __pos, __n);
1442*4bdff4beSrobert    }
1443*4bdff4beSrobert
1444*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI constexpr
1445*4bdff4beSrobert    basic_string substr(size_type __pos = 0, size_type __n = npos) && {
1446*4bdff4beSrobert      return basic_string(std::move(*this), __pos, __n);
1447*4bdff4beSrobert    }
1448*4bdff4beSrobert#endif
1449*4bdff4beSrobert
1450*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
145146035553Spatrick    void swap(basic_string& __str)
145246035553Spatrick#if _LIBCPP_STD_VER >= 14
145346035553Spatrick        _NOEXCEPT;
145446035553Spatrick#else
145546035553Spatrick        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
145646035553Spatrick                    __is_nothrow_swappable<allocator_type>::value);
145746035553Spatrick#endif
145846035553Spatrick
1459*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
146046035553Spatrick    const value_type* c_str() const _NOEXCEPT {return data();}
1461*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1462*4bdff4beSrobert    const value_type* data() const _NOEXCEPT  {return std::__to_address(__get_pointer());}
146346035553Spatrick#if _LIBCPP_STD_VER > 14 || defined(_LIBCPP_BUILDING_LIBRARY)
1464*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1465*4bdff4beSrobert    value_type* data()             _NOEXCEPT  {return std::__to_address(__get_pointer());}
146646035553Spatrick#endif
146746035553Spatrick
1468*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
146946035553Spatrick    allocator_type get_allocator() const _NOEXCEPT {return __alloc();}
147046035553Spatrick
1471*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
147246035553Spatrick    size_type find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
147346035553Spatrick
147446035553Spatrick    template <class _Tp>
1475*4bdff4beSrobert    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1476*4bdff4beSrobert    __enable_if_t
147746035553Spatrick        <
147846035553Spatrick            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
147946035553Spatrick            size_type
1480037e7968Spatrick        >
148176d0caaeSpatrick              find(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
1482*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20
148346035553Spatrick    size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1484*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
148546035553Spatrick    size_type find(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
1486*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT;
148746035553Spatrick
1488*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
148946035553Spatrick    size_type rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
149046035553Spatrick
149146035553Spatrick    template <class _Tp>
1492*4bdff4beSrobert    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1493*4bdff4beSrobert    __enable_if_t
149446035553Spatrick        <
149546035553Spatrick            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
149646035553Spatrick            size_type
1497037e7968Spatrick        >
149876d0caaeSpatrick              rfind(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
1499*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20
150046035553Spatrick    size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1501*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
150246035553Spatrick    size_type rfind(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
1503*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type rfind(value_type __c, size_type __pos = npos) const _NOEXCEPT;
150446035553Spatrick
1505*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
150646035553Spatrick    size_type find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
150746035553Spatrick
150846035553Spatrick    template <class _Tp>
1509*4bdff4beSrobert    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1510*4bdff4beSrobert    __enable_if_t
151146035553Spatrick        <
151246035553Spatrick            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
151346035553Spatrick            size_type
1514037e7968Spatrick        >
151576d0caaeSpatrick              find_first_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
1516*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20
151746035553Spatrick    size_type find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1518*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
151946035553Spatrick    size_type find_first_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
1520*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
152146035553Spatrick    size_type find_first_of(value_type __c, size_type __pos = 0) const _NOEXCEPT;
152246035553Spatrick
1523*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
152446035553Spatrick    size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
152546035553Spatrick
152646035553Spatrick    template <class _Tp>
1527*4bdff4beSrobert    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1528*4bdff4beSrobert    __enable_if_t
152946035553Spatrick        <
153046035553Spatrick            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
153146035553Spatrick            size_type
1532037e7968Spatrick        >
153376d0caaeSpatrick              find_last_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
1534*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20
153546035553Spatrick    size_type find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1536*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
153746035553Spatrick    size_type find_last_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
1538*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
153946035553Spatrick    size_type find_last_of(value_type __c, size_type __pos = npos) const _NOEXCEPT;
154046035553Spatrick
1541*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
154246035553Spatrick    size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
154346035553Spatrick
154446035553Spatrick    template <class _Tp>
1545*4bdff4beSrobert    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1546*4bdff4beSrobert    __enable_if_t
154746035553Spatrick        <
154846035553Spatrick            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
154946035553Spatrick            size_type
1550037e7968Spatrick        >
155176d0caaeSpatrick              find_first_not_of(const _Tp &__t, size_type __pos = 0) const _NOEXCEPT;
1552*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20
155346035553Spatrick    size_type find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1554*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
155546035553Spatrick    size_type find_first_not_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
1556*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
155746035553Spatrick    size_type find_first_not_of(value_type __c, size_type __pos = 0) const _NOEXCEPT;
155846035553Spatrick
1559*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
156046035553Spatrick    size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
156146035553Spatrick
156246035553Spatrick    template <class _Tp>
1563*4bdff4beSrobert    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1564*4bdff4beSrobert    __enable_if_t
156546035553Spatrick        <
156646035553Spatrick            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
156746035553Spatrick            size_type
1568037e7968Spatrick        >
156976d0caaeSpatrick              find_last_not_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
1570*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20
157146035553Spatrick    size_type find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1572*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
157346035553Spatrick    size_type find_last_not_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
1574*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
157546035553Spatrick    size_type find_last_not_of(value_type __c, size_type __pos = npos) const _NOEXCEPT;
157646035553Spatrick
1577*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
157846035553Spatrick    int compare(const basic_string& __str) const _NOEXCEPT;
157946035553Spatrick
158046035553Spatrick    template <class _Tp>
1581*4bdff4beSrobert    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1582*4bdff4beSrobert    __enable_if_t
158346035553Spatrick        <
158446035553Spatrick            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
158546035553Spatrick            int
1586037e7968Spatrick        >
158776d0caaeSpatrick        compare(const _Tp &__t) const _NOEXCEPT;
158846035553Spatrick
158946035553Spatrick    template <class _Tp>
1590*4bdff4beSrobert    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1591*4bdff4beSrobert    __enable_if_t
159246035553Spatrick        <
159346035553Spatrick            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
159446035553Spatrick            int
1595037e7968Spatrick        >
159646035553Spatrick         compare(size_type __pos1, size_type __n1, const _Tp& __t) const;
159746035553Spatrick
1598*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
159946035553Spatrick    int compare(size_type __pos1, size_type __n1, const basic_string& __str) const;
1600*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20
1601*4bdff4beSrobert    int compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2,
1602*4bdff4beSrobert                size_type __n2 = npos) const;
160346035553Spatrick
160446035553Spatrick    template <class _Tp>
1605*4bdff4beSrobert    inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1606*4bdff4beSrobert        __enable_if_t
160746035553Spatrick        <
1608037e7968Spatrick            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value  && !__is_same_uncvref<_Tp, basic_string>::value,
160946035553Spatrick            int
1610037e7968Spatrick        >
161146035553Spatrick        compare(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos) const;
1612*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(const value_type* __s) const _NOEXCEPT;
1613*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(size_type __pos1, size_type __n1, const value_type* __s) const;
1614*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20
161546035553Spatrick    int compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const;
161646035553Spatrick
161746035553Spatrick#if _LIBCPP_STD_VER > 17
1618*4bdff4beSrobert    constexpr _LIBCPP_HIDE_FROM_ABI
1619*4bdff4beSrobert    bool starts_with(__self_view __sv) const noexcept
162046035553Spatrick    { return __self_view(data(), size()).starts_with(__sv); }
162146035553Spatrick
1622*4bdff4beSrobert    constexpr _LIBCPP_HIDE_FROM_ABI
1623*4bdff4beSrobert    bool starts_with(value_type __c) const noexcept
162446035553Spatrick    { return !empty() && _Traits::eq(front(), __c); }
162546035553Spatrick
1626*4bdff4beSrobert    constexpr _LIBCPP_HIDE_FROM_ABI
1627*4bdff4beSrobert    bool starts_with(const value_type* __s) const noexcept
162846035553Spatrick    { return starts_with(__self_view(__s)); }
162946035553Spatrick
1630*4bdff4beSrobert    constexpr _LIBCPP_HIDE_FROM_ABI
1631*4bdff4beSrobert    bool ends_with(__self_view __sv) const noexcept
163246035553Spatrick    { return __self_view(data(), size()).ends_with( __sv); }
163346035553Spatrick
1634*4bdff4beSrobert    constexpr _LIBCPP_HIDE_FROM_ABI
1635*4bdff4beSrobert    bool ends_with(value_type __c) const noexcept
163646035553Spatrick    { return !empty() && _Traits::eq(back(), __c); }
163746035553Spatrick
1638*4bdff4beSrobert    constexpr _LIBCPP_HIDE_FROM_ABI
1639*4bdff4beSrobert    bool ends_with(const value_type* __s) const noexcept
164046035553Spatrick    { return ends_with(__self_view(__s)); }
164146035553Spatrick#endif
164246035553Spatrick
164376d0caaeSpatrick#if _LIBCPP_STD_VER > 20
1644*4bdff4beSrobert    constexpr _LIBCPP_HIDE_FROM_ABI
164576d0caaeSpatrick    bool contains(__self_view __sv) const noexcept
164676d0caaeSpatrick    { return __self_view(data(), size()).contains(__sv); }
164776d0caaeSpatrick
1648*4bdff4beSrobert    constexpr _LIBCPP_HIDE_FROM_ABI
164976d0caaeSpatrick    bool contains(value_type __c) const noexcept
165076d0caaeSpatrick    { return __self_view(data(), size()).contains(__c); }
165176d0caaeSpatrick
1652*4bdff4beSrobert    constexpr _LIBCPP_HIDE_FROM_ABI
165376d0caaeSpatrick    bool contains(const value_type* __s) const
165476d0caaeSpatrick    { return __self_view(data(), size()).contains(__s); }
165576d0caaeSpatrick#endif
165676d0caaeSpatrick
1657*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __invariants() const;
165846035553Spatrick
1659*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __clear_and_shrink() _NOEXCEPT;
166046035553Spatrick
1661*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE
166246035553Spatrick
166346035553Spatrick    bool __dereferenceable(const const_iterator* __i) const;
166446035553Spatrick    bool __decrementable(const const_iterator* __i) const;
166546035553Spatrick    bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
166646035553Spatrick    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
166746035553Spatrick
1668*4bdff4beSrobert#endif // _LIBCPP_ENABLE_DEBUG_MODE
166946035553Spatrick
167046035553Spatrickprivate:
1671*4bdff4beSrobert    template<class _Alloc>
1672*4bdff4beSrobert    inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1673*4bdff4beSrobert    bool friend operator==(const basic_string<char, char_traits<char>, _Alloc>& __lhs,
1674*4bdff4beSrobert                           const basic_string<char, char_traits<char>, _Alloc>& __rhs) _NOEXCEPT;
167546035553Spatrick
1676*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __shrink_or_extend(size_type __target_capacity);
167746035553Spatrick
1678*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1679*4bdff4beSrobert    bool __is_long() const _NOEXCEPT {
1680*4bdff4beSrobert        if (__libcpp_is_constant_evaluated())
1681*4bdff4beSrobert            return true;
1682*4bdff4beSrobert        return __r_.first().__s.__is_long_;
1683*4bdff4beSrobert    }
1684*4bdff4beSrobert
1685*4bdff4beSrobert    static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __begin_lifetime(pointer __begin, size_type __n) {
1686*4bdff4beSrobert#if _LIBCPP_STD_VER > 17
1687*4bdff4beSrobert        if (__libcpp_is_constant_evaluated()) {
1688*4bdff4beSrobert            for (size_type __i = 0; __i != __n; ++__i)
1689*4bdff4beSrobert                std::construct_at(std::addressof(__begin[__i]));
1690*4bdff4beSrobert        }
169146035553Spatrick#else
1692*4bdff4beSrobert        (void)__begin;
1693*4bdff4beSrobert        (void)__n;
1694*4bdff4beSrobert#endif // _LIBCPP_STD_VER > 17
1695*4bdff4beSrobert    }
169646035553Spatrick
1697*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __default_init() {
1698*4bdff4beSrobert        __r_.first() = __rep();
1699*4bdff4beSrobert        if (__libcpp_is_constant_evaluated()) {
1700*4bdff4beSrobert            size_type __sz = __recommend(0) + 1;
1701*4bdff4beSrobert            pointer __ptr = __alloc_traits::allocate(__alloc(), __sz);
1702*4bdff4beSrobert            __begin_lifetime(__ptr, __sz);
1703*4bdff4beSrobert            __set_long_pointer(__ptr);
1704*4bdff4beSrobert            __set_long_cap(__sz);
1705*4bdff4beSrobert            __set_long_size(0);
1706*4bdff4beSrobert        }
1707*4bdff4beSrobert    }
170846035553Spatrick
1709*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __deallocate_constexpr() {
1710*4bdff4beSrobert        if (__libcpp_is_constant_evaluated() && __get_pointer() != nullptr)
1711*4bdff4beSrobert            __alloc_traits::deallocate(__alloc(), __get_pointer(), __get_long_cap());
1712*4bdff4beSrobert    }
171346035553Spatrick
1714*4bdff4beSrobert    _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI static bool __fits_in_sso(size_type __sz) {
1715*4bdff4beSrobert        // SSO is disabled during constant evaluation because `__is_long` isn't constexpr friendly
1716*4bdff4beSrobert        return !__libcpp_is_constant_evaluated() && (__sz < __min_cap);
1717*4bdff4beSrobert    }
171846035553Spatrick
1719*4bdff4beSrobert    template <class _ForwardIterator>
1720*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
1721*4bdff4beSrobert    iterator __insert_from_safe_copy(size_type __n, size_type __ip, _ForwardIterator __first, _ForwardIterator __last) {
1722*4bdff4beSrobert        size_type __sz = size();
1723*4bdff4beSrobert        size_type __cap = capacity();
1724*4bdff4beSrobert        value_type* __p;
1725*4bdff4beSrobert        if (__cap - __sz >= __n)
1726*4bdff4beSrobert        {
1727*4bdff4beSrobert            __p = std::__to_address(__get_pointer());
1728*4bdff4beSrobert            size_type __n_move = __sz - __ip;
1729*4bdff4beSrobert            if (__n_move != 0)
1730*4bdff4beSrobert                traits_type::move(__p + __ip + __n, __p + __ip, __n_move);
1731*4bdff4beSrobert        }
1732*4bdff4beSrobert        else
1733*4bdff4beSrobert        {
1734*4bdff4beSrobert            __grow_by(__cap, __sz + __n - __cap, __sz, __ip, 0, __n);
1735*4bdff4beSrobert            __p = std::__to_address(__get_long_pointer());
1736*4bdff4beSrobert        }
1737*4bdff4beSrobert        __sz += __n;
1738*4bdff4beSrobert        __set_size(__sz);
1739*4bdff4beSrobert        traits_type::assign(__p[__sz], value_type());
1740*4bdff4beSrobert        for (__p += __ip; __first != __last; ++__p, ++__first)
1741*4bdff4beSrobert            traits_type::assign(*__p, *__first);
174246035553Spatrick
1743*4bdff4beSrobert        return begin() + __ip;
1744*4bdff4beSrobert    }
174546035553Spatrick
1746*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 allocator_type& __alloc() _NOEXCEPT { return __r_.second(); }
1747*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const allocator_type& __alloc() const _NOEXCEPT { return __r_.second(); }
1748*4bdff4beSrobert
1749*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1750*4bdff4beSrobert    void __set_short_size(size_type __s) _NOEXCEPT {
1751*4bdff4beSrobert        _LIBCPP_ASSERT(__s < __min_cap, "__s should never be greater than or equal to the short string capacity");
1752*4bdff4beSrobert        __r_.first().__s.__size_ = __s;
1753*4bdff4beSrobert        __r_.first().__s.__is_long_ = false;
1754*4bdff4beSrobert    }
1755*4bdff4beSrobert
1756*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1757*4bdff4beSrobert    size_type __get_short_size() const _NOEXCEPT {
1758*4bdff4beSrobert        _LIBCPP_ASSERT(!__r_.first().__s.__is_long_, "String has to be short when trying to get the short size");
1759*4bdff4beSrobert        return __r_.first().__s.__size_;
1760*4bdff4beSrobert    }
1761*4bdff4beSrobert
1762*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
176346035553Spatrick    void __set_long_size(size_type __s) _NOEXCEPT
176446035553Spatrick        {__r_.first().__l.__size_ = __s;}
1765*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
176646035553Spatrick    size_type __get_long_size() const _NOEXCEPT
176746035553Spatrick        {return __r_.first().__l.__size_;}
1768*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
176946035553Spatrick    void __set_size(size_type __s) _NOEXCEPT
177046035553Spatrick        {if (__is_long()) __set_long_size(__s); else __set_short_size(__s);}
177146035553Spatrick
1772*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1773*4bdff4beSrobert    void __set_long_cap(size_type __s) _NOEXCEPT {
1774*4bdff4beSrobert        __r_.first().__l.__cap_ = __s / __endian_factor;
1775*4bdff4beSrobert        __r_.first().__l.__is_long_ = true;
1776*4bdff4beSrobert    }
177746035553Spatrick
1778*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1779*4bdff4beSrobert    size_type __get_long_cap() const _NOEXCEPT {
1780*4bdff4beSrobert        return __r_.first().__l.__cap_ * __endian_factor;
1781*4bdff4beSrobert    }
1782*4bdff4beSrobert
1783*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
178446035553Spatrick    void __set_long_pointer(pointer __p) _NOEXCEPT
178546035553Spatrick        {__r_.first().__l.__data_ = __p;}
1786*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
178746035553Spatrick    pointer __get_long_pointer() _NOEXCEPT
178846035553Spatrick        {return __r_.first().__l.__data_;}
1789*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
179046035553Spatrick    const_pointer __get_long_pointer() const _NOEXCEPT
179146035553Spatrick        {return __r_.first().__l.__data_;}
1792*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
179346035553Spatrick    pointer __get_short_pointer() _NOEXCEPT
179446035553Spatrick        {return pointer_traits<pointer>::pointer_to(__r_.first().__s.__data_[0]);}
1795*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
179646035553Spatrick    const_pointer __get_short_pointer() const _NOEXCEPT
179746035553Spatrick        {return pointer_traits<const_pointer>::pointer_to(__r_.first().__s.__data_[0]);}
1798*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
179946035553Spatrick    pointer __get_pointer() _NOEXCEPT
180046035553Spatrick        {return __is_long() ? __get_long_pointer() : __get_short_pointer();}
1801*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
180246035553Spatrick    const_pointer __get_pointer() const _NOEXCEPT
180346035553Spatrick        {return __is_long() ? __get_long_pointer() : __get_short_pointer();}
180446035553Spatrick
180546035553Spatrick    template <size_type __a> static
1806*4bdff4beSrobert        _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
180746035553Spatrick        size_type __align_it(size_type __s) _NOEXCEPT
180846035553Spatrick            {return (__s + (__a-1)) & ~(__a-1);}
180946035553Spatrick    enum {__alignment = 16};
1810*4bdff4beSrobert    static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
181146035553Spatrick    size_type __recommend(size_type __s) _NOEXCEPT
181246035553Spatrick    {
1813*4bdff4beSrobert        if (__s < __min_cap) {
1814*4bdff4beSrobert            if (__libcpp_is_constant_evaluated())
1815*4bdff4beSrobert                return static_cast<size_type>(__min_cap);
1816*4bdff4beSrobert            else
1817*4bdff4beSrobert                return static_cast<size_type>(__min_cap) - 1;
1818*4bdff4beSrobert        }
181946035553Spatrick        size_type __guess = __align_it<sizeof(value_type) < __alignment ?
182046035553Spatrick                     __alignment/sizeof(value_type) : 1 > (__s+1) - 1;
182146035553Spatrick        if (__guess == __min_cap) ++__guess;
182246035553Spatrick        return __guess;
182346035553Spatrick    }
182446035553Spatrick
1825*4bdff4beSrobert    inline _LIBCPP_CONSTEXPR_SINCE_CXX20
182646035553Spatrick    void __init(const value_type* __s, size_type __sz, size_type __reserve);
1827*4bdff4beSrobert    inline _LIBCPP_CONSTEXPR_SINCE_CXX20
182846035553Spatrick    void __init(const value_type* __s, size_type __sz);
1829*4bdff4beSrobert    inline _LIBCPP_CONSTEXPR_SINCE_CXX20
183046035553Spatrick    void __init(size_type __n, value_type __c);
183146035553Spatrick
1832037e7968Spatrick    // Slow path for the (inlined) copy constructor for 'long' strings.
1833037e7968Spatrick    // Always externally instantiated and not inlined.
1834037e7968Spatrick    // Requires that __s is zero terminated.
1835037e7968Spatrick    // The main reason for this function to exist is because for unstable, we
1836037e7968Spatrick    // want to allow inlining of the copy constructor. However, we don't want
1837037e7968Spatrick    // to call the __init() functions as those are marked as inline which may
1838037e7968Spatrick    // result in over-aggressive inlining by the compiler, where our aim is
1839037e7968Spatrick    // to only inline the fast path code directly in the ctor.
1840*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init_copy_ctor_external(const value_type* __s, size_type __sz);
1841037e7968Spatrick
184246035553Spatrick    template <class _InputIterator>
1843*4bdff4beSrobert    inline _LIBCPP_CONSTEXPR_SINCE_CXX20
1844*4bdff4beSrobert    __enable_if_t
184546035553Spatrick    <
1846037e7968Spatrick        __is_exactly_cpp17_input_iterator<_InputIterator>::value
1847037e7968Spatrick    >
184846035553Spatrick    __init(_InputIterator __first, _InputIterator __last);
184946035553Spatrick
185046035553Spatrick    template <class _ForwardIterator>
1851*4bdff4beSrobert    inline _LIBCPP_CONSTEXPR_SINCE_CXX20
1852*4bdff4beSrobert    __enable_if_t
185346035553Spatrick    <
1854037e7968Spatrick        __is_cpp17_forward_iterator<_ForwardIterator>::value
1855037e7968Spatrick    >
185646035553Spatrick    __init(_ForwardIterator __first, _ForwardIterator __last);
185746035553Spatrick
1858*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20
185946035553Spatrick    void __grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
186046035553Spatrick                   size_type __n_copy,  size_type __n_del,     size_type __n_add = 0);
1861*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20
186246035553Spatrick    void __grow_by_and_replace(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
186346035553Spatrick                               size_type __n_copy,  size_type __n_del,
186446035553Spatrick                               size_type __n_add, const value_type* __p_new_stuff);
186546035553Spatrick
1866037e7968Spatrick    // __assign_no_alias is invoked for assignment operations where we
1867037e7968Spatrick    // have proof that the input does not alias the current instance.
1868037e7968Spatrick    // For example, operator=(basic_string) performs a 'self' check.
1869037e7968Spatrick    template <bool __is_short>
1870*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& __assign_no_alias(const value_type* __s, size_type __n);
1871037e7968Spatrick
1872*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __erase_to_end(size_type __pos) {
1873*4bdff4beSrobert    __null_terminate_at(std::__to_address(__get_pointer()), __pos);
1874*4bdff4beSrobert  }
187546035553Spatrick
1876037e7968Spatrick    // __erase_external_with_move is invoked for erase() invocations where
1877037e7968Spatrick    // `n ~= npos`, likely requiring memory moves on the string data.
1878*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 void __erase_external_with_move(size_type __pos, size_type __n);
1879037e7968Spatrick
1880*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
188146035553Spatrick    void __copy_assign_alloc(const basic_string& __str)
188246035553Spatrick        {__copy_assign_alloc(__str, integral_constant<bool,
188346035553Spatrick                      __alloc_traits::propagate_on_container_copy_assignment::value>());}
188446035553Spatrick
1885*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
188646035553Spatrick    void __copy_assign_alloc(const basic_string& __str, true_type)
188746035553Spatrick        {
188846035553Spatrick            if (__alloc() == __str.__alloc())
188946035553Spatrick                __alloc() = __str.__alloc();
189046035553Spatrick            else
189146035553Spatrick            {
189246035553Spatrick                if (!__str.__is_long())
189346035553Spatrick                {
189446035553Spatrick                    __clear_and_shrink();
189546035553Spatrick                    __alloc() = __str.__alloc();
189646035553Spatrick                }
189746035553Spatrick                else
189846035553Spatrick                {
189946035553Spatrick                    allocator_type __a = __str.__alloc();
1900*4bdff4beSrobert                    auto __allocation = std::__allocate_at_least(__a, __str.__get_long_cap());
1901*4bdff4beSrobert                    __begin_lifetime(__allocation.ptr, __allocation.count);
1902*4bdff4beSrobert                    __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
1903*4bdff4beSrobert                    __alloc() = std::move(__a);
1904*4bdff4beSrobert                    __set_long_pointer(__allocation.ptr);
1905*4bdff4beSrobert                    __set_long_cap(__allocation.count);
190646035553Spatrick                    __set_long_size(__str.size());
190746035553Spatrick                }
190846035553Spatrick            }
190946035553Spatrick        }
191046035553Spatrick
1911*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
191246035553Spatrick    void __copy_assign_alloc(const basic_string&, false_type) _NOEXCEPT
191346035553Spatrick        {}
191446035553Spatrick
191546035553Spatrick#ifndef _LIBCPP_CXX03_LANG
1916*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
191746035553Spatrick    void __move_assign(basic_string& __str, false_type)
191846035553Spatrick        _NOEXCEPT_(__alloc_traits::is_always_equal::value);
1919*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
192046035553Spatrick    void __move_assign(basic_string& __str, true_type)
192146035553Spatrick#if _LIBCPP_STD_VER > 14
192246035553Spatrick        _NOEXCEPT;
192346035553Spatrick#else
192446035553Spatrick        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
192546035553Spatrick#endif
192646035553Spatrick#endif
192746035553Spatrick
1928*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
192946035553Spatrick    void
193046035553Spatrick    __move_assign_alloc(basic_string& __str)
193146035553Spatrick        _NOEXCEPT_(
193246035553Spatrick            !__alloc_traits::propagate_on_container_move_assignment::value ||
193346035553Spatrick            is_nothrow_move_assignable<allocator_type>::value)
193446035553Spatrick    {__move_assign_alloc(__str, integral_constant<bool,
193546035553Spatrick                      __alloc_traits::propagate_on_container_move_assignment::value>());}
193646035553Spatrick
1937*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
193846035553Spatrick    void __move_assign_alloc(basic_string& __c, true_type)
193946035553Spatrick        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
194046035553Spatrick        {
1941*4bdff4beSrobert            __alloc() = std::move(__c.__alloc());
194246035553Spatrick        }
194346035553Spatrick
1944*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
194546035553Spatrick    void __move_assign_alloc(basic_string&, false_type)
194646035553Spatrick        _NOEXCEPT
194746035553Spatrick        {}
194846035553Spatrick
1949*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& __assign_external(const value_type* __s);
1950*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& __assign_external(const value_type* __s, size_type __n);
1951037e7968Spatrick
1952037e7968Spatrick    // Assigns the value in __s, guaranteed to be __n < __min_cap in length.
1953037e7968Spatrick    inline basic_string& __assign_short(const value_type* __s, size_type __n) {
1954037e7968Spatrick      pointer __p = __is_long()
1955037e7968Spatrick                        ? (__set_long_size(__n), __get_long_pointer())
1956037e7968Spatrick                        : (__set_short_size(__n), __get_short_pointer());
1957*4bdff4beSrobert      traits_type::move(std::__to_address(__p), __s, __n);
1958037e7968Spatrick      traits_type::assign(__p[__n], value_type());
1959037e7968Spatrick      return *this;
1960037e7968Spatrick    }
1961037e7968Spatrick
1962*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1963*4bdff4beSrobert    basic_string& __null_terminate_at(value_type* __p, size_type __newsz) {
1964*4bdff4beSrobert      __set_size(__newsz);
1965*4bdff4beSrobert      __invalidate_iterators_past(__newsz);
1966*4bdff4beSrobert      traits_type::assign(__p[__newsz], value_type());
1967*4bdff4beSrobert      return *this;
1968*4bdff4beSrobert    }
1969*4bdff4beSrobert
1970*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __invalidate_iterators_past(size_type);
197146035553Spatrick
197276d0caaeSpatrick    template<class _Tp>
1973*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
197476d0caaeSpatrick    bool __addr_in_range(_Tp&& __t) const {
1975*4bdff4beSrobert        // assume that the ranges overlap, because we can't check during constant evaluation
1976*4bdff4beSrobert        if (__libcpp_is_constant_evaluated())
1977*4bdff4beSrobert          return true;
1978*4bdff4beSrobert        const volatile void *__p = std::addressof(__t);
197976d0caaeSpatrick        return data() <= __p && __p <= data() + size();
198076d0caaeSpatrick    }
198176d0caaeSpatrick
198276d0caaeSpatrick    _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI
198376d0caaeSpatrick    void __throw_length_error() const {
1984*4bdff4beSrobert        std::__throw_length_error("basic_string");
198576d0caaeSpatrick    }
198676d0caaeSpatrick
198776d0caaeSpatrick    _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI
198876d0caaeSpatrick    void __throw_out_of_range() const {
1989*4bdff4beSrobert        std::__throw_out_of_range("basic_string");
199076d0caaeSpatrick    }
199176d0caaeSpatrick
1992*4bdff4beSrobert    friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+<>(const basic_string&, const basic_string&);
1993*4bdff4beSrobert    friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+<>(const value_type*, const basic_string&);
1994*4bdff4beSrobert    friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+<>(value_type, const basic_string&);
1995*4bdff4beSrobert    friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+<>(const basic_string&, const value_type*);
1996*4bdff4beSrobert    friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+<>(const basic_string&, value_type);
199746035553Spatrick};
199846035553Spatrick
1999037e7968Spatrick// These declarations must appear before any functions are implicitly used
2000037e7968Spatrick// so that they have the correct visibility specifier.
2001*4bdff4beSrobert#define _LIBCPP_DECLARE(...) extern template __VA_ARGS__;
2002037e7968Spatrick#ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
2003*4bdff4beSrobert    _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, char)
2004*4bdff4beSrobert#   ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
2005*4bdff4beSrobert        _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, wchar_t)
2006037e7968Spatrick#   endif
2007*4bdff4beSrobert#else
2008*4bdff4beSrobert    _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, char)
2009*4bdff4beSrobert#   ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
2010*4bdff4beSrobert        _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, wchar_t)
2011*4bdff4beSrobert#   endif
2012*4bdff4beSrobert#endif
2013*4bdff4beSrobert#undef _LIBCPP_DECLARE
2014037e7968Spatrick
2015037e7968Spatrick
2016*4bdff4beSrobert#if _LIBCPP_STD_VER >= 17
201746035553Spatricktemplate<class _InputIterator,
201876d0caaeSpatrick         class _CharT = __iter_value_type<_InputIterator>,
201946035553Spatrick         class _Allocator = allocator<_CharT>,
2020*4bdff4beSrobert         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
2021*4bdff4beSrobert         class = enable_if_t<__is_allocator<_Allocator>::value>
202246035553Spatrick         >
202346035553Spatrickbasic_string(_InputIterator, _InputIterator, _Allocator = _Allocator())
202446035553Spatrick  -> basic_string<_CharT, char_traits<_CharT>, _Allocator>;
202546035553Spatrick
202646035553Spatricktemplate<class _CharT,
202746035553Spatrick         class _Traits,
202846035553Spatrick         class _Allocator = allocator<_CharT>,
2029*4bdff4beSrobert         class = enable_if_t<__is_allocator<_Allocator>::value>
203046035553Spatrick         >
203146035553Spatrickexplicit basic_string(basic_string_view<_CharT, _Traits>, const _Allocator& = _Allocator())
203246035553Spatrick  -> basic_string<_CharT, _Traits, _Allocator>;
203346035553Spatrick
203446035553Spatricktemplate<class _CharT,
203546035553Spatrick         class _Traits,
203646035553Spatrick         class _Allocator = allocator<_CharT>,
2037*4bdff4beSrobert         class = enable_if_t<__is_allocator<_Allocator>::value>,
203846035553Spatrick         class _Sz = typename allocator_traits<_Allocator>::size_type
203946035553Spatrick         >
204046035553Spatrickbasic_string(basic_string_view<_CharT, _Traits>, _Sz, _Sz, const _Allocator& = _Allocator())
204146035553Spatrick  -> basic_string<_CharT, _Traits, _Allocator>;
204246035553Spatrick#endif
204346035553Spatrick
204446035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
2045*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
204646035553Spatrickvoid
204776d0caaeSpatrickbasic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type __pos)
204846035553Spatrick{
2049*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE
2050*4bdff4beSrobert    if (!__libcpp_is_constant_evaluated()) {
205146035553Spatrick        __c_node* __c = __get_db()->__find_c_and_lock(this);
205246035553Spatrick        if (__c)
205346035553Spatrick        {
205446035553Spatrick            const_pointer __new_last = __get_pointer() + __pos;
205546035553Spatrick            for (__i_node** __p = __c->end_; __p != __c->beg_; )
205646035553Spatrick            {
205746035553Spatrick                --__p;
205846035553Spatrick                const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
205946035553Spatrick                if (__i->base() > __new_last)
206046035553Spatrick                {
206146035553Spatrick                    (*__p)->__c_ = nullptr;
206246035553Spatrick                    if (--__c->end_ != __p)
2063*4bdff4beSrobert                        std::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
206446035553Spatrick                }
206546035553Spatrick            }
206646035553Spatrick            __get_db()->unlock();
206746035553Spatrick        }
2068*4bdff4beSrobert    }
206976d0caaeSpatrick#else
207076d0caaeSpatrick    (void)__pos;
2071*4bdff4beSrobert#endif // _LIBCPP_ENABLE_DEBUG_MODE
207246035553Spatrick}
207346035553Spatrick
207446035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
2075*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
207646035553Spatrickvoid basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s,
207746035553Spatrick                                                       size_type __sz,
207846035553Spatrick                                                       size_type __reserve)
207946035553Spatrick{
2080*4bdff4beSrobert    if (__libcpp_is_constant_evaluated())
2081*4bdff4beSrobert        __r_.first() = __rep();
208246035553Spatrick    if (__reserve > max_size())
2083*4bdff4beSrobert        __throw_length_error();
208446035553Spatrick    pointer __p;
2085*4bdff4beSrobert    if (__fits_in_sso(__reserve))
208646035553Spatrick    {
208746035553Spatrick        __set_short_size(__sz);
208846035553Spatrick        __p = __get_short_pointer();
208946035553Spatrick    }
209046035553Spatrick    else
209146035553Spatrick    {
2092*4bdff4beSrobert        auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__reserve) + 1);
2093*4bdff4beSrobert        __p = __allocation.ptr;
2094*4bdff4beSrobert        __begin_lifetime(__p, __allocation.count);
209546035553Spatrick        __set_long_pointer(__p);
2096*4bdff4beSrobert        __set_long_cap(__allocation.count);
209746035553Spatrick        __set_long_size(__sz);
209846035553Spatrick    }
2099*4bdff4beSrobert    traits_type::copy(std::__to_address(__p), __s, __sz);
210046035553Spatrick    traits_type::assign(__p[__sz], value_type());
210146035553Spatrick}
210246035553Spatrick
210346035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
2104*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
210546035553Spatrickvoid
210646035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz)
210746035553Spatrick{
2108*4bdff4beSrobert    if (__libcpp_is_constant_evaluated())
2109*4bdff4beSrobert        __r_.first() = __rep();
211046035553Spatrick    if (__sz > max_size())
2111*4bdff4beSrobert        __throw_length_error();
211246035553Spatrick    pointer __p;
2113*4bdff4beSrobert    if (__fits_in_sso(__sz))
211446035553Spatrick    {
211546035553Spatrick        __set_short_size(__sz);
211646035553Spatrick        __p = __get_short_pointer();
211746035553Spatrick    }
211846035553Spatrick    else
211946035553Spatrick    {
2120*4bdff4beSrobert        auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1);
2121*4bdff4beSrobert        __p = __allocation.ptr;
2122*4bdff4beSrobert        __begin_lifetime(__p, __allocation.count);
212346035553Spatrick        __set_long_pointer(__p);
2124*4bdff4beSrobert        __set_long_cap(__allocation.count);
212546035553Spatrick        __set_long_size(__sz);
212646035553Spatrick    }
2127*4bdff4beSrobert    traits_type::copy(std::__to_address(__p), __s, __sz);
212846035553Spatrick    traits_type::assign(__p[__sz], value_type());
212946035553Spatrick}
213046035553Spatrick
213146035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
213246035553Spatricktemplate <class>
2133*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
213446035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const _Allocator& __a)
213546035553Spatrick    : __r_(__default_init_tag(), __a)
213646035553Spatrick{
213746035553Spatrick    _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr");
213846035553Spatrick    __init(__s, traits_type::length(__s));
2139*4bdff4beSrobert    std::__debug_db_insert_c(this);
214046035553Spatrick}
214146035553Spatrick
214246035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
2143*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
214446035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str)
214546035553Spatrick    : __r_(__default_init_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc()))
214646035553Spatrick{
214746035553Spatrick    if (!__str.__is_long())
2148*4bdff4beSrobert        __r_.first() = __str.__r_.first();
214946035553Spatrick    else
2150*4bdff4beSrobert        __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()),
2151037e7968Spatrick                                  __str.__get_long_size());
2152*4bdff4beSrobert    std::__debug_db_insert_c(this);
215346035553Spatrick}
215446035553Spatrick
215546035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
2156*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
215746035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::basic_string(
215846035553Spatrick    const basic_string& __str, const allocator_type& __a)
215946035553Spatrick    : __r_(__default_init_tag(), __a)
216046035553Spatrick{
216146035553Spatrick    if (!__str.__is_long())
2162*4bdff4beSrobert        __r_.first() = __str.__r_.first();
216346035553Spatrick    else
2164*4bdff4beSrobert        __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()),
2165037e7968Spatrick                                  __str.__get_long_size());
2166*4bdff4beSrobert    std::__debug_db_insert_c(this);
216746035553Spatrick}
216846035553Spatrick
2169037e7968Spatricktemplate <class _CharT, class _Traits, class _Allocator>
2170*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
2171037e7968Spatrickvoid basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external(
2172037e7968Spatrick    const value_type* __s, size_type __sz) {
2173*4bdff4beSrobert  if (__libcpp_is_constant_evaluated())
2174*4bdff4beSrobert    __r_.first() = __rep();
2175*4bdff4beSrobert
2176037e7968Spatrick  pointer __p;
2177*4bdff4beSrobert  if (__fits_in_sso(__sz)) {
2178037e7968Spatrick    __p = __get_short_pointer();
2179037e7968Spatrick    __set_short_size(__sz);
2180037e7968Spatrick  } else {
2181037e7968Spatrick    if (__sz > max_size())
2182*4bdff4beSrobert      __throw_length_error();
2183*4bdff4beSrobert    auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1);
2184*4bdff4beSrobert    __p = __allocation.ptr;
2185*4bdff4beSrobert    __begin_lifetime(__p, __allocation.count);
2186037e7968Spatrick    __set_long_pointer(__p);
2187*4bdff4beSrobert    __set_long_cap(__allocation.count);
2188037e7968Spatrick    __set_long_size(__sz);
2189037e7968Spatrick  }
2190*4bdff4beSrobert  traits_type::copy(std::__to_address(__p), __s, __sz + 1);
219146035553Spatrick}
219246035553Spatrick
219346035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
2194*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
219546035553Spatrickvoid
219646035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c)
219746035553Spatrick{
2198*4bdff4beSrobert    if (__libcpp_is_constant_evaluated())
2199*4bdff4beSrobert        __r_.first() = __rep();
2200*4bdff4beSrobert
220146035553Spatrick    if (__n > max_size())
2202*4bdff4beSrobert        __throw_length_error();
220346035553Spatrick    pointer __p;
2204*4bdff4beSrobert    if (__fits_in_sso(__n))
220546035553Spatrick    {
220646035553Spatrick        __set_short_size(__n);
220746035553Spatrick        __p = __get_short_pointer();
220846035553Spatrick    }
220946035553Spatrick    else
221046035553Spatrick    {
2211*4bdff4beSrobert        auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__n) + 1);
2212*4bdff4beSrobert        __p = __allocation.ptr;
2213*4bdff4beSrobert        __begin_lifetime(__p, __allocation.count);
221446035553Spatrick        __set_long_pointer(__p);
2215*4bdff4beSrobert        __set_long_cap(__allocation.count);
221646035553Spatrick        __set_long_size(__n);
221746035553Spatrick    }
2218*4bdff4beSrobert    traits_type::assign(std::__to_address(__p), __n, __c);
221946035553Spatrick    traits_type::assign(__p[__n], value_type());
222046035553Spatrick}
222146035553Spatrick
222246035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
222346035553Spatricktemplate <class>
2224*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
222546035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c, const _Allocator& __a)
222646035553Spatrick    : __r_(__default_init_tag(), __a)
222746035553Spatrick{
222846035553Spatrick    __init(__n, __c);
2229*4bdff4beSrobert    std::__debug_db_insert_c(this);
223046035553Spatrick}
223146035553Spatrick
223246035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
2233*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
223446035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str,
223546035553Spatrick                                                        size_type __pos, size_type __n,
223646035553Spatrick                                                        const _Allocator& __a)
223746035553Spatrick    : __r_(__default_init_tag(), __a)
223846035553Spatrick{
223946035553Spatrick    size_type __str_sz = __str.size();
224046035553Spatrick    if (__pos > __str_sz)
2241*4bdff4beSrobert        __throw_out_of_range();
2242*4bdff4beSrobert    __init(__str.data() + __pos, std::min(__n, __str_sz - __pos));
2243*4bdff4beSrobert    std::__debug_db_insert_c(this);
224446035553Spatrick}
224546035553Spatrick
224646035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
224746035553Spatricktemplate <class _Tp, class>
2248*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
224946035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::basic_string(
225046035553Spatrick             const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a)
225146035553Spatrick    : __r_(__default_init_tag(), __a)
225246035553Spatrick{
225346035553Spatrick    __self_view __sv0 = __t;
225446035553Spatrick    __self_view __sv = __sv0.substr(__pos, __n);
225546035553Spatrick    __init(__sv.data(), __sv.size());
2256*4bdff4beSrobert    std::__debug_db_insert_c(this);
225746035553Spatrick}
225846035553Spatrick
225946035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
226046035553Spatricktemplate <class _Tp, class>
2261*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
226246035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t)
226346035553Spatrick     : __r_(__default_init_tag(), __default_init_tag())
226446035553Spatrick{
226546035553Spatrick    __self_view __sv = __t;
226646035553Spatrick    __init(__sv.data(), __sv.size());
2267*4bdff4beSrobert    std::__debug_db_insert_c(this);
226846035553Spatrick}
226946035553Spatrick
227046035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
227146035553Spatricktemplate <class _Tp, class>
2272*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
227346035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t, const _Allocator& __a)
227446035553Spatrick    : __r_(__default_init_tag(), __a)
227546035553Spatrick{
227646035553Spatrick    __self_view __sv = __t;
227746035553Spatrick    __init(__sv.data(), __sv.size());
2278*4bdff4beSrobert    std::__debug_db_insert_c(this);
227946035553Spatrick}
228046035553Spatrick
228146035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
228246035553Spatricktemplate <class _InputIterator>
2283*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
2284*4bdff4beSrobert__enable_if_t
228546035553Spatrick<
2286037e7968Spatrick    __is_exactly_cpp17_input_iterator<_InputIterator>::value
2287037e7968Spatrick>
228846035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last)
228946035553Spatrick{
2290*4bdff4beSrobert    __default_init();
229146035553Spatrick#ifndef _LIBCPP_NO_EXCEPTIONS
229246035553Spatrick    try
229346035553Spatrick    {
229446035553Spatrick#endif // _LIBCPP_NO_EXCEPTIONS
229546035553Spatrick    for (; __first != __last; ++__first)
229646035553Spatrick        push_back(*__first);
229746035553Spatrick#ifndef _LIBCPP_NO_EXCEPTIONS
229846035553Spatrick    }
229946035553Spatrick    catch (...)
230046035553Spatrick    {
230146035553Spatrick        if (__is_long())
230246035553Spatrick            __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
230346035553Spatrick        throw;
230446035553Spatrick    }
230546035553Spatrick#endif // _LIBCPP_NO_EXCEPTIONS
230646035553Spatrick}
230746035553Spatrick
230846035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
230946035553Spatricktemplate <class _ForwardIterator>
2310*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
2311*4bdff4beSrobert__enable_if_t
231246035553Spatrick<
2313037e7968Spatrick    __is_cpp17_forward_iterator<_ForwardIterator>::value
2314037e7968Spatrick>
231546035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last)
231646035553Spatrick{
2317*4bdff4beSrobert    if (__libcpp_is_constant_evaluated())
2318*4bdff4beSrobert        __r_.first() = __rep();
2319*4bdff4beSrobert    size_type __sz = static_cast<size_type>(std::distance(__first, __last));
232046035553Spatrick    if (__sz > max_size())
2321*4bdff4beSrobert        __throw_length_error();
232246035553Spatrick    pointer __p;
2323*4bdff4beSrobert    if (__fits_in_sso(__sz))
232446035553Spatrick    {
232546035553Spatrick        __set_short_size(__sz);
232646035553Spatrick        __p = __get_short_pointer();
232746035553Spatrick    }
232846035553Spatrick    else
232946035553Spatrick    {
2330*4bdff4beSrobert        auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1);
2331*4bdff4beSrobert        __p = __allocation.ptr;
2332*4bdff4beSrobert        __begin_lifetime(__p, __allocation.count);
233346035553Spatrick        __set_long_pointer(__p);
2334*4bdff4beSrobert        __set_long_cap(__allocation.count);
233546035553Spatrick        __set_long_size(__sz);
233646035553Spatrick    }
233776d0caaeSpatrick
233876d0caaeSpatrick#ifndef _LIBCPP_NO_EXCEPTIONS
233976d0caaeSpatrick    try
234076d0caaeSpatrick    {
234176d0caaeSpatrick#endif  // _LIBCPP_NO_EXCEPTIONS
234246035553Spatrick    for (; __first != __last; ++__first, (void) ++__p)
234346035553Spatrick        traits_type::assign(*__p, *__first);
234446035553Spatrick    traits_type::assign(*__p, value_type());
234576d0caaeSpatrick#ifndef _LIBCPP_NO_EXCEPTIONS
234676d0caaeSpatrick    }
234776d0caaeSpatrick    catch (...)
234876d0caaeSpatrick    {
234976d0caaeSpatrick        if (__is_long())
235076d0caaeSpatrick            __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
235176d0caaeSpatrick        throw;
235276d0caaeSpatrick    }
235376d0caaeSpatrick#endif  // _LIBCPP_NO_EXCEPTIONS
235446035553Spatrick}
235546035553Spatrick
235646035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
2357*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
235846035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::~basic_string()
235946035553Spatrick{
2360*4bdff4beSrobert    std::__debug_db_erase_c(this);
236146035553Spatrick    if (__is_long())
236246035553Spatrick        __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
236346035553Spatrick}
236446035553Spatrick
236546035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
2366*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
236746035553Spatrickvoid
236846035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace
236946035553Spatrick    (size_type __old_cap, size_type __delta_cap, size_type __old_sz,
237046035553Spatrick     size_type __n_copy,  size_type __n_del,     size_type __n_add, const value_type* __p_new_stuff)
237146035553Spatrick{
237246035553Spatrick    size_type __ms = max_size();
237346035553Spatrick    if (__delta_cap > __ms - __old_cap - 1)
2374*4bdff4beSrobert        __throw_length_error();
237546035553Spatrick    pointer __old_p = __get_pointer();
237646035553Spatrick    size_type __cap = __old_cap < __ms / 2 - __alignment ?
2377*4bdff4beSrobert                          __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) :
237846035553Spatrick                          __ms - 1;
2379*4bdff4beSrobert    auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1);
2380*4bdff4beSrobert    pointer __p = __allocation.ptr;
2381*4bdff4beSrobert    __begin_lifetime(__p, __allocation.count);
2382*4bdff4beSrobert    std::__debug_db_invalidate_all(this);
238346035553Spatrick    if (__n_copy != 0)
2384*4bdff4beSrobert        traits_type::copy(std::__to_address(__p),
2385*4bdff4beSrobert                          std::__to_address(__old_p), __n_copy);
238646035553Spatrick    if (__n_add != 0)
2387*4bdff4beSrobert        traits_type::copy(std::__to_address(__p) + __n_copy, __p_new_stuff, __n_add);
238846035553Spatrick    size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
238946035553Spatrick    if (__sec_cp_sz != 0)
2390*4bdff4beSrobert        traits_type::copy(std::__to_address(__p) + __n_copy + __n_add,
2391*4bdff4beSrobert                          std::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz);
2392*4bdff4beSrobert    if (__old_cap+1 != __min_cap || __libcpp_is_constant_evaluated())
239346035553Spatrick        __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1);
239446035553Spatrick    __set_long_pointer(__p);
2395*4bdff4beSrobert    __set_long_cap(__allocation.count);
239646035553Spatrick    __old_sz = __n_copy + __n_add + __sec_cp_sz;
239746035553Spatrick    __set_long_size(__old_sz);
239846035553Spatrick    traits_type::assign(__p[__old_sz], value_type());
239946035553Spatrick}
240046035553Spatrick
240146035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
240246035553Spatrickvoid
2403*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
240446035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
240546035553Spatrick                                                     size_type __n_copy,  size_type __n_del,     size_type __n_add)
240646035553Spatrick{
240746035553Spatrick    size_type __ms = max_size();
240846035553Spatrick    if (__delta_cap > __ms - __old_cap)
2409*4bdff4beSrobert        __throw_length_error();
241046035553Spatrick    pointer __old_p = __get_pointer();
241146035553Spatrick    size_type __cap = __old_cap < __ms / 2 - __alignment ?
2412*4bdff4beSrobert                          __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) :
241346035553Spatrick                          __ms - 1;
2414*4bdff4beSrobert    auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1);
2415*4bdff4beSrobert    pointer __p = __allocation.ptr;
2416*4bdff4beSrobert    __begin_lifetime(__p, __allocation.count);
2417*4bdff4beSrobert    std::__debug_db_invalidate_all(this);
241846035553Spatrick    if (__n_copy != 0)
2419*4bdff4beSrobert        traits_type::copy(std::__to_address(__p),
2420*4bdff4beSrobert                          std::__to_address(__old_p), __n_copy);
242146035553Spatrick    size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
242246035553Spatrick    if (__sec_cp_sz != 0)
2423*4bdff4beSrobert        traits_type::copy(std::__to_address(__p) + __n_copy + __n_add,
2424*4bdff4beSrobert                          std::__to_address(__old_p) + __n_copy + __n_del,
242546035553Spatrick                          __sec_cp_sz);
2426*4bdff4beSrobert    if (__libcpp_is_constant_evaluated() || __old_cap + 1 != __min_cap)
242746035553Spatrick        __alloc_traits::deallocate(__alloc(), __old_p, __old_cap + 1);
242846035553Spatrick    __set_long_pointer(__p);
2429*4bdff4beSrobert    __set_long_cap(__allocation.count);
243046035553Spatrick}
243146035553Spatrick
243246035553Spatrick// assign
243346035553Spatrick
243446035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
2435037e7968Spatricktemplate <bool __is_short>
2436*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
243746035553Spatrickbasic_string<_CharT, _Traits, _Allocator>&
2438037e7968Spatrickbasic_string<_CharT, _Traits, _Allocator>::__assign_no_alias(
2439037e7968Spatrick    const value_type* __s, size_type __n) {
2440*4bdff4beSrobert  size_type __cap = __is_short ? static_cast<size_type>(__min_cap) : __get_long_cap();
2441037e7968Spatrick  if (__n < __cap) {
2442037e7968Spatrick    pointer __p = __is_short ? __get_short_pointer() : __get_long_pointer();
2443037e7968Spatrick    __is_short ? __set_short_size(__n) : __set_long_size(__n);
2444*4bdff4beSrobert    traits_type::copy(std::__to_address(__p), __s, __n);
2445037e7968Spatrick    traits_type::assign(__p[__n], value_type());
2446037e7968Spatrick    __invalidate_iterators_past(__n);
2447037e7968Spatrick  } else {
2448037e7968Spatrick    size_type __sz = __is_short ? __get_short_size() : __get_long_size();
2449037e7968Spatrick    __grow_by_and_replace(__cap - 1, __n - __cap + 1, __sz, 0, __sz, __n, __s);
2450037e7968Spatrick  }
2451037e7968Spatrick  return *this;
2452037e7968Spatrick}
2453037e7968Spatrick
2454037e7968Spatricktemplate <class _CharT, class _Traits, class _Allocator>
2455*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
2456037e7968Spatrickbasic_string<_CharT, _Traits, _Allocator>&
2457037e7968Spatrickbasic_string<_CharT, _Traits, _Allocator>::__assign_external(
2458037e7968Spatrick    const value_type* __s, size_type __n) {
245946035553Spatrick  size_type __cap = capacity();
2460037e7968Spatrick  if (__cap >= __n) {
2461*4bdff4beSrobert    value_type* __p = std::__to_address(__get_pointer());
246246035553Spatrick    traits_type::move(__p, __s, __n);
2463*4bdff4beSrobert    return __null_terminate_at(__p, __n);
2464037e7968Spatrick  } else {
246546035553Spatrick    size_type __sz = size();
246646035553Spatrick    __grow_by_and_replace(__cap, __n - __cap, __sz, 0, __sz, __n, __s);
246746035553Spatrick    return *this;
246846035553Spatrick  }
2469*4bdff4beSrobert}
247046035553Spatrick
247146035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
2472*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
247346035553Spatrickbasic_string<_CharT, _Traits, _Allocator>&
2474037e7968Spatrickbasic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n)
2475037e7968Spatrick{
2476037e7968Spatrick    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::assign received nullptr");
2477*4bdff4beSrobert    return (__builtin_constant_p(__n) && __fits_in_sso(__n))
2478037e7968Spatrick               ? __assign_short(__s, __n)
2479037e7968Spatrick               : __assign_external(__s, __n);
2480037e7968Spatrick}
2481037e7968Spatrick
2482037e7968Spatricktemplate <class _CharT, class _Traits, class _Allocator>
2483*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
2484037e7968Spatrickbasic_string<_CharT, _Traits, _Allocator>&
248546035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c)
248646035553Spatrick{
248746035553Spatrick    size_type __cap = capacity();
248846035553Spatrick    if (__cap < __n)
248946035553Spatrick    {
249046035553Spatrick        size_type __sz = size();
249146035553Spatrick        __grow_by(__cap, __n - __cap, __sz, 0, __sz);
249246035553Spatrick    }
2493*4bdff4beSrobert    value_type* __p = std::__to_address(__get_pointer());
249446035553Spatrick    traits_type::assign(__p, __n, __c);
2495*4bdff4beSrobert    return __null_terminate_at(__p, __n);
249646035553Spatrick}
249746035553Spatrick
249846035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
2499*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
250046035553Spatrickbasic_string<_CharT, _Traits, _Allocator>&
250146035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c)
250246035553Spatrick{
250346035553Spatrick    pointer __p;
250446035553Spatrick    if (__is_long())
250546035553Spatrick    {
250646035553Spatrick        __p = __get_long_pointer();
250746035553Spatrick        __set_long_size(1);
250846035553Spatrick    }
250946035553Spatrick    else
251046035553Spatrick    {
251146035553Spatrick        __p = __get_short_pointer();
251246035553Spatrick        __set_short_size(1);
251346035553Spatrick    }
251446035553Spatrick    traits_type::assign(*__p, __c);
251546035553Spatrick    traits_type::assign(*++__p, value_type());
251646035553Spatrick    __invalidate_iterators_past(1);
251746035553Spatrick    return *this;
251846035553Spatrick}
251946035553Spatrick
252046035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
2521*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
252246035553Spatrickbasic_string<_CharT, _Traits, _Allocator>&
252346035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str)
252446035553Spatrick{
2525037e7968Spatrick  if (this != &__str) {
252646035553Spatrick    __copy_assign_alloc(__str);
2527037e7968Spatrick    if (!__is_long()) {
2528037e7968Spatrick      if (!__str.__is_long()) {
2529*4bdff4beSrobert        __r_.first() = __str.__r_.first();
2530037e7968Spatrick      } else {
2531037e7968Spatrick        return __assign_no_alias<true>(__str.data(), __str.size());
2532037e7968Spatrick      }
2533037e7968Spatrick    } else {
2534037e7968Spatrick      return __assign_no_alias<false>(__str.data(), __str.size());
2535037e7968Spatrick    }
253646035553Spatrick  }
253746035553Spatrick  return *this;
253846035553Spatrick}
253946035553Spatrick
254046035553Spatrick#ifndef _LIBCPP_CXX03_LANG
254146035553Spatrick
254246035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
2543*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
254446035553Spatrickvoid
254546035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, false_type)
254646035553Spatrick    _NOEXCEPT_(__alloc_traits::is_always_equal::value)
254746035553Spatrick{
254846035553Spatrick    if (__alloc() != __str.__alloc())
254946035553Spatrick        assign(__str);
255046035553Spatrick    else
255146035553Spatrick        __move_assign(__str, true_type());
255246035553Spatrick}
255346035553Spatrick
255446035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
2555*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
255646035553Spatrickvoid
255746035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type)
255846035553Spatrick#if _LIBCPP_STD_VER > 14
255946035553Spatrick    _NOEXCEPT
256046035553Spatrick#else
256146035553Spatrick    _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
256246035553Spatrick#endif
256346035553Spatrick{
256446035553Spatrick  if (__is_long()) {
256546035553Spatrick    __alloc_traits::deallocate(__alloc(), __get_long_pointer(),
256646035553Spatrick                               __get_long_cap());
256746035553Spatrick#if _LIBCPP_STD_VER <= 14
256846035553Spatrick    if (!is_nothrow_move_assignable<allocator_type>::value) {
256946035553Spatrick      __set_short_size(0);
257046035553Spatrick      traits_type::assign(__get_short_pointer()[0], value_type());
257146035553Spatrick    }
257246035553Spatrick#endif
257346035553Spatrick  }
257446035553Spatrick  __move_assign_alloc(__str);
257546035553Spatrick  __r_.first() = __str.__r_.first();
2576*4bdff4beSrobert  if (__libcpp_is_constant_evaluated()) {
2577*4bdff4beSrobert    __str.__default_init();
2578*4bdff4beSrobert  } else {
257946035553Spatrick    __str.__set_short_size(0);
258046035553Spatrick    traits_type::assign(__str.__get_short_pointer()[0], value_type());
258146035553Spatrick  }
258246035553Spatrick}
258346035553Spatrick
258446035553Spatrick#endif
258546035553Spatrick
258646035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
258746035553Spatricktemplate<class _InputIterator>
2588*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
2589*4bdff4beSrobert__enable_if_t
259046035553Spatrick<
259176d0caaeSpatrick     __is_exactly_cpp17_input_iterator<_InputIterator>::value,
259246035553Spatrick    basic_string<_CharT, _Traits, _Allocator>&
2593037e7968Spatrick>
259446035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
259546035553Spatrick{
259646035553Spatrick    const basic_string __temp(__first, __last, __alloc());
259746035553Spatrick    assign(__temp.data(), __temp.size());
259846035553Spatrick    return *this;
259946035553Spatrick}
260046035553Spatrick
260146035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
260246035553Spatricktemplate<class _ForwardIterator>
2603*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
2604*4bdff4beSrobert__enable_if_t
260546035553Spatrick<
260676d0caaeSpatrick    __is_cpp17_forward_iterator<_ForwardIterator>::value,
260746035553Spatrick    basic_string<_CharT, _Traits, _Allocator>&
2608037e7968Spatrick>
260946035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)
261046035553Spatrick{
261146035553Spatrick    size_type __cap = capacity();
261276d0caaeSpatrick    size_type __n = __string_is_trivial_iterator<_ForwardIterator>::value ?
2613*4bdff4beSrobert        static_cast<size_type>(std::distance(__first, __last)) : 0;
261476d0caaeSpatrick
261576d0caaeSpatrick    if (__string_is_trivial_iterator<_ForwardIterator>::value &&
261676d0caaeSpatrick        (__cap >= __n || !__addr_in_range(*__first)))
261776d0caaeSpatrick    {
261846035553Spatrick        if (__cap < __n)
261946035553Spatrick        {
262046035553Spatrick            size_type __sz = size();
262146035553Spatrick            __grow_by(__cap, __n - __cap, __sz, 0, __sz);
262246035553Spatrick        }
262346035553Spatrick        pointer __p = __get_pointer();
2624*4bdff4beSrobert        for (; __first != __last; ++__p, (void) ++__first)
262546035553Spatrick            traits_type::assign(*__p, *__first);
262646035553Spatrick        traits_type::assign(*__p, value_type());
262746035553Spatrick        __set_size(__n);
262876d0caaeSpatrick        __invalidate_iterators_past(__n);
262976d0caaeSpatrick    }
263076d0caaeSpatrick    else
263176d0caaeSpatrick    {
263276d0caaeSpatrick        const basic_string __temp(__first, __last, __alloc());
263376d0caaeSpatrick        assign(__temp.data(), __temp.size());
263476d0caaeSpatrick    }
263546035553Spatrick    return *this;
263646035553Spatrick}
263746035553Spatrick
263846035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
2639*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
264046035553Spatrickbasic_string<_CharT, _Traits, _Allocator>&
264146035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, size_type __pos, size_type __n)
264246035553Spatrick{
264346035553Spatrick    size_type __sz = __str.size();
264446035553Spatrick    if (__pos > __sz)
2645*4bdff4beSrobert        __throw_out_of_range();
2646*4bdff4beSrobert    return assign(__str.data() + __pos, std::min(__n, __sz - __pos));
264746035553Spatrick}
264846035553Spatrick
264946035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
265046035553Spatricktemplate <class _Tp>
2651*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
2652*4bdff4beSrobert__enable_if_t
265346035553Spatrick<
2654037e7968Spatrick    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
2655037e7968Spatrick    && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
265646035553Spatrick    basic_string<_CharT, _Traits, _Allocator>&
2657037e7968Spatrick>
265846035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t, size_type __pos, size_type __n)
265946035553Spatrick{
266046035553Spatrick    __self_view __sv = __t;
266146035553Spatrick    size_type __sz = __sv.size();
266246035553Spatrick    if (__pos > __sz)
2663*4bdff4beSrobert        __throw_out_of_range();
2664*4bdff4beSrobert    return assign(__sv.data() + __pos, std::min(__n, __sz - __pos));
266546035553Spatrick}
266646035553Spatrick
266746035553Spatrick
266846035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
2669*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
267046035553Spatrickbasic_string<_CharT, _Traits, _Allocator>&
2671037e7968Spatrickbasic_string<_CharT, _Traits, _Allocator>::__assign_external(const value_type* __s) {
2672037e7968Spatrick  return __assign_external(__s, traits_type::length(__s));
2673037e7968Spatrick}
2674037e7968Spatrick
2675037e7968Spatricktemplate <class _CharT, class _Traits, class _Allocator>
2676*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
2677037e7968Spatrickbasic_string<_CharT, _Traits, _Allocator>&
267846035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s)
267946035553Spatrick{
268046035553Spatrick    _LIBCPP_ASSERT(__s != nullptr, "string::assign received nullptr");
2681*4bdff4beSrobert    return __builtin_constant_p(*__s)
2682*4bdff4beSrobert               ? (__fits_in_sso(traits_type::length(__s))
2683037e7968Spatrick                      ? __assign_short(__s, traits_type::length(__s))
2684037e7968Spatrick                      : __assign_external(__s, traits_type::length(__s)))
2685037e7968Spatrick               : __assign_external(__s);
268646035553Spatrick}
268746035553Spatrick// append
268846035553Spatrick
268946035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
2690*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
269146035553Spatrickbasic_string<_CharT, _Traits, _Allocator>&
269246035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n)
269346035553Spatrick{
269446035553Spatrick    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::append received nullptr");
269546035553Spatrick    size_type __cap = capacity();
269646035553Spatrick    size_type __sz = size();
269746035553Spatrick    if (__cap - __sz >= __n)
269846035553Spatrick    {
269946035553Spatrick        if (__n)
270046035553Spatrick        {
2701*4bdff4beSrobert            value_type* __p = std::__to_address(__get_pointer());
270246035553Spatrick            traits_type::copy(__p + __sz, __s, __n);
270346035553Spatrick            __sz += __n;
270446035553Spatrick            __set_size(__sz);
270546035553Spatrick            traits_type::assign(__p[__sz], value_type());
270646035553Spatrick        }
270746035553Spatrick    }
270846035553Spatrick    else
270946035553Spatrick        __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __sz, 0, __n, __s);
271046035553Spatrick    return *this;
271146035553Spatrick}
271246035553Spatrick
271346035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
2714*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
271546035553Spatrickbasic_string<_CharT, _Traits, _Allocator>&
271646035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c)
271746035553Spatrick{
271846035553Spatrick    if (__n)
271946035553Spatrick    {
272046035553Spatrick        size_type __cap = capacity();
272146035553Spatrick        size_type __sz = size();
272246035553Spatrick        if (__cap - __sz < __n)
272346035553Spatrick            __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
272446035553Spatrick        pointer __p = __get_pointer();
2725*4bdff4beSrobert        traits_type::assign(std::__to_address(__p) + __sz, __n, __c);
272646035553Spatrick        __sz += __n;
272746035553Spatrick        __set_size(__sz);
272846035553Spatrick        traits_type::assign(__p[__sz], value_type());
272946035553Spatrick    }
273046035553Spatrick    return *this;
273146035553Spatrick}
273246035553Spatrick
273346035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
2734*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20 inline void
273546035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n)
273646035553Spatrick{
273746035553Spatrick    if (__n)
273846035553Spatrick    {
273946035553Spatrick        size_type __cap = capacity();
274046035553Spatrick        size_type __sz = size();
274146035553Spatrick        if (__cap - __sz < __n)
274246035553Spatrick            __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
274346035553Spatrick        pointer __p = __get_pointer();
274446035553Spatrick        __sz += __n;
274546035553Spatrick        __set_size(__sz);
274646035553Spatrick        traits_type::assign(__p[__sz], value_type());
274746035553Spatrick    }
274846035553Spatrick}
274946035553Spatrick
275046035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
2751*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
275246035553Spatrickvoid
275346035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c)
275446035553Spatrick{
275546035553Spatrick    bool __is_short = !__is_long();
275646035553Spatrick    size_type __cap;
275746035553Spatrick    size_type __sz;
275846035553Spatrick    if (__is_short)
275946035553Spatrick    {
276046035553Spatrick        __cap = __min_cap - 1;
276146035553Spatrick        __sz = __get_short_size();
276246035553Spatrick    }
276346035553Spatrick    else
276446035553Spatrick    {
276546035553Spatrick        __cap = __get_long_cap() - 1;
276646035553Spatrick        __sz = __get_long_size();
276746035553Spatrick    }
276846035553Spatrick    if (__sz == __cap)
276946035553Spatrick    {
277046035553Spatrick        __grow_by(__cap, 1, __sz, __sz, 0);
2771*4bdff4beSrobert        __is_short = false; // the string is always long after __grow_by
277246035553Spatrick    }
2773*4bdff4beSrobert    pointer __p = __get_pointer();
277446035553Spatrick    if (__is_short)
277546035553Spatrick    {
277646035553Spatrick        __p = __get_short_pointer() + __sz;
277746035553Spatrick        __set_short_size(__sz+1);
277846035553Spatrick    }
277946035553Spatrick    else
278046035553Spatrick    {
278146035553Spatrick        __p = __get_long_pointer() + __sz;
278246035553Spatrick        __set_long_size(__sz+1);
278346035553Spatrick    }
278446035553Spatrick    traits_type::assign(*__p, __c);
278546035553Spatrick    traits_type::assign(*++__p, value_type());
278646035553Spatrick}
278746035553Spatrick
278846035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
278946035553Spatricktemplate<class _ForwardIterator>
2790*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
2791*4bdff4beSrobert__enable_if_t
279276d0caaeSpatrick<
279376d0caaeSpatrick    __is_cpp17_forward_iterator<_ForwardIterator>::value,
279446035553Spatrick    basic_string<_CharT, _Traits, _Allocator>&
279576d0caaeSpatrick>
279676d0caaeSpatrickbasic_string<_CharT, _Traits, _Allocator>::append(
279746035553Spatrick    _ForwardIterator __first, _ForwardIterator __last)
279846035553Spatrick{
279946035553Spatrick    size_type __sz = size();
280046035553Spatrick    size_type __cap = capacity();
2801*4bdff4beSrobert    size_type __n = static_cast<size_type>(std::distance(__first, __last));
280246035553Spatrick    if (__n)
280346035553Spatrick    {
280476d0caaeSpatrick        if (__string_is_trivial_iterator<_ForwardIterator>::value &&
280576d0caaeSpatrick            !__addr_in_range(*__first))
280646035553Spatrick        {
280746035553Spatrick            if (__cap - __sz < __n)
280846035553Spatrick                __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
280946035553Spatrick            pointer __p = __get_pointer() + __sz;
2810*4bdff4beSrobert            for (; __first != __last; ++__p, (void) ++__first)
281146035553Spatrick                traits_type::assign(*__p, *__first);
281246035553Spatrick            traits_type::assign(*__p, value_type());
281346035553Spatrick            __set_size(__sz + __n);
281446035553Spatrick        }
281576d0caaeSpatrick        else
281676d0caaeSpatrick        {
281776d0caaeSpatrick            const basic_string __temp(__first, __last, __alloc());
281876d0caaeSpatrick            append(__temp.data(), __temp.size());
281976d0caaeSpatrick        }
282046035553Spatrick    }
282146035553Spatrick    return *this;
282246035553Spatrick}
282346035553Spatrick
282446035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
2825*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
282646035553Spatrickbasic_string<_CharT, _Traits, _Allocator>&
282746035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, size_type __pos, size_type __n)
282846035553Spatrick{
282946035553Spatrick    size_type __sz = __str.size();
283046035553Spatrick    if (__pos > __sz)
2831*4bdff4beSrobert        __throw_out_of_range();
2832*4bdff4beSrobert    return append(__str.data() + __pos, std::min(__n, __sz - __pos));
283346035553Spatrick}
283446035553Spatrick
283546035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
283646035553Spatricktemplate <class _Tp>
2837*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
2838*4bdff4beSrobert    __enable_if_t
283946035553Spatrick    <
2840037e7968Spatrick        __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value  && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
284146035553Spatrick        basic_string<_CharT, _Traits, _Allocator>&
2842037e7968Spatrick    >
284346035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::append(const _Tp & __t, size_type __pos, size_type __n)
284446035553Spatrick{
284546035553Spatrick    __self_view __sv = __t;
284646035553Spatrick    size_type __sz = __sv.size();
284746035553Spatrick    if (__pos > __sz)
2848*4bdff4beSrobert        __throw_out_of_range();
2849*4bdff4beSrobert    return append(__sv.data() + __pos, std::min(__n, __sz - __pos));
285046035553Spatrick}
285146035553Spatrick
285246035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
2853*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
285446035553Spatrickbasic_string<_CharT, _Traits, _Allocator>&
285546035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s)
285646035553Spatrick{
285746035553Spatrick    _LIBCPP_ASSERT(__s != nullptr, "string::append received nullptr");
285846035553Spatrick    return append(__s, traits_type::length(__s));
285946035553Spatrick}
286046035553Spatrick
286146035553Spatrick// insert
286246035553Spatrick
286346035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
2864*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
286546035553Spatrickbasic_string<_CharT, _Traits, _Allocator>&
286646035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n)
286746035553Spatrick{
286846035553Spatrick    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::insert received nullptr");
286946035553Spatrick    size_type __sz = size();
287046035553Spatrick    if (__pos > __sz)
2871*4bdff4beSrobert        __throw_out_of_range();
287246035553Spatrick    size_type __cap = capacity();
2873*4bdff4beSrobert    if (__libcpp_is_constant_evaluated()) {
2874*4bdff4beSrobert        if (__cap - __sz >= __n)
2875*4bdff4beSrobert            __grow_by_and_replace(__cap, 0, __sz, __pos, 0, __n, __s);
2876*4bdff4beSrobert        else
2877*4bdff4beSrobert            __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s);
2878*4bdff4beSrobert        return *this;
2879*4bdff4beSrobert    }
288046035553Spatrick    if (__cap - __sz >= __n)
288146035553Spatrick    {
288246035553Spatrick        if (__n)
288346035553Spatrick        {
2884*4bdff4beSrobert            value_type* __p = std::__to_address(__get_pointer());
288546035553Spatrick            size_type __n_move = __sz - __pos;
288646035553Spatrick            if (__n_move != 0)
288746035553Spatrick            {
288846035553Spatrick                if (__p + __pos <= __s && __s < __p + __sz)
288946035553Spatrick                    __s += __n;
289046035553Spatrick                traits_type::move(__p + __pos + __n, __p + __pos, __n_move);
289146035553Spatrick            }
289246035553Spatrick            traits_type::move(__p + __pos, __s, __n);
289346035553Spatrick            __sz += __n;
289446035553Spatrick            __set_size(__sz);
289546035553Spatrick            traits_type::assign(__p[__sz], value_type());
289646035553Spatrick        }
289746035553Spatrick    }
289846035553Spatrick    else
289946035553Spatrick        __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s);
290046035553Spatrick    return *this;
290146035553Spatrick}
290246035553Spatrick
290346035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
2904*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
290546035553Spatrickbasic_string<_CharT, _Traits, _Allocator>&
290646035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n, value_type __c)
290746035553Spatrick{
290846035553Spatrick    size_type __sz = size();
290946035553Spatrick    if (__pos > __sz)
2910*4bdff4beSrobert        __throw_out_of_range();
291146035553Spatrick    if (__n)
291246035553Spatrick    {
291346035553Spatrick        size_type __cap = capacity();
291446035553Spatrick        value_type* __p;
291546035553Spatrick        if (__cap - __sz >= __n)
291646035553Spatrick        {
2917*4bdff4beSrobert            __p = std::__to_address(__get_pointer());
291846035553Spatrick            size_type __n_move = __sz - __pos;
291946035553Spatrick            if (__n_move != 0)
292046035553Spatrick                traits_type::move(__p + __pos + __n, __p + __pos, __n_move);
292146035553Spatrick        }
292246035553Spatrick        else
292346035553Spatrick        {
292446035553Spatrick            __grow_by(__cap, __sz + __n - __cap, __sz, __pos, 0, __n);
2925*4bdff4beSrobert            __p = std::__to_address(__get_long_pointer());
292646035553Spatrick        }
292746035553Spatrick        traits_type::assign(__p + __pos, __n, __c);
292846035553Spatrick        __sz += __n;
292946035553Spatrick        __set_size(__sz);
293046035553Spatrick        traits_type::assign(__p[__sz], value_type());
293146035553Spatrick    }
293246035553Spatrick    return *this;
293346035553Spatrick}
293446035553Spatrick
293546035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
293646035553Spatricktemplate<class _InputIterator>
2937*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
2938*4bdff4beSrobert__enable_if_t
293946035553Spatrick<
294076d0caaeSpatrick   __is_exactly_cpp17_input_iterator<_InputIterator>::value,
294146035553Spatrick   typename basic_string<_CharT, _Traits, _Allocator>::iterator
2942037e7968Spatrick>
294346035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last)
294446035553Spatrick{
2945*4bdff4beSrobert  _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
294646035553Spatrick                       "string::insert(iterator, range) called with an iterator not"
294746035553Spatrick                       " referring to this string");
294846035553Spatrick  const basic_string __temp(__first, __last, __alloc());
294946035553Spatrick  return insert(__pos, __temp.data(), __temp.data() + __temp.size());
295046035553Spatrick}
295146035553Spatrick
295246035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
295346035553Spatricktemplate<class _ForwardIterator>
2954*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
2955*4bdff4beSrobert__enable_if_t
295646035553Spatrick<
295776d0caaeSpatrick    __is_cpp17_forward_iterator<_ForwardIterator>::value,
295846035553Spatrick    typename basic_string<_CharT, _Traits, _Allocator>::iterator
2959037e7968Spatrick>
296046035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last)
296146035553Spatrick{
2962*4bdff4beSrobert    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
2963*4bdff4beSrobert                         "string::insert(iterator, range) called with an iterator not referring to this string");
2964*4bdff4beSrobert
296546035553Spatrick    size_type __ip = static_cast<size_type>(__pos - begin());
2966*4bdff4beSrobert    size_type __n = static_cast<size_type>(std::distance(__first, __last));
2967*4bdff4beSrobert    if (__n == 0)
2968*4bdff4beSrobert        return begin() + __ip;
2969*4bdff4beSrobert
2970*4bdff4beSrobert    if (__string_is_trivial_iterator<_ForwardIterator>::value && !__addr_in_range(*__first))
297146035553Spatrick    {
2972*4bdff4beSrobert        return __insert_from_safe_copy(__n, __ip, __first, __last);
297346035553Spatrick    }
297476d0caaeSpatrick    else
297576d0caaeSpatrick    {
297676d0caaeSpatrick        const basic_string __temp(__first, __last, __alloc());
2977*4bdff4beSrobert        return __insert_from_safe_copy(__n, __ip, __temp.begin(), __temp.end());
297876d0caaeSpatrick    }
297976d0caaeSpatrick}
298046035553Spatrick
298146035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
2982*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
298346035553Spatrickbasic_string<_CharT, _Traits, _Allocator>&
298446035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str,
298546035553Spatrick                                                  size_type __pos2, size_type __n)
298646035553Spatrick{
298746035553Spatrick    size_type __str_sz = __str.size();
298846035553Spatrick    if (__pos2 > __str_sz)
2989*4bdff4beSrobert        __throw_out_of_range();
2990*4bdff4beSrobert    return insert(__pos1, __str.data() + __pos2, std::min(__n, __str_sz - __pos2));
299146035553Spatrick}
299246035553Spatrick
299346035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
299446035553Spatricktemplate <class _Tp>
2995*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
2996*4bdff4beSrobert__enable_if_t
299746035553Spatrick<
2998037e7968Spatrick    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value  && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
299946035553Spatrick    basic_string<_CharT, _Traits, _Allocator>&
3000037e7968Spatrick>
300146035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& __t,
300246035553Spatrick                                                  size_type __pos2, size_type __n)
300346035553Spatrick{
300446035553Spatrick    __self_view __sv = __t;
300546035553Spatrick    size_type __str_sz = __sv.size();
300646035553Spatrick    if (__pos2 > __str_sz)
3007*4bdff4beSrobert        __throw_out_of_range();
3008*4bdff4beSrobert    return insert(__pos1, __sv.data() + __pos2, std::min(__n, __str_sz - __pos2));
300946035553Spatrick}
301046035553Spatrick
301146035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
3012*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
301346035553Spatrickbasic_string<_CharT, _Traits, _Allocator>&
301446035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s)
301546035553Spatrick{
301646035553Spatrick    _LIBCPP_ASSERT(__s != nullptr, "string::insert received nullptr");
301746035553Spatrick    return insert(__pos, __s, traits_type::length(__s));
301846035553Spatrick}
301946035553Spatrick
302046035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
3021*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
302246035553Spatricktypename basic_string<_CharT, _Traits, _Allocator>::iterator
302346035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c)
302446035553Spatrick{
3025*4bdff4beSrobert    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
3026*4bdff4beSrobert                         "string::insert(iterator, character) called with an iterator not"
3027*4bdff4beSrobert                         " referring to this string");
3028*4bdff4beSrobert
302946035553Spatrick    size_type __ip = static_cast<size_type>(__pos - begin());
303046035553Spatrick    size_type __sz = size();
303146035553Spatrick    size_type __cap = capacity();
303246035553Spatrick    value_type* __p;
303346035553Spatrick    if (__cap == __sz)
303446035553Spatrick    {
303546035553Spatrick        __grow_by(__cap, 1, __sz, __ip, 0, 1);
3036*4bdff4beSrobert        __p = std::__to_address(__get_long_pointer());
303746035553Spatrick    }
303846035553Spatrick    else
303946035553Spatrick    {
3040*4bdff4beSrobert        __p = std::__to_address(__get_pointer());
304146035553Spatrick        size_type __n_move = __sz - __ip;
304246035553Spatrick        if (__n_move != 0)
304346035553Spatrick            traits_type::move(__p + __ip + 1, __p + __ip, __n_move);
304446035553Spatrick    }
304546035553Spatrick    traits_type::assign(__p[__ip], __c);
304646035553Spatrick    traits_type::assign(__p[++__sz], value_type());
304746035553Spatrick    __set_size(__sz);
304846035553Spatrick    return begin() + static_cast<difference_type>(__ip);
304946035553Spatrick}
305046035553Spatrick
305146035553Spatrick// replace
305246035553Spatrick
305346035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
3054*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
305546035553Spatrickbasic_string<_CharT, _Traits, _Allocator>&
305646035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2)
305746035553Spatrick    _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
305846035553Spatrick{
305946035553Spatrick    _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::replace received nullptr");
306046035553Spatrick    size_type __sz = size();
306146035553Spatrick    if (__pos > __sz)
3062*4bdff4beSrobert        __throw_out_of_range();
3063*4bdff4beSrobert    __n1 = std::min(__n1, __sz - __pos);
306446035553Spatrick    size_type __cap = capacity();
306546035553Spatrick    if (__cap - __sz + __n1 >= __n2)
306646035553Spatrick    {
3067*4bdff4beSrobert        if (__libcpp_is_constant_evaluated()) {
3068*4bdff4beSrobert            __grow_by_and_replace(__cap, 0, __sz, __pos, __n1, __n2, __s);
3069*4bdff4beSrobert            return *this;
3070*4bdff4beSrobert        }
3071*4bdff4beSrobert        value_type* __p = std::__to_address(__get_pointer());
307246035553Spatrick        if (__n1 != __n2)
307346035553Spatrick        {
307446035553Spatrick            size_type __n_move = __sz - __pos - __n1;
307546035553Spatrick            if (__n_move != 0)
307646035553Spatrick            {
307746035553Spatrick                if (__n1 > __n2)
307846035553Spatrick                {
307946035553Spatrick                    traits_type::move(__p + __pos, __s, __n2);
308046035553Spatrick                    traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
3081*4bdff4beSrobert                    return __null_terminate_at(__p, __sz + (__n2 - __n1));
308246035553Spatrick                }
308346035553Spatrick                if (__p + __pos < __s && __s < __p + __sz)
308446035553Spatrick                {
308546035553Spatrick                    if (__p + __pos + __n1 <= __s)
308646035553Spatrick                        __s += __n2 - __n1;
308746035553Spatrick                    else // __p + __pos < __s < __p + __pos + __n1
308846035553Spatrick                    {
308946035553Spatrick                        traits_type::move(__p + __pos, __s, __n1);
309046035553Spatrick                        __pos += __n1;
309146035553Spatrick                        __s += __n2;
309246035553Spatrick                        __n2 -= __n1;
309346035553Spatrick                        __n1 = 0;
309446035553Spatrick                    }
309546035553Spatrick                }
309646035553Spatrick                traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
309746035553Spatrick            }
309846035553Spatrick        }
309946035553Spatrick        traits_type::move(__p + __pos, __s, __n2);
3100*4bdff4beSrobert        return __null_terminate_at(__p, __sz + (__n2 - __n1));
310146035553Spatrick    }
310246035553Spatrick    else
310346035553Spatrick        __grow_by_and_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2, __s);
310446035553Spatrick    return *this;
310546035553Spatrick}
310646035553Spatrick
310746035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
3108*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
310946035553Spatrickbasic_string<_CharT, _Traits, _Allocator>&
311046035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, size_type __n2, value_type __c)
311146035553Spatrick{
311246035553Spatrick    size_type __sz = size();
311346035553Spatrick    if (__pos > __sz)
3114*4bdff4beSrobert        __throw_out_of_range();
3115*4bdff4beSrobert    __n1 = std::min(__n1, __sz - __pos);
311646035553Spatrick    size_type __cap = capacity();
311746035553Spatrick    value_type* __p;
311846035553Spatrick    if (__cap - __sz + __n1 >= __n2)
311946035553Spatrick    {
3120*4bdff4beSrobert        __p = std::__to_address(__get_pointer());
312146035553Spatrick        if (__n1 != __n2)
312246035553Spatrick        {
312346035553Spatrick            size_type __n_move = __sz - __pos - __n1;
312446035553Spatrick            if (__n_move != 0)
312546035553Spatrick                traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
312646035553Spatrick        }
312746035553Spatrick    }
312846035553Spatrick    else
312946035553Spatrick    {
313046035553Spatrick        __grow_by(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2);
3131*4bdff4beSrobert        __p = std::__to_address(__get_long_pointer());
313246035553Spatrick    }
313346035553Spatrick    traits_type::assign(__p + __pos, __n2, __c);
3134*4bdff4beSrobert    return __null_terminate_at(__p, __sz - (__n1 - __n2));
313546035553Spatrick}
313646035553Spatrick
313746035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
313846035553Spatricktemplate<class _InputIterator>
3139*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
3140*4bdff4beSrobert__enable_if_t
314146035553Spatrick<
314246035553Spatrick    __is_cpp17_input_iterator<_InputIterator>::value,
314346035553Spatrick    basic_string<_CharT, _Traits, _Allocator>&
3144037e7968Spatrick>
314546035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2,
314646035553Spatrick                                                   _InputIterator __j1, _InputIterator __j2)
314746035553Spatrick{
314846035553Spatrick    const basic_string __temp(__j1, __j2, __alloc());
3149*4bdff4beSrobert    return replace(__i1, __i2, __temp);
315046035553Spatrick}
315146035553Spatrick
315246035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
3153*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
315446035553Spatrickbasic_string<_CharT, _Traits, _Allocator>&
315546035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str,
315646035553Spatrick                                                   size_type __pos2, size_type __n2)
315746035553Spatrick{
315846035553Spatrick    size_type __str_sz = __str.size();
315946035553Spatrick    if (__pos2 > __str_sz)
3160*4bdff4beSrobert        __throw_out_of_range();
3161*4bdff4beSrobert    return replace(__pos1, __n1, __str.data() + __pos2, std::min(__n2, __str_sz - __pos2));
316246035553Spatrick}
316346035553Spatrick
316446035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
316546035553Spatricktemplate <class _Tp>
3166*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
3167*4bdff4beSrobert__enable_if_t
316846035553Spatrick<
3169037e7968Spatrick    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
317046035553Spatrick    basic_string<_CharT, _Traits, _Allocator>&
3171037e7968Spatrick>
317246035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const _Tp& __t,
317346035553Spatrick                                                   size_type __pos2, size_type __n2)
317446035553Spatrick{
317546035553Spatrick    __self_view __sv = __t;
317646035553Spatrick    size_type __str_sz = __sv.size();
317746035553Spatrick    if (__pos2 > __str_sz)
3178*4bdff4beSrobert        __throw_out_of_range();
3179*4bdff4beSrobert    return replace(__pos1, __n1, __sv.data() + __pos2, std::min(__n2, __str_sz - __pos2));
318046035553Spatrick}
318146035553Spatrick
318246035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
3183*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
318446035553Spatrickbasic_string<_CharT, _Traits, _Allocator>&
318546035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s)
318646035553Spatrick{
318746035553Spatrick    _LIBCPP_ASSERT(__s != nullptr, "string::replace received nullptr");
318846035553Spatrick    return replace(__pos, __n1, __s, traits_type::length(__s));
318946035553Spatrick}
319046035553Spatrick
319146035553Spatrick// erase
319246035553Spatrick
3193037e7968Spatrick// 'externally instantiated' erase() implementation, called when __n != npos.
3194037e7968Spatrick// Does not check __pos against size()
319546035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
3196*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
3197037e7968Spatrickvoid
3198037e7968Spatrickbasic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move(
3199037e7968Spatrick    size_type __pos, size_type __n)
320046035553Spatrick{
320146035553Spatrick    if (__n)
320246035553Spatrick    {
3203037e7968Spatrick        size_type __sz = size();
3204*4bdff4beSrobert        value_type* __p = std::__to_address(__get_pointer());
3205*4bdff4beSrobert        __n = std::min(__n, __sz - __pos);
320646035553Spatrick        size_type __n_move = __sz - __pos - __n;
320746035553Spatrick        if (__n_move != 0)
320846035553Spatrick            traits_type::move(__p + __pos, __p + __pos + __n, __n_move);
3209*4bdff4beSrobert        __null_terminate_at(__p, __sz - __n);
321046035553Spatrick    }
3211037e7968Spatrick}
3212037e7968Spatrick
3213037e7968Spatricktemplate <class _CharT, class _Traits, class _Allocator>
3214*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
3215037e7968Spatrickbasic_string<_CharT, _Traits, _Allocator>&
3216037e7968Spatrickbasic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos,
3217037e7968Spatrick                                                 size_type __n) {
3218*4bdff4beSrobert  if (__pos > size())
3219*4bdff4beSrobert    __throw_out_of_range();
3220037e7968Spatrick  if (__n == npos) {
3221037e7968Spatrick    __erase_to_end(__pos);
3222037e7968Spatrick  } else {
3223037e7968Spatrick    __erase_external_with_move(__pos, __n);
3224037e7968Spatrick  }
322546035553Spatrick  return *this;
322646035553Spatrick}
322746035553Spatrick
322846035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
3229*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
323046035553Spatricktypename basic_string<_CharT, _Traits, _Allocator>::iterator
323146035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos)
323246035553Spatrick{
3233*4bdff4beSrobert  _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
323446035553Spatrick                       "string::erase(iterator) called with an iterator not"
323546035553Spatrick                       " referring to this string");
3236*4bdff4beSrobert
3237*4bdff4beSrobert  _LIBCPP_ASSERT(__pos != end(), "string::erase(iterator) called with a non-dereferenceable iterator");
323846035553Spatrick  iterator __b = begin();
323946035553Spatrick  size_type __r = static_cast<size_type>(__pos - __b);
324046035553Spatrick  erase(__r, 1);
324146035553Spatrick  return __b + static_cast<difference_type>(__r);
324246035553Spatrick}
324346035553Spatrick
324446035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
3245*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
324646035553Spatricktypename basic_string<_CharT, _Traits, _Allocator>::iterator
324746035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last)
324846035553Spatrick{
3249*4bdff4beSrobert  _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this,
325046035553Spatrick                       "string::erase(iterator,  iterator) called with an iterator not"
325146035553Spatrick                       " referring to this string");
3252*4bdff4beSrobert
325346035553Spatrick  _LIBCPP_ASSERT(__first <= __last, "string::erase(first, last) called with invalid range");
325446035553Spatrick  iterator __b = begin();
325546035553Spatrick  size_type __r = static_cast<size_type>(__first - __b);
325646035553Spatrick  erase(__r, static_cast<size_type>(__last - __first));
325746035553Spatrick  return __b + static_cast<difference_type>(__r);
325846035553Spatrick}
325946035553Spatrick
326046035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
3261*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
326246035553Spatrickvoid
326346035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::pop_back()
326446035553Spatrick{
326546035553Spatrick    _LIBCPP_ASSERT(!empty(), "string::pop_back(): string is already empty");
3266*4bdff4beSrobert    __erase_to_end(size() - 1);
326746035553Spatrick}
326846035553Spatrick
326946035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
3270*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
327146035553Spatrickvoid
327246035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT
327346035553Spatrick{
3274*4bdff4beSrobert    std::__debug_db_invalidate_all(this);
327546035553Spatrick    if (__is_long())
327646035553Spatrick    {
327746035553Spatrick        traits_type::assign(*__get_long_pointer(), value_type());
327846035553Spatrick        __set_long_size(0);
327946035553Spatrick    }
328046035553Spatrick    else
328146035553Spatrick    {
328246035553Spatrick        traits_type::assign(*__get_short_pointer(), value_type());
328346035553Spatrick        __set_short_size(0);
328446035553Spatrick    }
328546035553Spatrick}
328646035553Spatrick
328746035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
3288*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
328946035553Spatrickvoid
329046035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c)
329146035553Spatrick{
329246035553Spatrick    size_type __sz = size();
329346035553Spatrick    if (__n > __sz)
329446035553Spatrick        append(__n - __sz, __c);
329546035553Spatrick    else
329646035553Spatrick        __erase_to_end(__n);
329746035553Spatrick}
329846035553Spatrick
329946035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
3300*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20 inline void
330146035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::__resize_default_init(size_type __n)
330246035553Spatrick{
330346035553Spatrick    size_type __sz = size();
330446035553Spatrick    if (__n > __sz) {
330546035553Spatrick       __append_default_init(__n - __sz);
330646035553Spatrick    } else
330746035553Spatrick        __erase_to_end(__n);
330846035553Spatrick}
330946035553Spatrick
331046035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
3311*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
331246035553Spatrickvoid
331376d0caaeSpatrickbasic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacity)
331446035553Spatrick{
331576d0caaeSpatrick    if (__requested_capacity > max_size())
3316*4bdff4beSrobert        __throw_length_error();
331776d0caaeSpatrick
3318*4bdff4beSrobert    // Make sure reserve(n) never shrinks. This is technically only required in C++20
3319*4bdff4beSrobert    // and later (since P0966R1), however we provide consistent behavior in all Standard
3320*4bdff4beSrobert    // modes because this function is instantiated in the shared library.
3321*4bdff4beSrobert    if (__requested_capacity <= capacity())
3322*4bdff4beSrobert        return;
332376d0caaeSpatrick
3324*4bdff4beSrobert    size_type __target_capacity = std::max(__requested_capacity, size());
332576d0caaeSpatrick    __target_capacity = __recommend(__target_capacity);
332676d0caaeSpatrick    if (__target_capacity == capacity()) return;
332776d0caaeSpatrick
332876d0caaeSpatrick    __shrink_or_extend(__target_capacity);
332976d0caaeSpatrick}
333076d0caaeSpatrick
333176d0caaeSpatricktemplate <class _CharT, class _Traits, class _Allocator>
3332*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
333376d0caaeSpatrickvoid
333476d0caaeSpatrickbasic_string<_CharT, _Traits, _Allocator>::shrink_to_fit() _NOEXCEPT
333576d0caaeSpatrick{
333676d0caaeSpatrick    size_type __target_capacity = __recommend(size());
333776d0caaeSpatrick    if (__target_capacity == capacity()) return;
333876d0caaeSpatrick
333976d0caaeSpatrick    __shrink_or_extend(__target_capacity);
334076d0caaeSpatrick}
334176d0caaeSpatrick
334276d0caaeSpatricktemplate <class _CharT, class _Traits, class _Allocator>
3343*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
334476d0caaeSpatrickvoid
334576d0caaeSpatrickbasic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target_capacity)
334676d0caaeSpatrick{
334746035553Spatrick    size_type __cap = capacity();
334846035553Spatrick    size_type __sz = size();
334976d0caaeSpatrick
335046035553Spatrick    pointer __new_data, __p;
335146035553Spatrick    bool __was_long, __now_long;
3352*4bdff4beSrobert    if (__fits_in_sso(__target_capacity))
335346035553Spatrick    {
335446035553Spatrick        __was_long = true;
335546035553Spatrick        __now_long = false;
335646035553Spatrick        __new_data = __get_short_pointer();
335746035553Spatrick        __p = __get_long_pointer();
335846035553Spatrick    }
335946035553Spatrick    else
336046035553Spatrick    {
3361*4bdff4beSrobert        if (__target_capacity > __cap) {
3362*4bdff4beSrobert            auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1);
3363*4bdff4beSrobert            __new_data = __allocation.ptr;
3364*4bdff4beSrobert            __target_capacity = __allocation.count - 1;
3365*4bdff4beSrobert        }
336646035553Spatrick        else
336746035553Spatrick        {
336846035553Spatrick        #ifndef _LIBCPP_NO_EXCEPTIONS
336946035553Spatrick            try
337046035553Spatrick            {
337146035553Spatrick        #endif // _LIBCPP_NO_EXCEPTIONS
3372*4bdff4beSrobert                auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1);
3373*4bdff4beSrobert                __new_data = __allocation.ptr;
3374*4bdff4beSrobert                __target_capacity = __allocation.count - 1;
337546035553Spatrick        #ifndef _LIBCPP_NO_EXCEPTIONS
337646035553Spatrick            }
337746035553Spatrick            catch (...)
337846035553Spatrick            {
337946035553Spatrick                return;
338046035553Spatrick            }
338146035553Spatrick        #else  // _LIBCPP_NO_EXCEPTIONS
338246035553Spatrick            if (__new_data == nullptr)
338346035553Spatrick                return;
338446035553Spatrick        #endif // _LIBCPP_NO_EXCEPTIONS
338546035553Spatrick        }
3386*4bdff4beSrobert        __begin_lifetime(__new_data, __target_capacity + 1);
338746035553Spatrick        __now_long = true;
338846035553Spatrick        __was_long = __is_long();
338946035553Spatrick        __p = __get_pointer();
339046035553Spatrick    }
3391*4bdff4beSrobert    traits_type::copy(std::__to_address(__new_data),
3392*4bdff4beSrobert                      std::__to_address(__p), size()+1);
339346035553Spatrick    if (__was_long)
339446035553Spatrick        __alloc_traits::deallocate(__alloc(), __p, __cap+1);
339546035553Spatrick    if (__now_long)
339646035553Spatrick    {
339776d0caaeSpatrick        __set_long_cap(__target_capacity+1);
339846035553Spatrick        __set_long_size(__sz);
339946035553Spatrick        __set_long_pointer(__new_data);
340046035553Spatrick    }
340146035553Spatrick    else
340246035553Spatrick        __set_short_size(__sz);
3403*4bdff4beSrobert    std::__debug_db_invalidate_all(this);
340446035553Spatrick}
340546035553Spatrick
340646035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
3407*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
340846035553Spatricktypename basic_string<_CharT, _Traits, _Allocator>::const_reference
340946035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const
341046035553Spatrick{
341146035553Spatrick    if (__n >= size())
3412*4bdff4beSrobert        __throw_out_of_range();
341346035553Spatrick    return (*this)[__n];
341446035553Spatrick}
341546035553Spatrick
341646035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
3417*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
341846035553Spatricktypename basic_string<_CharT, _Traits, _Allocator>::reference
341946035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::at(size_type __n)
342046035553Spatrick{
342146035553Spatrick    if (__n >= size())
3422*4bdff4beSrobert        __throw_out_of_range();
342346035553Spatrick    return (*this)[__n];
342446035553Spatrick}
342546035553Spatrick
342646035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
3427*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
342846035553Spatricktypename basic_string<_CharT, _Traits, _Allocator>::size_type
342946035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n, size_type __pos) const
343046035553Spatrick{
343146035553Spatrick    size_type __sz = size();
343246035553Spatrick    if (__pos > __sz)
3433*4bdff4beSrobert        __throw_out_of_range();
3434*4bdff4beSrobert    size_type __rlen = std::min(__n, __sz - __pos);
343546035553Spatrick    traits_type::copy(__s, data() + __pos, __rlen);
343646035553Spatrick    return __rlen;
343746035553Spatrick}
343846035553Spatrick
343946035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
3440*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
344146035553Spatrickvoid
344246035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str)
344346035553Spatrick#if _LIBCPP_STD_VER >= 14
344446035553Spatrick        _NOEXCEPT
344546035553Spatrick#else
344646035553Spatrick        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
344746035553Spatrick                    __is_nothrow_swappable<allocator_type>::value)
344846035553Spatrick#endif
344946035553Spatrick{
345046035553Spatrick    if (!__is_long())
3451*4bdff4beSrobert        std::__debug_db_invalidate_all(this);
345246035553Spatrick    if (!__str.__is_long())
3453*4bdff4beSrobert        std::__debug_db_invalidate_all(&__str);
3454*4bdff4beSrobert    std::__debug_db_swap(this, &__str);
3455*4bdff4beSrobert
345646035553Spatrick    _LIBCPP_ASSERT(
345746035553Spatrick        __alloc_traits::propagate_on_container_swap::value ||
345846035553Spatrick        __alloc_traits::is_always_equal::value ||
345946035553Spatrick        __alloc() == __str.__alloc(), "swapping non-equal allocators");
3460*4bdff4beSrobert    std::swap(__r_.first(), __str.__r_.first());
3461*4bdff4beSrobert    std::__swap_allocator(__alloc(), __str.__alloc());
346246035553Spatrick}
346346035553Spatrick
346446035553Spatrick// find
346546035553Spatrick
346646035553Spatricktemplate <class _Traits>
346746035553Spatrickstruct _LIBCPP_HIDDEN __traits_eq
346846035553Spatrick{
346946035553Spatrick    typedef typename _Traits::char_type char_type;
3470*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI
347146035553Spatrick    bool operator()(const char_type& __x, const char_type& __y) _NOEXCEPT
347246035553Spatrick        {return _Traits::eq(__x, __y);}
347346035553Spatrick};
347446035553Spatrick
347546035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
3476*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
347746035553Spatricktypename basic_string<_CharT, _Traits, _Allocator>::size_type
347846035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
347946035553Spatrick                                                size_type __pos,
348046035553Spatrick                                                size_type __n) const _NOEXCEPT
348146035553Spatrick{
348246035553Spatrick    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find(): received nullptr");
3483*4bdff4beSrobert    return std::__str_find<value_type, size_type, traits_type, npos>
348446035553Spatrick        (data(), size(), __s, __pos, __n);
348546035553Spatrick}
348646035553Spatrick
348746035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
3488*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
348946035553Spatricktypename basic_string<_CharT, _Traits, _Allocator>::size_type
349046035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str,
349146035553Spatrick                                                size_type __pos) const _NOEXCEPT
349246035553Spatrick{
3493*4bdff4beSrobert    return std::__str_find<value_type, size_type, traits_type, npos>
349446035553Spatrick        (data(), size(), __str.data(), __pos, __str.size());
349546035553Spatrick}
349646035553Spatrick
349746035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
349846035553Spatricktemplate <class _Tp>
3499*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
3500*4bdff4beSrobert__enable_if_t
350146035553Spatrick<
350246035553Spatrick    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
350346035553Spatrick    typename basic_string<_CharT, _Traits, _Allocator>::size_type
3504037e7968Spatrick>
350546035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::find(const _Tp &__t,
350676d0caaeSpatrick                                                size_type __pos) const _NOEXCEPT
350746035553Spatrick{
350846035553Spatrick    __self_view __sv = __t;
3509*4bdff4beSrobert    return std::__str_find<value_type, size_type, traits_type, npos>
351046035553Spatrick        (data(), size(), __sv.data(), __pos, __sv.size());
351146035553Spatrick}
351246035553Spatrick
351346035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
3514*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
351546035553Spatricktypename basic_string<_CharT, _Traits, _Allocator>::size_type
351646035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
351746035553Spatrick                                                size_type __pos) const _NOEXCEPT
351846035553Spatrick{
351946035553Spatrick    _LIBCPP_ASSERT(__s != nullptr, "string::find(): received nullptr");
3520*4bdff4beSrobert    return std::__str_find<value_type, size_type, traits_type, npos>
352146035553Spatrick        (data(), size(), __s, __pos, traits_type::length(__s));
352246035553Spatrick}
352346035553Spatrick
352446035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
3525*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
352646035553Spatricktypename basic_string<_CharT, _Traits, _Allocator>::size_type
352746035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::find(value_type __c,
352846035553Spatrick                                                size_type __pos) const _NOEXCEPT
352946035553Spatrick{
3530*4bdff4beSrobert    return std::__str_find<value_type, size_type, traits_type, npos>
353146035553Spatrick        (data(), size(), __c, __pos);
353246035553Spatrick}
353346035553Spatrick
353446035553Spatrick// rfind
353546035553Spatrick
353646035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
3537*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
353846035553Spatricktypename basic_string<_CharT, _Traits, _Allocator>::size_type
353946035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
354046035553Spatrick                                                 size_type __pos,
354146035553Spatrick                                                 size_type __n) const _NOEXCEPT
354246035553Spatrick{
354346035553Spatrick    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::rfind(): received nullptr");
3544*4bdff4beSrobert    return std::__str_rfind<value_type, size_type, traits_type, npos>
354546035553Spatrick        (data(), size(), __s, __pos, __n);
354646035553Spatrick}
354746035553Spatrick
354846035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
3549*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
355046035553Spatricktypename basic_string<_CharT, _Traits, _Allocator>::size_type
355146035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str,
355246035553Spatrick                                                 size_type __pos) const _NOEXCEPT
355346035553Spatrick{
3554*4bdff4beSrobert    return std::__str_rfind<value_type, size_type, traits_type, npos>
355546035553Spatrick        (data(), size(), __str.data(), __pos, __str.size());
355646035553Spatrick}
355746035553Spatrick
355846035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
355946035553Spatricktemplate <class _Tp>
3560*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
3561*4bdff4beSrobert__enable_if_t
356246035553Spatrick<
356346035553Spatrick    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
356446035553Spatrick    typename basic_string<_CharT, _Traits, _Allocator>::size_type
3565037e7968Spatrick>
356646035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::rfind(const _Tp& __t,
356776d0caaeSpatrick                                                size_type __pos) const _NOEXCEPT
356846035553Spatrick{
356946035553Spatrick    __self_view __sv = __t;
3570*4bdff4beSrobert    return std::__str_rfind<value_type, size_type, traits_type, npos>
357146035553Spatrick        (data(), size(), __sv.data(), __pos, __sv.size());
357246035553Spatrick}
357346035553Spatrick
357446035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
3575*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
357646035553Spatricktypename basic_string<_CharT, _Traits, _Allocator>::size_type
357746035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
357846035553Spatrick                                                 size_type __pos) const _NOEXCEPT
357946035553Spatrick{
358046035553Spatrick    _LIBCPP_ASSERT(__s != nullptr, "string::rfind(): received nullptr");
3581*4bdff4beSrobert    return std::__str_rfind<value_type, size_type, traits_type, npos>
358246035553Spatrick        (data(), size(), __s, __pos, traits_type::length(__s));
358346035553Spatrick}
358446035553Spatrick
358546035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
3586*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
358746035553Spatricktypename basic_string<_CharT, _Traits, _Allocator>::size_type
358846035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c,
358946035553Spatrick                                                 size_type __pos) const _NOEXCEPT
359046035553Spatrick{
3591*4bdff4beSrobert    return std::__str_rfind<value_type, size_type, traits_type, npos>
359246035553Spatrick        (data(), size(), __c, __pos);
359346035553Spatrick}
359446035553Spatrick
359546035553Spatrick// find_first_of
359646035553Spatrick
359746035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
3598*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
359946035553Spatricktypename basic_string<_CharT, _Traits, _Allocator>::size_type
360046035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
360146035553Spatrick                                                         size_type __pos,
360246035553Spatrick                                                         size_type __n) const _NOEXCEPT
360346035553Spatrick{
360446035553Spatrick    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr");
3605*4bdff4beSrobert    return std::__str_find_first_of<value_type, size_type, traits_type, npos>
360646035553Spatrick        (data(), size(), __s, __pos, __n);
360746035553Spatrick}
360846035553Spatrick
360946035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
3610*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
361146035553Spatricktypename basic_string<_CharT, _Traits, _Allocator>::size_type
361246035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str,
361346035553Spatrick                                                         size_type __pos) const _NOEXCEPT
361446035553Spatrick{
3615*4bdff4beSrobert    return std::__str_find_first_of<value_type, size_type, traits_type, npos>
361646035553Spatrick        (data(), size(), __str.data(), __pos, __str.size());
361746035553Spatrick}
361846035553Spatrick
361946035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
362046035553Spatricktemplate <class _Tp>
3621*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
3622*4bdff4beSrobert__enable_if_t
362346035553Spatrick<
362446035553Spatrick    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
362546035553Spatrick    typename basic_string<_CharT, _Traits, _Allocator>::size_type
3626037e7968Spatrick>
362746035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::find_first_of(const _Tp& __t,
362876d0caaeSpatrick                                                size_type __pos) const _NOEXCEPT
362946035553Spatrick{
363046035553Spatrick    __self_view __sv = __t;
3631*4bdff4beSrobert    return std::__str_find_first_of<value_type, size_type, traits_type, npos>
363246035553Spatrick        (data(), size(), __sv.data(), __pos, __sv.size());
363346035553Spatrick}
363446035553Spatrick
363546035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
3636*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
363746035553Spatricktypename basic_string<_CharT, _Traits, _Allocator>::size_type
363846035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
363946035553Spatrick                                                         size_type __pos) const _NOEXCEPT
364046035553Spatrick{
364146035553Spatrick    _LIBCPP_ASSERT(__s != nullptr, "string::find_first_of(): received nullptr");
3642*4bdff4beSrobert    return std::__str_find_first_of<value_type, size_type, traits_type, npos>
364346035553Spatrick        (data(), size(), __s, __pos, traits_type::length(__s));
364446035553Spatrick}
364546035553Spatrick
364646035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
3647*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
364846035553Spatricktypename basic_string<_CharT, _Traits, _Allocator>::size_type
364946035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c,
365046035553Spatrick                                                         size_type __pos) const _NOEXCEPT
365146035553Spatrick{
365246035553Spatrick    return find(__c, __pos);
365346035553Spatrick}
365446035553Spatrick
365546035553Spatrick// find_last_of
365646035553Spatrick
365746035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
3658*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
365946035553Spatricktypename basic_string<_CharT, _Traits, _Allocator>::size_type
366046035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
366146035553Spatrick                                                        size_type __pos,
366246035553Spatrick                                                        size_type __n) const _NOEXCEPT
366346035553Spatrick{
366446035553Spatrick    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr");
3665*4bdff4beSrobert    return std::__str_find_last_of<value_type, size_type, traits_type, npos>
366646035553Spatrick        (data(), size(), __s, __pos, __n);
366746035553Spatrick}
366846035553Spatrick
366946035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
3670*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
367146035553Spatricktypename basic_string<_CharT, _Traits, _Allocator>::size_type
367246035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str,
367346035553Spatrick                                                        size_type __pos) const _NOEXCEPT
367446035553Spatrick{
3675*4bdff4beSrobert    return std::__str_find_last_of<value_type, size_type, traits_type, npos>
367646035553Spatrick        (data(), size(), __str.data(), __pos, __str.size());
367746035553Spatrick}
367846035553Spatrick
367946035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
368046035553Spatricktemplate <class _Tp>
3681*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
3682*4bdff4beSrobert__enable_if_t
368346035553Spatrick<
368446035553Spatrick    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
368546035553Spatrick    typename basic_string<_CharT, _Traits, _Allocator>::size_type
3686037e7968Spatrick>
368746035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::find_last_of(const _Tp& __t,
368876d0caaeSpatrick                                                size_type __pos) const _NOEXCEPT
368946035553Spatrick{
369046035553Spatrick    __self_view __sv = __t;
3691*4bdff4beSrobert    return std::__str_find_last_of<value_type, size_type, traits_type, npos>
369246035553Spatrick        (data(), size(), __sv.data(), __pos, __sv.size());
369346035553Spatrick}
369446035553Spatrick
369546035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
3696*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
369746035553Spatricktypename basic_string<_CharT, _Traits, _Allocator>::size_type
369846035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
369946035553Spatrick                                                        size_type __pos) const _NOEXCEPT
370046035553Spatrick{
370146035553Spatrick    _LIBCPP_ASSERT(__s != nullptr, "string::find_last_of(): received nullptr");
3702*4bdff4beSrobert    return std::__str_find_last_of<value_type, size_type, traits_type, npos>
370346035553Spatrick        (data(), size(), __s, __pos, traits_type::length(__s));
370446035553Spatrick}
370546035553Spatrick
370646035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
3707*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
370846035553Spatricktypename basic_string<_CharT, _Traits, _Allocator>::size_type
370946035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c,
371046035553Spatrick                                                        size_type __pos) const _NOEXCEPT
371146035553Spatrick{
371246035553Spatrick    return rfind(__c, __pos);
371346035553Spatrick}
371446035553Spatrick
371546035553Spatrick// find_first_not_of
371646035553Spatrick
371746035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
3718*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
371946035553Spatricktypename basic_string<_CharT, _Traits, _Allocator>::size_type
372046035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s,
372146035553Spatrick                                                             size_type __pos,
372246035553Spatrick                                                             size_type __n) const _NOEXCEPT
372346035553Spatrick{
372446035553Spatrick    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr");
3725*4bdff4beSrobert    return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
372646035553Spatrick        (data(), size(), __s, __pos, __n);
372746035553Spatrick}
372846035553Spatrick
372946035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
3730*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
373146035553Spatricktypename basic_string<_CharT, _Traits, _Allocator>::size_type
373246035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string& __str,
373346035553Spatrick                                                             size_type __pos) const _NOEXCEPT
373446035553Spatrick{
3735*4bdff4beSrobert    return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
373646035553Spatrick        (data(), size(), __str.data(), __pos, __str.size());
373746035553Spatrick}
373846035553Spatrick
373946035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
374046035553Spatricktemplate <class _Tp>
3741*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
3742*4bdff4beSrobert__enable_if_t
374346035553Spatrick<
374446035553Spatrick    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
374546035553Spatrick    typename basic_string<_CharT, _Traits, _Allocator>::size_type
3746037e7968Spatrick>
374746035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const _Tp& __t,
374876d0caaeSpatrick                                                size_type __pos) const _NOEXCEPT
374946035553Spatrick{
375046035553Spatrick    __self_view __sv = __t;
3751*4bdff4beSrobert    return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
375246035553Spatrick        (data(), size(), __sv.data(), __pos, __sv.size());
375346035553Spatrick}
375446035553Spatrick
375546035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
3756*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
375746035553Spatricktypename basic_string<_CharT, _Traits, _Allocator>::size_type
375846035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s,
375946035553Spatrick                                                             size_type __pos) const _NOEXCEPT
376046035553Spatrick{
376146035553Spatrick    _LIBCPP_ASSERT(__s != nullptr, "string::find_first_not_of(): received nullptr");
3762*4bdff4beSrobert    return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
376346035553Spatrick        (data(), size(), __s, __pos, traits_type::length(__s));
376446035553Spatrick}
376546035553Spatrick
376646035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
3767*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
376846035553Spatricktypename basic_string<_CharT, _Traits, _Allocator>::size_type
376946035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c,
377046035553Spatrick                                                             size_type __pos) const _NOEXCEPT
377146035553Spatrick{
3772*4bdff4beSrobert    return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
377346035553Spatrick        (data(), size(), __c, __pos);
377446035553Spatrick}
377546035553Spatrick
377646035553Spatrick// find_last_not_of
377746035553Spatrick
377846035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
3779*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
378046035553Spatricktypename basic_string<_CharT, _Traits, _Allocator>::size_type
378146035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s,
378246035553Spatrick                                                            size_type __pos,
378346035553Spatrick                                                            size_type __n) const _NOEXCEPT
378446035553Spatrick{
378546035553Spatrick    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr");
3786*4bdff4beSrobert    return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
378746035553Spatrick        (data(), size(), __s, __pos, __n);
378846035553Spatrick}
378946035553Spatrick
379046035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
3791*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
379246035553Spatricktypename basic_string<_CharT, _Traits, _Allocator>::size_type
379346035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string& __str,
379446035553Spatrick                                                            size_type __pos) const _NOEXCEPT
379546035553Spatrick{
3796*4bdff4beSrobert    return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
379746035553Spatrick        (data(), size(), __str.data(), __pos, __str.size());
379846035553Spatrick}
379946035553Spatrick
380046035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
380146035553Spatricktemplate <class _Tp>
3802*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
3803*4bdff4beSrobert__enable_if_t
380446035553Spatrick<
380546035553Spatrick    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
380646035553Spatrick    typename basic_string<_CharT, _Traits, _Allocator>::size_type
3807037e7968Spatrick>
380846035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const _Tp& __t,
380976d0caaeSpatrick                                                size_type __pos) const _NOEXCEPT
381046035553Spatrick{
381146035553Spatrick    __self_view __sv = __t;
3812*4bdff4beSrobert    return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
381346035553Spatrick        (data(), size(), __sv.data(), __pos, __sv.size());
381446035553Spatrick}
381546035553Spatrick
381646035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
3817*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
381846035553Spatricktypename basic_string<_CharT, _Traits, _Allocator>::size_type
381946035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s,
382046035553Spatrick                                                            size_type __pos) const _NOEXCEPT
382146035553Spatrick{
382246035553Spatrick    _LIBCPP_ASSERT(__s != nullptr, "string::find_last_not_of(): received nullptr");
3823*4bdff4beSrobert    return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
382446035553Spatrick        (data(), size(), __s, __pos, traits_type::length(__s));
382546035553Spatrick}
382646035553Spatrick
382746035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
3828*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
382946035553Spatricktypename basic_string<_CharT, _Traits, _Allocator>::size_type
383046035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c,
383146035553Spatrick                                                            size_type __pos) const _NOEXCEPT
383246035553Spatrick{
3833*4bdff4beSrobert    return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
383446035553Spatrick        (data(), size(), __c, __pos);
383546035553Spatrick}
383646035553Spatrick
383746035553Spatrick// compare
383846035553Spatrick
383946035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
384046035553Spatricktemplate <class _Tp>
3841*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
3842*4bdff4beSrobert__enable_if_t
384346035553Spatrick<
384446035553Spatrick    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
384546035553Spatrick    int
3846037e7968Spatrick>
384776d0caaeSpatrickbasic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const _NOEXCEPT
384846035553Spatrick{
384946035553Spatrick    __self_view __sv = __t;
385046035553Spatrick    size_t __lhs_sz = size();
385146035553Spatrick    size_t __rhs_sz = __sv.size();
385246035553Spatrick    int __result = traits_type::compare(data(), __sv.data(),
3853*4bdff4beSrobert                                        std::min(__lhs_sz, __rhs_sz));
385446035553Spatrick    if (__result != 0)
385546035553Spatrick        return __result;
385646035553Spatrick    if (__lhs_sz < __rhs_sz)
385746035553Spatrick        return -1;
385846035553Spatrick    if (__lhs_sz > __rhs_sz)
385946035553Spatrick        return 1;
386046035553Spatrick    return 0;
386146035553Spatrick}
386246035553Spatrick
386346035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
3864*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
386546035553Spatrickint
386646035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT
386746035553Spatrick{
386846035553Spatrick    return compare(__self_view(__str));
386946035553Spatrick}
387046035553Spatrick
387146035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
3872*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
387346035553Spatrickint
387446035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
387546035553Spatrick                                                   size_type __n1,
387646035553Spatrick                                                   const value_type* __s,
387746035553Spatrick                                                   size_type __n2) const
387846035553Spatrick{
387946035553Spatrick    _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr");
388046035553Spatrick    size_type __sz = size();
388146035553Spatrick    if (__pos1 > __sz || __n2 == npos)
3882*4bdff4beSrobert        __throw_out_of_range();
3883*4bdff4beSrobert    size_type __rlen = std::min(__n1, __sz - __pos1);
3884*4bdff4beSrobert    int __r = traits_type::compare(data() + __pos1, __s, std::min(__rlen, __n2));
388546035553Spatrick    if (__r == 0)
388646035553Spatrick    {
388746035553Spatrick        if (__rlen < __n2)
388846035553Spatrick            __r = -1;
388946035553Spatrick        else if (__rlen > __n2)
389046035553Spatrick            __r = 1;
389146035553Spatrick    }
389246035553Spatrick    return __r;
389346035553Spatrick}
389446035553Spatrick
389546035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
389646035553Spatricktemplate <class _Tp>
3897*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
3898*4bdff4beSrobert__enable_if_t
389946035553Spatrick<
390046035553Spatrick    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
390146035553Spatrick    int
3902037e7968Spatrick>
390346035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
390446035553Spatrick                                                   size_type __n1,
390546035553Spatrick                                                   const _Tp& __t) const
390646035553Spatrick{
390746035553Spatrick    __self_view __sv = __t;
390846035553Spatrick    return compare(__pos1, __n1, __sv.data(), __sv.size());
390946035553Spatrick}
391046035553Spatrick
391146035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
3912*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
391346035553Spatrickint
391446035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
391546035553Spatrick                                                   size_type __n1,
391646035553Spatrick                                                   const basic_string& __str) const
391746035553Spatrick{
391846035553Spatrick    return compare(__pos1, __n1, __str.data(), __str.size());
391946035553Spatrick}
392046035553Spatrick
392146035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
392246035553Spatricktemplate <class _Tp>
3923*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
3924*4bdff4beSrobert__enable_if_t
392546035553Spatrick<
3926037e7968Spatrick    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
3927037e7968Spatrick    && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
392846035553Spatrick    int
3929037e7968Spatrick>
393046035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
393146035553Spatrick                                                   size_type __n1,
393246035553Spatrick                                                   const _Tp& __t,
393346035553Spatrick                                                   size_type __pos2,
393446035553Spatrick                                                   size_type __n2) const
393546035553Spatrick{
393646035553Spatrick    __self_view __sv = __t;
393746035553Spatrick    return __self_view(*this).substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
393846035553Spatrick}
393946035553Spatrick
394046035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
3941*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
394246035553Spatrickint
394346035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
394446035553Spatrick                                                   size_type __n1,
394546035553Spatrick                                                   const basic_string& __str,
394646035553Spatrick                                                   size_type __pos2,
394746035553Spatrick                                                   size_type __n2) const
394846035553Spatrick{
394946035553Spatrick    return compare(__pos1, __n1, __self_view(__str), __pos2, __n2);
395046035553Spatrick}
395146035553Spatrick
395246035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
3953*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
395446035553Spatrickint
395546035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT
395646035553Spatrick{
395746035553Spatrick    _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr");
395846035553Spatrick    return compare(0, npos, __s, traits_type::length(__s));
395946035553Spatrick}
396046035553Spatrick
396146035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
3962*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20
396346035553Spatrickint
396446035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
396546035553Spatrick                                                   size_type __n1,
396646035553Spatrick                                                   const value_type* __s) const
396746035553Spatrick{
396846035553Spatrick    _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr");
396946035553Spatrick    return compare(__pos1, __n1, __s, traits_type::length(__s));
397046035553Spatrick}
397146035553Spatrick
397246035553Spatrick// __invariants
397346035553Spatrick
397446035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
3975*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
397646035553Spatrickbool
397746035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::__invariants() const
397846035553Spatrick{
397946035553Spatrick    if (size() > capacity())
398046035553Spatrick        return false;
398146035553Spatrick    if (capacity() < __min_cap - 1)
398246035553Spatrick        return false;
398376d0caaeSpatrick    if (data() == nullptr)
398446035553Spatrick        return false;
398576d0caaeSpatrick    if (data()[size()] != value_type())
398646035553Spatrick        return false;
398746035553Spatrick    return true;
398846035553Spatrick}
398946035553Spatrick
399046035553Spatrick// __clear_and_shrink
399146035553Spatrick
399246035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
3993*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
399446035553Spatrickvoid
399546035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT
399646035553Spatrick{
399746035553Spatrick    clear();
399846035553Spatrick    if(__is_long())
399946035553Spatrick    {
400046035553Spatrick        __alloc_traits::deallocate(__alloc(), __get_long_pointer(), capacity() + 1);
4001*4bdff4beSrobert        __default_init();
400246035553Spatrick    }
400346035553Spatrick}
400446035553Spatrick
400546035553Spatrick// operator==
400646035553Spatrick
400746035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4008*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
400946035553Spatrickbool
401046035553Spatrickoperator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
401146035553Spatrick           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
401246035553Spatrick{
4013*4bdff4beSrobert#if _LIBCPP_STD_VER > 17
4014*4bdff4beSrobert    return basic_string_view<_CharT, _Traits>(__lhs) == basic_string_view<_CharT, _Traits>(__rhs);
4015*4bdff4beSrobert#else
401646035553Spatrick    size_t __lhs_sz = __lhs.size();
401746035553Spatrick    return __lhs_sz == __rhs.size() && _Traits::compare(__lhs.data(),
401846035553Spatrick                                                        __rhs.data(),
401946035553Spatrick                                                        __lhs_sz) == 0;
4020*4bdff4beSrobert#endif
402146035553Spatrick}
402246035553Spatrick
402346035553Spatricktemplate<class _Allocator>
4024*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
402546035553Spatrickbool
402646035553Spatrickoperator==(const basic_string<char, char_traits<char>, _Allocator>& __lhs,
402746035553Spatrick           const basic_string<char, char_traits<char>, _Allocator>& __rhs) _NOEXCEPT
402846035553Spatrick{
402946035553Spatrick    size_t __lhs_sz = __lhs.size();
403046035553Spatrick    if (__lhs_sz != __rhs.size())
403146035553Spatrick        return false;
403246035553Spatrick    const char* __lp = __lhs.data();
403346035553Spatrick    const char* __rp = __rhs.data();
403446035553Spatrick    if (__lhs.__is_long())
403546035553Spatrick        return char_traits<char>::compare(__lp, __rp, __lhs_sz) == 0;
403646035553Spatrick    for (; __lhs_sz != 0; --__lhs_sz, ++__lp, ++__rp)
403746035553Spatrick        if (*__lp != *__rp)
403846035553Spatrick            return false;
403946035553Spatrick    return true;
404046035553Spatrick}
404146035553Spatrick
4042*4bdff4beSrobert#if _LIBCPP_STD_VER <= 17
404346035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4044*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI
404546035553Spatrickbool
404646035553Spatrickoperator==(const _CharT* __lhs,
404746035553Spatrick           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
404846035553Spatrick{
404946035553Spatrick    typedef basic_string<_CharT, _Traits, _Allocator> _String;
405046035553Spatrick    _LIBCPP_ASSERT(__lhs != nullptr, "operator==(char*, basic_string): received nullptr");
405146035553Spatrick    size_t __lhs_len = _Traits::length(__lhs);
405246035553Spatrick    if (__lhs_len != __rhs.size()) return false;
405346035553Spatrick    return __rhs.compare(0, _String::npos, __lhs, __lhs_len) == 0;
405446035553Spatrick}
4055*4bdff4beSrobert#endif // _LIBCPP_STD_VER <= 17
405646035553Spatrick
405746035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4058*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
405946035553Spatrickbool
406046035553Spatrickoperator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
406146035553Spatrick           const _CharT* __rhs) _NOEXCEPT
406246035553Spatrick{
4063*4bdff4beSrobert#if _LIBCPP_STD_VER > 17
4064*4bdff4beSrobert    return basic_string_view<_CharT, _Traits>(__lhs) == basic_string_view<_CharT, _Traits>(__rhs);
4065*4bdff4beSrobert#else
406646035553Spatrick    typedef basic_string<_CharT, _Traits, _Allocator> _String;
406746035553Spatrick    _LIBCPP_ASSERT(__rhs != nullptr, "operator==(basic_string, char*): received nullptr");
406846035553Spatrick    size_t __rhs_len = _Traits::length(__rhs);
406946035553Spatrick    if (__rhs_len != __lhs.size()) return false;
407046035553Spatrick    return __lhs.compare(0, _String::npos, __rhs, __rhs_len) == 0;
4071*4bdff4beSrobert#endif
4072*4bdff4beSrobert}
4073*4bdff4beSrobert
4074*4bdff4beSrobert#if _LIBCPP_STD_VER > 17
4075*4bdff4beSrobert
4076*4bdff4beSroberttemplate <class _CharT, class _Traits, class _Allocator>
4077*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI constexpr auto operator<=>(
4078*4bdff4beSrobert    const basic_string<_CharT, _Traits, _Allocator>& __lhs,
4079*4bdff4beSrobert    const basic_string<_CharT, _Traits, _Allocator>& __rhs) noexcept {
4080*4bdff4beSrobert    return basic_string_view<_CharT, _Traits>(__lhs) <=> basic_string_view<_CharT, _Traits>(__rhs);
408146035553Spatrick}
408246035553Spatrick
408346035553Spatricktemplate <class _CharT, class _Traits, class _Allocator>
4084*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI constexpr auto
4085*4bdff4beSrobertoperator<=>(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) {
4086*4bdff4beSrobert    return basic_string_view<_CharT, _Traits>(__lhs) <=> basic_string_view<_CharT, _Traits>(__rhs);
4087*4bdff4beSrobert}
4088*4bdff4beSrobert
4089*4bdff4beSrobert#else // _LIBCPP_STD_VER > 17
4090*4bdff4beSrobert
4091*4bdff4beSroberttemplate<class _CharT, class _Traits, class _Allocator>
4092*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI
409346035553Spatrickbool
409446035553Spatrickoperator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
409546035553Spatrick           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
409646035553Spatrick{
409746035553Spatrick    return !(__lhs == __rhs);
409846035553Spatrick}
409946035553Spatrick
410046035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4101*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI
410246035553Spatrickbool
410346035553Spatrickoperator!=(const _CharT* __lhs,
410446035553Spatrick           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
410546035553Spatrick{
410646035553Spatrick    return !(__lhs == __rhs);
410746035553Spatrick}
410846035553Spatrick
410946035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4110*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI
411146035553Spatrickbool
411246035553Spatrickoperator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
411346035553Spatrick           const _CharT* __rhs) _NOEXCEPT
411446035553Spatrick{
411546035553Spatrick    return !(__lhs == __rhs);
411646035553Spatrick}
411746035553Spatrick
411846035553Spatrick// operator<
411946035553Spatrick
412046035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4121*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI
412246035553Spatrickbool
412346035553Spatrickoperator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
412446035553Spatrick           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
412546035553Spatrick{
412646035553Spatrick    return __lhs.compare(__rhs) < 0;
412746035553Spatrick}
412846035553Spatrick
412946035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4130*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI
413146035553Spatrickbool
413246035553Spatrickoperator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
413346035553Spatrick           const _CharT* __rhs) _NOEXCEPT
413446035553Spatrick{
413546035553Spatrick    return __lhs.compare(__rhs) < 0;
413646035553Spatrick}
413746035553Spatrick
413846035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4139*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI
414046035553Spatrickbool
414146035553Spatrickoperator< (const _CharT* __lhs,
414246035553Spatrick           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
414346035553Spatrick{
414446035553Spatrick    return __rhs.compare(__lhs) > 0;
414546035553Spatrick}
414646035553Spatrick
414746035553Spatrick// operator>
414846035553Spatrick
414946035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4150*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI
415146035553Spatrickbool
415246035553Spatrickoperator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
415346035553Spatrick           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
415446035553Spatrick{
415546035553Spatrick    return __rhs < __lhs;
415646035553Spatrick}
415746035553Spatrick
415846035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4159*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI
416046035553Spatrickbool
416146035553Spatrickoperator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
416246035553Spatrick           const _CharT* __rhs) _NOEXCEPT
416346035553Spatrick{
416446035553Spatrick    return __rhs < __lhs;
416546035553Spatrick}
416646035553Spatrick
416746035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4168*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI
416946035553Spatrickbool
417046035553Spatrickoperator> (const _CharT* __lhs,
417146035553Spatrick           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
417246035553Spatrick{
417346035553Spatrick    return __rhs < __lhs;
417446035553Spatrick}
417546035553Spatrick
417646035553Spatrick// operator<=
417746035553Spatrick
417846035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4179*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI
418046035553Spatrickbool
418146035553Spatrickoperator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
418246035553Spatrick           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
418346035553Spatrick{
418446035553Spatrick    return !(__rhs < __lhs);
418546035553Spatrick}
418646035553Spatrick
418746035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4188*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI
418946035553Spatrickbool
419046035553Spatrickoperator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
419146035553Spatrick           const _CharT* __rhs) _NOEXCEPT
419246035553Spatrick{
419346035553Spatrick    return !(__rhs < __lhs);
419446035553Spatrick}
419546035553Spatrick
419646035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4197*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI
419846035553Spatrickbool
419946035553Spatrickoperator<=(const _CharT* __lhs,
420046035553Spatrick           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
420146035553Spatrick{
420246035553Spatrick    return !(__rhs < __lhs);
420346035553Spatrick}
420446035553Spatrick
420546035553Spatrick// operator>=
420646035553Spatrick
420746035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4208*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI
420946035553Spatrickbool
421046035553Spatrickoperator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
421146035553Spatrick           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
421246035553Spatrick{
421346035553Spatrick    return !(__lhs < __rhs);
421446035553Spatrick}
421546035553Spatrick
421646035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4217*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI
421846035553Spatrickbool
421946035553Spatrickoperator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
422046035553Spatrick           const _CharT* __rhs) _NOEXCEPT
422146035553Spatrick{
422246035553Spatrick    return !(__lhs < __rhs);
422346035553Spatrick}
422446035553Spatrick
422546035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4226*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI
422746035553Spatrickbool
422846035553Spatrickoperator>=(const _CharT* __lhs,
422946035553Spatrick           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
423046035553Spatrick{
423146035553Spatrick    return !(__lhs < __rhs);
423246035553Spatrick}
4233*4bdff4beSrobert#endif // _LIBCPP_STD_VER > 17
423446035553Spatrick
423546035553Spatrick// operator +
423646035553Spatrick
423746035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4238*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
423946035553Spatrickbasic_string<_CharT, _Traits, _Allocator>
424046035553Spatrickoperator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
424146035553Spatrick          const basic_string<_CharT, _Traits, _Allocator>& __rhs)
424246035553Spatrick{
4243*4bdff4beSrobert    using _String = basic_string<_CharT, _Traits, _Allocator>;
4244*4bdff4beSrobert    auto __lhs_sz = __lhs.size();
4245*4bdff4beSrobert    auto __rhs_sz = __rhs.size();
4246*4bdff4beSrobert    _String __r(__uninitialized_size_tag(),
4247*4bdff4beSrobert                __lhs_sz + __rhs_sz,
4248*4bdff4beSrobert                _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator()));
4249*4bdff4beSrobert    auto __ptr = std::__to_address(__r.__get_pointer());
4250*4bdff4beSrobert    _Traits::copy(__ptr, __lhs.data(), __lhs_sz);
4251*4bdff4beSrobert    _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz);
4252*4bdff4beSrobert    _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());
425346035553Spatrick    return __r;
425446035553Spatrick}
425546035553Spatrick
425646035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4257*4bdff4beSrobert_LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX20
425846035553Spatrickbasic_string<_CharT, _Traits, _Allocator>
425946035553Spatrickoperator+(const _CharT* __lhs , const basic_string<_CharT,_Traits,_Allocator>& __rhs)
426046035553Spatrick{
4261*4bdff4beSrobert    using _String = basic_string<_CharT, _Traits, _Allocator>;
4262*4bdff4beSrobert    auto __lhs_sz = _Traits::length(__lhs);
4263*4bdff4beSrobert    auto __rhs_sz = __rhs.size();
4264*4bdff4beSrobert    _String __r(__uninitialized_size_tag(),
4265*4bdff4beSrobert                __lhs_sz + __rhs_sz,
4266*4bdff4beSrobert                _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator()));
4267*4bdff4beSrobert    auto __ptr = std::__to_address(__r.__get_pointer());
4268*4bdff4beSrobert    _Traits::copy(__ptr, __lhs, __lhs_sz);
4269*4bdff4beSrobert    _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz);
4270*4bdff4beSrobert    _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());
427146035553Spatrick    return __r;
427246035553Spatrick}
427346035553Spatrick
427446035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4275*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
427646035553Spatrickbasic_string<_CharT, _Traits, _Allocator>
427746035553Spatrickoperator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Allocator>& __rhs)
427846035553Spatrick{
4279*4bdff4beSrobert    using _String = basic_string<_CharT, _Traits, _Allocator>;
4280*4bdff4beSrobert    typename _String::size_type __rhs_sz = __rhs.size();
4281*4bdff4beSrobert    _String __r(__uninitialized_size_tag(),
4282*4bdff4beSrobert                __rhs_sz + 1,
4283*4bdff4beSrobert                _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator()));
4284*4bdff4beSrobert    auto __ptr = std::__to_address(__r.__get_pointer());
4285*4bdff4beSrobert    _Traits::assign(__ptr, 1, __lhs);
4286*4bdff4beSrobert    _Traits::copy(__ptr + 1, __rhs.data(), __rhs_sz);
4287*4bdff4beSrobert    _Traits::assign(__ptr + 1 + __rhs_sz, 1, _CharT());
428846035553Spatrick    return __r;
428946035553Spatrick}
429046035553Spatrick
429146035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4292*4bdff4beSrobertinline _LIBCPP_CONSTEXPR_SINCE_CXX20
429346035553Spatrickbasic_string<_CharT, _Traits, _Allocator>
429446035553Spatrickoperator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs)
429546035553Spatrick{
4296*4bdff4beSrobert    using _String = basic_string<_CharT, _Traits, _Allocator>;
4297*4bdff4beSrobert    typename _String::size_type __lhs_sz = __lhs.size();
4298*4bdff4beSrobert    typename _String::size_type __rhs_sz = _Traits::length(__rhs);
4299*4bdff4beSrobert    _String __r(__uninitialized_size_tag(),
4300*4bdff4beSrobert                __lhs_sz + __rhs_sz,
4301*4bdff4beSrobert                _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator()));
4302*4bdff4beSrobert    auto __ptr = std::__to_address(__r.__get_pointer());
4303*4bdff4beSrobert    _Traits::copy(__ptr, __lhs.data(), __lhs_sz);
4304*4bdff4beSrobert    _Traits::copy(__ptr + __lhs_sz, __rhs, __rhs_sz);
4305*4bdff4beSrobert    _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());
430646035553Spatrick    return __r;
430746035553Spatrick}
430846035553Spatrick
430946035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4310*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
431146035553Spatrickbasic_string<_CharT, _Traits, _Allocator>
431246035553Spatrickoperator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs)
431346035553Spatrick{
4314*4bdff4beSrobert    using _String = basic_string<_CharT, _Traits, _Allocator>;
4315*4bdff4beSrobert    typename _String::size_type __lhs_sz = __lhs.size();
4316*4bdff4beSrobert    _String __r(__uninitialized_size_tag(),
4317*4bdff4beSrobert                __lhs_sz + 1,
4318*4bdff4beSrobert                _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator()));
4319*4bdff4beSrobert    auto __ptr = std::__to_address(__r.__get_pointer());
4320*4bdff4beSrobert    _Traits::copy(__ptr, __lhs.data(), __lhs_sz);
4321*4bdff4beSrobert    _Traits::assign(__ptr + __lhs_sz, 1, __rhs);
4322*4bdff4beSrobert    _Traits::assign(__ptr + 1 + __lhs_sz, 1, _CharT());
432346035553Spatrick    return __r;
432446035553Spatrick}
432546035553Spatrick
432646035553Spatrick#ifndef _LIBCPP_CXX03_LANG
432746035553Spatrick
432846035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4329*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
433046035553Spatrickbasic_string<_CharT, _Traits, _Allocator>
433146035553Spatrickoperator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs)
433246035553Spatrick{
4333*4bdff4beSrobert    return std::move(__lhs.append(__rhs));
433446035553Spatrick}
433546035553Spatrick
433646035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4337*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
433846035553Spatrickbasic_string<_CharT, _Traits, _Allocator>
433946035553Spatrickoperator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs)
434046035553Spatrick{
4341*4bdff4beSrobert    return std::move(__rhs.insert(0, __lhs));
434246035553Spatrick}
434346035553Spatrick
434446035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4345*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
434646035553Spatrickbasic_string<_CharT, _Traits, _Allocator>
434746035553Spatrickoperator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs)
434846035553Spatrick{
4349*4bdff4beSrobert    return std::move(__lhs.append(__rhs));
435046035553Spatrick}
435146035553Spatrick
435246035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4353*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
435446035553Spatrickbasic_string<_CharT, _Traits, _Allocator>
435546035553Spatrickoperator+(const _CharT* __lhs , basic_string<_CharT,_Traits,_Allocator>&& __rhs)
435646035553Spatrick{
4357*4bdff4beSrobert    return std::move(__rhs.insert(0, __lhs));
435846035553Spatrick}
435946035553Spatrick
436046035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4361*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
436246035553Spatrickbasic_string<_CharT, _Traits, _Allocator>
436346035553Spatrickoperator+(_CharT __lhs, basic_string<_CharT,_Traits,_Allocator>&& __rhs)
436446035553Spatrick{
436546035553Spatrick    __rhs.insert(__rhs.begin(), __lhs);
4366*4bdff4beSrobert    return std::move(__rhs);
436746035553Spatrick}
436846035553Spatrick
436946035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4370*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
437146035553Spatrickbasic_string<_CharT, _Traits, _Allocator>
437246035553Spatrickoperator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const _CharT* __rhs)
437346035553Spatrick{
4374*4bdff4beSrobert    return std::move(__lhs.append(__rhs));
437546035553Spatrick}
437646035553Spatrick
437746035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4378*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
437946035553Spatrickbasic_string<_CharT, _Traits, _Allocator>
438046035553Spatrickoperator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT __rhs)
438146035553Spatrick{
438246035553Spatrick    __lhs.push_back(__rhs);
4383*4bdff4beSrobert    return std::move(__lhs);
438446035553Spatrick}
438546035553Spatrick
438646035553Spatrick#endif // _LIBCPP_CXX03_LANG
438746035553Spatrick
438846035553Spatrick// swap
438946035553Spatrick
439046035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4391*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
439246035553Spatrickvoid
439346035553Spatrickswap(basic_string<_CharT, _Traits, _Allocator>& __lhs,
439446035553Spatrick     basic_string<_CharT, _Traits, _Allocator>& __rhs)
439546035553Spatrick     _NOEXCEPT_(_NOEXCEPT_(__lhs.swap(__rhs)))
439646035553Spatrick{
439746035553Spatrick    __lhs.swap(__rhs);
439846035553Spatrick}
439946035553Spatrick
440076d0caaeSpatrick_LIBCPP_FUNC_VIS int                stoi  (const string& __str, size_t* __idx = nullptr, int __base = 10);
440176d0caaeSpatrick_LIBCPP_FUNC_VIS long               stol  (const string& __str, size_t* __idx = nullptr, int __base = 10);
440276d0caaeSpatrick_LIBCPP_FUNC_VIS unsigned long      stoul (const string& __str, size_t* __idx = nullptr, int __base = 10);
440376d0caaeSpatrick_LIBCPP_FUNC_VIS long long          stoll (const string& __str, size_t* __idx = nullptr, int __base = 10);
440476d0caaeSpatrick_LIBCPP_FUNC_VIS unsigned long long stoull(const string& __str, size_t* __idx = nullptr, int __base = 10);
440546035553Spatrick
440676d0caaeSpatrick_LIBCPP_FUNC_VIS float       stof (const string& __str, size_t* __idx = nullptr);
440776d0caaeSpatrick_LIBCPP_FUNC_VIS double      stod (const string& __str, size_t* __idx = nullptr);
440876d0caaeSpatrick_LIBCPP_FUNC_VIS long double stold(const string& __str, size_t* __idx = nullptr);
440946035553Spatrick
441046035553Spatrick_LIBCPP_FUNC_VIS string to_string(int __val);
441146035553Spatrick_LIBCPP_FUNC_VIS string to_string(unsigned __val);
441246035553Spatrick_LIBCPP_FUNC_VIS string to_string(long __val);
441346035553Spatrick_LIBCPP_FUNC_VIS string to_string(unsigned long __val);
441446035553Spatrick_LIBCPP_FUNC_VIS string to_string(long long __val);
441546035553Spatrick_LIBCPP_FUNC_VIS string to_string(unsigned long long __val);
441646035553Spatrick_LIBCPP_FUNC_VIS string to_string(float __val);
441746035553Spatrick_LIBCPP_FUNC_VIS string to_string(double __val);
441846035553Spatrick_LIBCPP_FUNC_VIS string to_string(long double __val);
441946035553Spatrick
4420*4bdff4beSrobert#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
442176d0caaeSpatrick_LIBCPP_FUNC_VIS int                stoi  (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
442276d0caaeSpatrick_LIBCPP_FUNC_VIS long               stol  (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
442376d0caaeSpatrick_LIBCPP_FUNC_VIS unsigned long      stoul (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
442476d0caaeSpatrick_LIBCPP_FUNC_VIS long long          stoll (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
442576d0caaeSpatrick_LIBCPP_FUNC_VIS unsigned long long stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
442646035553Spatrick
442776d0caaeSpatrick_LIBCPP_FUNC_VIS float       stof (const wstring& __str, size_t* __idx = nullptr);
442876d0caaeSpatrick_LIBCPP_FUNC_VIS double      stod (const wstring& __str, size_t* __idx = nullptr);
442976d0caaeSpatrick_LIBCPP_FUNC_VIS long double stold(const wstring& __str, size_t* __idx = nullptr);
443046035553Spatrick
443146035553Spatrick_LIBCPP_FUNC_VIS wstring to_wstring(int __val);
443246035553Spatrick_LIBCPP_FUNC_VIS wstring to_wstring(unsigned __val);
443346035553Spatrick_LIBCPP_FUNC_VIS wstring to_wstring(long __val);
443446035553Spatrick_LIBCPP_FUNC_VIS wstring to_wstring(unsigned long __val);
443546035553Spatrick_LIBCPP_FUNC_VIS wstring to_wstring(long long __val);
443646035553Spatrick_LIBCPP_FUNC_VIS wstring to_wstring(unsigned long long __val);
443746035553Spatrick_LIBCPP_FUNC_VIS wstring to_wstring(float __val);
443846035553Spatrick_LIBCPP_FUNC_VIS wstring to_wstring(double __val);
443946035553Spatrick_LIBCPP_FUNC_VIS wstring to_wstring(long double __val);
4440*4bdff4beSrobert#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
444146035553Spatrick
444246035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
444376d0caaeSpatrick_LIBCPP_TEMPLATE_DATA_VIS
444446035553Spatrickconst typename basic_string<_CharT, _Traits, _Allocator>::size_type
444546035553Spatrick               basic_string<_CharT, _Traits, _Allocator>::npos;
444646035553Spatrick
444746035553Spatricktemplate <class _CharT, class _Allocator>
4448*4bdff4beSrobertstruct __string_hash : public __unary_function<basic_string<_CharT, char_traits<_CharT>, _Allocator>, size_t>
444946035553Spatrick{
445046035553Spatrick    size_t
445146035553Spatrick    operator()(const basic_string<_CharT, char_traits<_CharT>, _Allocator>& __val) const _NOEXCEPT
4452*4bdff4beSrobert    { return std::__do_string_hash(__val.data(), __val.data() + __val.size()); }
445346035553Spatrick};
445446035553Spatrick
4455*4bdff4beSroberttemplate <class _Allocator>
4456*4bdff4beSrobertstruct hash<basic_string<char, char_traits<char>, _Allocator> > : __string_hash<char, _Allocator> {};
4457*4bdff4beSrobert
4458*4bdff4beSrobert#ifndef _LIBCPP_HAS_NO_CHAR8_T
4459*4bdff4beSroberttemplate <class _Allocator>
4460*4bdff4beSrobertstruct hash<basic_string<char8_t, char_traits<char8_t>, _Allocator> > : __string_hash<char8_t, _Allocator> {};
4461*4bdff4beSrobert#endif
4462*4bdff4beSrobert
4463*4bdff4beSroberttemplate <class _Allocator>
4464*4bdff4beSrobertstruct hash<basic_string<char16_t, char_traits<char16_t>, _Allocator> > : __string_hash<char16_t, _Allocator> {};
4465*4bdff4beSrobert
4466*4bdff4beSroberttemplate <class _Allocator>
4467*4bdff4beSrobertstruct hash<basic_string<char32_t, char_traits<char32_t>, _Allocator> > : __string_hash<char32_t, _Allocator> {};
4468*4bdff4beSrobert
4469*4bdff4beSrobert#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4470*4bdff4beSroberttemplate <class _Allocator>
4471*4bdff4beSrobertstruct hash<basic_string<wchar_t, char_traits<wchar_t>, _Allocator> > : __string_hash<wchar_t, _Allocator> {};
4472*4bdff4beSrobert#endif
447346035553Spatrick
447446035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4475*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
447646035553Spatrickoperator<<(basic_ostream<_CharT, _Traits>& __os,
447746035553Spatrick           const basic_string<_CharT, _Traits, _Allocator>& __str);
447846035553Spatrick
447946035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4480*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
448146035553Spatrickoperator>>(basic_istream<_CharT, _Traits>& __is,
448246035553Spatrick           basic_string<_CharT, _Traits, _Allocator>& __str);
448346035553Spatrick
448446035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4485*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
448646035553Spatrickgetline(basic_istream<_CharT, _Traits>& __is,
448746035553Spatrick        basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm);
448846035553Spatrick
448946035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4490*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI
449146035553Spatrickbasic_istream<_CharT, _Traits>&
449246035553Spatrickgetline(basic_istream<_CharT, _Traits>& __is,
449346035553Spatrick        basic_string<_CharT, _Traits, _Allocator>& __str);
449446035553Spatrick
449546035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4496*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI
449746035553Spatrickbasic_istream<_CharT, _Traits>&
449846035553Spatrickgetline(basic_istream<_CharT, _Traits>&& __is,
449946035553Spatrick        basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm);
450046035553Spatrick
450146035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
4502*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI
450346035553Spatrickbasic_istream<_CharT, _Traits>&
450446035553Spatrickgetline(basic_istream<_CharT, _Traits>&& __is,
450546035553Spatrick        basic_string<_CharT, _Traits, _Allocator>& __str);
450646035553Spatrick
450746035553Spatrick#if _LIBCPP_STD_VER > 17
450846035553Spatricktemplate <class _CharT, class _Traits, class _Allocator, class _Up>
4509*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI
4510037e7968Spatrick    typename basic_string<_CharT, _Traits, _Allocator>::size_type
4511037e7968Spatrick    erase(basic_string<_CharT, _Traits, _Allocator>& __str, const _Up& __v) {
4512037e7968Spatrick  auto __old_size = __str.size();
4513*4bdff4beSrobert  __str.erase(std::remove(__str.begin(), __str.end(), __v), __str.end());
4514037e7968Spatrick  return __old_size - __str.size();
4515037e7968Spatrick}
451646035553Spatrick
451746035553Spatricktemplate <class _CharT, class _Traits, class _Allocator, class _Predicate>
4518*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI
4519037e7968Spatrick    typename basic_string<_CharT, _Traits, _Allocator>::size_type
4520037e7968Spatrick    erase_if(basic_string<_CharT, _Traits, _Allocator>& __str,
4521037e7968Spatrick             _Predicate __pred) {
4522037e7968Spatrick  auto __old_size = __str.size();
4523*4bdff4beSrobert  __str.erase(std::remove_if(__str.begin(), __str.end(), __pred),
4524037e7968Spatrick              __str.end());
4525037e7968Spatrick  return __old_size - __str.size();
4526037e7968Spatrick}
452746035553Spatrick#endif
452846035553Spatrick
4529*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE
453046035553Spatrick
453146035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
453246035553Spatrickbool
453346035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::__dereferenceable(const const_iterator* __i) const
453446035553Spatrick{
4535*4bdff4beSrobert    return data() <= std::__to_address(__i->base()) &&
4536*4bdff4beSrobert           std::__to_address(__i->base()) < data() + size();
453746035553Spatrick}
453846035553Spatrick
453946035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
454046035553Spatrickbool
454146035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::__decrementable(const const_iterator* __i) const
454246035553Spatrick{
4543*4bdff4beSrobert    return data() < std::__to_address(__i->base()) &&
4544*4bdff4beSrobert           std::__to_address(__i->base()) <= data() + size();
454546035553Spatrick}
454646035553Spatrick
454746035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
454846035553Spatrickbool
454946035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const
455046035553Spatrick{
4551*4bdff4beSrobert    const value_type* __p = std::__to_address(__i->base()) + __n;
4552*4bdff4beSrobert    return data() <= __p && __p <= data() + size();
455346035553Spatrick}
455446035553Spatrick
455546035553Spatricktemplate<class _CharT, class _Traits, class _Allocator>
455646035553Spatrickbool
455746035553Spatrickbasic_string<_CharT, _Traits, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const
455846035553Spatrick{
4559*4bdff4beSrobert    const value_type* __p = std::__to_address(__i->base()) + __n;
4560*4bdff4beSrobert    return data() <= __p && __p < data() + size();
456146035553Spatrick}
456246035553Spatrick
4563*4bdff4beSrobert#endif // _LIBCPP_ENABLE_DEBUG_MODE
456446035553Spatrick
456546035553Spatrick#if _LIBCPP_STD_VER > 11
456646035553Spatrick// Literal suffixes for basic_string [basic.string.literals]
456746035553Spatrickinline namespace literals
456846035553Spatrick{
456946035553Spatrick  inline namespace string_literals
457046035553Spatrick  {
4571*4bdff4beSrobert    inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
457246035553Spatrick    basic_string<char> operator "" s( const char *__str, size_t __len )
457346035553Spatrick    {
457446035553Spatrick        return basic_string<char> (__str, __len);
457546035553Spatrick    }
457646035553Spatrick
4577*4bdff4beSrobert#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4578*4bdff4beSrobert    inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
457946035553Spatrick    basic_string<wchar_t> operator "" s( const wchar_t *__str, size_t __len )
458046035553Spatrick    {
458146035553Spatrick        return basic_string<wchar_t> (__str, __len);
458246035553Spatrick    }
4583*4bdff4beSrobert#endif
458446035553Spatrick
458576d0caaeSpatrick#ifndef _LIBCPP_HAS_NO_CHAR8_T
4586*4bdff4beSrobert    inline _LIBCPP_HIDE_FROM_ABI constexpr
4587*4bdff4beSrobert    basic_string<char8_t> operator "" s(const char8_t *__str, size_t __len)
458846035553Spatrick    {
458946035553Spatrick        return basic_string<char8_t> (__str, __len);
459046035553Spatrick    }
459146035553Spatrick#endif
459246035553Spatrick
4593*4bdff4beSrobert    inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
459446035553Spatrick    basic_string<char16_t> operator "" s( const char16_t *__str, size_t __len )
459546035553Spatrick    {
459646035553Spatrick        return basic_string<char16_t> (__str, __len);
459746035553Spatrick    }
459846035553Spatrick
4599*4bdff4beSrobert    inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
460046035553Spatrick    basic_string<char32_t> operator "" s( const char32_t *__str, size_t __len )
460146035553Spatrick    {
460246035553Spatrick        return basic_string<char32_t> (__str, __len);
460346035553Spatrick    }
4604*4bdff4beSrobert  } // namespace string_literals
4605*4bdff4beSrobert} // namespace literals
4606*4bdff4beSrobert
4607*4bdff4beSrobert#if _LIBCPP_STD_VER > 17
4608*4bdff4beSroberttemplate <>
4609*4bdff4beSrobertinline constexpr bool __format::__enable_insertable<std::basic_string<char>> = true;
4610*4bdff4beSrobert#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4611*4bdff4beSroberttemplate <>
4612*4bdff4beSrobertinline constexpr bool __format::__enable_insertable<std::basic_string<wchar_t>> = true;
4613*4bdff4beSrobert#endif
4614*4bdff4beSrobert#endif
4615*4bdff4beSrobert
461646035553Spatrick#endif
461746035553Spatrick
461846035553Spatrick_LIBCPP_END_NAMESPACE_STD
461946035553Spatrick
462046035553Spatrick_LIBCPP_POP_MACROS
462146035553Spatrick
4622*4bdff4beSrobert#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
4623*4bdff4beSrobert#  include <algorithm>
4624*4bdff4beSrobert#  include <concepts>
4625*4bdff4beSrobert#  include <functional>
4626*4bdff4beSrobert#  include <iterator>
4627*4bdff4beSrobert#  include <new>
4628*4bdff4beSrobert#  include <typeinfo>
4629*4bdff4beSrobert#  include <utility>
4630*4bdff4beSrobert#  include <vector>
4631*4bdff4beSrobert#endif
4632*4bdff4beSrobert
463346035553Spatrick#endif // _LIBCPP_STRING
4634