libstdc++
cow_string.h
Go to the documentation of this file.
1// Definition of gcc4-compatible Copy-on-Write basic_string -*- C++ -*-
2
3// Copyright (C) 1997-2023 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/cow_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 * Defines the reference-counted COW string implementation.
30 */
31
32#ifndef _COW_STRING_H
33#define _COW_STRING_H 1
34
35#if ! _GLIBCXX_USE_CXX11_ABI
36
37#include <ext/atomicity.h> // _Atomic_word, __is_single_threaded
38
39#ifdef __cpp_lib_is_constant_evaluated
40// Support P1032R1 in C++20 (but not P0980R1 for COW strings).
41# define __cpp_lib_constexpr_string 201811L
42#elif __cplusplus >= 201703L && _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED
43// Support P0426R1 changes to char_traits in C++17.
44# define __cpp_lib_constexpr_string 201611L
45#endif
46
47namespace std _GLIBCXX_VISIBILITY(default)
48{
49_GLIBCXX_BEGIN_NAMESPACE_VERSION
50
51 /**
52 * @class basic_string basic_string.h <string>
53 * @brief Managing sequences of characters and character-like objects.
54 *
55 * @ingroup strings
56 * @ingroup sequences
57 * @headerfile string
58 * @since C++98
59 *
60 * @tparam _CharT Type of character
61 * @tparam _Traits Traits for character type, defaults to
62 * char_traits<_CharT>.
63 * @tparam _Alloc Allocator type, defaults to allocator<_CharT>.
64 *
65 * Meets the requirements of a <a href="tables.html#65">container</a>, a
66 * <a href="tables.html#66">reversible container</a>, and a
67 * <a href="tables.html#67">sequence</a>. Of the
68 * <a href="tables.html#68">optional sequence requirements</a>, only
69 * @c push_back, @c at, and @c %array access are supported.
70 *
71 * @doctodo
72 *
73 *
74 * Documentation? What's that?
75 * Nathan Myers <ncm@cantrip.org>.
76 *
77 * A string looks like this:
78 *
79 * @code
80 * [_Rep]
81 * _M_length
82 * [basic_string<char_type>] _M_capacity
83 * _M_dataplus _M_refcount
84 * _M_p ----------------> unnamed array of char_type
85 * @endcode
86 *
87 * Where the _M_p points to the first character in the string, and
88 * you cast it to a pointer-to-_Rep and subtract 1 to get a
89 * pointer to the header.
90 *
91 * This approach has the enormous advantage that a string object
92 * requires only one allocation. All the ugliness is confined
93 * within a single %pair of inline functions, which each compile to
94 * a single @a add instruction: _Rep::_M_data(), and
95 * string::_M_rep(); and the allocation function which gets a
96 * block of raw bytes and with room enough and constructs a _Rep
97 * object at the front.
98 *
99 * The reason you want _M_data pointing to the character %array and
100 * not the _Rep is so that the debugger can see the string
101 * contents. (Probably we should add a non-inline member to get
102 * the _Rep for the debugger to use, so users can check the actual
103 * string length.)
104 *
105 * Note that the _Rep object is a POD so that you can have a
106 * static <em>empty string</em> _Rep object already @a constructed before
107 * static constructors have run. The reference-count encoding is
108 * chosen so that a 0 indicates one reference, so you never try to
109 * destroy the empty-string _Rep object.
110 *
111 * All but the last paragraph is considered pretty conventional
112 * for a Copy-On-Write C++ string implementation.
113 */
114 // 21.3 Template class basic_string
115 template<typename _CharT, typename _Traits, typename _Alloc>
117 {
119 rebind<_CharT>::other _CharT_alloc_type;
121
122 // Types:
123 public:
124 typedef _Traits traits_type;
125 typedef typename _Traits::char_type value_type;
126 typedef _Alloc allocator_type;
127 typedef typename _CharT_alloc_traits::size_type size_type;
128 typedef typename _CharT_alloc_traits::difference_type difference_type;
129#if __cplusplus < 201103L
130 typedef typename _CharT_alloc_type::reference reference;
131 typedef typename _CharT_alloc_type::const_reference const_reference;
132#else
133 typedef value_type& reference;
134 typedef const value_type& const_reference;
135#endif
136 typedef typename _CharT_alloc_traits::pointer pointer;
137 typedef typename _CharT_alloc_traits::const_pointer const_pointer;
138 typedef __gnu_cxx::__normal_iterator<pointer, basic_string> iterator;
139 typedef __gnu_cxx::__normal_iterator<const_pointer, basic_string>
140 const_iterator;
143
144 protected:
145 // type used for positions in insert, erase etc.
146 typedef iterator __const_iterator;
147
148 private:
149 // _Rep: string representation
150 // Invariants:
151 // 1. String really contains _M_length + 1 characters: due to 21.3.4
152 // must be kept null-terminated.
153 // 2. _M_capacity >= _M_length
154 // Allocated memory is always (_M_capacity + 1) * sizeof(_CharT).
155 // 3. _M_refcount has three states:
156 // -1: leaked, one reference, no ref-copies allowed, non-const.
157 // 0: one reference, non-const.
158 // n>0: n + 1 references, operations require a lock, const.
159 // 4. All fields==0 is an empty string, given the extra storage
160 // beyond-the-end for a null terminator; thus, the shared
161 // empty string representation needs no constructor.
162
163 struct _Rep_base
164 {
165 size_type _M_length;
166 size_type _M_capacity;
167 _Atomic_word _M_refcount;
168 };
169
170 struct _Rep : _Rep_base
171 {
172 // Types:
174 rebind<char>::other _Raw_bytes_alloc;
175
176 // (Public) Data members:
177
178 // The maximum number of individual char_type elements of an
179 // individual string is determined by _S_max_size. This is the
180 // value that will be returned by max_size(). (Whereas npos
181 // is the maximum number of bytes the allocator can allocate.)
182 // If one was to divvy up the theoretical largest size string,
183 // with a terminating character and m _CharT elements, it'd
184 // look like this:
185 // npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT)
186 // Solving for m:
187 // m = ((npos - sizeof(_Rep))/sizeof(CharT)) - 1
188 // In addition, this implementation quarters this amount.
189 static const size_type _S_max_size;
190 static const _CharT _S_terminal;
191
192 // The following storage is init'd to 0 by the linker, resulting
193 // (carefully) in an empty string with one reference.
194 static size_type _S_empty_rep_storage[];
195
196 static _Rep&
197 _S_empty_rep() _GLIBCXX_NOEXCEPT
198 {
199 // NB: Mild hack to avoid strict-aliasing warnings. Note that
200 // _S_empty_rep_storage is never modified and the punning should
201 // be reasonably safe in this case.
202 void* __p = reinterpret_cast<void*>(&_S_empty_rep_storage);
203 return *reinterpret_cast<_Rep*>(__p);
204 }
205
206 bool
207 _M_is_leaked() const _GLIBCXX_NOEXCEPT
208 {
209#if defined(__GTHREADS)
210 // _M_refcount is mutated concurrently by _M_refcopy/_M_dispose,
211 // so we need to use an atomic load. However, _M_is_leaked
212 // predicate does not change concurrently (i.e. the string is either
213 // leaked or not), so a relaxed load is enough.
214 return __atomic_load_n(&this->_M_refcount, __ATOMIC_RELAXED) < 0;
215#else
216 return this->_M_refcount < 0;
217#endif
218 }
219
220 bool
221 _M_is_shared() const _GLIBCXX_NOEXCEPT
222 {
223#if defined(__GTHREADS)
224 // _M_refcount is mutated concurrently by _M_refcopy/_M_dispose,
225 // so we need to use an atomic load. Another thread can drop last
226 // but one reference concurrently with this check, so we need this
227 // load to be acquire to synchronize with release fetch_and_add in
228 // _M_dispose.
229 if (!__gnu_cxx::__is_single_threaded())
230 return __atomic_load_n(&this->_M_refcount, __ATOMIC_ACQUIRE) > 0;
231#endif
232 return this->_M_refcount > 0;
233 }
234
235 void
236 _M_set_leaked() _GLIBCXX_NOEXCEPT
237 { this->_M_refcount = -1; }
238
239 void
240 _M_set_sharable() _GLIBCXX_NOEXCEPT
241 { this->_M_refcount = 0; }
242
243 void
244 _M_set_length_and_sharable(size_type __n) _GLIBCXX_NOEXCEPT
245 {
246#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
247 if (__builtin_expect(this != &_S_empty_rep(), false))
248#endif
249 {
250 this->_M_set_sharable(); // One reference.
251 this->_M_length = __n;
252 traits_type::assign(this->_M_refdata()[__n], _S_terminal);
253 // grrr. (per 21.3.4)
254 // You cannot leave those LWG people alone for a second.
255 }
256 }
257
258 _CharT*
259 _M_refdata() throw()
260 { return reinterpret_cast<_CharT*>(this + 1); }
261
262 _CharT*
263 _M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2)
264 {
265 return (!_M_is_leaked() && __alloc1 == __alloc2)
266 ? _M_refcopy() : _M_clone(__alloc1);
267 }
268
269 // Create & Destroy
270 static _Rep*
271 _S_create(size_type, size_type, const _Alloc&);
272
273 void
274 _M_dispose(const _Alloc& __a) _GLIBCXX_NOEXCEPT
275 {
276#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
277 if (__builtin_expect(this != &_S_empty_rep(), false))
278#endif
279 {
280 // Be race-detector-friendly. For more info see bits/c++config.
281 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&this->_M_refcount);
282 // Decrement of _M_refcount is acq_rel, because:
283 // - all but last decrements need to release to synchronize with
284 // the last decrement that will delete the object.
285 // - the last decrement needs to acquire to synchronize with
286 // all the previous decrements.
287 // - last but one decrement needs to release to synchronize with
288 // the acquire load in _M_is_shared that will conclude that
289 // the object is not shared anymore.
290 if (__gnu_cxx::__exchange_and_add_dispatch(&this->_M_refcount,
291 -1) <= 0)
292 {
293 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&this->_M_refcount);
294 _M_destroy(__a);
295 }
296 }
297 } // XXX MT
298
299 void
300 _M_destroy(const _Alloc&) throw();
301
302 _CharT*
303 _M_refcopy() throw()
304 {
305#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
306 if (__builtin_expect(this != &_S_empty_rep(), false))
307#endif
308 __gnu_cxx::__atomic_add_dispatch(&this->_M_refcount, 1);
309 return _M_refdata();
310 } // XXX MT
311
312 _CharT*
313 _M_clone(const _Alloc&, size_type __res = 0);
314 };
315
316 // Use empty-base optimization: http://www.cantrip.org/emptyopt.html
317 struct _Alloc_hider : _Alloc
318 {
319 _Alloc_hider(_CharT* __dat, const _Alloc& __a) _GLIBCXX_NOEXCEPT
320 : _Alloc(__a), _M_p(__dat) { }
321
322 _CharT* _M_p; // The actual data.
323 };
324
325 public:
326 // Data Members (public):
327 // NB: This is an unsigned type, and thus represents the maximum
328 // size that the allocator can hold.
329 /// Value returned by various member functions when they fail.
330 static const size_type npos = static_cast<size_type>(-1);
331
332 private:
333 // Data Members (private):
334 mutable _Alloc_hider _M_dataplus;
335
336 _CharT*
337 _M_data() const _GLIBCXX_NOEXCEPT
338 { return _M_dataplus._M_p; }
339
340 _CharT*
341 _M_data(_CharT* __p) _GLIBCXX_NOEXCEPT
342 { return (_M_dataplus._M_p = __p); }
343
344 _Rep*
345 _M_rep() const _GLIBCXX_NOEXCEPT
346 { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); }
347
348 // For the internal use we have functions similar to `begin'/`end'
349 // but they do not call _M_leak.
350 iterator
351 _M_ibegin() const _GLIBCXX_NOEXCEPT
352 { return iterator(_M_data()); }
353
354 iterator
355 _M_iend() const _GLIBCXX_NOEXCEPT
356 { return iterator(_M_data() + this->size()); }
357
358 void
359 _M_leak() // for use in begin() & non-const op[]
360 {
361 if (!_M_rep()->_M_is_leaked())
362 _M_leak_hard();
363 }
364
365 size_type
366 _M_check(size_type __pos, const char* __s) const
367 {
368 if (__pos > this->size())
369 __throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > "
370 "this->size() (which is %zu)"),
371 __s, __pos, this->size());
372 return __pos;
373 }
374
375 void
376 _M_check_length(size_type __n1, size_type __n2, const char* __s) const
377 {
378 if (this->max_size() - (this->size() - __n1) < __n2)
379 __throw_length_error(__N(__s));
380 }
381
382 // NB: _M_limit doesn't check for a bad __pos value.
383 size_type
384 _M_limit(size_type __pos, size_type __off) const _GLIBCXX_NOEXCEPT
385 {
386 const bool __testoff = __off < this->size() - __pos;
387 return __testoff ? __off : this->size() - __pos;
388 }
389
390 // True if _Rep and source do not overlap.
391 bool
392 _M_disjunct(const _CharT* __s) const _GLIBCXX_NOEXCEPT
393 {
394 return (less<const _CharT*>()(__s, _M_data())
395 || less<const _CharT*>()(_M_data() + this->size(), __s));
396 }
397
398 // When __n = 1 way faster than the general multichar
399 // traits_type::copy/move/assign.
400 static void
401 _M_copy(_CharT* __d, const _CharT* __s, size_type __n) _GLIBCXX_NOEXCEPT
402 {
403 if (__n == 1)
404 traits_type::assign(*__d, *__s);
405 else
406 traits_type::copy(__d, __s, __n);
407 }
408
409 static void
410 _M_move(_CharT* __d, const _CharT* __s, size_type __n) _GLIBCXX_NOEXCEPT
411 {
412 if (__n == 1)
413 traits_type::assign(*__d, *__s);
414 else
415 traits_type::move(__d, __s, __n);
416 }
417
418 static void
419 _M_assign(_CharT* __d, size_type __n, _CharT __c) _GLIBCXX_NOEXCEPT
420 {
421 if (__n == 1)
422 traits_type::assign(*__d, __c);
423 else
424 traits_type::assign(__d, __n, __c);
425 }
426
427 // _S_copy_chars is a separate template to permit specialization
428 // to optimize for the common case of pointers as iterators.
429 template<class _Iterator>
430 static void
431 _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2)
432 {
433 for (; __k1 != __k2; ++__k1, (void)++__p)
434 traits_type::assign(*__p, *__k1); // These types are off.
435 }
436
437 static void
438 _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2) _GLIBCXX_NOEXCEPT
439 { _S_copy_chars(__p, __k1.base(), __k2.base()); }
440
441 static void
442 _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2)
443 _GLIBCXX_NOEXCEPT
444 { _S_copy_chars(__p, __k1.base(), __k2.base()); }
445
446 static void
447 _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) _GLIBCXX_NOEXCEPT
448 { _M_copy(__p, __k1, __k2 - __k1); }
449
450 static void
451 _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2)
452 _GLIBCXX_NOEXCEPT
453 { _M_copy(__p, __k1, __k2 - __k1); }
454
455 static int
456 _S_compare(size_type __n1, size_type __n2) _GLIBCXX_NOEXCEPT
457 {
458 const difference_type __d = difference_type(__n1 - __n2);
459
460 if (__d > __gnu_cxx::__numeric_traits<int>::__max)
461 return __gnu_cxx::__numeric_traits<int>::__max;
462 else if (__d < __gnu_cxx::__numeric_traits<int>::__min)
463 return __gnu_cxx::__numeric_traits<int>::__min;
464 else
465 return int(__d);
466 }
467
468 void
469 _M_mutate(size_type __pos, size_type __len1, size_type __len2);
470
471 void
472 _M_leak_hard();
473
474 static _Rep&
475 _S_empty_rep() _GLIBCXX_NOEXCEPT
476 { return _Rep::_S_empty_rep(); }
477
478#if __cplusplus >= 201703L
479 // A helper type for avoiding boiler-plate.
480 typedef basic_string_view<_CharT, _Traits> __sv_type;
481
482 template<typename _Tp, typename _Res>
483 using _If_sv = enable_if_t<
484 __and_<is_convertible<const _Tp&, __sv_type>,
485 __not_<is_convertible<const _Tp*, const basic_string*>>,
486 __not_<is_convertible<const _Tp&, const _CharT*>>>::value,
487 _Res>;
488
489 // Allows an implicit conversion to __sv_type.
490 static __sv_type
491 _S_to_string_view(__sv_type __svt) noexcept
492 { return __svt; }
493
494 // Wraps a string_view by explicit conversion and thus
495 // allows to add an internal constructor that does not
496 // participate in overload resolution when a string_view
497 // is provided.
498 struct __sv_wrapper
499 {
500 explicit __sv_wrapper(__sv_type __sv) noexcept : _M_sv(__sv) { }
501 __sv_type _M_sv;
502 };
503
504 /**
505 * @brief Only internally used: Construct string from a string view
506 * wrapper.
507 * @param __svw string view wrapper.
508 * @param __a Allocator to use.
509 */
510 explicit
511 basic_string(__sv_wrapper __svw, const _Alloc& __a)
512 : basic_string(__svw._M_sv.data(), __svw._M_sv.size(), __a) { }
513#endif
514
515 public:
516 // Construct/copy/destroy:
517 // NB: We overload ctors in some cases instead of using default
518 // arguments, per 17.4.4.4 para. 2 item 2.
519
520 /**
521 * @brief Default constructor creates an empty string.
522 */
524#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
525 _GLIBCXX_NOEXCEPT
526 : _M_dataplus(_S_empty_rep()._M_refdata(), _Alloc())
527#else
528 : _M_dataplus(_S_construct(size_type(), _CharT(), _Alloc()), _Alloc())
529#endif
530 { }
531
532 /**
533 * @brief Construct an empty string using allocator @a a.
534 */
535 explicit
536 basic_string(const _Alloc& __a)
537 : _M_dataplus(_S_construct(size_type(), _CharT(), __a), __a)
538 { }
539
540 // NB: per LWG issue 42, semantics different from IS:
541 /**
542 * @brief Construct string with copy of value of @a str.
543 * @param __str Source string.
544 */
546 : _M_dataplus(__str._M_rep()->_M_grab(_Alloc(__str.get_allocator()),
547 __str.get_allocator()),
548 __str.get_allocator())
549 { }
550
551 // _GLIBCXX_RESOLVE_LIB_DEFECTS
552 // 2583. no way to supply an allocator for basic_string(str, pos)
553 /**
554 * @brief Construct string as copy of a substring.
555 * @param __str Source string.
556 * @param __pos Index of first character to copy from.
557 * @param __a Allocator to use.
558 */
559 basic_string(const basic_string& __str, size_type __pos,
560 const _Alloc& __a = _Alloc());
561
562 /**
563 * @brief Construct string as copy of a substring.
564 * @param __str Source string.
565 * @param __pos Index of first character to copy from.
566 * @param __n Number of characters to copy.
567 */
568 basic_string(const basic_string& __str, size_type __pos,
569 size_type __n);
570 /**
571 * @brief Construct string as copy of a substring.
572 * @param __str Source string.
573 * @param __pos Index of first character to copy from.
574 * @param __n Number of characters to copy.
575 * @param __a Allocator to use.
576 */
577 basic_string(const basic_string& __str, size_type __pos,
578 size_type __n, const _Alloc& __a);
579
580 /**
581 * @brief Construct string initialized by a character %array.
582 * @param __s Source character %array.
583 * @param __n Number of characters to copy.
584 * @param __a Allocator to use (default is default allocator).
585 *
586 * NB: @a __s must have at least @a __n characters, &apos;\\0&apos;
587 * has no special meaning.
588 */
589 basic_string(const _CharT* __s, size_type __n,
590 const _Alloc& __a = _Alloc())
591 : _M_dataplus(_S_construct(__s, __s + __n, __a), __a)
592 { }
593
594 /**
595 * @brief Construct string as copy of a C string.
596 * @param __s Source C string.
597 * @param __a Allocator to use (default is default allocator).
598 */
599#if __cpp_deduction_guides && ! defined _GLIBCXX_DEFINING_STRING_INSTANTIATIONS
600 // _GLIBCXX_RESOLVE_LIB_DEFECTS
601 // 3076. basic_string CTAD ambiguity
602 template<typename = _RequireAllocator<_Alloc>>
603#endif
604 basic_string(const _CharT* __s, const _Alloc& __a = _Alloc())
605 : _M_dataplus(_S_construct(__s, __s ? __s + traits_type::length(__s) :
606 __s + npos, __a), __a)
607 { }
608
609 /**
610 * @brief Construct string as multiple characters.
611 * @param __n Number of characters.
612 * @param __c Character to use.
613 * @param __a Allocator to use (default is default allocator).
614 */
615 basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc())
616 : _M_dataplus(_S_construct(__n, __c, __a), __a)
617 { }
618
619#if __cplusplus >= 201103L
620 /**
621 * @brief Move construct string.
622 * @param __str Source string.
623 *
624 * The newly-created string contains the exact contents of @a __str.
625 * @a __str is a valid, but unspecified string.
626 */
627 basic_string(basic_string&& __str) noexcept
628 : _M_dataplus(std::move(__str._M_dataplus))
629 {
630#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
631 // Make __str use the shared empty string rep.
632 __str._M_data(_S_empty_rep()._M_refdata());
633#else
634 // Rather than allocate an empty string for the rvalue string,
635 // just share ownership with it by incrementing the reference count.
636 // If the rvalue string was the unique owner then there are exactly
637 // two owners now.
638 if (_M_rep()->_M_is_shared())
639 __gnu_cxx::__atomic_add_dispatch(&_M_rep()->_M_refcount, 1);
640 else
641 _M_rep()->_M_refcount = 1;
642#endif
643 }
644
645 /**
646 * @brief Construct string from an initializer %list.
647 * @param __l std::initializer_list of characters.
648 * @param __a Allocator to use (default is default allocator).
649 */
650 basic_string(initializer_list<_CharT> __l, const _Alloc& __a = _Alloc())
651 : _M_dataplus(_S_construct(__l.begin(), __l.end(), __a), __a)
652 { }
653
654 basic_string(const basic_string& __str, const _Alloc& __a)
655 : _M_dataplus(__str._M_rep()->_M_grab(__a, __str.get_allocator()), __a)
656 { }
657
658 basic_string(basic_string&& __str, const _Alloc& __a)
659 : _M_dataplus(__str._M_data(), __a)
660 {
661 if (__a == __str.get_allocator())
662 {
663#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
664 __str._M_data(_S_empty_rep()._M_refdata());
665#else
666 __str._M_data(_S_construct(size_type(), _CharT(), __a));
667#endif
668 }
669 else
670 _M_dataplus._M_p = _S_construct(__str.begin(), __str.end(), __a);
671 }
672#endif // C++11
673
674#if __cplusplus >= 202100L
675 basic_string(nullptr_t) = delete;
676 basic_string& operator=(nullptr_t) = delete;
677#endif // C++23
678
679 /**
680 * @brief Construct string as copy of a range.
681 * @param __beg Start of range.
682 * @param __end End of range.
683 * @param __a Allocator to use (default is default allocator).
684 */
685 template<class _InputIterator>
686 basic_string(_InputIterator __beg, _InputIterator __end,
687 const _Alloc& __a = _Alloc())
688 : _M_dataplus(_S_construct(__beg, __end, __a), __a)
689 { }
690
691#if __cplusplus >= 201703L
692 /**
693 * @brief Construct string from a substring of a string_view.
694 * @param __t Source object convertible to string view.
695 * @param __pos The index of the first character to copy from __t.
696 * @param __n The number of characters to copy from __t.
697 * @param __a Allocator to use.
698 */
699 template<typename _Tp,
701 basic_string(const _Tp& __t, size_type __pos, size_type __n,
702 const _Alloc& __a = _Alloc())
703 : basic_string(_S_to_string_view(__t).substr(__pos, __n), __a) { }
704
705 /**
706 * @brief Construct string from a string_view.
707 * @param __t Source object convertible to string view.
708 * @param __a Allocator to use (default is default allocator).
709 */
710 template<typename _Tp, typename = _If_sv<_Tp, void>>
711 explicit
712 basic_string(const _Tp& __t, const _Alloc& __a = _Alloc())
713 : basic_string(__sv_wrapper(_S_to_string_view(__t)), __a) { }
714#endif // C++17
715
716 /**
717 * @brief Destroy the string instance.
718 */
719 ~basic_string() _GLIBCXX_NOEXCEPT
720 { _M_rep()->_M_dispose(this->get_allocator()); }
721
722 /**
723 * @brief Assign the value of @a str to this string.
724 * @param __str Source string.
725 */
728 { return this->assign(__str); }
729
730 /**
731 * @brief Copy contents of @a s into this string.
732 * @param __s Source null-terminated string.
733 */
735 operator=(const _CharT* __s)
736 { return this->assign(__s); }
737
738 /**
739 * @brief Set value to string of length 1.
740 * @param __c Source character.
741 *
742 * Assigning to a character makes this string length 1 and
743 * (*this)[0] == @a c.
744 */
746 operator=(_CharT __c)
747 {
748 this->assign(1, __c);
749 return *this;
750 }
751
752#if __cplusplus >= 201103L
753 /**
754 * @brief Move assign the value of @a str to this string.
755 * @param __str Source string.
756 *
757 * The contents of @a str are moved into this string (without copying).
758 * @a str is a valid, but unspecified string.
759 */
763 {
764 // NB: DR 1204.
765 this->swap(__str);
766 return *this;
767 }
768
769 /**
770 * @brief Set value to string constructed from initializer %list.
771 * @param __l std::initializer_list.
772 */
775 {
776 this->assign(__l.begin(), __l.size());
777 return *this;
778 }
779#endif // C++11
780
781#if __cplusplus >= 201703L
782 /**
783 * @brief Set value to string constructed from a string_view.
784 * @param __svt An object convertible to string_view.
785 */
786 template<typename _Tp>
787 _If_sv<_Tp, basic_string&>
788 operator=(const _Tp& __svt)
789 { return this->assign(__svt); }
790
791 /**
792 * @brief Convert to a string_view.
793 * @return A string_view.
794 */
795 operator __sv_type() const noexcept
796 { return __sv_type(data(), size()); }
797#endif // C++17
798
799 // Iterators:
800 /**
801 * Returns a read/write iterator that points to the first character in
802 * the %string. Unshares the string.
803 */
805 begin() // FIXME C++11: should be noexcept.
806 {
807 _M_leak();
808 return iterator(_M_data());
809 }
810
811 /**
812 * Returns a read-only (constant) iterator that points to the first
813 * character in the %string.
814 */
815 const_iterator
816 begin() const _GLIBCXX_NOEXCEPT
817 { return const_iterator(_M_data()); }
818
819 /**
820 * Returns a read/write iterator that points one past the last
821 * character in the %string. Unshares the string.
822 */
824 end() // FIXME C++11: should be noexcept.
825 {
826 _M_leak();
827 return iterator(_M_data() + this->size());
828 }
829
830 /**
831 * Returns a read-only (constant) iterator that points one past the
832 * last character in the %string.
833 */
834 const_iterator
835 end() const _GLIBCXX_NOEXCEPT
836 { return const_iterator(_M_data() + this->size()); }
837
838 /**
839 * Returns a read/write reverse iterator that points to the last
840 * character in the %string. Iteration is done in reverse element
841 * order. Unshares the string.
842 */
843 reverse_iterator
844 rbegin() // FIXME C++11: should be noexcept.
845 { return reverse_iterator(this->end()); }
846
847 /**
848 * Returns a read-only (constant) reverse iterator that points
849 * to the last character in the %string. Iteration is done in
850 * reverse element order.
851 */
852 const_reverse_iterator
853 rbegin() const _GLIBCXX_NOEXCEPT
854 { return const_reverse_iterator(this->end()); }
855
856 /**
857 * Returns a read/write reverse iterator that points to one before the
858 * first character in the %string. Iteration is done in reverse
859 * element order. Unshares the string.
860 */
861 reverse_iterator
862 rend() // FIXME C++11: should be noexcept.
863 { return reverse_iterator(this->begin()); }
864
865 /**
866 * Returns a read-only (constant) reverse iterator that points
867 * to one before the first character in the %string. Iteration
868 * is done in reverse element order.
869 */
870 const_reverse_iterator
871 rend() const _GLIBCXX_NOEXCEPT
872 { return const_reverse_iterator(this->begin()); }
873
874#if __cplusplus >= 201103L
875 /**
876 * Returns a read-only (constant) iterator that points to the first
877 * character in the %string.
878 */
879 const_iterator
880 cbegin() const noexcept
881 { return const_iterator(this->_M_data()); }
882
883 /**
884 * Returns a read-only (constant) iterator that points one past the
885 * last character in the %string.
886 */
887 const_iterator
888 cend() const noexcept
889 { return const_iterator(this->_M_data() + this->size()); }
890
891 /**
892 * Returns a read-only (constant) reverse iterator that points
893 * to the last character in the %string. Iteration is done in
894 * reverse element order.
895 */
896 const_reverse_iterator
897 crbegin() const noexcept
898 { return const_reverse_iterator(this->end()); }
899
900 /**
901 * Returns a read-only (constant) reverse iterator that points
902 * to one before the first character in the %string. Iteration
903 * is done in reverse element order.
904 */
905 const_reverse_iterator
906 crend() const noexcept
907 { return const_reverse_iterator(this->begin()); }
908#endif
909
910 public:
911 // Capacity:
912
913 /// Returns the number of characters in the string, not including any
914 /// null-termination.
915 size_type
916 size() const _GLIBCXX_NOEXCEPT
917 {
918#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 && __OPTIMIZE__
919 if (_S_empty_rep()._M_length != 0)
920 __builtin_unreachable();
921#endif
922 return _M_rep()->_M_length;
923 }
924
925 /// Returns the number of characters in the string, not including any
926 /// null-termination.
927 size_type
928 length() const _GLIBCXX_NOEXCEPT
929 { return size(); }
930
931 /// Returns the size() of the largest possible %string.
932 size_type
933 max_size() const _GLIBCXX_NOEXCEPT
934 { return _Rep::_S_max_size; }
935
936 /**
937 * @brief Resizes the %string to the specified number of characters.
938 * @param __n Number of characters the %string should contain.
939 * @param __c Character to fill any new elements.
940 *
941 * This function will %resize the %string to the specified
942 * number of characters. If the number is smaller than the
943 * %string's current size the %string is truncated, otherwise
944 * the %string is extended and new elements are %set to @a __c.
945 */
946 void
947 resize(size_type __n, _CharT __c);
948
949 /**
950 * @brief Resizes the %string to the specified number of characters.
951 * @param __n Number of characters the %string should contain.
952 *
953 * This function will resize the %string to the specified length. If
954 * the new size is smaller than the %string's current size the %string
955 * is truncated, otherwise the %string is extended and new characters
956 * are default-constructed. For basic types such as char, this means
957 * setting them to 0.
958 */
959 void
960 resize(size_type __n)
961 { this->resize(__n, _CharT()); }
962
963#if __cplusplus >= 201103L
964#pragma GCC diagnostic push
965#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
966 /// A non-binding request to reduce capacity() to size().
967 void
968 shrink_to_fit() noexcept
969 { reserve(); }
970#pragma GCC diagnostic pop
971#endif
972
973 /**
974 * Returns the total number of characters that the %string can hold
975 * before needing to allocate more memory.
976 */
977 size_type
978 capacity() const _GLIBCXX_NOEXCEPT
979 { return _M_rep()->_M_capacity; }
980
981 /**
982 * @brief Attempt to preallocate enough memory for specified number of
983 * characters.
984 * @param __res_arg Number of characters required.
985 * @throw std::length_error If @a __res_arg exceeds @c max_size().
986 *
987 * This function attempts to reserve enough memory for the
988 * %string to hold the specified number of characters. If the
989 * number requested is more than max_size(), length_error is
990 * thrown.
991 *
992 * The advantage of this function is that if optimal code is a
993 * necessity and the user can determine the string length that will be
994 * required, the user can reserve the memory in %advance, and thus
995 * prevent a possible reallocation of memory and copying of %string
996 * data.
997 */
998 void
999 reserve(size_type __res_arg);
1000
1001 /// Equivalent to shrink_to_fit().
1002#if __cplusplus > 201703L
1003 [[deprecated("use shrink_to_fit() instead")]]
1004#endif
1005 void
1007
1008 /**
1009 * Erases the string, making it empty.
1010 */
1011#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
1012 void
1013 clear() _GLIBCXX_NOEXCEPT
1014 {
1015 if (_M_rep()->_M_is_shared())
1016 {
1017 _M_rep()->_M_dispose(this->get_allocator());
1018 _M_data(_S_empty_rep()._M_refdata());
1019 }
1020 else
1021 _M_rep()->_M_set_length_and_sharable(0);
1022 }
1023#else
1024 // PR 56166: this should not throw.
1025 void
1026 clear()
1027 { _M_mutate(0, this->size(), 0); }
1028#endif
1029
1030 /**
1031 * Returns true if the %string is empty. Equivalent to
1032 * <code>*this == ""</code>.
1033 */
1034 _GLIBCXX_NODISCARD bool
1035 empty() const _GLIBCXX_NOEXCEPT
1036 { return this->size() == 0; }
1037
1038 // Element access:
1039 /**
1040 * @brief Subscript access to the data contained in the %string.
1041 * @param __pos The index of the character to access.
1042 * @return Read-only (constant) reference to the character.
1043 *
1044 * This operator allows for easy, array-style, data access.
1045 * Note that data access with this operator is unchecked and
1046 * out_of_range lookups are not defined. (For checked lookups
1047 * see at().)
1048 */
1049 const_reference
1050 operator[] (size_type __pos) const _GLIBCXX_NOEXCEPT
1051 {
1052 __glibcxx_assert(__pos <= size());
1053 return _M_data()[__pos];
1054 }
1055
1056 /**
1057 * @brief Subscript access to the data contained in the %string.
1058 * @param __pos The index of the character to access.
1059 * @return Read/write reference to the character.
1060 *
1061 * This operator allows for easy, array-style, data access.
1062 * Note that data access with this operator is unchecked and
1063 * out_of_range lookups are not defined. (For checked lookups
1064 * see at().) Unshares the string.
1065 */
1066 reference
1067 operator[](size_type __pos)
1068 {
1069 // Allow pos == size() both in C++98 mode, as v3 extension,
1070 // and in C++11 mode.
1071 __glibcxx_assert(__pos <= size());
1072 // In pedantic mode be strict in C++98 mode.
1073 _GLIBCXX_DEBUG_PEDASSERT(__cplusplus >= 201103L || __pos < size());
1074 _M_leak();
1075 return _M_data()[__pos];
1076 }
1077
1078 /**
1079 * @brief Provides access to the data contained in the %string.
1080 * @param __n The index of the character to access.
1081 * @return Read-only (const) reference to the character.
1082 * @throw std::out_of_range If @a n is an invalid index.
1083 *
1084 * This function provides for safer data access. The parameter is
1085 * first checked that it is in the range of the string. The function
1086 * throws out_of_range if the check fails.
1087 */
1088 const_reference
1089 at(size_type __n) const
1090 {
1091 if (__n >= this->size())
1092 __throw_out_of_range_fmt(__N("basic_string::at: __n "
1093 "(which is %zu) >= this->size() "
1094 "(which is %zu)"),
1095 __n, this->size());
1096 return _M_data()[__n];
1097 }
1098
1099 /**
1100 * @brief Provides access to the data contained in the %string.
1101 * @param __n The index of the character to access.
1102 * @return Read/write reference to the character.
1103 * @throw std::out_of_range If @a n is an invalid index.
1104 *
1105 * This function provides for safer data access. The parameter is
1106 * first checked that it is in the range of the string. The function
1107 * throws out_of_range if the check fails. Success results in
1108 * unsharing the string.
1109 */
1110 reference
1111 at(size_type __n)
1112 {
1113 if (__n >= size())
1114 __throw_out_of_range_fmt(__N("basic_string::at: __n "
1115 "(which is %zu) >= this->size() "
1116 "(which is %zu)"),
1117 __n, this->size());
1118 _M_leak();
1119 return _M_data()[__n];
1120 }
1121
1122#if __cplusplus >= 201103L
1123 /**
1124 * Returns a read/write reference to the data at the first
1125 * element of the %string.
1126 */
1127 reference
1129 {
1130 __glibcxx_assert(!empty());
1131 return operator[](0);
1132 }
1133
1134 /**
1135 * Returns a read-only (constant) reference to the data at the first
1136 * element of the %string.
1137 */
1138 const_reference
1139 front() const noexcept
1140 {
1141 __glibcxx_assert(!empty());
1142 return operator[](0);
1143 }
1144
1145 /**
1146 * Returns a read/write reference to the data at the last
1147 * element of the %string.
1148 */
1149 reference
1151 {
1152 __glibcxx_assert(!empty());
1153 return operator[](this->size() - 1);
1154 }
1155
1156 /**
1157 * Returns a read-only (constant) reference to the data at the
1158 * last element of the %string.
1159 */
1160 const_reference
1161 back() const noexcept
1162 {
1163 __glibcxx_assert(!empty());
1164 return operator[](this->size() - 1);
1165 }
1166#endif
1167
1168 // Modifiers:
1169 /**
1170 * @brief Append a string to this string.
1171 * @param __str The string to append.
1172 * @return Reference to this string.
1173 */
1176 { return this->append(__str); }
1177
1178 /**
1179 * @brief Append a C string.
1180 * @param __s The C string to append.
1181 * @return Reference to this string.
1182 */
1184 operator+=(const _CharT* __s)
1185 { return this->append(__s); }
1186
1187 /**
1188 * @brief Append a character.
1189 * @param __c The character to append.
1190 * @return Reference to this string.
1191 */
1193 operator+=(_CharT __c)
1194 {
1195 this->push_back(__c);
1196 return *this;
1197 }
1198
1199#if __cplusplus >= 201103L
1200 /**
1201 * @brief Append an initializer_list of characters.
1202 * @param __l The initializer_list of characters to be appended.
1203 * @return Reference to this string.
1204 */
1207 { return this->append(__l.begin(), __l.size()); }
1208#endif // C++11
1209
1210#if __cplusplus >= 201703L
1211 /**
1212 * @brief Append a string_view.
1213 * @param __svt The object convertible to string_view to be appended.
1214 * @return Reference to this string.
1215 */
1216 template<typename _Tp>
1217 _If_sv<_Tp, basic_string&>
1218 operator+=(const _Tp& __svt)
1219 { return this->append(__svt); }
1220#endif // C++17
1221
1222 /**
1223 * @brief Append a string to this string.
1224 * @param __str The string to append.
1225 * @return Reference to this string.
1226 */
1228 append(const basic_string& __str);
1229
1230 /**
1231 * @brief Append a substring.
1232 * @param __str The string to append.
1233 * @param __pos Index of the first character of str to append.
1234 * @param __n The number of characters to append.
1235 * @return Reference to this string.
1236 * @throw std::out_of_range if @a __pos is not a valid index.
1237 *
1238 * This function appends @a __n characters from @a __str
1239 * starting at @a __pos to this string. If @a __n is is larger
1240 * than the number of available characters in @a __str, the
1241 * remainder of @a __str is appended.
1242 */
1244 append(const basic_string& __str, size_type __pos, size_type __n = npos);
1245
1246 /**
1247 * @brief Append a C substring.
1248 * @param __s The C string to append.
1249 * @param __n The number of characters to append.
1250 * @return Reference to this string.
1251 */
1253 append(const _CharT* __s, size_type __n);
1254
1255 /**
1256 * @brief Append a C string.
1257 * @param __s The C string to append.
1258 * @return Reference to this string.
1259 */
1261 append(const _CharT* __s)
1262 {
1263 __glibcxx_requires_string(__s);
1264 return this->append(__s, traits_type::length(__s));
1265 }
1266
1267 /**
1268 * @brief Append multiple characters.
1269 * @param __n The number of characters to append.
1270 * @param __c The character to use.
1271 * @return Reference to this string.
1272 *
1273 * Appends __n copies of __c to this string.
1274 */
1276 append(size_type __n, _CharT __c);
1277
1278#if __cplusplus >= 201103L
1279 /**
1280 * @brief Append an initializer_list of characters.
1281 * @param __l The initializer_list of characters to append.
1282 * @return Reference to this string.
1283 */
1286 { return this->append(__l.begin(), __l.size()); }
1287#endif // C++11
1288
1289 /**
1290 * @brief Append a range of characters.
1291 * @param __first Iterator referencing the first character to append.
1292 * @param __last Iterator marking the end of the range.
1293 * @return Reference to this string.
1294 *
1295 * Appends characters in the range [__first,__last) to this string.
1296 */
1297 template<class _InputIterator>
1299 append(_InputIterator __first, _InputIterator __last)
1300 { return this->replace(_M_iend(), _M_iend(), __first, __last); }
1301
1302#if __cplusplus >= 201703L
1303 /**
1304 * @brief Append a string_view.
1305 * @param __svt The object convertible to string_view to be appended.
1306 * @return Reference to this string.
1307 */
1308 template<typename _Tp>
1309 _If_sv<_Tp, basic_string&>
1310 append(const _Tp& __svt)
1311 {
1312 __sv_type __sv = __svt;
1313 return this->append(__sv.data(), __sv.size());
1314 }
1315
1316 /**
1317 * @brief Append a range of characters from a string_view.
1318 * @param __svt The object convertible to string_view to be appended
1319 * from.
1320 * @param __pos The position in the string_view to append from.
1321 * @param __n The number of characters to append from the string_view.
1322 * @return Reference to this string.
1323 */
1324 template<typename _Tp>
1325 _If_sv<_Tp, basic_string&>
1326 append(const _Tp& __svt, size_type __pos, size_type __n = npos)
1327 {
1328 __sv_type __sv = __svt;
1329 return append(__sv.data()
1330 + std::__sv_check(__sv.size(), __pos, "basic_string::append"),
1331 std::__sv_limit(__sv.size(), __pos, __n));
1332 }
1333#endif // C++17
1334
1335 /**
1336 * @brief Append a single character.
1337 * @param __c Character to append.
1338 */
1339 void
1340 push_back(_CharT __c)
1341 {
1342 const size_type __len = 1 + this->size();
1343 if (__len > this->capacity() || _M_rep()->_M_is_shared())
1344 this->reserve(__len);
1345 traits_type::assign(_M_data()[this->size()], __c);
1346 _M_rep()->_M_set_length_and_sharable(__len);
1347 }
1348
1349 /**
1350 * @brief Set value to contents of another string.
1351 * @param __str Source string to use.
1352 * @return Reference to this string.
1353 */
1355 assign(const basic_string& __str);
1356
1357#if __cplusplus >= 201103L
1358 /**
1359 * @brief Set value to contents of another string.
1360 * @param __str Source string to use.
1361 * @return Reference to this string.
1362 *
1363 * This function sets this string to the exact contents of @a __str.
1364 * @a __str is a valid, but unspecified string.
1365 */
1369 {
1370 this->swap(__str);
1371 return *this;
1372 }
1373#endif // C++11
1374
1375 /**
1376 * @brief Set value to a substring of a string.
1377 * @param __str The string to use.
1378 * @param __pos Index of the first character of str.
1379 * @param __n Number of characters to use.
1380 * @return Reference to this string.
1381 * @throw std::out_of_range if @a pos is not a valid index.
1382 *
1383 * This function sets this string to the substring of @a __str
1384 * consisting of @a __n characters at @a __pos. If @a __n is
1385 * is larger than the number of available characters in @a
1386 * __str, the remainder of @a __str is used.
1387 */
1389 assign(const basic_string& __str, size_type __pos, size_type __n = npos)
1390 { return this->assign(__str._M_data()
1391 + __str._M_check(__pos, "basic_string::assign"),
1392 __str._M_limit(__pos, __n)); }
1393
1394 /**
1395 * @brief Set value to a C substring.
1396 * @param __s The C string to use.
1397 * @param __n Number of characters to use.
1398 * @return Reference to this string.
1399 *
1400 * This function sets the value of this string to the first @a __n
1401 * characters of @a __s. If @a __n is is larger than the number of
1402 * available characters in @a __s, the remainder of @a __s is used.
1403 */
1405 assign(const _CharT* __s, size_type __n);
1406
1407 /**
1408 * @brief Set value to contents of a C string.
1409 * @param __s The C string to use.
1410 * @return Reference to this string.
1411 *
1412 * This function sets the value of this string to the value of @a __s.
1413 * The data is copied, so there is no dependence on @a __s once the
1414 * function returns.
1415 */
1417 assign(const _CharT* __s)
1418 {
1419 __glibcxx_requires_string(__s);
1420 return this->assign(__s, traits_type::length(__s));
1421 }
1422
1423 /**
1424 * @brief Set value to multiple characters.
1425 * @param __n Length of the resulting string.
1426 * @param __c The character to use.
1427 * @return Reference to this string.
1428 *
1429 * This function sets the value of this string to @a __n copies of
1430 * character @a __c.
1431 */
1433 assign(size_type __n, _CharT __c)
1434 { return _M_replace_aux(size_type(0), this->size(), __n, __c); }
1435
1436 /**
1437 * @brief Set value to a range of characters.
1438 * @param __first Iterator referencing the first character to append.
1439 * @param __last Iterator marking the end of the range.
1440 * @return Reference to this string.
1441 *
1442 * Sets value of string to characters in the range [__first,__last).
1443 */
1444 template<class _InputIterator>
1446 assign(_InputIterator __first, _InputIterator __last)
1447 { return this->replace(_M_ibegin(), _M_iend(), __first, __last); }
1448
1449#if __cplusplus >= 201103L
1450 /**
1451 * @brief Set value to an initializer_list of characters.
1452 * @param __l The initializer_list of characters to assign.
1453 * @return Reference to this string.
1454 */
1457 { return this->assign(__l.begin(), __l.size()); }
1458#endif // C++11
1459
1460#if __cplusplus >= 201703L
1461 /**
1462 * @brief Set value from a string_view.
1463 * @param __svt The source object convertible to string_view.
1464 * @return Reference to this string.
1465 */
1466 template<typename _Tp>
1467 _If_sv<_Tp, basic_string&>
1468 assign(const _Tp& __svt)
1469 {
1470 __sv_type __sv = __svt;
1471 return this->assign(__sv.data(), __sv.size());
1472 }
1473
1474 /**
1475 * @brief Set value from a range of characters in a string_view.
1476 * @param __svt The source object convertible to string_view.
1477 * @param __pos The position in the string_view to assign from.
1478 * @param __n The number of characters to assign.
1479 * @return Reference to this string.
1480 */
1481 template<typename _Tp>
1482 _If_sv<_Tp, basic_string&>
1483 assign(const _Tp& __svt, size_type __pos, size_type __n = npos)
1484 {
1485 __sv_type __sv = __svt;
1486 return assign(__sv.data()
1487 + std::__sv_check(__sv.size(), __pos, "basic_string::assign"),
1488 std::__sv_limit(__sv.size(), __pos, __n));
1489 }
1490#endif // C++17
1491
1492 /**
1493 * @brief Insert multiple characters.
1494 * @param __p Iterator referencing location in string to insert at.
1495 * @param __n Number of characters to insert
1496 * @param __c The character to insert.
1497 * @throw std::length_error If new length exceeds @c max_size().
1498 *
1499 * Inserts @a __n copies of character @a __c starting at the
1500 * position referenced by iterator @a __p. If adding
1501 * characters causes the length to exceed max_size(),
1502 * length_error is thrown. The value of the string doesn't
1503 * change if an error is thrown.
1504 */
1505 void
1506 insert(iterator __p, size_type __n, _CharT __c)
1507 { this->replace(__p, __p, __n, __c); }
1508
1509 /**
1510 * @brief Insert a range of characters.
1511 * @param __p Iterator referencing location in string to insert at.
1512 * @param __beg Start of range.
1513 * @param __end End of range.
1514 * @throw std::length_error If new length exceeds @c max_size().
1515 *
1516 * Inserts characters in range [__beg,__end). If adding
1517 * characters causes the length to exceed max_size(),
1518 * length_error is thrown. The value of the string doesn't
1519 * change if an error is thrown.
1520 */
1521 template<class _InputIterator>
1522 void
1523 insert(iterator __p, _InputIterator __beg, _InputIterator __end)
1524 { this->replace(__p, __p, __beg, __end); }
1525
1526#if __cplusplus >= 201103L
1527 /**
1528 * @brief Insert an initializer_list of characters.
1529 * @param __p Iterator referencing location in string to insert at.
1530 * @param __l The initializer_list of characters to insert.
1531 * @throw std::length_error If new length exceeds @c max_size().
1532 */
1533 void
1535 {
1536 _GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend());
1537 this->insert(__p - _M_ibegin(), __l.begin(), __l.size());
1538 }
1539#endif // C++11
1540
1541 /**
1542 * @brief Insert value of a string.
1543 * @param __pos1 Position in string to insert at.
1544 * @param __str The string to insert.
1545 * @return Reference to this string.
1546 * @throw std::length_error If new length exceeds @c max_size().
1547 *
1548 * Inserts value of @a __str starting at @a __pos1. If adding
1549 * characters causes the length to exceed max_size(),
1550 * length_error is thrown. The value of the string doesn't
1551 * change if an error is thrown.
1552 */
1554 insert(size_type __pos1, const basic_string& __str)
1555 { return this->insert(__pos1, __str, size_type(0), __str.size()); }
1556
1557 /**
1558 * @brief Insert a substring.
1559 * @param __pos1 Position in string to insert at.
1560 * @param __str The string to insert.
1561 * @param __pos2 Start of characters in str to insert.
1562 * @param __n Number of characters to insert.
1563 * @return Reference to this string.
1564 * @throw std::length_error If new length exceeds @c max_size().
1565 * @throw std::out_of_range If @a pos1 > size() or
1566 * @a __pos2 > @a str.size().
1567 *
1568 * Starting at @a pos1, insert @a __n character of @a __str
1569 * beginning with @a __pos2. If adding characters causes the
1570 * length to exceed max_size(), length_error is thrown. If @a
1571 * __pos1 is beyond the end of this string or @a __pos2 is
1572 * beyond the end of @a __str, out_of_range is thrown. The
1573 * value of the string doesn't change if an error is thrown.
1574 */
1576 insert(size_type __pos1, const basic_string& __str,
1577 size_type __pos2, size_type __n = npos)
1578 { return this->insert(__pos1, __str._M_data()
1579 + __str._M_check(__pos2, "basic_string::insert"),
1580 __str._M_limit(__pos2, __n)); }
1581
1582 /**
1583 * @brief Insert a C substring.
1584 * @param __pos Position in string to insert at.
1585 * @param __s The C string to insert.
1586 * @param __n The number of characters to insert.
1587 * @return Reference to this string.
1588 * @throw std::length_error If new length exceeds @c max_size().
1589 * @throw std::out_of_range If @a __pos is beyond the end of this
1590 * string.
1591 *
1592 * Inserts the first @a __n characters of @a __s starting at @a
1593 * __pos. If adding characters causes the length to exceed
1594 * max_size(), length_error is thrown. If @a __pos is beyond
1595 * end(), out_of_range is thrown. The value of the string
1596 * doesn't change if an error is thrown.
1597 */
1599 insert(size_type __pos, const _CharT* __s, size_type __n);
1600
1601 /**
1602 * @brief Insert a C string.
1603 * @param __pos Position in string to insert at.
1604 * @param __s The C string to insert.
1605 * @return Reference to this string.
1606 * @throw std::length_error If new length exceeds @c max_size().
1607 * @throw std::out_of_range If @a pos is beyond the end of this
1608 * string.
1609 *
1610 * Inserts the first @a n characters of @a __s starting at @a __pos. If
1611 * adding characters causes the length to exceed max_size(),
1612 * length_error is thrown. If @a __pos is beyond end(), out_of_range is
1613 * thrown. The value of the string doesn't change if an error is
1614 * thrown.
1615 */
1617 insert(size_type __pos, const _CharT* __s)
1618 {
1619 __glibcxx_requires_string(__s);
1620 return this->insert(__pos, __s, traits_type::length(__s));
1621 }
1622
1623 /**
1624 * @brief Insert multiple characters.
1625 * @param __pos Index in string to insert at.
1626 * @param __n Number of characters to insert
1627 * @param __c The character to insert.
1628 * @return Reference to this string.
1629 * @throw std::length_error If new length exceeds @c max_size().
1630 * @throw std::out_of_range If @a __pos is beyond the end of this
1631 * string.
1632 *
1633 * Inserts @a __n copies of character @a __c starting at index
1634 * @a __pos. If adding characters causes the length to exceed
1635 * max_size(), length_error is thrown. If @a __pos > length(),
1636 * out_of_range is thrown. The value of the string doesn't
1637 * change if an error is thrown.
1638 */
1640 insert(size_type __pos, size_type __n, _CharT __c)
1641 { return _M_replace_aux(_M_check(__pos, "basic_string::insert"),
1642 size_type(0), __n, __c); }
1643
1644 /**
1645 * @brief Insert one character.
1646 * @param __p Iterator referencing position in string to insert at.
1647 * @param __c The character to insert.
1648 * @return Iterator referencing newly inserted char.
1649 * @throw std::length_error If new length exceeds @c max_size().
1650 *
1651 * Inserts character @a __c at position referenced by @a __p.
1652 * If adding character causes the length to exceed max_size(),
1653 * length_error is thrown. If @a __p is beyond end of string,
1654 * out_of_range is thrown. The value of the string doesn't
1655 * change if an error is thrown.
1656 */
1657 iterator
1658 insert(iterator __p, _CharT __c)
1659 {
1660 _GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend());
1661 const size_type __pos = __p - _M_ibegin();
1662 _M_replace_aux(__pos, size_type(0), size_type(1), __c);
1663 _M_rep()->_M_set_leaked();
1664 return iterator(_M_data() + __pos);
1665 }
1666
1667#if __cplusplus >= 201703L
1668 /**
1669 * @brief Insert a string_view.
1670 * @param __pos Position in string to insert at.
1671 * @param __svt The object convertible to string_view to insert.
1672 * @return Reference to this string.
1673 */
1674 template<typename _Tp>
1675 _If_sv<_Tp, basic_string&>
1676 insert(size_type __pos, const _Tp& __svt)
1677 {
1678 __sv_type __sv = __svt;
1679 return this->insert(__pos, __sv.data(), __sv.size());
1680 }
1681
1682 /**
1683 * @brief Insert a string_view.
1684 * @param __pos1 Position in string to insert at.
1685 * @param __svt The object convertible to string_view to insert from.
1686 * @param __pos2 Position in string_view to insert from.
1687 * @param __n The number of characters to insert.
1688 * @return Reference to this string.
1689 */
1690 template<typename _Tp>
1691 _If_sv<_Tp, basic_string&>
1692 insert(size_type __pos1, const _Tp& __svt,
1693 size_type __pos2, size_type __n = npos)
1694 {
1695 __sv_type __sv = __svt;
1696 return this->replace(__pos1, size_type(0), __sv.data()
1697 + std::__sv_check(__sv.size(), __pos2, "basic_string::insert"),
1698 std::__sv_limit(__sv.size(), __pos2, __n));
1699 }
1700#endif // C++17
1701
1702 /**
1703 * @brief Remove characters.
1704 * @param __pos Index of first character to remove (default 0).
1705 * @param __n Number of characters to remove (default remainder).
1706 * @return Reference to this string.
1707 * @throw std::out_of_range If @a pos is beyond the end of this
1708 * string.
1709 *
1710 * Removes @a __n characters from this string starting at @a
1711 * __pos. The length of the string is reduced by @a __n. If
1712 * there are < @a __n characters to remove, the remainder of
1713 * the string is truncated. If @a __p is beyond end of string,
1714 * out_of_range is thrown. The value of the string doesn't
1715 * change if an error is thrown.
1716 */
1718 erase(size_type __pos = 0, size_type __n = npos)
1719 {
1720 _M_mutate(_M_check(__pos, "basic_string::erase"),
1721 _M_limit(__pos, __n), size_type(0));
1722 return *this;
1723 }
1724
1725 /**
1726 * @brief Remove one character.
1727 * @param __position Iterator referencing the character to remove.
1728 * @return iterator referencing same location after removal.
1729 *
1730 * Removes the character at @a __position from this string. The value
1731 * of the string doesn't change if an error is thrown.
1732 */
1733 iterator
1734 erase(iterator __position)
1735 {
1736 _GLIBCXX_DEBUG_PEDASSERT(__position >= _M_ibegin()
1737 && __position < _M_iend());
1738 const size_type __pos = __position - _M_ibegin();
1739 _M_mutate(__pos, size_type(1), size_type(0));
1740 _M_rep()->_M_set_leaked();
1741 return iterator(_M_data() + __pos);
1742 }
1743
1744 /**
1745 * @brief Remove a range of characters.
1746 * @param __first Iterator referencing the first character to remove.
1747 * @param __last Iterator referencing the end of the range.
1748 * @return Iterator referencing location of first after removal.
1749 *
1750 * Removes the characters in the range [first,last) from this string.
1751 * The value of the string doesn't change if an error is thrown.
1752 */
1753 iterator
1754 erase(iterator __first, iterator __last);
1755
1756#if __cplusplus >= 201103L
1757 /**
1758 * @brief Remove the last character.
1759 *
1760 * The string must be non-empty.
1761 */
1762 void
1763 pop_back() // FIXME C++11: should be noexcept.
1764 {
1765 __glibcxx_assert(!empty());
1766 erase(size() - 1, 1);
1767 }
1768#endif // C++11
1769
1770 /**
1771 * @brief Replace characters with value from another string.
1772 * @param __pos Index of first character to replace.
1773 * @param __n Number of characters to be replaced.
1774 * @param __str String to insert.
1775 * @return Reference to this string.
1776 * @throw std::out_of_range If @a pos is beyond the end of this
1777 * string.
1778 * @throw std::length_error If new length exceeds @c max_size().
1779 *
1780 * Removes the characters in the range [__pos,__pos+__n) from
1781 * this string. In place, the value of @a __str is inserted.
1782 * If @a __pos is beyond end of string, out_of_range is thrown.
1783 * If the length of the result exceeds max_size(), length_error
1784 * is thrown. The value of the string doesn't change if an
1785 * error is thrown.
1786 */
1788 replace(size_type __pos, size_type __n, const basic_string& __str)
1789 { return this->replace(__pos, __n, __str._M_data(), __str.size()); }
1790
1791 /**
1792 * @brief Replace characters with value from another string.
1793 * @param __pos1 Index of first character to replace.
1794 * @param __n1 Number of characters to be replaced.
1795 * @param __str String to insert.
1796 * @param __pos2 Index of first character of str to use.
1797 * @param __n2 Number of characters from str to use.
1798 * @return Reference to this string.
1799 * @throw std::out_of_range If @a __pos1 > size() or @a __pos2 >
1800 * __str.size().
1801 * @throw std::length_error If new length exceeds @c max_size().
1802 *
1803 * Removes the characters in the range [__pos1,__pos1 + n) from this
1804 * string. In place, the value of @a __str is inserted. If @a __pos is
1805 * beyond end of string, out_of_range is thrown. If the length of the
1806 * result exceeds max_size(), length_error is thrown. The value of the
1807 * string doesn't change if an error is thrown.
1808 */
1810 replace(size_type __pos1, size_type __n1, const basic_string& __str,
1811 size_type __pos2, size_type __n2 = npos)
1812 { return this->replace(__pos1, __n1, __str._M_data()
1813 + __str._M_check(__pos2, "basic_string::replace"),
1814 __str._M_limit(__pos2, __n2)); }
1815
1816 /**
1817 * @brief Replace characters with value of a C substring.
1818 * @param __pos Index of first character to replace.
1819 * @param __n1 Number of characters to be replaced.
1820 * @param __s C string to insert.
1821 * @param __n2 Number of characters from @a s to use.
1822 * @return Reference to this string.
1823 * @throw std::out_of_range If @a pos1 > size().
1824 * @throw std::length_error If new length exceeds @c max_size().
1825 *
1826 * Removes the characters in the range [__pos,__pos + __n1)
1827 * from this string. In place, the first @a __n2 characters of
1828 * @a __s are inserted, or all of @a __s if @a __n2 is too large. If
1829 * @a __pos is beyond end of string, out_of_range is thrown. If
1830 * the length of result exceeds max_size(), length_error is
1831 * thrown. The value of the string doesn't change if an error
1832 * is thrown.
1833 */
1835 replace(size_type __pos, size_type __n1, const _CharT* __s,
1836 size_type __n2);
1837
1838 /**
1839 * @brief Replace characters with value of a C string.
1840 * @param __pos Index of first character to replace.
1841 * @param __n1 Number of characters to be replaced.
1842 * @param __s C string to insert.
1843 * @return Reference to this string.
1844 * @throw std::out_of_range If @a pos > size().
1845 * @throw std::length_error If new length exceeds @c max_size().
1846 *
1847 * Removes the characters in the range [__pos,__pos + __n1)
1848 * from this string. In place, the characters of @a __s are
1849 * inserted. If @a __pos is beyond end of string, out_of_range
1850 * is thrown. If the length of result exceeds max_size(),
1851 * length_error is thrown. The value of the string doesn't
1852 * change if an error is thrown.
1853 */
1855 replace(size_type __pos, size_type __n1, const _CharT* __s)
1856 {
1857 __glibcxx_requires_string(__s);
1858 return this->replace(__pos, __n1, __s, traits_type::length(__s));
1859 }
1860
1861 /**
1862 * @brief Replace characters with multiple characters.
1863 * @param __pos Index of first character to replace.
1864 * @param __n1 Number of characters to be replaced.
1865 * @param __n2 Number of characters to insert.
1866 * @param __c Character to insert.
1867 * @return Reference to this string.
1868 * @throw std::out_of_range If @a __pos > size().
1869 * @throw std::length_error If new length exceeds @c max_size().
1870 *
1871 * Removes the characters in the range [pos,pos + n1) from this
1872 * string. In place, @a __n2 copies of @a __c are inserted.
1873 * If @a __pos is beyond end of string, out_of_range is thrown.
1874 * If the length of result exceeds max_size(), length_error is
1875 * thrown. The value of the string doesn't change if an error
1876 * is thrown.
1877 */
1879 replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
1880 { return _M_replace_aux(_M_check(__pos, "basic_string::replace"),
1881 _M_limit(__pos, __n1), __n2, __c); }
1882
1883 /**
1884 * @brief Replace range of characters with string.
1885 * @param __i1 Iterator referencing start of range to replace.
1886 * @param __i2 Iterator referencing end of range to replace.
1887 * @param __str String value to insert.
1888 * @return Reference to this string.
1889 * @throw std::length_error If new length exceeds @c max_size().
1890 *
1891 * Removes the characters in the range [__i1,__i2). In place,
1892 * the value of @a __str is inserted. If the length of result
1893 * exceeds max_size(), length_error is thrown. The value of
1894 * the string doesn't change if an error is thrown.
1895 */
1897 replace(iterator __i1, iterator __i2, const basic_string& __str)
1898 { return this->replace(__i1, __i2, __str._M_data(), __str.size()); }
1899
1900 /**
1901 * @brief Replace range of characters with C substring.
1902 * @param __i1 Iterator referencing start of range to replace.
1903 * @param __i2 Iterator referencing end of range to replace.
1904 * @param __s C string value to insert.
1905 * @param __n Number of characters from s to insert.
1906 * @return Reference to this string.
1907 * @throw std::length_error If new length exceeds @c max_size().
1908 *
1909 * Removes the characters in the range [__i1,__i2). In place,
1910 * the first @a __n characters of @a __s are inserted. If the
1911 * length of result exceeds max_size(), length_error is thrown.
1912 * The value of the string doesn't change if an error is
1913 * thrown.
1914 */
1916 replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n)
1917 {
1918 _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
1919 && __i2 <= _M_iend());
1920 return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n);
1921 }
1922
1923 /**
1924 * @brief Replace range of characters with C string.
1925 * @param __i1 Iterator referencing start of range to replace.
1926 * @param __i2 Iterator referencing end of range to replace.
1927 * @param __s C string value to insert.
1928 * @return Reference to this string.
1929 * @throw std::length_error If new length exceeds @c max_size().
1930 *
1931 * Removes the characters in the range [__i1,__i2). In place,
1932 * the characters of @a __s are inserted. If the length of
1933 * result exceeds max_size(), length_error is thrown. The
1934 * value of the string doesn't change if an error is thrown.
1935 */
1937 replace(iterator __i1, iterator __i2, const _CharT* __s)
1938 {
1939 __glibcxx_requires_string(__s);
1940 return this->replace(__i1, __i2, __s, traits_type::length(__s));
1941 }
1942
1943 /**
1944 * @brief Replace range of characters with multiple characters
1945 * @param __i1 Iterator referencing start of range to replace.
1946 * @param __i2 Iterator referencing end of range to replace.
1947 * @param __n Number of characters to insert.
1948 * @param __c Character to insert.
1949 * @return Reference to this string.
1950 * @throw std::length_error If new length exceeds @c max_size().
1951 *
1952 * Removes the characters in the range [__i1,__i2). In place,
1953 * @a __n copies of @a __c are inserted. If the length of
1954 * result exceeds max_size(), length_error is thrown. The
1955 * value of the string doesn't change if an error is thrown.
1956 */
1958 replace(iterator __i1, iterator __i2, size_type __n, _CharT __c)
1959 {
1960 _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
1961 && __i2 <= _M_iend());
1962 return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __c);
1963 }
1964
1965 /**
1966 * @brief Replace range of characters with range.
1967 * @param __i1 Iterator referencing start of range to replace.
1968 * @param __i2 Iterator referencing end of range to replace.
1969 * @param __k1 Iterator referencing start of range to insert.
1970 * @param __k2 Iterator referencing end of range to insert.
1971 * @return Reference to this string.
1972 * @throw std::length_error If new length exceeds @c max_size().
1973 *
1974 * Removes the characters in the range [__i1,__i2). In place,
1975 * characters in the range [__k1,__k2) are inserted. If the
1976 * length of result exceeds max_size(), length_error is thrown.
1977 * The value of the string doesn't change if an error is
1978 * thrown.
1979 */
1980 template<class _InputIterator>
1982 replace(iterator __i1, iterator __i2,
1983 _InputIterator __k1, _InputIterator __k2)
1984 {
1985 _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
1986 && __i2 <= _M_iend());
1987 __glibcxx_requires_valid_range(__k1, __k2);
1988 typedef typename std::__is_integer<_InputIterator>::__type _Integral;
1989 return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral());
1990 }
1991
1992 // Specializations for the common case of pointer and iterator:
1993 // useful to avoid the overhead of temporary buffering in _M_replace.
1995 replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2)
1996 {
1997 _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
1998 && __i2 <= _M_iend());
1999 __glibcxx_requires_valid_range(__k1, __k2);
2000 return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
2001 __k1, __k2 - __k1);
2002 }
2003
2005 replace(iterator __i1, iterator __i2,
2006 const _CharT* __k1, const _CharT* __k2)
2007 {
2008 _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
2009 && __i2 <= _M_iend());
2010 __glibcxx_requires_valid_range(__k1, __k2);
2011 return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
2012 __k1, __k2 - __k1);
2013 }
2014
2016 replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2)
2017 {
2018 _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
2019 && __i2 <= _M_iend());
2020 __glibcxx_requires_valid_range(__k1, __k2);
2021 return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
2022 __k1.base(), __k2 - __k1);
2023 }
2024
2026 replace(iterator __i1, iterator __i2,
2027 const_iterator __k1, const_iterator __k2)
2028 {
2029 _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
2030 && __i2 <= _M_iend());
2031 __glibcxx_requires_valid_range(__k1, __k2);
2032 return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
2033 __k1.base(), __k2 - __k1);
2034 }
2035
2036#if __cplusplus >= 201103L
2037 /**
2038 * @brief Replace range of characters with initializer_list.
2039 * @param __i1 Iterator referencing start of range to replace.
2040 * @param __i2 Iterator referencing end of range to replace.
2041 * @param __l The initializer_list of characters to insert.
2042 * @return Reference to this string.
2043 * @throw std::length_error If new length exceeds @c max_size().
2044 *
2045 * Removes the characters in the range [__i1,__i2). In place,
2046 * characters in the range [__k1,__k2) are inserted. If the
2047 * length of result exceeds max_size(), length_error is thrown.
2048 * The value of the string doesn't change if an error is
2049 * thrown.
2050 */
2051 basic_string& replace(iterator __i1, iterator __i2,
2053 { return this->replace(__i1, __i2, __l.begin(), __l.end()); }
2054#endif // C++11
2055
2056#if __cplusplus >= 201703L
2057 /**
2058 * @brief Replace range of characters with string_view.
2059 * @param __pos The position to replace at.
2060 * @param __n The number of characters to replace.
2061 * @param __svt The object convertible to string_view to insert.
2062 * @return Reference to this string.
2063 */
2064 template<typename _Tp>
2065 _If_sv<_Tp, basic_string&>
2066 replace(size_type __pos, size_type __n, const _Tp& __svt)
2067 {
2068 __sv_type __sv = __svt;
2069 return this->replace(__pos, __n, __sv.data(), __sv.size());
2070 }
2071
2072 /**
2073 * @brief Replace range of characters with string_view.
2074 * @param __pos1 The position to replace at.
2075 * @param __n1 The number of characters to replace.
2076 * @param __svt The object convertible to string_view to insert from.
2077 * @param __pos2 The position in the string_view to insert from.
2078 * @param __n2 The number of characters to insert.
2079 * @return Reference to this string.
2080 */
2081 template<typename _Tp>
2082 _If_sv<_Tp, basic_string&>
2083 replace(size_type __pos1, size_type __n1, const _Tp& __svt,
2084 size_type __pos2, size_type __n2 = npos)
2085 {
2086 __sv_type __sv = __svt;
2087 return this->replace(__pos1, __n1,
2088 __sv.data()
2089 + std::__sv_check(__sv.size(), __pos2, "basic_string::replace"),
2090 std::__sv_limit(__sv.size(), __pos2, __n2));
2091 }
2092
2093 /**
2094 * @brief Replace range of characters with string_view.
2095 * @param __i1 An iterator referencing the start position
2096 * to replace at.
2097 * @param __i2 An iterator referencing the end position
2098 * for the replace.
2099 * @param __svt The object convertible to string_view to insert from.
2100 * @return Reference to this string.
2101 */
2102 template<typename _Tp>
2103 _If_sv<_Tp, basic_string&>
2104 replace(const_iterator __i1, const_iterator __i2, const _Tp& __svt)
2105 {
2106 __sv_type __sv = __svt;
2107 return this->replace(__i1 - begin(), __i2 - __i1, __sv);
2108 }
2109#endif // C++17
2110
2111 private:
2112 template<class _Integer>
2114 _M_replace_dispatch(iterator __i1, iterator __i2, _Integer __n,
2115 _Integer __val, __true_type)
2116 { return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __val); }
2117
2118 template<class _InputIterator>
2120 _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1,
2121 _InputIterator __k2, __false_type);
2122
2124 _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
2125 _CharT __c);
2126
2128 _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s,
2129 size_type __n2);
2130
2131 // _S_construct_aux is used to implement the 21.3.1 para 15 which
2132 // requires special behaviour if _InIter is an integral type
2133 template<class _InIterator>
2134 static _CharT*
2135 _S_construct_aux(_InIterator __beg, _InIterator __end,
2136 const _Alloc& __a, __false_type)
2137 {
2138 typedef typename iterator_traits<_InIterator>::iterator_category _Tag;
2139 return _S_construct(__beg, __end, __a, _Tag());
2140 }
2141
2142 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2143 // 438. Ambiguity in the "do the right thing" clause
2144 template<class _Integer>
2145 static _CharT*
2146 _S_construct_aux(_Integer __beg, _Integer __end,
2147 const _Alloc& __a, __true_type)
2148 { return _S_construct_aux_2(static_cast<size_type>(__beg),
2149 __end, __a); }
2150
2151 static _CharT*
2152 _S_construct_aux_2(size_type __req, _CharT __c, const _Alloc& __a)
2153 { return _S_construct(__req, __c, __a); }
2154
2155 template<class _InIterator>
2156 static _CharT*
2157 _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a)
2158 {
2159 typedef typename std::__is_integer<_InIterator>::__type _Integral;
2160 return _S_construct_aux(__beg, __end, __a, _Integral());
2161 }
2162
2163 // For Input Iterators, used in istreambuf_iterators, etc.
2164 template<class _InIterator>
2165 static _CharT*
2166 _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a,
2167 input_iterator_tag);
2168
2169 // For forward_iterators up to random_access_iterators, used for
2170 // string::iterator, _CharT*, etc.
2171 template<class _FwdIterator>
2172 static _CharT*
2173 _S_construct(_FwdIterator __beg, _FwdIterator __end, const _Alloc& __a,
2174 forward_iterator_tag);
2175
2176 static _CharT*
2177 _S_construct(size_type __req, _CharT __c, const _Alloc& __a);
2178
2179 public:
2180
2181 /**
2182 * @brief Copy substring into C string.
2183 * @param __s C string to copy value into.
2184 * @param __n Number of characters to copy.
2185 * @param __pos Index of first character to copy.
2186 * @return Number of characters actually copied
2187 * @throw std::out_of_range If __pos > size().
2188 *
2189 * Copies up to @a __n characters starting at @a __pos into the
2190 * C string @a __s. If @a __pos is %greater than size(),
2191 * out_of_range is thrown.
2192 */
2193 size_type
2194 copy(_CharT* __s, size_type __n, size_type __pos = 0) const;
2195
2196 /**
2197 * @brief Swap contents with another string.
2198 * @param __s String to swap with.
2199 *
2200 * Exchanges the contents of this string with that of @a __s in constant
2201 * time.
2202 */
2203 void
2206
2207 // String operations:
2208 /**
2209 * @brief Return const pointer to null-terminated contents.
2210 *
2211 * This is a handle to internal data. Do not modify or dire things may
2212 * happen.
2213 */
2214 const _CharT*
2215 c_str() const _GLIBCXX_NOEXCEPT
2216 { return _M_data(); }
2217
2218 /**
2219 * @brief Return const pointer to contents.
2220 *
2221 * This is a pointer to internal data. It is undefined to modify
2222 * the contents through the returned pointer. To get a pointer that
2223 * allows modifying the contents use @c &str[0] instead,
2224 * (or in C++17 the non-const @c str.data() overload).
2225 */
2226 const _CharT*
2227 data() const _GLIBCXX_NOEXCEPT
2228 { return _M_data(); }
2229
2230#if __cplusplus >= 201703L
2231 /**
2232 * @brief Return non-const pointer to contents.
2233 *
2234 * This is a pointer to the character sequence held by the string.
2235 * Modifying the characters in the sequence is allowed.
2236 */
2237 _CharT*
2238 data() noexcept
2239 {
2240 _M_leak();
2241 return _M_data();
2242 }
2243#endif
2244
2245 /**
2246 * @brief Return copy of allocator used to construct this string.
2247 */
2248 allocator_type
2249 get_allocator() const _GLIBCXX_NOEXCEPT
2250 { return _M_dataplus; }
2251
2252 /**
2253 * @brief Find position of a C substring.
2254 * @param __s C string to locate.
2255 * @param __pos Index of character to search from.
2256 * @param __n Number of characters from @a s to search for.
2257 * @return Index of start of first occurrence.
2258 *
2259 * Starting from @a __pos, searches forward for the first @a
2260 * __n characters in @a __s within this string. If found,
2261 * returns the index where it begins. If not found, returns
2262 * npos.
2263 */
2264 size_type
2265 find(const _CharT* __s, size_type __pos, size_type __n) const
2266 _GLIBCXX_NOEXCEPT;
2267
2268 /**
2269 * @brief Find position of a string.
2270 * @param __str String to locate.
2271 * @param __pos Index of character to search from (default 0).
2272 * @return Index of start of first occurrence.
2273 *
2274 * Starting from @a __pos, searches forward for value of @a __str within
2275 * this string. If found, returns the index where it begins. If not
2276 * found, returns npos.
2277 */
2278 size_type
2279 find(const basic_string& __str, size_type __pos = 0) const
2280 _GLIBCXX_NOEXCEPT
2281 { return this->find(__str.data(), __pos, __str.size()); }
2282
2283 /**
2284 * @brief Find position of a C string.
2285 * @param __s C string to locate.
2286 * @param __pos Index of character to search from (default 0).
2287 * @return Index of start of first occurrence.
2288 *
2289 * Starting from @a __pos, searches forward for the value of @a
2290 * __s within this string. If found, returns the index where
2291 * it begins. If not found, returns npos.
2292 */
2293 size_type
2294 find(const _CharT* __s, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
2295 {
2296 __glibcxx_requires_string(__s);
2297 return this->find(__s, __pos, traits_type::length(__s));
2298 }
2299
2300 /**
2301 * @brief Find position of a character.
2302 * @param __c Character to locate.
2303 * @param __pos Index of character to search from (default 0).
2304 * @return Index of first occurrence.
2305 *
2306 * Starting from @a __pos, searches forward for @a __c within
2307 * this string. If found, returns the index where it was
2308 * found. If not found, returns npos.
2309 */
2310 size_type
2311 find(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT;
2312
2313#if __cplusplus >= 201703L
2314 /**
2315 * @brief Find position of a string_view.
2316 * @param __svt The object convertible to string_view to locate.
2317 * @param __pos Index of character to search from (default 0).
2318 * @return Index of start of first occurrence.
2319 */
2320 template<typename _Tp>
2321 _If_sv<_Tp, size_type>
2322 find(const _Tp& __svt, size_type __pos = 0) const
2323 noexcept(is_same<_Tp, __sv_type>::value)
2324 {
2325 __sv_type __sv = __svt;
2326 return this->find(__sv.data(), __pos, __sv.size());
2327 }
2328#endif // C++17
2329
2330 /**
2331 * @brief Find last position of a string.
2332 * @param __str String to locate.
2333 * @param __pos Index of character to search back from (default end).
2334 * @return Index of start of last occurrence.
2335 *
2336 * Starting from @a __pos, searches backward for value of @a
2337 * __str within this string. If found, returns the index where
2338 * it begins. If not found, returns npos.
2339 */
2340 size_type
2341 rfind(const basic_string& __str, size_type __pos = npos) const
2342 _GLIBCXX_NOEXCEPT
2343 { return this->rfind(__str.data(), __pos, __str.size()); }
2344
2345 /**
2346 * @brief Find last position of a C substring.
2347 * @param __s C string to locate.
2348 * @param __pos Index of character to search back from.
2349 * @param __n Number of characters from s to search for.
2350 * @return Index of start of last occurrence.
2351 *
2352 * Starting from @a __pos, searches backward for the first @a
2353 * __n characters in @a __s within this string. If found,
2354 * returns the index where it begins. If not found, returns
2355 * npos.
2356 */
2357 size_type
2358 rfind(const _CharT* __s, size_type __pos, size_type __n) const
2359 _GLIBCXX_NOEXCEPT;
2360
2361 /**
2362 * @brief Find last position of a C string.
2363 * @param __s C string to locate.
2364 * @param __pos Index of character to start search at (default end).
2365 * @return Index of start of last occurrence.
2366 *
2367 * Starting from @a __pos, searches backward for the value of
2368 * @a __s within this string. If found, returns the index
2369 * where it begins. If not found, returns npos.
2370 */
2371 size_type
2372 rfind(const _CharT* __s, size_type __pos = npos) const _GLIBCXX_NOEXCEPT
2373 {
2374 __glibcxx_requires_string(__s);
2375 return this->rfind(__s, __pos, traits_type::length(__s));
2376 }
2377
2378 /**
2379 * @brief Find last position of a character.
2380 * @param __c Character to locate.
2381 * @param __pos Index of character to search back from (default end).
2382 * @return Index of last occurrence.
2383 *
2384 * Starting from @a __pos, searches backward for @a __c within
2385 * this string. If found, returns the index where it was
2386 * found. If not found, returns npos.
2387 */
2388 size_type
2389 rfind(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT;
2390
2391#if __cplusplus >= 201703L
2392 /**
2393 * @brief Find last position of a string_view.
2394 * @param __svt The object convertible to string_view to locate.
2395 * @param __pos Index of character to search back from (default end).
2396 * @return Index of start of last occurrence.
2397 */
2398 template<typename _Tp>
2399 _If_sv<_Tp, size_type>
2400 rfind(const _Tp& __svt, size_type __pos = npos) const
2402 {
2403 __sv_type __sv = __svt;
2404 return this->rfind(__sv.data(), __pos, __sv.size());
2405 }
2406#endif // C++17
2407
2408 /**
2409 * @brief Find position of a character of string.
2410 * @param __str String containing characters to locate.
2411 * @param __pos Index of character to search from (default 0).
2412 * @return Index of first occurrence.
2413 *
2414 * Starting from @a __pos, searches forward for one of the
2415 * characters of @a __str within this string. If found,
2416 * returns the index where it was found. If not found, returns
2417 * npos.
2418 */
2419 size_type
2420 find_first_of(const basic_string& __str, size_type __pos = 0) const
2421 _GLIBCXX_NOEXCEPT
2422 { return this->find_first_of(__str.data(), __pos, __str.size()); }
2423
2424 /**
2425 * @brief Find position of a character of C substring.
2426 * @param __s String containing characters to locate.
2427 * @param __pos Index of character to search from.
2428 * @param __n Number of characters from s to search for.
2429 * @return Index of first occurrence.
2430 *
2431 * Starting from @a __pos, searches forward for one of the
2432 * first @a __n characters of @a __s within this string. If
2433 * found, returns the index where it was found. If not found,
2434 * returns npos.
2435 */
2436 size_type
2437 find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
2438 _GLIBCXX_NOEXCEPT;
2439
2440 /**
2441 * @brief Find position of a character of C string.
2442 * @param __s String containing characters to locate.
2443 * @param __pos Index of character to search from (default 0).
2444 * @return Index of first occurrence.
2445 *
2446 * Starting from @a __pos, searches forward for one of the
2447 * characters of @a __s within this string. If found, returns
2448 * the index where it was found. If not found, returns npos.
2449 */
2450 size_type
2451 find_first_of(const _CharT* __s, size_type __pos = 0) const
2452 _GLIBCXX_NOEXCEPT
2453 {
2454 __glibcxx_requires_string(__s);
2455 return this->find_first_of(__s, __pos, traits_type::length(__s));
2456 }
2457
2458 /**
2459 * @brief Find position of a character.
2460 * @param __c Character to locate.
2461 * @param __pos Index of character to search from (default 0).
2462 * @return Index of first occurrence.
2463 *
2464 * Starting from @a __pos, searches forward for the character
2465 * @a __c within this string. If found, returns the index
2466 * where it was found. If not found, returns npos.
2467 *
2468 * Note: equivalent to find(__c, __pos).
2469 */
2470 size_type
2471 find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
2472 { return this->find(__c, __pos); }
2473
2474#if __cplusplus >= 201703L
2475 /**
2476 * @brief Find position of a character of a string_view.
2477 * @param __svt An object convertible to string_view containing
2478 * characters to locate.
2479 * @param __pos Index of character to search from (default 0).
2480 * @return Index of first occurrence.
2481 */
2482 template<typename _Tp>
2483 _If_sv<_Tp, size_type>
2484 find_first_of(const _Tp& __svt, size_type __pos = 0) const
2485 noexcept(is_same<_Tp, __sv_type>::value)
2486 {
2487 __sv_type __sv = __svt;
2488 return this->find_first_of(__sv.data(), __pos, __sv.size());
2489 }
2490#endif // C++17
2491
2492 /**
2493 * @brief Find last position of a character of string.
2494 * @param __str String containing characters to locate.
2495 * @param __pos Index of character to search back from (default end).
2496 * @return Index of last occurrence.
2497 *
2498 * Starting from @a __pos, searches backward for one of the
2499 * characters of @a __str within this string. If found,
2500 * returns the index where it was found. If not found, returns
2501 * npos.
2502 */
2503 size_type
2504 find_last_of(const basic_string& __str, size_type __pos = npos) const
2505 _GLIBCXX_NOEXCEPT
2506 { return this->find_last_of(__str.data(), __pos, __str.size()); }
2507
2508 /**
2509 * @brief Find last position of a character of C substring.
2510 * @param __s C string containing characters to locate.
2511 * @param __pos Index of character to search back from.
2512 * @param __n Number of characters from s to search for.
2513 * @return Index of last occurrence.
2514 *
2515 * Starting from @a __pos, searches backward for one of the
2516 * first @a __n characters of @a __s within this string. If
2517 * found, returns the index where it was found. If not found,
2518 * returns npos.
2519 */
2520 size_type
2521 find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
2522 _GLIBCXX_NOEXCEPT;
2523
2524 /**
2525 * @brief Find last position of a character of C string.
2526 * @param __s C string containing characters to locate.
2527 * @param __pos Index of character to search back from (default end).
2528 * @return Index of last occurrence.
2529 *
2530 * Starting from @a __pos, searches backward for one of the
2531 * characters of @a __s within this string. If found, returns
2532 * the index where it was found. If not found, returns npos.
2533 */
2534 size_type
2535 find_last_of(const _CharT* __s, size_type __pos = npos) const
2536 _GLIBCXX_NOEXCEPT
2537 {
2538 __glibcxx_requires_string(__s);
2539 return this->find_last_of(__s, __pos, traits_type::length(__s));
2540 }
2541
2542 /**
2543 * @brief Find last position of a character.
2544 * @param __c Character to locate.
2545 * @param __pos Index of character to search back from (default end).
2546 * @return Index of last occurrence.
2547 *
2548 * Starting from @a __pos, searches backward for @a __c within
2549 * this string. If found, returns the index where it was
2550 * found. If not found, returns npos.
2551 *
2552 * Note: equivalent to rfind(__c, __pos).
2553 */
2554 size_type
2555 find_last_of(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT
2556 { return this->rfind(__c, __pos); }
2557
2558#if __cplusplus >= 201703L
2559 /**
2560 * @brief Find last position of a character of string.
2561 * @param __svt An object convertible to string_view containing
2562 * characters to locate.
2563 * @param __pos Index of character to search back from (default end).
2564 * @return Index of last occurrence.
2565 */
2566 template<typename _Tp>
2567 _If_sv<_Tp, size_type>
2568 find_last_of(const _Tp& __svt, size_type __pos = npos) const
2570 {
2571 __sv_type __sv = __svt;
2572 return this->find_last_of(__sv.data(), __pos, __sv.size());
2573 }
2574#endif // C++17
2575
2576 /**
2577 * @brief Find position of a character not in string.
2578 * @param __str String containing characters to avoid.
2579 * @param __pos Index of character to search from (default 0).
2580 * @return Index of first occurrence.
2581 *
2582 * Starting from @a __pos, searches forward for a character not contained
2583 * in @a __str within this string. If found, returns the index where it
2584 * was found. If not found, returns npos.
2585 */
2586 size_type
2587 find_first_not_of(const basic_string& __str, size_type __pos = 0) const
2588 _GLIBCXX_NOEXCEPT
2589 { return this->find_first_not_of(__str.data(), __pos, __str.size()); }
2590
2591 /**
2592 * @brief Find position of a character not in C substring.
2593 * @param __s C string containing characters to avoid.
2594 * @param __pos Index of character to search from.
2595 * @param __n Number of characters from __s to consider.
2596 * @return Index of first occurrence.
2597 *
2598 * Starting from @a __pos, searches forward for a character not
2599 * contained in the first @a __n characters of @a __s within
2600 * this string. If found, returns the index where it was
2601 * found. If not found, returns npos.
2602 */
2603 size_type
2604 find_first_not_of(const _CharT* __s, size_type __pos,
2605 size_type __n) const _GLIBCXX_NOEXCEPT;
2606
2607 /**
2608 * @brief Find position of a character not in C string.
2609 * @param __s C string containing characters to avoid.
2610 * @param __pos Index of character to search from (default 0).
2611 * @return Index of first occurrence.
2612 *
2613 * Starting from @a __pos, searches forward for a character not
2614 * contained in @a __s within this string. If found, returns
2615 * the index where it was found. If not found, returns npos.
2616 */
2617 size_type
2618 find_first_not_of(const _CharT* __s, size_type __pos = 0) const
2619 _GLIBCXX_NOEXCEPT
2620 {
2621 __glibcxx_requires_string(__s);
2622 return this->find_first_not_of(__s, __pos, traits_type::length(__s));
2623 }
2624
2625 /**
2626 * @brief Find position of a different character.
2627 * @param __c Character to avoid.
2628 * @param __pos Index of character to search from (default 0).
2629 * @return Index of first occurrence.
2630 *
2631 * Starting from @a __pos, searches forward for a character
2632 * other than @a __c within this string. If found, returns the
2633 * index where it was found. If not found, returns npos.
2634 */
2635 size_type
2636 find_first_not_of(_CharT __c, size_type __pos = 0) const
2637 _GLIBCXX_NOEXCEPT;
2638
2639#if __cplusplus >= 201703L
2640 /**
2641 * @brief Find position of a character not in a string_view.
2642 * @param __svt An object convertible to string_view containing
2643 * characters to avoid.
2644 * @param __pos Index of character to search from (default 0).
2645 * @return Index of first occurrence.
2646 */
2647 template<typename _Tp>
2648 _If_sv<_Tp, size_type>
2649 find_first_not_of(const _Tp& __svt, size_type __pos = 0) const
2650 noexcept(is_same<_Tp, __sv_type>::value)
2651 {
2652 __sv_type __sv = __svt;
2653 return this->find_first_not_of(__sv.data(), __pos, __sv.size());
2654 }
2655#endif // C++17
2656
2657 /**
2658 * @brief Find last position of a character not in string.
2659 * @param __str String containing characters to avoid.
2660 * @param __pos Index of character to search back from (default end).
2661 * @return Index of last occurrence.
2662 *
2663 * Starting from @a __pos, searches backward for a character
2664 * not contained in @a __str within this string. If found,
2665 * returns the index where it was found. If not found, returns
2666 * npos.
2667 */
2668 size_type
2669 find_last_not_of(const basic_string& __str, size_type __pos = npos) const
2670 _GLIBCXX_NOEXCEPT
2671 { return this->find_last_not_of(__str.data(), __pos, __str.size()); }
2672
2673 /**
2674 * @brief Find last position of a character not in C substring.
2675 * @param __s C string containing characters to avoid.
2676 * @param __pos Index of character to search back from.
2677 * @param __n Number of characters from s to consider.
2678 * @return Index of last occurrence.
2679 *
2680 * Starting from @a __pos, searches backward for a character not
2681 * contained in the first @a __n characters of @a __s within this string.
2682 * If found, returns the index where it was found. If not found,
2683 * returns npos.
2684 */
2685 size_type
2686 find_last_not_of(const _CharT* __s, size_type __pos,
2687 size_type __n) const _GLIBCXX_NOEXCEPT;
2688 /**
2689 * @brief Find last position of a character not in C string.
2690 * @param __s C string containing characters to avoid.
2691 * @param __pos Index of character to search back from (default end).
2692 * @return Index of last occurrence.
2693 *
2694 * Starting from @a __pos, searches backward for a character
2695 * not contained in @a __s within this string. If found,
2696 * returns the index where it was found. If not found, returns
2697 * npos.
2698 */
2699 size_type
2700 find_last_not_of(const _CharT* __s, size_type __pos = npos) const
2701 _GLIBCXX_NOEXCEPT
2702 {
2703 __glibcxx_requires_string(__s);
2704 return this->find_last_not_of(__s, __pos, traits_type::length(__s));
2705 }
2706
2707 /**
2708 * @brief Find last position of a different character.
2709 * @param __c Character to avoid.
2710 * @param __pos Index of character to search back from (default end).
2711 * @return Index of last occurrence.
2712 *
2713 * Starting from @a __pos, searches backward for a character other than
2714 * @a __c within this string. If found, returns the index where it was
2715 * found. If not found, returns npos.
2716 */
2717 size_type
2718 find_last_not_of(_CharT __c, size_type __pos = npos) const
2719 _GLIBCXX_NOEXCEPT;
2720
2721#if __cplusplus >= 201703L
2722 /**
2723 * @brief Find last position of a character not in a string_view.
2724 * @param __svt An object convertible to string_view containing
2725 * characters to avoid.
2726 * @param __pos Index of character to search back from (default end).
2727 * @return Index of last occurrence.
2728 */
2729 template<typename _Tp>
2730 _If_sv<_Tp, size_type>
2731 find_last_not_of(const _Tp& __svt, size_type __pos = npos) const
2733 {
2734 __sv_type __sv = __svt;
2735 return this->find_last_not_of(__sv.data(), __pos, __sv.size());
2736 }
2737#endif // C++17
2738
2739 /**
2740 * @brief Get a substring.
2741 * @param __pos Index of first character (default 0).
2742 * @param __n Number of characters in substring (default remainder).
2743 * @return The new string.
2744 * @throw std::out_of_range If __pos > size().
2745 *
2746 * Construct and return a new string using the @a __n
2747 * characters starting at @a __pos. If the string is too
2748 * short, use the remainder of the characters. If @a __pos is
2749 * beyond the end of the string, out_of_range is thrown.
2750 */
2752 substr(size_type __pos = 0, size_type __n = npos) const
2753 { return basic_string(*this,
2754 _M_check(__pos, "basic_string::substr"), __n); }
2755
2756 /**
2757 * @brief Compare to a string.
2758 * @param __str String to compare against.
2759 * @return Integer < 0, 0, or > 0.
2760 *
2761 * Returns an integer < 0 if this string is ordered before @a
2762 * __str, 0 if their values are equivalent, or > 0 if this
2763 * string is ordered after @a __str. Determines the effective
2764 * length rlen of the strings to compare as the smallest of
2765 * size() and str.size(). The function then compares the two
2766 * strings by calling traits::compare(data(), str.data(),rlen).
2767 * If the result of the comparison is nonzero returns it,
2768 * otherwise the shorter one is ordered first.
2769 */
2770 int
2771 compare(const basic_string& __str) const
2772 {
2773 const size_type __size = this->size();
2774 const size_type __osize = __str.size();
2775 const size_type __len = std::min(__size, __osize);
2776
2777 int __r = traits_type::compare(_M_data(), __str.data(), __len);
2778 if (!__r)
2779 __r = _S_compare(__size, __osize);
2780 return __r;
2781 }
2782
2783#if __cplusplus >= 201703L
2784 /**
2785 * @brief Compare to a string_view.
2786 * @param __svt An object convertible to string_view to compare against.
2787 * @return Integer < 0, 0, or > 0.
2788 */
2789 template<typename _Tp>
2790 _If_sv<_Tp, int>
2791 compare(const _Tp& __svt) const
2793 {
2794 __sv_type __sv = __svt;
2795 const size_type __size = this->size();
2796 const size_type __osize = __sv.size();
2797 const size_type __len = std::min(__size, __osize);
2798
2799 int __r = traits_type::compare(_M_data(), __sv.data(), __len);
2800 if (!__r)
2801 __r = _S_compare(__size, __osize);
2802 return __r;
2803 }
2804
2805 /**
2806 * @brief Compare to a string_view.
2807 * @param __pos A position in the string to start comparing from.
2808 * @param __n The number of characters to compare.
2809 * @param __svt An object convertible to string_view to compare
2810 * against.
2811 * @return Integer < 0, 0, or > 0.
2812 */
2813 template<typename _Tp>
2814 _If_sv<_Tp, int>
2815 compare(size_type __pos, size_type __n, const _Tp& __svt) const
2817 {
2818 __sv_type __sv = __svt;
2819 return __sv_type(*this).substr(__pos, __n).compare(__sv);
2820 }
2821
2822 /**
2823 * @brief Compare to a string_view.
2824 * @param __pos1 A position in the string to start comparing from.
2825 * @param __n1 The number of characters to compare.
2826 * @param __svt An object convertible to string_view to compare
2827 * against.
2828 * @param __pos2 A position in the string_view to start comparing from.
2829 * @param __n2 The number of characters to compare.
2830 * @return Integer < 0, 0, or > 0.
2831 */
2832 template<typename _Tp>
2833 _If_sv<_Tp, int>
2834 compare(size_type __pos1, size_type __n1, const _Tp& __svt,
2835 size_type __pos2, size_type __n2 = npos) const
2837 {
2838 __sv_type __sv = __svt;
2839 return __sv_type(*this)
2840 .substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
2841 }
2842#endif // C++17
2843
2844 /**
2845 * @brief Compare substring to a string.
2846 * @param __pos Index of first character of substring.
2847 * @param __n Number of characters in substring.
2848 * @param __str String to compare against.
2849 * @return Integer < 0, 0, or > 0.
2850 *
2851 * Form the substring of this string from the @a __n characters
2852 * starting at @a __pos. Returns an integer < 0 if the
2853 * substring is ordered before @a __str, 0 if their values are
2854 * equivalent, or > 0 if the substring is ordered after @a
2855 * __str. Determines the effective length rlen of the strings
2856 * to compare as the smallest of the length of the substring
2857 * and @a __str.size(). The function then compares the two
2858 * strings by calling
2859 * traits::compare(substring.data(),str.data(),rlen). If the
2860 * result of the comparison is nonzero returns it, otherwise
2861 * the shorter one is ordered first.
2862 */
2863 int
2864 compare(size_type __pos, size_type __n, const basic_string& __str) const
2865 {
2866 _M_check(__pos, "basic_string::compare");
2867 __n = _M_limit(__pos, __n);
2868 const size_type __osize = __str.size();
2869 const size_type __len = std::min(__n, __osize);
2870 int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len);
2871 if (!__r)
2872 __r = _S_compare(__n, __osize);
2873 return __r;
2874 }
2875
2876 /**
2877 * @brief Compare substring to a substring.
2878 * @param __pos1 Index of first character of substring.
2879 * @param __n1 Number of characters in substring.
2880 * @param __str String to compare against.
2881 * @param __pos2 Index of first character of substring of str.
2882 * @param __n2 Number of characters in substring of str.
2883 * @return Integer < 0, 0, or > 0.
2884 *
2885 * Form the substring of this string from the @a __n1
2886 * characters starting at @a __pos1. Form the substring of @a
2887 * __str from the @a __n2 characters starting at @a __pos2.
2888 * Returns an integer < 0 if this substring is ordered before
2889 * the substring of @a __str, 0 if their values are equivalent,
2890 * or > 0 if this substring is ordered after the substring of
2891 * @a __str. Determines the effective length rlen of the
2892 * strings to compare as the smallest of the lengths of the
2893 * substrings. The function then compares the two strings by
2894 * calling
2895 * traits::compare(substring.data(),str.substr(pos2,n2).data(),rlen).
2896 * If the result of the comparison is nonzero returns it,
2897 * otherwise the shorter one is ordered first.
2898 */
2899 int
2900 compare(size_type __pos1, size_type __n1, const basic_string& __str,
2901 size_type __pos2, size_type __n2 = npos) const
2902 {
2903 _M_check(__pos1, "basic_string::compare");
2904 __str._M_check(__pos2, "basic_string::compare");
2905 __n1 = _M_limit(__pos1, __n1);
2906 __n2 = __str._M_limit(__pos2, __n2);
2907 const size_type __len = std::min(__n1, __n2);
2908 int __r = traits_type::compare(_M_data() + __pos1,
2909 __str.data() + __pos2, __len);
2910 if (!__r)
2911 __r = _S_compare(__n1, __n2);
2912 return __r;
2913 }
2914
2915 /**
2916 * @brief Compare to a C string.
2917 * @param __s C string to compare against.
2918 * @return Integer < 0, 0, or > 0.
2919 *
2920 * Returns an integer < 0 if this string is ordered before @a __s, 0 if
2921 * their values are equivalent, or > 0 if this string is ordered after
2922 * @a __s. Determines the effective length rlen of the strings to
2923 * compare as the smallest of size() and the length of a string
2924 * constructed from @a __s. The function then compares the two strings
2925 * by calling traits::compare(data(),s,rlen). If the result of the
2926 * comparison is nonzero returns it, otherwise the shorter one is
2927 * ordered first.
2928 */
2929 int
2930 compare(const _CharT* __s) const _GLIBCXX_NOEXCEPT
2931 {
2932 __glibcxx_requires_string(__s);
2933 const size_type __size = this->size();
2934 const size_type __osize = traits_type::length(__s);
2935 const size_type __len = std::min(__size, __osize);
2936 int __r = traits_type::compare(_M_data(), __s, __len);
2937 if (!__r)
2938 __r = _S_compare(__size, __osize);
2939 return __r;
2940 }
2941
2942 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2943 // 5 String::compare specification questionable
2944 /**
2945 * @brief Compare substring to a C string.
2946 * @param __pos Index of first character of substring.
2947 * @param __n1 Number of characters in substring.
2948 * @param __s C string to compare against.
2949 * @return Integer < 0, 0, or > 0.
2950 *
2951 * Form the substring of this string from the @a __n1
2952 * characters starting at @a pos. Returns an integer < 0 if
2953 * the substring is ordered before @a __s, 0 if their values
2954 * are equivalent, or > 0 if the substring is ordered after @a
2955 * __s. Determines the effective length rlen of the strings to
2956 * compare as the smallest of the length of the substring and
2957 * the length of a string constructed from @a __s. The
2958 * function then compares the two string by calling
2959 * traits::compare(substring.data(),__s,rlen). If the result of
2960 * the comparison is nonzero returns it, otherwise the shorter
2961 * one is ordered first.
2962 */
2963 int
2964 compare(size_type __pos, size_type __n1, const _CharT* __s) const
2965 {
2966 __glibcxx_requires_string(__s);
2967 _M_check(__pos, "basic_string::compare");
2968 __n1 = _M_limit(__pos, __n1);
2969 const size_type __osize = traits_type::length(__s);
2970 const size_type __len = std::min(__n1, __osize);
2971 int __r = traits_type::compare(_M_data() + __pos, __s, __len);
2972 if (!__r)
2973 __r = _S_compare(__n1, __osize);
2974 return __r;
2975 }
2976
2977 /**
2978 * @brief Compare substring against a character %array.
2979 * @param __pos Index of first character of substring.
2980 * @param __n1 Number of characters in substring.
2981 * @param __s character %array to compare against.
2982 * @param __n2 Number of characters of s.
2983 * @return Integer < 0, 0, or > 0.
2984 *
2985 * Form the substring of this string from the @a __n1
2986 * characters starting at @a __pos. Form a string from the
2987 * first @a __n2 characters of @a __s. Returns an integer < 0
2988 * if this substring is ordered before the string from @a __s,
2989 * 0 if their values are equivalent, or > 0 if this substring
2990 * is ordered after the string from @a __s. Determines the
2991 * effective length rlen of the strings to compare as the
2992 * smallest of the length of the substring and @a __n2. The
2993 * function then compares the two strings by calling
2994 * traits::compare(substring.data(),s,rlen). If the result of
2995 * the comparison is nonzero returns it, otherwise the shorter
2996 * one is ordered first.
2997 *
2998 * NB: s must have at least n2 characters, &apos;\\0&apos; has
2999 * no special meaning.
3000 */
3001 int
3002 compare(size_type __pos, size_type __n1, const _CharT* __s,
3003 size_type __n2) const
3004 {
3005 __glibcxx_requires_string_len(__s, __n2);
3006 _M_check(__pos, "basic_string::compare");
3007 __n1 = _M_limit(__pos, __n1);
3008 const size_type __len = std::min(__n1, __n2);
3009 int __r = traits_type::compare(_M_data() + __pos, __s, __len);
3010 if (!__r)
3011 __r = _S_compare(__n1, __n2);
3012 return __r;
3013 }
3014
3015#if __cplusplus > 201703L
3016 bool
3017 starts_with(basic_string_view<_CharT, _Traits> __x) const noexcept
3018 { return __sv_type(this->data(), this->size()).starts_with(__x); }
3019
3020 bool
3021 starts_with(_CharT __x) const noexcept
3022 { return __sv_type(this->data(), this->size()).starts_with(__x); }
3023
3024 [[__gnu__::__nonnull__]]
3025 bool
3026 starts_with(const _CharT* __x) const noexcept
3027 { return __sv_type(this->data(), this->size()).starts_with(__x); }
3028
3029 bool
3030 ends_with(basic_string_view<_CharT, _Traits> __x) const noexcept
3031 { return __sv_type(this->data(), this->size()).ends_with(__x); }
3032
3033 bool
3034 ends_with(_CharT __x) const noexcept
3035 { return __sv_type(this->data(), this->size()).ends_with(__x); }
3036
3037 [[__gnu__::__nonnull__]]
3038 bool
3039 ends_with(const _CharT* __x) const noexcept
3040 { return __sv_type(this->data(), this->size()).ends_with(__x); }
3041#endif // C++20
3042
3043#if __cplusplus > 202011L
3044 bool
3045 contains(basic_string_view<_CharT, _Traits> __x) const noexcept
3046 { return __sv_type(this->data(), this->size()).contains(__x); }
3047
3048 bool
3049 contains(_CharT __x) const noexcept
3050 { return __sv_type(this->data(), this->size()).contains(__x); }
3051
3052 [[__gnu__::__nonnull__]]
3053 bool
3054 contains(const _CharT* __x) const noexcept
3055 { return __sv_type(this->data(), this->size()).contains(__x); }
3056#endif // C++23
3057
3058# ifdef _GLIBCXX_TM_TS_INTERNAL
3059 friend void
3060 ::_txnal_cow_string_C1_for_exceptions(void* that, const char* s,
3061 void* exc);
3062 friend const char*
3063 ::_txnal_cow_string_c_str(const void *that);
3064 friend void
3065 ::_txnal_cow_string_D1(void *that);
3066 friend void
3067 ::_txnal_cow_string_D1_commit(void *that);
3068# endif
3069 };
3070
3071 template<typename _CharT, typename _Traits, typename _Alloc>
3072 const typename basic_string<_CharT, _Traits, _Alloc>::size_type
3073 basic_string<_CharT, _Traits, _Alloc>::
3074 _Rep::_S_max_size = (((npos - sizeof(_Rep_base))/sizeof(_CharT)) - 1) / 4;
3075
3076 template<typename _CharT, typename _Traits, typename _Alloc>
3077 const _CharT
3078 basic_string<_CharT, _Traits, _Alloc>::
3079 _Rep::_S_terminal = _CharT();
3080
3081 template<typename _CharT, typename _Traits, typename _Alloc>
3082 const typename basic_string<_CharT, _Traits, _Alloc>::size_type
3084
3085 // Linker sets _S_empty_rep_storage to all 0s (one reference, empty string)
3086 // at static init time (before static ctors are run).
3087 template<typename _CharT, typename _Traits, typename _Alloc>
3088 typename basic_string<_CharT, _Traits, _Alloc>::size_type
3089 basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_empty_rep_storage[
3090 (sizeof(_Rep_base) + sizeof(_CharT) + sizeof(size_type) - 1) /
3091 sizeof(size_type)];
3092
3093 // NB: This is the special case for Input Iterators, used in
3094 // istreambuf_iterators, etc.
3095 // Input Iterators have a cost structure very different from
3096 // pointers, calling for a different coding style.
3097 template<typename _CharT, typename _Traits, typename _Alloc>
3098 template<typename _InIterator>
3099 _CharT*
3100 basic_string<_CharT, _Traits, _Alloc>::
3101 _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a,
3102 input_iterator_tag)
3103 {
3104#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
3105 if (__beg == __end && __a == _Alloc())
3106 return _S_empty_rep()._M_refdata();
3107#endif
3108 // Avoid reallocation for common case.
3109 _CharT __buf[128];
3110 size_type __len = 0;
3111 while (__beg != __end && __len < sizeof(__buf) / sizeof(_CharT))
3112 {
3113 __buf[__len++] = *__beg;
3114 ++__beg;
3115 }
3116 _Rep* __r = _Rep::_S_create(__len, size_type(0), __a);
3117 _M_copy(__r->_M_refdata(), __buf, __len);
3118 __try
3119 {
3120 while (__beg != __end)
3121 {
3122 if (__len == __r->_M_capacity)
3123 {
3124 // Allocate more space.
3125 _Rep* __another = _Rep::_S_create(__len + 1, __len, __a);
3126 _M_copy(__another->_M_refdata(), __r->_M_refdata(), __len);
3127 __r->_M_destroy(__a);
3128 __r = __another;
3129 }
3130 __r->_M_refdata()[__len++] = *__beg;
3131 ++__beg;
3132 }
3133 }
3134 __catch(...)
3135 {
3136 __r->_M_destroy(__a);
3137 __throw_exception_again;
3138 }
3139 __r->_M_set_length_and_sharable(__len);
3140 return __r->_M_refdata();
3141 }
3142
3143 template<typename _CharT, typename _Traits, typename _Alloc>
3144 template <typename _InIterator>
3145 _CharT*
3146 basic_string<_CharT, _Traits, _Alloc>::
3147 _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a,
3148 forward_iterator_tag)
3149 {
3150#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
3151 if (__beg == __end && __a == _Alloc())
3152 return _S_empty_rep()._M_refdata();
3153#endif
3154 // NB: Not required, but considered best practice.
3155 if (__gnu_cxx::__is_null_pointer(__beg) && __beg != __end)
3156 __throw_logic_error(__N("basic_string::_S_construct null not valid"));
3157
3158 const size_type __dnew = static_cast<size_type>(std::distance(__beg,
3159 __end));
3160 // Check for out_of_range and length_error exceptions.
3161 _Rep* __r = _Rep::_S_create(__dnew, size_type(0), __a);
3162 __try
3163 { _S_copy_chars(__r->_M_refdata(), __beg, __end); }
3164 __catch(...)
3165 {
3166 __r->_M_destroy(__a);
3167 __throw_exception_again;
3168 }
3169 __r->_M_set_length_and_sharable(__dnew);
3170 return __r->_M_refdata();
3171 }
3172
3173 template<typename _CharT, typename _Traits, typename _Alloc>
3174 _CharT*
3175 basic_string<_CharT, _Traits, _Alloc>::
3176 _S_construct(size_type __n, _CharT __c, const _Alloc& __a)
3177 {
3178#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
3179 if (__n == 0 && __a == _Alloc())
3180 return _S_empty_rep()._M_refdata();
3181#endif
3182 // Check for out_of_range and length_error exceptions.
3183 _Rep* __r = _Rep::_S_create(__n, size_type(0), __a);
3184 if (__n)
3185 _M_assign(__r->_M_refdata(), __n, __c);
3186
3187 __r->_M_set_length_and_sharable(__n);
3188 return __r->_M_refdata();
3189 }
3190
3191 template<typename _CharT, typename _Traits, typename _Alloc>
3193 basic_string(const basic_string& __str, size_type __pos, const _Alloc& __a)
3194 : _M_dataplus(_S_construct(__str._M_data()
3195 + __str._M_check(__pos,
3196 "basic_string::basic_string"),
3197 __str._M_data() + __str._M_limit(__pos, npos)
3198 + __pos, __a), __a)
3199 { }
3200
3201 template<typename _CharT, typename _Traits, typename _Alloc>
3203 basic_string(const basic_string& __str, size_type __pos, size_type __n)
3204 : _M_dataplus(_S_construct(__str._M_data()
3205 + __str._M_check(__pos,
3206 "basic_string::basic_string"),
3207 __str._M_data() + __str._M_limit(__pos, __n)
3208 + __pos, _Alloc()), _Alloc())
3209 { }
3210
3211 template<typename _CharT, typename _Traits, typename _Alloc>
3213 basic_string(const basic_string& __str, size_type __pos,
3214 size_type __n, const _Alloc& __a)
3215 : _M_dataplus(_S_construct(__str._M_data()
3216 + __str._M_check(__pos,
3217 "basic_string::basic_string"),
3218 __str._M_data() + __str._M_limit(__pos, __n)
3219 + __pos, __a), __a)
3220 { }
3221
3222 template<typename _CharT, typename _Traits, typename _Alloc>
3225 assign(const basic_string& __str)
3226 {
3227 if (_M_rep() != __str._M_rep())
3228 {
3229 // XXX MT
3230 const allocator_type __a = this->get_allocator();
3231 _CharT* __tmp = __str._M_rep()->_M_grab(__a, __str.get_allocator());
3232 _M_rep()->_M_dispose(__a);
3233 _M_data(__tmp);
3234 }
3235 return *this;
3236 }
3237
3238 template<typename _CharT, typename _Traits, typename _Alloc>
3241 assign(const _CharT* __s, size_type __n)
3242 {
3243 __glibcxx_requires_string_len(__s, __n);
3244 _M_check_length(this->size(), __n, "basic_string::assign");
3245 if (_M_disjunct(__s) || _M_rep()->_M_is_shared())
3246 return _M_replace_safe(size_type(0), this->size(), __s, __n);
3247 else
3248 {
3249 // Work in-place.
3250 const size_type __pos = __s - _M_data();
3251 if (__pos >= __n)
3252 _M_copy(_M_data(), __s, __n);
3253 else if (__pos)
3254 _M_move(_M_data(), __s, __n);
3255 _M_rep()->_M_set_length_and_sharable(__n);
3256 return *this;
3257 }
3258 }
3259
3260 template<typename _CharT, typename _Traits, typename _Alloc>
3263 append(size_type __n, _CharT __c)
3264 {
3265 if (__n)
3266 {
3267 _M_check_length(size_type(0), __n, "basic_string::append");
3268 const size_type __len = __n + this->size();
3269 if (__len > this->capacity() || _M_rep()->_M_is_shared())
3270 this->reserve(__len);
3271 _M_assign(_M_data() + this->size(), __n, __c);
3272 _M_rep()->_M_set_length_and_sharable(__len);
3273 }
3274 return *this;
3275 }
3276
3277 template<typename _CharT, typename _Traits, typename _Alloc>
3280 append(const _CharT* __s, size_type __n)
3281 {
3282 __glibcxx_requires_string_len(__s, __n);
3283 if (__n)
3284 {
3285 _M_check_length(size_type(0), __n, "basic_string::append");
3286 const size_type __len = __n + this->size();
3287 if (__len > this->capacity() || _M_rep()->_M_is_shared())
3288 {
3289 if (_M_disjunct(__s))
3290 this->reserve(__len);
3291 else
3292 {
3293 const size_type __off = __s - _M_data();
3294 this->reserve(__len);
3295 __s = _M_data() + __off;
3296 }
3297 }
3298 _M_copy(_M_data() + this->size(), __s, __n);
3299 _M_rep()->_M_set_length_and_sharable(__len);
3300 }
3301 return *this;
3302 }
3303
3304 template<typename _CharT, typename _Traits, typename _Alloc>
3307 append(const basic_string& __str)
3308 {
3309 const size_type __size = __str.size();
3310 if (__size)
3311 {
3312 const size_type __len = __size + this->size();
3313 if (__len > this->capacity() || _M_rep()->_M_is_shared())
3314 this->reserve(__len);
3315 _M_copy(_M_data() + this->size(), __str._M_data(), __size);
3316 _M_rep()->_M_set_length_and_sharable(__len);
3317 }
3318 return *this;
3319 }
3320
3321 template<typename _CharT, typename _Traits, typename _Alloc>
3324 append(const basic_string& __str, size_type __pos, size_type __n)
3325 {
3326 __str._M_check(__pos, "basic_string::append");
3327 __n = __str._M_limit(__pos, __n);
3328 if (__n)
3329 {
3330 const size_type __len = __n + this->size();
3331 if (__len > this->capacity() || _M_rep()->_M_is_shared())
3332 this->reserve(__len);
3333 _M_copy(_M_data() + this->size(), __str._M_data() + __pos, __n);
3334 _M_rep()->_M_set_length_and_sharable(__len);
3335 }
3336 return *this;
3337 }
3338
3339 template<typename _CharT, typename _Traits, typename _Alloc>
3342 insert(size_type __pos, const _CharT* __s, size_type __n)
3343 {
3344 __glibcxx_requires_string_len(__s, __n);
3345 _M_check(__pos, "basic_string::insert");
3346 _M_check_length(size_type(0), __n, "basic_string::insert");
3347 if (_M_disjunct(__s) || _M_rep()->_M_is_shared())
3348 return _M_replace_safe(__pos, size_type(0), __s, __n);
3349 else
3350 {
3351 // Work in-place.
3352 const size_type __off = __s - _M_data();
3353 _M_mutate(__pos, 0, __n);
3354 __s = _M_data() + __off;
3355 _CharT* __p = _M_data() + __pos;
3356 if (__s + __n <= __p)
3357 _M_copy(__p, __s, __n);
3358 else if (__s >= __p)
3359 _M_copy(__p, __s + __n, __n);
3360 else
3361 {
3362 const size_type __nleft = __p - __s;
3363 _M_copy(__p, __s, __nleft);
3364 _M_copy(__p + __nleft, __p + __n, __n - __nleft);
3365 }
3366 return *this;
3367 }
3368 }
3369
3370 template<typename _CharT, typename _Traits, typename _Alloc>
3371 typename basic_string<_CharT, _Traits, _Alloc>::iterator
3373 erase(iterator __first, iterator __last)
3374 {
3375 _GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last
3376 && __last <= _M_iend());
3377
3378 // NB: This isn't just an optimization (bail out early when
3379 // there is nothing to do, really), it's also a correctness
3380 // issue vs MT, see libstdc++/40518.
3381 const size_type __size = __last - __first;
3382 if (__size)
3383 {
3384 const size_type __pos = __first - _M_ibegin();
3385 _M_mutate(__pos, __size, size_type(0));
3386 _M_rep()->_M_set_leaked();
3387 return iterator(_M_data() + __pos);
3388 }
3389 else
3390 return __first;
3391 }
3392
3393 template<typename _CharT, typename _Traits, typename _Alloc>
3396 replace(size_type __pos, size_type __n1, const _CharT* __s,
3397 size_type __n2)
3398 {
3399 __glibcxx_requires_string_len(__s, __n2);
3400 _M_check(__pos, "basic_string::replace");
3401 __n1 = _M_limit(__pos, __n1);
3402 _M_check_length(__n1, __n2, "basic_string::replace");
3403 bool __left;
3404 if (_M_disjunct(__s) || _M_rep()->_M_is_shared())
3405 return _M_replace_safe(__pos, __n1, __s, __n2);
3406 else if ((__left = __s + __n2 <= _M_data() + __pos)
3407 || _M_data() + __pos + __n1 <= __s)
3408 {
3409 // Work in-place: non-overlapping case.
3410 size_type __off = __s - _M_data();
3411 __left ? __off : (__off += __n2 - __n1);
3412 _M_mutate(__pos, __n1, __n2);
3413 _M_copy(_M_data() + __pos, _M_data() + __off, __n2);
3414 return *this;
3415 }
3416 else
3417 {
3418 // TODO: overlapping case.
3419 const basic_string __tmp(__s, __n2);
3420 return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2);
3421 }
3422 }
3423
3424 template<typename _CharT, typename _Traits, typename _Alloc>
3425 void
3427 _M_destroy(const _Alloc& __a) throw ()
3428 {
3429 const size_type __size = sizeof(_Rep_base)
3430 + (this->_M_capacity + 1) * sizeof(_CharT);
3431 _Raw_bytes_alloc(__a).deallocate(reinterpret_cast<char*>(this), __size);
3432 }
3433
3434 template<typename _CharT, typename _Traits, typename _Alloc>
3435 void
3436 basic_string<_CharT, _Traits, _Alloc>::
3437 _M_leak_hard()
3438 {
3439 // No need to create a new copy of an empty string when a non-const
3440 // reference/pointer/iterator into it is obtained. Modifying the
3441 // trailing null character is undefined, so the ref/pointer/iterator
3442 // is effectively const anyway.
3443 if (this->empty())
3444 return;
3445
3446 if (_M_rep()->_M_is_shared())
3447 _M_mutate(0, 0, 0);
3448 _M_rep()->_M_set_leaked();
3449 }
3450
3451 template<typename _CharT, typename _Traits, typename _Alloc>
3452 void
3453 basic_string<_CharT, _Traits, _Alloc>::
3454 _M_mutate(size_type __pos, size_type __len1, size_type __len2)
3455 {
3456 const size_type __old_size = this->size();
3457 const size_type __new_size = __old_size + __len2 - __len1;
3458 const size_type __how_much = __old_size - __pos - __len1;
3459
3460 if (__new_size > this->capacity() || _M_rep()->_M_is_shared())
3461 {
3462 // Must reallocate.
3463 const allocator_type __a = get_allocator();
3464 _Rep* __r = _Rep::_S_create(__new_size, this->capacity(), __a);
3465
3466 if (__pos)
3467 _M_copy(__r->_M_refdata(), _M_data(), __pos);
3468 if (__how_much)
3469 _M_copy(__r->_M_refdata() + __pos + __len2,
3470 _M_data() + __pos + __len1, __how_much);
3471
3472 _M_rep()->_M_dispose(__a);
3473 _M_data(__r->_M_refdata());
3474 }
3475 else if (__how_much && __len1 != __len2)
3476 {
3477 // Work in-place.
3478 _M_move(_M_data() + __pos + __len2,
3479 _M_data() + __pos + __len1, __how_much);
3480 }
3481 _M_rep()->_M_set_length_and_sharable(__new_size);
3482 }
3483
3484 template<typename _CharT, typename _Traits, typename _Alloc>
3485 void
3487 reserve(size_type __res)
3488 {
3489 const size_type __capacity = capacity();
3490
3491 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3492 // 2968. Inconsistencies between basic_string reserve and
3493 // vector/unordered_map/unordered_set reserve functions
3494 // P0966 reserve should not shrink
3495 if (__res <= __capacity)
3496 {
3497 if (!_M_rep()->_M_is_shared())
3498 return;
3499
3500 // unshare, but keep same capacity
3501 __res = __capacity;
3502 }
3503
3504 const allocator_type __a = get_allocator();
3505 _CharT* __tmp = _M_rep()->_M_clone(__a, __res - this->size());
3506 _M_rep()->_M_dispose(__a);
3507 _M_data(__tmp);
3508 }
3509
3510 template<typename _CharT, typename _Traits, typename _Alloc>
3511 void
3513 swap(basic_string& __s)
3515 {
3516 if (_M_rep()->_M_is_leaked())
3517 _M_rep()->_M_set_sharable();
3518 if (__s._M_rep()->_M_is_leaked())
3519 __s._M_rep()->_M_set_sharable();
3520 if (this->get_allocator() == __s.get_allocator())
3521 {
3522 _CharT* __tmp = _M_data();
3523 _M_data(__s._M_data());
3524 __s._M_data(__tmp);
3525 }
3526 // The code below can usually be optimized away.
3527 else
3528 {
3529 const basic_string __tmp1(_M_ibegin(), _M_iend(),
3530 __s.get_allocator());
3531 const basic_string __tmp2(__s._M_ibegin(), __s._M_iend(),
3532 this->get_allocator());
3533 *this = __tmp2;
3534 __s = __tmp1;
3535 }
3536 }
3537
3538 template<typename _CharT, typename _Traits, typename _Alloc>
3541 _S_create(size_type __capacity, size_type __old_capacity,
3542 const _Alloc& __alloc)
3543 {
3544 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3545 // 83. String::npos vs. string::max_size()
3546 if (__capacity > _S_max_size)
3547 __throw_length_error(__N("basic_string::_S_create"));
3548
3549 // The standard places no restriction on allocating more memory
3550 // than is strictly needed within this layer at the moment or as
3551 // requested by an explicit application call to reserve(n).
3552
3553 // Many malloc implementations perform quite poorly when an
3554 // application attempts to allocate memory in a stepwise fashion
3555 // growing each allocation size by only 1 char. Additionally,
3556 // it makes little sense to allocate less linear memory than the
3557 // natural blocking size of the malloc implementation.
3558 // Unfortunately, we would need a somewhat low-level calculation
3559 // with tuned parameters to get this perfect for any particular
3560 // malloc implementation. Fortunately, generalizations about
3561 // common features seen among implementations seems to suffice.
3562
3563 // __pagesize need not match the actual VM page size for good
3564 // results in practice, thus we pick a common value on the low
3565 // side. __malloc_header_size is an estimate of the amount of
3566 // overhead per memory allocation (in practice seen N * sizeof
3567 // (void*) where N is 0, 2 or 4). According to folklore,
3568 // picking this value on the high side is better than
3569 // low-balling it (especially when this algorithm is used with
3570 // malloc implementations that allocate memory blocks rounded up
3571 // to a size which is a power of 2).
3572 const size_type __pagesize = 4096;
3573 const size_type __malloc_header_size = 4 * sizeof(void*);
3574
3575 // The below implements an exponential growth policy, necessary to
3576 // meet amortized linear time requirements of the library: see
3577 // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html.
3578 // It's active for allocations requiring an amount of memory above
3579 // system pagesize. This is consistent with the requirements of the
3580 // standard: http://gcc.gnu.org/ml/libstdc++/2001-07/msg00130.html
3581 if (__capacity > __old_capacity && __capacity < 2 * __old_capacity)
3582 __capacity = 2 * __old_capacity;
3583
3584 // NB: Need an array of char_type[__capacity], plus a terminating
3585 // null char_type() element, plus enough for the _Rep data structure.
3586 // Whew. Seemingly so needy, yet so elemental.
3587 size_type __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
3588
3589 const size_type __adj_size = __size + __malloc_header_size;
3590 if (__adj_size > __pagesize && __capacity > __old_capacity)
3591 {
3592 const size_type __extra = __pagesize - __adj_size % __pagesize;
3593 __capacity += __extra / sizeof(_CharT);
3594 // Never allocate a string bigger than _S_max_size.
3595 if (__capacity > _S_max_size)
3596 __capacity = _S_max_size;
3597 __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
3598 }
3599
3600 // NB: Might throw, but no worries about a leak, mate: _Rep()
3601 // does not throw.
3602 void* __place = _Raw_bytes_alloc(__alloc).allocate(__size);
3603 _Rep *__p = new (__place) _Rep;
3604 __p->_M_capacity = __capacity;
3605 // ABI compatibility - 3.4.x set in _S_create both
3606 // _M_refcount and _M_length. All callers of _S_create
3607 // in basic_string.tcc then set just _M_length.
3608 // In 4.0.x and later both _M_refcount and _M_length
3609 // are initialized in the callers, unfortunately we can
3610 // have 3.4.x compiled code with _S_create callers inlined
3611 // calling 4.0.x+ _S_create.
3612 __p->_M_set_sharable();
3613 return __p;
3614 }
3615
3616 template<typename _CharT, typename _Traits, typename _Alloc>
3617 _CharT*
3618 basic_string<_CharT, _Traits, _Alloc>::_Rep::
3619 _M_clone(const _Alloc& __alloc, size_type __res)
3620 {
3621 // Requested capacity of the clone.
3622 const size_type __requested_cap = this->_M_length + __res;
3623 _Rep* __r = _Rep::_S_create(__requested_cap, this->_M_capacity,
3624 __alloc);
3625 if (this->_M_length)
3626 _M_copy(__r->_M_refdata(), _M_refdata(), this->_M_length);
3627
3628 __r->_M_set_length_and_sharable(this->_M_length);
3629 return __r->_M_refdata();
3630 }
3631
3632 template<typename _CharT, typename _Traits, typename _Alloc>
3633 void
3635 resize(size_type __n, _CharT __c)
3636 {
3637 const size_type __size = this->size();
3638 _M_check_length(__size, __n, "basic_string::resize");
3639 if (__size < __n)
3640 this->append(__n - __size, __c);
3641 else if (__n < __size)
3642 this->erase(__n);
3643 // else nothing (in particular, avoid calling _M_mutate() unnecessarily.)
3644 }
3645
3646 template<typename _CharT, typename _Traits, typename _Alloc>
3647 template<typename _InputIterator>
3650 _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1,
3651 _InputIterator __k2, __false_type)
3652 {
3653 const basic_string __s(__k1, __k2);
3654 const size_type __n1 = __i2 - __i1;
3655 _M_check_length(__n1, __s.size(), "basic_string::_M_replace_dispatch");
3656 return _M_replace_safe(__i1 - _M_ibegin(), __n1, __s._M_data(),
3657 __s.size());
3658 }
3659
3660 template<typename _CharT, typename _Traits, typename _Alloc>
3661 basic_string<_CharT, _Traits, _Alloc>&
3662 basic_string<_CharT, _Traits, _Alloc>::
3663 _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
3664 _CharT __c)
3665 {
3666 _M_check_length(__n1, __n2, "basic_string::_M_replace_aux");
3667 _M_mutate(__pos1, __n1, __n2);
3668 if (__n2)
3669 _M_assign(_M_data() + __pos1, __n2, __c);
3670 return *this;
3671 }
3672
3673 template<typename _CharT, typename _Traits, typename _Alloc>
3674 basic_string<_CharT, _Traits, _Alloc>&
3675 basic_string<_CharT, _Traits, _Alloc>::
3676 _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s,
3677 size_type __n2)
3678 {
3679 _M_mutate(__pos1, __n1, __n2);
3680 if (__n2)
3681 _M_copy(_M_data() + __pos1, __s, __n2);
3682 return *this;
3683 }
3684
3685 template<typename _CharT, typename _Traits, typename _Alloc>
3686 void
3688 reserve()
3689 {
3690#if __cpp_exceptions
3691 if (length() < capacity() || _M_rep()->_M_is_shared())
3692 try
3693 {
3694 const allocator_type __a = get_allocator();
3695 _CharT* __tmp = _M_rep()->_M_clone(__a);
3696 _M_rep()->_M_dispose(__a);
3697 _M_data(__tmp);
3698 }
3699 catch (const __cxxabiv1::__forced_unwind&)
3700 { throw; }
3701 catch (...)
3702 { /* swallow the exception */ }
3703#endif
3704 }
3705
3706 template<typename _CharT, typename _Traits, typename _Alloc>
3707 typename basic_string<_CharT, _Traits, _Alloc>::size_type
3709 copy(_CharT* __s, size_type __n, size_type __pos) const
3710 {
3711 _M_check(__pos, "basic_string::copy");
3712 __n = _M_limit(__pos, __n);
3713 __glibcxx_requires_string_len(__s, __n);
3714 if (__n)
3715 _M_copy(__s, _M_data() + __pos, __n);
3716 // 21.3.5.7 par 3: do not append null. (good.)
3717 return __n;
3718 }
3719_GLIBCXX_END_NAMESPACE_VERSION
3720} // namespace std
3721#endif // ! _GLIBCXX_USE_CXX11_ABI
3722#endif // _COW_STRING_H
typename enable_if< _Cond, _Tp >::type enable_if_t
Alias template for enable_if.
Definition type_traits:2610
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition move.h:97
constexpr const _Tp & min(const _Tp &, const _Tp &)
This does what you think it does.
ISO C++ entities toplevel namespace is std.
constexpr iterator_traits< _InputIterator >::difference_type distance(_InputIterator __first, _InputIterator __last)
A generalization of pointer arithmetic.
constexpr auto empty(const _Container &__cont) noexcept(noexcept(__cont.empty())) -> decltype(__cont.empty())
Return whether a container is empty.
constexpr auto size(const _Container &__cont) noexcept(noexcept(__cont.size())) -> decltype(__cont.size())
Return the size of a container.
initializer_list
Uniform interface to all allocator types.
Managing sequences of characters and character-like objects.
Definition cow_string.h:117
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.
const_reverse_iterator crbegin() const noexcept
Definition cow_string.h:897
void swap(basic_string &__s) noexcept(/*conditional */)
Swap contents with another string.
_If_sv< _Tp, basic_string & > operator=(const _Tp &__svt)
Set value to string constructed from a string_view.
Definition cow_string.h:788
basic_string & operator=(const _CharT *__s)
Copy contents of s into this string.
Definition cow_string.h:735
basic_string & append(const basic_string &__str, size_type __pos, size_type __n=npos)
Append a substring.
void push_back(_CharT __c)
Append a single character.
const_iterator cend() const noexcept
Definition cow_string.h:888
basic_string & operator+=(initializer_list< _CharT > __l)
Append an initializer_list of characters.
size_type find(const _CharT *__s, size_type __pos=0) const noexcept
Find position of a C string.
basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc &__a=_Alloc())
Construct string as copy of a range.
Definition cow_string.h:686
basic_string & replace(iterator __i1, iterator __i2, const _CharT *__s, size_type __n)
Replace range of characters with C substring.
basic_string & assign(initializer_list< _CharT > __l)
Set value to an initializer_list of characters.
size_type find_first_of(const basic_string &__str, size_type __pos=0) const noexcept
Find position of a character of string.
iterator erase(iterator __first, iterator __last)
Remove a range of characters.
_If_sv< _Tp, basic_string & > insert(size_type __pos1, const _Tp &__svt, size_type __pos2, size_type __n=npos)
Insert a string_view.
_If_sv< _Tp, int > compare(size_type __pos1, size_type __n1, const _Tp &__svt, size_type __pos2, size_type __n2=npos) const noexcept(is_same< _Tp, __sv_type >::value)
Compare to a string_view.
const _CharT * data() const noexcept
Return const pointer to contents.
basic_string(const _Alloc &__a)
Construct an empty string using allocator a.
Definition cow_string.h:536
size_type find_last_of(const _CharT *__s, size_type __pos=npos) const noexcept
Find last position of a character of C string.
_If_sv< _Tp, basic_string & > insert(size_type __pos, const _Tp &__svt)
Insert a string_view.
int compare(const _CharT *__s) const noexcept
Compare to a C string.
void insert(iterator __p, initializer_list< _CharT > __l)
Insert an initializer_list of characters.
basic_string & insert(size_type __pos1, const basic_string &__str)
Insert value of a string.
size_type rfind(const _CharT *__s, size_type __pos=npos) const noexcept
Find last position of a C string.
basic_string substr(size_type __pos=0, size_type __n=npos) const
Get a substring.
iterator erase(iterator __position)
Remove one character.
size_type find(const _CharT *__s, size_type __pos, size_type __n) const noexcept
Find position of a C substring.
size_type find(const basic_string &__str, size_type __pos=0) const noexcept
Find position of a string.
basic_string & assign(const _CharT *__s, size_type __n)
Set value to a C substring.
size_type find_last_not_of(const basic_string &__str, size_type __pos=npos) const noexcept
Find last position of a character not in string.
int compare(size_type __pos, size_type __n, const basic_string &__str) const
Compare substring to a string.
basic_string(const basic_string &__str)
Construct string with copy of value of str.
Definition cow_string.h:545
int compare(const basic_string &__str) const
Compare to a string.
int compare(size_type __pos, size_type __n1, const _CharT *__s) const
Compare substring to a C string.
_If_sv< _Tp, size_type > find_last_not_of(const _Tp &__svt, size_type __pos=npos) const noexcept(is_same< _Tp, __sv_type >::value)
Find last position of a character not in a string_view.
int compare(size_type __pos, size_type __n1, const _CharT *__s, size_type __n2) const
Compare substring against a character array.
reverse_iterator rend()
Definition cow_string.h:862
_If_sv< _Tp, basic_string & > replace(size_type __pos1, size_type __n1, const _Tp &__svt, size_type __pos2, size_type __n2=npos)
Replace range of characters with string_view.
_If_sv< _Tp, basic_string & > replace(const_iterator __i1, const_iterator __i2, const _Tp &__svt)
Replace range of characters with string_view.
basic_string & replace(iterator __i1, iterator __i2, const basic_string &__str)
Replace range of characters with string.
basic_string(const basic_string &__str, size_type __pos, const _Alloc &__a=_Alloc())
Construct string as copy of a substring.
basic_string(const basic_string &__str, size_type __pos, size_type __n)
Construct string as copy of a substring.
size_type find_first_not_of(const basic_string &__str, size_type __pos=0) const noexcept
Find position of a character not in string.
const_reference front() const noexcept
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.
void insert(iterator __p, size_type __n, _CharT __c)
Insert multiple characters.
basic_string & assign(const basic_string &__str)
Set value to contents of another string.
basic_string & append(size_type __n, _CharT __c)
Append multiple characters.
basic_string(const _Tp &__t, size_type __pos, size_type __n, const _Alloc &__a=_Alloc())
Construct string from a substring of a string_view.
Definition cow_string.h:701
_If_sv< _Tp, basic_string & > assign(const _Tp &__svt)
Set value from a string_view.
reverse_iterator rbegin()
Definition cow_string.h:844
basic_string & insert(size_type __pos1, const basic_string &__str, size_type __pos2, size_type __n=npos)
Insert a substring.
basic_string(initializer_list< _CharT > __l, const _Alloc &__a=_Alloc())
Construct string from an initializer list.
Definition cow_string.h:650
reference front()
basic_string(const basic_string &__str, size_type __pos, size_type __n, const _Alloc &__a)
Construct string as copy of a substring.
basic_string(const _Tp &__t, const _Alloc &__a=_Alloc())
Construct string from a string_view.
Definition cow_string.h:712
basic_string & replace(size_type __pos, size_type __n1, const _CharT *__s, size_type __n2)
Replace characters with value of a C substring.
basic_string & replace(iterator __i1, iterator __i2, _InputIterator __k1, _InputIterator __k2)
Replace range of characters with range.
basic_string & assign(basic_string &&__str) noexcept(allocator_traits< _Alloc >::is_always_equal::value)
Set value to contents of another string.
_If_sv< _Tp, basic_string & > operator+=(const _Tp &__svt)
Append a string_view.
void pop_back()
Remove the last character.
basic_string(basic_string &&__str) noexcept
Move construct string.
Definition cow_string.h:627
size_type copy(_CharT *__s, size_type __n, size_type __pos=0) const
Copy substring into C string.
size_type length() const noexcept
Returns the number of characters in the string, not including any null-termination.
Definition cow_string.h:928
size_type find_last_of(const basic_string &__str, size_type __pos=npos) const noexcept
Find last position of a character of string.
basic_string & insert(size_type __pos, const _CharT *__s, size_type __n)
Insert a C substring.
basic_string & operator+=(const basic_string &__str)
Append a string to this string.
size_type size() const noexcept
Returns the number of characters in the string, not including any null-termination.
Definition cow_string.h:916
size_type rfind(const basic_string &__str, size_type __pos=npos) const noexcept
Find last position of a string.
basic_string & operator+=(const _CharT *__s)
Append a C string.
basic_string(size_type __n, _CharT __c, const _Alloc &__a=_Alloc())
Construct string as multiple characters.
Definition cow_string.h:615
void shrink_to_fit() noexcept
A non-binding request to reduce capacity() to size().
Definition cow_string.h:968
void resize(size_type __n, _CharT __c)
Resizes the string to the specified number of characters.
void reserve()
Equivalent to shrink_to_fit().
_If_sv< _Tp, int > compare(const _Tp &__svt) const noexcept(is_same< _Tp, __sv_type >::value)
Compare to a string_view.
const_reference at(size_type __n) const
Provides access to the data contained in the string.
const_reference back() const noexcept
const_reverse_iterator rend() const noexcept
Definition cow_string.h:871
const_iterator end() const noexcept
Definition cow_string.h:835
_If_sv< _Tp, size_type > find_first_of(const _Tp &__svt, size_type __pos=0) const noexcept(is_same< _Tp, __sv_type >::value)
Find position of a character of a string_view.
size_type find_last_of(_CharT __c, size_type __pos=npos) const noexcept
Find last position of a character.
_If_sv< _Tp, basic_string & > replace(size_type __pos, size_type __n, const _Tp &__svt)
Replace range of characters with string_view.
iterator begin()
Definition cow_string.h:805
basic_string & append(const basic_string &__str)
Append a string to this string.
const_iterator begin() const noexcept
Definition cow_string.h:816
basic_string & operator=(basic_string &&__str) noexcept(/*conditional */)
Move assign the value of str to this string.
Definition cow_string.h:761
basic_string & replace(iterator __i1, iterator __i2, initializer_list< _CharT > __l)
Replace range of characters with initializer_list.
basic_string & operator+=(_CharT __c)
Append a character.
const_reverse_iterator crend() const noexcept
Definition cow_string.h:906
basic_string & operator=(const basic_string &__str)
Assign the value of str to this string.
Definition cow_string.h:727
basic_string & operator=(_CharT __c)
Set value to string of length 1.
Definition cow_string.h:746
void resize(size_type __n)
Resizes the string to the specified number of characters.
Definition cow_string.h:960
const_reverse_iterator rbegin() const noexcept
Definition cow_string.h:853
basic_string & assign(_InputIterator __first, _InputIterator __last)
Set value to a range of characters.
basic_string & append(initializer_list< _CharT > __l)
Append an initializer_list of characters.
basic_string & append(_InputIterator __first, _InputIterator __last)
Append a range of characters.
const_reference operator[](size_type __pos) const noexcept
Subscript access to the data contained in the string.
_If_sv< _Tp, basic_string & > assign(const _Tp &__svt, size_type __pos, size_type __n=npos)
Set value from a range of characters in a string_view.
basic_string(const _CharT *__s, const _Alloc &__a=_Alloc())
Construct string as copy of a C string.
Definition cow_string.h:604
void clear() noexcept
size_type find_first_of(_CharT __c, size_type __pos=0) const noexcept
Find position of a character.
_If_sv< _Tp, basic_string & > append(const _Tp &__svt, size_type __pos, size_type __n=npos)
Append a range of characters from a string_view.
basic_string & assign(size_type __n, _CharT __c)
Set value to multiple characters.
basic_string & replace(iterator __i1, iterator __i2, const _CharT *__s)
Replace range of characters with C string.
bool empty() const noexcept
_If_sv< _Tp, basic_string & > append(const _Tp &__svt)
Append a string_view.
_If_sv< _Tp, size_type > find(const _Tp &__svt, size_type __pos=0) const noexcept(is_same< _Tp, __sv_type >::value)
Find position of a string_view.
basic_string & insert(size_type __pos, const _CharT *__s)
Insert a C string.
basic_string & assign(const basic_string &__str, size_type __pos, size_type __n=npos)
Set value to a substring of a string.
const _CharT * c_str() const noexcept
Return const pointer to null-terminated contents.
reference back()
_If_sv< _Tp, int > compare(size_type __pos, size_type __n, const _Tp &__svt) const noexcept(is_same< _Tp, __sv_type >::value)
Compare to a string_view.
basic_string & replace(size_type __pos, size_type __n1, const _CharT *__s)
Replace characters with value of a C string.
static const size_type npos
Value returned by various member functions when they fail.
Definition cow_string.h:330
allocator_type get_allocator() const noexcept
Return copy of allocator used to construct this string.
basic_string & assign(const _CharT *__s)
Set value to contents of a C string.
basic_string & replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
Replace characters with multiple characters.
const_iterator cbegin() const noexcept
Definition cow_string.h:880
basic_string & replace(iterator __i1, iterator __i2, size_type __n, _CharT __c)
Replace range of characters with multiple characters.
basic_string & operator=(initializer_list< _CharT > __l)
Set value to string constructed from initializer list.
Definition cow_string.h:774
~basic_string() noexcept
Destroy the string instance.
Definition cow_string.h:719
size_type capacity() const noexcept
Definition cow_string.h:978
basic_string() noexcept
Default constructor creates an empty string.
Definition cow_string.h:523
void insert(iterator __p, _InputIterator __beg, _InputIterator __end)
Insert a range of characters.
size_type find_first_of(const _CharT *__s, size_type __pos=0) const noexcept
Find position of a character of C string.
_If_sv< _Tp, size_type > find_first_not_of(const _Tp &__svt, size_type __pos=0) const noexcept(is_same< _Tp, __sv_type >::value)
Find position of a character not in a string_view.
_If_sv< _Tp, size_type > rfind(const _Tp &__svt, size_type __pos=npos) const noexcept(is_same< _Tp, __sv_type >::value)
Find last position of a string_view.
size_type max_size() const noexcept
Returns the size() of the largest possible string.
Definition cow_string.h:933
reference operator[](size_type __pos)
Subscript access to the data contained in the string.
basic_string & insert(size_type __pos, size_type __n, _CharT __c)
Insert multiple characters.
basic_string & erase(size_type __pos=0, size_type __n=npos)
Remove characters.
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.
basic_string & append(const _CharT *__s, size_type __n)
Append a C substring.
_CharT * data() noexcept
Return non-const pointer to contents.
basic_string(const _CharT *__s, size_type __n, const _Alloc &__a=_Alloc())
Construct string initialized by a character array.
Definition cow_string.h:589
basic_string & append(const _CharT *__s)
Append a C string.
_If_sv< _Tp, size_type > find_last_of(const _Tp &__svt, size_type __pos=npos) const noexcept(is_same< _Tp, __sv_type >::value)
Find last position of a character of string.
basic_string & replace(size_type __pos, size_type __n, const basic_string &__str)
Replace characters with value from another string.
size_type find_first_not_of(const _CharT *__s, size_type __pos=0) const noexcept
Find position of a character not in C string.
reference at(size_type __n)
Provides access to the data contained in the string.
iterator insert(iterator __p, _CharT __c)
Insert one character.
Thrown as part of forced unwinding.
Common iterator class.
Uniform interface to C++98 and C++11 allocators.