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 <class _Tp, class _Ref, class _Ptr> 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 <class _Tp, class _Ref, class _Ptr> 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 _Tp, class _Alloc> 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 <class _Tp, class _Alloc> _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 <class _Tp, class _Alloc> 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 <class _Tp, class _Alloc> 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 <class _Tp, class _Alloc> 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 _Tp, class _Alloc = Stl_Default_Alloc > 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_iterator, value_type, const_reference, difference_type> const_reverse_iterator; typedef reverse_iterator<iterator, value_type, reference, difference_type> 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 <class _InputIterator> 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 <class _Integer> void _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) { _M_initialize_map(__n); _M_fill_initialize(__x); } template <class _InputIter> 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 <class _InputIterator> 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 <class _Integer> void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) { _M_fill_assign((size_type) __n, (_Tp) __val); } template <class _InputIterator> void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, __false_type) { ///依據迭代器不同採取不同的方法,以取得最佳效率 _M_assign_aux(__first, __last, __ITERATOR_CATEGORY(__first)); } template <class _InputIterator> void _M_assign_aux(_InputIterator __first, _InputIterator __last, input_iterator_tag); template <class _ForwardIterator> 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 <class _InputIterator> void insert(iterator __pos, _InputIterator __first, _InputIterator __last) { typedef typename _Is_integer<_InputIterator>::_Integral _Integral; _M_insert_dispatch(__pos, __first, __last, _Integral()); } template <class _Integer> void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, __true_type) { _M_fill_insert(__pos, (size_type) __n, (value_type) __x); } template <class _InputIterator> 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 <class _InputIterator> void _M_range_initialize(_InputIterator __first, _InputIterator __last, input_iterator_tag); template <class _ForwardIterator> 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 <class _InputIterator> void insert(iterator __pos, _InputIterator __first, _InputIterator __last, input_iterator_tag); template <class _ForwardIterator> 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 <class _ForwardIterator> 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 <class _Tp, class _Alloc> template <class _InputIter> 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 <class _Tp, class _Alloc> 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 <class _Tp, class _Alloc> 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 <class _Tp, class _Alloc> 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 <class _Tp, class _Alloc> 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 <class _Tp, class _Alloc> 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 <class _Tp, class _Alloc> 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 <class _Tp, class _Alloc> template <class _InputIterator> 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 <class _Tp, class _Alloc> template <class _ForwardIterator> 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 <class _Tp, class _Alloc> 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 <class _Tp, class _Alloc> 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 <class _Tp, class _Alloc> 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 <class _Tp, class _Alloc> 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 <class _Tp, class _Alloc> 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 <class _Tp, class _Alloc> 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 <class _Tp, class _Alloc> template <class _InputIterator> void deque<_Tp,_Alloc>::insert(iterator __pos, _InputIterator __first, _InputIterator __last, input_iterator_tag) { copy(__first, __last, inserter(*this, __pos)); } template <class _Tp, class _Alloc> template <class _ForwardIterator> 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 <class _Tp, class _Alloc> 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 <class _Tp, class _Alloc> 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 <class _Tp, class _Alloc> 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 <class _Tp, class _Alloc> template <class _ForwardIterator> 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 <class _Tp, class _Alloc> 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 <class _Tp, class _Alloc> 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 <class _Tp, class _Alloc> 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 <class _Tp, class _Alloc> 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 <class _Tp, class _Alloc> inline bool operator<(const deque<_Tp, _Alloc>& __x, const deque<_Tp, _Alloc>& __y) { return lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); }


deque中,內存是分段的,每個段的大小為512字節,所以deque的內存擴充不須要像vector那樣復制原有內存的對象,僅僅須要分配一個新的段來保存新分配的內存。那么

這些互不相關的段是怎樣給用戶提供一個線性隨機訪問的機制呢?答案是靠中控器和配合中控器的迭代器。中控器是一個指針數組,按順序存儲每個內存段的頭指針,中控器一般並不從開頭使用。而是從中間使用,使得用戶頻繁插入到前面時避免中控器的又一次分配內存導致過大開銷。在deque的迭代器中,保存着兩個主要元素。一是該迭代器所指向元素所在段的頭指針在中控器中的位置記為pseg,二是該迭代器所指向元素在其所在段的位置記為pidx。這兩者結合就能夠唯一確定一個元素的准確位置。

當執operator++/--/+n/-n時,假設操作后的元素沒有超出當前段,就直接對pidx運行對應操作。假設超出了當前段,則同一時候改動pseg和pidx,從而為用戶提供隨機訪問。當運行插入操作時,假設當前已分配的段夠用,先推斷插入位置前面的元素少還是后面的元素少。假設前面的元素少而且前面的空間足夠容納插入元素,就將直接前面的元素向前移動。為插入元素騰出位置。

假設前面空間不夠容納插入元素,就分配新的段,並將其首地址插入到中控器前面,而且更改deque首段地址為新分配的段首地址。然后再將插入位置之前的元素向前移動然后進行插入。

假設插入位置后面元素少,和剛才所述相似。僅僅是向后移動元素。將新分配的段插入中控器之后,和改動deque末端地址。假設要刪除元素。也是一個道理,僅僅只是運行的是回收不再使用的段操作。從這些分析能夠看出。僅僅有在內存不夠。確實須要又一次分配時分配新的內存 。deque通過分配新的段來避免vector那種大量的復制操作,以及在不須要使用內存 時。deque及時釋放內存等雙方面deque相比vector顯示了其優勢。在運行刪除操作和沒有內存擴充的情況下。全部的復制操作都是不可避免的,並不像list那樣的數據結構插入和其它元素不須要不論什么的復制操作。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM