1 // Debugging string implementation -*- C++ -*-
 
    3 // Copyright (C) 2003-2014 Free Software Foundation, Inc.
 
    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)
 
   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.
 
   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.
 
   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/>.
 
   25 /** @file debug/string
 
   26  *  This file is a GNU debug extension to the Standard C++ Library.
 
   29 #ifndef _GLIBCXX_DEBUG_STRING
 
   30 #define _GLIBCXX_DEBUG_STRING 1
 
   33 #include <debug/safe_sequence.h>
 
   34 #include <debug/safe_iterator.h>
 
   38   /// Class std::basic_string with safety/checking/debug instrumentation.
 
   39   template<typename _CharT, typename _Traits = std::char_traits<_CharT>,
 
   40             typename _Allocator = std::allocator<_CharT> >
 
   42     : public std::basic_string<_CharT, _Traits, _Allocator>,
 
   43       public __gnu_debug::_Safe_sequence<basic_string<_CharT, _Traits,
 
   46       typedef std::basic_string<_CharT, _Traits, _Allocator> _Base;
 
   47       typedef __gnu_debug::_Safe_sequence<basic_string>     _Safe_base;
 
   51     typedef _Traits                       traits_type;
 
   52     typedef typename _Traits::char_type               value_type;
 
   53     typedef _Allocator                    allocator_type;
 
   54     typedef typename _Base::size_type                  size_type;
 
   55     typedef typename _Base::difference_type            difference_type;
 
   56     typedef typename _Base::reference                  reference;
 
   57     typedef typename _Base::const_reference            const_reference;
 
   58     typedef typename _Base::pointer                    pointer;
 
   59     typedef typename _Base::const_pointer              const_pointer;
 
   61     typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, basic_string>
 
   63     typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,
 
   64                                          basic_string> const_iterator;
 
   66     typedef std::reverse_iterator<iterator>            reverse_iterator;
 
   67     typedef std::reverse_iterator<const_iterator>      const_reverse_iterator;
 
   71     // 21.3.1 construct/copy/destroy:
 
   72     explicit basic_string(const _Allocator& __a = _Allocator())
 
   77     // Provides conversion from a release-mode string to a debug-mode string
 
   78     basic_string(const _Base& __base) : _Base(__base) { }
 
   80     // _GLIBCXX_RESOLVE_LIB_DEFECTS
 
   81     // 42. string ctors specify wrong default allocator
 
   82     basic_string(const basic_string& __str)
 
   83     : _Base(__str, 0, _Base::npos, __str.get_allocator())
 
   86     // _GLIBCXX_RESOLVE_LIB_DEFECTS
 
   87     // 42. string ctors specify wrong default allocator
 
   88     basic_string(const basic_string& __str, size_type __pos,
 
   89           size_type __n = _Base::npos,
 
   90           const _Allocator& __a = _Allocator())
 
   91     : _Base(__str, __pos, __n, __a)
 
   94     basic_string(const _CharT* __s, size_type __n,
 
   95           const _Allocator& __a = _Allocator())
 
   96     : _Base(__gnu_debug::__check_string(__s, __n), __n, __a)
 
   99     basic_string(const _CharT* __s, const _Allocator& __a = _Allocator())
 
  100     : _Base(__gnu_debug::__check_string(__s), __a)
 
  101     { this->assign(__s); }
 
  103     basic_string(size_type __n, _CharT __c,
 
  104           const _Allocator& __a = _Allocator())
 
  105     : _Base(__n, __c, __a)
 
  108     template<typename _InputIterator>
 
  109       basic_string(_InputIterator __begin, _InputIterator __end,
 
  110           const _Allocator& __a = _Allocator())
 
  111       : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__begin,
 
  113          __gnu_debug::__base(__end), __a)
 
  116 #if __cplusplus >= 201103L
 
  117     basic_string(basic_string&& __str) // noexcept
 
  118     : _Base(std::move(__str))
 
  121     basic_string(std::initializer_list<_CharT> __l,
 
  122         const _Allocator& __a = _Allocator())
 
  127     ~basic_string() _GLIBCXX_NOEXCEPT { }
 
  130     operator=(const basic_string& __str)
 
  132       *static_cast<_Base*>(this) = __str;
 
  133       this->_M_invalidate_all();
 
  138     operator=(const _CharT* __s)
 
  140       __glibcxx_check_string(__s);
 
  141       *static_cast<_Base*>(this) = __s;
 
  142       this->_M_invalidate_all();
 
  147     operator=(_CharT __c)
 
  149       *static_cast<_Base*>(this) = __c;
 
  150       this->_M_invalidate_all();
 
  154 #if __cplusplus >= 201103L
 
  156     operator=(basic_string&& __str)
 
  158       __glibcxx_check_self_move_assign(__str);
 
  159       *static_cast<_Base*>(this) = std::move(__str);
 
  160       this->_M_invalidate_all();
 
  165     operator=(std::initializer_list<_CharT> __l)
 
  167       *static_cast<_Base*>(this) = __l;
 
  168       this->_M_invalidate_all();
 
  175     begin() // _GLIBCXX_NOEXCEPT
 
  176     { return iterator(_Base::begin(), this); }
 
  179     begin() const _GLIBCXX_NOEXCEPT
 
  180     { return const_iterator(_Base::begin(), this); }
 
  183     end() // _GLIBCXX_NOEXCEPT
 
  184     { return iterator(_Base::end(), this); }
 
  187     end() const _GLIBCXX_NOEXCEPT
 
  188     { return const_iterator(_Base::end(), this); }
 
  191     rbegin() // _GLIBCXX_NOEXCEPT
 
  192     { return reverse_iterator(end()); }
 
  194     const_reverse_iterator
 
  195     rbegin() const _GLIBCXX_NOEXCEPT
 
  196     { return const_reverse_iterator(end()); }
 
  199     rend() // _GLIBCXX_NOEXCEPT
 
  200     { return reverse_iterator(begin()); }
 
  202     const_reverse_iterator
 
  203     rend() const _GLIBCXX_NOEXCEPT
 
  204     { return const_reverse_iterator(begin()); }
 
  206 #if __cplusplus >= 201103L
 
  208     cbegin() const noexcept
 
  209     { return const_iterator(_Base::begin(), this); }
 
  212     cend() const noexcept
 
  213     { return const_iterator(_Base::end(), this); }
 
  215     const_reverse_iterator
 
  216     crbegin() const noexcept
 
  217     { return const_reverse_iterator(end()); }
 
  219     const_reverse_iterator
 
  220     crend() const noexcept
 
  221     { return const_reverse_iterator(begin()); }
 
  227     using _Base::max_size;
 
  230     resize(size_type __n, _CharT __c)
 
  232       _Base::resize(__n, __c);
 
  233       this->_M_invalidate_all();
 
  237     resize(size_type __n)
 
  238     { this->resize(__n, _CharT()); }
 
  240 #if __cplusplus >= 201103L
 
  242     shrink_to_fit() noexcept
 
  244       if (capacity() > size())
 
  249          this->_M_invalidate_all();
 
  257     using _Base::capacity;
 
  258     using _Base::reserve;
 
  261     clear() // _GLIBCXX_NOEXCEPT
 
  264       this->_M_invalidate_all();
 
  269     // 21.3.4 element access:
 
  271     operator[](size_type __pos) const _GLIBCXX_NOEXCEPT
 
  273       _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(),
 
  274                _M_message(__gnu_debug::__msg_subscript_oob)
 
  275                ._M_sequence(*this, "this")
 
  276                ._M_integer(__pos, "__pos")
 
  277                ._M_integer(this->size(), "size"));
 
  278       return _M_base()[__pos];
 
  282     operator[](size_type __pos) // _GLIBCXX_NOEXCEPT
 
  284 #ifdef _GLIBCXX_DEBUG_PEDANTIC
 
  285       __glibcxx_check_subscript(__pos);
 
  287       // as an extension v3 allows s[s.size()] when s is non-const.
 
  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"));
 
  294       return _M_base()[__pos];
 
  299 #if __cplusplus >= 201103L
 
  306     operator+=(const basic_string& __str)
 
  309       this->_M_invalidate_all();
 
  314     operator+=(const _CharT* __s)
 
  316       __glibcxx_check_string(__s);
 
  318       this->_M_invalidate_all();
 
  323     operator+=(_CharT __c)
 
  326       this->_M_invalidate_all();
 
  330 #if __cplusplus >= 201103L
 
  332     operator+=(std::initializer_list<_CharT> __l)
 
  335       this->_M_invalidate_all();
 
  341     append(const basic_string& __str)
 
  343       _Base::append(__str);
 
  344       this->_M_invalidate_all();
 
  349     append(const basic_string& __str, size_type __pos, size_type __n)
 
  351       _Base::append(__str, __pos, __n);
 
  352       this->_M_invalidate_all();
 
  357     append(const _CharT* __s, size_type __n)
 
  359       __glibcxx_check_string_len(__s, __n);
 
  360       _Base::append(__s, __n);
 
  361       this->_M_invalidate_all();
 
  366     append(const _CharT* __s)
 
  368       __glibcxx_check_string(__s);
 
  370       this->_M_invalidate_all();
 
  375     append(size_type __n, _CharT __c)
 
  377       _Base::append(__n, __c);
 
  378       this->_M_invalidate_all();
 
  382     template<typename _InputIterator>
 
  384       append(_InputIterator __first, _InputIterator __last)
 
  386    __glibcxx_check_valid_range(__first, __last);
 
  387    _Base::append(__gnu_debug::__base(__first),
 
  388              __gnu_debug::__base(__last));
 
  389    this->_M_invalidate_all();
 
  393     // _GLIBCXX_RESOLVE_LIB_DEFECTS
 
  394     // 7. string clause minor problems
 
  396     push_back(_CharT __c)
 
  398       _Base::push_back(__c);
 
  399       this->_M_invalidate_all();
 
  403     assign(const basic_string& __x)
 
  406       this->_M_invalidate_all();
 
  410 #if __cplusplus >= 201103L
 
  412     assign(basic_string&& __x)
 
  414       _Base::assign(std::move(__x));
 
  415       this->_M_invalidate_all();
 
  421     assign(const basic_string& __str, size_type __pos, size_type __n)
 
  423       _Base::assign(__str, __pos, __n);
 
  424       this->_M_invalidate_all();
 
  429     assign(const _CharT* __s, size_type __n)
 
  431       __glibcxx_check_string_len(__s, __n);
 
  432       _Base::assign(__s, __n);
 
  433       this->_M_invalidate_all();
 
  438     assign(const _CharT* __s)
 
  440       __glibcxx_check_string(__s);
 
  442       this->_M_invalidate_all();
 
  447     assign(size_type __n, _CharT __c)
 
  449       _Base::assign(__n, __c);
 
  450       this->_M_invalidate_all();
 
  454     template<typename _InputIterator>
 
  456       assign(_InputIterator __first, _InputIterator __last)
 
  458    __glibcxx_check_valid_range(__first, __last);
 
  459    _Base::assign(__gnu_debug::__base(__first),
 
  460              __gnu_debug::__base(__last));
 
  461    this->_M_invalidate_all();
 
  465 #if __cplusplus >= 201103L
 
  467     assign(std::initializer_list<_CharT> __l)
 
  470       this->_M_invalidate_all();
 
  476     insert(size_type __pos1, const basic_string& __str)
 
  478       _Base::insert(__pos1, __str);
 
  479       this->_M_invalidate_all();
 
  484     insert(size_type __pos1, const basic_string& __str,
 
  485       size_type __pos2, size_type __n)
 
  487       _Base::insert(__pos1, __str, __pos2, __n);
 
  488       this->_M_invalidate_all();
 
  493     insert(size_type __pos, const _CharT* __s, size_type __n)
 
  495       __glibcxx_check_string(__s);
 
  496       _Base::insert(__pos, __s, __n);
 
  497       this->_M_invalidate_all();
 
  502     insert(size_type __pos, const _CharT* __s)
 
  504       __glibcxx_check_string(__s);
 
  505       _Base::insert(__pos, __s);
 
  506       this->_M_invalidate_all();
 
  511     insert(size_type __pos, size_type __n, _CharT __c)
 
  513       _Base::insert(__pos, __n, __c);
 
  514       this->_M_invalidate_all();
 
  519     insert(iterator __p, _CharT __c)
 
  521       __glibcxx_check_insert(__p);
 
  522       typename _Base::iterator __res = _Base::insert(__p.base(), __c);
 
  523       this->_M_invalidate_all();
 
  524       return iterator(__res, this);
 
  528     insert(iterator __p, size_type __n, _CharT __c)
 
  530       __glibcxx_check_insert(__p);
 
  531       _Base::insert(__p.base(), __n, __c);
 
  532       this->_M_invalidate_all();
 
  535     template<typename _InputIterator>
 
  537       insert(iterator __p, _InputIterator __first, _InputIterator __last)
 
  539    __glibcxx_check_insert_range(__p, __first, __last);
 
  540    _Base::insert(__p.base(), __gnu_debug::__base(__first),
 
  541                  __gnu_debug::__base(__last));
 
  542    this->_M_invalidate_all();
 
  545 #if __cplusplus >= 201103L
 
  547     insert(iterator __p, std::initializer_list<_CharT> __l)
 
  549       __glibcxx_check_insert(__p);
 
  550       _Base::insert(__p.base(), __l);
 
  551       this->_M_invalidate_all();
 
  556     erase(size_type __pos = 0, size_type __n = _Base::npos)
 
  558       _Base::erase(__pos, __n);
 
  559       this->_M_invalidate_all();
 
  564     erase(iterator __position)
 
  566       __glibcxx_check_erase(__position);
 
  567       typename _Base::iterator __res = _Base::erase(__position.base());
 
  568       this->_M_invalidate_all();
 
  569       return iterator(__res, this);
 
  573     erase(iterator __first, iterator __last)
 
  575       // _GLIBCXX_RESOLVE_LIB_DEFECTS
 
  576       // 151. can't currently clear() empty container
 
  577       __glibcxx_check_erase_range(__first, __last);
 
  578       typename _Base::iterator __res = _Base::erase(__first.base(),
 
  580       this->_M_invalidate_all();
 
  581       return iterator(__res, this);
 
  584 #if __cplusplus >= 201103L
 
  586     pop_back() // noexcept
 
  588       __glibcxx_check_nonempty();
 
  590       this->_M_invalidate_all();
 
  595     replace(size_type __pos1, size_type __n1, const basic_string& __str)
 
  597       _Base::replace(__pos1, __n1, __str);
 
  598       this->_M_invalidate_all();
 
  603     replace(size_type __pos1, size_type __n1, const basic_string& __str,
 
  604        size_type __pos2, size_type __n2)
 
  606       _Base::replace(__pos1, __n1, __str, __pos2, __n2);
 
  607       this->_M_invalidate_all();
 
  612     replace(size_type __pos, size_type __n1, const _CharT* __s,
 
  615       __glibcxx_check_string_len(__s, __n2);
 
  616       _Base::replace(__pos, __n1, __s, __n2);
 
  617       this->_M_invalidate_all();
 
  622     replace(size_type __pos, size_type __n1, const _CharT* __s)
 
  624       __glibcxx_check_string(__s);
 
  625       _Base::replace(__pos, __n1, __s);
 
  626       this->_M_invalidate_all();
 
  631     replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
 
  633       _Base::replace(__pos, __n1, __n2, __c);
 
  634       this->_M_invalidate_all();
 
  639     replace(iterator __i1, iterator __i2, const basic_string& __str)
 
  641       __glibcxx_check_erase_range(__i1, __i2);
 
  642       _Base::replace(__i1.base(), __i2.base(), __str);
 
  643       this->_M_invalidate_all();
 
  648     replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n)
 
  650       __glibcxx_check_erase_range(__i1, __i2);
 
  651       __glibcxx_check_string_len(__s, __n);
 
  652       _Base::replace(__i1.base(), __i2.base(), __s, __n);
 
  653       this->_M_invalidate_all();
 
  658     replace(iterator __i1, iterator __i2, const _CharT* __s)
 
  660       __glibcxx_check_erase_range(__i1, __i2);
 
  661       __glibcxx_check_string(__s);
 
  662       _Base::replace(__i1.base(), __i2.base(), __s);
 
  663       this->_M_invalidate_all();
 
  668     replace(iterator __i1, iterator __i2, size_type __n, _CharT __c)
 
  670       __glibcxx_check_erase_range(__i1, __i2);
 
  671       _Base::replace(__i1.base(), __i2.base(), __n, __c);
 
  672       this->_M_invalidate_all();
 
  676     template<typename _InputIterator>
 
  678       replace(iterator __i1, iterator __i2,
 
  679          _InputIterator __j1, _InputIterator __j2)
 
  681    __glibcxx_check_erase_range(__i1, __i2);
 
  682    __glibcxx_check_valid_range(__j1, __j2);
 
  683    _Base::replace(__i1.base(), __i2.base(), __j1, __j2);
 
  684    this->_M_invalidate_all();
 
  688 #if __cplusplus >= 201103L
 
  689       basic_string& replace(iterator __i1, iterator __i2,
 
  690                std::initializer_list<_CharT> __l)
 
  692    __glibcxx_check_erase_range(__i1, __i2);
 
  693    _Base::replace(__i1.base(), __i2.base(), __l);
 
  694    this->_M_invalidate_all();
 
  700     copy(_CharT* __s, size_type __n, size_type __pos = 0) const
 
  702       __glibcxx_check_string_len(__s, __n);
 
  703       return _Base::copy(__s, __n, __pos);
 
  707     swap(basic_string<_CharT,_Traits,_Allocator>& __x)
 
  711       this->_M_invalidate_all();
 
  712       __x._M_invalidate_all();
 
  715     // 21.3.6 string operations:
 
  717     c_str() const _GLIBCXX_NOEXCEPT
 
  719       const _CharT* __res = _Base::c_str();
 
  720       this->_M_invalidate_all();
 
  725     data() const _GLIBCXX_NOEXCEPT
 
  727       const _CharT* __res = _Base::data();
 
  728       this->_M_invalidate_all();
 
  732     using _Base::get_allocator;
 
  735     find(const basic_string& __str, size_type __pos = 0) const
 
  737     { return _Base::find(__str, __pos); }
 
  740     find(const _CharT* __s, size_type __pos, size_type __n) const
 
  742       __glibcxx_check_string(__s);
 
  743       return _Base::find(__s, __pos, __n);
 
  747     find(const _CharT* __s, size_type __pos = 0) const
 
  749       __glibcxx_check_string(__s);
 
  750       return _Base::find(__s, __pos);
 
  754     find(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
 
  755     { return _Base::find(__c, __pos); }
 
  758     rfind(const basic_string& __str, size_type __pos = _Base::npos) const
 
  760     { return _Base::rfind(__str, __pos); }
 
  763     rfind(const _CharT* __s, size_type __pos, size_type __n) const
 
  765       __glibcxx_check_string_len(__s, __n);
 
  766       return _Base::rfind(__s, __pos, __n);
 
  770     rfind(const _CharT* __s, size_type __pos = _Base::npos) const
 
  772       __glibcxx_check_string(__s);
 
  773       return _Base::rfind(__s, __pos);
 
  777     rfind(_CharT __c, size_type __pos = _Base::npos) const _GLIBCXX_NOEXCEPT
 
  778     { return _Base::rfind(__c, __pos); }
 
  781     find_first_of(const basic_string& __str, size_type __pos = 0) const
 
  783     { return _Base::find_first_of(__str, __pos); }
 
  786     find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
 
  788       __glibcxx_check_string(__s);
 
  789       return _Base::find_first_of(__s, __pos, __n);
 
  793     find_first_of(const _CharT* __s, size_type __pos = 0) const
 
  795       __glibcxx_check_string(__s);
 
  796       return _Base::find_first_of(__s, __pos);
 
  800     find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
 
  801     { return _Base::find_first_of(__c, __pos); }
 
  804     find_last_of(const basic_string& __str, 
 
  805         size_type __pos = _Base::npos) const _GLIBCXX_NOEXCEPT
 
  806     { return _Base::find_last_of(__str, __pos); }
 
  809     find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
 
  811       __glibcxx_check_string(__s);
 
  812       return _Base::find_last_of(__s, __pos, __n);
 
  816     find_last_of(const _CharT* __s, size_type __pos = _Base::npos) const
 
  818       __glibcxx_check_string(__s);
 
  819       return _Base::find_last_of(__s, __pos);
 
  823     find_last_of(_CharT __c, size_type __pos = _Base::npos) const
 
  825     { return _Base::find_last_of(__c, __pos); }
 
  828     find_first_not_of(const basic_string& __str, size_type __pos = 0) const
 
  830     { return _Base::find_first_not_of(__str, __pos); }
 
  833     find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
 
  835       __glibcxx_check_string_len(__s, __n);
 
  836       return _Base::find_first_not_of(__s, __pos, __n);
 
  840     find_first_not_of(const _CharT* __s, size_type __pos = 0) const
 
  842       __glibcxx_check_string(__s);
 
  843       return _Base::find_first_not_of(__s, __pos);
 
  847     find_first_not_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
 
  848     { return _Base::find_first_not_of(__c, __pos); }
 
  851     find_last_not_of(const basic_string& __str,
 
  852                  size_type __pos = _Base::npos) const
 
  854     { return _Base::find_last_not_of(__str, __pos); }
 
  857     find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
 
  859       __glibcxx_check_string(__s);
 
  860       return _Base::find_last_not_of(__s, __pos, __n);
 
  864     find_last_not_of(const _CharT* __s, size_type __pos = _Base::npos) const
 
  866       __glibcxx_check_string(__s);
 
  867       return _Base::find_last_not_of(__s, __pos);
 
  871     find_last_not_of(_CharT __c, size_type __pos = _Base::npos) const
 
  873     { return _Base::find_last_not_of(__c, __pos); }
 
  876     substr(size_type __pos = 0, size_type __n = _Base::npos) const
 
  877     { return basic_string(_Base::substr(__pos, __n)); }
 
  880     compare(const basic_string& __str) const
 
  881     { return _Base::compare(__str); }
 
  884     compare(size_type __pos1, size_type __n1,
 
  885          const basic_string& __str) const
 
  886     { return _Base::compare(__pos1, __n1, __str); }
 
  889     compare(size_type __pos1, size_type __n1, const basic_string& __str,
 
  890          size_type __pos2, size_type __n2) const
 
  891     { return _Base::compare(__pos1, __n1, __str, __pos2, __n2); }
 
  894     compare(const _CharT* __s) const
 
  896       __glibcxx_check_string(__s);
 
  897       return _Base::compare(__s);
 
  900     //  _GLIBCXX_RESOLVE_LIB_DEFECTS
 
  901     //  5. string::compare specification questionable
 
  903     compare(size_type __pos1, size_type __n1, const _CharT* __s) const
 
  905       __glibcxx_check_string(__s);
 
  906       return _Base::compare(__pos1, __n1, __s);
 
  909     //  _GLIBCXX_RESOLVE_LIB_DEFECTS
 
  910     //  5. string::compare specification questionable
 
  912     compare(size_type __pos1, size_type __n1,const _CharT* __s,
 
  913          size_type __n2) const
 
  915       __glibcxx_check_string_len(__s, __n2);
 
  916       return _Base::compare(__pos1, __n1, __s, __n2);
 
  920     _M_base() _GLIBCXX_NOEXCEPT       { return *this; }
 
  923     _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
 
  925     using _Safe_base::_M_invalidate_all;
 
  928   template<typename _CharT, typename _Traits, typename _Allocator>
 
  929     inline basic_string<_CharT,_Traits,_Allocator>
 
  930     operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
 
  931          const basic_string<_CharT,_Traits,_Allocator>& __rhs)
 
  932     { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
 
  934   template<typename _CharT, typename _Traits, typename _Allocator>
 
  935     inline basic_string<_CharT,_Traits,_Allocator>
 
  936     operator+(const _CharT* __lhs,
 
  937          const basic_string<_CharT,_Traits,_Allocator>& __rhs)
 
  939       __glibcxx_check_string(__lhs);
 
  940       return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
 
  943   template<typename _CharT, typename _Traits, typename _Allocator>
 
  944     inline basic_string<_CharT,_Traits,_Allocator>
 
  945     operator+(_CharT __lhs,
 
  946          const basic_string<_CharT,_Traits,_Allocator>& __rhs)
 
  947     { return basic_string<_CharT,_Traits,_Allocator>(1, __lhs) += __rhs; }
 
  949   template<typename _CharT, typename _Traits, typename _Allocator>
 
  950     inline basic_string<_CharT,_Traits,_Allocator>
 
  951     operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
 
  954       __glibcxx_check_string(__rhs);
 
  955       return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
 
  958   template<typename _CharT, typename _Traits, typename _Allocator>
 
  959     inline basic_string<_CharT,_Traits,_Allocator>
 
  960     operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
 
  962     { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
 
  964   template<typename _CharT, typename _Traits, typename _Allocator>
 
  966     operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
 
  967           const basic_string<_CharT,_Traits,_Allocator>& __rhs)
 
  968     { return __lhs._M_base() == __rhs._M_base(); }
 
  970   template<typename _CharT, typename _Traits, typename _Allocator>
 
  972     operator==(const _CharT* __lhs,
 
  973           const basic_string<_CharT,_Traits,_Allocator>& __rhs)
 
  975       __glibcxx_check_string(__lhs);
 
  976       return __lhs == __rhs._M_base();
 
  979   template<typename _CharT, typename _Traits, typename _Allocator>
 
  981     operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
 
  984       __glibcxx_check_string(__rhs);
 
  985       return __lhs._M_base() == __rhs;
 
  988   template<typename _CharT, typename _Traits, typename _Allocator>
 
  990     operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
 
  991           const basic_string<_CharT,_Traits,_Allocator>& __rhs)
 
  992     { return __lhs._M_base() != __rhs._M_base(); }
 
  994   template<typename _CharT, typename _Traits, typename _Allocator>
 
  996     operator!=(const _CharT* __lhs,
 
  997           const basic_string<_CharT,_Traits,_Allocator>& __rhs)
 
  999       __glibcxx_check_string(__lhs);
 
 1000       return __lhs != __rhs._M_base();
 
 1003   template<typename _CharT, typename _Traits, typename _Allocator>
 
 1005     operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
 
 1006           const _CharT* __rhs)
 
 1008       __glibcxx_check_string(__rhs);
 
 1009       return __lhs._M_base() != __rhs;
 
 1012   template<typename _CharT, typename _Traits, typename _Allocator>
 
 1014     operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
 
 1015          const basic_string<_CharT,_Traits,_Allocator>& __rhs)
 
 1016     { return __lhs._M_base() < __rhs._M_base(); }
 
 1018   template<typename _CharT, typename _Traits, typename _Allocator>
 
 1020     operator<(const _CharT* __lhs,
 
 1021          const basic_string<_CharT,_Traits,_Allocator>& __rhs)
 
 1023       __glibcxx_check_string(__lhs);
 
 1024       return __lhs < __rhs._M_base();
 
 1027   template<typename _CharT, typename _Traits, typename _Allocator>
 
 1029     operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
 
 1030          const _CharT* __rhs)
 
 1032       __glibcxx_check_string(__rhs);
 
 1033       return __lhs._M_base() < __rhs;
 
 1036   template<typename _CharT, typename _Traits, typename _Allocator>
 
 1038     operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
 
 1039           const basic_string<_CharT,_Traits,_Allocator>& __rhs)
 
 1040     { return __lhs._M_base() <= __rhs._M_base(); }
 
 1042   template<typename _CharT, typename _Traits, typename _Allocator>
 
 1044     operator<=(const _CharT* __lhs,
 
 1045           const basic_string<_CharT,_Traits,_Allocator>& __rhs)
 
 1047       __glibcxx_check_string(__lhs);
 
 1048       return __lhs <= __rhs._M_base();
 
 1051   template<typename _CharT, typename _Traits, typename _Allocator>
 
 1053     operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
 
 1054           const _CharT* __rhs)
 
 1056       __glibcxx_check_string(__rhs);
 
 1057       return __lhs._M_base() <= __rhs;
 
 1060   template<typename _CharT, typename _Traits, typename _Allocator>
 
 1062     operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
 
 1063           const basic_string<_CharT,_Traits,_Allocator>& __rhs)
 
 1064     { return __lhs._M_base() >= __rhs._M_base(); }
 
 1066   template<typename _CharT, typename _Traits, typename _Allocator>
 
 1068     operator>=(const _CharT* __lhs,
 
 1069           const basic_string<_CharT,_Traits,_Allocator>& __rhs)
 
 1071       __glibcxx_check_string(__lhs);
 
 1072       return __lhs >= __rhs._M_base();
 
 1075   template<typename _CharT, typename _Traits, typename _Allocator>
 
 1077     operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
 
 1078           const _CharT* __rhs)
 
 1080       __glibcxx_check_string(__rhs);
 
 1081       return __lhs._M_base() >= __rhs;
 
 1084   template<typename _CharT, typename _Traits, typename _Allocator>
 
 1086     operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
 
 1087          const basic_string<_CharT,_Traits,_Allocator>& __rhs)
 
 1088     { return __lhs._M_base() > __rhs._M_base(); }
 
 1090   template<typename _CharT, typename _Traits, typename _Allocator>
 
 1092     operator>(const _CharT* __lhs,
 
 1093          const basic_string<_CharT,_Traits,_Allocator>& __rhs)
 
 1095       __glibcxx_check_string(__lhs);
 
 1096       return __lhs > __rhs._M_base();
 
 1099   template<typename _CharT, typename _Traits, typename _Allocator>
 
 1101     operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
 
 1102          const _CharT* __rhs)
 
 1104       __glibcxx_check_string(__rhs);
 
 1105       return __lhs._M_base() > __rhs;
 
 1109   template<typename _CharT, typename _Traits, typename _Allocator>
 
 1111     swap(basic_string<_CharT,_Traits,_Allocator>& __lhs,
 
 1112     basic_string<_CharT,_Traits,_Allocator>& __rhs)
 
 1113     { __lhs.swap(__rhs); }
 
 1115   template<typename _CharT, typename _Traits, typename _Allocator>
 
 1116     std::basic_ostream<_CharT, _Traits>&
 
 1117     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
 
 1118           const basic_string<_CharT, _Traits, _Allocator>& __str)
 
 1119     { return __os << __str._M_base(); }
 
 1121   template<typename _CharT, typename _Traits, typename _Allocator>
 
 1122     std::basic_istream<_CharT,_Traits>&
 
 1123     operator>>(std::basic_istream<_CharT,_Traits>& __is,
 
 1124           basic_string<_CharT,_Traits,_Allocator>& __str)
 
 1126       std::basic_istream<_CharT,_Traits>& __res = __is >> __str._M_base();
 
 1127       __str._M_invalidate_all();
 
 1131   template<typename _CharT, typename _Traits, typename _Allocator>
 
 1132     std::basic_istream<_CharT,_Traits>&
 
 1133     getline(std::basic_istream<_CharT,_Traits>& __is,
 
 1134        basic_string<_CharT,_Traits,_Allocator>& __str, _CharT __delim)
 
 1136       std::basic_istream<_CharT,_Traits>& __res = getline(__is,
 
 1139       __str._M_invalidate_all();
 
 1143   template<typename _CharT, typename _Traits, typename _Allocator>
 
 1144     std::basic_istream<_CharT,_Traits>&
 
 1145     getline(std::basic_istream<_CharT,_Traits>& __is,
 
 1146        basic_string<_CharT,_Traits,_Allocator>& __str)
 
 1148       std::basic_istream<_CharT,_Traits>& __res = getline(__is,
 
 1150       __str._M_invalidate_all();
 
 1154   typedef basic_string<char>    string;
 
 1156 #ifdef _GLIBCXX_USE_WCHAR_T
 
 1157   typedef basic_string<wchar_t> wstring;
 
 1160   template<typename _CharT, typename _Traits, typename _Allocator>
 
 1161     struct _Insert_range_from_self_is_safe<
 
 1162       __gnu_debug::basic_string<_CharT, _Traits, _Allocator> >
 
 1163       { enum { __value = 1 }; };
 
 1165 } // namespace __gnu_debug