STL源码剖析-----deque


//
template <class T, class Alloc = alloc, size_t BufSiz = 0>
class deque {
public:                         // Basic types
	typedef T 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;

public:                         // Iterators
	typedef __deque_iterator<T, T&, T*, BufSiz>              iterator;
	typedef __deque_iterator<T, const T&, const T&, BufSiz>  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;
	typedef simple_alloc<value_type, Alloc> data_allocator;
	typedef simple_alloc<pointer, Alloc> map_allocator;

	static size_type buffer_size() {
		return __deque_buf_size(BufSiz, sizeof(value_type));
	}
	//一个map最少要管理8个节点,在产生deque结构时用到
	//create_map_and_nodes()函数中:map_size = max(initial_map_size(), num_nodes + 2);
	//map_size 是map要的节点数,num_nodes 客户需求的节点数,详看create_map_and_nodes()函数
	static size_type initial_map_size() { return 8; }

protected:                      // Data members
//看图4.4-2
//start对应第一个缓冲区,start.node指向已经在使用的第一个map节点
//finish对应最后一个缓冲区,finish.node指向已经在使用的最后一个map节点
//如果map只有一个节点在使用,则start.node==finish.node,但start不一定等finish
//start是否等于finish,要看start.cur是否等于finish.cur (迭代器重载==)
	iterator start;
	iterator finish;

	map_pointer map;
	size_type map_size;

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

	reverse_iterator rbegin() { return reverse_iterator(finish); }
	reverse_iterator rend() { return reverse_iterator(start); }
	const_reverse_iterator rbegin() const {
		return const_reverse_iterator(finish);
	}
	const_reverse_iterator rend() const {
		return const_reverse_iterator(start);
	}

	reference operator[](size_type n) { return start[difference_type(n)]; }
	const_reference operator[](size_type n) const {
		return start[difference_type(n)];
	}

	reference front() { return *start; }
	//如图4.4-3,finish.cur指向的备用空间,最后一个元素在cur的前一个
	//所以--tmp(调用重载,看__deque_iterator),cur会前移一位,*tmp会返回*cur
	//tmp是finish的拷贝,所以tmp的cur改变,并不影响finish的cur
	reference back() {
		iterator tmp = finish;
		--tmp;
		return *tmp;
	}
	const_reference front() const { return *start; }
	const_reference back() const {
		const_iterator tmp = finish;
		--tmp;
		return *tmp;
	}

	//调用迭代器的重载operator-(const self& x)
	size_type size() const { return finish - start;; }
	size_type max_size() const { return size_type(-1); }
	//调用迭代器的重载operator==(const self& x)判断finish.cur==start.cur
	bool empty() const { return finish == start; }

public:                         // Constructor, destructor.
	deque()
		: start(), finish(), map(0), map_size(0)
	{
		//构建了一个有8个map节点,一个缓冲区的deque
		//start.node==finish.node且start.cur==finish.cur
		create_map_and_nodes(0);
	}

	deque(const deque& x)
		: start(), finish(), map(0), map_size(0)
	{
		//配置好deque整个结构(只差数据没填入)
		create_map_and_nodes(x.size());
		__STL_TRY{
			//填充数据,p70-1
			uninitialized_copy(x.begin(), x.end(), start);
		}
		__STL_UNWIND(destroy_map_and_nodes());
	}

	deque(size_type n, const value_type& value)
		: start(), finish(), map(0), map_size(0)
	{
		//传入元素个数和初值,构建好deque
		fill_initialize(n, value);
	}

	deque(int n, const value_type& value)
		: start(), finish(), map(0), map_size(0)
	{
		fill_initialize(n, value);
	}

	deque(long n, const value_type& value)
		: start(), finish(), map(0), map_size(0)
	{
		fill_initialize(n, value);
	}

	explicit deque(size_type n)
		: start(), finish(), map(0), map_size(0)
	{
		fill_initialize(n, value_type());
	}

	deque(const value_type* first, const value_type* last)
		: start(), finish(), map(0), map_size(0)
	{
		create_map_and_nodes(last - first);
		__STL_TRY{
			uninitialized_copy(first, last, start);
		}
		__STL_UNWIND(destroy_map_and_nodes());
	}

	deque(const_iterator first, const_iterator last)
		: start(), finish(), map(0), map_size(0)
	{
		create_map_and_nodes(last - first);
		__STL_TRY{
			uninitialized_copy(first, last, start);
		}
		__STL_UNWIND(destroy_map_and_nodes());
	}


	~deque() {
		//销毁掉所有元素 @
		destroy(start, finish);
		//销毁掉map所有节点和所有缓冲区
		destroy_map_and_nodes();
	}

	deque& operator= (const deque& x) {
		const size_type len = size();
		if (&x != this) {
			if (len >= x.size())
				 //copy详见stl_algobase.h p315-1
				//把x的元素全部copy过来,并把原deque后面多余的移除掉
				erase(copy(x.begin(), x.end(), start), finish);
			else {
				const_iterator mid = x.begin() + difference_type(len);
				//把x的前len个元素copy过来,再把后面的元素用插入的方式移进
				copy(x.begin(), mid, start);
				insert(finish, mid, x.end());
			}
		}
		return *this;
	}

	void swap(deque& x) {
		__STD::swap(start, x.start);
		__STD::swap(finish, x.finish);
		__STD::swap(map, x.map);
		__STD::swap(map_size, x.map_size);
	}

public:                         // push_* and pop_*

	void push_back(const value_type& t) {
		if (finish.cur != finish.last - 1) {
			//当前缓冲区备用空间>=2
			//finish.cur指向最后一个元素的尾地址(第一个备用空间首地址),finish.last指向缓冲区末尾地址

			//详见stl_construct.h
			construct(finish.cur, t);
			++finish.cur;
		}
		else
			//当前缓冲区剩最后一个备用空间,插入后,要增加一个缓冲区
			push_back_aux(t);
	}

	void push_front(const value_type& t) {
		if (start.cur != start.first) {
			construct(start.cur - 1, t);
			--start.cur;
		}
		else
			//要向前加缓冲区
			push_front_aux(t);
	}

	void pop_back() {
		//start.cur指向第一个元素首址,finish.cur指向最后一个元素尾地址
		if (finish.cur != finish.first) {
			--finish.cur;
			destroy(finish.cur);
		}
		else
			//尾端缓冲区一个元素都没有,全都是备用空间
			pop_back_aux();
	}

	void pop_front() {
		if (start.cur != start.last - 1) {
			destroy(start.cur);
			++start.cur;
		}
		else
			//前端缓冲区只有一个元素
			pop_front_aux();
	}

public:                         // Insert

	iterator insert(iterator position, const value_type& x) {
		if (position.cur == start.cur) {
			//前端插入
			push_front(x);
			return start;
		}
		else if (position.cur == finish.cur) {
			//后端插入
			push_back(x);
			//因为finish.cur指向第一个备用(最后元素尾地址),要返回插入的元素,所以--tmp
			iterator tmp = finish;
			--tmp;
			return tmp;
		}
		else {
			//中间插入
			return insert_aux(position, x);
		}
	}

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

	void insert(iterator pos, size_type n, const value_type& x);

	void insert(iterator pos, int n, const value_type& x) {
		insert(pos, (size_type)n, x);
	}
	void insert(iterator pos, long n, const value_type& x) {
		insert(pos, (size_type)n, x);
	}


	void insert(iterator pos, const value_type* first, const value_type* last);
	void insert(iterator pos, const_iterator first, const_iterator last);


	void resize(size_type new_size, const value_type& x) {
		const size_type len = size();
		if (new_size < len)
			erase(start + new_size, finish);
		else
			insert(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 - start;
		if (index < (size() >> 1)) {
			copy_backward(start, pos, next);
			pop_front();
		}
		else {
			copy(next, finish, pos);
			pop_back();
		}
		return start + index;
	}

	iterator erase(iterator first, iterator last);
	void clear();

protected:                        // Internal construction/destruction

	void create_map_and_nodes(size_type num_elements);
	void destroy_map_and_nodes();
	void fill_initialize(size_type n, const value_type& value);

protected:                        // Internal push_* and pop_*

	void push_back_aux(const value_type& t);
	void push_front_aux(const value_type& t);
	void pop_back_aux();
	void pop_front_aux();

protected:                        // Internal insert functions


	iterator insert_aux(iterator pos, const value_type& x);
	void insert_aux(iterator pos, size_type n, const value_type& x);



	void insert_aux(iterator pos,
		const value_type* first, const value_type* last,
		size_type n);

	void insert_aux(iterator pos, const_iterator first, const_iterator last,
		size_type n);

	iterator reserve_elements_at_front(size_type n) {
		//在前端预留出n个元素空间
		size_type vacancies = start.cur - start.first;
		if (n > vacancies)
			//备用空间不够,要添加缓冲区,预留出空间
			new_elements_at_front(n - vacancies);
		return start - difference_type(n);
	}

	iterator reserve_elements_at_back(size_type n) {
		size_type vacancies = (finish.last - finish.cur) - 1;
		if (n > vacancies)
			new_elements_at_back(n - vacancies);
		return finish + difference_type(n);
	}

	void new_elements_at_front(size_type new_elements);
	void new_elements_at_back(size_type new_elements);

	void destroy_nodes_at_front(iterator before_start);
	void destroy_nodes_at_back(iterator after_finish);

protected:                      // Allocation of map and nodes

								// Makes sure the map has space for new nodes.  Does not actually
								//  add the nodes.  Can invalidate map pointers.  (And consequently, 
								//  deque iterators.)

	//如果map尾端的备用节点不够,则重配置一个更大的
	void reserve_map_at_back(size_type nodes_to_add = 1) {
		if (nodes_to_add + 1 > map_size - (finish.node - map))
			//如果符合条件,配置一个更大的map,只是改变map,其他不变(缓冲区和迭代器)
			reallocate_map(nodes_to_add, false);
	}

	void reserve_map_at_front(size_type nodes_to_add = 1) {
		if (nodes_to_add > start.node - map)
			reallocate_map(nodes_to_add, true);
	}

	void reallocate_map(size_type nodes_to_add, bool add_at_front);

	pointer allocate_node() { return data_allocator::allocate(buffer_size()); }
	void deallocate_node(pointer n) {
		data_allocator::deallocate(n, buffer_size());
	}
};

// Non-inline member functions

template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::insert(iterator pos,
	size_type n, const value_type& x) {
	if (pos.cur == start.cur) {
		iterator new_start = reserve_elements_at_front(n);
		uninitialized_fill(new_start, start, x);
		start = new_start;
	}
	else if (pos.cur == finish.cur) {
		iterator new_finish = reserve_elements_at_back(n);
		uninitialized_fill(finish, new_finish, x);
		finish = new_finish;
	}
	else
		insert_aux(pos, n, x);
}

template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::insert(iterator pos,
	const value_type* first,
	const value_type* last) {
	size_type n = last - first;
	if (pos.cur == start.cur) {
		iterator new_start = reserve_elements_at_front(n);
		__STL_TRY{
			uninitialized_copy(first, last, new_start);
		start = new_start;
		}
		__STL_UNWIND(destroy_nodes_at_front(new_start));
	}
	else if (pos.cur == finish.cur) {
		iterator new_finish = reserve_elements_at_back(n);
		__STL_TRY{
			uninitialized_copy(first, last, finish);
		finish = new_finish;
		}
		__STL_UNWIND(destroy_nodes_at_back(new_finish));
	}
	else
		insert_aux(pos, first, last, n);
}

template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::insert(iterator pos,
	const_iterator first,
	const_iterator last)
{
	size_type n = last - first;
	if (pos.cur == start.cur) {
		iterator new_start = reserve_elements_at_front(n);
		__STL_TRY{
			uninitialized_copy(first, last, new_start);
		start = new_start;
		}
		__STL_UNWIND(destroy_nodes_at_front(new_start));
	}
	else if (pos.cur == finish.cur) {
		iterator new_finish = reserve_elements_at_back(n);
		__STL_TRY{
			uninitialized_copy(first, last, finish);
		finish = new_finish;
		}
		__STL_UNWIND(destroy_nodes_at_back(new_finish));
	}
	else
		insert_aux(pos, first, last, n);
}

template <class T, class Alloc, size_t BufSize>
deque<T, Alloc, BufSize>::iterator
deque<T, Alloc, BufSize>::erase(iterator first, iterator last) {			
	if (first == start && last == finish) {
		clear();
		return finish;
	}
	else {
		difference_type n = last - first;
		difference_type elems_before = first - start;
		if (elems_before < (size() - n) / 2) {
			copy_backward(start, first, last);
			iterator new_start = start + n;
			destroy(start, new_start);
			for (map_pointer cur = start.node; cur < new_start.node; ++cur)
				data_allocator::deallocate(*cur, buffer_size());
			start = new_start;
		}
		else {
			copy(last, finish, first);
			iterator new_finish = finish - n;
			destroy(new_finish, finish);
			for (map_pointer cur = new_finish.node + 1; cur <= finish.node; ++cur)
				data_allocator::deallocate(*cur, buffer_size());
			finish = new_finish;
		}
		return start + elems_before;
	}
}

template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::clear() {
	for (map_pointer node = start.node + 1; node < finish.node; ++node) {
		destroy(*node, *node + buffer_size());
		data_allocator::deallocate(*node, buffer_size());
	}

	if (start.node != finish.node) {
		destroy(start.cur, start.last);
		destroy(finish.first, finish.cur);
		data_allocator::deallocate(finish.first, buffer_size());
	}
	else
		destroy(start.cur, finish.cur);

	finish = start;
}

//传入元素个数,配置好deque整个结构(只差数据没填入)
//配置好map_size、map、start、finish,
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::create_map_and_nodes(size_type num_elements) {
	//num_elements:deque需要的元素个数
	// buffer_size()缓冲区元素个数,因为除会把余数忽略,所以要多加一个节点存余的,例:10/8,需要两个节点存
	//如果刚好整除,则多配一个节点
	size_type num_nodes = num_elements / buffer_size() + 1;

	//num_nodes + 2:在需要的节点数上前后预留一个,以便扩充时用
	//initial_map_size()这里为8
	//map_size :要给map分配的节点数
	//一个map最少要管理8个节点,所以map_size 选择比较大的值
	map_size = max(initial_map_size(), num_nodes + 2); 
	//配置出一个具有map_size 节点的map
	map = map_allocator::allocate(map_size);

	//假设这里map已经全部配置好,则(实际这里map节点都还没用)
	//nstart 指向有指向缓冲区的第一个map节点(即已经在使用的第一个map节点)
	//nfinish 指向有指向缓冲区的最后一个map节点(即已经在使用的最后一个map节点)

	//map_size - num_nodes得到备用空间个数,再除2,把备用空间分成两份
	// 前后个一份备用空间
	map_pointer nstart = map + (map_size - num_nodes) / 2;
	map_pointer nfinish = nstart + num_nodes - 1;

	map_pointer cur;
	__STL_TRY{
		for (cur = nstart; cur <= nfinish; ++cur)
		//为map节点配置缓冲区,每个map节点都指向缓冲区首地址
		// 返回缓冲区首地址赋给map节点
			*cur = allocate_node();
	}
#     ifdef  __STL_USE_EXCEPTIONS 
		catch (...) {
		// 如果不是全部成功,则都销毁掉
		for (map_pointer n = nstart; n < cur; ++n)
			//销毁缓冲区
			deallocate_node(*n);
		//销毁map
		map_allocator::deallocate(map, map_size);
		throw;
	}
#     endif /* __STL_USE_EXCEPTIONS */
	//配置start、finish迭代器,
	// 迭代器内cur、first、last、node的配置
	//finish.cur指向的最后一个元素的下一个
	start.set_node(nstart);
	finish.set_node(nfinish);
	start.cur = start.first;
	finish.cur = finish.first + num_elements % buffer_size();
}

// This is only used as a cleanup function in catch clauses.
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::destroy_map_and_nodes() {
	for (map_pointer cur = start.node; cur <= finish.node; ++cur)
		//遍历销毁点所有元素
		deallocate_node(*cur);
	//销毁掉所有map节点
	map_allocator::deallocate(map, map_size);
}

//传入元素个数和初值,构建好deque
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::fill_initialize(size_type n,
	const value_type& value) {
	//配置好deque整个结构(只差数据没填入)
	create_map_and_nodes(n);
	map_pointer cur;
	__STL_TRY{
		for (cur = start.node; cur < finish.node; ++cur)
		//填入数据
		uninitialized_fill(*cur, *cur + buffer_size(), value);
	// 最后一个缓冲区可能有备用空间,不必填入
	uninitialized_fill(finish.first, finish.cur, value);
	}
#       ifdef __STL_USE_EXCEPTIONS
		catch (...) {
		for (map_pointer n = start.node; n < cur; ++n)
			destroy(*n, *n + buffer_size());
		destroy_map_and_nodes();
		throw;
	}
#       endif /* __STL_USE_EXCEPTIONS */
}


// Called only if finish.cur == finish.last - 1.
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::push_back_aux(const value_type& t) {
	value_type t_copy = t;
	//如果条件需要,要配置一个更大的map
	reserve_map_at_back();
	//配置一个新的缓冲区
	*(finish.node + 1) = allocate_node();
	__STL_TRY{
		//这里的finish.cur还是指向要加元素的缓冲区
		construct(finish.cur, t_copy);
	//调整finish,让其指向新的缓冲区
	finish.set_node(finish.node + 1);
	finish.cur = finish.first;
	}
	__STL_UNWIND(deallocate_node(*(finish.node + 1)));
}

// Called only if start.cur == start.first.
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::push_front_aux(const value_type& t) {
	value_type t_copy = t;
	//如果条件需要,要配置一个更大的map
	reserve_map_at_front();
	//配置一个新的缓冲区
	*(start.node - 1) = allocate_node();
	__STL_TRY{
		//调整start,让其指向新的缓冲区
		start.set_node(start.node - 1);
	start.cur = start.last - 1;
	//填值
	construct(start.cur, t_copy);
	}
#     ifdef __STL_USE_EXCEPTIONS
		catch (...) {
		start.set_node(start.node + 1);
		start.cur = start.first;
		deallocate_node(*(start.node - 1));
		throw;
	}
#     endif /* __STL_USE_EXCEPTIONS */
}

// Called only if finish.cur == finish.first.
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::pop_back_aux() {
	//销毁缓冲区
	deallocate_node(finish.first);
	//调整finish
	finish.set_node(finish.node - 1);
	finish.cur = finish.last - 1;

	//销毁元素
	destroy(finish.cur);
}

// Called only if start.cur == start.last - 1.  Note that if the deque
//  has at least one element (a necessary precondition for this member
//  function), and if start.cur == start.last, then the deque must have
//  at least two nodes.
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::pop_front_aux() {
	//销毁元素
	destroy(start.cur);
	//销毁缓冲区
	deallocate_node(start.first);

	//调整start
	start.set_node(start.node + 1);
	start.cur = start.first;
}

//在pos位置插入x
template <class T, class Alloc, size_t BufSize>
typename deque<T, Alloc, BufSize>::iterator
deque<T, Alloc, BufSize>::insert_aux(iterator pos, const value_type& x) {
	//插入位置和头部的距离
	difference_type index = pos - start;
	value_type x_copy = x;
	if (index < size() / 2) {
		//插入点比较靠近头部
		//先在前端插入一个front(),扩展空间
		push_front(front());
		iterator front1 = start;
		++front1;
		iterator front2 = front1;
		++front2;
		pos = start + index;
		iterator pos1 = pos;
		++pos1;
		//除了第一个元素,所以在pos之前(包括pos)都前移一个位置
		copy(front2, pos1, front1);
	}
	else {
		//插入点比较靠近尾部
		//先在尾端插入一个back(),扩展空间
		push_back(back());
		iterator back1 = finish;
		--back1;
		iterator back2 = back1;
		--back2;
		pos = start + index;
		//除了最后元素,所以在pos之后(包括pos)都后移一个位置
		copy_backward(pos, back2, back1);
	}
	//在pos位置填入新值
	*pos = x_copy;
	return pos;
}

//在pos位置插入n个x
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::insert_aux(iterator pos,
	size_type n, const value_type& x) {
	const difference_type elems_before = pos - start;
	size_type length = size();
	value_type x_copy = x;
	if (elems_before < length / 2) {
		//插入点比较靠近头部
		//预留出空间,如果需要,要增加缓冲区
		iterator new_start = reserve_elements_at_front(n);
		iterator old_start = start;
		pos = start + elems_before;
		__STL_TRY{
			if (elems_before >= difference_type(n)) {
				//@
				iterator start_n = start + difference_type(n);
				uninitialized_copy(start, start_n, new_start);
				start = new_start;
				copy(start_n, pos, old_start);
				fill(pos - difference_type(n), pos, x_copy);
			}
			else {
				__uninitialized_copy_fill(start, pos, new_start, start, x_copy);
				start = new_start;
				fill(old_start, pos, x_copy);
			}
		}
		__STL_UNWIND(destroy_nodes_at_front(new_start));
	}
	else {
		//插入点比较靠近尾部
		//预留出空间,如果需要,要增加缓冲区
		iterator new_finish = reserve_elements_at_back(n);
		iterator old_finish = finish;
		const difference_type elems_after = difference_type(length) - elems_before;
		pos = finish - elems_after;
		__STL_TRY{
			if (elems_after > difference_type(n)) {
				iterator finish_n = finish - difference_type(n);
				uninitialized_copy(finish_n, finish, finish);
				finish = new_finish;
				copy_backward(pos, finish_n, old_finish);
				fill(pos, pos + difference_type(n), x_copy);
			}
			else {
				__uninitialized_fill_copy(finish, pos + difference_type(n),
					x_copy,
					pos, finish);
				finish = new_finish;
				fill(pos, old_finish, x_copy);
			}
		}
		__STL_UNWIND(destroy_nodes_at_back(new_finish));
	}
}

template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::insert_aux(iterator pos,
	const value_type* first,
	const value_type* last,
	size_type n)
{
	const difference_type elems_before = pos - start;
	size_type length = size();
	if (elems_before < length / 2) {
		iterator new_start = reserve_elements_at_front(n);
		iterator old_start = start;
		pos = start + elems_before;
		__STL_TRY{
			if (elems_before >= difference_type(n)) {
				iterator start_n = start + difference_type(n);
				uninitialized_copy(start, start_n, new_start);
				start = new_start;
				copy(start_n, pos, old_start);
				copy(first, last, pos - difference_type(n));
			}
			else {
				const value_type* mid = first + (difference_type(n) - elems_before);
				__uninitialized_copy_copy(start, pos, first, mid, new_start);
				start = new_start;
				copy(mid, last, old_start);
			}
		}
		__STL_UNWIND(destroy_nodes_at_front(new_start));
	}
	else {
		iterator new_finish = reserve_elements_at_back(n);
		iterator old_finish = finish;
		const difference_type elems_after = difference_type(length) - elems_before;
		pos = finish - elems_after;
		__STL_TRY{
			if (elems_after > difference_type(n)) {
				iterator finish_n = finish - difference_type(n);
				uninitialized_copy(finish_n, finish, finish);
				finish = new_finish;
				copy_backward(pos, finish_n, old_finish);
				copy(first, last, pos);
			}
			else {
				const value_type* mid = first + elems_after;
				__uninitialized_copy_copy(mid, last, pos, finish, finish);
				finish = new_finish;
				copy(first, mid, pos);
			}
		}
		__STL_UNWIND(destroy_nodes_at_back(new_finish));
	}
}

template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::insert_aux(iterator pos,
	const_iterator first,
	const_iterator last,
	size_type n)
{
	const difference_type elems_before = pos - start;
	size_type length = size();
	if (elems_before < length / 2) {
		iterator new_start = reserve_elements_at_front(n);
		iterator old_start = start;
		pos = start + elems_before;
		__STL_TRY{
			if (elems_before >= n) {
				iterator start_n = start + n;
				uninitialized_copy(start, start_n, new_start);
				start = new_start;
				copy(start_n, pos, old_start);
				copy(first, last, pos - difference_type(n));
			}
			else {
				const_iterator mid = first + (n - elems_before);
				__uninitialized_copy_copy(start, pos, first, mid, new_start);
				start = new_start;
				copy(mid, last, old_start);
			}
		}
		__STL_UNWIND(destroy_nodes_at_front(new_start));
	}
	else {
		iterator new_finish = reserve_elements_at_back(n);
		iterator old_finish = finish;
		const difference_type elems_after = length - elems_before;
		pos = finish - elems_after;
		__STL_TRY{
			if (elems_after > n) {
				iterator finish_n = finish - difference_type(n);
				uninitialized_copy(finish_n, finish, finish);
				finish = new_finish;
				copy_backward(pos, finish_n, old_finish);
				copy(first, last, pos);
			}
			else {
				const_iterator mid = first + elems_after;
				__uninitialized_copy_copy(mid, last, pos, finish, finish);
				finish = new_finish;
				copy(first, mid, pos);
			}
		}
		__STL_UNWIND(destroy_nodes_at_back(new_finish));
	}
}

//但缓冲区的备用节点不够需求时,会调用,
//通过增加缓冲区,预留出new_elements个元素备用空间
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::new_elements_at_front(size_type new_elements) {
	//new_elements:要在前端预留的元素个数
	//new_nodes要预留的缓冲区个数
	size_type new_nodes = (new_elements + buffer_size() - 1) / buffer_size();
	//如果map的前端备用节点不够,则调整(把后端备用节点调到前端)或增加map前端的备用节点
	reserve_map_at_front(new_nodes);
	size_type i;
	__STL_TRY{
		for (i = 1; i <= new_nodes; ++i)
		//分配缓冲区,map预留节点指向预留缓冲区
		*(start.node - i) = allocate_node();
	}
#       ifdef __STL_USE_EXCEPTIONS
		catch (...) {
		for (size_type j = 1; j < i; ++j)
			deallocate_node(*(start.node - j));
		throw;
	}
#       endif /* __STL_USE_EXCEPTIONS */
}

template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::new_elements_at_back(size_type new_elements) {
	size_type new_nodes = (new_elements + buffer_size() - 1) / buffer_size();
	reserve_map_at_back(new_nodes);
	size_type i;
	__STL_TRY{
		for (i = 1; i <= new_nodes; ++i)
		*(finish.node + i) = allocate_node();
	}
#       ifdef __STL_USE_EXCEPTIONS
		catch (...) {
		for (size_type j = 1; j < i; ++j)
			deallocate_node(*(finish.node + j));
		throw;
	}
#       endif /* __STL_USE_EXCEPTIONS */
}

template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::destroy_nodes_at_front(iterator before_start) {
	for (map_pointer n = before_start.node; n < start.node; ++n)
		deallocate_node(*n);
}

template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::destroy_nodes_at_back(iterator after_finish) {
	for (map_pointer n = after_finish.node; n > finish.node; --n)
		deallocate_node(*n);
}


//map某一端的备用节点不够用,扩展或调整map的备用节点,已使用节点的个数不变
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::reallocate_map(size_type nodes_to_add,
	bool add_at_front) {
	size_type old_num_nodes = finish.node - start.node + 1;
	size_type new_num_nodes = old_num_nodes + nodes_to_add;

	map_pointer new_nstart;
	if (map_size > 2 * new_num_nodes) {
		//map的大小大于需求的两倍,只是调整一下map,并没有重换,比如两端一端节点过多,一端很少
		//保持元素在中央
		new_nstart = map + (map_size - new_num_nodes) / 2
			+ (add_at_front ? nodes_to_add : 0);
		if (new_nstart < start.node)
			//finish.node指向最后一个元素的首址,copy作用区间[start.node, finish.node + 1),所以要+1
			copy(start.node, finish.node + 1, new_nstart);
		else
			//避免被覆盖掉,从后面开始拷贝
			copy_backward(start.node, finish.node + 1, new_nstart + old_num_nodes);
	}
	else {
		size_type new_map_size = map_size + max(map_size, nodes_to_add) + 2;
		// 配置一块新空间,给新map使用
		map_pointer new_map = map_allocator::allocate(new_map_size);
		new_nstart = new_map + (new_map_size - new_num_nodes) / 2
			+ (add_at_front ? nodes_to_add : 0);
		copy(start.node, finish.node + 1, new_nstart);
		//释放原来的map
		map_allocator::deallocate(map, map_size);

		map = new_map;
		map_size = new_map_size;
	}

	start.set_node(new_nstart);
	finish.set_node(new_nstart + old_num_nodes - 1);
}


// Nonmember functions.



template <class T, class Alloc, size_t BufSiz>
bool operator==(const deque<T, Alloc, BufSiz>& x,
	const deque<T, Alloc, BufSiz>& y) {
	return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
}

template <class T, class Alloc, size_t BufSiz>
bool operator<(const deque<T, Alloc, BufSiz>& x,
	const deque<T, Alloc, BufSiz>& y) {
	return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值