1 // Components for manipulating sequences of characters -*- C++ -*-
 
    3 // Copyright (C) 1997-2014 Free Software Foundation, Inc.
 
    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)
 
   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.
 
   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.
 
   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/>.
 
   25 /** @file bits/basic_string.tcc
 
   26  *  This is an internal header file, included by other library headers.
 
   27  *  Do not attempt to use it directly. @headername{string}
 
   31 // ISO C++ 14882: 21  Strings library
 
   34 // Written by Jason Merrill based upon the specification by Takanori Adachi
 
   35 // in ANSI X3J16/94-0013R2.  Rewritten by Nathan Myers to ISO-14882.
 
   37 #ifndef _BASIC_STRING_TCC
 
   38 #define _BASIC_STRING_TCC 1
 
   40 #pragma GCC system_header
 
   42 #include <bits/cxxabi_forced.h>
 
   44 namespace std _GLIBCXX_VISIBILITY(default)
 
   46 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   48   template<typename _CharT, typename _Traits, typename _Alloc>
 
   49     const typename basic_string<_CharT, _Traits, _Alloc>::size_type
 
   50     basic_string<_CharT, _Traits, _Alloc>::
 
   51     _Rep::_S_max_size = (((npos - sizeof(_Rep_base))/sizeof(_CharT)) - 1) / 4;
 
   53   template<typename _CharT, typename _Traits, typename _Alloc>
 
   55     basic_string<_CharT, _Traits, _Alloc>::
 
   56     _Rep::_S_terminal = _CharT();
 
   58   template<typename _CharT, typename _Traits, typename _Alloc>
 
   59     const typename basic_string<_CharT, _Traits, _Alloc>::size_type
 
   60     basic_string<_CharT, _Traits, _Alloc>::npos;
 
   62   // Linker sets _S_empty_rep_storage to all 0s (one reference, empty string)
 
   63   // at static init time (before static ctors are run).
 
   64   template<typename _CharT, typename _Traits, typename _Alloc>
 
   65     typename basic_string<_CharT, _Traits, _Alloc>::size_type
 
   66     basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_empty_rep_storage[
 
   67     (sizeof(_Rep_base) + sizeof(_CharT) + sizeof(size_type) - 1) /
 
   70   // NB: This is the special case for Input Iterators, used in
 
   71   // istreambuf_iterators, etc.
 
   72   // Input Iterators have a cost structure very different from
 
   73   // pointers, calling for a different coding style.
 
   74   template<typename _CharT, typename _Traits, typename _Alloc>
 
   75     template<typename _InIterator>
 
   77       basic_string<_CharT, _Traits, _Alloc>::
 
   78       _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a,
 
   81 #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
 
   82    if (__beg == __end && __a == _Alloc())
 
   83      return _S_empty_rep()._M_refdata();
 
   85    // Avoid reallocation for common case.
 
   88    while (__beg != __end && __len < sizeof(__buf) / sizeof(_CharT))
 
   90        __buf[__len++] = *__beg;
 
   93    _Rep* __r = _Rep::_S_create(__len, size_type(0), __a);
 
   94    _M_copy(__r->_M_refdata(), __buf, __len);
 
   97        while (__beg != __end)
 
   99        if (__len == __r->_M_capacity)
 
  101            // Allocate more space.
 
  102            _Rep* __another = _Rep::_S_create(__len + 1, __len, __a);
 
  103            _M_copy(__another->_M_refdata(), __r->_M_refdata(), __len);
 
  104            __r->_M_destroy(__a);
 
  107        __r->_M_refdata()[__len++] = *__beg;
 
  113        __r->_M_destroy(__a);
 
  114        __throw_exception_again;
 
  116    __r->_M_set_length_and_sharable(__len);
 
  117    return __r->_M_refdata();
 
  120   template<typename _CharT, typename _Traits, typename _Alloc>
 
  121     template <typename _InIterator>
 
  123       basic_string<_CharT, _Traits, _Alloc>::
 
  124       _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a,
 
  125           forward_iterator_tag)
 
  127 #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
 
  128    if (__beg == __end && __a == _Alloc())
 
  129      return _S_empty_rep()._M_refdata();
 
  131    // NB: Not required, but considered best practice.
 
  132    if (__gnu_cxx::__is_null_pointer(__beg) && __beg != __end)
 
  133      __throw_logic_error(__N("basic_string::_S_construct null not valid"));
 
  135    const size_type __dnew = static_cast<size_type>(std::distance(__beg,
 
  137    // Check for out_of_range and length_error exceptions.
 
  138    _Rep* __r = _Rep::_S_create(__dnew, size_type(0), __a);
 
  140      { _S_copy_chars(__r->_M_refdata(), __beg, __end); }
 
  143        __r->_M_destroy(__a);
 
  144        __throw_exception_again;
 
  146    __r->_M_set_length_and_sharable(__dnew);
 
  147    return __r->_M_refdata();
 
  150   template<typename _CharT, typename _Traits, typename _Alloc>
 
  152     basic_string<_CharT, _Traits, _Alloc>::
 
  153     _S_construct(size_type __n, _CharT __c, const _Alloc& __a)
 
  155 #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
 
  156       if (__n == 0 && __a == _Alloc())
 
  157    return _S_empty_rep()._M_refdata();
 
  159       // Check for out_of_range and length_error exceptions.
 
  160       _Rep* __r = _Rep::_S_create(__n, size_type(0), __a);
 
  162    _M_assign(__r->_M_refdata(), __n, __c);
 
  164       __r->_M_set_length_and_sharable(__n);
 
  165       return __r->_M_refdata();
 
  168   template<typename _CharT, typename _Traits, typename _Alloc>
 
  169     basic_string<_CharT, _Traits, _Alloc>::
 
  170     basic_string(const basic_string& __str)
 
  171     : _M_dataplus(__str._M_rep()->_M_grab(_Alloc(__str.get_allocator()),
 
  172                      __str.get_allocator()),
 
  173          __str.get_allocator())
 
  176   template<typename _CharT, typename _Traits, typename _Alloc>
 
  177     basic_string<_CharT, _Traits, _Alloc>::
 
  178     basic_string(const _Alloc& __a)
 
  179     : _M_dataplus(_S_construct(size_type(), _CharT(), __a), __a)
 
  182   template<typename _CharT, typename _Traits, typename _Alloc>
 
  183     basic_string<_CharT, _Traits, _Alloc>::
 
  184     basic_string(const basic_string& __str, size_type __pos, size_type __n)
 
  185     : _M_dataplus(_S_construct(__str._M_data()
 
  186                   + __str._M_check(__pos,
 
  187                        "basic_string::basic_string"),
 
  188                   __str._M_data() + __str._M_limit(__pos, __n)
 
  189                   + __pos, _Alloc()), _Alloc())
 
  192   template<typename _CharT, typename _Traits, typename _Alloc>
 
  193     basic_string<_CharT, _Traits, _Alloc>::
 
  194     basic_string(const basic_string& __str, size_type __pos,
 
  195         size_type __n, const _Alloc& __a)
 
  196     : _M_dataplus(_S_construct(__str._M_data()
 
  197                   + __str._M_check(__pos,
 
  198                        "basic_string::basic_string"),
 
  199                   __str._M_data() + __str._M_limit(__pos, __n)
 
  204   template<typename _CharT, typename _Traits, typename _Alloc>
 
  205     basic_string<_CharT, _Traits, _Alloc>::
 
  206     basic_string(const _CharT* __s, size_type __n, const _Alloc& __a)
 
  207     : _M_dataplus(_S_construct(__s, __s + __n, __a), __a)
 
  211   template<typename _CharT, typename _Traits, typename _Alloc>
 
  212     basic_string<_CharT, _Traits, _Alloc>::
 
  213     basic_string(const _CharT* __s, const _Alloc& __a)
 
  214     : _M_dataplus(_S_construct(__s, __s ? __s + traits_type::length(__s) :
 
  215                   __s + npos, __a), __a)
 
  218   template<typename _CharT, typename _Traits, typename _Alloc>
 
  219     basic_string<_CharT, _Traits, _Alloc>::
 
  220     basic_string(size_type __n, _CharT __c, const _Alloc& __a)
 
  221     : _M_dataplus(_S_construct(__n, __c, __a), __a)
 
  225   template<typename _CharT, typename _Traits, typename _Alloc>
 
  226     template<typename _InputIterator>
 
  227     basic_string<_CharT, _Traits, _Alloc>::
 
  228     basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a)
 
  229     : _M_dataplus(_S_construct(__beg, __end, __a), __a)
 
  232 #if __cplusplus >= 201103L
 
  233   template<typename _CharT, typename _Traits, typename _Alloc>
 
  234     basic_string<_CharT, _Traits, _Alloc>::
 
  235     basic_string(initializer_list<_CharT> __l, const _Alloc& __a)
 
  236     : _M_dataplus(_S_construct(__l.begin(), __l.end(), __a), __a)
 
  240   template<typename _CharT, typename _Traits, typename _Alloc>
 
  241     basic_string<_CharT, _Traits, _Alloc>&
 
  242     basic_string<_CharT, _Traits, _Alloc>::
 
  243     assign(const basic_string& __str)
 
  245       if (_M_rep() != __str._M_rep())
 
  248      const allocator_type __a = this->get_allocator();
 
  249      _CharT* __tmp = __str._M_rep()->_M_grab(__a, __str.get_allocator());
 
  250      _M_rep()->_M_dispose(__a);
 
  256   template<typename _CharT, typename _Traits, typename _Alloc>
 
  257     basic_string<_CharT, _Traits, _Alloc>&
 
  258     basic_string<_CharT, _Traits, _Alloc>::
 
  259     assign(const _CharT* __s, size_type __n)
 
  261       __glibcxx_requires_string_len(__s, __n);
 
  262       _M_check_length(this->size(), __n, "basic_string::assign");
 
  263       if (_M_disjunct(__s) || _M_rep()->_M_is_shared())
 
  264    return _M_replace_safe(size_type(0), this->size(), __s, __n);
 
  268      const size_type __pos = __s - _M_data();
 
  270        _M_copy(_M_data(), __s, __n);
 
  272        _M_move(_M_data(), __s, __n);
 
  273      _M_rep()->_M_set_length_and_sharable(__n);
 
  278   template<typename _CharT, typename _Traits, typename _Alloc>
 
  279     basic_string<_CharT, _Traits, _Alloc>&
 
  280     basic_string<_CharT, _Traits, _Alloc>::
 
  281     append(size_type __n, _CharT __c)
 
  285      _M_check_length(size_type(0), __n, "basic_string::append");     
 
  286      const size_type __len = __n + this->size();
 
  287      if (__len > this->capacity() || _M_rep()->_M_is_shared())
 
  288        this->reserve(__len);
 
  289      _M_assign(_M_data() + this->size(), __n, __c);
 
  290      _M_rep()->_M_set_length_and_sharable(__len);
 
  295   template<typename _CharT, typename _Traits, typename _Alloc>
 
  296     basic_string<_CharT, _Traits, _Alloc>&
 
  297     basic_string<_CharT, _Traits, _Alloc>::
 
  298     append(const _CharT* __s, size_type __n)
 
  300       __glibcxx_requires_string_len(__s, __n);
 
  303      _M_check_length(size_type(0), __n, "basic_string::append");
 
  304      const size_type __len = __n + this->size();
 
  305      if (__len > this->capacity() || _M_rep()->_M_is_shared())
 
  307          if (_M_disjunct(__s))
 
  308        this->reserve(__len);
 
  311          const size_type __off = __s - _M_data();
 
  312          this->reserve(__len);
 
  313          __s = _M_data() + __off;
 
  316      _M_copy(_M_data() + this->size(), __s, __n);
 
  317      _M_rep()->_M_set_length_and_sharable(__len);
 
  322   template<typename _CharT, typename _Traits, typename _Alloc>
 
  323     basic_string<_CharT, _Traits, _Alloc>&
 
  324     basic_string<_CharT, _Traits, _Alloc>::
 
  325     append(const basic_string& __str)
 
  327       const size_type __size = __str.size();
 
  330      const size_type __len = __size + this->size();
 
  331      if (__len > this->capacity() || _M_rep()->_M_is_shared())
 
  332        this->reserve(__len);
 
  333      _M_copy(_M_data() + this->size(), __str._M_data(), __size);
 
  334      _M_rep()->_M_set_length_and_sharable(__len);
 
  339   template<typename _CharT, typename _Traits, typename _Alloc>
 
  340     basic_string<_CharT, _Traits, _Alloc>&
 
  341     basic_string<_CharT, _Traits, _Alloc>::
 
  342     append(const basic_string& __str, size_type __pos, size_type __n)
 
  344       __str._M_check(__pos, "basic_string::append");
 
  345       __n = __str._M_limit(__pos, __n);
 
  348      const size_type __len = __n + this->size();
 
  349      if (__len > this->capacity() || _M_rep()->_M_is_shared())
 
  350        this->reserve(__len);
 
  351      _M_copy(_M_data() + this->size(), __str._M_data() + __pos, __n);
 
  352      _M_rep()->_M_set_length_and_sharable(__len);    
 
  357    template<typename _CharT, typename _Traits, typename _Alloc>
 
  358      basic_string<_CharT, _Traits, _Alloc>&
 
  359      basic_string<_CharT, _Traits, _Alloc>::
 
  360      insert(size_type __pos, const _CharT* __s, size_type __n)
 
  362        __glibcxx_requires_string_len(__s, __n);
 
  363        _M_check(__pos, "basic_string::insert");
 
  364        _M_check_length(size_type(0), __n, "basic_string::insert");
 
  365        if (_M_disjunct(__s) || _M_rep()->_M_is_shared())
 
  366          return _M_replace_safe(__pos, size_type(0), __s, __n);
 
  370            const size_type __off = __s - _M_data();
 
  371            _M_mutate(__pos, 0, __n);
 
  372            __s = _M_data() + __off;
 
  373            _CharT* __p = _M_data() + __pos;
 
  374            if (__s  + __n <= __p)
 
  375              _M_copy(__p, __s, __n);
 
  377              _M_copy(__p, __s + __n, __n);
 
  380           const size_type __nleft = __p - __s;
 
  381                _M_copy(__p, __s, __nleft);
 
  382                _M_copy(__p + __nleft, __p + __n, __n - __nleft);
 
  388    template<typename _CharT, typename _Traits, typename _Alloc>
 
  389      typename basic_string<_CharT, _Traits, _Alloc>::iterator
 
  390      basic_string<_CharT, _Traits, _Alloc>::
 
  391      erase(iterator __first, iterator __last)
 
  393        _GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last
 
  394                && __last <= _M_iend());
 
  396        // NB: This isn't just an optimization (bail out early when
 
  397        // there is nothing to do, really), it's also a correctness
 
  398        // issue vs MT, see libstdc++/40518.
 
  399        const size_type __size = __last - __first;
 
  402       const size_type __pos = __first - _M_ibegin();
 
  403       _M_mutate(__pos, __size, size_type(0));
 
  404       _M_rep()->_M_set_leaked();
 
  405       return iterator(_M_data() + __pos);
 
  411    template<typename _CharT, typename _Traits, typename _Alloc>
 
  412      basic_string<_CharT, _Traits, _Alloc>&
 
  413      basic_string<_CharT, _Traits, _Alloc>::
 
  414      replace(size_type __pos, size_type __n1, const _CharT* __s,
 
  417        __glibcxx_requires_string_len(__s, __n2);
 
  418        _M_check(__pos, "basic_string::replace");
 
  419        __n1 = _M_limit(__pos, __n1);
 
  420        _M_check_length(__n1, __n2, "basic_string::replace");
 
  422        if (_M_disjunct(__s) || _M_rep()->_M_is_shared())
 
  423          return _M_replace_safe(__pos, __n1, __s, __n2);
 
  424        else if ((__left = __s + __n2 <= _M_data() + __pos)
 
  425        || _M_data() + __pos + __n1 <= __s)
 
  427       // Work in-place: non-overlapping case.
 
  428       size_type __off = __s - _M_data();
 
  429       __left ? __off : (__off += __n2 - __n1);
 
  430       _M_mutate(__pos, __n1, __n2);
 
  431       _M_copy(_M_data() + __pos, _M_data() + __off, __n2);
 
  436       // Todo: overlapping case.
 
  437       const basic_string __tmp(__s, __n2);
 
  438       return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2);
 
  442   template<typename _CharT, typename _Traits, typename _Alloc>
 
  444     basic_string<_CharT, _Traits, _Alloc>::_Rep::
 
  445     _M_destroy(const _Alloc& __a) throw ()
 
  447       const size_type __size = sizeof(_Rep_base) +
 
  448                           (this->_M_capacity + 1) * sizeof(_CharT);
 
  449       _Raw_bytes_alloc(__a).deallocate(reinterpret_cast<char*>(this), __size);
 
  452   template<typename _CharT, typename _Traits, typename _Alloc>
 
  454     basic_string<_CharT, _Traits, _Alloc>::
 
  457 #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
 
  458       if (_M_rep() == &_S_empty_rep())
 
  461       if (_M_rep()->_M_is_shared())
 
  463       _M_rep()->_M_set_leaked();
 
  466   template<typename _CharT, typename _Traits, typename _Alloc>
 
  468     basic_string<_CharT, _Traits, _Alloc>::
 
  469     _M_mutate(size_type __pos, size_type __len1, size_type __len2)
 
  471       const size_type __old_size = this->size();
 
  472       const size_type __new_size = __old_size + __len2 - __len1;
 
  473       const size_type __how_much = __old_size - __pos - __len1;
 
  475       if (__new_size > this->capacity() || _M_rep()->_M_is_shared())
 
  478      const allocator_type __a = get_allocator();
 
  479      _Rep* __r = _Rep::_S_create(__new_size, this->capacity(), __a);
 
  482        _M_copy(__r->_M_refdata(), _M_data(), __pos);
 
  484        _M_copy(__r->_M_refdata() + __pos + __len2,
 
  485            _M_data() + __pos + __len1, __how_much);
 
  487      _M_rep()->_M_dispose(__a);
 
  488      _M_data(__r->_M_refdata());
 
  490       else if (__how_much && __len1 != __len2)
 
  493      _M_move(_M_data() + __pos + __len2,
 
  494          _M_data() + __pos + __len1, __how_much);
 
  496       _M_rep()->_M_set_length_and_sharable(__new_size);
 
  499   template<typename _CharT, typename _Traits, typename _Alloc>
 
  501     basic_string<_CharT, _Traits, _Alloc>::
 
  502     reserve(size_type __res)
 
  504       if (__res != this->capacity() || _M_rep()->_M_is_shared())
 
  506      // Make sure we don't shrink below the current size
 
  507      if (__res < this->size())
 
  508        __res = this->size();
 
  509      const allocator_type __a = get_allocator();
 
  510      _CharT* __tmp = _M_rep()->_M_clone(__a, __res - this->size());
 
  511      _M_rep()->_M_dispose(__a);
 
  516   template<typename _CharT, typename _Traits, typename _Alloc>
 
  518     basic_string<_CharT, _Traits, _Alloc>::
 
  519     swap(basic_string& __s)
 
  521       if (_M_rep()->_M_is_leaked())
 
  522    _M_rep()->_M_set_sharable();
 
  523       if (__s._M_rep()->_M_is_leaked())
 
  524    __s._M_rep()->_M_set_sharable();
 
  525       if (this->get_allocator() == __s.get_allocator())
 
  527      _CharT* __tmp = _M_data();
 
  528      _M_data(__s._M_data());
 
  531       // The code below can usually be optimized away.
 
  534      const basic_string __tmp1(_M_ibegin(), _M_iend(),
 
  535                    __s.get_allocator());
 
  536      const basic_string __tmp2(__s._M_ibegin(), __s._M_iend(),
 
  537                    this->get_allocator());
 
  543   template<typename _CharT, typename _Traits, typename _Alloc>
 
  544     typename basic_string<_CharT, _Traits, _Alloc>::_Rep*
 
  545     basic_string<_CharT, _Traits, _Alloc>::_Rep::
 
  546     _S_create(size_type __capacity, size_type __old_capacity,
 
  547          const _Alloc& __alloc)
 
  549       // _GLIBCXX_RESOLVE_LIB_DEFECTS
 
  550       // 83.  String::npos vs. string::max_size()
 
  551       if (__capacity > _S_max_size)
 
  552    __throw_length_error(__N("basic_string::_S_create"));
 
  554       // The standard places no restriction on allocating more memory
 
  555       // than is strictly needed within this layer at the moment or as
 
  556       // requested by an explicit application call to reserve().
 
  558       // Many malloc implementations perform quite poorly when an
 
  559       // application attempts to allocate memory in a stepwise fashion
 
  560       // growing each allocation size by only 1 char.  Additionally,
 
  561       // it makes little sense to allocate less linear memory than the
 
  562       // natural blocking size of the malloc implementation.
 
  563       // Unfortunately, we would need a somewhat low-level calculation
 
  564       // with tuned parameters to get this perfect for any particular
 
  565       // malloc implementation.  Fortunately, generalizations about
 
  566       // common features seen among implementations seems to suffice.
 
  568       // __pagesize need not match the actual VM page size for good
 
  569       // results in practice, thus we pick a common value on the low
 
  570       // side.  __malloc_header_size is an estimate of the amount of
 
  571       // overhead per memory allocation (in practice seen N * sizeof
 
  572       // (void*) where N is 0, 2 or 4).  According to folklore,
 
  573       // picking this value on the high side is better than
 
  574       // low-balling it (especially when this algorithm is used with
 
  575       // malloc implementations that allocate memory blocks rounded up
 
  576       // to a size which is a power of 2).
 
  577       const size_type __pagesize = 4096;
 
  578       const size_type __malloc_header_size = 4 * sizeof(void*);
 
  580       // The below implements an exponential growth policy, necessary to
 
  581       // meet amortized linear time requirements of the library: see
 
  582       // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html.
 
  583       // It's active for allocations requiring an amount of memory above
 
  584       // system pagesize. This is consistent with the requirements of the
 
  585       // standard: http://gcc.gnu.org/ml/libstdc++/2001-07/msg00130.html
 
  586       if (__capacity > __old_capacity && __capacity < 2 * __old_capacity)
 
  587    __capacity = 2 * __old_capacity;
 
  589       // NB: Need an array of char_type[__capacity], plus a terminating
 
  590       // null char_type() element, plus enough for the _Rep data structure.
 
  591       // Whew. Seemingly so needy, yet so elemental.
 
  592       size_type __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
 
  594       const size_type __adj_size = __size + __malloc_header_size;
 
  595       if (__adj_size > __pagesize && __capacity > __old_capacity)
 
  597      const size_type __extra = __pagesize - __adj_size % __pagesize;
 
  598      __capacity += __extra / sizeof(_CharT);
 
  599      // Never allocate a string bigger than _S_max_size.
 
  600      if (__capacity > _S_max_size)
 
  601        __capacity = _S_max_size;
 
  602      __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
 
  605       // NB: Might throw, but no worries about a leak, mate: _Rep()
 
  607       void* __place = _Raw_bytes_alloc(__alloc).allocate(__size);
 
  608       _Rep *__p = new (__place) _Rep;
 
  609       __p->_M_capacity = __capacity;
 
  610       // ABI compatibility - 3.4.x set in _S_create both
 
  611       // _M_refcount and _M_length.  All callers of _S_create
 
  612       // in basic_string.tcc then set just _M_length.
 
  613       // In 4.0.x and later both _M_refcount and _M_length
 
  614       // are initialized in the callers, unfortunately we can
 
  615       // have 3.4.x compiled code with _S_create callers inlined
 
  616       // calling 4.0.x+ _S_create.
 
  617       __p->_M_set_sharable();
 
  621   template<typename _CharT, typename _Traits, typename _Alloc>
 
  623     basic_string<_CharT, _Traits, _Alloc>::_Rep::
 
  624     _M_clone(const _Alloc& __alloc, size_type __res)
 
  626       // Requested capacity of the clone.
 
  627       const size_type __requested_cap = this->_M_length + __res;
 
  628       _Rep* __r = _Rep::_S_create(__requested_cap, this->_M_capacity,
 
  631    _M_copy(__r->_M_refdata(), _M_refdata(), this->_M_length);
 
  633       __r->_M_set_length_and_sharable(this->_M_length);
 
  634       return __r->_M_refdata();
 
  637   template<typename _CharT, typename _Traits, typename _Alloc>
 
  639     basic_string<_CharT, _Traits, _Alloc>::
 
  640     resize(size_type __n, _CharT __c)
 
  642       const size_type __size = this->size();
 
  643       _M_check_length(__size, __n, "basic_string::resize");
 
  645    this->append(__n - __size, __c);
 
  646       else if (__n < __size)
 
  648       // else nothing (in particular, avoid calling _M_mutate() unnecessarily.)
 
  651   template<typename _CharT, typename _Traits, typename _Alloc>
 
  652     template<typename _InputIterator>
 
  653       basic_string<_CharT, _Traits, _Alloc>&
 
  654       basic_string<_CharT, _Traits, _Alloc>::
 
  655       _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1,
 
  656              _InputIterator __k2, __false_type)
 
  658    const basic_string __s(__k1, __k2);
 
  659    const size_type __n1 = __i2 - __i1;
 
  660    _M_check_length(__n1, __s.size(), "basic_string::_M_replace_dispatch");
 
  661    return _M_replace_safe(__i1 - _M_ibegin(), __n1, __s._M_data(),
 
  665   template<typename _CharT, typename _Traits, typename _Alloc>
 
  666     basic_string<_CharT, _Traits, _Alloc>&
 
  667     basic_string<_CharT, _Traits, _Alloc>::
 
  668     _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
 
  671       _M_check_length(__n1, __n2, "basic_string::_M_replace_aux");
 
  672       _M_mutate(__pos1, __n1, __n2);
 
  674    _M_assign(_M_data() + __pos1, __n2, __c);
 
  678   template<typename _CharT, typename _Traits, typename _Alloc>
 
  679     basic_string<_CharT, _Traits, _Alloc>&
 
  680     basic_string<_CharT, _Traits, _Alloc>::
 
  681     _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s,
 
  684       _M_mutate(__pos1, __n1, __n2);
 
  686    _M_copy(_M_data() + __pos1, __s, __n2);
 
  690   template<typename _CharT, typename _Traits, typename _Alloc>
 
  691     basic_string<_CharT, _Traits, _Alloc>
 
  692     operator+(const _CharT* __lhs,
 
  693          const basic_string<_CharT, _Traits, _Alloc>& __rhs)
 
  695       __glibcxx_requires_string(__lhs);
 
  696       typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
 
  697       typedef typename __string_type::size_type      __size_type;
 
  698       const __size_type __len = _Traits::length(__lhs);
 
  700       __str.reserve(__len + __rhs.size());
 
  701       __str.append(__lhs, __len);
 
  706   template<typename _CharT, typename _Traits, typename _Alloc>
 
  707     basic_string<_CharT, _Traits, _Alloc>
 
  708     operator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs)
 
  710       typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
 
  711       typedef typename __string_type::size_type      __size_type;
 
  713       const __size_type __len = __rhs.size();
 
  714       __str.reserve(__len + 1);
 
  715       __str.append(__size_type(1), __lhs);
 
  720   template<typename _CharT, typename _Traits, typename _Alloc>
 
  721     typename basic_string<_CharT, _Traits, _Alloc>::size_type
 
  722     basic_string<_CharT, _Traits, _Alloc>::
 
  723     copy(_CharT* __s, size_type __n, size_type __pos) const
 
  725       _M_check(__pos, "basic_string::copy");
 
  726       __n = _M_limit(__pos, __n);
 
  727       __glibcxx_requires_string_len(__s, __n);
 
  729    _M_copy(__s, _M_data() + __pos, __n);
 
  730       // 21.3.5.7 par 3: do not append null.  (good.)
 
  734   template<typename _CharT, typename _Traits, typename _Alloc>
 
  735     typename basic_string<_CharT, _Traits, _Alloc>::size_type
 
  736     basic_string<_CharT, _Traits, _Alloc>::
 
  737     find(const _CharT* __s, size_type __pos, size_type __n) const
 
  739       __glibcxx_requires_string_len(__s, __n);
 
  740       const size_type __size = this->size();
 
  741       const _CharT* __data = _M_data();
 
  744    return __pos <= __size ? __pos : npos;
 
  748      for (; __pos <= __size - __n; ++__pos)
 
  749        if (traits_type::eq(__data[__pos], __s[0])
 
  750        && traits_type::compare(__data + __pos + 1,
 
  751                    __s + 1, __n - 1) == 0)
 
  757   template<typename _CharT, typename _Traits, typename _Alloc>
 
  758     typename basic_string<_CharT, _Traits, _Alloc>::size_type
 
  759     basic_string<_CharT, _Traits, _Alloc>::
 
  760     find(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
 
  762       size_type __ret = npos;
 
  763       const size_type __size = this->size();
 
  766      const _CharT* __data = _M_data();
 
  767      const size_type __n = __size - __pos;
 
  768      const _CharT* __p = traits_type::find(__data + __pos, __n, __c);
 
  770        __ret = __p - __data;
 
  775   template<typename _CharT, typename _Traits, typename _Alloc>
 
  776     typename basic_string<_CharT, _Traits, _Alloc>::size_type
 
  777     basic_string<_CharT, _Traits, _Alloc>::
 
  778     rfind(const _CharT* __s, size_type __pos, size_type __n) const
 
  780       __glibcxx_requires_string_len(__s, __n);
 
  781       const size_type __size = this->size();
 
  784      __pos = std::min(size_type(__size - __n), __pos);
 
  785      const _CharT* __data = _M_data();
 
  788          if (traits_type::compare(__data + __pos, __s, __n) == 0)
 
  796   template<typename _CharT, typename _Traits, typename _Alloc>
 
  797     typename basic_string<_CharT, _Traits, _Alloc>::size_type
 
  798     basic_string<_CharT, _Traits, _Alloc>::
 
  799     rfind(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
 
  801       size_type __size = this->size();
 
  804      if (--__size > __pos)
 
  806      for (++__size; __size-- > 0; )
 
  807        if (traits_type::eq(_M_data()[__size], __c))
 
  813   template<typename _CharT, typename _Traits, typename _Alloc>
 
  814     typename basic_string<_CharT, _Traits, _Alloc>::size_type
 
  815     basic_string<_CharT, _Traits, _Alloc>::
 
  816     find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
 
  818       __glibcxx_requires_string_len(__s, __n);
 
  819       for (; __n && __pos < this->size(); ++__pos)
 
  821      const _CharT* __p = traits_type::find(__s, __n, _M_data()[__pos]);
 
  828   template<typename _CharT, typename _Traits, typename _Alloc>
 
  829     typename basic_string<_CharT, _Traits, _Alloc>::size_type
 
  830     basic_string<_CharT, _Traits, _Alloc>::
 
  831     find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
 
  833       __glibcxx_requires_string_len(__s, __n);
 
  834       size_type __size = this->size();
 
  837      if (--__size > __pos)
 
  841          if (traits_type::find(__s, __n, _M_data()[__size]))
 
  844      while (__size-- != 0);
 
  849   template<typename _CharT, typename _Traits, typename _Alloc>
 
  850     typename basic_string<_CharT, _Traits, _Alloc>::size_type
 
  851     basic_string<_CharT, _Traits, _Alloc>::
 
  852     find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
 
  854       __glibcxx_requires_string_len(__s, __n);
 
  855       for (; __pos < this->size(); ++__pos)
 
  856    if (!traits_type::find(__s, __n, _M_data()[__pos]))
 
  861   template<typename _CharT, typename _Traits, typename _Alloc>
 
  862     typename basic_string<_CharT, _Traits, _Alloc>::size_type
 
  863     basic_string<_CharT, _Traits, _Alloc>::
 
  864     find_first_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
 
  866       for (; __pos < this->size(); ++__pos)
 
  867    if (!traits_type::eq(_M_data()[__pos], __c))
 
  872   template<typename _CharT, typename _Traits, typename _Alloc>
 
  873     typename basic_string<_CharT, _Traits, _Alloc>::size_type
 
  874     basic_string<_CharT, _Traits, _Alloc>::
 
  875     find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
 
  877       __glibcxx_requires_string_len(__s, __n);
 
  878       size_type __size = this->size();
 
  881      if (--__size > __pos)
 
  885          if (!traits_type::find(__s, __n, _M_data()[__size]))
 
  893   template<typename _CharT, typename _Traits, typename _Alloc>
 
  894     typename basic_string<_CharT, _Traits, _Alloc>::size_type
 
  895     basic_string<_CharT, _Traits, _Alloc>::
 
  896     find_last_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
 
  898       size_type __size = this->size();
 
  901      if (--__size > __pos)
 
  905          if (!traits_type::eq(_M_data()[__size], __c))
 
  913   template<typename _CharT, typename _Traits, typename _Alloc>
 
  915     basic_string<_CharT, _Traits, _Alloc>::
 
  916     compare(size_type __pos, size_type __n, const basic_string& __str) const
 
  918       _M_check(__pos, "basic_string::compare");
 
  919       __n = _M_limit(__pos, __n);
 
  920       const size_type __osize = __str.size();
 
  921       const size_type __len = std::min(__n, __osize);
 
  922       int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len);
 
  924    __r = _S_compare(__n, __osize);
 
  928   template<typename _CharT, typename _Traits, typename _Alloc>
 
  930     basic_string<_CharT, _Traits, _Alloc>::
 
  931     compare(size_type __pos1, size_type __n1, const basic_string& __str,
 
  932        size_type __pos2, size_type __n2) const
 
  934       _M_check(__pos1, "basic_string::compare");
 
  935       __str._M_check(__pos2, "basic_string::compare");
 
  936       __n1 = _M_limit(__pos1, __n1);
 
  937       __n2 = __str._M_limit(__pos2, __n2);
 
  938       const size_type __len = std::min(__n1, __n2);
 
  939       int __r = traits_type::compare(_M_data() + __pos1,
 
  940                     __str.data() + __pos2, __len);
 
  942    __r = _S_compare(__n1, __n2);
 
  946   template<typename _CharT, typename _Traits, typename _Alloc>
 
  948     basic_string<_CharT, _Traits, _Alloc>::
 
  949     compare(const _CharT* __s) const
 
  951       __glibcxx_requires_string(__s);
 
  952       const size_type __size = this->size();
 
  953       const size_type __osize = traits_type::length(__s);
 
  954       const size_type __len = std::min(__size, __osize);
 
  955       int __r = traits_type::compare(_M_data(), __s, __len);
 
  957    __r = _S_compare(__size, __osize);
 
  961   template<typename _CharT, typename _Traits, typename _Alloc>
 
  963     basic_string <_CharT, _Traits, _Alloc>::
 
  964     compare(size_type __pos, size_type __n1, const _CharT* __s) const
 
  966       __glibcxx_requires_string(__s);
 
  967       _M_check(__pos, "basic_string::compare");
 
  968       __n1 = _M_limit(__pos, __n1);
 
  969       const size_type __osize = traits_type::length(__s);
 
  970       const size_type __len = std::min(__n1, __osize);
 
  971       int __r = traits_type::compare(_M_data() + __pos, __s, __len);
 
  973    __r = _S_compare(__n1, __osize);
 
  977   template<typename _CharT, typename _Traits, typename _Alloc>
 
  979     basic_string <_CharT, _Traits, _Alloc>::
 
  980     compare(size_type __pos, size_type __n1, const _CharT* __s,
 
  981        size_type __n2) const
 
  983       __glibcxx_requires_string_len(__s, __n2);
 
  984       _M_check(__pos, "basic_string::compare");
 
  985       __n1 = _M_limit(__pos, __n1);
 
  986       const size_type __len = std::min(__n1, __n2);
 
  987       int __r = traits_type::compare(_M_data() + __pos, __s, __len);
 
  989    __r = _S_compare(__n1, __n2);
 
  993   // 21.3.7.9 basic_string::getline and operators
 
  994   template<typename _CharT, typename _Traits, typename _Alloc>
 
  995     basic_istream<_CharT, _Traits>&
 
  996     operator>>(basic_istream<_CharT, _Traits>& __in,
 
  997           basic_string<_CharT, _Traits, _Alloc>& __str)
 
  999       typedef basic_istream<_CharT, _Traits>       __istream_type;
 
 1000       typedef basic_string<_CharT, _Traits, _Alloc>    __string_type;
 
 1001       typedef typename __istream_type::ios_base         __ios_base;
 
 1002       typedef typename __istream_type::int_type        __int_type;
 
 1003       typedef typename __string_type::size_type        __size_type;
 
 1004       typedef ctype<_CharT>                __ctype_type;
 
 1005       typedef typename __ctype_type::ctype_base         __ctype_base;
 
 1007       __size_type __extracted = 0;
 
 1008       typename __ios_base::iostate __err = __ios_base::goodbit;
 
 1009       typename __istream_type::sentry __cerb(__in, false);
 
 1014          // Avoid reallocation for common case.
 
 1017          __size_type __len = 0;          
 
 1018          const streamsize __w = __in.width();
 
 1019          const __size_type __n = __w > 0 ? static_cast<__size_type>(__w)
 
 1021          const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
 
 1022          const __int_type __eof = _Traits::eof();
 
 1023          __int_type __c = __in.rdbuf()->sgetc();
 
 1025          while (__extracted < __n
 
 1026             && !_Traits::eq_int_type(__c, __eof)
 
 1027             && !__ct.is(__ctype_base::space,
 
 1028                 _Traits::to_char_type(__c)))
 
 1030          if (__len == sizeof(__buf) / sizeof(_CharT))
 
 1032              __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
 
 1035          __buf[__len++] = _Traits::to_char_type(__c);
 
 1037          __c = __in.rdbuf()->snextc();
 
 1039          __str.append(__buf, __len);
 
 1041          if (_Traits::eq_int_type(__c, __eof))
 
 1042        __err |= __ios_base::eofbit;
 
 1045      __catch(__cxxabiv1::__forced_unwind&)
 
 1047          __in._M_setstate(__ios_base::badbit);
 
 1048          __throw_exception_again;
 
 1052          // _GLIBCXX_RESOLVE_LIB_DEFECTS
 
 1053          // 91. Description of operator>> and getline() for string<>
 
 1054          // might cause endless loop
 
 1055          __in._M_setstate(__ios_base::badbit);
 
 1058       // 211.  operator>>(istream&, string&) doesn't set failbit
 
 1060    __err |= __ios_base::failbit;
 
 1062    __in.setstate(__err);
 
 1066   template<typename _CharT, typename _Traits, typename _Alloc>
 
 1067     basic_istream<_CharT, _Traits>&
 
 1068     getline(basic_istream<_CharT, _Traits>& __in,
 
 1069        basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim)
 
 1071       typedef basic_istream<_CharT, _Traits>       __istream_type;
 
 1072       typedef basic_string<_CharT, _Traits, _Alloc>    __string_type;
 
 1073       typedef typename __istream_type::ios_base         __ios_base;
 
 1074       typedef typename __istream_type::int_type        __int_type;
 
 1075       typedef typename __string_type::size_type        __size_type;
 
 1077       __size_type __extracted = 0;
 
 1078       const __size_type __n = __str.max_size();
 
 1079       typename __ios_base::iostate __err = __ios_base::goodbit;
 
 1080       typename __istream_type::sentry __cerb(__in, true);
 
 1086          const __int_type __idelim = _Traits::to_int_type(__delim);
 
 1087          const __int_type __eof = _Traits::eof();
 
 1088          __int_type __c = __in.rdbuf()->sgetc();
 
 1090          while (__extracted < __n
 
 1091             && !_Traits::eq_int_type(__c, __eof)
 
 1092             && !_Traits::eq_int_type(__c, __idelim))
 
 1094          __str += _Traits::to_char_type(__c);
 
 1096          __c = __in.rdbuf()->snextc();
 
 1099          if (_Traits::eq_int_type(__c, __eof))
 
 1100        __err |= __ios_base::eofbit;
 
 1101          else if (_Traits::eq_int_type(__c, __idelim))
 
 1104          __in.rdbuf()->sbumpc();
 
 1107        __err |= __ios_base::failbit;
 
 1109      __catch(__cxxabiv1::__forced_unwind&)
 
 1111          __in._M_setstate(__ios_base::badbit);
 
 1112          __throw_exception_again;
 
 1116          // _GLIBCXX_RESOLVE_LIB_DEFECTS
 
 1117          // 91. Description of operator>> and getline() for string<>
 
 1118          // might cause endless loop
 
 1119          __in._M_setstate(__ios_base::badbit);
 
 1123    __err |= __ios_base::failbit;
 
 1125    __in.setstate(__err);
 
 1129   // Inhibit implicit instantiations for required instantiations,
 
 1130   // which are defined via explicit instantiations elsewhere.
 
 1131 #if _GLIBCXX_EXTERN_TEMPLATE > 0
 
 1132   extern template class basic_string<char>;
 
 1134     basic_istream<char>&
 
 1135     operator>>(basic_istream<char>&, string&);
 
 1137     basic_ostream<char>&
 
 1138     operator<<(basic_ostream<char>&, const string&);
 
 1140     basic_istream<char>&
 
 1141     getline(basic_istream<char>&, string&, char);
 
 1143     basic_istream<char>&
 
 1144     getline(basic_istream<char>&, string&);
 
 1146 #ifdef _GLIBCXX_USE_WCHAR_T
 
 1147   extern template class basic_string<wchar_t>;
 
 1149     basic_istream<wchar_t>&
 
 1150     operator>>(basic_istream<wchar_t>&, wstring&);
 
 1152     basic_ostream<wchar_t>&
 
 1153     operator<<(basic_ostream<wchar_t>&, const wstring&);
 
 1155     basic_istream<wchar_t>&
 
 1156     getline(basic_istream<wchar_t>&, wstring&, wchar_t);
 
 1158     basic_istream<wchar_t>&
 
 1159     getline(basic_istream<wchar_t>&, wstring&);
 
 1163 _GLIBCXX_END_NAMESPACE_VERSION