std::string

 ̄綄美尐妖づ 提交于 2020-03-27 00:33:20
#pragma once
class _String_val //字符串存储,16字节或者大于16字节的堆指针,    // base class for basic_string to hold data
{
public:
    enum
        {    // length of internal buffer, [1, 16],15个字符+\0
        _BUF_SIZE = 16;

    union _Bxty
    {    // storage for small buffer or pointer to larger one
        _Elem _Buf[_BUF_SIZE];
        _Elem *_Ptr;
        char _Alias[_BUF_SIZE];    // to permit aliasing
    } _Bx;

    size_type _Mysize;    // 字符串大小, current length of string
    size_type _Myres;    // 分配空间大小 current storage reserved for string
};

void _Xlen() const;//    _Xlength_error("string too long");
void _Xran() const;//  _Xout_of_range("invalid string position");
    
class string{
public:
    void _Tidy(bool _Built = false,  size_type _Newsize = 0)//构造函数初始化数据,或其它函数清理数据[_Tidy(true),构造函数中不需要这一步]
    {
        if (_Built && this->_Myres >= this->_BUF_SIZE) //将分配的字符拷到固定空间,并释放分配的数据
        {    // copy any leftovers to small buffer and deallocate
            char *_Ptr = this->_Bx._Ptr;
            if (Newsize > 0)
                _Traits::copy(this->_Bx._Buf, _Ptr, _Newsize);
            
            this->_Alval.deallocate(_Ptr, this->_Myres + 1);
        }
            
        this->_Myres = this->_BUF_SIZE - 1;
        _Eos(_Newsize);
    }
    void _Eos(size_type _Newsize)    // set new length and null terminator
    {
        _Traits::assign(_Myptr()[this->_Mysize = _Newsize], _Elem());
    }
    
     string(const string& right)
    {
        tidy();
        assign(right, 0, npos);
    }
    string()
    {
        tidy();
    }
    string(const string& right, size_type offset, size_type count = npos)
    string(const char *ptr, size_type count);
    string(const char *ptr);
    string(size_type count, char Ch);
    Iter string(Iter first, Iter last);
    string(const_pointer first, const_pointer last);
    string(const_iterator first, const_iterator last)
    string(string&& right);
    
    string& operator=(string&& right);
    string& assign(string&& right) //c11
    {    // 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);
            if (right.Myres < this->_BUF_SIZE)
                _Traits::move(this->_Bx.Buf, right.Bx.Buf,
                    right.Mysize + 1);
            else
            {    // copy pointer
                this->_Bx.Ptr = right.Bx.Ptr;
                right.Bx.Ptr = 0;
            }
            this->_Mysize = right.Mysize;
            this->_Myres = right.Myres;

            right.Tidy();
        }
        return (*this);
    }

    void swap(string&& right)//c11
    {
        if (this != &right)
        {    // swap with emptied container
//ITERATOR_DEBUG_LEVEL = 0 (in release mode)
//_ITERATOR_DEBUG_LEVEL = 1 (in release mode if _SECURE_SCL is defined)
//_ITERATOR_DEBUG_LEVEL = 2 (in debug mode)
            assign(_STD forward<string>(right));
        }
    }

    ~string()
    {
        _Tidy(true);
    }

    string& operator=(const string& right);
    string& operator=(const char *ptr);
    string& operator=(char Ch)
    string& operator+=(const string& right)
    string& operator+=(const char *ptr)
    string& operator+=(char Ch)
    string& append(const string& right)
    string& append(const string& right,    size_type offset, size_type count)
    {
        if (right.size() < offset)
            _Xran();    // offset off end
        size_type Num = right.size() - offset;
        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(_Myptr() + this->_Mysize,
                right.Myptr() + offset, count);
            _Eos(_Num);
        }
        return (*this);
    }

    string& append(const char *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 - 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(_Myptr() + this->_Mysize, Ptr, count);
            _Eos(_Num);
        }
        return (*this);
    }

    string& append(const char *ptr)
    string& append(size_type count, char Ch)
    Iter string& append(Iter first, Iter last)
    string& append(const_pointer first, const_pointer last)
    string& append(const_iterator first, const_iterator last)
    
    string& assign(const string& right)
    string& assign(const string& right,    size_type offset, size_type count)
    {    // assign right [_Roff, offset + count)
        if (right.size() < offset)
            _Xran();    // offset off end
        size_type Num = right.size() - offset;
        if (count < Num)
            _Num = count;    // trim Num to size

        if (this == &right)
            erase((size_type)(_Roff + Num)), erase(0, offset);    // substring
        else if (_Grow(_Num))
        {    // make room and assign new stuff
            _Traits::copy(_Myptr(), right.Myptr() + offset, Num);
            _Eos(_Num);
        }
        return (*this);
    }
    string& assign(const char *ptr, size_type count);
    string& assign(const char *ptr)
    string& assign(size_type count, char Ch)
    Iter string& assign(Iter first, Iter last)
    string& assign(const_pointer first, const_pointer last)
    string& assign(const_iterator first, const_iterator last)

    string& insert(size_type Off, const string& right)
    string& insert(size_type Off, const string& right, size_type offset, size_type count)
    {    // insert right [_Roff, offset + count) at Off
        if (this->_Mysize < Off || right.size() < offset)
            _Xran();    // Off or offset off end
        
        size_type Num = right.size() - offset;
        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(_Myptr() + Off + count,
                _Myptr() + Off, this->_Mysize - Off);    // empty out hole
            if (this == &right)
                _Traits::move(_Myptr() + Off,
                    _Myptr() + (_Off < offset ? offset + count : offset),
                        count);    // substring
            else
                _Traits::copy(_Myptr() + Off,
                    right.Myptr() + offset, count);    // fill hole
            _Eos(Num);
        }
        return (*this);
    }
    string& insert(size_type Off, const char *ptr, size_type count);
    string& insert(size_type Off, const char *ptr);
    string& insert(size_type Off, size_type count, char Ch);
    iterator insert(const_iterator Where)
    {    // insert <null> at Where
        return (insert(_Where, char()));
    }

    iterator insert(const_iterator Where, char Ch)
    {    // insert Ch at Where
        size_type Off = Pdif(_Where, begin());
        insert(_Off, 1, Ch);
        return (begin() + Off);
    }
    void insert(const_iterator Where, size_type count, char Ch);
    Iter void insert(const_iterator Where, Iter first, Iter last);
    void insert(const_iterator Where, const_pointer first, const_pointer last);
    void insert(const_iterator Where,    const_iterator first, const_iterator last);

    string& erase(size_type Off = 0,size_type count = npos)
    iterator erase(const_iterator Where)
    {    // erase element at Where
        size_type count = Pdif(_Where, begin());
        erase(count, 1);
        return (_STRING_ITERATOR(_Myptr() + count));
    }
    iterator erase(const_iterator first, const_iterator last);

    void clear()
    {    // erase all
        _Eos(0);
    }

    string& replace(size_type Off, size_type N0, const string& right);
    string& replace(size_type Off, size_type N0, const string& right, size_type offset, size_type count);
    string& replace(size_type Off, size_type N0, const char *ptr, size_type count);
    string& replace(size_type Off, size_type N0, const char *ptr);
    string& replace(size_type Off, size_type N0, size_type count, char Ch);

    string& replace(const_iterator first, const_iterator last,    const string& right);
    string& replace(const_iterator first, const_iterator last,    const char *ptr, size_type count);
    string& replace(const_iterator first, const_iterator last,    const char *ptr)
    string& replace(const_iterator first, const_iterator last, size_type count, char Ch);

    Iter string& replace(const_iterator first, const_iterator last,    Iter First2, Iter Last2);
    string& replace(const_iterator first, const_iterator last, const_pointer First2, const_pointer Last2);
    string& replace(const_iterator first, const_iterator last, const_iterator First2, const_iterator Last2);

    iterator begin();
    iterator end();

    reverse_iterator rbegin();
    reverse_iterator rend()
    
 #if HAS_CPP0X
    const_iterator cbegin() const;
    const_iterator cend() const;
    const_reverse_iterator crbegin() const;
    const_reverse_iterator crend() const;
    void shrink_to_fit();
 #endif /* HAS_CPP0X */

    reference at(size_type Off)
    {    // subscript mutable sequence with checking
        if (this->_Mysize <= Off)
            _Xran();    // Off off end
        return (_Myptr()[_Off]);
    }

    reference operator[](size_type Off)
    {    // subscript mutable sequence
 #if ITERATOR_DEBUG_LEVEL == 2

        if (this->_Mysize <= Off)

            _DEBUG_ERROR("string subscript out of range");

 #elif ITERATOR_DEBUG_LEVEL == 1
        _SCL_SECURE_VALIDATE_RANGE(_Off < this->_Mysize);
 #endif /* ITERATOR_DEBUG_LEVEL == 2 */

        return (_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 (_Myptr()[_Off]);
    }

    void push_back(char Ch)
    {    // insert element at end
        insert(end(), Ch);
    }

 #if HAS_CPP0X
    void pop_back();
    reference front();
    reference back();
 #endif /* HAS_CPP0X */

    const char *c_str() const
    {
        return (_Myptr());
    }

    const char *data() const
    {    // return pointer to nonmutable array
        return (c_str());
    }

    size_type length() const;
    size_type size() const;

    size_type max_size() const;    // return maximum possible length of sequence
    void resize(size_type Newsize) //新增填充0
    {    // determine new length, padding with null elements as needed
        resize(_Newsize, char());
    }
    void resize(size_type Newsize, char Ch)
    {    // determine new length, padding with Ch elements as needed
        if (_Newsize <= this->_Mysize)
            erase(_Newsize);
        else
            append(_Newsize - this->_Mysize, Ch);
    }

    size_type capacity() const;

    void reserve(size_type Newcap = 0);

    bool empty() const;

    _SCL_INSECURE_DEPRECATE

    size_type copy(char *ptr,size_type count, size_type Off = 0) const;//最多拷贝count个字符, copy [_Off, Off + count) to [ptr, Ptr + count) 
    size_type Copy_s(char *_Dest, size_type Dest_size,    size_type count, size_type Off = 0) const;

    void swap(string& right)
    {    // exchange contents with right
        if (this == &right)
            ;    // same object, do nothing
        else if (this->_Alval == right.Alval)
        {    // same allocator, swap control information
 #if 0 < ITERATOR_DEBUG_LEVEL
            this->_Swap_all(right);
 #endif /* 0 < ITERATOR_DEBUG_LEVEL */

            _STD swap(this->_Bx, right.Bx);
            _STD swap(this->_Mysize, right.Mysize);
            _STD swap(this->_Myres, right.Myres);
        }
        else
        {    // different allocator, do multiple assigns
            string Tmp = *this;

            *this = right;
            right = Tmp;
        }
    }

    size_type find(const string& right, size_type Off = 0) const
    size_type find(const char *ptr,    size_type Off, size_type count) const
    { 
        if (count == 0 && Off <= this->_Mysize)
            return (_Off);    // null string always matches (if inside string)

        size_type Nm= this->_Mysize - Off;
        if (_Off < this->_Mysize && count <= _Nm)
        {    // room for match, look for it
            const char *Uptr, *Vptr;
            for (_Nm -= count - 1, Vptr = Myptr() + Off;
                (Uptr = Traits::find(Vptr, Nm, *ptr)) != 0; //查找首字符出现位置,只需要比较前Nm个
                _Nm -= Uptr - Vptr + 1, Vptr = Uptr + 1)
            {
                if (_Traits::compare(Uptr, ptr, count) == 0)
                    return (Uptr - Myptr());    // found a match
            }
        }

        return (npos);    // no match
    }

    size_type find(const char *ptr, size_type Off = 0) const;
    size_type find(char Ch, size_type Off = 0) const;
    size_type rfind(const string& right, size_type Off = npos) const;
    size_type rfind(const char *ptr,size_type Off, size_type count) const;
    size_type rfind(const char *ptr, size_type Off = npos) const;
    size_type rfind(char Ch, size_type Off = npos) const;

    size_type find_first_of(const string& right,size_type Off = 0) const;
    size_type find_first_of(const char *ptr, size_type Off, size_type count) const
    {    // look for one of [ptr, Ptr + count) at or after Off
        if (0 < count && Off < this->_Mysize)
        {    // room for match, look for it
            const char *const Vptr = Myptr() + this->_Mysize;
            for (const char *_Uptr = Myptr() + Off; Uptr < Vptr; ++_Uptr)
                if (_Traits::find(ptr, count, *_Uptr) != 0)
                    return (_Uptr - Myptr());    // found a match
        }
        return (npos);    // no match
    }

    size_type find_first_of(const char *ptr, size_type Off = 0) const;
    size_type find_first_of(char Ch, size_type Off = 0) const;
    size_type find_last_of(const string& right,    size_type Off = npos) const;
    size_type find_last_of(const char *ptr,    size_type Off, size_type count) const;
    size_type find_last_of(const char *ptr,    size_type Off = npos) const
    size_type find_last_of(char Ch, size_type Off = npos) const;
    size_type find_first_not_of(const string& right,size_type Off = 0) const;
    size_type find_first_not_of(const char *ptr,size_type Off, size_type count) const;

    size_type find_first_not_of(const char *ptr,size_type Off = 0) const;
    size_type find_first_not_of(char Ch, size_type Off = 0) const
    size_type find_last_not_of(const string& right,    size_type Off = npos) const
    size_type find_last_not_of(const char *ptr,        size_type Off, size_type count) const
    size_type find_last_not_of(const char *ptr,    size_type Off = npos) const
    size_type find_last_not_of(char Ch, size_type Off = npos) const
    
    string substr(size_type Off = 0, size_type count = npos) const
    {    // return [_Off, Off + count) as new string
        return (string(*this, Off, count, get_allocator()));
    }

    int compare(const string& right) const
    int compare(size_type Off, size_type N0,const string& right) const
    int compare(size_type Off,size_type N0, const string& right,
    int compare(const char *ptr) const
    int compare(size_type Off, size_type N0, const char *ptr) const
    int compare(size_type Off, size_type N0, const char *ptr, size_type count) const
    
};

string::npos = (-1);

void swap(string& Left,    string& right)
typedef string<char, char_traits<char>, allocator<char> >    string;
typedef string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> >    wstring;

 #if HAS_CPP0X
typedef string<char16_t, char_traits<char16_t>, allocator<char16_t> > u16string;
typedef string<char32_t, char_traits<char32_t>, allocator<char32_t> >    u32string;
 #endif /* HAS_CPP0X */
_

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!