libstdc++
debug/string
Go to the documentation of this file.
1// Debugging string implementation -*- C++ -*-
2
3// Copyright (C) 2003-2016 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 debug/string
26 * This file is a GNU debug extension to the Standard C++ Library.
27 */
28
29#ifndef _GLIBCXX_DEBUG_STRING
30#define _GLIBCXX_DEBUG_STRING 1
31
32#include <string>
33#include <debug/safe_sequence.h>
34#include <debug/safe_container.h>
35#include <debug/safe_iterator.h>
36
37namespace __gnu_debug
38{
39/// Class std::basic_string with safety/checking/debug instrumentation.
40template<typename _CharT, typename _Traits = std::char_traits<_CharT>,
41 typename _Allocator = std::allocator<_CharT> >
42 class basic_string
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>
47 {
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)>
51 _Safe;
52
53 public:
54 // types:
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;
64
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;
69
70 typedef std::reverse_iterator<iterator> reverse_iterator;
71 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
72
73 using _Base::npos;
74
75 basic_string()
76 _GLIBCXX_NOEXCEPT_IF(std::is_nothrow_default_constructible<_Base>::value)
77 : _Base() { }
78
79 // 21.3.1 construct/copy/destroy:
80 explicit
81 basic_string(const _Allocator& __a) _GLIBCXX_NOEXCEPT
82 : _Base(__a) { }
83
84#if __cplusplus < 201103L
85 basic_string(const basic_string& __str)
86 : _Base(__str) { }
87
88 ~basic_string() { }
89#else
90 basic_string(const basic_string&) = default;
91 basic_string(basic_string&&) = default;
92
93 basic_string(std::initializer_list<_CharT> __l,
94 const _Allocator& __a = _Allocator())
95 : _Base(__l, __a)
96 { }
97
98#if _GLIBCXX_USE_CXX11_ABI
99 basic_string(const basic_string& __s, const _Allocator& __a)
100 : _Base(__s, __a) { }
101
102 basic_string(basic_string&& __s, const _Allocator& __a)
103 : _Base(std::move(__s), __a) { }
104#endif
105
106 ~basic_string() = default;
107
108 // Provides conversion from a normal-mode string to a debug-mode string
109 basic_string(_Base&& __base) noexcept
110 : _Base(std::move(__base)) { }
111#endif // C++11
112
113 // Provides conversion from a normal-mode string to a debug-mode string
114 basic_string(const _Base& __base)
115 : _Base(__base) { }
116
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) { }
123
124 basic_string(const _CharT* __s, size_type __n,
125 const _Allocator& __a = _Allocator())
126 : _Base(__gnu_debug::__check_string(__s, __n), __n, __a) { }
127
128 basic_string(const _CharT* __s, const _Allocator& __a = _Allocator())
129 : _Base(__gnu_debug::__check_string(__s), __a)
130 { this->assign(__s); }
131
132 basic_string(size_type __n, _CharT __c,
133 const _Allocator& __a = _Allocator())
134 : _Base(__n, __c, __a) { }
135
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,
140 __end)),
141 __gnu_debug::__base(__end), __a) { }
142
143#if __cplusplus < 201103L
144 basic_string&
145 operator=(const basic_string& __str)
146 {
147 this->_M_safe() = __str;
148 _M_base() = __str;
149 return *this;
150 }
151#else
152 basic_string&
153 operator=(const basic_string&) = default;
154
155 basic_string&
156 operator=(basic_string&&) = default;
157#endif
158
159 basic_string&
160 operator=(const _CharT* __s)
161 {
162 __glibcxx_check_string(__s);
163 _M_base() = __s;
164 this->_M_invalidate_all();
165 return *this;
166 }
167
168 basic_string&
169 operator=(_CharT __c)
170 {
171 _M_base() = __c;
172 this->_M_invalidate_all();
173 return *this;
174 }
175
176#if __cplusplus >= 201103L
177 basic_string&
178 operator=(std::initializer_list<_CharT> __l)
179 {
180 _M_base() = __l;
181 this->_M_invalidate_all();
182 return *this;
183 }
184#endif // C++11
185
186 // 21.3.2 iterators:
187 iterator
188 begin() // _GLIBCXX_NOEXCEPT
189 { return iterator(_Base::begin(), this); }
190
191 const_iterator
192 begin() const _GLIBCXX_NOEXCEPT
193 { return const_iterator(_Base::begin(), this); }
194
195 iterator
196 end() // _GLIBCXX_NOEXCEPT
197 { return iterator(_Base::end(), this); }
198
199 const_iterator
200 end() const _GLIBCXX_NOEXCEPT
201 { return const_iterator(_Base::end(), this); }
202
203 reverse_iterator
204 rbegin() // _GLIBCXX_NOEXCEPT
205 { return reverse_iterator(end()); }
206
207 const_reverse_iterator
208 rbegin() const _GLIBCXX_NOEXCEPT
209 { return const_reverse_iterator(end()); }
210
211 reverse_iterator
212 rend() // _GLIBCXX_NOEXCEPT
213 { return reverse_iterator(begin()); }
214
215 const_reverse_iterator
216 rend() const _GLIBCXX_NOEXCEPT
217 { return const_reverse_iterator(begin()); }
218
219#if __cplusplus >= 201103L
220 const_iterator
221 cbegin() const noexcept
222 { return const_iterator(_Base::begin(), this); }
223
224 const_iterator
225 cend() const noexcept
226 { return const_iterator(_Base::end(), this); }
227
228 const_reverse_iterator
229 crbegin() const noexcept
230 { return const_reverse_iterator(end()); }
231
232 const_reverse_iterator
233 crend() const noexcept
234 { return const_reverse_iterator(begin()); }
235#endif
236
237 // 21.3.3 capacity:
238 using _Base::size;
239 using _Base::length;
240 using _Base::max_size;
241
242 void
243 resize(size_type __n, _CharT __c)
244 {
245 _Base::resize(__n, __c);
246 this->_M_invalidate_all();
247 }
248
249 void
250 resize(size_type __n)
251 { this->resize(__n, _CharT()); }
252
253#if __cplusplus >= 201103L
254 void
255 shrink_to_fit() noexcept
256 {
257 if (capacity() > size())
258 {
259 __try
260 {
261 reserve(0);
262 this->_M_invalidate_all();
263 }
264 __catch(...)
265 { }
266 }
267 }
268#endif
269
270 using _Base::capacity;
271 using _Base::reserve;
272
273 void
274 clear() // _GLIBCXX_NOEXCEPT
275 {
276 _Base::clear();
277 this->_M_invalidate_all();
278 }
279
280 using _Base::empty;
281
282 // 21.3.4 element access:
283 const_reference
284 operator[](size_type __pos) const _GLIBCXX_NOEXCEPT
285 {
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];
292 }
293
294 reference
295 operator[](size_type __pos) // _GLIBCXX_NOEXCEPT
296 {
297#if __cplusplus < 201103L && defined(_GLIBCXX_DEBUG_PEDANTIC)
298 __glibcxx_check_subscript(__pos);
299#else
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"));
306#endif
307 return _M_base()[__pos];
308 }
309
310 using _Base::at;
311
312#if __cplusplus >= 201103L
313 using _Base::front;
314 using _Base::back;
315#endif
316
317 // 21.3.5 modifiers:
318 basic_string&
319 operator+=(const basic_string& __str)
320 {
321 _M_base() += __str;
322 this->_M_invalidate_all();
323 return *this;
324 }
325
326 basic_string&
327 operator+=(const _CharT* __s)
328 {
329 __glibcxx_check_string(__s);
330 _M_base() += __s;
331 this->_M_invalidate_all();
332 return *this;
333 }
334
335 basic_string&
336 operator+=(_CharT __c)
337 {
338 _M_base() += __c;
339 this->_M_invalidate_all();
340 return *this;
341 }
342
343#if __cplusplus >= 201103L
344 basic_string&
345 operator+=(std::initializer_list<_CharT> __l)
346 {
347 _M_base() += __l;
348 this->_M_invalidate_all();
349 return *this;
350 }
351#endif // C++11
352
353 basic_string&
354 append(const basic_string& __str)
355 {
356 _Base::append(__str);
357 this->_M_invalidate_all();
358 return *this;
359 }
360
361 basic_string&
362 append(const basic_string& __str, size_type __pos, size_type __n)
363 {
364 _Base::append(__str, __pos, __n);
365 this->_M_invalidate_all();
366 return *this;
367 }
368
369 basic_string&
370 append(const _CharT* __s, size_type __n)
371 {
372 __glibcxx_check_string_len(__s, __n);
373 _Base::append(__s, __n);
374 this->_M_invalidate_all();
375 return *this;
376 }
377
378 basic_string&
379 append(const _CharT* __s)
380 {
381 __glibcxx_check_string(__s);
382 _Base::append(__s);
383 this->_M_invalidate_all();
384 return *this;
385 }
386
387 basic_string&
388 append(size_type __n, _CharT __c)
389 {
390 _Base::append(__n, __c);
391 this->_M_invalidate_all();
392 return *this;
393 }
394
395 template<typename _InputIterator>
396 basic_string&
397 append(_InputIterator __first, _InputIterator __last)
398 {
399 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
400 __glibcxx_check_valid_range2(__first, __last, __dist);
401
402 if (__dist.second >= __dp_sign)
403 _Base::append(__gnu_debug::__unsafe(__first),
404 __gnu_debug::__unsafe(__last));
405 else
406 _Base::append(__first, __last);
407
408 this->_M_invalidate_all();
409 return *this;
410 }
411
412 // _GLIBCXX_RESOLVE_LIB_DEFECTS
413 // 7. string clause minor problems
414 void
415 push_back(_CharT __c)
416 {
417 _Base::push_back(__c);
418 this->_M_invalidate_all();
419 }
420
421 basic_string&
422 assign(const basic_string& __x)
423 {
424 _Base::assign(__x);
425 this->_M_invalidate_all();
426 return *this;
427 }
428
429#if __cplusplus >= 201103L
430 basic_string&
431 assign(basic_string&& __x)
432 noexcept(noexcept(std::declval<_Base&>().assign(std::move(__x))))
433 {
434 _Base::assign(std::move(__x));
435 this->_M_invalidate_all();
436 return *this;
437 }
438#endif // C++11
439
440 basic_string&
441 assign(const basic_string& __str, size_type __pos, size_type __n)
442 {
443 _Base::assign(__str, __pos, __n);
444 this->_M_invalidate_all();
445 return *this;
446 }
447
448 basic_string&
449 assign(const _CharT* __s, size_type __n)
450 {
451 __glibcxx_check_string_len(__s, __n);
452 _Base::assign(__s, __n);
453 this->_M_invalidate_all();
454 return *this;
455 }
456
457 basic_string&
458 assign(const _CharT* __s)
459 {
460 __glibcxx_check_string(__s);
461 _Base::assign(__s);
462 this->_M_invalidate_all();
463 return *this;
464 }
465
466 basic_string&
467 assign(size_type __n, _CharT __c)
468 {
469 _Base::assign(__n, __c);
470 this->_M_invalidate_all();
471 return *this;
472 }
473
474 template<typename _InputIterator>
475 basic_string&
476 assign(_InputIterator __first, _InputIterator __last)
477 {
478 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
479 __glibcxx_check_valid_range2(__first, __last, __dist);
480
481 if (__dist.second >= __dp_sign)
482 _Base::assign(__gnu_debug::__unsafe(__first),
483 __gnu_debug::__unsafe(__last));
484 else
485 _Base::assign(__first, __last);
486
487 this->_M_invalidate_all();
488 return *this;
489 }
490
491#if __cplusplus >= 201103L
492 basic_string&
493 assign(std::initializer_list<_CharT> __l)
494 {
495 _Base::assign(__l);
496 this->_M_invalidate_all();
497 return *this;
498 }
499#endif // C++11
500
501 basic_string&
502 insert(size_type __pos1, const basic_string& __str)
503 {
504 _Base::insert(__pos1, __str);
505 this->_M_invalidate_all();
506 return *this;
507 }
508
509 basic_string&
510 insert(size_type __pos1, const basic_string& __str,
511 size_type __pos2, size_type __n)
512 {
513 _Base::insert(__pos1, __str, __pos2, __n);
514 this->_M_invalidate_all();
515 return *this;
516 }
517
518 basic_string&
519 insert(size_type __pos, const _CharT* __s, size_type __n)
520 {
521 __glibcxx_check_string(__s);
522 _Base::insert(__pos, __s, __n);
523 this->_M_invalidate_all();
524 return *this;
525 }
526
527 basic_string&
528 insert(size_type __pos, const _CharT* __s)
529 {
530 __glibcxx_check_string(__s);
531 _Base::insert(__pos, __s);
532 this->_M_invalidate_all();
533 return *this;
534 }
535
536 basic_string&
537 insert(size_type __pos, size_type __n, _CharT __c)
538 {
539 _Base::insert(__pos, __n, __c);
540 this->_M_invalidate_all();
541 return *this;
542 }
543
544 iterator
545 insert(iterator __p, _CharT __c)
546 {
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);
551 }
552
553 void
554 insert(iterator __p, size_type __n, _CharT __c)
555 {
556 __glibcxx_check_insert(__p);
557 _Base::insert(__p.base(), __n, __c);
558 this->_M_invalidate_all();
559 }
560
561 template<typename _InputIterator>
562 void
563 insert(iterator __p, _InputIterator __first, _InputIterator __last)
564 {
565 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
566 __glibcxx_check_insert_range(__p, __first, __last, __dist);
567
568 if (__dist.second >= __dp_sign)
569 _Base::insert(__p.base(), __gnu_debug::__unsafe(__first),
570 __gnu_debug::__unsafe(__last));
571 else
572 _Base::insert(__p.base(), __first, __last);
573
574 this->_M_invalidate_all();
575 }
576
577#if __cplusplus >= 201103L
578 void
579 insert(iterator __p, std::initializer_list<_CharT> __l)
580 {
581 __glibcxx_check_insert(__p);
582 _Base::insert(__p.base(), __l);
583 this->_M_invalidate_all();
584 }
585#endif // C++11
586
587 basic_string&
588 erase(size_type __pos = 0, size_type __n = _Base::npos)
589 {
590 _Base::erase(__pos, __n);
591 this->_M_invalidate_all();
592 return *this;
593 }
594
595 iterator
596 erase(iterator __position)
597 {
598 __glibcxx_check_erase(__position);
599 typename _Base::iterator __res = _Base::erase(__position.base());
600 this->_M_invalidate_all();
601 return iterator(__res, this);
602 }
603
604 iterator
605 erase(iterator __first, iterator __last)
606 {
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(),
611 __last.base());
612 this->_M_invalidate_all();
613 return iterator(__res, this);
614 }
615
616#if __cplusplus >= 201103L
617 void
618 pop_back() // noexcept
619 {
620 __glibcxx_check_nonempty();
621 _Base::pop_back();
622 this->_M_invalidate_all();
623 }
624#endif // C++11
625
626 basic_string&
627 replace(size_type __pos1, size_type __n1, const basic_string& __str)
628 {
629 _Base::replace(__pos1, __n1, __str);
630 this->_M_invalidate_all();
631 return *this;
632 }
633
634 basic_string&
635 replace(size_type __pos1, size_type __n1, const basic_string& __str,
636 size_type __pos2, size_type __n2)
637 {
638 _Base::replace(__pos1, __n1, __str, __pos2, __n2);
639 this->_M_invalidate_all();
640 return *this;
641 }
642
643 basic_string&
644 replace(size_type __pos, size_type __n1, const _CharT* __s,
645 size_type __n2)
646 {
647 __glibcxx_check_string_len(__s, __n2);
648 _Base::replace(__pos, __n1, __s, __n2);
649 this->_M_invalidate_all();
650 return *this;
651 }
652
653 basic_string&
654 replace(size_type __pos, size_type __n1, const _CharT* __s)
655 {
656 __glibcxx_check_string(__s);
657 _Base::replace(__pos, __n1, __s);
658 this->_M_invalidate_all();
659 return *this;
660 }
661
662 basic_string&
663 replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
664 {
665 _Base::replace(__pos, __n1, __n2, __c);
666 this->_M_invalidate_all();
667 return *this;
668 }
669
670 basic_string&
671 replace(iterator __i1, iterator __i2, const basic_string& __str)
672 {
673 __glibcxx_check_erase_range(__i1, __i2);
674 _Base::replace(__i1.base(), __i2.base(), __str);
675 this->_M_invalidate_all();
676 return *this;
677 }
678
679 basic_string&
680 replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n)
681 {
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();
686 return *this;
687 }
688
689 basic_string&
690 replace(iterator __i1, iterator __i2, const _CharT* __s)
691 {
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();
696 return *this;
697 }
698
699 basic_string&
700 replace(iterator __i1, iterator __i2, size_type __n, _CharT __c)
701 {
702 __glibcxx_check_erase_range(__i1, __i2);
703 _Base::replace(__i1.base(), __i2.base(), __n, __c);
704 this->_M_invalidate_all();
705 return *this;
706 }
707
708 template<typename _InputIterator>
709 basic_string&
710 replace(iterator __i1, iterator __i2,
711 _InputIterator __j1, _InputIterator __j2)
712 {
713 __glibcxx_check_erase_range(__i1, __i2);
714
715 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
716 __glibcxx_check_valid_range2(__j1, __j2, __dist);
717
718 if (__dist.second >= __dp_sign)
719 _Base::replace(__i1.base(), __i2.base(),
720 __gnu_debug::__unsafe(__j1),
721 __gnu_debug::__unsafe(__j2));
722 else
723 _Base::replace(__i1.base(), __i2.base(), __j1, __j2);
724
725 this->_M_invalidate_all();
726 return *this;
727 }
728
729#if __cplusplus >= 201103L
730 basic_string& replace(iterator __i1, iterator __i2,
731 std::initializer_list<_CharT> __l)
732 {
733 __glibcxx_check_erase_range(__i1, __i2);
734 _Base::replace(__i1.base(), __i2.base(), __l);
735 this->_M_invalidate_all();
736 return *this;
737 }
738#endif // C++11
739
740 size_type
741 copy(_CharT* __s, size_type __n, size_type __pos = 0) const
742 {
743 __glibcxx_check_string_len(__s, __n);
744 return _Base::copy(__s, __n, __pos);
745 }
746
747 void
748 swap(basic_string& __x)
749 _GLIBCXX_NOEXCEPT_IF(std::__is_nothrow_swappable<_Base>::value)
750 {
751 _Safe::_M_swap(__x);
752 _Base::swap(__x);
753 }
754
755 // 21.3.6 string operations:
756 const _CharT*
757 c_str() const _GLIBCXX_NOEXCEPT
758 {
759 const _CharT* __res = _Base::c_str();
760 this->_M_invalidate_all();
761 return __res;
762 }
763
764 const _CharT*
765 data() const _GLIBCXX_NOEXCEPT
766 {
767 const _CharT* __res = _Base::data();
768 this->_M_invalidate_all();
769 return __res;
770 }
771
772 using _Base::get_allocator;
773
774 size_type
775 find(const basic_string& __str, size_type __pos = 0) const
776 _GLIBCXX_NOEXCEPT
777 { return _Base::find(__str, __pos); }
778
779 size_type
780 find(const _CharT* __s, size_type __pos, size_type __n) const
781 {
782 __glibcxx_check_string(__s);
783 return _Base::find(__s, __pos, __n);
784 }
785
786 size_type
787 find(const _CharT* __s, size_type __pos = 0) const
788 {
789 __glibcxx_check_string(__s);
790 return _Base::find(__s, __pos);
791 }
792
793 size_type
794 find(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
795 { return _Base::find(__c, __pos); }
796
797 size_type
798 rfind(const basic_string& __str, size_type __pos = _Base::npos) const
799 _GLIBCXX_NOEXCEPT
800 { return _Base::rfind(__str, __pos); }
801
802 size_type
803 rfind(const _CharT* __s, size_type __pos, size_type __n) const
804 {
805 __glibcxx_check_string_len(__s, __n);
806 return _Base::rfind(__s, __pos, __n);
807 }
808
809 size_type
810 rfind(const _CharT* __s, size_type __pos = _Base::npos) const
811 {
812 __glibcxx_check_string(__s);
813 return _Base::rfind(__s, __pos);
814 }
815
816 size_type
817 rfind(_CharT __c, size_type __pos = _Base::npos) const _GLIBCXX_NOEXCEPT
818 { return _Base::rfind(__c, __pos); }
819
820 size_type
821 find_first_of(const basic_string& __str, size_type __pos = 0) const
822 _GLIBCXX_NOEXCEPT
823 { return _Base::find_first_of(__str, __pos); }
824
825 size_type
826 find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
827 {
828 __glibcxx_check_string(__s);
829 return _Base::find_first_of(__s, __pos, __n);
830 }
831
832 size_type
833 find_first_of(const _CharT* __s, size_type __pos = 0) const
834 {
835 __glibcxx_check_string(__s);
836 return _Base::find_first_of(__s, __pos);
837 }
838
839 size_type
840 find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
841 { return _Base::find_first_of(__c, __pos); }
842
843 size_type
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); }
847
848 size_type
849 find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
850 {
851 __glibcxx_check_string(__s);
852 return _Base::find_last_of(__s, __pos, __n);
853 }
854
855 size_type
856 find_last_of(const _CharT* __s, size_type __pos = _Base::npos) const
857 {
858 __glibcxx_check_string(__s);
859 return _Base::find_last_of(__s, __pos);
860 }
861
862 size_type
863 find_last_of(_CharT __c, size_type __pos = _Base::npos) const
864 _GLIBCXX_NOEXCEPT
865 { return _Base::find_last_of(__c, __pos); }
866
867 size_type
868 find_first_not_of(const basic_string& __str, size_type __pos = 0) const
869 _GLIBCXX_NOEXCEPT
870 { return _Base::find_first_not_of(__str, __pos); }
871
872 size_type
873 find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
874 {
875 __glibcxx_check_string_len(__s, __n);
876 return _Base::find_first_not_of(__s, __pos, __n);
877 }
878
879 size_type
880 find_first_not_of(const _CharT* __s, size_type __pos = 0) const
881 {
882 __glibcxx_check_string(__s);
883 return _Base::find_first_not_of(__s, __pos);
884 }
885
886 size_type
887 find_first_not_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
888 { return _Base::find_first_not_of(__c, __pos); }
889
890 size_type
891 find_last_not_of(const basic_string& __str,
892 size_type __pos = _Base::npos) const
893 _GLIBCXX_NOEXCEPT
894 { return _Base::find_last_not_of(__str, __pos); }
895
896 size_type
897 find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
898 {
899 __glibcxx_check_string(__s);
900 return _Base::find_last_not_of(__s, __pos, __n);
901 }
902
903 size_type
904 find_last_not_of(const _CharT* __s, size_type __pos = _Base::npos) const
905 {
906 __glibcxx_check_string(__s);
907 return _Base::find_last_not_of(__s, __pos);
908 }
909
910 size_type
911 find_last_not_of(_CharT __c, size_type __pos = _Base::npos) const
912 _GLIBCXX_NOEXCEPT
913 { return _Base::find_last_not_of(__c, __pos); }
914
915 basic_string
916 substr(size_type __pos = 0, size_type __n = _Base::npos) const
917 { return basic_string(_Base::substr(__pos, __n)); }
918
919 int
920 compare(const basic_string& __str) const
921 { return _Base::compare(__str); }
922
923 int
924 compare(size_type __pos1, size_type __n1,
925 const basic_string& __str) const
926 { return _Base::compare(__pos1, __n1, __str); }
927
928 int
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); }
932
933 int
934 compare(const _CharT* __s) const
935 {
936 __glibcxx_check_string(__s);
937 return _Base::compare(__s);
938 }
939
940 // _GLIBCXX_RESOLVE_LIB_DEFECTS
941 // 5. string::compare specification questionable
942 int
943 compare(size_type __pos1, size_type __n1, const _CharT* __s) const
944 {
945 __glibcxx_check_string(__s);
946 return _Base::compare(__pos1, __n1, __s);
947 }
948
949 // _GLIBCXX_RESOLVE_LIB_DEFECTS
950 // 5. string::compare specification questionable
951 int
952 compare(size_type __pos1, size_type __n1,const _CharT* __s,
953 size_type __n2) const
954 {
955 __glibcxx_check_string_len(__s, __n2);
956 return _Base::compare(__pos1, __n1, __s, __n2);
957 }
958
959 _Base&
960 _M_base() _GLIBCXX_NOEXCEPT { return *this; }
961
962 const _Base&
963 _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
964
965 using _Safe::_M_invalidate_all;
966 };
967
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; }
973
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)
978 {
979 __glibcxx_check_string(__lhs);
980 return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
981 }
982
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; }
988
989 template<typename _CharT, typename _Traits, typename _Allocator>
990 inline basic_string<_CharT,_Traits,_Allocator>
991 operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
992 const _CharT* __rhs)
993 {
994 __glibcxx_check_string(__rhs);
995 return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
996 }
997
998 template<typename _CharT, typename _Traits, typename _Allocator>
999 inline basic_string<_CharT,_Traits,_Allocator>
1000 operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1001 _CharT __rhs)
1002 { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
1003
1004 template<typename _CharT, typename _Traits, typename _Allocator>
1005 inline bool
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(); }
1009
1010 template<typename _CharT, typename _Traits, typename _Allocator>
1011 inline bool
1012 operator==(const _CharT* __lhs,
1013 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1014 {
1015 __glibcxx_check_string(__lhs);
1016 return __lhs == __rhs._M_base();
1017 }
1018
1019 template<typename _CharT, typename _Traits, typename _Allocator>
1020 inline bool
1021 operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1022 const _CharT* __rhs)
1023 {
1024 __glibcxx_check_string(__rhs);
1025 return __lhs._M_base() == __rhs;
1026 }
1027
1028 template<typename _CharT, typename _Traits, typename _Allocator>
1029 inline bool
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(); }
1033
1034 template<typename _CharT, typename _Traits, typename _Allocator>
1035 inline bool
1036 operator!=(const _CharT* __lhs,
1037 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1038 {
1039 __glibcxx_check_string(__lhs);
1040 return __lhs != __rhs._M_base();
1041 }
1042
1043 template<typename _CharT, typename _Traits, typename _Allocator>
1044 inline bool
1045 operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1046 const _CharT* __rhs)
1047 {
1048 __glibcxx_check_string(__rhs);
1049 return __lhs._M_base() != __rhs;
1050 }
1051
1052 template<typename _CharT, typename _Traits, typename _Allocator>
1053 inline bool
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(); }
1057
1058 template<typename _CharT, typename _Traits, typename _Allocator>
1059 inline bool
1060 operator<(const _CharT* __lhs,
1061 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1062 {
1063 __glibcxx_check_string(__lhs);
1064 return __lhs < __rhs._M_base();
1065 }
1066
1067 template<typename _CharT, typename _Traits, typename _Allocator>
1068 inline bool
1069 operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1070 const _CharT* __rhs)
1071 {
1072 __glibcxx_check_string(__rhs);
1073 return __lhs._M_base() < __rhs;
1074 }
1075
1076 template<typename _CharT, typename _Traits, typename _Allocator>
1077 inline bool
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(); }
1081
1082 template<typename _CharT, typename _Traits, typename _Allocator>
1083 inline bool
1084 operator<=(const _CharT* __lhs,
1085 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1086 {
1087 __glibcxx_check_string(__lhs);
1088 return __lhs <= __rhs._M_base();
1089 }
1090
1091 template<typename _CharT, typename _Traits, typename _Allocator>
1092 inline bool
1093 operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1094 const _CharT* __rhs)
1095 {
1096 __glibcxx_check_string(__rhs);
1097 return __lhs._M_base() <= __rhs;
1098 }
1099
1100 template<typename _CharT, typename _Traits, typename _Allocator>
1101 inline bool
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(); }
1105
1106 template<typename _CharT, typename _Traits, typename _Allocator>
1107 inline bool
1108 operator>=(const _CharT* __lhs,
1109 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1110 {
1111 __glibcxx_check_string(__lhs);
1112 return __lhs >= __rhs._M_base();
1113 }
1114
1115 template<typename _CharT, typename _Traits, typename _Allocator>
1116 inline bool
1117 operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1118 const _CharT* __rhs)
1119 {
1120 __glibcxx_check_string(__rhs);
1121 return __lhs._M_base() >= __rhs;
1122 }
1123
1124 template<typename _CharT, typename _Traits, typename _Allocator>
1125 inline bool
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(); }
1129
1130 template<typename _CharT, typename _Traits, typename _Allocator>
1131 inline bool
1132 operator>(const _CharT* __lhs,
1133 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1134 {
1135 __glibcxx_check_string(__lhs);
1136 return __lhs > __rhs._M_base();
1137 }
1138
1139 template<typename _CharT, typename _Traits, typename _Allocator>
1140 inline bool
1141 operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1142 const _CharT* __rhs)
1143 {
1144 __glibcxx_check_string(__rhs);
1145 return __lhs._M_base() > __rhs;
1146 }
1147
1148 // 21.3.7.8:
1149 template<typename _CharT, typename _Traits, typename _Allocator>
1150 inline void
1151 swap(basic_string<_CharT,_Traits,_Allocator>& __lhs,
1152 basic_string<_CharT,_Traits,_Allocator>& __rhs)
1153 { __lhs.swap(__rhs); }
1154
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(); }
1160
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)
1165 {
1166 std::basic_istream<_CharT,_Traits>& __res = __is >> __str._M_base();
1167 __str._M_invalidate_all();
1168 return __res;
1169 }
1170
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)
1175 {
1176 std::basic_istream<_CharT,_Traits>& __res = getline(__is,
1177 __str._M_base(),
1178 __delim);
1179 __str._M_invalidate_all();
1180 return __res;
1181 }
1182
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)
1187 {
1188 std::basic_istream<_CharT,_Traits>& __res = getline(__is,
1189 __str._M_base());
1190 __str._M_invalidate_all();
1191 return __res;
1192 }
1193
1194 typedef basic_string<char> string;
1195
1196#ifdef _GLIBCXX_USE_WCHAR_T
1197 typedef basic_string<wchar_t> wstring;
1198#endif
1199
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 }; };
1204
1205} // namespace __gnu_debug
1206
1207#endif