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