string
上传用户:kellyonhid
上传日期:2013-10-12
资源大小:932k
文件大小:62k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. /*
  2.  * Copyright (c) 1997,1998
  3.  * Silicon Graphics Computer Systems, Inc.
  4.  *
  5.  * Permission to use, copy, modify, distribute and sell this software
  6.  * and its documentation for any purpose is hereby granted without fee,
  7.  * provided that the above copyright notice appear in all copies and
  8.  * that both that copyright notice and this permission notice appear
  9.  * in supporting documentation.  Silicon Graphics makes no
  10.  * representations about the suitability of this software for any
  11.  * purpose.  It is provided "as is" without express or implied warranty.
  12.  */ 
  13. #ifndef __SGI_STL_STRING
  14. #define __SGI_STL_STRING
  15. #include <ctype.h>        
  16. #include <stdexcept>      // Includes stl_string_fwd.h and stl_config.h
  17. #include <char_traits.h>  // This header name is an extension.
  18. #include <iterator>
  19. #include <functional>
  20. #include <memory>
  21. #include <algorithm>
  22. // Standard C++ string class.  This class has performance
  23. // characteristics very much like vector<>, meaning, for example, that
  24. // it does not perform reference-count or copy-on-write, and that
  25. // concatenation of two strings is an O(N) operation. 
  26. // There are three reasons why basic_string is not identical to
  27. // vector.  First, basic_string always stores a null character at the
  28. // end; this makes it possible for c_str to be a fast operation.
  29. // Second, the C++ standard requires basic_string to copy elements
  30. // using char_traits<>::assign, char_traits<>::copy, and
  31. // char_traits<>::move.  This means that all of vector<>'s low-level
  32. // operations must be rewritten.  Third, basic_string<> has a lot of
  33. // extra functions in its interface that are convenient but, strictly
  34. // speaking, redundant.
  35. // Additionally, the C++ standard imposes a major restriction: according
  36. // to the standard, the character type _CharT must be a POD type.  This
  37. // implementation weakens that restriction, and allows _CharT to be a
  38. // a user-defined non-POD type.  However, _CharT must still have a
  39. // default constructor.
  40. __STL_BEGIN_NAMESPACE
  41. #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
  42. #pragma set woff 1174
  43. #pragma set woff 1375
  44. #endif
  45. // Helper classes that turn char_traits into function objects.
  46. template <class _Traits>
  47. struct _Eq_traits
  48.   : public binary_function<typename _Traits::char_type,
  49.                            typename _Traits::char_type,
  50.                            bool>
  51. {
  52.   bool operator()(const typename _Traits::char_type& __x,
  53.                   const typename _Traits::char_type& __y) const
  54.     { return _Traits::eq(__x, __y); }
  55. };
  56. template <class _Traits>
  57. struct _Lt_traits
  58.   : public binary_function<typename _Traits::char_type,
  59.                            typename _Traits::char_type,
  60.                            bool>
  61. {
  62.   bool operator()(const typename _Traits::char_type& __x,
  63.                   const typename _Traits::char_type& __y) const
  64.     { return _Traits::lt(__x, __y); }
  65. };
  66. template <class _Traits>
  67. struct _Not_within_traits
  68.   : public unary_function<typename _Traits::char_type, bool>
  69. {
  70.   typedef const typename _Traits::char_type* _Pointer;
  71.   const _Pointer _M_first;
  72.   const _Pointer _M_last;
  73.   _Not_within_traits(_Pointer __f, _Pointer __l) 
  74.     : _M_first(__f), _M_last(__l) {}
  75.   bool operator()(const typename _Traits::char_type& __x) const {
  76.     return find_if(_M_first, _M_last, 
  77.                    bind1st(_Eq_traits<_Traits>(), __x)) == _M_last;
  78.   }
  79. };
  80. // ------------------------------------------------------------
  81. // Class _String_base.  
  82. // _String_base is a helper class that makes it it easier to write an
  83. // exception-safe version of basic_string.  The constructor allocates,
  84. // but does not initialize, a block of memory.  The destructor
  85. // deallocates, but does not destroy elements within, a block of
  86. // memory.  The destructor assumes that _M_start either is null, or else
  87. // points to a block of memory that was allocated using _String_base's 
  88. // allocator and whose size is _M_end_of_storage - _M_start.
  89. // Additionally, _String_base encapsulates the difference between
  90. // old SGI-style allocators and standard-conforming allocators.
  91. #ifdef __STL_USE_STD_ALLOCATORS
  92. // General base class.
  93. template <class _T, class _Alloc, bool _S_instanceless>
  94. class _String_alloc_base {
  95. public:
  96.   typedef typename _Alloc_traits<_T, _Alloc>::allocator_type allocator_type;
  97.   allocator_type get_allocator() const { return _M_data_allocator; }
  98.   _String_alloc_base(const allocator_type& __a)
  99.     : _M_data_allocator(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0)
  100.     {}
  101. protected:
  102.   _T* _M_allocate(size_t __n)
  103.     { return _M_data_allocator.allocate(__n); }
  104.   void _M_deallocate(_T* __p, size_t __n) {
  105.     if (__p)
  106.       _M_data_allocator.deallocate(__p, __n); 
  107.   }
  108. protected:
  109.   allocator_type _M_data_allocator;
  110.   _T* _M_start;
  111.   _T* _M_finish;
  112.   _T* _M_end_of_storage;
  113. };
  114. // Specialization for instanceless allocators.
  115. template <class _T, class _Alloc>
  116. class _String_alloc_base<_T,_Alloc,true> {
  117. public:
  118.   typedef typename _Alloc_traits<_T, _Alloc>::allocator_type allocator_type;
  119.   allocator_type get_allocator() const { return allocator_type(); }
  120.   _String_alloc_base(const allocator_type&)
  121.     : _M_start(0), _M_finish(0), _M_end_of_storage(0) {}
  122. protected:
  123.   typedef typename _Alloc_traits<_T, _Alloc>::_Alloc_type _Alloc_type;
  124.   _T* _M_allocate(size_t __n)
  125.     { return _Alloc_type::allocate(__n); }
  126.   void _M_deallocate(_T* __p, size_t __n)
  127.     { _Alloc_type::deallocate(__p, __n); }
  128. protected:
  129.   _T* _M_start;
  130.   _T* _M_finish;
  131.   _T* _M_end_of_storage;
  132. };
  133. template <class _T, class _Alloc>
  134. class _String_base 
  135.   : public _String_alloc_base<_T, _Alloc,
  136.                               _Alloc_traits<_T, _Alloc>::_S_instanceless>
  137. {
  138. protected:
  139.   typedef _String_alloc_base<_T, _Alloc,
  140.                              _Alloc_traits<_T, _Alloc>::_S_instanceless>
  141.           _Base;
  142.   typedef typename _Base::allocator_type allocator_type;
  143.   void _M_allocate_block(size_t __n) { 
  144.     if (__n <= max_size()) {
  145.       _M_start  = _M_allocate(__n);
  146.       _M_finish = _M_start;
  147.       _M_end_of_storage = _M_start + __n;
  148.     }
  149.     else
  150.       _M_throw_length_error();
  151.   }
  152.   void _M_deallocate_block() 
  153.     { _M_deallocate(_M_start, _M_end_of_storage - _M_start); }
  154.   
  155.   size_t max_size() const { return (size_t(-1) / sizeof(_T)) - 1; }
  156.   _String_base(const allocator_type& __a) : _Base(__a) { }
  157.   
  158.   _String_base(const allocator_type& __a, size_t __n) : _Base(__a)
  159.     { _M_allocate_block(__n); }
  160.   ~_String_base() { _M_deallocate_block(); }
  161.   void _M_throw_length_error() const;
  162.   void _M_throw_out_of_range() const;
  163. };
  164. #else /* __STL_USE_STD_ALLOCATORS */
  165. template <class _T, class _Alloc> class _String_base {
  166. protected:
  167.   typedef _Simple_alloc<_T, _Alloc> _Alloc_type;
  168.   typedef _Alloc allocator_type;
  169.   _T* _M_start;
  170.   _T* _M_finish;
  171.   _T* _M_end_of_storage;
  172.                                 // Precondition: 0 < __n <= max_size().
  173.   _T* _M_allocate(size_t __n) { return _Alloc_type.allocate(__n); }
  174.   void _M_deallocate(_T* __p, size_t __n) {
  175.     if (__p)
  176.       _Alloc_type.deallocate(__p, __n); 
  177.   }
  178.   void _M_allocate_block(size_t __n) { 
  179.     if (__n <= max_size()) {
  180.       _M_start  = allocate(__n);
  181.       _M_finish = _M_start;
  182.       _M_end_of_storage = _M_start + __n;
  183.     }
  184.     else
  185.       _M_throw_length_error();
  186.   }
  187.   void _M_deallocate_block() 
  188.     { _M_deallocate(_M_start, _M_end_of_storage - _M_start); }
  189.   
  190.   size_t max_size() const { return (size_t(-1) / sizeof(_T)) - 1; }
  191.   _String_base(const allocator_type&)
  192.     : _M_start(0), _M_finish(0), _M_end_of_storage(0) { }
  193.   
  194.   _String_base(const allocator_type&, size_t __n)
  195.     : _M_start(0), _M_finish(0), _M_end_of_storage(0)
  196.     { _M_allocate_block(__n); }
  197.   ~_String_base() { _M_deallocate_block(); }
  198.   void _M_throw_length_error() const;
  199.   void _M_throw_out_of_range() const;
  200. };
  201. #endif /* __STL_USE_STD_ALLOCATORS */
  202. template <class _T, class _Alloc> 
  203. void _String_base<_T,_Alloc>::_M_throw_length_error() const {
  204.   __STL_THROW(length_error("basic_string"));
  205. }
  206. template <class _T, class _Alloc> 
  207. void _String_base<_T, _Alloc>::_M_throw_out_of_range() const {
  208.   __STL_THROW(out_of_range("basic_string"));
  209. }
  210. // ------------------------------------------------------------
  211. // Class basic_string.  
  212. // Class invariants:
  213. // (1) [start, finish) is a valid range.
  214. // (2) Each iterator in [start, finish) points to a valid object
  215. //     of type value_type.
  216. // (3) *finish is a valid object of type value_type; in particular,
  217. //     it is value_type().
  218. // (4) [finish + 1, end_of_storage) is a valid range.
  219. // (5) Each iterator in [finish + 1, end_of_storage) points to 
  220. //     unininitialized memory.
  221. // Note one important consequence: a string of length n must manage
  222. // a block of memory whose size is at least n + 1.  
  223. template <class _CharT, class _Traits, class _Alloc> 
  224. class basic_string : private _String_base<_CharT,_Alloc> {
  225. public:
  226.   typedef _CharT value_type;
  227.   typedef _Traits traits_type;
  228.   typedef value_type* pointer;
  229.   typedef const value_type* const_pointer;
  230.   typedef value_type& reference;
  231.   typedef const value_type& const_reference;
  232.   typedef size_t size_type;
  233.   typedef ptrdiff_t difference_type;
  234.   typedef const value_type*                const_iterator;
  235.   typedef value_type*                      iterator;
  236.   typedef reverse_iterator<const_iterator> const_reverse_iterator;
  237.   typedef reverse_iterator<iterator>       reverse_iterator;
  238.   static const size_type npos = -1;
  239.   typedef _String_base<_CharT,_Alloc> _Base;
  240. public:                         // Constructor, destructor, assignment.
  241.   typedef typename _Base::allocator_type allocator_type;
  242. #ifdef __STL_USE_NAMESPACES
  243.   using _Base::get_allocator;
  244. #endif /* __STL_USE_NAMESPACES */
  245.   explicit basic_string(const allocator_type& __a = allocator_type())
  246.     : _Base(__a, 8) { construct(_M_finish); }
  247.   struct _Reserve_t {};
  248.   basic_string(_Reserve_t, size_t __n,
  249.                const allocator_type& __a = allocator_type())
  250.     : _Base(__a, __n + 1) { construct(_M_finish); }
  251.   basic_string(const basic_string& __s) : _Base(__s.get_allocator()) 
  252.     { _M_range_initialize(__s.begin(), __s.end()); }
  253.   basic_string(const basic_string& __s, size_type __pos, size_type __n = npos,
  254.                const allocator_type& __a = allocator_type()) 
  255.     : _Base(__a) {
  256.     if (__pos > __s.size())
  257.       _M_throw_out_of_range();
  258.     else
  259.       _M_range_initialize(__s.begin() + __pos,
  260.                           __s.begin() + __pos + min(__n, __s.size() - __pos));
  261.   }
  262.   basic_string(const _CharT* __s, size_type __n,
  263.                const allocator_type& __a = allocator_type()) 
  264.     : _Base(__a) 
  265.     { _M_range_initialize(__s, __s + __n); }
  266.   basic_string(const _CharT* __s,
  267.                const allocator_type& __a = allocator_type())
  268.     : _Base(__a) 
  269.     { _M_range_initialize(__s, __s + _Traits::length(__s)); }
  270.   basic_string(size_type __n, _CharT __c,
  271.                const allocator_type& __a = allocator_type())
  272.     : _Base(__a, __n + 1)
  273.   {
  274.     _M_finish = uninitialized_fill_n(_M_start, __n, __c);
  275.     _M_terminate_string();
  276.   }
  277.   // Check to see if _InputIterator is an integer type.  If so, then
  278.   // it can't be an iterator.
  279.   template <class _InputIterator>
  280.   basic_string(_InputIterator __f, _InputIterator __l,
  281.                const allocator_type& __a = allocator_type())
  282.     : _Base(__a)
  283.   {
  284.     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
  285.     _M_initialize_dispatch(__f, __l, _Integral());
  286.   }
  287.   ~basic_string() { destroy(_M_start, _M_finish + 1); }
  288.     
  289.   basic_string& operator=(const basic_string& __s) {
  290.     if (&__s != this) 
  291.       assign(__s.begin(), __s.end());
  292.     return *this;
  293.   }
  294.   basic_string& operator=(const _CharT* __s) 
  295.     { return assign(__s, __s + _Traits::length(__s)); }
  296.   basic_string& operator=(_CharT __c)
  297.     { return assign(static_cast<size_type>(1), __c); }
  298. private:                        // Protected members inherited from base.
  299. #ifdef __STL_HAS_NAMESPACES
  300.   using _Base::_M_allocate;
  301.   using _Base::_M_deallocate;
  302.   using _Base::_M_allocate_block;
  303.   using _Base::_M_deallocate_block;
  304.   using _Base::_M_throw_length_error;
  305.   using _Base::_M_throw_out_of_range;
  306.   using _Base::_M_start;
  307.   using _Base::_M_finish;
  308.   using _Base::_M_end_of_storage;
  309. #endif /* __STL_HAS_NAMESPACES */
  310. private:                        
  311.   // Helper functions used by constructors.  It is a severe error for
  312.   // any of them to be called anywhere except from within constructors.
  313.   void _M_terminate_string() {
  314.     __STL_TRY {
  315.       construct(_M_finish);
  316.     }
  317.     __STL_UNWIND(destroy(_M_start, _M_finish));
  318.   }
  319.     
  320.   template <class _InputIter>
  321.   void _M_range_initialize(_InputIter __f, _InputIter __l,
  322.                            input_iterator_tag) {
  323.     _M_allocate_block(8);
  324.     construct(_M_finish);
  325.     __STL_TRY {
  326.       append(__f, __l);
  327.     }
  328.     __STL_UNWIND(destroy(_M_start, _M_finish + 1));
  329.   }
  330.   template <class _ForwardIter>
  331.   void _M_range_initialize(_ForwardIter __f, _ForwardIter __l, 
  332.                            forward_iterator_tag) {
  333.     typename iterator_traits<_ForwardIter>::difference_type __n
  334.       = distance(__f, __l);
  335.     _M_allocate_block(__n + 1);
  336.     _M_finish = uninitialized_copy(__f, __l, _M_start);
  337.     _M_terminate_string();
  338.   }
  339.   template <class _InputIter>
  340.   void _M_range_initialize(_InputIter __f, _InputIter __l) {
  341.     typedef typename iterator_traits<_InputIter>::iterator_category _Category;
  342.     _M_range_initialize(__f, __l, _Category());
  343.   }
  344.   template <class _Integer>
  345.   void _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) {
  346.     _M_allocate_block(__n + 1);
  347.     _M_finish = uninitialized_fill_n(_M_start, __n, __x);
  348.     _M_terminate_string();
  349.   }
  350.   template <class _InputIter>
  351.   void _M_initialize_dispatch(_InputIter __f, _InputIter __l, __false_type) {
  352.      _M_range_initialize(__f, __l);
  353.   }
  354.     
  355. public:                         // Iterators.
  356.   iterator begin()             { return _M_start; }
  357.   iterator end()               { return _M_finish; }
  358.   const_iterator begin() const { return _M_start; }
  359.   const_iterator end()   const { return _M_finish; }  
  360.   reverse_iterator rbegin()             
  361.     { return reverse_iterator(_M_finish); }
  362.   reverse_iterator rend()               
  363.     { return reverse_iterator(_M_start); }
  364.   const_reverse_iterator rbegin() const 
  365.     { return const_reverse_iterator(_M_finish); }
  366.   const_reverse_iterator rend()   const 
  367.     { return const_reverse_iterator(_M_start); }
  368. public:                         // Size, capacity, etc.
  369.   size_type size() const { return _M_finish - _M_start; }
  370.   size_type length() const { return size(); }
  371. #ifdef __STL_USE_NAMESPACES
  372.   using _Base::max_size;
  373. #endif /* __STL_USE_NAMESPACES */
  374.   void resize(size_type __n, _CharT __c = _CharT()) {
  375.     if (__n <= size())
  376.       erase(begin() + __n, end());
  377.     else
  378.       append(__n - size(), __c);
  379.   }
  380.   void reserve(size_type = 0);
  381.   size_type capacity() const { return (_M_end_of_storage - _M_start) - 1; }
  382.   void clear() {
  383.     if (!empty()) {
  384.       _Traits::assign(*_M_start, _CharT());
  385.       destroy(_M_start+1, _M_finish+1);
  386.       _M_finish = _M_start;
  387.     }
  388.   } 
  389.   bool empty() const { return _M_start == _M_finish; }    
  390. public:                         // Element access.
  391.   const_reference operator[](size_type __n) const
  392.     { return *(_M_start + __n); }
  393.   reference operator[](size_type __n)
  394.     { return *(_M_start + __n); }
  395.   const_reference at(size_type __n) const {
  396.     if (__n >= size())
  397.       _M_throw_out_of_range();
  398.     return *(_M_start + __n);
  399.   }
  400.   reference at(size_type __n) {
  401.     if (__n >= size())
  402.       _M_throw_out_of_range();
  403.     return *(_M_start + __n);
  404.   }
  405. public:                         // Append, operator+=, push_back.
  406.   basic_string& operator+=(const basic_string& __s) { return append(__s); }
  407.   basic_string& operator+=(const _CharT* __s) { return append(__s); }
  408.   basic_string& operator+=(_CharT __c) { push_back(__c); return *this; }
  409.   basic_string& append(const basic_string& __s) 
  410.     { return append(__s.begin(), __s.end()); }
  411.   basic_string& append(const basic_string& __s,
  412.                        size_type __pos, size_type __n)
  413.   {
  414.     if (__pos > __s.size())
  415.       _M_throw_out_of_range();
  416.     return append(__s.begin() + __pos,
  417.                   __s.begin() + __pos + min(__n, __s.size() - __pos));
  418.   }
  419.   basic_string& append(const _CharT* __s, size_type __n) 
  420.     { return append(__s, __s+__n); }
  421.   basic_string& append(const _CharT* __s) 
  422.     { return append(__s, __s + _Traits::length(__s)); }
  423.   basic_string& append(size_type __n, _CharT __c);
  424.   // Check to see if _InputIterator is an integer type.  If so, then
  425.   // it can't be an iterator.
  426.   template <class _InputIter>
  427.   basic_string& append(_InputIter __first, _InputIter __last) {
  428.     typedef typename _Is_integer<_InputIter>::_Integral _Integral;
  429.     return _M_append_dispatch(__first, __last, _Integral());
  430.   }
  431.   void push_back(_CharT __c) {
  432.     if (_M_finish + 1 == _M_end_of_storage)
  433.       reserve(size() + max(size(), static_cast<size_type>(1)));
  434.     construct(_M_finish + 1);
  435.     _Traits::assign(*_M_finish, __c);
  436.     ++_M_finish;
  437.   }
  438.   void pop_back() {
  439.     _Traits::assign(*(_M_finish - 1), _CharT());
  440.     destroy(_M_finish);
  441.     --_M_finish;
  442.   }
  443. private:                        // Helper functions for append.
  444.   template <class _InputIter>
  445.   basic_string& append(_InputIter __f, _InputIter __l, input_iterator_tag);
  446.   template <class _ForwardIter>
  447.   basic_string& append(_ForwardIter __f, _ForwardIter __l, 
  448.                        forward_iterator_tag);
  449.   template <class _Integer>
  450.   basic_string& _M_append_dispatch(_Integer __n, _Integer __x, __true_type) {
  451.     return append((size_type) __n, (_CharT) __x);
  452.   }
  453.   template <class _InputIter>
  454.   basic_string& _M_append_dispatch(_InputIter __f, _InputIter __l,
  455.                                    __false_type) {
  456.     typedef typename iterator_traits<_InputIter>::iterator_category _Category;
  457.     return append(__f, __l, _Category());
  458.   }
  459. public:                         // Assign
  460.   
  461.   basic_string& assign(const basic_string& __s) 
  462.     { return assign(__s.begin(), __s.end()); }
  463.   basic_string& assign(const basic_string& __s, 
  464.                        size_type __pos, size_type __n) {
  465.     if (__pos > __s.size())
  466.       _M_throw_out_of_range();
  467.     return assign(__s.begin() + __pos, 
  468.                   __s.begin() + __pos + min(__n, __s.size() - __pos));
  469.   }
  470.   basic_string& assign(const _CharT* __s, size_type __n)
  471.     { return assign(__s, __s + __n); }
  472.   basic_string& assign(const _CharT* __s)
  473.     { return assign(__s, __s + _Traits::length(__s)); }
  474.   basic_string& assign(size_type __n, _CharT __c);
  475.   // Check to see if _InputIterator is an integer type.  If so, then
  476.   // it can't be an iterator.
  477.   template <class _InputIter>
  478.   basic_string& assign(_InputIter __first, _InputIter __last) {
  479.     typedef typename _Is_integer<_InputIter>::_Integral _Integral;
  480.     return _M_assign_dispatch(__first, __last, _Integral());
  481.   }
  482.   basic_string& assign(const _CharT* __f, const _CharT* __l);
  483. private:                        // Helper functions for assign.
  484.   template <class _Integer>
  485.   basic_string& _M_assign_dispatch(_Integer __n, _Integer __x, __true_type) {
  486.     return assign((size_type) __n, (_CharT) __x);
  487.   }
  488.   template <class _InputIter>
  489.   basic_string& _M_assign_dispatch(_InputIter __f, _InputIter __l,
  490.                                    __false_type);
  491. public:                         // Insert
  492.   basic_string& insert(size_type __pos, const basic_string& __s) {
  493.     if (__pos > size())
  494.       _M_throw_out_of_range();
  495.     if (size() > max_size() - __s.size())
  496.       _M_throw_length_error();
  497.     insert(_M_start + __pos, __s.begin(), __s.end());
  498.     return *this;
  499.   }
  500.   basic_string& insert(size_type __pos, const basic_string& __s,
  501.                        size_type __beg, size_type __n) {
  502.     if (__pos > size() || __beg > __s.size())
  503.       _M_throw_out_of_range();
  504.     size_type __len = min(__n, __s.size() - __beg);
  505.     if (size() > max_size() - __len)
  506.       _M_throw_length_error();
  507.     insert(_M_start + __pos,
  508.            __s.begin() + __beg, __s.begin() + __beg + __len);
  509.     return *this;
  510.   }
  511.   basic_string& insert(size_type __pos, const _CharT* __s, size_type __n) {
  512.     if (__pos > size())
  513.       _M_throw_out_of_range();
  514.     if (size() > max_size() - __n)
  515.       _M_throw_length_error();
  516.     insert(_M_start + __pos, __s, __s + __n);
  517.     return *this;
  518.   }
  519.   basic_string& insert(size_type __pos, const _CharT* __s) {
  520.     if (__pos > size())
  521.       _M_throw_out_of_range();
  522.     size_type __len = _Traits::length(__s);
  523.     if (size() > max_size() - __len)
  524.       _M_throw_length_error();
  525.     insert(_M_start + __pos, __s, __s + __len);
  526.     return *this;
  527.   }
  528.     
  529.   basic_string& insert(size_type __pos, size_type __n, _CharT __c) {
  530.     if (__pos > size())
  531.       _M_throw_out_of_range();
  532.     if (size() > max_size() - __n)
  533.       _M_throw_length_error();
  534.     insert(_M_start + __pos, __n, __c);
  535.     return *this;
  536.   }
  537.   iterator insert(iterator __p, _CharT __c) {
  538.     if (__p == _M_finish) {
  539.       push_back(__c);
  540.       return _M_finish - 1;
  541.     }
  542.     else
  543.       return _M_insert_aux(__p, __c);
  544.   }
  545.   void insert(iterator __p, size_t __n, _CharT __c);
  546.   // Check to see if _InputIterator is an integer type.  If so, then
  547.   // it can't be an iterator.
  548.   template <class _InputIter>
  549.   void insert(iterator __p, _InputIter __first, _InputIter __last) {
  550.     typedef typename _Is_integer<_InputIter>::_Integral _Integral;
  551.     _M_insert_dispatch(__p, __first, __last, _Integral());
  552.   }
  553. private:                        // Helper functions for insert.
  554.   template <class _InputIter>
  555.   void insert(iterator __p, _InputIter, _InputIter, input_iterator_tag);
  556.   template <class _ForwardIter>
  557.   void insert(iterator __p, _ForwardIter, _ForwardIter, forward_iterator_tag);
  558.   template <class _Integer>
  559.   void _M_insert_dispatch(iterator __p, _Integer __n, _Integer __x,
  560.                           __true_type) {
  561.     insert(__p, (size_type) __n, (_CharT) __x);
  562.   }
  563.   template <class _InputIter>
  564.   void _M_insert_dispatch(iterator __p, _InputIter __first, _InputIter __last,
  565.                           __false_type) {
  566.     typedef typename iterator_traits<_InputIter>::iterator_category _Category;
  567.     insert(__p, __first, __last, _Category());
  568.   }
  569.   iterator _M_insert_aux(iterator, _CharT);
  570.   template <class _InputIterator>
  571.   void 
  572.   _M_copy(_InputIterator __first, _InputIterator __last, iterator __result) {
  573.     for ( ; __first != __last; ++__first, ++__result)
  574.       _Traits::assign(*__result, *__first);
  575.   }
  576.   void 
  577.   _M_copy(const _CharT* __first, const _CharT* __last, _CharT* __result) {
  578.     _Traits::copy(__result, __first, __last - __first);
  579.   }
  580. public:                         // Erase.
  581.   basic_string& erase(size_type __pos = 0, size_type __n = npos) {
  582.     if (__pos > size())
  583.       _M_throw_out_of_range();
  584.     erase(_M_start + __pos, _M_start + __pos + min(__n, size() - __pos));
  585.     return *this;
  586.   }  
  587.   iterator erase(iterator __position) {
  588.                                 // The move includes the terminating _CharT().
  589.     _Traits::move(__position, __position + 1, _M_finish - __position);
  590.     destroy(_M_finish);
  591.     --_M_finish;
  592.     return __position;
  593.   }
  594.   iterator erase(iterator __first, iterator __last) {
  595.     if (__first != __last) {
  596.                                 // The move includes the terminating _CharT().
  597.       _Traits::move(__first, __last, (_M_finish - __last) + 1);
  598.       const iterator __new_finish = _M_finish - (__last - __first);
  599.       destroy(__new_finish + 1, _M_finish + 1);
  600.       _M_finish = __new_finish;
  601.     }
  602.     return __first;
  603.   }
  604. public:                         // Replace.  (Conceptually equivalent
  605.                                 // to erase followed by insert.)
  606.   basic_string& replace(size_type __pos, size_type __n, 
  607.                         const basic_string& __s) {
  608.     if (__pos > size())
  609.       _M_throw_out_of_range();
  610.     const size_type __len = min(__n, size() - __pos);
  611.     if (size() - __len >= max_size() - __s.size())
  612.       _M_throw_length_error();
  613.     return replace(_M_start + __pos, _M_start + __pos + __len, 
  614.                    __s.begin(), __s.end());
  615.   }
  616.   basic_string& replace(size_type __pos1, size_type __n1,
  617.                         const basic_string& __s,
  618.                         size_type __pos2, size_type __n2) {
  619.     if (__pos1 > size() || __pos2 > __s.size())
  620.       _M_throw_out_of_range();
  621.     const size_type __len1 = min(__n1, size() - __pos1);
  622.     const size_type __len2 = min(__n2, __s.size() - __pos2);
  623.     if (size() - __len1 >= max_size() - __len2)
  624.       _M_throw_length_error();
  625.     return replace(_M_start + __pos1, _M_start + __pos1 + __len1,
  626.                    __s._M_start + __pos2, __s._M_start + __pos2 + __len2);
  627.   }
  628.   basic_string& replace(size_type __pos, size_type __n1,
  629.                         const _CharT* __s, size_type __n2) {
  630.     if (__pos > size())
  631.       _M_throw_out_of_range();
  632.     const size_type __len = min(__n1, size() - __pos);
  633.     if (__n2 > max_size() || size() - __len >= max_size() - __n2)
  634.       _M_throw_length_error();
  635.     return replace(_M_start + __pos, _M_start + __pos + __len,
  636.                    __s, __s + __n2);
  637.   }
  638.   basic_string& replace(size_type __pos, size_type __n1,
  639.                         const _CharT* __s) {
  640.     if (__pos > size())
  641.       _M_throw_out_of_range();
  642.     const size_type __len = min(__n1, size() - __pos);
  643.     const size_type __n2 = _Traits::length(__s);
  644.     if (__n2 > max_size() || size() - __len >= max_size() - __n2)
  645.       _M_throw_length_error();
  646.     return replace(_M_start + __pos, _M_start + __pos + __len,
  647.                    __s, __s + _Traits::length(__s));
  648.   }
  649.   basic_string& replace(size_type __pos, size_type __n1,
  650.                         size_type __n2, _CharT __c) {
  651.     if (__pos > size())
  652.       _M_throw_out_of_range();
  653.     const size_type __len = min(__n1, size() - __pos);
  654.     if (__n2 > max_size() || size() - __len >= max_size() - __n2)
  655.       _M_throw_length_error();
  656.     return replace(_M_start + __pos, _M_start + __pos + __len, __n2, __c);
  657.   }
  658.   basic_string& replace(iterator __first, iterator __last, 
  659.                         const basic_string& __s) 
  660.     { return replace(__first, __last, __s.begin(), __s.end()); }
  661.   basic_string& replace(iterator __first, iterator __last,
  662.                         const _CharT* __s, size_type __n) 
  663.     { return replace(__first, __last, __s, __s + __n); }
  664.   basic_string& replace(iterator __first, iterator __last,
  665.                         const _CharT* __s) {
  666.     return replace(__first, __last, __s, __s + _Traits::length(__s));
  667.   }
  668.   basic_string& replace(iterator __first, iterator __last, 
  669.                         size_type __n, _CharT __c);
  670.   // Check to see if _InputIterator is an integer type.  If so, then
  671.   // it can't be an iterator.
  672.   template <class _InputIter>
  673.   basic_string& replace(iterator __first, iterator __last,
  674.                         _InputIter __f, _InputIter __l) {
  675.     typedef typename _Is_integer<_InputIter>::_Integral _Integral;
  676.     return _M_replace_dispatch(__first, __last, __f, __l,  _Integral());
  677.   }
  678. private:                        // Helper functions for replace.
  679.   template <class _Integer>
  680.   basic_string& _M_replace_dispatch(iterator __first, iterator __last,
  681.                                     _Integer __n, _Integer __x,
  682.                                     __true_type) {
  683.     return replace(__first, __last, (size_type) __n, (_CharT) __x);
  684.   }
  685.   template <class _InputIter>
  686.   basic_string& _M_replace_dispatch(iterator __first, iterator __last,
  687.                                     _InputIter __f, _InputIter __l,
  688.                                     __false_type) {
  689.     typedef typename iterator_traits<_InputIter>::iterator_category _Category;
  690.     return replace(__first, __last, __f, __l, _Category());
  691.   }
  692.   template <class _InputIter>
  693.   basic_string& replace(iterator __first, iterator __last,
  694.                         _InputIter __f, _InputIter __l, input_iterator_tag);
  695.   template <class _ForwardIter>
  696.   basic_string& replace(iterator __first, iterator __last,
  697.                         _ForwardIter __f, _ForwardIter __l, 
  698.                         forward_iterator_tag);
  699. public:                         // Other modifier member functions.
  700.   size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const {
  701.     if (__pos > size())
  702.       _M_throw_out_of_range();
  703.     const size_type __len = min(__n, size() - __pos);
  704.     _Traits::copy(__s, _M_start + __pos, __len);
  705.     return __len;
  706.   }
  707.   void swap(basic_string& __s) {
  708.     __STD::swap(_M_start, __s._M_start);
  709.     __STD::swap(_M_finish, __s._M_finish);
  710.     __STD::swap(_M_end_of_storage, __s._M_end_of_storage);
  711.   }
  712. public:                         // Conversion to C string.
  713.   const _CharT* c_str() const { return _M_start; }
  714.   const _CharT* data()  const { return _M_start; }
  715. public:                         // find.
  716.   size_type find(const basic_string& __s, size_type __pos = 0) const 
  717.     { return find(__s.begin(), __pos, __s.size()); }
  718.   size_type find(const _CharT* __s, size_type __pos = 0) const 
  719.     { return find(__s, __pos, _Traits::length(__s)); }
  720.   size_type find(const _CharT* __s, size_type __pos, size_type __n) const;
  721.   size_type find(_CharT __c, size_type __pos = 0) const;
  722. public:                         // rfind.
  723.   size_type rfind(const basic_string& __s, size_type __pos = npos) const 
  724.     { return rfind(__s.begin(), __pos, __s.size()); }
  725.   size_type rfind(const _CharT* __s, size_type __pos = npos) const 
  726.     { return rfind(__s, __pos, _Traits::length(__s)); }
  727.   size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const;
  728.   size_type rfind(_CharT __c, size_type __pos = npos) const;
  729. public:                         // find_first_of
  730.   
  731.   size_type find_first_of(const basic_string& __s, size_type __pos = 0) const 
  732.     { return find_first_of(__s.begin(), __pos, __s.size()); }
  733.   size_type find_first_of(const _CharT* __s, size_type __pos = 0) const 
  734.     { return find_first_of(__s, __pos, _Traits::length(__s)); }
  735.   size_type find_first_of(const _CharT* __s, size_type __pos, 
  736.                           size_type __n) const;
  737.   size_type find_first_of(_CharT __c, size_type __pos = 0) const 
  738.     { return find(__c, __pos); }
  739. public:                         // find_last_of
  740.   size_type find_last_of(const basic_string& __s,
  741.                          size_type __pos = npos) const
  742.     { return find_last_of(__s.begin(), __pos, __s.size()); }
  743.   size_type find_last_of(const _CharT* __s, size_type __pos = npos) const 
  744.     { return find_last_of(__s, __pos, _Traits::length(__s)); }
  745.   size_type find_last_of(const _CharT* __s, size_type __pos, 
  746.                          size_type __n) const;
  747.   size_type find_last_of(_CharT __c, size_type __pos = npos) const {
  748.     return rfind(__c, __pos);
  749.   }
  750. public:                         // find_first_not_of
  751.   size_type find_first_not_of(const basic_string& __s, 
  752.                               size_type __pos = 0) const 
  753.     { return find_first_not_of(__s.begin(), __pos, __s.size()); }
  754.   size_type find_first_not_of(const _CharT* __s, size_type __pos = 0) const 
  755.     { return find_first_not_of(__s, __pos, _Traits::length(__s)); }
  756.   size_type find_first_not_of(const _CharT* __s, size_type __pos,
  757.                               size_type __n) const;
  758.   size_type find_first_not_of(_CharT __c, size_type __pos = 0) const;
  759. public:                         // find_last_not_of
  760.   size_type find_last_not_of(const basic_string& __s, 
  761.                              size_type __pos = npos) const
  762.     { return find_last_not_of(__s.begin(), __pos, __s.size()); }
  763.   size_type find_last_not_of(const _CharT* __s, size_type __pos = npos) const
  764.     { return find_last_not_of(__s, __pos, _Traits::length(__s)); }
  765.   size_type find_last_not_of(const _CharT* __s, size_type __pos,
  766.                              size_type __n) const;
  767.   size_type find_last_not_of(_CharT __c, size_type __pos = npos) const;
  768. public:                         // Substring.
  769.   basic_string substr(size_type __pos = 0, size_type __n = npos) const {
  770.     if (__pos > size())
  771.       _M_throw_out_of_range();
  772.     return basic_string(_M_start + __pos, 
  773.                         _M_start + __pos + min(__n, size() - __pos));
  774.   }
  775. public:                         // Compare
  776.   int compare(const basic_string& __s) const 
  777.     { return _M_compare(_M_start, _M_finish, __s._M_start, __s._M_finish); }
  778.   int compare(size_type __pos1, size_type __n1,
  779.               const basic_string& __s) const {
  780.     if (__pos1 > size())
  781.       _M_throw_out_of_range();
  782.     return _M_compare(_M_start + __pos1, 
  783.                       _M_start + __pos1 + min(__n1, size() - __pos1),
  784.                       __s._M_start, __s._M_finish);
  785.   }
  786.     
  787.   int compare(size_type __pos1, size_type __n1,
  788.               const basic_string& __s,
  789.               size_type __pos2, size_type __n2) const {
  790.     if (__pos1 > size() || __pos2 > __s.size())
  791.       _M_throw_out_of_range();
  792.     return _M_compare(_M_start + __pos1, 
  793.                       _M_start + __pos1 + min(__n1, size() - __pos1),
  794.                       __s._M_start + __pos2, 
  795.                       __s._M_start + __pos2 + min(__n2, size() - __pos2));
  796.   }
  797.   int compare(const _CharT* __s) const {
  798.     return _M_compare(_M_start, _M_finish, __s, __s + _Traits::length(__s));
  799.   }
  800.   int compare(size_type __pos1, size_type __n1, const _CharT* __s) const {
  801.     if (__pos1 > size())
  802.       _M_throw_out_of_range();
  803.     return _M_compare(_M_start + __pos1, 
  804.                       _M_start + __pos1 + min(__n1, size() - __pos1),
  805.                       __s, __s + _Traits::length(__s));
  806.   }
  807.   int compare(size_type __pos1, size_type __n1, const _CharT* __s,
  808.               size_type __n2) const {
  809.     if (__pos1 > size())
  810.       _M_throw_out_of_range();
  811.     return _M_compare(_M_start + __pos1, 
  812.                       _M_start + __pos1 + min(__n1, size() - __pos1),
  813.                       __s, __s + __n2);
  814.   }
  815. private:                        // Helper functions for compare.
  816.   
  817.   static int _M_compare(const _CharT* __f1, const _CharT* __l1,
  818.                         const _CharT* __f2, const _CharT* __l2) {
  819.     const ptrdiff_t __n1 = __l1 - __f1;
  820.     const ptrdiff_t __n2 = __l2 - __f2;
  821.     const int cmp = _Traits::compare(__f1, __f2, min(__n1, __n2));
  822.     return cmp != 0 ? cmp : (__n1 < __n2 ? -1 : (__n1 > __n2 ? 1 : 0));
  823.   }
  824.   friend bool operator< __STL_NULL_TMPL_ARGS (const basic_string&,
  825.                                               const basic_string&);
  826.   friend bool operator< __STL_NULL_TMPL_ARGS (const _CharT*,
  827.                                               const basic_string&);
  828.   friend bool operator< __STL_NULL_TMPL_ARGS (const basic_string&,
  829.                                               const _CharT*);
  830. };
  831. // ------------------------------------------------------------
  832. // Non-inline declarations.
  833. template <class _CharT, class _Traits, class _Alloc> 
  834. const basic_string<_CharT,_Traits,_Alloc>::size_type 
  835. basic_string<_CharT,_Traits,_Alloc>::npos;
  836. // Change the string's capacity so that it is large enough to hold
  837. //  at least __res_arg elements, plus the terminating _CharT().  Note that,
  838. //  if __res_arg < capacity(), this member function may actually decrease
  839. //  the string's capacity.
  840. template <class _CharT, class _Traits, class _Alloc> 
  841. void basic_string<_CharT,_Traits,_Alloc>::reserve(size_type __res_arg = 0) {
  842.   if (__res_arg > max_size())
  843.     _M_throw_length_error();
  844.   size_type __n = max(__res_arg, size()) + 1;
  845.   pointer __new_start = _M_allocate(__n);
  846.   pointer __new_finish = __new_start;
  847.   __STL_TRY {
  848.     __new_finish = uninitialized_copy(_M_start, _M_finish, __new_start);
  849.     construct(__new_finish);
  850.   }
  851.   __STL_UNWIND((destroy(__new_start, __new_finish), 
  852.                 _M_deallocate(__new_start, __n)));
  853.   destroy(_M_start, _M_finish + 1);
  854.   _M_deallocate_block();
  855.   _M_start = __new_start;
  856.   _M_finish = __new_finish;
  857.   _M_end_of_storage = __new_start + __n;
  858. }
  859. template <class _CharT, class _Traits, class _Alloc> 
  860. basic_string<_CharT,_Traits,_Alloc>& 
  861. basic_string<_CharT,_Traits,_Alloc>::append(size_type __n, _CharT __c) {
  862.   if (__n > max_size() || size() > max_size() - __n)
  863.     _M_throw_length_error();
  864.   if (size() + __n > capacity())
  865.     reserve(size() + max(size(), __n));
  866.   if (__n > 0) {
  867.     uninitialized_fill_n(_M_finish + 1, __n - 1, __c);
  868.     __STL_TRY {
  869.       construct(_M_finish + __n);
  870.     }
  871.     __STL_UNWIND(destroy(_M_finish + 1, _M_finish + __n));
  872.     _Traits::assign(*_M_finish, __c);
  873.     _M_finish += __n;
  874.   }
  875.   return *this;
  876. }
  877. template <class _T, class _Traits, class _Alloc> 
  878. template <class _InputIterator>
  879. basic_string<_T, _Traits, _Alloc>& 
  880. basic_string<_T, _Traits, _Alloc>::append(_InputIterator __first, 
  881.                                           _InputIterator __last,
  882.                                           input_iterator_tag) {
  883.   for ( ; __first != __last ; ++__first)
  884.     push_back(*__first);
  885.   return *this;
  886. }
  887. template <class _T, class _Traits, class _Alloc> 
  888. template <class _ForwardIter>
  889. basic_string<_T, _Traits, _Alloc>& 
  890. basic_string<_T, _Traits, _Alloc>::append(_ForwardIter __first, 
  891.                                           _ForwardIter __last,
  892.                                           forward_iterator_tag) {
  893.   if (__first != __last) {
  894.     const size_type __old_size = size();
  895.     typename iterator_traits<_ForwardIter>::difference_type __n 
  896.       = distance(__first, __last);
  897.     if (__n > max_size() || __old_size > max_size() - __n)
  898.       _M_throw_length_error();
  899.     if (__old_size + __n > capacity()) {
  900.       const size_type __len = __old_size +
  901.                             max(__old_size, static_cast<size_type>(__n)) + 1;
  902.       pointer __new_start = _M_allocate(__len);
  903.       pointer __new_finish = __new_start;
  904.       __STL_TRY {
  905.         __new_finish = uninitialized_copy(_M_start, _M_finish, __new_start);
  906.         __new_finish = uninitialized_copy(__first, __last, __new_finish);
  907.         construct(__new_finish);
  908.       }
  909.       __STL_UNWIND((destroy(__new_start,__new_finish),
  910.                     _M_deallocate(__new_start,__len)));
  911.       destroy(_M_start, _M_finish + 1);
  912.       _M_deallocate_block();
  913.       _M_start = __new_start;
  914.       _M_finish = __new_finish;
  915.       _M_end_of_storage = __new_start + __len; 
  916.     }
  917.     else {
  918.       _ForwardIter __f1 = __first;
  919.       ++__f1;
  920.       uninitialized_copy(__f1, __last, _M_finish + 1);
  921.       __STL_TRY {
  922.         construct(_M_finish + __n);
  923.       }
  924.       __STL_UNWIND(destroy(_M_finish + 1, _M_finish + __n));
  925.       _Traits::assign(*_M_finish, *__first);
  926.       _M_finish += __n;
  927.     }
  928.   }
  929.   return *this;  
  930. }
  931. template <class _CharT, class _Traits, class _Alloc> 
  932. basic_string<_CharT,_Traits,_Alloc>& 
  933. basic_string<_CharT,_Traits,_Alloc>::assign(size_type __n, _CharT __c) {
  934.   if (__n <= size()) {
  935.     _Traits::assign(_M_start, __n, __c);
  936.     erase(_M_start + __n, _M_finish);
  937.   }
  938.   else {
  939.     _Traits::assign(_M_start, size(), __c);
  940.     append(__n - size(), __c);
  941.   }
  942.   return *this;
  943. }
  944. template <class _CharT, class _Traits, class _Alloc> 
  945. template <class _InputIter>
  946. basic_string<_CharT,_Traits,_Alloc>& basic_string<_CharT,_Traits,_Alloc>
  947.   ::_M_assign_dispatch(_InputIter __f, _InputIter __l, __false_type)
  948. {
  949.   pointer __cur = _M_start;
  950.   while (__f != __l && __cur != _M_finish) {
  951.     _Traits::assign(*__cur, *__f);
  952.     ++__f;
  953.     ++__cur;
  954.   }
  955.   if (__f == __l)
  956.     erase(__cur, _M_finish);
  957.   else
  958.     append(__f, __l);
  959.   return *this;
  960. }
  961. template <class _CharT, class _Traits, class _Alloc> 
  962. basic_string<_CharT,_Traits,_Alloc>& 
  963. basic_string<_CharT,_Traits,_Alloc>::assign(const _CharT* __f, 
  964.                                             const _CharT* __l)
  965. {
  966.   const ptrdiff_t __n = __l - __f;
  967.   if (__n <= size()) {
  968.     _Traits::copy(_M_start, __f, __n);
  969.     erase(_M_start + __n, _M_finish);
  970.   }
  971.   else {
  972.     _Traits::copy(_M_start, __f, size());
  973.     append(__f + size(), __l);
  974.   }
  975.   return *this;
  976. }
  977. template <class _CharT, class _Traits, class _Alloc>
  978. basic_string<_CharT,_Traits,_Alloc>::iterator 
  979. basic_string<_CharT,_Traits,_Alloc>
  980.   ::_M_insert_aux(basic_string<_CharT,_Traits,_Alloc>::iterator __p,
  981.                   _CharT __c)
  982. {
  983.   iterator __new_pos = __p;
  984.   if (_M_finish + 1 < _M_end_of_storage) {
  985.     construct(_M_finish + 1);
  986.     _Traits::move(__p + 1, __p, _M_finish - __p);
  987.     _Traits::assign(*__p, __c);
  988.     ++_M_finish;
  989.   }
  990.   else {
  991.     const size_type __old_len = size();
  992.     const size_type __len = __old_len +
  993.                             max(__old_len, static_cast<size_type>(1)) + 1;
  994.     iterator __new_start = _M_allocate(__len);
  995.     iterator __new_finish = __new_start;
  996.     __STL_TRY {
  997.       __new_pos = uninitialized_copy(_M_start, __p, __new_start);
  998.       construct(__new_pos, __c);
  999.       __new_finish = __new_pos + 1;
  1000.       __new_finish = uninitialized_copy(__p, _M_finish, __new_finish);
  1001.       construct(__new_finish);
  1002.     }
  1003.     __STL_UNWIND((destroy(__new_start,__new_finish), 
  1004.                   _M_deallocate(__new_start,__len)));
  1005.     destroy(_M_start, _M_finish + 1);
  1006.     _M_deallocate_block();
  1007.     _M_start = __new_start;
  1008.     _M_finish = __new_finish;
  1009.     _M_end_of_storage = __new_start + __len;
  1010.   }
  1011.   return __new_pos;
  1012. }
  1013. template <class _CharT, class _Traits, class _Alloc>
  1014. void basic_string<_CharT,_Traits,_Alloc>
  1015.   ::insert(basic_string<_CharT,_Traits,_Alloc>::iterator __position,
  1016.            size_t __n, _CharT __c)
  1017. {
  1018.   if (__n != 0) {
  1019.     if (size_type(_M_end_of_storage - _M_finish) >= __n + 1) {
  1020.       const size_type __elems_after = _M_finish - __position;
  1021.       iterator __old_finish = _M_finish;
  1022.       if (__elems_after >= __n) {
  1023.         uninitialized_copy((_M_finish - __n) + 1, _M_finish + 1,
  1024.                            _M_finish + 1);
  1025.         _M_finish += __n;
  1026.         _Traits::move(__position + __n,
  1027.                       __position, (__elems_after - __n) + 1);
  1028.         _Traits::assign(__position, __n, __c);
  1029.       }
  1030.       else {
  1031.         uninitialized_fill_n(_M_finish + 1, __n - __elems_after - 1, __c);
  1032.         _M_finish += __n - __elems_after;
  1033.         __STL_TRY {
  1034.           uninitialized_copy(__position, __old_finish + 1, _M_finish);
  1035.           _M_finish += __elems_after;
  1036.         }
  1037.         __STL_UNWIND((destroy(__old_finish + 1, _M_finish), 
  1038.                       _M_finish = __old_finish));
  1039.         _Traits::assign(__position, __elems_after + 1, __c);
  1040.       }
  1041.     }
  1042.     else {
  1043.       const size_type __old_size = size();        
  1044.       const size_type __len = __old_size + max(__old_size, __n) + 1;
  1045.       iterator __new_start = _M_allocate(__len);
  1046.       iterator __new_finish = __new_start;
  1047.       __STL_TRY {
  1048.         __new_finish = uninitialized_copy(_M_start, __position, __new_start);
  1049.         __new_finish = uninitialized_fill_n(__new_finish, __n, __c);
  1050.         __new_finish = uninitialized_copy(__position, _M_finish,
  1051.                                           __new_finish);
  1052.         construct(__new_finish);
  1053.       }
  1054.       __STL_UNWIND((destroy(__new_start,__new_finish),
  1055.                     _M_deallocate(__new_start,__len)));
  1056.       destroy(_M_start, _M_finish + 1);
  1057.       _M_deallocate_block();
  1058.       _M_start = __new_start;
  1059.       _M_finish = __new_finish;
  1060.       _M_end_of_storage = __new_start + __len;    
  1061.     }
  1062.   }
  1063. }
  1064. template <class _T, class _Traits, class _Alloc>
  1065. template <class _InputIter>
  1066. void basic_string<_T, _Traits, _Alloc>::insert(iterator __p,
  1067.                                                _InputIter __first, 
  1068.                                                _InputIter __last,
  1069.                                                input_iterator_tag)
  1070. {
  1071.   for ( ; __first != __last; ++__first) {
  1072.     __p = insert(__p, *__first);
  1073.     ++__p;
  1074.   }
  1075. }
  1076. template <class _CharT, class _Traits, class _Alloc>
  1077. template <class _ForwardIter>
  1078. void 
  1079. basic_string<_CharT,_Traits,_Alloc>::insert(iterator __position,
  1080.                                            _ForwardIter __first, 
  1081.                                            _ForwardIter __last,
  1082.                                            forward_iterator_tag)
  1083. {
  1084.   if (__first != __last) {
  1085.     const difference_type __n = distance(__first, __last);
  1086.     if (_M_end_of_storage - _M_finish >= __n + 1) {
  1087.       const difference_type __elems_after = _M_finish - __position;
  1088.       iterator __old_finish = _M_finish;
  1089.       if (__elems_after >= __n) {
  1090.         uninitialized_copy((_M_finish - __n) + 1, _M_finish + 1,
  1091.                            _M_finish + 1);
  1092.         _M_finish += __n;
  1093.         _Traits::move(__position + __n,
  1094.                       __position, (__elems_after - __n) + 1);
  1095.         _M_copy(__first, __last, __position);
  1096.       }
  1097.       else {
  1098.         _ForwardIter __mid = __first;
  1099.         advance(__mid, __elems_after + 1);
  1100.         uninitialized_copy(__mid, __last, _M_finish + 1);
  1101.         _M_finish += __n - __elems_after;
  1102.         __STL_TRY {
  1103.           uninitialized_copy(__position, __old_finish + 1, _M_finish);
  1104.           _M_finish += __elems_after;
  1105.         }
  1106.         __STL_UNWIND((destroy(__old_finish + 1, _M_finish), 
  1107.                       _M_finish = __old_finish));
  1108.         _M_copy(__first, __mid, __position);
  1109.       }
  1110.     }
  1111.     else {
  1112.       const size_type __old_size = size();        
  1113.       const size_type __len
  1114.         = __old_size + max(__old_size, static_cast<size_type>(__n)) + 1;
  1115.       pointer __new_start = _M_allocate(__len);
  1116.       pointer __new_finish = __new_start;
  1117.       __STL_TRY {
  1118.         __new_finish = uninitialized_copy(_M_start, __position, __new_start);
  1119.         __new_finish = uninitialized_copy(__first, __last, __new_finish);
  1120.         __new_finish
  1121.           = uninitialized_copy(__position, _M_finish, __new_finish);
  1122.         construct(__new_finish);
  1123.       }
  1124.       __STL_UNWIND((destroy(__new_start,__new_finish),
  1125.                     _M_deallocate(__new_start,__len)));
  1126.       destroy(_M_start, _M_finish + 1);
  1127.       _M_deallocate_block();
  1128.       _M_start = __new_start;
  1129.       _M_finish = __new_finish;
  1130.       _M_end_of_storage = __new_start + __len; 
  1131.     }
  1132.   }
  1133. }
  1134. template <class _CharT, class _Traits, class _Alloc>
  1135. basic_string<_CharT,_Traits,_Alloc>&
  1136. basic_string<_CharT,_Traits,_Alloc>
  1137.   ::replace(iterator __first, iterator __last, size_type __n, _CharT __c)
  1138. {
  1139.   const size_type __len = static_cast<size_type>(__last - __first);
  1140.   if (__len >= __n) {
  1141.     _Traits::assign(__first, __n, __c);
  1142.     erase(__first + __n, __last);
  1143.   }
  1144.   else {
  1145.     _Traits::assign(__first, __len, __c);
  1146.     insert(__last, __n - __len, __c);
  1147.   }
  1148.   return *this;
  1149. }
  1150. template <class _CharT, class _Traits, class _Alloc>
  1151. template <class _InputIter>
  1152. basic_string<_CharT,_Traits,_Alloc>&
  1153. basic_string<_CharT,_Traits,_Alloc>
  1154.   ::replace(iterator __first, iterator __last, _InputIter __f, _InputIter __l,
  1155.             input_iterator_tag) 
  1156. {
  1157.   for ( ; __first != __last && __f != __l; ++__first, ++__f)
  1158.     _Traits::assign(*__first, *__f);
  1159.   if (__f == __l)
  1160.     erase(__first, __last);
  1161.   else
  1162.     insert(__last, __f, __l);
  1163.   return *this;
  1164. }
  1165. template <class _CharT, class _Traits, class _Alloc>
  1166. template <class _ForwardIter>
  1167. basic_string<_CharT,_Traits,_Alloc>&
  1168. basic_string<_CharT,_Traits,_Alloc>
  1169.   ::replace(iterator __first, iterator __last,
  1170.             _ForwardIter __f, _ForwardIter __l,
  1171.             forward_iterator_tag) 
  1172. {
  1173.     const typename iterator_traits<_ForwardIter>::difference_type __n =
  1174.       distance(__f, __l);
  1175.     const difference_type __len = __last - __first;
  1176.     if (__len >= __n) {
  1177.       _M_copy(__f, __l, __first);
  1178.       erase(__first + __n, __last);
  1179.     }
  1180.     else {
  1181.       _ForwardIter m = __f;
  1182.       advance(m, __len);
  1183.       _M_copy(__f, m, __first);
  1184.       insert(__last, m, __l);
  1185.     }
  1186.     return *this;
  1187. }
  1188. template <class _CharT, class _Traits, class _Alloc>
  1189. basic_string<_CharT,_Traits,_Alloc>::size_type
  1190. basic_string<_CharT,_Traits,_Alloc>
  1191.   ::find(const _CharT* __s, size_type __pos, size_type __n) const 
  1192. {
  1193.   if (__pos >= size())
  1194.     return npos;
  1195.   else {
  1196.     const const_iterator __result =
  1197.       search(_M_start + __pos, _M_finish, 
  1198.              __s, __s + __n, _Eq_traits<_Traits>());
  1199.     return __result != _M_finish ? __result - begin() : npos;
  1200.   }
  1201. }
  1202. template <class _CharT, class _Traits, class _Alloc>
  1203. basic_string<_CharT,_Traits,_Alloc>::size_type
  1204. basic_string<_CharT,_Traits,_Alloc>
  1205.   ::find(_CharT __c, size_type __pos = 0) const 
  1206. {
  1207.   if (__pos >= size())
  1208.     return npos;
  1209.   else {
  1210.     const const_iterator __result =
  1211.       find_if(_M_start + __pos, _M_finish,
  1212.               bind2nd(_Eq_traits<_Traits>(), __c));
  1213.     return __result != _M_finish ? __result - begin() : npos;
  1214.   }
  1215. }    
  1216. template <class _CharT, class _Traits, class _Alloc>
  1217. basic_string<_CharT,_Traits,_Alloc>::size_type
  1218. basic_string<_CharT,_Traits,_Alloc>
  1219.   ::rfind(const _CharT* __s, size_type __pos, size_type __n) const 
  1220. {
  1221.   const size_t __len = size();
  1222.   if (__n > __len)
  1223.     return npos;
  1224.   else if (__n == 0)
  1225.     return min(__len, __pos);
  1226.   else {
  1227.     const const_iterator __last = begin() + min(__len - __n, __pos) + __n;
  1228.     const const_iterator __result = find_end(begin(), __last,
  1229.                                            __s, __s + __n,
  1230.                                            _Eq_traits<_Traits>());
  1231.     return __result != __last ? __result - begin() : npos;
  1232.   }
  1233. }
  1234. template <class _CharT, class _Traits, class _Alloc>
  1235. basic_string<_CharT,_Traits,_Alloc>::size_type
  1236. basic_string<_CharT,_Traits,_Alloc>
  1237.   ::rfind(_CharT __c, size_type __pos = npos) const 
  1238. {
  1239.   const size_type __len = size();
  1240.   if (__len < 1)
  1241.     return npos;
  1242.   else {
  1243.     const const_iterator __last = begin() + min(__len - 1, __pos) + 1;
  1244.     const_reverse_iterator __rresult =
  1245.       find_if(const_reverse_iterator(__last), rend(),
  1246.               bind2nd(_Eq_traits<_Traits>(), __c));
  1247.     return __rresult != rend() ? (__rresult.base() - 1) - begin() : npos;
  1248.   }
  1249. }
  1250. template <class _CharT, class _Traits, class _Alloc>
  1251. basic_string<_CharT,_Traits,_Alloc>::size_type
  1252. basic_string<_CharT,_Traits,_Alloc>
  1253.   ::find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
  1254. {
  1255.   if (__pos >= size())
  1256.     return npos;
  1257.   else {
  1258.     const const_iterator __result = std::find_first_of(begin() + __pos, end(),
  1259.                                                      __s, __s + __n,
  1260.                                                      _Eq_traits<_Traits>());
  1261.     return __result != _M_finish ? __result - begin() : npos;
  1262.   }
  1263. }
  1264. template <class _CharT, class _Traits, class _Alloc>
  1265. basic_string<_CharT,_Traits,_Alloc>::size_type
  1266. basic_string<_CharT,_Traits,_Alloc>
  1267.   ::find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
  1268. {
  1269.   const size_type __len = size();
  1270.   if (__len < 1)
  1271.     return npos;
  1272.   else {
  1273.     const const_iterator __last = _M_start + min(__len - 1, __pos) + 1;
  1274.     const const_reverse_iterator __rresult =
  1275.       std::find_first_of(const_reverse_iterator(__last), rend(),
  1276.                          __s, __s + __n,
  1277.                          _Eq_traits<_Traits>());
  1278.     return __rresult != rend() ? (__rresult.base() - 1) - _M_start : npos;
  1279.   }
  1280. }
  1281. template <class _CharT, class _Traits, class _Alloc>
  1282. basic_string<_CharT,_Traits,_Alloc>::size_type
  1283. basic_string<_CharT,_Traits,_Alloc>
  1284.   ::find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const 
  1285. {
  1286.   if (__pos > size())
  1287.     return npos;
  1288.   else {
  1289.     const_iterator __result = find_if(_M_start + __pos, _M_finish,
  1290.                                 _Not_within_traits<_Traits>(__s, __s + __n));
  1291.     return __result != _M_finish ? __result - _M_start : npos;
  1292.   }
  1293. }
  1294. template <class _CharT, class _Traits, class _Alloc>
  1295. basic_string<_CharT,_Traits,_Alloc>::size_type
  1296. basic_string<_CharT,_Traits,_Alloc>
  1297.   ::find_first_not_of(_CharT __c, size_type __pos = 0) const
  1298. {
  1299.   if (__pos > size())
  1300.     return npos;
  1301.   else {
  1302.     const_iterator __result = find_if(begin() + __pos, end(),
  1303.                                     not1(bind2nd(_Eq_traits<_Traits>(), __c)));
  1304.     return __result != _M_finish ? __result - begin() : npos;
  1305.   }
  1306. }    
  1307. template <class _CharT, class _Traits, class _Alloc>
  1308. basic_string<_CharT,_Traits,_Alloc>::size_type
  1309. basic_string<_CharT,_Traits,_Alloc>
  1310.   ::find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const 
  1311. {
  1312.   const size_type __len = size();
  1313.   if (__len < 1)
  1314.     return npos;
  1315.   else {
  1316.     const const_iterator __last = begin() + min(__len - 1, __pos) + 1;
  1317.     const const_reverse_iterator __rresult =
  1318.       find_if(const_reverse_iterator(__last), rend(),
  1319.               _Not_within_traits<_Traits>(__s, __s + __n));
  1320.     return __rresult != rend() ? (__rresult.base() - 1) - begin() : npos;
  1321.   }
  1322. }
  1323. template <class _T, class _Traits, class _Alloc>
  1324. basic_string<_T, _Traits, _Alloc>::size_type
  1325. basic_string<_T, _Traits, _Alloc>
  1326.   ::find_last_not_of(_T __c, size_type __pos = npos) const 
  1327. {
  1328.   const size_type __len = size();
  1329.   if (__len < 1)
  1330.     return npos;
  1331.   else {
  1332.     const const_iterator __last = begin() + min(__len - 1, __pos) + 1;
  1333.     const_reverse_iterator __rresult =
  1334.       find_if(const_reverse_iterator(__last), rend(),
  1335.               not1(bind2nd(_Eq_traits<_Traits>(), __c)));
  1336.     return __rresult != rend() ? (__rresult.base() - 1) - begin() : npos;
  1337.   }
  1338. }
  1339. // ------------------------------------------------------------
  1340. // Non-member functions.
  1341. // Operator+
  1342. template <class _CharT, class _Traits, class _Alloc>
  1343. inline basic_string<_CharT,_Traits,_Alloc>
  1344. operator+(const basic_string<_CharT,_Traits,_Alloc>& __x,
  1345.           const basic_string<_CharT,_Traits,_Alloc>& __y)
  1346. {
  1347.   typedef basic_string<_CharT,_Traits,_Alloc> _Str;
  1348.   typedef typename _Str::_Reserve_t _Reserve_t;
  1349.   _Str __result(_Reserve_t(), __x.size() + __y.size(), __x.get_allocator());
  1350.   __result.append(__x);
  1351.   __result.append(__y);
  1352.   return __result;
  1353. }
  1354. template <class _CharT, class _Traits, class _Alloc>
  1355. inline basic_string<_CharT,_Traits,_Alloc>
  1356. operator+(const _CharT* __s,
  1357.           const basic_string<_CharT,_Traits,_Alloc>& __y) {
  1358.   typedef basic_string<_CharT,_Traits,_Alloc> _Str;
  1359.   typedef typename _Str::_Reserve_t _Reserve_t;
  1360.   const size_t __n = _Traits::length(__s);
  1361.   _Str __result(_Reserve_t(), __n + __y.size());
  1362.   __result.append(__s, __s + __n);
  1363.   __result.append(__y);
  1364.   return __result;
  1365. }
  1366. template <class _CharT, class _Traits, class _Alloc>
  1367. inline basic_string<_CharT,_Traits,_Alloc>
  1368. operator+(_CharT __c,
  1369.           const basic_string<_CharT,_Traits,_Alloc>& __y) {
  1370.   typedef basic_string<_CharT,_Traits,_Alloc> _Str;
  1371.   typedef typename _Str::_Reserve_t _Reserve_t;
  1372.   _Str __result(_Reserve_t(), 1 + __y.size());
  1373.   __result.push_back(__c);
  1374.   __result.append(__y);
  1375.   return __result;
  1376. }
  1377. template <class _CharT, class _Traits, class _Alloc>
  1378. inline basic_string<_CharT,_Traits,_Alloc>
  1379. operator+(const basic_string<_CharT,_Traits,_Alloc>& __x,
  1380.           const _CharT* __s) {
  1381.   typedef basic_string<_CharT,_Traits,_Alloc> _Str;
  1382.   typedef typename _Str::_Reserve_t _Reserve_t;
  1383.   const size_t __n = _Traits::length(__s);
  1384.   _Str __result(_Reserve_t(), __x.size() + __n, __x.get_allocator());
  1385.   __result.append(__x);
  1386.   __result.append(__s, __s + __n);
  1387.   return __result;
  1388. }
  1389. template <class _CharT, class _Traits, class _Alloc>
  1390. inline basic_string<_CharT,_Traits,_Alloc>
  1391. operator+(const basic_string<_CharT,_Traits,_Alloc>& __x,
  1392.           const _CharT __c) {
  1393.   typedef basic_string<_CharT,_Traits,_Alloc> _Str;
  1394.   typedef typename _Str::_Reserve_t _Reserve_t;
  1395.   _Str __result(_Reserve_t(), __x.size() + 1, __x.get_allocator());
  1396.   __result.append(__x);
  1397.   __result.push_back(__c);
  1398.   return __result;
  1399. }
  1400. // Operator== and operator!=
  1401. template <class _CharT, class _Traits, class _Alloc>
  1402. inline bool
  1403. operator==(const basic_string<_CharT,_Traits,_Alloc>& __x,
  1404.            const basic_string<_CharT,_Traits,_Alloc>& __y) {
  1405.   return __x.size() == __y.size() &&
  1406.          _Traits::compare(__x.data(), __y.data(), __x.size()) == 0;
  1407. }
  1408. template <class _CharT, class _Traits, class _Alloc>
  1409. inline bool
  1410. operator==(const _CharT* __s,
  1411.            const basic_string<_CharT,_Traits,_Alloc>& __y) {
  1412.   size_t __n = _Traits::length(__s);
  1413.   return __n == __y.size() && _Traits::compare(__s, __y.data(), __n) == 0;
  1414. }
  1415. template <class _CharT, class _Traits, class _Alloc>
  1416. inline bool
  1417. operator==(const basic_string<_CharT,_Traits,_Alloc>& __x,
  1418.            const _CharT* __s) {
  1419.   size_t __n = _Traits::length(__s);
  1420.   return __x.size() == __n && _Traits::compare(__x.data(), __s, __n) == 0;
  1421. }
  1422. #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
  1423. template <class _CharT, class _Traits, class _Alloc>
  1424. inline bool
  1425. operator!=(const basic_string<_CharT,_Traits,_Alloc>& __x,
  1426.            const basic_string<_CharT,_Traits,_Alloc>& __y) {
  1427.   return !(__x == __y);
  1428. }
  1429. template <class _CharT, class _Traits, class _Alloc>
  1430. inline bool
  1431. operator!=(const _CharT* __s,
  1432.            const basic_string<_CharT,_Traits,_Alloc>& __y) {
  1433.   return !(__s == __y);
  1434. }
  1435. template <class _CharT, class _Traits, class _Alloc>
  1436. inline bool
  1437. operator!=(const basic_string<_CharT,_Traits,_Alloc>& __x,
  1438.            const _CharT* __s) {
  1439.   return !(__x == __s);
  1440. }
  1441. #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
  1442. // Operator< (and also >, <=, and >=).
  1443. template <class _CharT, class _Traits, class _Alloc>
  1444. inline bool
  1445. operator<(const basic_string<_CharT,_Traits,_Alloc>& __x,
  1446.           const basic_string<_CharT,_Traits,_Alloc>& __y) {
  1447.   return basic_string<_CharT,_Traits,_Alloc>
  1448.     ::_M_compare(__x.begin(), __x.end(), __y.begin(), __y.end()) < 0;
  1449. }
  1450. template <class _CharT, class _Traits, class _Alloc>
  1451. inline bool
  1452. operator<(const _CharT* __s,
  1453.           const basic_string<_CharT,_Traits,_Alloc>& __y) {
  1454.   size_t __n = _Traits::length(__s);
  1455.   return basic_string<_CharT,_Traits,_Alloc>
  1456.     ::_M_compare(__s, __s + __n, __y.begin(), __y.end()) < 0;
  1457. }
  1458. template <class _CharT, class _Traits, class _Alloc>
  1459. inline bool
  1460. operator<(const basic_string<_CharT,_Traits,_Alloc>& __x,
  1461.           const _CharT* __s) {
  1462.   size_t __n = _Traits::length(__s);
  1463.   return basic_string<_CharT,_Traits,_Alloc>
  1464.     ::_M_compare(__x.begin(), __x.end(), __s, __s + __n) < 0;
  1465. }
  1466. #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
  1467. template <class _CharT, class _Traits, class _Alloc>
  1468. inline bool
  1469. operator>(const basic_string<_CharT,_Traits,_Alloc>& __x,
  1470.           const basic_string<_CharT,_Traits,_Alloc>& __y) {
  1471.   return __y < __x;
  1472. }
  1473. template <class _CharT, class _Traits, class _Alloc>
  1474. inline bool
  1475. operator>(const _CharT* __s,
  1476.           const basic_string<_CharT,_Traits,_Alloc>& __y) {
  1477.   return __y < __s;
  1478. }
  1479. template <class _CharT, class _Traits, class _Alloc>
  1480. inline bool
  1481. operator>(const basic_string<_CharT,_Traits,_Alloc>& __x,
  1482.           const _CharT* __s) {
  1483.   return __s < __x;
  1484. }
  1485. template <class _CharT, class _Traits, class _Alloc>
  1486. inline bool
  1487. operator<=(const basic_string<_CharT,_Traits,_Alloc>& __x,
  1488.            const basic_string<_CharT,_Traits,_Alloc>& __y) {
  1489.   return !(__y < __x);
  1490. }
  1491. template <class _CharT, class _Traits, class _Alloc>
  1492. inline bool
  1493. operator<=(const _CharT* __s,
  1494.            const basic_string<_CharT,_Traits,_Alloc>& __y) {
  1495.   return !(__y < __s);
  1496. }
  1497. template <class _CharT, class _Traits, class _Alloc>
  1498. inline bool
  1499. operator<=(const basic_string<_CharT,_Traits,_Alloc>& __x,
  1500.            const _CharT* __s) {
  1501.   return !(__s < __x);
  1502. }
  1503. template <class _CharT, class _Traits, class _Alloc>
  1504. inline bool
  1505. operator>=(const basic_string<_CharT,_Traits,_Alloc>& __x,
  1506.            const basic_string<_CharT,_Traits,_Alloc>& __y) {
  1507.   return !(__x < __y);
  1508. }
  1509. template <class _CharT, class _Traits, class _Alloc>
  1510. inline bool
  1511. operator>=(const _CharT* __s,
  1512.            const basic_string<_CharT,_Traits,_Alloc>& __y) {
  1513.   return !(__s < __y);
  1514. }
  1515. template <class _CharT, class _Traits, class _Alloc>
  1516. inline bool
  1517. operator>=(const basic_string<_CharT,_Traits,_Alloc>& __x,
  1518.            const _CharT* __s) {
  1519.   return !(__x < __s);
  1520. }
  1521. #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
  1522. // Swap.
  1523. #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
  1524. template <class _CharT, class _Traits, class _Alloc>
  1525. inline void swap(basic_string<_CharT,_Traits,_Alloc>& __x,
  1526.                  basic_string<_CharT,_Traits,_Alloc>& __y) {
  1527.   __x.swap(__y);
  1528. }
  1529. #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
  1530. // I/O.  (Using istream and ostream only, as opposed to the 
  1531. // basic_istream and basic_ostream templates.  The result is that
  1532. // these functions really don't make all that much sense except
  1533. // for basic_string<char>.)
  1534. inline void __sgi_string_fill(ostream& __o, size_t __n)
  1535. {
  1536.   char __f = __o.fill();
  1537.   size_t __i;
  1538.   for (__i = 0; __i < __n; __i++) __o.put(__f);
  1539. }
  1540. template <class _CharT, class _Traits, class _Alloc>
  1541. ostream& operator<<(ostream& __os, 
  1542.                     const basic_string<_CharT,_Traits,_Alloc>& __s)
  1543. {
  1544.   size_t __n = __s.size();
  1545.   size_t __pad_len = 0;
  1546.   const bool __left = bool(__os.flags() & ios::left);
  1547.   const size_t __w = __os.width();
  1548.   if (__w > 0) {
  1549.     __n = min(__w, __n);
  1550.     __pad_len = __w - __n;
  1551.   }
  1552.     
  1553.   if (!__left)
  1554.     __sgi_string_fill(__os, __pad_len);
  1555.   
  1556.   const size_t __nwritten = __os.rdbuf()->sputn(__s.data(), __n);
  1557.   if (__left)
  1558.     __sgi_string_fill(__os, __pad_len);
  1559.   if (__nwritten != __n)
  1560.     __os.clear(__os.rdstate() | ios::failbit);
  1561.   __os.width(0);
  1562.   return __os;
  1563. }
  1564. template <class _CharT, class _Traits, class _Alloc>
  1565. istream& operator>>(istream& __is, basic_string<_CharT,_Traits,_Alloc>& __s)
  1566. {
  1567.   if (__is.flags() & ios::skipws) {
  1568.     _CharT __c;
  1569.     do 
  1570.       __is.get(__c);
  1571.     while (__is && isspace(__c));
  1572.     if (__is)
  1573.       __is.putback(__c);
  1574.   }
  1575.   if (__is) {
  1576.     __s.clear();
  1577.     size_t __n = __is.width();
  1578.     if (__n == 0)
  1579.       __n = (size_t)(-1);
  1580.     else
  1581.       __s.reserve(__n);
  1582.     while (__n-- > 0) {
  1583.       _CharT __c;
  1584.       __is.get(__c);
  1585.       if (!__is)
  1586.         break;
  1587.       else if (isspace(__c)) {
  1588.         __is.putback(__c);
  1589.         break;
  1590.       }
  1591.       __s.push_back(__c);
  1592.     }
  1593.   }
  1594.   __is.width(0);
  1595.   return __is;
  1596. }
  1597. template <class _CharT, class _Traits, class _Alloc>    
  1598. istream& getline(istream& __is,
  1599.                  basic_string<_CharT,_Traits,_Alloc>& __s,
  1600.                  _CharT __delim = 'n') {
  1601.   size_t __nread = 0;
  1602.   if (__is) {
  1603.     __s.clear();
  1604.     _CharT __c;
  1605.     while (__nread < __s.max_size() && __is.get(__c)) {
  1606.       ++__nread;
  1607.       if (!_Traits::eq(__c, __delim)) 
  1608.         __s.push_back(__c);
  1609.       else
  1610.         break;                  // Character is extracted but not appended.
  1611.     }
  1612.   }
  1613.   if (__nread == 0 || __nread >= __s.max_size())
  1614.     __is.clear(__is.rdstate() | ios::failbit);
  1615.   return __is;
  1616. }
  1617. template <class _CharT, class _Traits, class _Alloc>
  1618. void _S_string_copy(const basic_string<_CharT,_Traits,_Alloc>& __s,
  1619.                     _CharT* __buf,
  1620.                     size_t __n)
  1621. {
  1622.   if (__n > 0) {
  1623.     const size_t __n = min(__n - 1, __s.size());
  1624.     copy(__s.begin(), __s.begin() + __n, __buf);
  1625.     __buf[__n] = _CharT();
  1626.   }
  1627. }
  1628. // ------------------------------------------------------------
  1629. // Typedefs
  1630. typedef basic_string<char> string;
  1631. typedef basic_string<wchar_t> wstring;
  1632. #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
  1633. #pragma reset woff 1174
  1634. #pragma reset woff 1375
  1635. #endif
  1636. __STL_END_NAMESPACE
  1637. #include <stl_hash_fun.h>
  1638. __STL_BEGIN_NAMESPACE
  1639. template <class _CharT, class _Traits, class _Alloc>
  1640. struct hash<basic_string<_CharT,_Traits,_Alloc> > {
  1641.   size_t operator()(const basic_string<_CharT,_Traits,_Alloc>& __s) const {
  1642.     unsigned long __h = 0; 
  1643.     for (basic_string<_CharT,_Traits,_Alloc>::const_iterator __i
  1644.            = __s.begin();
  1645.          __i != __s.end();
  1646.          ++__i)
  1647.       __h = 5*__h + *__i;
  1648.     return size_t(__h);
  1649.   }
  1650. };
  1651. __STL_END_NAMESPACE
  1652. #endif /* __SGI_STL_STRING */
  1653. // Local Variables:
  1654. // mode:C++
  1655. // End: