libstdc++
debug/string
Go to the documentation of this file.
1 // Debugging string implementation -*- C++ -*-
2 
3 // Copyright (C) 2003-2015 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 #if __cplusplus >= 201103L
77  noexcept(std::is_nothrow_default_constructible<_Base>::value)
78 #endif
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  __glibcxx_check_valid_range(__first, __last);
402  _Base::append(__gnu_debug::__base(__first),
403  __gnu_debug::__base(__last));
404  this->_M_invalidate_all();
405  return *this;
406  }
407 
408  // _GLIBCXX_RESOLVE_LIB_DEFECTS
409  // 7. string clause minor problems
410  void
411  push_back(_CharT __c)
412  {
413  _Base::push_back(__c);
414  this->_M_invalidate_all();
415  }
416 
417  basic_string&
418  assign(const basic_string& __x)
419  {
420  _Base::assign(__x);
421  this->_M_invalidate_all();
422  return *this;
423  }
424 
425 #if __cplusplus >= 201103L
426  basic_string&
427  assign(basic_string&& __x)
428  noexcept(noexcept(std::declval<_Base&>().assign(std::move(__x))))
429  {
430  _Base::assign(std::move(__x));
431  this->_M_invalidate_all();
432  return *this;
433  }
434 #endif // C++11
435 
436  basic_string&
437  assign(const basic_string& __str, size_type __pos, size_type __n)
438  {
439  _Base::assign(__str, __pos, __n);
440  this->_M_invalidate_all();
441  return *this;
442  }
443 
444  basic_string&
445  assign(const _CharT* __s, size_type __n)
446  {
447  __glibcxx_check_string_len(__s, __n);
448  _Base::assign(__s, __n);
449  this->_M_invalidate_all();
450  return *this;
451  }
452 
453  basic_string&
454  assign(const _CharT* __s)
455  {
456  __glibcxx_check_string(__s);
457  _Base::assign(__s);
458  this->_M_invalidate_all();
459  return *this;
460  }
461 
462  basic_string&
463  assign(size_type __n, _CharT __c)
464  {
465  _Base::assign(__n, __c);
466  this->_M_invalidate_all();
467  return *this;
468  }
469 
470  template<typename _InputIterator>
471  basic_string&
472  assign(_InputIterator __first, _InputIterator __last)
473  {
474  __glibcxx_check_valid_range(__first, __last);
475  _Base::assign(__gnu_debug::__base(__first),
476  __gnu_debug::__base(__last));
477  this->_M_invalidate_all();
478  return *this;
479  }
480 
481 #if __cplusplus >= 201103L
482  basic_string&
483  assign(std::initializer_list<_CharT> __l)
484  {
485  _Base::assign(__l);
486  this->_M_invalidate_all();
487  return *this;
488  }
489 #endif // C++11
490 
491  basic_string&
492  insert(size_type __pos1, const basic_string& __str)
493  {
494  _Base::insert(__pos1, __str);
495  this->_M_invalidate_all();
496  return *this;
497  }
498 
499  basic_string&
500  insert(size_type __pos1, const basic_string& __str,
501  size_type __pos2, size_type __n)
502  {
503  _Base::insert(__pos1, __str, __pos2, __n);
504  this->_M_invalidate_all();
505  return *this;
506  }
507 
508  basic_string&
509  insert(size_type __pos, const _CharT* __s, size_type __n)
510  {
511  __glibcxx_check_string(__s);
512  _Base::insert(__pos, __s, __n);
513  this->_M_invalidate_all();
514  return *this;
515  }
516 
517  basic_string&
518  insert(size_type __pos, const _CharT* __s)
519  {
520  __glibcxx_check_string(__s);
521  _Base::insert(__pos, __s);
522  this->_M_invalidate_all();
523  return *this;
524  }
525 
526  basic_string&
527  insert(size_type __pos, size_type __n, _CharT __c)
528  {
529  _Base::insert(__pos, __n, __c);
530  this->_M_invalidate_all();
531  return *this;
532  }
533 
534  iterator
535  insert(iterator __p, _CharT __c)
536  {
537  __glibcxx_check_insert(__p);
538  typename _Base::iterator __res = _Base::insert(__p.base(), __c);
539  this->_M_invalidate_all();
540  return iterator(__res, this);
541  }
542 
543  void
544  insert(iterator __p, size_type __n, _CharT __c)
545  {
546  __glibcxx_check_insert(__p);
547  _Base::insert(__p.base(), __n, __c);
548  this->_M_invalidate_all();
549  }
550 
551  template<typename _InputIterator>
552  void
553  insert(iterator __p, _InputIterator __first, _InputIterator __last)
554  {
555  __glibcxx_check_insert_range(__p, __first, __last);
556  _Base::insert(__p.base(), __gnu_debug::__base(__first),
557  __gnu_debug::__base(__last));
558  this->_M_invalidate_all();
559  }
560 
561 #if __cplusplus >= 201103L
562  void
563  insert(iterator __p, std::initializer_list<_CharT> __l)
564  {
565  __glibcxx_check_insert(__p);
566  _Base::insert(__p.base(), __l);
567  this->_M_invalidate_all();
568  }
569 #endif // C++11
570 
571  basic_string&
572  erase(size_type __pos = 0, size_type __n = _Base::npos)
573  {
574  _Base::erase(__pos, __n);
575  this->_M_invalidate_all();
576  return *this;
577  }
578 
579  iterator
580  erase(iterator __position)
581  {
582  __glibcxx_check_erase(__position);
583  typename _Base::iterator __res = _Base::erase(__position.base());
584  this->_M_invalidate_all();
585  return iterator(__res, this);
586  }
587 
588  iterator
589  erase(iterator __first, iterator __last)
590  {
591  // _GLIBCXX_RESOLVE_LIB_DEFECTS
592  // 151. can't currently clear() empty container
593  __glibcxx_check_erase_range(__first, __last);
594  typename _Base::iterator __res = _Base::erase(__first.base(),
595  __last.base());
596  this->_M_invalidate_all();
597  return iterator(__res, this);
598  }
599 
600 #if __cplusplus >= 201103L
601  void
602  pop_back() // noexcept
603  {
604  __glibcxx_check_nonempty();
605  _Base::pop_back();
606  this->_M_invalidate_all();
607  }
608 #endif // C++11
609 
610  basic_string&
611  replace(size_type __pos1, size_type __n1, const basic_string& __str)
612  {
613  _Base::replace(__pos1, __n1, __str);
614  this->_M_invalidate_all();
615  return *this;
616  }
617 
618  basic_string&
619  replace(size_type __pos1, size_type __n1, const basic_string& __str,
620  size_type __pos2, size_type __n2)
621  {
622  _Base::replace(__pos1, __n1, __str, __pos2, __n2);
623  this->_M_invalidate_all();
624  return *this;
625  }
626 
627  basic_string&
628  replace(size_type __pos, size_type __n1, const _CharT* __s,
629  size_type __n2)
630  {
631  __glibcxx_check_string_len(__s, __n2);
632  _Base::replace(__pos, __n1, __s, __n2);
633  this->_M_invalidate_all();
634  return *this;
635  }
636 
637  basic_string&
638  replace(size_type __pos, size_type __n1, const _CharT* __s)
639  {
640  __glibcxx_check_string(__s);
641  _Base::replace(__pos, __n1, __s);
642  this->_M_invalidate_all();
643  return *this;
644  }
645 
646  basic_string&
647  replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
648  {
649  _Base::replace(__pos, __n1, __n2, __c);
650  this->_M_invalidate_all();
651  return *this;
652  }
653 
654  basic_string&
655  replace(iterator __i1, iterator __i2, const basic_string& __str)
656  {
657  __glibcxx_check_erase_range(__i1, __i2);
658  _Base::replace(__i1.base(), __i2.base(), __str);
659  this->_M_invalidate_all();
660  return *this;
661  }
662 
663  basic_string&
664  replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n)
665  {
666  __glibcxx_check_erase_range(__i1, __i2);
667  __glibcxx_check_string_len(__s, __n);
668  _Base::replace(__i1.base(), __i2.base(), __s, __n);
669  this->_M_invalidate_all();
670  return *this;
671  }
672 
673  basic_string&
674  replace(iterator __i1, iterator __i2, const _CharT* __s)
675  {
676  __glibcxx_check_erase_range(__i1, __i2);
677  __glibcxx_check_string(__s);
678  _Base::replace(__i1.base(), __i2.base(), __s);
679  this->_M_invalidate_all();
680  return *this;
681  }
682 
683  basic_string&
684  replace(iterator __i1, iterator __i2, size_type __n, _CharT __c)
685  {
686  __glibcxx_check_erase_range(__i1, __i2);
687  _Base::replace(__i1.base(), __i2.base(), __n, __c);
688  this->_M_invalidate_all();
689  return *this;
690  }
691 
692  template<typename _InputIterator>
693  basic_string&
694  replace(iterator __i1, iterator __i2,
695  _InputIterator __j1, _InputIterator __j2)
696  {
697  __glibcxx_check_erase_range(__i1, __i2);
698  __glibcxx_check_valid_range(__j1, __j2);
699  _Base::replace(__i1.base(), __i2.base(), __j1, __j2);
700  this->_M_invalidate_all();
701  return *this;
702  }
703 
704 #if __cplusplus >= 201103L
705  basic_string& replace(iterator __i1, iterator __i2,
706  std::initializer_list<_CharT> __l)
707  {
708  __glibcxx_check_erase_range(__i1, __i2);
709  _Base::replace(__i1.base(), __i2.base(), __l);
710  this->_M_invalidate_all();
711  return *this;
712  }
713 #endif // C++11
714 
715  size_type
716  copy(_CharT* __s, size_type __n, size_type __pos = 0) const
717  {
718  __glibcxx_check_string_len(__s, __n);
719  return _Base::copy(__s, __n, __pos);
720  }
721 
722  void
723  swap(basic_string& __x)
724 #if _GLIBCXX_USE_CXX11_ABI
725  _GLIBCXX_NOEXCEPT
726 #endif
727  {
728  _Safe::_M_swap(__x);
729  _Base::swap(__x);
730  }
731 
732  // 21.3.6 string operations:
733  const _CharT*
734  c_str() const _GLIBCXX_NOEXCEPT
735  {
736  const _CharT* __res = _Base::c_str();
737  this->_M_invalidate_all();
738  return __res;
739  }
740 
741  const _CharT*
742  data() const _GLIBCXX_NOEXCEPT
743  {
744  const _CharT* __res = _Base::data();
745  this->_M_invalidate_all();
746  return __res;
747  }
748 
749  using _Base::get_allocator;
750 
751  size_type
752  find(const basic_string& __str, size_type __pos = 0) const
753  _GLIBCXX_NOEXCEPT
754  { return _Base::find(__str, __pos); }
755 
756  size_type
757  find(const _CharT* __s, size_type __pos, size_type __n) const
758  {
759  __glibcxx_check_string(__s);
760  return _Base::find(__s, __pos, __n);
761  }
762 
763  size_type
764  find(const _CharT* __s, size_type __pos = 0) const
765  {
766  __glibcxx_check_string(__s);
767  return _Base::find(__s, __pos);
768  }
769 
770  size_type
771  find(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
772  { return _Base::find(__c, __pos); }
773 
774  size_type
775  rfind(const basic_string& __str, size_type __pos = _Base::npos) const
776  _GLIBCXX_NOEXCEPT
777  { return _Base::rfind(__str, __pos); }
778 
779  size_type
780  rfind(const _CharT* __s, size_type __pos, size_type __n) const
781  {
782  __glibcxx_check_string_len(__s, __n);
783  return _Base::rfind(__s, __pos, __n);
784  }
785 
786  size_type
787  rfind(const _CharT* __s, size_type __pos = _Base::npos) const
788  {
789  __glibcxx_check_string(__s);
790  return _Base::rfind(__s, __pos);
791  }
792 
793  size_type
794  rfind(_CharT __c, size_type __pos = _Base::npos) const _GLIBCXX_NOEXCEPT
795  { return _Base::rfind(__c, __pos); }
796 
797  size_type
798  find_first_of(const basic_string& __str, size_type __pos = 0) const
799  _GLIBCXX_NOEXCEPT
800  { return _Base::find_first_of(__str, __pos); }
801 
802  size_type
803  find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
804  {
805  __glibcxx_check_string(__s);
806  return _Base::find_first_of(__s, __pos, __n);
807  }
808 
809  size_type
810  find_first_of(const _CharT* __s, size_type __pos = 0) const
811  {
812  __glibcxx_check_string(__s);
813  return _Base::find_first_of(__s, __pos);
814  }
815 
816  size_type
817  find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
818  { return _Base::find_first_of(__c, __pos); }
819 
820  size_type
821  find_last_of(const basic_string& __str,
822  size_type __pos = _Base::npos) const _GLIBCXX_NOEXCEPT
823  { return _Base::find_last_of(__str, __pos); }
824 
825  size_type
826  find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
827  {
828  __glibcxx_check_string(__s);
829  return _Base::find_last_of(__s, __pos, __n);
830  }
831 
832  size_type
833  find_last_of(const _CharT* __s, size_type __pos = _Base::npos) const
834  {
835  __glibcxx_check_string(__s);
836  return _Base::find_last_of(__s, __pos);
837  }
838 
839  size_type
840  find_last_of(_CharT __c, size_type __pos = _Base::npos) const
841  _GLIBCXX_NOEXCEPT
842  { return _Base::find_last_of(__c, __pos); }
843 
844  size_type
845  find_first_not_of(const basic_string& __str, size_type __pos = 0) const
846  _GLIBCXX_NOEXCEPT
847  { return _Base::find_first_not_of(__str, __pos); }
848 
849  size_type
850  find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
851  {
852  __glibcxx_check_string_len(__s, __n);
853  return _Base::find_first_not_of(__s, __pos, __n);
854  }
855 
856  size_type
857  find_first_not_of(const _CharT* __s, size_type __pos = 0) const
858  {
859  __glibcxx_check_string(__s);
860  return _Base::find_first_not_of(__s, __pos);
861  }
862 
863  size_type
864  find_first_not_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
865  { return _Base::find_first_not_of(__c, __pos); }
866 
867  size_type
868  find_last_not_of(const basic_string& __str,
869  size_type __pos = _Base::npos) const
870  _GLIBCXX_NOEXCEPT
871  { return _Base::find_last_not_of(__str, __pos); }
872 
873  size_type
874  find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
875  {
876  __glibcxx_check_string(__s);
877  return _Base::find_last_not_of(__s, __pos, __n);
878  }
879 
880  size_type
881  find_last_not_of(const _CharT* __s, size_type __pos = _Base::npos) const
882  {
883  __glibcxx_check_string(__s);
884  return _Base::find_last_not_of(__s, __pos);
885  }
886 
887  size_type
888  find_last_not_of(_CharT __c, size_type __pos = _Base::npos) const
889  _GLIBCXX_NOEXCEPT
890  { return _Base::find_last_not_of(__c, __pos); }
891 
892  basic_string
893  substr(size_type __pos = 0, size_type __n = _Base::npos) const
894  { return basic_string(_Base::substr(__pos, __n)); }
895 
896  int
897  compare(const basic_string& __str) const
898  { return _Base::compare(__str); }
899 
900  int
901  compare(size_type __pos1, size_type __n1,
902  const basic_string& __str) const
903  { return _Base::compare(__pos1, __n1, __str); }
904 
905  int
906  compare(size_type __pos1, size_type __n1, const basic_string& __str,
907  size_type __pos2, size_type __n2) const
908  { return _Base::compare(__pos1, __n1, __str, __pos2, __n2); }
909 
910  int
911  compare(const _CharT* __s) const
912  {
913  __glibcxx_check_string(__s);
914  return _Base::compare(__s);
915  }
916 
917  // _GLIBCXX_RESOLVE_LIB_DEFECTS
918  // 5. string::compare specification questionable
919  int
920  compare(size_type __pos1, size_type __n1, const _CharT* __s) const
921  {
922  __glibcxx_check_string(__s);
923  return _Base::compare(__pos1, __n1, __s);
924  }
925 
926  // _GLIBCXX_RESOLVE_LIB_DEFECTS
927  // 5. string::compare specification questionable
928  int
929  compare(size_type __pos1, size_type __n1,const _CharT* __s,
930  size_type __n2) const
931  {
932  __glibcxx_check_string_len(__s, __n2);
933  return _Base::compare(__pos1, __n1, __s, __n2);
934  }
935 
936  _Base&
937  _M_base() _GLIBCXX_NOEXCEPT { return *this; }
938 
939  const _Base&
940  _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
941 
942  using _Safe::_M_invalidate_all;
943  };
944 
945  template<typename _CharT, typename _Traits, typename _Allocator>
946  inline basic_string<_CharT,_Traits,_Allocator>
947  operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
948  const basic_string<_CharT,_Traits,_Allocator>& __rhs)
949  { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
950 
951  template<typename _CharT, typename _Traits, typename _Allocator>
952  inline basic_string<_CharT,_Traits,_Allocator>
953  operator+(const _CharT* __lhs,
954  const basic_string<_CharT,_Traits,_Allocator>& __rhs)
955  {
956  __glibcxx_check_string(__lhs);
957  return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
958  }
959 
960  template<typename _CharT, typename _Traits, typename _Allocator>
961  inline basic_string<_CharT,_Traits,_Allocator>
962  operator+(_CharT __lhs,
963  const basic_string<_CharT,_Traits,_Allocator>& __rhs)
964  { return basic_string<_CharT,_Traits,_Allocator>(1, __lhs) += __rhs; }
965 
966  template<typename _CharT, typename _Traits, typename _Allocator>
967  inline basic_string<_CharT,_Traits,_Allocator>
968  operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
969  const _CharT* __rhs)
970  {
971  __glibcxx_check_string(__rhs);
972  return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
973  }
974 
975  template<typename _CharT, typename _Traits, typename _Allocator>
976  inline basic_string<_CharT,_Traits,_Allocator>
977  operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
978  _CharT __rhs)
979  { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
980 
981  template<typename _CharT, typename _Traits, typename _Allocator>
982  inline bool
983  operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
984  const basic_string<_CharT,_Traits,_Allocator>& __rhs)
985  { return __lhs._M_base() == __rhs._M_base(); }
986 
987  template<typename _CharT, typename _Traits, typename _Allocator>
988  inline bool
989  operator==(const _CharT* __lhs,
990  const basic_string<_CharT,_Traits,_Allocator>& __rhs)
991  {
992  __glibcxx_check_string(__lhs);
993  return __lhs == __rhs._M_base();
994  }
995 
996  template<typename _CharT, typename _Traits, typename _Allocator>
997  inline bool
998  operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
999  const _CharT* __rhs)
1000  {
1001  __glibcxx_check_string(__rhs);
1002  return __lhs._M_base() == __rhs;
1003  }
1004 
1005  template<typename _CharT, typename _Traits, typename _Allocator>
1006  inline bool
1007  operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1008  const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1009  { return __lhs._M_base() != __rhs._M_base(); }
1010 
1011  template<typename _CharT, typename _Traits, typename _Allocator>
1012  inline bool
1013  operator!=(const _CharT* __lhs,
1014  const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1015  {
1016  __glibcxx_check_string(__lhs);
1017  return __lhs != __rhs._M_base();
1018  }
1019 
1020  template<typename _CharT, typename _Traits, typename _Allocator>
1021  inline bool
1022  operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1023  const _CharT* __rhs)
1024  {
1025  __glibcxx_check_string(__rhs);
1026  return __lhs._M_base() != __rhs;
1027  }
1028 
1029  template<typename _CharT, typename _Traits, typename _Allocator>
1030  inline bool
1031  operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1032  const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1033  { return __lhs._M_base() < __rhs._M_base(); }
1034 
1035  template<typename _CharT, typename _Traits, typename _Allocator>
1036  inline bool
1037  operator<(const _CharT* __lhs,
1038  const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1039  {
1040  __glibcxx_check_string(__lhs);
1041  return __lhs < __rhs._M_base();
1042  }
1043 
1044  template<typename _CharT, typename _Traits, typename _Allocator>
1045  inline bool
1046  operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1047  const _CharT* __rhs)
1048  {
1049  __glibcxx_check_string(__rhs);
1050  return __lhs._M_base() < __rhs;
1051  }
1052 
1053  template<typename _CharT, typename _Traits, typename _Allocator>
1054  inline bool
1055  operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1056  const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1057  { return __lhs._M_base() <= __rhs._M_base(); }
1058 
1059  template<typename _CharT, typename _Traits, typename _Allocator>
1060  inline bool
1061  operator<=(const _CharT* __lhs,
1062  const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1063  {
1064  __glibcxx_check_string(__lhs);
1065  return __lhs <= __rhs._M_base();
1066  }
1067 
1068  template<typename _CharT, typename _Traits, typename _Allocator>
1069  inline bool
1070  operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1071  const _CharT* __rhs)
1072  {
1073  __glibcxx_check_string(__rhs);
1074  return __lhs._M_base() <= __rhs;
1075  }
1076 
1077  template<typename _CharT, typename _Traits, typename _Allocator>
1078  inline bool
1079  operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1080  const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1081  { return __lhs._M_base() >= __rhs._M_base(); }
1082 
1083  template<typename _CharT, typename _Traits, typename _Allocator>
1084  inline bool
1085  operator>=(const _CharT* __lhs,
1086  const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1087  {
1088  __glibcxx_check_string(__lhs);
1089  return __lhs >= __rhs._M_base();
1090  }
1091 
1092  template<typename _CharT, typename _Traits, typename _Allocator>
1093  inline bool
1094  operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1095  const _CharT* __rhs)
1096  {
1097  __glibcxx_check_string(__rhs);
1098  return __lhs._M_base() >= __rhs;
1099  }
1100 
1101  template<typename _CharT, typename _Traits, typename _Allocator>
1102  inline bool
1103  operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1104  const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1105  { return __lhs._M_base() > __rhs._M_base(); }
1106 
1107  template<typename _CharT, typename _Traits, typename _Allocator>
1108  inline bool
1109  operator>(const _CharT* __lhs,
1110  const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1111  {
1112  __glibcxx_check_string(__lhs);
1113  return __lhs > __rhs._M_base();
1114  }
1115 
1116  template<typename _CharT, typename _Traits, typename _Allocator>
1117  inline bool
1118  operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1119  const _CharT* __rhs)
1120  {
1121  __glibcxx_check_string(__rhs);
1122  return __lhs._M_base() > __rhs;
1123  }
1124 
1125  // 21.3.7.8:
1126  template<typename _CharT, typename _Traits, typename _Allocator>
1127  inline void
1128  swap(basic_string<_CharT,_Traits,_Allocator>& __lhs,
1129  basic_string<_CharT,_Traits,_Allocator>& __rhs)
1130  { __lhs.swap(__rhs); }
1131 
1132  template<typename _CharT, typename _Traits, typename _Allocator>
1133  std::basic_ostream<_CharT, _Traits>&
1134  operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1135  const basic_string<_CharT, _Traits, _Allocator>& __str)
1136  { return __os << __str._M_base(); }
1137 
1138  template<typename _CharT, typename _Traits, typename _Allocator>
1139  std::basic_istream<_CharT,_Traits>&
1140  operator>>(std::basic_istream<_CharT,_Traits>& __is,
1141  basic_string<_CharT,_Traits,_Allocator>& __str)
1142  {
1143  std::basic_istream<_CharT,_Traits>& __res = __is >> __str._M_base();
1144  __str._M_invalidate_all();
1145  return __res;
1146  }
1147 
1148  template<typename _CharT, typename _Traits, typename _Allocator>
1149  std::basic_istream<_CharT,_Traits>&
1150  getline(std::basic_istream<_CharT,_Traits>& __is,
1151  basic_string<_CharT,_Traits,_Allocator>& __str, _CharT __delim)
1152  {
1153  std::basic_istream<_CharT,_Traits>& __res = getline(__is,
1154  __str._M_base(),
1155  __delim);
1156  __str._M_invalidate_all();
1157  return __res;
1158  }
1159 
1160  template<typename _CharT, typename _Traits, typename _Allocator>
1161  std::basic_istream<_CharT,_Traits>&
1162  getline(std::basic_istream<_CharT,_Traits>& __is,
1163  basic_string<_CharT,_Traits,_Allocator>& __str)
1164  {
1165  std::basic_istream<_CharT,_Traits>& __res = getline(__is,
1166  __str._M_base());
1167  __str._M_invalidate_all();
1168  return __res;
1169  }
1170 
1171  typedef basic_string<char> string;
1172 
1173 #ifdef _GLIBCXX_USE_WCHAR_T
1174  typedef basic_string<wchar_t> wstring;
1175 #endif
1176 
1177  template<typename _CharT, typename _Traits, typename _Allocator>
1178  struct _Insert_range_from_self_is_safe<
1179  __gnu_debug::basic_string<_CharT, _Traits, _Allocator> >
1180  { enum { __value = 1 }; };
1181 
1182 } // namespace __gnu_debug
1183 
1184 #endif