home *** CD-ROM | disk | FTP | other *** search
/ H4CK3R 14 / hacker14.iso / programacao / cwin / c.exe / $INSTDIR / include / c++ / bits / basic_string.h < prev    next >
Encoding:
C/C++ Source or Header  |  2003-12-15  |  35.6 KB  |  1,112 lines

  1. // Components for manipulating sequences of characters -*- C++ -*-
  2.  
  3. // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
  4. // Free Software Foundation, Inc.
  5. //
  6. // This file is part of the GNU ISO C++ Library.  This library is free
  7. // software; you can redistribute it and/or modify it under the
  8. // terms of the GNU General Public License as published by the
  9. // Free Software Foundation; either version 2, or (at your option)
  10. // any later version.
  11.  
  12. // This library is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. // GNU General Public License for more details.
  16.  
  17. // You should have received a copy of the GNU General Public License along
  18. // with this library; see the file COPYING.  If not, write to the Free
  19. // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  20. // USA.
  21.  
  22. // As a special exception, you may use this file as part of a free software
  23. // library without restriction.  Specifically, if other files instantiate
  24. // templates or use macros or inline functions from this file, or you compile
  25. // this file and link it with other files to produce an executable, this
  26. // file does not by itself cause the resulting executable to be covered by
  27. // the GNU General Public License.  This exception does not however
  28. // invalidate any other reasons why the executable file might be covered by
  29. // the GNU General Public License.
  30.  
  31. //
  32. // ISO C++ 14882: 21 Strings library
  33. //
  34.  
  35. /** @file basic_string.h
  36.  *  This is an internal header file, included by other library headers.
  37.  *  You should not attempt to use it directly.
  38.  */
  39.  
  40. #ifndef _CPP_BITS_STRING_H
  41. #define _CPP_BITS_STRING_H    1
  42.  
  43. #pragma GCC system_header
  44.  
  45. #include <bits/atomicity.h>
  46.  
  47. namespace std
  48. {
  49.   // Documentation?  What's that? 
  50.   // Nathan Myers <ncm@cantrip.org>.
  51.   //
  52.   // A string looks like this:
  53.   //
  54.   //                                   [_Rep]
  55.   //                                   _M_length
  56.   //  [basic_string<char_type>]        _M_capacity
  57.   //  _M_dataplus                    _M_state
  58.   //  _M_p ---------------->           unnamed array of char_type
  59.   
  60.   // Where the _M_p points to the first character in the string, and
  61.   // you cast it to a pointer-to-_Rep and subtract 1 to get a
  62.   // pointer to the header.
  63.   
  64.   // This approach has the enormous advantage that a string object
  65.   // requires only one allocation.  All the ugliness is confined
  66.   // within a single pair of inline functions, which each compile to
  67.   // a single "add" instruction: _Rep::_M_data(), and
  68.   // string::_M_rep(); and the allocation function which gets a
  69.   // block of raw bytes and with room enough and constructs a _Rep
  70.   // object at the front.
  71.   
  72.   // The reason you want _M_data pointing to the character array and
  73.   // not the _Rep is so that the debugger can see the string
  74.   // contents. (Probably we should add a non-inline member to get
  75.   // the _Rep for the debugger to use, so users can check the actual
  76.   // string length.)
  77.   
  78.   // Note that the _Rep object is a POD so that you can have a
  79.   // static "empty string" _Rep object already "constructed" before
  80.   // static constructors have run.  The reference-count encoding is
  81.   // chosen so that a 0 indicates one reference, so you never try to
  82.   // destroy the empty-string _Rep object.
  83.   
  84.   // All but the last paragraph is considered pretty conventional
  85.   // for a C++ string implementation.
  86.   
  87.   // 21.3  Template class basic_string
  88.   template<typename _CharT, typename _Traits, typename _Alloc>
  89.     class basic_string
  90.     {
  91.       // Types:
  92.     public:
  93.       typedef _Traits                         traits_type;
  94.       typedef typename _Traits::char_type             value_type;
  95.       typedef _Alloc                         allocator_type;
  96.       typedef typename _Alloc::size_type             size_type;
  97.       typedef typename _Alloc::difference_type             difference_type;
  98.       typedef typename _Alloc::reference             reference;
  99.       typedef typename _Alloc::const_reference             const_reference;
  100.       typedef typename _Alloc::pointer                 pointer;
  101.       typedef typename _Alloc::const_pointer                const_pointer;
  102.       typedef __gnu_cxx::__normal_iterator<pointer, basic_string>  iterator;
  103.       typedef __gnu_cxx::__normal_iterator<const_pointer, basic_string>
  104.                                                             const_iterator;
  105.       typedef reverse_iterator<const_iterator>     const_reverse_iterator;
  106.       typedef reverse_iterator<iterator>             reverse_iterator;
  107.     
  108.     private:
  109.       // _Rep: string representation
  110.       //   Invariants:
  111.       //   1. String really contains _M_length + 1 characters; last is set
  112.       //      to 0 only on call to c_str().  We avoid instantiating
  113.       //      _CharT() where the interface does not require it.
  114.       //   2. _M_capacity >= _M_length
  115.       //      Allocated memory is always _M_capacity + (1 * sizeof(_CharT)).
  116.       //   3. _M_references has three states:
  117.       //      -1: leaked, one reference, no ref-copies allowed, non-const.
  118.       //       0: one reference, non-const.
  119.       //     n>0: n + 1 references, operations require a lock, const.
  120.       //   4. All fields==0 is an empty string, given the extra storage
  121.       //      beyond-the-end for a null terminator; thus, the shared
  122.       //      empty string representation needs no constructor.
  123.       struct _Rep
  124.       {
  125.     // Types:
  126.     typedef typename _Alloc::template rebind<char>::other _Raw_bytes_alloc;
  127.  
  128.     // (Public) Data members: 
  129.  
  130.     // The maximum number of individual char_type elements of an
  131.     // individual string is determined by _S_max_size. This is the
  132.     // value that will be returned by max_size().  (Whereas npos
  133.     // is the maximum number of bytes the allocator can allocate.)
  134.     // If one was to divvy up the theoretical largest size string,
  135.     // with a terminating character and m _CharT elements, it'd
  136.     // look like this: 
  137.     // npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT)
  138.     // Solving for m:
  139.     // m = ((npos - sizeof(_Rep))/sizeof(CharT)) - 1 
  140.     // In addition, this implementation quarters this ammount.
  141.     static const size_type     _S_max_size;
  142.     static const _CharT     _S_terminal;
  143.  
  144.     size_type         _M_length;
  145.     size_type         _M_capacity;
  146.     _Atomic_word        _M_references;
  147.     
  148.         bool
  149.     _M_is_leaked() const
  150.         { return _M_references < 0; }
  151.  
  152.         bool
  153.     _M_is_shared() const
  154.         { return _M_references > 0; }
  155.  
  156.         void
  157.     _M_set_leaked() 
  158.         { _M_references = -1; }
  159.  
  160.         void
  161.     _M_set_sharable() 
  162.         { _M_references = 0; }
  163.  
  164.     _CharT* 
  165.     _M_refdata() throw()
  166.     { return reinterpret_cast<_CharT*>(this + 1); }
  167.  
  168.     _CharT& 
  169.     operator[](size_t __s) throw()
  170.     { return _M_refdata() [__s]; }
  171.  
  172.     _CharT* 
  173.     _M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2)
  174.     { 
  175.       return (!_M_is_leaked() && __alloc1 == __alloc2) 
  176.               ? _M_refcopy() : _M_clone(__alloc1);  
  177.     }
  178.  
  179.     // Create & Destroy
  180.     static _Rep* 
  181.     _S_create(size_t, const _Alloc&);
  182.  
  183.     void 
  184.     _M_dispose(const _Alloc& __a)
  185.     { 
  186.       if (__exchange_and_add(&_M_references, -1) <= 0)  
  187.         _M_destroy(__a); 
  188.     }  // XXX MT
  189.  
  190.     void 
  191.     _M_destroy(const _Alloc&) throw();
  192.  
  193.     _CharT* 
  194.     _M_refcopy() throw()
  195.     { 
  196.       __atomic_add(&_M_references, 1); 
  197.       return _M_refdata(); 
  198.     }  // XXX MT
  199.  
  200.     _CharT* 
  201.     _M_clone(const _Alloc&, size_type __res = 0);
  202.       };
  203.  
  204.       // Use empty-base optimization: http://www.cantrip.org/emptyopt.html
  205.       struct _Alloc_hider : _Alloc
  206.       {
  207.     _Alloc_hider(_CharT* __dat, const _Alloc& __a)
  208.     : _Alloc(__a), _M_p(__dat) { }
  209.  
  210.     _CharT* _M_p; // The actual data.
  211.       };
  212.  
  213.     public:
  214.       // Data Members (public):
  215.       // NB: This is an unsigned type, and thus represents the maximum
  216.       // size that the allocator can hold.
  217.       static const size_type     npos = static_cast<size_type>(-1);
  218.  
  219.     private:
  220.       // Data Members (private):
  221.       mutable _Alloc_hider     _M_dataplus;
  222.  
  223.       // The following storage is init'd to 0 by the linker, resulting
  224.       // (carefully) in an empty string with one reference.
  225.       static size_type _S_empty_rep_storage[(sizeof(_Rep) + sizeof(_CharT) + sizeof(size_type) - 1)/sizeof(size_type)];
  226.  
  227.       _CharT* 
  228.       _M_data() const 
  229.       { return  _M_dataplus._M_p; }
  230.  
  231.       _CharT* 
  232.       _M_data(_CharT* __p) 
  233.       { return (_M_dataplus._M_p = __p); }
  234.  
  235.       _Rep* 
  236.       _M_rep() const
  237.       { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); }
  238.  
  239.       // For the internal use we have functions similar to `begin'/`end'
  240.       // but they do not call _M_leak.
  241.       iterator 
  242.       _M_ibegin() const { return iterator(_M_data()); }
  243.  
  244.       iterator 
  245.       _M_iend() const { return iterator(_M_data() + this->size()); }
  246.  
  247.       void 
  248.       _M_leak()    // for use in begin() & non-const op[]
  249.       { 
  250.     if (!_M_rep()->_M_is_leaked()) 
  251.       _M_leak_hard(); 
  252.       }
  253.  
  254.       iterator 
  255.       _M_check(size_type __pos) const
  256.       { 
  257.     if (__pos > this->size())
  258.       __throw_out_of_range("basic_string::_M_check"); 
  259.     return _M_ibegin() + __pos; 
  260.       }
  261.  
  262.       // NB: _M_fold doesn't check for a bad __pos1 value.
  263.       iterator 
  264.       _M_fold(size_type __pos, size_type __off) const
  265.       { 
  266.     bool __testoff =  __off < this->size() - __pos;
  267.     size_type __newoff = __testoff ? __off : this->size() - __pos;
  268.     return (_M_ibegin() + __pos + __newoff);
  269.       }
  270.  
  271.       // _S_copy_chars is a separate template to permit specialization
  272.       // to optimize for the common case of pointers as iterators.
  273.       template<class _Iterator>
  274.         static void
  275.         _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2)
  276.         { 
  277.       for (; __k1 != __k2; ++__k1, ++__p) 
  278.         traits_type::assign(*__p, *__k1); // These types are off.
  279.     }
  280.  
  281.       static void
  282.       _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2)
  283.       { _S_copy_chars(__p, __k1.base(), __k2.base()); }
  284.  
  285.       static void
  286.       _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2)
  287.       { _S_copy_chars(__p, __k1.base(), __k2.base()); }
  288.  
  289.       static void
  290.       _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2)
  291.       { traits_type::copy(__p, __k1, __k2 - __k1); }
  292.  
  293.       static void
  294.       _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2)
  295.       { traits_type::copy(__p, __k1, __k2 - __k1); }
  296.  
  297.       void 
  298.       _M_mutate(size_type __pos, size_type __len1, size_type __len2);
  299.  
  300.       void 
  301.       _M_leak_hard();
  302.  
  303.       static _Rep& 
  304.       _S_empty_rep()
  305.       { return *reinterpret_cast<_Rep*>(&_S_empty_rep_storage); }
  306.  
  307.     public:
  308.       // Construct/copy/destroy:
  309.       // NB: We overload ctors in some cases instead of using default
  310.       // arguments, per 17.4.4.4 para. 2 item 2.
  311.  
  312.       inline 
  313.       basic_string();
  314.  
  315.       explicit 
  316.       basic_string(const _Alloc& __a);
  317.  
  318.       // NB: per LWG issue 42, semantics different from IS:
  319.       basic_string(const basic_string& __str);
  320.       basic_string(const basic_string& __str, size_type __pos,
  321.            size_type __n = npos);
  322.       basic_string(const basic_string& __str, size_type __pos,
  323.            size_type __n, const _Alloc& __a);
  324.  
  325.       basic_string(const _CharT* __s, size_type __n,
  326.            const _Alloc& __a = _Alloc());
  327.       basic_string(const _CharT* __s, const _Alloc& __a = _Alloc());
  328.       basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc());
  329.  
  330.       template<class _InputIterator>
  331.         basic_string(_InputIterator __beg, _InputIterator __end,
  332.              const _Alloc& __a = _Alloc());
  333.  
  334.       ~basic_string() 
  335.       { _M_rep()->_M_dispose(this->get_allocator()); }
  336.  
  337.       basic_string& 
  338.       operator=(const basic_string& __str) { return this->assign(__str); }
  339.  
  340.       basic_string& 
  341.       operator=(const _CharT* __s) { return this->assign(__s); }
  342.  
  343.       basic_string& 
  344.       operator=(_CharT __c) { return this->assign(1, __c); }
  345.  
  346.       // Iterators:
  347.       iterator 
  348.       begin() 
  349.       { 
  350.     _M_leak(); 
  351.     return iterator(_M_data());
  352.       }
  353.  
  354.       const_iterator 
  355.       begin() const 
  356.       { return const_iterator(_M_data()); }
  357.  
  358.       iterator 
  359.       end()
  360.       {
  361.          _M_leak();
  362.      return iterator(_M_data() + this->size());
  363.       }
  364.  
  365.       const_iterator 
  366.       end() const
  367.       { return const_iterator(_M_data() + this->size()); }
  368.  
  369.       reverse_iterator 
  370.       rbegin() 
  371.       { return reverse_iterator(this->end()); }
  372.  
  373.       const_reverse_iterator 
  374.       rbegin() const 
  375.       { return const_reverse_iterator(this->end()); }
  376.  
  377.       reverse_iterator 
  378.       rend() 
  379.       { return reverse_iterator(this->begin()); }
  380.  
  381.       const_reverse_iterator 
  382.       rend() const 
  383.       { return const_reverse_iterator(this->begin()); }
  384.  
  385.     public:
  386.       // Capacity:
  387.       size_type 
  388.       size() const { return _M_rep()->_M_length; }
  389.  
  390.       size_type 
  391.       length() const { return _M_rep()->_M_length; }
  392.  
  393.       size_type 
  394.       max_size() const { return _Rep::_S_max_size; }
  395.  
  396.       void 
  397.       resize(size_type __n, _CharT __c);
  398.  
  399.       void 
  400.       resize(size_type __n) { this->resize(__n, _CharT()); }
  401.  
  402.       size_type 
  403.       capacity() const { return _M_rep()->_M_capacity; }
  404.  
  405.       void 
  406.       reserve(size_type __res_arg = 0);
  407.  
  408.       void 
  409.       clear() { _M_mutate(0, this->size(), 0); }
  410.  
  411.       bool 
  412.       empty() const { return this->size() == 0; }
  413.  
  414.       // Element access:
  415.       const_reference 
  416.       operator[] (size_type __pos) const 
  417.       { return _M_data()[__pos]; }
  418.  
  419.       reference 
  420.       operator[](size_type __pos) 
  421.       { 
  422.     _M_leak(); 
  423.     return _M_data()[__pos]; 
  424.       }
  425.  
  426.       const_reference 
  427.       at(size_type __n) const
  428.       {
  429.     if (__n >= this->size())
  430.       __throw_out_of_range("basic_string::at");
  431.     return _M_data()[__n]; 
  432.       }
  433.  
  434.       reference 
  435.       at(size_type __n)
  436.       {
  437.     if (__n >= size())
  438.       __throw_out_of_range("basic_string::at");
  439.     _M_leak(); 
  440.     return _M_data()[__n]; 
  441.       }
  442.  
  443.       // Modifiers:
  444.       basic_string& 
  445.       operator+=(const basic_string& __str) { return this->append(__str); }
  446.  
  447.       basic_string& 
  448.       operator+=(const _CharT* __s) { return this->append(__s); }
  449.  
  450.       basic_string& 
  451.       operator+=(_CharT __c) { return this->append(size_type(1), __c); }
  452.  
  453.       basic_string& 
  454.       append(const basic_string& __str);
  455.  
  456.       basic_string& 
  457.       append(const basic_string& __str, size_type __pos, size_type __n);
  458.  
  459.       basic_string& 
  460.       append(const _CharT* __s, size_type __n);
  461.  
  462.       basic_string& 
  463.       append(const _CharT* __s)
  464.       { return this->append(__s, traits_type::length(__s)); }
  465.  
  466.       basic_string& 
  467.       append(size_type __n, _CharT __c);
  468.  
  469.       template<class _InputIterator>
  470.         basic_string& 
  471.         append(_InputIterator __first, _InputIterator __last)
  472.         { return this->replace(_M_iend(), _M_iend(), __first, __last); }
  473.  
  474.       void 
  475.       push_back(_CharT __c)
  476.       { this->replace(_M_iend(), _M_iend(), 1, __c); }
  477.  
  478.       basic_string& 
  479.       assign(const basic_string& __str);
  480.  
  481.       basic_string& 
  482.       assign(const basic_string& __str, size_type __pos, size_type __n)
  483.       {
  484.     const size_type __strsize = __str.size();
  485.     if (__pos > __strsize)
  486.       __throw_out_of_range("basic_string::assign");
  487.     const bool __testn = __n < __strsize - __pos;
  488.     const size_type __newsize = __testn ? __n : __strsize - __pos;
  489.     return this->assign(__str._M_data() + __pos, __newsize);
  490.       }
  491.  
  492.       basic_string& 
  493.       assign(const _CharT* __s, size_type __n)
  494.       {
  495.     if (__n > this->max_size())
  496.       __throw_length_error("basic_string::assign");
  497.     if (_M_rep()->_M_is_shared() || less<const _CharT*>()(__s, _M_data())
  498.         || less<const _CharT*>()(_M_data() + this->size(), __s))
  499.       return _M_replace_safe(_M_ibegin(), _M_iend(), __s, __s + __n);
  500.     else
  501.       {
  502.         // Work in-place
  503.         const size_type __pos = __s - _M_data();
  504.         if (__pos >= __n)
  505.           traits_type::copy(_M_data(), __s, __n);
  506.         else if (__pos)
  507.           traits_type::move(_M_data(), __s, __n);
  508.         _M_rep()->_M_length = __n;
  509.         _M_data()[__n] = _Rep::_S_terminal;
  510.         return *this;
  511.       }
  512.       }
  513.  
  514.       basic_string& 
  515.       assign(const _CharT* __s)
  516.       { return this->assign(__s, traits_type::length(__s)); }
  517.  
  518.       basic_string& 
  519.       assign(size_type __n, _CharT __c)
  520.       { return this->replace(_M_ibegin(), _M_iend(), __n, __c); }
  521.  
  522.       template<class _InputIterator>
  523.         basic_string& 
  524.         assign(_InputIterator __first, _InputIterator __last)
  525.         { return this->replace(_M_ibegin(), _M_iend(), __first, __last); }
  526.  
  527.       void 
  528.       insert(iterator __p, size_type __n, _CharT __c)
  529.       {    this->replace(__p, __p, __n, __c);  }
  530.  
  531.       template<class _InputIterator>
  532.         void insert(iterator __p, _InputIterator __beg, _InputIterator __end)
  533.         { this->replace(__p, __p, __beg, __end); }
  534.  
  535.       basic_string& 
  536.       insert(size_type __pos1, const basic_string& __str)
  537.       { return this->insert(__pos1, __str, 0, __str.size()); }
  538.  
  539.       basic_string& 
  540.       insert(size_type __pos1, const basic_string& __str,
  541.          size_type __pos2, size_type __n)
  542.       {
  543.     const size_type __strsize = __str.size();
  544.      if (__pos2 > __strsize)
  545.       __throw_out_of_range("basic_string::insert");
  546.     const bool __testn = __n < __strsize - __pos2;
  547.     const size_type __newsize = __testn ? __n : __strsize - __pos2;
  548.     return this->insert(__pos1, __str._M_data() + __pos2, __newsize); 
  549.       }
  550.  
  551.       basic_string& 
  552.       insert(size_type __pos, const _CharT* __s, size_type __n)
  553.       {
  554.     const size_type __size = this->size();
  555.      if (__pos > __size)
  556.       __throw_out_of_range("basic_string::insert");
  557.     if (__size > this->max_size() - __n)
  558.       __throw_length_error("basic_string::insert");
  559.     if (_M_rep()->_M_is_shared() || less<const _CharT*>()(__s, _M_data())
  560.         || less<const _CharT*>()(_M_data() + __size, __s))
  561.       return _M_replace_safe(_M_ibegin() + __pos, _M_ibegin() + __pos,
  562.                  __s, __s + __n);
  563.     else
  564.       {
  565.         // Work in-place. If _M_mutate reallocates the string, __s
  566.         // does not point anymore to valid data, therefore we save its
  567.         // offset, then we restore it.
  568.         const size_type __off = __s - _M_data();
  569.         _M_mutate(__pos, 0, __n);
  570.         __s = _M_data() + __off;
  571.         _CharT* __p = _M_data() + __pos;
  572.         if (__s  + __n <= __p)
  573.           traits_type::copy(__p, __s, __n);
  574.         else if (__s >= __p)
  575.           traits_type::copy(__p, __s + __n, __n);
  576.         else
  577.           {
  578.         traits_type::copy(__p, __s, __p - __s);
  579.         traits_type::copy(__p + (__p - __s), __p + __n, __n - (__p - __s));
  580.           }
  581.         return *this;
  582.       }
  583.        }
  584.  
  585.       basic_string&  
  586.       insert(size_type __pos, const _CharT* __s)
  587.       { return this->insert(__pos, __s, traits_type::length(__s)); }
  588.  
  589.       basic_string& 
  590.       insert(size_type __pos, size_type __n, _CharT __c)
  591.       { 
  592.     this->insert(_M_check(__pos), __n, __c); 
  593.     return *this; 
  594.       }
  595.  
  596.       iterator 
  597.       insert(iterator __p, _CharT __c = _CharT())
  598.       {
  599.     size_type __pos = __p - _M_ibegin();
  600.     this->insert(_M_check(__pos), size_type(1), __c);
  601.     _M_rep()->_M_set_leaked(); 
  602.      return this->_M_ibegin() + __pos; 
  603.       }
  604.  
  605.       basic_string& 
  606.       erase(size_type __pos = 0, size_type __n = npos)
  607.       { 
  608.     return this->replace(_M_check(__pos), _M_fold(__pos, __n),
  609.                  _M_data(), _M_data()); 
  610.       }
  611.  
  612.       iterator 
  613.       erase(iterator __position)
  614.       {
  615.     size_type __i = __position - _M_ibegin();
  616.         this->replace(__position, __position + 1, _M_data(), _M_data());
  617.     _M_rep()->_M_set_leaked(); 
  618.     return _M_ibegin() + __i;
  619.       }
  620.  
  621.       iterator 
  622.       erase(iterator __first, iterator __last)
  623.       {
  624.         size_type __i = __first - _M_ibegin();
  625.     this->replace(__first, __last, _M_data(), _M_data());
  626.     _M_rep()->_M_set_leaked();
  627.        return _M_ibegin() + __i;
  628.       }
  629.  
  630.       basic_string& 
  631.       replace(size_type __pos, size_type __n, const basic_string& __str)
  632.       { return this->replace(__pos, __n, __str._M_data(), __str.size()); }
  633.  
  634.       basic_string& 
  635.       replace(size_type __pos1, size_type __n1, const basic_string& __str,
  636.           size_type __pos2, size_type __n2);
  637.  
  638.       basic_string& 
  639.       replace(size_type __pos, size_type __n1, const _CharT* __s,
  640.           size_type __n2)
  641.       { 
  642.     const size_type __size = this->size();
  643.      if (__pos > __size)
  644.       __throw_out_of_range("basic_string::replace");
  645.     const bool __testn1 = __n1 < __size - __pos;
  646.     const size_type __foldn1 = __testn1 ? __n1 : __size - __pos;
  647.     if (__size - __foldn1 > this->max_size() - __n2)
  648.       __throw_length_error("basic_string::replace");
  649.     if (_M_rep()->_M_is_shared() || less<const _CharT*>()(__s, _M_data())
  650.         || less<const _CharT*>()(_M_data() + __size, __s))
  651.       return _M_replace_safe(_M_ibegin() + __pos,
  652.                  _M_ibegin() + __pos + __foldn1, __s, __s + __n2);    
  653.     // Todo: optimized in-place replace.
  654.     else return
  655.            _M_replace(_M_ibegin() + __pos, _M_ibegin() + __pos + __foldn1,
  656.               __s, __s + __n2,
  657.               typename iterator_traits<const _CharT*>::iterator_category());
  658.       }
  659.  
  660.       basic_string& 
  661.       replace(size_type __pos, size_type __n1, const _CharT* __s)
  662.       { return this->replace(__pos, __n1, __s, traits_type::length(__s)); }
  663.  
  664.       basic_string& 
  665.       replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
  666.       { return this->replace(_M_check(__pos), _M_fold(__pos, __n1), __n2, __c); }
  667.  
  668.       basic_string& 
  669.       replace(iterator __i1, iterator __i2, const basic_string& __str)
  670.       { return this->replace(__i1, __i2, __str._M_data(), __str.size()); }
  671.  
  672.       basic_string& 
  673.       replace(iterator __i1, iterator __i2,
  674.                            const _CharT* __s, size_type __n)
  675.       { return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n); }
  676.  
  677.       basic_string& 
  678.       replace(iterator __i1, iterator __i2, const _CharT* __s)
  679.       { return this->replace(__i1, __i2, __s, traits_type::length(__s)); }
  680.  
  681.       basic_string& 
  682.       replace(iterator __i1, iterator __i2, size_type __n, _CharT __c);
  683.  
  684.       template<class _InputIterator>
  685.         basic_string& 
  686.         replace(iterator __i1, iterator __i2,
  687.         _InputIterator __k1, _InputIterator __k2)
  688.         { return _M_replace(__i1, __i2, __k1, __k2,
  689.          typename iterator_traits<_InputIterator>::iterator_category()); }
  690.  
  691.       // Specializations for the common case of pointer and iterator:
  692.       // useful to avoid the overhead of temporary buffering in _M_replace.
  693.       basic_string& 
  694.       replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2)
  695.         { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
  696.                    __k1, __k2 - __k1); }
  697.  
  698.       basic_string& 
  699.       replace(iterator __i1, iterator __i2, const _CharT* __k1, const _CharT* __k2)
  700.         { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
  701.                    __k1, __k2 - __k1); }
  702.  
  703.       basic_string& 
  704.       replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2)
  705.         { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
  706.                    __k1.base(), __k2 - __k1);
  707.     }
  708.  
  709.       basic_string& 
  710.       replace(iterator __i1, iterator __i2, const_iterator __k1, const_iterator __k2)
  711.         { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
  712.                    __k1.base(), __k2 - __k1);
  713.     }
  714.  
  715.     private:
  716.       template<class _InputIterator>
  717.         basic_string& 
  718.         _M_replace(iterator __i1, iterator __i2, _InputIterator __k1, 
  719.            _InputIterator __k2, input_iterator_tag);
  720.  
  721.       template<class _ForwardIterator>
  722.         basic_string& 
  723.         _M_replace_safe(iterator __i1, iterator __i2, _ForwardIterator __k1, 
  724.            _ForwardIterator __k2);
  725.  
  726.       // _S_construct_aux is used to implement the 21.3.1 para 15 which
  727.       // requires special behaviour if _InIter is an integral type
  728.       template<class _InIter>
  729.         static _CharT*
  730.         _S_construct_aux(_InIter __beg, _InIter __end, const _Alloc& __a,
  731.              __false_type)
  732.     {
  733.           typedef typename iterator_traits<_InIter>::iterator_category _Tag;
  734.           return _S_construct(__beg, __end, __a, _Tag());
  735.     }
  736.  
  737.       template<class _InIter>
  738.         static _CharT*
  739.         _S_construct_aux(_InIter __beg, _InIter __end, const _Alloc& __a,
  740.              __true_type)
  741.     {
  742.       return _S_construct(static_cast<size_type>(__beg),
  743.                   static_cast<value_type>(__end), __a);
  744.     }
  745.  
  746.       template<class _InIter>
  747.         static _CharT*
  748.         _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a)
  749.     {
  750.       typedef typename _Is_integer<_InIter>::_Integral _Integral;
  751.       return _S_construct_aux(__beg, __end, __a, _Integral());
  752.         }
  753.  
  754.       // For Input Iterators, used in istreambuf_iterators, etc.
  755.       template<class _InIter>
  756.         static _CharT*
  757.          _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a,
  758.               input_iterator_tag);
  759.       
  760.       // For forward_iterators up to random_access_iterators, used for
  761.       // string::iterator, _CharT*, etc.
  762.       template<class _FwdIter>
  763.         static _CharT*
  764.         _S_construct(_FwdIter __beg, _FwdIter __end, const _Alloc& __a,
  765.              forward_iterator_tag);
  766.  
  767.       static _CharT* 
  768.       _S_construct(size_type __req, _CharT __c, const _Alloc& __a);
  769.  
  770.     public:
  771.  
  772.       size_type 
  773.       copy(_CharT* __s, size_type __n, size_type __pos = 0) const;
  774.  
  775.       void 
  776.       swap(basic_string<_CharT, _Traits, _Alloc>& __s);
  777.  
  778.       // String operations:
  779.       const _CharT* 
  780.       c_str() const
  781.       {
  782.     // MT: This assumes concurrent writes are OK.
  783.     size_type __n = this->size();
  784.     traits_type::assign(_M_data()[__n], _Rep::_S_terminal);
  785.         return _M_data();
  786.       }
  787.  
  788.       const _CharT* 
  789.       data() const { return _M_data(); }
  790.  
  791.       allocator_type 
  792.       get_allocator() const { return _M_dataplus; }
  793.  
  794.       size_type 
  795.       find(const _CharT* __s, size_type __pos, size_type __n) const;
  796.  
  797.       size_type 
  798.       find(const basic_string& __str, size_type __pos = 0) const
  799.       { return this->find(__str.data(), __pos, __str.size()); }
  800.  
  801.       size_type 
  802.       find(const _CharT* __s, size_type __pos = 0) const
  803.       { return this->find(__s, __pos, traits_type::length(__s)); }
  804.  
  805.       size_type 
  806.       find(_CharT __c, size_type __pos = 0) const;
  807.  
  808.       size_type 
  809.       rfind(const basic_string& __str, size_type __pos = npos) const
  810.       { return this->rfind(__str.data(), __pos, __str.size()); }
  811.  
  812.       size_type 
  813.       rfind(const _CharT* __s, size_type __pos, size_type __n) const;
  814.  
  815.       size_type 
  816.       rfind(const _CharT* __s, size_type __pos = npos) const
  817.       { return this->rfind(__s, __pos, traits_type::length(__s)); }
  818.  
  819.       size_type 
  820.       rfind(_CharT __c, size_type __pos = npos) const;
  821.  
  822.       size_type 
  823.       find_first_of(const basic_string& __str, size_type __pos = 0) const
  824.       { return this->find_first_of(__str.data(), __pos, __str.size()); }
  825.  
  826.       size_type 
  827.       find_first_of(const _CharT* __s, size_type __pos, size_type __n) const;
  828.  
  829.       size_type 
  830.       find_first_of(const _CharT* __s, size_type __pos = 0) const
  831.       { return this->find_first_of(__s, __pos, traits_type::length(__s)); }
  832.  
  833.       size_type 
  834.       find_first_of(_CharT __c, size_type __pos = 0) const
  835.       { return this->find(__c, __pos); }
  836.  
  837.       size_type 
  838.       find_last_of(const basic_string& __str, size_type __pos = npos) const
  839.       { return this->find_last_of(__str.data(), __pos, __str.size()); }
  840.  
  841.       size_type 
  842.       find_last_of(const _CharT* __s, size_type __pos, size_type __n) const;
  843.  
  844.       size_type 
  845.       find_last_of(const _CharT* __s, size_type __pos = npos) const
  846.       { return this->find_last_of(__s, __pos, traits_type::length(__s)); }
  847.  
  848.       size_type 
  849.       find_last_of(_CharT __c, size_type __pos = npos) const
  850.       { return this->rfind(__c, __pos); }
  851.  
  852.       size_type 
  853.       find_first_not_of(const basic_string& __str, size_type __pos = 0) const
  854.       { return this->find_first_not_of(__str.data(), __pos, __str.size()); }
  855.  
  856.       size_type 
  857.       find_first_not_of(const _CharT* __s, size_type __pos, 
  858.             size_type __n) const;
  859.  
  860.       size_type 
  861.       find_first_not_of(const _CharT* __s, size_type __pos = 0) const
  862.       { return this->find_first_not_of(__s, __pos, traits_type::length(__s)); }
  863.  
  864.       size_type 
  865.       find_first_not_of(_CharT __c, size_type __pos = 0) const;
  866.  
  867.       size_type 
  868.       find_last_not_of(const basic_string& __str, size_type __pos = npos) const
  869.       { return this->find_last_not_of(__str.data(), __pos, __str.size()); }
  870.  
  871.       size_type 
  872.       find_last_not_of(const _CharT* __s, size_type __pos, 
  873.                size_type __n) const;
  874.       size_type 
  875.       find_last_not_of(const _CharT* __s, size_type __pos = npos) const
  876.       { return this->find_last_not_of(__s, __pos, traits_type::length(__s)); }
  877.  
  878.       size_type 
  879.       find_last_not_of(_CharT __c, size_type __pos = npos) const;
  880.  
  881.       basic_string 
  882.       substr(size_type __pos = 0, size_type __n = npos) const
  883.       { 
  884.     if (__pos > this->size())
  885.       __throw_out_of_range("basic_string::substr");
  886.     return basic_string(*this, __pos, __n); 
  887.       }
  888.  
  889.       int 
  890.       compare(const basic_string& __str) const
  891.       {
  892.     size_type __size = this->size();
  893.     size_type __osize = __str.size();
  894.     size_type __len = min(__size, __osize);
  895.       
  896.     int __r = traits_type::compare(_M_data(), __str.data(), __len);
  897.     if (!__r)
  898.       __r =  __size - __osize;
  899.     return __r;
  900.       }
  901.  
  902.       int 
  903.       compare(size_type __pos, size_type __n, const basic_string& __str) const;
  904.  
  905.       int 
  906.       compare(size_type __pos1, size_type __n1, const basic_string& __str,
  907.           size_type __pos2, size_type __n2) const;
  908.  
  909.       int 
  910.       compare(const _CharT* __s) const;
  911.  
  912.       // _GLIBCPP_RESOLVE_LIB_DEFECTS
  913.       // 5. String::compare specification questionable
  914.       int 
  915.       compare(size_type __pos, size_type __n1, const _CharT* __s) const;
  916.  
  917.       int 
  918.       compare(size_type __pos, size_type __n1, const _CharT* __s, 
  919.           size_type __n2) const;
  920.   };
  921.  
  922.  
  923.   template<typename _CharT, typename _Traits, typename _Alloc>
  924.     inline basic_string<_CharT, _Traits, _Alloc>::
  925.     basic_string()
  926.     : _M_dataplus(_S_empty_rep()._M_refcopy(), _Alloc()) { }
  927.  
  928.   // operator+
  929.   template<typename _CharT, typename _Traits, typename _Alloc>
  930.     basic_string<_CharT, _Traits, _Alloc>
  931.     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
  932.           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
  933.     {
  934.       basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
  935.       __str.append(__rhs);
  936.       return __str;
  937.     }
  938.  
  939.   template<typename _CharT, typename _Traits, typename _Alloc>
  940.     basic_string<_CharT,_Traits,_Alloc>
  941.     operator+(const _CharT* __lhs,
  942.           const basic_string<_CharT,_Traits,_Alloc>& __rhs);
  943.  
  944.   template<typename _CharT, typename _Traits, typename _Alloc>
  945.     basic_string<_CharT,_Traits,_Alloc>
  946.     operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs);
  947.  
  948.   template<typename _CharT, typename _Traits, typename _Alloc>
  949.     inline basic_string<_CharT, _Traits, _Alloc>
  950.     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
  951.          const _CharT* __rhs)
  952.     {
  953.       basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
  954.       __str.append(__rhs);
  955.       return __str;
  956.     }
  957.  
  958.   template<typename _CharT, typename _Traits, typename _Alloc>
  959.     inline basic_string<_CharT, _Traits, _Alloc>
  960.     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs)
  961.     {
  962.       typedef basic_string<_CharT, _Traits, _Alloc>     __string_type;
  963.       typedef typename __string_type::size_type        __size_type;
  964.       __string_type __str(__lhs);
  965.       __str.append(__size_type(1), __rhs);
  966.       return __str;
  967.     }
  968.  
  969.   // operator ==
  970.   template<typename _CharT, typename _Traits, typename _Alloc>
  971.     inline bool
  972.     operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
  973.            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
  974.     { return __lhs.compare(__rhs) == 0; }
  975.  
  976.   template<typename _CharT, typename _Traits, typename _Alloc>
  977.     inline bool
  978.     operator==(const _CharT* __lhs,
  979.            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
  980.     { return __rhs.compare(__lhs) == 0; }
  981.  
  982.   template<typename _CharT, typename _Traits, typename _Alloc>
  983.     inline bool
  984.     operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
  985.            const _CharT* __rhs)
  986.     { return __lhs.compare(__rhs) == 0; }
  987.  
  988.   // operator !=
  989.   template<typename _CharT, typename _Traits, typename _Alloc>
  990.     inline bool
  991.     operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
  992.            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
  993.     { return __rhs.compare(__lhs) != 0; }
  994.  
  995.   template<typename _CharT, typename _Traits, typename _Alloc>
  996.     inline bool
  997.     operator!=(const _CharT* __lhs,
  998.            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
  999.     { return __rhs.compare(__lhs) != 0; }
  1000.  
  1001.   template<typename _CharT, typename _Traits, typename _Alloc>
  1002.     inline bool
  1003.     operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
  1004.            const _CharT* __rhs)
  1005.     { return __lhs.compare(__rhs) != 0; }
  1006.  
  1007.   // operator <
  1008.   template<typename _CharT, typename _Traits, typename _Alloc>
  1009.     inline bool
  1010.     operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
  1011.           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
  1012.     { return __lhs.compare(__rhs) < 0; }
  1013.  
  1014.   template<typename _CharT, typename _Traits, typename _Alloc>
  1015.     inline bool
  1016.     operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
  1017.           const _CharT* __rhs)
  1018.     { return __lhs.compare(__rhs) < 0; }
  1019.  
  1020.   template<typename _CharT, typename _Traits, typename _Alloc>
  1021.     inline bool
  1022.     operator<(const _CharT* __lhs,
  1023.           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
  1024.     { return __rhs.compare(__lhs) > 0; }
  1025.  
  1026.   // operator >
  1027.   template<typename _CharT, typename _Traits, typename _Alloc>
  1028.     inline bool
  1029.     operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
  1030.           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
  1031.     { return __lhs.compare(__rhs) > 0; }
  1032.  
  1033.   template<typename _CharT, typename _Traits, typename _Alloc>
  1034.     inline bool
  1035.     operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
  1036.           const _CharT* __rhs)
  1037.     { return __lhs.compare(__rhs) > 0; }
  1038.  
  1039.   template<typename _CharT, typename _Traits, typename _Alloc>
  1040.     inline bool
  1041.     operator>(const _CharT* __lhs,
  1042.           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
  1043.     { return __rhs.compare(__lhs) < 0; }
  1044.  
  1045.   // operator <=
  1046.   template<typename _CharT, typename _Traits, typename _Alloc>
  1047.     inline bool
  1048.     operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
  1049.            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
  1050.     { return __lhs.compare(__rhs) <= 0; }
  1051.  
  1052.   template<typename _CharT, typename _Traits, typename _Alloc>
  1053.     inline bool
  1054.     operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
  1055.            const _CharT* __rhs)
  1056.     { return __lhs.compare(__rhs) <= 0; }
  1057.  
  1058.   template<typename _CharT, typename _Traits, typename _Alloc>
  1059.     inline bool
  1060.     operator<=(const _CharT* __lhs,
  1061.            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
  1062.   { return __rhs.compare(__lhs) >= 0; }
  1063.  
  1064.   // operator >=
  1065.   template<typename _CharT, typename _Traits, typename _Alloc>
  1066.     inline bool
  1067.     operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
  1068.            const basic_string<_CharT, _Traits, _Alloc>& __rhs)
  1069.     { return __lhs.compare(__rhs) >= 0; }
  1070.  
  1071.   template<typename _CharT, typename _Traits, typename _Alloc>
  1072.     inline bool
  1073.     operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
  1074.            const _CharT* __rhs)
  1075.     { return __lhs.compare(__rhs) >= 0; }
  1076.  
  1077.   template<typename _CharT, typename _Traits, typename _Alloc>
  1078.     inline bool
  1079.     operator>=(const _CharT* __lhs,
  1080.          const basic_string<_CharT, _Traits, _Alloc>& __rhs)
  1081.     { return __rhs.compare(__lhs) <= 0; }
  1082.  
  1083.  
  1084.   template<typename _CharT, typename _Traits, typename _Alloc>
  1085.     inline void
  1086.     swap(basic_string<_CharT, _Traits, _Alloc>& __lhs,
  1087.      basic_string<_CharT, _Traits, _Alloc>& __rhs)
  1088.     { __lhs.swap(__rhs); }
  1089.  
  1090.   template<typename _CharT, typename _Traits, typename _Alloc>
  1091.     basic_istream<_CharT, _Traits>&
  1092.     operator>>(basic_istream<_CharT, _Traits>& __is,
  1093.            basic_string<_CharT, _Traits, _Alloc>& __str);
  1094.  
  1095.   template<typename _CharT, typename _Traits, typename _Alloc>
  1096.     basic_ostream<_CharT, _Traits>&
  1097.     operator<<(basic_ostream<_CharT, _Traits>& __os,
  1098.            const basic_string<_CharT, _Traits, _Alloc>& __str);
  1099.  
  1100.   template<typename _CharT, typename _Traits, typename _Alloc>
  1101.     basic_istream<_CharT,_Traits>&
  1102.     getline(basic_istream<_CharT, _Traits>& __is,
  1103.         basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim);
  1104.  
  1105.   template<typename _CharT, typename _Traits, typename _Alloc>
  1106.     inline basic_istream<_CharT,_Traits>&
  1107.     getline(basic_istream<_CharT, _Traits>& __is,
  1108.         basic_string<_CharT, _Traits, _Alloc>& __str);
  1109. } // namespace std
  1110.  
  1111. #endif /* _CPP_BITS_STRING_H */
  1112.