Subversion Repositories Kolibri OS

Rev

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

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