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