xref: /freebsd/contrib/llvm-project/libcxx/include/string (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
10b57cec5SDimitry Andric// -*- C++ -*-
2349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
30b57cec5SDimitry Andric//
40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
70b57cec5SDimitry Andric//
80b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
90b57cec5SDimitry Andric
100b57cec5SDimitry Andric#ifndef _LIBCPP_STRING
110b57cec5SDimitry Andric#define _LIBCPP_STRING
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric/*
140b57cec5SDimitry Andric    string synopsis
150b57cec5SDimitry Andric
16*bdd1243dSDimitry Andric#include <compare>
17*bdd1243dSDimitry Andric#include <initializer_list>
18*bdd1243dSDimitry Andric
190b57cec5SDimitry Andricnamespace std
200b57cec5SDimitry Andric{
210b57cec5SDimitry Andric
220b57cec5SDimitry Andrictemplate <class stateT>
230b57cec5SDimitry Andricclass fpos
240b57cec5SDimitry Andric{
250b57cec5SDimitry Andricprivate:
260b57cec5SDimitry Andric    stateT st;
270b57cec5SDimitry Andricpublic:
280b57cec5SDimitry Andric    fpos(streamoff = streamoff());
290b57cec5SDimitry Andric
300b57cec5SDimitry Andric    operator streamoff() const;
310b57cec5SDimitry Andric
320b57cec5SDimitry Andric    stateT state() const;
330b57cec5SDimitry Andric    void state(stateT);
340b57cec5SDimitry Andric
350b57cec5SDimitry Andric    fpos& operator+=(streamoff);
360b57cec5SDimitry Andric    fpos  operator+ (streamoff) const;
370b57cec5SDimitry Andric    fpos& operator-=(streamoff);
380b57cec5SDimitry Andric    fpos  operator- (streamoff) const;
390b57cec5SDimitry Andric};
400b57cec5SDimitry Andric
410b57cec5SDimitry Andrictemplate <class stateT> streamoff operator-(const fpos<stateT>& x, const fpos<stateT>& y);
420b57cec5SDimitry Andric
430b57cec5SDimitry Andrictemplate <class stateT> bool operator==(const fpos<stateT>& x, const fpos<stateT>& y);
440b57cec5SDimitry Andrictemplate <class stateT> bool operator!=(const fpos<stateT>& x, const fpos<stateT>& y);
450b57cec5SDimitry Andric
460b57cec5SDimitry Andrictemplate <class charT>
470b57cec5SDimitry Andricstruct char_traits
480b57cec5SDimitry Andric{
49*bdd1243dSDimitry Andric    using char_type           = charT;
50*bdd1243dSDimitry Andric    using int_type            = ...;
51*bdd1243dSDimitry Andric    using off_type            = streamoff;
52*bdd1243dSDimitry Andric    using pos_type            = streampos;
53*bdd1243dSDimitry Andric    using state_type          = mbstate_t;
54*bdd1243dSDimitry Andric    using comparison_category = strong_ordering; // Since C++20 only for the specializations
55*bdd1243dSDimitry Andric                                                 // char, wchar_t, char8_t, char16_t, and char32_t.
560b57cec5SDimitry Andric
570b57cec5SDimitry Andric    static void assign(char_type& c1, const char_type& c2) noexcept;
580b57cec5SDimitry Andric    static constexpr bool eq(char_type c1, char_type c2) noexcept;
590b57cec5SDimitry Andric    static constexpr bool lt(char_type c1, char_type c2) noexcept;
600b57cec5SDimitry Andric
610b57cec5SDimitry Andric    static int              compare(const char_type* s1, const char_type* s2, size_t n);
620b57cec5SDimitry Andric    static size_t           length(const char_type* s);
630b57cec5SDimitry Andric    static const char_type* find(const char_type* s, size_t n, const char_type& a);
640b57cec5SDimitry Andric    static char_type*       move(char_type* s1, const char_type* s2, size_t n);
650b57cec5SDimitry Andric    static char_type*       copy(char_type* s1, const char_type* s2, size_t n);
660b57cec5SDimitry Andric    static char_type*       assign(char_type* s, size_t n, char_type a);
670b57cec5SDimitry Andric
680b57cec5SDimitry Andric    static constexpr int_type  not_eof(int_type c) noexcept;
690b57cec5SDimitry Andric    static constexpr char_type to_char_type(int_type c) noexcept;
700b57cec5SDimitry Andric    static constexpr int_type  to_int_type(char_type c) noexcept;
710b57cec5SDimitry Andric    static constexpr bool      eq_int_type(int_type c1, int_type c2) noexcept;
720b57cec5SDimitry Andric    static constexpr int_type  eof() noexcept;
730b57cec5SDimitry Andric};
740b57cec5SDimitry Andric
750b57cec5SDimitry Andrictemplate <> struct char_traits<char>;
760b57cec5SDimitry Andrictemplate <> struct char_traits<wchar_t>;
77fe6060f1SDimitry Andrictemplate <> struct char_traits<char8_t>;  // C++20
78fe6060f1SDimitry Andrictemplate <> struct char_traits<char16_t>;
79fe6060f1SDimitry Andrictemplate <> struct char_traits<char32_t>;
800b57cec5SDimitry Andric
810b57cec5SDimitry Andrictemplate<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
820b57cec5SDimitry Andricclass basic_string
830b57cec5SDimitry Andric{
840b57cec5SDimitry Andricpublic:
850b57cec5SDimitry Andric// types:
860b57cec5SDimitry Andric    typedef traits traits_type;
870b57cec5SDimitry Andric    typedef typename traits_type::char_type value_type;
880b57cec5SDimitry Andric    typedef Allocator allocator_type;
890b57cec5SDimitry Andric    typedef typename allocator_type::size_type size_type;
900b57cec5SDimitry Andric    typedef typename allocator_type::difference_type difference_type;
910b57cec5SDimitry Andric    typedef typename allocator_type::reference reference;
920b57cec5SDimitry Andric    typedef typename allocator_type::const_reference const_reference;
930b57cec5SDimitry Andric    typedef typename allocator_type::pointer pointer;
940b57cec5SDimitry Andric    typedef typename allocator_type::const_pointer const_pointer;
950b57cec5SDimitry Andric    typedef implementation-defined iterator;
960b57cec5SDimitry Andric    typedef implementation-defined const_iterator;
970b57cec5SDimitry Andric    typedef std::reverse_iterator<iterator> reverse_iterator;
980b57cec5SDimitry Andric    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
990b57cec5SDimitry Andric
1000b57cec5SDimitry Andric    static const size_type npos = -1;
1010b57cec5SDimitry Andric
1020b57cec5SDimitry Andric    basic_string()
10381ad6265SDimitry Andric        noexcept(is_nothrow_default_constructible<allocator_type>::value);                      // constexpr since C++20
10481ad6265SDimitry Andric    explicit basic_string(const allocator_type& a);                                             // constexpr since C++20
10581ad6265SDimitry Andric    basic_string(const basic_string& str);                                                      // constexpr since C++20
1060b57cec5SDimitry Andric    basic_string(basic_string&& str)
10781ad6265SDimitry Andric        noexcept(is_nothrow_move_constructible<allocator_type>::value);                         // constexpr since C++20
1080b57cec5SDimitry Andric    basic_string(const basic_string& str, size_type pos,
10981ad6265SDimitry Andric                 const allocator_type& a = allocator_type());                                   // constexpr since C++20
1100b57cec5SDimitry Andric    basic_string(const basic_string& str, size_type pos, size_type n,
11181ad6265SDimitry Andric                 const Allocator& a = Allocator());                                             // constexpr since C++20
112*bdd1243dSDimitry Andric    constexpr basic_string(
113*bdd1243dSDimitry Andric        basic_string&& str, size_type pos, const Allocator& a = Allocator());                   // since C++23
114*bdd1243dSDimitry Andric    constexpr basic_string(
115*bdd1243dSDimitry Andric        basic_string&& str, size_type pos, size_type n, const Allocator& a = Allocator());      // since C++23
1160b57cec5SDimitry Andric    template<class T>
11781ad6265SDimitry Andric        basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator()); // C++17, constexpr since C++20
1180b57cec5SDimitry Andric    template <class T>
11981ad6265SDimitry Andric        explicit basic_string(const T& t, const Allocator& a = Allocator());                    // C++17, constexpr since C++20
12081ad6265SDimitry Andric    basic_string(const value_type* s, const allocator_type& a = allocator_type());              // constexpr since C++20
12181ad6265SDimitry Andric    basic_string(const value_type* s, size_type n, const allocator_type& a = allocator_type()); // constexpr since C++20
122fe6060f1SDimitry Andric    basic_string(nullptr_t) = delete; // C++2b
12381ad6265SDimitry Andric    basic_string(size_type n, value_type c, const allocator_type& a = allocator_type());        // constexpr since C++20
1240b57cec5SDimitry Andric    template<class InputIterator>
1250b57cec5SDimitry Andric        basic_string(InputIterator begin, InputIterator end,
12681ad6265SDimitry Andric                     const allocator_type& a = allocator_type());                               // constexpr since C++20
12781ad6265SDimitry Andric    basic_string(initializer_list<value_type>, const Allocator& = Allocator());                 // constexpr since C++20
12881ad6265SDimitry Andric    basic_string(const basic_string&, const Allocator&);                                        // constexpr since C++20
12981ad6265SDimitry Andric    basic_string(basic_string&&, const Allocator&);                                             // constexpr since C++20
1300b57cec5SDimitry Andric
13181ad6265SDimitry Andric    ~basic_string();                                                                            // constexpr since C++20
1320b57cec5SDimitry Andric
13381ad6265SDimitry Andric    operator basic_string_view<charT, traits>() const noexcept;                                 // constexpr since C++20
1340b57cec5SDimitry Andric
13581ad6265SDimitry Andric    basic_string& operator=(const basic_string& str);                                           // constexpr since C++20
1360b57cec5SDimitry Andric    template <class T>
13781ad6265SDimitry Andric        basic_string& operator=(const T& t);                                                    // C++17, constexpr since C++20
1380b57cec5SDimitry Andric    basic_string& operator=(basic_string&& str)
1390b57cec5SDimitry Andric        noexcept(
1400b57cec5SDimitry Andric             allocator_type::propagate_on_container_move_assignment::value ||
14181ad6265SDimitry Andric             allocator_type::is_always_equal::value );                                          // C++17, constexpr since C++20
14281ad6265SDimitry Andric    basic_string& operator=(const value_type* s);                                               // constexpr since C++20
143fe6060f1SDimitry Andric    basic_string& operator=(nullptr_t) = delete; // C++2b
14481ad6265SDimitry Andric    basic_string& operator=(value_type c);                                                      // constexpr since C++20
14581ad6265SDimitry Andric    basic_string& operator=(initializer_list<value_type>);                                      // constexpr since C++20
1460b57cec5SDimitry Andric
14781ad6265SDimitry Andric    iterator       begin() noexcept;                                                            // constexpr since C++20
14881ad6265SDimitry Andric    const_iterator begin() const noexcept;                                                      // constexpr since C++20
14981ad6265SDimitry Andric    iterator       end() noexcept;                                                              // constexpr since C++20
15081ad6265SDimitry Andric    const_iterator end() const noexcept;                                                        // constexpr since C++20
1510b57cec5SDimitry Andric
15281ad6265SDimitry Andric    reverse_iterator       rbegin() noexcept;                                                   // constexpr since C++20
15381ad6265SDimitry Andric    const_reverse_iterator rbegin() const noexcept;                                             // constexpr since C++20
15481ad6265SDimitry Andric    reverse_iterator       rend() noexcept;                                                     // constexpr since C++20
15581ad6265SDimitry Andric    const_reverse_iterator rend() const noexcept;                                               // constexpr since C++20
1560b57cec5SDimitry Andric
15781ad6265SDimitry Andric    const_iterator         cbegin() const noexcept;                                             // constexpr since C++20
15881ad6265SDimitry Andric    const_iterator         cend() const noexcept;                                               // constexpr since C++20
15981ad6265SDimitry Andric    const_reverse_iterator crbegin() const noexcept;                                            // constexpr since C++20
16081ad6265SDimitry Andric    const_reverse_iterator crend() const noexcept;                                              // constexpr since C++20
1610b57cec5SDimitry Andric
16281ad6265SDimitry Andric    size_type size() const noexcept;                                                            // constexpr since C++20
16381ad6265SDimitry Andric    size_type length() const noexcept;                                                          // constexpr since C++20
16481ad6265SDimitry Andric    size_type max_size() const noexcept;                                                        // constexpr since C++20
16581ad6265SDimitry Andric    size_type capacity() const noexcept;                                                        // constexpr since C++20
1660b57cec5SDimitry Andric
16781ad6265SDimitry Andric    void resize(size_type n, value_type c);                                                     // constexpr since C++20
16881ad6265SDimitry Andric    void resize(size_type n);                                                                   // constexpr since C++20
1690b57cec5SDimitry Andric
17004eeddc0SDimitry Andric    template<class Operation>
17104eeddc0SDimitry Andric    constexpr void resize_and_overwrite(size_type n, Operation op); // since C++23
17204eeddc0SDimitry Andric
17381ad6265SDimitry Andric    void reserve(size_type res_arg);                                                            // constexpr since C++20
174e8d8bef9SDimitry Andric    void reserve(); // deprecated in C++20
17581ad6265SDimitry Andric    void shrink_to_fit();                                                                       // constexpr since C++20
17681ad6265SDimitry Andric    void clear() noexcept;                                                                      // constexpr since C++20
17781ad6265SDimitry Andric    bool empty() const noexcept;                                                                // constexpr since C++20
1780b57cec5SDimitry Andric
17981ad6265SDimitry Andric    const_reference operator[](size_type pos) const;                                            // constexpr since C++20
18081ad6265SDimitry Andric    reference       operator[](size_type pos);                                                  // constexpr since C++20
1810b57cec5SDimitry Andric
18281ad6265SDimitry Andric    const_reference at(size_type n) const;                                                      // constexpr since C++20
18381ad6265SDimitry Andric    reference       at(size_type n);                                                            // constexpr since C++20
1840b57cec5SDimitry Andric
18581ad6265SDimitry Andric    basic_string& operator+=(const basic_string& str);                                          // constexpr since C++20
1860b57cec5SDimitry Andric    template <class T>
18781ad6265SDimitry Andric        basic_string& operator+=(const T& t);                                                   // C++17, constexpr since C++20
18881ad6265SDimitry Andric    basic_string& operator+=(const value_type* s);                                              // constexpr since C++20
18981ad6265SDimitry Andric    basic_string& operator+=(value_type c);                                                     // constexpr since C++20
19081ad6265SDimitry Andric    basic_string& operator+=(initializer_list<value_type>);                                     // constexpr since C++20
1910b57cec5SDimitry Andric
19281ad6265SDimitry Andric    basic_string& append(const basic_string& str);                                              // constexpr since C++20
1930b57cec5SDimitry Andric    template <class T>
19481ad6265SDimitry Andric        basic_string& append(const T& t);                                                       // C++17, constexpr since C++20
19581ad6265SDimitry Andric    basic_string& append(const basic_string& str, size_type pos, size_type n=npos);             // C++14, constexpr since C++20
1960b57cec5SDimitry Andric    template <class T>
19781ad6265SDimitry Andric        basic_string& append(const T& t, size_type pos, size_type n=npos);                      // C++17, constexpr since C++20
19881ad6265SDimitry Andric    basic_string& append(const value_type* s, size_type n);                                     // constexpr since C++20
19981ad6265SDimitry Andric    basic_string& append(const value_type* s);                                                  // constexpr since C++20
20081ad6265SDimitry Andric    basic_string& append(size_type n, value_type c);                                            // constexpr since C++20
2010b57cec5SDimitry Andric    template<class InputIterator>
20281ad6265SDimitry Andric        basic_string& append(InputIterator first, InputIterator last);                          // constexpr since C++20
20381ad6265SDimitry Andric    basic_string& append(initializer_list<value_type>);                                         // constexpr since C++20
2040b57cec5SDimitry Andric
20581ad6265SDimitry Andric    void push_back(value_type c);                                                               // constexpr since C++20
20681ad6265SDimitry Andric    void pop_back();                                                                            // constexpr since C++20
20781ad6265SDimitry Andric    reference       front();                                                                    // constexpr since C++20
20881ad6265SDimitry Andric    const_reference front() const;                                                              // constexpr since C++20
20981ad6265SDimitry Andric    reference       back();                                                                     // constexpr since C++20
21081ad6265SDimitry Andric    const_reference back() const;                                                               // constexpr since C++20
2110b57cec5SDimitry Andric
21281ad6265SDimitry Andric    basic_string& assign(const basic_string& str);                                              // constexpr since C++20
2130b57cec5SDimitry Andric    template <class T>
21481ad6265SDimitry Andric        basic_string& assign(const T& t);                                                       // C++17, constexpr since C++20
21581ad6265SDimitry Andric    basic_string& assign(basic_string&& str);                                                   // constexpr since C++20
21681ad6265SDimitry Andric    basic_string& assign(const basic_string& str, size_type pos, size_type n=npos);             // C++14, constexpr since C++20
2170b57cec5SDimitry Andric    template <class T>
21881ad6265SDimitry Andric        basic_string& assign(const T& t, size_type pos, size_type n=npos);                      // C++17, constexpr since C++20
21981ad6265SDimitry Andric    basic_string& assign(const value_type* s, size_type n);                                     // constexpr since C++20
22081ad6265SDimitry Andric    basic_string& assign(const value_type* s);                                                  // constexpr since C++20
22181ad6265SDimitry Andric    basic_string& assign(size_type n, value_type c);                                            // constexpr since C++20
2220b57cec5SDimitry Andric    template<class InputIterator>
22381ad6265SDimitry Andric        basic_string& assign(InputIterator first, InputIterator last);                          // constexpr since C++20
22481ad6265SDimitry Andric    basic_string& assign(initializer_list<value_type>);                                         // constexpr since C++20
2250b57cec5SDimitry Andric
22681ad6265SDimitry Andric    basic_string& insert(size_type pos1, const basic_string& str);                              // constexpr since C++20
2270b57cec5SDimitry Andric    template <class T>
22881ad6265SDimitry Andric        basic_string& insert(size_type pos1, const T& t);                                       // constexpr since C++20
2290b57cec5SDimitry Andric    basic_string& insert(size_type pos1, const basic_string& str,
23081ad6265SDimitry Andric                         size_type pos2, size_type n);                                          // constexpr since C++20
2310b57cec5SDimitry Andric    template <class T>
23281ad6265SDimitry Andric        basic_string& insert(size_type pos1, const T& t, size_type pos2, size_type n);          // C++17, constexpr since C++20
23381ad6265SDimitry Andric    basic_string& insert(size_type pos, const value_type* s, size_type n=npos);                 // C++14, constexpr since C++20
23481ad6265SDimitry Andric    basic_string& insert(size_type pos, const value_type* s);                                   // constexpr since C++20
23581ad6265SDimitry Andric    basic_string& insert(size_type pos, size_type n, value_type c);                             // constexpr since C++20
23681ad6265SDimitry Andric    iterator      insert(const_iterator p, value_type c);                                       // constexpr since C++20
23781ad6265SDimitry Andric    iterator      insert(const_iterator p, size_type n, value_type c);                          // constexpr since C++20
2380b57cec5SDimitry Andric    template<class InputIterator>
23981ad6265SDimitry Andric        iterator insert(const_iterator p, InputIterator first, InputIterator last);             // constexpr since C++20
24081ad6265SDimitry Andric    iterator      insert(const_iterator p, initializer_list<value_type>);                       // constexpr since C++20
2410b57cec5SDimitry Andric
24281ad6265SDimitry Andric    basic_string& erase(size_type pos = 0, size_type n = npos);                                 // constexpr since C++20
24381ad6265SDimitry Andric    iterator      erase(const_iterator position);                                               // constexpr since C++20
24481ad6265SDimitry Andric    iterator      erase(const_iterator first, const_iterator last);                             // constexpr since C++20
2450b57cec5SDimitry Andric
24681ad6265SDimitry Andric    basic_string& replace(size_type pos1, size_type n1, const basic_string& str);               // constexpr since C++20
2470b57cec5SDimitry Andric    template <class T>
24881ad6265SDimitry Andric    basic_string& replace(size_type pos1, size_type n1, const T& t);                            // C++17, constexpr since C++20
2490b57cec5SDimitry Andric    basic_string& replace(size_type pos1, size_type n1, const basic_string& str,
25081ad6265SDimitry Andric                          size_type pos2, size_type n2=npos);                                   // C++14, constexpr since C++20
2510b57cec5SDimitry Andric    template <class T>
2520b57cec5SDimitry Andric        basic_string& replace(size_type pos1, size_type n1, const T& t,
25381ad6265SDimitry Andric                              size_type pos2, size_type n);                                     // C++17, constexpr since C++20
25481ad6265SDimitry Andric    basic_string& replace(size_type pos, size_type n1, const value_type* s, size_type n2);      // constexpr since C++20
25581ad6265SDimitry Andric    basic_string& replace(size_type pos, size_type n1, const value_type* s);                    // constexpr since C++20
25681ad6265SDimitry Andric    basic_string& replace(size_type pos, size_type n1, size_type n2, value_type c);             // constexpr since C++20
25781ad6265SDimitry Andric    basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str);       // constexpr since C++20
2580b57cec5SDimitry Andric    template <class T>
25981ad6265SDimitry Andric        basic_string& replace(const_iterator i1, const_iterator i2, const T& t);                // C++17, constexpr since C++20
26081ad6265SDimitry Andric    basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s, size_type n); // constexpr since C++20
26181ad6265SDimitry Andric    basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s);           // constexpr since C++20
26281ad6265SDimitry Andric    basic_string& replace(const_iterator i1, const_iterator i2, size_type n, value_type c);     // constexpr since C++20
2630b57cec5SDimitry Andric    template<class InputIterator>
26481ad6265SDimitry Andric        basic_string& replace(const_iterator i1, const_iterator i2, InputIterator j1, InputIterator j2); // constexpr since C++20
26581ad6265SDimitry Andric    basic_string& replace(const_iterator i1, const_iterator i2, initializer_list<value_type>);  // constexpr since C++20
2660b57cec5SDimitry Andric
26781ad6265SDimitry Andric    size_type copy(value_type* s, size_type n, size_type pos = 0) const;                        // constexpr since C++20
268*bdd1243dSDimitry Andric    basic_string substr(size_type pos = 0, size_type n = npos) const;                           // constexpr in C++20, removed in C++23
269*bdd1243dSDimitry Andric    basic_string substr(size_type pos = 0, size_type n = npos) const&;                          // since C++23
270*bdd1243dSDimitry Andric    constexpr basic_string substr(size_type pos = 0, size_type n = npos) &&;                    // since C++23
2710b57cec5SDimitry Andric    void swap(basic_string& str)
2720b57cec5SDimitry Andric        noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
27381ad6265SDimitry Andric                 allocator_traits<allocator_type>::is_always_equal::value);                     // C++17, constexpr since C++20
2740b57cec5SDimitry Andric
27581ad6265SDimitry Andric    const value_type* c_str() const noexcept;                                                   // constexpr since C++20
27681ad6265SDimitry Andric    const value_type* data() const noexcept;                                                    // constexpr since C++20
27781ad6265SDimitry Andric          value_type* data()       noexcept;                                                    // C++17, constexpr since C++20
2780b57cec5SDimitry Andric
27981ad6265SDimitry Andric    allocator_type get_allocator() const noexcept;                                              // constexpr since C++20
2800b57cec5SDimitry Andric
28181ad6265SDimitry Andric    size_type find(const basic_string& str, size_type pos = 0) const noexcept;                  // constexpr since C++20
2820b57cec5SDimitry Andric    template <class T>
28381ad6265SDimitry Andric        size_type find(const T& t, size_type pos = 0) const noexcept;                           // C++17, noexcept as an extension, constexpr since C++20
28481ad6265SDimitry Andric    size_type find(const value_type* s, size_type pos, size_type n) const noexcept;             // constexpr since C++20
28581ad6265SDimitry Andric    size_type find(const value_type* s, size_type pos = 0) const noexcept;                      // constexpr since C++20
28681ad6265SDimitry Andric    size_type find(value_type c, size_type pos = 0) const noexcept;                             // constexpr since C++20
2870b57cec5SDimitry Andric
28881ad6265SDimitry Andric    size_type rfind(const basic_string& str, size_type pos = npos) const noexcept;              // constexpr since C++20
2890b57cec5SDimitry Andric    template <class T>
29081ad6265SDimitry Andric        size_type rfind(const T& t, size_type pos = npos) const noexcept;                       // C++17, noexcept as an extension, constexpr since C++20
29181ad6265SDimitry Andric    size_type rfind(const value_type* s, size_type pos, size_type n) const noexcept;            // constexpr since C++20
29281ad6265SDimitry Andric    size_type rfind(const value_type* s, size_type pos = npos) const noexcept;                  // constexpr since C++20
29381ad6265SDimitry Andric    size_type rfind(value_type c, size_type pos = npos) const noexcept;                         // constexpr since C++20
2940b57cec5SDimitry Andric
29581ad6265SDimitry Andric    size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept;         // constexpr since C++20
2960b57cec5SDimitry Andric    template <class T>
29781ad6265SDimitry Andric        size_type find_first_of(const T& t, size_type pos = 0) const noexcept;                  // C++17, noexcept as an extension, constexpr since C++20
29881ad6265SDimitry Andric    size_type find_first_of(const value_type* s, size_type pos, size_type n) const noexcept;    // constexpr since C++20
29981ad6265SDimitry Andric    size_type find_first_of(const value_type* s, size_type pos = 0) const noexcept;             // constexpr since C++20
30081ad6265SDimitry Andric    size_type find_first_of(value_type c, size_type pos = 0) const noexcept;                    // constexpr since C++20
3010b57cec5SDimitry Andric
30281ad6265SDimitry Andric    size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept;       // constexpr since C++20
3030b57cec5SDimitry Andric    template <class T>
30481ad6265SDimitry Andric        size_type find_last_of(const T& t, size_type pos = npos) const noexcept noexcept;       // C++17, noexcept as an extension, constexpr since C++20
30581ad6265SDimitry Andric    size_type find_last_of(const value_type* s, size_type pos, size_type n) const noexcept;     // constexpr since C++20
30681ad6265SDimitry Andric    size_type find_last_of(const value_type* s, size_type pos = npos) const noexcept;           // constexpr since C++20
30781ad6265SDimitry Andric    size_type find_last_of(value_type c, size_type pos = npos) const noexcept;                  // constexpr since C++20
3080b57cec5SDimitry Andric
30981ad6265SDimitry Andric    size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept;     // constexpr since C++20
3100b57cec5SDimitry Andric    template <class T>
31181ad6265SDimitry Andric        size_type find_first_not_of(const T& t, size_type pos = 0) const noexcept;              // C++17, noexcept as an extension, constexpr since C++20
31281ad6265SDimitry Andric    size_type find_first_not_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20
31381ad6265SDimitry Andric    size_type find_first_not_of(const value_type* s, size_type pos = 0) const noexcept;         // constexpr since C++20
31481ad6265SDimitry Andric    size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept;                // constexpr since C++20
3150b57cec5SDimitry Andric
31681ad6265SDimitry Andric    size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept;   // constexpr since C++20
3170b57cec5SDimitry Andric    template <class T>
31881ad6265SDimitry Andric        size_type find_last_not_of(const T& t, size_type pos = npos) const noexcept;            // C++17, noexcept as an extension, constexpr since C++20
31981ad6265SDimitry Andric    size_type find_last_not_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20
32081ad6265SDimitry Andric    size_type find_last_not_of(const value_type* s, size_type pos = npos) const noexcept;       // constexpr since C++20
32181ad6265SDimitry Andric    size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept;              // constexpr since C++20
3220b57cec5SDimitry Andric
32381ad6265SDimitry Andric    int compare(const basic_string& str) const noexcept;                                        // constexpr since C++20
3240b57cec5SDimitry Andric    template <class T>
32581ad6265SDimitry Andric        int compare(const T& t) const noexcept;                                                 // C++17, noexcept as an extension, constexpr since C++20
32681ad6265SDimitry Andric    int compare(size_type pos1, size_type n1, const basic_string& str) const;                   // constexpr since C++20
3270b57cec5SDimitry Andric    template <class T>
32881ad6265SDimitry Andric        int compare(size_type pos1, size_type n1, const T& t) const;                            // C++17, constexpr since C++20
3290b57cec5SDimitry Andric    int compare(size_type pos1, size_type n1, const basic_string& str,
33081ad6265SDimitry Andric                size_type pos2, size_type n2=npos) const;                                       // C++14, constexpr since C++20
3310b57cec5SDimitry Andric    template <class T>
3320b57cec5SDimitry Andric        int compare(size_type pos1, size_type n1, const T& t,
33381ad6265SDimitry Andric                    size_type pos2, size_type n2=npos) const;                                   // C++17, constexpr since C++20
33481ad6265SDimitry Andric    int compare(const value_type* s) const noexcept;                                            // constexpr since C++20
33581ad6265SDimitry Andric    int compare(size_type pos1, size_type n1, const value_type* s) const;                       // constexpr since C++20
33681ad6265SDimitry Andric    int compare(size_type pos1, size_type n1, const value_type* s, size_type n2) const;         // constexpr since C++20
3370b57cec5SDimitry Andric
33881ad6265SDimitry Andric    constexpr bool starts_with(basic_string_view<charT, traits> sv) const noexcept;             // C++20
33981ad6265SDimitry Andric    constexpr bool starts_with(charT c) const noexcept;                                         // C++20
34081ad6265SDimitry Andric    constexpr bool starts_with(const charT* s) const;                                           // C++20
34181ad6265SDimitry Andric    constexpr bool ends_with(basic_string_view<charT, traits> sv) const noexcept;               // C++20
34281ad6265SDimitry Andric    constexpr bool ends_with(charT c) const noexcept;                                           // C++20
34381ad6265SDimitry Andric    constexpr bool ends_with(const charT* s) const;                                             // C++20
344e8d8bef9SDimitry Andric
345e8d8bef9SDimitry Andric    constexpr bool contains(basic_string_view<charT, traits> sv) const noexcept;                // C++2b
346e8d8bef9SDimitry Andric    constexpr bool contains(charT c) const noexcept;                                            // C++2b
347e8d8bef9SDimitry Andric    constexpr bool contains(const charT* s) const;                                              // C++2b
3480b57cec5SDimitry Andric};
3490b57cec5SDimitry Andric
3500b57cec5SDimitry Andrictemplate<class InputIterator,
3510b57cec5SDimitry Andric         class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
3520b57cec5SDimitry Andricbasic_string(InputIterator, InputIterator, Allocator = Allocator())
3530b57cec5SDimitry Andric   -> basic_string<typename iterator_traits<InputIterator>::value_type,
3540b57cec5SDimitry Andric                  char_traits<typename iterator_traits<InputIterator>::value_type>,
3550b57cec5SDimitry Andric                  Allocator>;   // C++17
3560b57cec5SDimitry Andric
3570b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator>
3580b57cec5SDimitry Andricbasic_string<charT, traits, Allocator>
3590b57cec5SDimitry Andricoperator+(const basic_string<charT, traits, Allocator>& lhs,
36081ad6265SDimitry Andric          const basic_string<charT, traits, Allocator>& rhs);                                   // constexpr since C++20
3610b57cec5SDimitry Andric
3620b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator>
3630b57cec5SDimitry Andricbasic_string<charT, traits, Allocator>
36481ad6265SDimitry Andricoperator+(const charT* lhs , const basic_string<charT,traits,Allocator>&rhs);                   // constexpr since C++20
3650b57cec5SDimitry Andric
3660b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator>
3670b57cec5SDimitry Andricbasic_string<charT, traits, Allocator>
36881ad6265SDimitry Andricoperator+(charT lhs, const basic_string<charT,traits,Allocator>& rhs);                          // constexpr since C++20
3690b57cec5SDimitry Andric
3700b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator>
3710b57cec5SDimitry Andricbasic_string<charT, traits, Allocator>
37281ad6265SDimitry Andricoperator+(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs);                 // constexpr since C++20
3730b57cec5SDimitry Andric
3740b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator>
3750b57cec5SDimitry Andricbasic_string<charT, traits, Allocator>
37681ad6265SDimitry Andricoperator+(const basic_string<charT, traits, Allocator>& lhs, charT rhs);                        // constexpr since C++20
3770b57cec5SDimitry Andric
3780b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator>
3790b57cec5SDimitry Andricbool operator==(const basic_string<charT, traits, Allocator>& lhs,
38081ad6265SDimitry Andric                const basic_string<charT, traits, Allocator>& rhs) noexcept;                    // constexpr since C++20
3810b57cec5SDimitry Andric
3820b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator>
383*bdd1243dSDimitry Andricbool operator==(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;  // removed in C++20
3840b57cec5SDimitry Andric
3850b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator>
38681ad6265SDimitry Andricbool operator==(const basic_string<charT,traits,Allocator>& lhs, const charT* rhs) noexcept;    // constexpr since C++20
3870b57cec5SDimitry Andric
3880b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator>
3890b57cec5SDimitry Andricbool operator!=(const basic_string<charT,traits,Allocator>& lhs,
390*bdd1243dSDimitry Andric                const basic_string<charT, traits, Allocator>& rhs) noexcept;                    // removed in C++20
3910b57cec5SDimitry Andric
3920b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator>
393*bdd1243dSDimitry Andricbool operator!=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;  // removed in C++20
3940b57cec5SDimitry Andric
3950b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator>
396*bdd1243dSDimitry Andricbool operator!=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;  // removed in C++20
3970b57cec5SDimitry Andric
3980b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator>
3990b57cec5SDimitry Andricbool operator< (const basic_string<charT, traits, Allocator>& lhs,
400*bdd1243dSDimitry Andric                const basic_string<charT, traits, Allocator>& rhs) noexcept;                    // removed in C++20
4010b57cec5SDimitry Andric
4020b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator>
403*bdd1243dSDimitry Andricbool operator< (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;  // removed in C++20
4040b57cec5SDimitry Andric
4050b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator>
406*bdd1243dSDimitry Andricbool operator< (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;  // removed in C++20
4070b57cec5SDimitry Andric
4080b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator>
4090b57cec5SDimitry Andricbool operator> (const basic_string<charT, traits, Allocator>& lhs,
410*bdd1243dSDimitry Andric                const basic_string<charT, traits, Allocator>& rhs) noexcept;                    // removed in C++20
4110b57cec5SDimitry Andric
4120b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator>
413*bdd1243dSDimitry Andricbool operator> (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;  // removed in C++20
4140b57cec5SDimitry Andric
4150b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator>
416*bdd1243dSDimitry Andricbool operator> (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;  // removed in C++20
4170b57cec5SDimitry Andric
4180b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator>
4190b57cec5SDimitry Andricbool operator<=(const basic_string<charT, traits, Allocator>& lhs,
420*bdd1243dSDimitry Andric                const basic_string<charT, traits, Allocator>& rhs) noexcept;                    // removed in C++20
4210b57cec5SDimitry Andric
4220b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator>
423*bdd1243dSDimitry Andricbool operator<=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;  // removed in C++20
4240b57cec5SDimitry Andric
4250b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator>
426*bdd1243dSDimitry Andricbool operator<=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;  // removed in C++20
4270b57cec5SDimitry Andric
4280b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator>
4290b57cec5SDimitry Andricbool operator>=(const basic_string<charT, traits, Allocator>& lhs,
430*bdd1243dSDimitry Andric                const basic_string<charT, traits, Allocator>& rhs) noexcept;                    // removed in C++20
4310b57cec5SDimitry Andric
4320b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator>
433*bdd1243dSDimitry Andricbool operator>=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;  // removed in C++20
4340b57cec5SDimitry Andric
4350b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator>
436*bdd1243dSDimitry Andricbool operator>=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;  // removed in C++20
437*bdd1243dSDimitry Andric
438*bdd1243dSDimitry Andrictemplate<class charT, class traits, class Allocator>                                            // since C++20
439*bdd1243dSDimitry Andricconstexpr see below operator<=>(const basic_string<charT, traits, Allocator>& lhs,
440*bdd1243dSDimitry Andric                                const basic_string<charT, traits, Allocator>& rhs) noexcept;
441*bdd1243dSDimitry Andric
442*bdd1243dSDimitry Andrictemplate<class charT, class traits, class Allocator>                                            // since C++20
443*bdd1243dSDimitry Andricconstexpr see below operator<=>(const basic_string<charT, traits, Allocator>& lhs,
444*bdd1243dSDimitry Andric                                const charT* rhs) noexcept;
4450b57cec5SDimitry Andric
4460b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator>
4470b57cec5SDimitry Andricvoid swap(basic_string<charT, traits, Allocator>& lhs,
4480b57cec5SDimitry Andric          basic_string<charT, traits, Allocator>& rhs)
44981ad6265SDimitry Andric            noexcept(noexcept(lhs.swap(rhs)));                                                  // constexpr since C++20
4500b57cec5SDimitry Andric
4510b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator>
4520b57cec5SDimitry Andricbasic_istream<charT, traits>&
4530b57cec5SDimitry Andricoperator>>(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str);
4540b57cec5SDimitry Andric
4550b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator>
4560b57cec5SDimitry Andricbasic_ostream<charT, traits>&
4570b57cec5SDimitry Andricoperator<<(basic_ostream<charT, traits>& os, const basic_string<charT, traits, Allocator>& str);
4580b57cec5SDimitry Andric
4590b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator>
4600b57cec5SDimitry Andricbasic_istream<charT, traits>&
4610b57cec5SDimitry Andricgetline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str,
4620b57cec5SDimitry Andric        charT delim);
4630b57cec5SDimitry Andric
4640b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator>
4650b57cec5SDimitry Andricbasic_istream<charT, traits>&
4660b57cec5SDimitry Andricgetline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str);
4670b57cec5SDimitry Andric
4680b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator, class U>
4695ffd83dbSDimitry Andrictypename basic_string<charT, traits, Allocator>::size_type
4705ffd83dbSDimitry Andricerase(basic_string<charT, traits, Allocator>& c, const U& value);    // C++20
4710b57cec5SDimitry Andrictemplate<class charT, class traits, class Allocator, class Predicate>
4725ffd83dbSDimitry Andrictypename basic_string<charT, traits, Allocator>::size_type
4735ffd83dbSDimitry Andricerase_if(basic_string<charT, traits, Allocator>& c, Predicate pred); // C++20
4740b57cec5SDimitry Andric
4750b57cec5SDimitry Andrictypedef basic_string<char>    string;
4760b57cec5SDimitry Andrictypedef basic_string<wchar_t> wstring;
477fe6060f1SDimitry Andrictypedef basic_string<char8_t> u8string; // C++20
4780b57cec5SDimitry Andrictypedef basic_string<char16_t> u16string;
4790b57cec5SDimitry Andrictypedef basic_string<char32_t> u32string;
4800b57cec5SDimitry Andric
481e8d8bef9SDimitry Andricint                stoi  (const string& str, size_t* idx = nullptr, int base = 10);
482e8d8bef9SDimitry Andriclong               stol  (const string& str, size_t* idx = nullptr, int base = 10);
483e8d8bef9SDimitry Andricunsigned long      stoul (const string& str, size_t* idx = nullptr, int base = 10);
484e8d8bef9SDimitry Andriclong long          stoll (const string& str, size_t* idx = nullptr, int base = 10);
485e8d8bef9SDimitry Andricunsigned long long stoull(const string& str, size_t* idx = nullptr, int base = 10);
4860b57cec5SDimitry Andric
487e8d8bef9SDimitry Andricfloat       stof (const string& str, size_t* idx = nullptr);
488e8d8bef9SDimitry Andricdouble      stod (const string& str, size_t* idx = nullptr);
489e8d8bef9SDimitry Andriclong double stold(const string& str, size_t* idx = nullptr);
4900b57cec5SDimitry Andric
4910b57cec5SDimitry Andricstring to_string(int val);
4920b57cec5SDimitry Andricstring to_string(unsigned val);
4930b57cec5SDimitry Andricstring to_string(long val);
4940b57cec5SDimitry Andricstring to_string(unsigned long val);
4950b57cec5SDimitry Andricstring to_string(long long val);
4960b57cec5SDimitry Andricstring to_string(unsigned long long val);
4970b57cec5SDimitry Andricstring to_string(float val);
4980b57cec5SDimitry Andricstring to_string(double val);
4990b57cec5SDimitry Andricstring to_string(long double val);
5000b57cec5SDimitry Andric
501e8d8bef9SDimitry Andricint                stoi  (const wstring& str, size_t* idx = nullptr, int base = 10);
502e8d8bef9SDimitry Andriclong               stol  (const wstring& str, size_t* idx = nullptr, int base = 10);
503e8d8bef9SDimitry Andricunsigned long      stoul (const wstring& str, size_t* idx = nullptr, int base = 10);
504e8d8bef9SDimitry Andriclong long          stoll (const wstring& str, size_t* idx = nullptr, int base = 10);
505e8d8bef9SDimitry Andricunsigned long long stoull(const wstring& str, size_t* idx = nullptr, int base = 10);
5060b57cec5SDimitry Andric
507e8d8bef9SDimitry Andricfloat       stof (const wstring& str, size_t* idx = nullptr);
508e8d8bef9SDimitry Andricdouble      stod (const wstring& str, size_t* idx = nullptr);
509e8d8bef9SDimitry Andriclong double stold(const wstring& str, size_t* idx = nullptr);
5100b57cec5SDimitry Andric
5110b57cec5SDimitry Andricwstring to_wstring(int val);
5120b57cec5SDimitry Andricwstring to_wstring(unsigned val);
5130b57cec5SDimitry Andricwstring to_wstring(long val);
5140b57cec5SDimitry Andricwstring to_wstring(unsigned long val);
5150b57cec5SDimitry Andricwstring to_wstring(long long val);
5160b57cec5SDimitry Andricwstring to_wstring(unsigned long long val);
5170b57cec5SDimitry Andricwstring to_wstring(float val);
5180b57cec5SDimitry Andricwstring to_wstring(double val);
5190b57cec5SDimitry Andricwstring to_wstring(long double val);
5200b57cec5SDimitry Andric
5210b57cec5SDimitry Andrictemplate <> struct hash<string>;
522fe6060f1SDimitry Andrictemplate <> struct hash<u8string>; // C++20
5230b57cec5SDimitry Andrictemplate <> struct hash<u16string>;
5240b57cec5SDimitry Andrictemplate <> struct hash<u32string>;
5250b57cec5SDimitry Andrictemplate <> struct hash<wstring>;
5260b57cec5SDimitry Andric
52781ad6265SDimitry Andricbasic_string<char>     operator "" s( const char *str,     size_t len );           // C++14, constexpr since C++20
52881ad6265SDimitry Andricbasic_string<wchar_t>  operator "" s( const wchar_t *str,  size_t len );           // C++14, constexpr since C++20
52981ad6265SDimitry Andricconstexpr basic_string<char8_t>  operator "" s( const char8_t *str,  size_t len ); // C++20
53081ad6265SDimitry Andricbasic_string<char16_t> operator "" s( const char16_t *str, size_t len );           // C++14, constexpr since C++20
53181ad6265SDimitry Andricbasic_string<char32_t> operator "" s( const char32_t *str, size_t len );           // C++14, constexpr since C++20
5320b57cec5SDimitry Andric
5330b57cec5SDimitry Andric}  // std
5340b57cec5SDimitry Andric
5350b57cec5SDimitry Andric*/
5360b57cec5SDimitry Andric
53781ad6265SDimitry Andric#include <__algorithm/max.h>
53881ad6265SDimitry Andric#include <__algorithm/min.h>
53981ad6265SDimitry Andric#include <__algorithm/remove.h>
54081ad6265SDimitry Andric#include <__algorithm/remove_if.h>
54181ad6265SDimitry Andric#include <__assert> // all public C++ headers provide the assertion handler
5420b57cec5SDimitry Andric#include <__config>
543fe6060f1SDimitry Andric#include <__debug>
54481ad6265SDimitry Andric#include <__format/enable_insertable.h>
54581ad6265SDimitry Andric#include <__functional/hash.h>
54681ad6265SDimitry Andric#include <__functional/unary_function.h>
547*bdd1243dSDimitry Andric#include <__fwd/string.h>
54881ad6265SDimitry Andric#include <__ios/fpos.h>
54981ad6265SDimitry Andric#include <__iterator/distance.h>
55081ad6265SDimitry Andric#include <__iterator/iterator_traits.h>
55181ad6265SDimitry Andric#include <__iterator/reverse_iterator.h>
552fe6060f1SDimitry Andric#include <__iterator/wrap_iter.h>
55381ad6265SDimitry Andric#include <__memory/allocate_at_least.h>
554*bdd1243dSDimitry Andric#include <__memory/allocator.h>
555*bdd1243dSDimitry Andric#include <__memory/allocator_traits.h>
556*bdd1243dSDimitry Andric#include <__memory/compressed_pair.h>
557*bdd1243dSDimitry Andric#include <__memory/construct_at.h>
558*bdd1243dSDimitry Andric#include <__memory/pointer_traits.h>
559972a253aSDimitry Andric#include <__memory/swap_allocator.h>
560*bdd1243dSDimitry Andric#include <__memory_resource/polymorphic_allocator.h>
56181ad6265SDimitry Andric#include <__string/char_traits.h>
56281ad6265SDimitry Andric#include <__string/extern_template_lists.h>
563*bdd1243dSDimitry Andric#include <__type_traits/is_allocator.h>
564*bdd1243dSDimitry Andric#include <__type_traits/noexcept_move_assign_container.h>
56581ad6265SDimitry Andric#include <__utility/auto_cast.h>
56681ad6265SDimitry Andric#include <__utility/move.h>
56781ad6265SDimitry Andric#include <__utility/swap.h>
56881ad6265SDimitry Andric#include <__utility/unreachable.h>
56981ad6265SDimitry Andric#include <climits>
57081ad6265SDimitry Andric#include <cstdint>
571fe6060f1SDimitry Andric#include <cstdio>  // EOF
57269ade1e0SDimitry Andric#include <cstdlib>
573fe6060f1SDimitry Andric#include <cstring>
57481ad6265SDimitry Andric#include <limits>
5750b57cec5SDimitry Andric#include <stdexcept>
576fe6060f1SDimitry Andric#include <string_view>
5770b57cec5SDimitry Andric#include <type_traits>
5780b57cec5SDimitry Andric#include <version>
579fe6060f1SDimitry Andric
580349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
581349cc55cSDimitry Andric#  include <cwchar>
582349cc55cSDimitry Andric#endif
583349cc55cSDimitry Andric
58481ad6265SDimitry Andric// standard-mandated includes
58581ad6265SDimitry Andric
58681ad6265SDimitry Andric// [iterator.range]
58781ad6265SDimitry Andric#include <__iterator/access.h>
58881ad6265SDimitry Andric#include <__iterator/data.h>
58981ad6265SDimitry Andric#include <__iterator/empty.h>
59081ad6265SDimitry Andric#include <__iterator/reverse_access.h>
59181ad6265SDimitry Andric#include <__iterator/size.h>
59281ad6265SDimitry Andric
59381ad6265SDimitry Andric// [string.syn]
59481ad6265SDimitry Andric#include <compare>
59581ad6265SDimitry Andric#include <initializer_list>
59681ad6265SDimitry Andric
5970b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
5980b57cec5SDimitry Andric#  pragma GCC system_header
5990b57cec5SDimitry Andric#endif
6000b57cec5SDimitry Andric
6010b57cec5SDimitry Andric_LIBCPP_PUSH_MACROS
6020b57cec5SDimitry Andric#include <__undef_macros>
6030b57cec5SDimitry Andric
6040b57cec5SDimitry Andric
6050b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
6060b57cec5SDimitry Andric
6070b57cec5SDimitry Andric// basic_string
6080b57cec5SDimitry Andric
6090b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
6100b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>
611*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
6120b57cec5SDimitry Andricoperator+(const basic_string<_CharT, _Traits, _Allocator>& __x,
6130b57cec5SDimitry Andric          const basic_string<_CharT, _Traits, _Allocator>& __y);
6140b57cec5SDimitry Andric
6150b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
616*bdd1243dSDimitry Andric_LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX20
6170b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>
6180b57cec5SDimitry Andricoperator+(const _CharT* __x, const basic_string<_CharT,_Traits,_Allocator>& __y);
6190b57cec5SDimitry Andric
6200b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
621*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
6220b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>
6230b57cec5SDimitry Andricoperator+(_CharT __x, const basic_string<_CharT,_Traits,_Allocator>& __y);
6240b57cec5SDimitry Andric
6250b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
626*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
6270b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>
6280b57cec5SDimitry Andricoperator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const _CharT* __y);
6290b57cec5SDimitry Andric
6300b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
631*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
6320b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>
6330b57cec5SDimitry Andricoperator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y);
6340b57cec5SDimitry Andric
63581ad6265SDimitry Andricextern template _LIBCPP_FUNC_VIS string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
6360b57cec5SDimitry Andric
6370b57cec5SDimitry Andrictemplate <class _Iter>
638fe6060f1SDimitry Andricstruct __string_is_trivial_iterator : public false_type {};
639fe6060f1SDimitry Andric
640fe6060f1SDimitry Andrictemplate <class _Tp>
641fe6060f1SDimitry Andricstruct __string_is_trivial_iterator<_Tp*>
642fe6060f1SDimitry Andric    : public is_arithmetic<_Tp> {};
6430b57cec5SDimitry Andric
6440b57cec5SDimitry Andrictemplate <class _Iter>
645fe6060f1SDimitry Andricstruct __string_is_trivial_iterator<__wrap_iter<_Iter> >
646fe6060f1SDimitry Andric    : public __string_is_trivial_iterator<_Iter> {};
6470b57cec5SDimitry Andric
6480b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Tp>
6495ffd83dbSDimitry Andricstruct __can_be_converted_to_string_view : public _BoolConstant<
6505ffd83dbSDimitry Andric      is_convertible<const _Tp&, basic_string_view<_CharT, _Traits> >::value &&
6515ffd83dbSDimitry Andric     !is_convertible<const _Tp&, const _CharT*>::value
6525ffd83dbSDimitry Andric    > {};
6530b57cec5SDimitry Andric
65481ad6265SDimitry Andricstruct __uninitialized_size_tag {};
655e8d8bef9SDimitry Andric
6560b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
657*bdd1243dSDimitry Andricclass basic_string
6580b57cec5SDimitry Andric{
6590b57cec5SDimitry Andricpublic:
6600b57cec5SDimitry Andric    typedef basic_string                                 __self;
6610b57cec5SDimitry Andric    typedef basic_string_view<_CharT, _Traits>           __self_view;
6620b57cec5SDimitry Andric    typedef _Traits                                      traits_type;
6630b57cec5SDimitry Andric    typedef _CharT                                       value_type;
6640b57cec5SDimitry Andric    typedef _Allocator                                   allocator_type;
6650b57cec5SDimitry Andric    typedef allocator_traits<allocator_type>             __alloc_traits;
6660b57cec5SDimitry Andric    typedef typename __alloc_traits::size_type           size_type;
6670b57cec5SDimitry Andric    typedef typename __alloc_traits::difference_type     difference_type;
6680b57cec5SDimitry Andric    typedef value_type&                                  reference;
6690b57cec5SDimitry Andric    typedef const value_type&                            const_reference;
6700b57cec5SDimitry Andric    typedef typename __alloc_traits::pointer             pointer;
6710b57cec5SDimitry Andric    typedef typename __alloc_traits::const_pointer       const_pointer;
6720b57cec5SDimitry Andric
6730b57cec5SDimitry Andric    static_assert((!is_array<value_type>::value), "Character type of basic_string must not be an array");
6740b57cec5SDimitry Andric    static_assert(( is_standard_layout<value_type>::value), "Character type of basic_string must be standard-layout");
6750b57cec5SDimitry Andric    static_assert(( is_trivial<value_type>::value), "Character type of basic_string must be trivial");
6760b57cec5SDimitry Andric    static_assert(( is_same<_CharT, typename traits_type::char_type>::value),
6770b57cec5SDimitry Andric                  "traits_type::char_type must be the same type as CharT");
6780b57cec5SDimitry Andric    static_assert(( is_same<typename allocator_type::value_type, value_type>::value),
6790b57cec5SDimitry Andric                  "Allocator::value_type must be same type as value_type");
6800b57cec5SDimitry Andric
681*bdd1243dSDimitry Andric    static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value,
682*bdd1243dSDimitry Andric                  "[allocator.requirements] states that rebinding an allocator to the same type should result in the "
683*bdd1243dSDimitry Andric                  "original allocator");
684*bdd1243dSDimitry Andric
685*bdd1243dSDimitry Andric    // TODO: Implement iterator bounds checking without requiring the global database.
6860b57cec5SDimitry Andric    typedef __wrap_iter<pointer>                         iterator;
6870b57cec5SDimitry Andric    typedef __wrap_iter<const_pointer>                   const_iterator;
68881ad6265SDimitry Andric    typedef std::reverse_iterator<iterator>              reverse_iterator;
68981ad6265SDimitry Andric    typedef std::reverse_iterator<const_iterator>        const_reverse_iterator;
6900b57cec5SDimitry Andric
6910b57cec5SDimitry Andricprivate:
69281ad6265SDimitry Andric    static_assert(CHAR_BIT == 8, "This implementation assumes that one byte contains 8 bits");
6930b57cec5SDimitry Andric
6940b57cec5SDimitry Andric#ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
6950b57cec5SDimitry Andric
6960b57cec5SDimitry Andric    struct __long
6970b57cec5SDimitry Andric    {
6980b57cec5SDimitry Andric        pointer   __data_;
6990b57cec5SDimitry Andric        size_type __size_;
70081ad6265SDimitry Andric        size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1;
70181ad6265SDimitry Andric        size_type __is_long_ : 1;
7020b57cec5SDimitry Andric    };
7030b57cec5SDimitry Andric
7040b57cec5SDimitry Andric    enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ?
7050b57cec5SDimitry Andric                      (sizeof(__long) - 1)/sizeof(value_type) : 2};
7060b57cec5SDimitry Andric
7070b57cec5SDimitry Andric    struct __short
7080b57cec5SDimitry Andric    {
7090b57cec5SDimitry Andric        value_type __data_[__min_cap];
71081ad6265SDimitry Andric        unsigned char __padding_[sizeof(value_type) - 1];
71181ad6265SDimitry Andric        unsigned char __size_ : 7;
71281ad6265SDimitry Andric        unsigned char __is_long_ : 1;
7130b57cec5SDimitry Andric    };
7140b57cec5SDimitry Andric
71581ad6265SDimitry Andric// The __endian_factor is required because the field we use to store the size
71681ad6265SDimitry Andric// has one fewer bit than it would if it were not a bitfield.
71781ad6265SDimitry Andric//
71881ad6265SDimitry Andric// If the LSB is used to store the short-flag in the short string representation,
71981ad6265SDimitry Andric// we have to multiply the size by two when it is stored and divide it by two when
72081ad6265SDimitry Andric// it is loaded to make sure that we always store an even number. In the long string
72181ad6265SDimitry Andric// representation, we can ignore this because we can assume that we always allocate
72281ad6265SDimitry Andric// an even amount of value_types.
72381ad6265SDimitry Andric//
72481ad6265SDimitry Andric// If the MSB is used for the short-flag, the max_size() is numeric_limits<size_type>::max() / 2.
72581ad6265SDimitry Andric// This does not impact the short string representation, since we never need the MSB
72681ad6265SDimitry Andric// for representing the size of a short string anyway.
72781ad6265SDimitry Andric
72881ad6265SDimitry Andric#ifdef _LIBCPP_BIG_ENDIAN
72981ad6265SDimitry Andric    static const size_type __endian_factor = 2;
7300b57cec5SDimitry Andric#else
73181ad6265SDimitry Andric    static const size_type __endian_factor = 1;
73281ad6265SDimitry Andric#endif
7330b57cec5SDimitry Andric
73481ad6265SDimitry Andric#else // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
73581ad6265SDimitry Andric
73681ad6265SDimitry Andric#ifdef _LIBCPP_BIG_ENDIAN
73781ad6265SDimitry Andric    static const size_type __endian_factor = 1;
73881ad6265SDimitry Andric#else
73981ad6265SDimitry Andric    static const size_type __endian_factor = 2;
74081ad6265SDimitry Andric#endif
74181ad6265SDimitry Andric
74281ad6265SDimitry Andric    // Attribute 'packed' is used to keep the layout compatible with the
74381ad6265SDimitry Andric    // previous definition that did not use bit fields. This is because on
74481ad6265SDimitry Andric    // some platforms bit fields have a default size rather than the actual
74581ad6265SDimitry Andric    // size used, e.g., it is 4 bytes on AIX. See D128285 for details.
7460b57cec5SDimitry Andric    struct __long
7470b57cec5SDimitry Andric    {
74881ad6265SDimitry Andric        struct _LIBCPP_PACKED {
74981ad6265SDimitry Andric            size_type __is_long_ : 1;
75081ad6265SDimitry Andric            size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1;
75181ad6265SDimitry Andric        };
7520b57cec5SDimitry Andric        size_type __size_;
7530b57cec5SDimitry Andric        pointer   __data_;
7540b57cec5SDimitry Andric    };
7550b57cec5SDimitry Andric
7560b57cec5SDimitry Andric    enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ?
7570b57cec5SDimitry Andric                      (sizeof(__long) - 1)/sizeof(value_type) : 2};
7580b57cec5SDimitry Andric
7590b57cec5SDimitry Andric    struct __short
7600b57cec5SDimitry Andric    {
76181ad6265SDimitry Andric        struct _LIBCPP_PACKED {
76281ad6265SDimitry Andric            unsigned char __is_long_ : 1;
76381ad6265SDimitry Andric            unsigned char __size_ : 7;
7640b57cec5SDimitry Andric        };
76581ad6265SDimitry Andric        char __padding_[sizeof(value_type) - 1];
7660b57cec5SDimitry Andric        value_type __data_[__min_cap];
7670b57cec5SDimitry Andric    };
7680b57cec5SDimitry Andric
7690b57cec5SDimitry Andric#endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
7700b57cec5SDimitry Andric
77181ad6265SDimitry Andric    static_assert(sizeof(__short) == (sizeof(value_type) * (__min_cap + 1)), "__short has an unexpected size.");
77281ad6265SDimitry Andric
7730b57cec5SDimitry Andric    union __ulx{__long __lx; __short __lxx;};
7740b57cec5SDimitry Andric
7750b57cec5SDimitry Andric    enum {__n_words = sizeof(__ulx) / sizeof(size_type)};
7760b57cec5SDimitry Andric
7770b57cec5SDimitry Andric    struct __raw
7780b57cec5SDimitry Andric    {
7790b57cec5SDimitry Andric        size_type __words[__n_words];
7800b57cec5SDimitry Andric    };
7810b57cec5SDimitry Andric
7820b57cec5SDimitry Andric    struct __rep
7830b57cec5SDimitry Andric    {
7840b57cec5SDimitry Andric        union
7850b57cec5SDimitry Andric        {
7860b57cec5SDimitry Andric            __long  __l;
7870b57cec5SDimitry Andric            __short __s;
7880b57cec5SDimitry Andric            __raw   __r;
7890b57cec5SDimitry Andric        };
7900b57cec5SDimitry Andric    };
7910b57cec5SDimitry Andric
7920b57cec5SDimitry Andric    __compressed_pair<__rep, allocator_type> __r_;
7930b57cec5SDimitry Andric
79481ad6265SDimitry Andric    // Construct a string with the given allocator and enough storage to hold `__size` characters, but
79581ad6265SDimitry Andric    // don't initialize the characters. The contents of the string, including the null terminator, must be
79681ad6265SDimitry Andric    // initialized separately.
797*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
79881ad6265SDimitry Andric    explicit basic_string(__uninitialized_size_tag, size_type __size, const allocator_type& __a)
79981ad6265SDimitry Andric            : __r_(__default_init_tag(), __a) {
80081ad6265SDimitry Andric        if (__size > max_size())
80181ad6265SDimitry Andric            __throw_length_error();
80281ad6265SDimitry Andric        if (__fits_in_sso(__size)) {
803*bdd1243dSDimitry Andric            __r_.first() = __rep();
80481ad6265SDimitry Andric            __set_short_size(__size);
80581ad6265SDimitry Andric        } else {
80681ad6265SDimitry Andric            auto __capacity = __recommend(__size) + 1;
80781ad6265SDimitry Andric            auto __allocation = __alloc_traits::allocate(__alloc(), __capacity);
80881ad6265SDimitry Andric            __begin_lifetime(__allocation, __capacity);
80981ad6265SDimitry Andric            __set_long_cap(__capacity);
81081ad6265SDimitry Andric            __set_long_pointer(__allocation);
81181ad6265SDimitry Andric            __set_long_size(__size);
81281ad6265SDimitry Andric        }
81381ad6265SDimitry Andric        std::__debug_db_insert_c(this);
81481ad6265SDimitry Andric    }
81581ad6265SDimitry Andric
816*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator __make_iterator(pointer __p) {
817*bdd1243dSDimitry Andric        return iterator(this, __p);
818*bdd1243dSDimitry Andric    }
819*bdd1243dSDimitry Andric
820*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator __make_const_iterator(const_pointer __p) const {
821*bdd1243dSDimitry Andric        return const_iterator(this, __p);
822*bdd1243dSDimitry Andric    }
823*bdd1243dSDimitry Andric
8240b57cec5SDimitry Andricpublic:
825*bdd1243dSDimitry Andric  _LIBCPP_TEMPLATE_DATA_VIS static const size_type npos = -1;
8260b57cec5SDimitry Andric
827*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string()
828*bdd1243dSDimitry Andric      _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
829*bdd1243dSDimitry Andric      : __r_(__default_init_tag(), __default_init_tag()) {
830*bdd1243dSDimitry Andric    std::__debug_db_insert_c(this);
831*bdd1243dSDimitry Andric    __default_init();
832*bdd1243dSDimitry Andric  }
8330b57cec5SDimitry Andric
834*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(const allocator_type& __a)
8350b57cec5SDimitry Andric#if _LIBCPP_STD_VER <= 14
836*bdd1243dSDimitry Andric      _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
8370b57cec5SDimitry Andric#else
838*bdd1243dSDimitry Andric      _NOEXCEPT
8390b57cec5SDimitry Andric#endif
840*bdd1243dSDimitry Andric      : __r_(__default_init_tag(), __a) {
841*bdd1243dSDimitry Andric    std::__debug_db_insert_c(this);
842*bdd1243dSDimitry Andric    __default_init();
843*bdd1243dSDimitry Andric  }
8440b57cec5SDimitry Andric
845*bdd1243dSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const basic_string& __str);
846*bdd1243dSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const basic_string& __str, const allocator_type& __a);
8470b57cec5SDimitry Andric
8480b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
849*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(basic_string&& __str)
8500b57cec5SDimitry Andric#  if _LIBCPP_STD_VER <= 14
851*bdd1243dSDimitry Andric      _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
8520b57cec5SDimitry Andric#  else
853*bdd1243dSDimitry Andric      _NOEXCEPT
8540b57cec5SDimitry Andric#  endif
855*bdd1243dSDimitry Andric      : __r_(std::move(__str.__r_)) {
856*bdd1243dSDimitry Andric    __str.__default_init();
857*bdd1243dSDimitry Andric    std::__debug_db_insert_c(this);
858*bdd1243dSDimitry Andric    if (__is_long())
859*bdd1243dSDimitry Andric      std::__debug_db_swap(this, &__str);
860*bdd1243dSDimitry Andric  }
8610b57cec5SDimitry Andric
862*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(basic_string&& __str, const allocator_type& __a)
863*bdd1243dSDimitry Andric      : __r_(__default_init_tag(), __a) {
864*bdd1243dSDimitry Andric    if (__str.__is_long() && __a != __str.__alloc()) // copy, not move
865*bdd1243dSDimitry Andric      __init(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size());
866*bdd1243dSDimitry Andric    else {
867*bdd1243dSDimitry Andric      if (__libcpp_is_constant_evaluated())
868*bdd1243dSDimitry Andric        __r_.first() = __rep();
869*bdd1243dSDimitry Andric      __r_.first() = __str.__r_.first();
870*bdd1243dSDimitry Andric      __str.__default_init();
871*bdd1243dSDimitry Andric    }
872*bdd1243dSDimitry Andric    std::__debug_db_insert_c(this);
873*bdd1243dSDimitry Andric    if (__is_long())
874*bdd1243dSDimitry Andric      std::__debug_db_swap(this, &__str);
875*bdd1243dSDimitry Andric  }
8760b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
8770b57cec5SDimitry Andric
878349cc55cSDimitry Andric  template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> >
879*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s)
880*bdd1243dSDimitry Andric      : __r_(__default_init_tag(), __default_init_tag()) {
8810b57cec5SDimitry Andric    _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr");
8820b57cec5SDimitry Andric    __init(__s, traits_type::length(__s));
88381ad6265SDimitry Andric    std::__debug_db_insert_c(this);
8840b57cec5SDimitry Andric  }
8850b57cec5SDimitry Andric
886349cc55cSDimitry Andric  template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> >
887*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s, const _Allocator& __a);
8880b57cec5SDimitry Andric
889fe6060f1SDimitry Andric#if _LIBCPP_STD_VER > 20
890fe6060f1SDimitry Andric  basic_string(nullptr_t) = delete;
891fe6060f1SDimitry Andric#endif
892fe6060f1SDimitry Andric
893*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s, size_type __n)
894*bdd1243dSDimitry Andric      : __r_(__default_init_tag(), __default_init_tag()) {
895*bdd1243dSDimitry Andric    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr");
896*bdd1243dSDimitry Andric    __init(__s, __n);
897*bdd1243dSDimitry Andric    std::__debug_db_insert_c(this);
898*bdd1243dSDimitry Andric  }
899*bdd1243dSDimitry Andric
900*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
901*bdd1243dSDimitry Andric  basic_string(const _CharT* __s, size_type __n, const _Allocator& __a)
902*bdd1243dSDimitry Andric      : __r_(__default_init_tag(), __a) {
903*bdd1243dSDimitry Andric    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr");
904*bdd1243dSDimitry Andric    __init(__s, __n);
905*bdd1243dSDimitry Andric    std::__debug_db_insert_c(this);
906*bdd1243dSDimitry Andric  }
907*bdd1243dSDimitry Andric
908*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(size_type __n, _CharT __c)
909*bdd1243dSDimitry Andric      : __r_(__default_init_tag(), __default_init_tag()) {
910*bdd1243dSDimitry Andric    __init(__n, __c);
911*bdd1243dSDimitry Andric    std::__debug_db_insert_c(this);
912*bdd1243dSDimitry Andric  }
913*bdd1243dSDimitry Andric
914*bdd1243dSDimitry Andric#if _LIBCPP_STD_VER > 20
915*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI constexpr
916*bdd1243dSDimitry Andric  basic_string(basic_string&& __str, size_type __pos, const _Allocator& __alloc = _Allocator())
917*bdd1243dSDimitry Andric      : basic_string(std::move(__str), __pos, npos, __alloc) {}
918*bdd1243dSDimitry Andric
919*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI constexpr
920*bdd1243dSDimitry Andric  basic_string(basic_string&& __str, size_type __pos, size_type __n, const _Allocator& __alloc = _Allocator())
921*bdd1243dSDimitry Andric      : __r_(__default_init_tag(), __alloc) {
922*bdd1243dSDimitry Andric    if (__pos > __str.size())
923*bdd1243dSDimitry Andric      __throw_out_of_range();
924*bdd1243dSDimitry Andric
925*bdd1243dSDimitry Andric    auto __len = std::min<size_type>(__n, __str.size() - __pos);
926*bdd1243dSDimitry Andric    if (__alloc_traits::is_always_equal::value || __alloc == __str.__alloc()) {
927*bdd1243dSDimitry Andric      __r_.first() = __str.__r_.first();
928*bdd1243dSDimitry Andric      __str.__default_init();
929*bdd1243dSDimitry Andric
930*bdd1243dSDimitry Andric      _Traits::move(data(), data() + __pos, __len);
931*bdd1243dSDimitry Andric      __set_size(__len);
932*bdd1243dSDimitry Andric      _Traits::assign(data()[__len], value_type());
933*bdd1243dSDimitry Andric    } else {
934*bdd1243dSDimitry Andric      // Perform a copy because the allocators are not compatible.
935*bdd1243dSDimitry Andric      __init(__str.data() + __pos, __len);
936*bdd1243dSDimitry Andric    }
937*bdd1243dSDimitry Andric
938*bdd1243dSDimitry Andric    std::__debug_db_insert_c(this);
939*bdd1243dSDimitry Andric    if (__is_long())
940*bdd1243dSDimitry Andric      std::__debug_db_swap(this, &__str);
941*bdd1243dSDimitry Andric  }
942*bdd1243dSDimitry Andric#endif
9430b57cec5SDimitry Andric
944349cc55cSDimitry Andric  template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> >
945*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(size_type __n, _CharT __c, const _Allocator& __a);
9460b57cec5SDimitry Andric
947*bdd1243dSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20
948*bdd1243dSDimitry Andric  basic_string(const basic_string& __str, size_type __pos, size_type __n, const _Allocator& __a = _Allocator());
9490b57cec5SDimitry Andric
950*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
951*bdd1243dSDimitry Andric  basic_string(const basic_string& __str, size_type __pos, const _Allocator& __a = _Allocator())
952*bdd1243dSDimitry Andric      : __r_(__default_init_tag(), __a) {
953*bdd1243dSDimitry Andric    size_type __str_sz = __str.size();
954*bdd1243dSDimitry Andric    if (__pos > __str_sz)
955*bdd1243dSDimitry Andric      __throw_out_of_range();
956*bdd1243dSDimitry Andric    __init(__str.data() + __pos, __str_sz - __pos);
957*bdd1243dSDimitry Andric    std::__debug_db_insert_c(this);
958*bdd1243dSDimitry Andric  }
9590b57cec5SDimitry Andric
960*bdd1243dSDimitry Andric  template <class _Tp,
961*bdd1243dSDimitry Andric            class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
9625ffd83dbSDimitry Andric                                  !__is_same_uncvref<_Tp, basic_string>::value> >
963*bdd1243dSDimitry Andric  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
964*bdd1243dSDimitry Andric  basic_string(const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a = allocator_type());
9650b57cec5SDimitry Andric
966*bdd1243dSDimitry Andric  template <class _Tp,
967*bdd1243dSDimitry Andric            class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
968*bdd1243dSDimitry Andric                                  !__is_same_uncvref<_Tp, basic_string>::value> >
969*bdd1243dSDimitry Andric  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(
970*bdd1243dSDimitry Andric      const _Tp& __t);
971*bdd1243dSDimitry Andric
972*bdd1243dSDimitry Andric  template <class _Tp,
973*bdd1243dSDimitry Andric            class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
974*bdd1243dSDimitry Andric                                  !__is_same_uncvref<_Tp, basic_string>::value> >
975*bdd1243dSDimitry Andric  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(
976*bdd1243dSDimitry Andric      const _Tp& __t, const allocator_type& __a);
9770b57cec5SDimitry Andric
978349cc55cSDimitry Andric  template <class _InputIterator, class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value> >
979*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(_InputIterator __first, _InputIterator __last)
980*bdd1243dSDimitry Andric      : __r_(__default_init_tag(), __default_init_tag()) {
981*bdd1243dSDimitry Andric    __init(__first, __last);
982*bdd1243dSDimitry Andric    std::__debug_db_insert_c(this);
983*bdd1243dSDimitry Andric  }
984*bdd1243dSDimitry Andric
985349cc55cSDimitry Andric  template <class _InputIterator, class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value> >
986*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
987*bdd1243dSDimitry Andric  basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a)
988*bdd1243dSDimitry Andric      : __r_(__default_init_tag(), __a) {
989*bdd1243dSDimitry Andric    __init(__first, __last);
990*bdd1243dSDimitry Andric    std::__debug_db_insert_c(this);
991*bdd1243dSDimitry Andric  }
992*bdd1243dSDimitry Andric
9930b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
994*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(initializer_list<_CharT> __il)
995*bdd1243dSDimitry Andric      : __r_(__default_init_tag(), __default_init_tag()) {
996*bdd1243dSDimitry Andric    __init(__il.begin(), __il.end());
997*bdd1243dSDimitry Andric    std::__debug_db_insert_c(this);
998*bdd1243dSDimitry Andric  }
999*bdd1243dSDimitry Andric
1000*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(initializer_list<_CharT> __il, const _Allocator& __a)
1001*bdd1243dSDimitry Andric      : __r_(__default_init_tag(), __a) {
1002*bdd1243dSDimitry Andric    __init(__il.begin(), __il.end());
1003*bdd1243dSDimitry Andric    std::__debug_db_insert_c(this);
1004*bdd1243dSDimitry Andric  }
10050b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
10060b57cec5SDimitry Andric
1007*bdd1243dSDimitry Andric    inline _LIBCPP_CONSTEXPR_SINCE_CXX20 ~basic_string();
10080b57cec5SDimitry Andric
1009*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
10100b57cec5SDimitry Andric    operator __self_view() const _NOEXCEPT { return __self_view(data(), size()); }
10110b57cec5SDimitry Andric
1012*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(const basic_string& __str);
10130b57cec5SDimitry Andric
101481ad6265SDimitry Andric    template <class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
101581ad6265SDimitry Andric                                               !__is_same_uncvref<_Tp, basic_string>::value> >
1016*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(const _Tp& __t) {
101781ad6265SDimitry Andric      __self_view __sv = __t;
101881ad6265SDimitry Andric      return assign(__sv);
101981ad6265SDimitry Andric    }
10200b57cec5SDimitry Andric
10210b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
1022*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(basic_string&& __str)
1023*bdd1243dSDimitry Andric      _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value)) {
1024*bdd1243dSDimitry Andric    __move_assign(__str, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>());
1025*bdd1243dSDimitry Andric    return *this;
1026*bdd1243dSDimitry Andric  }
1027*bdd1243dSDimitry Andric
1028*bdd1243dSDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
10290b57cec5SDimitry Andric    basic_string& operator=(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}
10300b57cec5SDimitry Andric#endif
1031*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
103281ad6265SDimitry Andric    basic_string& operator=(const value_type* __s) {return assign(__s);}
1033fe6060f1SDimitry Andric#if _LIBCPP_STD_VER > 20
1034fe6060f1SDimitry Andric    basic_string& operator=(nullptr_t) = delete;
1035fe6060f1SDimitry Andric#endif
1036*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(value_type __c);
10370b57cec5SDimitry Andric
1038*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
10390b57cec5SDimitry Andric    iterator begin() _NOEXCEPT
1040*bdd1243dSDimitry Andric        {return __make_iterator(__get_pointer());}
1041*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
10420b57cec5SDimitry Andric    const_iterator begin() const _NOEXCEPT
1043*bdd1243dSDimitry Andric        {return __make_const_iterator(__get_pointer());}
1044*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
10450b57cec5SDimitry Andric    iterator end() _NOEXCEPT
1046*bdd1243dSDimitry Andric        {return __make_iterator(__get_pointer() + size());}
1047*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
10480b57cec5SDimitry Andric    const_iterator end() const _NOEXCEPT
1049*bdd1243dSDimitry Andric        {return __make_const_iterator(__get_pointer() + size());}
105081ad6265SDimitry Andric
1051*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
10520b57cec5SDimitry Andric    reverse_iterator rbegin() _NOEXCEPT
10530b57cec5SDimitry Andric        {return reverse_iterator(end());}
1054*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
10550b57cec5SDimitry Andric    const_reverse_iterator rbegin() const _NOEXCEPT
10560b57cec5SDimitry Andric        {return const_reverse_iterator(end());}
1057*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
10580b57cec5SDimitry Andric    reverse_iterator rend() _NOEXCEPT
10590b57cec5SDimitry Andric        {return reverse_iterator(begin());}
1060*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
10610b57cec5SDimitry Andric    const_reverse_iterator rend() const _NOEXCEPT
10620b57cec5SDimitry Andric        {return const_reverse_iterator(begin());}
10630b57cec5SDimitry Andric
1064*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
10650b57cec5SDimitry Andric    const_iterator cbegin() const _NOEXCEPT
10660b57cec5SDimitry Andric        {return begin();}
1067*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
10680b57cec5SDimitry Andric    const_iterator cend() const _NOEXCEPT
10690b57cec5SDimitry Andric        {return end();}
1070*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
10710b57cec5SDimitry Andric    const_reverse_iterator crbegin() const _NOEXCEPT
10720b57cec5SDimitry Andric        {return rbegin();}
1073*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
10740b57cec5SDimitry Andric    const_reverse_iterator crend() const _NOEXCEPT
10750b57cec5SDimitry Andric        {return rend();}
10760b57cec5SDimitry Andric
1077*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type size() const _NOEXCEPT
10780b57cec5SDimitry Andric        {return __is_long() ? __get_long_size() : __get_short_size();}
1079*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type length() const _NOEXCEPT {return size();}
1080*bdd1243dSDimitry Andric
1081*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type max_size() const _NOEXCEPT {
1082*bdd1243dSDimitry Andric    size_type __m = __alloc_traits::max_size(__alloc());
1083*bdd1243dSDimitry Andric    if (__m <= std::numeric_limits<size_type>::max() / 2) {
1084*bdd1243dSDimitry Andric      return __m - __alignment;
1085*bdd1243dSDimitry Andric    } else {
1086*bdd1243dSDimitry Andric    bool __uses_lsb = __endian_factor == 2;
1087*bdd1243dSDimitry Andric      return __uses_lsb ? __m - __alignment : (__m / 2) - __alignment;
1088*bdd1243dSDimitry Andric    }
1089*bdd1243dSDimitry Andric  }
1090*bdd1243dSDimitry Andric
1091*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type capacity() const _NOEXCEPT {
109281ad6265SDimitry Andric        return (__is_long() ? __get_long_cap() : static_cast<size_type>(__min_cap)) - 1;
109381ad6265SDimitry Andric    }
10940b57cec5SDimitry Andric
1095*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 void resize(size_type __n, value_type __c);
1096*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void resize(size_type __n) { resize(__n, value_type()); }
10970b57cec5SDimitry Andric
1098*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 void reserve(size_type __requested_capacity);
109904eeddc0SDimitry Andric
110004eeddc0SDimitry Andric#if _LIBCPP_STD_VER > 20
110104eeddc0SDimitry Andric    template <class _Op>
110204eeddc0SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
110304eeddc0SDimitry Andric    void resize_and_overwrite(size_type __n, _Op __op) {
110404eeddc0SDimitry Andric      __resize_default_init(__n);
110581ad6265SDimitry Andric      __erase_to_end(std::move(__op)(data(), _LIBCPP_AUTO_CAST(__n)));
110604eeddc0SDimitry Andric    }
110704eeddc0SDimitry Andric#endif
110804eeddc0SDimitry Andric
1109*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __resize_default_init(size_type __n);
11100b57cec5SDimitry Andric
111181ad6265SDimitry Andric    _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI void reserve() _NOEXCEPT { shrink_to_fit(); }
1112*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void shrink_to_fit() _NOEXCEPT;
1113*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void clear() _NOEXCEPT;
111481ad6265SDimitry Andric
1115*bdd1243dSDimitry Andric    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
11160b57cec5SDimitry Andric    bool empty() const _NOEXCEPT {return size() == 0;}
11170b57cec5SDimitry Andric
1118*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference operator[](size_type __pos) const _NOEXCEPT {
1119*bdd1243dSDimitry Andric    _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
1120*bdd1243dSDimitry Andric    return *(data() + __pos);
1121*bdd1243dSDimitry Andric  }
11220b57cec5SDimitry Andric
1123*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](size_type __pos) _NOEXCEPT {
1124*bdd1243dSDimitry Andric    _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
1125*bdd1243dSDimitry Andric    return *(__get_pointer() + __pos);
1126*bdd1243dSDimitry Andric  }
11270b57cec5SDimitry Andric
1128*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference at(size_type __n) const;
1129*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 reference       at(size_type __n);
1130*bdd1243dSDimitry Andric
1131*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator+=(const basic_string& __str) {
113281ad6265SDimitry Andric        return append(__str);
113381ad6265SDimitry Andric    }
11340b57cec5SDimitry Andric
11350b57cec5SDimitry Andric    template <class _Tp>
1136*bdd1243dSDimitry Andric    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1137349cc55cSDimitry Andric    __enable_if_t
11380b57cec5SDimitry Andric        <
11395ffd83dbSDimitry Andric            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
11405ffd83dbSDimitry Andric            && !__is_same_uncvref<_Tp, basic_string >::value,
11410b57cec5SDimitry Andric            basic_string&
11425ffd83dbSDimitry Andric        >
114381ad6265SDimitry Andric    operator+=(const _Tp& __t) {
114481ad6265SDimitry Andric        __self_view __sv = __t; return append(__sv);
114581ad6265SDimitry Andric    }
114681ad6265SDimitry Andric
1147*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator+=(const value_type* __s) {
114881ad6265SDimitry Andric        return append(__s);
114981ad6265SDimitry Andric    }
115081ad6265SDimitry Andric
1151*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator+=(value_type __c) {
115281ad6265SDimitry Andric        push_back(__c);
115381ad6265SDimitry Andric        return *this;
115481ad6265SDimitry Andric    }
115581ad6265SDimitry Andric
11560b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
1157*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
115881ad6265SDimitry Andric    basic_string& operator+=(initializer_list<value_type> __il) { return append(__il); }
11590b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
11600b57cec5SDimitry Andric
1161*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const basic_string& __str) {
1162*bdd1243dSDimitry Andric        return append(__str.data(), __str.size());
1163*bdd1243dSDimitry Andric  }
11640b57cec5SDimitry Andric
11650b57cec5SDimitry Andric    template <class _Tp>
1166*bdd1243dSDimitry Andric    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1167349cc55cSDimitry Andric    __enable_if_t<
11685ffd83dbSDimitry Andric            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
11695ffd83dbSDimitry Andric            && !__is_same_uncvref<_Tp, basic_string>::value,
11700b57cec5SDimitry Andric            basic_string&
11715ffd83dbSDimitry Andric        >
11720b57cec5SDimitry Andric                  append(const _Tp& __t) { __self_view __sv = __t; return append(__sv.data(), __sv.size()); }
1173*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos);
11740b57cec5SDimitry Andric
11750b57cec5SDimitry Andric    template <class _Tp>
1176*bdd1243dSDimitry Andric    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1177349cc55cSDimitry Andric    __enable_if_t
11780b57cec5SDimitry Andric        <
11795ffd83dbSDimitry Andric            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
11805ffd83dbSDimitry Andric            && !__is_same_uncvref<_Tp, basic_string>::value,
11810b57cec5SDimitry Andric            basic_string&
11825ffd83dbSDimitry Andric        >
11830b57cec5SDimitry Andric                  append(const _Tp& __t, size_type __pos, size_type __n=npos);
1184*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const value_type* __s, size_type __n);
1185*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const value_type* __s);
1186*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(size_type __n, value_type __c);
11870b57cec5SDimitry Andric
1188*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
11890b57cec5SDimitry Andric    void __append_default_init(size_type __n);
11900b57cec5SDimitry Andric
11910b57cec5SDimitry Andric    template<class _InputIterator>
11920b57cec5SDimitry Andric    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
1193349cc55cSDimitry Andric    __enable_if_t
11940b57cec5SDimitry Andric        <
1195fe6060f1SDimitry Andric            __is_exactly_cpp17_input_iterator<_InputIterator>::value,
11960b57cec5SDimitry Andric            basic_string&
11975ffd83dbSDimitry Andric        >
1198*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
11990b57cec5SDimitry Andric    append(_InputIterator __first, _InputIterator __last) {
12000b57cec5SDimitry Andric      const basic_string __temp(__first, __last, __alloc());
12010b57cec5SDimitry Andric      append(__temp.data(), __temp.size());
12020b57cec5SDimitry Andric      return *this;
12030b57cec5SDimitry Andric    }
12040b57cec5SDimitry Andric    template<class _ForwardIterator>
12050b57cec5SDimitry Andric    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
1206349cc55cSDimitry Andric    __enable_if_t
12070b57cec5SDimitry Andric        <
1208fe6060f1SDimitry Andric            __is_cpp17_forward_iterator<_ForwardIterator>::value,
12090b57cec5SDimitry Andric            basic_string&
12105ffd83dbSDimitry Andric        >
1211*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1212fe6060f1SDimitry Andric    append(_ForwardIterator __first, _ForwardIterator __last);
12130b57cec5SDimitry Andric
12140b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
1215*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
12160b57cec5SDimitry Andric    basic_string& append(initializer_list<value_type> __il) {return append(__il.begin(), __il.size());}
12170b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
12180b57cec5SDimitry Andric
1219*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 void push_back(value_type __c);
1220*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void pop_back();
1221*bdd1243dSDimitry Andric
1222*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference front() _NOEXCEPT {
1223*bdd1243dSDimitry Andric    _LIBCPP_ASSERT(!empty(), "string::front(): string is empty");
1224*bdd1243dSDimitry Andric    return *__get_pointer();
1225*bdd1243dSDimitry Andric  }
1226*bdd1243dSDimitry Andric
1227*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference front() const _NOEXCEPT {
1228*bdd1243dSDimitry Andric    _LIBCPP_ASSERT(!empty(), "string::front(): string is empty");
1229*bdd1243dSDimitry Andric    return *data();
1230*bdd1243dSDimitry Andric  }
1231*bdd1243dSDimitry Andric
1232*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference back() _NOEXCEPT {
1233*bdd1243dSDimitry Andric    _LIBCPP_ASSERT(!empty(), "string::back(): string is empty");
1234*bdd1243dSDimitry Andric    return *(__get_pointer() + size() - 1);
1235*bdd1243dSDimitry Andric  }
1236*bdd1243dSDimitry Andric
1237*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference back() const _NOEXCEPT {
1238*bdd1243dSDimitry Andric    _LIBCPP_ASSERT(!empty(), "string::back(): string is empty");
1239*bdd1243dSDimitry Andric    return *(data() + size() - 1);
1240*bdd1243dSDimitry Andric  }
12410b57cec5SDimitry Andric
12420b57cec5SDimitry Andric    template <class _Tp>
1243*bdd1243dSDimitry Andric    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1244349cc55cSDimitry Andric    __enable_if_t
12450b57cec5SDimitry Andric        <
12460b57cec5SDimitry Andric            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
12470b57cec5SDimitry Andric            basic_string&
12485ffd83dbSDimitry Andric        >
12490b57cec5SDimitry Andric                 assign(const _Tp & __t) { __self_view __sv = __t; return assign(__sv.data(), __sv.size()); }
1250*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
12510b57cec5SDimitry Andric    basic_string& assign(const basic_string& __str) { return *this = __str; }
12520b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
1253*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
12540b57cec5SDimitry Andric    basic_string& assign(basic_string&& __str)
12550b57cec5SDimitry Andric        _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value))
125681ad6265SDimitry Andric        {*this = std::move(__str); return *this;}
12570b57cec5SDimitry Andric#endif
1258*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos);
12590b57cec5SDimitry Andric    template <class _Tp>
1260*bdd1243dSDimitry Andric    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1261349cc55cSDimitry Andric    __enable_if_t
12620b57cec5SDimitry Andric        <
12635ffd83dbSDimitry Andric            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
12645ffd83dbSDimitry Andric            && !__is_same_uncvref<_Tp, basic_string>::value,
12650b57cec5SDimitry Andric            basic_string&
12665ffd83dbSDimitry Andric        >
12670b57cec5SDimitry Andric                  assign(const _Tp & __t, size_type __pos, size_type __n=npos);
1268*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const value_type* __s, size_type __n);
1269*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const value_type* __s);
1270*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(size_type __n, value_type __c);
12710b57cec5SDimitry Andric    template<class _InputIterator>
1272*bdd1243dSDimitry Andric    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1273349cc55cSDimitry Andric    __enable_if_t
12740b57cec5SDimitry Andric        <
1275fe6060f1SDimitry Andric            __is_exactly_cpp17_input_iterator<_InputIterator>::value,
12760b57cec5SDimitry Andric            basic_string&
12775ffd83dbSDimitry Andric        >
12780b57cec5SDimitry Andric        assign(_InputIterator __first, _InputIterator __last);
12790b57cec5SDimitry Andric    template<class _ForwardIterator>
1280*bdd1243dSDimitry Andric    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1281349cc55cSDimitry Andric    __enable_if_t
12820b57cec5SDimitry Andric        <
1283fe6060f1SDimitry Andric            __is_cpp17_forward_iterator<_ForwardIterator>::value,
12840b57cec5SDimitry Andric            basic_string&
12855ffd83dbSDimitry Andric        >
12860b57cec5SDimitry Andric        assign(_ForwardIterator __first, _ForwardIterator __last);
12870b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
1288*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
12890b57cec5SDimitry Andric    basic_string& assign(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}
12900b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
12910b57cec5SDimitry Andric
1292*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1293*bdd1243dSDimitry Andric  insert(size_type __pos1, const basic_string& __str) {
1294*bdd1243dSDimitry Andric    return insert(__pos1, __str.data(), __str.size());
1295*bdd1243dSDimitry Andric  }
12960b57cec5SDimitry Andric
12970b57cec5SDimitry Andric    template <class _Tp>
1298*bdd1243dSDimitry Andric    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1299349cc55cSDimitry Andric    __enable_if_t
13000b57cec5SDimitry Andric        <
13010b57cec5SDimitry Andric            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
13020b57cec5SDimitry Andric            basic_string&
13035ffd83dbSDimitry Andric        >
13040b57cec5SDimitry Andric                 insert(size_type __pos1, const _Tp& __t)
13050b57cec5SDimitry Andric    { __self_view __sv = __t; return insert(__pos1, __sv.data(), __sv.size()); }
13060b57cec5SDimitry Andric
13070b57cec5SDimitry Andric    template <class _Tp>
1308*bdd1243dSDimitry Andric    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1309349cc55cSDimitry Andric    __enable_if_t
13100b57cec5SDimitry Andric        <
13115ffd83dbSDimitry Andric            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value,
13120b57cec5SDimitry Andric            basic_string&
13135ffd83dbSDimitry Andric        >
13140b57cec5SDimitry Andric                  insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n=npos);
1315*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20
13160b57cec5SDimitry Andric    basic_string& insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n=npos);
1317*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* __s, size_type __n);
1318*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* __s);
1319*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, size_type __n, value_type __c);
1320*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator      insert(const_iterator __pos, value_type __c);
1321*bdd1243dSDimitry Andric
1322*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator
1323*bdd1243dSDimitry Andric  insert(const_iterator __pos, size_type __n, value_type __c) {
1324*bdd1243dSDimitry Andric    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
1325*bdd1243dSDimitry Andric                         "string::insert(iterator, n, value) called with an iterator not referring to this string");
1326*bdd1243dSDimitry Andric    difference_type __p = __pos - begin();
1327*bdd1243dSDimitry Andric    insert(static_cast<size_type>(__p), __n, __c);
1328*bdd1243dSDimitry Andric    return begin() + __p;
1329*bdd1243dSDimitry Andric  }
1330*bdd1243dSDimitry Andric
13310b57cec5SDimitry Andric    template<class _InputIterator>
1332*bdd1243dSDimitry Andric    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1333349cc55cSDimitry Andric    __enable_if_t
13340b57cec5SDimitry Andric        <
1335fe6060f1SDimitry Andric            __is_exactly_cpp17_input_iterator<_InputIterator>::value,
13360b57cec5SDimitry Andric            iterator
13375ffd83dbSDimitry Andric        >
13380b57cec5SDimitry Andric        insert(const_iterator __pos, _InputIterator __first, _InputIterator __last);
13390b57cec5SDimitry Andric    template<class _ForwardIterator>
1340*bdd1243dSDimitry Andric    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1341349cc55cSDimitry Andric    __enable_if_t
13420b57cec5SDimitry Andric        <
1343fe6060f1SDimitry Andric            __is_cpp17_forward_iterator<_ForwardIterator>::value,
13440b57cec5SDimitry Andric            iterator
13455ffd83dbSDimitry Andric        >
13460b57cec5SDimitry Andric        insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last);
13470b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
1348*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
13490b57cec5SDimitry Andric    iterator insert(const_iterator __pos, initializer_list<value_type> __il)
13500b57cec5SDimitry Andric                    {return insert(__pos, __il.begin(), __il.end());}
13510b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
13520b57cec5SDimitry Andric
1353*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& erase(size_type __pos = 0, size_type __n = npos);
1354*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
13550b57cec5SDimitry Andric    iterator      erase(const_iterator __pos);
1356*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
13570b57cec5SDimitry Andric    iterator      erase(const_iterator __first, const_iterator __last);
13580b57cec5SDimitry Andric
1359*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1360*bdd1243dSDimitry Andric  replace(size_type __pos1, size_type __n1, const basic_string& __str) {
1361*bdd1243dSDimitry Andric    return replace(__pos1, __n1, __str.data(), __str.size());
1362*bdd1243dSDimitry Andric  }
13630b57cec5SDimitry Andric
13640b57cec5SDimitry Andric    template <class _Tp>
1365*bdd1243dSDimitry Andric    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1366349cc55cSDimitry Andric    __enable_if_t
13670b57cec5SDimitry Andric        <
13680b57cec5SDimitry Andric            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
13690b57cec5SDimitry Andric            basic_string&
13705ffd83dbSDimitry Andric        >
13710b57cec5SDimitry Andric                  replace(size_type __pos1, size_type __n1, const _Tp& __t) { __self_view __sv = __t; return replace(__pos1, __n1, __sv.data(), __sv.size()); }
1372*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20
13730b57cec5SDimitry Andric    basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos);
13740b57cec5SDimitry Andric    template <class _Tp>
1375*bdd1243dSDimitry Andric    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1376349cc55cSDimitry Andric    __enable_if_t
13770b57cec5SDimitry Andric        <
13785ffd83dbSDimitry Andric            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value  && !__is_same_uncvref<_Tp, basic_string>::value,
13790b57cec5SDimitry Andric            basic_string&
13805ffd83dbSDimitry Andric        >
13810b57cec5SDimitry Andric                  replace(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos);
1382*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20
13830b57cec5SDimitry Andric    basic_string& replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2);
1384*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& replace(size_type __pos, size_type __n1, const value_type* __s);
1385*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c);
1386*bdd1243dSDimitry Andric
1387*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1388*bdd1243dSDimitry Andric  replace(const_iterator __i1, const_iterator __i2, const basic_string& __str) {
1389*bdd1243dSDimitry Andric    return replace(
1390*bdd1243dSDimitry Andric        static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __str.data(), __str.size());
1391*bdd1243dSDimitry Andric  }
13920b57cec5SDimitry Andric
13930b57cec5SDimitry Andric    template <class _Tp>
1394*bdd1243dSDimitry Andric    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1395349cc55cSDimitry Andric    __enable_if_t
13960b57cec5SDimitry Andric        <
13970b57cec5SDimitry Andric            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
13980b57cec5SDimitry Andric            basic_string&
13995ffd83dbSDimitry Andric        >
14000b57cec5SDimitry Andric                  replace(const_iterator __i1, const_iterator __i2, const _Tp& __t) { __self_view __sv = __t; return replace(__i1 - begin(), __i2 - __i1, __sv); }
14010b57cec5SDimitry Andric
1402*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1403*bdd1243dSDimitry Andric  replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n) {
1404*bdd1243dSDimitry Andric    return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s, __n);
1405*bdd1243dSDimitry Andric  }
1406*bdd1243dSDimitry Andric
1407*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1408*bdd1243dSDimitry Andric  replace(const_iterator __i1, const_iterator __i2, const value_type* __s) {
1409*bdd1243dSDimitry Andric    return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s);
1410*bdd1243dSDimitry Andric  }
1411*bdd1243dSDimitry Andric
1412*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1413*bdd1243dSDimitry Andric  replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c) {
1414*bdd1243dSDimitry Andric    return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __n, __c);
1415*bdd1243dSDimitry Andric  }
1416*bdd1243dSDimitry Andric
14170b57cec5SDimitry Andric    template<class _InputIterator>
1418*bdd1243dSDimitry Andric    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1419349cc55cSDimitry Andric    __enable_if_t
14200b57cec5SDimitry Andric        <
1421480093f4SDimitry Andric            __is_cpp17_input_iterator<_InputIterator>::value,
14220b57cec5SDimitry Andric            basic_string&
14235ffd83dbSDimitry Andric        >
14240b57cec5SDimitry Andric        replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2);
14250b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
1426*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
14270b57cec5SDimitry Andric    basic_string& replace(const_iterator __i1, const_iterator __i2, initializer_list<value_type> __il)
14280b57cec5SDimitry Andric        {return replace(__i1, __i2, __il.begin(), __il.end());}
14290b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
14300b57cec5SDimitry Andric
1431*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type copy(value_type* __s, size_type __n, size_type __pos = 0) const;
14320b57cec5SDimitry Andric
1433*bdd1243dSDimitry Andric#if _LIBCPP_STD_VER <= 20
1434*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1435*bdd1243dSDimitry Andric    basic_string substr(size_type __pos = 0, size_type __n = npos) const {
1436*bdd1243dSDimitry Andric      return basic_string(*this, __pos, __n);
1437*bdd1243dSDimitry Andric    }
1438*bdd1243dSDimitry Andric#else
1439*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
1440*bdd1243dSDimitry Andric    basic_string substr(size_type __pos = 0, size_type __n = npos) const& {
1441*bdd1243dSDimitry Andric      return basic_string(*this, __pos, __n);
1442*bdd1243dSDimitry Andric    }
1443*bdd1243dSDimitry Andric
1444*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr
1445*bdd1243dSDimitry Andric    basic_string substr(size_type __pos = 0, size_type __n = npos) && {
1446*bdd1243dSDimitry Andric      return basic_string(std::move(*this), __pos, __n);
1447*bdd1243dSDimitry Andric    }
1448*bdd1243dSDimitry Andric#endif
1449*bdd1243dSDimitry Andric
1450*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
14510b57cec5SDimitry Andric    void swap(basic_string& __str)
14520b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14
14530b57cec5SDimitry Andric        _NOEXCEPT;
14540b57cec5SDimitry Andric#else
14550b57cec5SDimitry Andric        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
14560b57cec5SDimitry Andric                    __is_nothrow_swappable<allocator_type>::value);
14570b57cec5SDimitry Andric#endif
14580b57cec5SDimitry Andric
1459*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
14600b57cec5SDimitry Andric    const value_type* c_str() const _NOEXCEPT {return data();}
1461*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
146281ad6265SDimitry Andric    const value_type* data() const _NOEXCEPT  {return std::__to_address(__get_pointer());}
14630b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14 || defined(_LIBCPP_BUILDING_LIBRARY)
1464*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
146581ad6265SDimitry Andric    value_type* data()             _NOEXCEPT  {return std::__to_address(__get_pointer());}
14660b57cec5SDimitry Andric#endif
14670b57cec5SDimitry Andric
1468*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
14690b57cec5SDimitry Andric    allocator_type get_allocator() const _NOEXCEPT {return __alloc();}
14700b57cec5SDimitry Andric
1471*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
14720b57cec5SDimitry Andric    size_type find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
14730b57cec5SDimitry Andric
14740b57cec5SDimitry Andric    template <class _Tp>
1475*bdd1243dSDimitry Andric    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1476349cc55cSDimitry Andric    __enable_if_t
14770b57cec5SDimitry Andric        <
14780b57cec5SDimitry Andric            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
14790b57cec5SDimitry Andric            size_type
14805ffd83dbSDimitry Andric        >
1481fe6060f1SDimitry Andric              find(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
1482*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20
14830b57cec5SDimitry Andric    size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1484*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
14850b57cec5SDimitry Andric    size_type find(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
1486*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT;
14870b57cec5SDimitry Andric
1488*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
14890b57cec5SDimitry Andric    size_type rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
14900b57cec5SDimitry Andric
14910b57cec5SDimitry Andric    template <class _Tp>
1492*bdd1243dSDimitry Andric    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1493349cc55cSDimitry Andric    __enable_if_t
14940b57cec5SDimitry Andric        <
14950b57cec5SDimitry Andric            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
14960b57cec5SDimitry Andric            size_type
14975ffd83dbSDimitry Andric        >
1498fe6060f1SDimitry Andric              rfind(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
1499*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20
15000b57cec5SDimitry Andric    size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1501*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
15020b57cec5SDimitry Andric    size_type rfind(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
1503*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type rfind(value_type __c, size_type __pos = npos) const _NOEXCEPT;
15040b57cec5SDimitry Andric
1505*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
15060b57cec5SDimitry Andric    size_type find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
15070b57cec5SDimitry Andric
15080b57cec5SDimitry Andric    template <class _Tp>
1509*bdd1243dSDimitry Andric    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1510349cc55cSDimitry Andric    __enable_if_t
15110b57cec5SDimitry Andric        <
15120b57cec5SDimitry Andric            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
15130b57cec5SDimitry Andric            size_type
15145ffd83dbSDimitry Andric        >
1515fe6060f1SDimitry Andric              find_first_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
1516*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20
15170b57cec5SDimitry Andric    size_type find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1518*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
15190b57cec5SDimitry Andric    size_type find_first_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
1520*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
15210b57cec5SDimitry Andric    size_type find_first_of(value_type __c, size_type __pos = 0) const _NOEXCEPT;
15220b57cec5SDimitry Andric
1523*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
15240b57cec5SDimitry Andric    size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
15250b57cec5SDimitry Andric
15260b57cec5SDimitry Andric    template <class _Tp>
1527*bdd1243dSDimitry Andric    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1528349cc55cSDimitry Andric    __enable_if_t
15290b57cec5SDimitry Andric        <
15300b57cec5SDimitry Andric            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
15310b57cec5SDimitry Andric            size_type
15325ffd83dbSDimitry Andric        >
1533fe6060f1SDimitry Andric              find_last_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
1534*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20
15350b57cec5SDimitry Andric    size_type find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1536*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
15370b57cec5SDimitry Andric    size_type find_last_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
1538*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
15390b57cec5SDimitry Andric    size_type find_last_of(value_type __c, size_type __pos = npos) const _NOEXCEPT;
15400b57cec5SDimitry Andric
1541*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
15420b57cec5SDimitry Andric    size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
15430b57cec5SDimitry Andric
15440b57cec5SDimitry Andric    template <class _Tp>
1545*bdd1243dSDimitry Andric    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1546349cc55cSDimitry Andric    __enable_if_t
15470b57cec5SDimitry Andric        <
15480b57cec5SDimitry Andric            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
15490b57cec5SDimitry Andric            size_type
15505ffd83dbSDimitry Andric        >
1551fe6060f1SDimitry Andric              find_first_not_of(const _Tp &__t, size_type __pos = 0) const _NOEXCEPT;
1552*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20
15530b57cec5SDimitry Andric    size_type find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1554*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
15550b57cec5SDimitry Andric    size_type find_first_not_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
1556*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
15570b57cec5SDimitry Andric    size_type find_first_not_of(value_type __c, size_type __pos = 0) const _NOEXCEPT;
15580b57cec5SDimitry Andric
1559*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
15600b57cec5SDimitry Andric    size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
15610b57cec5SDimitry Andric
15620b57cec5SDimitry Andric    template <class _Tp>
1563*bdd1243dSDimitry Andric    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1564349cc55cSDimitry Andric    __enable_if_t
15650b57cec5SDimitry Andric        <
15660b57cec5SDimitry Andric            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
15670b57cec5SDimitry Andric            size_type
15685ffd83dbSDimitry Andric        >
1569fe6060f1SDimitry Andric              find_last_not_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
1570*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20
15710b57cec5SDimitry Andric    size_type find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
1572*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
15730b57cec5SDimitry Andric    size_type find_last_not_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
1574*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
15750b57cec5SDimitry Andric    size_type find_last_not_of(value_type __c, size_type __pos = npos) const _NOEXCEPT;
15760b57cec5SDimitry Andric
1577*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
15780b57cec5SDimitry Andric    int compare(const basic_string& __str) const _NOEXCEPT;
15790b57cec5SDimitry Andric
15800b57cec5SDimitry Andric    template <class _Tp>
1581*bdd1243dSDimitry Andric    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1582349cc55cSDimitry Andric    __enable_if_t
15830b57cec5SDimitry Andric        <
15840b57cec5SDimitry Andric            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
15850b57cec5SDimitry Andric            int
15865ffd83dbSDimitry Andric        >
1587fe6060f1SDimitry Andric        compare(const _Tp &__t) const _NOEXCEPT;
15880b57cec5SDimitry Andric
15890b57cec5SDimitry Andric    template <class _Tp>
1590*bdd1243dSDimitry Andric    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
1591349cc55cSDimitry Andric    __enable_if_t
15920b57cec5SDimitry Andric        <
15930b57cec5SDimitry Andric            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
15940b57cec5SDimitry Andric            int
15955ffd83dbSDimitry Andric        >
15960b57cec5SDimitry Andric         compare(size_type __pos1, size_type __n1, const _Tp& __t) const;
15970b57cec5SDimitry Andric
1598*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
15990b57cec5SDimitry Andric    int compare(size_type __pos1, size_type __n1, const basic_string& __str) const;
1600*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20
160181ad6265SDimitry Andric    int compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2,
160281ad6265SDimitry Andric                size_type __n2 = npos) const;
16030b57cec5SDimitry Andric
16040b57cec5SDimitry Andric    template <class _Tp>
1605*bdd1243dSDimitry Andric    inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1606349cc55cSDimitry Andric        __enable_if_t
16070b57cec5SDimitry Andric        <
16085ffd83dbSDimitry Andric            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value  && !__is_same_uncvref<_Tp, basic_string>::value,
16090b57cec5SDimitry Andric            int
16105ffd83dbSDimitry Andric        >
16110b57cec5SDimitry Andric        compare(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos) const;
1612*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(const value_type* __s) const _NOEXCEPT;
1613*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(size_type __pos1, size_type __n1, const value_type* __s) const;
1614*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20
16150b57cec5SDimitry Andric    int compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const;
16160b57cec5SDimitry Andric
16170b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 17
161881ad6265SDimitry Andric    constexpr _LIBCPP_HIDE_FROM_ABI
1619349cc55cSDimitry Andric    bool starts_with(__self_view __sv) const noexcept
16200b57cec5SDimitry Andric    { return __self_view(data(), size()).starts_with(__sv); }
16210b57cec5SDimitry Andric
162281ad6265SDimitry Andric    constexpr _LIBCPP_HIDE_FROM_ABI
1623349cc55cSDimitry Andric    bool starts_with(value_type __c) const noexcept
16240b57cec5SDimitry Andric    { return !empty() && _Traits::eq(front(), __c); }
16250b57cec5SDimitry Andric
162681ad6265SDimitry Andric    constexpr _LIBCPP_HIDE_FROM_ABI
1627349cc55cSDimitry Andric    bool starts_with(const value_type* __s) const noexcept
16280b57cec5SDimitry Andric    { return starts_with(__self_view(__s)); }
16290b57cec5SDimitry Andric
163081ad6265SDimitry Andric    constexpr _LIBCPP_HIDE_FROM_ABI
1631349cc55cSDimitry Andric    bool ends_with(__self_view __sv) const noexcept
16320b57cec5SDimitry Andric    { return __self_view(data(), size()).ends_with( __sv); }
16330b57cec5SDimitry Andric
163481ad6265SDimitry Andric    constexpr _LIBCPP_HIDE_FROM_ABI
1635349cc55cSDimitry Andric    bool ends_with(value_type __c) const noexcept
16360b57cec5SDimitry Andric    { return !empty() && _Traits::eq(back(), __c); }
16370b57cec5SDimitry Andric
163881ad6265SDimitry Andric    constexpr _LIBCPP_HIDE_FROM_ABI
1639349cc55cSDimitry Andric    bool ends_with(const value_type* __s) const noexcept
16400b57cec5SDimitry Andric    { return ends_with(__self_view(__s)); }
16410b57cec5SDimitry Andric#endif
16420b57cec5SDimitry Andric
1643e8d8bef9SDimitry Andric#if _LIBCPP_STD_VER > 20
164481ad6265SDimitry Andric    constexpr _LIBCPP_HIDE_FROM_ABI
1645e8d8bef9SDimitry Andric    bool contains(__self_view __sv) const noexcept
1646e8d8bef9SDimitry Andric    { return __self_view(data(), size()).contains(__sv); }
1647e8d8bef9SDimitry Andric
164881ad6265SDimitry Andric    constexpr _LIBCPP_HIDE_FROM_ABI
1649e8d8bef9SDimitry Andric    bool contains(value_type __c) const noexcept
1650e8d8bef9SDimitry Andric    { return __self_view(data(), size()).contains(__c); }
1651e8d8bef9SDimitry Andric
165281ad6265SDimitry Andric    constexpr _LIBCPP_HIDE_FROM_ABI
1653e8d8bef9SDimitry Andric    bool contains(const value_type* __s) const
1654e8d8bef9SDimitry Andric    { return __self_view(data(), size()).contains(__s); }
1655e8d8bef9SDimitry Andric#endif
1656e8d8bef9SDimitry Andric
1657*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __invariants() const;
16580b57cec5SDimitry Andric
1659*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __clear_and_shrink() _NOEXCEPT;
16600b57cec5SDimitry Andric
166181ad6265SDimitry Andric#ifdef _LIBCPP_ENABLE_DEBUG_MODE
16620b57cec5SDimitry Andric
16630b57cec5SDimitry Andric    bool __dereferenceable(const const_iterator* __i) const;
16640b57cec5SDimitry Andric    bool __decrementable(const const_iterator* __i) const;
16650b57cec5SDimitry Andric    bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
16660b57cec5SDimitry Andric    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
16670b57cec5SDimitry Andric
166881ad6265SDimitry Andric#endif // _LIBCPP_ENABLE_DEBUG_MODE
16690b57cec5SDimitry Andric
16700b57cec5SDimitry Andricprivate:
167181ad6265SDimitry Andric    template<class _Alloc>
1672*bdd1243dSDimitry Andric    inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
167381ad6265SDimitry Andric    bool friend operator==(const basic_string<char, char_traits<char>, _Alloc>& __lhs,
167481ad6265SDimitry Andric                           const basic_string<char, char_traits<char>, _Alloc>& __rhs) _NOEXCEPT;
167581ad6265SDimitry Andric
1676*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __shrink_or_extend(size_type __target_capacity);
167781ad6265SDimitry Andric
1678*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
167981ad6265SDimitry Andric    bool __is_long() const _NOEXCEPT {
168081ad6265SDimitry Andric        if (__libcpp_is_constant_evaluated())
168181ad6265SDimitry Andric            return true;
168281ad6265SDimitry Andric        return __r_.first().__s.__is_long_;
168381ad6265SDimitry Andric    }
168481ad6265SDimitry Andric
1685*bdd1243dSDimitry Andric    static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __begin_lifetime(pointer __begin, size_type __n) {
168681ad6265SDimitry Andric#if _LIBCPP_STD_VER > 17
168781ad6265SDimitry Andric        if (__libcpp_is_constant_evaluated()) {
168881ad6265SDimitry Andric            for (size_type __i = 0; __i != __n; ++__i)
168981ad6265SDimitry Andric                std::construct_at(std::addressof(__begin[__i]));
169081ad6265SDimitry Andric        }
169181ad6265SDimitry Andric#else
169281ad6265SDimitry Andric        (void)__begin;
169381ad6265SDimitry Andric        (void)__n;
169481ad6265SDimitry Andric#endif // _LIBCPP_STD_VER > 17
169581ad6265SDimitry Andric    }
169681ad6265SDimitry Andric
1697*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __default_init() {
1698*bdd1243dSDimitry Andric        __r_.first() = __rep();
169981ad6265SDimitry Andric        if (__libcpp_is_constant_evaluated()) {
170081ad6265SDimitry Andric            size_type __sz = __recommend(0) + 1;
170181ad6265SDimitry Andric            pointer __ptr = __alloc_traits::allocate(__alloc(), __sz);
170281ad6265SDimitry Andric            __begin_lifetime(__ptr, __sz);
170381ad6265SDimitry Andric            __set_long_pointer(__ptr);
170481ad6265SDimitry Andric            __set_long_cap(__sz);
170581ad6265SDimitry Andric            __set_long_size(0);
170681ad6265SDimitry Andric        }
170781ad6265SDimitry Andric    }
170881ad6265SDimitry Andric
1709*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __deallocate_constexpr() {
171081ad6265SDimitry Andric        if (__libcpp_is_constant_evaluated() && __get_pointer() != nullptr)
171181ad6265SDimitry Andric            __alloc_traits::deallocate(__alloc(), __get_pointer(), __get_long_cap());
171281ad6265SDimitry Andric    }
171381ad6265SDimitry Andric
171404eeddc0SDimitry Andric    _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI static bool __fits_in_sso(size_type __sz) {
171504eeddc0SDimitry Andric        // SSO is disabled during constant evaluation because `__is_long` isn't constexpr friendly
171604eeddc0SDimitry Andric        return !__libcpp_is_constant_evaluated() && (__sz < __min_cap);
171704eeddc0SDimitry Andric    }
171804eeddc0SDimitry Andric
171981ad6265SDimitry Andric    template <class _ForwardIterator>
1720*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
172181ad6265SDimitry Andric    iterator __insert_from_safe_copy(size_type __n, size_type __ip, _ForwardIterator __first, _ForwardIterator __last) {
172281ad6265SDimitry Andric        size_type __sz = size();
172381ad6265SDimitry Andric        size_type __cap = capacity();
172481ad6265SDimitry Andric        value_type* __p;
172581ad6265SDimitry Andric        if (__cap - __sz >= __n)
172681ad6265SDimitry Andric        {
172781ad6265SDimitry Andric            __p = std::__to_address(__get_pointer());
172881ad6265SDimitry Andric            size_type __n_move = __sz - __ip;
172981ad6265SDimitry Andric            if (__n_move != 0)
173081ad6265SDimitry Andric                traits_type::move(__p + __ip + __n, __p + __ip, __n_move);
173181ad6265SDimitry Andric        }
173281ad6265SDimitry Andric        else
173381ad6265SDimitry Andric        {
173481ad6265SDimitry Andric            __grow_by(__cap, __sz + __n - __cap, __sz, __ip, 0, __n);
173581ad6265SDimitry Andric            __p = std::__to_address(__get_long_pointer());
173681ad6265SDimitry Andric        }
173781ad6265SDimitry Andric        __sz += __n;
173881ad6265SDimitry Andric        __set_size(__sz);
173981ad6265SDimitry Andric        traits_type::assign(__p[__sz], value_type());
174081ad6265SDimitry Andric        for (__p += __ip; __first != __last; ++__p, ++__first)
174181ad6265SDimitry Andric            traits_type::assign(*__p, *__first);
17420b57cec5SDimitry Andric
174381ad6265SDimitry Andric        return begin() + __ip;
174481ad6265SDimitry Andric    }
17450b57cec5SDimitry Andric
1746*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 allocator_type& __alloc() _NOEXCEPT { return __r_.second(); }
174781ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const allocator_type& __alloc() const _NOEXCEPT { return __r_.second(); }
17480b57cec5SDimitry Andric
1749*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
175081ad6265SDimitry Andric    void __set_short_size(size_type __s) _NOEXCEPT {
175181ad6265SDimitry Andric        _LIBCPP_ASSERT(__s < __min_cap, "__s should never be greater than or equal to the short string capacity");
175281ad6265SDimitry Andric        __r_.first().__s.__size_ = __s;
175381ad6265SDimitry Andric        __r_.first().__s.__is_long_ = false;
175481ad6265SDimitry Andric    }
17550b57cec5SDimitry Andric
1756*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
175781ad6265SDimitry Andric    size_type __get_short_size() const _NOEXCEPT {
175881ad6265SDimitry Andric        _LIBCPP_ASSERT(!__r_.first().__s.__is_long_, "String has to be short when trying to get the short size");
175981ad6265SDimitry Andric        return __r_.first().__s.__size_;
176081ad6265SDimitry Andric    }
17610b57cec5SDimitry Andric
1762*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
17630b57cec5SDimitry Andric    void __set_long_size(size_type __s) _NOEXCEPT
17640b57cec5SDimitry Andric        {__r_.first().__l.__size_ = __s;}
1765*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
17660b57cec5SDimitry Andric    size_type __get_long_size() const _NOEXCEPT
17670b57cec5SDimitry Andric        {return __r_.first().__l.__size_;}
1768*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
17690b57cec5SDimitry Andric    void __set_size(size_type __s) _NOEXCEPT
17700b57cec5SDimitry Andric        {if (__is_long()) __set_long_size(__s); else __set_short_size(__s);}
17710b57cec5SDimitry Andric
1772*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
177381ad6265SDimitry Andric    void __set_long_cap(size_type __s) _NOEXCEPT {
177481ad6265SDimitry Andric        __r_.first().__l.__cap_ = __s / __endian_factor;
177581ad6265SDimitry Andric        __r_.first().__l.__is_long_ = true;
177681ad6265SDimitry Andric    }
17770b57cec5SDimitry Andric
1778*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
177981ad6265SDimitry Andric    size_type __get_long_cap() const _NOEXCEPT {
178081ad6265SDimitry Andric        return __r_.first().__l.__cap_ * __endian_factor;
178181ad6265SDimitry Andric    }
178281ad6265SDimitry Andric
1783*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
17840b57cec5SDimitry Andric    void __set_long_pointer(pointer __p) _NOEXCEPT
17850b57cec5SDimitry Andric        {__r_.first().__l.__data_ = __p;}
1786*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
17870b57cec5SDimitry Andric    pointer __get_long_pointer() _NOEXCEPT
17880b57cec5SDimitry Andric        {return __r_.first().__l.__data_;}
1789*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
17900b57cec5SDimitry Andric    const_pointer __get_long_pointer() const _NOEXCEPT
17910b57cec5SDimitry Andric        {return __r_.first().__l.__data_;}
1792*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
17930b57cec5SDimitry Andric    pointer __get_short_pointer() _NOEXCEPT
17940b57cec5SDimitry Andric        {return pointer_traits<pointer>::pointer_to(__r_.first().__s.__data_[0]);}
1795*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
17960b57cec5SDimitry Andric    const_pointer __get_short_pointer() const _NOEXCEPT
17970b57cec5SDimitry Andric        {return pointer_traits<const_pointer>::pointer_to(__r_.first().__s.__data_[0]);}
1798*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
17990b57cec5SDimitry Andric    pointer __get_pointer() _NOEXCEPT
18000b57cec5SDimitry Andric        {return __is_long() ? __get_long_pointer() : __get_short_pointer();}
1801*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
18020b57cec5SDimitry Andric    const_pointer __get_pointer() const _NOEXCEPT
18030b57cec5SDimitry Andric        {return __is_long() ? __get_long_pointer() : __get_short_pointer();}
18040b57cec5SDimitry Andric
18050b57cec5SDimitry Andric    template <size_type __a> static
1806*bdd1243dSDimitry Andric        _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
18070b57cec5SDimitry Andric        size_type __align_it(size_type __s) _NOEXCEPT
18080b57cec5SDimitry Andric            {return (__s + (__a-1)) & ~(__a-1);}
18090b57cec5SDimitry Andric    enum {__alignment = 16};
1810*bdd1243dSDimitry Andric    static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
18110b57cec5SDimitry Andric    size_type __recommend(size_type __s) _NOEXCEPT
18120b57cec5SDimitry Andric    {
181381ad6265SDimitry Andric        if (__s < __min_cap) {
181481ad6265SDimitry Andric            if (__libcpp_is_constant_evaluated())
181581ad6265SDimitry Andric                return static_cast<size_type>(__min_cap);
181681ad6265SDimitry Andric            else
181781ad6265SDimitry Andric                return static_cast<size_type>(__min_cap) - 1;
181881ad6265SDimitry Andric        }
18190b57cec5SDimitry Andric        size_type __guess = __align_it<sizeof(value_type) < __alignment ?
18200b57cec5SDimitry Andric                     __alignment/sizeof(value_type) : 1 > (__s+1) - 1;
18210b57cec5SDimitry Andric        if (__guess == __min_cap) ++__guess;
18220b57cec5SDimitry Andric        return __guess;
18230b57cec5SDimitry Andric    }
18240b57cec5SDimitry Andric
1825*bdd1243dSDimitry Andric    inline _LIBCPP_CONSTEXPR_SINCE_CXX20
18260b57cec5SDimitry Andric    void __init(const value_type* __s, size_type __sz, size_type __reserve);
1827*bdd1243dSDimitry Andric    inline _LIBCPP_CONSTEXPR_SINCE_CXX20
18280b57cec5SDimitry Andric    void __init(const value_type* __s, size_type __sz);
1829*bdd1243dSDimitry Andric    inline _LIBCPP_CONSTEXPR_SINCE_CXX20
18300b57cec5SDimitry Andric    void __init(size_type __n, value_type __c);
18310b57cec5SDimitry Andric
18325ffd83dbSDimitry Andric    // Slow path for the (inlined) copy constructor for 'long' strings.
18335ffd83dbSDimitry Andric    // Always externally instantiated and not inlined.
18345ffd83dbSDimitry Andric    // Requires that __s is zero terminated.
18355ffd83dbSDimitry Andric    // The main reason for this function to exist is because for unstable, we
18365ffd83dbSDimitry Andric    // want to allow inlining of the copy constructor. However, we don't want
18375ffd83dbSDimitry Andric    // to call the __init() functions as those are marked as inline which may
18385ffd83dbSDimitry Andric    // result in over-aggressive inlining by the compiler, where our aim is
18395ffd83dbSDimitry Andric    // to only inline the fast path code directly in the ctor.
1840*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init_copy_ctor_external(const value_type* __s, size_type __sz);
18415ffd83dbSDimitry Andric
18420b57cec5SDimitry Andric    template <class _InputIterator>
1843*bdd1243dSDimitry Andric    inline _LIBCPP_CONSTEXPR_SINCE_CXX20
1844349cc55cSDimitry Andric    __enable_if_t
18450b57cec5SDimitry Andric    <
18465ffd83dbSDimitry Andric        __is_exactly_cpp17_input_iterator<_InputIterator>::value
18475ffd83dbSDimitry Andric    >
18480b57cec5SDimitry Andric    __init(_InputIterator __first, _InputIterator __last);
18490b57cec5SDimitry Andric
18500b57cec5SDimitry Andric    template <class _ForwardIterator>
1851*bdd1243dSDimitry Andric    inline _LIBCPP_CONSTEXPR_SINCE_CXX20
1852349cc55cSDimitry Andric    __enable_if_t
18530b57cec5SDimitry Andric    <
18545ffd83dbSDimitry Andric        __is_cpp17_forward_iterator<_ForwardIterator>::value
18555ffd83dbSDimitry Andric    >
18560b57cec5SDimitry Andric    __init(_ForwardIterator __first, _ForwardIterator __last);
18570b57cec5SDimitry Andric
1858*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20
18590b57cec5SDimitry Andric    void __grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
18600b57cec5SDimitry Andric                   size_type __n_copy,  size_type __n_del,     size_type __n_add = 0);
1861*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20
18620b57cec5SDimitry Andric    void __grow_by_and_replace(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
18630b57cec5SDimitry Andric                               size_type __n_copy,  size_type __n_del,
18640b57cec5SDimitry Andric                               size_type __n_add, const value_type* __p_new_stuff);
18650b57cec5SDimitry Andric
18665ffd83dbSDimitry Andric    // __assign_no_alias is invoked for assignment operations where we
18675ffd83dbSDimitry Andric    // have proof that the input does not alias the current instance.
18685ffd83dbSDimitry Andric    // For example, operator=(basic_string) performs a 'self' check.
18695ffd83dbSDimitry Andric    template <bool __is_short>
1870*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& __assign_no_alias(const value_type* __s, size_type __n);
18715ffd83dbSDimitry Andric
1872*bdd1243dSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __erase_to_end(size_type __pos) {
1873*bdd1243dSDimitry Andric    __null_terminate_at(std::__to_address(__get_pointer()), __pos);
1874*bdd1243dSDimitry Andric  }
18750b57cec5SDimitry Andric
18765ffd83dbSDimitry Andric    // __erase_external_with_move is invoked for erase() invocations where
18775ffd83dbSDimitry Andric    // `n ~= npos`, likely requiring memory moves on the string data.
1878*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 void __erase_external_with_move(size_type __pos, size_type __n);
18795ffd83dbSDimitry Andric
1880*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
18810b57cec5SDimitry Andric    void __copy_assign_alloc(const basic_string& __str)
18820b57cec5SDimitry Andric        {__copy_assign_alloc(__str, integral_constant<bool,
18830b57cec5SDimitry Andric                      __alloc_traits::propagate_on_container_copy_assignment::value>());}
18840b57cec5SDimitry Andric
1885*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
18860b57cec5SDimitry Andric    void __copy_assign_alloc(const basic_string& __str, true_type)
18870b57cec5SDimitry Andric        {
18880b57cec5SDimitry Andric            if (__alloc() == __str.__alloc())
18890b57cec5SDimitry Andric                __alloc() = __str.__alloc();
18900b57cec5SDimitry Andric            else
18910b57cec5SDimitry Andric            {
18920b57cec5SDimitry Andric                if (!__str.__is_long())
18930b57cec5SDimitry Andric                {
18940b57cec5SDimitry Andric                    __clear_and_shrink();
18950b57cec5SDimitry Andric                    __alloc() = __str.__alloc();
18960b57cec5SDimitry Andric                }
18970b57cec5SDimitry Andric                else
18980b57cec5SDimitry Andric                {
18990b57cec5SDimitry Andric                    allocator_type __a = __str.__alloc();
190081ad6265SDimitry Andric                    auto __allocation = std::__allocate_at_least(__a, __str.__get_long_cap());
190181ad6265SDimitry Andric                    __begin_lifetime(__allocation.ptr, __allocation.count);
1902*bdd1243dSDimitry Andric                    __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
190381ad6265SDimitry Andric                    __alloc() = std::move(__a);
190481ad6265SDimitry Andric                    __set_long_pointer(__allocation.ptr);
190581ad6265SDimitry Andric                    __set_long_cap(__allocation.count);
19060b57cec5SDimitry Andric                    __set_long_size(__str.size());
19070b57cec5SDimitry Andric                }
19080b57cec5SDimitry Andric            }
19090b57cec5SDimitry Andric        }
19100b57cec5SDimitry Andric
1911*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
19120b57cec5SDimitry Andric    void __copy_assign_alloc(const basic_string&, false_type) _NOEXCEPT
19130b57cec5SDimitry Andric        {}
19140b57cec5SDimitry Andric
19150b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
1916*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
19170b57cec5SDimitry Andric    void __move_assign(basic_string& __str, false_type)
19180b57cec5SDimitry Andric        _NOEXCEPT_(__alloc_traits::is_always_equal::value);
1919*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
19200b57cec5SDimitry Andric    void __move_assign(basic_string& __str, true_type)
19210b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14
19220b57cec5SDimitry Andric        _NOEXCEPT;
19230b57cec5SDimitry Andric#else
19240b57cec5SDimitry Andric        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
19250b57cec5SDimitry Andric#endif
19260b57cec5SDimitry Andric#endif
19270b57cec5SDimitry Andric
1928*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
19290b57cec5SDimitry Andric    void
19300b57cec5SDimitry Andric    __move_assign_alloc(basic_string& __str)
19310b57cec5SDimitry Andric        _NOEXCEPT_(
19320b57cec5SDimitry Andric            !__alloc_traits::propagate_on_container_move_assignment::value ||
19330b57cec5SDimitry Andric            is_nothrow_move_assignable<allocator_type>::value)
19340b57cec5SDimitry Andric    {__move_assign_alloc(__str, integral_constant<bool,
19350b57cec5SDimitry Andric                      __alloc_traits::propagate_on_container_move_assignment::value>());}
19360b57cec5SDimitry Andric
1937*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
19380b57cec5SDimitry Andric    void __move_assign_alloc(basic_string& __c, true_type)
19390b57cec5SDimitry Andric        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
19400b57cec5SDimitry Andric        {
194181ad6265SDimitry Andric            __alloc() = std::move(__c.__alloc());
19420b57cec5SDimitry Andric        }
19430b57cec5SDimitry Andric
1944*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
19450b57cec5SDimitry Andric    void __move_assign_alloc(basic_string&, false_type)
19460b57cec5SDimitry Andric        _NOEXCEPT
19470b57cec5SDimitry Andric        {}
19480b57cec5SDimitry Andric
1949*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& __assign_external(const value_type* __s);
1950*bdd1243dSDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& __assign_external(const value_type* __s, size_type __n);
19515ffd83dbSDimitry Andric
19525ffd83dbSDimitry Andric    // Assigns the value in __s, guaranteed to be __n < __min_cap in length.
19535ffd83dbSDimitry Andric    inline basic_string& __assign_short(const value_type* __s, size_type __n) {
19545ffd83dbSDimitry Andric      pointer __p = __is_long()
19555ffd83dbSDimitry Andric                        ? (__set_long_size(__n), __get_long_pointer())
19565ffd83dbSDimitry Andric                        : (__set_short_size(__n), __get_short_pointer());
195781ad6265SDimitry Andric      traits_type::move(std::__to_address(__p), __s, __n);
19585ffd83dbSDimitry Andric      traits_type::assign(__p[__n], value_type());
19595ffd83dbSDimitry Andric      return *this;
19605ffd83dbSDimitry Andric    }
19615ffd83dbSDimitry Andric
1962*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
196381ad6265SDimitry Andric    basic_string& __null_terminate_at(value_type* __p, size_type __newsz) {
19640eae32dcSDimitry Andric      __set_size(__newsz);
19650eae32dcSDimitry Andric      __invalidate_iterators_past(__newsz);
19660eae32dcSDimitry Andric      traits_type::assign(__p[__newsz], value_type());
19670eae32dcSDimitry Andric      return *this;
19680eae32dcSDimitry Andric    }
19690eae32dcSDimitry Andric
1970*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __invalidate_iterators_past(size_type);
19710b57cec5SDimitry Andric
1972fe6060f1SDimitry Andric    template<class _Tp>
1973*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1974fe6060f1SDimitry Andric    bool __addr_in_range(_Tp&& __t) const {
197581ad6265SDimitry Andric        // assume that the ranges overlap, because we can't check during constant evaluation
197681ad6265SDimitry Andric        if (__libcpp_is_constant_evaluated())
197781ad6265SDimitry Andric          return true;
197881ad6265SDimitry Andric        const volatile void *__p = std::addressof(__t);
1979fe6060f1SDimitry Andric        return data() <= __p && __p <= data() + size();
1980fe6060f1SDimitry Andric    }
1981fe6060f1SDimitry Andric
198269ade1e0SDimitry Andric    _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI
198369ade1e0SDimitry Andric    void __throw_length_error() const {
198481ad6265SDimitry Andric        std::__throw_length_error("basic_string");
198569ade1e0SDimitry Andric    }
198669ade1e0SDimitry Andric
198769ade1e0SDimitry Andric    _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI
198869ade1e0SDimitry Andric    void __throw_out_of_range() const {
198981ad6265SDimitry Andric        std::__throw_out_of_range("basic_string");
199069ade1e0SDimitry Andric    }
199169ade1e0SDimitry Andric
1992*bdd1243dSDimitry Andric    friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+<>(const basic_string&, const basic_string&);
1993*bdd1243dSDimitry Andric    friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+<>(const value_type*, const basic_string&);
1994*bdd1243dSDimitry Andric    friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+<>(value_type, const basic_string&);
1995*bdd1243dSDimitry Andric    friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+<>(const basic_string&, const value_type*);
1996*bdd1243dSDimitry Andric    friend _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator+<>(const basic_string&, value_type);
19970b57cec5SDimitry Andric};
19980b57cec5SDimitry Andric
19995ffd83dbSDimitry Andric// These declarations must appear before any functions are implicitly used
20005ffd83dbSDimitry Andric// so that they have the correct visibility specifier.
200181ad6265SDimitry Andric#define _LIBCPP_DECLARE(...) extern template __VA_ARGS__;
20025ffd83dbSDimitry Andric#ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
200381ad6265SDimitry Andric    _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, char)
2004349cc55cSDimitry Andric#   ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
200581ad6265SDimitry Andric        _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, wchar_t)
2006349cc55cSDimitry Andric#   endif
20075ffd83dbSDimitry Andric#else
200881ad6265SDimitry Andric    _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, char)
2009349cc55cSDimitry Andric#   ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
201081ad6265SDimitry Andric        _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, wchar_t)
20115ffd83dbSDimitry Andric#   endif
2012349cc55cSDimitry Andric#endif
201381ad6265SDimitry Andric#undef _LIBCPP_DECLARE
20145ffd83dbSDimitry Andric
20155ffd83dbSDimitry Andric
2016349cc55cSDimitry Andric#if _LIBCPP_STD_VER >= 17
20170b57cec5SDimitry Andrictemplate<class _InputIterator,
2018fe6060f1SDimitry Andric         class _CharT = __iter_value_type<_InputIterator>,
20190b57cec5SDimitry Andric         class _Allocator = allocator<_CharT>,
2020349cc55cSDimitry Andric         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
2021349cc55cSDimitry Andric         class = enable_if_t<__is_allocator<_Allocator>::value>
20220b57cec5SDimitry Andric         >
20230b57cec5SDimitry Andricbasic_string(_InputIterator, _InputIterator, _Allocator = _Allocator())
20240b57cec5SDimitry Andric  -> basic_string<_CharT, char_traits<_CharT>, _Allocator>;
20250b57cec5SDimitry Andric
20260b57cec5SDimitry Andrictemplate<class _CharT,
20270b57cec5SDimitry Andric         class _Traits,
20280b57cec5SDimitry Andric         class _Allocator = allocator<_CharT>,
2029349cc55cSDimitry Andric         class = enable_if_t<__is_allocator<_Allocator>::value>
20300b57cec5SDimitry Andric         >
20310b57cec5SDimitry Andricexplicit basic_string(basic_string_view<_CharT, _Traits>, const _Allocator& = _Allocator())
20320b57cec5SDimitry Andric  -> basic_string<_CharT, _Traits, _Allocator>;
20330b57cec5SDimitry Andric
20340b57cec5SDimitry Andrictemplate<class _CharT,
20350b57cec5SDimitry Andric         class _Traits,
20360b57cec5SDimitry Andric         class _Allocator = allocator<_CharT>,
2037349cc55cSDimitry Andric         class = enable_if_t<__is_allocator<_Allocator>::value>,
20380b57cec5SDimitry Andric         class _Sz = typename allocator_traits<_Allocator>::size_type
20390b57cec5SDimitry Andric         >
20400b57cec5SDimitry Andricbasic_string(basic_string_view<_CharT, _Traits>, _Sz, _Sz, const _Allocator& = _Allocator())
20410b57cec5SDimitry Andric  -> basic_string<_CharT, _Traits, _Allocator>;
20420b57cec5SDimitry Andric#endif
20430b57cec5SDimitry Andric
20440b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
2045*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
20460b57cec5SDimitry Andricvoid
2047fe6060f1SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type __pos)
20480b57cec5SDimitry Andric{
204981ad6265SDimitry Andric#ifdef _LIBCPP_ENABLE_DEBUG_MODE
20500eae32dcSDimitry Andric    if (!__libcpp_is_constant_evaluated()) {
20510b57cec5SDimitry Andric        __c_node* __c = __get_db()->__find_c_and_lock(this);
20520b57cec5SDimitry Andric        if (__c)
20530b57cec5SDimitry Andric        {
20540b57cec5SDimitry Andric            const_pointer __new_last = __get_pointer() + __pos;
20550b57cec5SDimitry Andric            for (__i_node** __p = __c->end_; __p != __c->beg_; )
20560b57cec5SDimitry Andric            {
20570b57cec5SDimitry Andric                --__p;
20580b57cec5SDimitry Andric                const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
20590b57cec5SDimitry Andric                if (__i->base() > __new_last)
20600b57cec5SDimitry Andric                {
20610b57cec5SDimitry Andric                    (*__p)->__c_ = nullptr;
20620b57cec5SDimitry Andric                    if (--__c->end_ != __p)
206381ad6265SDimitry Andric                        std::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
20640b57cec5SDimitry Andric                }
20650b57cec5SDimitry Andric            }
20660b57cec5SDimitry Andric            __get_db()->unlock();
20670b57cec5SDimitry Andric        }
20680eae32dcSDimitry Andric    }
2069fe6060f1SDimitry Andric#else
2070fe6060f1SDimitry Andric    (void)__pos;
207181ad6265SDimitry Andric#endif // _LIBCPP_ENABLE_DEBUG_MODE
20720b57cec5SDimitry Andric}
20730b57cec5SDimitry Andric
20740b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
2075*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
20760b57cec5SDimitry Andricvoid basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s,
20770b57cec5SDimitry Andric                                                       size_type __sz,
20780b57cec5SDimitry Andric                                                       size_type __reserve)
20790b57cec5SDimitry Andric{
208081ad6265SDimitry Andric    if (__libcpp_is_constant_evaluated())
2081*bdd1243dSDimitry Andric        __r_.first() = __rep();
20820b57cec5SDimitry Andric    if (__reserve > max_size())
208304eeddc0SDimitry Andric        __throw_length_error();
20840b57cec5SDimitry Andric    pointer __p;
208504eeddc0SDimitry Andric    if (__fits_in_sso(__reserve))
20860b57cec5SDimitry Andric    {
20870b57cec5SDimitry Andric        __set_short_size(__sz);
20880b57cec5SDimitry Andric        __p = __get_short_pointer();
20890b57cec5SDimitry Andric    }
20900b57cec5SDimitry Andric    else
20910b57cec5SDimitry Andric    {
209281ad6265SDimitry Andric        auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__reserve) + 1);
209381ad6265SDimitry Andric        __p = __allocation.ptr;
209481ad6265SDimitry Andric        __begin_lifetime(__p, __allocation.count);
20950b57cec5SDimitry Andric        __set_long_pointer(__p);
209681ad6265SDimitry Andric        __set_long_cap(__allocation.count);
20970b57cec5SDimitry Andric        __set_long_size(__sz);
20980b57cec5SDimitry Andric    }
209981ad6265SDimitry Andric    traits_type::copy(std::__to_address(__p), __s, __sz);
21000b57cec5SDimitry Andric    traits_type::assign(__p[__sz], value_type());
21010b57cec5SDimitry Andric}
21020b57cec5SDimitry Andric
21030b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
2104*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
21050b57cec5SDimitry Andricvoid
21060b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz)
21070b57cec5SDimitry Andric{
210881ad6265SDimitry Andric    if (__libcpp_is_constant_evaluated())
2109*bdd1243dSDimitry Andric        __r_.first() = __rep();
21100b57cec5SDimitry Andric    if (__sz > max_size())
211104eeddc0SDimitry Andric        __throw_length_error();
21120b57cec5SDimitry Andric    pointer __p;
211304eeddc0SDimitry Andric    if (__fits_in_sso(__sz))
21140b57cec5SDimitry Andric    {
21150b57cec5SDimitry Andric        __set_short_size(__sz);
21160b57cec5SDimitry Andric        __p = __get_short_pointer();
21170b57cec5SDimitry Andric    }
21180b57cec5SDimitry Andric    else
21190b57cec5SDimitry Andric    {
212081ad6265SDimitry Andric        auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1);
212181ad6265SDimitry Andric        __p = __allocation.ptr;
212281ad6265SDimitry Andric        __begin_lifetime(__p, __allocation.count);
21230b57cec5SDimitry Andric        __set_long_pointer(__p);
212481ad6265SDimitry Andric        __set_long_cap(__allocation.count);
21250b57cec5SDimitry Andric        __set_long_size(__sz);
21260b57cec5SDimitry Andric    }
212781ad6265SDimitry Andric    traits_type::copy(std::__to_address(__p), __s, __sz);
21280b57cec5SDimitry Andric    traits_type::assign(__p[__sz], value_type());
21290b57cec5SDimitry Andric}
21300b57cec5SDimitry Andric
21310b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
21320b57cec5SDimitry Andrictemplate <class>
2133*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
21340b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const _Allocator& __a)
2135480093f4SDimitry Andric    : __r_(__default_init_tag(), __a)
21360b57cec5SDimitry Andric{
21370b57cec5SDimitry Andric    _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr");
21380b57cec5SDimitry Andric    __init(__s, traits_type::length(__s));
213981ad6265SDimitry Andric    std::__debug_db_insert_c(this);
21400b57cec5SDimitry Andric}
21410b57cec5SDimitry Andric
21420b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
2143*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
21440b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str)
2145480093f4SDimitry Andric    : __r_(__default_init_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc()))
21460b57cec5SDimitry Andric{
21470b57cec5SDimitry Andric    if (!__str.__is_long())
2148*bdd1243dSDimitry Andric        __r_.first() = __str.__r_.first();
21490b57cec5SDimitry Andric    else
215081ad6265SDimitry Andric        __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()),
21515ffd83dbSDimitry Andric                                  __str.__get_long_size());
215281ad6265SDimitry Andric    std::__debug_db_insert_c(this);
21530b57cec5SDimitry Andric}
21540b57cec5SDimitry Andric
21550b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
2156*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
21570b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::basic_string(
21580b57cec5SDimitry Andric    const basic_string& __str, const allocator_type& __a)
2159480093f4SDimitry Andric    : __r_(__default_init_tag(), __a)
21600b57cec5SDimitry Andric{
21610b57cec5SDimitry Andric    if (!__str.__is_long())
2162*bdd1243dSDimitry Andric        __r_.first() = __str.__r_.first();
21630b57cec5SDimitry Andric    else
216481ad6265SDimitry Andric        __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()),
21655ffd83dbSDimitry Andric                                  __str.__get_long_size());
216681ad6265SDimitry Andric    std::__debug_db_insert_c(this);
21670b57cec5SDimitry Andric}
21680b57cec5SDimitry Andric
21695ffd83dbSDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
2170*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
21715ffd83dbSDimitry Andricvoid basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external(
21725ffd83dbSDimitry Andric    const value_type* __s, size_type __sz) {
217381ad6265SDimitry Andric  if (__libcpp_is_constant_evaluated())
2174*bdd1243dSDimitry Andric    __r_.first() = __rep();
2175*bdd1243dSDimitry Andric
21765ffd83dbSDimitry Andric  pointer __p;
217704eeddc0SDimitry Andric  if (__fits_in_sso(__sz)) {
21785ffd83dbSDimitry Andric    __p = __get_short_pointer();
21795ffd83dbSDimitry Andric    __set_short_size(__sz);
21805ffd83dbSDimitry Andric  } else {
21815ffd83dbSDimitry Andric    if (__sz > max_size())
218204eeddc0SDimitry Andric      __throw_length_error();
218381ad6265SDimitry Andric    auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1);
218481ad6265SDimitry Andric    __p = __allocation.ptr;
218581ad6265SDimitry Andric    __begin_lifetime(__p, __allocation.count);
21865ffd83dbSDimitry Andric    __set_long_pointer(__p);
218781ad6265SDimitry Andric    __set_long_cap(__allocation.count);
21885ffd83dbSDimitry Andric    __set_long_size(__sz);
21895ffd83dbSDimitry Andric  }
219081ad6265SDimitry Andric  traits_type::copy(std::__to_address(__p), __s, __sz + 1);
21915ffd83dbSDimitry Andric}
21925ffd83dbSDimitry Andric
21930b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
2194*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
21950b57cec5SDimitry Andricvoid
21960b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c)
21970b57cec5SDimitry Andric{
219881ad6265SDimitry Andric    if (__libcpp_is_constant_evaluated())
2199*bdd1243dSDimitry Andric        __r_.first() = __rep();
2200*bdd1243dSDimitry Andric
22010b57cec5SDimitry Andric    if (__n > max_size())
220204eeddc0SDimitry Andric        __throw_length_error();
22030b57cec5SDimitry Andric    pointer __p;
220404eeddc0SDimitry Andric    if (__fits_in_sso(__n))
22050b57cec5SDimitry Andric    {
22060b57cec5SDimitry Andric        __set_short_size(__n);
22070b57cec5SDimitry Andric        __p = __get_short_pointer();
22080b57cec5SDimitry Andric    }
22090b57cec5SDimitry Andric    else
22100b57cec5SDimitry Andric    {
221181ad6265SDimitry Andric        auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__n) + 1);
221281ad6265SDimitry Andric        __p = __allocation.ptr;
221381ad6265SDimitry Andric        __begin_lifetime(__p, __allocation.count);
22140b57cec5SDimitry Andric        __set_long_pointer(__p);
221581ad6265SDimitry Andric        __set_long_cap(__allocation.count);
22160b57cec5SDimitry Andric        __set_long_size(__n);
22170b57cec5SDimitry Andric    }
221881ad6265SDimitry Andric    traits_type::assign(std::__to_address(__p), __n, __c);
22190b57cec5SDimitry Andric    traits_type::assign(__p[__n], value_type());
22200b57cec5SDimitry Andric}
22210b57cec5SDimitry Andric
22220b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
22230b57cec5SDimitry Andrictemplate <class>
2224*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
22250b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c, const _Allocator& __a)
2226480093f4SDimitry Andric    : __r_(__default_init_tag(), __a)
22270b57cec5SDimitry Andric{
22280b57cec5SDimitry Andric    __init(__n, __c);
222981ad6265SDimitry Andric    std::__debug_db_insert_c(this);
22300b57cec5SDimitry Andric}
22310b57cec5SDimitry Andric
22320b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
2233*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
22340b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str,
22350b57cec5SDimitry Andric                                                        size_type __pos, size_type __n,
22360b57cec5SDimitry Andric                                                        const _Allocator& __a)
2237480093f4SDimitry Andric    : __r_(__default_init_tag(), __a)
22380b57cec5SDimitry Andric{
22390b57cec5SDimitry Andric    size_type __str_sz = __str.size();
22400b57cec5SDimitry Andric    if (__pos > __str_sz)
224104eeddc0SDimitry Andric        __throw_out_of_range();
224281ad6265SDimitry Andric    __init(__str.data() + __pos, std::min(__n, __str_sz - __pos));
224381ad6265SDimitry Andric    std::__debug_db_insert_c(this);
22440b57cec5SDimitry Andric}
22450b57cec5SDimitry Andric
22460b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
22470b57cec5SDimitry Andrictemplate <class _Tp, class>
2248*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
22490b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::basic_string(
22500b57cec5SDimitry Andric             const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a)
2251480093f4SDimitry Andric    : __r_(__default_init_tag(), __a)
22520b57cec5SDimitry Andric{
22530b57cec5SDimitry Andric    __self_view __sv0 = __t;
22540b57cec5SDimitry Andric    __self_view __sv = __sv0.substr(__pos, __n);
22550b57cec5SDimitry Andric    __init(__sv.data(), __sv.size());
225681ad6265SDimitry Andric    std::__debug_db_insert_c(this);
22570b57cec5SDimitry Andric}
22580b57cec5SDimitry Andric
22590b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
22600b57cec5SDimitry Andrictemplate <class _Tp, class>
2261*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
22620b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t)
2263480093f4SDimitry Andric     : __r_(__default_init_tag(), __default_init_tag())
22640b57cec5SDimitry Andric{
22650b57cec5SDimitry Andric    __self_view __sv = __t;
22660b57cec5SDimitry Andric    __init(__sv.data(), __sv.size());
226781ad6265SDimitry Andric    std::__debug_db_insert_c(this);
22680b57cec5SDimitry Andric}
22690b57cec5SDimitry Andric
22700b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
22710b57cec5SDimitry Andrictemplate <class _Tp, class>
2272*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
22730b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t, const _Allocator& __a)
2274480093f4SDimitry Andric    : __r_(__default_init_tag(), __a)
22750b57cec5SDimitry Andric{
22760b57cec5SDimitry Andric    __self_view __sv = __t;
22770b57cec5SDimitry Andric    __init(__sv.data(), __sv.size());
227881ad6265SDimitry Andric    std::__debug_db_insert_c(this);
22790b57cec5SDimitry Andric}
22800b57cec5SDimitry Andric
22810b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
22820b57cec5SDimitry Andrictemplate <class _InputIterator>
2283*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
2284349cc55cSDimitry Andric__enable_if_t
22850b57cec5SDimitry Andric<
22865ffd83dbSDimitry Andric    __is_exactly_cpp17_input_iterator<_InputIterator>::value
22875ffd83dbSDimitry Andric>
22880b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last)
22890b57cec5SDimitry Andric{
229081ad6265SDimitry Andric    __default_init();
22910b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
22920b57cec5SDimitry Andric    try
22930b57cec5SDimitry Andric    {
22940b57cec5SDimitry Andric#endif // _LIBCPP_NO_EXCEPTIONS
22950b57cec5SDimitry Andric    for (; __first != __last; ++__first)
22960b57cec5SDimitry Andric        push_back(*__first);
22970b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
22980b57cec5SDimitry Andric    }
22990b57cec5SDimitry Andric    catch (...)
23000b57cec5SDimitry Andric    {
23010b57cec5SDimitry Andric        if (__is_long())
23020b57cec5SDimitry Andric            __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
23030b57cec5SDimitry Andric        throw;
23040b57cec5SDimitry Andric    }
23050b57cec5SDimitry Andric#endif // _LIBCPP_NO_EXCEPTIONS
23060b57cec5SDimitry Andric}
23070b57cec5SDimitry Andric
23080b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
23090b57cec5SDimitry Andrictemplate <class _ForwardIterator>
2310*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
2311349cc55cSDimitry Andric__enable_if_t
23120b57cec5SDimitry Andric<
23135ffd83dbSDimitry Andric    __is_cpp17_forward_iterator<_ForwardIterator>::value
23145ffd83dbSDimitry Andric>
23150b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last)
23160b57cec5SDimitry Andric{
231781ad6265SDimitry Andric    if (__libcpp_is_constant_evaluated())
2318*bdd1243dSDimitry Andric        __r_.first() = __rep();
231981ad6265SDimitry Andric    size_type __sz = static_cast<size_type>(std::distance(__first, __last));
23200b57cec5SDimitry Andric    if (__sz > max_size())
232104eeddc0SDimitry Andric        __throw_length_error();
23220b57cec5SDimitry Andric    pointer __p;
232304eeddc0SDimitry Andric    if (__fits_in_sso(__sz))
23240b57cec5SDimitry Andric    {
23250b57cec5SDimitry Andric        __set_short_size(__sz);
23260b57cec5SDimitry Andric        __p = __get_short_pointer();
23270b57cec5SDimitry Andric    }
23280b57cec5SDimitry Andric    else
23290b57cec5SDimitry Andric    {
233081ad6265SDimitry Andric        auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1);
233181ad6265SDimitry Andric        __p = __allocation.ptr;
233281ad6265SDimitry Andric        __begin_lifetime(__p, __allocation.count);
23330b57cec5SDimitry Andric        __set_long_pointer(__p);
233481ad6265SDimitry Andric        __set_long_cap(__allocation.count);
23350b57cec5SDimitry Andric        __set_long_size(__sz);
23360b57cec5SDimitry Andric    }
2337fe6060f1SDimitry Andric
2338fe6060f1SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
2339fe6060f1SDimitry Andric    try
2340fe6060f1SDimitry Andric    {
2341fe6060f1SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
23420b57cec5SDimitry Andric    for (; __first != __last; ++__first, (void) ++__p)
23430b57cec5SDimitry Andric        traits_type::assign(*__p, *__first);
23440b57cec5SDimitry Andric    traits_type::assign(*__p, value_type());
2345fe6060f1SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
2346fe6060f1SDimitry Andric    }
2347fe6060f1SDimitry Andric    catch (...)
2348fe6060f1SDimitry Andric    {
2349fe6060f1SDimitry Andric        if (__is_long())
2350fe6060f1SDimitry Andric            __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
2351fe6060f1SDimitry Andric        throw;
2352fe6060f1SDimitry Andric    }
2353fe6060f1SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
23540b57cec5SDimitry Andric}
23550b57cec5SDimitry Andric
23560b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
2357*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
23580b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::~basic_string()
23590b57cec5SDimitry Andric{
236081ad6265SDimitry Andric    std::__debug_db_erase_c(this);
23610b57cec5SDimitry Andric    if (__is_long())
23620b57cec5SDimitry Andric        __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
23630b57cec5SDimitry Andric}
23640b57cec5SDimitry Andric
23650b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
2366*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
23670b57cec5SDimitry Andricvoid
23680b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace
23690b57cec5SDimitry Andric    (size_type __old_cap, size_type __delta_cap, size_type __old_sz,
23700b57cec5SDimitry Andric     size_type __n_copy,  size_type __n_del,     size_type __n_add, const value_type* __p_new_stuff)
23710b57cec5SDimitry Andric{
23720b57cec5SDimitry Andric    size_type __ms = max_size();
23730b57cec5SDimitry Andric    if (__delta_cap > __ms - __old_cap - 1)
237404eeddc0SDimitry Andric        __throw_length_error();
23750b57cec5SDimitry Andric    pointer __old_p = __get_pointer();
23760b57cec5SDimitry Andric    size_type __cap = __old_cap < __ms / 2 - __alignment ?
237781ad6265SDimitry Andric                          __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) :
23780b57cec5SDimitry Andric                          __ms - 1;
237981ad6265SDimitry Andric    auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1);
238081ad6265SDimitry Andric    pointer __p = __allocation.ptr;
238181ad6265SDimitry Andric    __begin_lifetime(__p, __allocation.count);
238281ad6265SDimitry Andric    std::__debug_db_invalidate_all(this);
23830b57cec5SDimitry Andric    if (__n_copy != 0)
238481ad6265SDimitry Andric        traits_type::copy(std::__to_address(__p),
238581ad6265SDimitry Andric                          std::__to_address(__old_p), __n_copy);
23860b57cec5SDimitry Andric    if (__n_add != 0)
238781ad6265SDimitry Andric        traits_type::copy(std::__to_address(__p) + __n_copy, __p_new_stuff, __n_add);
23880b57cec5SDimitry Andric    size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
23890b57cec5SDimitry Andric    if (__sec_cp_sz != 0)
239081ad6265SDimitry Andric        traits_type::copy(std::__to_address(__p) + __n_copy + __n_add,
239181ad6265SDimitry Andric                          std::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz);
239281ad6265SDimitry Andric    if (__old_cap+1 != __min_cap || __libcpp_is_constant_evaluated())
23930b57cec5SDimitry Andric        __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1);
23940b57cec5SDimitry Andric    __set_long_pointer(__p);
239581ad6265SDimitry Andric    __set_long_cap(__allocation.count);
23960b57cec5SDimitry Andric    __old_sz = __n_copy + __n_add + __sec_cp_sz;
23970b57cec5SDimitry Andric    __set_long_size(__old_sz);
23980b57cec5SDimitry Andric    traits_type::assign(__p[__old_sz], value_type());
23990b57cec5SDimitry Andric}
24000b57cec5SDimitry Andric
24010b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
24020b57cec5SDimitry Andricvoid
2403*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
24040b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
24050b57cec5SDimitry Andric                                                     size_type __n_copy,  size_type __n_del,     size_type __n_add)
24060b57cec5SDimitry Andric{
24070b57cec5SDimitry Andric    size_type __ms = max_size();
24080b57cec5SDimitry Andric    if (__delta_cap > __ms - __old_cap)
240904eeddc0SDimitry Andric        __throw_length_error();
24100b57cec5SDimitry Andric    pointer __old_p = __get_pointer();
24110b57cec5SDimitry Andric    size_type __cap = __old_cap < __ms / 2 - __alignment ?
241281ad6265SDimitry Andric                          __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) :
24130b57cec5SDimitry Andric                          __ms - 1;
241481ad6265SDimitry Andric    auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1);
241581ad6265SDimitry Andric    pointer __p = __allocation.ptr;
241681ad6265SDimitry Andric    __begin_lifetime(__p, __allocation.count);
241781ad6265SDimitry Andric    std::__debug_db_invalidate_all(this);
24180b57cec5SDimitry Andric    if (__n_copy != 0)
241981ad6265SDimitry Andric        traits_type::copy(std::__to_address(__p),
242081ad6265SDimitry Andric                          std::__to_address(__old_p), __n_copy);
24210b57cec5SDimitry Andric    size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
24220b57cec5SDimitry Andric    if (__sec_cp_sz != 0)
242381ad6265SDimitry Andric        traits_type::copy(std::__to_address(__p) + __n_copy + __n_add,
242481ad6265SDimitry Andric                          std::__to_address(__old_p) + __n_copy + __n_del,
24250b57cec5SDimitry Andric                          __sec_cp_sz);
242681ad6265SDimitry Andric    if (__libcpp_is_constant_evaluated() || __old_cap + 1 != __min_cap)
24270b57cec5SDimitry Andric        __alloc_traits::deallocate(__alloc(), __old_p, __old_cap + 1);
24280b57cec5SDimitry Andric    __set_long_pointer(__p);
242981ad6265SDimitry Andric    __set_long_cap(__allocation.count);
24300b57cec5SDimitry Andric}
24310b57cec5SDimitry Andric
24320b57cec5SDimitry Andric// assign
24330b57cec5SDimitry Andric
24340b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
24355ffd83dbSDimitry Andrictemplate <bool __is_short>
2436*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
24370b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>&
24385ffd83dbSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__assign_no_alias(
24395ffd83dbSDimitry Andric    const value_type* __s, size_type __n) {
244081ad6265SDimitry Andric  size_type __cap = __is_short ? static_cast<size_type>(__min_cap) : __get_long_cap();
24415ffd83dbSDimitry Andric  if (__n < __cap) {
24425ffd83dbSDimitry Andric    pointer __p = __is_short ? __get_short_pointer() : __get_long_pointer();
24435ffd83dbSDimitry Andric    __is_short ? __set_short_size(__n) : __set_long_size(__n);
244481ad6265SDimitry Andric    traits_type::copy(std::__to_address(__p), __s, __n);
24455ffd83dbSDimitry Andric    traits_type::assign(__p[__n], value_type());
24465ffd83dbSDimitry Andric    __invalidate_iterators_past(__n);
24475ffd83dbSDimitry Andric  } else {
24485ffd83dbSDimitry Andric    size_type __sz = __is_short ? __get_short_size() : __get_long_size();
24495ffd83dbSDimitry Andric    __grow_by_and_replace(__cap - 1, __n - __cap + 1, __sz, 0, __sz, __n, __s);
24505ffd83dbSDimitry Andric  }
24515ffd83dbSDimitry Andric  return *this;
24525ffd83dbSDimitry Andric}
24535ffd83dbSDimitry Andric
24545ffd83dbSDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
2455*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
24565ffd83dbSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>&
24575ffd83dbSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__assign_external(
24585ffd83dbSDimitry Andric    const value_type* __s, size_type __n) {
24590b57cec5SDimitry Andric  size_type __cap = capacity();
24605ffd83dbSDimitry Andric  if (__cap >= __n) {
246181ad6265SDimitry Andric    value_type* __p = std::__to_address(__get_pointer());
24620b57cec5SDimitry Andric    traits_type::move(__p, __s, __n);
24630eae32dcSDimitry Andric    return __null_terminate_at(__p, __n);
24645ffd83dbSDimitry Andric  } else {
24650b57cec5SDimitry Andric    size_type __sz = size();
24660b57cec5SDimitry Andric    __grow_by_and_replace(__cap, __n - __cap, __sz, 0, __sz, __n, __s);
24670b57cec5SDimitry Andric    return *this;
24680b57cec5SDimitry Andric  }
24690eae32dcSDimitry Andric}
24700b57cec5SDimitry Andric
24710b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
2472*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
24730b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>&
24745ffd83dbSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n)
24755ffd83dbSDimitry Andric{
24765ffd83dbSDimitry Andric    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::assign received nullptr");
247704eeddc0SDimitry Andric    return (__builtin_constant_p(__n) && __fits_in_sso(__n))
24785ffd83dbSDimitry Andric               ? __assign_short(__s, __n)
24795ffd83dbSDimitry Andric               : __assign_external(__s, __n);
24805ffd83dbSDimitry Andric}
24815ffd83dbSDimitry Andric
24825ffd83dbSDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
2483*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
24845ffd83dbSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>&
24850b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c)
24860b57cec5SDimitry Andric{
24870b57cec5SDimitry Andric    size_type __cap = capacity();
24880b57cec5SDimitry Andric    if (__cap < __n)
24890b57cec5SDimitry Andric    {
24900b57cec5SDimitry Andric        size_type __sz = size();
24910b57cec5SDimitry Andric        __grow_by(__cap, __n - __cap, __sz, 0, __sz);
24920b57cec5SDimitry Andric    }
249381ad6265SDimitry Andric    value_type* __p = std::__to_address(__get_pointer());
24940b57cec5SDimitry Andric    traits_type::assign(__p, __n, __c);
24950eae32dcSDimitry Andric    return __null_terminate_at(__p, __n);
24960b57cec5SDimitry Andric}
24970b57cec5SDimitry Andric
24980b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
2499*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
25000b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>&
25010b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c)
25020b57cec5SDimitry Andric{
25030b57cec5SDimitry Andric    pointer __p;
25040b57cec5SDimitry Andric    if (__is_long())
25050b57cec5SDimitry Andric    {
25060b57cec5SDimitry Andric        __p = __get_long_pointer();
25070b57cec5SDimitry Andric        __set_long_size(1);
25080b57cec5SDimitry Andric    }
25090b57cec5SDimitry Andric    else
25100b57cec5SDimitry Andric    {
25110b57cec5SDimitry Andric        __p = __get_short_pointer();
25120b57cec5SDimitry Andric        __set_short_size(1);
25130b57cec5SDimitry Andric    }
25140b57cec5SDimitry Andric    traits_type::assign(*__p, __c);
25150b57cec5SDimitry Andric    traits_type::assign(*++__p, value_type());
25160b57cec5SDimitry Andric    __invalidate_iterators_past(1);
25170b57cec5SDimitry Andric    return *this;
25180b57cec5SDimitry Andric}
25190b57cec5SDimitry Andric
25200b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
2521*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
25220b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>&
25230b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str)
25240b57cec5SDimitry Andric{
25255ffd83dbSDimitry Andric  if (this != &__str) {
25260b57cec5SDimitry Andric    __copy_assign_alloc(__str);
25275ffd83dbSDimitry Andric    if (!__is_long()) {
25285ffd83dbSDimitry Andric      if (!__str.__is_long()) {
2529*bdd1243dSDimitry Andric        __r_.first() = __str.__r_.first();
25305ffd83dbSDimitry Andric      } else {
25315ffd83dbSDimitry Andric        return __assign_no_alias<true>(__str.data(), __str.size());
25325ffd83dbSDimitry Andric      }
25335ffd83dbSDimitry Andric    } else {
25345ffd83dbSDimitry Andric      return __assign_no_alias<false>(__str.data(), __str.size());
25355ffd83dbSDimitry Andric    }
25360b57cec5SDimitry Andric  }
25370b57cec5SDimitry Andric  return *this;
25380b57cec5SDimitry Andric}
25390b57cec5SDimitry Andric
25400b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
25410b57cec5SDimitry Andric
25420b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
2543*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
25440b57cec5SDimitry Andricvoid
25450b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, false_type)
25460b57cec5SDimitry Andric    _NOEXCEPT_(__alloc_traits::is_always_equal::value)
25470b57cec5SDimitry Andric{
25480b57cec5SDimitry Andric    if (__alloc() != __str.__alloc())
25490b57cec5SDimitry Andric        assign(__str);
25500b57cec5SDimitry Andric    else
25510b57cec5SDimitry Andric        __move_assign(__str, true_type());
25520b57cec5SDimitry Andric}
25530b57cec5SDimitry Andric
25540b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
2555*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
25560b57cec5SDimitry Andricvoid
25570b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type)
25580b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14
25590b57cec5SDimitry Andric    _NOEXCEPT
25600b57cec5SDimitry Andric#else
25610b57cec5SDimitry Andric    _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
25620b57cec5SDimitry Andric#endif
25630b57cec5SDimitry Andric{
2564480093f4SDimitry Andric  if (__is_long()) {
2565480093f4SDimitry Andric    __alloc_traits::deallocate(__alloc(), __get_long_pointer(),
2566480093f4SDimitry Andric                               __get_long_cap());
2567480093f4SDimitry Andric#if _LIBCPP_STD_VER <= 14
2568480093f4SDimitry Andric    if (!is_nothrow_move_assignable<allocator_type>::value) {
2569480093f4SDimitry Andric      __set_short_size(0);
2570480093f4SDimitry Andric      traits_type::assign(__get_short_pointer()[0], value_type());
2571480093f4SDimitry Andric    }
2572480093f4SDimitry Andric#endif
2573480093f4SDimitry Andric  }
25740b57cec5SDimitry Andric  __move_assign_alloc(__str);
2575480093f4SDimitry Andric  __r_.first() = __str.__r_.first();
257681ad6265SDimitry Andric  if (__libcpp_is_constant_evaluated()) {
257781ad6265SDimitry Andric    __str.__default_init();
257881ad6265SDimitry Andric  } else {
2579480093f4SDimitry Andric    __str.__set_short_size(0);
2580480093f4SDimitry Andric    traits_type::assign(__str.__get_short_pointer()[0], value_type());
25810b57cec5SDimitry Andric  }
258281ad6265SDimitry Andric}
25830b57cec5SDimitry Andric
25840b57cec5SDimitry Andric#endif
25850b57cec5SDimitry Andric
25860b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
25870b57cec5SDimitry Andrictemplate<class _InputIterator>
2588*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
2589349cc55cSDimitry Andric__enable_if_t
25900b57cec5SDimitry Andric<
2591fe6060f1SDimitry Andric     __is_exactly_cpp17_input_iterator<_InputIterator>::value,
25920b57cec5SDimitry Andric    basic_string<_CharT, _Traits, _Allocator>&
25935ffd83dbSDimitry Andric>
25940b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
25950b57cec5SDimitry Andric{
25960b57cec5SDimitry Andric    const basic_string __temp(__first, __last, __alloc());
25970b57cec5SDimitry Andric    assign(__temp.data(), __temp.size());
25980b57cec5SDimitry Andric    return *this;
25990b57cec5SDimitry Andric}
26000b57cec5SDimitry Andric
26010b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
26020b57cec5SDimitry Andrictemplate<class _ForwardIterator>
2603*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
2604349cc55cSDimitry Andric__enable_if_t
26050b57cec5SDimitry Andric<
2606fe6060f1SDimitry Andric    __is_cpp17_forward_iterator<_ForwardIterator>::value,
26070b57cec5SDimitry Andric    basic_string<_CharT, _Traits, _Allocator>&
26085ffd83dbSDimitry Andric>
26090b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)
26100b57cec5SDimitry Andric{
26110b57cec5SDimitry Andric    size_type __cap = capacity();
2612fe6060f1SDimitry Andric    size_type __n = __string_is_trivial_iterator<_ForwardIterator>::value ?
261381ad6265SDimitry Andric        static_cast<size_type>(std::distance(__first, __last)) : 0;
2614fe6060f1SDimitry Andric
2615fe6060f1SDimitry Andric    if (__string_is_trivial_iterator<_ForwardIterator>::value &&
2616fe6060f1SDimitry Andric        (__cap >= __n || !__addr_in_range(*__first)))
2617fe6060f1SDimitry Andric    {
26180b57cec5SDimitry Andric        if (__cap < __n)
26190b57cec5SDimitry Andric        {
26200b57cec5SDimitry Andric            size_type __sz = size();
26210b57cec5SDimitry Andric            __grow_by(__cap, __n - __cap, __sz, 0, __sz);
26220b57cec5SDimitry Andric        }
26230b57cec5SDimitry Andric        pointer __p = __get_pointer();
2624349cc55cSDimitry Andric        for (; __first != __last; ++__p, (void) ++__first)
26250b57cec5SDimitry Andric            traits_type::assign(*__p, *__first);
26260b57cec5SDimitry Andric        traits_type::assign(*__p, value_type());
26270b57cec5SDimitry Andric        __set_size(__n);
2628fe6060f1SDimitry Andric        __invalidate_iterators_past(__n);
2629fe6060f1SDimitry Andric    }
2630fe6060f1SDimitry Andric    else
2631fe6060f1SDimitry Andric    {
2632fe6060f1SDimitry Andric        const basic_string __temp(__first, __last, __alloc());
2633fe6060f1SDimitry Andric        assign(__temp.data(), __temp.size());
2634fe6060f1SDimitry Andric    }
26350b57cec5SDimitry Andric    return *this;
26360b57cec5SDimitry Andric}
26370b57cec5SDimitry Andric
26380b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
2639*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
26400b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>&
26410b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, size_type __pos, size_type __n)
26420b57cec5SDimitry Andric{
26430b57cec5SDimitry Andric    size_type __sz = __str.size();
26440b57cec5SDimitry Andric    if (__pos > __sz)
264504eeddc0SDimitry Andric        __throw_out_of_range();
264681ad6265SDimitry Andric    return assign(__str.data() + __pos, std::min(__n, __sz - __pos));
26470b57cec5SDimitry Andric}
26480b57cec5SDimitry Andric
26490b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
26500b57cec5SDimitry Andrictemplate <class _Tp>
2651*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
2652349cc55cSDimitry Andric__enable_if_t
26530b57cec5SDimitry Andric<
26545ffd83dbSDimitry Andric    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
26555ffd83dbSDimitry Andric    && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
26560b57cec5SDimitry Andric    basic_string<_CharT, _Traits, _Allocator>&
26575ffd83dbSDimitry Andric>
26580b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t, size_type __pos, size_type __n)
26590b57cec5SDimitry Andric{
26600b57cec5SDimitry Andric    __self_view __sv = __t;
26610b57cec5SDimitry Andric    size_type __sz = __sv.size();
26620b57cec5SDimitry Andric    if (__pos > __sz)
266304eeddc0SDimitry Andric        __throw_out_of_range();
266481ad6265SDimitry Andric    return assign(__sv.data() + __pos, std::min(__n, __sz - __pos));
26650b57cec5SDimitry Andric}
26660b57cec5SDimitry Andric
26670b57cec5SDimitry Andric
26680b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
2669*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
26700b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>&
26715ffd83dbSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__assign_external(const value_type* __s) {
26725ffd83dbSDimitry Andric  return __assign_external(__s, traits_type::length(__s));
26735ffd83dbSDimitry Andric}
26745ffd83dbSDimitry Andric
26755ffd83dbSDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
2676*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
26775ffd83dbSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>&
26780b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s)
26790b57cec5SDimitry Andric{
26800b57cec5SDimitry Andric    _LIBCPP_ASSERT(__s != nullptr, "string::assign received nullptr");
2681349cc55cSDimitry Andric    return __builtin_constant_p(*__s)
268204eeddc0SDimitry Andric               ? (__fits_in_sso(traits_type::length(__s))
26835ffd83dbSDimitry Andric                      ? __assign_short(__s, traits_type::length(__s))
26845ffd83dbSDimitry Andric                      : __assign_external(__s, traits_type::length(__s)))
26855ffd83dbSDimitry Andric               : __assign_external(__s);
26860b57cec5SDimitry Andric}
26870b57cec5SDimitry Andric// append
26880b57cec5SDimitry Andric
26890b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
2690*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
26910b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>&
26920b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n)
26930b57cec5SDimitry Andric{
26940b57cec5SDimitry Andric    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::append received nullptr");
26950b57cec5SDimitry Andric    size_type __cap = capacity();
26960b57cec5SDimitry Andric    size_type __sz = size();
26970b57cec5SDimitry Andric    if (__cap - __sz >= __n)
26980b57cec5SDimitry Andric    {
26990b57cec5SDimitry Andric        if (__n)
27000b57cec5SDimitry Andric        {
270181ad6265SDimitry Andric            value_type* __p = std::__to_address(__get_pointer());
27020b57cec5SDimitry Andric            traits_type::copy(__p + __sz, __s, __n);
27030b57cec5SDimitry Andric            __sz += __n;
27040b57cec5SDimitry Andric            __set_size(__sz);
27050b57cec5SDimitry Andric            traits_type::assign(__p[__sz], value_type());
27060b57cec5SDimitry Andric        }
27070b57cec5SDimitry Andric    }
27080b57cec5SDimitry Andric    else
27090b57cec5SDimitry Andric        __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __sz, 0, __n, __s);
27100b57cec5SDimitry Andric    return *this;
27110b57cec5SDimitry Andric}
27120b57cec5SDimitry Andric
27130b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
2714*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
27150b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>&
27160b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c)
27170b57cec5SDimitry Andric{
27180b57cec5SDimitry Andric    if (__n)
27190b57cec5SDimitry Andric    {
27200b57cec5SDimitry Andric        size_type __cap = capacity();
27210b57cec5SDimitry Andric        size_type __sz = size();
27220b57cec5SDimitry Andric        if (__cap - __sz < __n)
27230b57cec5SDimitry Andric            __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
27240b57cec5SDimitry Andric        pointer __p = __get_pointer();
272581ad6265SDimitry Andric        traits_type::assign(std::__to_address(__p) + __sz, __n, __c);
27260b57cec5SDimitry Andric        __sz += __n;
27270b57cec5SDimitry Andric        __set_size(__sz);
27280b57cec5SDimitry Andric        traits_type::assign(__p[__sz], value_type());
27290b57cec5SDimitry Andric    }
27300b57cec5SDimitry Andric    return *this;
27310b57cec5SDimitry Andric}
27320b57cec5SDimitry Andric
27330b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
2734*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 inline void
27350b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n)
27360b57cec5SDimitry Andric{
27370b57cec5SDimitry Andric    if (__n)
27380b57cec5SDimitry Andric    {
27390b57cec5SDimitry Andric        size_type __cap = capacity();
27400b57cec5SDimitry Andric        size_type __sz = size();
27410b57cec5SDimitry Andric        if (__cap - __sz < __n)
27420b57cec5SDimitry Andric            __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
27430b57cec5SDimitry Andric        pointer __p = __get_pointer();
27440b57cec5SDimitry Andric        __sz += __n;
27450b57cec5SDimitry Andric        __set_size(__sz);
27460b57cec5SDimitry Andric        traits_type::assign(__p[__sz], value_type());
27470b57cec5SDimitry Andric    }
27480b57cec5SDimitry Andric}
27490b57cec5SDimitry Andric
27500b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
2751*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
27520b57cec5SDimitry Andricvoid
27530b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c)
27540b57cec5SDimitry Andric{
27550b57cec5SDimitry Andric    bool __is_short = !__is_long();
27560b57cec5SDimitry Andric    size_type __cap;
27570b57cec5SDimitry Andric    size_type __sz;
27580b57cec5SDimitry Andric    if (__is_short)
27590b57cec5SDimitry Andric    {
27600b57cec5SDimitry Andric        __cap = __min_cap - 1;
27610b57cec5SDimitry Andric        __sz = __get_short_size();
27620b57cec5SDimitry Andric    }
27630b57cec5SDimitry Andric    else
27640b57cec5SDimitry Andric    {
27650b57cec5SDimitry Andric        __cap = __get_long_cap() - 1;
27660b57cec5SDimitry Andric        __sz = __get_long_size();
27670b57cec5SDimitry Andric    }
27680b57cec5SDimitry Andric    if (__sz == __cap)
27690b57cec5SDimitry Andric    {
27700b57cec5SDimitry Andric        __grow_by(__cap, 1, __sz, __sz, 0);
2771349cc55cSDimitry Andric        __is_short = false; // the string is always long after __grow_by
27720b57cec5SDimitry Andric    }
277381ad6265SDimitry Andric    pointer __p = __get_pointer();
27740b57cec5SDimitry Andric    if (__is_short)
27750b57cec5SDimitry Andric    {
27760b57cec5SDimitry Andric        __p = __get_short_pointer() + __sz;
27770b57cec5SDimitry Andric        __set_short_size(__sz+1);
27780b57cec5SDimitry Andric    }
27790b57cec5SDimitry Andric    else
27800b57cec5SDimitry Andric    {
27810b57cec5SDimitry Andric        __p = __get_long_pointer() + __sz;
27820b57cec5SDimitry Andric        __set_long_size(__sz+1);
27830b57cec5SDimitry Andric    }
27840b57cec5SDimitry Andric    traits_type::assign(*__p, __c);
27850b57cec5SDimitry Andric    traits_type::assign(*++__p, value_type());
27860b57cec5SDimitry Andric}
27870b57cec5SDimitry Andric
27880b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
27890b57cec5SDimitry Andrictemplate<class _ForwardIterator>
2790*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
2791349cc55cSDimitry Andric__enable_if_t
2792fe6060f1SDimitry Andric<
2793fe6060f1SDimitry Andric    __is_cpp17_forward_iterator<_ForwardIterator>::value,
27940b57cec5SDimitry Andric    basic_string<_CharT, _Traits, _Allocator>&
2795fe6060f1SDimitry Andric>
2796fe6060f1SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::append(
27970b57cec5SDimitry Andric    _ForwardIterator __first, _ForwardIterator __last)
27980b57cec5SDimitry Andric{
27990b57cec5SDimitry Andric    size_type __sz = size();
28000b57cec5SDimitry Andric    size_type __cap = capacity();
280181ad6265SDimitry Andric    size_type __n = static_cast<size_type>(std::distance(__first, __last));
28020b57cec5SDimitry Andric    if (__n)
28030b57cec5SDimitry Andric    {
2804fe6060f1SDimitry Andric        if (__string_is_trivial_iterator<_ForwardIterator>::value &&
2805fe6060f1SDimitry Andric            !__addr_in_range(*__first))
28060b57cec5SDimitry Andric        {
28070b57cec5SDimitry Andric            if (__cap - __sz < __n)
28080b57cec5SDimitry Andric                __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
28090b57cec5SDimitry Andric            pointer __p = __get_pointer() + __sz;
2810349cc55cSDimitry Andric            for (; __first != __last; ++__p, (void) ++__first)
28110b57cec5SDimitry Andric                traits_type::assign(*__p, *__first);
28120b57cec5SDimitry Andric            traits_type::assign(*__p, value_type());
28130b57cec5SDimitry Andric            __set_size(__sz + __n);
28140b57cec5SDimitry Andric        }
2815fe6060f1SDimitry Andric        else
2816fe6060f1SDimitry Andric        {
2817fe6060f1SDimitry Andric            const basic_string __temp(__first, __last, __alloc());
2818fe6060f1SDimitry Andric            append(__temp.data(), __temp.size());
2819fe6060f1SDimitry Andric        }
28200b57cec5SDimitry Andric    }
28210b57cec5SDimitry Andric    return *this;
28220b57cec5SDimitry Andric}
28230b57cec5SDimitry Andric
28240b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
2825*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
28260b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>&
28270b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, size_type __pos, size_type __n)
28280b57cec5SDimitry Andric{
28290b57cec5SDimitry Andric    size_type __sz = __str.size();
28300b57cec5SDimitry Andric    if (__pos > __sz)
283104eeddc0SDimitry Andric        __throw_out_of_range();
283281ad6265SDimitry Andric    return append(__str.data() + __pos, std::min(__n, __sz - __pos));
28330b57cec5SDimitry Andric}
28340b57cec5SDimitry Andric
28350b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
28360b57cec5SDimitry Andrictemplate <class _Tp>
2837*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
2838349cc55cSDimitry Andric    __enable_if_t
28390b57cec5SDimitry Andric    <
28405ffd83dbSDimitry Andric        __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value  && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
28410b57cec5SDimitry Andric        basic_string<_CharT, _Traits, _Allocator>&
28425ffd83dbSDimitry Andric    >
28430b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::append(const _Tp & __t, size_type __pos, size_type __n)
28440b57cec5SDimitry Andric{
28450b57cec5SDimitry Andric    __self_view __sv = __t;
28460b57cec5SDimitry Andric    size_type __sz = __sv.size();
28470b57cec5SDimitry Andric    if (__pos > __sz)
284804eeddc0SDimitry Andric        __throw_out_of_range();
284981ad6265SDimitry Andric    return append(__sv.data() + __pos, std::min(__n, __sz - __pos));
28500b57cec5SDimitry Andric}
28510b57cec5SDimitry Andric
28520b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
2853*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
28540b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>&
28550b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s)
28560b57cec5SDimitry Andric{
28570b57cec5SDimitry Andric    _LIBCPP_ASSERT(__s != nullptr, "string::append received nullptr");
28580b57cec5SDimitry Andric    return append(__s, traits_type::length(__s));
28590b57cec5SDimitry Andric}
28600b57cec5SDimitry Andric
28610b57cec5SDimitry Andric// insert
28620b57cec5SDimitry Andric
28630b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
2864*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
28650b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>&
28660b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n)
28670b57cec5SDimitry Andric{
28680b57cec5SDimitry Andric    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::insert received nullptr");
28690b57cec5SDimitry Andric    size_type __sz = size();
28700b57cec5SDimitry Andric    if (__pos > __sz)
287104eeddc0SDimitry Andric        __throw_out_of_range();
28720b57cec5SDimitry Andric    size_type __cap = capacity();
287381ad6265SDimitry Andric    if (__libcpp_is_constant_evaluated()) {
287481ad6265SDimitry Andric        if (__cap - __sz >= __n)
287581ad6265SDimitry Andric            __grow_by_and_replace(__cap, 0, __sz, __pos, 0, __n, __s);
287681ad6265SDimitry Andric        else
287781ad6265SDimitry Andric            __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s);
287881ad6265SDimitry Andric        return *this;
287981ad6265SDimitry Andric    }
28800b57cec5SDimitry Andric    if (__cap - __sz >= __n)
28810b57cec5SDimitry Andric    {
28820b57cec5SDimitry Andric        if (__n)
28830b57cec5SDimitry Andric        {
288481ad6265SDimitry Andric            value_type* __p = std::__to_address(__get_pointer());
28850b57cec5SDimitry Andric            size_type __n_move = __sz - __pos;
28860b57cec5SDimitry Andric            if (__n_move != 0)
28870b57cec5SDimitry Andric            {
28880b57cec5SDimitry Andric                if (__p + __pos <= __s && __s < __p + __sz)
28890b57cec5SDimitry Andric                    __s += __n;
28900b57cec5SDimitry Andric                traits_type::move(__p + __pos + __n, __p + __pos, __n_move);
28910b57cec5SDimitry Andric            }
28920b57cec5SDimitry Andric            traits_type::move(__p + __pos, __s, __n);
28930b57cec5SDimitry Andric            __sz += __n;
28940b57cec5SDimitry Andric            __set_size(__sz);
28950b57cec5SDimitry Andric            traits_type::assign(__p[__sz], value_type());
28960b57cec5SDimitry Andric        }
28970b57cec5SDimitry Andric    }
28980b57cec5SDimitry Andric    else
28990b57cec5SDimitry Andric        __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s);
29000b57cec5SDimitry Andric    return *this;
29010b57cec5SDimitry Andric}
29020b57cec5SDimitry Andric
29030b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
2904*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
29050b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>&
29060b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n, value_type __c)
29070b57cec5SDimitry Andric{
29080b57cec5SDimitry Andric    size_type __sz = size();
29090b57cec5SDimitry Andric    if (__pos > __sz)
291004eeddc0SDimitry Andric        __throw_out_of_range();
29110b57cec5SDimitry Andric    if (__n)
29120b57cec5SDimitry Andric    {
29130b57cec5SDimitry Andric        size_type __cap = capacity();
29140b57cec5SDimitry Andric        value_type* __p;
29150b57cec5SDimitry Andric        if (__cap - __sz >= __n)
29160b57cec5SDimitry Andric        {
291781ad6265SDimitry Andric            __p = std::__to_address(__get_pointer());
29180b57cec5SDimitry Andric            size_type __n_move = __sz - __pos;
29190b57cec5SDimitry Andric            if (__n_move != 0)
29200b57cec5SDimitry Andric                traits_type::move(__p + __pos + __n, __p + __pos, __n_move);
29210b57cec5SDimitry Andric        }
29220b57cec5SDimitry Andric        else
29230b57cec5SDimitry Andric        {
29240b57cec5SDimitry Andric            __grow_by(__cap, __sz + __n - __cap, __sz, __pos, 0, __n);
292581ad6265SDimitry Andric            __p = std::__to_address(__get_long_pointer());
29260b57cec5SDimitry Andric        }
29270b57cec5SDimitry Andric        traits_type::assign(__p + __pos, __n, __c);
29280b57cec5SDimitry Andric        __sz += __n;
29290b57cec5SDimitry Andric        __set_size(__sz);
29300b57cec5SDimitry Andric        traits_type::assign(__p[__sz], value_type());
29310b57cec5SDimitry Andric    }
29320b57cec5SDimitry Andric    return *this;
29330b57cec5SDimitry Andric}
29340b57cec5SDimitry Andric
29350b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
29360b57cec5SDimitry Andrictemplate<class _InputIterator>
2937*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
2938349cc55cSDimitry Andric__enable_if_t
29390b57cec5SDimitry Andric<
2940fe6060f1SDimitry Andric   __is_exactly_cpp17_input_iterator<_InputIterator>::value,
29410b57cec5SDimitry Andric   typename basic_string<_CharT, _Traits, _Allocator>::iterator
29425ffd83dbSDimitry Andric>
29430b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last)
29440b57cec5SDimitry Andric{
29450eae32dcSDimitry Andric  _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
29460b57cec5SDimitry Andric                       "string::insert(iterator, range) called with an iterator not"
29470b57cec5SDimitry Andric                       " referring to this string");
29480b57cec5SDimitry Andric  const basic_string __temp(__first, __last, __alloc());
29490b57cec5SDimitry Andric  return insert(__pos, __temp.data(), __temp.data() + __temp.size());
29500b57cec5SDimitry Andric}
29510b57cec5SDimitry Andric
29520b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
29530b57cec5SDimitry Andrictemplate<class _ForwardIterator>
2954*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
2955349cc55cSDimitry Andric__enable_if_t
29560b57cec5SDimitry Andric<
2957fe6060f1SDimitry Andric    __is_cpp17_forward_iterator<_ForwardIterator>::value,
29580b57cec5SDimitry Andric    typename basic_string<_CharT, _Traits, _Allocator>::iterator
29595ffd83dbSDimitry Andric>
29600b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last)
29610b57cec5SDimitry Andric{
29620eae32dcSDimitry Andric    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
296381ad6265SDimitry Andric                         "string::insert(iterator, range) called with an iterator not referring to this string");
29640eae32dcSDimitry Andric
29650b57cec5SDimitry Andric    size_type __ip = static_cast<size_type>(__pos - begin());
296681ad6265SDimitry Andric    size_type __n = static_cast<size_type>(std::distance(__first, __last));
296781ad6265SDimitry Andric    if (__n == 0)
296881ad6265SDimitry Andric        return begin() + __ip;
296981ad6265SDimitry Andric
297081ad6265SDimitry Andric    if (__string_is_trivial_iterator<_ForwardIterator>::value && !__addr_in_range(*__first))
29710b57cec5SDimitry Andric    {
297281ad6265SDimitry Andric        return __insert_from_safe_copy(__n, __ip, __first, __last);
29730b57cec5SDimitry Andric    }
2974fe6060f1SDimitry Andric    else
2975fe6060f1SDimitry Andric    {
2976fe6060f1SDimitry Andric        const basic_string __temp(__first, __last, __alloc());
297781ad6265SDimitry Andric        return __insert_from_safe_copy(__n, __ip, __temp.begin(), __temp.end());
2978fe6060f1SDimitry Andric    }
2979fe6060f1SDimitry Andric}
29800b57cec5SDimitry Andric
29810b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
2982*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
29830b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>&
29840b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str,
29850b57cec5SDimitry Andric                                                  size_type __pos2, size_type __n)
29860b57cec5SDimitry Andric{
29870b57cec5SDimitry Andric    size_type __str_sz = __str.size();
29880b57cec5SDimitry Andric    if (__pos2 > __str_sz)
298904eeddc0SDimitry Andric        __throw_out_of_range();
299081ad6265SDimitry Andric    return insert(__pos1, __str.data() + __pos2, std::min(__n, __str_sz - __pos2));
29910b57cec5SDimitry Andric}
29920b57cec5SDimitry Andric
29930b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
29940b57cec5SDimitry Andrictemplate <class _Tp>
2995*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
2996349cc55cSDimitry Andric__enable_if_t
29970b57cec5SDimitry Andric<
29985ffd83dbSDimitry Andric    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value  && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
29990b57cec5SDimitry Andric    basic_string<_CharT, _Traits, _Allocator>&
30005ffd83dbSDimitry Andric>
30010b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& __t,
30020b57cec5SDimitry Andric                                                  size_type __pos2, size_type __n)
30030b57cec5SDimitry Andric{
30040b57cec5SDimitry Andric    __self_view __sv = __t;
30050b57cec5SDimitry Andric    size_type __str_sz = __sv.size();
30060b57cec5SDimitry Andric    if (__pos2 > __str_sz)
300704eeddc0SDimitry Andric        __throw_out_of_range();
300881ad6265SDimitry Andric    return insert(__pos1, __sv.data() + __pos2, std::min(__n, __str_sz - __pos2));
30090b57cec5SDimitry Andric}
30100b57cec5SDimitry Andric
30110b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
3012*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
30130b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>&
30140b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s)
30150b57cec5SDimitry Andric{
30160b57cec5SDimitry Andric    _LIBCPP_ASSERT(__s != nullptr, "string::insert received nullptr");
30170b57cec5SDimitry Andric    return insert(__pos, __s, traits_type::length(__s));
30180b57cec5SDimitry Andric}
30190b57cec5SDimitry Andric
30200b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
3021*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
30220b57cec5SDimitry Andrictypename basic_string<_CharT, _Traits, _Allocator>::iterator
30230b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c)
30240b57cec5SDimitry Andric{
3025d56accc7SDimitry Andric    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
3026d56accc7SDimitry Andric                         "string::insert(iterator, character) called with an iterator not"
3027d56accc7SDimitry Andric                         " referring to this string");
3028d56accc7SDimitry Andric
30290b57cec5SDimitry Andric    size_type __ip = static_cast<size_type>(__pos - begin());
30300b57cec5SDimitry Andric    size_type __sz = size();
30310b57cec5SDimitry Andric    size_type __cap = capacity();
30320b57cec5SDimitry Andric    value_type* __p;
30330b57cec5SDimitry Andric    if (__cap == __sz)
30340b57cec5SDimitry Andric    {
30350b57cec5SDimitry Andric        __grow_by(__cap, 1, __sz, __ip, 0, 1);
303681ad6265SDimitry Andric        __p = std::__to_address(__get_long_pointer());
30370b57cec5SDimitry Andric    }
30380b57cec5SDimitry Andric    else
30390b57cec5SDimitry Andric    {
304081ad6265SDimitry Andric        __p = std::__to_address(__get_pointer());
30410b57cec5SDimitry Andric        size_type __n_move = __sz - __ip;
30420b57cec5SDimitry Andric        if (__n_move != 0)
30430b57cec5SDimitry Andric            traits_type::move(__p + __ip + 1, __p + __ip, __n_move);
30440b57cec5SDimitry Andric    }
30450b57cec5SDimitry Andric    traits_type::assign(__p[__ip], __c);
30460b57cec5SDimitry Andric    traits_type::assign(__p[++__sz], value_type());
30470b57cec5SDimitry Andric    __set_size(__sz);
30480b57cec5SDimitry Andric    return begin() + static_cast<difference_type>(__ip);
30490b57cec5SDimitry Andric}
30500b57cec5SDimitry Andric
30510b57cec5SDimitry Andric// replace
30520b57cec5SDimitry Andric
30530b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
3054*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
30550b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>&
30560b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2)
30570b57cec5SDimitry Andric    _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
30580b57cec5SDimitry Andric{
30590b57cec5SDimitry Andric    _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::replace received nullptr");
30600b57cec5SDimitry Andric    size_type __sz = size();
30610b57cec5SDimitry Andric    if (__pos > __sz)
306204eeddc0SDimitry Andric        __throw_out_of_range();
306381ad6265SDimitry Andric    __n1 = std::min(__n1, __sz - __pos);
30640b57cec5SDimitry Andric    size_type __cap = capacity();
30650b57cec5SDimitry Andric    if (__cap - __sz + __n1 >= __n2)
30660b57cec5SDimitry Andric    {
306781ad6265SDimitry Andric        if (__libcpp_is_constant_evaluated()) {
306881ad6265SDimitry Andric            __grow_by_and_replace(__cap, 0, __sz, __pos, __n1, __n2, __s);
306981ad6265SDimitry Andric            return *this;
307081ad6265SDimitry Andric        }
307181ad6265SDimitry Andric        value_type* __p = std::__to_address(__get_pointer());
30720b57cec5SDimitry Andric        if (__n1 != __n2)
30730b57cec5SDimitry Andric        {
30740b57cec5SDimitry Andric            size_type __n_move = __sz - __pos - __n1;
30750b57cec5SDimitry Andric            if (__n_move != 0)
30760b57cec5SDimitry Andric            {
30770b57cec5SDimitry Andric                if (__n1 > __n2)
30780b57cec5SDimitry Andric                {
30790b57cec5SDimitry Andric                    traits_type::move(__p + __pos, __s, __n2);
30800b57cec5SDimitry Andric                    traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
30810eae32dcSDimitry Andric                    return __null_terminate_at(__p, __sz + (__n2 - __n1));
30820b57cec5SDimitry Andric                }
30830b57cec5SDimitry Andric                if (__p + __pos < __s && __s < __p + __sz)
30840b57cec5SDimitry Andric                {
30850b57cec5SDimitry Andric                    if (__p + __pos + __n1 <= __s)
30860b57cec5SDimitry Andric                        __s += __n2 - __n1;
30870b57cec5SDimitry Andric                    else // __p + __pos < __s < __p + __pos + __n1
30880b57cec5SDimitry Andric                    {
30890b57cec5SDimitry Andric                        traits_type::move(__p + __pos, __s, __n1);
30900b57cec5SDimitry Andric                        __pos += __n1;
30910b57cec5SDimitry Andric                        __s += __n2;
30920b57cec5SDimitry Andric                        __n2 -= __n1;
30930b57cec5SDimitry Andric                        __n1 = 0;
30940b57cec5SDimitry Andric                    }
30950b57cec5SDimitry Andric                }
30960b57cec5SDimitry Andric                traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
30970b57cec5SDimitry Andric            }
30980b57cec5SDimitry Andric        }
30990b57cec5SDimitry Andric        traits_type::move(__p + __pos, __s, __n2);
31000eae32dcSDimitry Andric        return __null_terminate_at(__p, __sz + (__n2 - __n1));
31010b57cec5SDimitry Andric    }
31020b57cec5SDimitry Andric    else
31030b57cec5SDimitry Andric        __grow_by_and_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2, __s);
31040b57cec5SDimitry Andric    return *this;
31050b57cec5SDimitry Andric}
31060b57cec5SDimitry Andric
31070b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
3108*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
31090b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>&
31100b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, size_type __n2, value_type __c)
31110b57cec5SDimitry Andric{
31120b57cec5SDimitry Andric    size_type __sz = size();
31130b57cec5SDimitry Andric    if (__pos > __sz)
311404eeddc0SDimitry Andric        __throw_out_of_range();
311581ad6265SDimitry Andric    __n1 = std::min(__n1, __sz - __pos);
31160b57cec5SDimitry Andric    size_type __cap = capacity();
31170b57cec5SDimitry Andric    value_type* __p;
31180b57cec5SDimitry Andric    if (__cap - __sz + __n1 >= __n2)
31190b57cec5SDimitry Andric    {
312081ad6265SDimitry Andric        __p = std::__to_address(__get_pointer());
31210b57cec5SDimitry Andric        if (__n1 != __n2)
31220b57cec5SDimitry Andric        {
31230b57cec5SDimitry Andric            size_type __n_move = __sz - __pos - __n1;
31240b57cec5SDimitry Andric            if (__n_move != 0)
31250b57cec5SDimitry Andric                traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
31260b57cec5SDimitry Andric        }
31270b57cec5SDimitry Andric    }
31280b57cec5SDimitry Andric    else
31290b57cec5SDimitry Andric    {
31300b57cec5SDimitry Andric        __grow_by(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2);
313181ad6265SDimitry Andric        __p = std::__to_address(__get_long_pointer());
31320b57cec5SDimitry Andric    }
31330b57cec5SDimitry Andric    traits_type::assign(__p + __pos, __n2, __c);
31340eae32dcSDimitry Andric    return __null_terminate_at(__p, __sz - (__n1 - __n2));
31350b57cec5SDimitry Andric}
31360b57cec5SDimitry Andric
31370b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
31380b57cec5SDimitry Andrictemplate<class _InputIterator>
3139*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
3140349cc55cSDimitry Andric__enable_if_t
31410b57cec5SDimitry Andric<
3142480093f4SDimitry Andric    __is_cpp17_input_iterator<_InputIterator>::value,
31430b57cec5SDimitry Andric    basic_string<_CharT, _Traits, _Allocator>&
31445ffd83dbSDimitry Andric>
31450b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2,
31460b57cec5SDimitry Andric                                                   _InputIterator __j1, _InputIterator __j2)
31470b57cec5SDimitry Andric{
31480b57cec5SDimitry Andric    const basic_string __temp(__j1, __j2, __alloc());
314904eeddc0SDimitry Andric    return replace(__i1, __i2, __temp);
31500b57cec5SDimitry Andric}
31510b57cec5SDimitry Andric
31520b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
3153*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
31540b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>&
31550b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str,
31560b57cec5SDimitry Andric                                                   size_type __pos2, size_type __n2)
31570b57cec5SDimitry Andric{
31580b57cec5SDimitry Andric    size_type __str_sz = __str.size();
31590b57cec5SDimitry Andric    if (__pos2 > __str_sz)
316004eeddc0SDimitry Andric        __throw_out_of_range();
316181ad6265SDimitry Andric    return replace(__pos1, __n1, __str.data() + __pos2, std::min(__n2, __str_sz - __pos2));
31620b57cec5SDimitry Andric}
31630b57cec5SDimitry Andric
31640b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
31650b57cec5SDimitry Andrictemplate <class _Tp>
3166*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
3167349cc55cSDimitry Andric__enable_if_t
31680b57cec5SDimitry Andric<
31695ffd83dbSDimitry Andric    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
31700b57cec5SDimitry Andric    basic_string<_CharT, _Traits, _Allocator>&
31715ffd83dbSDimitry Andric>
31720b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const _Tp& __t,
31730b57cec5SDimitry Andric                                                   size_type __pos2, size_type __n2)
31740b57cec5SDimitry Andric{
31750b57cec5SDimitry Andric    __self_view __sv = __t;
31760b57cec5SDimitry Andric    size_type __str_sz = __sv.size();
31770b57cec5SDimitry Andric    if (__pos2 > __str_sz)
317804eeddc0SDimitry Andric        __throw_out_of_range();
317981ad6265SDimitry Andric    return replace(__pos1, __n1, __sv.data() + __pos2, std::min(__n2, __str_sz - __pos2));
31800b57cec5SDimitry Andric}
31810b57cec5SDimitry Andric
31820b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
3183*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
31840b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>&
31850b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s)
31860b57cec5SDimitry Andric{
31870b57cec5SDimitry Andric    _LIBCPP_ASSERT(__s != nullptr, "string::replace received nullptr");
31880b57cec5SDimitry Andric    return replace(__pos, __n1, __s, traits_type::length(__s));
31890b57cec5SDimitry Andric}
31900b57cec5SDimitry Andric
31910b57cec5SDimitry Andric// erase
31920b57cec5SDimitry Andric
31935ffd83dbSDimitry Andric// 'externally instantiated' erase() implementation, called when __n != npos.
31945ffd83dbSDimitry Andric// Does not check __pos against size()
31950b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
3196*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
31975ffd83dbSDimitry Andricvoid
31985ffd83dbSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move(
31995ffd83dbSDimitry Andric    size_type __pos, size_type __n)
32000b57cec5SDimitry Andric{
32010b57cec5SDimitry Andric    if (__n)
32020b57cec5SDimitry Andric    {
32035ffd83dbSDimitry Andric        size_type __sz = size();
320481ad6265SDimitry Andric        value_type* __p = std::__to_address(__get_pointer());
320581ad6265SDimitry Andric        __n = std::min(__n, __sz - __pos);
32060b57cec5SDimitry Andric        size_type __n_move = __sz - __pos - __n;
32070b57cec5SDimitry Andric        if (__n_move != 0)
32080b57cec5SDimitry Andric            traits_type::move(__p + __pos, __p + __pos + __n, __n_move);
32090eae32dcSDimitry Andric        __null_terminate_at(__p, __sz - __n);
32100b57cec5SDimitry Andric    }
32115ffd83dbSDimitry Andric}
32125ffd83dbSDimitry Andric
32135ffd83dbSDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
3214*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
32155ffd83dbSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>&
32165ffd83dbSDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos,
32175ffd83dbSDimitry Andric                                                 size_type __n) {
321804eeddc0SDimitry Andric  if (__pos > size())
321904eeddc0SDimitry Andric    __throw_out_of_range();
32205ffd83dbSDimitry Andric  if (__n == npos) {
32215ffd83dbSDimitry Andric    __erase_to_end(__pos);
32225ffd83dbSDimitry Andric  } else {
32235ffd83dbSDimitry Andric    __erase_external_with_move(__pos, __n);
32245ffd83dbSDimitry Andric  }
32250b57cec5SDimitry Andric  return *this;
32260b57cec5SDimitry Andric}
32270b57cec5SDimitry Andric
32280b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
3229*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
32300b57cec5SDimitry Andrictypename basic_string<_CharT, _Traits, _Allocator>::iterator
32310b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos)
32320b57cec5SDimitry Andric{
32330eae32dcSDimitry Andric  _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
32340b57cec5SDimitry Andric                       "string::erase(iterator) called with an iterator not"
32350b57cec5SDimitry Andric                       " referring to this string");
32360eae32dcSDimitry Andric
32370eae32dcSDimitry Andric  _LIBCPP_ASSERT(__pos != end(), "string::erase(iterator) called with a non-dereferenceable iterator");
32380b57cec5SDimitry Andric  iterator __b = begin();
32390b57cec5SDimitry Andric  size_type __r = static_cast<size_type>(__pos - __b);
32400b57cec5SDimitry Andric  erase(__r, 1);
32410b57cec5SDimitry Andric  return __b + static_cast<difference_type>(__r);
32420b57cec5SDimitry Andric}
32430b57cec5SDimitry Andric
32440b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
3245*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
32460b57cec5SDimitry Andrictypename basic_string<_CharT, _Traits, _Allocator>::iterator
32470b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last)
32480b57cec5SDimitry Andric{
32490eae32dcSDimitry Andric  _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this,
32500b57cec5SDimitry Andric                       "string::erase(iterator,  iterator) called with an iterator not"
32510b57cec5SDimitry Andric                       " referring to this string");
32520eae32dcSDimitry Andric
32530b57cec5SDimitry Andric  _LIBCPP_ASSERT(__first <= __last, "string::erase(first, last) called with invalid range");
32540b57cec5SDimitry Andric  iterator __b = begin();
32550b57cec5SDimitry Andric  size_type __r = static_cast<size_type>(__first - __b);
32560b57cec5SDimitry Andric  erase(__r, static_cast<size_type>(__last - __first));
32570b57cec5SDimitry Andric  return __b + static_cast<difference_type>(__r);
32580b57cec5SDimitry Andric}
32590b57cec5SDimitry Andric
32600b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
3261*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
32620b57cec5SDimitry Andricvoid
32630b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::pop_back()
32640b57cec5SDimitry Andric{
32650b57cec5SDimitry Andric    _LIBCPP_ASSERT(!empty(), "string::pop_back(): string is already empty");
32660eae32dcSDimitry Andric    __erase_to_end(size() - 1);
32670b57cec5SDimitry Andric}
32680b57cec5SDimitry Andric
32690b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
3270*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
32710b57cec5SDimitry Andricvoid
32720b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT
32730b57cec5SDimitry Andric{
327481ad6265SDimitry Andric    std::__debug_db_invalidate_all(this);
32750b57cec5SDimitry Andric    if (__is_long())
32760b57cec5SDimitry Andric    {
32770b57cec5SDimitry Andric        traits_type::assign(*__get_long_pointer(), value_type());
32780b57cec5SDimitry Andric        __set_long_size(0);
32790b57cec5SDimitry Andric    }
32800b57cec5SDimitry Andric    else
32810b57cec5SDimitry Andric    {
32820b57cec5SDimitry Andric        traits_type::assign(*__get_short_pointer(), value_type());
32830b57cec5SDimitry Andric        __set_short_size(0);
32840b57cec5SDimitry Andric    }
32850b57cec5SDimitry Andric}
32860b57cec5SDimitry Andric
32870b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
3288*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
32890b57cec5SDimitry Andricvoid
32900b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c)
32910b57cec5SDimitry Andric{
32920b57cec5SDimitry Andric    size_type __sz = size();
32930b57cec5SDimitry Andric    if (__n > __sz)
32940b57cec5SDimitry Andric        append(__n - __sz, __c);
32950b57cec5SDimitry Andric    else
32960b57cec5SDimitry Andric        __erase_to_end(__n);
32970b57cec5SDimitry Andric}
32980b57cec5SDimitry Andric
32990b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
3300*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 inline void
33010b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__resize_default_init(size_type __n)
33020b57cec5SDimitry Andric{
33030b57cec5SDimitry Andric    size_type __sz = size();
33040b57cec5SDimitry Andric    if (__n > __sz) {
33050b57cec5SDimitry Andric       __append_default_init(__n - __sz);
33060b57cec5SDimitry Andric    } else
33070b57cec5SDimitry Andric        __erase_to_end(__n);
33080b57cec5SDimitry Andric}
33090b57cec5SDimitry Andric
33100b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
3311*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
33120b57cec5SDimitry Andricvoid
3313e8d8bef9SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacity)
33140b57cec5SDimitry Andric{
3315e8d8bef9SDimitry Andric    if (__requested_capacity > max_size())
331604eeddc0SDimitry Andric        __throw_length_error();
3317e8d8bef9SDimitry Andric
331804eeddc0SDimitry Andric    // Make sure reserve(n) never shrinks. This is technically only required in C++20
331904eeddc0SDimitry Andric    // and later (since P0966R1), however we provide consistent behavior in all Standard
332004eeddc0SDimitry Andric    // modes because this function is instantiated in the shared library.
332104eeddc0SDimitry Andric    if (__requested_capacity <= capacity())
332204eeddc0SDimitry Andric        return;
3323e8d8bef9SDimitry Andric
332481ad6265SDimitry Andric    size_type __target_capacity = std::max(__requested_capacity, size());
3325e8d8bef9SDimitry Andric    __target_capacity = __recommend(__target_capacity);
3326e8d8bef9SDimitry Andric    if (__target_capacity == capacity()) return;
3327e8d8bef9SDimitry Andric
3328e8d8bef9SDimitry Andric    __shrink_or_extend(__target_capacity);
3329e8d8bef9SDimitry Andric}
3330e8d8bef9SDimitry Andric
3331e8d8bef9SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
3332*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
3333e8d8bef9SDimitry Andricvoid
3334e8d8bef9SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::shrink_to_fit() _NOEXCEPT
3335e8d8bef9SDimitry Andric{
3336e8d8bef9SDimitry Andric    size_type __target_capacity = __recommend(size());
3337e8d8bef9SDimitry Andric    if (__target_capacity == capacity()) return;
3338e8d8bef9SDimitry Andric
3339e8d8bef9SDimitry Andric    __shrink_or_extend(__target_capacity);
3340e8d8bef9SDimitry Andric}
3341e8d8bef9SDimitry Andric
3342e8d8bef9SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
3343*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
3344e8d8bef9SDimitry Andricvoid
3345e8d8bef9SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target_capacity)
3346e8d8bef9SDimitry Andric{
33470b57cec5SDimitry Andric    size_type __cap = capacity();
33480b57cec5SDimitry Andric    size_type __sz = size();
3349e8d8bef9SDimitry Andric
33500b57cec5SDimitry Andric    pointer __new_data, __p;
33510b57cec5SDimitry Andric    bool __was_long, __now_long;
335281ad6265SDimitry Andric    if (__fits_in_sso(__target_capacity))
33530b57cec5SDimitry Andric    {
33540b57cec5SDimitry Andric        __was_long = true;
33550b57cec5SDimitry Andric        __now_long = false;
33560b57cec5SDimitry Andric        __new_data = __get_short_pointer();
33570b57cec5SDimitry Andric        __p = __get_long_pointer();
33580b57cec5SDimitry Andric    }
33590b57cec5SDimitry Andric    else
33600b57cec5SDimitry Andric    {
336181ad6265SDimitry Andric        if (__target_capacity > __cap) {
336281ad6265SDimitry Andric            auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1);
336381ad6265SDimitry Andric            __new_data = __allocation.ptr;
336481ad6265SDimitry Andric            __target_capacity = __allocation.count - 1;
336581ad6265SDimitry Andric        }
33660b57cec5SDimitry Andric        else
33670b57cec5SDimitry Andric        {
33680b57cec5SDimitry Andric        #ifndef _LIBCPP_NO_EXCEPTIONS
33690b57cec5SDimitry Andric            try
33700b57cec5SDimitry Andric            {
33710b57cec5SDimitry Andric        #endif // _LIBCPP_NO_EXCEPTIONS
337281ad6265SDimitry Andric                auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1);
337381ad6265SDimitry Andric                __new_data = __allocation.ptr;
337481ad6265SDimitry Andric                __target_capacity = __allocation.count - 1;
33750b57cec5SDimitry Andric        #ifndef _LIBCPP_NO_EXCEPTIONS
33760b57cec5SDimitry Andric            }
33770b57cec5SDimitry Andric            catch (...)
33780b57cec5SDimitry Andric            {
33790b57cec5SDimitry Andric                return;
33800b57cec5SDimitry Andric            }
33810b57cec5SDimitry Andric        #else  // _LIBCPP_NO_EXCEPTIONS
33820b57cec5SDimitry Andric            if (__new_data == nullptr)
33830b57cec5SDimitry Andric                return;
33840b57cec5SDimitry Andric        #endif // _LIBCPP_NO_EXCEPTIONS
33850b57cec5SDimitry Andric        }
338681ad6265SDimitry Andric        __begin_lifetime(__new_data, __target_capacity + 1);
33870b57cec5SDimitry Andric        __now_long = true;
33880b57cec5SDimitry Andric        __was_long = __is_long();
33890b57cec5SDimitry Andric        __p = __get_pointer();
33900b57cec5SDimitry Andric    }
339181ad6265SDimitry Andric    traits_type::copy(std::__to_address(__new_data),
339281ad6265SDimitry Andric                      std::__to_address(__p), size()+1);
33930b57cec5SDimitry Andric    if (__was_long)
33940b57cec5SDimitry Andric        __alloc_traits::deallocate(__alloc(), __p, __cap+1);
33950b57cec5SDimitry Andric    if (__now_long)
33960b57cec5SDimitry Andric    {
3397e8d8bef9SDimitry Andric        __set_long_cap(__target_capacity+1);
33980b57cec5SDimitry Andric        __set_long_size(__sz);
33990b57cec5SDimitry Andric        __set_long_pointer(__new_data);
34000b57cec5SDimitry Andric    }
34010b57cec5SDimitry Andric    else
34020b57cec5SDimitry Andric        __set_short_size(__sz);
340381ad6265SDimitry Andric    std::__debug_db_invalidate_all(this);
34040b57cec5SDimitry Andric}
34050b57cec5SDimitry Andric
34060b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
3407*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
34080b57cec5SDimitry Andrictypename basic_string<_CharT, _Traits, _Allocator>::const_reference
34090b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const
34100b57cec5SDimitry Andric{
34110b57cec5SDimitry Andric    if (__n >= size())
341204eeddc0SDimitry Andric        __throw_out_of_range();
34130b57cec5SDimitry Andric    return (*this)[__n];
34140b57cec5SDimitry Andric}
34150b57cec5SDimitry Andric
34160b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
3417*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
34180b57cec5SDimitry Andrictypename basic_string<_CharT, _Traits, _Allocator>::reference
34190b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::at(size_type __n)
34200b57cec5SDimitry Andric{
34210b57cec5SDimitry Andric    if (__n >= size())
342204eeddc0SDimitry Andric        __throw_out_of_range();
34230b57cec5SDimitry Andric    return (*this)[__n];
34240b57cec5SDimitry Andric}
34250b57cec5SDimitry Andric
34260b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
3427*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
34280b57cec5SDimitry Andrictypename basic_string<_CharT, _Traits, _Allocator>::size_type
34290b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n, size_type __pos) const
34300b57cec5SDimitry Andric{
34310b57cec5SDimitry Andric    size_type __sz = size();
34320b57cec5SDimitry Andric    if (__pos > __sz)
343304eeddc0SDimitry Andric        __throw_out_of_range();
343481ad6265SDimitry Andric    size_type __rlen = std::min(__n, __sz - __pos);
34350b57cec5SDimitry Andric    traits_type::copy(__s, data() + __pos, __rlen);
34360b57cec5SDimitry Andric    return __rlen;
34370b57cec5SDimitry Andric}
34380b57cec5SDimitry Andric
34390b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
3440*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
34410b57cec5SDimitry Andricvoid
34420b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str)
34430b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14
34440b57cec5SDimitry Andric        _NOEXCEPT
34450b57cec5SDimitry Andric#else
34460b57cec5SDimitry Andric        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
34470b57cec5SDimitry Andric                    __is_nothrow_swappable<allocator_type>::value)
34480b57cec5SDimitry Andric#endif
34490b57cec5SDimitry Andric{
34500b57cec5SDimitry Andric    if (!__is_long())
345181ad6265SDimitry Andric        std::__debug_db_invalidate_all(this);
34520b57cec5SDimitry Andric    if (!__str.__is_long())
345381ad6265SDimitry Andric        std::__debug_db_invalidate_all(&__str);
345481ad6265SDimitry Andric    std::__debug_db_swap(this, &__str);
345581ad6265SDimitry Andric
34560b57cec5SDimitry Andric    _LIBCPP_ASSERT(
34570b57cec5SDimitry Andric        __alloc_traits::propagate_on_container_swap::value ||
34580b57cec5SDimitry Andric        __alloc_traits::is_always_equal::value ||
34590b57cec5SDimitry Andric        __alloc() == __str.__alloc(), "swapping non-equal allocators");
346081ad6265SDimitry Andric    std::swap(__r_.first(), __str.__r_.first());
346181ad6265SDimitry Andric    std::__swap_allocator(__alloc(), __str.__alloc());
34620b57cec5SDimitry Andric}
34630b57cec5SDimitry Andric
34640b57cec5SDimitry Andric// find
34650b57cec5SDimitry Andric
34660b57cec5SDimitry Andrictemplate <class _Traits>
34670b57cec5SDimitry Andricstruct _LIBCPP_HIDDEN __traits_eq
34680b57cec5SDimitry Andric{
34690b57cec5SDimitry Andric    typedef typename _Traits::char_type char_type;
347081ad6265SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
34710b57cec5SDimitry Andric    bool operator()(const char_type& __x, const char_type& __y) _NOEXCEPT
34720b57cec5SDimitry Andric        {return _Traits::eq(__x, __y);}
34730b57cec5SDimitry Andric};
34740b57cec5SDimitry Andric
34750b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
3476*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
34770b57cec5SDimitry Andrictypename basic_string<_CharT, _Traits, _Allocator>::size_type
34780b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
34790b57cec5SDimitry Andric                                                size_type __pos,
34800b57cec5SDimitry Andric                                                size_type __n) const _NOEXCEPT
34810b57cec5SDimitry Andric{
34820b57cec5SDimitry Andric    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find(): received nullptr");
3483*bdd1243dSDimitry Andric    return std::__str_find<value_type, size_type, traits_type, npos>
34840b57cec5SDimitry Andric        (data(), size(), __s, __pos, __n);
34850b57cec5SDimitry Andric}
34860b57cec5SDimitry Andric
34870b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
3488*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
34890b57cec5SDimitry Andrictypename basic_string<_CharT, _Traits, _Allocator>::size_type
34900b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str,
34910b57cec5SDimitry Andric                                                size_type __pos) const _NOEXCEPT
34920b57cec5SDimitry Andric{
3493*bdd1243dSDimitry Andric    return std::__str_find<value_type, size_type, traits_type, npos>
34940b57cec5SDimitry Andric        (data(), size(), __str.data(), __pos, __str.size());
34950b57cec5SDimitry Andric}
34960b57cec5SDimitry Andric
34970b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
34980b57cec5SDimitry Andrictemplate <class _Tp>
3499*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
3500349cc55cSDimitry Andric__enable_if_t
35010b57cec5SDimitry Andric<
35020b57cec5SDimitry Andric    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
35030b57cec5SDimitry Andric    typename basic_string<_CharT, _Traits, _Allocator>::size_type
35045ffd83dbSDimitry Andric>
35050b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find(const _Tp &__t,
3506fe6060f1SDimitry Andric                                                size_type __pos) const _NOEXCEPT
35070b57cec5SDimitry Andric{
35080b57cec5SDimitry Andric    __self_view __sv = __t;
3509*bdd1243dSDimitry Andric    return std::__str_find<value_type, size_type, traits_type, npos>
35100b57cec5SDimitry Andric        (data(), size(), __sv.data(), __pos, __sv.size());
35110b57cec5SDimitry Andric}
35120b57cec5SDimitry Andric
35130b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
3514*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
35150b57cec5SDimitry Andrictypename basic_string<_CharT, _Traits, _Allocator>::size_type
35160b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
35170b57cec5SDimitry Andric                                                size_type __pos) const _NOEXCEPT
35180b57cec5SDimitry Andric{
35190b57cec5SDimitry Andric    _LIBCPP_ASSERT(__s != nullptr, "string::find(): received nullptr");
3520*bdd1243dSDimitry Andric    return std::__str_find<value_type, size_type, traits_type, npos>
35210b57cec5SDimitry Andric        (data(), size(), __s, __pos, traits_type::length(__s));
35220b57cec5SDimitry Andric}
35230b57cec5SDimitry Andric
35240b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
3525*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
35260b57cec5SDimitry Andrictypename basic_string<_CharT, _Traits, _Allocator>::size_type
35270b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find(value_type __c,
35280b57cec5SDimitry Andric                                                size_type __pos) const _NOEXCEPT
35290b57cec5SDimitry Andric{
3530*bdd1243dSDimitry Andric    return std::__str_find<value_type, size_type, traits_type, npos>
35310b57cec5SDimitry Andric        (data(), size(), __c, __pos);
35320b57cec5SDimitry Andric}
35330b57cec5SDimitry Andric
35340b57cec5SDimitry Andric// rfind
35350b57cec5SDimitry Andric
35360b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
3537*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
35380b57cec5SDimitry Andrictypename basic_string<_CharT, _Traits, _Allocator>::size_type
35390b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
35400b57cec5SDimitry Andric                                                 size_type __pos,
35410b57cec5SDimitry Andric                                                 size_type __n) const _NOEXCEPT
35420b57cec5SDimitry Andric{
35430b57cec5SDimitry Andric    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::rfind(): received nullptr");
3544*bdd1243dSDimitry Andric    return std::__str_rfind<value_type, size_type, traits_type, npos>
35450b57cec5SDimitry Andric        (data(), size(), __s, __pos, __n);
35460b57cec5SDimitry Andric}
35470b57cec5SDimitry Andric
35480b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
3549*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
35500b57cec5SDimitry Andrictypename basic_string<_CharT, _Traits, _Allocator>::size_type
35510b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str,
35520b57cec5SDimitry Andric                                                 size_type __pos) const _NOEXCEPT
35530b57cec5SDimitry Andric{
3554*bdd1243dSDimitry Andric    return std::__str_rfind<value_type, size_type, traits_type, npos>
35550b57cec5SDimitry Andric        (data(), size(), __str.data(), __pos, __str.size());
35560b57cec5SDimitry Andric}
35570b57cec5SDimitry Andric
35580b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
35590b57cec5SDimitry Andrictemplate <class _Tp>
3560*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
3561349cc55cSDimitry Andric__enable_if_t
35620b57cec5SDimitry Andric<
35630b57cec5SDimitry Andric    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
35640b57cec5SDimitry Andric    typename basic_string<_CharT, _Traits, _Allocator>::size_type
35655ffd83dbSDimitry Andric>
35660b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::rfind(const _Tp& __t,
3567fe6060f1SDimitry Andric                                                size_type __pos) const _NOEXCEPT
35680b57cec5SDimitry Andric{
35690b57cec5SDimitry Andric    __self_view __sv = __t;
3570*bdd1243dSDimitry Andric    return std::__str_rfind<value_type, size_type, traits_type, npos>
35710b57cec5SDimitry Andric        (data(), size(), __sv.data(), __pos, __sv.size());
35720b57cec5SDimitry Andric}
35730b57cec5SDimitry Andric
35740b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
3575*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
35760b57cec5SDimitry Andrictypename basic_string<_CharT, _Traits, _Allocator>::size_type
35770b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
35780b57cec5SDimitry Andric                                                 size_type __pos) const _NOEXCEPT
35790b57cec5SDimitry Andric{
35800b57cec5SDimitry Andric    _LIBCPP_ASSERT(__s != nullptr, "string::rfind(): received nullptr");
3581*bdd1243dSDimitry Andric    return std::__str_rfind<value_type, size_type, traits_type, npos>
35820b57cec5SDimitry Andric        (data(), size(), __s, __pos, traits_type::length(__s));
35830b57cec5SDimitry Andric}
35840b57cec5SDimitry Andric
35850b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
3586*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
35870b57cec5SDimitry Andrictypename basic_string<_CharT, _Traits, _Allocator>::size_type
35880b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c,
35890b57cec5SDimitry Andric                                                 size_type __pos) const _NOEXCEPT
35900b57cec5SDimitry Andric{
3591*bdd1243dSDimitry Andric    return std::__str_rfind<value_type, size_type, traits_type, npos>
35920b57cec5SDimitry Andric        (data(), size(), __c, __pos);
35930b57cec5SDimitry Andric}
35940b57cec5SDimitry Andric
35950b57cec5SDimitry Andric// find_first_of
35960b57cec5SDimitry Andric
35970b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
3598*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
35990b57cec5SDimitry Andrictypename basic_string<_CharT, _Traits, _Allocator>::size_type
36000b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
36010b57cec5SDimitry Andric                                                         size_type __pos,
36020b57cec5SDimitry Andric                                                         size_type __n) const _NOEXCEPT
36030b57cec5SDimitry Andric{
36040b57cec5SDimitry Andric    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr");
3605*bdd1243dSDimitry Andric    return std::__str_find_first_of<value_type, size_type, traits_type, npos>
36060b57cec5SDimitry Andric        (data(), size(), __s, __pos, __n);
36070b57cec5SDimitry Andric}
36080b57cec5SDimitry Andric
36090b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
3610*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
36110b57cec5SDimitry Andrictypename basic_string<_CharT, _Traits, _Allocator>::size_type
36120b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str,
36130b57cec5SDimitry Andric                                                         size_type __pos) const _NOEXCEPT
36140b57cec5SDimitry Andric{
3615*bdd1243dSDimitry Andric    return std::__str_find_first_of<value_type, size_type, traits_type, npos>
36160b57cec5SDimitry Andric        (data(), size(), __str.data(), __pos, __str.size());
36170b57cec5SDimitry Andric}
36180b57cec5SDimitry Andric
36190b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
36200b57cec5SDimitry Andrictemplate <class _Tp>
3621*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
3622349cc55cSDimitry Andric__enable_if_t
36230b57cec5SDimitry Andric<
36240b57cec5SDimitry Andric    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
36250b57cec5SDimitry Andric    typename basic_string<_CharT, _Traits, _Allocator>::size_type
36265ffd83dbSDimitry Andric>
36270b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_first_of(const _Tp& __t,
3628fe6060f1SDimitry Andric                                                size_type __pos) const _NOEXCEPT
36290b57cec5SDimitry Andric{
36300b57cec5SDimitry Andric    __self_view __sv = __t;
3631*bdd1243dSDimitry Andric    return std::__str_find_first_of<value_type, size_type, traits_type, npos>
36320b57cec5SDimitry Andric        (data(), size(), __sv.data(), __pos, __sv.size());
36330b57cec5SDimitry Andric}
36340b57cec5SDimitry Andric
36350b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
3636*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
36370b57cec5SDimitry Andrictypename basic_string<_CharT, _Traits, _Allocator>::size_type
36380b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
36390b57cec5SDimitry Andric                                                         size_type __pos) const _NOEXCEPT
36400b57cec5SDimitry Andric{
36410b57cec5SDimitry Andric    _LIBCPP_ASSERT(__s != nullptr, "string::find_first_of(): received nullptr");
3642*bdd1243dSDimitry Andric    return std::__str_find_first_of<value_type, size_type, traits_type, npos>
36430b57cec5SDimitry Andric        (data(), size(), __s, __pos, traits_type::length(__s));
36440b57cec5SDimitry Andric}
36450b57cec5SDimitry Andric
36460b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
3647*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
36480b57cec5SDimitry Andrictypename basic_string<_CharT, _Traits, _Allocator>::size_type
36490b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c,
36500b57cec5SDimitry Andric                                                         size_type __pos) const _NOEXCEPT
36510b57cec5SDimitry Andric{
36520b57cec5SDimitry Andric    return find(__c, __pos);
36530b57cec5SDimitry Andric}
36540b57cec5SDimitry Andric
36550b57cec5SDimitry Andric// find_last_of
36560b57cec5SDimitry Andric
36570b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
3658*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
36590b57cec5SDimitry Andrictypename basic_string<_CharT, _Traits, _Allocator>::size_type
36600b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
36610b57cec5SDimitry Andric                                                        size_type __pos,
36620b57cec5SDimitry Andric                                                        size_type __n) const _NOEXCEPT
36630b57cec5SDimitry Andric{
36640b57cec5SDimitry Andric    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr");
3665*bdd1243dSDimitry Andric    return std::__str_find_last_of<value_type, size_type, traits_type, npos>
36660b57cec5SDimitry Andric        (data(), size(), __s, __pos, __n);
36670b57cec5SDimitry Andric}
36680b57cec5SDimitry Andric
36690b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
3670*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
36710b57cec5SDimitry Andrictypename basic_string<_CharT, _Traits, _Allocator>::size_type
36720b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str,
36730b57cec5SDimitry Andric                                                        size_type __pos) const _NOEXCEPT
36740b57cec5SDimitry Andric{
3675*bdd1243dSDimitry Andric    return std::__str_find_last_of<value_type, size_type, traits_type, npos>
36760b57cec5SDimitry Andric        (data(), size(), __str.data(), __pos, __str.size());
36770b57cec5SDimitry Andric}
36780b57cec5SDimitry Andric
36790b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
36800b57cec5SDimitry Andrictemplate <class _Tp>
3681*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
3682349cc55cSDimitry Andric__enable_if_t
36830b57cec5SDimitry Andric<
36840b57cec5SDimitry Andric    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
36850b57cec5SDimitry Andric    typename basic_string<_CharT, _Traits, _Allocator>::size_type
36865ffd83dbSDimitry Andric>
36870b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_last_of(const _Tp& __t,
3688fe6060f1SDimitry Andric                                                size_type __pos) const _NOEXCEPT
36890b57cec5SDimitry Andric{
36900b57cec5SDimitry Andric    __self_view __sv = __t;
3691*bdd1243dSDimitry Andric    return std::__str_find_last_of<value_type, size_type, traits_type, npos>
36920b57cec5SDimitry Andric        (data(), size(), __sv.data(), __pos, __sv.size());
36930b57cec5SDimitry Andric}
36940b57cec5SDimitry Andric
36950b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
3696*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
36970b57cec5SDimitry Andrictypename basic_string<_CharT, _Traits, _Allocator>::size_type
36980b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
36990b57cec5SDimitry Andric                                                        size_type __pos) const _NOEXCEPT
37000b57cec5SDimitry Andric{
37010b57cec5SDimitry Andric    _LIBCPP_ASSERT(__s != nullptr, "string::find_last_of(): received nullptr");
3702*bdd1243dSDimitry Andric    return std::__str_find_last_of<value_type, size_type, traits_type, npos>
37030b57cec5SDimitry Andric        (data(), size(), __s, __pos, traits_type::length(__s));
37040b57cec5SDimitry Andric}
37050b57cec5SDimitry Andric
37060b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
3707*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
37080b57cec5SDimitry Andrictypename basic_string<_CharT, _Traits, _Allocator>::size_type
37090b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c,
37100b57cec5SDimitry Andric                                                        size_type __pos) const _NOEXCEPT
37110b57cec5SDimitry Andric{
37120b57cec5SDimitry Andric    return rfind(__c, __pos);
37130b57cec5SDimitry Andric}
37140b57cec5SDimitry Andric
37150b57cec5SDimitry Andric// find_first_not_of
37160b57cec5SDimitry Andric
37170b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
3718*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
37190b57cec5SDimitry Andrictypename basic_string<_CharT, _Traits, _Allocator>::size_type
37200b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s,
37210b57cec5SDimitry Andric                                                             size_type __pos,
37220b57cec5SDimitry Andric                                                             size_type __n) const _NOEXCEPT
37230b57cec5SDimitry Andric{
37240b57cec5SDimitry Andric    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr");
3725*bdd1243dSDimitry Andric    return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
37260b57cec5SDimitry Andric        (data(), size(), __s, __pos, __n);
37270b57cec5SDimitry Andric}
37280b57cec5SDimitry Andric
37290b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
3730*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
37310b57cec5SDimitry Andrictypename basic_string<_CharT, _Traits, _Allocator>::size_type
37320b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string& __str,
37330b57cec5SDimitry Andric                                                             size_type __pos) const _NOEXCEPT
37340b57cec5SDimitry Andric{
3735*bdd1243dSDimitry Andric    return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
37360b57cec5SDimitry Andric        (data(), size(), __str.data(), __pos, __str.size());
37370b57cec5SDimitry Andric}
37380b57cec5SDimitry Andric
37390b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
37400b57cec5SDimitry Andrictemplate <class _Tp>
3741*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
3742349cc55cSDimitry Andric__enable_if_t
37430b57cec5SDimitry Andric<
37440b57cec5SDimitry Andric    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
37450b57cec5SDimitry Andric    typename basic_string<_CharT, _Traits, _Allocator>::size_type
37465ffd83dbSDimitry Andric>
37470b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const _Tp& __t,
3748fe6060f1SDimitry Andric                                                size_type __pos) const _NOEXCEPT
37490b57cec5SDimitry Andric{
37500b57cec5SDimitry Andric    __self_view __sv = __t;
3751*bdd1243dSDimitry Andric    return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
37520b57cec5SDimitry Andric        (data(), size(), __sv.data(), __pos, __sv.size());
37530b57cec5SDimitry Andric}
37540b57cec5SDimitry Andric
37550b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
3756*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
37570b57cec5SDimitry Andrictypename basic_string<_CharT, _Traits, _Allocator>::size_type
37580b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s,
37590b57cec5SDimitry Andric                                                             size_type __pos) const _NOEXCEPT
37600b57cec5SDimitry Andric{
37610b57cec5SDimitry Andric    _LIBCPP_ASSERT(__s != nullptr, "string::find_first_not_of(): received nullptr");
3762*bdd1243dSDimitry Andric    return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
37630b57cec5SDimitry Andric        (data(), size(), __s, __pos, traits_type::length(__s));
37640b57cec5SDimitry Andric}
37650b57cec5SDimitry Andric
37660b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
3767*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
37680b57cec5SDimitry Andrictypename basic_string<_CharT, _Traits, _Allocator>::size_type
37690b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c,
37700b57cec5SDimitry Andric                                                             size_type __pos) const _NOEXCEPT
37710b57cec5SDimitry Andric{
3772*bdd1243dSDimitry Andric    return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
37730b57cec5SDimitry Andric        (data(), size(), __c, __pos);
37740b57cec5SDimitry Andric}
37750b57cec5SDimitry Andric
37760b57cec5SDimitry Andric// find_last_not_of
37770b57cec5SDimitry Andric
37780b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
3779*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
37800b57cec5SDimitry Andrictypename basic_string<_CharT, _Traits, _Allocator>::size_type
37810b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s,
37820b57cec5SDimitry Andric                                                            size_type __pos,
37830b57cec5SDimitry Andric                                                            size_type __n) const _NOEXCEPT
37840b57cec5SDimitry Andric{
37850b57cec5SDimitry Andric    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr");
3786*bdd1243dSDimitry Andric    return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
37870b57cec5SDimitry Andric        (data(), size(), __s, __pos, __n);
37880b57cec5SDimitry Andric}
37890b57cec5SDimitry Andric
37900b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
3791*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
37920b57cec5SDimitry Andrictypename basic_string<_CharT, _Traits, _Allocator>::size_type
37930b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string& __str,
37940b57cec5SDimitry Andric                                                            size_type __pos) const _NOEXCEPT
37950b57cec5SDimitry Andric{
3796*bdd1243dSDimitry Andric    return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
37970b57cec5SDimitry Andric        (data(), size(), __str.data(), __pos, __str.size());
37980b57cec5SDimitry Andric}
37990b57cec5SDimitry Andric
38000b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
38010b57cec5SDimitry Andrictemplate <class _Tp>
3802*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
3803349cc55cSDimitry Andric__enable_if_t
38040b57cec5SDimitry Andric<
38050b57cec5SDimitry Andric    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
38060b57cec5SDimitry Andric    typename basic_string<_CharT, _Traits, _Allocator>::size_type
38075ffd83dbSDimitry Andric>
38080b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const _Tp& __t,
3809fe6060f1SDimitry Andric                                                size_type __pos) const _NOEXCEPT
38100b57cec5SDimitry Andric{
38110b57cec5SDimitry Andric    __self_view __sv = __t;
3812*bdd1243dSDimitry Andric    return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
38130b57cec5SDimitry Andric        (data(), size(), __sv.data(), __pos, __sv.size());
38140b57cec5SDimitry Andric}
38150b57cec5SDimitry Andric
38160b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
3817*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
38180b57cec5SDimitry Andrictypename basic_string<_CharT, _Traits, _Allocator>::size_type
38190b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s,
38200b57cec5SDimitry Andric                                                            size_type __pos) const _NOEXCEPT
38210b57cec5SDimitry Andric{
38220b57cec5SDimitry Andric    _LIBCPP_ASSERT(__s != nullptr, "string::find_last_not_of(): received nullptr");
3823*bdd1243dSDimitry Andric    return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
38240b57cec5SDimitry Andric        (data(), size(), __s, __pos, traits_type::length(__s));
38250b57cec5SDimitry Andric}
38260b57cec5SDimitry Andric
38270b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
3828*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
38290b57cec5SDimitry Andrictypename basic_string<_CharT, _Traits, _Allocator>::size_type
38300b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c,
38310b57cec5SDimitry Andric                                                            size_type __pos) const _NOEXCEPT
38320b57cec5SDimitry Andric{
3833*bdd1243dSDimitry Andric    return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
38340b57cec5SDimitry Andric        (data(), size(), __c, __pos);
38350b57cec5SDimitry Andric}
38360b57cec5SDimitry Andric
38370b57cec5SDimitry Andric// compare
38380b57cec5SDimitry Andric
38390b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
38400b57cec5SDimitry Andrictemplate <class _Tp>
3841*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
3842349cc55cSDimitry Andric__enable_if_t
38430b57cec5SDimitry Andric<
38440b57cec5SDimitry Andric    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
38450b57cec5SDimitry Andric    int
38465ffd83dbSDimitry Andric>
3847fe6060f1SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const _NOEXCEPT
38480b57cec5SDimitry Andric{
38490b57cec5SDimitry Andric    __self_view __sv = __t;
38500b57cec5SDimitry Andric    size_t __lhs_sz = size();
38510b57cec5SDimitry Andric    size_t __rhs_sz = __sv.size();
38520b57cec5SDimitry Andric    int __result = traits_type::compare(data(), __sv.data(),
385381ad6265SDimitry Andric                                        std::min(__lhs_sz, __rhs_sz));
38540b57cec5SDimitry Andric    if (__result != 0)
38550b57cec5SDimitry Andric        return __result;
38560b57cec5SDimitry Andric    if (__lhs_sz < __rhs_sz)
38570b57cec5SDimitry Andric        return -1;
38580b57cec5SDimitry Andric    if (__lhs_sz > __rhs_sz)
38590b57cec5SDimitry Andric        return 1;
38600b57cec5SDimitry Andric    return 0;
38610b57cec5SDimitry Andric}
38620b57cec5SDimitry Andric
38630b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
3864*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
38650b57cec5SDimitry Andricint
38660b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT
38670b57cec5SDimitry Andric{
38680b57cec5SDimitry Andric    return compare(__self_view(__str));
38690b57cec5SDimitry Andric}
38700b57cec5SDimitry Andric
38710b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
3872*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
38730b57cec5SDimitry Andricint
38740b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
38750b57cec5SDimitry Andric                                                   size_type __n1,
38760b57cec5SDimitry Andric                                                   const value_type* __s,
38770b57cec5SDimitry Andric                                                   size_type __n2) const
38780b57cec5SDimitry Andric{
38790b57cec5SDimitry Andric    _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr");
38800b57cec5SDimitry Andric    size_type __sz = size();
38810b57cec5SDimitry Andric    if (__pos1 > __sz || __n2 == npos)
388204eeddc0SDimitry Andric        __throw_out_of_range();
388381ad6265SDimitry Andric    size_type __rlen = std::min(__n1, __sz - __pos1);
388481ad6265SDimitry Andric    int __r = traits_type::compare(data() + __pos1, __s, std::min(__rlen, __n2));
38850b57cec5SDimitry Andric    if (__r == 0)
38860b57cec5SDimitry Andric    {
38870b57cec5SDimitry Andric        if (__rlen < __n2)
38880b57cec5SDimitry Andric            __r = -1;
38890b57cec5SDimitry Andric        else if (__rlen > __n2)
38900b57cec5SDimitry Andric            __r = 1;
38910b57cec5SDimitry Andric    }
38920b57cec5SDimitry Andric    return __r;
38930b57cec5SDimitry Andric}
38940b57cec5SDimitry Andric
38950b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
38960b57cec5SDimitry Andrictemplate <class _Tp>
3897*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
3898349cc55cSDimitry Andric__enable_if_t
38990b57cec5SDimitry Andric<
39000b57cec5SDimitry Andric    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
39010b57cec5SDimitry Andric    int
39025ffd83dbSDimitry Andric>
39030b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
39040b57cec5SDimitry Andric                                                   size_type __n1,
39050b57cec5SDimitry Andric                                                   const _Tp& __t) const
39060b57cec5SDimitry Andric{
39070b57cec5SDimitry Andric    __self_view __sv = __t;
39080b57cec5SDimitry Andric    return compare(__pos1, __n1, __sv.data(), __sv.size());
39090b57cec5SDimitry Andric}
39100b57cec5SDimitry Andric
39110b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
3912*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
39130b57cec5SDimitry Andricint
39140b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
39150b57cec5SDimitry Andric                                                   size_type __n1,
39160b57cec5SDimitry Andric                                                   const basic_string& __str) const
39170b57cec5SDimitry Andric{
39180b57cec5SDimitry Andric    return compare(__pos1, __n1, __str.data(), __str.size());
39190b57cec5SDimitry Andric}
39200b57cec5SDimitry Andric
39210b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
39220b57cec5SDimitry Andrictemplate <class _Tp>
3923*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
3924349cc55cSDimitry Andric__enable_if_t
39250b57cec5SDimitry Andric<
39265ffd83dbSDimitry Andric    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
39275ffd83dbSDimitry Andric    && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
39280b57cec5SDimitry Andric    int
39295ffd83dbSDimitry Andric>
39300b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
39310b57cec5SDimitry Andric                                                   size_type __n1,
39320b57cec5SDimitry Andric                                                   const _Tp& __t,
39330b57cec5SDimitry Andric                                                   size_type __pos2,
39340b57cec5SDimitry Andric                                                   size_type __n2) const
39350b57cec5SDimitry Andric{
39360b57cec5SDimitry Andric    __self_view __sv = __t;
39370b57cec5SDimitry Andric    return __self_view(*this).substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
39380b57cec5SDimitry Andric}
39390b57cec5SDimitry Andric
39400b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
3941*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
39420b57cec5SDimitry Andricint
39430b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
39440b57cec5SDimitry Andric                                                   size_type __n1,
39450b57cec5SDimitry Andric                                                   const basic_string& __str,
39460b57cec5SDimitry Andric                                                   size_type __pos2,
39470b57cec5SDimitry Andric                                                   size_type __n2) const
39480b57cec5SDimitry Andric{
39490b57cec5SDimitry Andric    return compare(__pos1, __n1, __self_view(__str), __pos2, __n2);
39500b57cec5SDimitry Andric}
39510b57cec5SDimitry Andric
39520b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
3953*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
39540b57cec5SDimitry Andricint
39550b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT
39560b57cec5SDimitry Andric{
39570b57cec5SDimitry Andric    _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr");
39580b57cec5SDimitry Andric    return compare(0, npos, __s, traits_type::length(__s));
39590b57cec5SDimitry Andric}
39600b57cec5SDimitry Andric
39610b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
3962*bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
39630b57cec5SDimitry Andricint
39640b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
39650b57cec5SDimitry Andric                                                   size_type __n1,
39660b57cec5SDimitry Andric                                                   const value_type* __s) const
39670b57cec5SDimitry Andric{
39680b57cec5SDimitry Andric    _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr");
39690b57cec5SDimitry Andric    return compare(__pos1, __n1, __s, traits_type::length(__s));
39700b57cec5SDimitry Andric}
39710b57cec5SDimitry Andric
39720b57cec5SDimitry Andric// __invariants
39730b57cec5SDimitry Andric
39740b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
3975*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
39760b57cec5SDimitry Andricbool
39770b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__invariants() const
39780b57cec5SDimitry Andric{
39790b57cec5SDimitry Andric    if (size() > capacity())
39800b57cec5SDimitry Andric        return false;
39810b57cec5SDimitry Andric    if (capacity() < __min_cap - 1)
39820b57cec5SDimitry Andric        return false;
3983e8d8bef9SDimitry Andric    if (data() == nullptr)
39840b57cec5SDimitry Andric        return false;
3985e8d8bef9SDimitry Andric    if (data()[size()] != value_type())
39860b57cec5SDimitry Andric        return false;
39870b57cec5SDimitry Andric    return true;
39880b57cec5SDimitry Andric}
39890b57cec5SDimitry Andric
39900b57cec5SDimitry Andric// __clear_and_shrink
39910b57cec5SDimitry Andric
39920b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
3993*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
39940b57cec5SDimitry Andricvoid
39950b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT
39960b57cec5SDimitry Andric{
39970b57cec5SDimitry Andric    clear();
39980b57cec5SDimitry Andric    if(__is_long())
39990b57cec5SDimitry Andric    {
40000b57cec5SDimitry Andric        __alloc_traits::deallocate(__alloc(), __get_long_pointer(), capacity() + 1);
4001*bdd1243dSDimitry Andric        __default_init();
40020b57cec5SDimitry Andric    }
40030b57cec5SDimitry Andric}
40040b57cec5SDimitry Andric
40050b57cec5SDimitry Andric// operator==
40060b57cec5SDimitry Andric
40070b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4008*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
40090b57cec5SDimitry Andricbool
40100b57cec5SDimitry Andricoperator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
40110b57cec5SDimitry Andric           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
40120b57cec5SDimitry Andric{
4013*bdd1243dSDimitry Andric#if _LIBCPP_STD_VER > 17
4014*bdd1243dSDimitry Andric    return basic_string_view<_CharT, _Traits>(__lhs) == basic_string_view<_CharT, _Traits>(__rhs);
4015*bdd1243dSDimitry Andric#else
40160b57cec5SDimitry Andric    size_t __lhs_sz = __lhs.size();
40170b57cec5SDimitry Andric    return __lhs_sz == __rhs.size() && _Traits::compare(__lhs.data(),
40180b57cec5SDimitry Andric                                                        __rhs.data(),
40190b57cec5SDimitry Andric                                                        __lhs_sz) == 0;
4020*bdd1243dSDimitry Andric#endif
40210b57cec5SDimitry Andric}
40220b57cec5SDimitry Andric
40230b57cec5SDimitry Andrictemplate<class _Allocator>
4024*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
40250b57cec5SDimitry Andricbool
40260b57cec5SDimitry Andricoperator==(const basic_string<char, char_traits<char>, _Allocator>& __lhs,
40270b57cec5SDimitry Andric           const basic_string<char, char_traits<char>, _Allocator>& __rhs) _NOEXCEPT
40280b57cec5SDimitry Andric{
40290b57cec5SDimitry Andric    size_t __lhs_sz = __lhs.size();
40300b57cec5SDimitry Andric    if (__lhs_sz != __rhs.size())
40310b57cec5SDimitry Andric        return false;
40320b57cec5SDimitry Andric    const char* __lp = __lhs.data();
40330b57cec5SDimitry Andric    const char* __rp = __rhs.data();
40340b57cec5SDimitry Andric    if (__lhs.__is_long())
40350b57cec5SDimitry Andric        return char_traits<char>::compare(__lp, __rp, __lhs_sz) == 0;
40360b57cec5SDimitry Andric    for (; __lhs_sz != 0; --__lhs_sz, ++__lp, ++__rp)
40370b57cec5SDimitry Andric        if (*__lp != *__rp)
40380b57cec5SDimitry Andric            return false;
40390b57cec5SDimitry Andric    return true;
40400b57cec5SDimitry Andric}
40410b57cec5SDimitry Andric
4042*bdd1243dSDimitry Andric#if _LIBCPP_STD_VER <= 17
40430b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4044*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
40450b57cec5SDimitry Andricbool
40460b57cec5SDimitry Andricoperator==(const _CharT* __lhs,
40470b57cec5SDimitry Andric           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
40480b57cec5SDimitry Andric{
40490b57cec5SDimitry Andric    typedef basic_string<_CharT, _Traits, _Allocator> _String;
40500b57cec5SDimitry Andric    _LIBCPP_ASSERT(__lhs != nullptr, "operator==(char*, basic_string): received nullptr");
40510b57cec5SDimitry Andric    size_t __lhs_len = _Traits::length(__lhs);
40520b57cec5SDimitry Andric    if (__lhs_len != __rhs.size()) return false;
40530b57cec5SDimitry Andric    return __rhs.compare(0, _String::npos, __lhs, __lhs_len) == 0;
40540b57cec5SDimitry Andric}
4055*bdd1243dSDimitry Andric#endif // _LIBCPP_STD_VER <= 17
40560b57cec5SDimitry Andric
40570b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4058*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
40590b57cec5SDimitry Andricbool
40600b57cec5SDimitry Andricoperator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
40610b57cec5SDimitry Andric           const _CharT* __rhs) _NOEXCEPT
40620b57cec5SDimitry Andric{
4063*bdd1243dSDimitry Andric#if _LIBCPP_STD_VER > 17
4064*bdd1243dSDimitry Andric    return basic_string_view<_CharT, _Traits>(__lhs) == basic_string_view<_CharT, _Traits>(__rhs);
4065*bdd1243dSDimitry Andric#else
40660b57cec5SDimitry Andric    typedef basic_string<_CharT, _Traits, _Allocator> _String;
40670b57cec5SDimitry Andric    _LIBCPP_ASSERT(__rhs != nullptr, "operator==(basic_string, char*): received nullptr");
40680b57cec5SDimitry Andric    size_t __rhs_len = _Traits::length(__rhs);
40690b57cec5SDimitry Andric    if (__rhs_len != __lhs.size()) return false;
40700b57cec5SDimitry Andric    return __lhs.compare(0, _String::npos, __rhs, __rhs_len) == 0;
4071*bdd1243dSDimitry Andric#endif
4072*bdd1243dSDimitry Andric}
4073*bdd1243dSDimitry Andric
4074*bdd1243dSDimitry Andric#if _LIBCPP_STD_VER > 17
4075*bdd1243dSDimitry Andric
4076*bdd1243dSDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
4077*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr auto operator<=>(
4078*bdd1243dSDimitry Andric    const basic_string<_CharT, _Traits, _Allocator>& __lhs,
4079*bdd1243dSDimitry Andric    const basic_string<_CharT, _Traits, _Allocator>& __rhs) noexcept {
4080*bdd1243dSDimitry Andric    return basic_string_view<_CharT, _Traits>(__lhs) <=> basic_string_view<_CharT, _Traits>(__rhs);
40810b57cec5SDimitry Andric}
40820b57cec5SDimitry Andric
40830b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator>
4084*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr auto
4085*bdd1243dSDimitry Andricoperator<=>(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) {
4086*bdd1243dSDimitry Andric    return basic_string_view<_CharT, _Traits>(__lhs) <=> basic_string_view<_CharT, _Traits>(__rhs);
4087*bdd1243dSDimitry Andric}
4088*bdd1243dSDimitry Andric
4089*bdd1243dSDimitry Andric#else // _LIBCPP_STD_VER > 17
4090*bdd1243dSDimitry Andric
4091*bdd1243dSDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4092*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
40930b57cec5SDimitry Andricbool
40940b57cec5SDimitry Andricoperator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
40950b57cec5SDimitry Andric           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
40960b57cec5SDimitry Andric{
40970b57cec5SDimitry Andric    return !(__lhs == __rhs);
40980b57cec5SDimitry Andric}
40990b57cec5SDimitry Andric
41000b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4101*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
41020b57cec5SDimitry Andricbool
41030b57cec5SDimitry Andricoperator!=(const _CharT* __lhs,
41040b57cec5SDimitry Andric           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
41050b57cec5SDimitry Andric{
41060b57cec5SDimitry Andric    return !(__lhs == __rhs);
41070b57cec5SDimitry Andric}
41080b57cec5SDimitry Andric
41090b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4110*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
41110b57cec5SDimitry Andricbool
41120b57cec5SDimitry Andricoperator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
41130b57cec5SDimitry Andric           const _CharT* __rhs) _NOEXCEPT
41140b57cec5SDimitry Andric{
41150b57cec5SDimitry Andric    return !(__lhs == __rhs);
41160b57cec5SDimitry Andric}
41170b57cec5SDimitry Andric
41180b57cec5SDimitry Andric// operator<
41190b57cec5SDimitry Andric
41200b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4121*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
41220b57cec5SDimitry Andricbool
41230b57cec5SDimitry Andricoperator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
41240b57cec5SDimitry Andric           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
41250b57cec5SDimitry Andric{
41260b57cec5SDimitry Andric    return __lhs.compare(__rhs) < 0;
41270b57cec5SDimitry Andric}
41280b57cec5SDimitry Andric
41290b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4130*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
41310b57cec5SDimitry Andricbool
41320b57cec5SDimitry Andricoperator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
41330b57cec5SDimitry Andric           const _CharT* __rhs) _NOEXCEPT
41340b57cec5SDimitry Andric{
41350b57cec5SDimitry Andric    return __lhs.compare(__rhs) < 0;
41360b57cec5SDimitry Andric}
41370b57cec5SDimitry Andric
41380b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4139*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
41400b57cec5SDimitry Andricbool
41410b57cec5SDimitry Andricoperator< (const _CharT* __lhs,
41420b57cec5SDimitry Andric           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
41430b57cec5SDimitry Andric{
41440b57cec5SDimitry Andric    return __rhs.compare(__lhs) > 0;
41450b57cec5SDimitry Andric}
41460b57cec5SDimitry Andric
41470b57cec5SDimitry Andric// operator>
41480b57cec5SDimitry Andric
41490b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4150*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
41510b57cec5SDimitry Andricbool
41520b57cec5SDimitry Andricoperator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
41530b57cec5SDimitry Andric           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
41540b57cec5SDimitry Andric{
41550b57cec5SDimitry Andric    return __rhs < __lhs;
41560b57cec5SDimitry Andric}
41570b57cec5SDimitry Andric
41580b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4159*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
41600b57cec5SDimitry Andricbool
41610b57cec5SDimitry Andricoperator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
41620b57cec5SDimitry Andric           const _CharT* __rhs) _NOEXCEPT
41630b57cec5SDimitry Andric{
41640b57cec5SDimitry Andric    return __rhs < __lhs;
41650b57cec5SDimitry Andric}
41660b57cec5SDimitry Andric
41670b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4168*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
41690b57cec5SDimitry Andricbool
41700b57cec5SDimitry Andricoperator> (const _CharT* __lhs,
41710b57cec5SDimitry Andric           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
41720b57cec5SDimitry Andric{
41730b57cec5SDimitry Andric    return __rhs < __lhs;
41740b57cec5SDimitry Andric}
41750b57cec5SDimitry Andric
41760b57cec5SDimitry Andric// operator<=
41770b57cec5SDimitry Andric
41780b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4179*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
41800b57cec5SDimitry Andricbool
41810b57cec5SDimitry Andricoperator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
41820b57cec5SDimitry Andric           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
41830b57cec5SDimitry Andric{
41840b57cec5SDimitry Andric    return !(__rhs < __lhs);
41850b57cec5SDimitry Andric}
41860b57cec5SDimitry Andric
41870b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4188*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
41890b57cec5SDimitry Andricbool
41900b57cec5SDimitry Andricoperator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
41910b57cec5SDimitry Andric           const _CharT* __rhs) _NOEXCEPT
41920b57cec5SDimitry Andric{
41930b57cec5SDimitry Andric    return !(__rhs < __lhs);
41940b57cec5SDimitry Andric}
41950b57cec5SDimitry Andric
41960b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4197*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
41980b57cec5SDimitry Andricbool
41990b57cec5SDimitry Andricoperator<=(const _CharT* __lhs,
42000b57cec5SDimitry Andric           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
42010b57cec5SDimitry Andric{
42020b57cec5SDimitry Andric    return !(__rhs < __lhs);
42030b57cec5SDimitry Andric}
42040b57cec5SDimitry Andric
42050b57cec5SDimitry Andric// operator>=
42060b57cec5SDimitry Andric
42070b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4208*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
42090b57cec5SDimitry Andricbool
42100b57cec5SDimitry Andricoperator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
42110b57cec5SDimitry Andric           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
42120b57cec5SDimitry Andric{
42130b57cec5SDimitry Andric    return !(__lhs < __rhs);
42140b57cec5SDimitry Andric}
42150b57cec5SDimitry Andric
42160b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4217*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
42180b57cec5SDimitry Andricbool
42190b57cec5SDimitry Andricoperator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
42200b57cec5SDimitry Andric           const _CharT* __rhs) _NOEXCEPT
42210b57cec5SDimitry Andric{
42220b57cec5SDimitry Andric    return !(__lhs < __rhs);
42230b57cec5SDimitry Andric}
42240b57cec5SDimitry Andric
42250b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4226*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
42270b57cec5SDimitry Andricbool
42280b57cec5SDimitry Andricoperator>=(const _CharT* __lhs,
42290b57cec5SDimitry Andric           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
42300b57cec5SDimitry Andric{
42310b57cec5SDimitry Andric    return !(__lhs < __rhs);
42320b57cec5SDimitry Andric}
4233*bdd1243dSDimitry Andric#endif // _LIBCPP_STD_VER > 17
42340b57cec5SDimitry Andric
42350b57cec5SDimitry Andric// operator +
42360b57cec5SDimitry Andric
42370b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4238*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
42390b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>
42400b57cec5SDimitry Andricoperator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
42410b57cec5SDimitry Andric          const basic_string<_CharT, _Traits, _Allocator>& __rhs)
42420b57cec5SDimitry Andric{
424381ad6265SDimitry Andric    using _String = basic_string<_CharT, _Traits, _Allocator>;
424481ad6265SDimitry Andric    auto __lhs_sz = __lhs.size();
424581ad6265SDimitry Andric    auto __rhs_sz = __rhs.size();
424681ad6265SDimitry Andric    _String __r(__uninitialized_size_tag(),
424781ad6265SDimitry Andric                __lhs_sz + __rhs_sz,
424881ad6265SDimitry Andric                _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator()));
424981ad6265SDimitry Andric    auto __ptr = std::__to_address(__r.__get_pointer());
425081ad6265SDimitry Andric    _Traits::copy(__ptr, __lhs.data(), __lhs_sz);
425181ad6265SDimitry Andric    _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz);
425281ad6265SDimitry Andric    _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());
42530b57cec5SDimitry Andric    return __r;
42540b57cec5SDimitry Andric}
42550b57cec5SDimitry Andric
42560b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4257*bdd1243dSDimitry Andric_LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX20
42580b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>
42590b57cec5SDimitry Andricoperator+(const _CharT* __lhs , const basic_string<_CharT,_Traits,_Allocator>& __rhs)
42600b57cec5SDimitry Andric{
426181ad6265SDimitry Andric    using _String = basic_string<_CharT, _Traits, _Allocator>;
426281ad6265SDimitry Andric    auto __lhs_sz = _Traits::length(__lhs);
426381ad6265SDimitry Andric    auto __rhs_sz = __rhs.size();
426481ad6265SDimitry Andric    _String __r(__uninitialized_size_tag(),
426581ad6265SDimitry Andric                __lhs_sz + __rhs_sz,
426681ad6265SDimitry Andric                _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator()));
426781ad6265SDimitry Andric    auto __ptr = std::__to_address(__r.__get_pointer());
426881ad6265SDimitry Andric    _Traits::copy(__ptr, __lhs, __lhs_sz);
426981ad6265SDimitry Andric    _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz);
427081ad6265SDimitry Andric    _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());
42710b57cec5SDimitry Andric    return __r;
42720b57cec5SDimitry Andric}
42730b57cec5SDimitry Andric
42740b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4275*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
42760b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>
42770b57cec5SDimitry Andricoperator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Allocator>& __rhs)
42780b57cec5SDimitry Andric{
427981ad6265SDimitry Andric    using _String = basic_string<_CharT, _Traits, _Allocator>;
428081ad6265SDimitry Andric    typename _String::size_type __rhs_sz = __rhs.size();
428181ad6265SDimitry Andric    _String __r(__uninitialized_size_tag(),
428281ad6265SDimitry Andric                __rhs_sz + 1,
428381ad6265SDimitry Andric                _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator()));
428481ad6265SDimitry Andric    auto __ptr = std::__to_address(__r.__get_pointer());
428581ad6265SDimitry Andric    _Traits::assign(__ptr, 1, __lhs);
428681ad6265SDimitry Andric    _Traits::copy(__ptr + 1, __rhs.data(), __rhs_sz);
428781ad6265SDimitry Andric    _Traits::assign(__ptr + 1 + __rhs_sz, 1, _CharT());
42880b57cec5SDimitry Andric    return __r;
42890b57cec5SDimitry Andric}
42900b57cec5SDimitry Andric
42910b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4292*bdd1243dSDimitry Andricinline _LIBCPP_CONSTEXPR_SINCE_CXX20
42930b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>
42940b57cec5SDimitry Andricoperator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs)
42950b57cec5SDimitry Andric{
429681ad6265SDimitry Andric    using _String = basic_string<_CharT, _Traits, _Allocator>;
429781ad6265SDimitry Andric    typename _String::size_type __lhs_sz = __lhs.size();
429881ad6265SDimitry Andric    typename _String::size_type __rhs_sz = _Traits::length(__rhs);
429981ad6265SDimitry Andric    _String __r(__uninitialized_size_tag(),
430081ad6265SDimitry Andric                __lhs_sz + __rhs_sz,
430181ad6265SDimitry Andric                _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator()));
430281ad6265SDimitry Andric    auto __ptr = std::__to_address(__r.__get_pointer());
430381ad6265SDimitry Andric    _Traits::copy(__ptr, __lhs.data(), __lhs_sz);
430481ad6265SDimitry Andric    _Traits::copy(__ptr + __lhs_sz, __rhs, __rhs_sz);
430581ad6265SDimitry Andric    _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());
43060b57cec5SDimitry Andric    return __r;
43070b57cec5SDimitry Andric}
43080b57cec5SDimitry Andric
43090b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4310*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
43110b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>
43120b57cec5SDimitry Andricoperator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs)
43130b57cec5SDimitry Andric{
431481ad6265SDimitry Andric    using _String = basic_string<_CharT, _Traits, _Allocator>;
431581ad6265SDimitry Andric    typename _String::size_type __lhs_sz = __lhs.size();
431681ad6265SDimitry Andric    _String __r(__uninitialized_size_tag(),
431781ad6265SDimitry Andric                __lhs_sz + 1,
431881ad6265SDimitry Andric                _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator()));
431981ad6265SDimitry Andric    auto __ptr = std::__to_address(__r.__get_pointer());
432081ad6265SDimitry Andric    _Traits::copy(__ptr, __lhs.data(), __lhs_sz);
432181ad6265SDimitry Andric    _Traits::assign(__ptr + __lhs_sz, 1, __rhs);
432281ad6265SDimitry Andric    _Traits::assign(__ptr + 1 + __lhs_sz, 1, _CharT());
43230b57cec5SDimitry Andric    return __r;
43240b57cec5SDimitry Andric}
43250b57cec5SDimitry Andric
43260b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
43270b57cec5SDimitry Andric
43280b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4329*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
43300b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>
43310b57cec5SDimitry Andricoperator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs)
43320b57cec5SDimitry Andric{
433381ad6265SDimitry Andric    return std::move(__lhs.append(__rhs));
43340b57cec5SDimitry Andric}
43350b57cec5SDimitry Andric
43360b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4337*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
43380b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>
43390b57cec5SDimitry Andricoperator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs)
43400b57cec5SDimitry Andric{
434181ad6265SDimitry Andric    return std::move(__rhs.insert(0, __lhs));
43420b57cec5SDimitry Andric}
43430b57cec5SDimitry Andric
43440b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4345*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
43460b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>
43470b57cec5SDimitry Andricoperator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs)
43480b57cec5SDimitry Andric{
434981ad6265SDimitry Andric    return std::move(__lhs.append(__rhs));
43500b57cec5SDimitry Andric}
43510b57cec5SDimitry Andric
43520b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4353*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
43540b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>
43550b57cec5SDimitry Andricoperator+(const _CharT* __lhs , basic_string<_CharT,_Traits,_Allocator>&& __rhs)
43560b57cec5SDimitry Andric{
435781ad6265SDimitry Andric    return std::move(__rhs.insert(0, __lhs));
43580b57cec5SDimitry Andric}
43590b57cec5SDimitry Andric
43600b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4361*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
43620b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>
43630b57cec5SDimitry Andricoperator+(_CharT __lhs, basic_string<_CharT,_Traits,_Allocator>&& __rhs)
43640b57cec5SDimitry Andric{
43650b57cec5SDimitry Andric    __rhs.insert(__rhs.begin(), __lhs);
436681ad6265SDimitry Andric    return std::move(__rhs);
43670b57cec5SDimitry Andric}
43680b57cec5SDimitry Andric
43690b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4370*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
43710b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>
43720b57cec5SDimitry Andricoperator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const _CharT* __rhs)
43730b57cec5SDimitry Andric{
437481ad6265SDimitry Andric    return std::move(__lhs.append(__rhs));
43750b57cec5SDimitry Andric}
43760b57cec5SDimitry Andric
43770b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4378*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
43790b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>
43800b57cec5SDimitry Andricoperator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT __rhs)
43810b57cec5SDimitry Andric{
43820b57cec5SDimitry Andric    __lhs.push_back(__rhs);
438381ad6265SDimitry Andric    return std::move(__lhs);
43840b57cec5SDimitry Andric}
43850b57cec5SDimitry Andric
43860b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
43870b57cec5SDimitry Andric
43880b57cec5SDimitry Andric// swap
43890b57cec5SDimitry Andric
43900b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4391*bdd1243dSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
43920b57cec5SDimitry Andricvoid
43930b57cec5SDimitry Andricswap(basic_string<_CharT, _Traits, _Allocator>& __lhs,
43940b57cec5SDimitry Andric     basic_string<_CharT, _Traits, _Allocator>& __rhs)
43950b57cec5SDimitry Andric     _NOEXCEPT_(_NOEXCEPT_(__lhs.swap(__rhs)))
43960b57cec5SDimitry Andric{
43970b57cec5SDimitry Andric    __lhs.swap(__rhs);
43980b57cec5SDimitry Andric}
43990b57cec5SDimitry Andric
4400e8d8bef9SDimitry Andric_LIBCPP_FUNC_VIS int                stoi  (const string& __str, size_t* __idx = nullptr, int __base = 10);
4401e8d8bef9SDimitry Andric_LIBCPP_FUNC_VIS long               stol  (const string& __str, size_t* __idx = nullptr, int __base = 10);
4402e8d8bef9SDimitry Andric_LIBCPP_FUNC_VIS unsigned long      stoul (const string& __str, size_t* __idx = nullptr, int __base = 10);
4403e8d8bef9SDimitry Andric_LIBCPP_FUNC_VIS long long          stoll (const string& __str, size_t* __idx = nullptr, int __base = 10);
4404e8d8bef9SDimitry Andric_LIBCPP_FUNC_VIS unsigned long long stoull(const string& __str, size_t* __idx = nullptr, int __base = 10);
44050b57cec5SDimitry Andric
4406e8d8bef9SDimitry Andric_LIBCPP_FUNC_VIS float       stof (const string& __str, size_t* __idx = nullptr);
4407e8d8bef9SDimitry Andric_LIBCPP_FUNC_VIS double      stod (const string& __str, size_t* __idx = nullptr);
4408e8d8bef9SDimitry Andric_LIBCPP_FUNC_VIS long double stold(const string& __str, size_t* __idx = nullptr);
44090b57cec5SDimitry Andric
44100b57cec5SDimitry Andric_LIBCPP_FUNC_VIS string to_string(int __val);
44110b57cec5SDimitry Andric_LIBCPP_FUNC_VIS string to_string(unsigned __val);
44120b57cec5SDimitry Andric_LIBCPP_FUNC_VIS string to_string(long __val);
44130b57cec5SDimitry Andric_LIBCPP_FUNC_VIS string to_string(unsigned long __val);
44140b57cec5SDimitry Andric_LIBCPP_FUNC_VIS string to_string(long long __val);
44150b57cec5SDimitry Andric_LIBCPP_FUNC_VIS string to_string(unsigned long long __val);
44160b57cec5SDimitry Andric_LIBCPP_FUNC_VIS string to_string(float __val);
44170b57cec5SDimitry Andric_LIBCPP_FUNC_VIS string to_string(double __val);
44180b57cec5SDimitry Andric_LIBCPP_FUNC_VIS string to_string(long double __val);
44190b57cec5SDimitry Andric
4420349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4421e8d8bef9SDimitry Andric_LIBCPP_FUNC_VIS int                stoi  (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
4422e8d8bef9SDimitry Andric_LIBCPP_FUNC_VIS long               stol  (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
4423e8d8bef9SDimitry Andric_LIBCPP_FUNC_VIS unsigned long      stoul (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
4424e8d8bef9SDimitry Andric_LIBCPP_FUNC_VIS long long          stoll (const wstring& __str, size_t* __idx = nullptr, int __base = 10);
4425e8d8bef9SDimitry Andric_LIBCPP_FUNC_VIS unsigned long long stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
44260b57cec5SDimitry Andric
4427e8d8bef9SDimitry Andric_LIBCPP_FUNC_VIS float       stof (const wstring& __str, size_t* __idx = nullptr);
4428e8d8bef9SDimitry Andric_LIBCPP_FUNC_VIS double      stod (const wstring& __str, size_t* __idx = nullptr);
4429e8d8bef9SDimitry Andric_LIBCPP_FUNC_VIS long double stold(const wstring& __str, size_t* __idx = nullptr);
44300b57cec5SDimitry Andric
44310b57cec5SDimitry Andric_LIBCPP_FUNC_VIS wstring to_wstring(int __val);
44320b57cec5SDimitry Andric_LIBCPP_FUNC_VIS wstring to_wstring(unsigned __val);
44330b57cec5SDimitry Andric_LIBCPP_FUNC_VIS wstring to_wstring(long __val);
44340b57cec5SDimitry Andric_LIBCPP_FUNC_VIS wstring to_wstring(unsigned long __val);
44350b57cec5SDimitry Andric_LIBCPP_FUNC_VIS wstring to_wstring(long long __val);
44360b57cec5SDimitry Andric_LIBCPP_FUNC_VIS wstring to_wstring(unsigned long long __val);
44370b57cec5SDimitry Andric_LIBCPP_FUNC_VIS wstring to_wstring(float __val);
44380b57cec5SDimitry Andric_LIBCPP_FUNC_VIS wstring to_wstring(double __val);
44390b57cec5SDimitry Andric_LIBCPP_FUNC_VIS wstring to_wstring(long double __val);
4440349cc55cSDimitry Andric#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
44410b57cec5SDimitry Andric
44420b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4443fe6060f1SDimitry Andric_LIBCPP_TEMPLATE_DATA_VIS
44440b57cec5SDimitry Andricconst typename basic_string<_CharT, _Traits, _Allocator>::size_type
44450b57cec5SDimitry Andric               basic_string<_CharT, _Traits, _Allocator>::npos;
44460b57cec5SDimitry Andric
44470b57cec5SDimitry Andrictemplate <class _CharT, class _Allocator>
4448*bdd1243dSDimitry Andricstruct __string_hash : public __unary_function<basic_string<_CharT, char_traits<_CharT>, _Allocator>, size_t>
44490b57cec5SDimitry Andric{
44500b57cec5SDimitry Andric    size_t
44510b57cec5SDimitry Andric    operator()(const basic_string<_CharT, char_traits<_CharT>, _Allocator>& __val) const _NOEXCEPT
4452*bdd1243dSDimitry Andric    { return std::__do_string_hash(__val.data(), __val.data() + __val.size()); }
44530b57cec5SDimitry Andric};
44540b57cec5SDimitry Andric
4455*bdd1243dSDimitry Andrictemplate <class _Allocator>
4456*bdd1243dSDimitry Andricstruct hash<basic_string<char, char_traits<char>, _Allocator> > : __string_hash<char, _Allocator> {};
4457*bdd1243dSDimitry Andric
4458*bdd1243dSDimitry Andric#ifndef _LIBCPP_HAS_NO_CHAR8_T
4459*bdd1243dSDimitry Andrictemplate <class _Allocator>
4460*bdd1243dSDimitry Andricstruct hash<basic_string<char8_t, char_traits<char8_t>, _Allocator> > : __string_hash<char8_t, _Allocator> {};
4461*bdd1243dSDimitry Andric#endif
4462*bdd1243dSDimitry Andric
4463*bdd1243dSDimitry Andrictemplate <class _Allocator>
4464*bdd1243dSDimitry Andricstruct hash<basic_string<char16_t, char_traits<char16_t>, _Allocator> > : __string_hash<char16_t, _Allocator> {};
4465*bdd1243dSDimitry Andric
4466*bdd1243dSDimitry Andrictemplate <class _Allocator>
4467*bdd1243dSDimitry Andricstruct hash<basic_string<char32_t, char_traits<char32_t>, _Allocator> > : __string_hash<char32_t, _Allocator> {};
4468*bdd1243dSDimitry Andric
4469*bdd1243dSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4470*bdd1243dSDimitry Andrictemplate <class _Allocator>
4471*bdd1243dSDimitry Andricstruct hash<basic_string<wchar_t, char_traits<wchar_t>, _Allocator> > : __string_hash<wchar_t, _Allocator> {};
4472*bdd1243dSDimitry Andric#endif
4473*bdd1243dSDimitry Andric
44740b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4475*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
44760b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os,
44770b57cec5SDimitry Andric           const basic_string<_CharT, _Traits, _Allocator>& __str);
44780b57cec5SDimitry Andric
44790b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4480*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
44810b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is,
44820b57cec5SDimitry Andric           basic_string<_CharT, _Traits, _Allocator>& __str);
44830b57cec5SDimitry Andric
44840b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
4485*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
44860b57cec5SDimitry Andricgetline(basic_istream<_CharT, _Traits>& __is,
44870b57cec5SDimitry Andric        basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm);
44880b57cec5SDimitry Andric
44890b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
449081ad6265SDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
44910b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
44920b57cec5SDimitry Andricgetline(basic_istream<_CharT, _Traits>& __is,
44930b57cec5SDimitry Andric        basic_string<_CharT, _Traits, _Allocator>& __str);
44940b57cec5SDimitry Andric
44950b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
449681ad6265SDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
44970b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
44980b57cec5SDimitry Andricgetline(basic_istream<_CharT, _Traits>&& __is,
44990b57cec5SDimitry Andric        basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm);
45000b57cec5SDimitry Andric
45010b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
450281ad6265SDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
45030b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
45040b57cec5SDimitry Andricgetline(basic_istream<_CharT, _Traits>&& __is,
45050b57cec5SDimitry Andric        basic_string<_CharT, _Traits, _Allocator>& __str);
45060b57cec5SDimitry Andric
45070b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 17
45080b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator, class _Up>
450981ad6265SDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
45105ffd83dbSDimitry Andric    typename basic_string<_CharT, _Traits, _Allocator>::size_type
45115ffd83dbSDimitry Andric    erase(basic_string<_CharT, _Traits, _Allocator>& __str, const _Up& __v) {
45125ffd83dbSDimitry Andric  auto __old_size = __str.size();
451381ad6265SDimitry Andric  __str.erase(std::remove(__str.begin(), __str.end(), __v), __str.end());
45145ffd83dbSDimitry Andric  return __old_size - __str.size();
45155ffd83dbSDimitry Andric}
45160b57cec5SDimitry Andric
45170b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Allocator, class _Predicate>
451881ad6265SDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
45195ffd83dbSDimitry Andric    typename basic_string<_CharT, _Traits, _Allocator>::size_type
45205ffd83dbSDimitry Andric    erase_if(basic_string<_CharT, _Traits, _Allocator>& __str,
45215ffd83dbSDimitry Andric             _Predicate __pred) {
45225ffd83dbSDimitry Andric  auto __old_size = __str.size();
452381ad6265SDimitry Andric  __str.erase(std::remove_if(__str.begin(), __str.end(), __pred),
45245ffd83dbSDimitry Andric              __str.end());
45255ffd83dbSDimitry Andric  return __old_size - __str.size();
45265ffd83dbSDimitry Andric}
45270b57cec5SDimitry Andric#endif
45280b57cec5SDimitry Andric
452981ad6265SDimitry Andric#ifdef _LIBCPP_ENABLE_DEBUG_MODE
45300b57cec5SDimitry Andric
45310b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
45320b57cec5SDimitry Andricbool
45330b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__dereferenceable(const const_iterator* __i) const
45340b57cec5SDimitry Andric{
453581ad6265SDimitry Andric    return data() <= std::__to_address(__i->base()) &&
453681ad6265SDimitry Andric           std::__to_address(__i->base()) < data() + size();
45370b57cec5SDimitry Andric}
45380b57cec5SDimitry Andric
45390b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
45400b57cec5SDimitry Andricbool
45410b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__decrementable(const const_iterator* __i) const
45420b57cec5SDimitry Andric{
454381ad6265SDimitry Andric    return data() < std::__to_address(__i->base()) &&
454481ad6265SDimitry Andric           std::__to_address(__i->base()) <= data() + size();
45450b57cec5SDimitry Andric}
45460b57cec5SDimitry Andric
45470b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
45480b57cec5SDimitry Andricbool
45490b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const
45500b57cec5SDimitry Andric{
455181ad6265SDimitry Andric    const value_type* __p = std::__to_address(__i->base()) + __n;
455204eeddc0SDimitry Andric    return data() <= __p && __p <= data() + size();
45530b57cec5SDimitry Andric}
45540b57cec5SDimitry Andric
45550b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Allocator>
45560b57cec5SDimitry Andricbool
45570b57cec5SDimitry Andricbasic_string<_CharT, _Traits, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const
45580b57cec5SDimitry Andric{
455981ad6265SDimitry Andric    const value_type* __p = std::__to_address(__i->base()) + __n;
456004eeddc0SDimitry Andric    return data() <= __p && __p < data() + size();
45610b57cec5SDimitry Andric}
45620b57cec5SDimitry Andric
456381ad6265SDimitry Andric#endif // _LIBCPP_ENABLE_DEBUG_MODE
45640b57cec5SDimitry Andric
45650b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 11
45660b57cec5SDimitry Andric// Literal suffixes for basic_string [basic.string.literals]
45670b57cec5SDimitry Andricinline namespace literals
45680b57cec5SDimitry Andric{
45690b57cec5SDimitry Andric  inline namespace string_literals
45700b57cec5SDimitry Andric  {
4571*bdd1243dSDimitry Andric    inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
45720b57cec5SDimitry Andric    basic_string<char> operator "" s( const char *__str, size_t __len )
45730b57cec5SDimitry Andric    {
45740b57cec5SDimitry Andric        return basic_string<char> (__str, __len);
45750b57cec5SDimitry Andric    }
45760b57cec5SDimitry Andric
4577349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4578*bdd1243dSDimitry Andric    inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
45790b57cec5SDimitry Andric    basic_string<wchar_t> operator "" s( const wchar_t *__str, size_t __len )
45800b57cec5SDimitry Andric    {
45810b57cec5SDimitry Andric        return basic_string<wchar_t> (__str, __len);
45820b57cec5SDimitry Andric    }
4583349cc55cSDimitry Andric#endif
45840b57cec5SDimitry Andric
4585fe6060f1SDimitry Andric#ifndef _LIBCPP_HAS_NO_CHAR8_T
458681ad6265SDimitry Andric    inline _LIBCPP_HIDE_FROM_ABI constexpr
4587*bdd1243dSDimitry Andric    basic_string<char8_t> operator "" s(const char8_t *__str, size_t __len)
45880b57cec5SDimitry Andric    {
45890b57cec5SDimitry Andric        return basic_string<char8_t> (__str, __len);
45900b57cec5SDimitry Andric    }
45910b57cec5SDimitry Andric#endif
45920b57cec5SDimitry Andric
4593*bdd1243dSDimitry Andric    inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
45940b57cec5SDimitry Andric    basic_string<char16_t> operator "" s( const char16_t *__str, size_t __len )
45950b57cec5SDimitry Andric    {
45960b57cec5SDimitry Andric        return basic_string<char16_t> (__str, __len);
45970b57cec5SDimitry Andric    }
45980b57cec5SDimitry Andric
4599*bdd1243dSDimitry Andric    inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
46000b57cec5SDimitry Andric    basic_string<char32_t> operator "" s( const char32_t *__str, size_t __len )
46010b57cec5SDimitry Andric    {
46020b57cec5SDimitry Andric        return basic_string<char32_t> (__str, __len);
46030b57cec5SDimitry Andric    }
46040eae32dcSDimitry Andric  } // namespace string_literals
46050eae32dcSDimitry Andric} // namespace literals
460681ad6265SDimitry Andric
460781ad6265SDimitry Andric#if _LIBCPP_STD_VER > 17
460881ad6265SDimitry Andrictemplate <>
460981ad6265SDimitry Andricinline constexpr bool __format::__enable_insertable<std::basic_string<char>> = true;
461081ad6265SDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
461181ad6265SDimitry Andrictemplate <>
461281ad6265SDimitry Andricinline constexpr bool __format::__enable_insertable<std::basic_string<wchar_t>> = true;
461381ad6265SDimitry Andric#endif
461481ad6265SDimitry Andric#endif
461581ad6265SDimitry Andric
46160b57cec5SDimitry Andric#endif
46170b57cec5SDimitry Andric
46180b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
46190b57cec5SDimitry Andric
46200b57cec5SDimitry Andric_LIBCPP_POP_MACROS
46210b57cec5SDimitry Andric
4622*bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
4623*bdd1243dSDimitry Andric#  include <algorithm>
4624*bdd1243dSDimitry Andric#  include <concepts>
4625*bdd1243dSDimitry Andric#  include <functional>
4626*bdd1243dSDimitry Andric#  include <iterator>
4627*bdd1243dSDimitry Andric#  include <new>
4628*bdd1243dSDimitry Andric#  include <typeinfo>
4629*bdd1243dSDimitry Andric#  include <utility>
4630*bdd1243dSDimitry Andric#  include <vector>
4631*bdd1243dSDimitry Andric#endif
4632*bdd1243dSDimitry Andric
46330b57cec5SDimitry Andric#endif // _LIBCPP_STRING
4634