Home | History | Annotate | Download | only in debug
      1 // Debugging string implementation -*- C++ -*-
      2 
      3 // Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
      4 // Free Software Foundation, Inc.
      5 //
      6 // This file is part of the GNU ISO C++ Library.  This library is free
      7 // software; you can redistribute it and/or modify it under the
      8 // terms of the GNU General Public License as published by the
      9 // Free Software Foundation; either version 3, or (at your option)
     10 // any later version.
     11 
     12 // This library is distributed in the hope that it will be useful,
     13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 // GNU General Public License for more details.
     16 
     17 // Under Section 7 of GPL version 3, you are granted additional
     18 // permissions described in the GCC Runtime Library Exception, version
     19 // 3.1, as published by the Free Software Foundation.
     20 
     21 // You should have received a copy of the GNU General Public License and
     22 // a copy of the GCC Runtime Library Exception along with this program;
     23 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     24 // <http://www.gnu.org/licenses/>.
     25 
     26 /** @file debug/string
     27  *  This file is a GNU debug extension to the Standard C++ Library.
     28  */
     29 
     30 #ifndef _GLIBCXX_DEBUG_STRING
     31 #define _GLIBCXX_DEBUG_STRING 1
     32 
     33 #include <string>
     34 #include <debug/safe_sequence.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 std::basic_string<_CharT, _Traits, _Allocator>,
     44       public __gnu_debug::_Safe_sequence<basic_string<_CharT, _Traits,
     45 						      _Allocator> >
     46     {
     47       typedef std::basic_string<_CharT, _Traits, _Allocator> _Base;
     48       typedef __gnu_debug::_Safe_sequence<basic_string>     _Safe_base;
     49 
     50   public:
     51     // types:
     52     typedef _Traits				       traits_type;
     53     typedef typename _Traits::char_type		       value_type;
     54     typedef _Allocator				       allocator_type;
     55     typedef typename _Base::size_type                  size_type;
     56     typedef typename _Base::difference_type            difference_type;
     57     typedef typename _Base::reference                  reference;
     58     typedef typename _Base::const_reference            const_reference;
     59     typedef typename _Base::pointer                    pointer;
     60     typedef typename _Base::const_pointer              const_pointer;
     61 
     62     typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, basic_string>
     63                                                        iterator;
     64     typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,
     65                                          basic_string> const_iterator;
     66 
     67     typedef std::reverse_iterator<iterator>            reverse_iterator;
     68     typedef std::reverse_iterator<const_iterator>      const_reverse_iterator;
     69 
     70     using _Base::npos;
     71 
     72     // 21.3.1 construct/copy/destroy:
     73     explicit basic_string(const _Allocator& __a = _Allocator())
     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 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    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 // __GXX_EXPERIMENTAL_CXX0X__
    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 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    155     basic_string&
    156     operator=(basic_string&& __str)
    157     {
    158       *static_cast<_Base*>(this) = std::move(__str);
    159       this->_M_invalidate_all();
    160       return *this;
    161     }
    162 
    163     basic_string&
    164     operator=(std::initializer_list<_CharT> __l)
    165     {
    166       *static_cast<_Base*>(this) = __l;
    167       this->_M_invalidate_all();
    168       return *this;
    169     }
    170 #endif // __GXX_EXPERIMENTAL_CXX0X__
    171 
    172     // 21.3.2 iterators:
    173     iterator
    174     begin() _GLIBCXX_NOEXCEPT
    175     { return iterator(_Base::begin(), this); }
    176 
    177     const_iterator
    178     begin() const _GLIBCXX_NOEXCEPT
    179     { return const_iterator(_Base::begin(), this); }
    180 
    181     iterator
    182     end() _GLIBCXX_NOEXCEPT
    183     { return iterator(_Base::end(), this); }
    184 
    185     const_iterator
    186     end() const _GLIBCXX_NOEXCEPT
    187     { return const_iterator(_Base::end(), this); }
    188 
    189     reverse_iterator
    190     rbegin() _GLIBCXX_NOEXCEPT
    191     { return reverse_iterator(end()); }
    192 
    193     const_reverse_iterator
    194     rbegin() const _GLIBCXX_NOEXCEPT
    195     { return const_reverse_iterator(end()); }
    196 
    197     reverse_iterator
    198     rend() _GLIBCXX_NOEXCEPT
    199     { return reverse_iterator(begin()); }
    200 
    201     const_reverse_iterator
    202     rend() const _GLIBCXX_NOEXCEPT
    203     { return const_reverse_iterator(begin()); }
    204 
    205 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    206     const_iterator
    207     cbegin() const noexcept
    208     { return const_iterator(_Base::begin(), this); }
    209 
    210     const_iterator
    211     cend() const noexcept
    212     { return const_iterator(_Base::end(), this); }
    213 
    214     const_reverse_iterator
    215     crbegin() const noexcept
    216     { return const_reverse_iterator(end()); }
    217 
    218     const_reverse_iterator
    219     crend() const noexcept
    220     { return const_reverse_iterator(begin()); }
    221 #endif
    222 
    223     // 21.3.3 capacity:
    224     using _Base::size;
    225     using _Base::length;
    226     using _Base::max_size;
    227 
    228     void
    229     resize(size_type __n, _CharT __c)
    230     {
    231       _Base::resize(__n, __c);
    232       this->_M_invalidate_all();
    233     }
    234 
    235     void
    236     resize(size_type __n)
    237     { this->resize(__n, _CharT()); }
    238 
    239 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    240     void
    241     shrink_to_fit()
    242     {
    243       if (capacity() > size())
    244 	{
    245 	  __try
    246 	    {
    247 	      reserve(0);
    248 	      this->_M_invalidate_all();
    249 	    }
    250 	  __catch(...)
    251 	    { }
    252 	}
    253     }
    254 #endif
    255 
    256     using _Base::capacity;
    257     using _Base::reserve;
    258 
    259     void
    260     clear() _GLIBCXX_NOEXCEPT
    261     {
    262       _Base::clear();
    263       this->_M_invalidate_all();
    264     }
    265 
    266     using _Base::empty;
    267 
    268     // 21.3.4 element access:
    269     const_reference
    270     operator[](size_type __pos) const
    271     {
    272       _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(),
    273 			    _M_message(__gnu_debug::__msg_subscript_oob)
    274 			    ._M_sequence(*this, "this")
    275 			    ._M_integer(__pos, "__pos")
    276 			    ._M_integer(this->size(), "size"));
    277       return _M_base()[__pos];
    278     }
    279 
    280     reference
    281     operator[](size_type __pos)
    282     {
    283 #ifdef _GLIBCXX_DEBUG_PEDANTIC
    284       __glibcxx_check_subscript(__pos);
    285 #else
    286       // as an extension v3 allows s[s.size()] when s is non-const.
    287       _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(),
    288 			    _M_message(__gnu_debug::__msg_subscript_oob)
    289 			    ._M_sequence(*this, "this")
    290 			    ._M_integer(__pos, "__pos")
    291 			    ._M_integer(this->size(), "size"));
    292 #endif
    293       return _M_base()[__pos];
    294     }
    295 
    296     using _Base::at;
    297 
    298 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    299     using _Base::front;
    300     using _Base::back;
    301 #endif
    302 
    303     // 21.3.5 modifiers:
    304     basic_string&
    305     operator+=(const basic_string& __str)
    306     {
    307       _M_base() += __str;
    308       this->_M_invalidate_all();
    309       return *this;
    310     }
    311 
    312     basic_string&
    313     operator+=(const _CharT* __s)
    314     {
    315       __glibcxx_check_string(__s);
    316       _M_base() += __s;
    317       this->_M_invalidate_all();
    318       return *this;
    319     }
    320 
    321     basic_string&
    322     operator+=(_CharT __c)
    323     {
    324       _M_base() += __c;
    325       this->_M_invalidate_all();
    326       return *this;
    327     }
    328 
    329 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    330     basic_string&
    331     operator+=(std::initializer_list<_CharT> __l)
    332     {
    333       _M_base() += __l;
    334       this->_M_invalidate_all();
    335       return *this;
    336     }
    337 #endif // __GXX_EXPERIMENTAL_CXX0X__
    338 
    339     basic_string&
    340     append(const basic_string& __str)
    341     {
    342       _Base::append(__str);
    343       this->_M_invalidate_all();
    344       return *this;
    345     }
    346 
    347     basic_string&
    348     append(const basic_string& __str, size_type __pos, size_type __n)
    349     {
    350       _Base::append(__str, __pos, __n);
    351       this->_M_invalidate_all();
    352       return *this;
    353     }
    354 
    355     basic_string&
    356     append(const _CharT* __s, size_type __n)
    357     {
    358       __glibcxx_check_string_len(__s, __n);
    359       _Base::append(__s, __n);
    360       this->_M_invalidate_all();
    361       return *this;
    362     }
    363 
    364     basic_string&
    365     append(const _CharT* __s)
    366     {
    367       __glibcxx_check_string(__s);
    368       _Base::append(__s);
    369       this->_M_invalidate_all();
    370       return *this;
    371     }
    372 
    373     basic_string&
    374     append(size_type __n, _CharT __c)
    375     {
    376       _Base::append(__n, __c);
    377       this->_M_invalidate_all();
    378       return *this;
    379     }
    380 
    381     template<typename _InputIterator>
    382       basic_string&
    383       append(_InputIterator __first, _InputIterator __last)
    384       {
    385 	__glibcxx_check_valid_range(__first, __last);
    386 	_Base::append(__gnu_debug::__base(__first),
    387 		      __gnu_debug::__base(__last));
    388 	this->_M_invalidate_all();
    389 	return *this;
    390       }
    391 
    392     // _GLIBCXX_RESOLVE_LIB_DEFECTS
    393     // 7. string clause minor problems
    394     void
    395     push_back(_CharT __c)
    396     {
    397       _Base::push_back(__c);
    398       this->_M_invalidate_all();
    399     }
    400 
    401     basic_string&
    402     assign(const basic_string& __x)
    403     {
    404       _Base::assign(__x);
    405       this->_M_invalidate_all();
    406       return *this;
    407     }
    408 
    409 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    410     basic_string&
    411     assign(basic_string&& __x)
    412     {
    413       _Base::assign(std::move(__x));
    414       this->_M_invalidate_all();
    415       return *this;
    416     }
    417 #endif // __GXX_EXPERIMENTAL_CXX0X__
    418 
    419     basic_string&
    420     assign(const basic_string& __str, size_type __pos, size_type __n)
    421     {
    422       _Base::assign(__str, __pos, __n);
    423       this->_M_invalidate_all();
    424       return *this;
    425     }
    426 
    427     basic_string&
    428     assign(const _CharT* __s, size_type __n)
    429     {
    430       __glibcxx_check_string_len(__s, __n);
    431       _Base::assign(__s, __n);
    432       this->_M_invalidate_all();
    433       return *this;
    434     }
    435 
    436     basic_string&
    437     assign(const _CharT* __s)
    438     {
    439       __glibcxx_check_string(__s);
    440       _Base::assign(__s);
    441       this->_M_invalidate_all();
    442       return *this;
    443     }
    444 
    445     basic_string&
    446     assign(size_type __n, _CharT __c)
    447     {
    448       _Base::assign(__n, __c);
    449       this->_M_invalidate_all();
    450       return *this;
    451     }
    452 
    453     template<typename _InputIterator>
    454       basic_string&
    455       assign(_InputIterator __first, _InputIterator __last)
    456       {
    457 	__glibcxx_check_valid_range(__first, __last);
    458 	_Base::assign(__gnu_debug::__base(__first),
    459 		      __gnu_debug::__base(__last));
    460 	this->_M_invalidate_all();
    461 	return *this;
    462       }
    463 
    464 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    465     basic_string&
    466     assign(std::initializer_list<_CharT> __l)
    467     {
    468       _Base::assign(__l);
    469       this->_M_invalidate_all();
    470       return *this;
    471     }
    472 #endif // __GXX_EXPERIMENTAL_CXX0X__
    473 
    474     basic_string&
    475     insert(size_type __pos1, const basic_string& __str)
    476     {
    477       _Base::insert(__pos1, __str);
    478       this->_M_invalidate_all();
    479       return *this;
    480     }
    481 
    482     basic_string&
    483     insert(size_type __pos1, const basic_string& __str,
    484 	   size_type __pos2, size_type __n)
    485     {
    486       _Base::insert(__pos1, __str, __pos2, __n);
    487       this->_M_invalidate_all();
    488       return *this;
    489     }
    490 
    491     basic_string&
    492     insert(size_type __pos, const _CharT* __s, size_type __n)
    493     {
    494       __glibcxx_check_string(__s);
    495       _Base::insert(__pos, __s, __n);
    496       this->_M_invalidate_all();
    497       return *this;
    498     }
    499 
    500     basic_string&
    501     insert(size_type __pos, const _CharT* __s)
    502     {
    503       __glibcxx_check_string(__s);
    504       _Base::insert(__pos, __s);
    505       this->_M_invalidate_all();
    506       return *this;
    507     }
    508 
    509     basic_string&
    510     insert(size_type __pos, size_type __n, _CharT __c)
    511     {
    512       _Base::insert(__pos, __n, __c);
    513       this->_M_invalidate_all();
    514       return *this;
    515     }
    516 
    517     iterator
    518     insert(iterator __p, _CharT __c)
    519     {
    520       __glibcxx_check_insert(__p);
    521       typename _Base::iterator __res = _Base::insert(__p.base(), __c);
    522       this->_M_invalidate_all();
    523       return iterator(__res, this);
    524     }
    525 
    526     void
    527     insert(iterator __p, size_type __n, _CharT __c)
    528     {
    529       __glibcxx_check_insert(__p);
    530       _Base::insert(__p.base(), __n, __c);
    531       this->_M_invalidate_all();
    532     }
    533 
    534     template<typename _InputIterator>
    535       void
    536       insert(iterator __p, _InputIterator __first, _InputIterator __last)
    537       {
    538 	__glibcxx_check_insert_range(__p, __first, __last);
    539 	_Base::insert(__p.base(), __gnu_debug::__base(__first),
    540 				  __gnu_debug::__base(__last));
    541 	this->_M_invalidate_all();
    542       }
    543 
    544 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    545     void
    546     insert(iterator __p, std::initializer_list<_CharT> __l)
    547     {
    548       __glibcxx_check_insert(__p);
    549       _Base::insert(__p.base(), __l);
    550       this->_M_invalidate_all();
    551     }
    552 #endif // __GXX_EXPERIMENTAL_CXX0X__
    553 
    554     basic_string&
    555     erase(size_type __pos = 0, size_type __n = _Base::npos)
    556     {
    557       _Base::erase(__pos, __n);
    558       this->_M_invalidate_all();
    559       return *this;
    560     }
    561 
    562     iterator
    563     erase(iterator __position)
    564     {
    565       __glibcxx_check_erase(__position);
    566       typename _Base::iterator __res = _Base::erase(__position.base());
    567       this->_M_invalidate_all();
    568       return iterator(__res, this);
    569     }
    570 
    571     iterator
    572     erase(iterator __first, iterator __last)
    573     {
    574       // _GLIBCXX_RESOLVE_LIB_DEFECTS
    575       // 151. can't currently clear() empty container
    576       __glibcxx_check_erase_range(__first, __last);
    577       typename _Base::iterator __res = _Base::erase(__first.base(),
    578 						       __last.base());
    579       this->_M_invalidate_all();
    580       return iterator(__res, this);
    581     }
    582 
    583 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    584     void
    585     pop_back()
    586     {
    587       __glibcxx_check_nonempty();
    588       _Base::pop_back();
    589       this->_M_invalidate_all();
    590     }
    591 #endif // __GXX_EXPERIMENTAL_CXX0X__
    592 
    593     basic_string&
    594     replace(size_type __pos1, size_type __n1, const basic_string& __str)
    595     {
    596       _Base::replace(__pos1, __n1, __str);
    597       this->_M_invalidate_all();
    598       return *this;
    599     }
    600 
    601     basic_string&
    602     replace(size_type __pos1, size_type __n1, const basic_string& __str,
    603 	    size_type __pos2, size_type __n2)
    604     {
    605       _Base::replace(__pos1, __n1, __str, __pos2, __n2);
    606       this->_M_invalidate_all();
    607       return *this;
    608     }
    609 
    610     basic_string&
    611     replace(size_type __pos, size_type __n1, const _CharT* __s,
    612 	    size_type __n2)
    613     {
    614       __glibcxx_check_string_len(__s, __n2);
    615       _Base::replace(__pos, __n1, __s, __n2);
    616       this->_M_invalidate_all();
    617       return *this;
    618     }
    619 
    620     basic_string&
    621     replace(size_type __pos, size_type __n1, const _CharT* __s)
    622     {
    623       __glibcxx_check_string(__s);
    624       _Base::replace(__pos, __n1, __s);
    625       this->_M_invalidate_all();
    626       return *this;
    627     }
    628 
    629     basic_string&
    630     replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
    631     {
    632       _Base::replace(__pos, __n1, __n2, __c);
    633       this->_M_invalidate_all();
    634       return *this;
    635     }
    636 
    637     basic_string&
    638     replace(iterator __i1, iterator __i2, const basic_string& __str)
    639     {
    640       __glibcxx_check_erase_range(__i1, __i2);
    641       _Base::replace(__i1.base(), __i2.base(), __str);
    642       this->_M_invalidate_all();
    643       return *this;
    644     }
    645 
    646     basic_string&
    647     replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n)
    648     {
    649       __glibcxx_check_erase_range(__i1, __i2);
    650       __glibcxx_check_string_len(__s, __n);
    651       _Base::replace(__i1.base(), __i2.base(), __s, __n);
    652       this->_M_invalidate_all();
    653       return *this;
    654     }
    655 
    656     basic_string&
    657     replace(iterator __i1, iterator __i2, const _CharT* __s)
    658     {
    659       __glibcxx_check_erase_range(__i1, __i2);
    660       __glibcxx_check_string(__s);
    661       _Base::replace(__i1.base(), __i2.base(), __s);
    662       this->_M_invalidate_all();
    663       return *this;
    664     }
    665 
    666     basic_string&
    667     replace(iterator __i1, iterator __i2, size_type __n, _CharT __c)
    668     {
    669       __glibcxx_check_erase_range(__i1, __i2);
    670       _Base::replace(__i1.base(), __i2.base(), __n, __c);
    671       this->_M_invalidate_all();
    672       return *this;
    673     }
    674 
    675     template<typename _InputIterator>
    676       basic_string&
    677       replace(iterator __i1, iterator __i2,
    678 	      _InputIterator __j1, _InputIterator __j2)
    679       {
    680 	__glibcxx_check_erase_range(__i1, __i2);
    681 	__glibcxx_check_valid_range(__j1, __j2);
    682 	_Base::replace(__i1.base(), __i2.base(), __j1, __j2);
    683 	this->_M_invalidate_all();
    684 	return *this;
    685       }
    686 
    687 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    688       basic_string& replace(iterator __i1, iterator __i2,
    689 			    std::initializer_list<_CharT> __l)
    690       {
    691 	__glibcxx_check_erase_range(__i1, __i2);
    692 	_Base::replace(__i1.base(), __i2.base(), __l);
    693 	this->_M_invalidate_all();
    694 	return *this;
    695       }
    696 #endif // __GXX_EXPERIMENTAL_CXX0X__
    697 
    698     size_type
    699     copy(_CharT* __s, size_type __n, size_type __pos = 0) const
    700     {
    701       __glibcxx_check_string_len(__s, __n);
    702       return _Base::copy(__s, __n, __pos);
    703     }
    704 
    705     void
    706     swap(basic_string<_CharT,_Traits,_Allocator>& __x)
    707     {
    708       _Base::swap(__x);
    709       this->_M_swap(__x);
    710       this->_M_invalidate_all();
    711       __x._M_invalidate_all();
    712     }
    713 
    714     // 21.3.6 string operations:
    715     const _CharT*
    716     c_str() const _GLIBCXX_NOEXCEPT
    717     {
    718       const _CharT* __res = _Base::c_str();
    719       this->_M_invalidate_all();
    720       return __res;
    721     }
    722 
    723     const _CharT*
    724     data() const _GLIBCXX_NOEXCEPT
    725     {
    726       const _CharT* __res = _Base::data();
    727       this->_M_invalidate_all();
    728       return __res;
    729     }
    730 
    731     using _Base::get_allocator;
    732 
    733     size_type
    734     find(const basic_string& __str, size_type __pos = 0) const
    735       _GLIBCXX_NOEXCEPT
    736     { return _Base::find(__str, __pos); }
    737 
    738     size_type
    739     find(const _CharT* __s, size_type __pos, size_type __n) const
    740     {
    741       __glibcxx_check_string(__s);
    742       return _Base::find(__s, __pos, __n);
    743     }
    744 
    745     size_type
    746     find(const _CharT* __s, size_type __pos = 0) const
    747     {
    748       __glibcxx_check_string(__s);
    749       return _Base::find(__s, __pos);
    750     }
    751 
    752     size_type
    753     find(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
    754     { return _Base::find(__c, __pos); }
    755 
    756     size_type
    757     rfind(const basic_string& __str, size_type __pos = _Base::npos) const
    758       _GLIBCXX_NOEXCEPT
    759     { return _Base::rfind(__str, __pos); }
    760 
    761     size_type
    762     rfind(const _CharT* __s, size_type __pos, size_type __n) const
    763     {
    764       __glibcxx_check_string_len(__s, __n);
    765       return _Base::rfind(__s, __pos, __n);
    766     }
    767 
    768     size_type
    769     rfind(const _CharT* __s, size_type __pos = _Base::npos) const
    770     {
    771       __glibcxx_check_string(__s);
    772       return _Base::rfind(__s, __pos);
    773     }
    774 
    775     size_type
    776     rfind(_CharT __c, size_type __pos = _Base::npos) const _GLIBCXX_NOEXCEPT
    777     { return _Base::rfind(__c, __pos); }
    778 
    779     size_type
    780     find_first_of(const basic_string& __str, size_type __pos = 0) const
    781       _GLIBCXX_NOEXCEPT
    782     { return _Base::find_first_of(__str, __pos); }
    783 
    784     size_type
    785     find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
    786     {
    787       __glibcxx_check_string(__s);
    788       return _Base::find_first_of(__s, __pos, __n);
    789     }
    790 
    791     size_type
    792     find_first_of(const _CharT* __s, size_type __pos = 0) const
    793     {
    794       __glibcxx_check_string(__s);
    795       return _Base::find_first_of(__s, __pos);
    796     }
    797 
    798     size_type
    799     find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
    800     { return _Base::find_first_of(__c, __pos); }
    801 
    802     size_type
    803     find_last_of(const basic_string& __str, 
    804 		 size_type __pos = _Base::npos) const _GLIBCXX_NOEXCEPT
    805     { return _Base::find_last_of(__str, __pos); }
    806 
    807     size_type
    808     find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
    809     {
    810       __glibcxx_check_string(__s);
    811       return _Base::find_last_of(__s, __pos, __n);
    812     }
    813 
    814     size_type
    815     find_last_of(const _CharT* __s, size_type __pos = _Base::npos) const
    816     {
    817       __glibcxx_check_string(__s);
    818       return _Base::find_last_of(__s, __pos);
    819     }
    820 
    821     size_type
    822     find_last_of(_CharT __c, size_type __pos = _Base::npos) const
    823       _GLIBCXX_NOEXCEPT
    824     { return _Base::find_last_of(__c, __pos); }
    825 
    826     size_type
    827     find_first_not_of(const basic_string& __str, size_type __pos = 0) const
    828       _GLIBCXX_NOEXCEPT
    829     { return _Base::find_first_not_of(__str, __pos); }
    830 
    831     size_type
    832     find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
    833     {
    834       __glibcxx_check_string_len(__s, __n);
    835       return _Base::find_first_not_of(__s, __pos, __n);
    836     }
    837 
    838     size_type
    839     find_first_not_of(const _CharT* __s, size_type __pos = 0) const
    840     {
    841       __glibcxx_check_string(__s);
    842       return _Base::find_first_not_of(__s, __pos);
    843     }
    844 
    845     size_type
    846     find_first_not_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
    847     { return _Base::find_first_not_of(__c, __pos); }
    848 
    849     size_type
    850     find_last_not_of(const basic_string& __str,
    851 				  size_type __pos = _Base::npos) const
    852       _GLIBCXX_NOEXCEPT
    853     { return _Base::find_last_not_of(__str, __pos); }
    854 
    855     size_type
    856     find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
    857     {
    858       __glibcxx_check_string(__s);
    859       return _Base::find_last_not_of(__s, __pos, __n);
    860     }
    861 
    862     size_type
    863     find_last_not_of(const _CharT* __s, size_type __pos = _Base::npos) const
    864     {
    865       __glibcxx_check_string(__s);
    866       return _Base::find_last_not_of(__s, __pos);
    867     }
    868 
    869     size_type
    870     find_last_not_of(_CharT __c, size_type __pos = _Base::npos) const
    871       _GLIBCXX_NOEXCEPT
    872     { return _Base::find_last_not_of(__c, __pos); }
    873 
    874     basic_string
    875     substr(size_type __pos = 0, size_type __n = _Base::npos) const
    876     { return basic_string(_Base::substr(__pos, __n)); }
    877 
    878     int
    879     compare(const basic_string& __str) const
    880     { return _Base::compare(__str); }
    881 
    882     int
    883     compare(size_type __pos1, size_type __n1,
    884 		  const basic_string& __str) const
    885     { return _Base::compare(__pos1, __n1, __str); }
    886 
    887     int
    888     compare(size_type __pos1, size_type __n1, const basic_string& __str,
    889 	      size_type __pos2, size_type __n2) const
    890     { return _Base::compare(__pos1, __n1, __str, __pos2, __n2); }
    891 
    892     int
    893     compare(const _CharT* __s) const
    894     {
    895       __glibcxx_check_string(__s);
    896       return _Base::compare(__s);
    897     }
    898 
    899     //  _GLIBCXX_RESOLVE_LIB_DEFECTS
    900     //  5. string::compare specification questionable
    901     int
    902     compare(size_type __pos1, size_type __n1, const _CharT* __s) const
    903     {
    904       __glibcxx_check_string(__s);
    905       return _Base::compare(__pos1, __n1, __s);
    906     }
    907 
    908     //  _GLIBCXX_RESOLVE_LIB_DEFECTS
    909     //  5. string::compare specification questionable
    910     int
    911     compare(size_type __pos1, size_type __n1,const _CharT* __s,
    912 	      size_type __n2) const
    913     {
    914       __glibcxx_check_string_len(__s, __n2);
    915       return _Base::compare(__pos1, __n1, __s, __n2);
    916     }
    917 
    918     _Base&
    919     _M_base() _GLIBCXX_NOEXCEPT       { return *this; }
    920 
    921     const _Base&
    922     _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
    923 
    924     using _Safe_base::_M_invalidate_all;
    925   };
    926 
    927   template<typename _CharT, typename _Traits, typename _Allocator>
    928     inline basic_string<_CharT,_Traits,_Allocator>
    929     operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
    930 	      const basic_string<_CharT,_Traits,_Allocator>& __rhs)
    931     { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
    932 
    933   template<typename _CharT, typename _Traits, typename _Allocator>
    934     inline basic_string<_CharT,_Traits,_Allocator>
    935     operator+(const _CharT* __lhs,
    936 	      const basic_string<_CharT,_Traits,_Allocator>& __rhs)
    937     {
    938       __glibcxx_check_string(__lhs);
    939       return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
    940     }
    941 
    942   template<typename _CharT, typename _Traits, typename _Allocator>
    943     inline basic_string<_CharT,_Traits,_Allocator>
    944     operator+(_CharT __lhs,
    945 	      const basic_string<_CharT,_Traits,_Allocator>& __rhs)
    946     { return basic_string<_CharT,_Traits,_Allocator>(1, __lhs) += __rhs; }
    947 
    948   template<typename _CharT, typename _Traits, typename _Allocator>
    949     inline basic_string<_CharT,_Traits,_Allocator>
    950     operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
    951 	      const _CharT* __rhs)
    952     {
    953       __glibcxx_check_string(__rhs);
    954       return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
    955     }
    956 
    957   template<typename _CharT, typename _Traits, typename _Allocator>
    958     inline basic_string<_CharT,_Traits,_Allocator>
    959     operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
    960 	      _CharT __rhs)
    961     { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
    962 
    963   template<typename _CharT, typename _Traits, typename _Allocator>
    964     inline bool
    965     operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
    966 	       const basic_string<_CharT,_Traits,_Allocator>& __rhs)
    967     { return __lhs._M_base() == __rhs._M_base(); }
    968 
    969   template<typename _CharT, typename _Traits, typename _Allocator>
    970     inline bool
    971     operator==(const _CharT* __lhs,
    972 	       const basic_string<_CharT,_Traits,_Allocator>& __rhs)
    973     {
    974       __glibcxx_check_string(__lhs);
    975       return __lhs == __rhs._M_base();
    976     }
    977 
    978   template<typename _CharT, typename _Traits, typename _Allocator>
    979     inline bool
    980     operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
    981 	       const _CharT* __rhs)
    982     {
    983       __glibcxx_check_string(__rhs);
    984       return __lhs._M_base() == __rhs;
    985     }
    986 
    987   template<typename _CharT, typename _Traits, typename _Allocator>
    988     inline bool
    989     operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
    990 	       const basic_string<_CharT,_Traits,_Allocator>& __rhs)
    991     { return __lhs._M_base() != __rhs._M_base(); }
    992 
    993   template<typename _CharT, typename _Traits, typename _Allocator>
    994     inline bool
    995     operator!=(const _CharT* __lhs,
    996 	       const basic_string<_CharT,_Traits,_Allocator>& __rhs)
    997     {
    998       __glibcxx_check_string(__lhs);
    999       return __lhs != __rhs._M_base();
   1000     }
   1001 
   1002   template<typename _CharT, typename _Traits, typename _Allocator>
   1003     inline bool
   1004     operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
   1005 	       const _CharT* __rhs)
   1006     {
   1007       __glibcxx_check_string(__rhs);
   1008       return __lhs._M_base() != __rhs;
   1009     }
   1010 
   1011   template<typename _CharT, typename _Traits, typename _Allocator>
   1012     inline bool
   1013     operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
   1014 	      const basic_string<_CharT,_Traits,_Allocator>& __rhs)
   1015     { return __lhs._M_base() < __rhs._M_base(); }
   1016 
   1017   template<typename _CharT, typename _Traits, typename _Allocator>
   1018     inline bool
   1019     operator<(const _CharT* __lhs,
   1020 	      const basic_string<_CharT,_Traits,_Allocator>& __rhs)
   1021     {
   1022       __glibcxx_check_string(__lhs);
   1023       return __lhs < __rhs._M_base();
   1024     }
   1025 
   1026   template<typename _CharT, typename _Traits, typename _Allocator>
   1027     inline bool
   1028     operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
   1029 	      const _CharT* __rhs)
   1030     {
   1031       __glibcxx_check_string(__rhs);
   1032       return __lhs._M_base() < __rhs;
   1033     }
   1034 
   1035   template<typename _CharT, typename _Traits, typename _Allocator>
   1036     inline bool
   1037     operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
   1038 	       const basic_string<_CharT,_Traits,_Allocator>& __rhs)
   1039     { return __lhs._M_base() <= __rhs._M_base(); }
   1040 
   1041   template<typename _CharT, typename _Traits, typename _Allocator>
   1042     inline bool
   1043     operator<=(const _CharT* __lhs,
   1044 	       const basic_string<_CharT,_Traits,_Allocator>& __rhs)
   1045     {
   1046       __glibcxx_check_string(__lhs);
   1047       return __lhs <= __rhs._M_base();
   1048     }
   1049 
   1050   template<typename _CharT, typename _Traits, typename _Allocator>
   1051     inline bool
   1052     operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
   1053 	       const _CharT* __rhs)
   1054     {
   1055       __glibcxx_check_string(__rhs);
   1056       return __lhs._M_base() <= __rhs;
   1057     }
   1058 
   1059   template<typename _CharT, typename _Traits, typename _Allocator>
   1060     inline bool
   1061     operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
   1062 	       const basic_string<_CharT,_Traits,_Allocator>& __rhs)
   1063     { return __lhs._M_base() >= __rhs._M_base(); }
   1064 
   1065   template<typename _CharT, typename _Traits, typename _Allocator>
   1066     inline bool
   1067     operator>=(const _CharT* __lhs,
   1068 	       const basic_string<_CharT,_Traits,_Allocator>& __rhs)
   1069     {
   1070       __glibcxx_check_string(__lhs);
   1071       return __lhs >= __rhs._M_base();
   1072     }
   1073 
   1074   template<typename _CharT, typename _Traits, typename _Allocator>
   1075     inline bool
   1076     operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
   1077 	       const _CharT* __rhs)
   1078     {
   1079       __glibcxx_check_string(__rhs);
   1080       return __lhs._M_base() >= __rhs;
   1081     }
   1082 
   1083   template<typename _CharT, typename _Traits, typename _Allocator>
   1084     inline bool
   1085     operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
   1086 	      const basic_string<_CharT,_Traits,_Allocator>& __rhs)
   1087     { return __lhs._M_base() > __rhs._M_base(); }
   1088 
   1089   template<typename _CharT, typename _Traits, typename _Allocator>
   1090     inline bool
   1091     operator>(const _CharT* __lhs,
   1092 	      const basic_string<_CharT,_Traits,_Allocator>& __rhs)
   1093     {
   1094       __glibcxx_check_string(__lhs);
   1095       return __lhs > __rhs._M_base();
   1096     }
   1097 
   1098   template<typename _CharT, typename _Traits, typename _Allocator>
   1099     inline bool
   1100     operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
   1101 	      const _CharT* __rhs)
   1102     {
   1103       __glibcxx_check_string(__rhs);
   1104       return __lhs._M_base() > __rhs;
   1105     }
   1106 
   1107   // 21.3.7.8:
   1108   template<typename _CharT, typename _Traits, typename _Allocator>
   1109     inline void
   1110     swap(basic_string<_CharT,_Traits,_Allocator>& __lhs,
   1111 	 basic_string<_CharT,_Traits,_Allocator>& __rhs)
   1112     { __lhs.swap(__rhs); }
   1113 
   1114   template<typename _CharT, typename _Traits, typename _Allocator>
   1115     std::basic_ostream<_CharT, _Traits>&
   1116     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
   1117 	       const basic_string<_CharT, _Traits, _Allocator>& __str)
   1118     { return __os << __str._M_base(); }
   1119 
   1120   template<typename _CharT, typename _Traits, typename _Allocator>
   1121     std::basic_istream<_CharT,_Traits>&
   1122     operator>>(std::basic_istream<_CharT,_Traits>& __is,
   1123 	       basic_string<_CharT,_Traits,_Allocator>& __str)
   1124     {
   1125       std::basic_istream<_CharT,_Traits>& __res = __is >> __str._M_base();
   1126       __str._M_invalidate_all();
   1127       return __res;
   1128     }
   1129 
   1130   template<typename _CharT, typename _Traits, typename _Allocator>
   1131     std::basic_istream<_CharT,_Traits>&
   1132     getline(std::basic_istream<_CharT,_Traits>& __is,
   1133 	    basic_string<_CharT,_Traits,_Allocator>& __str, _CharT __delim)
   1134     {
   1135       std::basic_istream<_CharT,_Traits>& __res = getline(__is,
   1136 							  __str._M_base(),
   1137 							__delim);
   1138       __str._M_invalidate_all();
   1139       return __res;
   1140     }
   1141 
   1142   template<typename _CharT, typename _Traits, typename _Allocator>
   1143     std::basic_istream<_CharT,_Traits>&
   1144     getline(std::basic_istream<_CharT,_Traits>& __is,
   1145 	    basic_string<_CharT,_Traits,_Allocator>& __str)
   1146     {
   1147       std::basic_istream<_CharT,_Traits>& __res = getline(__is,
   1148 							  __str._M_base());
   1149       __str._M_invalidate_all();
   1150       return __res;
   1151     }
   1152 
   1153   typedef basic_string<char>    string;
   1154 
   1155 #ifdef _GLIBCXX_USE_WCHAR_T
   1156   typedef basic_string<wchar_t> wstring;
   1157 #endif
   1158 
   1159 } // namespace __gnu_debug
   1160 
   1161 #endif
   1162