1 // Debugging string implementation -*- C++ -*-
3 // Copyright (C) 2003-2016 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/>.
25 /** @file debug/string
26 * This file is a GNU debug extension to the Standard C++ Library.
29 #ifndef _GLIBCXX_DEBUG_STRING
30 #define _GLIBCXX_DEBUG_STRING 1
33 #include <debug/safe_sequence.h>
34 #include <debug/safe_container.h>
35 #include <debug/safe_iterator.h>
39 /// Class std::basic_string with safety/checking/debug instrumentation.
40 template<typename _CharT, typename _Traits = std::char_traits<_CharT>,
41 typename _Allocator = std::allocator<_CharT> >
43 : public __gnu_debug::_Safe_container<
44 basic_string<_CharT, _Traits, _Allocator>,
45 _Allocator, _Safe_sequence, bool(_GLIBCXX_USE_CXX11_ABI)>,
46 public std::basic_string<_CharT, _Traits, _Allocator>
48 typedef std::basic_string<_CharT, _Traits, _Allocator> _Base;
49 typedef __gnu_debug::_Safe_container<
50 basic_string, _Allocator, _Safe_sequence, bool(_GLIBCXX_USE_CXX11_ABI)>
55 typedef _Traits traits_type;
56 typedef typename _Traits::char_type value_type;
57 typedef _Allocator allocator_type;
58 typedef typename _Base::size_type size_type;
59 typedef typename _Base::difference_type difference_type;
60 typedef typename _Base::reference reference;
61 typedef typename _Base::const_reference const_reference;
62 typedef typename _Base::pointer pointer;
63 typedef typename _Base::const_pointer const_pointer;
65 typedef __gnu_debug::_Safe_iterator<
66 typename _Base::iterator, basic_string> iterator;
67 typedef __gnu_debug::_Safe_iterator<
68 typename _Base::const_iterator, basic_string> const_iterator;
70 typedef std::reverse_iterator<iterator> reverse_iterator;
71 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
76 _GLIBCXX_NOEXCEPT_IF(std::is_nothrow_default_constructible<_Base>::value)
79 // 21.3.1 construct/copy/destroy:
81 basic_string(const _Allocator& __a) _GLIBCXX_NOEXCEPT
84 #if __cplusplus < 201103L
85 basic_string(const basic_string& __str)
90 basic_string(const basic_string&) = default;
91 basic_string(basic_string&&) = default;
93 basic_string(std::initializer_list<_CharT> __l,
94 const _Allocator& __a = _Allocator())
98 #if _GLIBCXX_USE_CXX11_ABI
99 basic_string(const basic_string& __s, const _Allocator& __a)
100 : _Base(__s, __a) { }
102 basic_string(basic_string&& __s, const _Allocator& __a)
103 : _Base(std::move(__s), __a) { }
106 ~basic_string() = default;
108 // Provides conversion from a normal-mode string to a debug-mode string
109 basic_string(_Base&& __base) noexcept
110 : _Base(std::move(__base)) { }
113 // Provides conversion from a normal-mode string to a debug-mode string
114 basic_string(const _Base& __base)
117 // _GLIBCXX_RESOLVE_LIB_DEFECTS
118 // 42. string ctors specify wrong default allocator
119 basic_string(const basic_string& __str, size_type __pos,
120 size_type __n = _Base::npos,
121 const _Allocator& __a = _Allocator())
122 : _Base(__str, __pos, __n, __a) { }
124 basic_string(const _CharT* __s, size_type __n,
125 const _Allocator& __a = _Allocator())
126 : _Base(__gnu_debug::__check_string(__s, __n), __n, __a) { }
128 basic_string(const _CharT* __s, const _Allocator& __a = _Allocator())
129 : _Base(__gnu_debug::__check_string(__s), __a)
130 { this->assign(__s); }
132 basic_string(size_type __n, _CharT __c,
133 const _Allocator& __a = _Allocator())
134 : _Base(__n, __c, __a) { }
136 template<typename _InputIterator>
137 basic_string(_InputIterator __begin, _InputIterator __end,
138 const _Allocator& __a = _Allocator())
139 : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__begin,
141 __gnu_debug::__base(__end), __a) { }
143 #if __cplusplus < 201103L
145 operator=(const basic_string& __str)
147 this->_M_safe() = __str;
153 operator=(const basic_string&) = default;
156 operator=(basic_string&&) = default;
160 operator=(const _CharT* __s)
162 __glibcxx_check_string(__s);
164 this->_M_invalidate_all();
169 operator=(_CharT __c)
172 this->_M_invalidate_all();
176 #if __cplusplus >= 201103L
178 operator=(std::initializer_list<_CharT> __l)
181 this->_M_invalidate_all();
188 begin() // _GLIBCXX_NOEXCEPT
189 { return iterator(_Base::begin(), this); }
192 begin() const _GLIBCXX_NOEXCEPT
193 { return const_iterator(_Base::begin(), this); }
196 end() // _GLIBCXX_NOEXCEPT
197 { return iterator(_Base::end(), this); }
200 end() const _GLIBCXX_NOEXCEPT
201 { return const_iterator(_Base::end(), this); }
204 rbegin() // _GLIBCXX_NOEXCEPT
205 { return reverse_iterator(end()); }
207 const_reverse_iterator
208 rbegin() const _GLIBCXX_NOEXCEPT
209 { return const_reverse_iterator(end()); }
212 rend() // _GLIBCXX_NOEXCEPT
213 { return reverse_iterator(begin()); }
215 const_reverse_iterator
216 rend() const _GLIBCXX_NOEXCEPT
217 { return const_reverse_iterator(begin()); }
219 #if __cplusplus >= 201103L
221 cbegin() const noexcept
222 { return const_iterator(_Base::begin(), this); }
225 cend() const noexcept
226 { return const_iterator(_Base::end(), this); }
228 const_reverse_iterator
229 crbegin() const noexcept
230 { return const_reverse_iterator(end()); }
232 const_reverse_iterator
233 crend() const noexcept
234 { return const_reverse_iterator(begin()); }
240 using _Base::max_size;
243 resize(size_type __n, _CharT __c)
245 _Base::resize(__n, __c);
246 this->_M_invalidate_all();
250 resize(size_type __n)
251 { this->resize(__n, _CharT()); }
253 #if __cplusplus >= 201103L
255 shrink_to_fit() noexcept
257 if (capacity() > size())
262 this->_M_invalidate_all();
270 using _Base::capacity;
271 using _Base::reserve;
274 clear() // _GLIBCXX_NOEXCEPT
277 this->_M_invalidate_all();
282 // 21.3.4 element access:
284 operator[](size_type __pos) const _GLIBCXX_NOEXCEPT
286 _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(),
287 _M_message(__gnu_debug::__msg_subscript_oob)
288 ._M_sequence(*this, "this")
289 ._M_integer(__pos, "__pos")
290 ._M_integer(this->size(), "size"));
291 return _M_base()[__pos];
295 operator[](size_type __pos) // _GLIBCXX_NOEXCEPT
297 #if __cplusplus < 201103L && defined(_GLIBCXX_DEBUG_PEDANTIC)
298 __glibcxx_check_subscript(__pos);
300 // as an extension v3 allows s[s.size()] when s is non-const.
301 _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(),
302 _M_message(__gnu_debug::__msg_subscript_oob)
303 ._M_sequence(*this, "this")
304 ._M_integer(__pos, "__pos")
305 ._M_integer(this->size(), "size"));
307 return _M_base()[__pos];
312 #if __cplusplus >= 201103L
319 operator+=(const basic_string& __str)
322 this->_M_invalidate_all();
327 operator+=(const _CharT* __s)
329 __glibcxx_check_string(__s);
331 this->_M_invalidate_all();
336 operator+=(_CharT __c)
339 this->_M_invalidate_all();
343 #if __cplusplus >= 201103L
345 operator+=(std::initializer_list<_CharT> __l)
348 this->_M_invalidate_all();
354 append(const basic_string& __str)
356 _Base::append(__str);
357 this->_M_invalidate_all();
362 append(const basic_string& __str, size_type __pos, size_type __n)
364 _Base::append(__str, __pos, __n);
365 this->_M_invalidate_all();
370 append(const _CharT* __s, size_type __n)
372 __glibcxx_check_string_len(__s, __n);
373 _Base::append(__s, __n);
374 this->_M_invalidate_all();
379 append(const _CharT* __s)
381 __glibcxx_check_string(__s);
383 this->_M_invalidate_all();
388 append(size_type __n, _CharT __c)
390 _Base::append(__n, __c);
391 this->_M_invalidate_all();
395 template<typename _InputIterator>
397 append(_InputIterator __first, _InputIterator __last)
399 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
400 __glibcxx_check_valid_range2(__first, __last, __dist);
402 if (__dist.second >= __dp_sign)
403 _Base::append(__gnu_debug::__unsafe(__first),
404 __gnu_debug::__unsafe(__last));
406 _Base::append(__first, __last);
408 this->_M_invalidate_all();
412 // _GLIBCXX_RESOLVE_LIB_DEFECTS
413 // 7. string clause minor problems
415 push_back(_CharT __c)
417 _Base::push_back(__c);
418 this->_M_invalidate_all();
422 assign(const basic_string& __x)
425 this->_M_invalidate_all();
429 #if __cplusplus >= 201103L
431 assign(basic_string&& __x)
432 noexcept(noexcept(std::declval<_Base&>().assign(std::move(__x))))
434 _Base::assign(std::move(__x));
435 this->_M_invalidate_all();
441 assign(const basic_string& __str, size_type __pos, size_type __n)
443 _Base::assign(__str, __pos, __n);
444 this->_M_invalidate_all();
449 assign(const _CharT* __s, size_type __n)
451 __glibcxx_check_string_len(__s, __n);
452 _Base::assign(__s, __n);
453 this->_M_invalidate_all();
458 assign(const _CharT* __s)
460 __glibcxx_check_string(__s);
462 this->_M_invalidate_all();
467 assign(size_type __n, _CharT __c)
469 _Base::assign(__n, __c);
470 this->_M_invalidate_all();
474 template<typename _InputIterator>
476 assign(_InputIterator __first, _InputIterator __last)
478 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
479 __glibcxx_check_valid_range2(__first, __last, __dist);
481 if (__dist.second >= __dp_sign)
482 _Base::assign(__gnu_debug::__unsafe(__first),
483 __gnu_debug::__unsafe(__last));
485 _Base::assign(__first, __last);
487 this->_M_invalidate_all();
491 #if __cplusplus >= 201103L
493 assign(std::initializer_list<_CharT> __l)
496 this->_M_invalidate_all();
502 insert(size_type __pos1, const basic_string& __str)
504 _Base::insert(__pos1, __str);
505 this->_M_invalidate_all();
510 insert(size_type __pos1, const basic_string& __str,
511 size_type __pos2, size_type __n)
513 _Base::insert(__pos1, __str, __pos2, __n);
514 this->_M_invalidate_all();
519 insert(size_type __pos, const _CharT* __s, size_type __n)
521 __glibcxx_check_string(__s);
522 _Base::insert(__pos, __s, __n);
523 this->_M_invalidate_all();
528 insert(size_type __pos, const _CharT* __s)
530 __glibcxx_check_string(__s);
531 _Base::insert(__pos, __s);
532 this->_M_invalidate_all();
537 insert(size_type __pos, size_type __n, _CharT __c)
539 _Base::insert(__pos, __n, __c);
540 this->_M_invalidate_all();
545 insert(iterator __p, _CharT __c)
547 __glibcxx_check_insert(__p);
548 typename _Base::iterator __res = _Base::insert(__p.base(), __c);
549 this->_M_invalidate_all();
550 return iterator(__res, this);
554 insert(iterator __p, size_type __n, _CharT __c)
556 __glibcxx_check_insert(__p);
557 _Base::insert(__p.base(), __n, __c);
558 this->_M_invalidate_all();
561 template<typename _InputIterator>
563 insert(iterator __p, _InputIterator __first, _InputIterator __last)
565 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
566 __glibcxx_check_insert_range2(__p, __first, __last, __dist);
568 if (__dist.second >= __dp_sign)
569 _Base::insert(__p.base(), __gnu_debug::__unsafe(__first),
570 __gnu_debug::__unsafe(__last));
572 _Base::insert(__p.base(), __first, __last);
574 this->_M_invalidate_all();
577 #if __cplusplus >= 201103L
579 insert(iterator __p, std::initializer_list<_CharT> __l)
581 __glibcxx_check_insert(__p);
582 _Base::insert(__p.base(), __l);
583 this->_M_invalidate_all();
588 erase(size_type __pos = 0, size_type __n = _Base::npos)
590 _Base::erase(__pos, __n);
591 this->_M_invalidate_all();
596 erase(iterator __position)
598 __glibcxx_check_erase(__position);
599 typename _Base::iterator __res = _Base::erase(__position.base());
600 this->_M_invalidate_all();
601 return iterator(__res, this);
605 erase(iterator __first, iterator __last)
607 // _GLIBCXX_RESOLVE_LIB_DEFECTS
608 // 151. can't currently clear() empty container
609 __glibcxx_check_erase_range(__first, __last);
610 typename _Base::iterator __res = _Base::erase(__first.base(),
612 this->_M_invalidate_all();
613 return iterator(__res, this);
616 #if __cplusplus >= 201103L
618 pop_back() // noexcept
620 __glibcxx_check_nonempty();
622 this->_M_invalidate_all();
627 replace(size_type __pos1, size_type __n1, const basic_string& __str)
629 _Base::replace(__pos1, __n1, __str);
630 this->_M_invalidate_all();
635 replace(size_type __pos1, size_type __n1, const basic_string& __str,
636 size_type __pos2, size_type __n2)
638 _Base::replace(__pos1, __n1, __str, __pos2, __n2);
639 this->_M_invalidate_all();
644 replace(size_type __pos, size_type __n1, const _CharT* __s,
647 __glibcxx_check_string_len(__s, __n2);
648 _Base::replace(__pos, __n1, __s, __n2);
649 this->_M_invalidate_all();
654 replace(size_type __pos, size_type __n1, const _CharT* __s)
656 __glibcxx_check_string(__s);
657 _Base::replace(__pos, __n1, __s);
658 this->_M_invalidate_all();
663 replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
665 _Base::replace(__pos, __n1, __n2, __c);
666 this->_M_invalidate_all();
671 replace(iterator __i1, iterator __i2, const basic_string& __str)
673 __glibcxx_check_erase_range(__i1, __i2);
674 _Base::replace(__i1.base(), __i2.base(), __str);
675 this->_M_invalidate_all();
680 replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n)
682 __glibcxx_check_erase_range(__i1, __i2);
683 __glibcxx_check_string_len(__s, __n);
684 _Base::replace(__i1.base(), __i2.base(), __s, __n);
685 this->_M_invalidate_all();
690 replace(iterator __i1, iterator __i2, const _CharT* __s)
692 __glibcxx_check_erase_range(__i1, __i2);
693 __glibcxx_check_string(__s);
694 _Base::replace(__i1.base(), __i2.base(), __s);
695 this->_M_invalidate_all();
700 replace(iterator __i1, iterator __i2, size_type __n, _CharT __c)
702 __glibcxx_check_erase_range(__i1, __i2);
703 _Base::replace(__i1.base(), __i2.base(), __n, __c);
704 this->_M_invalidate_all();
708 template<typename _InputIterator>
710 replace(iterator __i1, iterator __i2,
711 _InputIterator __j1, _InputIterator __j2)
713 __glibcxx_check_erase_range(__i1, __i2);
715 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
716 __glibcxx_check_valid_range2(__j1, __j2, __dist);
718 if (__dist.second >= __dp_sign)
719 _Base::replace(__i1.base(), __i2.base(),
720 __gnu_debug::__unsafe(__j1),
721 __gnu_debug::__unsafe(__j2));
723 _Base::replace(__i1.base(), __i2.base(), __j1, __j2);
725 this->_M_invalidate_all();
729 #if __cplusplus >= 201103L
730 basic_string& replace(iterator __i1, iterator __i2,
731 std::initializer_list<_CharT> __l)
733 __glibcxx_check_erase_range(__i1, __i2);
734 _Base::replace(__i1.base(), __i2.base(), __l);
735 this->_M_invalidate_all();
741 copy(_CharT* __s, size_type __n, size_type __pos = 0) const
743 __glibcxx_check_string_len(__s, __n);
744 return _Base::copy(__s, __n, __pos);
748 swap(basic_string& __x)
749 _GLIBCXX_NOEXCEPT_IF(std::__is_nothrow_swappable<_Base>::value)
755 // 21.3.6 string operations:
757 c_str() const _GLIBCXX_NOEXCEPT
759 const _CharT* __res = _Base::c_str();
760 this->_M_invalidate_all();
765 data() const _GLIBCXX_NOEXCEPT
767 const _CharT* __res = _Base::data();
768 this->_M_invalidate_all();
772 using _Base::get_allocator;
775 find(const basic_string& __str, size_type __pos = 0) const
777 { return _Base::find(__str, __pos); }
780 find(const _CharT* __s, size_type __pos, size_type __n) const
782 __glibcxx_check_string(__s);
783 return _Base::find(__s, __pos, __n);
787 find(const _CharT* __s, size_type __pos = 0) const
789 __glibcxx_check_string(__s);
790 return _Base::find(__s, __pos);
794 find(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
795 { return _Base::find(__c, __pos); }
798 rfind(const basic_string& __str, size_type __pos = _Base::npos) const
800 { return _Base::rfind(__str, __pos); }
803 rfind(const _CharT* __s, size_type __pos, size_type __n) const
805 __glibcxx_check_string_len(__s, __n);
806 return _Base::rfind(__s, __pos, __n);
810 rfind(const _CharT* __s, size_type __pos = _Base::npos) const
812 __glibcxx_check_string(__s);
813 return _Base::rfind(__s, __pos);
817 rfind(_CharT __c, size_type __pos = _Base::npos) const _GLIBCXX_NOEXCEPT
818 { return _Base::rfind(__c, __pos); }
821 find_first_of(const basic_string& __str, size_type __pos = 0) const
823 { return _Base::find_first_of(__str, __pos); }
826 find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
828 __glibcxx_check_string(__s);
829 return _Base::find_first_of(__s, __pos, __n);
833 find_first_of(const _CharT* __s, size_type __pos = 0) const
835 __glibcxx_check_string(__s);
836 return _Base::find_first_of(__s, __pos);
840 find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
841 { return _Base::find_first_of(__c, __pos); }
844 find_last_of(const basic_string& __str,
845 size_type __pos = _Base::npos) const _GLIBCXX_NOEXCEPT
846 { return _Base::find_last_of(__str, __pos); }
849 find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
851 __glibcxx_check_string(__s);
852 return _Base::find_last_of(__s, __pos, __n);
856 find_last_of(const _CharT* __s, size_type __pos = _Base::npos) const
858 __glibcxx_check_string(__s);
859 return _Base::find_last_of(__s, __pos);
863 find_last_of(_CharT __c, size_type __pos = _Base::npos) const
865 { return _Base::find_last_of(__c, __pos); }
868 find_first_not_of(const basic_string& __str, size_type __pos = 0) const
870 { return _Base::find_first_not_of(__str, __pos); }
873 find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
875 __glibcxx_check_string_len(__s, __n);
876 return _Base::find_first_not_of(__s, __pos, __n);
880 find_first_not_of(const _CharT* __s, size_type __pos = 0) const
882 __glibcxx_check_string(__s);
883 return _Base::find_first_not_of(__s, __pos);
887 find_first_not_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
888 { return _Base::find_first_not_of(__c, __pos); }
891 find_last_not_of(const basic_string& __str,
892 size_type __pos = _Base::npos) const
894 { return _Base::find_last_not_of(__str, __pos); }
897 find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
899 __glibcxx_check_string(__s);
900 return _Base::find_last_not_of(__s, __pos, __n);
904 find_last_not_of(const _CharT* __s, size_type __pos = _Base::npos) const
906 __glibcxx_check_string(__s);
907 return _Base::find_last_not_of(__s, __pos);
911 find_last_not_of(_CharT __c, size_type __pos = _Base::npos) const
913 { return _Base::find_last_not_of(__c, __pos); }
916 substr(size_type __pos = 0, size_type __n = _Base::npos) const
917 { return basic_string(_Base::substr(__pos, __n)); }
920 compare(const basic_string& __str) const
921 { return _Base::compare(__str); }
924 compare(size_type __pos1, size_type __n1,
925 const basic_string& __str) const
926 { return _Base::compare(__pos1, __n1, __str); }
929 compare(size_type __pos1, size_type __n1, const basic_string& __str,
930 size_type __pos2, size_type __n2) const
931 { return _Base::compare(__pos1, __n1, __str, __pos2, __n2); }
934 compare(const _CharT* __s) const
936 __glibcxx_check_string(__s);
937 return _Base::compare(__s);
940 // _GLIBCXX_RESOLVE_LIB_DEFECTS
941 // 5. string::compare specification questionable
943 compare(size_type __pos1, size_type __n1, const _CharT* __s) const
945 __glibcxx_check_string(__s);
946 return _Base::compare(__pos1, __n1, __s);
949 // _GLIBCXX_RESOLVE_LIB_DEFECTS
950 // 5. string::compare specification questionable
952 compare(size_type __pos1, size_type __n1,const _CharT* __s,
953 size_type __n2) const
955 __glibcxx_check_string_len(__s, __n2);
956 return _Base::compare(__pos1, __n1, __s, __n2);
960 _M_base() _GLIBCXX_NOEXCEPT { return *this; }
963 _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
965 using _Safe::_M_invalidate_all;
968 template<typename _CharT, typename _Traits, typename _Allocator>
969 inline basic_string<_CharT,_Traits,_Allocator>
970 operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
971 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
972 { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
974 template<typename _CharT, typename _Traits, typename _Allocator>
975 inline basic_string<_CharT,_Traits,_Allocator>
976 operator+(const _CharT* __lhs,
977 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
979 __glibcxx_check_string(__lhs);
980 return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
983 template<typename _CharT, typename _Traits, typename _Allocator>
984 inline basic_string<_CharT,_Traits,_Allocator>
985 operator+(_CharT __lhs,
986 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
987 { return basic_string<_CharT,_Traits,_Allocator>(1, __lhs) += __rhs; }
989 template<typename _CharT, typename _Traits, typename _Allocator>
990 inline basic_string<_CharT,_Traits,_Allocator>
991 operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
994 __glibcxx_check_string(__rhs);
995 return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
998 template<typename _CharT, typename _Traits, typename _Allocator>
999 inline basic_string<_CharT,_Traits,_Allocator>
1000 operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1002 { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
1004 template<typename _CharT, typename _Traits, typename _Allocator>
1006 operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1007 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1008 { return __lhs._M_base() == __rhs._M_base(); }
1010 template<typename _CharT, typename _Traits, typename _Allocator>
1012 operator==(const _CharT* __lhs,
1013 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1015 __glibcxx_check_string(__lhs);
1016 return __lhs == __rhs._M_base();
1019 template<typename _CharT, typename _Traits, typename _Allocator>
1021 operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1022 const _CharT* __rhs)
1024 __glibcxx_check_string(__rhs);
1025 return __lhs._M_base() == __rhs;
1028 template<typename _CharT, typename _Traits, typename _Allocator>
1030 operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1031 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1032 { return __lhs._M_base() != __rhs._M_base(); }
1034 template<typename _CharT, typename _Traits, typename _Allocator>
1036 operator!=(const _CharT* __lhs,
1037 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1039 __glibcxx_check_string(__lhs);
1040 return __lhs != __rhs._M_base();
1043 template<typename _CharT, typename _Traits, typename _Allocator>
1045 operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1046 const _CharT* __rhs)
1048 __glibcxx_check_string(__rhs);
1049 return __lhs._M_base() != __rhs;
1052 template<typename _CharT, typename _Traits, typename _Allocator>
1054 operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1055 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1056 { return __lhs._M_base() < __rhs._M_base(); }
1058 template<typename _CharT, typename _Traits, typename _Allocator>
1060 operator<(const _CharT* __lhs,
1061 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1063 __glibcxx_check_string(__lhs);
1064 return __lhs < __rhs._M_base();
1067 template<typename _CharT, typename _Traits, typename _Allocator>
1069 operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1070 const _CharT* __rhs)
1072 __glibcxx_check_string(__rhs);
1073 return __lhs._M_base() < __rhs;
1076 template<typename _CharT, typename _Traits, typename _Allocator>
1078 operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1079 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1080 { return __lhs._M_base() <= __rhs._M_base(); }
1082 template<typename _CharT, typename _Traits, typename _Allocator>
1084 operator<=(const _CharT* __lhs,
1085 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1087 __glibcxx_check_string(__lhs);
1088 return __lhs <= __rhs._M_base();
1091 template<typename _CharT, typename _Traits, typename _Allocator>
1093 operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1094 const _CharT* __rhs)
1096 __glibcxx_check_string(__rhs);
1097 return __lhs._M_base() <= __rhs;
1100 template<typename _CharT, typename _Traits, typename _Allocator>
1102 operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1103 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1104 { return __lhs._M_base() >= __rhs._M_base(); }
1106 template<typename _CharT, typename _Traits, typename _Allocator>
1108 operator>=(const _CharT* __lhs,
1109 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1111 __glibcxx_check_string(__lhs);
1112 return __lhs >= __rhs._M_base();
1115 template<typename _CharT, typename _Traits, typename _Allocator>
1117 operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1118 const _CharT* __rhs)
1120 __glibcxx_check_string(__rhs);
1121 return __lhs._M_base() >= __rhs;
1124 template<typename _CharT, typename _Traits, typename _Allocator>
1126 operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1127 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1128 { return __lhs._M_base() > __rhs._M_base(); }
1130 template<typename _CharT, typename _Traits, typename _Allocator>
1132 operator>(const _CharT* __lhs,
1133 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1135 __glibcxx_check_string(__lhs);
1136 return __lhs > __rhs._M_base();
1139 template<typename _CharT, typename _Traits, typename _Allocator>
1141 operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1142 const _CharT* __rhs)
1144 __glibcxx_check_string(__rhs);
1145 return __lhs._M_base() > __rhs;
1149 template<typename _CharT, typename _Traits, typename _Allocator>
1151 swap(basic_string<_CharT,_Traits,_Allocator>& __lhs,
1152 basic_string<_CharT,_Traits,_Allocator>& __rhs)
1153 { __lhs.swap(__rhs); }
1155 template<typename _CharT, typename _Traits, typename _Allocator>
1156 std::basic_ostream<_CharT, _Traits>&
1157 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1158 const basic_string<_CharT, _Traits, _Allocator>& __str)
1159 { return __os << __str._M_base(); }
1161 template<typename _CharT, typename _Traits, typename _Allocator>
1162 std::basic_istream<_CharT,_Traits>&
1163 operator>>(std::basic_istream<_CharT,_Traits>& __is,
1164 basic_string<_CharT,_Traits,_Allocator>& __str)
1166 std::basic_istream<_CharT,_Traits>& __res = __is >> __str._M_base();
1167 __str._M_invalidate_all();
1171 template<typename _CharT, typename _Traits, typename _Allocator>
1172 std::basic_istream<_CharT,_Traits>&
1173 getline(std::basic_istream<_CharT,_Traits>& __is,
1174 basic_string<_CharT,_Traits,_Allocator>& __str, _CharT __delim)
1176 std::basic_istream<_CharT,_Traits>& __res = getline(__is,
1179 __str._M_invalidate_all();
1183 template<typename _CharT, typename _Traits, typename _Allocator>
1184 std::basic_istream<_CharT,_Traits>&
1185 getline(std::basic_istream<_CharT,_Traits>& __is,
1186 basic_string<_CharT,_Traits,_Allocator>& __str)
1188 std::basic_istream<_CharT,_Traits>& __res = getline(__is,
1190 __str._M_invalidate_all();
1194 typedef basic_string<char> string;
1196 #ifdef _GLIBCXX_USE_WCHAR_T
1197 typedef basic_string<wchar_t> wstring;
1200 template<typename _CharT, typename _Traits, typename _Allocator>
1201 struct _Insert_range_from_self_is_safe<
1202 __gnu_debug::basic_string<_CharT, _Traits, _Allocator> >
1203 { enum { __value = 1 }; };
1205 } // namespace __gnu_debug