zoukankan      html  css  js  c++  java
  • std::string

    #pragma once
    class _String_val //字符串存储,16字节或者大于16字节的堆指针,    // base class for basic_string to hold data
    {
    public:
        enum
            {    // length of internal buffer, [1, 16],15个字符+
            _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 */
    _
  • 相关阅读:
    条件类的设计
    条件对象的设计
    又是一个星期天,明天又要开始一周的工作了,想想上周的工作情况,不怎么理想。
    自动设置的类,版本2,在设计上比前一个版本有进步。
    最近写了一个自动保存设置的类。
    关于异常信息"未找到成员"
    表达式类的设计
    IExtenderProvider 接口的应用.实现自定义组件LilyValidateProvider
    IIS404的问题
    程序开发[对象的旅行]
  • 原文地址:https://www.cnblogs.com/wiki3d/p/7505032.html
Copyright © 2011-2022 走看看