Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- template<class _Elem,
- class _Traits,
- class _Alloc>
- class basic_string
- : public _String_alloc<!is_empty<_Alloc>::value,
- _String_base_types<_Elem, _Alloc> >
- { // null-terminated transparent array of elements
- public:
- typedef basic_string<_Elem, _Traits, _Alloc> _Myt;
- typedef _String_alloc<!is_empty<_Alloc>::value,
- _String_base_types<_Elem, _Alloc> > _Mybase;
- typedef _Traits traits_type;
- typedef _Alloc allocator_type;
- typedef typename _Mybase::_Alty _Alty;
- typedef typename _Mybase::value_type value_type;
- typedef typename _Mybase::size_type size_type;
- typedef typename _Mybase::difference_type difference_type;
- typedef typename _Mybase::pointer pointer;
- typedef typename _Mybase::const_pointer const_pointer;
- typedef typename _Mybase::reference reference;
- typedef typename _Mybase::const_reference const_reference;
- typedef typename _Mybase::iterator iterator;
- typedef typename _Mybase::const_iterator const_iterator;
- typedef _STD reverse_iterator<iterator> reverse_iterator;
- typedef _STD reverse_iterator<const_iterator> const_reverse_iterator;
- basic_string(const _Myt& _Right)
- : _Mybase(_Right._Getal().select_on_container_copy_construction())
- { // construct by copying _Right
- _Tidy();
- assign(_Right, 0, npos);
- }
- basic_string(const _Myt& _Right, const _Alloc& _Al)
- : _Mybase(_Al)
- { // construct by copying with allocator
- _Tidy();
- assign(_Right, 0, npos);
- }
- basic_string()
- : _Mybase()
- { // construct empty string
- _Tidy();
- }
- explicit basic_string(const _Alloc& _Al)
- : _Mybase(_Al)
- { // construct empty string with allocator
- _Tidy();
- }
- basic_string(const _Myt& _Right, size_type _Roff,
- size_type _Count = npos)
- : _Mybase(_Right._Getal())
- { // construct from _Right [_Roff, _Roff + _Count)
- _Tidy();
- assign(_Right, _Roff, _Count);
- }
- basic_string(const _Myt& _Right, size_type _Roff, size_type _Count,
- const _Alloc& _Al)
- : _Mybase(_Al)
- { // construct from _Right [_Roff, _Roff + _Count) with allocator
- _Tidy();
- assign(_Right, _Roff, _Count);
- }
- basic_string(const _Elem *_Ptr, size_type _Count)
- : _Mybase()
- { // construct from [_Ptr, _Ptr + _Count)
- _Tidy();
- assign(_Ptr, _Count);
- }
- basic_string(const _Elem *_Ptr, size_type _Count, const _Alloc& _Al)
- : _Mybase(_Al)
- { // construct from [_Ptr, _Ptr + _Count) with allocator
- _Tidy();
- assign(_Ptr, _Count);
- }
- basic_string(const _Elem *_Ptr)
- : _Mybase()
- { // construct from [_Ptr, <null>)
- _Tidy();
- assign(_Ptr);
- }
- basic_string(const _Elem *_Ptr, const _Alloc& _Al)
- : _Mybase(_Al)
- { // construct from [_Ptr, <null>) with allocator
- _Tidy();
- assign(_Ptr);
- }
- basic_string(size_type _Count, _Elem _Ch)
- : _Mybase()
- { // construct from _Count * _Ch
- _Tidy();
- assign(_Count, _Ch);
- }
- basic_string(size_type _Count, _Elem _Ch, const _Alloc& _Al)
- : _Mybase(_Al)
- { // construct from _Count * _Ch with allocator
- _Tidy();
- assign(_Count, _Ch);
- }
- template<class _Iter,
- class = typename enable_if<_Is_iterator<_Iter>::value,
- void>::type>
- basic_string(_Iter _First, _Iter _Last)
- : _Mybase()
- { // construct from [_First, _Last)
- _Tidy();
- _Construct(_First, _Last, _Iter_cat(_First));
- }
- template<class _Iter,
- class = typename enable_if<_Is_iterator<_Iter>::value,
- void>::type>
- basic_string(_Iter _First, _Iter _Last, const _Alloc& _Al)
- : _Mybase(_Al)
- { // construct from [_First, _Last) with allocator
- _Tidy();
- _Construct(_First, _Last, _Iter_cat(_First));
- }
- template<class _Iter>
- void _Construct(_Iter _First,
- _Iter _Last, input_iterator_tag)
- { // initialize from [_First, _Last), input iterators
- _TRY_BEGIN
- for (; _First != _Last; ++_First)
- append((size_type)1, (_Elem)*_First);
- _CATCH_ALL
- _Tidy(true);
- _RERAISE;
- _CATCH_END
- }
- template<class _Iter>
- void _Construct(_Iter _First,
- _Iter _Last, forward_iterator_tag)
- { // initialize from [_First, _Last), forward iterators
- _DEBUG_RANGE(_First, _Last);
- size_type _Count = 0;
- _Distance(_First, _Last, _Count);
- reserve(_Count);
- _TRY_BEGIN
- for (; _First != _Last; ++_First)
- append((size_type)1, (_Elem)*_First);
- _CATCH_ALL
- _Tidy(true);
- _RERAISE;
- _CATCH_END
- }
- basic_string(const_pointer _First, const_pointer _Last)
- : _Mybase()
- { // construct from [_First, _Last), const pointers
- _DEBUG_RANGE(_First, _Last);
- _Tidy();
- if (_First != _Last)
- assign(&*_First, _Last - _First);
- }
- basic_string(const_pointer _First, const_pointer _Last,
- const _Alloc& _Al)
- : _Mybase(_Al)
- { // construct from [_First, _Last), const pointers
- _DEBUG_RANGE(_First, _Last);
- _Tidy();
- if (_First != _Last)
- assign(&*_First, _Last - _First);
- }
- basic_string(const_iterator _First, const_iterator _Last)
- : _Mybase()
- { // construct from [_First, _Last), const_iterators
- _DEBUG_RANGE(_First, _Last);
- _Tidy();
- if (_First != _Last)
- assign(&*_First, _Last - _First);
- }
- basic_string(_Myt&& _Right) _NOEXCEPT
- : _Mybase(_Right._Getal())
- { // construct by moving _Right
- _Tidy();
- _Assign_rv(_STD forward<_Myt>(_Right));
- }
- basic_string(_Myt&& _Right, const _Alloc& _Al)
- : _Mybase(_Al)
- { // construct by moving _Right, allocator
- if (this->_Getal() != _Right._Getal())
- assign(_Right.begin(), _Right.end());
- else
- _Assign_rv(_STD forward<_Myt>(_Right));
- }
- _Myt& operator=(_Myt&& _Right) _NOEXCEPT
- { // assign by moving _Right
- if (this != &_Right)
- { // different, assign it
- _Tidy(true);
- if (_Alty::propagate_on_container_move_assignment::value
- && this->_Getal() != _Right._Getal())
- this->_Change_alloc(_Right._Getal());
- if (this->_Getal() != _Right._Getal())
- assign(_Right.begin(), _Right.end());
- else
- _Assign_rv(_STD forward<_Myt>(_Right));
- }
- return (*this);
- }
- _Myt& assign(_Myt&& _Right) _NOEXCEPT
- { // assign by moving _Right
- if (this == &_Right)
- ;
- else if (get_allocator() != _Right.get_allocator()
- && this->_BUF_SIZE <= _Right._Myres)
- *this = _Right;
- else
- { // not same, clear this and steal from _Right
- _Tidy(true);
- _Assign_rv(_STD forward<_Myt>(_Right));
- }
- return (*this);
- }
- void _Assign_rv(_Myt&& _Right)
- { // assign by moving _Right
- if (_Right._Myres < this->_BUF_SIZE)
- _Traits::move(this->_Bx._Buf, _Right._Bx._Buf,
- _Right._Mysize + 1);
- else
- { // copy pointer
- this->_Getal().construct(&this->_Bx._Ptr, _Right._Bx._Ptr);
- _Right._Bx._Ptr = pointer();
- }
- this->_Mysize = _Right._Mysize;
- this->_Myres = _Right._Myres;
- _Right._Tidy();
- }
- basic_string(_XSTD initializer_list<_Elem> _Ilist,
- const _Alloc& _Al = allocator_type())
- : _Mybase(_Al)
- { // construct from initializer_list
- _Tidy();
- assign(_Ilist.begin(), _Ilist.end());
- }
- _Myt& operator=(_XSTD initializer_list<_Elem> _Ilist)
- { // assign initializer_list
- return (assign(_Ilist.begin(), _Ilist.end()));
- }
- _Myt& operator+=(_XSTD initializer_list<_Elem> _Ilist)
- { // append initializer_list
- return (append(_Ilist.begin(), _Ilist.end()));
- }
- _Myt& assign(_XSTD initializer_list<_Elem> _Ilist)
- { // assign initializer_list
- return (assign(_Ilist.begin(), _Ilist.end()));
- }
- _Myt& append(_XSTD initializer_list<_Elem> _Ilist)
- { // append initializer_list
- return (append(_Ilist.begin(), _Ilist.end()));
- }
- iterator insert(const_iterator _Where,
- _XSTD initializer_list<_Elem> _Ilist)
- { // insert initializer_list
- return (insert(_Where, _Ilist.begin(), _Ilist.end()));
- }
- _Myt& replace(const_iterator _First, const_iterator _Last,
- _XSTD initializer_list<_Elem> _Ilist)
- { // replace with initializer_list
- return (replace(_First, _Last, _Ilist.begin(), _Ilist.end()));
- }
- ~basic_string() _NOEXCEPT
- { // destroy the string
- _Tidy(true);
- }
- _PGLOBAL static const size_type npos; // bad/missing length/position
- _Myt& operator=(const _Myt& _Right)
- { // assign _Right
- if (this != &_Right)
- { // different, assign it
- if (this->_Getal() != _Right._Getal()
- && _Alty::propagate_on_container_copy_assignment::value)
- { // change allocator before copying
- _Tidy(true);
- this->_Change_alloc(_Right._Getal());
- }
- assign(_Right);
- }
- return (*this);
- }
- _Myt& operator=(const _Elem *_Ptr)
- { // assign [_Ptr, <null>)
- return (assign(_Ptr));
- }
- _Myt& operator=(_Elem _Ch)
- { // assign 1 * _Ch
- return (assign(1, _Ch));
- }
- _Myt& operator+=(const _Myt& _Right)
- { // append _Right
- return (append(_Right));
- }
- _Myt& operator+=(const _Elem *_Ptr)
- { // append [_Ptr, <null>)
- return (append(_Ptr));
- }
- _Myt& operator+=(_Elem _Ch)
- { // append 1 * _Ch
- return (append((size_type)1, _Ch));
- }
- _Myt& append(const _Myt& _Right)
- { // append _Right
- return (append(_Right, 0, npos));
- }
- _Myt& append(const _Myt& _Right,
- size_type _Roff, size_type _Count)
- { // append _Right [_Roff, _Roff + _Count)
- if (_Right.size() < _Roff)
- _Xran(); // _Roff off end
- size_type _Num = _Right.size() - _Roff;
- if (_Num < _Count)
- _Count = _Num; // trim _Count to size
- if (npos - this->_Mysize <= _Count)
- _Xlen(); // result too long
- if (0 < _Count && _Grow(_Num = this->_Mysize + _Count))
- { // make room and append new stuff
- _Traits::copy(this->_Myptr() + this->_Mysize,
- _Right._Myptr() + _Roff, _Count);
- _Eos(_Num);
- }
- return (*this);
- }
- _Myt& append(const _Elem *_Ptr, size_type _Count)
- { // append [_Ptr, _Ptr + _Count)
- #if _ITERATOR_DEBUG_LEVEL == 2
- if (_Count != 0)
- _DEBUG_POINTER(_Ptr);
- #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
- if (_Inside(_Ptr))
- return (append(*this,
- _Ptr - this->_Myptr(), _Count)); // substring
- if (npos - this->_Mysize <= _Count)
- _Xlen(); // result too long
- size_type _Num;
- if (0 < _Count && _Grow(_Num = this->_Mysize + _Count))
- { // make room and append new stuff
- _Traits::copy(this->_Myptr() + this->_Mysize, _Ptr, _Count);
- _Eos(_Num);
- }
- return (*this);
- }
- _Myt& append(const _Elem *_Ptr)
- { // append [_Ptr, <null>)
- _DEBUG_POINTER(_Ptr);
- return (append(_Ptr, _Traits::length(_Ptr)));
- }
- _Myt& append(size_type _Count, _Elem _Ch)
- { // append _Count * _Ch
- if (npos - this->_Mysize <= _Count)
- _Xlen(); // result too long
- size_type _Num;
- if (0 < _Count && _Grow(_Num = this->_Mysize + _Count))
- { // make room and append new stuff using assign
- _Chassign(this->_Mysize, _Count, _Ch);
- _Eos(_Num);
- }
- return (*this);
- }
- template<class _Iter>
- typename enable_if<_Is_iterator<_Iter>::value,
- _Myt&>::type
- append(_Iter _First, _Iter _Last)
- { // append [_First, _Last), input iterators
- return (replace(end(), end(), _First, _Last));
- }
- _Myt& append(const_pointer _First, const_pointer _Last)
- { // append [_First, _Last), const pointers
- return (replace(end(), end(), _First, _Last));
- }
- _Myt& append(const_iterator _First, const_iterator _Last)
- { // append [_First, _Last), const_iterators
- return (replace(end(), end(), _First, _Last));
- }
- _Myt& assign(const _Myt& _Right)
- { // assign _Right
- return (assign(_Right, 0, npos));
- }
- _Myt& assign(const _Myt& _Right,
- size_type _Roff, size_type _Count)
- { // assign _Right [_Roff, _Roff + _Count)
- if (_Right.size() < _Roff)
- _Xran(); // _Roff off end
- size_type _Num = _Right.size() - _Roff;
- if (_Count < _Num)
- _Num = _Count; // trim _Num to size
- if (this == &_Right)
- erase((size_type)(_Roff + _Num)), erase(0, _Roff); // substring
- else if (_Grow(_Num))
- { // make room and assign new stuff
- _Traits::copy(this->_Myptr(),
- _Right._Myptr() + _Roff, _Num);
- _Eos(_Num);
- }
- return (*this);
- }
- _Myt& assign(const _Elem *_Ptr, size_type _Count)
- { // assign [_Ptr, _Ptr + _Count)
- #if _ITERATOR_DEBUG_LEVEL == 2
- if (_Count != 0)
- _DEBUG_POINTER(_Ptr);
- #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
- if (_Inside(_Ptr))
- return (assign(*this,
- _Ptr - this->_Myptr(), _Count)); // substring
- if (_Grow(_Count))
- { // make room and assign new stuff
- _Traits::copy(this->_Myptr(), _Ptr, _Count);
- _Eos(_Count);
- }
- return (*this);
- }
- _Myt& assign(const _Elem *_Ptr)
- { // assign [_Ptr, <null>)
- _DEBUG_POINTER(_Ptr);
- return (assign(_Ptr, _Traits::length(_Ptr)));
- }
- _Myt& assign(size_type _Count, _Elem _Ch)
- { // assign _Count * _Ch
- if (_Count == npos)
- _Xlen(); // result too long
- if (_Grow(_Count))
- { // make room and assign new stuff
- _Chassign(0, _Count, _Ch);
- _Eos(_Count);
- }
- return (*this);
- }
- template<class _Iter>
- typename enable_if<_Is_iterator<_Iter>::value,
- _Myt&>::type
- assign(_Iter _First, _Iter _Last)
- { // assign [_First, _Last), input iterators
- return (replace(begin(), end(), _First, _Last));
- }
- _Myt& assign(const_pointer _First, const_pointer _Last)
- { // assign [_First, _Last), const pointers
- return (replace(begin(), end(), _First, _Last));
- }
- _Myt& assign(const_iterator _First, const_iterator _Last)
- { // assign [_First, _Last), const_iterators
- return (replace(begin(), end(), _First, _Last));
- }
- _Myt& insert(size_type _Off, const _Myt& _Right)
- { // insert _Right at _Off
- return (insert(_Off, _Right, 0, npos));
- }
- _Myt& insert(size_type _Off,
- const _Myt& _Right, size_type _Roff, size_type _Count)
- { // insert _Right [_Roff, _Roff + _Count) at _Off
- if (this->_Mysize < _Off || _Right.size() < _Roff)
- _Xran(); // _Off or _Roff off end
- size_type _Num = _Right.size() - _Roff;
- if (_Num < _Count)
- _Count = _Num; // trim _Count to size
- if (npos - this->_Mysize <= _Count)
- _Xlen(); // result too long
- if (0 < _Count && _Grow(_Num = this->_Mysize + _Count))
- { // make room and insert new stuff
- _Traits::move(this->_Myptr() + _Off + _Count,
- this->_Myptr() + _Off,
- this->_Mysize - _Off); // empty out hole
- if (this == &_Right)
- _Traits::move(this->_Myptr() + _Off,
- this->_Myptr() + (_Off < _Roff ? _Roff + _Count : _Roff),
- _Count); // substring
- else
- _Traits::copy(this->_Myptr() + _Off,
- _Right._Myptr() + _Roff, _Count); // fill hole
- _Eos(_Num);
- }
- return (*this);
- }
- _Myt& insert(size_type _Off,
- const _Elem *_Ptr, size_type _Count)
- { // insert [_Ptr, _Ptr + _Count) at _Off
- #if _ITERATOR_DEBUG_LEVEL == 2
- if (_Count != 0)
- _DEBUG_POINTER(_Ptr);
- #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
- if (_Inside(_Ptr))
- return (insert(_Off, *this,
- _Ptr - this->_Myptr(), _Count)); // substring
- if (this->_Mysize < _Off)
- _Xran(); // _Off off end
- if (npos - this->_Mysize <= _Count)
- _Xlen(); // result too long
- size_type _Num;
- if (0 < _Count && _Grow(_Num = this->_Mysize + _Count))
- { // make room and insert new stuff
- _Traits::move(this->_Myptr() + _Off + _Count,
- this->_Myptr() + _Off,
- this->_Mysize - _Off); // empty out hole
- _Traits::copy(this->_Myptr() + _Off, _Ptr, _Count); // fill hole
- _Eos(_Num);
- }
- return (*this);
- }
- _Myt& insert(size_type _Off, const _Elem *_Ptr)
- { // insert [_Ptr, <null>) at _Off
- _DEBUG_POINTER(_Ptr);
- return (insert(_Off, _Ptr, _Traits::length(_Ptr)));
- }
- _Myt& insert(size_type _Off,
- size_type _Count, _Elem _Ch)
- { // insert _Count * _Ch at _Off
- if (this->_Mysize < _Off)
- _Xran(); // _Off off end
- if (npos - this->_Mysize <= _Count)
- _Xlen(); // result too long
- size_type _Num;
- if (0 < _Count && _Grow(_Num = this->_Mysize + _Count))
- { // make room and insert new stuff
- _Traits::move(this->_Myptr() + _Off + _Count,
- this->_Myptr() + _Off,
- this->_Mysize - _Off); // empty out hole
- _Chassign(_Off, _Count, _Ch); // fill hole
- _Eos(_Num);
- }
- return (*this);
- }
- iterator insert(const_iterator _Where)
- { // insert <null> at _Where
- return (insert(_Where, _Elem()));
- }
- iterator insert(const_iterator _Where, _Elem _Ch)
- { // insert _Ch at _Where
- size_type _Off = _Pdif(_Where, begin());
- insert(_Off, 1, _Ch);
- return (begin() + _Off);
- }
- iterator insert(const_iterator _Where, size_type _Count, _Elem _Ch)
- { // insert _Count * _Elem at _Where
- size_type _Off = _Pdif(_Where, begin());
- insert(_Off, _Count, _Ch);
- return (begin() + _Off);
- }
- template<class _Iter>
- typename enable_if<_Is_iterator<_Iter>::value,
- iterator>::type
- insert(const_iterator _Where, _Iter _First, _Iter _Last)
- { // insert [_First, _Last) at _Where, input iterators
- size_type _Off = _Pdif(_Where, begin());
- replace(_Where, _Where, _First, _Last);
- return (begin() + _Off);
- }
- iterator insert(const_iterator _Where,
- const_pointer _First, const_pointer _Last)
- { // insert [_First, _Last) at _Where, const pointers
- size_type _Off = _Pdif(_Where, begin());
- replace(_Where, _Where, _First, _Last);
- return (begin() + _Off);
- }
- iterator insert(const_iterator _Where,
- const_iterator _First, const_iterator _Last)
- { // insert [_First, _Last) at _Where, const_iterators
- size_type _Off = _Pdif(_Where, begin());
- replace(_Where, _Where, _First, _Last);
- return (begin() + _Off);
- }
- _Myt& erase(size_type _Off = 0)
- { // erase elements [_Off, ...)
- if (this->_Mysize < _Off)
- _Xran(); // _Off off end
- _Eos(_Off);
- return (*this);
- }
- _Myt& erase(size_type _Off, size_type _Count)
- { // erase elements [_Off, _Off + _Count)
- if (this->_Mysize < _Off)
- _Xran(); // _Off off end
- if (this->_Mysize - _Off <= _Count)
- _Eos(_Off); // erase elements [_Off, ...)
- else if (0 < _Count)
- { // move elements down
- value_type *_Ptr = this->_Myptr() + _Off;
- size_type _Newsize = this->_Mysize - _Count;
- _Traits::move(_Ptr, _Ptr + _Count, _Newsize - _Off);
- _Eos(_Newsize);
- }
- return (*this);
- }
- iterator erase(const_iterator _Where)
- { // erase element at _Where
- size_type _Count = _Pdif(_Where, begin());
- erase(_Count, 1);
- return (_STRING_ITERATOR(this->_Myptr() + _Count));
- }
- iterator erase(const_iterator _First, const_iterator _Last)
- { // erase substring [_First, _Last)
- _DEBUG_RANGE(_First, _Last);
- size_type _Count = _Pdif(_First, begin());
- erase(_Count, _Pdif(_Last, _First));
- return (_STRING_ITERATOR(this->_Myptr() + _Count));
- }
- void clear() _NOEXCEPT
- { // erase all
- _Eos(0);
- }
- _Myt& replace(size_type _Off, size_type _N0, const _Myt& _Right)
- { // replace [_Off, _Off + _N0) with _Right
- return (replace(_Off, _N0, _Right, 0, npos));
- }
- _Myt& replace(size_type _Off,
- size_type _N0, const _Myt& _Right, size_type _Roff, size_type _Count)
- { // replace [_Off, _Off + _N0) with _Right [_Roff, _Roff + _Count)
- if (this->_Mysize < _Off || _Right.size() < _Roff)
- _Xran(); // _Off or _Roff off end
- if (this->_Mysize - _Off < _N0)
- _N0 = this->_Mysize - _Off; // trim _N0 to size
- size_type _Num = _Right.size() - _Roff;
- if (_Num < _Count)
- _Count = _Num; // trim _Count to size
- if (npos - _Count <= this->_Mysize - _N0)
- _Xlen(); // result too long
- size_type _Nm = this->_Mysize - _N0 - _Off; // length of kept tail
- size_type _Newsize = this->_Mysize + _Count - _N0;
- if (this->_Mysize < _Newsize)
- _Grow(_Newsize);
- if (this != &_Right)
- { // no overlap, just move down and copy in new stuff
- _Traits::move(this->_Myptr() + _Off + _Count,
- this->_Myptr() + _Off + _N0, _Nm); // empty hole
- _Traits::copy(this->_Myptr() + _Off,
- _Right._Myptr() + _Roff, _Count); // fill hole
- }
- else if (_Count <= _N0)
- { // hole doesn't get larger, just copy in substring
- _Traits::move(this->_Myptr() + _Off,
- this->_Myptr() + _Roff, _Count); // fill hole
- _Traits::move(this->_Myptr() + _Off + _Count,
- this->_Myptr() + _Off + _N0, _Nm); // move tail down
- }
- else if (_Roff <= _Off)
- { // hole gets larger, substring begins before hole
- _Traits::move(this->_Myptr() + _Off + _Count,
- this->_Myptr() + _Off + _N0, _Nm); // move tail down
- _Traits::move(this->_Myptr() + _Off,
- this->_Myptr() + _Roff, _Count); // fill hole
- }
- else if (_Off + _N0 <= _Roff)
- { // hole gets larger, substring begins after hole
- _Traits::move(this->_Myptr() + _Off + _Count,
- this->_Myptr() + _Off + _N0, _Nm); // move tail down
- _Traits::move(this->_Myptr() + _Off,
- this->_Myptr() + (_Roff + _Count - _N0),
- _Count); // fill hole
- }
- else
- { // hole gets larger, substring begins in hole
- _Traits::move(this->_Myptr() + _Off,
- this->_Myptr() + _Roff, _N0); // fill old hole
- _Traits::move(this->_Myptr() + _Off + _Count,
- this->_Myptr() + _Off + _N0, _Nm); // move tail down
- _Traits::move(this->_Myptr() + _Off + _N0,
- this->_Myptr() + _Roff + _Count,
- _Count - _N0); // fill rest of new hole
- }
- _Eos(_Newsize);
- return (*this);
- }
- _Myt& replace(size_type _Off,
- size_type _N0, const _Elem *_Ptr, size_type _Count)
- { // replace [_Off, _Off + _N0) with [_Ptr, _Ptr + _Count)
- #if _ITERATOR_DEBUG_LEVEL == 2
- if (_Count != 0)
- _DEBUG_POINTER(_Ptr);
- #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
- if (_Inside(_Ptr))
- return (replace(_Off, _N0, *this,
- _Ptr - this->_Myptr(),
- _Count)); // substring, replace carefully
- if (this->_Mysize < _Off)
- _Xran(); // _Off off end
- if (this->_Mysize - _Off < _N0)
- _N0 = this->_Mysize - _Off; // trim _N0 to size
- if (npos - _Count <= this->_Mysize - _N0)
- _Xlen(); // result too long
- size_type _Nm = this->_Mysize - _N0 - _Off;
- if (_Count < _N0)
- _Traits::move(this->_Myptr() + _Off + _Count,
- this->_Myptr() + _Off + _N0,
- _Nm); // smaller hole, move tail up
- size_type _Num;
- if ((0 < _Count || 0 < _N0)
- && _Grow(_Num = this->_Mysize + _Count - _N0))
- { // make room and rearrange
- if (_N0 < _Count)
- _Traits::move(this->_Myptr() + _Off + _Count,
- this->_Myptr() + _Off + _N0, _Nm); // move tail down
- _Traits::copy(this->_Myptr() + _Off, _Ptr, _Count); // fill hole
- _Eos(_Num);
- }
- return (*this);
- }
- _Myt& replace(size_type _Off, size_type _N0, const _Elem *_Ptr)
- { // replace [_Off, _Off + _N0) with [_Ptr, <null>)
- _DEBUG_POINTER(_Ptr);
- return (replace(_Off, _N0, _Ptr, _Traits::length(_Ptr)));
- }
- _Myt& replace(size_type _Off,
- size_type _N0, size_type _Count, _Elem _Ch)
- { // replace [_Off, _Off + _N0) with _Count * _Ch
- if (this->_Mysize < _Off)
- _Xran(); // _Off off end
- if (this->_Mysize - _Off < _N0)
- _N0 = this->_Mysize - _Off; // trim _N0 to size
- if (npos - _Count <= this->_Mysize - _N0)
- _Xlen(); // result too long
- size_type _Nm = this->_Mysize - _N0 - _Off;
- if (_Count < _N0)
- _Traits::move(this->_Myptr() + _Off + _Count,
- this->_Myptr() + _Off + _N0,
- _Nm); // smaller hole, move tail up
- size_type _Num;
- if ((0 < _Count || 0 < _N0)
- && _Grow(_Num = this->_Mysize + _Count - _N0))
- { // make room and rearrange
- if (_N0 < _Count)
- _Traits::move(this->_Myptr() + _Off + _Count,
- this->_Myptr() + _Off + _N0, _Nm); // move tail down
- _Chassign(_Off, _Count, _Ch); // fill hole
- _Eos(_Num);
- }
- return (*this);
- }
- _Myt& replace(const_iterator _First, const_iterator _Last,
- const _Myt& _Right)
- { // replace [_First, _Last) with _Right
- return (replace(
- _Pdif(_First, begin()), _Pdif(_Last, _First), _Right));
- }
- _Myt& replace(const_iterator _First, const_iterator _Last,
- const _Elem *_Ptr, size_type _Count)
- { // replace [_First, _Last) with [_Ptr, _Ptr + _Count)
- return (replace(
- _Pdif(_First, begin()), _Pdif(_Last, _First), _Ptr, _Count));
- }
- _Myt& replace(const_iterator _First, const_iterator _Last,
- const _Elem *_Ptr)
- { // replace [_First, _Last) with [_Ptr, <null>)
- return (replace(
- _Pdif(_First, begin()), _Pdif(_Last, _First), _Ptr));
- }
- _Myt& replace(const_iterator _First, const_iterator _Last,
- size_type _Count, _Elem _Ch)
- { // replace [_First, _Last) with _Count * _Ch
- return (replace(
- _Pdif(_First, begin()), _Pdif(_Last, _First), _Count, _Ch));
- }
- template<class _Iter>
- typename enable_if<_Is_iterator<_Iter>::value,
- _Myt&>::type
- replace(const_iterator _First, const_iterator _Last,
- _Iter _First2, _Iter _Last2)
- { // replace [_First, _Last) with [_First2, _Last2), input iterators
- _Myt _Right(_First2, _Last2);
- replace(_First, _Last, _Right);
- return (*this);
- }
- _Myt& replace(const_iterator _First, const_iterator _Last,
- const_pointer _First2, const_pointer _Last2)
- { // replace [_First, _Last) with [_First2, _Last2), const pointers
- if (_First2 == _Last2)
- erase(_Pdif(_First, begin()), _Pdif(_Last, _First));
- else
- replace(_Pdif(_First, begin()), _Pdif(_Last, _First),
- &*_First2, _Last2 - _First2);
- return (*this);
- }
- _Myt& replace(const_iterator _First, const_iterator _Last,
- pointer _First2, pointer _Last2)
- { // replace [_First, _Last) with [_First2, _Last2), const pointers
- if (_First2 == _Last2)
- erase(_Pdif(_First, begin()), _Pdif(_Last, _First));
- else
- replace(_Pdif(_First, begin()), _Pdif(_Last, _First),
- &*_First2, _Last2 - _First2);
- return (*this);
- }
- _Myt& replace(const_iterator _First, const_iterator _Last,
- const_iterator _First2, const_iterator _Last2)
- { // replace [_First, _Last) with [_First2, _Last2), const_iterators
- if (_First2 == _Last2)
- erase(_Pdif(_First, begin()), _Pdif(_Last, _First));
- else
- replace(_Pdif(_First, begin()), _Pdif(_Last, _First),
- &*_First2, _Last2 - _First2);
- return (*this);
- }
- _Myt& replace(const_iterator _First, const_iterator _Last,
- iterator _First2, iterator _Last2)
- { // replace [_First, _Last) with [_First2, _Last2), const_iterators
- if (_First2 == _Last2)
- erase(_Pdif(_First, begin()), _Pdif(_Last, _First));
- else
- replace(_Pdif(_First, begin()), _Pdif(_Last, _First),
- &*_First2, _Last2 - _First2);
- return (*this);
- }
- iterator begin() _NOEXCEPT
- { // return iterator for beginning of mutable sequence
- return (_STRING_ITERATOR(this->_Myptr()));
- }
- const_iterator begin() const _NOEXCEPT
- { // return iterator for beginning of nonmutable sequence
- return (_STRING_CONST_ITERATOR(this->_Myptr()));
- }
- iterator end() _NOEXCEPT
- { // return iterator for end of mutable sequence
- return (_STRING_ITERATOR(this->_Myptr() + this->_Mysize));
- }
- const_iterator end() const _NOEXCEPT
- { // return iterator for end of nonmutable sequence
- return (_STRING_CONST_ITERATOR(this->_Myptr() + this->_Mysize));
- }
- reverse_iterator rbegin() _NOEXCEPT
- { // return iterator for beginning of reversed mutable sequence
- return (reverse_iterator(end()));
- }
- const_reverse_iterator rbegin() const _NOEXCEPT
- { // return iterator for beginning of reversed nonmutable sequence
- return (const_reverse_iterator(end()));
- }
- reverse_iterator rend() _NOEXCEPT
- { // return iterator for end of reversed mutable sequence
- return (reverse_iterator(begin()));
- }
- const_reverse_iterator rend() const _NOEXCEPT
- { // return iterator for end of reversed nonmutable sequence
- return (const_reverse_iterator(begin()));
- }
- const_iterator cbegin() const _NOEXCEPT
- { // return iterator for beginning of nonmutable sequence
- return (((const _Myt *)this)->begin());
- }
- const_iterator cend() const _NOEXCEPT
- { // return iterator for end of nonmutable sequence
- return (((const _Myt *)this)->end());
- }
- const_reverse_iterator crbegin() const _NOEXCEPT
- { // return iterator for beginning of reversed nonmutable sequence
- return (((const _Myt *)this)->rbegin());
- }
- const_reverse_iterator crend() const _NOEXCEPT
- { // return iterator for end of reversed nonmutable sequence
- return (((const _Myt *)this)->rend());
- }
- void shrink_to_fit()
- { // reduce capacity
- if ((size() | this->_ALLOC_MASK) < capacity())
- { // worth shrinking, do it
- _Myt _Tmp(*this);
- swap(_Tmp);
- }
- }
- reference at(size_type _Off)
- { // subscript mutable sequence with checking
- if (this->_Mysize <= _Off)
- _Xran(); // _Off off end
- return (this->_Myptr()[_Off]);
- }
- const_reference at(size_type _Off) const
- { // subscript nonmutable sequence with checking
- if (this->_Mysize <= _Off)
- _Xran(); // _Off off end
- return (this->_Myptr()[_Off]);
- }
- reference operator[](size_type _Off)
- { // subscript mutable sequence
- #if _ITERATOR_DEBUG_LEVEL == 2
- if (this->_Mysize < _Off) // sic
- _DEBUG_ERROR("string subscript out of range");
- #elif _ITERATOR_DEBUG_LEVEL == 1
- _SCL_SECURE_VALIDATE_RANGE(_Off <= this->_Mysize); // sic
- #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
- return (this->_Myptr()[_Off]);
- }
- const_reference operator[](size_type _Off) const
- { // subscript nonmutable sequence
- #if _ITERATOR_DEBUG_LEVEL == 2
- if (this->_Mysize < _Off) // sic
- _DEBUG_ERROR("string subscript out of range");
- #elif _ITERATOR_DEBUG_LEVEL == 1
- _SCL_SECURE_VALIDATE_RANGE(_Off <= this->_Mysize); // sic
- #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
- return (this->_Myptr()[_Off]);
- }
- void push_back(_Elem _Ch)
- { // insert element at end
- insert(end(), _Ch);
- }
- void pop_back()
- { // erase element at end
- erase(this->_Mysize - 1); // throws if _Mysize == 0
- }
- reference front()
- { // return first element of mutable sequence
- return (*begin());
- }
- const_reference front() const
- { // return first element of nonmutable sequence
- return (*begin());
- }
- reference back()
- { // return last element of mutable sequence
- return (*(end() - 1));
- }
- const_reference back() const
- { // return last element of nonmutable sequence
- return (*(end() - 1));
- }
- const _Elem *c_str() const _NOEXCEPT
- { // return pointer to null-terminated nonmutable array
- return (this->_Myptr());
- }
- const _Elem *data() const _NOEXCEPT
- { // return pointer to nonmutable array
- return (c_str());
- }
- size_type length() const _NOEXCEPT
- { // return length of sequence
- return (this->_Mysize);
- }
- size_type size() const _NOEXCEPT
- { // return length of sequence
- return (this->_Mysize);
- }
- size_type max_size() const _NOEXCEPT
- { // return maximum possible length of sequence
- size_type _Num = this->_Getal().max_size();
- return (_Num <= 1 ? 1 : _Num - 1);
- }
- void resize(size_type _Newsize)
- { // determine new length, padding with null elements as needed
- resize(_Newsize, _Elem());
- }
- void resize(size_type _Newsize, _Elem _Ch)
- { // determine new length, padding with _Ch elements as needed
- if (_Newsize <= this->_Mysize)
- _Eos(_Newsize);
- else
- append(_Newsize - this->_Mysize, _Ch);
- }
- size_type capacity() const _NOEXCEPT
- { // return current length of allocated storage
- return (this->_Myres);
- }
- void reserve(size_type _Newcap = 0)
- { // determine new minimum length of allocated storage
- if (this->_Mysize <= _Newcap && this->_Myres != _Newcap)
- { // change reservation
- size_type _Size = this->_Mysize;
- if (_Grow(_Newcap, true))
- _Eos(_Size);
- }
- }
- bool empty() const _NOEXCEPT
- { // test if sequence is empty
- return (this->_Mysize == 0);
- }
- _SCL_INSECURE_DEPRECATE
- size_type copy(_Elem *_Ptr,
- size_type _Count, size_type _Off = 0) const
- { // copy [_Off, _Off + _Count) to [_Ptr, _Ptr + _Count)
- #if _ITERATOR_DEBUG_LEVEL == 2
- if (_Count != 0)
- _DEBUG_POINTER(_Ptr);
- #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
- if (this->_Mysize < _Off)
- _Xran(); // _Off off end
- if (this->_Mysize - _Off < _Count)
- _Count = this->_Mysize - _Off;
- _Traits::copy(_Ptr, this->_Myptr() + _Off, _Count);
- return (_Count);
- }
- size_type _Copy_s(_Elem *_Dest, size_type _Dest_size,
- size_type _Count, size_type _Off = 0) const
- { // copy [_Off, _Off + _Count) to [_Dest, _Dest + _Count)
- #if _ITERATOR_DEBUG_LEVEL == 2
- if (_Count != 0)
- _DEBUG_POINTER(_Dest);
- #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
- if (this->_Mysize < _Off)
- _Xran(); // _Off off end
- if (this->_Mysize - _Off < _Count)
- _Count = this->_Mysize - _Off;
- _Traits::_Copy_s(_Dest, _Dest_size, this->_Myptr() + _Off, _Count);
- return (_Count);
- }
- void _Swap_bx(_Myt& _Right)
- { // exchange _Bx with _Right._Bx
- if (this->_BUF_SIZE <= this->_Myres)
- if (this->_BUF_SIZE <= _Right._Myres)
- _Swap_adl(this->_Bx._Ptr, _Right._Bx._Ptr);
- else
- { // swap large with small
- pointer _Ptr = this->_Bx._Ptr;
- this->_Getal().destroy(&this->_Bx._Ptr);
- _Traits::copy(this->_Bx._Buf,
- _Right._Bx._Buf, _Right._Mysize + 1);
- this->_Getal().construct(&_Right._Bx._Ptr, _Ptr);
- }
- else
- if (_Right._Myres < this->_BUF_SIZE)
- _STD swap(this->_Bx._Buf, _Right._Bx._Buf);
- else
- { // swap small with large
- pointer _Ptr = _Right._Bx._Ptr;
- this->_Getal().destroy(&_Right._Bx._Ptr);
- _Traits::copy(_Right._Bx._Buf,
- this->_Bx._Buf, this->_Mysize + 1);
- this->_Getal().construct(&this->_Bx._Ptr, _Ptr);
- }
- }
- void swap(_Myt& _Right)
- { // exchange contents with _Right
- if (this == &_Right)
- ; // same object, do nothing
- else if (this->_Getal() == _Right._Getal())
- { // same allocator, swap control information
- this->_Swap_all(_Right);
- _Swap_bx(_Right);
- _STD swap(this->_Mysize, _Right._Mysize);
- _STD swap(this->_Myres, _Right._Myres);
- }
- else if (_Alty::propagate_on_container_swap::value)
- { // swap allocators and control information
- this->_Swap_alloc(_Right);
- _Swap_bx(_Right);
- _STD swap(this->_Bx, _Right._Bx); // pointer bitwise copyable?
- _STD swap(this->_Mysize, _Right._Mysize);
- _STD swap(this->_Myres, _Right._Myres);
- }
- else
- { // different allocator, do multiple assigns
- _Myt _Tmp = *this;
- *this = _Right;
- _Right = _Tmp;
- }
- }
- size_type find(const _Myt& _Right, size_type _Off = 0) const _NOEXCEPT
- { // look for _Right beginning at or after _Off
- return (find(_Right._Myptr(), _Off, _Right.size()));
- }
- size_type find(const _Elem *_Ptr,
- size_type _Off, size_type _Count) const
- { // look for [_Ptr, _Ptr + _Count) beginning at or after _Off
- #if _ITERATOR_DEBUG_LEVEL == 2
- if (_Count != 0)
- _DEBUG_POINTER(_Ptr);
- #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
- if (_Count == 0 && _Off <= this->_Mysize)
- return (_Off); // null string always matches (if inside string)
- size_type _Nm;
- if (_Off < this->_Mysize && _Count <= (_Nm = this->_Mysize - _Off))
- { // room for match, look for it
- const _Elem *_Uptr, *_Vptr;
- for (_Nm -= _Count - 1, _Vptr = this->_Myptr() + _Off;
- (_Uptr = _Traits::find(_Vptr, _Nm, *_Ptr)) != 0;
- _Nm -= _Uptr - _Vptr + 1, _Vptr = _Uptr + 1)
- if (_Traits::compare(_Uptr, _Ptr, _Count) == 0)
- return (_Uptr - this->_Myptr()); // found a match
- }
- return (npos); // no match
- }
- size_type find(const _Elem *_Ptr, size_type _Off = 0) const
- { // look for [_Ptr, <null>) beginning at or after _Off
- _DEBUG_POINTER(_Ptr);
- return (find(_Ptr, _Off, _Traits::length(_Ptr)));
- }
- size_type find(_Elem _Ch, size_type _Off = 0) const
- { // look for _Ch at or after _Off
- return (find((const _Elem *)&_Ch, _Off, 1));
- }
- size_type rfind(const _Myt& _Right, size_type _Off = npos) const _NOEXCEPT
- { // look for _Right beginning before _Off
- return (rfind(_Right._Myptr(), _Off, _Right.size()));
- }
- size_type rfind(const _Elem *_Ptr,
- size_type _Off, size_type _Count) const
- { // look for [_Ptr, _Ptr + _Count) beginning before _Off
- #if _ITERATOR_DEBUG_LEVEL == 2
- if (_Count != 0)
- _DEBUG_POINTER(_Ptr);
- #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
- if (_Count == 0)
- return (_Off < this->_Mysize ? _Off
- : this->_Mysize); // null always matches
- if (_Count <= this->_Mysize)
- { // room for match, look for it
- const _Elem *_Uptr = this->_Myptr() +
- (_Off < this->_Mysize - _Count ? _Off
- : this->_Mysize - _Count);
- for (; ; --_Uptr)
- if (_Traits::eq(*_Uptr, *_Ptr)
- && _Traits::compare(_Uptr, _Ptr, _Count) == 0)
- return (_Uptr - this->_Myptr()); // found a match
- else if (_Uptr == this->_Myptr())
- break; // at beginning, no more chance for match
- }
- return (npos); // no match
- }
- size_type rfind(const _Elem *_Ptr, size_type _Off = npos) const
- { // look for [_Ptr, <null>) beginning before _Off
- _DEBUG_POINTER(_Ptr);
- return (rfind(_Ptr, _Off, _Traits::length(_Ptr)));
- }
- size_type rfind(_Elem _Ch, size_type _Off = npos) const
- { // look for _Ch before _Off
- return (rfind((const _Elem *)&_Ch, _Off, 1));
- }
- size_type find_first_of(const _Myt& _Right,
- size_type _Off = 0) const _NOEXCEPT
- { // look for one of _Right at or after _Off
- return (find_first_of(_Right._Myptr(), _Off, _Right.size()));
- }
- size_type find_first_of(const _Elem *_Ptr,
- size_type _Off, size_type _Count) const
- { // look for one of [_Ptr, _Ptr + _Count) at or after _Off
- #if _ITERATOR_DEBUG_LEVEL == 2
- if (_Count != 0)
- _DEBUG_POINTER(_Ptr);
- #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
- if (0 < _Count && _Off < this->_Mysize)
- { // room for match, look for it
- const _Elem *const _Vptr = this->_Myptr() + this->_Mysize;
- for (const _Elem *_Uptr = this->_Myptr() + _Off;
- _Uptr < _Vptr; ++_Uptr)
- if (_Traits::find(_Ptr, _Count, *_Uptr) != 0)
- return (_Uptr - this->_Myptr()); // found a match
- }
- return (npos); // no match
- }
- size_type find_first_of(const _Elem *_Ptr,
- size_type _Off = 0) const
- { // look for one of [_Ptr, <null>) at or after _Off
- _DEBUG_POINTER(_Ptr);
- return (find_first_of(_Ptr, _Off, _Traits::length(_Ptr)));
- }
- size_type find_first_of(_Elem _Ch,
- size_type _Off = 0) const
- { // look for _Ch at or after _Off
- return (find((const _Elem *)&_Ch, _Off, 1));
- }
- size_type find_last_of(const _Myt& _Right,
- size_type _Off = npos) const _NOEXCEPT
- { // look for one of _Right before _Off
- return (find_last_of(_Right._Myptr(), _Off, _Right.size()));
- }
- size_type find_last_of(const _Elem *_Ptr,
- size_type _Off, size_type _Count) const
- { // look for one of [_Ptr, _Ptr + _Count) before _Off
- #if _ITERATOR_DEBUG_LEVEL == 2
- if (_Count != 0)
- _DEBUG_POINTER(_Ptr);
- #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
- if (0 < _Count && 0 < this->_Mysize)
- { // worth searching, do it
- const _Elem *_Uptr = this->_Myptr()
- + (_Off < this->_Mysize ? _Off : this->_Mysize - 1);
- for (; ; --_Uptr)
- if (_Traits::find(_Ptr, _Count, *_Uptr) != 0)
- return (_Uptr - this->_Myptr()); // found a match
- else if (_Uptr == this->_Myptr())
- break; // at beginning, no more chance for match
- }
- return (npos); // no match
- }
- size_type find_last_of(const _Elem *_Ptr,
- size_type _Off = npos) const
- { // look for one of [_Ptr, <null>) before _Off
- _DEBUG_POINTER(_Ptr);
- return (find_last_of(_Ptr, _Off, _Traits::length(_Ptr)));
- }
- size_type find_last_of(_Elem _Ch,
- size_type _Off = npos) const
- { // look for _Ch before _Off
- return (rfind((const _Elem *)&_Ch, _Off, 1));
- }
- size_type find_first_not_of(const _Myt& _Right,
- size_type _Off = 0) const _NOEXCEPT
- { // look for none of _Right at or after _Off
- return (find_first_not_of(_Right._Myptr(), _Off,
- _Right.size()));
- }
- size_type find_first_not_of(const _Elem *_Ptr,
- size_type _Off, size_type _Count) const
- { // look for none of [_Ptr, _Ptr + _Count) at or after _Off
- #if _ITERATOR_DEBUG_LEVEL == 2
- if (_Count != 0)
- _DEBUG_POINTER(_Ptr);
- #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
- if (_Off < this->_Mysize)
- { // room for match, look for it
- const _Elem *const _Vptr = this->_Myptr() + this->_Mysize;
- for (const _Elem *_Uptr = this->_Myptr() + _Off;
- _Uptr < _Vptr; ++_Uptr)
- if (_Traits::find(_Ptr, _Count, *_Uptr) == 0)
- return (_Uptr - this->_Myptr());
- }
- return (npos);
- }
- size_type find_first_not_of(const _Elem *_Ptr,
- size_type _Off = 0) const
- { // look for one of [_Ptr, <null>) at or after _Off
- _DEBUG_POINTER(_Ptr);
- return (find_first_not_of(_Ptr, _Off, _Traits::length(_Ptr)));
- }
- size_type find_first_not_of(_Elem _Ch,
- size_type _Off = 0) const
- { // look for non _Ch at or after _Off
- return (find_first_not_of((const _Elem *)&_Ch, _Off, 1));
- }
- size_type find_last_not_of(const _Myt& _Right,
- size_type _Off = npos) const _NOEXCEPT
- { // look for none of _Right before _Off
- return (find_last_not_of(_Right._Myptr(), _Off, _Right.size()));
- }
- size_type find_last_not_of(const _Elem *_Ptr,
- size_type _Off, size_type _Count) const
- { // look for none of [_Ptr, _Ptr + _Count) before _Off
- #if _ITERATOR_DEBUG_LEVEL == 2
- if (_Count != 0)
- _DEBUG_POINTER(_Ptr);
- #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
- if (0 < this->_Mysize)
- { // worth searching, do it
- const _Elem *_Uptr = this->_Myptr()
- + (_Off < this->_Mysize ? _Off : this->_Mysize - 1);
- for (; ; --_Uptr)
- if (_Traits::find(_Ptr, _Count, *_Uptr) == 0)
- return (_Uptr - this->_Myptr());
- else if (_Uptr == this->_Myptr())
- break;
- }
- return (npos);
- }
- size_type find_last_not_of(const _Elem *_Ptr,
- size_type _Off = npos) const
- { // look for none of [_Ptr, <null>) before _Off
- _DEBUG_POINTER(_Ptr);
- return (find_last_not_of(_Ptr, _Off, _Traits::length(_Ptr)));
- }
- size_type find_last_not_of(_Elem _Ch,
- size_type _Off = npos) const
- { // look for non _Ch before _Off
- return (find_last_not_of((const _Elem *)&_Ch, _Off, 1));
- }
- _Myt substr(size_type _Off = 0, size_type _Count = npos) const
- { // return [_Off, _Off + _Count) as new string
- return (_Myt(*this, _Off, _Count, get_allocator()));
- }
- int compare(const _Myt& _Right) const _NOEXCEPT
- { // compare [0, _Mysize) with _Right
- return (compare(0, this->_Mysize, _Right._Myptr(), _Right.size()));
- }
- int compare(size_type _Off, size_type _N0,
- const _Myt& _Right) const
- { // compare [_Off, _Off + _N0) with _Right
- return (compare(_Off, _N0, _Right, 0, npos));
- }
- int compare(size_type _Off,
- size_type _N0, const _Myt& _Right,
- size_type _Roff, size_type _Count) const
- { // compare [_Off, _Off + _N0) with _Right [_Roff, _Roff + _Count)
- if (_Right.size() < _Roff)
- _Xran(); // _Off off end
- if (_Right._Mysize - _Roff < _Count)
- _Count = _Right._Mysize - _Roff; // trim _Count to size
- return (compare(_Off, _N0, _Right._Myptr() + _Roff, _Count));
- }
- int compare(const _Elem *_Ptr) const
- { // compare [0, _Mysize) with [_Ptr, <null>)
- _DEBUG_POINTER(_Ptr);
- return (compare(0, this->_Mysize, _Ptr, _Traits::length(_Ptr)));
- }
- int compare(size_type _Off, size_type _N0, const _Elem *_Ptr) const
- { // compare [_Off, _Off + _N0) with [_Ptr, <null>)
- _DEBUG_POINTER(_Ptr);
- return (compare(_Off, _N0, _Ptr, _Traits::length(_Ptr)));
- }
- int compare(size_type _Off,
- size_type _N0, const _Elem *_Ptr, size_type _Count) const
- { // compare [_Off, _Off + _N0) with [_Ptr, _Ptr + _Count)
- #if _ITERATOR_DEBUG_LEVEL == 2
- if (_Count != 0)
- _DEBUG_POINTER(_Ptr);
- #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
- if (this->_Mysize < _Off)
- _Xran(); // _Off off end
- if (this->_Mysize - _Off < _N0)
- _N0 = this->_Mysize - _Off; // trim _N0 to size
- size_type _Ans = _Traits::compare(this->_Myptr() + _Off, _Ptr,
- _N0 < _Count ? _N0 : _Count);
- return (_Ans != 0 ? (int)_Ans : _N0 < _Count ? -1
- : _N0 == _Count ? 0 : +1);
- }
- allocator_type get_allocator() const _NOEXCEPT
- { // return allocator object for values
- return (this->_Getal());
- }
- void _Chassign(size_type _Off, size_type _Count, _Elem _Ch)
- { // assign _Count copies of _Ch beginning at _Off
- if (_Count == 1)
- _Traits::assign(*(this->_Myptr() + _Off), _Ch);
- else
- _Traits::assign(this->_Myptr() + _Off, _Count, _Ch);
- }
- void _Copy(size_type _Newsize, size_type _Oldlen)
- { // copy _Oldlen elements to newly allocated buffer
- size_type _Newres = _Newsize | this->_ALLOC_MASK;
- if (max_size() < _Newres)
- _Newres = _Newsize; // undo roundup if too big
- else if (this->_Myres / 2 <= _Newres / 3)
- ;
- else if (this->_Myres <= max_size() - this->_Myres / 2)
- _Newres = this->_Myres
- + this->_Myres / 2; // grow exponentially if possible
- else
- _Newres = max_size(); // settle for max_size()
- _Elem *_Ptr;
- _TRY_BEGIN
- _Ptr = this->_Getal().allocate(_Newres + 1);
- _CATCH_ALL
- _Newres = _Newsize; // allocation failed, undo roundup and retry
- _TRY_BEGIN
- _Ptr = this->_Getal().allocate(_Newres + 1);
- _CATCH_ALL
- _Tidy(true); // failed again, discard storage and reraise
- _RERAISE;
- _CATCH_END
- _CATCH_END
- if (0 < _Oldlen)
- _Traits::copy(_Ptr, this->_Myptr(),
- _Oldlen); // copy existing elements
- _Tidy(true);
- this->_Getal().construct(&this->_Bx._Ptr, _Ptr);
- this->_Myres = _Newres;
- _Eos(_Oldlen);
- }
- void _Eos(size_type _Newsize)
- { // set new length and null terminator
- _Traits::assign(this->_Myptr()[this->_Mysize = _Newsize], _Elem());
- }
- bool _Grow(size_type _Newsize,
- bool _Trim = false)
- { // ensure buffer is big enough, trim to size if _Trim is true
- if (max_size() < _Newsize)
- _Xlen(); // result too long
- if (this->_Myres < _Newsize)
- _Copy(_Newsize, this->_Mysize); // reallocate to grow
- else if (_Trim && _Newsize < this->_BUF_SIZE)
- _Tidy(true, // copy and deallocate if trimming to small string
- _Newsize < this->_Mysize ? _Newsize : this->_Mysize);
- else if (_Newsize == 0)
- _Eos(0); // new size is zero, just null terminate
- return (0 < _Newsize); // return true only if more work to do
- }
- bool _Inside(const _Elem *_Ptr)
- { // test if _Ptr points inside string
- if (_Ptr == 0 || _Ptr < this->_Myptr()
- || this->_Myptr() + this->_Mysize <= _Ptr)
- return (false); // don't ask
- else
- return (true);
- }
- static size_type _Pdif(const_iterator _P2,
- const_iterator _P1)
- { // compute safe iterator difference
- return (_STRING_ITER_BASE(_P2) == 0 ? 0 : _P2 - _P1);
- }
- void _Tidy(bool _Built = false,
- size_type _Newsize = 0)
- { // initialize buffer, deallocating any storage
- if (!_Built)
- ;
- else if (this->_BUF_SIZE <= this->_Myres)
- { // copy any leftovers to small buffer and deallocate
- pointer _Ptr = this->_Bx._Ptr;
- this->_Getal().destroy(&this->_Bx._Ptr);
- if (0 < _Newsize)
- _Traits::copy(this->_Bx._Buf,
- _STD addressof(*_Ptr), _Newsize);
- this->_Getal().deallocate(_Ptr, this->_Myres + 1);
- }
- this->_Myres = this->_BUF_SIZE - 1;
- _Eos(_Newsize);
- }
- __declspec(noreturn) void _Xlen() const
- { // report a length_error
- _Xlength_error("string too long");
- }
- __declspec(noreturn) void _Xran() const
- { // report an out_of_range error
- _Xout_of_range("invalid string position");
- }
- };
Advertisement
Add Comment
Please, Sign In to add comment