1// Debugging string implementation -*- C++ -*-
3// Copyright (C) 2003-2023 Free Software Foundation, Inc.
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)
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.
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.
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/>.
26 * This file is a GNU debug extension to the Standard C++ Library.
29#ifndef _GLIBCXX_DEBUG_STRING
30#define _GLIBCXX_DEBUG_STRING 1
32#pragma GCC system_header
35#include <debug/safe_sequence.h>
36#include <debug/safe_container.h>
37#include <debug/safe_iterator.h>
39#define _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(_Cond,_File,_Line,_Func) \
41 __gnu_debug::_Error_formatter::_S_at(_File, _Line, _Func) \
42 ._M_message(#_Cond)._M_error()
44#if _GLIBCXX_USE_CXX11_ABI && __cplusplus >= 201103
45# define _GLIBCXX_INSERT_RETURNS_ITERATOR 1
46# define _GLIBCXX_INSERT_RETURNS_ITERATOR_ONLY(expr) expr
48# define _GLIBCXX_INSERT_RETURNS_ITERATOR 0
49# define _GLIBCXX_INSERT_RETURNS_ITERATOR_ONLY(expr)
52#ifdef _GLIBCXX_DEBUG_PEDANTIC
53# if __cplusplus < 201103L
54# define __glibcxx_check_string(_String) \
55 _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(_String != 0, \
58# define __glibcxx_check_string_len(_String,_Len) \
59 _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(_String != 0 || _Len == 0, \
63# define __glibcxx_check_string(_String) \
64 _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(_String != nullptr, \
67# define __glibcxx_check_string_len(_String,_Len) \
68 _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(_String != nullptr || _Len == 0, \
73# define __glibcxx_check_string(_String)
74# define __glibcxx_check_string_len(_String,_Len)
79 /** Checks that __s is non-NULL or __n == 0, and then returns __s. */
80 template<typename _CharT, typename _Integer>
82 __check_string(const _CharT* __s,
83 _Integer __n __attribute__((__unused__)),
84 const char* __file __attribute__((__unused__)),
85 unsigned int __line __attribute__((__unused__)),
86 const char* __function __attribute__((__unused__)))
88#ifdef _GLIBCXX_DEBUG_PEDANTIC
89# if __cplusplus < 201103L
90 _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(__s != 0 || __n == 0,
91 __file, __line, __function);
93 _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(__s != nullptr || __n == 0,
94 __file, __line, __function);
100 /** Checks that __s is non-NULL and then returns __s. */
101 template<typename _CharT>
103 __check_string(const _CharT* __s,
104 const char* __file __attribute__((__unused__)),
105 unsigned int __line __attribute__((__unused__)),
106 const char* __function __attribute__((__unused__)))
108#ifdef _GLIBCXX_DEBUG_PEDANTIC
109# if __cplusplus < 201103L
110 _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(__s != 0,
111 __file, __line, __function);
113 _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(__s != nullptr,
114 __file, __line, __function);
120#define __glibcxx_check_string_n_constructor(_Str, _Size) \
121 __check_string(_Str, _Size, __FILE__, __LINE__, __PRETTY_FUNCTION__)
123#define __glibcxx_check_string_constructor(_Str) \
124 __check_string(_Str, __FILE__, __LINE__, __PRETTY_FUNCTION__)
126 /// Class std::basic_string with safety/checking/debug instrumentation.
127 template<typename _CharT, typename _Traits = std::char_traits<_CharT>,
128 typename _Allocator = std::allocator<_CharT> >
130 : public __gnu_debug::_Safe_container<
131 basic_string<_CharT, _Traits, _Allocator>,
132 _Allocator, _Safe_sequence, bool(_GLIBCXX_USE_CXX11_ABI)>,
133 public std::basic_string<_CharT, _Traits, _Allocator>
135 typedef std::basic_string<_CharT, _Traits, _Allocator> _Base;
136 typedef __gnu_debug::_Safe_container<
137 basic_string, _Allocator, _Safe_sequence, bool(_GLIBCXX_USE_CXX11_ABI)>
140 template<typename _ItT, typename _SeqT, typename _CatT>
141 friend class ::__gnu_debug::_Safe_iterator;
143 // type used for positions in insert, erase etc.
144 typedef __gnu_debug::_Safe_iterator<
145 typename _Base::__const_iterator, basic_string> __const_iterator;
149 typedef _Traits traits_type;
150 typedef typename _Traits::char_type value_type;
151 typedef _Allocator allocator_type;
152 typedef typename _Base::size_type size_type;
153 typedef typename _Base::difference_type difference_type;
154 typedef typename _Base::reference reference;
155 typedef typename _Base::const_reference const_reference;
156 typedef typename _Base::pointer pointer;
157 typedef typename _Base::const_pointer const_pointer;
159 typedef __gnu_debug::_Safe_iterator<
160 typename _Base::iterator, basic_string> iterator;
161 typedef __gnu_debug::_Safe_iterator<
162 typename _Base::const_iterator, basic_string> const_iterator;
164 typedef std::reverse_iterator<iterator> reverse_iterator;
165 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
169 // 21.3.1 construct/copy/destroy:
172 basic_string(const _Allocator& __a) _GLIBCXX_NOEXCEPT
175#if __cplusplus < 201103L
176 basic_string() : _Base() { }
178 basic_string(const basic_string& __str)
183 basic_string() = default;
184 basic_string(const basic_string&) = default;
185 basic_string(basic_string&&) = default;
187 basic_string(std::initializer_list<_CharT> __l,
188 const _Allocator& __a = _Allocator())
192 basic_string(const basic_string& __s, const _Allocator& __a)
193 : _Base(__s, __a) { }
195 basic_string(basic_string&& __s, const _Allocator& __a)
197 std::is_nothrow_constructible<_Base, _Base, const _Allocator&>::value )
198 : _Safe(std::move(__s), __a),
199 _Base(std::move(__s), __a)
202 ~basic_string() = default;
204 // Provides conversion from a normal-mode string to a debug-mode string
205 basic_string(_Base&& __base) noexcept
206 : _Base(std::move(__base)) { }
209 // Provides conversion from a normal-mode string to a debug-mode string
210 basic_string(const _Base& __base)
213 // _GLIBCXX_RESOLVE_LIB_DEFECTS
214 // 42. string ctors specify wrong default allocator
215 basic_string(const basic_string& __str, size_type __pos,
216 size_type __n = _Base::npos,
217 const _Allocator& __a = _Allocator())
218 : _Base(__str, __pos, __n, __a) { }
220 basic_string(const _CharT* __s, size_type __n,
221 const _Allocator& __a = _Allocator())
222 : _Base(__glibcxx_check_string_n_constructor(__s, __n), __n, __a) { }
224 basic_string(const _CharT* __s, const _Allocator& __a = _Allocator())
225 : _Base(__glibcxx_check_string_constructor(__s), __a)
228 basic_string(size_type __n, _CharT __c,
229 const _Allocator& __a = _Allocator())
230 : _Base(__n, __c, __a) { }
232 template<typename _InputIterator>
233 basic_string(_InputIterator __begin, _InputIterator __end,
234 const _Allocator& __a = _Allocator())
235 : _Base(__gnu_debug::__base(
236 __glibcxx_check_valid_constructor_range(__begin, __end)),
237 __gnu_debug::__base(__end), __a) { }
239#if __cplusplus >= 201103L
241 operator=(const basic_string&) = default;
244 operator=(basic_string&&) = default;
248 operator=(const _CharT* __s)
250 __glibcxx_check_string(__s);
251 _Base::operator=(__s);
252 this->_M_invalidate_all();
257 operator=(_CharT __c)
259 _Base::operator=(__c);
260 this->_M_invalidate_all();
264#if __cplusplus >= 201103L
266 operator=(std::initializer_list<_CharT> __l)
268 _Base::operator=(__l);
269 this->_M_invalidate_all();
276 begin() // _GLIBCXX_NOEXCEPT
277 { return iterator(_Base::begin(), this); }
280 begin() const _GLIBCXX_NOEXCEPT
281 { return const_iterator(_Base::begin(), this); }
284 end() // _GLIBCXX_NOEXCEPT
285 { return iterator(_Base::end(), this); }
288 end() const _GLIBCXX_NOEXCEPT
289 { return const_iterator(_Base::end(), this); }
292 rbegin() // _GLIBCXX_NOEXCEPT
293 { return reverse_iterator(end()); }
295 const_reverse_iterator
296 rbegin() const _GLIBCXX_NOEXCEPT
297 { return const_reverse_iterator(end()); }
300 rend() // _GLIBCXX_NOEXCEPT
301 { return reverse_iterator(begin()); }
303 const_reverse_iterator
304 rend() const _GLIBCXX_NOEXCEPT
305 { return const_reverse_iterator(begin()); }
307#if __cplusplus >= 201103L
309 cbegin() const noexcept
310 { return const_iterator(_Base::begin(), this); }
313 cend() const noexcept
314 { return const_iterator(_Base::end(), this); }
316 const_reverse_iterator
317 crbegin() const noexcept
318 { return const_reverse_iterator(end()); }
320 const_reverse_iterator
321 crend() const noexcept
322 { return const_reverse_iterator(begin()); }
328 using _Base::max_size;
331 resize(size_type __n, _CharT __c)
333 _Base::resize(__n, __c);
334 this->_M_invalidate_all();
338 resize(size_type __n)
339 { this->resize(__n, _CharT()); }
341#if __cplusplus >= 201103L
343 shrink_to_fit() noexcept
345 if (capacity() > size())
350 this->_M_invalidate_all();
358 using _Base::capacity;
359 using _Base::reserve;
362 clear() // _GLIBCXX_NOEXCEPT
365 this->_M_invalidate_all();
370 // 21.3.4 element access:
372 operator[](size_type __pos) const _GLIBCXX_NOEXCEPT
374 _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(),
375 _M_message(__gnu_debug::__msg_subscript_oob)
376 ._M_sequence(*this, "this")
377 ._M_integer(__pos, "__pos")
378 ._M_integer(this->size(), "size"));
379 return _Base::operator[](__pos);
383 operator[](size_type __pos) // _GLIBCXX_NOEXCEPT
385#if __cplusplus < 201103L && defined(_GLIBCXX_DEBUG_PEDANTIC)
386 __glibcxx_check_subscript(__pos);
388 // as an extension v3 allows s[s.size()] when s is non-const.
389 _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(),
390 _M_message(__gnu_debug::__msg_subscript_oob)
391 ._M_sequence(*this, "this")
392 ._M_integer(__pos, "__pos")
393 ._M_integer(this->size(), "size"));
395 return _Base::operator[](__pos);
400#if __cplusplus >= 201103L
407 operator+=(const basic_string& __str)
409 _Base::operator+=(__str);
410 this->_M_invalidate_all();
415 operator+=(const _CharT* __s)
417 __glibcxx_check_string(__s);
418 _Base::operator+=(__s);
419 this->_M_invalidate_all();
424 operator+=(_CharT __c)
426 _Base::operator+=(__c);
427 this->_M_invalidate_all();
431#if __cplusplus >= 201103L
433 operator+=(std::initializer_list<_CharT> __l)
435 _Base::operator+=(__l);
436 this->_M_invalidate_all();
442 append(const basic_string& __str)
444 _Base::append(__str);
445 this->_M_invalidate_all();
450 append(const basic_string& __str, size_type __pos, size_type __n)
452 _Base::append(__str, __pos, __n);
453 this->_M_invalidate_all();
458 append(const _CharT* __s, size_type __n)
460 __glibcxx_check_string_len(__s, __n);
461 _Base::append(__s, __n);
462 this->_M_invalidate_all();
467 append(const _CharT* __s)
469 __glibcxx_check_string(__s);
471 this->_M_invalidate_all();
476 append(size_type __n, _CharT __c)
478 _Base::append(__n, __c);
479 this->_M_invalidate_all();
483 template<typename _InputIterator>
485 append(_InputIterator __first, _InputIterator __last)
487 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
488 __glibcxx_check_valid_range2(__first, __last, __dist);
490 if (__dist.second >= __dp_sign)
491 _Base::append(__gnu_debug::__unsafe(__first),
492 __gnu_debug::__unsafe(__last));
494 _Base::append(__first, __last);
496 this->_M_invalidate_all();
500 // _GLIBCXX_RESOLVE_LIB_DEFECTS
501 // 7. string clause minor problems
503 push_back(_CharT __c)
505 _Base::push_back(__c);
506 this->_M_invalidate_all();
510 assign(const basic_string& __x)
513 this->_M_invalidate_all();
517#if __cplusplus >= 201103L
519 assign(basic_string&& __x)
520 noexcept(noexcept(std::declval<_Base&>().assign(std::move(__x))))
522 _Base::assign(std::move(__x));
523 this->_M_invalidate_all();
529 assign(const basic_string& __str, size_type __pos, size_type __n)
531 _Base::assign(__str, __pos, __n);
532 this->_M_invalidate_all();
537 assign(const _CharT* __s, size_type __n)
539 __glibcxx_check_string_len(__s, __n);
540 _Base::assign(__s, __n);
541 this->_M_invalidate_all();
546 assign(const _CharT* __s)
548 __glibcxx_check_string(__s);
550 this->_M_invalidate_all();
555 assign(size_type __n, _CharT __c)
557 _Base::assign(__n, __c);
558 this->_M_invalidate_all();
562 template<typename _InputIterator>
564 assign(_InputIterator __first, _InputIterator __last)
566 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
567 __glibcxx_check_valid_range2(__first, __last, __dist);
569 if (__dist.second >= __dp_sign)
570 _Base::assign(__gnu_debug::__unsafe(__first),
571 __gnu_debug::__unsafe(__last));
573 _Base::assign(__first, __last);
575 this->_M_invalidate_all();
579#if __cplusplus >= 201103L
581 assign(std::initializer_list<_CharT> __l)
584 this->_M_invalidate_all();
590 insert(size_type __pos1, const basic_string& __str)
592 _Base::insert(__pos1, __str);
593 this->_M_invalidate_all();
598 insert(size_type __pos1, const basic_string& __str,
599 size_type __pos2, size_type __n)
601 _Base::insert(__pos1, __str, __pos2, __n);
602 this->_M_invalidate_all();
607 insert(size_type __pos, const _CharT* __s, size_type __n)
609 __glibcxx_check_string(__s);
610 _Base::insert(__pos, __s, __n);
611 this->_M_invalidate_all();
616 insert(size_type __pos, const _CharT* __s)
618 __glibcxx_check_string(__s);
619 _Base::insert(__pos, __s);
620 this->_M_invalidate_all();
625 insert(size_type __pos, size_type __n, _CharT __c)
627 _Base::insert(__pos, __n, __c);
628 this->_M_invalidate_all();
633 insert(__const_iterator __p, _CharT __c)
635 __glibcxx_check_insert(__p);
636 typename _Base::iterator __res = _Base::insert(__p.base(), __c);
637 this->_M_invalidate_all();
638 return iterator(__res, this);
641#if __cplusplus >= 201103L
643 insert(const_iterator __p, size_type __n, _CharT __c)
645 __glibcxx_check_insert(__p);
646#if _GLIBCXX_USE_CXX11_ABI
647 typename _Base::iterator __res = _Base::insert(__p.base(), __n, __c);
649 const size_type __offset = __p.base() - _Base::cbegin();
650 _Base::insert(_Base::begin() + __offset, __n, __c);
651 typename _Base::iterator __res = _Base::begin() + __offset;
653 this->_M_invalidate_all();
654 return iterator(__res, this);
658 insert(iterator __p, size_type __n, _CharT __c)
660 __glibcxx_check_insert(__p);
661 _Base::insert(__p.base(), __n, __c);
662 this->_M_invalidate_all();
666 template<typename _InputIterator>
668 insert(__const_iterator __p,
669 _InputIterator __first, _InputIterator __last)
671 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
672 __glibcxx_check_insert_range(__p, __first, __last, __dist);
674 typename _Base::iterator __res;
675#if ! _GLIBCXX_INSERT_RETURNS_ITERATOR
676 const size_type __offset = __p.base() - _Base::begin();
678 if (__dist.second >= __dp_sign)
680 _GLIBCXX_INSERT_RETURNS_ITERATOR_ONLY(__res =)
681 _Base::insert(__p.base(), __gnu_debug::__unsafe(__first),
682 __gnu_debug::__unsafe(__last));
686 _GLIBCXX_INSERT_RETURNS_ITERATOR_ONLY(__res =)
687 _Base::insert(__p.base(), __first, __last);
690#if ! _GLIBCXX_INSERT_RETURNS_ITERATOR
691 __res = _Base::begin() + __offset;
693 this->_M_invalidate_all();
694 return iterator(__res, this);
697#if __cplusplus >= 201103L
699 insert(const_iterator __p, std::initializer_list<_CharT> __l)
701 __glibcxx_check_insert(__p);
702#if _GLIBCXX_USE_CXX11_ABI
703 const auto __res = _Base::insert(__p.base(), __l);
705 const size_type __offset = __p.base() - _Base::cbegin();
706 _Base::insert(_Base::begin() + __offset, __l);
707 auto __res = _Base::begin() + __offset;
709 this->_M_invalidate_all();
710 return iterator(__res, this);
715 erase(size_type __pos = 0, size_type __n = _Base::npos)
717 _Base::erase(__pos, __n);
718 this->_M_invalidate_all();
723 erase(__const_iterator __position)
725 __glibcxx_check_erase(__position);
726 typename _Base::iterator __res = _Base::erase(__position.base());
727 this->_M_invalidate_all();
728 return iterator(__res, this);
732 erase(__const_iterator __first, __const_iterator __last)
734 // _GLIBCXX_RESOLVE_LIB_DEFECTS
735 // 151. can't currently clear() empty container
736 __glibcxx_check_erase_range(__first, __last);
737 typename _Base::iterator __res = _Base::erase(__first.base(),
739 this->_M_invalidate_all();
740 return iterator(__res, this);
743#if __cplusplus >= 201103L
745 pop_back() // noexcept
747 __glibcxx_check_nonempty();
749 this->_M_invalidate_all();
754 replace(size_type __pos1, size_type __n1, const basic_string& __str)
756 _Base::replace(__pos1, __n1, __str);
757 this->_M_invalidate_all();
762 replace(size_type __pos1, size_type __n1, const basic_string& __str,
763 size_type __pos2, size_type __n2)
765 _Base::replace(__pos1, __n1, __str, __pos2, __n2);
766 this->_M_invalidate_all();
771 replace(size_type __pos, size_type __n1, const _CharT* __s,
774 __glibcxx_check_string_len(__s, __n2);
775 _Base::replace(__pos, __n1, __s, __n2);
776 this->_M_invalidate_all();
781 replace(size_type __pos, size_type __n1, const _CharT* __s)
783 __glibcxx_check_string(__s);
784 _Base::replace(__pos, __n1, __s);
785 this->_M_invalidate_all();
790 replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
792 _Base::replace(__pos, __n1, __n2, __c);
793 this->_M_invalidate_all();
798 replace(__const_iterator __i1, __const_iterator __i2,
799 const basic_string& __str)
801 __glibcxx_check_erase_range(__i1, __i2);
802 _Base::replace(__i1.base(), __i2.base(), __str);
803 this->_M_invalidate_all();
808 replace(__const_iterator __i1, __const_iterator __i2,
809 const _CharT* __s, size_type __n)
811 __glibcxx_check_erase_range(__i1, __i2);
812 __glibcxx_check_string_len(__s, __n);
813 _Base::replace(__i1.base(), __i2.base(), __s, __n);
814 this->_M_invalidate_all();
819 replace(__const_iterator __i1, __const_iterator __i2,
822 __glibcxx_check_erase_range(__i1, __i2);
823 __glibcxx_check_string(__s);
824 _Base::replace(__i1.base(), __i2.base(), __s);
825 this->_M_invalidate_all();
830 replace(__const_iterator __i1, __const_iterator __i2,
831 size_type __n, _CharT __c)
833 __glibcxx_check_erase_range(__i1, __i2);
834 _Base::replace(__i1.base(), __i2.base(), __n, __c);
835 this->_M_invalidate_all();
839 template<typename _InputIterator>
841 replace(__const_iterator __i1, __const_iterator __i2,
842 _InputIterator __j1, _InputIterator __j2)
844 __glibcxx_check_erase_range(__i1, __i2);
846 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
847 __glibcxx_check_valid_range2(__j1, __j2, __dist);
849 if (__dist.second >= __dp_sign)
850 _Base::replace(__i1.base(), __i2.base(),
851 __gnu_debug::__unsafe(__j1),
852 __gnu_debug::__unsafe(__j2));
854 _Base::replace(__i1.base(), __i2.base(), __j1, __j2);
856 this->_M_invalidate_all();
860#if __cplusplus >= 201103L
862 replace(__const_iterator __i1, __const_iterator __i2,
863 std::initializer_list<_CharT> __l)
865 __glibcxx_check_erase_range(__i1, __i2);
866 _Base::replace(__i1.base(), __i2.base(), __l);
867 this->_M_invalidate_all();
873 copy(_CharT* __s, size_type __n, size_type __pos = 0) const
875 __glibcxx_check_string_len(__s, __n);
876 return _Base::copy(__s, __n, __pos);
880 swap(basic_string& __x)
881 _GLIBCXX_NOEXCEPT_IF(std::__is_nothrow_swappable<_Base>::value)
887 // 21.3.6 string operations:
889 c_str() const _GLIBCXX_NOEXCEPT
891 const _CharT* __res = _Base::c_str();
892 this->_M_invalidate_all();
897 data() const _GLIBCXX_NOEXCEPT
899 const _CharT* __res = _Base::data();
900 this->_M_invalidate_all();
904 using _Base::get_allocator;
910 find(const _CharT* __s, size_type __pos, size_type __n) const
913 __glibcxx_check_string(__s);
914 return _Base::find(__s, __pos, __n);
919 find(const _CharT* __s, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
921 __glibcxx_check_string(__s);
922 return _Base::find(__s, __pos);
929 rfind(const _CharT* __s, size_type __pos, size_type __n) const
931 __glibcxx_check_string_len(__s, __n);
932 return _Base::rfind(__s, __pos, __n);
937 rfind(const _CharT* __s, size_type __pos = _Base::npos) const
939 __glibcxx_check_string(__s);
940 return _Base::rfind(__s, __pos);
943 using _Base::find_first_of;
947 find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
950 __glibcxx_check_string(__s);
951 return _Base::find_first_of(__s, __pos, __n);
956 find_first_of(const _CharT* __s, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
958 __glibcxx_check_string(__s);
959 return _Base::find_first_of(__s, __pos);
962 using _Base::find_last_of;
966 find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
969 __glibcxx_check_string(__s);
970 return _Base::find_last_of(__s, __pos, __n);
975 find_last_of(const _CharT* __s, size_type __pos = _Base::npos) const
978 __glibcxx_check_string(__s);
979 return _Base::find_last_of(__s, __pos);
982 using _Base::find_first_not_of;
986 find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
989 __glibcxx_check_string_len(__s, __n);
990 return _Base::find_first_not_of(__s, __pos, __n);
995 find_first_not_of(const _CharT* __s, size_type __pos = 0) const
998 __glibcxx_check_string(__s);
999 return _Base::find_first_not_of(__s, __pos);
1002 using _Base::find_last_not_of;
1004 _GLIBCXX20_CONSTEXPR
1006 find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
1009 __glibcxx_check_string(__s);
1010 return _Base::find_last_not_of(__s, __pos, __n);
1013 _GLIBCXX20_CONSTEXPR
1015 find_last_not_of(const _CharT* __s, size_type __pos = _Base::npos) const
1018 __glibcxx_check_string(__s);
1019 return _Base::find_last_not_of(__s, __pos);
1023 substr(size_type __pos = 0, size_type __n = _Base::npos) const
1024 { return basic_string(_Base::substr(__pos, __n)); }
1026 using _Base::compare;
1028 _GLIBCXX20_CONSTEXPR
1030 compare(const _CharT* __s) const _GLIBCXX_NOEXCEPT
1032 __glibcxx_check_string(__s);
1033 return _Base::compare(__s);
1036 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1037 // 5. string::compare specification questionable
1038 _GLIBCXX20_CONSTEXPR
1040 compare(size_type __pos1, size_type __n1, const _CharT* __s) const
1042 __glibcxx_check_string(__s);
1043 return _Base::compare(__pos1, __n1, __s);
1046 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1047 // 5. string::compare specification questionable
1048 _GLIBCXX20_CONSTEXPR
1050 compare(size_type __pos1, size_type __n1,const _CharT* __s,
1051 size_type __n2) const
1053 __glibcxx_check_string_len(__s, __n2);
1054 return _Base::compare(__pos1, __n1, __s, __n2);
1058 _M_base() _GLIBCXX_NOEXCEPT { return *this; }
1061 _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
1063 using _Safe::_M_invalidate_all;
1066 template<typename _CharT, typename _Traits, typename _Allocator>
1067 inline basic_string<_CharT,_Traits,_Allocator>
1068 operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1069 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1070 { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
1072 template<typename _CharT, typename _Traits, typename _Allocator>
1073 inline basic_string<_CharT,_Traits,_Allocator>
1074 operator+(const _CharT* __lhs,
1075 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1077 __glibcxx_check_string(__lhs);
1078 return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
1081 template<typename _CharT, typename _Traits, typename _Allocator>
1082 inline basic_string<_CharT,_Traits,_Allocator>
1083 operator+(_CharT __lhs,
1084 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1085 { return basic_string<_CharT,_Traits,_Allocator>(1, __lhs) += __rhs; }
1087 template<typename _CharT, typename _Traits, typename _Allocator>
1088 inline basic_string<_CharT,_Traits,_Allocator>
1089 operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1090 const _CharT* __rhs)
1092 __glibcxx_check_string(__rhs);
1093 return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
1096 template<typename _CharT, typename _Traits, typename _Allocator>
1097 inline basic_string<_CharT,_Traits,_Allocator>
1098 operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1100 { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
1102 template<typename _CharT, typename _Traits, typename _Allocator>
1104 operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1105 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1106 { return __lhs._M_base() == __rhs._M_base(); }
1108 template<typename _CharT, typename _Traits, typename _Allocator>
1110 operator==(const _CharT* __lhs,
1111 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1113 __glibcxx_check_string(__lhs);
1114 return __lhs == __rhs._M_base();
1117 template<typename _CharT, typename _Traits, typename _Allocator>
1119 operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1120 const _CharT* __rhs)
1122 __glibcxx_check_string(__rhs);
1123 return __lhs._M_base() == __rhs;
1126 template<typename _CharT, typename _Traits, typename _Allocator>
1128 operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1129 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1130 { return __lhs._M_base() != __rhs._M_base(); }
1132 template<typename _CharT, typename _Traits, typename _Allocator>
1134 operator!=(const _CharT* __lhs,
1135 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1137 __glibcxx_check_string(__lhs);
1138 return __lhs != __rhs._M_base();
1141 template<typename _CharT, typename _Traits, typename _Allocator>
1143 operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1144 const _CharT* __rhs)
1146 __glibcxx_check_string(__rhs);
1147 return __lhs._M_base() != __rhs;
1150 template<typename _CharT, typename _Traits, typename _Allocator>
1152 operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1153 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1154 { return __lhs._M_base() < __rhs._M_base(); }
1156 template<typename _CharT, typename _Traits, typename _Allocator>
1158 operator<(const _CharT* __lhs,
1159 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1161 __glibcxx_check_string(__lhs);
1162 return __lhs < __rhs._M_base();
1165 template<typename _CharT, typename _Traits, typename _Allocator>
1167 operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1168 const _CharT* __rhs)
1170 __glibcxx_check_string(__rhs);
1171 return __lhs._M_base() < __rhs;
1174 template<typename _CharT, typename _Traits, typename _Allocator>
1176 operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1177 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1178 { return __lhs._M_base() <= __rhs._M_base(); }
1180 template<typename _CharT, typename _Traits, typename _Allocator>
1182 operator<=(const _CharT* __lhs,
1183 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1185 __glibcxx_check_string(__lhs);
1186 return __lhs <= __rhs._M_base();
1189 template<typename _CharT, typename _Traits, typename _Allocator>
1191 operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1192 const _CharT* __rhs)
1194 __glibcxx_check_string(__rhs);
1195 return __lhs._M_base() <= __rhs;
1198 template<typename _CharT, typename _Traits, typename _Allocator>
1200 operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1201 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1202 { return __lhs._M_base() >= __rhs._M_base(); }
1204 template<typename _CharT, typename _Traits, typename _Allocator>
1206 operator>=(const _CharT* __lhs,
1207 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1209 __glibcxx_check_string(__lhs);
1210 return __lhs >= __rhs._M_base();
1213 template<typename _CharT, typename _Traits, typename _Allocator>
1215 operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1216 const _CharT* __rhs)
1218 __glibcxx_check_string(__rhs);
1219 return __lhs._M_base() >= __rhs;
1222 template<typename _CharT, typename _Traits, typename _Allocator>
1224 operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1225 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1226 { return __lhs._M_base() > __rhs._M_base(); }
1228 template<typename _CharT, typename _Traits, typename _Allocator>
1230 operator>(const _CharT* __lhs,
1231 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1233 __glibcxx_check_string(__lhs);
1234 return __lhs > __rhs._M_base();
1237 template<typename _CharT, typename _Traits, typename _Allocator>
1239 operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1240 const _CharT* __rhs)
1242 __glibcxx_check_string(__rhs);
1243 return __lhs._M_base() > __rhs;
1247 template<typename _CharT, typename _Traits, typename _Allocator>
1249 swap(basic_string<_CharT,_Traits,_Allocator>& __lhs,
1250 basic_string<_CharT,_Traits,_Allocator>& __rhs)
1251 { __lhs.swap(__rhs); }
1253 template<typename _CharT, typename _Traits, typename _Allocator>
1254 std::basic_ostream<_CharT, _Traits>&
1255 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1256 const basic_string<_CharT, _Traits, _Allocator>& __str)
1257 { return __os << __str._M_base(); }
1259 template<typename _CharT, typename _Traits, typename _Allocator>
1260 std::basic_istream<_CharT,_Traits>&
1261 operator>>(std::basic_istream<_CharT,_Traits>& __is,
1262 basic_string<_CharT,_Traits,_Allocator>& __str)
1264 std::basic_istream<_CharT,_Traits>& __res = __is >> __str._M_base();
1265 __str._M_invalidate_all();
1269 template<typename _CharT, typename _Traits, typename _Allocator>
1270 std::basic_istream<_CharT,_Traits>&
1271 getline(std::basic_istream<_CharT,_Traits>& __is,
1272 basic_string<_CharT,_Traits,_Allocator>& __str, _CharT __delim)
1274 std::basic_istream<_CharT,_Traits>& __res = getline(__is,
1277 __str._M_invalidate_all();
1281 template<typename _CharT, typename _Traits, typename _Allocator>
1282 std::basic_istream<_CharT,_Traits>&
1283 getline(std::basic_istream<_CharT,_Traits>& __is,
1284 basic_string<_CharT,_Traits,_Allocator>& __str)
1286 std::basic_istream<_CharT,_Traits>& __res = getline(__is,
1288 __str._M_invalidate_all();
1292 typedef basic_string<char> string;
1294 typedef basic_string<wchar_t> wstring;
1296#ifdef _GLIBCXX_USE_CHAR8_T
1297 /// A string of @c char8_t
1298 typedef basic_string<char8_t> u8string;
1301#if __cplusplus >= 201103L
1302 /// A string of @c char16_t
1303 typedef basic_string<char16_t> u16string;
1305 /// A string of @c char32_t
1306 typedef basic_string<char32_t> u32string;
1309 template<typename _CharT, typename _Traits, typename _Allocator>
1310 struct _Insert_range_from_self_is_safe<
1311 __gnu_debug::basic_string<_CharT, _Traits, _Allocator> >
1312 { enum { __value = 1 }; };
1314} // namespace __gnu_debug
1316#if __cplusplus >= 201103L
1317namespace std _GLIBCXX_VISIBILITY(default)
1319_GLIBCXX_BEGIN_NAMESPACE_VERSION
1321 /// std::hash specialization for __gnu_debug::basic_string.
1322 template<typename _CharT>
1323 struct hash<__gnu_debug::basic_string<_CharT>>
1324 : public hash<std::basic_string<_CharT>>
1327 template<typename _CharT>
1328 struct __is_fast_hash<hash<__gnu_debug::basic_string<_CharT>>>
1329 : __is_fast_hash<hash<std::basic_string<_CharT>>>
1332_GLIBCXX_END_NAMESPACE_VERSION
1336#undef _GLIBCXX_INSERT_RETURNS_ITERATOR
1337#undef _GLIBCXX_INSERT_RETURNS_ITERATOR_ONLY