libstdc++: basic_string.h Source File

libstdc++

basic_string.h
Go to the documentation of this file.
1// Components for manipulating sequences of characters -*- C++ -*-
2
3// Copyright (C) 1997-2026 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file bits/basic_string.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{string}
28 */
29
30//
31// ISO C++ 14882: 21 Strings library
32//
33
34#ifndef _BASIC_STRING_H
35#define _BASIC_STRING_H 1
36
37#ifdef _GLIBCXX_SYSHDR
38#pragma GCC system_header
39#endif
40
41#include <ext/alloc_traits.h>
42#include <debug/debug.h>
43
44#if __cplusplus >= 201103L
45#include <initializer_list>
46#endif
47
48#include <bits/version.h>
49
50#ifdef __glibcxx_string_view // >= C++17
51# include <string_view>
52#endif
53
54#if __glibcxx_containers_ranges // C++ >= 23
55# include <bits/ranges_algobase.h> // ranges::copy
56# include <bits/ranges_util.h> // ranges::subrange
57#endif
58
59#if __glibcxx_to_string >= 202306L // C++ >= 26
60# include <charconv>
61#endif
62
63#if ! _GLIBCXX_USE_CXX11_ABI
64# include "cow_string.h"
65#else
66
67namespace std _GLIBCXX_VISIBILITY(default)
68{
69_GLIBCXX_BEGIN_NAMESPACE_VERSION
70_GLIBCXX_BEGIN_NAMESPACE_CXX11
71
72 /**
73 * @class basic_string basic_string.h <string>
74 * @brief Managing sequences of characters and character-like objects.
75 *
76 * @ingroup strings
77 * @ingroup sequences
78 * @headerfile string
79 * @since C++98
80 *
81 * @tparam _CharT Type of character
82 * @tparam _Traits Traits for character type, defaults to
83 * char_traits<_CharT>.
84 * @tparam _Alloc Allocator type, defaults to allocator<_CharT>.
85 *
86 * Meets the requirements of a <a href="tables.html#65">container</a>, a
87 * <a href="tables.html#66">reversible container</a>, and a
88 * <a href="tables.html#67">sequence</a>. Of the
89 * <a href="tables.html#68">optional sequence requirements</a>, only
90 * @c push_back, @c at, and @c %array access are supported.
91 */
92 template<typename _CharT, typename _Traits, typename _Alloc>
93 class basic_string
94 {
95#if __cplusplus >= 202002L
96 static_assert(is_trivially_copyable_v<_CharT>
97 && is_trivially_default_constructible_v<_CharT>
98 && is_standard_layout_v<_CharT>);
99 static_assert(is_same_v<_CharT, typename _Traits::char_type>);
100 static_assert(is_same_v<_CharT, typename _Alloc::value_type>);
101 using _Char_alloc_type = _Alloc;
102#else
103 typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
104 rebind<_CharT>::other _Char_alloc_type;
105#endif
106
107 typedef __gnu_cxx::__alloc_traits<_Char_alloc_type> _Alloc_traits;
108
109 // Types:
110 public:
111 typedef _Traits traits_type;
112 typedef typename _Traits::char_type value_type;
113 typedef _Char_alloc_type allocator_type;
114 typedef typename _Alloc_traits::size_type size_type;
115 typedef typename _Alloc_traits::difference_type difference_type;
116 typedef typename _Alloc_traits::reference reference;
117 typedef typename _Alloc_traits::const_reference const_reference;
118 typedef typename _Alloc_traits::pointer pointer;
119 typedef typename _Alloc_traits::const_pointer const_pointer;
120 typedef __gnu_cxx::__normal_iterator<pointer, basic_string> iterator;
121 typedef __gnu_cxx::__normal_iterator<const_pointer, basic_string>
122 const_iterator;
123 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
124 typedef std::reverse_iterator<iterator> reverse_iterator;
125
126 /// Value returned by various member functions when they fail.
127 static const size_type npos = static_cast<size_type>(-1);
128
129 protected:
130 // type used for positions in insert, erase etc.
131#if __cplusplus < 201103L
132 typedef iterator __const_iterator;
133#else
134 typedef const_iterator __const_iterator;
135#endif
136
137 private:
138 // For ABI reasons this must remain, though unused.
139 static _GLIBCXX20_CONSTEXPR pointer
140 _S_allocate(_Char_alloc_type& __a, size_type __n)
141 { return _Alloc_traits::allocate(__a, __n); }
142
143 struct _Alloc_result { pointer __ptr; size_type __count; };
144
145 static _GLIBCXX20_CONSTEXPR _Alloc_result
146 _S_allocate_at_least(_Char_alloc_type& __a, size_type __n)
147 {
148 _Alloc_result __r;
149#ifdef __glibcxx_allocate_at_least // C++23
150 auto [__ptr, __count] = _Alloc_traits::allocate_at_least(__a, __n);
151 __r.__ptr = __ptr;
152 __r.__count = __count;
153#else
154 __r.__ptr = _Alloc_traits::allocate(__a, __n);
155 __r.__count = __n;
156#endif
157#if __glibcxx_constexpr_string >= 201907L
158 // std::char_traits begins the lifetime of characters,
159 // but custom traits might not, so do it here.
160 if constexpr (!is_same_v<_Traits, char_traits<_CharT>>)
161 if (std::__is_constant_evaluated())
162 // Begin the lifetime of characters in allocated storage.
163 for (size_type __i = 0; __i < __r.__count; ++__i)
164 std::construct_at(__builtin_addressof(__r.__ptr[__i]));
165#endif
166 return __r;
167 }
168
169#ifdef __glibcxx_string_view // >= C++17
170 // A helper type for avoiding boiler-plate.
171 typedef basic_string_view<_CharT, _Traits> __sv_type;
172
173 template<typename _Tp, typename _Res>
174 using _If_sv = enable_if_t<
175 __and_<is_convertible<const _Tp&, __sv_type>,
176 __not_<is_convertible<const _Tp*, const basic_string*>>,
177 __not_<is_convertible<const _Tp&, const _CharT*>>>::value,
178 _Res>;
179
180 // Allows an implicit conversion to __sv_type.
181 _GLIBCXX20_CONSTEXPR
182 static __sv_type
183 _S_to_string_view(__sv_type __svt) noexcept
184 { return __svt; }
185
186 // Wraps a string_view by explicit conversion and thus
187 // allows to add an internal constructor that does not
188 // participate in overload resolution when a string_view
189 // is provided.
190 struct __sv_wrapper
191 {
192 _GLIBCXX20_CONSTEXPR explicit
193 __sv_wrapper(__sv_type __sv) noexcept : _M_sv(__sv) { }
194
195 __sv_type _M_sv;
196 };
197
198 /**
199 * @brief Only internally used: Construct string from a string view
200 * wrapper.
201 * @param __svw string view wrapper.
202 * @param __a Allocator to use.
203 */
204 _GLIBCXX20_CONSTEXPR
205 explicit
206 basic_string(__sv_wrapper __svw, const _Alloc& __a)
207 : basic_string(__svw._M_sv.data(), __svw._M_sv.size(), __a) { }
208#endif
209
210 // Use empty-base optimization: http://www.cantrip.org/emptyopt.html
211 struct _Alloc_hider : allocator_type // TODO check __is_final
212 {
213#if __cplusplus < 201103L
214 _Alloc_hider(pointer __dat, const _Alloc& __a = _Alloc())
215 : allocator_type(__a), _M_p(__dat) { }
216#else
217 _GLIBCXX20_CONSTEXPR
218 _Alloc_hider(pointer __dat, const _Alloc& __a)
219 : allocator_type(__a), _M_p(__dat) { }
220
221 _GLIBCXX20_CONSTEXPR
222 _Alloc_hider(pointer __dat, _Alloc&& __a = _Alloc())
223 : allocator_type(std::move(__a)), _M_p(__dat) { }
224#endif
225
226 pointer _M_p; // The actual data.
227 };
228
229 _Alloc_hider _M_dataplus;
230 size_type _M_string_length;
231
232 enum { _S_local_capacity = 15 / sizeof(_CharT) };
233
234 union
235 {
236 _CharT _M_local_buf[_S_local_capacity + 1];
237 size_type _M_allocated_capacity;
238 };
239
240 _GLIBCXX20_CONSTEXPR
241 void
242 _M_data(pointer __p)
243 { _M_dataplus._M_p = __p; }
244
245 _GLIBCXX20_CONSTEXPR
246 void
247 _M_length(size_type __length)
248 { _M_string_length = __length; }
249
250 _GLIBCXX20_CONSTEXPR
251 pointer
252 _M_data() const
253 { return _M_dataplus._M_p; }
254
255 _GLIBCXX20_CONSTEXPR
256 pointer
257 _M_local_data()
258 {
259#if __cplusplus >= 201103L
260 return std::pointer_traits<pointer>::pointer_to(*_M_local_buf);
261#else
262 return pointer(_M_local_buf);
263#endif
264 }
265
266 _GLIBCXX20_CONSTEXPR
267 const_pointer
268 _M_local_data() const
269 {
270#if __cplusplus >= 201103L
271 return std::pointer_traits<const_pointer>::pointer_to(*_M_local_buf);
272#else
273 return const_pointer(_M_local_buf);
274#endif
275 }
276
277 _GLIBCXX20_CONSTEXPR
278 void
279 _M_capacity(size_type __capacity)
280 { _M_allocated_capacity = __capacity; }
281
282 _GLIBCXX20_CONSTEXPR
283 void
284 _M_set_length(size_type __n)
285 {
286 traits_type::assign(_M_data()[__n], _CharT());
287 _M_length(__n);
288 }
289
290 _GLIBCXX20_CONSTEXPR
291 bool
292 _M_is_local() const
293 {
294 if (_M_data() == _M_local_data())
295 {
296 if (_M_string_length > _S_local_capacity)
297 __builtin_unreachable();
298 return true;
299 }
300 return false;
301 }
302
303 // Create & Destroy
304 _GLIBCXX20_CONSTEXPR
305 _Alloc_result
306 _M_create_plus(size_type __new_capacity, size_type __old_capacity);
307
308 __attribute__((__always_inline__))
309 _GLIBCXX20_CONSTEXPR
310 void
311 _M_create_and_place(size_type __new_capacity, size_type __old_capacity)
312 {
313 _Alloc_result __r = _M_create_plus(__new_capacity, __old_capacity);
314 _M_data(__r.__ptr);
315 _M_capacity(__r.__count - 1); // Leave room for NUL.
316 }
317
318 // This must remain for ABI stability though unused.
319 _GLIBCXX20_CONSTEXPR
320 pointer
321 _M_create(size_type&, size_type);
322
323 _GLIBCXX20_CONSTEXPR
324 void
325 _M_dispose()
326 {
327 if (!_M_is_local())
328 _M_destroy(_M_allocated_capacity);
329 }
330
331 _GLIBCXX20_CONSTEXPR
332 void
333 _M_destroy(size_type __size) throw()
334 { _Alloc_traits::deallocate(_M_get_allocator(), _M_data(), __size + 1); }
335
336#if __cplusplus < 201103L || defined _GLIBCXX_DEFINING_STRING_INSTANTIATIONS
337 // _M_construct_aux is used to implement the 21.3.1 para 15 which
338 // requires special behaviour if _InIterator is an integral type
339 template<typename _InIterator>
340 void
341 _M_construct_aux(_InIterator __beg, _InIterator __end,
342 std::__false_type)
343 {
344 typedef typename iterator_traits<_InIterator>::iterator_category _Tag;
345 _M_construct(__beg, __end, _Tag());
346 }
347
348 // _GLIBCXX_RESOLVE_LIB_DEFECTS
349 // 438. Ambiguity in the "do the right thing" clause
350 template<typename _Integer>
351 void
352 _M_construct_aux(_Integer __beg, _Integer __end, std::__true_type)
353 { _M_construct_aux_2(static_cast<size_type>(__beg), __end); }
354
355 void
356 _M_construct_aux_2(size_type __req, _CharT __c)
357 { _M_construct(__req, __c); }
358#endif
359
360 // For Input Iterators, used in istreambuf_iterators, etc.
361 template<typename _InIterator>
362 _GLIBCXX20_CONSTEXPR
363 void
364 _M_construct(_InIterator __beg, _InIterator __end,
365 std::input_iterator_tag);
366
367 // For forward_iterators up to random_access_iterators, used for
368 // string::iterator, _CharT*, etc.
369 template<typename _FwdIterator>
370 _GLIBCXX20_CONSTEXPR
371 void
372 _M_construct(_FwdIterator __beg, _FwdIterator __end,
373 std::forward_iterator_tag);
374
375 _GLIBCXX20_CONSTEXPR
376 void
377 _M_construct(size_type __req, _CharT __c);
378
379 // Construct using block of memory of known size.
380 // If _Terminated is true assume that source is already 0 terminated.
381 template<bool _Terminated>
382 _GLIBCXX20_CONSTEXPR
383 void
384 _M_construct(const _CharT *__c, size_type __n);
385
386#if __cplusplus >= 202302L
387 constexpr void
388 _M_construct(basic_string&& __str, size_type __pos, size_type __n);
389#endif
390
391 _GLIBCXX20_CONSTEXPR
392 allocator_type&
393 _M_get_allocator()
394 { return _M_dataplus; }
395
396 _GLIBCXX20_CONSTEXPR
397 const allocator_type&
398 _M_get_allocator() const
399 { return _M_dataplus; }
400
401 // Ensure that _M_local_buf is the active member of the union.
402 __attribute__((__always_inline__))
403 _GLIBCXX14_CONSTEXPR
404 void
405 _M_init_local_buf() _GLIBCXX_NOEXCEPT
406 {
407#if __glibcxx_is_constant_evaluated
408 if (std::is_constant_evaluated())
409 for (size_type __i = 0; __i <= _S_local_capacity; ++__i)
410 _M_local_buf[__i] = _CharT();
411#endif
412 }
413
414 __attribute__((__always_inline__))
415 _GLIBCXX14_CONSTEXPR
416 pointer
417 _M_use_local_data() _GLIBCXX_NOEXCEPT
418 {
419#if __cpp_lib_is_constant_evaluated
420 _M_init_local_buf();
421#endif
422 return _M_local_data();
423 }
424
425 private:
426
427#ifdef _GLIBCXX_DISAMBIGUATE_REPLACE_INST
428 // The explicit instantiations in misc-inst.cc require this due to
429 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64063
430 template<typename _Tp, bool _Requires =
431 !__are_same<_Tp, _CharT*>::__value
432 && !__are_same<_Tp, const _CharT*>::__value
433 && !__are_same<_Tp, iterator>::__value
434 && !__are_same<_Tp, const_iterator>::__value>
435 struct __enable_if_not_native_iterator
436 { typedef basic_string& __type; };
437 template<typename _Tp>
438 struct __enable_if_not_native_iterator<_Tp, false> { };
439#endif
440
441 _GLIBCXX20_CONSTEXPR
442 size_type
443 _M_check(size_type __pos, const char* __s) const
444 {
445 if (__pos > this->size())
446 __throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > "
447 "this->size() (which is %zu)"),
448 __s, (size_t)__pos, (size_t)this->size());
449 return __pos;
450 }
451
452 _GLIBCXX20_CONSTEXPR
453 void
454 _M_check_length(size_type __n1, size_type __n2, const char* __s) const
455 {
456 if (this->max_size() - (this->size() - __n1) < __n2)
457 __throw_length_error(__N(__s));
458 }
459
460
461 // NB: _M_limit doesn't check for a bad __pos value.
462 _GLIBCXX20_CONSTEXPR
463 size_type
464 _M_limit(size_type __pos, size_type __off) const _GLIBCXX_NOEXCEPT
465 {
466 const bool __testoff = __off < this->size() - __pos;
467 return __testoff ? __off : this->size() - __pos;
468 }
469
470 // True if _Rep and source do not overlap.
471 bool
472 _M_disjunct(const _CharT* __s) const _GLIBCXX_NOEXCEPT
473 {
474 return (less<const _CharT*>()(__s, _M_data())
475 || less<const _CharT*>()(_M_data() + this->size(), __s));
476 }
477
478 // When __n = 1 way faster than the general multichar
479 // traits_type::copy/move/assign.
480 _GLIBCXX20_CONSTEXPR
481 static void
482 _S_copy(_CharT* __d, const _CharT* __s, size_type __n)
483 {
484 if (__n == 1)
485 traits_type::assign(*__d, *__s);
486 else
487 traits_type::copy(__d, __s, __n);
488 }
489
490 _GLIBCXX20_CONSTEXPR
491 static void
492 _S_move(_CharT* __d, const _CharT* __s, size_type __n)
493 {
494 if (__n == 1)
495 traits_type::assign(*__d, *__s);
496 else
497 traits_type::move(__d, __s, __n);
498 }
499
500 _GLIBCXX20_CONSTEXPR
501 static void
502 _S_assign(_CharT* __d, size_type __n, _CharT __c)
503 {
504 if (__n == 1)
505 traits_type::assign(*__d, __c);
506 else
507 traits_type::assign(__d, __n, __c);
508 }
509
510#pragma GCC diagnostic push
511#pragma GCC diagnostic ignored "-Wc++17-extensions"
512 // _S_copy_chars is a separate template to permit specialization
513 // to optimize for the common case of pointers as iterators.
514 template<class _Iterator>
515 _GLIBCXX20_CONSTEXPR
516 static void
517 _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2)
518 {
519#if __cplusplus >= 201103L
520 using _IterBase = decltype(std::__niter_base(__k1));
521 if constexpr (__or_<is_same<_IterBase, _CharT*>,
522 is_same<_IterBase, const _CharT*>>::value)
523 _S_copy(__p, std::__niter_base(__k1), __k2 - __k1);
524#if __cpp_lib_concepts
525 else if constexpr (requires {
526 requires contiguous_iterator<_Iterator>;
527 { std::to_address(__k1) }
528 -> convertible_to<const _CharT*>;
529 })
530 {
531 const auto __d = __k2 - __k1;
532 (void) (__k1 + __d); // See P3349R1
533 _S_copy(__p, std::to_address(__k1), static_cast<size_type>(__d));
534 }
535#endif
536 else
537#endif
538 for (; __k1 != __k2; ++__k1, (void)++__p)
539 traits_type::assign(*__p, static_cast<_CharT>(*__k1));
540 }
541#pragma GCC diagnostic pop
542
543#if __cplusplus < 201103L || defined _GLIBCXX_DEFINING_STRING_INSTANTIATIONS
544 static void
545 _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2)
546 { _S_copy_chars(__p, __k1.base(), __k2.base()); }
547
548 static void
549 _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2)
550 { _S_copy_chars(__p, __k1.base(), __k2.base()); }
551
552 static void
553 _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2)
554 { _S_copy(__p, __k1, __k2 - __k1); }
555
556 static void
557 _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2)
558 { _S_copy(__p, __k1, __k2 - __k1); }
559#endif
560
561#if __glibcxx_containers_ranges // C++ >= 23
562 // pre: __n == ranges::distance(__rg). __p+[0,__n) is a valid range.
563 template<typename _Rg>
564 static constexpr void
565 _S_copy_range(pointer __p, _Rg&& __rg, size_type __n)
566 {
567 if constexpr (requires {
568 requires ranges::contiguous_range<_Rg>;
569 { ranges::data(std::forward<_Rg>(__rg)) }
570 -> convertible_to<const _CharT*>;
571 })
572 _S_copy(__p, ranges::data(std::forward<_Rg>(__rg)), __n);
573 else
574 {
575 auto __first = ranges::begin(__rg);
576 const auto __last = ranges::end(__rg);
577 for (; __first != __last; ++__first)
578 traits_type::assign(*__p++, static_cast<_CharT>(*__first));
579 }
580 }
581#endif
582
583 _GLIBCXX20_CONSTEXPR
584 static int
585 _S_compare(size_type __n1, size_type __n2) _GLIBCXX_NOEXCEPT
586 {
587 const difference_type __d = difference_type(__n1 - __n2);
588
589 if (__d > __gnu_cxx::__numeric_traits<int>::__max)
590 return __gnu_cxx::__numeric_traits<int>::__max;
591 else if (__d < __gnu_cxx::__numeric_traits<int>::__min)
592 return __gnu_cxx::__numeric_traits<int>::__min;
593 else
594 return int(__d);
595 }
596
597 _GLIBCXX20_CONSTEXPR
598 void
599 _M_assign(const basic_string&);
600
601 _GLIBCXX20_CONSTEXPR
602 void
603 _M_mutate(size_type __pos, size_type __len1, const _CharT* __s,
604 size_type __len2);
605
606 _GLIBCXX20_CONSTEXPR
607 void
608 _M_erase(size_type __pos, size_type __n);
609
610 public:
611 // Construct/copy/destroy:
612 // NB: We overload ctors in some cases instead of using default
613 // arguments, per 17.4.4.4 para. 2 item 2.
614
615 /**
616 * @brief Default constructor creates an empty string.
617 */
618 _GLIBCXX20_CONSTEXPR
619 basic_string()
620 _GLIBCXX_NOEXCEPT_IF(is_nothrow_default_constructible<_Alloc>::value)
621#if __cpp_concepts && __glibcxx_type_trait_variable_templates
622 requires is_default_constructible_v<_Alloc>
623#endif
624 : _M_dataplus(_M_local_data())
625 {
626 _M_init_local_buf();
627 _M_set_length(0);
628 }
629
630 /**
631 * @brief Construct an empty string using allocator @a a.
632 */
633 _GLIBCXX20_CONSTEXPR
634 explicit
635 basic_string(const _Alloc& __a) _GLIBCXX_NOEXCEPT
636 : _M_dataplus(_M_local_data(), __a)
637 {
638 _M_init_local_buf();
639 _M_set_length(0);
640 }
641
642 /**
643 * @brief Construct string with copy of value of @a __str.
644 * @param __str Source string.
645 */
646 _GLIBCXX20_CONSTEXPR
647 basic_string(const basic_string& __str)
648 : _M_dataplus(_M_local_data(),
649 _Alloc_traits::_S_select_on_copy(__str._M_get_allocator()))
650 {
651 _M_construct<true>(__str._M_data(), __str.length());
652 }
653
654 // _GLIBCXX_RESOLVE_LIB_DEFECTS
655 // 2583. no way to supply an allocator for basic_string(str, pos)
656 /**
657 * @brief Construct string as copy of a substring.
658 * @param __str Source string.
659 * @param __pos Index of first character to copy from.
660 * @param __a Allocator to use.
661 */
662 _GLIBCXX20_CONSTEXPR
663 basic_string(const basic_string& __str, size_type __pos,
664 const _Alloc& __a = _Alloc())
665 : _M_dataplus(_M_local_data(), __a)
666 {
667 const _CharT* __start = __str._M_data()
668 + __str._M_check(__pos, "basic_string::basic_string");
669 _M_construct(__start, __start + __str._M_limit(__pos, npos),
670 std::forward_iterator_tag());
671 }
672
673 /**
674 * @brief Construct string as copy of a substring.
675 * @param __str Source string.
676 * @param __pos Index of first character to copy from.
677 * @param __n Number of characters to copy.
678 */
679 _GLIBCXX20_CONSTEXPR
680 basic_string(const basic_string& __str, size_type __pos,
681 size_type __n)
682 : _M_dataplus(_M_local_data())
683 {
684 const _CharT* __start = __str._M_data()
685 + __str._M_check(__pos, "basic_string::basic_string");
686 _M_construct(__start, __start + __str._M_limit(__pos, __n),
687 std::forward_iterator_tag());
688 }
689
690 /**
691 * @brief Construct string as copy of a substring.
692 * @param __str Source string.
693 * @param __pos Index of first character to copy from.
694 * @param __n Number of characters to copy.
695 * @param __a Allocator to use.
696 */
697 _GLIBCXX20_CONSTEXPR
698 basic_string(const basic_string& __str, size_type __pos,
699 size_type __n, const _Alloc& __a)
700 : _M_dataplus(_M_local_data(), __a)
701 {
702 const _CharT* __start
703 = __str._M_data() + __str._M_check(__pos, "string::string");
704 _M_construct(__start, __start + __str._M_limit(__pos, __n),
705 std::forward_iterator_tag());
706 }
707
708#if __cplusplus >= 202302L
709 _GLIBCXX20_CONSTEXPR
710 basic_string(basic_string&& __str, size_type __pos,
711 const _Alloc& __a = _Alloc())
712 : _M_dataplus(_M_local_data(), __a)
713 {
714 __pos = __str._M_check(__pos, "string::string");
715 _M_construct(std::move(__str), __pos, __str.length() - __pos);
716 }
717
718 _GLIBCXX20_CONSTEXPR
719 basic_string(basic_string&& __str, size_type __pos, size_type __n,
720 const _Alloc& __a = _Alloc())
721 : _M_dataplus(_M_local_data(), __a)
722 {
723 __pos = __str._M_check(__pos, "string::string");
724 _M_construct(std::move(__str), __pos, __str._M_limit(__pos, __n));
725 }
726#endif // C++23
727
728 /**
729 * @brief Construct string initialized by a character %array.
730 * @param __s Source character %array.
731 * @param __n Number of characters to copy.
732 * @param __a Allocator to use (default is default allocator).
733 *
734 * NB: @a __s must have at least @a __n characters, &apos;\\0&apos;
735 * has no special meaning.
736 */
737 _GLIBCXX20_CONSTEXPR
738 basic_string(const _CharT* __s, size_type __n,
739 const _Alloc& __a = _Alloc())
740 : _M_dataplus(_M_local_data(), __a)
741 {
742 // NB: Not required, but considered best practice.
743 if (__s == 0 && __n > 0)
744 std::__throw_logic_error(__N("basic_string: "
745 "construction from null is not valid"));
746 _M_construct(__s, __s + __n, std::forward_iterator_tag());
747 }
748
749 /**
750 * @brief Construct string as copy of a C string.
751 * @param __s Source C string.
752 * @param __a Allocator to use (default is default allocator).
753 */
754#if __cpp_deduction_guides && ! defined _GLIBCXX_DEFINING_STRING_INSTANTIATIONS
755 // _GLIBCXX_RESOLVE_LIB_DEFECTS
756 // 3076. basic_string CTAD ambiguity
757 template<typename = _RequireAllocator<_Alloc>>
758#endif
759 _GLIBCXX20_CONSTEXPR
760 basic_string(const _CharT* __s, const _Alloc& __a = _Alloc())
761 : _M_dataplus(_M_local_data(), __a)
762 {
763 // NB: Not required, but considered best practice.
764 if (__s == 0)
765 std::__throw_logic_error(__N("basic_string: "
766 "construction from null is not valid"));
767 const _CharT* __end = __s + traits_type::length(__s);
768 _M_construct(__s, __end, forward_iterator_tag());
769 }
770
771 /**
772 * @brief Construct string as multiple characters.
773 * @param __n Number of characters.
774 * @param __c Character to use.
775 * @param __a Allocator to use (default is default allocator).
776 */
777#if __cpp_deduction_guides && ! defined _GLIBCXX_DEFINING_STRING_INSTANTIATIONS
778 // _GLIBCXX_RESOLVE_LIB_DEFECTS
779 // 3076. basic_string CTAD ambiguity
780 template<typename = _RequireAllocator<_Alloc>>
781#endif
782 _GLIBCXX20_CONSTEXPR
783 basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc())
784 : _M_dataplus(_M_local_data(), __a)
785 { _M_construct(__n, __c); }
786
787#if __cplusplus >= 201103L
788 /**
789 * @brief Move construct string.
790 * @param __str Source string.
791 *
792 * The newly-created string contains the exact contents of @a __str.
793 * @a __str is a valid, but unspecified string.
794 */
795 _GLIBCXX20_CONSTEXPR
796 basic_string(basic_string&& __str) noexcept
797 : _M_dataplus(_M_local_data(), std::move(__str._M_get_allocator()))
798 {
799 if (__str._M_is_local())
800 {
801 _M_init_local_buf();
802 traits_type::copy(_M_local_buf, __str._M_local_buf,
803 __str.length() + 1);
804 }
805 else
806 {
807 _M_data(__str._M_data());
808 _M_capacity(__str._M_allocated_capacity);
809 }
810
811 // Must use _M_length() here not _M_set_length() because
812 // basic_stringbuf relies on writing into unallocated capacity so
813 // we mess up the contents if we put a '\0' in the string.
814 _M_length(__str.length());
815 __str._M_data(__str._M_use_local_data());
816 __str._M_set_length(0);
817 }
818
819#if __glibcxx_containers_ranges // C++ >= 23
820 /**
821 * @brief Construct a string from a range.
822 * @since C++23
823 */
824 template<__detail::__container_compatible_range<_CharT> _Rg>
825 constexpr
826 basic_string(from_range_t, _Rg&& __rg, const _Alloc& __a = _Alloc())
827 : basic_string(__a)
828 {
829 if constexpr (ranges::forward_range<_Rg> || ranges::sized_range<_Rg>)
830 {
831 const auto __n = static_cast<size_type>(ranges::distance(__rg));
832 reserve(__n);
833 _S_copy_range(_M_data(), std::forward<_Rg>(__rg), __n);
834 _M_set_length(__n);
835 }
836 else
837 {
838 auto __first = ranges::begin(__rg);
839 const auto __last = ranges::end(__rg);
840 for (; __first != __last; ++__first)
841 push_back(*__first);
842 }
843 }
844#endif
845
846 /**
847 * @brief Construct string from an initializer %list.
848 * @param __l std::initializer_list of characters.
849 * @param __a Allocator to use (default is default allocator).
850 */
851 _GLIBCXX20_CONSTEXPR
852 basic_string(initializer_list<_CharT> __l, const _Alloc& __a = _Alloc())
853 : _M_dataplus(_M_local_data(), __a)
854 { _M_construct(__l.begin(), __l.end(), std::forward_iterator_tag()); }
855
856 _GLIBCXX20_CONSTEXPR
857 basic_string(const basic_string& __str, const _Alloc& __a)
858 : _M_dataplus(_M_local_data(), __a)
859 { _M_construct(__str.begin(), __str.end(), std::forward_iterator_tag()); }
860
861 _GLIBCXX20_CONSTEXPR
862 basic_string(basic_string&& __str, const _Alloc& __a)
863 noexcept(_Alloc_traits::_S_always_equal())
864 : _M_dataplus(_M_local_data(), __a)
865 {
866 if (__str._M_is_local())
867 {
868 _M_init_local_buf();
869 traits_type::copy(_M_local_buf, __str._M_local_buf,
870 __str.length() + 1);
871 _M_length(__str.length());
872 __str._M_set_length(0);
873 }
874 else if (_Alloc_traits::_S_always_equal()
875 || __str.get_allocator() == __a)
876 {
877 _M_data(__str._M_data());
878 _M_length(__str.length());
879 _M_capacity(__str._M_allocated_capacity);
880 __str._M_data(__str._M_use_local_data());
881 __str._M_set_length(0);
882 }
883 else
884 _M_construct(__str.begin(), __str.end(), std::forward_iterator_tag());
885 }
886#endif // C++11
887
888#if __cplusplus >= 202100L
889 basic_string(nullptr_t) = delete;
890 basic_string& operator=(nullptr_t) = delete;
891#endif // C++23
892
893 /**
894 * @brief Construct string as copy of a range.
895 * @param __beg Start of range.
896 * @param __end End of range.
897 * @param __a Allocator to use (default is default allocator).
898 */
899#if __cplusplus >= 201103L
900 template<typename _InputIterator,
901 typename = std::_RequireInputIter<_InputIterator>>
902#else
903 template<typename _InputIterator>
904#endif
905 _GLIBCXX20_CONSTEXPR
906 basic_string(_InputIterator __beg, _InputIterator __end,
907 const _Alloc& __a = _Alloc())
908 : _M_dataplus(_M_local_data(), __a), _M_string_length(0)
909 {
910#if __cplusplus >= 201103L
911 _M_construct(__beg, __end, std::__iterator_category(__beg));
912#else
913 typedef typename std::__is_integer<_InputIterator>::__type _Integral;
914 _M_construct_aux(__beg, __end, _Integral());
915#endif
916 }
917
918#ifdef __glibcxx_string_view // >= C++17
919 /**
920 * @brief Construct string from a substring of a string_view.
921 * @param __t Source object convertible to string view.
922 * @param __pos The index of the first character to copy from __t.
923 * @param __n The number of characters to copy from __t.
924 * @param __a Allocator to use.
925 */
926 template<typename _Tp,
927 typename = enable_if_t<is_convertible_v<const _Tp&, __sv_type>>>
928 _GLIBCXX20_CONSTEXPR
929 basic_string(const _Tp& __t, size_type __pos, size_type __n,
930 const _Alloc& __a = _Alloc())
931 : basic_string(_S_to_string_view(__t).substr(__pos, __n), __a) { }
932
933 /**
934 * @brief Construct string from a string_view.
935 * @param __t Source object convertible to string view.
936 * @param __a Allocator to use (default is default allocator).
937 */
938 template<typename _Tp, typename = _If_sv<_Tp, void>>
939 _GLIBCXX20_CONSTEXPR
940 explicit
941 basic_string(const _Tp& __t, const _Alloc& __a = _Alloc())
942 : basic_string(__sv_wrapper(_S_to_string_view(__t)), __a) { }
943#endif // C++17
944
945 /**
946 * @brief Destroy the string instance.
947 */
948 _GLIBCXX20_CONSTEXPR
949 ~basic_string()
950 { _M_dispose(); }
951
952 /**
953 * @brief Assign the value of @a str to this string.
954 * @param __str Source string.
955 */
956 _GLIBCXX20_CONSTEXPR
957 basic_string&
958 operator=(const basic_string& __str)
959 {
960 return this->assign(__str);
961 }
962
963 /**
964 * @brief Copy contents of @a s into this string.
965 * @param __s Source null-terminated string.
966 */
967 _GLIBCXX20_CONSTEXPR
968 basic_string&
969 operator=(const _CharT* __s)
970 { return this->assign(__s); }
971
972 /**
973 * @brief Set value to string of length 1.
974 * @param __c Source character.
975 *
976 * Assigning to a character makes this string length 1 and
977 * (*this)[0] == @a c.
978 */
979 _GLIBCXX20_CONSTEXPR
980 basic_string&
981 operator=(_CharT __c)
982 {
983 this->assign(1, __c);
984 return *this;
985 }
986
987#if __cplusplus >= 201103L
988 /**
989 * @brief Move assign the value of @a str to this string.
990 * @param __str Source string.
991 *
992 * The contents of @a str are moved into this string (without copying).
993 * @a str is a valid, but unspecified string.
994 */
995 // _GLIBCXX_RESOLVE_LIB_DEFECTS
996 // 2063. Contradictory requirements for string move assignment
997 _GLIBCXX20_CONSTEXPR
998 basic_string&
999 operator=(basic_string&& __str)
1000 noexcept(_Alloc_traits::_S_nothrow_move())
1001 {
1002 const bool __equal_allocs = _Alloc_traits::_S_always_equal()
1003 || _M_get_allocator() == __str._M_get_allocator();
1004 if (!_M_is_local() && _Alloc_traits::_S_propagate_on_move_assign()
1005 && !__equal_allocs)
1006 {
1007 // Destroy existing storage before replacing allocator.
1008 _M_destroy(_M_allocated_capacity);
1009 _M_data(_M_local_data());
1010 _M_set_length(0);
1011 }
1012 // Replace allocator if POCMA is true.
1013 std::__alloc_on_move(_M_get_allocator(), __str._M_get_allocator());
1014
1015 if (__str._M_is_local())
1016 {
1017 // We've always got room for a short string, just copy it
1018 // (unless this is a self-move, because that would violate the
1019 // char_traits::copy precondition that the ranges don't overlap).
1020 if (__builtin_expect(std::__addressof(__str) != this, true))
1021 {
1022 if (__str.size())
1023 this->_S_copy(_M_data(), __str._M_data(), __str.size());
1024 _M_set_length(__str.size());
1025 }
1026 }
1027 else if (_Alloc_traits::_S_propagate_on_move_assign() || __equal_allocs)
1028 {
1029 // Just move the allocated pointer, our allocator can free it.
1030 pointer __data = nullptr;
1031 size_type __capacity;
1032 if (!_M_is_local())
1033 {
1034 if (__equal_allocs)
1035 {
1036 // __str can reuse our existing storage.
1037 __data = _M_data();
1038 __capacity = _M_allocated_capacity;
1039 }
1040 else // __str can't use it, so free it.
1041 _M_destroy(_M_allocated_capacity);
1042 }
1043
1044 _M_data(__str._M_data());
1045 _M_length(__str.length());
1046 _M_capacity(__str._M_allocated_capacity);
1047 if (__data)
1048 {
1049 __str._M_data(__data);
1050 __str._M_capacity(__capacity);
1051 }
1052 else
1053 __str._M_data(__str._M_use_local_data());
1054 }
1055 else // Need to do a deep copy
1056 _M_assign(__str);
1057 __str.clear();
1058 return *this;
1059 }
1060
1061 /**
1062 * @brief Set value to string constructed from initializer %list.
1063 * @param __l std::initializer_list.
1064 */
1065 _GLIBCXX20_CONSTEXPR
1066 basic_string&
1067 operator=(initializer_list<_CharT> __l)
1068 {
1069 this->assign(__l.begin(), __l.size());
1070 return *this;
1071 }
1072#endif // C++11
1073
1074#ifdef __glibcxx_string_view // >= C++17
1075 /**
1076 * @brief Set value to string constructed from a string_view.
1077 * @param __svt An object convertible to string_view.
1078 */
1079 template<typename _Tp>
1080 _GLIBCXX20_CONSTEXPR
1081 _If_sv<_Tp, basic_string&>
1082 operator=(const _Tp& __svt)
1083 { return this->assign(__svt); }
1084
1085 /**
1086 * @brief Convert to a string_view.
1087 * @return A string_view.
1088 */
1089 _GLIBCXX20_CONSTEXPR
1090 operator __sv_type() const noexcept
1091 { return __sv_type(data(), size()); }
1092#endif // C++17
1093
1094 // Iterators:
1095 /**
1096 * Returns a read/write iterator that points to the first character in
1097 * the %string.
1098 */
1099 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1100 iterator
1101 begin() _GLIBCXX_NOEXCEPT
1102 { return iterator(_M_data()); }
1103
1104 /**
1105 * Returns a read-only (constant) iterator that points to the first
1106 * character in the %string.
1107 */
1108 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1109 const_iterator
1110 begin() const _GLIBCXX_NOEXCEPT
1111 { return const_iterator(_M_data()); }
1112
1113 /**
1114 * Returns a read/write iterator that points one past the last
1115 * character in the %string.
1116 */
1117 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1118 iterator
1119 end() _GLIBCXX_NOEXCEPT
1120 { return iterator(_M_data() + this->size()); }
1121
1122 /**
1123 * Returns a read-only (constant) iterator that points one past the
1124 * last character in the %string.
1125 */
1126 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1127 const_iterator
1128 end() const _GLIBCXX_NOEXCEPT
1129 { return const_iterator(_M_data() + this->size()); }
1130
1131 /**
1132 * Returns a read/write reverse iterator that points to the last
1133 * character in the %string. Iteration is done in reverse element
1134 * order.
1135 */
1136 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1137 reverse_iterator
1138 rbegin() _GLIBCXX_NOEXCEPT
1139 { return reverse_iterator(this->end()); }
1140
1141 /**
1142 * Returns a read-only (constant) reverse iterator that points
1143 * to the last character in the %string. Iteration is done in
1144 * reverse element order.
1145 */
1146 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1147 const_reverse_iterator
1148 rbegin() const _GLIBCXX_NOEXCEPT
1149 { return const_reverse_iterator(this->end()); }
1150
1151 /**
1152 * Returns a read/write reverse iterator that points to one before the
1153 * first character in the %string. Iteration is done in reverse
1154 * element order.
1155 */
1156 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1157 reverse_iterator
1158 rend() _GLIBCXX_NOEXCEPT
1159 { return reverse_iterator(this->begin()); }
1160
1161 /**
1162 * Returns a read-only (constant) reverse iterator that points
1163 * to one before the first character in the %string. Iteration
1164 * is done in reverse element order.
1165 */
1166 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1167 const_reverse_iterator
1168 rend() const _GLIBCXX_NOEXCEPT
1169 { return const_reverse_iterator(this->begin()); }
1170
1171#if __cplusplus >= 201103L
1172 /**
1173 * Returns a read-only (constant) iterator that points to the first
1174 * character in the %string.
1175 */
1176 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1177 const_iterator
1178 cbegin() const noexcept
1179 { return const_iterator(this->_M_data()); }
1180
1181 /**
1182 * Returns a read-only (constant) iterator that points one past the
1183 * last character in the %string.
1184 */
1185 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1186 const_iterator
1187 cend() const noexcept
1188 { return const_iterator(this->_M_data() + this->size()); }
1189
1190 /**
1191 * Returns a read-only (constant) reverse iterator that points
1192 * to the last character in the %string. Iteration is done in
1193 * reverse element order.
1194 */
1195 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1196 const_reverse_iterator
1197 crbegin() const noexcept
1198 { return const_reverse_iterator(this->end()); }
1199
1200 /**
1201 * Returns a read-only (constant) reverse iterator that points
1202 * to one before the first character in the %string. Iteration
1203 * is done in reverse element order.
1204 */
1205 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1206 const_reverse_iterator
1207 crend() const noexcept
1208 { return const_reverse_iterator(this->begin()); }
1209#endif
1210
1211 public:
1212 // Capacity:
1213 /// Returns the number of characters in the string, not including any
1214 /// null-termination.
1215 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1216 size_type
1217 size() const _GLIBCXX_NOEXCEPT
1218 {
1219 size_type __sz = _M_string_length;
1220 if (__sz > max_size ())
1221 __builtin_unreachable();
1222 return __sz;
1223 }
1224
1225 /// Returns the number of characters in the string, not including any
1226 /// null-termination.
1227 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1228 size_type
1229 length() const _GLIBCXX_NOEXCEPT
1230 { return size(); }
1231
1232 /// Returns the size() of the largest possible %string.
1233 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1234 size_type
1235 max_size() const _GLIBCXX_NOEXCEPT
1236 {
1237 const size_t __diffmax
1238 = __gnu_cxx::__numeric_traits<ptrdiff_t>::__max / sizeof(_CharT);
1239 const size_t __allocmax = _Alloc_traits::max_size(_M_get_allocator());
1240 return (std::min)(__diffmax, __allocmax) - 1;
1241 }
1242
1243 /**
1244 * @brief Resizes the %string to the specified number of characters.
1245 * @param __n Number of characters the %string should contain.
1246 * @param __c Character to fill any new elements.
1247 *
1248 * This function will %resize the %string to the specified
1249 * number of characters. If the number is smaller than the
1250 * %string's current size the %string is truncated, otherwise
1251 * the %string is extended and new elements are %set to @a __c.
1252 */
1253 _GLIBCXX20_CONSTEXPR
1254 void
1255 resize(size_type __n, _CharT __c);
1256
1257 /**
1258 * @brief Resizes the %string to the specified number of characters.
1259 * @param __n Number of characters the %string should contain.
1260 *
1261 * This function will resize the %string to the specified length. If
1262 * the new size is smaller than the %string's current size the %string
1263 * is truncated, otherwise the %string is extended and new characters
1264 * are default-constructed. For basic types such as char, this means
1265 * setting them to 0.
1266 */
1267 _GLIBCXX20_CONSTEXPR
1268 void
1269 resize(size_type __n)
1270 { this->resize(__n, _CharT()); }
1271
1272#if __cplusplus >= 201103L
1273#pragma GCC diagnostic push
1274#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1275 /// A non-binding request to reduce capacity() to size().
1276 _GLIBCXX20_CONSTEXPR
1277 void
1278 shrink_to_fit() noexcept
1279 { reserve(); }
1280#pragma GCC diagnostic pop
1281#endif
1282
1283#ifdef __glibcxx_string_resize_and_overwrite // C++ >= 23
1284 /** Resize the string and call a function to fill it.
1285 *
1286 * @param __n The maximum size requested.
1287 * @param __op A callable object that writes characters to the string.
1288 *
1289 * This is a low-level function that is easy to misuse, be careful.
1290 *
1291 * Calling `str.resize_and_overwrite(n, op)` will reserve at least `n`
1292 * characters in `str`, evaluate `n2 = std::move(op)(str.data(), n)`,
1293 * and finally set the string length to `n2` (adding a null terminator
1294 * at the end). The function object `op` is allowed to write to the
1295 * extra capacity added by the initial reserve operation, which is not
1296 * allowed if you just call `str.reserve(n)` yourself.
1297 *
1298 * This can be used to efficiently fill a `string` buffer without the
1299 * overhead of zero-initializing characters that will be overwritten
1300 * anyway.
1301 *
1302 * The callable `op` must not access the string directly (only through
1303 * the pointer passed as its first argument), must not write more than
1304 * `n` characters to the string, must return a value no greater than `n`,
1305 * and must ensure that all characters up to the returned length are
1306 * valid after it returns (i.e. there must be no uninitialized values
1307 * left in the string after the call, because accessing them would
1308 * have undefined behaviour). If `op` exits by throwing an exception
1309 * the behaviour is undefined.
1310 *
1311 * @since C++23
1312 */
1313 template<typename _Operation>
1314 constexpr void
1315 resize_and_overwrite(size_type __n, _Operation __op);
1316#endif
1317
1318#if __cplusplus >= 201103L
1319 /// Non-standard version of resize_and_overwrite for C++11 and above.
1320 template<typename _Operation>
1321 _GLIBCXX20_CONSTEXPR void
1322 __resize_and_overwrite(size_type __n, _Operation __op);
1323#endif
1324
1325 /**
1326 * Returns the total number of characters that the %string can hold
1327 * before needing to allocate more memory.
1328 */
1329 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1330 size_type
1331 capacity() const _GLIBCXX_NOEXCEPT
1332 {
1333 size_t __sz = _M_is_local() ? size_type(_S_local_capacity)
1334 : _M_allocated_capacity;
1335 if (__sz < _S_local_capacity || __sz > max_size ())
1336 __builtin_unreachable();
1337 return __sz;
1338 }
1339
1340 /**
1341 * @brief Attempt to preallocate enough memory for specified number of
1342 * characters.
1343 * @param __res_arg Number of characters required.
1344 * @throw std::length_error If @a __res_arg exceeds @c max_size().
1345 *
1346 * This function attempts to reserve enough memory for the
1347 * %string to hold the specified number of characters. If the
1348 * number requested is more than max_size(), length_error is
1349 * thrown.
1350 *
1351 * The advantage of this function is that if optimal code is a
1352 * necessity and the user can determine the string length that will be
1353 * required, the user can reserve the memory in %advance, and thus
1354 * prevent a possible reallocation of memory and copying of %string
1355 * data.
1356 */
1357 _GLIBCXX20_CONSTEXPR
1358 void
1359 reserve(size_type __res_arg);
1360
1361 /**
1362 * Equivalent to shrink_to_fit().
1363 */
1364#if __cplusplus >= 202002L
1365 [[deprecated("use shrink_to_fit() instead")]]
1366#endif
1367 _GLIBCXX20_CONSTEXPR
1368 void
1369 reserve();
1370
1371 /**
1372 * Erases the string, making it empty.
1373 */
1374 _GLIBCXX20_CONSTEXPR
1375 void
1376 clear() _GLIBCXX_NOEXCEPT
1377 { _M_set_length(0); }
1378
1379 /**
1380 * Returns true if the %string is empty. Equivalent to
1381 * <code>*this == ""</code>.
1382 */
1383 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1384 bool
1385 empty() const _GLIBCXX_NOEXCEPT
1386 { return _M_string_length == 0; }
1387
1388 // Element access:
1389 /**
1390 * @brief Subscript access to the data contained in the %string.
1391 * @param __pos The index of the character to access.
1392 * @return Read-only (constant) reference to the character.
1393 *
1394 * This operator allows for easy, array-style, data access.
1395 * Note that data access with this operator is unchecked and
1396 * out_of_range lookups are not defined. (For checked lookups
1397 * see at().)
1398 */
1399 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1400 const_reference
1401 operator[] (size_type __pos) const _GLIBCXX_NOEXCEPT
1402 {
1403 __glibcxx_assert(__pos <= size());
1404 return _M_data()[__pos];
1405 }
1406
1407 /**
1408 * @brief Subscript access to the data contained in the %string.
1409 * @param __pos The index of the character to access.
1410 * @return Read/write reference to the character.
1411 *
1412 * This operator allows for easy, array-style, data access.
1413 * Note that data access with this operator is unchecked and
1414 * out_of_range lookups are not defined. (For checked lookups
1415 * see at().)
1416 */
1417 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1418 reference
1419 operator[](size_type __pos)
1420 {
1421 // Allow pos == size() both in C++98 mode, as v3 extension,
1422 // and in C++11 mode.
1423 __glibcxx_assert(__pos <= size());
1424 // In pedantic mode be strict in C++98 mode.
1425 _GLIBCXX_DEBUG_PEDASSERT(__cplusplus >= 201103L || __pos < size());
1426 return _M_data()[__pos];
1427 }
1428
1429 /**
1430 * @brief Provides access to the data contained in the %string.
1431 * @param __n The index of the character to access.
1432 * @return Read-only (const) reference to the character.
1433 * @throw std::out_of_range If @a n is an invalid index.
1434 *
1435 * This function provides for safer data access. The parameter is
1436 * first checked that it is in the range of the string. The function
1437 * throws out_of_range if the check fails.
1438 */
1439 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1440 const_reference
1441 at(size_type __n) const
1442 {
1443 if (__n >= this->size())
1444 __throw_out_of_range_fmt(__N("basic_string::at: __n "
1445 "(which is %zu) >= this->size() "
1446 "(which is %zu)"),
1447 __n, this->size());
1448 return _M_data()[__n];
1449 }
1450
1451 /**
1452 * @brief Provides access to the data contained in the %string.
1453 * @param __n The index of the character to access.
1454 * @return Read/write reference to the character.
1455 * @throw std::out_of_range If @a n is an invalid index.
1456 *
1457 * This function provides for safer data access. The parameter is
1458 * first checked that it is in the range of the string. The function
1459 * throws out_of_range if the check fails.
1460 */
1461 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1462 reference
1463 at(size_type __n)
1464 {
1465 if (__n >= size())
1466 __throw_out_of_range_fmt(__N("basic_string::at: __n "
1467 "(which is %zu) >= this->size() "
1468 "(which is %zu)"),
1469 __n, this->size());
1470 return _M_data()[__n];
1471 }
1472
1473#if __cplusplus >= 201103L
1474 /**
1475 * Returns a read/write reference to the data at the first
1476 * element of the %string.
1477 */
1478 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1479 reference
1480 front() noexcept
1481 {
1482 __glibcxx_assert(!empty());
1483 return operator[](0);
1484 }
1485
1486 /**
1487 * Returns a read-only (constant) reference to the data at the first
1488 * element of the %string.
1489 */
1490 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1491 const_reference
1492 front() const noexcept
1493 {
1494 __glibcxx_assert(!empty());
1495 return operator[](0);
1496 }
1497
1498 /**
1499 * Returns a read/write reference to the data at the last
1500 * element of the %string.
1501 */
1502 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1503 reference
1504 back() noexcept
1505 {
1506 __glibcxx_assert(!empty());
1507 return operator[](this->size() - 1);
1508 }
1509
1510 /**
1511 * Returns a read-only (constant) reference to the data at the
1512 * last element of the %string.
1513 */
1514 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1515 const_reference
1516 back() const noexcept
1517 {
1518 __glibcxx_assert(!empty());
1519 return operator[](this->size() - 1);
1520 }
1521#endif
1522
1523 // Modifiers:
1524 /**
1525 * @brief Append a string to this string.
1526 * @param __str The string to append.
1527 * @return Reference to this string.
1528 */
1529 _GLIBCXX20_CONSTEXPR
1530 basic_string&
1531 operator+=(const basic_string& __str)
1532 { return this->append(__str); }
1533
1534 /**
1535 * @brief Append a C string.
1536 * @param __s The C string to append.
1537 * @return Reference to this string.
1538 */
1539 _GLIBCXX20_CONSTEXPR
1540 basic_string&
1541 operator+=(const _CharT* __s)
1542 { return this->append(__s); }
1543
1544 /**
1545 * @brief Append a character.
1546 * @param __c The character to append.
1547 * @return Reference to this string.
1548 */
1549 _GLIBCXX20_CONSTEXPR
1550 basic_string&
1551 operator+=(_CharT __c)
1552 {
1553 this->push_back(__c);
1554 return *this;
1555 }
1556
1557#if __cplusplus >= 201103L
1558 /**
1559 * @brief Append an initializer_list of characters.
1560 * @param __l The initializer_list of characters to be appended.
1561 * @return Reference to this string.
1562 */
1563 _GLIBCXX20_CONSTEXPR
1564 basic_string&
1565 operator+=(initializer_list<_CharT> __l)
1566 { return this->append(__l.begin(), __l.size()); }
1567#endif // C++11
1568
1569#ifdef __glibcxx_string_view // >= C++17
1570 /**
1571 * @brief Append a string_view.
1572 * @param __svt An object convertible to string_view to be appended.
1573 * @return Reference to this string.
1574 */
1575 template<typename _Tp>
1576 _GLIBCXX20_CONSTEXPR
1577 _If_sv<_Tp, basic_string&>
1578 operator+=(const _Tp& __svt)
1579 { return this->append(__svt); }
1580#endif // C++17
1581
1582 /**
1583 * @brief Append a string to this string.
1584 * @param __str The string to append.
1585 * @return Reference to this string.
1586 */
1587 _GLIBCXX20_CONSTEXPR
1588 basic_string&
1589 append(const basic_string& __str)
1590 { return this->append(__str._M_data(), __str.size()); }
1591
1592 /**
1593 * @brief Append a substring.
1594 * @param __str The string to append.
1595 * @param __pos Index of the first character of str to append.
1596 * @param __n The number of characters to append.
1597 * @return Reference to this string.
1598 * @throw std::out_of_range if @a __pos is not a valid index.
1599 *
1600 * This function appends @a __n characters from @a __str
1601 * starting at @a __pos to this string. If @a __n is is larger
1602 * than the number of available characters in @a __str, the
1603 * remainder of @a __str is appended.
1604 */
1605 _GLIBCXX20_CONSTEXPR
1606 basic_string&
1607 append(const basic_string& __str, size_type __pos, size_type __n = npos)
1608 { return this->append(__str._M_data()
1609 + __str._M_check(__pos, "basic_string::append"),
1610 __str._M_limit(__pos, __n)); }
1611
1612 /**
1613 * @brief Append a C substring.
1614 * @param __s The C string to append.
1615 * @param __n The number of characters to append.
1616 * @return Reference to this string.
1617 */
1618 _GLIBCXX20_CONSTEXPR
1619 basic_string&
1620 append(const _CharT* __s, size_type __n)
1621 {
1622 __glibcxx_requires_string_len(__s, __n);
1623 _M_check_length(size_type(0), __n, "basic_string::append");
1624 return _M_append(__s, __n);
1625 }
1626
1627 /**
1628 * @brief Append a C string.
1629 * @param __s The C string to append.
1630 * @return Reference to this string.
1631 */
1632 _GLIBCXX20_CONSTEXPR
1633 basic_string&
1634 append(const _CharT* __s)
1635 {
1636 __glibcxx_requires_string(__s);
1637 const size_type __n = traits_type::length(__s);
1638 _M_check_length(size_type(0), __n, "basic_string::append");
1639 return _M_append(__s, __n);
1640 }
1641
1642 /**
1643 * @brief Append multiple characters.
1644 * @param __n The number of characters to append.
1645 * @param __c The character to use.
1646 * @return Reference to this string.
1647 *
1648 * Appends __n copies of __c to this string.
1649 */
1650 _GLIBCXX20_CONSTEXPR
1651 basic_string&
1652 append(size_type __n, _CharT __c)
1653 { return _M_replace_aux(this->size(), size_type(0), __n, __c); }
1654
1655#if __glibcxx_containers_ranges // C++ >= 23
1656 /**
1657 * @brief Append a range to the string.
1658 * @param __rg A range of values that are convertible to `value_type`.
1659 * @since C++23
1660 *
1661 * The range `__rg` is allowed to overlap with `*this`.
1662 */
1663 template<__detail::__container_compatible_range<_CharT> _Rg>
1664 constexpr basic_string&
1665 append_range(_Rg&& __rg)
1666 {
1667 // N.B. __rg may overlap with *this, so we must copy from __rg before
1668 // existing elements or iterators referring to *this are invalidated.
1669 // e.g. in s.append_range(views::concat(s, str)), rg overlaps s.
1670 if constexpr (ranges::forward_range<_Rg> || ranges::sized_range<_Rg>)
1671 {
1672 const auto __len = size_type(ranges::distance(__rg));
1673
1674 // Don't care if this addition wraps around, we check it below:
1675 const size_type __newlen = size() + __len;
1676
1677 if ((capacity() - size()) >= __len)
1678 _S_copy_range(_M_data() + size(), std::forward<_Rg>(__rg),
1679 __len);
1680 else
1681 {
1682 _M_check_length(0, __len, "basic_string::append_range");
1683 basic_string __s(_M_get_allocator());
1684 __s.reserve(__newlen);
1685 _S_copy_range(__s._M_data() + size(), std::forward<_Rg>(__rg),
1686 __len);
1687 _S_copy(__s._M_data(), _M_data(), size());
1688 if (!_M_is_local())
1689 _M_destroy(_M_allocated_capacity);
1690 _M_data(__s._M_data());
1691 _M_capacity(__s._M_allocated_capacity);
1692 __s._M_data(__s._M_local_data());
1693 __s._M_length(0);
1694 }
1695 _M_set_length(__newlen); // adds null-terminator
1696 }
1697 else
1698 {
1699 basic_string __s(from_range, std::forward<_Rg>(__rg),
1700 _M_get_allocator());
1701 append(__s);
1702 }
1703 return *this;
1704 }
1705#endif
1706
1707#if __cplusplus >= 201103L
1708 /**
1709 * @brief Append an initializer_list of characters.
1710 * @param __l The initializer_list of characters to append.
1711 * @return Reference to this string.
1712 */
1713 _GLIBCXX20_CONSTEXPR
1714 basic_string&
1715 append(initializer_list<_CharT> __l)
1716 { return this->append(__l.begin(), __l.size()); }
1717#endif // C++11
1718
1719 /**
1720 * @brief Append a range of characters.
1721 * @param __first Iterator referencing the first character to append.
1722 * @param __last Iterator marking the end of the range.
1723 * @return Reference to this string.
1724 *
1725 * Appends characters in the range [__first,__last) to this string.
1726 */
1727#if __cplusplus >= 201103L
1728 template<class _InputIterator,
1729 typename = std::_RequireInputIter<_InputIterator>>
1730 _GLIBCXX20_CONSTEXPR
1731#else
1732 template<class _InputIterator>
1733#endif
1734 basic_string&
1735 append(_InputIterator __first, _InputIterator __last)
1736 { return this->replace(end(), end(), __first, __last); }
1737
1738#ifdef __glibcxx_string_view
1739 /**
1740 * @brief Append a string_view.
1741 * @param __svt An object convertible to string_view to be appended.
1742 * @return Reference to this string.
1743 */
1744 template<typename _Tp>
1745 _GLIBCXX20_CONSTEXPR
1746 _If_sv<_Tp, basic_string&>
1747 append(const _Tp& __svt)
1748 {
1749 __sv_type __sv = __svt;
1750 return this->append(__sv.data(), __sv.size());
1751 }
1752
1753 /**
1754 * @brief Append a range of characters from a string_view.
1755 * @param __svt An object convertible to string_view to be appended from.
1756 * @param __pos The position in the string_view to append from.
1757 * @param __n The number of characters to append from the string_view.
1758 * @return Reference to this string.
1759 */
1760 template<typename _Tp>
1761 _GLIBCXX20_CONSTEXPR
1762 _If_sv<_Tp, basic_string&>
1763 append(const _Tp& __svt, size_type __pos, size_type __n = npos)
1764 {
1765 __sv_type __sv = __svt;
1766 return _M_append(__sv.data()
1767 + std::__sv_check(__sv.size(), __pos, "basic_string::append"),
1768 std::__sv_limit(__sv.size(), __pos, __n));
1769 }
1770
1771 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1772 // 3662. basic_string::append/assign(NTBS, pos, n) suboptimal
1773 /**
1774 * @brief Append a C substring.
1775 * @param __s The C string to append.
1776 * @param __pos The position in the C string to append from.
1777 * @param __n The number of characters to append.
1778 * @return Reference to this string.
1779 */
1780 _GLIBCXX20_CONSTEXPR
1781 basic_string&
1782 append(const _CharT* __s, size_type __pos, size_type __n)
1783 { return append(__sv_type(__s).substr(__pos, __n)); }
1784#endif // C++17
1785
1786 /**
1787 * @brief Append a single character.
1788 * @param __c Character to append.
1789 */
1790 _GLIBCXX20_CONSTEXPR
1791 void
1792 push_back(_CharT __c)
1793 {
1794 const size_type __size = this->size();
1795 if (__size + 1 > this->capacity())
1796 this->_M_mutate(__size, size_type(0), 0, size_type(1));
1797 traits_type::assign(this->_M_data()[__size], __c);
1798 this->_M_set_length(__size + 1);
1799 }
1800
1801 /**
1802 * @brief Set value to contents of another string.
1803 * @param __str Source string to use.
1804 * @return Reference to this string.
1805 */
1806 _GLIBCXX20_CONSTEXPR
1807 basic_string&
1808 assign(const basic_string& __str)
1809 {
1810#if __cplusplus >= 201103L
1811 if (_Alloc_traits::_S_propagate_on_copy_assign())
1812 {
1813 if (!_Alloc_traits::_S_always_equal() && !_M_is_local()
1814 && _M_get_allocator() != __str._M_get_allocator())
1815 {
1816 // Propagating allocator cannot free existing storage so must
1817 // deallocate it before replacing current allocator.
1818 if (__str.size() <= _S_local_capacity)
1819 {
1820 _M_destroy(_M_allocated_capacity);
1821 _M_data(_M_use_local_data());
1822 _M_set_length(0);
1823 }
1824 else
1825 {
1826 const auto __len = __str.size();
1827 auto __alloc = __str._M_get_allocator();
1828 // If this allocation throws there are no effects:
1829 auto __r = _S_allocate_at_least(__alloc, __len + 1);
1830 _M_destroy(_M_allocated_capacity);
1831 _M_data(__r.__ptr);
1832 _M_capacity(__r.__count - 1);
1833 _M_set_length(__len);
1834 }
1835 }
1836 std::__alloc_on_copy(_M_get_allocator(), __str._M_get_allocator());
1837 }
1838#endif
1839 this->_M_assign(__str);
1840 return *this;
1841 }
1842
1843#if __cplusplus >= 201103L
1844 /**
1845 * @brief Set value to contents of another string.
1846 * @param __str Source string to use.
1847 * @return Reference to this string.
1848 *
1849 * This function sets this string to the exact contents of @a __str.
1850 * @a __str is a valid, but unspecified string.
1851 */
1852 _GLIBCXX20_CONSTEXPR
1853 basic_string&
1854 assign(basic_string&& __str)
1855 noexcept(_Alloc_traits::_S_nothrow_move())
1856 {
1857 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1858 // 2063. Contradictory requirements for string move assignment
1859 return *this = std::move(__str);
1860 }
1861#endif // C++11
1862
1863 /**
1864 * @brief Set value to a substring of a string.
1865 * @param __str The string to use.
1866 * @param __pos Index of the first character of str.
1867 * @param __n Number of characters to use.
1868 * @return Reference to this string.
1869 * @throw std::out_of_range if @a pos is not a valid index.
1870 *
1871 * This function sets this string to the substring of @a __str
1872 * consisting of @a __n characters at @a __pos. If @a __n is
1873 * is larger than the number of available characters in @a
1874 * __str, the remainder of @a __str is used.
1875 */
1876 _GLIBCXX20_CONSTEXPR
1877 basic_string&
1878 assign(const basic_string& __str, size_type __pos, size_type __n = npos)
1879 { return _M_replace(size_type(0), this->size(), __str._M_data()
1880 + __str._M_check(__pos, "basic_string::assign"),
1881 __str._M_limit(__pos, __n)); }
1882
1883 /**
1884 * @brief Set value to a C substring.
1885 * @param __s The C string to use.
1886 * @param __n Number of characters to use.
1887 * @return Reference to this string.
1888 *
1889 * This function sets the value of this string to the first @a __n
1890 * characters of @a __s. If @a __n is is larger than the number of
1891 * available characters in @a __s, the remainder of @a __s is used.
1892 */
1893 _GLIBCXX20_CONSTEXPR
1894 basic_string&
1895 assign(const _CharT* __s, size_type __n)
1896 {
1897 __glibcxx_requires_string_len(__s, __n);
1898 return _M_replace(size_type(0), this->size(), __s, __n);
1899 }
1900
1901 /**
1902 * @brief Set value to contents of a C string.
1903 * @param __s The C string to use.
1904 * @return Reference to this string.
1905 *
1906 * This function sets the value of this string to the value of @a __s.
1907 * The data is copied, so there is no dependence on @a __s once the
1908 * function returns.
1909 */
1910 _GLIBCXX20_CONSTEXPR
1911 basic_string&
1912 assign(const _CharT* __s)
1913 {
1914 __glibcxx_requires_string(__s);
1915 return _M_replace(size_type(0), this->size(), __s,
1916 traits_type::length(__s));
1917 }
1918
1919 /**
1920 * @brief Set value to multiple characters.
1921 * @param __n Length of the resulting string.
1922 * @param __c The character to use.
1923 * @return Reference to this string.
1924 *
1925 * This function sets the value of this string to @a __n copies of
1926 * character @a __c.
1927 */
1928 _GLIBCXX20_CONSTEXPR
1929 basic_string&
1930 assign(size_type __n, _CharT __c)
1931 { return _M_replace_aux(size_type(0), this->size(), __n, __c); }
1932
1933 /**
1934 * @brief Set value to a range of characters.
1935 * @param __first Iterator referencing the first character to append.
1936 * @param __last Iterator marking the end of the range.
1937 * @return Reference to this string.
1938 *
1939 * Sets value of string to characters in the range [__first,__last).
1940 */
1941#if __cplusplus >= 201103L
1942#pragma GCC diagnostic push
1943#pragma GCC diagnostic ignored "-Wc++17-extensions"
1944 template<class _InputIterator,
1945 typename = std::_RequireInputIter<_InputIterator>>
1946 _GLIBCXX20_CONSTEXPR
1947 basic_string&
1948 assign(_InputIterator __first, _InputIterator __last)
1949 {
1950 using _IterTraits = iterator_traits<_InputIterator>;
1951 if constexpr (is_pointer<decltype(std::__niter_base(__first))>::value
1952 && is_same<typename _IterTraits::value_type,
1953 _CharT>::value)
1954 {
1955 __glibcxx_requires_valid_range(__first, __last);
1956 return _M_replace(size_type(0), size(),
1957 std::__niter_base(__first), __last - __first);
1958 }
1959#if __cplusplus >= 202002L
1960 else if constexpr (contiguous_iterator<_InputIterator>
1961 && is_same_v<iter_value_t<_InputIterator>,
1962 _CharT>)
1963 {
1964 __glibcxx_requires_valid_range(__first, __last);
1965 return _M_replace(size_type(0), size(),
1966 std::to_address(__first), __last - __first);
1967 }
1968#endif
1969 else
1970 return *this = basic_string(__first, __last, get_allocator());
1971 }
1972#pragma GCC diagnostic pop
1973#else
1974 template<class _InputIterator>
1975 basic_string&
1976 assign(_InputIterator __first, _InputIterator __last)
1977 { return this->replace(begin(), end(), __first, __last); }
1978#endif
1979
1980#if __glibcxx_containers_ranges // C++ >= 23
1981 /**
1982 * @brief Assign a range to the string.
1983 * @param __rg A range of values that are convertible to `value_type`.
1984 * @since C++23
1985 *
1986 * The range `__rg` is allowed to overlap with `*this`.
1987 */
1988 template<__detail::__container_compatible_range<_CharT> _Rg>
1989 constexpr basic_string&
1990 assign_range(_Rg&& __rg)
1991 {
1992 basic_string __s(from_range, std::forward<_Rg>(__rg),
1993 _M_get_allocator());
1994 assign(std::move(__s));
1995 return *this;
1996 }
1997#endif
1998
1999#if __cplusplus >= 201103L
2000 /**
2001 * @brief Set value to an initializer_list of characters.
2002 * @param __l The initializer_list of characters to assign.
2003 * @return Reference to this string.
2004 */
2005 _GLIBCXX20_CONSTEXPR
2006 basic_string&
2007 assign(initializer_list<_CharT> __l)
2008 {
2009 // The initializer_list array cannot alias the characters in *this
2010 // so we don't need to use replace to that case.
2011 const size_type __n = __l.size();
2012 if (__n > capacity())
2013 *this = basic_string(__l.begin(), __l.end(), get_allocator());
2014 else
2015 {
2016 if (__n)
2017 _S_copy(_M_data(), __l.begin(), __n);
2018 _M_set_length(__n);
2019 }
2020 return *this;
2021 }
2022#endif // C++11
2023
2024#ifdef __glibcxx_string_view // >= C++17
2025 /**
2026 * @brief Set value from a string_view.
2027 * @param __svt The source object convertible to string_view.
2028 * @return Reference to this string.
2029 */
2030 template<typename _Tp>
2031 _GLIBCXX20_CONSTEXPR
2032 _If_sv<_Tp, basic_string&>
2033 assign(const _Tp& __svt)
2034 {
2035 __sv_type __sv = __svt;
2036 return this->assign(__sv.data(), __sv.size());
2037 }
2038
2039 /**
2040 * @brief Set value from a range of characters in a string_view.
2041 * @param __svt The source object convertible to string_view.
2042 * @param __pos The position in the string_view to assign from.
2043 * @param __n The number of characters to assign.
2044 * @return Reference to this string.
2045 */
2046 template<typename _Tp>
2047 _GLIBCXX20_CONSTEXPR
2048 _If_sv<_Tp, basic_string&>
2049 assign(const _Tp& __svt, size_type __pos, size_type __n = npos)
2050 {
2051 __sv_type __sv = __svt;
2052 return _M_replace(size_type(0), this->size(),
2053 __sv.data()
2054 + std::__sv_check(__sv.size(), __pos, "basic_string::assign"),
2055 std::__sv_limit(__sv.size(), __pos, __n));
2056 }
2057
2058 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2059 // 3662. basic_string::append/assign(NTBS, pos, n) suboptimal
2060 /**
2061 * @brief Set value to a C substring.
2062 * @param __s The C string to use.
2063 * @param __pos The position in the C string to assign from.
2064 * @param __n Number of characters to use.
2065 * @return Reference to this string.
2066 */
2067 _GLIBCXX20_CONSTEXPR
2068 basic_string&
2069 assign(const _CharT* __s, size_type __pos, size_type __n)
2070 { return assign(__sv_type(__s).substr(__pos, __n)); }
2071#endif // C++17
2072
2073#if __cplusplus >= 201103L
2074 /**
2075 * @brief Insert multiple characters.
2076 * @param __p Const_iterator referencing location in string to
2077 * insert at.
2078 * @param __n Number of characters to insert
2079 * @param __c The character to insert.
2080 * @return Iterator referencing the first inserted char.
2081 * @throw std::length_error If new length exceeds @c max_size().
2082 *
2083 * Inserts @a __n copies of character @a __c starting at the
2084 * position referenced by iterator @a __p. If adding
2085 * characters causes the length to exceed max_size(),
2086 * length_error is thrown. The value of the string doesn't
2087 * change if an error is thrown.
2088 */
2089 _GLIBCXX20_CONSTEXPR
2090 iterator
2091 insert(const_iterator __p, size_type __n, _CharT __c)
2092 {
2093 _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end());
2094 const size_type __pos = __p - begin();
2095 this->replace(__p, __p, __n, __c);
2096 return iterator(this->_M_data() + __pos);
2097 }
2098#else
2099 /**
2100 * @brief Insert multiple characters.
2101 * @param __p Iterator referencing location in string to insert at.
2102 * @param __n Number of characters to insert
2103 * @param __c The character to insert.
2104 * @throw std::length_error If new length exceeds @c max_size().
2105 *
2106 * Inserts @a __n copies of character @a __c starting at the
2107 * position referenced by iterator @a __p. If adding
2108 * characters causes the length to exceed max_size(),
2109 * length_error is thrown. The value of the string doesn't
2110 * change if an error is thrown.
2111 */
2112 void
2113 insert(iterator __p, size_type __n, _CharT __c)
2114 { this->replace(__p, __p, __n, __c); }
2115#endif
2116
2117#if __cplusplus >= 201103L
2118 /**
2119 * @brief Insert a range of characters.
2120 * @param __p Const_iterator referencing location in string to
2121 * insert at.
2122 * @param __beg Start of range.
2123 * @param __end End of range.
2124 * @return Iterator referencing the first inserted char.
2125 * @throw std::length_error If new length exceeds @c max_size().
2126 *
2127 * Inserts characters in range [beg,end). If adding characters
2128 * causes the length to exceed max_size(), length_error is
2129 * thrown. The value of the string doesn't change if an error
2130 * is thrown.
2131 */
2132 template<class _InputIterator,
2133 typename = std::_RequireInputIter<_InputIterator>>
2134 _GLIBCXX20_CONSTEXPR
2135 iterator
2136 insert(const_iterator __p, _InputIterator __beg, _InputIterator __end)
2137 {
2138 _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end());
2139 const size_type __pos = __p - begin();
2140 this->replace(__p, __p, __beg, __end);
2141 return iterator(this->_M_data() + __pos);
2142 }
2143#else
2144 /**
2145 * @brief Insert a range of characters.
2146 * @param __p Iterator referencing location in string to insert at.
2147 * @param __beg Start of range.
2148 * @param __end End of range.
2149 * @throw std::length_error If new length exceeds @c max_size().
2150 *
2151 * Inserts characters in range [__beg,__end). If adding
2152 * characters causes the length to exceed max_size(),
2153 * length_error is thrown. The value of the string doesn't
2154 * change if an error is thrown.
2155 */
2156 template<class _InputIterator>
2157 void
2158 insert(iterator __p, _InputIterator __beg, _InputIterator __end)
2159 { this->replace(__p, __p, __beg, __end); }
2160#endif
2161
2162#if __glibcxx_containers_ranges // C++ >= 23
2163 /**
2164 * @brief Insert a range into the string.
2165 * @param __rg A range of values that are convertible to `value_type`.
2166 * @since C++23
2167 *
2168 * The range `__rg` is allowed to overlap with `*this`.
2169 */
2170 template<__detail::__container_compatible_range<_CharT> _Rg>
2171 constexpr iterator
2172 insert_range(const_iterator __p, _Rg&& __rg)
2173 {
2174 auto __pos = __p - cbegin();
2175
2176 if constexpr (ranges::forward_range<_Rg>)
2177 if (ranges::empty(__rg))
2178 return begin() + __pos;
2179
2180
2181 if (__p == cend())
2182 append_range(std::forward<_Rg>(__rg));
2183 else
2184 {
2185 basic_string __s(from_range, std::forward<_Rg>(__rg),
2186 _M_get_allocator());
2187 insert(__pos, __s);
2188 }
2189 return begin() + __pos;
2190 }
2191#endif
2192
2193#if __cplusplus >= 201103L
2194 /**
2195 * @brief Insert an initializer_list of characters.
2196 * @param __p Iterator referencing location in string to insert at.
2197 * @param __l The initializer_list of characters to insert.
2198 * @throw std::length_error If new length exceeds @c max_size().
2199 */
2200 _GLIBCXX20_CONSTEXPR
2201 iterator
2202 insert(const_iterator __p, initializer_list<_CharT> __l)
2203 { return this->insert(__p, __l.begin(), __l.end()); }
2204
2205#ifdef _GLIBCXX_DEFINING_STRING_INSTANTIATIONS
2206 // See PR libstdc++/83328
2207 void
2208 insert(iterator __p, initializer_list<_CharT> __l)
2209 {
2210 _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end());
2211 this->insert(__p - begin(), __l.begin(), __l.size());
2212 }
2213#endif
2214#endif // C++11
2215
2216 /**
2217 * @brief Insert value of a string.
2218 * @param __pos1 Position in string to insert at.
2219 * @param __str The string to insert.
2220 * @return Reference to this string.
2221 * @throw std::length_error If new length exceeds @c max_size().
2222 *
2223 * Inserts value of @a __str starting at @a __pos1. If adding
2224 * characters causes the length to exceed max_size(),
2225 * length_error is thrown. The value of the string doesn't
2226 * change if an error is thrown.
2227 */
2228 _GLIBCXX20_CONSTEXPR
2229 basic_string&
2230 insert(size_type __pos1, const basic_string& __str)
2231 { return this->replace(__pos1, size_type(0),
2232 __str._M_data(), __str.size()); }
2233
2234 /**
2235 * @brief Insert a substring.
2236 * @param __pos1 Position in string to insert at.
2237 * @param __str The string to insert.
2238 * @param __pos2 Start of characters in str to insert.
2239 * @param __n Number of characters to insert.
2240 * @return Reference to this string.
2241 * @throw std::length_error If new length exceeds @c max_size().
2242 * @throw std::out_of_range If @a pos1 > size() or
2243 * @a __pos2 > @a str.size().
2244 *
2245 * Starting at @a pos1, insert @a __n character of @a __str
2246 * beginning with @a __pos2. If adding characters causes the
2247 * length to exceed max_size(), length_error is thrown. If @a
2248 * __pos1 is beyond the end of this string or @a __pos2 is
2249 * beyond the end of @a __str, out_of_range is thrown. The
2250 * value of the string doesn't change if an error is thrown.
2251 */
2252 _GLIBCXX20_CONSTEXPR
2253 basic_string&
2254 insert(size_type __pos1, const basic_string& __str,
2255 size_type __pos2, size_type __n = npos)
2256 { return this->replace(__pos1, size_type(0), __str._M_data()
2257 + __str._M_check(__pos2, "basic_string::insert"),
2258 __str._M_limit(__pos2, __n)); }
2259
2260 /**
2261 * @brief Insert a C substring.
2262 * @param __pos Position in string to insert at.
2263 * @param __s The C string to insert.
2264 * @param __n The number of characters to insert.
2265 * @return Reference to this string.
2266 * @throw std::length_error If new length exceeds @c max_size().
2267 * @throw std::out_of_range If @a __pos is beyond the end of this
2268 * string.
2269 *
2270 * Inserts the first @a __n characters of @a __s starting at @a
2271 * __pos. If adding characters causes the length to exceed
2272 * max_size(), length_error is thrown. If @a __pos is beyond
2273 * end(), out_of_range is thrown. The value of the string
2274 * doesn't change if an error is thrown.
2275 */
2276 _GLIBCXX20_CONSTEXPR
2277 basic_string&
2278 insert(size_type __pos, const _CharT* __s, size_type __n)
2279 { return this->replace(__pos, size_type(0), __s, __n); }
2280
2281 /**
2282 * @brief Insert a C string.
2283 * @param __pos Position in string to insert at.
2284 * @param __s The C string to insert.
2285 * @return Reference to this string.
2286 * @throw std::length_error If new length exceeds @c max_size().
2287 * @throw std::out_of_range If @a pos is beyond the end of this
2288 * string.
2289 *
2290 * Inserts the first @a n characters of @a __s starting at @a __pos. If
2291 * adding characters causes the length to exceed max_size(),
2292 * length_error is thrown. If @a __pos is beyond end(), out_of_range is
2293 * thrown. The value of the string doesn't change if an error is
2294 * thrown.
2295 */
2296 _GLIBCXX20_CONSTEXPR
2297 basic_string&
2298 insert(size_type __pos, const _CharT* __s)
2299 {
2300 __glibcxx_requires_string(__s);
2301 return this->replace(__pos, size_type(0), __s,
2302 traits_type::length(__s));
2303 }
2304
2305 /**
2306 * @brief Insert multiple characters.
2307 * @param __pos Index in string to insert at.
2308 * @param __n Number of characters to insert
2309 * @param __c The character to insert.
2310 * @return Reference to this string.
2311 * @throw std::length_error If new length exceeds @c max_size().
2312 * @throw std::out_of_range If @a __pos is beyond the end of this
2313 * string.
2314 *
2315 * Inserts @a __n copies of character @a __c starting at index
2316 * @a __pos. If adding characters causes the length to exceed
2317 * max_size(), length_error is thrown. If @a __pos > length(),
2318 * out_of_range is thrown. The value of the string doesn't
2319 * change if an error is thrown.
2320 */
2321 _GLIBCXX20_CONSTEXPR
2322 basic_string&
2323 insert(size_type __pos, size_type __n, _CharT __c)
2324 { return _M_replace_aux(_M_check(__pos, "basic_string::insert"),
2325 size_type(0), __n, __c); }
2326
2327 /**
2328 * @brief Insert one character.
2329 * @param __p Iterator referencing position in string to insert at.
2330 * @param __c The character to insert.
2331 * @return Iterator referencing newly inserted char.
2332 * @throw std::length_error If new length exceeds @c max_size().
2333 *
2334 * Inserts character @a __c at position referenced by @a __p.
2335 * If adding character causes the length to exceed max_size(),
2336 * length_error is thrown. If @a __p is beyond end of string,
2337 * out_of_range is thrown. The value of the string doesn't
2338 * change if an error is thrown.
2339 */
2340 _GLIBCXX20_CONSTEXPR
2341 iterator
2342 insert(__const_iterator __p, _CharT __c)
2343 {
2344 _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end());
2345 const size_type __pos = __p - begin();
2346 _M_replace_aux(__pos, size_type(0), size_type(1), __c);
2347 return iterator(_M_data() + __pos);
2348 }
2349
2350#ifdef __glibcxx_string_view // >= C++17
2351 /**
2352 * @brief Insert a string_view.
2353 * @param __pos Position in string to insert at.
2354 * @param __svt The object convertible to string_view to insert.
2355 * @return Reference to this string.
2356 */
2357 template<typename _Tp>
2358 _GLIBCXX20_CONSTEXPR
2359 _If_sv<_Tp, basic_string&>
2360 insert(size_type __pos, const _Tp& __svt)
2361 {
2362 __sv_type __sv = __svt;
2363 return this->insert(__pos, __sv.data(), __sv.size());
2364 }
2365
2366 /**
2367 * @brief Insert a string_view.
2368 * @param __pos1 Position in string to insert at.
2369 * @param __svt The object convertible to string_view to insert from.
2370 * @param __pos2 Start of characters in str to insert.
2371 * @param __n The number of characters to insert.
2372 * @return Reference to this string.
2373 */
2374 template<typename _Tp>
2375 _GLIBCXX20_CONSTEXPR
2376 _If_sv<_Tp, basic_string&>
2377 insert(size_type __pos1, const _Tp& __svt,
2378 size_type __pos2, size_type __n = npos)
2379 {
2380 __sv_type __sv = __svt;
2381 return this->replace(__pos1, size_type(0),
2382 __sv.data()
2383 + std::__sv_check(__sv.size(), __pos2, "basic_string::insert"),
2384 std::__sv_limit(__sv.size(), __pos2, __n));
2385 }
2386#endif // C++17
2387
2388 /**
2389 * @brief Remove characters.
2390 * @param __pos Index of first character to remove (default 0).
2391 * @param __n Number of characters to remove (default remainder).
2392 * @return Reference to this string.
2393 * @throw std::out_of_range If @a pos is beyond the end of this
2394 * string.
2395 *
2396 * Removes @a __n characters from this string starting at @a
2397 * __pos. The length of the string is reduced by @a __n. If
2398 * there are < @a __n characters to remove, the remainder of
2399 * the string is truncated. If @a __p is beyond end of string,
2400 * out_of_range is thrown. The value of the string doesn't
2401 * change if an error is thrown.
2402 */
2403 _GLIBCXX20_CONSTEXPR
2404 basic_string&
2405 erase(size_type __pos = 0, size_type __n = npos)
2406 {
2407 _M_check(__pos, "basic_string::erase");
2408 if (__n == npos)
2409 this->_M_set_length(__pos);
2410 else if (__n != 0)
2411 this->_M_erase(__pos, _M_limit(__pos, __n));
2412 return *this;
2413 }
2414
2415 /**
2416 * @brief Remove one character.
2417 * @param __position Iterator referencing the character to remove.
2418 * @return iterator referencing same location after removal.
2419 *
2420 * Removes the character at @a __position from this string. The value
2421 * of the string doesn't change if an error is thrown.
2422 */
2423 _GLIBCXX20_CONSTEXPR
2424 iterator
2425 erase(__const_iterator __position)
2426 {
2427 _GLIBCXX_DEBUG_PEDASSERT(__position >= begin()
2428 && __position < end());
2429 const size_type __pos = __position - begin();
2430 this->_M_erase(__pos, size_type(1));
2431 return iterator(_M_data() + __pos);
2432 }
2433
2434 /**
2435 * @brief Remove a range of characters.
2436 * @param __first Iterator referencing the first character to remove.
2437 * @param __last Iterator referencing the end of the range.
2438 * @return Iterator referencing location of first after removal.
2439 *
2440 * Removes the characters in the range [first,last) from this string.
2441 * The value of the string doesn't change if an error is thrown.
2442 */
2443 _GLIBCXX20_CONSTEXPR
2444 iterator
2445 erase(__const_iterator __first, __const_iterator __last)
2446 {
2447 _GLIBCXX_DEBUG_PEDASSERT(__first >= begin() && __first <= __last
2448 && __last <= end());
2449 const size_type __pos = __first - begin();
2450 if (__last == end())
2451 this->_M_set_length(__pos);
2452 else
2453 this->_M_erase(__pos, __last - __first);
2454 return iterator(this->_M_data() + __pos);
2455 }
2456
2457#if __cplusplus >= 201103L
2458 /**
2459 * @brief Remove the last character.
2460 *
2461 * The string must be non-empty.
2462 */
2463 _GLIBCXX20_CONSTEXPR
2464 void
2465 pop_back() noexcept
2466 {
2467 __glibcxx_assert(!empty());
2468 _M_erase(size() - 1, 1);
2469 }
2470#endif // C++11
2471
2472 /**
2473 * @brief Replace characters with value from another string.
2474 * @param __pos Index of first character to replace.
2475 * @param __n Number of characters to be replaced.
2476 * @param __str String to insert.
2477 * @return Reference to this string.
2478 * @throw std::out_of_range If @a pos is beyond the end of this
2479 * string.
2480 * @throw std::length_error If new length exceeds @c max_size().
2481 *
2482 * Removes the characters in the range [__pos,__pos+__n) from
2483 * this string. In place, the value of @a __str is inserted.
2484 * If @a __pos is beyond end of string, out_of_range is thrown.
2485 * If the length of the result exceeds max_size(), length_error
2486 * is thrown. The value of the string doesn't change if an
2487 * error is thrown.
2488 */
2489 _GLIBCXX20_CONSTEXPR
2490 basic_string&
2491 replace(size_type __pos, size_type __n, const basic_string& __str)
2492 { return this->replace(__pos, __n, __str._M_data(), __str.size()); }
2493
2494 /**
2495 * @brief Replace characters with value from another string.
2496 * @param __pos1 Index of first character to replace.
2497 * @param __n1 Number of characters to be replaced.
2498 * @param __str String to insert.
2499 * @param __pos2 Index of first character of str to use.
2500 * @param __n2 Number of characters from str to use.
2501 * @return Reference to this string.
2502 * @throw std::out_of_range If @a __pos1 > size() or @a __pos2 >
2503 * __str.size().
2504 * @throw std::length_error If new length exceeds @c max_size().
2505 *
2506 * Removes the characters in the range [__pos1,__pos1 + n) from this
2507 * string. In place, the value of @a __str is inserted. If @a __pos is
2508 * beyond end of string, out_of_range is thrown. If the length of the
2509 * result exceeds max_size(), length_error is thrown. The value of the
2510 * string doesn't change if an error is thrown.
2511 */
2512 _GLIBCXX20_CONSTEXPR
2513 basic_string&
2514 replace(size_type __pos1, size_type __n1, const basic_string& __str,
2515 size_type __pos2, size_type __n2 = npos)
2516 { return this->replace(__pos1, __n1, __str._M_data()
2517 + __str._M_check(__pos2, "basic_string::replace"),
2518 __str._M_limit(__pos2, __n2)); }
2519
2520 /**
2521 * @brief Replace characters with value of a C substring.
2522 * @param __pos Index of first character to replace.
2523 * @param __n1 Number of characters to be replaced.
2524 * @param __s C string to insert.
2525 * @param __n2 Number of characters from @a s to use.
2526 * @return Reference to this string.
2527 * @throw std::out_of_range If @a pos1 > size().
2528 * @throw std::length_error If new length exceeds @c max_size().
2529 *
2530 * Removes the characters in the range [__pos,__pos + __n1)
2531 * from this string. In place, the first @a __n2 characters of
2532 * @a __s are inserted, or all of @a __s if @a __n2 is too large. If
2533 * @a __pos is beyond end of string, out_of_range is thrown. If
2534 * the length of result exceeds max_size(), length_error is
2535 * thrown. The value of the string doesn't change if an error
2536 * is thrown.
2537 */
2538 _GLIBCXX20_CONSTEXPR
2539 basic_string&
2540 replace(size_type __pos, size_type __n1, const _CharT* __s,
2541 size_type __n2)
2542 {
2543 __glibcxx_requires_string_len(__s, __n2);
2544 return _M_replace(_M_check(__pos, "basic_string::replace"),
2545 _M_limit(__pos, __n1), __s, __n2);
2546 }
2547
2548 /**
2549 * @brief Replace characters with value of a C string.
2550 * @param __pos Index of first character to replace.
2551 * @param __n1 Number of characters to be replaced.
2552 * @param __s C string to insert.
2553 * @return Reference to this string.
2554 * @throw std::out_of_range If @a pos > size().
2555 * @throw std::length_error If new length exceeds @c max_size().
2556 *
2557 * Removes the characters in the range [__pos,__pos + __n1)
2558 * from this string. In place, the characters of @a __s are
2559 * inserted. If @a __pos is beyond end of string, out_of_range
2560 * is thrown. If the length of result exceeds max_size(),
2561 * length_error is thrown. The value of the string doesn't
2562 * change if an error is thrown.
2563 */
2564 _GLIBCXX20_CONSTEXPR
2565 basic_string&
2566 replace(size_type __pos, size_type __n1, const _CharT* __s)
2567 {
2568 __glibcxx_requires_string(__s);
2569 return this->replace(__pos, __n1, __s, traits_type::length(__s));
2570 }
2571
2572 /**
2573 * @brief Replace characters with multiple characters.
2574 * @param __pos Index of first character to replace.
2575 * @param __n1 Number of characters to be replaced.
2576 * @param __n2 Number of characters to insert.
2577 * @param __c Character to insert.
2578 * @return Reference to this string.
2579 * @throw std::out_of_range If @a __pos > size().
2580 * @throw std::length_error If new length exceeds @c max_size().
2581 *
2582 * Removes the characters in the range [pos,pos + n1) from this
2583 * string. In place, @a __n2 copies of @a __c are inserted.
2584 * If @a __pos is beyond end of string, out_of_range is thrown.
2585 * If the length of result exceeds max_size(), length_error is
2586 * thrown. The value of the string doesn't change if an error
2587 * is thrown.
2588 */
2589 _GLIBCXX20_CONSTEXPR
2590 basic_string&
2591 replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
2592 { return _M_replace_aux(_M_check(__pos, "basic_string::replace"),
2593 _M_limit(__pos, __n1), __n2, __c); }
2594
2595 /**
2596 * @brief Replace range of characters with string.
2597 * @param __i1 Iterator referencing start of range to replace.
2598 * @param __i2 Iterator referencing end of range to replace.
2599 * @param __str String value to insert.
2600 * @return Reference to this string.
2601 * @throw std::length_error If new length exceeds @c max_size().
2602 *
2603 * Removes the characters in the range [__i1,__i2). In place,
2604 * the value of @a __str is inserted. If the length of result
2605 * exceeds max_size(), length_error is thrown. The value of
2606 * the string doesn't change if an error is thrown.
2607 */
2608 _GLIBCXX20_CONSTEXPR
2609 basic_string&
2610 replace(__const_iterator __i1, __const_iterator __i2,
2611 const basic_string& __str)
2612 { return this->replace(__i1, __i2, __str._M_data(), __str.size()); }
2613
2614 /**
2615 * @brief Replace range of characters with C substring.
2616 * @param __i1 Iterator referencing start of range to replace.
2617 * @param __i2 Iterator referencing end of range to replace.
2618 * @param __s C string value to insert.
2619 * @param __n Number of characters from s to insert.
2620 * @return Reference to this string.
2621 * @throw std::length_error If new length exceeds @c max_size().
2622 *
2623 * Removes the characters in the range [__i1,__i2). In place,
2624 * the first @a __n characters of @a __s are inserted. If the
2625 * length of result exceeds max_size(), length_error is thrown.
2626 * The value of the string doesn't change if an error is
2627 * thrown.
2628 */
2629 _GLIBCXX20_CONSTEXPR
2630 basic_string&
2631 replace(__const_iterator __i1, __const_iterator __i2,
2632 const _CharT* __s, size_type __n)
2633 {
2634 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2635 && __i2 <= end());
2636 return this->replace(__i1 - begin(), __i2 - __i1, __s, __n);
2637 }
2638
2639 /**
2640 * @brief Replace range of characters with C string.
2641 * @param __i1 Iterator referencing start of range to replace.
2642 * @param __i2 Iterator referencing end of range to replace.
2643 * @param __s C string value to insert.
2644 * @return Reference to this string.
2645 * @throw std::length_error If new length exceeds @c max_size().
2646 *
2647 * Removes the characters in the range [__i1,__i2). In place,
2648 * the characters of @a __s are inserted. If the length of
2649 * result exceeds max_size(), length_error is thrown. The
2650 * value of the string doesn't change if an error is thrown.
2651 */
2652 _GLIBCXX20_CONSTEXPR
2653 basic_string&
2654 replace(__const_iterator __i1, __const_iterator __i2, const _CharT* __s)
2655 {
2656 __glibcxx_requires_string(__s);
2657 return this->replace(__i1, __i2, __s, traits_type::length(__s));
2658 }
2659
2660 /**
2661 * @brief Replace range of characters with multiple characters
2662 * @param __i1 Iterator referencing start of range to replace.
2663 * @param __i2 Iterator referencing end of range to replace.
2664 * @param __n Number of characters to insert.
2665 * @param __c Character to insert.
2666 * @return Reference to this string.
2667 * @throw std::length_error If new length exceeds @c max_size().
2668 *
2669 * Removes the characters in the range [__i1,__i2). In place,
2670 * @a __n copies of @a __c are inserted. If the length of
2671 * result exceeds max_size(), length_error is thrown. The
2672 * value of the string doesn't change if an error is thrown.
2673 */
2674 _GLIBCXX20_CONSTEXPR
2675 basic_string&
2676 replace(__const_iterator __i1, __const_iterator __i2, size_type __n,
2677 _CharT __c)
2678 {
2679 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2680 && __i2 <= end());
2681 return _M_replace_aux(__i1 - begin(), __i2 - __i1, __n, __c);
2682 }
2683
2684 /**
2685 * @brief Replace range of characters with range.
2686 * @param __i1 Iterator referencing start of range to replace.
2687 * @param __i2 Iterator referencing end of range to replace.
2688 * @param __k1 Iterator referencing start of range to insert.
2689 * @param __k2 Iterator referencing end of range to insert.
2690 * @return Reference to this string.
2691 * @throw std::length_error If new length exceeds @c max_size().
2692 *
2693 * Removes the characters in the range [__i1,__i2). In place,
2694 * characters in the range [__k1,__k2) are inserted. If the
2695 * length of result exceeds max_size(), length_error is thrown.
2696 * The value of the string doesn't change if an error is
2697 * thrown.
2698 */
2699#if __cplusplus >= 201103L
2700 template<class _InputIterator,
2701 typename = std::_RequireInputIter<_InputIterator>>
2702 _GLIBCXX20_CONSTEXPR
2703 basic_string&
2704 replace(const_iterator __i1, const_iterator __i2,
2705 _InputIterator __k1, _InputIterator __k2)
2706 {
2707 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2708 && __i2 <= end());
2709 __glibcxx_requires_valid_range(__k1, __k2);
2710 return this->_M_replace_dispatch(__i1, __i2, __k1, __k2,
2711 std::__false_type());
2712 }
2713#else
2714 template<class _InputIterator>
2715#ifdef _GLIBCXX_DISAMBIGUATE_REPLACE_INST
2716 typename __enable_if_not_native_iterator<_InputIterator>::__type
2717#else
2718 basic_string&
2719#endif
2720 replace(iterator __i1, iterator __i2,
2721 _InputIterator __k1, _InputIterator __k2)
2722 {
2723 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2724 && __i2 <= end());
2725 __glibcxx_requires_valid_range(__k1, __k2);
2726 typedef typename std::__is_integer<_InputIterator>::__type _Integral;
2727 return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral());
2728 }
2729#endif
2730
2731 // Specializations for the common case of pointer and iterator:
2732 // useful to avoid the overhead of temporary buffering in _M_replace.
2733 _GLIBCXX20_CONSTEXPR
2734 basic_string&
2735 replace(__const_iterator __i1, __const_iterator __i2,
2736 _CharT* __k1, _CharT* __k2)
2737 {
2738 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2739 && __i2 <= end());
2740 __glibcxx_requires_valid_range(__k1, __k2);
2741 return this->replace(__i1 - begin(), __i2 - __i1,
2742 __k1, __k2 - __k1);
2743 }
2744
2745 _GLIBCXX20_CONSTEXPR
2746 basic_string&
2747 replace(__const_iterator __i1, __const_iterator __i2,
2748 const _CharT* __k1, const _CharT* __k2)
2749 {
2750 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2751 && __i2 <= end());
2752 __glibcxx_requires_valid_range(__k1, __k2);
2753 return this->replace(__i1 - begin(), __i2 - __i1,
2754 __k1, __k2 - __k1);
2755 }
2756
2757 _GLIBCXX20_CONSTEXPR
2758 basic_string&
2759 replace(__const_iterator __i1, __const_iterator __i2,
2760 iterator __k1, iterator __k2)
2761 {
2762 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2763 && __i2 <= end());
2764 __glibcxx_requires_valid_range(__k1, __k2);
2765 return this->replace(__i1 - begin(), __i2 - __i1,
2766 __k1.base(), __k2 - __k1);
2767 }
2768
2769 _GLIBCXX20_CONSTEXPR
2770 basic_string&
2771 replace(__const_iterator __i1, __const_iterator __i2,
2772 const_iterator __k1, const_iterator __k2)
2773 {
2774 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2775 && __i2 <= end());
2776 __glibcxx_requires_valid_range(__k1, __k2);
2777 return this->replace(__i1 - begin(), __i2 - __i1,
2778 __k1.base(), __k2 - __k1);
2779 }
2780
2781#if __glibcxx_containers_ranges // C++ >= 23
2782 /**
2783 * @brief Replace part of the string with a range.
2784 * @param __rg A range of values that are convertible to `value_type`.
2785 * @since C++23
2786 *
2787 * The range `__rg` is allowed to overlap with `*this`.
2788 */
2789 template<__detail::__container_compatible_range<_CharT> _Rg>
2790 constexpr basic_string&
2791 replace_with_range(const_iterator __i1, const_iterator __i2, _Rg&& __rg)
2792 {
2793 if (__i1 == cend())
2794 append_range(std::forward<_Rg>(__rg));
2795 else
2796 {
2797 basic_string __s(from_range, std::forward<_Rg>(__rg),
2798 _M_get_allocator());
2799 replace(__i1, __i2, __s);
2800 }
2801 return *this;
2802 }
2803#endif
2804
2805#if __cplusplus >= 201103L
2806 /**
2807 * @brief Replace range of characters with initializer_list.
2808 * @param __i1 Iterator referencing start of range to replace.
2809 * @param __i2 Iterator referencing end of range to replace.
2810 * @param __l The initializer_list of characters to insert.
2811 * @return Reference to this string.
2812 * @throw std::length_error If new length exceeds @c max_size().
2813 *
2814 * Removes the characters in the range [__i1,__i2). In place,
2815 * characters in the range [__k1,__k2) are inserted. If the
2816 * length of result exceeds max_size(), length_error is thrown.
2817 * The value of the string doesn't change if an error is
2818 * thrown.
2819 */
2820 _GLIBCXX20_CONSTEXPR
2821 basic_string& replace(const_iterator __i1, const_iterator __i2,
2822 initializer_list<_CharT> __l)
2823 { return this->replace(__i1, __i2, __l.begin(), __l.size()); }
2824#endif // C++11
2825
2826#ifdef __glibcxx_string_view // >= C++17
2827 /**
2828 * @brief Replace range of characters with string_view.
2829 * @param __pos The position to replace at.
2830 * @param __n The number of characters to replace.
2831 * @param __svt The object convertible to string_view to insert.
2832 * @return Reference to this string.
2833 */
2834 template<typename _Tp>
2835 _GLIBCXX20_CONSTEXPR
2836 _If_sv<_Tp, basic_string&>
2837 replace(size_type __pos, size_type __n, const _Tp& __svt)
2838 {
2839 __sv_type __sv = __svt;
2840 return this->replace(__pos, __n, __sv.data(), __sv.size());
2841 }
2842
2843 /**
2844 * @brief Replace range of characters with string_view.
2845 * @param __pos1 The position to replace at.
2846 * @param __n1 The number of characters to replace.
2847 * @param __svt The object convertible to string_view to insert from.
2848 * @param __pos2 The position in the string_view to insert from.
2849 * @param __n2 The number of characters to insert.
2850 * @return Reference to this string.
2851 */
2852 template<typename _Tp>
2853 _GLIBCXX20_CONSTEXPR
2854 _If_sv<_Tp, basic_string&>
2855 replace(size_type __pos1, size_type __n1, const _Tp& __svt,
2856 size_type __pos2, size_type __n2 = npos)
2857 {
2858 __sv_type __sv = __svt;
2859 return this->replace(__pos1, __n1,
2860 __sv.data()
2861 + std::__sv_check(__sv.size(), __pos2, "basic_string::replace"),
2862 std::__sv_limit(__sv.size(), __pos2, __n2));
2863 }
2864
2865 /**
2866 * @brief Replace range of characters with string_view.
2867 * @param __i1 An iterator referencing the start position
2868 to replace at.
2869 * @param __i2 An iterator referencing the end position
2870 for the replace.
2871 * @param __svt The object convertible to string_view to insert from.
2872 * @return Reference to this string.
2873 */
2874 template<typename _Tp>
2875 _GLIBCXX20_CONSTEXPR
2876 _If_sv<_Tp, basic_string&>
2877 replace(const_iterator __i1, const_iterator __i2, const _Tp& __svt)
2878 {
2879 __sv_type __sv = __svt;
2880 return this->replace(__i1 - begin(), __i2 - __i1, __sv);
2881 }
2882#endif // C++17
2883
2884 private:
2885 template<class _Integer>
2886 _GLIBCXX20_CONSTEXPR
2887 basic_string&
2888 _M_replace_dispatch(const_iterator __i1, const_iterator __i2,
2889 _Integer __n, _Integer __val, __true_type)
2890 { return _M_replace_aux(__i1 - begin(), __i2 - __i1, __n, __val); }
2891
2892 template<class _InputIterator>
2893 _GLIBCXX20_CONSTEXPR
2894 basic_string&
2895 _M_replace_dispatch(const_iterator __i1, const_iterator __i2,
2896 _InputIterator __k1, _InputIterator __k2,
2897 __false_type);
2898
2899 _GLIBCXX20_CONSTEXPR
2900 basic_string&
2901 _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
2902 _CharT __c);
2903
2904 __attribute__((__noinline__, __noclone__, __cold__)) void
2905 _M_replace_cold(pointer __p, size_type __len1, const _CharT* __s,
2906 const size_type __len2, const size_type __how_much);
2907
2908 _GLIBCXX20_CONSTEXPR
2909 basic_string&
2910 _M_replace(size_type __pos, size_type __len1, const _CharT* __s,
2911 const size_type __len2);
2912
2913 _GLIBCXX20_CONSTEXPR
2914 basic_string&
2915 _M_append(const _CharT* __s, size_type __n);
2916
2917 public:
2918
2919 /**
2920 * @brief Copy substring into C string.
2921 * @param __s C string to copy value into.
2922 * @param __n Number of characters to copy.
2923 * @param __pos Index of first character to copy.
2924 * @return Number of characters actually copied
2925 * @throw std::out_of_range If __pos > size().
2926 *
2927 * Copies up to @a __n characters starting at @a __pos into the
2928 * C string @a __s. If @a __pos is %greater than size(),
2929 * out_of_range is thrown.
2930 */
2931 _GLIBCXX20_CONSTEXPR
2932 size_type
2933 copy(_CharT* __s, size_type __n, size_type __pos = 0) const;
2934
2935 /**
2936 * @brief Swap contents with another string.
2937 * @param __s String to swap with.
2938 *
2939 * Exchanges the contents of this string with that of @a __s in constant
2940 * time.
2941 */
2942 _GLIBCXX20_CONSTEXPR
2943 void
2944 swap(basic_string& __s) _GLIBCXX_NOEXCEPT;
2945
2946 // String operations:
2947 /**
2948 * @brief Return const pointer to null-terminated contents.
2949 *
2950 * This is a handle to internal data. Do not modify or dire things may
2951 * happen.
2952 */
2953 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
2954 const _CharT*
2955 c_str() const _GLIBCXX_NOEXCEPT
2956 { return _M_data(); }
2957
2958 /**
2959 * @brief Return const pointer to contents.
2960 *
2961 * This is a pointer to internal data. It is undefined to modify
2962 * the contents through the returned pointer. To get a pointer that
2963 * allows modifying the contents use @c &str[0] instead,
2964 * (or in C++17 the non-const @c str.data() overload).
2965 */
2966 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
2967 const _CharT*
2968 data() const _GLIBCXX_NOEXCEPT
2969 { return _M_data(); }
2970
2971#if __cplusplus >= 201703L
2972 /**
2973 * @brief Return non-const pointer to contents.
2974 *
2975 * This is a pointer to the character sequence held by the string.
2976 * Modifying the characters in the sequence is allowed.
2977 */
2978 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
2979 _CharT*
2980 data() noexcept
2981 { return _M_data(); }
2982#endif
2983
2984 /**
2985 * @brief Return copy of allocator used to construct this string.
2986 */
2987 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
2988 allocator_type
2989 get_allocator() const _GLIBCXX_NOEXCEPT
2990 { return _M_get_allocator(); }
2991
2992 /**
2993 * @brief Find position of a C substring.
2994 * @param __s C string to locate.
2995 * @param __pos Index of character to search from.
2996 * @param __n Number of characters from @a s to search for.
2997 * @return Index of start of first occurrence.
2998 *
2999 * Starting from @a __pos, searches forward for the first @a
3000 * __n characters in @a __s within this string. If found,
3001 * returns the index where it begins. If not found, returns
3002 * npos.
3003 */
3004 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3005 size_type
3006 find(const _CharT* __s, size_type __pos, size_type __n) const
3007 _GLIBCXX_NOEXCEPT;
3008
3009 /**
3010 * @brief Find position of a string.
3011 * @param __str String to locate.
3012 * @param __pos Index of character to search from (default 0).
3013 * @return Index of start of first occurrence.
3014 *
3015 * Starting from @a __pos, searches forward for value of @a __str within
3016 * this string. If found, returns the index where it begins. If not
3017 * found, returns npos.
3018 */
3019 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3020 size_type
3021 find(const basic_string& __str, size_type __pos = 0) const
3022 _GLIBCXX_NOEXCEPT
3023 { return this->find(__str.data(), __pos, __str.size()); }
3024
3025#ifdef __glibcxx_string_view // >= C++17
3026 /**
3027 * @brief Find position of a string_view.
3028 * @param __svt The object convertible to string_view to locate.
3029 * @param __pos Index of character to search from (default 0).
3030 * @return Index of start of first occurrence.
3031 */
3032 template<typename _Tp>
3033 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3034 _If_sv<_Tp, size_type>
3035 find(const _Tp& __svt, size_type __pos = 0) const
3036 noexcept(is_same<_Tp, __sv_type>::value)
3037 {
3038 __sv_type __sv = __svt;
3039 return this->find(__sv.data(), __pos, __sv.size());
3040 }
3041#endif // C++17
3042
3043 /**
3044 * @brief Find position of a C string.
3045 * @param __s C string to locate.
3046 * @param __pos Index of character to search from (default 0).
3047 * @return Index of start of first occurrence.
3048 *
3049 * Starting from @a __pos, searches forward for the value of @a
3050 * __s within this string. If found, returns the index where
3051 * it begins. If not found, returns npos.
3052 */
3053 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3054 size_type
3055 find(const _CharT* __s, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
3056 {
3057 __glibcxx_requires_string(__s);
3058 return this->find(__s, __pos, traits_type::length(__s));
3059 }
3060
3061 /**
3062 * @brief Find position of a character.
3063 * @param __c Character to locate.
3064 * @param __pos Index of character to search from (default 0).
3065 * @return Index of first occurrence.
3066 *
3067 * Starting from @a __pos, searches forward for @a __c within
3068 * this string. If found, returns the index where it was
3069 * found. If not found, returns npos.
3070 */
3071 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3072 size_type
3073 find(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT;
3074
3075 /**
3076 * @brief Find last position of a string.
3077 * @param __str String to locate.
3078 * @param __pos Index of character to search back from (default end).
3079 * @return Index of start of last occurrence.
3080 *
3081 * Starting from @a __pos, searches backward for value of @a
3082 * __str within this string. If found, returns the index where
3083 * it begins. If not found, returns npos.
3084 */
3085 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3086 size_type
3087 rfind(const basic_string& __str, size_type __pos = npos) const
3088 _GLIBCXX_NOEXCEPT
3089 { return this->rfind(__str.data(), __pos, __str.size()); }
3090
3091#ifdef __glibcxx_string_view // >= C++17
3092 /**
3093 * @brief Find last position of a string_view.
3094 * @param __svt The object convertible to string_view to locate.
3095 * @param __pos Index of character to search back from (default end).
3096 * @return Index of start of last occurrence.
3097 */
3098 template<typename _Tp>
3099 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3100 _If_sv<_Tp, size_type>
3101 rfind(const _Tp& __svt, size_type __pos = npos) const
3102 noexcept(is_same<_Tp, __sv_type>::value)
3103 {
3104 __sv_type __sv = __svt;
3105 return this->rfind(__sv.data(), __pos, __sv.size());
3106 }
3107#endif // C++17
3108
3109 /**
3110 * @brief Find last position of a C substring.
3111 * @param __s C string to locate.
3112 * @param __pos Index of character to search back from.
3113 * @param __n Number of characters from s to search for.
3114 * @return Index of start of last occurrence.
3115 *
3116 * Starting from @a __pos, searches backward for the first @a
3117 * __n characters in @a __s within this string. If found,
3118 * returns the index where it begins. If not found, returns
3119 * npos.
3120 */
3121 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3122 size_type
3123 rfind(const _CharT* __s, size_type __pos, size_type __n) const
3124 _GLIBCXX_NOEXCEPT;
3125
3126 /**
3127 * @brief Find last position of a C string.
3128 * @param __s C string to locate.
3129 * @param __pos Index of character to start search at (default end).
3130 * @return Index of start of last occurrence.
3131 *
3132 * Starting from @a __pos, searches backward for the value of
3133 * @a __s within this string. If found, returns the index
3134 * where it begins. If not found, returns npos.
3135 */
3136 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3137 size_type
3138 rfind(const _CharT* __s, size_type __pos = npos) const
3139 {
3140 __glibcxx_requires_string(__s);
3141 return this->rfind(__s, __pos, traits_type::length(__s));
3142 }
3143
3144 /**
3145 * @brief Find last position of a character.
3146 * @param __c Character to locate.
3147 * @param __pos Index of character to search back from (default end).
3148 * @return Index of last occurrence.
3149 *
3150 * Starting from @a __pos, searches backward for @a __c within
3151 * this string. If found, returns the index where it was
3152 * found. If not found, returns npos.
3153 */
3154 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3155 size_type
3156 rfind(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT;
3157
3158 /**
3159 * @brief Find position of a character of string.
3160 * @param __str String containing characters to locate.
3161 * @param __pos Index of character to search from (default 0).
3162 * @return Index of first occurrence.
3163 *
3164 * Starting from @a __pos, searches forward for one of the
3165 * characters of @a __str within this string. If found,
3166 * returns the index where it was found. If not found, returns
3167 * npos.
3168 */
3169 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3170 size_type
3171 find_first_of(const basic_string& __str, size_type __pos = 0) const
3172 _GLIBCXX_NOEXCEPT
3173 { return this->find_first_of(__str.data(), __pos, __str.size()); }
3174
3175#ifdef __glibcxx_string_view // >= C++17
3176 /**
3177 * @brief Find position of a character of a string_view.
3178 * @param __svt An object convertible to string_view containing
3179 * characters to locate.
3180 * @param __pos Index of character to search from (default 0).
3181 * @return Index of first occurrence.
3182 */
3183 template<typename _Tp>
3184 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3185 _If_sv<_Tp, size_type>
3186 find_first_of(const _Tp& __svt, size_type __pos = 0) const
3187 noexcept(is_same<_Tp, __sv_type>::value)
3188 {
3189 __sv_type __sv = __svt;
3190 return this->find_first_of(__sv.data(), __pos, __sv.size());
3191 }
3192#endif // C++17
3193
3194 /**
3195 * @brief Find position of a character of C substring.
3196 * @param __s String containing characters to locate.
3197 * @param __pos Index of character to search from.
3198 * @param __n Number of characters from s to search for.
3199 * @return Index of first occurrence.
3200 *
3201 * Starting from @a __pos, searches forward for one of the
3202 * first @a __n characters of @a __s within this string. If
3203 * found, returns the index where it was found. If not found,
3204 * returns npos.
3205 */
3206 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3207 size_type
3208 find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
3209 _GLIBCXX_NOEXCEPT;
3210
3211 /**
3212 * @brief Find position of a character of C string.
3213 * @param __s String containing characters to locate.
3214 * @param __pos Index of character to search from (default 0).
3215 * @return Index of first occurrence.
3216 *
3217 * Starting from @a __pos, searches forward for one of the
3218 * characters of @a __s within this string. If found, returns
3219 * the index where it was found. If not found, returns npos.
3220 */
3221 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3222 size_type
3223 find_first_of(const _CharT* __s, size_type __pos = 0) const
3224 _GLIBCXX_NOEXCEPT
3225 {
3226 __glibcxx_requires_string(__s);
3227 return this->find_first_of(__s, __pos, traits_type::length(__s));
3228 }
3229
3230 /**
3231 * @brief Find position of a character.
3232 * @param __c Character to locate.
3233 * @param __pos Index of character to search from (default 0).
3234 * @return Index of first occurrence.
3235 *
3236 * Starting from @a __pos, searches forward for the character
3237 * @a __c within this string. If found, returns the index
3238 * where it was found. If not found, returns npos.
3239 *
3240 * Note: equivalent to find(__c, __pos).
3241 */
3242 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3243 size_type
3244 find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
3245 { return this->find(__c, __pos); }
3246
3247 /**
3248 * @brief Find last position of a character of string.
3249 * @param __str String containing characters to locate.
3250 * @param __pos Index of character to search back from (default end).
3251 * @return Index of last occurrence.
3252 *
3253 * Starting from @a __pos, searches backward for one of the
3254 * characters of @a __str within this string. If found,
3255 * returns the index where it was found. If not found, returns
3256 * npos.
3257 */
3258 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3259 size_type
3260 find_last_of(const basic_string& __str, size_type __pos = npos) const
3261 _GLIBCXX_NOEXCEPT
3262 { return this->find_last_of(__str.data(), __pos, __str.size()); }
3263
3264#ifdef __glibcxx_string_view // >= C++17
3265 /**
3266 * @brief Find last position of a character of string.
3267 * @param __svt An object convertible to string_view containing
3268 * characters to locate.
3269 * @param __pos Index of character to search back from (default end).
3270 * @return Index of last occurrence.
3271 */
3272 template<typename _Tp>
3273 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3274 _If_sv<_Tp, size_type>
3275 find_last_of(const _Tp& __svt, size_type __pos = npos) const
3276 noexcept(is_same<_Tp, __sv_type>::value)
3277 {
3278 __sv_type __sv = __svt;
3279 return this->find_last_of(__sv.data(), __pos, __sv.size());
3280 }
3281#endif // C++17
3282
3283 /**
3284 * @brief Find last position of a character of C substring.
3285 * @param __s C string containing characters to locate.
3286 * @param __pos Index of character to search back from.
3287 * @param __n Number of characters from s to search for.
3288 * @return Index of last occurrence.
3289 *
3290 * Starting from @a __pos, searches backward for one of the
3291 * first @a __n characters of @a __s within this string. If
3292 * found, returns the index where it was found. If not found,
3293 * returns npos.
3294 */
3295 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3296 size_type
3297 find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
3298 _GLIBCXX_NOEXCEPT;
3299
3300 /**
3301 * @brief Find last position of a character of C string.
3302 * @param __s C string containing characters to locate.
3303 * @param __pos Index of character to search back from (default end).
3304 * @return Index of last occurrence.
3305 *
3306 * Starting from @a __pos, searches backward for one of the
3307 * characters of @a __s within this string. If found, returns
3308 * the index where it was found. If not found, returns npos.
3309 */
3310 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3311 size_type
3312 find_last_of(const _CharT* __s, size_type __pos = npos) const
3313 _GLIBCXX_NOEXCEPT
3314 {
3315 __glibcxx_requires_string(__s);
3316 return this->find_last_of(__s, __pos, traits_type::length(__s));
3317 }
3318
3319 /**
3320 * @brief Find last position of a character.
3321 * @param __c Character to locate.
3322 * @param __pos Index of character to search back from (default end).
3323 * @return Index of last occurrence.
3324 *
3325 * Starting from @a __pos, searches backward for @a __c within
3326 * this string. If found, returns the index where it was
3327 * found. If not found, returns npos.
3328 *
3329 * Note: equivalent to rfind(__c, __pos).
3330 */
3331 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3332 size_type
3333 find_last_of(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT
3334 { return this->rfind(__c, __pos); }
3335
3336 /**
3337 * @brief Find position of a character not in string.
3338 * @param __str String containing characters to avoid.
3339 * @param __pos Index of character to search from (default 0).
3340 * @return Index of first occurrence.
3341 *
3342 * Starting from @a __pos, searches forward for a character not contained
3343 * in @a __str within this string. If found, returns the index where it
3344 * was found. If not found, returns npos.
3345 */
3346 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3347 size_type
3348 find_first_not_of(const basic_string& __str, size_type __pos = 0) const
3349 _GLIBCXX_NOEXCEPT
3350 { return this->find_first_not_of(__str.data(), __pos, __str.size()); }
3351
3352#ifdef __glibcxx_string_view // >= C++17
3353 /**
3354 * @brief Find position of a character not in a string_view.
3355 * @param __svt A object convertible to string_view containing
3356 * characters to avoid.
3357 * @param __pos Index of character to search from (default 0).
3358 * @return Index of first occurrence.
3359 */
3360 template<typename _Tp>
3361 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3362 _If_sv<_Tp, size_type>
3363 find_first_not_of(const _Tp& __svt, size_type __pos = 0) const
3364 noexcept(is_same<_Tp, __sv_type>::value)
3365 {
3366 __sv_type __sv = __svt;
3367 return this->find_first_not_of(__sv.data(), __pos, __sv.size());
3368 }
3369#endif // C++17
3370
3371 /**
3372 * @brief Find position of a character not in C substring.
3373 * @param __s C string containing characters to avoid.
3374 * @param __pos Index of character to search from.
3375 * @param __n Number of characters from __s to consider.
3376 * @return Index of first occurrence.
3377 *
3378 * Starting from @a __pos, searches forward for a character not
3379 * contained in the first @a __n characters of @a __s within
3380 * this string. If found, returns the index where it was
3381 * found. If not found, returns npos.
3382 */
3383 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3384 size_type
3385 find_first_not_of(const _CharT* __s, size_type __pos,
3386 size_type __n) const _GLIBCXX_NOEXCEPT;
3387
3388 /**
3389 * @brief Find position of a character not in C string.
3390 * @param __s C string containing characters to avoid.
3391 * @param __pos Index of character to search from (default 0).
3392 * @return Index of first occurrence.
3393 *
3394 * Starting from @a __pos, searches forward for a character not
3395 * contained in @a __s within this string. If found, returns
3396 * the index where it was found. If not found, returns npos.
3397 */
3398 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3399 size_type
3400 find_first_not_of(const _CharT* __s, size_type __pos = 0) const
3401 _GLIBCXX_NOEXCEPT
3402 {
3403 __glibcxx_requires_string(__s);
3404 return this->find_first_not_of(__s, __pos, traits_type::length(__s));
3405 }
3406
3407 /**
3408 * @brief Find position of a different character.
3409 * @param __c Character to avoid.
3410 * @param __pos Index of character to search from (default 0).
3411 * @return Index of first occurrence.
3412 *
3413 * Starting from @a __pos, searches forward for a character
3414 * other than @a __c within this string. If found, returns the
3415 * index where it was found. If not found, returns npos.
3416 */
3417 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3418 size_type
3419 find_first_not_of(_CharT __c, size_type __pos = 0) const
3420 _GLIBCXX_NOEXCEPT;
3421
3422 /**
3423 * @brief Find last position of a character not in string.
3424 * @param __str String containing characters to avoid.
3425 * @param __pos Index of character to search back from (default end).
3426 * @return Index of last occurrence.
3427 *
3428 * Starting from @a __pos, searches backward for a character
3429 * not contained in @a __str within this string. If found,
3430 * returns the index where it was found. If not found, returns
3431 * npos.
3432 */
3433 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3434 size_type
3435 find_last_not_of(const basic_string& __str, size_type __pos = npos) const
3436 _GLIBCXX_NOEXCEPT
3437 { return this->find_last_not_of(__str.data(), __pos, __str.size()); }
3438
3439#ifdef __glibcxx_string_view // >= C++17
3440 /**
3441 * @brief Find last position of a character not in a string_view.
3442 * @param __svt An object convertible to string_view containing
3443 * characters to avoid.
3444 * @param __pos Index of character to search back from (default end).
3445 * @return Index of last occurrence.
3446 */
3447 template<typename _Tp>
3448 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3449 _If_sv<_Tp, size_type>
3450 find_last_not_of(const _Tp& __svt, size_type __pos = npos) const
3451 noexcept(is_same<_Tp, __sv_type>::value)
3452 {
3453 __sv_type __sv = __svt;
3454 return this->find_last_not_of(__sv.data(), __pos, __sv.size());
3455 }
3456#endif // C++17
3457
3458 /**
3459 * @brief Find last position of a character not in C substring.
3460 * @param __s C string containing characters to avoid.
3461 * @param __pos Index of character to search back from.
3462 * @param __n Number of characters from s to consider.
3463 * @return Index of last occurrence.
3464 *
3465 * Starting from @a __pos, searches backward for a character not
3466 * contained in the first @a __n characters of @a __s within this string.
3467 * If found, returns the index where it was found. If not found,
3468 * returns npos.
3469 */
3470 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3471 size_type
3472 find_last_not_of(const _CharT* __s, size_type __pos,
3473 size_type __n) const _GLIBCXX_NOEXCEPT;
3474 /**
3475 * @brief Find last position of a character not in C string.
3476 * @param __s C string containing characters to avoid.
3477 * @param __pos Index of character to search back from (default end).
3478 * @return Index of last occurrence.
3479 *
3480 * Starting from @a __pos, searches backward for a character
3481 * not contained in @a __s within this string. If found,
3482 * returns the index where it was found. If not found, returns
3483 * npos.
3484 */
3485 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3486 size_type
3487 find_last_not_of(const _CharT* __s, size_type __pos = npos) const
3488 _GLIBCXX_NOEXCEPT
3489 {
3490 __glibcxx_requires_string(__s);
3491 return this->find_last_not_of(__s, __pos, traits_type::length(__s));
3492 }
3493
3494 /**
3495 * @brief Find last position of a different character.
3496 * @param __c Character to avoid.
3497 * @param __pos Index of character to search back from (default end).
3498 * @return Index of last occurrence.
3499 *
3500 * Starting from @a __pos, searches backward for a character other than
3501 * @a __c within this string. If found, returns the index where it was
3502 * found. If not found, returns npos.
3503 */
3504 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3505 size_type
3506 find_last_not_of(_CharT __c, size_type __pos = npos) const
3507 _GLIBCXX_NOEXCEPT;
3508
3509 /**
3510 * @brief Get a substring.
3511 * @param __pos Index of first character (default 0).
3512 * @param __n Number of characters in substring (default remainder).
3513 * @return The new string.
3514 * @throw std::out_of_range If __pos > size().
3515 *
3516 * Construct and return a new string using the @a __n
3517 * characters starting at @a __pos. If the string is too
3518 * short, use the remainder of the characters. If @a __pos is
3519 * beyond the end of the string, out_of_range is thrown.
3520 */
3521 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3522 basic_string
3523 substr(size_type __pos = 0, size_type __n = npos) const
3524 { return basic_string(*this,
3525 _M_check(__pos, "basic_string::substr"), __n); }
3526
3527#if __cplusplus >= 202302L
3528 _GLIBCXX_NODISCARD
3529 constexpr basic_string
3530 substr(size_type __pos = 0) &&
3531 { return basic_string(std::move(*this), __pos); }
3532
3533 _GLIBCXX_NODISCARD
3534 constexpr basic_string
3535 substr(size_type __pos, size_type __n) &&
3536 { return basic_string(std::move(*this), __pos, __n); }
3537#endif // C++23
3538
3539#ifdef __glibcxx_string_subview // >= C++26
3540 /**
3541 * @brief Get a subview.
3542 * @param __pos Index of first character (default 0).
3543 * @param __n Number of characters in subview (default remainder).
3544 * @return The subview.
3545 * @throw std::out_of_range If __pos > size().
3546 *
3547 * Construct and return a subview using the `__n` characters starting at
3548 * `__pos`. If the string is too short, use the remainder of the
3549 * characters. If `__pos` is beyond the end of the string, out_of_range
3550 * is thrown.
3551 */
3552 [[nodiscard]]
3553 constexpr basic_string_view<_CharT, _Traits>
3554 subview(size_type __pos = 0, size_type __n = npos) const
3555 { return __sv_type(*this).subview(__pos, __n); }
3556#endif
3557
3558 /**
3559 * @brief Compare to a string.
3560 * @param __str String to compare against.
3561 * @return Integer < 0, 0, or > 0.
3562 *
3563 * Returns an integer < 0 if this string is ordered before @a
3564 * __str, 0 if their values are equivalent, or > 0 if this
3565 * string is ordered after @a __str. Determines the effective
3566 * length rlen of the strings to compare as the smallest of
3567 * size() and str.size(). The function then compares the two
3568 * strings by calling traits::compare(data(), str.data(),rlen).
3569 * If the result of the comparison is nonzero returns it,
3570 * otherwise the shorter one is ordered first.
3571 */
3572 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3573 int
3574 compare(const basic_string& __str) const
3575 {
3576 const size_type __size = this->size();
3577 const size_type __osize = __str.size();
3578 const size_type __len = std::min(__size, __osize);
3579
3580 int __r = traits_type::compare(_M_data(), __str.data(), __len);
3581 if (!__r)
3582 __r = _S_compare(__size, __osize);
3583 return __r;
3584 }
3585
3586#ifdef __glibcxx_string_view // >= C++17
3587 /**
3588 * @brief Compare to a string_view.
3589 * @param __svt An object convertible to string_view to compare against.
3590 * @return Integer < 0, 0, or > 0.
3591 */
3592 template<typename _Tp>
3593 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3594 _If_sv<_Tp, int>
3595 compare(const _Tp& __svt) const
3596 noexcept(is_same<_Tp, __sv_type>::value)
3597 {
3598 __sv_type __sv = __svt;
3599 const size_type __size = this->size();
3600 const size_type __osize = __sv.size();
3601 const size_type __len = std::min(__size, __osize);
3602
3603 int __r = traits_type::compare(_M_data(), __sv.data(), __len);
3604 if (!__r)
3605 __r = _S_compare(__size, __osize);
3606 return __r;
3607 }
3608
3609 /**
3610 * @brief Compare to a string_view.
3611 * @param __pos A position in the string to start comparing from.
3612 * @param __n The number of characters to compare.
3613 * @param __svt An object convertible to string_view to compare
3614 * against.
3615 * @return Integer < 0, 0, or > 0.
3616 */
3617 template<typename _Tp>
3618 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3619 _If_sv<_Tp, int>
3620 compare(size_type __pos, size_type __n, const _Tp& __svt) const
3621 {
3622 __sv_type __sv = __svt;
3623 return __sv_type(*this).substr(__pos, __n).compare(__sv);
3624 }
3625
3626 /**
3627 * @brief Compare to a string_view.
3628 * @param __pos1 A position in the string to start comparing from.
3629 * @param __n1 The number of characters to compare.
3630 * @param __svt An object convertible to string_view to compare
3631 * against.
3632 * @param __pos2 A position in the string_view to start comparing from.
3633 * @param __n2 The number of characters to compare.
3634 * @return Integer < 0, 0, or > 0.
3635 */
3636 template<typename _Tp>
3637 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3638 _If_sv<_Tp, int>
3639 compare(size_type __pos1, size_type __n1, const _Tp& __svt,
3640 size_type __pos2, size_type __n2 = npos) const
3641 {
3642 __sv_type __sv = __svt;
3643 return __sv_type(*this)
3644 .substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
3645 }
3646#endif // C++17
3647
3648 /**
3649 * @brief Compare substring to a string.
3650 * @param __pos Index of first character of substring.
3651 * @param __n Number of characters in substring.
3652 * @param __str String to compare against.
3653 * @return Integer < 0, 0, or > 0.
3654 *
3655 * Form the substring of this string from the @a __n characters
3656 * starting at @a __pos. Returns an integer < 0 if the
3657 * substring is ordered before @a __str, 0 if their values are
3658 * equivalent, or > 0 if the substring is ordered after @a
3659 * __str. Determines the effective length rlen of the strings
3660 * to compare as the smallest of the length of the substring
3661 * and @a __str.size(). The function then compares the two
3662 * strings by calling
3663 * traits::compare(substring.data(),str.data(),rlen). If the
3664 * result of the comparison is nonzero returns it, otherwise
3665 * the shorter one is ordered first.
3666 */
3667 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3668 int
3669 compare(size_type __pos, size_type __n, const basic_string& __str) const
3670 {
3671 _M_check(__pos, "basic_string::compare");
3672 __n = _M_limit(__pos, __n);
3673 const size_type __osize = __str.size();
3674 const size_type __len = std::min(__n, __osize);
3675 int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len);
3676 if (!__r)
3677 __r = _S_compare(__n, __osize);
3678 return __r;
3679 }
3680
3681 /**
3682 * @brief Compare substring to a substring.
3683 * @param __pos1 Index of first character of substring.
3684 * @param __n1 Number of characters in substring.
3685 * @param __str String to compare against.
3686 * @param __pos2 Index of first character of substring of str.
3687 * @param __n2 Number of characters in substring of str.
3688 * @return Integer < 0, 0, or > 0.
3689 *
3690 * Form the substring of this string from the @a __n1
3691 * characters starting at @a __pos1. Form the substring of @a
3692 * __str from the @a __n2 characters starting at @a __pos2.
3693 * Returns an integer < 0 if this substring is ordered before
3694 * the substring of @a __str, 0 if their values are equivalent,
3695 * or > 0 if this substring is ordered after the substring of
3696 * @a __str. Determines the effective length rlen of the
3697 * strings to compare as the smallest of the lengths of the
3698 * substrings. The function then compares the two strings by
3699 * calling
3700 * traits::compare(substring.data(),str.substr(pos2,n2).data(),rlen).
3701 * If the result of the comparison is nonzero returns it,
3702 * otherwise the shorter one is ordered first.
3703 */
3704 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3705 int
3706 compare(size_type __pos1, size_type __n1, const basic_string& __str,
3707 size_type __pos2, size_type __n2 = npos) const
3708 {
3709 _M_check(__pos1, "basic_string::compare");
3710 __str._M_check(__pos2, "basic_string::compare");
3711 __n1 = _M_limit(__pos1, __n1);
3712 __n2 = __str._M_limit(__pos2, __n2);
3713 const size_type __len = std::min(__n1, __n2);
3714 int __r = traits_type::compare(_M_data() + __pos1,
3715 __str.data() + __pos2, __len);
3716 if (!__r)
3717 __r = _S_compare(__n1, __n2);
3718 return __r;
3719 }
3720
3721 /**
3722 * @brief Compare to a C string.
3723 * @param __s C string to compare against.
3724 * @return Integer < 0, 0, or > 0.
3725 *
3726 * Returns an integer < 0 if this string is ordered before @a __s, 0 if
3727 * their values are equivalent, or > 0 if this string is ordered after
3728 * @a __s. Determines the effective length rlen of the strings to
3729 * compare as the smallest of size() and the length of a string
3730 * constructed from @a __s. The function then compares the two strings
3731 * by calling traits::compare(data(),s,rlen). If the result of the
3732 * comparison is nonzero returns it, otherwise the shorter one is
3733 * ordered first.
3734 */
3735 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3736 int
3737 compare(const _CharT* __s) const _GLIBCXX_NOEXCEPT
3738 {
3739 __glibcxx_requires_string(__s);
3740 const size_type __size = this->size();
3741 const size_type __osize = traits_type::length(__s);
3742 const size_type __len = std::min(__size, __osize);
3743 int __r = traits_type::compare(_M_data(), __s, __len);
3744 if (!__r)
3745 __r = _S_compare(__size, __osize);
3746 return __r;
3747 }
3748
3749 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3750 // 5 String::compare specification questionable
3751 /**
3752 * @brief Compare substring to a C string.
3753 * @param __pos Index of first character of substring.
3754 * @param __n1 Number of characters in substring.
3755 * @param __s C string to compare against.
3756 * @return Integer < 0, 0, or > 0.
3757 *
3758 * Form the substring of this string from the @a __n1
3759 * characters starting at @a pos. Returns an integer < 0 if
3760 * the substring is ordered before @a __s, 0 if their values
3761 * are equivalent, or > 0 if the substring is ordered after @a
3762 * __s. Determines the effective length rlen of the strings to
3763 * compare as the smallest of the length of the substring and
3764 * the length of a string constructed from @a __s. The
3765 * function then compares the two string by calling
3766 * traits::compare(substring.data(),__s,rlen). If the result of
3767 * the comparison is nonzero returns it, otherwise the shorter
3768 * one is ordered first.
3769 */
3770 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3771 int
3772 compare(size_type __pos, size_type __n1, const _CharT* __s) const
3773 {
3774 __glibcxx_requires_string(__s);
3775 _M_check(__pos, "basic_string::compare");
3776 __n1 = _M_limit(__pos, __n1);
3777 const size_type __osize = traits_type::length(__s);
3778 const size_type __len = std::min(__n1, __osize);
3779 int __r = traits_type::compare(_M_data() + __pos, __s, __len);
3780 if (!__r)
3781 __r = _S_compare(__n1, __osize);
3782 return __r;
3783 }
3784
3785 /**
3786 * @brief Compare substring against a character %array.
3787 * @param __pos Index of first character of substring.
3788 * @param __n1 Number of characters in substring.
3789 * @param __s character %array to compare against.
3790 * @param __n2 Number of characters of s.
3791 * @return Integer < 0, 0, or > 0.
3792 *
3793 * Form the substring of this string from the @a __n1
3794 * characters starting at @a __pos. Form a string from the
3795 * first @a __n2 characters of @a __s. Returns an integer < 0
3796 * if this substring is ordered before the string from @a __s,
3797 * 0 if their values are equivalent, or > 0 if this substring
3798 * is ordered after the string from @a __s. Determines the
3799 * effective length rlen of the strings to compare as the
3800 * smallest of the length of the substring and @a __n2. The
3801 * function then compares the two strings by calling
3802 * traits::compare(substring.data(),s,rlen). If the result of
3803 * the comparison is nonzero returns it, otherwise the shorter
3804 * one is ordered first.
3805 *
3806 * NB: s must have at least n2 characters, &apos;\\0&apos; has
3807 * no special meaning.
3808 */
3809 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3810 int
3811 compare(size_type __pos, size_type __n1, const _CharT* __s,
3812 size_type __n2) const
3813 {
3814 __glibcxx_requires_string_len(__s, __n2);
3815 _M_check(__pos, "basic_string::compare");
3816 __n1 = _M_limit(__pos, __n1);
3817 const size_type __len = std::min(__n1, __n2);
3818 int __r = traits_type::compare(_M_data() + __pos, __s, __len);
3819 if (!__r)
3820 __r = _S_compare(__n1, __n2);
3821 return __r;
3822 }
3823
3824#if __cplusplus >= 202002L
3825 [[nodiscard]]
3826 constexpr bool
3827 starts_with(basic_string_view<_CharT, _Traits> __x) const noexcept
3828 { return __sv_type(this->data(), this->size()).starts_with(__x); }
3829
3830 [[nodiscard]]
3831 constexpr bool
3832 starts_with(_CharT __x) const noexcept
3833 { return __sv_type(this->data(), this->size()).starts_with(__x); }
3834
3835 [[nodiscard, __gnu__::__nonnull__]]
3836 constexpr bool
3837 starts_with(const _CharT* __x) const noexcept
3838 { return __sv_type(this->data(), this->size()).starts_with(__x); }
3839
3840 [[nodiscard]]
3841 constexpr bool
3842 ends_with(basic_string_view<_CharT, _Traits> __x) const noexcept
3843 { return __sv_type(this->data(), this->size()).ends_with(__x); }
3844
3845 [[nodiscard]]
3846 constexpr bool
3847 ends_with(_CharT __x) const noexcept
3848 { return __sv_type(this->data(), this->size()).ends_with(__x); }
3849
3850 [[nodiscard, __gnu__::__nonnull__]]
3851 constexpr bool
3852 ends_with(const _CharT* __x) const noexcept
3853 { return __sv_type(this->data(), this->size()).ends_with(__x); }
3854#endif // C++20
3855
3856#if __cplusplus > 202002L
3857 [[nodiscard]]
3858 constexpr bool
3859 contains(basic_string_view<_CharT, _Traits> __x) const noexcept
3860 { return __sv_type(this->data(), this->size()).contains(__x); }
3861
3862 [[nodiscard]]
3863 constexpr bool
3864 contains(_CharT __x) const noexcept
3865 { return __sv_type(this->data(), this->size()).contains(__x); }
3866
3867 [[nodiscard, __gnu__::__nonnull__]]
3868 constexpr bool
3869 contains(const _CharT* __x) const noexcept
3870 { return __sv_type(this->data(), this->size()).contains(__x); }
3871#endif // C++23
3872
3873 // Allow basic_stringbuf::__xfer_bufptrs to call _M_length:
3874 template<typename, typename, typename> friend class basic_stringbuf;
3875 };
3876_GLIBCXX_END_NAMESPACE_CXX11
3877_GLIBCXX_END_NAMESPACE_VERSION
3878} // namespace std
3879#endif // _GLIBCXX_USE_CXX11_ABI
3880
3881namespace std _GLIBCXX_VISIBILITY(default)
3882{
3883_GLIBCXX_BEGIN_NAMESPACE_VERSION
3884
3885#if __cpp_deduction_guides >= 201606
3886_GLIBCXX_BEGIN_NAMESPACE_CXX11
3887 template<typename _InputIterator, typename _CharT
3888 = typename iterator_traits<_InputIterator>::value_type,
3889 typename _Allocator = allocator<_CharT>,
3890 typename = _RequireInputIter<_InputIterator>,
3891 typename = _RequireAllocator<_Allocator>>
3892 basic_string(_InputIterator, _InputIterator, _Allocator = _Allocator())
3893 -> basic_string<_CharT, char_traits<_CharT>, _Allocator>;
3894
3895 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3896 // 3075. basic_string needs deduction guides from basic_string_view
3897 template<typename _CharT, typename _Traits,
3898 typename _Allocator = allocator<_CharT>,
3899 typename = _RequireAllocator<_Allocator>>
3900 basic_string(basic_string_view<_CharT, _Traits>, const _Allocator& = _Allocator())
3901 -> basic_string<_CharT, _Traits, _Allocator>;
3902
3903 template<typename _CharT, typename _Traits,
3904 typename _Allocator = allocator<_CharT>,
3905 typename = _RequireAllocator<_Allocator>>
3906 basic_string(basic_string_view<_CharT, _Traits>,
3907 typename basic_string<_CharT, _Traits, _Allocator>::size_type,
3908 typename basic_string<_CharT, _Traits, _Allocator>::size_type,
3909 const _Allocator& = _Allocator())
3910 -> basic_string<_CharT, _Traits, _Allocator>;
3911
3912#if __glibcxx_containers_ranges // C++ >= 23
3913 template<ranges::input_range _Rg,
3914 typename _Allocator = allocator<ranges::range_value_t<_Rg>>>
3915 basic_string(from_range_t, _Rg&&, _Allocator = _Allocator())
3916 -> basic_string<ranges::range_value_t<_Rg>,
3917 char_traits<ranges::range_value_t<_Rg>>,
3918 _Allocator>;
3919#endif
3920_GLIBCXX_END_NAMESPACE_CXX11
3921#endif
3922
3923 template<typename _Str>
3924 _GLIBCXX20_CONSTEXPR
3925 inline _Str
3926 __str_concat(typename _Str::value_type const* __lhs,
3927 typename _Str::size_type __lhs_len,
3928 typename _Str::value_type const* __rhs,
3929 typename _Str::size_type __rhs_len,
3930 typename _Str::allocator_type const& __a)
3931 {
3932 typedef typename _Str::allocator_type allocator_type;
3933 typedef __gnu_cxx::__alloc_traits<allocator_type> _Alloc_traits;
3934 _Str __str(_Alloc_traits::_S_select_on_copy(__a));
3935 __str.reserve(__lhs_len + __rhs_len);
3936 __str.append(__lhs, __lhs_len);
3937 __str.append(__rhs, __rhs_len);
3938 return __str;
3939 }
3940
3941 // operator+
3942 /**
3943 * @brief Concatenate two strings.
3944 * @param __lhs First string.
3945 * @param __rhs Last string.
3946 * @return New string with value of @a __lhs followed by @a __rhs.
3947 */
3948 template<typename _CharT, typename _Traits, typename _Alloc>
3949 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3950 inline basic_string<_CharT, _Traits, _Alloc>
3951 operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
3952 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
3953 {
3954 typedef basic_string<_CharT, _Traits, _Alloc> _Str;
3955 return std::__str_concat<_Str>(__lhs.c_str(), __lhs.size(),
3956 __rhs.c_str(), __rhs.size(),
3957 __lhs.get_allocator());
3958 }
3959
3960 /**
3961 * @brief Concatenate C string and string.
3962 * @param __lhs First string.
3963 * @param __rhs Last string.
3964 * @return New string with value of @a __lhs followed by @a __rhs.
3965 */
3966 template<typename _CharT, typename _Traits, typename _Alloc>
3967 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3968 inline basic_string<_CharT,_Traits,_Alloc>
3969 operator+(const _CharT* __lhs,
3970 const basic_string<_CharT,_Traits,_Alloc>& __rhs)
3971 {
3972 __glibcxx_requires_string(__lhs);
3973 typedef basic_string<_CharT, _Traits, _Alloc> _Str;
3974 return std::__str_concat<_Str>(__lhs, _Traits::length(__lhs),
3975 __rhs.c_str(), __rhs.size(),
3976 __rhs.get_allocator());
3977 }
3978
3979 /**
3980 * @brief Concatenate character and string.
3981 * @param __lhs First string.
3982 * @param __rhs Last string.
3983 * @return New string with @a __lhs followed by @a __rhs.
3984 */
3985 template<typename _CharT, typename _Traits, typename _Alloc>
3986 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
3987 inline basic_string<_CharT,_Traits,_Alloc>
3988 operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs)
3989 {
3990 typedef basic_string<_CharT, _Traits, _Alloc> _Str;
3991 return std::__str_concat<_Str>(__builtin_addressof(__lhs), 1,
3992 __rhs.c_str(), __rhs.size(),
3993 __rhs.get_allocator());
3994 }
3995
3996 /**
3997 * @brief Concatenate string and C string.
3998 * @param __lhs First string.
3999 * @param __rhs Last string.
4000 * @return New string with @a __lhs followed by @a __rhs.
4001 */
4002 template<typename _CharT, typename _Traits, typename _Alloc>
4003 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
4004 inline basic_string<_CharT, _Traits, _Alloc>
4005 operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4006 const _CharT* __rhs)
4007 {
4008 __glibcxx_requires_string(__rhs);
4009 typedef basic_string<_CharT, _Traits, _Alloc> _Str;
4010 return std::__str_concat<_Str>(__lhs.c_str(), __lhs.size(),
4011 __rhs, _Traits::length(__rhs),
4012 __lhs.get_allocator());
4013 }
4014 /**
4015 * @brief Concatenate string and character.
4016 * @param __lhs First string.
4017 * @param __rhs Last string.
4018 * @return New string with @a __lhs followed by @a __rhs.
4019 */
4020 template<typename _CharT, typename _Traits, typename _Alloc>
4021 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
4022 inline basic_string<_CharT, _Traits, _Alloc>
4023 operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs)
4024 {
4025 typedef basic_string<_CharT, _Traits, _Alloc> _Str;
4026 return std::__str_concat<_Str>(__lhs.c_str(), __lhs.size(),
4027 __builtin_addressof(__rhs), 1,
4028 __lhs.get_allocator());
4029 }
4030
4031#if __cplusplus >= 201103L
4032 template<typename _CharT, typename _Traits, typename _Alloc>
4033 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
4034 inline basic_string<_CharT, _Traits, _Alloc>
4035 operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
4036 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
4037 { return std::move(__lhs.append(__rhs)); }
4038
4039 template<typename _CharT, typename _Traits, typename _Alloc>
4040 _GLIBCXX20_CONSTEXPR
4041 inline basic_string<_CharT, _Traits, _Alloc>
4042 operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4043 basic_string<_CharT, _Traits, _Alloc>&& __rhs)
4044 { return std::move(__rhs.insert(0, __lhs)); }
4045
4046 template<typename _CharT, typename _Traits, typename _Alloc>
4047 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
4048 inline basic_string<_CharT, _Traits, _Alloc>
4049 operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
4050 basic_string<_CharT, _Traits, _Alloc>&& __rhs)
4051 {
4052#pragma GCC diagnostic push
4053#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr
4054 // Return value must use __lhs.get_allocator(), but if __rhs has equal
4055 // allocator then we can choose which parameter to modify in-place.
4056 bool __use_rhs = false;
4057 if constexpr (allocator_traits<_Alloc>::is_always_equal::value)
4058 __use_rhs = true;
4059 else if (__lhs.get_allocator() == __rhs.get_allocator())
4060 __use_rhs = true;
4061 if (__use_rhs)
4062 {
4063 const auto __size = __lhs.size() + __rhs.size();
4064 if (__size > __lhs.capacity() && __size <= __rhs.capacity())
4065 return std::move(__rhs.insert(0, __lhs));
4066 }
4067 return std::move(__lhs.append(__rhs));
4068#pragma GCC diagnostic pop
4069 }
4070
4071 template<typename _CharT, typename _Traits, typename _Alloc>
4072 _GLIBCXX_NODISCARD _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
4073 inline basic_string<_CharT, _Traits, _Alloc>
4074 operator+(const _CharT* __lhs,
4075 basic_string<_CharT, _Traits, _Alloc>&& __rhs)
4076 { return std::move(__rhs.insert(0, __lhs)); }
4077
4078 template<typename _CharT, typename _Traits, typename _Alloc>
4079 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
4080 inline basic_string<_CharT, _Traits, _Alloc>
4081 operator+(_CharT __lhs,
4082 basic_string<_CharT, _Traits, _Alloc>&& __rhs)
4083 { return std::move(__rhs.insert(0, 1, __lhs)); }
4084
4085 template<typename _CharT, typename _Traits, typename _Alloc>
4086 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
4087 inline basic_string<_CharT, _Traits, _Alloc>
4088 operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
4089 const _CharT* __rhs)
4090 { return std::move(__lhs.append(__rhs)); }
4091
4092 template<typename _CharT, typename _Traits, typename _Alloc>
4093 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
4094 inline basic_string<_CharT, _Traits, _Alloc>
4095 operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
4096 _CharT __rhs)
4097 { return std::move(__lhs.append(1, __rhs)); }
4098#endif
4099
4100#if __glibcxx_string_view >= 202403L
4101 // const string & + string_view
4102 template<typename _CharT, typename _Traits, typename _Alloc>
4103 [[nodiscard]]
4104 constexpr basic_string<_CharT, _Traits, _Alloc>
4105 operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4106 type_identity_t<basic_string_view<_CharT, _Traits>> __rhs)
4107 {
4108 using _Str = basic_string<_CharT, _Traits, _Alloc>;
4109 return std::__str_concat<_Str>(__lhs.data(), __lhs.size(),
4110 __rhs.data(), __rhs.size(),
4111 __lhs.get_allocator());
4112 }
4113
4114 // string && + string_view
4115 template<typename _CharT, typename _Traits, typename _Alloc>
4116 [[nodiscard]]
4117 constexpr basic_string<_CharT, _Traits, _Alloc>
4118 operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
4119 type_identity_t<basic_string_view<_CharT, _Traits>> __rhs)
4120 {
4121 return std::move(__lhs.append(__rhs));
4122 }
4123
4124 // string_view + const string &
4125 template<typename _CharT, typename _Traits, typename _Alloc>
4126 [[nodiscard]]
4127 constexpr basic_string<_CharT, _Traits, _Alloc>
4128 operator+(type_identity_t<basic_string_view<_CharT, _Traits>> __lhs,
4129 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
4130 {
4131 using _Str = basic_string<_CharT, _Traits, _Alloc>;
4132 return std::__str_concat<_Str>(__lhs.data(), __lhs.size(),
4133 __rhs.data(), __rhs.size(),
4134 __rhs.get_allocator());
4135 }
4136
4137 // string_view + string &&
4138 template<typename _CharT, typename _Traits, typename _Alloc>
4139 [[nodiscard]]
4140 constexpr basic_string<_CharT, _Traits, _Alloc>
4141 operator+(type_identity_t<basic_string_view<_CharT, _Traits>> __lhs,
4142 basic_string<_CharT, _Traits, _Alloc>&& __rhs)
4143 {
4144 return std::move(__rhs.insert(0, __lhs));
4145 }
4146#endif
4147
4148 // operator ==
4149 /**
4150 * @brief Test equivalence of two strings.
4151 * @param __lhs First string.
4152 * @param __rhs Second string.
4153 * @return True if @a __lhs.compare(@a __rhs) == 0. False otherwise.
4154 */
4155 template<typename _CharT, typename _Traits, typename _Alloc>
4156 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
4157 inline bool
4158 operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4159 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
4160 _GLIBCXX_NOEXCEPT
4161 {
4162 return __lhs.size() == __rhs.size()
4163 && !_Traits::compare(__lhs.data(), __rhs.data(), __lhs.size());
4164 }
4165
4166 /**
4167 * @brief Test equivalence of string and C string.
4168 * @param __lhs String.
4169 * @param __rhs C string.
4170 * @return True if @a __lhs.compare(@a __rhs) == 0. False otherwise.
4171 */
4172 template<typename _CharT, typename _Traits, typename _Alloc>
4173 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
4174 inline bool
4175 operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4176 const _CharT* __rhs)
4177 {
4178 return __lhs.size() == _Traits::length(__rhs)
4179 && !_Traits::compare(__lhs.data(), __rhs, __lhs.size());
4180 }
4181
4182#if __cpp_lib_three_way_comparison
4183 /**
4184 * @brief Three-way comparison of a string and a C string.
4185 * @param __lhs A string.
4186 * @param __rhs A null-terminated string.
4187 * @return A value indicating whether `__lhs` is less than, equal to,
4188 * greater than, or incomparable with `__rhs`.
4189 */
4190 template<typename _CharT, typename _Traits, typename _Alloc>
4191 [[nodiscard]]
4192 constexpr auto
4193 operator<=>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4194 const basic_string<_CharT, _Traits, _Alloc>& __rhs) noexcept
4195 -> decltype(__detail::__char_traits_cmp_cat<_Traits>(0))
4196 { return __detail::__char_traits_cmp_cat<_Traits>(__lhs.compare(__rhs)); }
4197
4198 /**
4199 * @brief Three-way comparison of a string and a C string.
4200 * @param __lhs A string.
4201 * @param __rhs A null-terminated string.
4202 * @return A value indicating whether `__lhs` is less than, equal to,
4203 * greater than, or incomparable with `__rhs`.
4204 */
4205 template<typename _CharT, typename _Traits, typename _Alloc>
4206 [[nodiscard]]
4207 constexpr auto
4208 operator<=>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4209 const _CharT* __rhs) noexcept
4210 -> decltype(__detail::__char_traits_cmp_cat<_Traits>(0))
4211 { return __detail::__char_traits_cmp_cat<_Traits>(__lhs.compare(__rhs)); }
4212#else
4213 /**
4214 * @brief Test equivalence of C string and string.
4215 * @param __lhs C string.
4216 * @param __rhs String.
4217 * @return True if @a __rhs.compare(@a __lhs) == 0. False otherwise.
4218 */
4219 template<typename _CharT, typename _Traits, typename _Alloc>
4220 _GLIBCXX_NODISCARD
4221 inline bool
4222 operator==(const _CharT* __lhs,
4223 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
4224 { return __rhs == __lhs; }
4225
4226 // operator !=
4227 /**
4228 * @brief Test difference of two strings.
4229 * @param __lhs First string.
4230 * @param __rhs Second string.
4231 * @return True if @a __lhs.compare(@a __rhs) != 0. False otherwise.
4232 */
4233 template<typename _CharT, typename _Traits, typename _Alloc>
4234 _GLIBCXX_NODISCARD
4235 inline bool
4236 operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4237 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
4238 _GLIBCXX_NOEXCEPT
4239 { return !(__lhs == __rhs); }
4240
4241 /**
4242 * @brief Test difference of C string and string.
4243 * @param __lhs C string.
4244 * @param __rhs String.
4245 * @return True if @a __rhs.compare(@a __lhs) != 0. False otherwise.
4246 */
4247 template<typename _CharT, typename _Traits, typename _Alloc>
4248 _GLIBCXX_NODISCARD
4249 inline bool
4250 operator!=(const _CharT* __lhs,
4251 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
4252 { return !(__rhs == __lhs); }
4253
4254 /**
4255 * @brief Test difference of string and C string.
4256 * @param __lhs String.
4257 * @param __rhs C string.
4258 * @return True if @a __lhs.compare(@a __rhs) != 0. False otherwise.
4259 */
4260 template<typename _CharT, typename _Traits, typename _Alloc>
4261 _GLIBCXX_NODISCARD
4262 inline bool
4263 operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4264 const _CharT* __rhs)
4265 { return !(__lhs == __rhs); }
4266
4267 // operator <
4268 /**
4269 * @brief Test if string precedes string.
4270 * @param __lhs First string.
4271 * @param __rhs Second string.
4272 * @return True if @a __lhs precedes @a __rhs. False otherwise.
4273 */
4274 template<typename _CharT, typename _Traits, typename _Alloc>
4275 _GLIBCXX_NODISCARD
4276 inline bool
4277 operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4278 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
4279 _GLIBCXX_NOEXCEPT
4280 { return __lhs.compare(__rhs) < 0; }
4281
4282 /**
4283 * @brief Test if string precedes C string.
4284 * @param __lhs String.
4285 * @param __rhs C string.
4286 * @return True if @a __lhs precedes @a __rhs. False otherwise.
4287 */
4288 template<typename _CharT, typename _Traits, typename _Alloc>
4289 _GLIBCXX_NODISCARD
4290 inline bool
4291 operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4292 const _CharT* __rhs)
4293 { return __lhs.compare(__rhs) < 0; }
4294
4295 /**
4296 * @brief Test if C string precedes string.
4297 * @param __lhs C string.
4298 * @param __rhs String.
4299 * @return True if @a __lhs precedes @a __rhs. False otherwise.
4300 */
4301 template<typename _CharT, typename _Traits, typename _Alloc>
4302 _GLIBCXX_NODISCARD
4303 inline bool
4304 operator<(const _CharT* __lhs,
4305 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
4306 { return __rhs.compare(__lhs) > 0; }
4307
4308 // operator >
4309 /**
4310 * @brief Test if string follows string.
4311 * @param __lhs First string.
4312 * @param __rhs Second string.
4313 * @return True if @a __lhs follows @a __rhs. False otherwise.
4314 */
4315 template<typename _CharT, typename _Traits, typename _Alloc>
4316 _GLIBCXX_NODISCARD
4317 inline bool
4318 operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4319 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
4320 _GLIBCXX_NOEXCEPT
4321 { return __lhs.compare(__rhs) > 0; }
4322
4323 /**
4324 * @brief Test if string follows C string.
4325 * @param __lhs String.
4326 * @param __rhs C string.
4327 * @return True if @a __lhs follows @a __rhs. False otherwise.
4328 */
4329 template<typename _CharT, typename _Traits, typename _Alloc>
4330 _GLIBCXX_NODISCARD
4331 inline bool
4332 operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4333 const _CharT* __rhs)
4334 { return __lhs.compare(__rhs) > 0; }
4335
4336 /**
4337 * @brief Test if C string follows string.
4338 * @param __lhs C string.
4339 * @param __rhs String.
4340 * @return True if @a __lhs follows @a __rhs. False otherwise.
4341 */
4342 template<typename _CharT, typename _Traits, typename _Alloc>
4343 _GLIBCXX_NODISCARD
4344 inline bool
4345 operator>(const _CharT* __lhs,
4346 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
4347 { return __rhs.compare(__lhs) < 0; }
4348
4349 // operator <=
4350 /**
4351 * @brief Test if string doesn't follow string.
4352 * @param __lhs First string.
4353 * @param __rhs Second string.
4354 * @return True if @a __lhs doesn't follow @a __rhs. False otherwise.
4355 */
4356 template<typename _CharT, typename _Traits, typename _Alloc>
4357 _GLIBCXX_NODISCARD
4358 inline bool
4359 operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4360 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
4361 _GLIBCXX_NOEXCEPT
4362 { return __lhs.compare(__rhs) <= 0; }
4363
4364 /**
4365 * @brief Test if string doesn't follow C string.
4366 * @param __lhs String.
4367 * @param __rhs C string.
4368 * @return True if @a __lhs doesn't follow @a __rhs. False otherwise.
4369 */
4370 template<typename _CharT, typename _Traits, typename _Alloc>
4371 _GLIBCXX_NODISCARD
4372 inline bool
4373 operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4374 const _CharT* __rhs)
4375 { return __lhs.compare(__rhs) <= 0; }
4376
4377 /**
4378 * @brief Test if C string doesn't follow string.
4379 * @param __lhs C string.
4380 * @param __rhs String.
4381 * @return True if @a __lhs doesn't follow @a __rhs. False otherwise.
4382 */
4383 template<typename _CharT, typename _Traits, typename _Alloc>
4384 _GLIBCXX_NODISCARD
4385 inline bool
4386 operator<=(const _CharT* __lhs,
4387 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
4388 { return __rhs.compare(__lhs) >= 0; }
4389
4390 // operator >=
4391 /**
4392 * @brief Test if string doesn't precede string.
4393 * @param __lhs First string.
4394 * @param __rhs Second string.
4395 * @return True if @a __lhs doesn't precede @a __rhs. False otherwise.
4396 */
4397 template<typename _CharT, typename _Traits, typename _Alloc>
4398 _GLIBCXX_NODISCARD
4399 inline bool
4400 operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4401 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
4402 _GLIBCXX_NOEXCEPT
4403 { return __lhs.compare(__rhs) >= 0; }
4404
4405 /**
4406 * @brief Test if string doesn't precede C string.
4407 * @param __lhs String.
4408 * @param __rhs C string.
4409 * @return True if @a __lhs doesn't precede @a __rhs. False otherwise.
4410 */
4411 template<typename _CharT, typename _Traits, typename _Alloc>
4412 _GLIBCXX_NODISCARD
4413 inline bool
4414 operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4415 const _CharT* __rhs)
4416 { return __lhs.compare(__rhs) >= 0; }
4417
4418 /**
4419 * @brief Test if C string doesn't precede string.
4420 * @param __lhs C string.
4421 * @param __rhs String.
4422 * @return True if @a __lhs doesn't precede @a __rhs. False otherwise.
4423 */
4424 template<typename _CharT, typename _Traits, typename _Alloc>
4425 _GLIBCXX_NODISCARD
4426 inline bool
4427 operator>=(const _CharT* __lhs,
4428 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
4429 { return __rhs.compare(__lhs) <= 0; }
4430#endif // three-way comparison
4431
4432 /**
4433 * @brief Swap contents of two strings.
4434 * @param __lhs First string.
4435 * @param __rhs Second string.
4436 *
4437 * Exchanges the contents of @a __lhs and @a __rhs in constant time.
4438 */
4439 template<typename _CharT, typename _Traits, typename _Alloc>
4440 _GLIBCXX20_CONSTEXPR
4441 inline void
4442 swap(basic_string<_CharT, _Traits, _Alloc>& __lhs,
4443 basic_string<_CharT, _Traits, _Alloc>& __rhs)
4444 _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs)))
4445 { __lhs.swap(__rhs); }
4446
4447
4448 /**
4449 * @brief Read stream into a string.
4450 * @param __is Input stream.
4451 * @param __str Buffer to store into.
4452 * @return Reference to the input stream.
4453 *
4454 * Stores characters from @a __is into @a __str until whitespace is
4455 * found, the end of the stream is encountered, or str.max_size()
4456 * is reached. If is.width() is non-zero, that is the limit on the
4457 * number of characters stored into @a __str. Any previous
4458 * contents of @a __str are erased.
4459 */
4460 template<typename _CharT, typename _Traits, typename _Alloc>
4461 basic_istream<_CharT, _Traits>&
4462 operator>>(basic_istream<_CharT, _Traits>& __is,
4463 basic_string<_CharT, _Traits, _Alloc>& __str);
4464
4465 template<>
4466 basic_istream<char>&
4467 operator>>(basic_istream<char>& __is, basic_string<char>& __str);
4468
4469 /**
4470 * @brief Write string to a stream.
4471 * @param __os Output stream.
4472 * @param __str String to write out.
4473 * @return Reference to the output stream.
4474 *
4475 * Output characters of @a __str into os following the same rules as for
4476 * writing a C string.
4477 */
4478 template<typename _CharT, typename _Traits, typename _Alloc>
4479 inline basic_ostream<_CharT, _Traits>&
4480 operator<<(basic_ostream<_CharT, _Traits>& __os,
4481 const basic_string<_CharT, _Traits, _Alloc>& __str)
4482 {
4483 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4484 // 586. string inserter not a formatted function
4485 return __ostream_insert(__os, __str.data(), __str.size());
4486 }
4487
4488 /**
4489 * @brief Read a line from stream into a string.
4490 * @param __is Input stream.
4491 * @param __str Buffer to store into.
4492 * @param __delim Character marking end of line.
4493 * @return Reference to the input stream.
4494 *
4495 * Stores characters from @a __is into @a __str until @a __delim is
4496 * found, the end of the stream is encountered, or str.max_size()
4497 * is reached. Any previous contents of @a __str are erased. If
4498 * @a __delim is encountered, it is extracted but not stored into
4499 * @a __str.
4500 */
4501 template<typename _CharT, typename _Traits, typename _Alloc>
4502 basic_istream<_CharT, _Traits>&
4503 getline(basic_istream<_CharT, _Traits>& __is,
4504 basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim);
4505
4506 /**
4507 * @brief Read a line from stream into a string.
4508 * @param __is Input stream.
4509 * @param __str Buffer to store into.
4510 * @return Reference to the input stream.
4511 *
4512 * Stores characters from is into @a __str until &apos;\n&apos; is
4513 * found, the end of the stream is encountered, or str.max_size()
4514 * is reached. Any previous contents of @a __str are erased. If
4515 * end of line is encountered, it is extracted but not stored into
4516 * @a __str.
4517 */
4518 template<typename _CharT, typename _Traits, typename _Alloc>
4519 inline basic_istream<_CharT, _Traits>&
4520 getline(basic_istream<_CharT, _Traits>& __is,
4521 basic_string<_CharT, _Traits, _Alloc>& __str)
4522 { return std::getline(__is, __str, __is.widen('\n')); }
4523
4524#if __cplusplus >= 201103L
4525 /// Read a line from an rvalue stream into a string.
4526 template<typename _CharT, typename _Traits, typename _Alloc>
4527 inline basic_istream<_CharT, _Traits>&
4528 getline(basic_istream<_CharT, _Traits>&& __is,
4529 basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim)
4530 { return std::getline(__is, __str, __delim); }
4531
4532 /// Read a line from an rvalue stream into a string.
4533 template<typename _CharT, typename _Traits, typename _Alloc>
4534 inline basic_istream<_CharT, _Traits>&
4535 getline(basic_istream<_CharT, _Traits>&& __is,
4536 basic_string<_CharT, _Traits, _Alloc>& __str)
4537 { return std::getline(__is, __str); }
4538#endif
4539
4540 template<>
4541 basic_istream<char>&
4542 getline(basic_istream<char>& __in, basic_string<char>& __str,
4543 char __delim);
4544
4545#ifdef _GLIBCXX_USE_WCHAR_T
4546 template<>
4547 basic_istream<wchar_t>&
4548 getline(basic_istream<wchar_t>& __in, basic_string<wchar_t>& __str,
4549 wchar_t __delim);
4550#endif
4551
4552_GLIBCXX_END_NAMESPACE_VERSION
4553} // namespace
4554
4555#if __cplusplus >= 201103L
4556
4557#include <ext/string_conversions.h>
4558#include <bits/charconv.h>
4559
4560namespace std _GLIBCXX_VISIBILITY(default)
4561{
4562_GLIBCXX_BEGIN_NAMESPACE_VERSION
4563_GLIBCXX_BEGIN_NAMESPACE_CXX11
4564
4565 // 21.4 Numeric Conversions [string.conversions].
4566 inline int
4567 stoi(const string& __str, size_t* __idx = 0, int __base = 10)
4568 { return __gnu_cxx::__stoa<long, int>(&std::strtol, "stoi", __str.c_str(),
4569 __idx, __base); }
4570
4571 inline long
4572 stol(const string& __str, size_t* __idx = 0, int __base = 10)
4573 { return __gnu_cxx::__stoa(&std::strtol, "stol", __str.c_str(),
4574 __idx, __base); }
4575
4576 inline unsigned long
4577 stoul(const string& __str, size_t* __idx = 0, int __base = 10)
4578 { return __gnu_cxx::__stoa(&std::strtoul, "stoul", __str.c_str(),
4579 __idx, __base); }
4580
4581#if _GLIBCXX_USE_C99_STDLIB
4582 inline long long
4583 stoll(const string& __str, size_t* __idx = 0, int __base = 10)
4584 { return __gnu_cxx::__stoa(&std::strtoll, "stoll", __str.c_str(),
4585 __idx, __base); }
4586
4587 inline unsigned long long
4588 stoull(const string& __str, size_t* __idx = 0, int __base = 10)
4589 { return __gnu_cxx::__stoa(&std::strtoull, "stoull", __str.c_str(),
4590 __idx, __base); }
4591#elif __LONG_WIDTH__ == __LONG_LONG_WIDTH__
4592 inline long long
4593 stoll(const string& __str, size_t* __idx = 0, int __base = 10)
4594 { return std::stol(__str, __idx, __base); }
4595
4596 inline unsigned long long
4597 stoull(const string& __str, size_t* __idx = 0, int __base = 10)
4598 { return std::stoul(__str, __idx, __base); }
4599#endif
4600
4601 inline double
4602 stod(const string& __str, size_t* __idx = 0)
4603 { return __gnu_cxx::__stoa(&std::strtod, "stod", __str.c_str(), __idx); }
4604
4605#if _GLIBCXX_HAVE_STRTOF
4606 // NB: strtof vs strtod.
4607 inline float
4608 stof(const string& __str, size_t* __idx = 0)
4609 { return __gnu_cxx::__stoa(&std::strtof, "stof", __str.c_str(), __idx); }
4610#else
4611 inline float
4612 stof(const string& __str, size_t* __idx = 0)
4613 {
4614 double __d = std::stod(__str, __idx);
4615 if (__builtin_isfinite(__d) && __d != 0.0)
4616 {
4617 double __abs_d = __builtin_fabs(__d);
4618 if (__abs_d < __FLT_MIN__ || __abs_d > __FLT_MAX__)
4619 {
4620 errno = ERANGE;
4621 std::__throw_out_of_range("stof");
4622 }
4623 }
4624 return __d;
4625 }
4626#endif
4627
4628#if _GLIBCXX_HAVE_STRTOLD && ! _GLIBCXX_HAVE_BROKEN_STRTOLD
4629 inline long double
4630 stold(const string& __str, size_t* __idx = 0)
4631 { return __gnu_cxx::__stoa(&std::strtold, "stold", __str.c_str(), __idx); }
4632#elif __DBL_MANT_DIG__ == __LDBL_MANT_DIG__
4633 inline long double
4634 stold(const string& __str, size_t* __idx = 0)
4635 { return std::stod(__str, __idx); }
4636#endif
4637
4638#if __glibcxx_constexpr_string >= 202511L
4639# define _GLIBCXX_TO_STRING_CONSTEXPR constexpr
4640#else
4641# define _GLIBCXX_TO_STRING_CONSTEXPR inline
4642#endif
4643
4644 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4645 // DR 1261. Insufficient overloads for to_string / to_wstring
4646
4647 _GLIBCXX_NODISCARD
4648 _GLIBCXX_TO_STRING_CONSTEXPR string
4649 to_string(int __val)
4650#if _GLIBCXX_USE_CXX11_ABI && (__CHAR_BIT__ * __SIZEOF_INT__) <= 32
4651 noexcept // any 32-bit value fits in the SSO buffer
4652#endif
4653 {
4654 const bool __neg = __val < 0;
4655 const unsigned __uval = __neg ? (unsigned)~__val + 1u : __val;
4656 const auto __len = __detail::__to_chars_len(__uval);
4657 string __str;
4658 __str.__resize_and_overwrite(__neg + __len, [=](char* __p, size_t __n) {
4659 __p[0] = '-';
4660 __detail::__to_chars_10_impl(__p + (int)__neg, __len, __uval);
4661 return __n;
4662 });
4663 return __str;
4664 }
4665
4666 _GLIBCXX_NODISCARD
4667 _GLIBCXX_TO_STRING_CONSTEXPR string
4668 to_string(unsigned __val)
4669#if _GLIBCXX_USE_CXX11_ABI && (__CHAR_BIT__ * __SIZEOF_INT__) <= 32
4670 noexcept // any 32-bit value fits in the SSO buffer
4671#endif
4672 {
4673 const auto __len = __detail::__to_chars_len(__val);
4674 string __str;
4675 __str.__resize_and_overwrite(__len, [__val](char* __p, size_t __n) {
4676 __detail::__to_chars_10_impl(__p, __n, __val);
4677 return __n;
4678 });
4679 return __str;
4680 }
4681
4682 _GLIBCXX_NODISCARD
4683 _GLIBCXX_TO_STRING_CONSTEXPR string
4684 to_string(long __val)
4685#if _GLIBCXX_USE_CXX11_ABI && (__CHAR_BIT__ * __SIZEOF_LONG__) <= 32
4686 noexcept // any 32-bit value fits in the SSO buffer
4687#endif
4688 {
4689 const bool __neg = __val < 0;
4690 const unsigned long __uval = __neg ? (unsigned long)~__val + 1ul : __val;
4691 const auto __len = __detail::__to_chars_len(__uval);
4692 string __str;
4693 __str.__resize_and_overwrite(__neg + __len, [=](char* __p, size_t __n) {
4694 __p[0] = '-';
4695 __detail::__to_chars_10_impl(__p + (int)__neg, __len, __uval);
4696 return __n;
4697 });
4698 return __str;
4699 }
4700
4701 _GLIBCXX_NODISCARD
4702 _GLIBCXX_TO_STRING_CONSTEXPR string
4703 to_string(unsigned long __val)
4704#if _GLIBCXX_USE_CXX11_ABI && (__CHAR_BIT__ * __SIZEOF_LONG__) <= 32
4705 noexcept // any 32-bit value fits in the SSO buffer
4706#endif
4707 {
4708 const auto __len = __detail::__to_chars_len(__val);
4709 string __str;
4710 __str.__resize_and_overwrite(__len, [__val](char* __p, size_t __n) {
4711 __detail::__to_chars_10_impl(__p, __n, __val);
4712 return __n;
4713 });
4714 return __str;
4715 }
4716
4717 _GLIBCXX_NODISCARD
4718 _GLIBCXX_TO_STRING_CONSTEXPR string
4719 to_string(long long __val)
4720 {
4721 const bool __neg = __val < 0;
4722 const unsigned long long __uval
4723 = __neg ? (unsigned long long)~__val + 1ull : __val;
4724 const auto __len = __detail::__to_chars_len(__uval);
4725 string __str;
4726 __str.__resize_and_overwrite(__neg + __len, [=](char* __p, size_t __n) {
4727 __p[0] = '-';
4728 __detail::__to_chars_10_impl(__p + (int)__neg, __len, __uval);
4729 return __n;
4730 });
4731 return __str;
4732 }
4733
4734 _GLIBCXX_NODISCARD
4735 _GLIBCXX_TO_STRING_CONSTEXPR string
4736 to_string(unsigned long long __val)
4737 {
4738 const auto __len = __detail::__to_chars_len(__val);
4739 string __str;
4740 __str.__resize_and_overwrite(__len, [__val](char* __p, size_t __n) {
4741 __detail::__to_chars_10_impl(__p, __n, __val);
4742 return __n;
4743 });
4744 return __str;
4745 }
4746
4747#if __glibcxx_to_string >= 202306L // C++ >= 26
4748
4749 [[nodiscard]]
4750 inline string
4751 to_string(float __val)
4752 {
4753 string __str;
4754 size_t __len = 15;
4755 do {
4756 __str.resize_and_overwrite(__len,
4757 [__val, &__len] (char* __p, size_t __n) {
4758 auto [__end, __err] = std::to_chars(__p, __p + __n, __val);
4759 if (__err == errc{}) [[likely]]
4760 return __end - __p;
4761 __len *= 2;
4762 return __p - __p;;
4763 });
4764 } while (__str.empty());
4765 return __str;
4766 }
4767
4768 [[nodiscard]]
4769 inline string
4770 to_string(double __val)
4771 {
4772 string __str;
4773 size_t __len = 15;
4774 do {
4775 __str.resize_and_overwrite(__len,
4776 [__val, &__len] (char* __p, size_t __n) {
4777 auto [__end, __err] = std::to_chars(__p, __p + __n, __val);
4778 if (__err == errc{}) [[likely]]
4779 return __end - __p;
4780 __len *= 2;
4781 return __p - __p;;
4782 });
4783 } while (__str.empty());
4784 return __str;
4785 }
4786
4787 [[nodiscard]]
4788 inline string
4789 to_string(long double __val)
4790 {
4791 string __str;
4792 size_t __len = 15;
4793 do {
4794 __str.resize_and_overwrite(__len,
4795 [__val, &__len] (char* __p, size_t __n) {
4796 auto [__end, __err] = std::to_chars(__p, __p + __n, __val);
4797 if (__err == errc{}) [[likely]]
4798 return __end - __p;
4799 __len *= 2;
4800 return __p - __p;;
4801 });
4802 } while (__str.empty());
4803 return __str;
4804 }
4805#elif _GLIBCXX_USE_C99_STDIO
4806#pragma GCC diagnostic push
4807#pragma GCC diagnostic ignored "-Wsuggest-attribute=format"
4808 // NB: (v)snprintf vs sprintf.
4809
4810 _GLIBCXX_NODISCARD
4811 inline string
4812 to_string(float __val)
4813 {
4814 const int __n =
4815 __gnu_cxx::__numeric_traits<float>::__max_exponent10 + 20;
4816 return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, __n,
4817 "%f", __val);
4818 }
4819
4820 _GLIBCXX_NODISCARD
4821 inline string
4822 to_string(double __val)
4823 {
4824 const int __n =
4825 __gnu_cxx::__numeric_traits<double>::__max_exponent10 + 20;
4826 return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, __n,
4827 "%f", __val);
4828 }
4829
4830 _GLIBCXX_NODISCARD
4831 inline string
4832 to_string(long double __val)
4833 {
4834 const int __n =
4835 __gnu_cxx::__numeric_traits<long double>::__max_exponent10 + 20;
4836 return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, __n,
4837 "%Lf", __val);
4838 }
4839#pragma GCC diagnostic pop
4840#endif // _GLIBCXX_USE_C99_STDIO
4841
4842#if defined(_GLIBCXX_USE_WCHAR_T) && _GLIBCXX_USE_C99_WCHAR
4843 inline int
4844 stoi(const wstring& __str, size_t* __idx = 0, int __base = 10)
4845 { return __gnu_cxx::__stoa<long, int>(&std::wcstol, "stoi", __str.c_str(),
4846 __idx, __base); }
4847
4848 inline long
4849 stol(const wstring& __str, size_t* __idx = 0, int __base = 10)
4850 { return __gnu_cxx::__stoa(&std::wcstol, "stol", __str.c_str(),
4851 __idx, __base); }
4852
4853 inline unsigned long
4854 stoul(const wstring& __str, size_t* __idx = 0, int __base = 10)
4855 { return __gnu_cxx::__stoa(&std::wcstoul, "stoul", __str.c_str(),
4856 __idx, __base); }
4857
4858 inline long long
4859 stoll(const wstring& __str, size_t* __idx = 0, int __base = 10)
4860 { return __gnu_cxx::__stoa(&std::wcstoll, "stoll", __str.c_str(),
4861 __idx, __base); }
4862
4863 inline unsigned long long
4864 stoull(const wstring& __str, size_t* __idx = 0, int __base = 10)
4865 { return __gnu_cxx::__stoa(&std::wcstoull, "stoull", __str.c_str(),
4866 __idx, __base); }
4867
4868 // NB: wcstof vs wcstod.
4869 inline float
4870 stof(const wstring& __str, size_t* __idx = 0)
4871 { return __gnu_cxx::__stoa(&std::wcstof, "stof", __str.c_str(), __idx); }
4872
4873 inline double
4874 stod(const wstring& __str, size_t* __idx = 0)
4875 { return __gnu_cxx::__stoa(&std::wcstod, "stod", __str.c_str(), __idx); }
4876
4877 inline long double
4878 stold(const wstring& __str, size_t* __idx = 0)
4879 { return __gnu_cxx::__stoa(&std::wcstold, "stold", __str.c_str(), __idx); }
4880#endif
4881
4882#ifdef _GLIBCXX_USE_WCHAR_T
4883#pragma GCC diagnostic push
4884#pragma GCC diagnostic ignored "-Wc++17-extensions"
4885 _GLIBCXX20_CONSTEXPR
4886 inline void
4887 __to_wstring_numeric(const char* __s, int __len, wchar_t* __wout)
4888 {
4889 // This condition is true if exec-charset and wide-exec-charset share the
4890 // same values for the ASCII subset or the EBCDIC invariant character set.
4891 if constexpr (wchar_t('0') == L'0' && wchar_t('-') == L'-'
4892 && wchar_t('.') == L'.' && wchar_t('e') == L'e')
4893 {
4894 for (int __i = 0; __i < __len; ++__i)
4895 __wout[__i] = (wchar_t) __s[__i];
4896 }
4897 else
4898 {
4899 wchar_t __wc[256];
4900 for (int __i = '0'; __i <= '9'; ++__i)
4901 __wc[__i] = L'0' + __i;
4902 __wc['.'] = L'.';
4903 __wc['+'] = L'+';
4904 __wc['-'] = L'-';
4905 __wc['a'] = L'a';
4906 __wc['b'] = L'b';
4907 __wc['c'] = L'c';
4908 __wc['d'] = L'd';
4909 __wc['e'] = L'e';
4910 __wc['f'] = L'f';
4911 __wc['i'] = L'i'; // for "inf"
4912 __wc['n'] = L'n'; // for "nan" and "inf"
4913 __wc['p'] = L'p'; // for hexfloats "0x1p1"
4914 __wc['x'] = L'x';
4915 __wc['A'] = L'A';
4916 __wc['B'] = L'B';
4917 __wc['C'] = L'C';
4918 __wc['D'] = L'D';
4919 __wc['E'] = L'E';
4920 __wc['F'] = L'F';
4921 __wc['I'] = L'I';
4922 __wc['N'] = L'N';
4923 __wc['P'] = L'P';
4924 __wc['X'] = L'X';
4925
4926 for (int __i = 0; __i < __len; ++__i)
4927 __wout[__i] = __wc[(int)__s[__i]];
4928 }
4929 }
4930
4931#if __glibcxx_constexpr_string >= 201907L
4932 constexpr
4933#endif
4934 inline wstring
4935#ifdef __glibcxx_string_view // >= C++17
4936 __to_wstring_numeric(string_view __s)
4937#else
4938 __to_wstring_numeric(const string& __s)
4939#endif
4940 {
4941 if constexpr (wchar_t('0') == L'0' && wchar_t('-') == L'-'
4942 && wchar_t('.') == L'.' && wchar_t('e') == L'e')
4943 return wstring(__s.data(), __s.data() + __s.size());
4944 else
4945 {
4946 wstring __ws;
4947 auto __f = __s.data();
4948 __ws.__resize_and_overwrite(__s.size(),
4949 [__f] (wchar_t* __to, int __n) {
4950 std::__to_wstring_numeric(__f, __n, __to);
4951 return __n;
4952 });
4953 return __ws;
4954 }
4955 }
4956#pragma GCC diagnostic pop
4957
4958 _GLIBCXX_NODISCARD
4959 _GLIBCXX_TO_STRING_CONSTEXPR wstring
4960 to_wstring(int __val)
4961 { return std::__to_wstring_numeric(std::to_string(__val)); }
4962
4963 _GLIBCXX_NODISCARD
4964 _GLIBCXX_TO_STRING_CONSTEXPR wstring
4965 to_wstring(unsigned __val)
4966 { return std::__to_wstring_numeric(std::to_string(__val)); }
4967
4968 _GLIBCXX_NODISCARD
4969 _GLIBCXX_TO_STRING_CONSTEXPR wstring
4970 to_wstring(long __val)
4971 { return std::__to_wstring_numeric(std::to_string(__val)); }
4972
4973 _GLIBCXX_NODISCARD
4974 _GLIBCXX_TO_STRING_CONSTEXPR wstring
4975 to_wstring(unsigned long __val)
4976 { return std::__to_wstring_numeric(std::to_string(__val)); }
4977
4978 _GLIBCXX_NODISCARD
4979 _GLIBCXX_TO_STRING_CONSTEXPR wstring
4980 to_wstring(long long __val)
4981 { return std::__to_wstring_numeric(std::to_string(__val)); }
4982
4983 _GLIBCXX_NODISCARD
4984 _GLIBCXX_TO_STRING_CONSTEXPR wstring
4985 to_wstring(unsigned long long __val)
4986 { return std::__to_wstring_numeric(std::to_string(__val)); }
4987
4988#if __glibcxx_to_string || _GLIBCXX_USE_C99_STDIO
4989 _GLIBCXX_NODISCARD
4990 inline wstring
4991 to_wstring(float __val)
4992 { return std::__to_wstring_numeric(std::to_string(__val)); }
4993
4994 _GLIBCXX_NODISCARD
4995 inline wstring
4996 to_wstring(double __val)
4997 { return std::__to_wstring_numeric(std::to_string(__val)); }
4998
4999 _GLIBCXX_NODISCARD
5000 inline wstring
5001 to_wstring(long double __val)
5002 { return std::__to_wstring_numeric(std::to_string(__val)); }
5003#endif
5004#endif // _GLIBCXX_USE_WCHAR_T
5005#undef _GLIBCXX_TO_STRING_CONSTEXPR
5006
5007_GLIBCXX_END_NAMESPACE_CXX11
5008_GLIBCXX_END_NAMESPACE_VERSION
5009} // namespace
5010
5011#endif /* C++11 */
5012
5013#if __cplusplus >= 201103L
5014
5015#include <bits/functional_hash.h>
5016
5017namespace std _GLIBCXX_VISIBILITY(default)
5018{
5019_GLIBCXX_BEGIN_NAMESPACE_VERSION
5020
5021 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5022 // 3705. Hashability shouldn't depend on basic_string's allocator
5023
5024 template<typename _CharT, typename _Alloc,
5025 typename _StrT = basic_string<_CharT, char_traits<_CharT>, _Alloc>>
5026 struct __str_hash_base
5027 : public __hash_base<size_t, _StrT>
5028 {
5029 [[__nodiscard__]]
5030 size_t
5031 operator()(const _StrT& __s) const noexcept
5032 { return _Hash_impl::hash(__s.data(), __s.length() * sizeof(_CharT)); }
5033 };
5034
5035#ifndef _GLIBCXX_COMPATIBILITY_CXX0X
5036 /// std::hash specialization for string.
5037 template<typename _Alloc>
5038 struct hash<basic_string<char, char_traits<char>, _Alloc>>
5039 : public __str_hash_base<char, _Alloc>
5040 { };
5041
5042 /// std::hash specialization for wstring.
5043 template<typename _Alloc>
5044 struct hash<basic_string<wchar_t, char_traits<wchar_t>, _Alloc>>
5045 : public __str_hash_base<wchar_t, _Alloc>
5046 { };
5047
5048 template<typename _Alloc>
5049 struct __is_fast_hash<hash<basic_string<wchar_t, char_traits<wchar_t>,
5050 _Alloc>>>
5051 : std::false_type
5052 { };
5053#endif /* _GLIBCXX_COMPATIBILITY_CXX0X */
5054
5055#ifdef _GLIBCXX_USE_CHAR8_T
5056 /// std::hash specialization for u8string.
5057 template<typename _Alloc>
5058 struct hash<basic_string<char8_t, char_traits<char8_t>, _Alloc>>
5059 : public __str_hash_base<char8_t, _Alloc>
5060 { };
5061#endif
5062
5063 /// std::hash specialization for u16string.
5064 template<typename _Alloc>
5065 struct hash<basic_string<char16_t, char_traits<char16_t>, _Alloc>>
5066 : public __str_hash_base<char16_t, _Alloc>
5067 { };
5068
5069 /// std::hash specialization for u32string.
5070 template<typename _Alloc>
5071 struct hash<basic_string<char32_t, char_traits<char32_t>, _Alloc>>
5072 : public __str_hash_base<char32_t, _Alloc>
5073 { };
5074
5075#if ! _GLIBCXX_INLINE_VERSION
5076 // PR libstdc++/105907 - __is_fast_hash affects unordered container ABI.
5077 template<> struct __is_fast_hash<hash<string>> : std::false_type { };
5078 template<> struct __is_fast_hash<hash<wstring>> : std::false_type { };
5079 template<> struct __is_fast_hash<hash<u16string>> : std::false_type { };
5080 template<> struct __is_fast_hash<hash<u32string>> : std::false_type { };
5081#ifdef _GLIBCXX_USE_CHAR8_T
5082 template<> struct __is_fast_hash<hash<u8string>> : std::false_type { };
5083#endif
5084#else
5085 // For versioned namespace, assume every std::hash<basic_string<>> is slow.
5086 template<typename _CharT, typename _Traits, typename _Alloc>
5087 struct __is_fast_hash<hash<basic_string<_CharT, _Traits, _Alloc>>>
5088 : std::false_type
5089 { };
5090#endif
5091
5092#ifdef __glibcxx_string_udls // C++ >= 14
5093 inline namespace literals
5094 {
5095 inline namespace string_literals
5096 {
5097#pragma GCC diagnostic push
5098#pragma GCC diagnostic ignored "-Wliteral-suffix"
5099
5100#if __glibcxx_constexpr_string >= 201907L
5101# define _GLIBCXX_STRING_CONSTEXPR constexpr
5102#else
5103# define _GLIBCXX_STRING_CONSTEXPR
5104#endif
5105
5106 _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_STRING_CONSTEXPR
5107 inline basic_string<char>
5108 operator""s(const char* __str, size_t __len)
5109 { return basic_string<char>{__str, __len}; }
5110
5111 _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_STRING_CONSTEXPR
5112 inline basic_string<wchar_t>
5113 operator""s(const wchar_t* __str, size_t __len)
5114 { return basic_string<wchar_t>{__str, __len}; }
5115
5116#ifdef _GLIBCXX_USE_CHAR8_T
5117 _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_STRING_CONSTEXPR
5118 inline basic_string<char8_t>
5119 operator""s(const char8_t* __str, size_t __len)
5120 { return basic_string<char8_t>{__str, __len}; }
5121#endif
5122
5123 _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_STRING_CONSTEXPR
5124 inline basic_string<char16_t>
5125 operator""s(const char16_t* __str, size_t __len)
5126 { return basic_string<char16_t>{__str, __len}; }
5127
5128 _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_STRING_CONSTEXPR
5129 inline basic_string<char32_t>
5130 operator""s(const char32_t* __str, size_t __len)
5131 { return basic_string<char32_t>{__str, __len}; }
5132
5133#undef _GLIBCXX_STRING_CONSTEXPR
5134#pragma GCC diagnostic pop
5135 } // inline namespace string_literals
5136 } // inline namespace literals
5137#endif // __glibcxx_string_udls
5138
5139#ifdef __glibcxx_variant // >= C++17
5140 namespace __detail::__variant
5141 {
5142 template<typename> struct _Never_valueless_alt; // see <variant>
5143
5144 // Provide the strong exception-safety guarantee when emplacing a
5145 // basic_string into a variant, but only if moving the string cannot throw.
5146 template<typename _Tp, typename _Traits, typename _Alloc>
5147 struct _Never_valueless_alt<std::basic_string<_Tp, _Traits, _Alloc>>
5148 : __and_<
5149 is_nothrow_move_constructible<std::basic_string<_Tp, _Traits, _Alloc>>,
5150 is_nothrow_move_assignable<std::basic_string<_Tp, _Traits, _Alloc>>
5151 >::type
5152 { };
5153 } // namespace __detail::__variant
5154#endif // C++17
5155
5156_GLIBCXX_END_NAMESPACE_VERSION
5157} // namespace std
5158
5159#endif // C++11
5160
5161#endif /* _BASIC_STRING_H */
initializer_list
charconv
string_view
functional_hash.h
ranges_algobase.h
ranges_util.h
version.h
charconv.h
cow_string.h
debug.h
string_conversions.h
std::operator+
constexpr complex< _Tp > operator+(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x plus y.
Definition complex:374
std::to_address
constexpr _Tp * to_address(_Tp *__ptr) noexcept
Obtain address referenced by a pointer to an object.
Definition ptr_traits.h:234
std::enable_if_t
typename enable_if< _Cond, _Tp >::type enable_if_t
Alias template for enable_if.
Definition type_traits:2969
std::false_type
__bool_constant< false > false_type
The type used as a compile-time boolean with false value.
Definition type_traits:122
std::move
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition move.h:138
std::__addressof
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
Definition move.h:52
std::forward
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
Definition move.h:72
std::min
constexpr const _Tp & min(const _Tp &, const _Tp &)
This does what you think it does.
Definition stl_algobase.h:232
std::string
basic_string< char > string
A string of char.
Definition stringfwd.h:79
std::u32string
basic_string< char32_t > u32string
A string of char32_t.
Definition stringfwd.h:94
std::u16string
basic_string< char16_t > u16string
A string of char16_t.
Definition stringfwd.h:91
std::wstring
basic_string< wchar_t > wstring
A string of wchar_t.
Definition stringfwd.h:82
std
ISO C++ entities toplevel namespace is std.
std::getline
basic_istream< _CharT, _Traits > & getline(basic_istream< _CharT, _Traits > &__is, basic_string< _CharT, _Traits, _Alloc > &__str, _CharT __delim)
Read a line from stream into a string.
Definition basic_string.tcc:982
std::size
constexpr auto size(const _Container &__cont) noexcept(noexcept(__cont.size())) -> decltype(__cont.size())
Return the size of a container.
Definition range_access.h:294
std::operator>>
std::basic_istream< _CharT, _Traits > & operator>>(std::basic_istream< _CharT, _Traits > &__is, bitset< _Nb > &__x)
Global I/O operators for bitsets.
Definition bitset:1702
std::operator<<
std::basic_ostream< _CharT, _Traits > & operator<<(std::basic_ostream< _CharT, _Traits > &__os, const bitset< _Nb > &__x)
Global I/O operators for bitsets.
Definition bitset:1798
std::literals
ISO C++ inline namespace for literal suffixes.
std::initializer_list
initializer_list
Definition initializer_list:53
std::basic_istream
Template class basic_istream.
Definition istream:73
std::basic_string_view
A non-owning reference to a string.
Definition string_view:114
std::hash
Primary class template hash.
Definition functional_hash.h:106
std::is_pointer
is_pointer
Definition type_traits:651
std::is_same
is_same
Definition type_traits:1649
std::is_nothrow_default_constructible
is_nothrow_default_constructible
Definition type_traits:1352
std::size_type
__gnu_cxx::__alloc_traits< _Char_alloc_type >::allocate_at_least
static constexpr allocation_result< pointer, size_type > allocate_at_least(_Char_alloc_type &__a, size_type __n)
Definition bits/alloc_traits.h:424
std::allocator
The standard allocator, as per C++03 [20.4.1].
Definition allocator.h:134
std::basic_ios::widen
char_type widen(char __c) const
Widens characters.
Definition basic_ios.h:465
std::basic_string
Managing sequences of characters and character-like objects.
Definition basic_string.h:94
std::basic_string::c_str
constexpr const _CharT * c_str() const noexcept
Return const pointer to null-terminated contents.
Definition basic_string.h:2955
std::basic_string::basic_string
constexpr basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc &__a=_Alloc())
Construct string as copy of a range.
Definition basic_string.h:906
std::basic_string::basic_string
constexpr basic_string(const _Alloc &__a) noexcept
Construct an empty string using allocator a.
Definition basic_string.h:635
std::basic_string::find_first_not_of
constexpr size_type find_first_not_of(_CharT __c, size_type __pos=0) const noexcept
Find position of a different character.
Definition basic_string.tcc:853
std::basic_string::append
constexpr basic_string & append(const basic_string &__str, size_type __pos, size_type __n=npos)
Append a substring.
Definition basic_string.h:1607
std::basic_string::basic_string
constexpr basic_string() noexcept(/*conditional */)
Default constructor creates an empty string.
Definition basic_string.h:619
std::basic_string::at
constexpr reference at(size_type __n)
Provides access to the data contained in the string.
Definition basic_string.h:1463
std::basic_string::replace
constexpr basic_string & replace(size_type __pos, size_type __n1, const _CharT *__s)
Replace characters with value of a C string.
Definition basic_string.h:2566
std::basic_string::find
constexpr size_type find(const _CharT *__s, size_type __pos=0) const noexcept
Find position of a C string.
Definition basic_string.h:3055
std::basic_string::replace
constexpr basic_string & replace(__const_iterator __i1, __const_iterator __i2, const basic_string &__str)
Replace range of characters with string.
Definition basic_string.h:2610
std::basic_string::size
constexpr size_type size() const noexcept
Returns the number of characters in the string, not including any null-termination.
Definition basic_string.h:1217
std::basic_string::basic_string
constexpr basic_string(const _CharT *__s, const _Alloc &__a=_Alloc())
Construct string as copy of a C string.
Definition basic_string.h:760
std::basic_string::begin
constexpr const_iterator begin() const noexcept
Definition basic_string.h:1110
std::basic_string::clear
constexpr void clear() noexcept
Definition basic_string.h:1376
std::basic_string< _CharT >::find_last_not_of
constexpr size_type find_last_not_of(const basic_string &__str, size_type __pos=npos) const noexcept
Definition basic_string.h:3435
std::basic_string::operator=
constexpr basic_string & operator=(const _CharT *__s)
Copy contents of s into this string.
Definition basic_string.h:969
std::basic_string::rend
constexpr const_reverse_iterator rend() const noexcept
Definition basic_string.h:1168
std::basic_string::reserve
constexpr void reserve(size_type __res_arg)
Attempt to preallocate enough memory for specified number of characters.
Definition cow_string.h:3695
std::basic_string::find
constexpr size_type find(const _CharT *__s, size_type __pos, size_type __n) const noexcept
Find position of a C substring.
Definition basic_string.tcc:702
std::basic_string::assign
constexpr basic_string & assign(const _CharT *__s, size_type __n)
Set value to a C substring.
Definition basic_string.h:1895
std::basic_string::replace
constexpr basic_string & replace(__const_iterator __i1, __const_iterator __i2, size_type __n, _CharT __c)
Replace range of characters with multiple characters.
Definition basic_string.h:2676
std::basic_string::data
constexpr const _CharT * data() const noexcept
Return const pointer to contents.
Definition basic_string.h:2968
std::basic_string::shrink_to_fit
constexpr void shrink_to_fit() noexcept
A non-binding request to reduce capacity() to size().
Definition basic_string.h:1278
std::basic_string::find_first_not_of
constexpr size_type find_first_not_of(const _CharT *__s, size_type __pos, size_type __n) const noexcept
Find position of a character not in C substring.
Definition basic_string.tcc:839
std::basic_string::substr
constexpr basic_string substr(size_type __pos=0, size_type __n=npos) const
Get a substring.
Definition basic_string.h:3523
std::basic_string::find_first_of
constexpr size_type find_first_of(const _CharT *__s, size_type __pos=0) const noexcept
Find position of a character of C string.
Definition basic_string.h:3223
std::basic_string::compare
constexpr int compare(size_type __pos, size_type __n, const basic_string &__str) const
Compare substring to a string.
Definition basic_string.h:3669
std::basic_string::compare
constexpr int compare(size_type __pos1, size_type __n1, const basic_string &__str, size_type __pos2, size_type __n2=npos) const
Compare substring to a substring.
Definition basic_string.h:3706
std::basic_string::rfind
constexpr size_type rfind(_CharT __c, size_type __pos=npos) const noexcept
Find last position of a character.
Definition basic_string.tcc:781
std::basic_string::back
constexpr reference back() noexcept
Definition basic_string.h:1504
std::basic_string::find_first_of
constexpr size_type find_first_of(const _CharT *__s, size_type __pos, size_type __n) const noexcept
Find position of a character of C substring.
Definition basic_string.tcc:799
std::basic_string::basic_string
constexpr basic_string(const basic_string &__str, size_type __pos, const _Alloc &__a=_Alloc())
Construct string as copy of a substring.
Definition basic_string.h:663
std::basic_string::basic_string
constexpr basic_string(const basic_string &__str, size_type __pos, size_type __n)
Construct string as copy of a substring.
Definition basic_string.h:680
std::basic_string::replace
constexpr basic_string & replace(const_iterator __i1, const_iterator __i2, initializer_list< _CharT > __l)
Replace range of characters with initializer_list.
Definition basic_string.h:2821
std::basic_string::assign
constexpr basic_string & assign(initializer_list< _CharT > __l)
Set value to an initializer_list of characters.
Definition basic_string.h:2007
std::basic_string::rfind
constexpr size_type rfind(const _CharT *__s, size_type __pos=npos) const
Find last position of a C string.
Definition basic_string.h:3138
std::basic_string::find_first_not_of
constexpr size_type find_first_not_of(const _CharT *__s, size_type __pos=0) const noexcept
Find position of a character not in C string.
Definition basic_string.h:3400
std::basic_string::operator+=
constexpr basic_string & operator+=(const _CharT *__s)
Append a C string.
Definition basic_string.h:1541
std::basic_string::assign
constexpr basic_string & assign(const basic_string &__str)
Set value to contents of another string.
Definition basic_string.h:1808
std::basic_string::basic_string
constexpr basic_string(const basic_string &__str)
Construct string with copy of value of __str.
Definition basic_string.h:647
std::basic_string::append
constexpr basic_string & append(initializer_list< _CharT > __l)
Append an initializer_list of characters.
Definition basic_string.h:1715
std::basic_string::basic_string
constexpr basic_string(size_type __n, _CharT __c, const _Alloc &__a=_Alloc())
Construct string as multiple characters.
Definition basic_string.h:783
std::basic_string::append
constexpr basic_string & append(size_type __n, _CharT __c)
Append multiple characters.
Definition basic_string.h:1652
std::basic_string::length
constexpr size_type length() const noexcept
Returns the number of characters in the string, not including any null-termination.
Definition basic_string.h:1229
std::basic_string::crbegin
constexpr const_reverse_iterator crbegin() const noexcept
Definition basic_string.h:1197
std::basic_string::basic_string
constexpr basic_string(const basic_string &__str, size_type __pos, size_type __n, const _Alloc &__a)
Construct string as copy of a substring.
Definition basic_string.h:698
std::basic_string::find_last_of
constexpr size_type find_last_of(_CharT __c, size_type __pos=npos) const noexcept
Find last position of a character.
Definition basic_string.h:3333
std::basic_string::replace
constexpr basic_string & replace(size_type __pos, size_type __n1, const _CharT *__s, size_type __n2)
Replace characters with value of a C substring.
Definition basic_string.h:2540
std::basic_string::assign
constexpr basic_string & assign(basic_string &&__str) noexcept(_Alloc_traits::_S_nothrow_move())
Set value to contents of another string.
Definition basic_string.h:1854
std::basic_string::replace
constexpr basic_string & replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
Replace characters with multiple characters.
Definition basic_string.h:2591
std::basic_string::append
constexpr basic_string & append(_InputIterator __first, _InputIterator __last)
Append a range of characters.
Definition basic_string.h:1735
std::basic_string::rbegin
constexpr const_reverse_iterator rbegin() const noexcept
Definition basic_string.h:1148
std::basic_string::copy
constexpr size_type copy(_CharT *__s, size_type __n, size_type __pos=0) const
Copy substring into C string.
Definition cow_string.h:3918
std::basic_string::end
constexpr const_iterator end() const noexcept
Definition basic_string.h:1128
std::basic_string::insert
constexpr basic_string & insert(size_type __pos, const _CharT *__s, size_type __n)
Insert a C substring.
Definition basic_string.h:2278
std::basic_string::find_last_not_of
constexpr size_type find_last_not_of(const _CharT *__s, size_type __pos=npos) const noexcept
Find last position of a character not in C string.
Definition basic_string.h:3487
std::basic_string::cbegin
constexpr const_iterator cbegin() const noexcept
Definition basic_string.h:1178
std::basic_string::rfind
constexpr size_type rfind(const _CharT *__s, size_type __pos, size_type __n) const noexcept
Find last position of a C substring.
Definition basic_string.tcc:758
std::basic_string::erase
constexpr iterator erase(__const_iterator __first, __const_iterator __last)
Remove a range of characters.
Definition basic_string.h:2445
std::basic_string::find_first_of
constexpr size_type find_first_of(const basic_string &__str, size_type __pos=0) const noexcept
Find position of a character of string.
Definition basic_string.h:3171
std::basic_string::at
constexpr const_reference at(size_type __n) const
Provides access to the data contained in the string.
Definition basic_string.h:1441
std::basic_string::operator[]
constexpr reference operator[](size_type __pos)
Subscript access to the data contained in the string.
Definition basic_string.h:1419
std::basic_string::assign
constexpr basic_string & assign(const basic_string &__str, size_type __pos, size_type __n=npos)
Set value to a substring of a string.
Definition basic_string.h:1878
std::basic_string::rend
constexpr reverse_iterator rend() noexcept
Definition basic_string.h:1158
std::basic_string::resize
constexpr void resize(size_type __n, _CharT __c)
Resizes the string to the specified number of characters.
Definition cow_string.h:3843
std::basic_string::insert
constexpr iterator insert(const_iterator __p, _InputIterator __beg, _InputIterator __end)
Insert a range of characters.
Definition basic_string.h:2136
std::basic_string::reserve
constexpr void reserve()
Definition cow_string.h:3897
std::basic_string::find_last_not_of
constexpr size_type find_last_not_of(_CharT __c, size_type __pos=npos) const noexcept
Find last position of a different character.
Definition basic_string.tcc:888
std::basic_string::insert
constexpr basic_string & insert(size_type __pos1, const basic_string &__str)
Insert value of a string.
Definition basic_string.h:2230
std::basic_string::insert
constexpr iterator insert(__const_iterator __p, _CharT __c)
Insert one character.
Definition basic_string.h:2342
std::basic_string::~basic_string
constexpr ~basic_string()
Destroy the string instance.
Definition basic_string.h:949
std::basic_string::operator=
constexpr basic_string & operator=(basic_string &&__str) noexcept(_Alloc_traits::_S_nothrow_move())
Move assign the value of str to this string.
Definition basic_string.h:999
std::basic_string::__resize_and_overwrite
constexpr void __resize_and_overwrite(size_type __n, _Operation __op)
Non-standard version of resize_and_overwrite for C++11 and above.
std::basic_string< _CharT >::rfind
constexpr size_type rfind(const basic_string &__str, size_type __pos=npos) const noexcept
Definition basic_string.h:3087
std::basic_string::append
constexpr basic_string & append(const basic_string &__str)
Append a string to this string.
Definition basic_string.h:1589
std::basic_string::operator+=
constexpr basic_string & operator+=(initializer_list< _CharT > __l)
Append an initializer_list of characters.
Definition basic_string.h:1565
std::basic_string::back
constexpr const_reference back() const noexcept
Definition basic_string.h:1516
std::basic_string::operator=
constexpr basic_string & operator=(const basic_string &__str)
Assign the value of str to this string.
Definition basic_string.h:958
std::basic_string::find_last_of
constexpr size_type find_last_of(const basic_string &__str, size_type __pos=npos) const noexcept
Find last position of a character of string.
Definition basic_string.h:3260
std::basic_string::front
constexpr reference front() noexcept
Definition basic_string.h:1480
std::basic_string::end
constexpr iterator end() noexcept
Definition basic_string.h:1119
std::basic_string::append
constexpr basic_string & append(const _CharT *__s)
Append a C string.
Definition basic_string.h:1634
std::basic_string::begin
constexpr iterator begin() noexcept
Definition basic_string.h:1101
std::basic_string::replace
constexpr basic_string & replace(__const_iterator __i1, __const_iterator __i2, const _CharT *__s, size_type __n)
Replace range of characters with C substring.
Definition basic_string.h:2631
std::basic_string::find
constexpr size_type find(const basic_string &__str, size_type __pos=0) const noexcept
Find position of a string.
Definition basic_string.h:3021
std::basic_string::replace
constexpr basic_string & replace(__const_iterator __i1, __const_iterator __i2, const _CharT *__s)
Replace range of characters with C string.
Definition basic_string.h:2654
std::basic_string::insert
constexpr basic_string & insert(size_type __pos, size_type __n, _CharT __c)
Insert multiple characters.
Definition basic_string.h:2323
std::basic_string::push_back
constexpr void push_back(_CharT __c)
Append a single character.
Definition basic_string.h:1792
std::basic_string::rbegin
constexpr reverse_iterator rbegin() noexcept
Definition basic_string.h:1138
std::basic_string::operator=
constexpr basic_string & operator=(initializer_list< _CharT > __l)
Set value to string constructed from initializer list.
Definition basic_string.h:1067
std::basic_string::resize
constexpr void resize(size_type __n)
Resizes the string to the specified number of characters.
Definition basic_string.h:1269
std::basic_string::find_first_not_of
constexpr size_type find_first_not_of(const basic_string &__str, size_type __pos=0) const noexcept
Find position of a character not in string.
Definition basic_string.h:3348
std::basic_string::assign
constexpr basic_string & assign(const _CharT *__s)
Set value to contents of a C string.
Definition basic_string.h:1912
std::basic_string::insert
constexpr basic_string & insert(size_type __pos1, const basic_string &__str, size_type __pos2, size_type __n=npos)
Insert a substring.
Definition basic_string.h:2254
std::basic_string::assign
constexpr basic_string & assign(size_type __n, _CharT __c)
Set value to multiple characters.
Definition basic_string.h:1930
std::basic_string::insert
constexpr iterator insert(const_iterator __p, size_type __n, _CharT __c)
Insert multiple characters.
Definition basic_string.h:2091
std::basic_string::find_last_of
constexpr size_type find_last_of(const _CharT *__s, size_type __pos, size_type __n) const noexcept
Find last position of a character of C substring.
Definition basic_string.tcc:816
std::basic_string::capacity
constexpr size_type capacity() const noexcept
Definition basic_string.h:1331
std::basic_string::insert
constexpr basic_string & insert(size_type __pos, const _CharT *__s)
Insert a C string.
Definition basic_string.h:2298
std::basic_string::empty
constexpr bool empty() const noexcept
Definition basic_string.h:1385
std::basic_string::replace
constexpr basic_string & replace(size_type __pos1, size_type __n1, const basic_string &__str, size_type __pos2, size_type __n2=npos)
Replace characters with value from another string.
Definition basic_string.h:2514
std::basic_string::compare
constexpr int compare(const _CharT *__s) const noexcept
Compare to a C string.
Definition basic_string.h:3737
std::basic_string< _CharT >::npos
static const size_type npos
Definition basic_string.h:127
std::basic_string::erase
constexpr basic_string & erase(size_type __pos=0, size_type __n=npos)
Remove characters.
Definition basic_string.h:2405
std::basic_string::find_first_of
constexpr size_type find_first_of(_CharT __c, size_type __pos=0) const noexcept
Find position of a character.
Definition basic_string.h:3244
std::basic_string::replace
constexpr basic_string & replace(const_iterator __i1, const_iterator __i2, _InputIterator __k1, _InputIterator __k2)
Replace range of characters with range.
Definition basic_string.h:2704
std::basic_string::erase
constexpr iterator erase(__const_iterator __position)
Remove one character.
Definition basic_string.h:2425
std::basic_string::get_allocator
constexpr allocator_type get_allocator() const noexcept
Return copy of allocator used to construct this string.
Definition basic_string.h:2989
std::basic_string::find
constexpr size_type find(_CharT __c, size_type __pos=0) const noexcept
Find position of a character.
Definition basic_string.tcc:739
std::basic_string::replace
constexpr basic_string & replace(size_type __pos, size_type __n, const basic_string &__str)
Replace characters with value from another string.
Definition basic_string.h:2491
std::basic_string::assign
constexpr basic_string & assign(_InputIterator __first, _InputIterator __last)
Set value to a range of characters.
Definition basic_string.h:1948
std::basic_string::crend
constexpr const_reverse_iterator crend() const noexcept
Definition basic_string.h:1207
std::basic_string::operator+=
constexpr basic_string & operator+=(_CharT __c)
Append a character.
Definition basic_string.h:1551
std::basic_string::basic_string
constexpr basic_string(const _CharT *__s, size_type __n, const _Alloc &__a=_Alloc())
Construct string initialized by a character array.
Definition basic_string.h:738
std::basic_string::front
constexpr const_reference front() const noexcept
Definition basic_string.h:1492
std::basic_string::subview
constexpr basic_string_view< _CharT, _Traits > subview(size_type __pos=0, size_type __n=npos) const
Get a subview.
Definition basic_string.h:3554
std::basic_string::compare
constexpr int compare(const basic_string &__str) const
Compare to a string.
Definition basic_string.h:3574
std::basic_string::compare
constexpr int compare(size_type __pos, size_type __n1, const _CharT *__s, size_type __n2) const
Compare substring against a character array.
Definition basic_string.h:3811
std::basic_string::find_last_not_of
constexpr size_type find_last_not_of(const _CharT *__s, size_type __pos, size_type __n) const noexcept
Find last position of a character not in C substring.
Definition basic_string.tcc:865
std::basic_string::basic_string
constexpr basic_string(initializer_list< _CharT > __l, const _Alloc &__a=_Alloc())
Construct string from an initializer list.
Definition basic_string.h:852
std::basic_string::data
constexpr _CharT * data() noexcept
Return non-const pointer to contents.
Definition basic_string.h:2980
std::basic_string::append
constexpr basic_string & append(const _CharT *__s, size_type __n)
Append a C substring.
Definition basic_string.h:1620
std::basic_string::max_size
constexpr size_type max_size() const noexcept
Returns the size() of the largest possible string.
Definition basic_string.h:1235
std::basic_string::swap
constexpr void swap(basic_string &__s) noexcept
Swap contents with another string.
Definition cow_string.h:3721
std::basic_string::basic_string
constexpr basic_string(basic_string &&__str) noexcept
Move construct string.
Definition basic_string.h:796
std::basic_string::operator[]
constexpr const_reference operator[](size_type __pos) const noexcept
Subscript access to the data contained in the string.
Definition basic_string.h:1401
std::basic_string::pop_back
constexpr void pop_back() noexcept
Remove the last character.
Definition basic_string.h:2465
std::basic_string::compare
constexpr int compare(size_type __pos, size_type __n1, const _CharT *__s) const
Compare substring to a C string.
Definition basic_string.h:3772
std::basic_string::operator+=
constexpr basic_string & operator+=(const basic_string &__str)
Append a string to this string.
Definition basic_string.h:1531
std::basic_string::insert
constexpr iterator insert(const_iterator __p, initializer_list< _CharT > __l)
Insert an initializer_list of characters.
Definition basic_string.h:2202
std::basic_string::cend
constexpr const_iterator cend() const noexcept
Definition basic_string.h:1187
std::basic_string::operator=
constexpr basic_string & operator=(_CharT __c)
Set value to string of length 1.
Definition basic_string.h:981
std::basic_string::find_last_of
constexpr size_type find_last_of(const _CharT *__s, size_type __pos=npos) const noexcept
Find last position of a character of C string.
Definition basic_string.h:3312
std::char_traits
Basis for explicit traits specializations.
Definition char_traits.h:329
std::__is_fast_hash
Definition functional_hash.h:308
std::basic_ostream
Template class basic_ostream.
Definition ostream.h:72
std::iterator_traits
Traits class for iterators.
Definition stl_iterator_base_types.h:185
std::reverse_iterator
Definition bits/stl_iterator.h:137
std::forward_iterator_tag
Forward iterators support a superset of input iterator operations.
Definition stl_iterator_base_types.h:103
std::iterator
Common iterator class.
Definition stl_iterator_base_types.h:135
__gnu_cxx::__alloc_traits
Uniform interface to C++98 and C++11 allocators.
Definition ext/alloc_traits.h:51
__gnu_cxx::__alloc_traits< _Char_alloc_type >::allocate
static constexpr pointer allocate(_Char_alloc_type &__a, size_type __n)
__gnu_cxx::__alloc_traits< _Char_alloc_type >::deallocate
static constexpr void deallocate(_Char_alloc_type &__a, pointer __p, size_type __n)
__gnu_cxx::__alloc_traits< _Char_alloc_type >::max_size
static constexpr size_type max_size(const _Char_alloc_type &__a) noexcept
std::ranges::sized_range
[range.sized] The sized_range concept.
Definition ranges_base.h:553
std::ranges::input_range
A range for which ranges::begin returns an input iterator.
Definition ranges_base.h:619
std::ranges::forward_range
A range for which ranges::begin returns a forward iterator.
Definition ranges_base.h:624
alloc_traits.h