Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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