libstdc++

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