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