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