您的位置:首页 > 编程语言 > C语言/C++

C++ STL 源码学习(之deque篇)

2014-10-11 22:42 295 查看
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那样的数据结构插入和其他元素不需要任何的复制操作。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++ stl 源码 泛型 存储