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