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