home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_13_08 / plauger / basicstr.h < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-10  |  23.1 KB  |  518 lines

  1. ------------------ Listing 2: The template class basic_string -------
  2.  
  3. template<class _E,
  4.         class _T = string_char_traits<_E>,
  5.         class _A = _ALLOCATOR(_E)>
  6.         class basic_string {
  7. public:
  8.         typedef basic_string<_E, _T, _A> _Myt;
  9.         typedef _T traits_type;
  10.         typedef _SIZ_TYPE(_E, _A)::size_type size_type;
  11.         typedef _SIZ_TYPE(_E, _A)::difference_type difference_type;
  12.         typedef _PTR_TYPE(_E, _A)::pointer pointer;
  13.         typedef _PTR_TYPE(_E, _A)::const_pointer const_pointer;
  14.         typedef _PTR_TYPE(_E, _A)::reference reference;
  15.         typedef _PTR_TYPE(_E, _A)::const_reference const_reference;
  16.         typedef _PTR_TYPE(_E, _A)::value_type value_type;
  17.         typedef _PTR_TYPE(_E, _A)::pointer iterator;
  18.         typedef _PTR_TYPE(_E, _A)::const_pointer const_iterator;
  19.         typedef reverse_iterator<const_iterator, value_type,
  20.                 const_reference, difference_type> const_reverse_iterator;
  21.         typedef reverse_iterator<iterator, value_type,
  22.                 reference, difference_type> reverse_iterator;
  23. #if _HAS_STATIC_MEMBER_INIT
  24.         static const size_type npos = -1;
  25. #else
  26.         enum _Npos_enum {npos = ~0};    // CAN HAVE WRONG SIZE/TYPE
  27. #endif
  28.         basic_string(_A& _Al = _A())
  29.                 : allocator(_Al) {_Tidy(); }
  30.         basic_string(const _Myt& _X, size_type _P = 0,
  31.                 size_type _N = npos, _A& _Al = _A())
  32.                 : allocator(_Al) {_Tidy(), assign(_X, _P, _N); }
  33.         basic_string(const _E *_S, size_type _N = npos,
  34.                 _A& _Al = _A())
  35.                 : allocator(_Al) {_Tidy(), assign(_S, _N); }
  36.         basic_string(size_type _N, _E _C, _A& _Al = _A())
  37.                 : allocator(_Al) {_Tidy(), assign(_N, _C); }
  38. #if _HAS_MEMBER_TEMPLATES
  39.         template<class _It>
  40. #else
  41.         typedef const_iterator _It;
  42. #endif
  43.                 basic_string(_It _F, _It _L, _A& _Al = _A())
  44.                 : allocator(_Al) {_Tidy(); assign(_F, _L); }
  45.         ~basic_string()
  46.                 {_Tidy(true); }
  47.         _Myt& operator=(const _Myt& _X)
  48.                 {return (assign(_X)); }
  49.         _Myt& operator=(const _E *_S)
  50.                 {return (assign(_S)); }
  51.         _Myt& operator=(_E _C)
  52.                 {return (assign(1, _C)); }
  53.         _Myt& operator+=(const _Myt& _X)
  54.                 {return (append(_X)); }
  55.         _Myt& operator+=(const _E *_S)
  56.                 {return (append(_S)); }
  57.         _Myt& operator+=(_E _C)
  58.                 {return (append(1, _C)); }
  59.         _Myt& append(const _Myt& _X, size_type _P = 0,
  60.                 size_type _M = npos)
  61.                 {if (_X.size() < _P)
  62.                         _Xran();
  63.                 size_type _N = _X.size() - _P;
  64.                 if (_N < _M)
  65.                         _M = _N;
  66.                 if (npos - _Len <= _M)
  67.                         _Xlen();
  68.                 if (0 < _M && _Grow(_N = _Len + _M))
  69.                         {_T::copy(_Ptr + _Len, &_X.c_str()[_P], _M);
  70.                         _Eos(_N); }
  71.                 return (*this); }
  72.         _Myt& append(const _E *_S, size_type _M = npos)
  73.                 {if (_M == (size_type)npos)
  74.                         _M = _T::length(_S);
  75.                 if (npos - _Len <= _M)
  76.                         _Xlen();
  77.                 size_type _N;
  78.                 if (0 < _M && _Grow(_N = _Len + _M))
  79.                         {_T::copy(_Ptr + _Len, _S, _M);
  80.                         _Eos(_N); }
  81.                 return (*this); }
  82.         _Myt& append(size_type _M, _E _C = _T::eos())
  83.                 {if (npos - _Len <= _M)
  84.                         _Xlen();
  85.                 size_type _N;
  86.                 if (0 < _M && _Grow(_N = _Len + _M))
  87.                         {_Memset(_Ptr + _Len, _C, _M);
  88.                         _Eos(_N); }
  89.                 return (*this); }
  90. #if _HAS_MEMBER_TEMPLATES
  91.         template<class _It>
  92. #endif
  93.                 _Myt& append(_It _F, _It _L)
  94.                 {insert(end(), _F, _L);
  95.                 return (*this); }
  96.         _Myt& assign(const _Myt& _X, size_type _P = 0,
  97.                 size_type _M = npos)
  98.                 {if (_X.size() < _P)
  99.                         _Xran();
  100.                 size_type _N = _X.size() - _P;
  101.                 if (_M < _N)
  102.                         _N = _M;
  103.                 if (this == &_X)
  104.                         remove(_P + _N), remove(0, _P);
  105.                 else if (_Grow(_N, true))
  106.                         {_T::copy(_Ptr, &_X.c_str()[_P], _N);
  107.                         _Eos(_N); }
  108.                 return (*this); }
  109.         _Myt& assign(const _E *_S, size_type _N = npos)
  110.                 {if (_N == (size_type)npos)
  111.                         _N = _T::length(_S);
  112.                 if (_Grow(_N, true))
  113.                         {_T::copy(_Ptr, _S, _N);
  114.                         _Eos(_N); }
  115.                 return (*this); }
  116.         _Myt& assign(size_type _N, _E _C = _T::eos())
  117.                 {if (_N == (size_type)npos)
  118.                         _Xlen();
  119.                 if (_Grow(_N, true))
  120.                         {_Memset(_Ptr, _C, _N);
  121.                         _Eos(_N); }
  122.                 return (*this); }
  123. #if _HAS_MEMBER_TEMPLATES
  124.         template<class _It>
  125. #endif
  126.                 _Myt& assign(_It _F, _It _L)
  127.                 {return (replace(begin(), end(), _F, _L)); }
  128.         _Myt& insert(size_type _P0, const _Myt& _X, size_type _P = 0,
  129.                 size_type _M = npos)
  130.                 {if (_Len < _P0 || _X.size() < _P)
  131.                         _Xran();
  132.                 size_type _N = _X.size() - _P;
  133.                 if (_N < _M)
  134.                         _M = _N;
  135.                 if (npos - _Len <= _M)
  136.                         _Xlen();
  137.                 if (0 < _M && _Grow(_N = _Len + _M))
  138.                         {_Memmove(_Ptr + _P0 + _M, _Ptr + _P0,
  139.                                 _Len - _P0);
  140.                         _T::copy(_Ptr + _P0, &_X.c_str()[_P], _M);
  141.                         _Eos(_N); }
  142.                 return (*this); }
  143.         _Myt& insert(size_type _P0, const _E *_S,
  144.                 size_type _M = npos)
  145.                 {if (_Len < _P0)
  146.                         _Xran();
  147.                 if (_M == (size_type)npos)
  148.                         _M = _T::length(_S);
  149.                 if (npos - _Len <= _M)
  150.                         _Xlen();
  151.                 size_type _N;
  152.                 if (0 < _M && _Grow(_N = _Len + _M))
  153.                         {_Memmove(_Ptr + _P0 + _M, _Ptr + _P0,
  154.                                 _Len - _P0);
  155.                         _T::copy(_Ptr + _P0, _S, _M);
  156.                         _Eos(_N); }
  157.                 return (*this); }
  158.         _Myt& insert(size_type _P0, size_type _M,
  159.                 _E _C = _T::eos())
  160.                 {if (_Len < _P0)
  161.                         _Xran();
  162.                 if (npos - _Len <= _M)
  163.                         _Xlen();
  164.                 size_type _N;
  165.                 if (0 < _M && _Grow(_N = _Len + _M))
  166.                         {_Memmove(_Ptr + _P0 + _M, _Ptr + _P0,
  167.                                 _Len - _P0);
  168.                         _Memset(_Ptr + _P0, _C, _M);
  169.                         _Eos(_N); }
  170.                 return (*this); }
  171.         iterator insert(iterator _P, _E _C = _T::eos())
  172.                 {size_type _P0 = _P - begin();
  173.                 insert(_P0, 1, _C);
  174.                 return (begin() + _P0); }
  175.         void insert(iterator _P, size_type _M,
  176.                 _E _C = _T::eos())
  177.                 {size_type _P0 = _P - begin();
  178.                 insert(_P0, _M, _C); }
  179. #if _HAS_MEMBER_TEMPLATES
  180.         template<class _It>
  181. #endif
  182.                 void insert(iterator _P, _It _F, _It _L)
  183.                 {size_type _M = 0;
  184.                 distance(_F, _L, _M);
  185.                 insert(size_type(_P - begin()), (const _E *)_F, _M); }
  186.         _Myt& remove(size_type _P0 = 0, size_type _M = npos)
  187.                 {if (_Len < _P0)
  188.                         _Xran();
  189.                 if (_Len - _P0 < _M)
  190.                         _M = _Len - _P0;
  191.                 if (0 < _M)
  192.                         {_Memmove(_Ptr + _P0, _Ptr + _P0 + _M,
  193.                                 _Len - _P0 - _M);
  194.                         size_type _N = _Len - _M;
  195.                         if (_Grow(_N))
  196.                                 _Eos(_N); }
  197.                 return (*this); }
  198.         _Myt& remove(iterator _P)
  199.                 {return (remove(_P - begin(), 1)); }
  200.         _Myt& remove(iterator _F, iterator _L)
  201.                 {return (remove(_F - begin(), _L - _F)); }
  202.         _Myt& replace(size_type _P0, size_type _N0, const _Myt& _X,
  203.                 size_type _P = 0, size_type _M = npos)
  204.                 {if (_Len < _P0 || _X.size() < _P)
  205.                         _Xran();
  206.                 size_type _N = _X.size() - _P;
  207.                 if (_N < _M)
  208.                         _M = _N;
  209.                 if (npos - _M <= _Len - _N0)
  210.                         _Xlen();
  211.                 size_type _Nm = _Len - _N0 - _P0;
  212.                 if (_M < _N0)
  213.                         _Memmove(_Ptr + _P0 + _M, _Ptr + _P0 + _N0, _Nm);
  214.                 if ((0 < _M || 0 < _N0) && _Grow(_N = _Len + _M - _N0))
  215.                         {if (_N0 < _M)
  216.                                 _Memmove(_Ptr + _P0 + _M, _Ptr + _P0 + _N0,
  217.                                         _Nm);
  218.                         _T::copy(_Ptr + _P0, &_X.c_str()[_P], _M);
  219.                         _Eos(_N); }
  220.                 return (*this); }
  221.         _Myt& replace(size_type _P0, size_type _N0, const _E *_S,
  222.                 size_type _M = npos)
  223.                 {if (_Len < _P0)
  224.                         _Xran();
  225.                 if (_M == (size_type)npos)
  226.                         _M = _T::length(_S);
  227.                 if (npos - _M <= _Len - _N0)
  228.                         _Xlen();
  229.                 size_type _Nm = _Len - _N0 - _P0;
  230.                 if (_M < _N0)
  231.                         _Memmove(_Ptr + _P0 + _M, _Ptr + _P0 + _N0, _Nm);
  232.                 size_type _N;
  233.                 if ((0 < _M || 0 < _N0) && _Grow(_N = _Len + _M - _N0))
  234.                         {if (_N0 < _M)
  235.                                 _Memmove(_Ptr + _P0 + _M, _Ptr + _P0 + _N0,
  236.                                         _Nm);
  237.                         _T::copy(_Ptr + _P0, _S, _M);
  238.                         _Eos(_N); }
  239.                 return (*this); }
  240.         _Myt& replace(size_type _P0, size_type _N0,     size_type _M,
  241.                 _E _C = _T::eos())
  242.                 {if (_Len < _P0)
  243.                         _Xran();
  244.                 if (_Len - _P0 < _N0)
  245.                         _N0 = _Len - _P0;
  246.                 if (npos - _M <= _Len - _N0)
  247.                         _Xlen();
  248.                 size_type _Nm = _Len - _N0 - _P0;
  249.                 if (_M < _N0)
  250.                         _Memmove(_Ptr + _P0 + _M, _Ptr + _P0 + _N0, _Nm);
  251.                 size_type _N;
  252.                 if ((0 < _M || 0 < _N0) && _Grow(_N = _Len + _M - _N0))
  253.                         {if (_N0 < _M)
  254.                                 _Memmove(_Ptr + _P0 + _M, _Ptr + _P0 + _N0,
  255.                                         _Nm);
  256.                         _Memset(_Ptr + _P0, _C, _M);
  257.                         _Eos(_N); }
  258.                 return (*this); }
  259.         _Myt& replace(iterator _F, iterator _L, const _Myt& _X)
  260.                 {return (replace(size_type(_F - begin()),
  261.                         size_type(_L - _F), _X)); }
  262.         _Myt& replace(iterator _F, iterator _L, const _E *_S,
  263.                 size_type _M = npos)
  264.                 {return (replace(size_type(_F - begin()),
  265.                         size_type(_L - _F), _S, _M)); }
  266.         _Myt& replace(iterator _F, iterator _L, size_type _M,
  267.                 _E _C = _T::eos())
  268.                 {return (replace(size_type(_F - begin()),
  269.                         size_type(_L - _F), _M, _C)); }
  270. #if _HAS_MEMBER_TEMPLATES
  271.         template<class _It>
  272. #endif
  273.                 _Myt& replace(iterator _F1, iterator _L1,
  274.                         _It _F2, _It _L2)
  275.                 {size_type _M = 0;
  276.                 distance(_F2, _L2, _M);
  277.                 return (replace(size_type(_F1 - begin()),
  278.                         size_type(_L1 - _F1), (const _E *)_F2, _M)); }
  279.         iterator begin()
  280.                 {return (_Ptr); }
  281.         const_iterator begin() const
  282.                 {return (begin()); }
  283.         iterator end()
  284.                 {return (_Ptr == 0 ? 0 : _Ptr + _Len); }
  285.         const_iterator end() const
  286.                 {return (end()); }
  287.         reverse_iterator rbegin()
  288.                 {return (reverse_iterator(end())); }
  289.         const_reverse_iterator rbegin() const
  290.                 {return (const_reverse_iterator(end())); }
  291.         reverse_iterator rend()
  292.                 {return (reverse_iterator(begin())); }
  293.         const_reverse_iterator rend() const
  294.                 {return (const_reverse_iterator(begin())); }
  295.         const_reference at(size_type _P0) const
  296.                 {if (_Len <= _P0)
  297.                         _Xran();
  298.                 return (_Ptr[_P0]); }
  299.         reference at(size_type _P0)
  300.                 {if (_Len <= _P0)
  301.                         _Xran();
  302.                 return (_Ptr[_P0]); }
  303.         const_reference operator[](size_type _P0) const
  304.                 {return (_Ptr[_P0]); }
  305.         reference operator[](size_type _P0)
  306.                 {_Grow(_Len);
  307.                 return (_Ptr[_P0]); }
  308.         const _E *c_str() const
  309.                 {return (_Ptr != 0 ? _Ptr : _Null()); }
  310.         const _E *data() const
  311.                 {return (0 < _Len ? _Ptr : 0); }
  312.         size_type length() const
  313.                 {return (_Len); }
  314.         size_type size() const
  315.                 {return (_Len); }
  316.         size_type max_size() const
  317.                 {size_type _N = _MAX_SIZE(_E, allocator);
  318.                 return (_N <= 2 ? 1 : _N - 2); }
  319.         void resize(size_type _N, _E _C = _T::eos())
  320.                 {_N <= _Len ? remove(_N) : append(_N - _Len, _C); }
  321.         size_type capacity() const
  322.                 {return (_Res); }
  323.         void reserve(size_type _N)
  324.                 {if (_Res < _N)
  325.                         _Grow(_N), _Eos(_Len); }
  326.         bool empty() const
  327.                 {return (_Len == 0); }
  328.         size_type copy(_E *_S, size_type _N,
  329.                 size_type _P0 = 0) const
  330.                 {if (_Len < _P0)
  331.                         _Xran();
  332.                 if (_Len - _P0 < _N)
  333.                         _N = _Len - _P0;
  334.                 _T::copy(_S, _Ptr + _P0, _N);
  335.                 return (_N); }
  336.         void swap(_Myt& _X)
  337.                 {_E *_Tp = _Ptr; _Ptr = _X._Ptr, _X._Ptr = _Tp;
  338.                 size_type _Tl = _Len; _Len = _X._Len, _X._Len = _Tl;
  339.                 size_type _Tr = _Res; _Res = _X._Res, _X._Res = _Tr; }
  340.         size_type find(const _Myt& _X, size_type _P = 0) const
  341.                 {return (find(_X.c_str(), _P, _X.size())); }
  342.         size_type find(const _E *_S, size_type _P = 0,
  343.                 size_type _N = npos) const
  344.                 {if (_Len0(_N, _S))
  345.                         return (0);
  346.                 size_type _Nm;
  347.                 if (_P < _Len && _N <= (_Nm = _Len - _P))
  348.                         {const _E *_U, *_V;
  349.                         for (_Nm -= _N - 1, _V = _Ptr + _P;
  350.                                 (_U = _Memchr(_V, *_S, _Nm)) != 0;
  351.                                 _Nm -= _U - _V + 1, _V = _U + 1)
  352.                                 if (_T::compare(_U, _S, _N) == 0)
  353.                                         return (_U - _Ptr); }
  354.                 return (npos); }
  355.         size_type find(_E _C, size_type _P = 0) const
  356.                 {return (find((const _E *)&_C, _P, 1)); }
  357.         size_type rfind(const _Myt& _X, size_type _P = npos) const
  358.                 {return (rfind(_X.c_str(), _P, _X.size())); }
  359.         size_type rfind(const _E *_S, size_type _P = npos,
  360.                 size_type _N = npos) const
  361.                 {if (_Len0(_N, _S))
  362.                         return (0);
  363.                 if (_N <= _Len)
  364.                         for (const _E *_U = _Ptr
  365.                                 + (_P < _Len - _N ? _P : _Len - _N); ; --_U)
  366.                                 if (*_U == *_S && _T::compare(_U, _S, _N) == 0)
  367.                                         return (_U - _Ptr);
  368.                                 else if (_U == _Ptr)
  369.                                         break;
  370.                 return (npos); }
  371.         size_type rfind(_E _C, size_type _P = npos) const
  372.                 {return (rfind((const _E *)&_C, _P, 1)); }
  373.         size_type find_first_of(const _Myt& _X,
  374.                 size_type _P = 0) const
  375.                 {return (find_first_of(_X.c_str(), _P, _X.size())); }
  376.         size_type find_first_of(const _E *_S, size_type _P = 0,
  377.                 size_type _N = npos) const
  378.                 {if (_Len0(_N, _S))
  379.                         return (0);
  380.                 if (_P < _Len)
  381.                         {const _E *const _V = _Ptr + _Len;
  382.                         for (const _E *_U = _Ptr + _P; _U < _V; ++_U)
  383.                                 if (_Memchr(_S, *_U, _N) != 0)
  384.                                         return (_U - _Ptr); }
  385.                 return (npos); }
  386.         size_type find_first_of(_E _C, size_type _P = 0) const
  387.                 {return (find((const _E *)&_C, _P, 1)); }
  388.         size_type find_last_of(const _Myt& _X,
  389.                 size_type _P = npos) const
  390.                 {return (find_last_of(_X.c_str(), _P, _X.size())); }
  391.         size_type find_last_of(const _E *_S,
  392.                 size_type _P = npos, size_type _N = npos) const
  393.                 {if (_Len0(_N, _S))
  394.                         return (0);
  395.                 if (0 < _Len)
  396.                         for (const _E *_U = _Ptr
  397.                                 + (_P < _Len ? _P : _Len - 1); ; --_U)
  398.                                 if (_Memchr(_S, *_U, _N) != 0)
  399.                                         return (_U - _Ptr);
  400.                                 else if (_U == _Ptr)
  401.                                         break;
  402.                 return (npos); }
  403.         size_type find_last_of(_E _C, size_type _P = npos) const
  404.                 {return (rfind((const _E *)&_C, _P, 1)); }
  405.         size_type find_first_not_of(const _Myt& _X,
  406.                 size_type _P = 0) const
  407.                 {return (find_first_not_of(_X.c_str(), _P,
  408.                         _X.size())); }
  409.         size_type find_first_not_of(const _E *_S, size_type _P = 0,
  410.                 size_type _N = npos) const
  411.                 {if (_Len0(_N, _S))
  412.                         return (0);
  413.                 if (_P < _Len)
  414.                         {const _E *const _V = _Ptr + _Len;
  415.                         for (const _E *_U = _Ptr + _P; _U < _V; ++_U)
  416.                                 if (_Memchr(_S, *_U, _N) == 0)
  417.                                         return (_U - _Ptr); }
  418.                 return (npos); }
  419.         size_type find_first_not_of(_E _C, size_type _P = 0) const
  420.                 {return (find_first_not_of((const _E *)&_C, _P, 1)); }
  421.         size_type find_last_not_of(const _Myt& _X,
  422.                 size_type _P = npos) const
  423.                 {return (find_last_not_of(_X.c_str(), _P,
  424.                         _X.size())); }
  425.         size_type find_last_not_of(const _E *_S, size_type _P = npos,
  426.                  size_type _N = npos) const
  427.                 {if (_Len0(_N, _S))
  428.                         return (0);
  429.                 if (0 < _Len)
  430.                         for (const _E *_U = _Ptr
  431.                                 + (_P < _Len ? _P : _Len - 1); ; --_U)
  432.                                 if (_Memchr(_S, *_U, _N) == 0)
  433.                                         return (_U - _Ptr);
  434.                                 else if (_U == _Ptr)
  435.                                         break;
  436.                 return (npos); }
  437.         size_type find_last_not_of(_E _C, size_type _P = npos) const
  438.                 {return (find_last_not_of((const _E *)&_C, _P, 1)); }
  439.         _Myt substr(size_type _P = 0, size_type _N = npos) const
  440.                 {return (_Myt(*this, _P, _N)); }
  441.         int compare(const _Myt& _X, size_type _P = 0,
  442.                 size_type _M = npos) const
  443.                 {if (_Len < _P)
  444.                         _Xran();
  445.                 size_type _N = _Len - _P;
  446.                 if (_X.size() < _M)
  447.                         _M = _X.size();
  448.                 size_type _Ans = _T::compare(_Ptr + _P, _X.c_str(),
  449.                         _N < _M ? _N : _M);
  450.                 return (_Ans != 0 ? _Ans : _N < _M ? -1
  451.                         : _N == _M ? 0 : +1); }
  452.         int compare(const _E *_S, size_type _P = 0,
  453.                 size_type _M = npos) const
  454.                 {if (_Len < _P)
  455.                         _Xran();
  456.                 size_type _N = _Len - _P;
  457.                 if (_M == (size_type)npos)
  458.                         _M = _T::length(_S);
  459.                 size_type _Ans = _T::compare(_Ptr + _P, _S,
  460.                         _N < _M ? _N : _M);
  461.                 return (_Ans != 0 ? _Ans : _N < _M ? -1
  462.                         : _N == _M ? 0 : +1); }
  463. protected:
  464.         _A allocator;
  465. private:
  466.         enum {_MIN_SIZE = sizeof (_E) <= 32 ? 31 : 7};
  467.         void _Eos(_N)
  468.                 {_T::assign(_Ptr[_Len = _N], _T::eos()); }
  469.         bool _Grow(size_type _N, bool _Trim = false)
  470.                 {if (max_size() < _N)
  471.                         _Xlen();
  472.                 if (_N == 0)
  473.                         _Tidy(true);
  474.                 else
  475.                         {_Res = _N < _Len ? _Len : _N;
  476.                         _E *_S = _ALLOCATE(_E, allocator, _Res + 1);
  477.                         _Ptr = _T::copy(_S, _Ptr, _Len + 1); }
  478.                 size_type _Os = _Ptr == 0 ? 0 : _Res;
  479.                 if (_N == 0)
  480.                         {if (_Trim && _MIN_SIZE < _Os)
  481.                                 _Tidy(true);
  482.                         else if (_Ptr != 0)
  483.                                 _Eos(0);
  484.                         return (0); }
  485.                 else if (_N == _Os || _N < _Os && !_Trim)
  486.                         return (1);
  487.                 else
  488.                         {size_type _Ns = _Ptr == 0 && _N < _Res ? _Res : _N;
  489.                         if (max_size() < (_Ns |= _MIN_SIZE))
  490.                                 _Ns = max_size();
  491.                         _E *_S;
  492.                         _TRY_BEGIN
  493.                                 _S = _ALLOCATE(_E, allocator, _Ns + 1);
  494.                         _CATCH_ALL
  495.                                 _Ns = _N;
  496.                                 _S = _ALLOCATE(_E, allocator, _Ns + 1);
  497.                         _CATCH_END
  498.                         if (0 < _Len)
  499.                                 _T::copy(_S, _Ptr,
  500.                                         (_Len < _Ns ? _Len : _Ns) + 1);
  501.                         _DEALLOCATE(_E, allocator, _Ptr);
  502.                         _Ptr = _S;
  503.                         _Res = _Ns;
  504.                         return (1); }}
  505.         static bool _Len0(size_type& _N, const _E *_S)
  506.                 {return (_N == 0 || _N == (size_type)npos &&
  507.                         (_N = _T::length(_S)) == 0); }
  508.         static const _E *_Null()
  509.                 {static const _E _C = _T::eos();
  510.                 return (&_C); }
  511.         void _Tidy(bool _Built = false)
  512.                 {if (_Built && _Ptr != 0)
  513.                         _DEALLOCATE(_E, allocator, _Ptr);
  514.                 _Ptr = 0, _Len = 0, _Res = 0; }
  515.         _E *_Ptr;
  516.         size_type _Len, _Res;
  517.         };
  518.