vector (仿sgi stl)

   // 参考侯捷大大的《STL源码剖析》尝试自己写一个vector调高下代码水平
  // VS2013下编译 基本模仿sgi stl 
 // by : Ricardo
 
#include <iostream>
#include <memory> 
#include <iterator>
#include <algorithm>
using namespace std;

// 空间配置器默认用allocator<T>  sgi-STL里面用的simple_alloc
template <typename T, typename Alloc = allocator<T> >
class vector
{
public:
	typedef T value_type; //STL标准要求
	typedef value_type* pointer; //STL标准要求
	typedef const value_type* const_pointer;
	 
	// vector内部维护的是一个连续线性空间 普通指针满足所有条件 vector提供随机迭代器
	typedef value_type* iterator; //STL标准要求 
	typedef const value_type* const_iterator;
	typedef value_type& reference; //STL标准要求
	typedef const value_type& const_reference;
	typedef size_t size_type;
	typedef ptrdiff_t difference_type; //STL标准要求

	// 下面两个顺序不能反 如果先typedef iterator版本的话话 reverse_iterator就不是模板了
	typedef reverse_iterator<const_iterator> const_reverse_iterator;  // 反向迭代器
	typedef reverse_iterator<iterator> reverse_iterator;
	
protected:
	// data_allocator 为空间配置器 
	Alloc data_allocator;
	iterator start; // 目前使用空间的头
	iterator finish; // 目前使用空间的尾
	iterator end_of_storage; // 目前可用空间的尾

protected:
	void insert_aux(iterator positiion, const T &x); // 提供插入操作

	template <typename InputIterator>
	void range_insert(iterator pos, InputIterator first, InputIterator last, input_iterator_tag);
	// 填充并且初始化
	void fill_initialize(size_type n, const T& value)
	{
		start = allocate_and_fill(n, value);
		finish = start + n;
		end_of_storage = finish;
	}
	// 分配空间,并且复制对象到分配的空间处
	iterator allocate_and_fill(size_type n, const T& x)
	{
		iterator result = data_allocator.allocate(n);
		uninitialized_fill_n(result, n, x);
		return result;
	}
	// 分配空间并copy一个区间的元素到新空间处
	template <typename ForwardIterator>
	iterator allocate_and_copy(size_type n, ForwardIterator first, ForwardIterator last)
	{
		iterator result = data_allocator.allocate(n);
		uninitialized_copy(first, last, result);
		return result;
	}
	// 将一个迭代器范围插入到内存空间
	template <typename InputIterator>
	void range_initialize(InputIterator first, InputIterator last, input_iterator_tag)
	{
		for (; first != last; ++first)
		{
			push_back(*first);
		}
	}
	// 销毁元素
	void destory(iterator first, iterator last)
	{
		for (; last != first; --last)
			data_allocator.destroy(--last);
	}
	// 释放内存
	void deallocate()
	{			
		if (start)
			data_allocator.deallocate(start, end_of_storage - start);
		start = finish = end_of_storage = nullptr;
	}
public:
	//  获取几种迭代器
	iterator begin()
	{
		return start;
	}
	const_iterator begin() const
	{
		return start;
	}
	iterator end()
	{
		return finish;
	}
	const_iterator end() const
	{
		return finish;
	}
	reverse_iterator rbegin()
	{
		return reverse_iterator(end());
	}
	const_reverse_iterator rbegin() const
	{
		return const_reverse_iterator(end());
	}
	reverse_iterator rend()
	{
		return reverse_iterator(begin());
	}
	
	size_type size() const // 返回当前对象个数
	{
		return size_type(end() - begin());
	}
	size_type max_size() const // size_type是无符号数 -1溢出后为size_t的最大值
	{
		return size_type(-1) / sizeof(T);
	}
	size_type capacity() const // 返回当前vector在重新进行内存分配以前所能容纳的元素数量.
	{
		return size_type(end_of_storage - begin());
	}

	bool empty() const{ return begin() == end(); } //判空

	reference operator[](size_type n) // 重载下标运算符
	{
		return *(begin() + n);
	}
	const_reference operator[](size_type n) const
	{
		return *(begin() + n);
	}

public:
	// 默认构造函数 不分配内存空间 成为一个空容器
	vector() : start(nullptr), finish(nullptr), end_of_storage(nullptr){}
	// 比如vector<int> demo(4, value); 构造n个连续的value
	vector(size_type n, const T &value)
	{
		fill_initialize(n, value);
	}
	vector(int n, const T &value)
	{
		fill_initialize(n, value);
	}
	vector(long n, const T &value)
	{
		fill_initialize(n, value);
	}
	// 比如vector<int> demo(4); 需要T提供默认构造函数
	explicit vector(size_type n) { fill_initialize(n, T()); }
	// copy构造函数
	vector(const vector<T, Alloc>& x)
	{
		start = allocate_and_copy(x.end()-x.begin(), x.begin(), x.end());
		finish = start + (x.end() - x.begin());
		end_of_storage = finish;
	}
	// 接受一个迭代器范围来构造
	template <typename InputIterator>
	vector(InputIterator first, InputIterator last) : start(nullptr), finish(nullptr), end_of_storage(nullptr)
	{
		range_initialize(first, last, _Iter_cat(first)); // _Iter_cat是VS2013下的iterator_category()函数实现 决定某个迭代器的类型
	}
	// 析构函数
	~vector()
	{
		destory(start, finish); // 销毁元素
		deallocate(); // 释放内存
	}
	// 重载赋值运算符
	vector<T, Alloc>& operator=(const vector<T, Alloc>& x);

public:
	void reserve(size_type n) // 分配至少能容纳n个元素的空间 不改变元素的数量 仅影响预先分配多大的内存
	{
		if (n > capacity())
		{
			const size_type old_size = size();
			iterator tmp = allocate_and_copy(n, start, finish);
			destory();
			deallocate();
			start = tmp;
			finish = tmp + old_size;
			end_of_storage = start + n;
		}
	}
	// 提供访问函数 返回头 尾的引用
	reference front() { return *begin(); }
	const_reference front() const { return *begin(); }
	reference back() { return *(end() - 1); }
	const_reference back() const { return *(end() - 1); }

	// 像vector尾部添加一个元素 如果有备用空间直接构造 如果木有则要重新分配内存
	void push_back(const T &x)
	{
		if (finish != end_of_storage)
		{
			data_allocator.construct(finish, x);
			++finish;
		}
		else
			insert_aux(end(), x);
	}
	// 删除尾后元素 只析构 不释放内存
	void pop_back()
	{
		--finish;
		data_allocator.destory(finish);
	}
	// 交换两个vector 实际上是交换两个容器内部指针	
	void swap(vector<T, Alloc> &x)
	{
		using std::swap;
		swap(start, x.start);
		swap(finish, x.finish);
		swap(end_of_storage, x.end_of_storage);
	}
	iterator erase(iterator position) // 删除元素 不释放内存
	{
		if ((position + 1) != end())
			copy(position+1, finish, position);
		--finsih;
		data_allocator.destory(finish);
		return position; // 返回值是指向删除的最后一个元素的下一位置的迭代器
	}
	iterator erase(iterator first, iterator last) // 删除一个范围内的元素
	{
		iterator i = copy(last, finish, first);
		destory(i, finish);
		finish = finish - (last - first);
		return first; // 返回值是指向删除的最后一个元素的下一位置的迭代器
	}
	void clear() // 清空容器
	{
		erase(begin(), end());
	}
	void resize(size_type new_size, const T& x) // 调整size但不会重新调整内存
	{
		if (new_size < size())
			erase(begin() + new_size, end());
		else
			insert(end(), new_size - size(), x);
	}

	iterator insert(iterator position, const T& x) // 在指定位置插入元素 返回指向新插入元素的迭代器
	{
		size_type n = position - begin(); //记录position的距离
		if (finish != end_of_storage && position == end()) // 有备用空间并且在尾后插入
		{
			data_allocator.construct(finish, x);
			++finish;
		}
		else // 木有备用空间或者在中间某个地方插入 调用insert_aux来插入
			insert_aux(position, x);
		return begin() + n;
	}
	iterator insert(iterator position) // 插入一个默认构造的东东
	{
		return insert(position, T());
	}
	// 在指定位置position 插入n个元素
	void insert(iterator position, size_type n, const T& x);
	// 插入一个区间
	/*template <typename InputIterator>
	iterator insert(iterator position, InputIterator first, InputIterator last)
	{
		range_insert(position, first, last, _Iter_cat(first));
	}*/
	void insert(iterator position, const_iterator first, const_iterator last);

};
// vector内部实现部分如下


// 比较两个容器是否相等
template <typename T, typename Alloc>
inline bool operator==(const vector<T, Alloc>& x, const vector<T, Alloc>& y)
{
	return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
}
// 字典序
template <typename T, typename Alloc>
inline bool operator<(const vector<T, Alloc>& x, const vector<T, Alloc>& y)
{
	return lexicographical_compare(x.begin(), x.end(), y.back(), y.end());
}
// 交换两个vector
template <typename T, typename Alloc>
inline void swap(vector<T, Alloc>& x, vector<T, Alloc>& y)
{
	x.swap(y);
}
// 重载赋值运算符
template <typename T, typename Alloc>
vector<T, Alloc>& vector<T, Alloc>::operator=(const vector<T, Alloc>& x)
{
	if (&x != this)
	{
		if (x.size() > capacity()) // 容量不够
		{
			iterator tmp = allocate_and_copy(x.end()-x.begin(), x.begin(), x.end());
			destory(start, finish);
			deallocate();
			start = tmp;
			end_of_storage = start + (x.end() - x.begin());
		}
		else if (size() >= x.size()) // 容量足够
		{
			iterator i = copy(x.begin(), x.end(), begin());
			destory(i, finish);
		}
		else // 有备用空间且元素数少于x
		{
			copy(x.begin(), x.begin() + size(), start);
			uninitialized_copy(x.begin() + size(), x.end(), finish);
		}
	}

}

//在position处插入x 可被insert使用
template <typename T, typename Alloc>
void vector<T, Alloc>::insert_aux(iterator position, const T& x)
{
	if (finish != end_of_storage) // 有备用空间的时候 将position开始 整体后移一位
	{
		data_allocator.construct(finish, *(finish-1));
		++finish;
		T x_copy = x;
		copy_backward(position, finish - 2, finish - 1);
		*position = x_copy;
	}
	else // 备用空间木有了 要插入怎么办
	{
		const size_type old_size = size();
		const size_type len = old_size != 0 ? 2 * old_size : 1; // 如果原大小为0 配置一个元素的空间 不为0则配置原大小两倍大小空间
		iterator new_start = data_allocator.allocate(len); // 分配内存 new_start为实际位置
		iterator new_finish = new_start;
		
		new_finish = uninitialized_copy(start, position, new_start);// 把原来vector的position之前的内容copy到新vector
		data_allocator.construct(new_finish, x); 
		++new_finish;
		new_finish = uninitialized_copy(position, finish, new_finish); //安插点的原内容全部拷贝过来
		//析构并释放原vector
		destory(start, finish);
		deallocate();
		// 调整迭代器 指向新vector
		start = new_start;
		finish = new_finish;
		end_of_storage = new_start + len;
	}
}

// 在position处插入n个x对象
template <typename T, typename Alloc>
void vector<T, Alloc>::insert(iterator position, size_type n, const T& x)
{
	if (n != 0) // n = 0 直接return
	{
		if (size_type(end_of_storage - finish) >= n) //备用空间 >= n
		{
			T x_copy = x;
			const size_type elems_after = finish - position; //插入点后有几个元素
			iterator old_finish = finish;
			if (elems_after > n) // 插入点后的现有元素个数大于新增元素个数
			{
				uninitialized_copy(finish - n, finish, finish);
				finish += n;
				copy_backward(position, old_finish - n, old_finish);
				fill(position, position + n, x_copy);
			}
			else // 小于等于
			{
				uninitialized_fill_n(finish, n-elems_after, x_copy);
				finish += n - elems_after;
				uninitialized_copy(position, old_finish, finish);
				finish += elems_after;
				fill(position, old_finish, x_copy);
			}
		}
		else // 备用空间不能满足新增元素的大小 必须配置额外内存
		{
			const size_type old_size = size();
			const size_type len = old_size + max(old_size, n);
			iterator new_start = data_allocator.allocate(len);
			iterator new_finish = new_start;

			new_finish = uninitialized_copy(start, position, new_start);
			new_finish = uninitialized_fill_n(new_finish, n, x);
			new_finish = uninitialized_copy(position, finish, new_finish);

			// 销毁并释放原vector
			destory(begin(), end());
			deallocate();
			// 调整标记
			start = new_start;
			finish = new_finish;
			end_of_storage = new_start + len;
		}
	}
}
// 在指定位置插入指定区间的对象 
/*template <typename T, typename Alloc>
template <typename InputIterator> // 顺序插入
void vector<T, Alloc>::range_insert(iterator pos, InputIterator first, InputIterator last, input_iterator_tag)
{
	for (; first != last; ++first)
	{
		pos = insert(pos, *first);
		++pos;
	}
}*/

template <typename T, typename Alloc>
void vector<T, Alloc>::insert(iterator position, const_iterator first, const_iterator last)
{
	if (first != last)
	{
		size_type n = last - first;
		if (size_type(end_of_storage-finish) >= n)
		{
			const size_type elems_after = finish - position;
			iterator old_finish = finish;
			if (elems_after > n)
			{
				uninitialized_copy(finish-n, finish, finish);
				finish += n - elems_after;
				copy_backward(position, old_finish-n, old_finish);
				copy(first, last, position);
			}
			else
			{
				uninitialized_copy(first+elems_after, last, finish);
				finish += n - elems_after;
				uninitialized_copy(position, old_finish, finish);
				finish += elems_after;
				copy(first, first + elems_after, position);
			}
		}
		else // 备用空间不足
		{
			const size_type old_size = size();
			const size_type len = old_size + max(old_size, n);
			iterator new_start = data_allocator.allocate(len);
			new_finish = new_start;

			new_finish = uninitialized_copy(start, position, new_start);
			new_finish = uninitialized_copy(first, last, new_finish);
			new_finish = uninitialized_copy(position, finish, new_finish);

			destory(start, finish);
			deallocate();
			start = new_start;
			finish = new_finish;
			end_of_storage = new_start + len;
		}
	}
}

int main()
{
	vector<int> demo(10, 1);
	for (auto &a : demo)
	{
		cout << a << " ";
	}
	cout << endl;
	vector<int> _demo(20, 2);

	swap(demo, _demo);
	for (auto &a : demo)
	{
		cout << a << " ";
	}
	cout << endl;
	demo.push_back(5);
	for (auto &a : demo)
	{
		cout << a << " ";
	}
	cout << endl;
	demo.insert(demo.begin(), 5, 2);
	for (auto &a : demo)
	{
		cout << a << " ";
	}
	cout << endl;
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值