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