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