home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / include / xstring < prev    next >
Text File  |  1998-06-16  |  20KB  |  628 lines

  1. // xstring internal header (from <string>)
  2.  
  3. #if     _MSC_VER > 1000
  4. #pragma once
  5. #endif
  6.  
  7. #ifndef _XSTRING_
  8. #define _XSTRING_
  9. #include <xmemory>
  10.  
  11. #ifdef  _MSC_VER
  12. #pragma pack(push,8)
  13. #endif  /* _MSC_VER */
  14.  #include <xutility>
  15. _STD_BEGIN
  16. _CRTIMP void __cdecl _Xlen();
  17. _CRTIMP void __cdecl _Xran();
  18.         // TEMPLATE CLASS basic_string
  19. template<class _E,
  20.     class _Tr = char_traits<_E>,
  21.     class _A = allocator<_E> >
  22.     class basic_string {
  23. public:
  24.     typedef basic_string<_E, _Tr, _A> _Myt;
  25.     typedef _A::size_type size_type;
  26.     typedef _A::difference_type difference_type;
  27.     typedef _A::pointer pointer;
  28.     typedef _A::const_pointer const_pointer;
  29.     typedef _A::reference reference;
  30.     typedef _A::const_reference const_reference;
  31.     typedef _A::value_type value_type;
  32.     typedef _A::pointer iterator;
  33.     typedef _A::const_pointer const_iterator;
  34.     typedef reverse_iterator<const_iterator, value_type,
  35.         const_reference, const_pointer, difference_type>
  36.             const_reverse_iterator;
  37.     typedef reverse_iterator<iterator, value_type,
  38.         reference, pointer, difference_type>
  39.             reverse_iterator;
  40.     explicit basic_string(const _A& _Al = _A())
  41.         : allocator(_Al) {_Tidy(); }
  42.     basic_string(const _Myt& _X)
  43.         : allocator(_X.allocator)
  44.         {_Tidy(), assign(_X, 0, npos); }
  45.     basic_string(const _Myt& _X, size_type _P, size_type _M,
  46.         const _A& _Al = _A())
  47.         : allocator(_Al) {_Tidy(), assign(_X, _P, _M); }
  48.     basic_string(const _E *_S, size_type _N,
  49.         const _A& _Al = _A())
  50.         : allocator(_Al) {_Tidy(), assign(_S, _N); }
  51.     basic_string(const _E *_S, const _A& _Al = _A())
  52.         : allocator(_Al) {_Tidy(), assign(_S); }
  53.     basic_string(size_type _N, _E _C, const _A& _Al = _A())
  54.         : allocator(_Al) {_Tidy(), assign(_N, _C); }
  55.     typedef const_iterator _It;
  56.     basic_string(_It _F, _It _L, const _A& _Al = _A())
  57.         : allocator(_Al) {_Tidy(); assign(_F, _L); }
  58.     ~basic_string()
  59.         {_Tidy(true); }
  60.     typedef _Tr traits_type;
  61.     typedef _A allocator_type;
  62.     enum _Mref {_FROZEN = 255};
  63.     static const size_type npos;
  64.     _Myt& operator=(const _Myt& _X)
  65.         {return (assign(_X)); }
  66.     _Myt& operator=(const _E *_S)
  67.         {return (assign(_S)); }
  68.     _Myt& operator=(_E _C)
  69.         {return (assign(1, _C)); }
  70.     _Myt& operator+=(const _Myt& _X)
  71.         {return (append(_X)); }
  72.     _Myt& operator+=(const _E *_S)
  73.         {return (append(_S)); }
  74.     _Myt& operator+=(_E _C)
  75.         {return (append(1, _C)); }
  76.     _Myt& append(const _Myt& _X)
  77.         {return (append(_X, 0, npos)); }
  78.     _Myt& append(const _Myt& _X, size_type _P, size_type _M)
  79.         {if (_X.size() < _P)
  80.             _Xran();
  81.         size_type _N = _X.size() - _P;
  82.         if (_N < _M)
  83.             _M = _N;
  84.         if (npos - _Len <= _M)
  85.             _Xlen();
  86.         if (0 < _M && _Grow(_N = _Len + _M))
  87.             {_Tr::copy(_Ptr + _Len, &_X.c_str()[_P], _M);
  88.             _Eos(_N); }
  89.         return (*this); }
  90.     _Myt& append(const _E *_S, size_type _M)
  91.         {if (npos - _Len <= _M)
  92.             _Xlen();
  93.         size_type _N;
  94.         if (0 < _M && _Grow(_N = _Len + _M))
  95.             {_Tr::copy(_Ptr + _Len, _S, _M);
  96.             _Eos(_N); }
  97.         return (*this); }
  98.     _Myt& append(const _E *_S)
  99.         {return (append(_S, _Tr::length(_S))); }
  100.     _Myt& append(size_type _M, _E _C)
  101.         {if (npos - _Len <= _M)
  102.             _Xlen();
  103.         size_type _N;
  104.         if (0 < _M && _Grow(_N = _Len + _M))
  105.             {_Tr::assign(_Ptr + _Len, _M, _C);
  106.             _Eos(_N); }
  107.         return (*this); }
  108.     _Myt& append(_It _F, _It _L)
  109.         {return (replace(end(), end(), _F, _L)); }
  110.     _Myt& assign(const _Myt& _X)
  111.         {return (assign(_X, 0, npos)); }
  112.     _Myt& assign(const _Myt& _X, size_type _P, size_type _M)
  113.         {if (_X.size() < _P)
  114.             _Xran();
  115.         size_type _N = _X.size() - _P;
  116.         if (_M < _N)
  117.             _N = _M;
  118.         if (this == &_X)
  119.             erase((size_type)(_P + _N)), erase(0, _P);
  120.         else if (0 < _N && _N == _X.size()
  121.             && _Refcnt(_X.c_str()) < _FROZEN - 1
  122.             && allocator == _X.allocator)
  123.             {_Tidy(true);
  124.             _Ptr = (_E *)_X.c_str();
  125.             _Len = _X.size();
  126.             _Res = _X.capacity();
  127.             ++_Refcnt(_Ptr); }
  128.         else if (_Grow(_N, true))
  129.             {_Tr::copy(_Ptr, &_X.c_str()[_P], _N);
  130.             _Eos(_N); }
  131.         return (*this); }
  132.     _Myt& assign(const _E *_S, size_type _N)
  133.         {if (_Grow(_N, true))
  134.             {_Tr::copy(_Ptr, _S, _N);
  135.             _Eos(_N); }
  136.         return (*this); }
  137.     _Myt& assign(const _E *_S)
  138.         {return (assign(_S, _Tr::length(_S))); }
  139.     _Myt& assign(size_type _N, _E _C)
  140.         {if (_N == npos)
  141.             _Xlen();
  142.         if (_Grow(_N, true))
  143.             {_Tr::assign(_Ptr, _N, _C);
  144.             _Eos(_N); }
  145.         return (*this); }
  146.     _Myt& assign(_It _F, _It _L)
  147.         {return (replace(begin(), end(), _F, _L)); }
  148.     _Myt& insert(size_type _P0, const _Myt& _X)
  149.         {return (insert(_P0, _X, 0, npos)); }
  150.     _Myt& insert(size_type _P0, const _Myt& _X, size_type _P,
  151.         size_type _M)
  152.         {if (_Len < _P0 || _X.size() < _P)
  153.             _Xran();
  154.         size_type _N = _X.size() - _P;
  155.         if (_N < _M)
  156.             _M = _N;
  157.         if (npos - _Len <= _M)
  158.             _Xlen();
  159.         if (0 < _M && _Grow(_N = _Len + _M))
  160.             {_Tr::move(_Ptr + _P0 + _M, _Ptr + _P0, _Len - _P0);
  161.             _Tr::copy(_Ptr + _P0, &_X.c_str()[_P], _M);
  162.             _Eos(_N); }
  163.         return (*this); }
  164.     _Myt& insert(size_type _P0, const _E *_S, size_type _M)
  165.         {if (_Len < _P0)
  166.             _Xran();
  167.         if (npos - _Len <= _M)
  168.             _Xlen();
  169.         size_type _N;
  170.         if (0 < _M && _Grow(_N = _Len + _M))
  171.             {_Tr::move(_Ptr + _P0 + _M, _Ptr + _P0, _Len - _P0);
  172.             _Tr::copy(_Ptr + _P0, _S, _M);
  173.             _Eos(_N); }
  174.         return (*this); }
  175.     _Myt& insert(size_type _P0, const _E *_S)
  176.         {return (insert(_P0, _S, _Tr::length(_S))); }
  177.     _Myt& insert(size_type _P0, size_type _M, _E _C)
  178.         {if (_Len < _P0)
  179.             _Xran();
  180.         if (npos - _Len <= _M)
  181.             _Xlen();
  182.         size_type _N;
  183.         if (0 < _M && _Grow(_N = _Len + _M))
  184.             {_Tr::move(_Ptr + _P0 + _M, _Ptr + _P0, _Len - _P0);
  185.             _Tr::assign(_Ptr + _P0, _M, _C);
  186.             _Eos(_N); }
  187.         return (*this); }
  188.     iterator insert(iterator _P, _E _C)
  189.         {size_type _P0 = _Pdif(_P, begin());
  190.         insert(_P0, 1, _C);
  191.         return (begin() + _P0); }
  192.     void insert(iterator _P, size_type _M, _E _C)
  193.         {size_type _P0 = _Pdif(_P, begin());
  194.         insert(_P0, _M, _C); }
  195.     void insert(iterator _P, _It _F, _It _L)
  196.         {replace(_P, _P, _F, _L); }
  197.     _Myt& erase(size_type _P0 = 0, size_type _M = npos)
  198.         {if (_Len < _P0)
  199.             _Xran();
  200.         _Split();
  201.         if (_Len - _P0 < _M)
  202.             _M = _Len - _P0;
  203.         if (0 < _M)
  204.             {_Tr::move(_Ptr + _P0, _Ptr + _P0 + _M,
  205.                 _Len - _P0 - _M);
  206.             size_type _N = _Len - _M;
  207.             if (_Grow(_N))
  208.                 _Eos(_N); }
  209.         return (*this); }
  210.     iterator erase(iterator _P)
  211.         {size_t _M = _Pdif(_P, begin());
  212.         erase(_M, 1);
  213.         return (_Psum(_Ptr, _M)); }
  214.     iterator erase(iterator _F, iterator _L)
  215.         {size_t _M = _Pdif(_F, begin());
  216.         erase(_M, _Pdif(_L, _F));
  217.         return (_Psum(_Ptr, _M)); }
  218.     _Myt& replace(size_type _P0, size_type _N0, const _Myt& _X)
  219.         {return (replace(_P0, _N0, _X, 0, npos)); }
  220.     _Myt& replace(size_type _P0, size_type _N0, const _Myt& _X,
  221.         size_type _P, size_type _M)
  222.         {if (_Len < _P0 || _X.size() < _P)
  223.             _Xran();
  224.         if (_Len - _P0 < _N0)
  225.             _N0 = _Len - _P0;
  226.         size_type _N = _X.size() - _P;
  227.         if (_N < _M)
  228.             _M = _N;
  229.         if (npos - _M <= _Len - _N0)
  230.             _Xlen();
  231.         _Split();
  232.         size_type _Nm = _Len - _N0 - _P0;
  233.         if (_M < _N0)
  234.             _Tr::move(_Ptr + _P0 + _M, _Ptr + _P0 + _N0, _Nm);
  235.         if ((0 < _M || 0 < _N0) && _Grow(_N = _Len + _M - _N0))
  236.             {if (_N0 < _M)
  237.                 _Tr::move(_Ptr + _P0 + _M, _Ptr + _P0 + _N0, _Nm);
  238.             _Tr::copy(_Ptr + _P0, &_X.c_str()[_P], _M);
  239.             _Eos(_N); }
  240.         return (*this); }
  241.     _Myt& replace(size_type _P0, size_type _N0, const _E *_S,
  242.         size_type _M)
  243.         {if (_Len < _P0)
  244.             _Xran();
  245.         if (_Len - _P0 < _N0)
  246.             _N0 = _Len - _P0;
  247.         if (npos - _M <= _Len - _N0)
  248.             _Xlen();
  249.         _Split();
  250.         size_type _Nm = _Len - _N0 - _P0;
  251.         if (_M < _N0)
  252.             _Tr::move(_Ptr + _P0 + _M, _Ptr + _P0 + _N0, _Nm);
  253.         size_type _N;
  254.         if ((0 < _M || 0 < _N0) && _Grow(_N = _Len + _M - _N0))
  255.             {if (_N0 < _M)
  256.                 _Tr::move(_Ptr + _P0 + _M, _Ptr + _P0 + _N0, _Nm);
  257.             _Tr::copy(_Ptr + _P0, _S, _M);
  258.             _Eos(_N); }
  259.         return (*this); }
  260.     _Myt& replace(size_type _P0, size_type _N0, const _E *_S)
  261.         {return (replace(_P0, _N0, _S, _Tr::length(_S))); }
  262.     _Myt& replace(size_type _P0, size_type _N0,
  263.         size_type _M, _E _C)
  264.         {if (_Len < _P0)
  265.             _Xran();
  266.         if (_Len - _P0 < _N0)
  267.             _N0 = _Len - _P0;
  268.         if (npos - _M <= _Len - _N0)
  269.             _Xlen();
  270.         _Split();
  271.         size_type _Nm = _Len - _N0 - _P0;
  272.         if (_M < _N0)
  273.             _Tr::move(_Ptr + _P0 + _M, _Ptr + _P0 + _N0, _Nm);
  274.         size_type _N;
  275.         if ((0 < _M || 0 < _N0) && _Grow(_N = _Len + _M - _N0))
  276.             {if (_N0 < _M)
  277.                 _Tr::move(_Ptr + _P0 + _M, _Ptr + _P0 + _N0,
  278.                     _Nm);
  279.             _Tr::assign(_Ptr + _P0, _M, _C);
  280.             _Eos(_N); }
  281.         return (*this); }
  282.     _Myt& replace(iterator _F, iterator _L, const _Myt& _X)
  283.         {return (replace(
  284.             _Pdif(_F, begin()), _Pdif(_L, _F), _X)); }
  285.     _Myt& replace(iterator _F, iterator _L, const _E *_S,
  286.         size_type _M)
  287.         {return (replace(
  288.             _Pdif(_F, begin()), _Pdif(_L, _F), _S, _M)); }
  289.     _Myt& replace(iterator _F, iterator _L, const _E *_S)
  290.         {return (replace(
  291.             _Pdif(_F, begin()), _Pdif(_L, _F), _S)); }
  292.     _Myt& replace(iterator _F, iterator _L,    size_type _M, _E _C)
  293.         {return (replace(
  294.             _Pdif(_F, begin()), _Pdif(_L, _F), _M, _C)); }
  295.     _Myt& replace(iterator _F1, iterator _L1,
  296.         _It _F2, _It _L2)
  297.         {size_type _P0 = _Pdif(_F1, begin());
  298.         size_type _M = 0;
  299.         _Distance(_F2, _L2, _M);
  300.         replace(_P0, _Pdif(_L1, _F1), _M, _E(0));
  301.         for (_F1 = begin() + _P0; 0 < _M; ++_F1, ++_F2, --_M)
  302.             *_F1 = *_F2;
  303.         return (*this); }
  304.     iterator begin()
  305.         {_Freeze();
  306.         return (_Ptr); }
  307.     const_iterator begin() const
  308.         {return (_Ptr); }
  309.     iterator end()
  310.         {_Freeze();
  311.         return ((iterator)_Psum(_Ptr, _Len)); }
  312.     const_iterator end() const
  313.         {return ((const_iterator)_Psum(_Ptr, _Len)); }
  314.     reverse_iterator rbegin()
  315.         {return (reverse_iterator(end())); }
  316.     const_reverse_iterator rbegin() const
  317.         {return (const_reverse_iterator(end())); }
  318.     reverse_iterator rend()
  319.         {return (reverse_iterator(begin())); }
  320.     const_reverse_iterator rend() const
  321.         {return (const_reverse_iterator(begin())); }
  322.     reference at(size_type _P0)
  323.         {if (_Len <= _P0)
  324.             _Xran();
  325.         _Freeze();
  326.         return (_Ptr[_P0]); }
  327.     const_reference at(size_type _P0) const
  328.         {if (_Len <= _P0)
  329.             _Xran();
  330.         return (_Ptr[_P0]); }
  331.     reference operator[](size_type _P0)
  332.         {if (_Len < _P0 || _Ptr == 0)
  333.             return ((reference)*_Nullstr());
  334.         _Freeze();
  335.         return (_Ptr[_P0]); }
  336.     const_reference operator[](size_type _P0) const
  337.         {if (_Ptr == 0)
  338.             return (*_Nullstr());
  339.         else
  340.             return (_Ptr[_P0]); }
  341.     const _E *c_str() const
  342.         {return (_Ptr == 0 ? _Nullstr() : _Ptr); }
  343.     const _E *data() const
  344.         {return (c_str()); }
  345.     size_type length() const
  346.         {return (_Len); }
  347.     size_type size() const
  348.         {return (_Len); }
  349.     size_type max_size() const
  350.         {size_type _N = allocator.max_size();
  351.         return (_N <= 2 ? 1 : _N - 2); }
  352.     void resize(size_type _N, _E _C)
  353.         {_N <= _Len ? erase(_N) : append(_N - _Len, _C); }
  354.     void resize(size_type _N)
  355.         {_N <= _Len ? erase(_N) : append(_N - _Len, _E(0)); }
  356.     size_type capacity() const
  357.         {return (_Res); }
  358.     void reserve(size_type _N = 0)
  359.         {if (_Res < _N)
  360.             _Grow(_N); }
  361.     bool empty() const
  362.         {return (_Len == 0); }
  363.     size_type copy(_E *_S, size_type _N, size_type _P0 = 0) const
  364.         {if (_Len < _P0)
  365.             _Xran();
  366.         if (_Len - _P0 < _N)
  367.             _N = _Len - _P0;
  368.         if (0 < _N)
  369.             _Tr::copy(_S, _Ptr + _P0, _N);
  370.         return (_N); }
  371.     void swap(_Myt& _X)
  372.         {if (allocator == _X.allocator)
  373.             {std::swap(_Ptr, _X._Ptr);
  374.             std::swap(_Len, _X._Len);
  375.             std::swap(_Res, _X._Res); }
  376.         else
  377.             {_Myt _Ts = *this; *this = _X, _X = _Ts; }}
  378.     friend void swap(_Myt& _X, _Myt& _Y)
  379.         {_X.swap(_Y); }
  380.     size_type find(const _Myt& _X, size_type _P = 0) const
  381.         {return (find(_X.c_str(), _P, _X.size())); }
  382.     size_type find(const _E *_S, size_type _P,
  383.         size_type _N) const
  384.         {if (_N == 0 && _P <= _Len)
  385.             return (_P);
  386.         size_type _Nm;
  387.         if (_P < _Len && _N <= (_Nm = _Len - _P))
  388.             {const _E *_U, *_V;
  389.             for (_Nm -= _N - 1, _V = _Ptr + _P;
  390.                 (_U = _Tr::find(_V, _Nm, *_S)) != 0;
  391.                 _Nm -= _U - _V + 1, _V = _U + 1)
  392.                 if (_Tr::compare(_U, _S, _N) == 0)
  393.                     return (_U - _Ptr); }
  394.         return (npos); }
  395.     size_type find(const _E *_S, size_type _P = 0) const
  396.         {return (find(_S, _P, _Tr::length(_S))); }
  397.     size_type find(_E _C, size_type _P = 0) const
  398.         {return (find((const _E *)&_C, _P, 1)); }
  399.     size_type rfind(const _Myt& _X, size_type _P = npos) const
  400.         {return (rfind(_X.c_str(), _P, _X.size())); }
  401.     size_type rfind(const _E *_S, size_type _P,
  402.         size_type _N) const
  403.         {if (_N == 0)
  404.             return (_P < _Len ? _P : _Len);
  405.         if (_N <= _Len)
  406.             for (const _E *_U = _Ptr +
  407.                 + (_P < _Len - _N ? _P : _Len - _N); ; --_U)
  408.                 if (_Tr::eq(*_U, *_S)
  409.                     && _Tr::compare(_U, _S, _N) == 0)
  410.                     return (_U - _Ptr);
  411.                 else if (_U == _Ptr)
  412.                     break;
  413.         return (npos); }
  414.     size_type rfind(const _E *_S, size_type _P = npos) const
  415.         {return (rfind(_S, _P, _Tr::length(_S))); }
  416.     size_type rfind(_E _C, size_type _P = npos) const
  417.         {return (rfind((const _E *)&_C, _P, 1)); }
  418.     size_type find_first_of(const _Myt& _X,
  419.         size_type _P = 0) const
  420.         {return (find_first_of(_X.c_str(), _P, _X.size())); }
  421.     size_type find_first_of(const _E *_S, size_type _P,
  422.         size_type _N) const
  423.         {if (0 < _N && _P < _Len)
  424.             {const _E *const _V = _Ptr + _Len;
  425.             for (const _E *_U = _Ptr + _P; _U < _V; ++_U)
  426.                 if (_Tr::find(_S, _N, *_U) != 0)
  427.                     return (_U - _Ptr); }
  428.         return (npos); }
  429.     size_type find_first_of(const _E *_S, size_type _P = 0) const
  430.         {return (find_first_of(_S, _P, _Tr::length(_S))); }
  431.     size_type find_first_of(_E _C, size_type _P = 0) const
  432.         {return (find((const _E *)&_C, _P, 1)); }
  433.     size_type find_last_of(const _Myt& _X,
  434.         size_type _P = npos) const
  435.         {return (find_last_of(_X.c_str(), _P, _X.size())); }
  436.     size_type find_last_of(const _E *_S, size_type _P,
  437.         size_type _N) const
  438.         {if (0 < _N && 0 < _Len)
  439.             for (const _E *_U = _Ptr
  440.                 + (_P < _Len ? _P : _Len - 1); ; --_U)
  441.                 if (_Tr::find(_S, _N, *_U) != 0)
  442.                     return (_U - _Ptr);
  443.                 else if (_U == _Ptr)
  444.                     break;
  445.         return (npos); }
  446.     size_type find_last_of(const _E *_S,
  447.         size_type _P = npos) const
  448.         {return (find_last_of(_S, _P, _Tr::length(_S))); }
  449.     size_type find_last_of(_E _C, size_type _P = npos) const
  450.         {return (rfind((const _E *)&_C, _P, 1)); }
  451.     size_type find_first_not_of(const _Myt& _X,
  452.         size_type _P = 0) const
  453.         {return (find_first_not_of(_X.c_str(), _P,
  454.             _X.size())); }
  455.     size_type find_first_not_of(const _E *_S, size_type _P,
  456.         size_type _N) const
  457.         {if (_P < _Len)
  458.             {const _E *const _V = _Ptr + _Len;
  459.             for (const _E *_U = _Ptr + _P; _U < _V; ++_U)
  460.                 if (_Tr::find(_S, _N, *_U) == 0)
  461.                     return (_U - _Ptr); }
  462.         return (npos); }
  463.     size_type find_first_not_of(const _E *_S,
  464.         size_type _P = 0) const
  465.         {return (find_first_not_of(_S, _P, _Tr::length(_S))); }
  466.     size_type find_first_not_of(_E _C, size_type _P = 0) const
  467.         {return (find_first_not_of((const _E *)&_C, _P, 1)); }
  468.     size_type find_last_not_of(const _Myt& _X,
  469.         size_type _P = npos) const
  470.         {return (find_last_not_of(_X.c_str(), _P, _X.size())); }
  471.     size_type find_last_not_of(const _E *_S, size_type _P,
  472.          size_type _N) const
  473.         {if (0 < _Len)
  474.             for (const _E *_U = _Ptr
  475.                 + (_P < _Len ? _P : _Len - 1); ; --_U)
  476.                 if (_Tr::find(_S, _N, *_U) == 0)
  477.                     return (_U - _Ptr);
  478.                 else if (_U == _Ptr)
  479.                     break;
  480.         return (npos); }
  481.     size_type find_last_not_of(const _E *_S,
  482.         size_type _P = npos) const
  483.         {return (find_last_not_of(_S, _P, _Tr::length(_S))); }
  484.     size_type find_last_not_of(_E _C, size_type _P = npos) const
  485.         {return (find_last_not_of((const _E *)&_C, _P, 1)); }
  486.     _Myt substr(size_type _P = 0, size_type _M = npos) const
  487.         {return (_Myt(*this, _P, _M)); }
  488.     int compare(const _Myt& _X) const
  489.         {return (compare(0, _Len, _X.c_str(), _X.size())); }
  490.     int compare(size_type _P0, size_type _N0,
  491.         const _Myt& _X) const
  492.         {return (compare(_P0, _N0, _X, 0, npos)); }
  493.     int compare(size_type _P0, size_type _N0, const _Myt& _X,
  494.         size_type _P, size_type _M) const
  495.         {if (_X.size() < _P)
  496.             _Xran();
  497.         if (_X._Len - _P < _M)
  498.             _M = _X._Len - _P;
  499.         return (compare(_P0, _N0, _X.c_str() + _P, _M)); }
  500.     int compare(const _E *_S) const
  501.         {return (compare(0, _Len, _S, _Tr::length(_S))); }
  502.     int compare(size_type _P0, size_type _N0, const _E *_S) const
  503.         {return (compare(_P0, _N0, _S, _Tr::length(_S))); }
  504.     int compare(size_type _P0, size_type _N0, const _E *_S,
  505.         size_type _M) const
  506.         {if (_Len < _P0)
  507.             _Xran();
  508.         if (_Len - _P0 < _N0)
  509.             _N0 = _Len - _P0;
  510.         size_type _Ans = _Tr::compare(_Psum(_Ptr, _P0), _S,
  511.             _N0 < _M ? _N0 : _M);
  512.         return (_Ans != 0 ? _Ans : _N0 < _M ? -1
  513.             : _N0 == _M ? 0 : +1); }
  514.     _A get_allocator() const
  515.         {return (allocator); }
  516. protected:
  517.     _A allocator;
  518. private:
  519.     enum {_MIN_SIZE = sizeof (_E) <= 32 ? 31 : 7};
  520.     void _Copy(size_type _N)
  521.         {size_type _Ns = _N | _MIN_SIZE;
  522.         if (max_size() < _Ns)
  523.             _Ns = _N;
  524.         _E *_S;
  525.         _TRY_BEGIN
  526.             _S = allocator.allocate(_Ns + 2, (void *)0);
  527.         _CATCH_ALL
  528.             _Ns = _N;
  529.             _S = allocator.allocate(_Ns + 2, (void *)0);
  530.         _CATCH_END
  531.         if (0 < _Len)
  532.             _Tr::copy(_S + 1, _Ptr,_Len>_Ns?_Ns:_Len);
  533.         size_type _Olen = _Len;
  534.         _Tidy(true);
  535.         _Ptr = _S + 1;
  536.         _Refcnt(_Ptr) = 0;
  537.         _Res = _Ns;
  538.         _Eos(_Olen>_Ns?_Ns:_Olen); }
  539.     void _Eos(size_type _N)
  540.         {_Tr::assign(_Ptr[_Len = _N], _E(0)); }
  541.     void _Freeze()
  542.         {if (_Ptr != 0
  543.             && _Refcnt(_Ptr) != 0 && _Refcnt(_Ptr) != _FROZEN)
  544.             _Grow(_Len);
  545.         if (_Ptr != 0)
  546.             _Refcnt(_Ptr) = _FROZEN; }
  547.     bool _Grow(size_type _N, bool _Trim = false)
  548.         {if (max_size() < _N)
  549.             _Xlen();
  550.         if (_Ptr != 0
  551.             && _Refcnt(_Ptr) != 0 && _Refcnt(_Ptr) != _FROZEN)
  552.             if (_N == 0)
  553.                 {--_Refcnt(_Ptr), _Tidy();
  554.                 return (false); }
  555.             else
  556.                 {_Copy(_N);
  557.                 return (true); }
  558.         if (_N == 0)
  559.             {if (_Trim)
  560.                 _Tidy(true);
  561.             else if (_Ptr != 0)
  562.                 _Eos(0);
  563.             return (false); }
  564.         else
  565.             {if (_Trim && (_MIN_SIZE < _Res || _Res < _N))
  566.                 {_Tidy(true);
  567.                 _Copy(_N); }
  568.             else if (!_Trim && _Res < _N)
  569.                 _Copy(_N);
  570.             return (true); }}
  571.     static const _E * __cdecl _Nullstr()
  572.         {static const _E _C = _E(0);
  573.         return (&_C); }
  574.     static size_type _Pdif(const_pointer _P2, const_pointer _P1)
  575.         {return (_P2 == 0 ? 0 : _P2 - _P1); }
  576.     static const_pointer _Psum(const_pointer _P, size_type _N)
  577.         {return (_P == 0 ? 0 : _P + _N); }
  578.     static pointer _Psum(pointer _P, size_type _N)
  579.         {return (_P == 0 ? 0 : _P + _N); }
  580.     unsigned char& _Refcnt(const _E *_U)
  581.         {return (((unsigned char *)_U)[-1]); }
  582.     void _Split()
  583.         {if (_Ptr != 0 && _Refcnt(_Ptr) != 0 && _Refcnt(_Ptr) != _FROZEN)
  584.             {_E *_Temp = _Ptr;
  585.             _Tidy(true);
  586.             assign(_Temp); }}
  587.     void _Tidy(bool _Built = false)
  588.         {if (!_Built || _Ptr == 0)
  589.             ;
  590.         else if (_Refcnt(_Ptr) == 0 || _Refcnt(_Ptr) == _FROZEN)
  591.             allocator.deallocate(_Ptr - 1, _Res + 2);
  592.         else
  593.             --_Refcnt(_Ptr);
  594.         _Ptr = 0, _Len = 0, _Res = 0; }
  595.     _E *_Ptr;
  596.     size_type _Len, _Res;
  597.     };
  598. template<class _E, class _Tr, class _A>
  599.     const basic_string<_E, _Tr, _A>::size_type
  600.         basic_string<_E, _Tr, _A>::npos = -1;
  601.  
  602. #ifdef    _DLL
  603. #pragma warning(disable:4231) /* the extern before template is a non-standard extension */
  604.  
  605. extern template class _CRTIMP basic_string<char, char_traits<char>, allocator<char> >;
  606. extern template class _CRTIMP basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> >;
  607.  
  608. #pragma warning(default:4231) /* restore previous warning */
  609. #endif        // _DLL
  610.  
  611. typedef basic_string<char, char_traits<char>, allocator<char> >
  612.     string;
  613.  
  614. typedef basic_string<wchar_t, char_traits<wchar_t>,
  615.     allocator<wchar_t> > wstring;
  616.  
  617. _STD_END
  618. #ifdef  _MSC_VER
  619. #pragma pack(pop)
  620. #endif  /* _MSC_VER */
  621.  
  622. #endif /* _XSTRING */
  623.  
  624. /*
  625.  * Copyright (c) 1995 by P.J. Plauger.  ALL RIGHTS RESERVED. 
  626.  * Consult your license regarding permissions and restrictions.
  627.  */
  628.