Home | History | Annotate | Download | only in debug
      1 // Debugging string implementation -*- C++ -*-
      2 
      3 // Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
      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), _Safe_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()), _Safe_base()
     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)
    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() { }
    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()
    175     { return iterator(_Base::begin(), this); }
    176 
    177     const_iterator
    178     begin() const
    179     { return const_iterator(_Base::begin(), this); }
    180 
    181     iterator
    182     end()
    183     { return iterator(_Base::end(), this); }
    184 
    185     const_iterator
    186     end() const
    187     { return const_iterator(_Base::end(), this); }
    188 
    189     reverse_iterator
    190     rbegin()
    191     { return reverse_iterator(end()); }
    192 
    193     const_reverse_iterator
    194     rbegin() const
    195     { return const_reverse_iterator(end()); }
    196 
    197     reverse_iterator
    198     rend()
    199     { return reverse_iterator(begin()); }
    200 
    201     const_reverse_iterator
    202     rend() const
    203     { return const_reverse_iterator(begin()); }
    204 
    205     // 21.3.3 capacity:
    206     using _Base::size;
    207     using _Base::length;
    208     using _Base::max_size;
    209 
    210     void
    211     resize(size_type __n, _CharT __c)
    212     {
    213       _Base::resize(__n, __c);
    214       this->_M_invalidate_all();
    215     }
    216 
    217     void
    218     resize(size_type __n)
    219     { this->resize(__n, _CharT()); }
    220 
    221 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    222     using _Base::shrink_to_fit;
    223 #endif
    224 
    225     using _Base::capacity;
    226     using _Base::reserve;
    227 
    228     void
    229     clear()
    230     {
    231       _Base::clear();
    232       this->_M_invalidate_all();
    233     }
    234 
    235     using _Base::empty;
    236 
    237     // 21.3.4 element access:
    238     const_reference
    239     operator[](size_type __pos) const
    240     {
    241       _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(),
    242 			    _M_message(__gnu_debug::__msg_subscript_oob)
    243 			    ._M_sequence(*this, "this")
    244 			    ._M_integer(__pos, "__pos")
    245 			    ._M_integer(this->size(), "size"));
    246       return _M_base()[__pos];
    247     }
    248 
    249     reference
    250     operator[](size_type __pos)
    251     {
    252 #ifdef _GLIBCXX_DEBUG_PEDANTIC
    253       __glibcxx_check_subscript(__pos);
    254 #else
    255       // as an extension v3 allows s[s.size()] when s is non-const.
    256       _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(),
    257 			    _M_message(__gnu_debug::__msg_subscript_oob)
    258 			    ._M_sequence(*this, "this")
    259 			    ._M_integer(__pos, "__pos")
    260 			    ._M_integer(this->size(), "size"));
    261 #endif
    262       return _M_base()[__pos];
    263     }
    264 
    265     using _Base::at;
    266 
    267 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    268     using _Base::front;
    269     using _Base::back;
    270 #endif
    271 
    272     // 21.3.5 modifiers:
    273     basic_string&
    274     operator+=(const basic_string& __str)
    275     {
    276       _M_base() += __str;
    277       this->_M_invalidate_all();
    278       return *this;
    279     }
    280 
    281     basic_string&
    282     operator+=(const _CharT* __s)
    283     {
    284       __glibcxx_check_string(__s);
    285       _M_base() += __s;
    286       this->_M_invalidate_all();
    287       return *this;
    288     }
    289 
    290     basic_string&
    291     operator+=(_CharT __c)
    292     {
    293       _M_base() += __c;
    294       this->_M_invalidate_all();
    295       return *this;
    296     }
    297 
    298 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    299     basic_string&
    300     operator+=(std::initializer_list<_CharT> __l)
    301     {
    302       _M_base() += __l;
    303       this->_M_invalidate_all();
    304       return *this;
    305     }
    306 #endif // __GXX_EXPERIMENTAL_CXX0X__
    307 
    308     basic_string&
    309     append(const basic_string& __str)
    310     {
    311       _Base::append(__str);
    312       this->_M_invalidate_all();
    313       return *this;
    314     }
    315 
    316     basic_string&
    317     append(const basic_string& __str, size_type __pos, size_type __n)
    318     {
    319       _Base::append(__str, __pos, __n);
    320       this->_M_invalidate_all();
    321       return *this;
    322     }
    323 
    324     basic_string&
    325     append(const _CharT* __s, size_type __n)
    326     {
    327       __glibcxx_check_string_len(__s, __n);
    328       _Base::append(__s, __n);
    329       this->_M_invalidate_all();
    330       return *this;
    331     }
    332 
    333     basic_string&
    334     append(const _CharT* __s)
    335     {
    336       __glibcxx_check_string(__s);
    337       _Base::append(__s);
    338       this->_M_invalidate_all();
    339       return *this;
    340     }
    341 
    342     basic_string&
    343     append(size_type __n, _CharT __c)
    344     {
    345       _Base::append(__n, __c);
    346       this->_M_invalidate_all();
    347       return *this;
    348     }
    349 
    350     template<typename _InputIterator>
    351       basic_string&
    352       append(_InputIterator __first, _InputIterator __last)
    353       {
    354 	__glibcxx_check_valid_range(__first, __last);
    355 	_Base::append(__gnu_debug::__base(__first),
    356 		      __gnu_debug::__base(__last));
    357 	this->_M_invalidate_all();
    358 	return *this;
    359       }
    360 
    361     // _GLIBCXX_RESOLVE_LIB_DEFECTS
    362     // 7. string clause minor problems
    363     void
    364     push_back(_CharT __c)
    365     {
    366       _Base::push_back(__c);
    367       this->_M_invalidate_all();
    368     }
    369 
    370     basic_string&
    371     assign(const basic_string& __x)
    372     {
    373       _Base::assign(__x);
    374       this->_M_invalidate_all();
    375       return *this;
    376     }
    377 
    378 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    379     basic_string&
    380     assign(basic_string&& __x)
    381     {
    382       _Base::assign(std::move(__x));
    383       this->_M_invalidate_all();
    384       return *this;
    385     }
    386 #endif // __GXX_EXPERIMENTAL_CXX0X__
    387 
    388     basic_string&
    389     assign(const basic_string& __str, size_type __pos, size_type __n)
    390     {
    391       _Base::assign(__str, __pos, __n);
    392       this->_M_invalidate_all();
    393       return *this;
    394     }
    395 
    396     basic_string&
    397     assign(const _CharT* __s, size_type __n)
    398     {
    399       __glibcxx_check_string_len(__s, __n);
    400       _Base::assign(__s, __n);
    401       this->_M_invalidate_all();
    402       return *this;
    403     }
    404 
    405     basic_string&
    406     assign(const _CharT* __s)
    407     {
    408       __glibcxx_check_string(__s);
    409       _Base::assign(__s);
    410       this->_M_invalidate_all();
    411       return *this;
    412     }
    413 
    414     basic_string&
    415     assign(size_type __n, _CharT __c)
    416     {
    417       _Base::assign(__n, __c);
    418       this->_M_invalidate_all();
    419       return *this;
    420     }
    421 
    422     template<typename _InputIterator>
    423       basic_string&
    424       assign(_InputIterator __first, _InputIterator __last)
    425       {
    426 	__glibcxx_check_valid_range(__first, __last);
    427 	_Base::assign(__gnu_debug::__base(__first),
    428 		      __gnu_debug::__base(__last));
    429 	this->_M_invalidate_all();
    430 	return *this;
    431       }
    432 
    433 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    434     basic_string&
    435     assign(std::initializer_list<_CharT> __l)
    436     {
    437       _Base::assign(__l);
    438       this->_M_invalidate_all();
    439       return *this;
    440     }
    441 #endif // __GXX_EXPERIMENTAL_CXX0X__
    442 
    443     basic_string&
    444     insert(size_type __pos1, const basic_string& __str)
    445     {
    446       _Base::insert(__pos1, __str);
    447       this->_M_invalidate_all();
    448       return *this;
    449     }
    450 
    451     basic_string&
    452     insert(size_type __pos1, const basic_string& __str,
    453 	   size_type __pos2, size_type __n)
    454     {
    455       _Base::insert(__pos1, __str, __pos2, __n);
    456       this->_M_invalidate_all();
    457       return *this;
    458     }
    459 
    460     basic_string&
    461     insert(size_type __pos, const _CharT* __s, size_type __n)
    462     {
    463       __glibcxx_check_string(__s);
    464       _Base::insert(__pos, __s, __n);
    465       this->_M_invalidate_all();
    466       return *this;
    467     }
    468 
    469     basic_string&
    470     insert(size_type __pos, const _CharT* __s)
    471     {
    472       __glibcxx_check_string(__s);
    473       _Base::insert(__pos, __s);
    474       this->_M_invalidate_all();
    475       return *this;
    476     }
    477 
    478     basic_string&
    479     insert(size_type __pos, size_type __n, _CharT __c)
    480     {
    481       _Base::insert(__pos, __n, __c);
    482       this->_M_invalidate_all();
    483       return *this;
    484     }
    485 
    486     iterator
    487     insert(iterator __p, _CharT __c)
    488     {
    489       __glibcxx_check_insert(__p);
    490       typename _Base::iterator __res = _Base::insert(__p.base(), __c);
    491       this->_M_invalidate_all();
    492       return iterator(__res, this);
    493     }
    494 
    495     void
    496     insert(iterator __p, size_type __n, _CharT __c)
    497     {
    498       __glibcxx_check_insert(__p);
    499       _Base::insert(__p.base(), __n, __c);
    500       this->_M_invalidate_all();
    501     }
    502 
    503     template<typename _InputIterator>
    504       void
    505       insert(iterator __p, _InputIterator __first, _InputIterator __last)
    506       {
    507 	__glibcxx_check_insert_range(__p, __first, __last);
    508 	_Base::insert(__p.base(), __gnu_debug::__base(__first),
    509 				  __gnu_debug::__base(__last));
    510 	this->_M_invalidate_all();
    511       }
    512 
    513 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    514     void
    515     insert(iterator __p, std::initializer_list<_CharT> __l)
    516     {
    517       __glibcxx_check_insert(__p);
    518       _Base::insert(__p.base(), __l);
    519       this->_M_invalidate_all();
    520     }
    521 #endif // __GXX_EXPERIMENTAL_CXX0X__
    522 
    523     basic_string&
    524     erase(size_type __pos = 0, size_type __n = _Base::npos)
    525     {
    526       _Base::erase(__pos, __n);
    527       this->_M_invalidate_all();
    528       return *this;
    529     }
    530 
    531     iterator
    532     erase(iterator __position)
    533     {
    534       __glibcxx_check_erase(__position);
    535       typename _Base::iterator __res = _Base::erase(__position.base());
    536       this->_M_invalidate_all();
    537       return iterator(__res, this);
    538     }
    539 
    540     iterator
    541     erase(iterator __first, iterator __last)
    542     {
    543       // _GLIBCXX_RESOLVE_LIB_DEFECTS
    544       // 151. can't currently clear() empty container
    545       __glibcxx_check_erase_range(__first, __last);
    546       typename _Base::iterator __res = _Base::erase(__first.base(),
    547 						       __last.base());
    548       this->_M_invalidate_all();
    549       return iterator(__res, this);
    550     }
    551 
    552     basic_string&
    553     replace(size_type __pos1, size_type __n1, const basic_string& __str)
    554     {
    555       _Base::replace(__pos1, __n1, __str);
    556       this->_M_invalidate_all();
    557       return *this;
    558     }
    559 
    560     basic_string&
    561     replace(size_type __pos1, size_type __n1, const basic_string& __str,
    562 	    size_type __pos2, size_type __n2)
    563     {
    564       _Base::replace(__pos1, __n1, __str, __pos2, __n2);
    565       this->_M_invalidate_all();
    566       return *this;
    567     }
    568 
    569     basic_string&
    570     replace(size_type __pos, size_type __n1, const _CharT* __s,
    571 	    size_type __n2)
    572     {
    573       __glibcxx_check_string_len(__s, __n2);
    574       _Base::replace(__pos, __n1, __s, __n2);
    575       this->_M_invalidate_all();
    576       return *this;
    577     }
    578 
    579     basic_string&
    580     replace(size_type __pos, size_type __n1, const _CharT* __s)
    581     {
    582       __glibcxx_check_string(__s);
    583       _Base::replace(__pos, __n1, __s);
    584       this->_M_invalidate_all();
    585       return *this;
    586     }
    587 
    588     basic_string&
    589     replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
    590     {
    591       _Base::replace(__pos, __n1, __n2, __c);
    592       this->_M_invalidate_all();
    593       return *this;
    594     }
    595 
    596     basic_string&
    597     replace(iterator __i1, iterator __i2, const basic_string& __str)
    598     {
    599       __glibcxx_check_erase_range(__i1, __i2);
    600       _Base::replace(__i1.base(), __i2.base(), __str);
    601       this->_M_invalidate_all();
    602       return *this;
    603     }
    604 
    605     basic_string&
    606     replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n)
    607     {
    608       __glibcxx_check_erase_range(__i1, __i2);
    609       __glibcxx_check_string_len(__s, __n);
    610       _Base::replace(__i1.base(), __i2.base(), __s, __n);
    611       this->_M_invalidate_all();
    612       return *this;
    613     }
    614 
    615     basic_string&
    616     replace(iterator __i1, iterator __i2, const _CharT* __s)
    617     {
    618       __glibcxx_check_erase_range(__i1, __i2);
    619       __glibcxx_check_string(__s);
    620       _Base::replace(__i1.base(), __i2.base(), __s);
    621       this->_M_invalidate_all();
    622       return *this;
    623     }
    624 
    625     basic_string&
    626     replace(iterator __i1, iterator __i2, size_type __n, _CharT __c)
    627     {
    628       __glibcxx_check_erase_range(__i1, __i2);
    629       _Base::replace(__i1.base(), __i2.base(), __n, __c);
    630       this->_M_invalidate_all();
    631       return *this;
    632     }
    633 
    634     template<typename _InputIterator>
    635       basic_string&
    636       replace(iterator __i1, iterator __i2,
    637 	      _InputIterator __j1, _InputIterator __j2)
    638       {
    639 	__glibcxx_check_erase_range(__i1, __i2);
    640 	__glibcxx_check_valid_range(__j1, __j2);
    641 	_Base::replace(__i1.base(), __i2.base(), __j1, __j2);
    642 	this->_M_invalidate_all();
    643 	return *this;
    644       }
    645 
    646 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    647       basic_string& replace(iterator __i1, iterator __i2,
    648 			    std::initializer_list<_CharT> __l)
    649       {
    650 	__glibcxx_check_erase_range(__i1, __i2);
    651 	_Base::replace(__i1.base(), __i2.base(), __l);
    652 	this->_M_invalidate_all();
    653 	return *this;
    654       }
    655 #endif // __GXX_EXPERIMENTAL_CXX0X__
    656 
    657     size_type
    658     copy(_CharT* __s, size_type __n, size_type __pos = 0) const
    659     {
    660       __glibcxx_check_string_len(__s, __n);
    661       return _Base::copy(__s, __n, __pos);
    662     }
    663 
    664     void
    665     swap(basic_string<_CharT,_Traits,_Allocator>& __x)
    666     {
    667       _Base::swap(__x);
    668       this->_M_swap(__x);
    669       this->_M_invalidate_all();
    670       __x._M_invalidate_all();
    671     }
    672 
    673     // 21.3.6 string operations:
    674     const _CharT*
    675     c_str() const
    676     {
    677       const _CharT* __res = _Base::c_str();
    678       this->_M_invalidate_all();
    679       return __res;
    680     }
    681 
    682     const _CharT*
    683     data() const
    684     {
    685       const _CharT* __res = _Base::data();
    686       this->_M_invalidate_all();
    687       return __res;
    688     }
    689 
    690     using _Base::get_allocator;
    691 
    692     size_type
    693     find(const basic_string& __str, size_type __pos = 0) const
    694     { return _Base::find(__str, __pos); }
    695 
    696     size_type
    697     find(const _CharT* __s, size_type __pos, size_type __n) const
    698     {
    699       __glibcxx_check_string(__s);
    700       return _Base::find(__s, __pos, __n);
    701     }
    702 
    703     size_type
    704     find(const _CharT* __s, size_type __pos = 0) const
    705     {
    706       __glibcxx_check_string(__s);
    707       return _Base::find(__s, __pos);
    708     }
    709 
    710     size_type
    711     find(_CharT __c, size_type __pos = 0) const
    712     { return _Base::find(__c, __pos); }
    713 
    714     size_type
    715     rfind(const basic_string& __str, size_type __pos = _Base::npos) const
    716     { return _Base::rfind(__str, __pos); }
    717 
    718     size_type
    719     rfind(const _CharT* __s, size_type __pos, size_type __n) const
    720     {
    721       __glibcxx_check_string_len(__s, __n);
    722       return _Base::rfind(__s, __pos, __n);
    723     }
    724 
    725     size_type
    726     rfind(const _CharT* __s, size_type __pos = _Base::npos) const
    727     {
    728       __glibcxx_check_string(__s);
    729       return _Base::rfind(__s, __pos);
    730     }
    731 
    732     size_type
    733     rfind(_CharT __c, size_type __pos = _Base::npos) const
    734     { return _Base::rfind(__c, __pos); }
    735 
    736     size_type
    737     find_first_of(const basic_string& __str, size_type __pos = 0) const
    738     { return _Base::find_first_of(__str, __pos); }
    739 
    740     size_type
    741     find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
    742     {
    743       __glibcxx_check_string(__s);
    744       return _Base::find_first_of(__s, __pos, __n);
    745     }
    746 
    747     size_type
    748     find_first_of(const _CharT* __s, size_type __pos = 0) const
    749     {
    750       __glibcxx_check_string(__s);
    751       return _Base::find_first_of(__s, __pos);
    752     }
    753 
    754     size_type
    755     find_first_of(_CharT __c, size_type __pos = 0) const
    756     { return _Base::find_first_of(__c, __pos); }
    757 
    758     size_type
    759     find_last_of(const basic_string& __str, 
    760 		 size_type __pos = _Base::npos) const
    761     { return _Base::find_last_of(__str, __pos); }
    762 
    763     size_type
    764     find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
    765     {
    766       __glibcxx_check_string(__s);
    767       return _Base::find_last_of(__s, __pos, __n);
    768     }
    769 
    770     size_type
    771     find_last_of(const _CharT* __s, size_type __pos = _Base::npos) const
    772     {
    773       __glibcxx_check_string(__s);
    774       return _Base::find_last_of(__s, __pos);
    775     }
    776 
    777     size_type
    778     find_last_of(_CharT __c, size_type __pos = _Base::npos) const
    779     { return _Base::find_last_of(__c, __pos); }
    780 
    781     size_type
    782     find_first_not_of(const basic_string& __str, size_type __pos = 0) const
    783     { return _Base::find_first_not_of(__str, __pos); }
    784 
    785     size_type
    786     find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
    787     {
    788       __glibcxx_check_string_len(__s, __n);
    789       return _Base::find_first_not_of(__s, __pos, __n);
    790     }
    791 
    792     size_type
    793     find_first_not_of(const _CharT* __s, size_type __pos = 0) const
    794     {
    795       __glibcxx_check_string(__s);
    796       return _Base::find_first_not_of(__s, __pos);
    797     }
    798 
    799     size_type
    800     find_first_not_of(_CharT __c, size_type __pos = 0) const
    801     { return _Base::find_first_not_of(__c, __pos); }
    802 
    803     size_type
    804     find_last_not_of(const basic_string& __str,
    805 				  size_type __pos = _Base::npos) const
    806     { return _Base::find_last_not_of(__str, __pos); }
    807 
    808     size_type
    809     find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
    810     {
    811       __glibcxx_check_string(__s);
    812       return _Base::find_last_not_of(__s, __pos, __n);
    813     }
    814 
    815     size_type
    816     find_last_not_of(const _CharT* __s, size_type __pos = _Base::npos) const
    817     {
    818       __glibcxx_check_string(__s);
    819       return _Base::find_last_not_of(__s, __pos);
    820     }
    821 
    822     size_type
    823     find_last_not_of(_CharT __c, size_type __pos = _Base::npos) const
    824     { return _Base::find_last_not_of(__c, __pos); }
    825 
    826     basic_string
    827     substr(size_type __pos = 0, size_type __n = _Base::npos) const
    828     { return basic_string(_Base::substr(__pos, __n)); }
    829 
    830     int
    831     compare(const basic_string& __str) const
    832     { return _Base::compare(__str); }
    833 
    834     int
    835     compare(size_type __pos1, size_type __n1,
    836 		  const basic_string& __str) const
    837     { return _Base::compare(__pos1, __n1, __str); }
    838 
    839     int
    840     compare(size_type __pos1, size_type __n1, const basic_string& __str,
    841 	      size_type __pos2, size_type __n2) const
    842     { return _Base::compare(__pos1, __n1, __str, __pos2, __n2); }
    843 
    844     int
    845     compare(const _CharT* __s) const
    846     {
    847       __glibcxx_check_string(__s);
    848       return _Base::compare(__s);
    849     }
    850 
    851     //  _GLIBCXX_RESOLVE_LIB_DEFECTS
    852     //  5. string::compare specification questionable
    853     int
    854     compare(size_type __pos1, size_type __n1, const _CharT* __s) const
    855     {
    856       __glibcxx_check_string(__s);
    857       return _Base::compare(__pos1, __n1, __s);
    858     }
    859 
    860     //  _GLIBCXX_RESOLVE_LIB_DEFECTS
    861     //  5. string::compare specification questionable
    862     int
    863     compare(size_type __pos1, size_type __n1,const _CharT* __s,
    864 	      size_type __n2) const
    865     {
    866       __glibcxx_check_string_len(__s, __n2);
    867       return _Base::compare(__pos1, __n1, __s, __n2);
    868     }
    869 
    870     _Base&
    871     _M_base() { return *this; }
    872 
    873     const _Base&
    874     _M_base() const { return *this; }
    875 
    876     using _Safe_base::_M_invalidate_all;
    877   };
    878 
    879   template<typename _CharT, typename _Traits, typename _Allocator>
    880     inline basic_string<_CharT,_Traits,_Allocator>
    881     operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
    882 	      const basic_string<_CharT,_Traits,_Allocator>& __rhs)
    883     { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
    884 
    885   template<typename _CharT, typename _Traits, typename _Allocator>
    886     inline basic_string<_CharT,_Traits,_Allocator>
    887     operator+(const _CharT* __lhs,
    888 	      const basic_string<_CharT,_Traits,_Allocator>& __rhs)
    889     {
    890       __glibcxx_check_string(__lhs);
    891       return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
    892     }
    893 
    894   template<typename _CharT, typename _Traits, typename _Allocator>
    895     inline basic_string<_CharT,_Traits,_Allocator>
    896     operator+(_CharT __lhs,
    897 	      const basic_string<_CharT,_Traits,_Allocator>& __rhs)
    898     { return basic_string<_CharT,_Traits,_Allocator>(1, __lhs) += __rhs; }
    899 
    900   template<typename _CharT, typename _Traits, typename _Allocator>
    901     inline basic_string<_CharT,_Traits,_Allocator>
    902     operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
    903 	      const _CharT* __rhs)
    904     {
    905       __glibcxx_check_string(__rhs);
    906       return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
    907     }
    908 
    909   template<typename _CharT, typename _Traits, typename _Allocator>
    910     inline basic_string<_CharT,_Traits,_Allocator>
    911     operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
    912 	      _CharT __rhs)
    913     { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
    914 
    915   template<typename _CharT, typename _Traits, typename _Allocator>
    916     inline bool
    917     operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
    918 	       const basic_string<_CharT,_Traits,_Allocator>& __rhs)
    919     { return __lhs._M_base() == __rhs._M_base(); }
    920 
    921   template<typename _CharT, typename _Traits, typename _Allocator>
    922     inline bool
    923     operator==(const _CharT* __lhs,
    924 	       const basic_string<_CharT,_Traits,_Allocator>& __rhs)
    925     {
    926       __glibcxx_check_string(__lhs);
    927       return __lhs == __rhs._M_base();
    928     }
    929 
    930   template<typename _CharT, typename _Traits, typename _Allocator>
    931     inline bool
    932     operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
    933 	       const _CharT* __rhs)
    934     {
    935       __glibcxx_check_string(__rhs);
    936       return __lhs._M_base() == __rhs;
    937     }
    938 
    939   template<typename _CharT, typename _Traits, typename _Allocator>
    940     inline bool
    941     operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
    942 	       const basic_string<_CharT,_Traits,_Allocator>& __rhs)
    943     { return __lhs._M_base() != __rhs._M_base(); }
    944 
    945   template<typename _CharT, typename _Traits, typename _Allocator>
    946     inline bool
    947     operator!=(const _CharT* __lhs,
    948 	       const basic_string<_CharT,_Traits,_Allocator>& __rhs)
    949     {
    950       __glibcxx_check_string(__lhs);
    951       return __lhs != __rhs._M_base();
    952     }
    953 
    954   template<typename _CharT, typename _Traits, typename _Allocator>
    955     inline bool
    956     operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
    957 	       const _CharT* __rhs)
    958     {
    959       __glibcxx_check_string(__rhs);
    960       return __lhs._M_base() != __rhs;
    961     }
    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   // 21.3.7.8:
   1060   template<typename _CharT, typename _Traits, typename _Allocator>
   1061     inline void
   1062     swap(basic_string<_CharT,_Traits,_Allocator>& __lhs,
   1063 	 basic_string<_CharT,_Traits,_Allocator>& __rhs)
   1064     { __lhs.swap(__rhs); }
   1065 
   1066   template<typename _CharT, typename _Traits, typename _Allocator>
   1067     std::basic_ostream<_CharT, _Traits>&
   1068     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
   1069 	       const basic_string<_CharT, _Traits, _Allocator>& __str)
   1070     { return __os << __str._M_base(); }
   1071 
   1072   template<typename _CharT, typename _Traits, typename _Allocator>
   1073     std::basic_istream<_CharT,_Traits>&
   1074     operator>>(std::basic_istream<_CharT,_Traits>& __is,
   1075 	       basic_string<_CharT,_Traits,_Allocator>& __str)
   1076     {
   1077       std::basic_istream<_CharT,_Traits>& __res = __is >> __str._M_base();
   1078       __str._M_invalidate_all();
   1079       return __res;
   1080     }
   1081 
   1082   template<typename _CharT, typename _Traits, typename _Allocator>
   1083     std::basic_istream<_CharT,_Traits>&
   1084     getline(std::basic_istream<_CharT,_Traits>& __is,
   1085 	    basic_string<_CharT,_Traits,_Allocator>& __str, _CharT __delim)
   1086     {
   1087       std::basic_istream<_CharT,_Traits>& __res = getline(__is,
   1088 							  __str._M_base(),
   1089 							__delim);
   1090       __str._M_invalidate_all();
   1091       return __res;
   1092     }
   1093 
   1094   template<typename _CharT, typename _Traits, typename _Allocator>
   1095     std::basic_istream<_CharT,_Traits>&
   1096     getline(std::basic_istream<_CharT,_Traits>& __is,
   1097 	    basic_string<_CharT,_Traits,_Allocator>& __str)
   1098     {
   1099       std::basic_istream<_CharT,_Traits>& __res = getline(__is,
   1100 							  __str._M_base());
   1101       __str._M_invalidate_all();
   1102       return __res;
   1103     }
   1104 
   1105   typedef basic_string<char>    string;
   1106 
   1107 #ifdef _GLIBCXX_USE_WCHAR_T
   1108   typedef basic_string<wchar_t> wstring;
   1109 #endif
   1110 
   1111 } // namespace __gnu_debug
   1112 
   1113 #endif
   1114