libstdc++
debug/string
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