程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++ STL 源碼學習(之deque篇)

C++ STL 源碼學習(之deque篇)

編輯:C++入門知識

C++ STL 源碼學習(之deque篇)


stl_deque.h

/** Class invariants:
 *  For any nonsingular iterator i:
 *    i.node is the address of an element in the map array.  The
 *      contents of i.node is a pointer to the beginning of a node.
 *    i.first == *(i.node)
 *    i.last  == i.first + node_size
 *    i.cur is a pointer in the range [i.first, i.last).  NOTE:
 *      the implication of this is that i.cur is always a dereferenceable
 *      pointer, even if i is a past-the-end iterator.
 *  Start and Finish are always nonsingular iterators.  NOTE: this means
 *    that an empty deque must have one node, and that a deque
 *    with N elements, where N is the buffer size, must have two nodes.
 *  For every node other than start.node and finish.node, every element
 *    in the node is an initialized object.  If start.node == finish.node,
 *    then [start.cur, finish.cur) are initialized objects, and
 *    the elements outside that range are uninitialized storage.  Otherwise,
 *    [start.cur, start.last) and [finish.first, finish.cur) are initialized
 *    objects, and [start.first, start.cur) and [finish.cur, finish.last)
 *    are uninitialized storage.
 *  [map, map + map_size) is a valid, non-empty range.
 *  [start.node, finish.node] is a valid range contained within
 *    [map, map + map_size).
 *  A pointer in the range [map, map + map_size) points to an allocated node
 *    if and only if the pointer is in the range [start.node, finish.node].
 */

/// Note: this function is simply a kludge to work around several compilers'
///  bugs in handling constant expressions.
inline size_t __deque_buf_size(size_t __size)
{
    return __size < 512 ? size_t(512 / __size) : size_t(1);   ///計算deque每個區段大小
}

template 
struct _Deque_iterator
{
    typedef _Deque_iterator<_Tp, _Tp&, _Tp*>             iterator;
    typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
    static size_t _S_buffer_size()
    {
        return __deque_buf_size(sizeof(_Tp));
    }

    typedef random_access_iterator_tag iterator_category;
    typedef _Tp value_type;
    typedef _Ptr pointer;
    typedef _Ref reference;
    typedef size_t size_type;
    typedef ptrdiff_t difference_type;
    typedef _Tp** _Map_pointer;

    typedef _Deque_iterator _Self;

    ///指向迭代器所在區段頭指針在區段中控器(一個按序存儲區段頭指針
    ///的數組,也可以理解為區段位置的索引表)中的存儲位置,存儲順序決定了
    ///各個區段的順序,據此來控制迭代器跨區段移動
    _Map_pointer _M_node;
    _Tp* _M_cur;   ///指向迭代器實指位置

    _Tp* _M_first;    ///指向迭代器所在區段的頭指針,由*_M_node可得
    ///指向超出迭代器所在區段的第一個指針,由_M_first與區段大小求和可得
    _Tp* _M_last;

    _Deque_iterator(_Tp* __x, _Map_pointer __y)
        : _M_cur(__x), _M_first(*__y),
          _M_last(*__y + _S_buffer_size()), _M_node(__y) {}

    _Deque_iterator() : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) {}
    _Deque_iterator(const iterator& __x)
        : _M_cur(__x._M_cur), _M_first(__x._M_first),
          _M_last(__x._M_last), _M_node(__x._M_node) {}

    reference operator*() const
    {
        return *_M_cur;
    }
    pointer operator->() const
    {
        return _M_cur;
    }

    difference_type operator-(const _Self& __x) const
    {
        ///_M_node - __x._M_node-1計算x和本迭代器之間相隔的完整區段數
        return difference_type(_S_buffer_size()) * (_M_node - __x._M_node - 1) +
               (_M_cur - _M_first) + (__x._M_last - __x._M_cur);
    }

    _Self& operator++()
    {
        ++_M_cur;
        if (_M_cur == _M_last)      ///已超出該區段,需要向下一個區段移動
        {
            _M_set_node(_M_node + 1);    ///修改中控器位置記錄
            _M_cur = _M_first;            ///指向下一個區段的頭指針
        }
        return *this;
    }
    _Self operator++(int)
    {
        _Self __tmp = *this;
        ++*this;
        return __tmp;
    }

    _Self& operator--()
    {
        if (_M_cur == _M_first)       ///位於頭指針,需要向上一個區段移動
        {
            _M_set_node(_M_node - 1);
            _M_cur = _M_last;              ///指向上一個區段超出末尾的第一個指針
        }

        --_M_cur;                            ///向前移動一位
        return *this;
    }
    _Self operator--(int)
    {
        _Self __tmp = *this;
        --*this;
        return __tmp;
    }

    ///為使迭代器成為隨機迭代器所做的工作
    _Self& operator+=(difference_type __n)
    {
        difference_type __offset = __n + (_M_cur - _M_first);
        if (__offset >= 0 && __offset < difference_type(_S_buffer_size()))
        {
            ///向後移動,而且並未超出目前所在區段
            _M_cur += __n;
        }
        else
        {
            ///計算需要前移/後移的區段數
            difference_type __node_offset =
                __offset > 0 ? __offset / difference_type(_S_buffer_size())
                : -difference_type((-__offset - 1) / _S_buffer_size()) - 1;

            _M_set_node(_M_node + __node_offset);

            ///計算迭代器確指位置
            _M_cur = _M_first +
                     (__offset - __node_offset * difference_type(_S_buffer_size()));
        }
        return *this;
    }

    _Self operator+(difference_type __n) const
    {
        _Self __tmp = *this;
        return __tmp += __n;
    }

    _Self& operator-=(difference_type __n)
    {
        return *this += -__n;
    }

    _Self operator-(difference_type __n) const
    {
        _Self __tmp = *this;
        return __tmp -= __n;
    }

    reference operator[](difference_type __n) const
    {
        return *(*this + __n);
    }

    bool operator==(const _Self& __x) const
    {
        return _M_cur == __x._M_cur;
    }
    bool operator!=(const _Self& __x) const
    {
        return !(*this == __x);
    }

    ///按迭代器所在區段頭指針在中控器中的存儲位置進行比較
    ///若在同一區段,再比較迭代器確指指針
    bool operator<(const _Self& __x) const
    {
        return (_M_node == __x._M_node) ?
               (_M_cur < __x._M_cur) : (_M_node < __x._M_node);
    }

    bool operator>(const _Self& __x) const
    {
        return __x < *this;
    }
    bool operator<=(const _Self& __x) const
    {
        return !(__x < *this);
    }
    bool operator>=(const _Self& __x) const
    {
        return !(*this < __x);
    }

    void _M_set_node(_Map_pointer __new_node)
    {
        ///設置迭代器所在區段
        _M_node = __new_node;
        _M_first = *__new_node;
        _M_last = _M_first + difference_type(_S_buffer_size());
    }
};

template 
inline _Deque_iterator<_Tp, _Ref, _Ptr>
operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x)
{
    return __x + __n;
}

/// Deque base class.  Its constructor and destructor allocate
/// (but don't initialize) storage.  This makes exception safety easier.
template 
class _Deque_base
{
public:
    typedef _Deque_iterator<_Tp,_Tp&,_Tp*>             iterator;
    typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;

    typedef _Alloc allocator_type;
    allocator_type get_allocator() const
    {
        return allocator_type();
    }

    _Deque_base(const allocator_type&, size_t __num_elements)
        : _M_map(0), _M_map_size(0),  _M_start(), _M_finish()
    {
        _M_initialize_map(__num_elements);
    }
    _Deque_base(const allocator_type&)
        : _M_map(0), _M_map_size(0),  _M_start(), _M_finish() {}
    ~_Deque_base();

protected:
    void _M_initialize_map(size_t);
    void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish);
    void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish);

    ///默認中控器大小為8,即可創建8個區段
    enum { _S_initial_map_size = 8 };

protected:
    _Tp** _M_map;              ///中控器,一個指向_Tp類型數組指針的數組

    ///中控器大小,決定了不擴充中控器時最多可容納的區段數
    size_t _M_map_size;
    iterator _M_start;        ///起始迭代器
    iterator _M_finish;        ///結束迭代器,其實際指向最後一個元素的下一個位置

    typedef simple_alloc<_Tp, _Alloc>  _Node_alloc_type;
    typedef simple_alloc<_Tp*, _Alloc> _Map_alloc_type;

    ///每次分配、回收一個區段
    _Tp* _M_allocate_node()
    {
        return _Node_alloc_type::allocate(__deque_buf_size(sizeof(_Tp)));
    }
    void _M_deallocate_node(_Tp* __p)
    {
        _Node_alloc_type::deallocate(__p, __deque_buf_size(sizeof(_Tp)));
    }

    ///中控器內存的分配與回收,實際是Tp* 類型數組的分配、回收
    _Tp** _M_allocate_map(size_t __n)
    {
        return _Map_alloc_type::allocate(__n);
    }
    void _M_deallocate_map(_Tp** __p, size_t __n)
    {
        _Map_alloc_type::deallocate(__p, __n);
    }
};

/// Non-inline member functions from _Deque_base.

template 
_Deque_base<_Tp,_Alloc>::~_Deque_base()
{
    if (_M_map)
    {
        ///回收各個區段的內存
        _M_destroy_nodes(_M_start._M_node, _M_finish._M_node + 1);

        ///回收中控器的內存
        _M_deallocate_map(_M_map, _M_map_size);
    }
}

///初始化中控器
template 
void
_Deque_base<_Tp,_Alloc>::_M_initialize_map(size_t __num_elements)
{
    ///計算所需的區段數目,從而決定中控器的大小
    size_t __num_nodes =
        __num_elements / __deque_buf_size(sizeof(_Tp)) + 1;

    ///計算中控器大小,並為之分配內存(至少為其分配的單元要多於區段數目兩個)
    ///為了避免擴充過程中過多的重新分配中控器而導致的效率降低
    _M_map_size = max((size_t) _S_initial_map_size, __num_nodes + 2);
    _M_map = _M_allocate_map(_M_map_size);

///使用中控器的中間部分,這樣可以保證前後都可以繼續擴充區段
    _Tp** __nstart = _M_map + (_M_map_size - __num_nodes) / 2;
    _Tp** __nfinish = __nstart + __num_nodes;

    try
    {
        _M_create_nodes(__nstart, __nfinish);
    }
    catch(...)
    {
        _M_deallocate_map(_M_map, _M_map_size);
        _M_map = 0;
        _M_map_size = 0;
    }

    ///設置起始、終止迭代器的指向
    _M_start._M_set_node(__nstart);
    _M_finish._M_set_node(__nfinish - 1);
    _M_start._M_cur = _M_start._M_first;
    _M_finish._M_cur = _M_finish._M_first +
                       __num_elements % __deque_buf_size(sizeof(_Tp));
}

///為各個區段分配內存
template 
void _Deque_base<_Tp,_Alloc>::_M_create_nodes(_Tp** __nstart, _Tp** __nfinish)
{
    _Tp** __cur;
    try
    {
        for (__cur = __nstart; __cur < __nfinish; ++__cur)
            *__cur = _M_allocate_node();
    }
    catch(...)
    {
        _M_destroy_nodes(__nstart, __cur);
    }
}

///回收各個區段的內存
template 
void
_Deque_base<_Tp,_Alloc>::_M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish)
{
    for (_Tp** __n = __nstart; __n < __nfinish; ++__n)
        _M_deallocate_node(*__n);
}

template 
class deque : protected _Deque_base<_Tp, _Alloc>
{

    /// requirements:

    __STL_CLASS_REQUIRES(_Tp, _Assignable);

    typedef _Deque_base<_Tp, _Alloc> _Base;
public:                         /// Basic types
    typedef _Tp value_type;
    typedef value_type* pointer;
    typedef const value_type* const_pointer;
    typedef value_type& reference;
    typedef const value_type& const_reference;
    typedef size_t size_type;
    typedef ptrdiff_t difference_type;

    typedef typename _Base::allocator_type allocator_type;
    allocator_type get_allocator() const
    {
        return _Base::get_allocator();
    }

public:                         /// Iterators
    typedef typename _Base::iterator       iterator;
    typedef typename _Base::const_iterator const_iterator;

    typedef reverse_iterator
            const_reverse_iterator;
    typedef reverse_iterator
    reverse_iterator;

protected:                      /// Internal typedefs
    typedef pointer* _Map_pointer;
    static size_t _S_buffer_size()
    {
        return __deque_buf_size(sizeof(_Tp));
    }

protected:
    using _Base::_M_initialize_map;
    using _Base::_M_create_nodes;
    using _Base::_M_destroy_nodes;
    using _Base::_M_allocate_node;
    using _Base::_M_deallocate_node;
    using _Base::_M_allocate_map;
    using _Base::_M_deallocate_map;

    using _Base::_M_map;
    using _Base::_M_map_size;
    using _Base::_M_start;
    using _Base::_M_finish;

public:                         /// Basic accessors
    iterator begin()
    {
        return _M_start;
    }
    iterator end()
    {
        return _M_finish;
    }
    const_iterator begin() const
    {
        return _M_start;
    }
    const_iterator end() const
    {
        return _M_finish;
    }

    reverse_iterator rbegin()
    {
        return reverse_iterator(_M_finish);
    }
    reverse_iterator rend()
    {
        return reverse_iterator(_M_start);
    }
    const_reverse_iterator rbegin() const
    {
        return const_reverse_iterator(_M_finish);
    }
    const_reverse_iterator rend() const
    {
        return const_reverse_iterator(_M_start);
    }

    reference operator[](size_type __n)
    {
        return _M_start[difference_type(__n)];
    }
    const_reference operator[](size_type __n) const
    {
        return _M_start[difference_type(__n)];
    }

    reference front()
    {
        return *_M_start;
    }
    reference back()
    {
        iterator __tmp = _M_finish;
        --__tmp;
        return *__tmp;
    }

    const_reference front() const
    {
        return *_M_start;
    }
    const_reference back() const
    {
        const_iterator __tmp = _M_finish;
        --__tmp;
        return *__tmp;
    }

    size_type size() const
    {
        return _M_finish - _M_start;
    }
    size_type max_size() const
    {
        return size_type(-1);
    }
    bool empty() const
    {
        return _M_finish == _M_start;
    }

public:                         /// Constructor, destructor.
    explicit deque(const allocator_type& __a = allocator_type())
        : _Base(__a, 0) {}
    deque(const deque& __x) : _Base(__x.get_allocator(), __x.size())
    {
        uninitialized_copy(__x.begin(), __x.end(), _M_start);
    }
    deque(size_type __n, const value_type& __value,
          const allocator_type& __a = allocator_type()) : _Base(__a, __n)
    {
        _M_fill_initialize(__value);
    }
    explicit deque(size_type __n) : _Base(allocator_type(), __n)
    {
        _M_fill_initialize(value_type());
    }

    /// Check whether it's an integral type.  If so, it's not an iterator.
    template 
    deque(_InputIterator __first, _InputIterator __last,
          const allocator_type& __a = allocator_type()) : _Base(__a)
    {
        ///根據型別做不同的處理
        typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
        _M_initialize_dispatch(__first, __last, _Integral());
    }

    template 
    void _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type)
    {
        _M_initialize_map(__n);
        _M_fill_initialize(__x);
    }

    template 
    void _M_initialize_dispatch(_InputIter __first, _InputIter __last,
                                __false_type)
    {
        _M_range_initialize(__first, __last, __ITERATOR_CATEGORY(__first));
    }
    ///一次析構每個對象元素,回收內存交由基類處理
    ~deque()
    {
        destroy(_M_start, _M_finish);
    }

    deque& operator= (const deque& __x)
    {
        const size_type __len = size();
        if (&__x != this)
        {
            if (__len >= __x.size())
                erase(copy(__x.begin(), __x.end(), _M_start), _M_finish);
            else
            {
                const_iterator __mid = __x.begin() + difference_type(__len);
                copy(__x.begin(), __mid, _M_start);
                insert(_M_finish, __mid, __x.end());
            }
        }
        return *this;
    }

    void swap(deque& __x)
    {
        __STD::swap(_M_start, __x._M_start);
        __STD::swap(_M_finish, __x._M_finish);
        __STD::swap(_M_map, __x._M_map);
        __STD::swap(_M_map_size, __x._M_map_size);
    }

public:
    /// assign(), a generalized assignment member function.  Two
    /// versions: one that takes a count, and one that takes a range.
    /// The range version is a member template, so we dispatch on whether
    /// or not the type is an integer.

    void _M_fill_assign(size_type __n, const _Tp& __val)
    {
        if (__n > size())
        {
            fill(begin(), end(), __val);
            insert(end(), __n - size(), __val);
        }
        else
        {
            erase(begin() + __n, end());
            fill(begin(), end(), __val);
        }
    }

    void assign(size_type __n, const _Tp& __val)
    {
        _M_fill_assign(__n, __val);
    }

    template 
    void assign(_InputIterator __first, _InputIterator __last)
    {
        typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
        _M_assign_dispatch(__first, __last, _Integral());
    }

private:                        /// helper functions for assign()

    template 
    void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
    {
        _M_fill_assign((size_type) __n, (_Tp) __val);
    }

    template 
    void _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
                            __false_type)
    {

        ///根據迭代器不同采取不同的方法,以取得最佳效率
        _M_assign_aux(__first, __last, __ITERATOR_CATEGORY(__first));
    }

    template 
    void _M_assign_aux(_InputIterator __first, _InputIterator __last,
                       input_iterator_tag);

    template 
    void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
                       forward_iterator_tag)
    {
        size_type __len = 0;
        distance(__first, __last, __len);
        if (__len > size())
        {
            _ForwardIterator __mid = __first;
            advance(__mid, size());
            copy(__first, __mid, begin());
            insert(end(), __mid, __last);
        }
        else
            erase(copy(__first, __last, begin()), end());
    }

public:                         /// push_* and pop_*

    void push_back(const value_type& __t)
    {
        if (_M_finish._M_cur != _M_finish._M_last - 1)
        {
            ///結束迭代器所指位置之後,該區段尚有空間
            construct(_M_finish._M_cur, __t);
            ++_M_finish._M_cur;
        }
        else               ///已到最後一個區段區段末尾,需另行處理
            _M_push_back_aux(__t);
    }

    void push_back()
    {
        if (_M_finish._M_cur != _M_finish._M_last - 1)
        {
            construct(_M_finish._M_cur);
            ++_M_finish._M_cur;
        }
        else
            _M_push_back_aux();
    }

    void push_front(const value_type& __t)
    {
        if (_M_start._M_cur != _M_start._M_first)
        {
            ///起始迭代器所指為止之前該區段尚有空間
            construct(_M_start._M_cur - 1, __t);
            --_M_start._M_cur;
        }
        else            ///在第一個區段頭部插入,需另行處理
            _M_push_front_aux(__t);
    }

    void push_front()
    {
        if (_M_start._M_cur != _M_start._M_first)
        {
            construct(_M_start._M_cur - 1);
            --_M_start._M_cur;
        }
        else
            _M_push_front_aux();
    }


    void pop_back()
    {
        if (_M_finish._M_cur != _M_finish._M_first)
        {
            ///最後一個元素不是最後一個區段的第一個元素
            --_M_finish._M_cur;
            destroy(_M_finish._M_cur);
        }
        else
            _M_pop_back_aux();
    }

    void pop_front()
    {
        if (_M_start._M_cur != _M_start._M_last - 1)
        {
            destroy(_M_start._M_cur);
            ++_M_start._M_cur;
        }
        else
            _M_pop_front_aux();
    }

public:                         /// Insert

///都是通過函數調用實現的,很清晰
    iterator insert(iterator position, const value_type& __x)
    {
        if (position._M_cur == _M_start._M_cur)
        {
            push_front(__x);
            return _M_start;
        }
        else if (position._M_cur == _M_finish._M_cur)
        {
            push_back(__x);
            iterator __tmp = _M_finish;
            --__tmp;
            return __tmp;
        }
        else
        {
            return _M_insert_aux(position, __x);
        }
    }

    iterator insert(iterator __position)
    {
        return insert(__position, value_type());
    }

    void insert(iterator __pos, size_type __n, const value_type& __x)
    {
        _M_fill_insert(__pos, __n, __x);
    }

    void _M_fill_insert(iterator __pos, size_type __n, const value_type& __x);

    /// Check whether it's an integral type.  If so, it's not an iterator.
    template 
    void insert(iterator __pos, _InputIterator __first, _InputIterator __last)
    {
        typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
        _M_insert_dispatch(__pos, __first, __last, _Integral());
    }

    template 
    void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x,
                            __true_type)
    {
        _M_fill_insert(__pos, (size_type) __n, (value_type) __x);
    }

    template 
    void _M_insert_dispatch(iterator __pos,
                            _InputIterator __first, _InputIterator __last,
                            __false_type)
    {
        insert(__pos, __first, __last, __ITERATOR_CATEGORY(__first));
    }

    void resize(size_type __new_size, const value_type& __x)
    {
        const size_type __len = size();
        if (__new_size < __len)
            erase(_M_start + __new_size, _M_finish);
        else
            insert(_M_finish, __new_size - __len, __x);
    }

    void resize(size_type new_size)
    {
        resize(new_size, value_type());
    }

public:                         /// Erase
    iterator erase(iterator __pos)
    {

        iterator __next = __pos;
        ++__next;
        difference_type __index = __pos - _M_start;
        if (size_type(__index) < (this->size() >> 1))      ///位於deque前半段
        {
            copy_backward(_M_start, __pos, __next);
            pop_front();
        }
        else
        {
            copy(__next, _M_finish, __pos);
            pop_back();
        }
        return _M_start + __index;
    }

    iterator erase(iterator __first, iterator __last);
    void clear();

protected:                        /// Internal construction/destruction

    void _M_fill_initialize(const value_type& __value);

    template 
    void _M_range_initialize(_InputIterator __first, _InputIterator __last,
                             input_iterator_tag);

    template 
    void _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
                             forward_iterator_tag);

protected:                        /// Internal push_* and pop_*

    void _M_push_back_aux(const value_type&);
    void _M_push_back_aux();
    void _M_push_front_aux(const value_type&);
    void _M_push_front_aux();
    void _M_pop_back_aux();
    void _M_pop_front_aux();

protected:                        /// Internal insert functions

    template 
    void insert(iterator __pos, _InputIterator __first, _InputIterator __last,
                input_iterator_tag);

    template 
    void insert(iterator __pos,
                _ForwardIterator __first, _ForwardIterator __last,
                forward_iterator_tag);

    iterator _M_insert_aux(iterator __pos, const value_type& __x);
    iterator _M_insert_aux(iterator __pos);
    void _M_insert_aux(iterator __pos, size_type __n, const value_type& __x);

    template 
    void _M_insert_aux(iterator __pos,
                       _ForwardIterator __first, _ForwardIterator __last,
                       size_type __n);

    void _M_insert_aux(iterator __pos,
                       const value_type* __first, const value_type* __last,
                       size_type __n);

    void _M_insert_aux(iterator __pos,
                       const_iterator __first, const_iterator __last,
                       size_type __n);

    iterator _M_reserve_elements_at_front(size_type __n)
    {
        size_type __vacancies = _M_start._M_cur - _M_start._M_first;
        if (__n > __vacancies)
            _M_new_elements_at_front(__n - __vacancies);
        return _M_start - difference_type(__n);
    }

    iterator _M_reserve_elements_at_back(size_type __n)
    {
        size_type __vacancies = (_M_finish._M_last - _M_finish._M_cur) - 1;
        if (__n > __vacancies)
            _M_new_elements_at_back(__n - __vacancies);
        return _M_finish + difference_type(__n);
    }

    void _M_new_elements_at_front(size_type __new_elements);
    void _M_new_elements_at_back(size_type __new_elements);

protected:                      /// Allocation of _M_map and nodes

    /// Makes sure the _M_map has space for new nodes.  Does not actually
    ///  add the nodes.  Can invalidate _M_map pointers.  (And consequently,
    ///  deque iterators.)
    void _M_reserve_map_at_back (size_type __nodes_to_add = 1)
    {
        if (__nodes_to_add + 1 > _M_map_size - (_M_finish._M_node - _M_map))
            _M_reallocate_map(__nodes_to_add, false);
    }

    void _M_reserve_map_at_front (size_type __nodes_to_add = 1)
    {
        if (__nodes_to_add > size_type(_M_start._M_node - _M_map))
            _M_reallocate_map(__nodes_to_add, true);
    }

    void _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front);
};

/// Non-inline member functions

template 
template 
void deque<_Tp, _Alloc>
::_M_assign_aux(_InputIter __first, _InputIter __last, input_iterator_tag)
{
    iterator __cur = begin();
    for ( ; __first != __last && __cur != end(); ++__cur, ++__first)
        *__cur = *__first;
    if (__first == __last)
        erase(__cur, end());
    else
        insert(end(), __first, __last);
}

template 
void deque<_Tp, _Alloc>::_M_fill_insert(iterator __pos,
                                        size_type __n, const value_type& __x)
{
    if (__pos._M_cur == _M_start._M_cur)
    {
        iterator __new_start = _M_reserve_elements_at_front(__n);
        try
        {
            uninitialized_fill(__new_start, _M_start, __x);
            _M_start = __new_start;
        }
        catch(...)
        {
            _M_destroy_nodes(__new_start._M_node, _M_start._M_node);
            throw;
        }
    }
    else if (__pos._M_cur == _M_finish._M_cur)
    {
        iterator __new_finish = _M_reserve_elements_at_back(__n);
        try
        {
            uninitialized_fill(_M_finish, __new_finish, __x);
            _M_finish = __new_finish;
        }
        catch(...)
        {
            _M_destroy_nodes(_M_finish._M_node + 1,
                             __new_finish._M_node + 1);
            throw;
        }
    }
    else
        _M_insert_aux(__pos, __n, __x);
}

template 
void deque<_Tp, _Alloc>::insert(iterator __pos,
                                const value_type* __first,
                                const value_type* __last)
{
    size_type __n = __last - __first;
    if (__pos._M_cur == _M_start._M_cur)
    {
        iterator __new_start = _M_reserve_elements_at_front(__n);
        try
        {
            uninitialized_copy(__first, __last, __new_start);
            _M_start = __new_start;
        }
        catch(...)
        {
            _M_destroy_nodes(__new_start._M_node, _M_start._M_node);
            throw;
        }

    }
    else if (__pos._M_cur == _M_finish._M_cur)
    {
        iterator __new_finish = _M_reserve_elements_at_back(__n);
        try
        {
            uninitialized_copy(__first, __last, _M_finish);
            _M_finish = __new_finish;
        }
        catch(...)
        {
            _M_destroy_nodes(_M_finish._M_node + 1,
                             __new_finish._M_node + 1);
            throw;
        }

    }
    else
        _M_insert_aux(__pos, __first, __last, __n);
}

template 
void deque<_Tp,_Alloc>::insert(iterator __pos,
                               const_iterator __first, const_iterator __last)
{
    size_type __n = __last - __first;
    if (__pos._M_cur == _M_start._M_cur)
    {
        iterator __new_start = _M_reserve_elements_at_front(__n);
        try
        {
            uninitialized_copy(__first, __last, __new_start);
            _M_start = __new_start;
        }
        catch(...)
        {
            _M_destroy_nodes(__new_start._M_node, _M_start._M_node);
            throw;
        }

    }
    else if (__pos._M_cur == _M_finish._M_cur)
    {
        iterator __new_finish = _M_reserve_elements_at_back(__n);
        try
        {
            uninitialized_copy(__first, __last, _M_finish);
            _M_finish = __new_finish;
        }
        catch(...)
        {
            _M_destroy_nodes(_M_finish._M_node + 1,
                             __new_finish._M_node + 1);
            throw;
        }

    }
    else
        _M_insert_aux(__pos, __first, __last, __n);
}

template 
typename deque<_Tp,_Alloc>::iterator
deque<_Tp,_Alloc>::erase(iterator __first, iterator __last)
{
    if (__first == _M_start && __last == _M_finish)
    {
        clear();
        return _M_finish;
    }
    else
    {
        difference_type __n = __last - __first;
        difference_type __elems_before = __first - _M_start;
        if (__elems_before < difference_type((this->size() - __n) / 2))
        {
            ///位於刪除區間之間的元素少於之後的元素
            copy_backward(_M_start, __first, __last);
            iterator __new_start = _M_start + __n;
            ///析構多余元素
            destroy(_M_start, __new_start);
            ///回收未用區段
            _M_destroy_nodes(__new_start._M_node, _M_start._M_node);
            _M_start = __new_start;
        }
        else
        {
            copy(__last, _M_finish, __first);
            iterator __new_finish = _M_finish - __n;
            destroy(__new_finish, _M_finish);
            _M_destroy_nodes(__new_finish._M_node + 1, _M_finish._M_node + 1);
            _M_finish = __new_finish;
        }
        return _M_start + __elems_before;
    }
}

template 
void deque<_Tp,_Alloc>::clear()
{
    ///依次析構每個區段的對象元素,然後回收析構完的區段

    for (_Map_pointer __node = _M_start._M_node + 1;
            __node < _M_finish._M_node;
            ++__node)          ///對完整區段進行統一處理
    {
        destroy(*__node, *__node + _S_buffer_size());
        _M_deallocate_node(*__node);
    }

    if (_M_start._M_node != _M_finish._M_node)
    {
        ///所有元素分布在不少於兩個區段上,對尚未處理的第一個和最後一個
        ///區段進行處理
        destroy(_M_start._M_cur, _M_start._M_last);
        destroy(_M_finish._M_first, _M_finish._M_cur);
        _M_deallocate_node(_M_finish._M_first);
    }
    else
        destroy(_M_start._M_cur, _M_finish._M_cur);

    _M_finish = _M_start;
}

/// Precondition: _M_start and _M_finish have already been initialized,
/// but none of the deque's elements have yet been constructed.
template 
void deque<_Tp,_Alloc>::_M_fill_initialize(const value_type& __value)
{
    _Map_pointer __cur;
    try
    {
        ///對完整區段統一處理
        for (__cur = _M_start._M_node; __cur < _M_finish._M_node; ++__cur)
            uninitialized_fill(*__cur, *__cur + _S_buffer_size(), __value);

        ///處理最後一個區段
        uninitialized_fill(_M_finish._M_first, _M_finish._M_cur, __value);
    }
    catch(...)
    {
        destroy(_M_start, iterator(*__cur, __cur));
        throw;
    }

}

template  template 
void deque<_Tp,_Alloc>::_M_range_initialize(_InputIterator __first,
        _InputIterator __last,
        input_iterator_tag)
{
    _M_initialize_map(0);
    try
    {
        for ( ; __first != __last; ++__first)
            push_back(*__first);
    }
    catch(...)
    {
        clear();
        throw;
    }
}

template  template 
void deque<_Tp,_Alloc>::_M_range_initialize(_ForwardIterator __first,
        _ForwardIterator __last,
        forward_iterator_tag)
{
    size_type __n = 0;
    distance(__first, __last, __n);
    _M_initialize_map(__n);

    _Map_pointer __cur_node;
    try
    {
        for (__cur_node = _M_start._M_node;
                __cur_node < _M_finish._M_node;
                ++__cur_node)
        {
            _ForwardIterator __mid = __first;
            advance(__mid, _S_buffer_size());
            uninitialized_copy(__first, __mid, *__cur_node);
            __first = __mid;
        }
        uninitialized_copy(__first, __last, _M_finish._M_first);
    }
    catch(...)
    {
        destroy(_M_start, iterator(*__cur_node, __cur_node));
        throw;
    }

}

/// Called only if _M_finish._M_cur == _M_finish._M_last - 1.
template 
void deque<_Tp,_Alloc>::_M_push_back_aux(const value_type& __t)
{
    value_type __t_copy = __t;
    _M_reserve_map_at_back();    ///為中控器後面補充空間

    ///在最後一個區段後面再分配一個區段
    *(_M_finish._M_node + 1) = _M_allocate_node();

    ///在新分配的區段上創建對象,調整deque相關狀態
    try
    {
        construct(_M_finish._M_cur, __t_copy);
        _M_finish._M_set_node(_M_finish._M_node + 1);
        _M_finish._M_cur = _M_finish._M_first;
    }
    catch(...)
    {
        _M_deallocate_node(*(_M_finish._M_node + 1));
        throw;
    }

}

/// Called only if _M_finish._M_cur == _M_finish._M_last - 1.
template 
void deque<_Tp,_Alloc>::_M_push_back_aux()
{
    _M_reserve_map_at_back();
    *(_M_finish._M_node + 1) = _M_allocate_node();
    try
    {
        construct(_M_finish._M_cur);
        _M_finish._M_set_node(_M_finish._M_node + 1);
        _M_finish._M_cur = _M_finish._M_first;
    }
    catch(...)
    {
        _M_deallocate_node(*(_M_finish._M_node + 1));
        throw;
    }

}

///和_M_push_back_aux實現大同小異
/// Called only if _M_start._M_cur == _M_start._M_first.
template 
void  deque<_Tp,_Alloc>::_M_push_front_aux(const value_type& __t)
{
    value_type __t_copy = __t;
    _M_reserve_map_at_front();
    *(_M_start._M_node - 1) = _M_allocate_node();
    try
    {
        _M_start._M_set_node(_M_start._M_node - 1);
        _M_start._M_cur = _M_start._M_last - 1;
        construct(_M_start._M_cur, __t_copy);
    }
    catch(...)
    {
        ++_M_start;
        _M_deallocate_node(*(_M_start._M_node - 1));
        throw;
    }

}

/// Called only if _M_start._M_cur == _M_start._M_first.
template 
void deque<_Tp,_Alloc>::_M_push_front_aux()
{
    _M_reserve_map_at_front();
    *(_M_start._M_node - 1) = _M_allocate_node();
    try
    {
        _M_start._M_set_node(_M_start._M_node - 1);
        _M_start._M_cur = _M_start._M_last - 1;
        construct(_M_start._M_cur);
    }
    catch(...)
    {
        ++_M_start;
        _M_deallocate_node(*(_M_start._M_node - 1));
        throw;
    }

}

/// Called only if _M_finish._M_cur == _M_finish._M_first.
template 
void deque<_Tp,_Alloc>::_M_pop_back_aux()
{
    ///歸還不用區段
    _M_deallocate_node(_M_finish._M_first);

    ///調整狀態
    _M_finish._M_set_node(_M_finish._M_node - 1);
    _M_finish._M_cur = _M_finish._M_last - 1;

    ///析構被刪除對象
    destroy(_M_finish._M_cur);
}

/// Called only if _M_start._M_cur == _M_start._M_last - 1.  Note that
/// if the deque has at least one element (a precondition for this member
/// function), and if _M_start._M_cur == _M_start._M_last, then the deque
/// must have at least two nodes.
template 
void deque<_Tp,_Alloc>::_M_pop_front_aux()
{
    destroy(_M_start._M_cur);
    _M_deallocate_node(_M_start._M_first);
    _M_start._M_set_node(_M_start._M_node + 1);
    _M_start._M_cur = _M_start._M_first;
}

template  template 
void deque<_Tp,_Alloc>::insert(iterator __pos,
                               _InputIterator __first, _InputIterator __last,
                               input_iterator_tag)
{
    copy(__first, __last, inserter(*this, __pos));
}

template  template 
void
deque<_Tp,_Alloc>::insert(iterator __pos,
                          _ForwardIterator __first, _ForwardIterator __last,
                          forward_iterator_tag)
{
    size_type __n = 0;
    distance(__first, __last, __n);
    if (__pos._M_cur == _M_start._M_cur)
    {
        iterator __new_start = _M_reserve_elements_at_front(__n);
        try
        {
            uninitialized_copy(__first, __last, __new_start);
            _M_start = __new_start;
        }
        catch(...)
        {
            _M_destroy_nodes(__new_start._M_node, _M_start._M_node);
            throw;
        }

    }
    else if (__pos._M_cur == _M_finish._M_cur)
    {
        iterator __new_finish = _M_reserve_elements_at_back(__n);
        try
        {
            uninitialized_copy(__first, __last, _M_finish);
            _M_finish = __new_finish;
        }
        catch(...)
        {
            _M_destroy_nodes(_M_finish._M_node + 1,
                             __new_finish._M_node + 1);
            throw;
        }

    }
    else
        _M_insert_aux(__pos, __first, __last, __n);
}

///這個函數雖然長,但邏輯很清晰
template 
typename deque<_Tp, _Alloc>::iterator
deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos, const value_type& __x)
{
    difference_type __index = __pos - _M_start;
    value_type __x_copy = __x;
    if (size_type(__index) < this->size() / 2)
    {
        push_front(front());
        iterator __front1 = _M_start;
        ++__front1;
        iterator __front2 = __front1;
        ++__front2;
        __pos = _M_start + __index;
        iterator __pos1 = __pos;
        ++__pos1;
        copy(__front2, __pos1, __front1);
    }
    else
    {
        push_back(back());
        iterator __back1 = _M_finish;
        --__back1;
        iterator __back2 = __back1;
        --__back2;
        __pos = _M_start + __index;
        copy_backward(__pos, __back2, __back1);
    }
    *__pos = __x_copy;
    return __pos;
}

template 
typename deque<_Tp,_Alloc>::iterator
deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos)
{
    difference_type __index = __pos - _M_start;
    if (__index < size() / 2)
    {
        push_front(front());
        iterator __front1 = _M_start;
        ++__front1;
        iterator __front2 = __front1;
        ++__front2;
        __pos = _M_start + __index;
        iterator __pos1 = __pos;
        ++__pos1;
        copy(__front2, __pos1, __front1);
    }
    else
    {
        push_back(back());
        iterator __back1 = _M_finish;
        --__back1;
        iterator __back2 = __back1;
        --__back2;
        __pos = _M_start + __index;
        copy_backward(__pos, __back2, __back1);
    }
    *__pos = value_type();
    return __pos;
}

template 
void deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos,
                                      size_type __n,
                                      const value_type& __x)
{
    const difference_type __elems_before = __pos - _M_start;
    size_type __length = this->size();
    value_type __x_copy = __x;
    if (__elems_before < difference_type(__length / 2))    ///插入位置的前面元素少
    {

        ///在_M_start之前擴容n個元素,將插入位置之前的元素前移
        iterator __new_start = _M_reserve_elements_at_front(__n);
        iterator __old_start = _M_start;
        __pos = _M_start + __elems_before;
        try
        {
            if (__elems_before >= difference_type(__n))
            {
                ///插入位置之前的元素多於需要插入的元素,舊有元素的移動
                ///需要分兩次進行,一次是向空白內存復制,一次是向已有對象賦值
                iterator __start_n = _M_start + difference_type(__n);
                uninitialized_copy(_M_start, __start_n, __new_start);
                _M_start = __new_start;
                copy(__start_n, __pos, __old_start);

                ///新元素的插入只需一次進行,都是向已有對象賦值
                fill(__pos - difference_type(__n), __pos, __x_copy);
            }
            else
            {
                ///舊有元素移動一次可以完成,而新元素插入需要兩次
                __uninitialized_copy_fill(_M_start, __pos, __new_start,
                                          _M_start, __x_copy);
                _M_start = __new_start;
                fill(__old_start, __pos, __x_copy);
            }
        }
        catch(...)
        {
            _M_destroy_nodes(__new_start._M_node, _M_start._M_node);
            throw;
        }

    }
    else
    {
        ///在_M_finish之後擴容n個元素,然後將插入位置之後的元素後移
        ///其余原理和上一種情況相同
        iterator __new_finish = _M_reserve_elements_at_back(__n);
        iterator __old_finish = _M_finish;
        const difference_type __elems_after =
            difference_type(__length) - __elems_before;
        __pos = _M_finish - __elems_after;
        try
        {
            if (__elems_after > difference_type(__n))
            {
                iterator __finish_n = _M_finish - difference_type(__n);
                uninitialized_copy(__finish_n, _M_finish, _M_finish);
                _M_finish = __new_finish;
                copy_backward(__pos, __finish_n, __old_finish);
                fill(__pos, __pos + difference_type(__n), __x_copy);
            }
            else
            {
                __uninitialized_fill_copy(_M_finish, __pos + difference_type(__n),
                                          __x_copy, __pos, _M_finish);
                _M_finish = __new_finish;
                fill(__pos, __old_finish, __x_copy);
            }
        }
        catch(...)
        {
            _M_destroy_nodes(_M_finish._M_node + 1,
                             __new_finish._M_node + 1);
            throw;
        }
    }
}

///實現和上面的重載函數大同小異
template  template 
void deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos,
                                      _ForwardIterator __first,
                                      _ForwardIterator __last,
                                      size_type __n)
{
    const difference_type __elemsbefore = __pos - _M_start;
    size_type __length = size();
    if (__elemsbefore < __length / 2)
    {
        iterator __new_start = _M_reserve_elements_at_front(__n);
        iterator __old_start = _M_start;
        __pos = _M_start + __elemsbefore;
        try
        {
            if (__elemsbefore >= difference_type(__n))
            {
                iterator __start_n = _M_start + difference_type(__n);
                uninitialized_copy(_M_start, __start_n, __new_start);
                _M_start = __new_start;
                copy(__start_n, __pos, __old_start);
                copy(__first, __last, __pos - difference_type(__n));
            }
            else
            {
                _ForwardIterator __mid = __first;
                advance(__mid, difference_type(__n) - __elemsbefore);
                __uninitialized_copy_copy(_M_start, __pos, __first, __mid,
                                          __new_start);
                _M_start = __new_start;
                copy(__mid, __last, __old_start);
            }
        }
        catch(...)
        {
            _M_destroy_nodes(__new_start._M_node, _M_start._M_node);
        }
    }
    else
    {
        iterator __new_finish = _M_reserve_elements_at_back(__n);
        iterator __old_finish = _M_finish;
        const difference_type __elemsafter =
            difference_type(__length) - __elemsbefore;
        __pos = _M_finish - __elemsafter;
        try
        {
            if (__elemsafter > difference_type(__n))
            {
                iterator __finish_n = _M_finish - difference_type(__n);
                uninitialized_copy(__finish_n, _M_finish, _M_finish);
                _M_finish = __new_finish;
                copy_backward(__pos, __finish_n, __old_finish);
                copy(__first, __last, __pos);
            }
            else
            {
                _ForwardIterator __mid = __first;
                advance(__mid, __elemsafter);
                __uninitialized_copy_copy(__mid, __last, __pos, _M_finish, _M_finish);
                _M_finish = __new_finish;
                copy(__first, __mid, __pos);
            }
        }
        catch(...)
        {
            _M_destroy_nodes(_M_finish._M_node + 1,
                             __new_finish._M_node + 1);
            throw;
        }

    }
}

template 
void deque<_Tp,_Alloc>::_M_new_elements_at_front(size_type __new_elems)
{
    ///根據需要擴充的元素擴充相應數量的中控器單元
    size_type __new_nodes
        = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size();
    _M_reserve_map_at_front(__new_nodes);

    ///真正進行每個區段的分配
    size_type __i;
    try
    {
        for (__i = 1; __i <= __new_nodes; ++__i)
            *(_M_start._M_node - __i) = _M_allocate_node();
    }
    catch(...)
    {
        for (size_type __j = 1; __j < __i; ++__j)
            _M_deallocate_node(*(_M_start._M_node - __j));
        throw;
    }

}

///和_M_new_elements_at_front原理相同
template 
void deque<_Tp,_Alloc>::_M_new_elements_at_back(size_type __new_elems)
{
    size_type __new_nodes
        = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size();
    _M_reserve_map_at_back(__new_nodes);
    size_type __i;
    try
    {
        for (__i = 1; __i <= __new_nodes; ++__i)
            *(_M_finish._M_node + __i) = _M_allocate_node();
    }
    catch(...)
    {
        for (size_type __j = 1; __j < __i; ++__j)
            _M_deallocate_node(*(_M_finish._M_node + __j));
        throw;
    }
}

///重新分配中控器
template 
void deque<_Tp,_Alloc>::_M_reallocate_map(size_type __nodes_to_add,
        bool __add_at_front)
{
    size_type __old_num_nodes = _M_finish._M_node - _M_start._M_node + 1;
    size_type __new_num_nodes = __old_num_nodes + __nodes_to_add;

    _Map_pointer __new_nstart;
    if (_M_map_size > 2 * __new_num_nodes)
    {
        ///中控器現有容量比需要容量的2賠還多,只需要將中控器中的元素
        ///向一端挪動以騰出足夠容量即可

        __new_nstart = _M_map + (_M_map_size - __new_num_nodes) / 2
                       + (__add_at_front ? __nodes_to_add : 0);

        if (__new_nstart < _M_start._M_node)
            copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart);
        else
            copy_backward(_M_start._M_node, _M_finish._M_node + 1,
                          __new_nstart + __old_num_nodes);
    }
    else
    {
        ///否則,需要為中控器重新分配內存並且復制原有中控器的數據.
        size_type __new_map_size =
            _M_map_size + max(_M_map_size, __nodes_to_add) + 2;

        _Map_pointer __new_map = _M_allocate_map(__new_map_size);
        __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2
                       + (__add_at_front ? __nodes_to_add : 0);
        copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart);
        _M_deallocate_map(_M_map, _M_map_size);

        _M_map = __new_map;
        _M_map_size = __new_map_size;
    }

    ///調整迭代器狀態
    _M_start._M_set_node(__new_nstart);
    _M_finish._M_set_node(__new_nstart + __old_num_nodes - 1);
}


/// Nonmember functions.

template 
inline bool operator==(const deque<_Tp, _Alloc>& __x,
                       const deque<_Tp, _Alloc>& __y)
{
    return __x.size() == __y.size() &&
           equal(__x.begin(), __x.end(), __y.begin());
}

template 
inline bool operator<(const deque<_Tp, _Alloc>& __x,
                      const deque<_Tp, _Alloc>& __y)
{
    return lexicographical_compare(__x.begin(), __x.end(),
                                   __y.begin(), __y.end());
}


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved