Q009

Untitled

Jan 19th, 2015
334
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 46.45 KB | None | 0 0
  1. template<class _Elem,
  2.     class _Traits,
  3.     class _Alloc>
  4.     class basic_string
  5.         : public _String_alloc<!is_empty<_Alloc>::value,
  6.             _String_base_types<_Elem, _Alloc> >
  7.     {   // null-terminated transparent array of elements
  8. public:
  9.     typedef basic_string<_Elem, _Traits, _Alloc> _Myt;
  10.     typedef _String_alloc<!is_empty<_Alloc>::value,
  11.         _String_base_types<_Elem, _Alloc> > _Mybase;
  12.     typedef _Traits traits_type;
  13.     typedef _Alloc allocator_type;
  14.  
  15.     typedef typename _Mybase::_Alty _Alty;
  16.  
  17.     typedef typename _Mybase::value_type value_type;
  18.     typedef typename _Mybase::size_type size_type;
  19.     typedef typename _Mybase::difference_type difference_type;
  20.     typedef typename _Mybase::pointer pointer;
  21.     typedef typename _Mybase::const_pointer const_pointer;
  22.     typedef typename _Mybase::reference reference;
  23.     typedef typename _Mybase::const_reference const_reference;
  24.  
  25.     typedef typename _Mybase::iterator iterator;
  26.     typedef typename _Mybase::const_iterator const_iterator;
  27.  
  28.     typedef _STD reverse_iterator<iterator> reverse_iterator;
  29.     typedef _STD reverse_iterator<const_iterator> const_reverse_iterator;
  30.  
  31.     basic_string(const _Myt& _Right)
  32.  
  33.         : _Mybase(_Right._Getal().select_on_container_copy_construction())
  34.  
  35.  
  36.         {   // construct by copying _Right
  37.         _Tidy();
  38.         assign(_Right, 0, npos);
  39.         }
  40.  
  41.     basic_string(const _Myt& _Right, const _Alloc& _Al)
  42.         : _Mybase(_Al)
  43.         {   // construct by copying with allocator
  44.         _Tidy();
  45.         assign(_Right, 0, npos);
  46.         }
  47.  
  48.     basic_string()
  49.         : _Mybase()
  50.         {   // construct empty string
  51.         _Tidy();
  52.         }
  53.  
  54.     explicit basic_string(const _Alloc& _Al)
  55.         : _Mybase(_Al)
  56.         {   // construct empty string with allocator
  57.         _Tidy();
  58.         }
  59.  
  60.     basic_string(const _Myt& _Right, size_type _Roff,
  61.         size_type _Count = npos)
  62.         : _Mybase(_Right._Getal())
  63.         {   // construct from _Right [_Roff, _Roff + _Count)
  64.         _Tidy();
  65.         assign(_Right, _Roff, _Count);
  66.         }
  67.  
  68.     basic_string(const _Myt& _Right, size_type _Roff, size_type _Count,
  69.         const _Alloc& _Al)
  70.         : _Mybase(_Al)
  71.         {   // construct from _Right [_Roff, _Roff + _Count) with allocator
  72.         _Tidy();
  73.         assign(_Right, _Roff, _Count);
  74.         }
  75.  
  76.     basic_string(const _Elem *_Ptr, size_type _Count)
  77.         : _Mybase()
  78.         {   // construct from [_Ptr, _Ptr + _Count)
  79.         _Tidy();
  80.         assign(_Ptr, _Count);
  81.         }
  82.  
  83.     basic_string(const _Elem *_Ptr, size_type _Count, const _Alloc& _Al)
  84.         : _Mybase(_Al)
  85.         {   // construct from [_Ptr, _Ptr + _Count) with allocator
  86.         _Tidy();
  87.         assign(_Ptr, _Count);
  88.         }
  89.  
  90.     basic_string(const _Elem *_Ptr)
  91.         : _Mybase()
  92.         {   // construct from [_Ptr, <null>)
  93.         _Tidy();
  94.         assign(_Ptr);
  95.         }
  96.  
  97.     basic_string(const _Elem *_Ptr, const _Alloc& _Al)
  98.         : _Mybase(_Al)
  99.         {   // construct from [_Ptr, <null>) with allocator
  100.         _Tidy();
  101.         assign(_Ptr);
  102.         }
  103.  
  104.     basic_string(size_type _Count, _Elem _Ch)
  105.         : _Mybase()
  106.         {   // construct from _Count * _Ch
  107.         _Tidy();
  108.         assign(_Count, _Ch);
  109.         }
  110.  
  111.     basic_string(size_type _Count, _Elem _Ch, const _Alloc& _Al)
  112.         : _Mybase(_Al)
  113.         {   // construct from _Count * _Ch with allocator
  114.         _Tidy();
  115.         assign(_Count, _Ch);
  116.         }
  117.  
  118.     template<class _Iter,
  119.         class = typename enable_if<_Is_iterator<_Iter>::value,
  120.             void>::type>
  121.         basic_string(_Iter _First, _Iter _Last)
  122.         : _Mybase()
  123.         {   // construct from [_First, _Last)
  124.         _Tidy();
  125.         _Construct(_First, _Last, _Iter_cat(_First));
  126.         }
  127.  
  128.     template<class _Iter,
  129.         class = typename enable_if<_Is_iterator<_Iter>::value,
  130.             void>::type>
  131.         basic_string(_Iter _First, _Iter _Last, const _Alloc& _Al)
  132.         : _Mybase(_Al)
  133.         {   // construct from [_First, _Last) with allocator
  134.         _Tidy();
  135.         _Construct(_First, _Last, _Iter_cat(_First));
  136.         }
  137.  
  138.     template<class _Iter>
  139.         void _Construct(_Iter _First,
  140.             _Iter _Last, input_iterator_tag)
  141.         {   // initialize from [_First, _Last), input iterators
  142.         _TRY_BEGIN
  143.         for (; _First != _Last; ++_First)
  144.             append((size_type)1, (_Elem)*_First);
  145.         _CATCH_ALL
  146.         _Tidy(true);
  147.         _RERAISE;
  148.         _CATCH_END
  149.         }
  150.  
  151.     template<class _Iter>
  152.         void _Construct(_Iter _First,
  153.             _Iter _Last, forward_iterator_tag)
  154.         {   // initialize from [_First, _Last), forward iterators
  155.         _DEBUG_RANGE(_First, _Last);
  156.         size_type _Count = 0;
  157.         _Distance(_First, _Last, _Count);
  158.         reserve(_Count);
  159.  
  160.         _TRY_BEGIN
  161.         for (; _First != _Last; ++_First)
  162.             append((size_type)1, (_Elem)*_First);
  163.         _CATCH_ALL
  164.         _Tidy(true);
  165.         _RERAISE;
  166.         _CATCH_END
  167.         }
  168.  
  169.     basic_string(const_pointer _First, const_pointer _Last)
  170.         : _Mybase()
  171.         {   // construct from [_First, _Last), const pointers
  172.         _DEBUG_RANGE(_First, _Last);
  173.         _Tidy();
  174.         if (_First != _Last)
  175.             assign(&*_First, _Last - _First);
  176.         }
  177.  
  178.     basic_string(const_pointer _First, const_pointer _Last,
  179.         const _Alloc& _Al)
  180.         : _Mybase(_Al)
  181.         {   // construct from [_First, _Last), const pointers
  182.         _DEBUG_RANGE(_First, _Last);
  183.         _Tidy();
  184.         if (_First != _Last)
  185.             assign(&*_First, _Last - _First);
  186.         }
  187.  
  188.     basic_string(const_iterator _First, const_iterator _Last)
  189.         : _Mybase()
  190.         {   // construct from [_First, _Last), const_iterators
  191.         _DEBUG_RANGE(_First, _Last);
  192.         _Tidy();
  193.         if (_First != _Last)
  194.             assign(&*_First, _Last - _First);
  195.         }
  196.  
  197.     basic_string(_Myt&& _Right) _NOEXCEPT
  198.         : _Mybase(_Right._Getal())
  199.         {   // construct by moving _Right
  200.         _Tidy();
  201.         _Assign_rv(_STD forward<_Myt>(_Right));
  202.         }
  203.  
  204.     basic_string(_Myt&& _Right, const _Alloc& _Al)
  205.         : _Mybase(_Al)
  206.         {   // construct by moving _Right, allocator
  207.         if (this->_Getal() != _Right._Getal())
  208.             assign(_Right.begin(), _Right.end());
  209.         else
  210.             _Assign_rv(_STD forward<_Myt>(_Right));
  211.         }
  212.  
  213.     _Myt& operator=(_Myt&& _Right) _NOEXCEPT
  214.         {   // assign by moving _Right
  215.         if (this != &_Right)
  216.             {   // different, assign it
  217.             _Tidy(true);
  218.  
  219.             if (_Alty::propagate_on_container_move_assignment::value
  220.                 && this->_Getal() != _Right._Getal())
  221.                 this->_Change_alloc(_Right._Getal());
  222.  
  223.             if (this->_Getal() != _Right._Getal())
  224.                 assign(_Right.begin(), _Right.end());
  225.             else
  226.                 _Assign_rv(_STD forward<_Myt>(_Right));
  227.             }
  228.         return (*this);
  229.         }
  230.  
  231.     _Myt& assign(_Myt&& _Right) _NOEXCEPT
  232.         {   // assign by moving _Right
  233.         if (this == &_Right)
  234.             ;
  235.         else if (get_allocator() != _Right.get_allocator()
  236.             && this->_BUF_SIZE <= _Right._Myres)
  237.             *this = _Right;
  238.         else
  239.             {   // not same, clear this and steal from _Right
  240.             _Tidy(true);
  241.             _Assign_rv(_STD forward<_Myt>(_Right));
  242.             }
  243.         return (*this);
  244.         }
  245.  
  246.     void _Assign_rv(_Myt&& _Right)
  247.         {   // assign by moving _Right
  248.         if (_Right._Myres < this->_BUF_SIZE)
  249.             _Traits::move(this->_Bx._Buf, _Right._Bx._Buf,
  250.                 _Right._Mysize + 1);
  251.         else
  252.             {   // copy pointer
  253.             this->_Getal().construct(&this->_Bx._Ptr, _Right._Bx._Ptr);
  254.             _Right._Bx._Ptr = pointer();
  255.             }
  256.         this->_Mysize = _Right._Mysize;
  257.         this->_Myres = _Right._Myres;
  258.         _Right._Tidy();
  259.         }
  260.  
  261.     basic_string(_XSTD initializer_list<_Elem> _Ilist,
  262.         const _Alloc& _Al = allocator_type())
  263.         : _Mybase(_Al)
  264.         {   // construct from initializer_list
  265.         _Tidy();
  266.         assign(_Ilist.begin(), _Ilist.end());
  267.         }
  268.  
  269.     _Myt& operator=(_XSTD initializer_list<_Elem> _Ilist)
  270.         {   // assign initializer_list
  271.         return (assign(_Ilist.begin(), _Ilist.end()));
  272.         }
  273.  
  274.     _Myt& operator+=(_XSTD initializer_list<_Elem> _Ilist)
  275.         {   // append initializer_list
  276.         return (append(_Ilist.begin(), _Ilist.end()));
  277.         }
  278.  
  279.     _Myt& assign(_XSTD initializer_list<_Elem> _Ilist)
  280.         {   // assign initializer_list
  281.         return (assign(_Ilist.begin(), _Ilist.end()));
  282.         }
  283.  
  284.     _Myt& append(_XSTD initializer_list<_Elem> _Ilist)
  285.         {   // append initializer_list
  286.         return (append(_Ilist.begin(), _Ilist.end()));
  287.         }
  288.  
  289.     iterator insert(const_iterator _Where,
  290.         _XSTD initializer_list<_Elem> _Ilist)
  291.         {   // insert initializer_list
  292.         return (insert(_Where, _Ilist.begin(), _Ilist.end()));
  293.         }
  294.  
  295.     _Myt& replace(const_iterator _First, const_iterator _Last,
  296.         _XSTD initializer_list<_Elem> _Ilist)
  297.         {   // replace with initializer_list
  298.         return (replace(_First, _Last, _Ilist.begin(), _Ilist.end()));
  299.         }
  300.  
  301.     ~basic_string() _NOEXCEPT
  302.         {   // destroy the string
  303.         _Tidy(true);
  304.         }
  305.  
  306.     _PGLOBAL static const size_type npos;   // bad/missing length/position
  307.  
  308.     _Myt& operator=(const _Myt& _Right)
  309.         {   // assign _Right
  310.         if (this != &_Right)
  311.             {   // different, assign it
  312.             if (this->_Getal() != _Right._Getal()
  313.                 && _Alty::propagate_on_container_copy_assignment::value)
  314.                 {   // change allocator before copying
  315.                 _Tidy(true);
  316.                 this->_Change_alloc(_Right._Getal());
  317.                 }
  318.  
  319.             assign(_Right);
  320.             }
  321.         return (*this);
  322.         }
  323.  
  324.     _Myt& operator=(const _Elem *_Ptr)
  325.         {   // assign [_Ptr, <null>)
  326.         return (assign(_Ptr));
  327.         }
  328.  
  329.     _Myt& operator=(_Elem _Ch)
  330.         {   // assign 1 * _Ch
  331.         return (assign(1, _Ch));
  332.         }
  333.  
  334.     _Myt& operator+=(const _Myt& _Right)
  335.         {   // append _Right
  336.         return (append(_Right));
  337.         }
  338.  
  339.     _Myt& operator+=(const _Elem *_Ptr)
  340.         {   // append [_Ptr, <null>)
  341.         return (append(_Ptr));
  342.         }
  343.  
  344.     _Myt& operator+=(_Elem _Ch)
  345.         {   // append 1 * _Ch
  346.         return (append((size_type)1, _Ch));
  347.         }
  348.  
  349.     _Myt& append(const _Myt& _Right)
  350.         {   // append _Right
  351.         return (append(_Right, 0, npos));
  352.         }
  353.  
  354.     _Myt& append(const _Myt& _Right,
  355.         size_type _Roff, size_type _Count)
  356.         {   // append _Right [_Roff, _Roff + _Count)
  357.         if (_Right.size() < _Roff)
  358.             _Xran();    // _Roff off end
  359.         size_type _Num = _Right.size() - _Roff;
  360.         if (_Num < _Count)
  361.             _Count = _Num;  // trim _Count to size
  362.         if (npos - this->_Mysize <= _Count)
  363.             _Xlen();    // result too long
  364.  
  365.         if (0 < _Count && _Grow(_Num = this->_Mysize + _Count))
  366.             {   // make room and append new stuff
  367.             _Traits::copy(this->_Myptr() + this->_Mysize,
  368.                 _Right._Myptr() + _Roff, _Count);
  369.             _Eos(_Num);
  370.             }
  371.         return (*this);
  372.         }
  373.  
  374.     _Myt& append(const _Elem *_Ptr, size_type _Count)
  375.         {   // append [_Ptr, _Ptr + _Count)
  376.  #if _ITERATOR_DEBUG_LEVEL == 2
  377.         if (_Count != 0)
  378.             _DEBUG_POINTER(_Ptr);
  379.  #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
  380.  
  381.         if (_Inside(_Ptr))
  382.             return (append(*this,
  383.                 _Ptr - this->_Myptr(), _Count));    // substring
  384.         if (npos - this->_Mysize <= _Count)
  385.             _Xlen();    // result too long
  386.  
  387.         size_type _Num;
  388.         if (0 < _Count && _Grow(_Num = this->_Mysize + _Count))
  389.             {   // make room and append new stuff
  390.             _Traits::copy(this->_Myptr() + this->_Mysize, _Ptr, _Count);
  391.             _Eos(_Num);
  392.             }
  393.         return (*this);
  394.         }
  395.  
  396.     _Myt& append(const _Elem *_Ptr)
  397.         {   // append [_Ptr, <null>)
  398.         _DEBUG_POINTER(_Ptr);
  399.         return (append(_Ptr, _Traits::length(_Ptr)));
  400.         }
  401.  
  402.     _Myt& append(size_type _Count, _Elem _Ch)
  403.         {   // append _Count * _Ch
  404.         if (npos - this->_Mysize <= _Count)
  405.             _Xlen();    // result too long
  406.  
  407.         size_type _Num;
  408.         if (0 < _Count && _Grow(_Num = this->_Mysize + _Count))
  409.             {   // make room and append new stuff using assign
  410.             _Chassign(this->_Mysize, _Count, _Ch);
  411.             _Eos(_Num);
  412.             }
  413.         return (*this);
  414.         }
  415.  
  416.     template<class _Iter>
  417.         typename enable_if<_Is_iterator<_Iter>::value,
  418.             _Myt&>::type
  419.         append(_Iter _First, _Iter _Last)
  420.         {   // append [_First, _Last), input iterators
  421.         return (replace(end(), end(), _First, _Last));
  422.         }
  423.  
  424.     _Myt& append(const_pointer _First, const_pointer _Last)
  425.         {   // append [_First, _Last), const pointers
  426.         return (replace(end(), end(), _First, _Last));
  427.         }
  428.  
  429.     _Myt& append(const_iterator _First, const_iterator _Last)
  430.         {   // append [_First, _Last), const_iterators
  431.         return (replace(end(), end(), _First, _Last));
  432.         }
  433.  
  434.     _Myt& assign(const _Myt& _Right)
  435.         {   // assign _Right
  436.         return (assign(_Right, 0, npos));
  437.         }
  438.  
  439.     _Myt& assign(const _Myt& _Right,
  440.         size_type _Roff, size_type _Count)
  441.         {   // assign _Right [_Roff, _Roff + _Count)
  442.         if (_Right.size() < _Roff)
  443.             _Xran();    // _Roff off end
  444.         size_type _Num = _Right.size() - _Roff;
  445.         if (_Count < _Num)
  446.             _Num = _Count;  // trim _Num to size
  447.  
  448.         if (this == &_Right)
  449.             erase((size_type)(_Roff + _Num)), erase(0, _Roff);  // substring
  450.         else if (_Grow(_Num))
  451.             {   // make room and assign new stuff
  452.             _Traits::copy(this->_Myptr(),
  453.                 _Right._Myptr() + _Roff, _Num);
  454.             _Eos(_Num);
  455.             }
  456.         return (*this);
  457.         }
  458.  
  459.     _Myt& assign(const _Elem *_Ptr, size_type _Count)
  460.         {   // assign [_Ptr, _Ptr + _Count)
  461.  #if _ITERATOR_DEBUG_LEVEL == 2
  462.         if (_Count != 0)
  463.             _DEBUG_POINTER(_Ptr);
  464.  #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
  465.  
  466.         if (_Inside(_Ptr))
  467.             return (assign(*this,
  468.                 _Ptr - this->_Myptr(), _Count));    // substring
  469.  
  470.         if (_Grow(_Count))
  471.             {   // make room and assign new stuff
  472.             _Traits::copy(this->_Myptr(), _Ptr, _Count);
  473.             _Eos(_Count);
  474.             }
  475.         return (*this);
  476.         }
  477.  
  478.     _Myt& assign(const _Elem *_Ptr)
  479.         {   // assign [_Ptr, <null>)
  480.         _DEBUG_POINTER(_Ptr);
  481.         return (assign(_Ptr, _Traits::length(_Ptr)));
  482.         }
  483.  
  484.     _Myt& assign(size_type _Count, _Elem _Ch)
  485.         {   // assign _Count * _Ch
  486.         if (_Count == npos)
  487.             _Xlen();    // result too long
  488.  
  489.         if (_Grow(_Count))
  490.             {   // make room and assign new stuff
  491.             _Chassign(0, _Count, _Ch);
  492.             _Eos(_Count);
  493.             }
  494.         return (*this);
  495.         }
  496.  
  497.     template<class _Iter>
  498.         typename enable_if<_Is_iterator<_Iter>::value,
  499.             _Myt&>::type
  500.         assign(_Iter _First, _Iter _Last)
  501.         {   // assign [_First, _Last), input iterators
  502.         return (replace(begin(), end(), _First, _Last));
  503.         }
  504.  
  505.     _Myt& assign(const_pointer _First, const_pointer _Last)
  506.         {   // assign [_First, _Last), const pointers
  507.         return (replace(begin(), end(), _First, _Last));
  508.         }
  509.  
  510.     _Myt& assign(const_iterator _First, const_iterator _Last)
  511.         {   // assign [_First, _Last), const_iterators
  512.         return (replace(begin(), end(), _First, _Last));
  513.         }
  514.  
  515.     _Myt& insert(size_type _Off, const _Myt& _Right)
  516.         {   // insert _Right at _Off
  517.         return (insert(_Off, _Right, 0, npos));
  518.         }
  519.  
  520.     _Myt& insert(size_type _Off,
  521.         const _Myt& _Right, size_type _Roff, size_type _Count)
  522.         {   // insert _Right [_Roff, _Roff + _Count) at _Off
  523.         if (this->_Mysize < _Off || _Right.size() < _Roff)
  524.             _Xran();    // _Off or _Roff off end
  525.         size_type _Num = _Right.size() - _Roff;
  526.         if (_Num < _Count)
  527.             _Count = _Num;  // trim _Count to size
  528.         if (npos - this->_Mysize <= _Count)
  529.             _Xlen();    // result too long
  530.  
  531.         if (0 < _Count && _Grow(_Num = this->_Mysize + _Count))
  532.             {   // make room and insert new stuff
  533.             _Traits::move(this->_Myptr() + _Off + _Count,
  534.                 this->_Myptr() + _Off,
  535.                 this->_Mysize - _Off);  // empty out hole
  536.             if (this == &_Right)
  537.                 _Traits::move(this->_Myptr() + _Off,
  538.                     this->_Myptr() + (_Off < _Roff ? _Roff + _Count : _Roff),
  539.                         _Count);    // substring
  540.             else
  541.                 _Traits::copy(this->_Myptr() + _Off,
  542.                     _Right._Myptr() + _Roff, _Count);   // fill hole
  543.             _Eos(_Num);
  544.             }
  545.         return (*this);
  546.         }
  547.  
  548.     _Myt& insert(size_type _Off,
  549.         const _Elem *_Ptr, size_type _Count)
  550.         {   // insert [_Ptr, _Ptr + _Count) at _Off
  551.  #if _ITERATOR_DEBUG_LEVEL == 2
  552.         if (_Count != 0)
  553.             _DEBUG_POINTER(_Ptr);
  554.  #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
  555.  
  556.         if (_Inside(_Ptr))
  557.             return (insert(_Off, *this,
  558.                 _Ptr - this->_Myptr(), _Count));    // substring
  559.         if (this->_Mysize < _Off)
  560.             _Xran();    // _Off off end
  561.         if (npos - this->_Mysize <= _Count)
  562.             _Xlen();    // result too long
  563.         size_type _Num;
  564.         if (0 < _Count && _Grow(_Num = this->_Mysize + _Count))
  565.             {   // make room and insert new stuff
  566.             _Traits::move(this->_Myptr() + _Off + _Count,
  567.                 this->_Myptr() + _Off,
  568.                 this->_Mysize - _Off);  // empty out hole
  569.             _Traits::copy(this->_Myptr() + _Off, _Ptr, _Count); // fill hole
  570.             _Eos(_Num);
  571.             }
  572.         return (*this);
  573.         }
  574.  
  575.     _Myt& insert(size_type _Off, const _Elem *_Ptr)
  576.         {   // insert [_Ptr, <null>) at _Off
  577.         _DEBUG_POINTER(_Ptr);
  578.         return (insert(_Off, _Ptr, _Traits::length(_Ptr)));
  579.         }
  580.  
  581.     _Myt& insert(size_type _Off,
  582.         size_type _Count, _Elem _Ch)
  583.         {   // insert _Count * _Ch at _Off
  584.         if (this->_Mysize < _Off)
  585.             _Xran();    // _Off off end
  586.         if (npos - this->_Mysize <= _Count)
  587.             _Xlen();    // result too long
  588.         size_type _Num;
  589.         if (0 < _Count && _Grow(_Num = this->_Mysize + _Count))
  590.             {   // make room and insert new stuff
  591.             _Traits::move(this->_Myptr() + _Off + _Count,
  592.                 this->_Myptr() + _Off,
  593.                 this->_Mysize - _Off);  // empty out hole
  594.             _Chassign(_Off, _Count, _Ch);   // fill hole
  595.             _Eos(_Num);
  596.             }
  597.         return (*this);
  598.         }
  599.  
  600.     iterator insert(const_iterator _Where)
  601.         {   // insert <null> at _Where
  602.         return (insert(_Where, _Elem()));
  603.         }
  604.  
  605.     iterator insert(const_iterator _Where, _Elem _Ch)
  606.         {   // insert _Ch at _Where
  607.         size_type _Off = _Pdif(_Where, begin());
  608.         insert(_Off, 1, _Ch);
  609.         return (begin() + _Off);
  610.         }
  611.  
  612.     iterator insert(const_iterator _Where, size_type _Count, _Elem _Ch)
  613.         {   // insert _Count * _Elem at _Where
  614.         size_type _Off = _Pdif(_Where, begin());
  615.         insert(_Off, _Count, _Ch);
  616.         return (begin() + _Off);
  617.         }
  618.  
  619.     template<class _Iter>
  620.         typename enable_if<_Is_iterator<_Iter>::value,
  621.             iterator>::type
  622.         insert(const_iterator _Where, _Iter _First, _Iter _Last)
  623.         {   // insert [_First, _Last) at _Where, input iterators
  624.         size_type _Off = _Pdif(_Where, begin());
  625.         replace(_Where, _Where, _First, _Last);
  626.         return (begin() + _Off);
  627.         }
  628.  
  629.     iterator insert(const_iterator _Where,
  630.         const_pointer _First, const_pointer _Last)
  631.         {   // insert [_First, _Last) at _Where, const pointers
  632.         size_type _Off = _Pdif(_Where, begin());
  633.         replace(_Where, _Where, _First, _Last);
  634.         return (begin() + _Off);
  635.         }
  636.  
  637.     iterator insert(const_iterator _Where,
  638.         const_iterator _First, const_iterator _Last)
  639.         {   // insert [_First, _Last) at _Where, const_iterators
  640.         size_type _Off = _Pdif(_Where, begin());
  641.         replace(_Where, _Where, _First, _Last);
  642.         return (begin() + _Off);
  643.         }
  644.  
  645.     _Myt& erase(size_type _Off = 0)
  646.         {   // erase elements [_Off, ...)
  647.         if (this->_Mysize < _Off)
  648.             _Xran();    // _Off off end
  649.         _Eos(_Off);
  650.         return (*this);
  651.         }
  652.  
  653.     _Myt& erase(size_type _Off, size_type _Count)
  654.         {   // erase elements [_Off, _Off + _Count)
  655.         if (this->_Mysize < _Off)
  656.             _Xran();    // _Off off end
  657.         if (this->_Mysize - _Off <= _Count)
  658.             _Eos(_Off); // erase elements [_Off, ...)
  659.         else if (0 < _Count)
  660.             {   // move elements down
  661.             value_type *_Ptr = this->_Myptr() + _Off;
  662.             size_type _Newsize = this->_Mysize - _Count;
  663.             _Traits::move(_Ptr, _Ptr + _Count, _Newsize - _Off);
  664.             _Eos(_Newsize);
  665.             }
  666.         return (*this);
  667.         }
  668.  
  669.     iterator erase(const_iterator _Where)
  670.         {   // erase element at _Where
  671.         size_type _Count = _Pdif(_Where, begin());
  672.         erase(_Count, 1);
  673.         return (_STRING_ITERATOR(this->_Myptr() + _Count));
  674.         }
  675.  
  676.     iterator erase(const_iterator _First, const_iterator _Last)
  677.         {   // erase substring [_First, _Last)
  678.         _DEBUG_RANGE(_First, _Last);
  679.         size_type _Count = _Pdif(_First, begin());
  680.         erase(_Count, _Pdif(_Last, _First));
  681.         return (_STRING_ITERATOR(this->_Myptr() + _Count));
  682.         }
  683.  
  684.     void clear() _NOEXCEPT
  685.         {   // erase all
  686.         _Eos(0);
  687.         }
  688.  
  689.     _Myt& replace(size_type _Off, size_type _N0, const _Myt& _Right)
  690.         {   // replace [_Off, _Off + _N0) with _Right
  691.         return (replace(_Off, _N0, _Right, 0, npos));
  692.         }
  693.  
  694.     _Myt& replace(size_type _Off,
  695.         size_type _N0, const _Myt& _Right, size_type _Roff, size_type _Count)
  696.         {   // replace [_Off, _Off + _N0) with _Right [_Roff, _Roff + _Count)
  697.         if (this->_Mysize < _Off || _Right.size() < _Roff)
  698.             _Xran();    // _Off or _Roff off end
  699.         if (this->_Mysize - _Off < _N0)
  700.             _N0 = this->_Mysize - _Off; // trim _N0 to size
  701.         size_type _Num = _Right.size() - _Roff;
  702.         if (_Num < _Count)
  703.             _Count = _Num;  // trim _Count to size
  704.         if (npos - _Count <= this->_Mysize - _N0)
  705.             _Xlen();    // result too long
  706.  
  707.         size_type _Nm = this->_Mysize - _N0 - _Off; // length of kept tail
  708.         size_type _Newsize = this->_Mysize + _Count - _N0;
  709.         if (this->_Mysize < _Newsize)
  710.             _Grow(_Newsize);
  711.  
  712.         if (this != &_Right)
  713.             {   // no overlap, just move down and copy in new stuff
  714.             _Traits::move(this->_Myptr() + _Off + _Count,
  715.                 this->_Myptr() + _Off + _N0, _Nm);  // empty hole
  716.             _Traits::copy(this->_Myptr() + _Off,
  717.                 _Right._Myptr() + _Roff, _Count);   // fill hole
  718.             }
  719.         else if (_Count <= _N0)
  720.             {   // hole doesn't get larger, just copy in substring
  721.             _Traits::move(this->_Myptr() + _Off,
  722.                 this->_Myptr() + _Roff, _Count);    // fill hole
  723.             _Traits::move(this->_Myptr() + _Off + _Count,
  724.                 this->_Myptr() + _Off + _N0, _Nm);  // move tail down
  725.             }
  726.         else if (_Roff <= _Off)
  727.             {   // hole gets larger, substring begins before hole
  728.             _Traits::move(this->_Myptr() + _Off + _Count,
  729.                 this->_Myptr() + _Off + _N0, _Nm);  // move tail down
  730.             _Traits::move(this->_Myptr() + _Off,
  731.                 this->_Myptr() + _Roff, _Count);    // fill hole
  732.             }
  733.         else if (_Off + _N0 <= _Roff)
  734.             {   // hole gets larger, substring begins after hole
  735.             _Traits::move(this->_Myptr() + _Off + _Count,
  736.                 this->_Myptr() + _Off + _N0, _Nm);  // move tail down
  737.             _Traits::move(this->_Myptr() + _Off,
  738.                 this->_Myptr() + (_Roff + _Count - _N0),
  739.                 _Count);    // fill hole
  740.             }
  741.         else
  742.             {   // hole gets larger, substring begins in hole
  743.             _Traits::move(this->_Myptr() + _Off,
  744.                 this->_Myptr() + _Roff, _N0);   // fill old hole
  745.             _Traits::move(this->_Myptr() + _Off + _Count,
  746.                 this->_Myptr() + _Off + _N0, _Nm);  // move tail down
  747.             _Traits::move(this->_Myptr() + _Off + _N0,
  748.                 this->_Myptr() + _Roff + _Count,
  749.                 _Count - _N0);  // fill rest of new hole
  750.             }
  751.  
  752.         _Eos(_Newsize);
  753.         return (*this);
  754.         }
  755.  
  756.     _Myt& replace(size_type _Off,
  757.         size_type _N0, const _Elem *_Ptr, size_type _Count)
  758.         {   // replace [_Off, _Off + _N0) with [_Ptr, _Ptr + _Count)
  759.  #if _ITERATOR_DEBUG_LEVEL == 2
  760.         if (_Count != 0)
  761.             _DEBUG_POINTER(_Ptr);
  762.  #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
  763.  
  764.         if (_Inside(_Ptr))
  765.             return (replace(_Off, _N0, *this,
  766.                 _Ptr - this->_Myptr(),
  767.                 _Count));   // substring, replace carefully
  768.         if (this->_Mysize < _Off)
  769.             _Xran();    // _Off off end
  770.         if (this->_Mysize - _Off < _N0)
  771.             _N0 = this->_Mysize - _Off; // trim _N0 to size
  772.         if (npos - _Count <= this->_Mysize - _N0)
  773.             _Xlen();    // result too long
  774.         size_type _Nm = this->_Mysize - _N0 - _Off;
  775.  
  776.         if (_Count < _N0)
  777.             _Traits::move(this->_Myptr() + _Off + _Count,
  778.                 this->_Myptr() + _Off + _N0,
  779.                 _Nm);   // smaller hole, move tail up
  780.         size_type _Num;
  781.         if ((0 < _Count || 0 < _N0)
  782.             && _Grow(_Num = this->_Mysize + _Count - _N0))
  783.             {   // make room and rearrange
  784.             if (_N0 < _Count)
  785.                 _Traits::move(this->_Myptr() + _Off + _Count,
  786.                     this->_Myptr() + _Off + _N0, _Nm);  // move tail down
  787.             _Traits::copy(this->_Myptr() + _Off, _Ptr, _Count); // fill hole
  788.             _Eos(_Num);
  789.             }
  790.         return (*this);
  791.         }
  792.  
  793.     _Myt& replace(size_type _Off, size_type _N0, const _Elem *_Ptr)
  794.         {   // replace [_Off, _Off + _N0) with [_Ptr, <null>)
  795.         _DEBUG_POINTER(_Ptr);
  796.         return (replace(_Off, _N0, _Ptr, _Traits::length(_Ptr)));
  797.         }
  798.  
  799.     _Myt& replace(size_type _Off,
  800.         size_type _N0, size_type _Count, _Elem _Ch)
  801.         {   // replace [_Off, _Off + _N0) with _Count * _Ch
  802.         if (this->_Mysize < _Off)
  803.             _Xran();    // _Off off end
  804.         if (this->_Mysize - _Off < _N0)
  805.             _N0 = this->_Mysize - _Off; // trim _N0 to size
  806.         if (npos - _Count <= this->_Mysize - _N0)
  807.             _Xlen();    // result too long
  808.         size_type _Nm = this->_Mysize - _N0 - _Off;
  809.  
  810.         if (_Count < _N0)
  811.             _Traits::move(this->_Myptr() + _Off + _Count,
  812.                 this->_Myptr() + _Off + _N0,
  813.                 _Nm);   // smaller hole, move tail up
  814.         size_type _Num;
  815.         if ((0 < _Count || 0 < _N0)
  816.             && _Grow(_Num = this->_Mysize + _Count - _N0))
  817.             {   // make room and rearrange
  818.             if (_N0 < _Count)
  819.                 _Traits::move(this->_Myptr() + _Off + _Count,
  820.                     this->_Myptr() + _Off + _N0, _Nm);  // move tail down
  821.             _Chassign(_Off, _Count, _Ch);   // fill hole
  822.             _Eos(_Num);
  823.             }
  824.         return (*this);
  825.         }
  826.  
  827.     _Myt& replace(const_iterator _First, const_iterator _Last,
  828.         const _Myt& _Right)
  829.         {   // replace [_First, _Last) with _Right
  830.         return (replace(
  831.             _Pdif(_First, begin()), _Pdif(_Last, _First), _Right));
  832.         }
  833.  
  834.     _Myt& replace(const_iterator _First, const_iterator _Last,
  835.         const _Elem *_Ptr, size_type _Count)
  836.         {   // replace [_First, _Last) with [_Ptr, _Ptr + _Count)
  837.         return (replace(
  838.             _Pdif(_First, begin()), _Pdif(_Last, _First), _Ptr, _Count));
  839.         }
  840.  
  841.     _Myt& replace(const_iterator _First, const_iterator _Last,
  842.         const _Elem *_Ptr)
  843.         {   // replace [_First, _Last) with [_Ptr, <null>)
  844.         return (replace(
  845.             _Pdif(_First, begin()), _Pdif(_Last, _First), _Ptr));
  846.         }
  847.  
  848.     _Myt& replace(const_iterator _First, const_iterator _Last,
  849.         size_type _Count, _Elem _Ch)
  850.         {   // replace [_First, _Last) with _Count * _Ch
  851.         return (replace(
  852.             _Pdif(_First, begin()), _Pdif(_Last, _First), _Count, _Ch));
  853.         }
  854.  
  855.     template<class _Iter>
  856.         typename enable_if<_Is_iterator<_Iter>::value,
  857.             _Myt&>::type
  858.         replace(const_iterator _First, const_iterator _Last,
  859.             _Iter _First2, _Iter _Last2)
  860.         {   // replace [_First, _Last) with [_First2, _Last2), input iterators
  861.         _Myt _Right(_First2, _Last2);
  862.         replace(_First, _Last, _Right);
  863.         return (*this);
  864.         }
  865.  
  866.     _Myt& replace(const_iterator _First, const_iterator _Last,
  867.         const_pointer _First2, const_pointer _Last2)
  868.         {   // replace [_First, _Last) with [_First2, _Last2), const pointers
  869.         if (_First2 == _Last2)
  870.             erase(_Pdif(_First, begin()), _Pdif(_Last, _First));
  871.         else
  872.             replace(_Pdif(_First, begin()), _Pdif(_Last, _First),
  873.                 &*_First2, _Last2 - _First2);
  874.         return (*this);
  875.         }
  876.  
  877.     _Myt& replace(const_iterator _First, const_iterator _Last,
  878.         pointer _First2, pointer _Last2)
  879.         {   // replace [_First, _Last) with [_First2, _Last2), const pointers
  880.         if (_First2 == _Last2)
  881.             erase(_Pdif(_First, begin()), _Pdif(_Last, _First));
  882.         else
  883.             replace(_Pdif(_First, begin()), _Pdif(_Last, _First),
  884.                 &*_First2, _Last2 - _First2);
  885.         return (*this);
  886.         }
  887.  
  888.     _Myt& replace(const_iterator _First, const_iterator _Last,
  889.         const_iterator _First2, const_iterator _Last2)
  890.         {   // replace [_First, _Last) with [_First2, _Last2), const_iterators
  891.         if (_First2 == _Last2)
  892.             erase(_Pdif(_First, begin()), _Pdif(_Last, _First));
  893.         else
  894.             replace(_Pdif(_First, begin()), _Pdif(_Last, _First),
  895.                 &*_First2, _Last2 - _First2);
  896.         return (*this);
  897.         }
  898.  
  899.     _Myt& replace(const_iterator _First, const_iterator _Last,
  900.         iterator _First2, iterator _Last2)
  901.         {   // replace [_First, _Last) with [_First2, _Last2), const_iterators
  902.         if (_First2 == _Last2)
  903.             erase(_Pdif(_First, begin()), _Pdif(_Last, _First));
  904.         else
  905.             replace(_Pdif(_First, begin()), _Pdif(_Last, _First),
  906.                 &*_First2, _Last2 - _First2);
  907.         return (*this);
  908.         }
  909.  
  910.     iterator begin() _NOEXCEPT
  911.         {   // return iterator for beginning of mutable sequence
  912.         return (_STRING_ITERATOR(this->_Myptr()));
  913.         }
  914.  
  915.     const_iterator begin() const _NOEXCEPT
  916.         {   // return iterator for beginning of nonmutable sequence
  917.         return (_STRING_CONST_ITERATOR(this->_Myptr()));
  918.         }
  919.  
  920.     iterator end() _NOEXCEPT
  921.         {   // return iterator for end of mutable sequence
  922.         return (_STRING_ITERATOR(this->_Myptr() + this->_Mysize));
  923.         }
  924.  
  925.     const_iterator end() const _NOEXCEPT
  926.         {   // return iterator for end of nonmutable sequence
  927.         return (_STRING_CONST_ITERATOR(this->_Myptr() + this->_Mysize));
  928.         }
  929.  
  930.     reverse_iterator rbegin() _NOEXCEPT
  931.         {   // return iterator for beginning of reversed mutable sequence
  932.         return (reverse_iterator(end()));
  933.         }
  934.  
  935.     const_reverse_iterator rbegin() const _NOEXCEPT
  936.         {   // return iterator for beginning of reversed nonmutable sequence
  937.         return (const_reverse_iterator(end()));
  938.         }
  939.  
  940.     reverse_iterator rend() _NOEXCEPT
  941.         {   // return iterator for end of reversed mutable sequence
  942.         return (reverse_iterator(begin()));
  943.         }
  944.  
  945.     const_reverse_iterator rend() const _NOEXCEPT
  946.         {   // return iterator for end of reversed nonmutable sequence
  947.         return (const_reverse_iterator(begin()));
  948.         }
  949.  
  950.     const_iterator cbegin() const _NOEXCEPT
  951.         {   // return iterator for beginning of nonmutable sequence
  952.         return (((const _Myt *)this)->begin());
  953.         }
  954.  
  955.     const_iterator cend() const _NOEXCEPT
  956.         {   // return iterator for end of nonmutable sequence
  957.         return (((const _Myt *)this)->end());
  958.         }
  959.  
  960.     const_reverse_iterator crbegin() const _NOEXCEPT
  961.         {   // return iterator for beginning of reversed nonmutable sequence
  962.         return (((const _Myt *)this)->rbegin());
  963.         }
  964.  
  965.     const_reverse_iterator crend() const _NOEXCEPT
  966.         {   // return iterator for end of reversed nonmutable sequence
  967.         return (((const _Myt *)this)->rend());
  968.         }
  969.  
  970.     void shrink_to_fit()
  971.         {   // reduce capacity
  972.         if ((size() | this->_ALLOC_MASK) < capacity())
  973.             {   // worth shrinking, do it
  974.             _Myt _Tmp(*this);
  975.             swap(_Tmp);
  976.             }
  977.         }
  978.  
  979.     reference at(size_type _Off)
  980.         {   // subscript mutable sequence with checking
  981.         if (this->_Mysize <= _Off)
  982.             _Xran();    // _Off off end
  983.         return (this->_Myptr()[_Off]);
  984.         }
  985.  
  986.     const_reference at(size_type _Off) const
  987.         {   // subscript nonmutable sequence with checking
  988.         if (this->_Mysize <= _Off)
  989.             _Xran();    // _Off off end
  990.         return (this->_Myptr()[_Off]);
  991.         }
  992.  
  993.     reference operator[](size_type _Off)
  994.         {   // subscript mutable sequence
  995.  #if _ITERATOR_DEBUG_LEVEL == 2
  996.         if (this->_Mysize < _Off)   // sic
  997.             _DEBUG_ERROR("string subscript out of range");
  998.  
  999.  #elif _ITERATOR_DEBUG_LEVEL == 1
  1000.         _SCL_SECURE_VALIDATE_RANGE(_Off <= this->_Mysize);  // sic
  1001.  #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
  1002.  
  1003.         return (this->_Myptr()[_Off]);
  1004.         }
  1005.  
  1006.     const_reference operator[](size_type _Off) const
  1007.         {   // subscript nonmutable sequence
  1008.  #if _ITERATOR_DEBUG_LEVEL == 2
  1009.         if (this->_Mysize < _Off)   // sic
  1010.             _DEBUG_ERROR("string subscript out of range");
  1011.  
  1012.  #elif _ITERATOR_DEBUG_LEVEL == 1
  1013.         _SCL_SECURE_VALIDATE_RANGE(_Off <= this->_Mysize);  // sic
  1014.  #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
  1015.  
  1016.         return (this->_Myptr()[_Off]);
  1017.         }
  1018.  
  1019.     void push_back(_Elem _Ch)
  1020.         {   // insert element at end
  1021.         insert(end(), _Ch);
  1022.         }
  1023.  
  1024.     void pop_back()
  1025.         {   // erase element at end
  1026.         erase(this->_Mysize - 1);   // throws if _Mysize == 0
  1027.         }
  1028.  
  1029.     reference front()
  1030.         {   // return first element of mutable sequence
  1031.         return (*begin());
  1032.         }
  1033.  
  1034.     const_reference front() const
  1035.         {   // return first element of nonmutable sequence
  1036.         return (*begin());
  1037.         }
  1038.  
  1039.     reference back()
  1040.         {   // return last element of mutable sequence
  1041.         return (*(end() - 1));
  1042.         }
  1043.  
  1044.     const_reference back() const
  1045.         {   // return last element of nonmutable sequence
  1046.         return (*(end() - 1));
  1047.         }
  1048.  
  1049.     const _Elem *c_str() const _NOEXCEPT
  1050.         {   // return pointer to null-terminated nonmutable array
  1051.         return (this->_Myptr());
  1052.         }
  1053.  
  1054.     const _Elem *data() const _NOEXCEPT
  1055.         {   // return pointer to nonmutable array
  1056.         return (c_str());
  1057.         }
  1058.  
  1059.     size_type length() const _NOEXCEPT
  1060.         {   // return length of sequence
  1061.         return (this->_Mysize);
  1062.         }
  1063.  
  1064.     size_type size() const _NOEXCEPT
  1065.         {   // return length of sequence
  1066.         return (this->_Mysize);
  1067.         }
  1068.  
  1069.     size_type max_size() const _NOEXCEPT
  1070.         {   // return maximum possible length of sequence
  1071.         size_type _Num = this->_Getal().max_size();
  1072.         return (_Num <= 1 ? 1 : _Num - 1);
  1073.         }
  1074.  
  1075.     void resize(size_type _Newsize)
  1076.         {   // determine new length, padding with null elements as needed
  1077.         resize(_Newsize, _Elem());
  1078.         }
  1079.  
  1080.     void resize(size_type _Newsize, _Elem _Ch)
  1081.         {   // determine new length, padding with _Ch elements as needed
  1082.         if (_Newsize <= this->_Mysize)
  1083.             _Eos(_Newsize);
  1084.         else
  1085.             append(_Newsize - this->_Mysize, _Ch);
  1086.         }
  1087.  
  1088.     size_type capacity() const _NOEXCEPT
  1089.         {   // return current length of allocated storage
  1090.         return (this->_Myres);
  1091.         }
  1092.  
  1093.     void reserve(size_type _Newcap = 0)
  1094.         {   // determine new minimum length of allocated storage
  1095.         if (this->_Mysize <= _Newcap && this->_Myres != _Newcap)
  1096.             {   // change reservation
  1097.             size_type _Size = this->_Mysize;
  1098.             if (_Grow(_Newcap, true))
  1099.                 _Eos(_Size);
  1100.             }
  1101.         }
  1102.  
  1103.     bool empty() const _NOEXCEPT
  1104.         {   // test if sequence is empty
  1105.         return (this->_Mysize == 0);
  1106.         }
  1107.  
  1108.     _SCL_INSECURE_DEPRECATE
  1109.  
  1110.     size_type copy(_Elem *_Ptr,
  1111.         size_type _Count, size_type _Off = 0) const
  1112.         {   // copy [_Off, _Off + _Count) to [_Ptr, _Ptr + _Count)
  1113.  #if _ITERATOR_DEBUG_LEVEL == 2
  1114.         if (_Count != 0)
  1115.             _DEBUG_POINTER(_Ptr);
  1116.  #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
  1117.  
  1118.         if (this->_Mysize < _Off)
  1119.             _Xran();    // _Off off end
  1120.         if (this->_Mysize - _Off < _Count)
  1121.             _Count = this->_Mysize - _Off;
  1122.         _Traits::copy(_Ptr, this->_Myptr() + _Off, _Count);
  1123.         return (_Count);
  1124.         }
  1125.  
  1126.     size_type _Copy_s(_Elem *_Dest, size_type _Dest_size,
  1127.         size_type _Count, size_type _Off = 0) const
  1128.         {   // copy [_Off, _Off + _Count) to [_Dest, _Dest + _Count)
  1129.  #if _ITERATOR_DEBUG_LEVEL == 2
  1130.         if (_Count != 0)
  1131.             _DEBUG_POINTER(_Dest);
  1132.  #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
  1133.  
  1134.         if (this->_Mysize < _Off)
  1135.             _Xran();    // _Off off end
  1136.         if (this->_Mysize - _Off < _Count)
  1137.             _Count = this->_Mysize - _Off;
  1138.         _Traits::_Copy_s(_Dest, _Dest_size, this->_Myptr() + _Off, _Count);
  1139.         return (_Count);
  1140.         }
  1141.  
  1142.     void _Swap_bx(_Myt& _Right)
  1143.         {   // exchange _Bx with _Right._Bx
  1144.         if (this->_BUF_SIZE <= this->_Myres)
  1145.             if (this->_BUF_SIZE <= _Right._Myres)
  1146.                 _Swap_adl(this->_Bx._Ptr, _Right._Bx._Ptr);
  1147.             else
  1148.                 {   // swap large with small
  1149.                 pointer _Ptr = this->_Bx._Ptr;
  1150.                 this->_Getal().destroy(&this->_Bx._Ptr);
  1151.                 _Traits::copy(this->_Bx._Buf,
  1152.                     _Right._Bx._Buf, _Right._Mysize + 1);
  1153.                 this->_Getal().construct(&_Right._Bx._Ptr, _Ptr);
  1154.                 }
  1155.         else
  1156.             if (_Right._Myres < this->_BUF_SIZE)
  1157.                 _STD swap(this->_Bx._Buf, _Right._Bx._Buf);
  1158.             else
  1159.                 {   // swap small with large
  1160.                 pointer _Ptr = _Right._Bx._Ptr;
  1161.                 this->_Getal().destroy(&_Right._Bx._Ptr);
  1162.                 _Traits::copy(_Right._Bx._Buf,
  1163.                     this->_Bx._Buf, this->_Mysize + 1);
  1164.                 this->_Getal().construct(&this->_Bx._Ptr, _Ptr);
  1165.                 }
  1166.         }
  1167.  
  1168.     void swap(_Myt& _Right)
  1169.         {   // exchange contents with _Right
  1170.         if (this == &_Right)
  1171.             ;   // same object, do nothing
  1172.         else if (this->_Getal() == _Right._Getal())
  1173.             {   // same allocator, swap control information
  1174.             this->_Swap_all(_Right);
  1175.             _Swap_bx(_Right);
  1176.             _STD swap(this->_Mysize, _Right._Mysize);
  1177.             _STD swap(this->_Myres, _Right._Myres);
  1178.             }
  1179.  
  1180.         else if (_Alty::propagate_on_container_swap::value)
  1181.             {   // swap allocators and control information
  1182.             this->_Swap_alloc(_Right);
  1183.             _Swap_bx(_Right);
  1184.             _STD swap(this->_Bx, _Right._Bx);   // pointer bitwise copyable?
  1185.             _STD swap(this->_Mysize, _Right._Mysize);
  1186.             _STD swap(this->_Myres, _Right._Myres);
  1187.             }
  1188.  
  1189.         else
  1190.             {   // different allocator, do multiple assigns
  1191.             _Myt _Tmp = *this;
  1192.  
  1193.             *this = _Right;
  1194.             _Right = _Tmp;
  1195.             }
  1196.         }
  1197.  
  1198.     size_type find(const _Myt& _Right, size_type _Off = 0) const _NOEXCEPT
  1199.         {   // look for _Right beginning at or after _Off
  1200.         return (find(_Right._Myptr(), _Off, _Right.size()));
  1201.         }
  1202.  
  1203.     size_type find(const _Elem *_Ptr,
  1204.         size_type _Off, size_type _Count) const
  1205.         {   // look for [_Ptr, _Ptr + _Count) beginning at or after _Off
  1206.  #if _ITERATOR_DEBUG_LEVEL == 2
  1207.         if (_Count != 0)
  1208.             _DEBUG_POINTER(_Ptr);
  1209.  #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
  1210.  
  1211.         if (_Count == 0 && _Off <= this->_Mysize)
  1212.             return (_Off);  // null string always matches (if inside string)
  1213.  
  1214.         size_type _Nm;
  1215.         if (_Off < this->_Mysize && _Count <= (_Nm = this->_Mysize - _Off))
  1216.             {   // room for match, look for it
  1217.             const _Elem *_Uptr, *_Vptr;
  1218.             for (_Nm -= _Count - 1, _Vptr = this->_Myptr() + _Off;
  1219.                 (_Uptr = _Traits::find(_Vptr, _Nm, *_Ptr)) != 0;
  1220.                 _Nm -= _Uptr - _Vptr + 1, _Vptr = _Uptr + 1)
  1221.                 if (_Traits::compare(_Uptr, _Ptr, _Count) == 0)
  1222.                     return (_Uptr - this->_Myptr());    // found a match
  1223.             }
  1224.  
  1225.         return (npos);  // no match
  1226.         }
  1227.  
  1228.     size_type find(const _Elem *_Ptr, size_type _Off = 0) const
  1229.         {   // look for [_Ptr, <null>) beginning at or after _Off
  1230.         _DEBUG_POINTER(_Ptr);
  1231.         return (find(_Ptr, _Off, _Traits::length(_Ptr)));
  1232.         }
  1233.  
  1234.     size_type find(_Elem _Ch, size_type _Off = 0) const
  1235.         {   // look for _Ch at or after _Off
  1236.         return (find((const _Elem *)&_Ch, _Off, 1));
  1237.         }
  1238.  
  1239.     size_type rfind(const _Myt& _Right, size_type _Off = npos) const _NOEXCEPT
  1240.         {   // look for _Right beginning before _Off
  1241.         return (rfind(_Right._Myptr(), _Off, _Right.size()));
  1242.         }
  1243.  
  1244.     size_type rfind(const _Elem *_Ptr,
  1245.         size_type _Off, size_type _Count) const
  1246.         {   // look for [_Ptr, _Ptr + _Count) beginning before _Off
  1247.  #if _ITERATOR_DEBUG_LEVEL == 2
  1248.         if (_Count != 0)
  1249.             _DEBUG_POINTER(_Ptr);
  1250.  #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
  1251.  
  1252.         if (_Count == 0)
  1253.             return (_Off < this->_Mysize ? _Off
  1254.                 : this->_Mysize);   // null always matches
  1255.         if (_Count <= this->_Mysize)
  1256.             {   // room for match, look for it
  1257.             const _Elem *_Uptr = this->_Myptr() +
  1258.                 (_Off < this->_Mysize - _Count ? _Off
  1259.                     : this->_Mysize - _Count);
  1260.             for (; ; --_Uptr)
  1261.                 if (_Traits::eq(*_Uptr, *_Ptr)
  1262.                     && _Traits::compare(_Uptr, _Ptr, _Count) == 0)
  1263.                     return (_Uptr - this->_Myptr());    // found a match
  1264.                 else if (_Uptr == this->_Myptr())
  1265.                     break;  // at beginning, no more chance for match
  1266.             }
  1267.  
  1268.         return (npos);  // no match
  1269.         }
  1270.  
  1271.     size_type rfind(const _Elem *_Ptr, size_type _Off = npos) const
  1272.         {   // look for [_Ptr, <null>) beginning before _Off
  1273.         _DEBUG_POINTER(_Ptr);
  1274.         return (rfind(_Ptr, _Off, _Traits::length(_Ptr)));
  1275.         }
  1276.  
  1277.     size_type rfind(_Elem _Ch, size_type _Off = npos) const
  1278.         {   // look for _Ch before _Off
  1279.         return (rfind((const _Elem *)&_Ch, _Off, 1));
  1280.         }
  1281.  
  1282.     size_type find_first_of(const _Myt& _Right,
  1283.         size_type _Off = 0) const _NOEXCEPT
  1284.         {   // look for one of _Right at or after _Off
  1285.         return (find_first_of(_Right._Myptr(), _Off, _Right.size()));
  1286.         }
  1287.  
  1288.     size_type find_first_of(const _Elem *_Ptr,
  1289.         size_type _Off, size_type _Count) const
  1290.         {   // look for one of [_Ptr, _Ptr + _Count) at or after _Off
  1291.  #if _ITERATOR_DEBUG_LEVEL == 2
  1292.         if (_Count != 0)
  1293.             _DEBUG_POINTER(_Ptr);
  1294.  #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
  1295.  
  1296.         if (0 < _Count && _Off < this->_Mysize)
  1297.             {   // room for match, look for it
  1298.             const _Elem *const _Vptr = this->_Myptr() + this->_Mysize;
  1299.             for (const _Elem *_Uptr = this->_Myptr() + _Off;
  1300.                 _Uptr < _Vptr; ++_Uptr)
  1301.                 if (_Traits::find(_Ptr, _Count, *_Uptr) != 0)
  1302.                     return (_Uptr - this->_Myptr());    // found a match
  1303.             }
  1304.  
  1305.         return (npos);  // no match
  1306.         }
  1307.  
  1308.     size_type find_first_of(const _Elem *_Ptr,
  1309.         size_type _Off = 0) const
  1310.         {   // look for one of [_Ptr, <null>) at or after _Off
  1311.         _DEBUG_POINTER(_Ptr);
  1312.         return (find_first_of(_Ptr, _Off, _Traits::length(_Ptr)));
  1313.         }
  1314.  
  1315.     size_type find_first_of(_Elem _Ch,
  1316.         size_type _Off = 0) const
  1317.         {   // look for _Ch at or after _Off
  1318.         return (find((const _Elem *)&_Ch, _Off, 1));
  1319.         }
  1320.  
  1321.     size_type find_last_of(const _Myt& _Right,
  1322.         size_type _Off = npos) const _NOEXCEPT
  1323.         {   // look for one of _Right before _Off
  1324.         return (find_last_of(_Right._Myptr(), _Off, _Right.size()));
  1325.         }
  1326.  
  1327.     size_type find_last_of(const _Elem *_Ptr,
  1328.         size_type _Off, size_type _Count) const
  1329.         {   // look for one of [_Ptr, _Ptr + _Count) before _Off
  1330.  #if _ITERATOR_DEBUG_LEVEL == 2
  1331.         if (_Count != 0)
  1332.             _DEBUG_POINTER(_Ptr);
  1333.  #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
  1334.  
  1335.         if (0 < _Count && 0 < this->_Mysize)
  1336.             {   // worth searching, do it
  1337.             const _Elem *_Uptr = this->_Myptr()
  1338.                 + (_Off < this->_Mysize ? _Off : this->_Mysize - 1);
  1339.             for (; ; --_Uptr)
  1340.                 if (_Traits::find(_Ptr, _Count, *_Uptr) != 0)
  1341.                     return (_Uptr - this->_Myptr());    // found a match
  1342.                 else if (_Uptr == this->_Myptr())
  1343.                     break;  // at beginning, no more chance for match
  1344.             }
  1345.  
  1346.         return (npos);  // no match
  1347.         }
  1348.  
  1349.     size_type find_last_of(const _Elem *_Ptr,
  1350.         size_type _Off = npos) const
  1351.         {   // look for one of [_Ptr, <null>) before _Off
  1352.         _DEBUG_POINTER(_Ptr);
  1353.         return (find_last_of(_Ptr, _Off, _Traits::length(_Ptr)));
  1354.         }
  1355.  
  1356.     size_type find_last_of(_Elem _Ch,
  1357.         size_type _Off = npos) const
  1358.         {   // look for _Ch before _Off
  1359.         return (rfind((const _Elem *)&_Ch, _Off, 1));
  1360.         }
  1361.  
  1362.     size_type find_first_not_of(const _Myt& _Right,
  1363.         size_type _Off = 0) const _NOEXCEPT
  1364.         {   // look for none of _Right at or after _Off
  1365.         return (find_first_not_of(_Right._Myptr(), _Off,
  1366.             _Right.size()));
  1367.         }
  1368.  
  1369.     size_type find_first_not_of(const _Elem *_Ptr,
  1370.         size_type _Off, size_type _Count) const
  1371.         {   // look for none of [_Ptr, _Ptr + _Count) at or after _Off
  1372.  #if _ITERATOR_DEBUG_LEVEL == 2
  1373.         if (_Count != 0)
  1374.             _DEBUG_POINTER(_Ptr);
  1375.  #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
  1376.  
  1377.         if (_Off < this->_Mysize)
  1378.             {   // room for match, look for it
  1379.             const _Elem *const _Vptr = this->_Myptr() + this->_Mysize;
  1380.             for (const _Elem *_Uptr = this->_Myptr() + _Off;
  1381.                 _Uptr < _Vptr; ++_Uptr)
  1382.                 if (_Traits::find(_Ptr, _Count, *_Uptr) == 0)
  1383.                     return (_Uptr - this->_Myptr());
  1384.             }
  1385.         return (npos);
  1386.         }
  1387.  
  1388.     size_type find_first_not_of(const _Elem *_Ptr,
  1389.         size_type _Off = 0) const
  1390.         {   // look for one of [_Ptr, <null>) at or after _Off
  1391.         _DEBUG_POINTER(_Ptr);
  1392.         return (find_first_not_of(_Ptr, _Off, _Traits::length(_Ptr)));
  1393.         }
  1394.  
  1395.     size_type find_first_not_of(_Elem _Ch,
  1396.         size_type _Off = 0) const
  1397.         {   // look for non _Ch at or after _Off
  1398.         return (find_first_not_of((const _Elem *)&_Ch, _Off, 1));
  1399.         }
  1400.  
  1401.     size_type find_last_not_of(const _Myt& _Right,
  1402.         size_type _Off = npos) const _NOEXCEPT
  1403.         {   // look for none of _Right before _Off
  1404.         return (find_last_not_of(_Right._Myptr(), _Off, _Right.size()));
  1405.         }
  1406.  
  1407.     size_type find_last_not_of(const _Elem *_Ptr,
  1408.         size_type _Off, size_type _Count) const
  1409.         {   // look for none of [_Ptr, _Ptr + _Count) before _Off
  1410.  #if _ITERATOR_DEBUG_LEVEL == 2
  1411.         if (_Count != 0)
  1412.             _DEBUG_POINTER(_Ptr);
  1413.  #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
  1414.  
  1415.         if (0 < this->_Mysize)
  1416.             {   // worth searching, do it
  1417.             const _Elem *_Uptr = this->_Myptr()
  1418.                 + (_Off < this->_Mysize ? _Off : this->_Mysize - 1);
  1419.             for (; ; --_Uptr)
  1420.                 if (_Traits::find(_Ptr, _Count, *_Uptr) == 0)
  1421.                     return (_Uptr - this->_Myptr());
  1422.                 else if (_Uptr == this->_Myptr())
  1423.                     break;
  1424.             }
  1425.         return (npos);
  1426.         }
  1427.  
  1428.     size_type find_last_not_of(const _Elem *_Ptr,
  1429.         size_type _Off = npos) const
  1430.         {   // look for none of [_Ptr, <null>) before _Off
  1431.         _DEBUG_POINTER(_Ptr);
  1432.         return (find_last_not_of(_Ptr, _Off, _Traits::length(_Ptr)));
  1433.         }
  1434.  
  1435.     size_type find_last_not_of(_Elem _Ch,
  1436.         size_type _Off = npos) const
  1437.         {   // look for non _Ch before _Off
  1438.         return (find_last_not_of((const _Elem *)&_Ch, _Off, 1));
  1439.         }
  1440.  
  1441.     _Myt substr(size_type _Off = 0, size_type _Count = npos) const
  1442.         {   // return [_Off, _Off + _Count) as new string
  1443.         return (_Myt(*this, _Off, _Count, get_allocator()));
  1444.         }
  1445.  
  1446.     int compare(const _Myt& _Right) const _NOEXCEPT
  1447.         {   // compare [0, _Mysize) with _Right
  1448.         return (compare(0, this->_Mysize, _Right._Myptr(), _Right.size()));
  1449.         }
  1450.  
  1451.     int compare(size_type _Off, size_type _N0,
  1452.         const _Myt& _Right) const
  1453.         {   // compare [_Off, _Off + _N0) with _Right
  1454.         return (compare(_Off, _N0, _Right, 0, npos));
  1455.         }
  1456.  
  1457.     int compare(size_type _Off,
  1458.         size_type _N0, const _Myt& _Right,
  1459.         size_type _Roff, size_type _Count) const
  1460.         {   // compare [_Off, _Off + _N0) with _Right [_Roff, _Roff + _Count)
  1461.         if (_Right.size() < _Roff)
  1462.             _Xran();    // _Off off end
  1463.         if (_Right._Mysize - _Roff < _Count)
  1464.             _Count = _Right._Mysize - _Roff;    // trim _Count to size
  1465.         return (compare(_Off, _N0, _Right._Myptr() + _Roff, _Count));
  1466.         }
  1467.  
  1468.     int compare(const _Elem *_Ptr) const
  1469.         {   // compare [0, _Mysize) with [_Ptr, <null>)
  1470.         _DEBUG_POINTER(_Ptr);
  1471.         return (compare(0, this->_Mysize, _Ptr, _Traits::length(_Ptr)));
  1472.         }
  1473.  
  1474.     int compare(size_type _Off, size_type _N0, const _Elem *_Ptr) const
  1475.         {   // compare [_Off, _Off + _N0) with [_Ptr, <null>)
  1476.         _DEBUG_POINTER(_Ptr);
  1477.         return (compare(_Off, _N0, _Ptr, _Traits::length(_Ptr)));
  1478.         }
  1479.  
  1480.     int compare(size_type _Off,
  1481.         size_type _N0, const _Elem *_Ptr, size_type _Count) const
  1482.         {   // compare [_Off, _Off + _N0) with [_Ptr, _Ptr + _Count)
  1483.  #if _ITERATOR_DEBUG_LEVEL == 2
  1484.         if (_Count != 0)
  1485.             _DEBUG_POINTER(_Ptr);
  1486.  #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
  1487.  
  1488.         if (this->_Mysize < _Off)
  1489.             _Xran();    // _Off off end
  1490.         if (this->_Mysize - _Off < _N0)
  1491.             _N0 = this->_Mysize - _Off; // trim _N0 to size
  1492.  
  1493.         size_type _Ans = _Traits::compare(this->_Myptr() + _Off, _Ptr,
  1494.             _N0 < _Count ? _N0 : _Count);
  1495.         return (_Ans != 0 ? (int)_Ans : _N0 < _Count ? -1
  1496.             : _N0 == _Count ? 0 : +1);
  1497.         }
  1498.  
  1499.     allocator_type get_allocator() const _NOEXCEPT
  1500.         {   // return allocator object for values
  1501.         return (this->_Getal());
  1502.         }
  1503.  
  1504.     void _Chassign(size_type _Off, size_type _Count, _Elem _Ch)
  1505.         {   // assign _Count copies of _Ch beginning at _Off
  1506.         if (_Count == 1)
  1507.             _Traits::assign(*(this->_Myptr() + _Off), _Ch);
  1508.         else
  1509.             _Traits::assign(this->_Myptr() + _Off, _Count, _Ch);
  1510.         }
  1511.  
  1512.     void _Copy(size_type _Newsize, size_type _Oldlen)
  1513.         {   // copy _Oldlen elements to newly allocated buffer
  1514.         size_type _Newres = _Newsize | this->_ALLOC_MASK;
  1515.         if (max_size() < _Newres)
  1516.             _Newres = _Newsize; // undo roundup if too big
  1517.         else if (this->_Myres / 2 <= _Newres / 3)
  1518.             ;
  1519.         else if (this->_Myres <= max_size() - this->_Myres / 2)
  1520.             _Newres = this->_Myres
  1521.                 + this->_Myres / 2; // grow exponentially if possible
  1522.         else
  1523.             _Newres = max_size();   // settle for max_size()
  1524.  
  1525.         _Elem *_Ptr;
  1526.         _TRY_BEGIN
  1527.             _Ptr = this->_Getal().allocate(_Newres + 1);
  1528.         _CATCH_ALL
  1529.             _Newres = _Newsize; // allocation failed, undo roundup and retry
  1530.             _TRY_BEGIN
  1531.                 _Ptr = this->_Getal().allocate(_Newres + 1);
  1532.             _CATCH_ALL
  1533.             _Tidy(true);    // failed again, discard storage and reraise
  1534.             _RERAISE;
  1535.             _CATCH_END
  1536.         _CATCH_END
  1537.  
  1538.         if (0 < _Oldlen)
  1539.             _Traits::copy(_Ptr, this->_Myptr(),
  1540.                 _Oldlen);   // copy existing elements
  1541.         _Tidy(true);
  1542.         this->_Getal().construct(&this->_Bx._Ptr, _Ptr);
  1543.         this->_Myres = _Newres;
  1544.         _Eos(_Oldlen);
  1545.         }
  1546.  
  1547.     void _Eos(size_type _Newsize)
  1548.         {   // set new length and null terminator
  1549.         _Traits::assign(this->_Myptr()[this->_Mysize = _Newsize], _Elem());
  1550.         }
  1551.  
  1552.     bool _Grow(size_type _Newsize,
  1553.         bool _Trim = false)
  1554.         {   // ensure buffer is big enough, trim to size if _Trim is true
  1555.         if (max_size() < _Newsize)
  1556.             _Xlen();    // result too long
  1557.         if (this->_Myres < _Newsize)
  1558.             _Copy(_Newsize, this->_Mysize); // reallocate to grow
  1559.         else if (_Trim && _Newsize < this->_BUF_SIZE)
  1560.             _Tidy(true, // copy and deallocate if trimming to small string
  1561.                 _Newsize < this->_Mysize ? _Newsize : this->_Mysize);
  1562.         else if (_Newsize == 0)
  1563.             _Eos(0);    // new size is zero, just null terminate
  1564.         return (0 < _Newsize);  // return true only if more work to do
  1565.         }
  1566.  
  1567.     bool _Inside(const _Elem *_Ptr)
  1568.         {   // test if _Ptr points inside string
  1569.         if (_Ptr == 0 || _Ptr < this->_Myptr()
  1570.             || this->_Myptr() + this->_Mysize <= _Ptr)
  1571.             return (false); // don't ask
  1572.         else
  1573.             return (true);
  1574.         }
  1575.  
  1576.     static size_type _Pdif(const_iterator _P2,
  1577.         const_iterator _P1)
  1578.         {   // compute safe iterator difference
  1579.         return (_STRING_ITER_BASE(_P2) == 0 ? 0 : _P2 - _P1);
  1580.         }
  1581.  
  1582.     void _Tidy(bool _Built = false,
  1583.         size_type _Newsize = 0)
  1584.         {   // initialize buffer, deallocating any storage
  1585.         if (!_Built)
  1586.             ;
  1587.         else if (this->_BUF_SIZE <= this->_Myres)
  1588.             {   // copy any leftovers to small buffer and deallocate
  1589.             pointer _Ptr = this->_Bx._Ptr;
  1590.             this->_Getal().destroy(&this->_Bx._Ptr);
  1591.             if (0 < _Newsize)
  1592.                 _Traits::copy(this->_Bx._Buf,
  1593.                     _STD addressof(*_Ptr), _Newsize);
  1594.             this->_Getal().deallocate(_Ptr, this->_Myres + 1);
  1595.             }
  1596.         this->_Myres = this->_BUF_SIZE - 1;
  1597.         _Eos(_Newsize);
  1598.         }
  1599.  
  1600.     __declspec(noreturn) void _Xlen() const
  1601.         {   // report a length_error
  1602.         _Xlength_error("string too long");
  1603.         }
  1604.  
  1605.     __declspec(noreturn) void _Xran() const
  1606.         {   // report an out_of_range error
  1607.         _Xout_of_range("invalid string position");
  1608.         }
  1609.     };
Advertisement
Add Comment
Please, Sign In to add comment