Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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