编程便笺:Iterator(一)

  Iterator是序列概念的体现,Iterator指向值而不是值本身,因而也就具有两方面的特性,一方面Iterator可以指代值,另一方面具有序列指示特性,可以在序列中移动,指针和数组序号都具有这样的特性。Iterator(迭代器)可以说是std的灵魂所在,也可以这样说,Iterator为std的成功提供了保证。

  Iterator为什么会如此重要,因为大部分程序都是图灵完备的,所以可以分析一下图灵机,我们把图灵机分成三个部件:条带、接口部件(包括移动和数据捡取部分)、处理部件。这三个部件中,接口部件对应就是Iterator,它是条带与处理部件的纽带,从中可以看出Iterator的重要性。

  看std代码,觉得Iterator带点神奇也比较复杂,其实这也是std整体带给我们的印象。从上面图灵机的分析可以看出,Iterator要体现的意图还是比较明确的,而且拨开各种迷雾,std的实现还是非常简洁的。

  这篇文章,先来学学迭代器的写法,然后在后续文章中试着编写树、图形等特殊迭代器。

  以下的代码摘录自std vector的iterator,为了看起来清楚,做了一些简化。不是很长,就整个列在上面了。

template<class _Ty> class vector;
template<class _Ty>
class _Vector_iterator
{    
public:
    typedef  vector<_Ty> _Myvec;
    typedef _Ty* _Tptr;
    typedef _Ty value_type;
    typedef _Vector_iterator<_Ty> _Myt;
    //typedef _Vector_iterator<_Ty> _Mybase; //原来指向const_iterator,简化了。
    typedef _Ty value_type;
    typedef int difference_type;
    typedef _Ty* pointer;
    typedef _Ty& reference;

    _Vector_iterator()
    {     // construct with null vector pointer

    }

    _Vector_iterator(pointer _Ptr):_Myptr(_Ptr)
    {    // construct with pointer _Ptr
    }

    reference operator*() const
    {    // return designated object
        return ((reference)*_Myptr);
    }

    pointer operator->() const
    {    // return pointer to class object
        return (&**this);
    }

    _Myt& operator++()
    {    // preincrement
        ++_Myptr;
        return (*this);
    }

    _Myt operator++(int)
    {    // postincrement
        _Myt _Tmp = *this;
        ++*this;
        return (_Tmp);
    }

    _Myt& operator--()
    {    // predecrement
        --_Myptr;
        return (*this);
    }

    _Myt operator--(int)
    {    // postdecrement
        _Myt _Tmp = *this;
        --*this;
        return (_Tmp);
    }

    _Myt& operator+=(difference_type _Off)
    {    // increment by integer
        _Myptr += _Off;
        return (*this);
    }

    _Myt operator+(difference_type _Off) const
    {    // return this + integer
        _Myt _Tmp = *this;
        return (_Tmp += _Off);
    }

    _Myt& operator-=(difference_type _Off)
    {    // decrement by integer
        return (*this += -_Off);
    }

    _Myt operator-(difference_type _Off) const
    {    // return this - integer
        _Myt _Tmp = *this;
        return (_Tmp -= _Off);
    }

    difference_type operator-(const _Mybase& _Right) const
    {    // return difference of iterators
        return _Myptr  - _Right._Myptr;
    }

    reference operator[](difference_type _Off) const
    {    // subscript
        return (*(*this + _Off));
    }

    bool operator==(const _Myt& _Right) const
    {    // test for iterator equality
        return (_Myptr == _Right._Myptr);
    }

    bool operator!=(const _Myt& _Right) const
    {    // test for iterator inequality
        return (!(*this == _Right));
    }

    bool operator<(const _Myt& _Right) const
    {    // test if this < _Right

        return (_Myptr < _Right._Myptr);
    }

    bool operator>(const _Myt& _Right) const
    {    // test if this > _Right
        return (_Right < *this);
    }

    bool operator<=(const _Myt& _Right) const
    {    // test if this <= _Right
        return (!(_Right < *this));
    }

    bool operator>=(const _Myt& _Right) const
    {    // test if this >= _Right
        return (!(*this < _Right));
    }
    _Tptr _Myptr;
};

template<class _Ty> 
_Vector_iterator<_Ty> operator+(typename _Vector_iterator<_Ty>::difference_type _Off,
                                _Vector_iterator<_Ty> _Next)
{    // add offset to iterator
    return (_Next += _Off);
}

  从代码可以看出,其实std还是写得比较简洁。在布局、取名、注释、代码行文等方面着比较鲜明的std风格,取名的简洁以及difference_type这样的名字,可以看得出作者的一些偏好,至少是偏重数学。熟悉这些风格,代码看起来还是比较容易。

  从上面的代码可以看出,在这里iterator只是对指针作了包装,当然复杂的迭代器不会这么简单,对于iterator来说,主要是移动和取值操作,也就是 *、 ++、 --这三个操作,另外 -> 操作为复合数据提供方便。

operator * 取值代码如下,可以看出只是对指针直接求值。 

    reference operator*() const
    {    // return designated object
        return ((reference)*_Myptr);
    }

operator ++、 -- 操作有两组,分别对应于前置和后置操作。

operator ++、 -- 的前置操作代码如下,比较简单,只是把对应操作作用到指针。

    _Myt& operator++()
    {    // preincrement
        ++_Myptr;
        return (*this);
    }
    _Myt& operator--()
    {    // predecrement
        --_Myptr;
        return (*this);
    }

operator ++、 -- 的后置操作稍微复杂一些,也有点意思,代码如下。与前项操作不一样,多了一个int的参数,至于依据是什么,说实在我也没搞清楚。后缀操作   复制了一个对象,然后本身做前置操作,然后返回拷贝的对象。从这里可以看出实现后缀操作的一些特性,在这里不是等句子结束,而是在这个操作的后续操作中,如继续引用这个对象,则对这个对象并不是指向原来位置,而已经指向新的位置。

    _Myt operator++(int)
    {    // postincrement
        _Myt _Tmp = *this;
        ++*this;
        return (_Tmp);
    }
    _Myt operator--(int)
    {    // postdecrement
        _Myt _Tmp = *this;
        --*this;
        return (_Tmp);
    }

  

   下面再来看看vector的代码,与iterator一样,摘录的代码已经对原来代码做了简化。vector的代码如下,因为较长,就不展开了。

vector Code
template<class _Ty>
class vector
{    // varying size array of values
public:
    typedef vector<_Ty> _Myt;
    typedef vector<_Ty> _Mybase;
    typedef size_t size_type;
    typedef int _Dift;
    typedef _Dift difference_type;
    typedef _Ty* _Tptr;
    typedef const _Ty* _Ctptr;
    typedef _Tptr pointer;
    typedef _Ctptr const_pointer;
    typedef _Ty & _Reft;
    typedef _Reft reference;
    typedef const _Ty & const_reference;
    typedef _Ty value_type;

#define _VEC_ITER_BASE(it)    (it)._Myptr

    typedef _Vector_iterator<_Ty> iterator;

    vector() //构造函数很多,就全简化了
    {    // construct empty vector
        _Buy(0);
    }

    ~vector()
    {    // destroy the object
        _Tidy();
    }

    void reserve(size_type _Count)
    {    // determine new minimum length of allocated storage
        if (capacity() < _Count)
        {    // not enough room, reallocate
            pointer _Ptr = allocate(_Count);
            _Umove(begin(), end(), _Ptr);

            size_type _Size = size();
            if (_Myfirst != 0)
            {    // destroy and deallocate old array
                deallocate(_Myfirst, _Myend - _Myfirst);
            }

            _Myend = _Ptr + _Count;
            _Mylast = _Ptr + _Size;
            _Myfirst = _Ptr;
        }
    }

    size_type capacity() const
    {    // return current length of allocated storage
        return (_Myfirst == 0 ? 0 : _Myend - _Myfirst);
    }

    iterator begin()
    {    // return iterator for beginning of mutable sequence
        return (iterator(_Myfirst));
    }

    iterator end()
    {    // return iterator for end of mutable sequence
        return (iterator(_Mylast));
    }

    void resize(size_type _Newsize)
    {    // determine new length, padding with _Ty() elements as needed
        resize(_Newsize, _Ty());
    }

    void resize(size_type _Newsize, _Ty _Val)
    {    // determine new length, padding with _Val elements as needed
        if (size() < _Newsize)
            _Insert_n(end(), _Newsize - size(), _Val);
        else if (_Newsize < size())
            erase(begin() + _Newsize, end());
    }

    size_type size() const
    {    // return length of sequence
        return (_Myfirst == 0 ? 0 : _Mylast - _Myfirst);
    }

    size_type max_size() const
    {    // return maximum possible length of sequence
        return -1;
    }

    bool empty() const
    {    // test if sequence is empty
        return (size() == 0);
    }

    const_reference at(size_type _Pos) const
    {    // subscript nonmutable sequence with checking
        return (*(begin() + _Pos));
    }

    reference at(size_type _Pos)
    {    // subscript mutable sequence with checking
        return (*(begin() + _Pos));
    }

    const_reference operator[](size_type _Pos) const
    {    // subscript nonmutable sequence
        return (*(_Myfirst + _Pos));
    }

    reference operator[](size_type _Pos)
    {    // subscript mutable sequence
        return (*(_Myfirst + _Pos));
    }

    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));
    }

    void push_back(const _Ty& _Val)
    {    // insert element at end
        if (size() < capacity())
            _Mylast = _Ufill(_Mylast, 1, _Val);
        else
            insert(end(), _Val);
    }

    void pop_back()
    {    // erase element at end
        if (!empty())
        {    // erase last element
            _Destroy(_Ptr, _Mylast);
            --_Mylast;
        }
    }

    iterator insert(iterator _Where, const _Ty& _Val)
    {    // insert _Val at _Where
        size_type _Off = size() == 0 ? 0 : _Where - begin();
        _Insert_n(_Where, (size_type)1, _Val);
        return (begin() + _Off);
    }

    void insert(iterator _Where, size_type _Count, const _Ty& _Val)
    {    // insert _Count * _Val at _Where
        _Insert_n(_Where, _Count, _Val);
    }

    iterator erase(iterator _Where)
    {    // erase element at where
        _STDEXT unchecked_copy(_VEC_ITER_BASE(_Where) + 1, _Mylast,
            _VEC_ITER_BASE(_Where));
        _Destroy(_Mylast - 1, _Mylast);
        --_Mylast;
        return (_Where);
    }

    iterator erase(iterator _First, iterator _Last)
    {    // erase [_First, _Last)
        if (_First != _Last)
        {    // worth doing, copy down over hole
            pointer _Ptr = _STDEXT unchecked_copy(_VEC_ITER_BASE(_Last), _Mylast,
                _VEC_ITER_BASE(_First));

            _Destroy(_Ptr, _Mylast);
            _Mylast = _Ptr;
        }
        return (_First);
    }

    void clear()
    {    // erase all
        erase(begin(), end());
    }

protected:
    bool _Buy(size_type _Capacity)
    {    // allocate array with _Capacity elements
        _Myfirst = 0, _Mylast = 0, _Myend = 0;
        if (_Capacity == 0)
            return (false);
        else
        {    // nonempty array, allocate storage
            _Myfirst = allocate(_Capacity);
            _Mylast = _Myfirst;
            _Myend = _Myfirst + _Capacity;
        }
        return (true);
    }

    void _Destroy(pointer _First, pointer _Last)
    {    // destroy [_First, _Last) using allocator
    }

    void _Tidy()
    {    // free all storage
        if (_Myfirst != 0)
        {    // something to free, destroy and deallocate it
            _Destroy(_Myfirst, _Mylast);
            deallocate(_Myfirst, _Myend - _Myfirst);
        }
        _Myfirst = 0, _Mylast = 0, _Myend = 0;
    }

    template<class _Iter>
    pointer _Ucopy(_Iter _First, _Iter _Last, pointer _Ptr)
    {    // copy initializing [_First, _Last), using allocator
        return unchecked_uninitialized_copy(_First, _Last, _Ptr);
    }

    template<class _Iter>
    pointer _Umove(_Iter _First, _Iter _Last, pointer _Ptr)
    {    // move initializing [_First, _Last), using allocator
        return (  unchecked_uninitialized_move(_First, _Last,
            _Ptr));
    }

    void _Insert_n(iterator _Where,
        size_type _Count, const _Ty& _Val)
    {    // insert _Count * _Val at _Where

        _Ty _Tmp = _Val;    // in case _Val is in sequence
        size_type _Capacity = capacity();

        if (_Count == 0)
            ;
        else if (_Capacity < size() + _Count)
        {    // not enough room, reallocate
            _Capacity = max_size() - _Capacity / 2 < _Capacity
                ? 0 : _Capacity + _Capacity / 2;    // try to grow by 50%
            if (_Capacity < size() + _Count)
                _Capacity = size() + _Count;
            pointer _Newvec = allocate(_Capacity);
            pointer _Ptr = _Newvec;

            _Ptr = _Umove(_Myfirst, _VEC_ITER_BASE(_Where),
                _Newvec);    // copy prefix
            _Ptr = _Ufill(_Ptr, _Count, _Tmp);    // add new stuff
            _Umove(_VEC_ITER_BASE(_Where), _Mylast, _Ptr);    // copy suffix

            _Count += size();
            if (_Myfirst != 0)
            {    // destroy and deallocate old array
                _Destroy(_Myfirst, _Mylast);
                deallocate(_Myfirst, _Myend - _Myfirst);
            }

            _Myend = _Newvec + _Capacity;
            _Mylast = _Newvec + _Count;
            _Myfirst = _Newvec;
        }
        else if ((size_type)(_Mylast - _VEC_ITER_BASE(_Where)) < _Count)
        {    // new stuff spills off end
            _Umove(_VEC_ITER_BASE(_Where), _Mylast,
                _VEC_ITER_BASE(_Where) + _Count);    // copy suffix

            _Ufill(_Mylast, _Count - (_Mylast - _VEC_ITER_BASE(_Where)),
                _Tmp);    // insert new stuff off end
            _Mylast += _Count;

            fill(_VEC_ITER_BASE(_Where), _Mylast - _Count,
                _Tmp);    // insert up to old end
        }
        else
        {    // new stuff can all be assigned
            pointer _Oldend = _Mylast;
            _Mylast = _Umove(_Oldend - _Count, _Oldend,
                _Mylast);    // copy suffix

            _Unchecked_move_backward(_VEC_ITER_BASE(_Where), _Oldend - _Count,
                _Oldend);    // copy hole
            fill(_VEC_ITER_BASE(_Where), _VEC_ITER_BASE(_Where) + _Count,
                _Tmp);    // insert into hole
        }
    }

    pointer _Ufill(pointer _Ptr, size_type _Count, const _Ty &_Val)
    {    // copy initializing _Count * _Val, using allocator
        unchecked_uninitialized_fill_n(_Ptr, _Count, _Val);
        return (_Ptr + _Count);
    }

private: //这一段代码,是为了简化添加的
    _Tptr allocate(size_t count)
    {
        return new _Ty[count];
    }
    void deallocate(_Tptr p,size_t count)
    {
        return delete[] p;
    }

    void  fill(pointer _First, pointer _Last, const _Ty &_Val)
    {    // copy _Val through [_First, _Last)
        for (; _First != _Last; ++_First)*_First = _Val;
    }

    pointer unchecked_uninitialized_move(pointer _First, pointer _Last, pointer _Dest)
    {    // move [_First, _Last) to raw _Dest, using _Al
        return unchecked_uninitialized_copy(_First, _Last, _Dest);
    }

    pointer unchecked_uninitialized_copy(pointer _First, pointer _Last, pointer _Dest)
    {
        pointer _Next = _Dest;
        for (; _First != _Last; ++_Dest, ++_First)
            *_Dest = *_First;
        return (_Dest);
    }

    void unchecked_uninitialized_fill_n(pointer _Ptr, size_type _Count, const _Ty &_Val)
    {
        for(;_Count > 0;_Count--) *_Ptr++ = _Val; 
    }

    pointer _Unchecked_move_backward(pointer _First, pointer _Last, pointer _Dest)
    {
        while (_First != _Last) *--_Dest = *--_Last;
        return (_Dest);
    }

protected:
    pointer _Myfirst;    // pointer to beginning of array
    pointer _Mylast;    // pointer to current end of sequence
    pointer _Myend;        // pointer to end of array
};

  vector的主体函数都比较简单,有几个辅助代码稍多一些,为简单起见,把allocator整个简化了,去掉的还有反向iterator

  为了保证vector可以独立运行,把几个allocator和内存移动相关的函数,简化后并进到vector中,具体的实现方式只能説是有用,但不严谨,也不高效。而这方面std其实是着墨很多,并使用了许多技巧。但通过上面的结构,对于了解std的设计还是有帮助的。

  现在我们还是把注意力回到iterator,从代码可以看出,vector有三个字段,_Myfirst指向数组的起点,_Mylast指向数组数据的后一位置,vector会根据需要多申请一些空间,_Myend指向整个空间的末尾。_Mylast是数据越界的开始,_Myend是内存越界的开始。

protected:
    pointer _Myfirst;    // pointer to beginning of array
    pointer _Mylast;    // pointer to current end of sequence
    pointer _Myend;        // pointer to end of array

  从下面的代码可以看出,iterator构建在_Myfirst和_Mylast上,begin()以_Myfirst构建iterator,end()以_Mylast构建iterator,所以可以分别作为迭代的开始和终止条件。

    iterator begin()
    {    // return iterator for beginning of mutable sequence
        return (iterator(_Myfirst));
    }

    iterator end()
    {    // return iterator for end of mutable sequence
        return (iterator(_Mylast));
    }

  关于vector其他的就不多説,只是顺带説一下关于vector的内存扩充。从下面摘录自_Insert_n函数的语句可以看出,每一次按50%的容量内存扩充。 

else if (_Capacity < size() + _Count)
        {    // not enough room, reallocate
            _Capacity = max_size() - _Capacity / 2 < _Capacity
                ? 0 : _Capacity + _Capacity / 2;    // try to grow by 50%
            if (_Capacity < size() + _Count)
                _Capacity = size() + _Count;
            pointer _Newvec = allocate(_Capacity);

  下面是整个完整的代码,并加了一小段测试。

View Code
#include "stdafx.h"
#include "stdio.h"

#define _DESTRUCTOR(ty, ptr)    (ptr)->~ty()

template<class _T1,    class _T2>
inline    void _Construct(_T1 *_Ptr, const _T2& _Val)
{    // construct object at _Ptr with value _Val
    void *_Vptr = _Ptr;
    ::new (_Vptr) _T1(_Val);
}

template<class _Ty> inline
void _Destroy(_Ty *_Ptr)
{    // destroy object at _Ptr
    _DESTRUCTOR(_Ty, _Ptr);
}

template<> inline
void _Destroy(char *)
{    // destroy a char (do nothing)
}

template<> inline
void _Destroy(wchar_t  *)
{    // destroy a wchar_t (do nothing)
}

template<class _Ty> class vector;
template<class _Ty>
class _Vector_iterator
{    
public:
    typedef  vector<_Ty> _Myvec;
    typedef _Ty* _Tptr;
    typedef _Ty value_type;
    typedef _Vector_iterator<_Ty> _Myt;
    //typedef _Vector_iterator<_Ty> _Mybase; //原来指向const_iterator,简化了。
    typedef _Ty value_type;
    typedef int difference_type;
    typedef _Ty* pointer;
    typedef _Ty& reference;

    _Vector_iterator()
    {     // construct with null vector pointer

    }

    _Vector_iterator(pointer _Ptr):_Myptr(_Ptr)
    {    // construct with pointer _Ptr
    }

    reference operator*() const
    {    // return designated object
        return ((reference)*_Myptr);
    }

    pointer operator->() const
    {    // return pointer to class object
        return (&**this);
    }

    _Myt& operator++()
    {    // preincrement
        ++_Myptr;
        return (*this);
    }

    _Myt operator++(int)
    {    // postincrement
        _Myt _Tmp = *this;
        ++*this;
        return (_Tmp);
    }

    _Myt& operator--()
    {    // predecrement
        --(*(_Mybase *)this);
        return (*this);
    }

    _Myt operator--(int)
    {    // postdecrement
        _Myt _Tmp = *this;
        --*this;
        return (_Tmp);
    }

    _Myt& operator+=(difference_type _Off)
    {    // increment by integer
        _Myptr += _Off;
        return (*this);
    }

    _Myt operator+(difference_type _Off) const
    {    // return this + integer
        _Myt _Tmp = *this;
        return (_Tmp += _Off);
    }

    _Myt& operator-=(difference_type _Off)
    {    // decrement by integer
        return (*this += -_Off);
    }

    _Myt operator-(difference_type _Off) const
    {    // return this - integer
        _Myt _Tmp = *this;
        return (_Tmp -= _Off);
    }

    difference_type operator-(const _Mybase& _Right) const
    {    // return difference of iterators
        return _Myptr  - _Right._Myptr;
    }

    reference operator[](difference_type _Off) const
    {    // subscript
        return (*(*this + _Off));
    }

    bool operator==(const _Myt& _Right) const
    {    // test for iterator equality
        return (_Myptr == _Right._Myptr);
    }

    bool operator!=(const _Myt& _Right) const
    {    // test for iterator inequality
        return (!(*this == _Right));
    }

    bool operator<(const _Myt& _Right) const
    {    // test if this < _Right

        return (_Myptr < _Right._Myptr);
    }

    bool operator>(const _Myt& _Right) const
    {    // test if this > _Right
        return (_Right < *this);
    }

    bool operator<=(const _Myt& _Right) const
    {    // test if this <= _Right
        return (!(_Right < *this));
    }

    bool operator>=(const _Myt& _Right) const
    {    // test if this >= _Right
        return (!(*this < _Right));
    }
    _Tptr _Myptr;
};

template<class _Ty> 
_Vector_iterator<_Ty> operator+(typename _Vector_iterator<_Ty>::difference_type _Off,
                                _Vector_iterator<_Ty> _Next)
{    // add offset to iterator
    return (_Next += _Off);
}

template<class _Ty>
class vector
{    // varying size array of values
public:
    typedef vector<_Ty> _Myt;
    typedef vector<_Ty> _Mybase;
    typedef size_t size_type;
    typedef int _Dift;
    typedef _Dift difference_type;
    typedef _Ty* _Tptr;
    typedef const _Ty* _Ctptr;
    typedef _Tptr pointer;
    typedef _Ctptr const_pointer;
    typedef _Ty & _Reft;
    typedef _Reft reference;
    typedef const _Ty & const_reference;
    typedef _Ty value_type;

#define _VEC_ITER_BASE(it)    (it)._Myptr

    typedef _Vector_iterator<_Ty> iterator;

    vector() //构造函数很多,就全简化了
    {    // construct empty vector
        _Buy(0);
    }

    ~vector()
    {    // destroy the object
        _Tidy();
    }

    void reserve(size_type _Count)
    {    // determine new minimum length of allocated storage
        if (capacity() < _Count)
        {    // not enough room, reallocate
            pointer _Ptr = allocate(_Count);
            _Umove(begin(), end(), _Ptr);

            size_type _Size = size();
            if (_Myfirst != 0)
            {    // destroy and deallocate old array
                deallocate(_Myfirst, _Myend - _Myfirst);
            }

            _Myend = _Ptr + _Count;
            _Mylast = _Ptr + _Size;
            _Myfirst = _Ptr;
        }
    }

    size_type capacity() const
    {    // return current length of allocated storage
        return (_Myfirst == 0 ? 0 : _Myend - _Myfirst);
    }

    iterator begin()
    {    // return iterator for beginning of mutable sequence
        return (iterator(_Myfirst));
    }

    iterator end()
    {    // return iterator for end of mutable sequence
        return (iterator(_Mylast));
    }

    void resize(size_type _Newsize)
    {    // determine new length, padding with _Ty() elements as needed
        resize(_Newsize, _Ty());
    }

    void resize(size_type _Newsize, _Ty _Val)
    {    // determine new length, padding with _Val elements as needed
        if (size() < _Newsize)
            _Insert_n(end(), _Newsize - size(), _Val);
        else if (_Newsize < size())
            erase(begin() + _Newsize, end());
    }

    size_type size() const
    {    // return length of sequence
        return (_Myfirst == 0 ? 0 : _Mylast - _Myfirst);
    }

    size_type max_size() const
    {    // return maximum possible length of sequence
        return -1;
    }

    bool empty() const
    {    // test if sequence is empty
        return (size() == 0);
    }

    const_reference at(size_type _Pos) const
    {    // subscript nonmutable sequence with checking
        return (*(begin() + _Pos));
    }

    reference at(size_type _Pos)
    {    // subscript mutable sequence with checking
        return (*(begin() + _Pos));
    }

    const_reference operator[](size_type _Pos) const
    {    // subscript nonmutable sequence
        return (*(_Myfirst + _Pos));
    }

    reference operator[](size_type _Pos)
    {    // subscript mutable sequence
        return (*(_Myfirst + _Pos));
    }

    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));
    }

    void push_back(const _Ty& _Val)
    {    // insert element at end
        if (size() < capacity())
            _Mylast = _Ufill(_Mylast, 1, _Val);
        else
            insert(end(), _Val);
    }

    void pop_back()
    {    // erase element at end
        if (!empty())
        {    // erase last element
            _Destroy(_Ptr, _Mylast);
            --_Mylast;
        }
    }

    iterator insert(iterator _Where, const _Ty& _Val)
    {    // insert _Val at _Where
        size_type _Off = size() == 0 ? 0 : _Where - begin();
        _Insert_n(_Where, (size_type)1, _Val);
        return (begin() + _Off);
    }

    void insert(iterator _Where, size_type _Count, const _Ty& _Val)
    {    // insert _Count * _Val at _Where
        _Insert_n(_Where, _Count, _Val);
    }

    iterator erase(iterator _Where)
    {    // erase element at where
        _STDEXT unchecked_copy(_VEC_ITER_BASE(_Where) + 1, _Mylast,
            _VEC_ITER_BASE(_Where));
        _Destroy(_Mylast - 1, _Mylast);
        --_Mylast;
        return (_Where);
    }

    iterator erase(iterator _First, iterator _Last)
    {    // erase [_First, _Last)
        if (_First != _Last)
        {    // worth doing, copy down over hole
            pointer _Ptr = _STDEXT unchecked_copy(_VEC_ITER_BASE(_Last), _Mylast,
                _VEC_ITER_BASE(_First));

            _Destroy(_Ptr, _Mylast);
            _Mylast = _Ptr;
        }
        return (_First);
    }

    void clear()
    {    // erase all
        erase(begin(), end());
    }

protected:
    bool _Buy(size_type _Capacity)
    {    // allocate array with _Capacity elements
        _Myfirst = 0, _Mylast = 0, _Myend = 0;
        if (_Capacity == 0)
            return (false);
        else
        {    // nonempty array, allocate storage
            _Myfirst = allocate(_Capacity);
            _Mylast = _Myfirst;
            _Myend = _Myfirst + _Capacity;
        }
        return (true);
    }

    void _Destroy(pointer _First, pointer _Last)
    {    // destroy [_First, _Last) using allocator
    }

    void _Tidy()
    {    // free all storage
        if (_Myfirst != 0)
        {    // something to free, destroy and deallocate it
            _Destroy(_Myfirst, _Mylast);
            deallocate(_Myfirst, _Myend - _Myfirst);
        }
        _Myfirst = 0, _Mylast = 0, _Myend = 0;
    }

    template<class _Iter>
    pointer _Ucopy(_Iter _First, _Iter _Last, pointer _Ptr)
    {    // copy initializing [_First, _Last), using allocator
        return unchecked_uninitialized_copy(_First, _Last, _Ptr);
    }

    template<class _Iter>
    pointer _Umove(_Iter _First, _Iter _Last, pointer _Ptr)
    {    // move initializing [_First, _Last), using allocator
        return (  unchecked_uninitialized_move(_First, _Last,
            _Ptr));
    }

    void _Insert_n(iterator _Where,
        size_type _Count, const _Ty& _Val)
    {    // insert _Count * _Val at _Where

        _Ty _Tmp = _Val;    // in case _Val is in sequence
        size_type _Capacity = capacity();

        if (_Count == 0)
            ;
        else if (_Capacity < size() + _Count)
        {    // not enough room, reallocate
            _Capacity = max_size() - _Capacity / 2 < _Capacity
                ? 0 : _Capacity + _Capacity / 2;    // try to grow by 50%
            if (_Capacity < size() + _Count)
                _Capacity = size() + _Count;
            pointer _Newvec = allocate(_Capacity);
            pointer _Ptr = _Newvec;

            _Ptr = _Umove(_Myfirst, _VEC_ITER_BASE(_Where),
                _Newvec);    // copy prefix
            _Ptr = _Ufill(_Ptr, _Count, _Tmp);    // add new stuff
            _Umove(_VEC_ITER_BASE(_Where), _Mylast, _Ptr);    // copy suffix

            _Count += size();
            if (_Myfirst != 0)
            {    // destroy and deallocate old array
                _Destroy(_Myfirst, _Mylast);
                deallocate(_Myfirst, _Myend - _Myfirst);
            }

            _Myend = _Newvec + _Capacity;
            _Mylast = _Newvec + _Count;
            _Myfirst = _Newvec;
        }
        else if ((size_type)(_Mylast - _VEC_ITER_BASE(_Where)) < _Count)
        {    // new stuff spills off end
            _Umove(_VEC_ITER_BASE(_Where), _Mylast,
                _VEC_ITER_BASE(_Where) + _Count);    // copy suffix

            _Ufill(_Mylast, _Count - (_Mylast - _VEC_ITER_BASE(_Where)),
                _Tmp);    // insert new stuff off end
            _Mylast += _Count;

            fill(_VEC_ITER_BASE(_Where), _Mylast - _Count,
                _Tmp);    // insert up to old end
        }
        else
        {    // new stuff can all be assigned
            pointer _Oldend = _Mylast;
            _Mylast = _Umove(_Oldend - _Count, _Oldend,
                _Mylast);    // copy suffix

            _Unchecked_move_backward(_VEC_ITER_BASE(_Where), _Oldend - _Count,
                _Oldend);    // copy hole
            fill(_VEC_ITER_BASE(_Where), _VEC_ITER_BASE(_Where) + _Count,
                _Tmp);    // insert into hole
        }
    }

    pointer _Ufill(pointer _Ptr, size_type _Count, const _Ty &_Val)
    {    // copy initializing _Count * _Val, using allocator
        unchecked_uninitialized_fill_n(_Ptr, _Count, _Val);
        return (_Ptr + _Count);
    }

private: //这一段代码,是为了简化添加的
    _Tptr allocate(size_t count)
    {
        return new _Ty[count];
    }
    void deallocate(_Tptr p,size_t count)
    {
        return delete[] p;
    }

    void  fill(pointer _First, pointer _Last, const _Ty &_Val)
    {    // copy _Val through [_First, _Last)
        for (; _First != _Last; ++_First)*_First = _Val;
    }

    pointer unchecked_uninitialized_move(pointer _First, pointer _Last, pointer _Dest)
    {    // move [_First, _Last) to raw _Dest, using _Al
        return unchecked_uninitialized_copy(_First, _Last, _Dest);
    }

    pointer unchecked_uninitialized_copy(pointer _First, pointer _Last, pointer _Dest)
    {
        pointer _Next = _Dest;
        for (; _First != _Last; ++_Dest, ++_First)
            *_Dest = *_First;
        return (_Dest);
    }

    void unchecked_uninitialized_fill_n(pointer _Ptr, size_type _Count, const _Ty &_Val)
    {
        for(;_Count > 0;_Count--) *_Ptr++ = _Val; 
    }

    pointer _Unchecked_move_backward(pointer _First, pointer _Last, pointer _Dest)
    {
        while (_First != _Last) *--_Dest = *--_Last;
        return (_Dest);
    }

protected:
    pointer _Myfirst;    // pointer to beginning of array
    pointer _Mylast;    // pointer to current end of sequence
    pointer _Myend;        // pointer to end of array
};

int _tmain(int argc, _TCHAR* argv[])
{
    vector<int> v;
    v.push_back(1);
    v.push_back(2);

    for(int i=0;i<v.size();i++)
        printf("v%d: %d\r\n",i,v[i]);

    vector<int>::iterator tr;
    for( tr = v.begin();tr!=v.end();tr++)
        printf("v%d: %d\r\n",tr - v.begin(),*tr);

    getchar();

    return 1;
}

   

posted @ 2012-12-24 10:47  走在溪边  阅读(2313)  评论(0编辑  收藏  举报