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 
37 namespace __gnu_debug
38 {
39 /// Class std::basic_string with safety/checking/debug instrumentation.
40 template<typename _CharT, typename _Traits = std::char_traits<_CharT>,
41  typename _Allocator = std::allocator<_CharT> >
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_range2(__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