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