vector的实现

9 篇文章 0 订阅
3 篇文章 0 订阅

磨磨蹭蹭了三

个月终于吧vector的实现给写了一遍 = =

/*
 * Vector.h
 *
 *  Created on: Dec 6, 2018
 *      Author: clh01s
 */

#ifndef VECTOR_H_
#define VECTOR_H_

//#include <vector>
#include <bits/stl_iterator_base_funcs.h>
#include <bits/functexcept.h>
#include <bits/concept_check.h>
#include <initializer_list>
#include <iostream>

template<typename _Tp, typename _Alloc>
struct _Vector_base
{
	typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
		rebind<_Tp>::other _Tp_alloc_type;
	typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type>::pointer
		pointer;
	struct _Vector_impl: public _Tp_alloc_type
	{
		pointer _M_start;			//表示目前使用空间的头
		pointer _M_finish;			//表示目前使用空间的尾
		pointer _M_end_of_storage;  //表示目前可用空间的尾
		_Vector_impl()
		: _Tp_alloc_type(),_M_start(),_M_finish(),_M_end_of_storage()
		{}

		_Vector_impl(_Tp_alloc_type const& __a) _GLIBCXX_NOEXCEPT
		: _Tp_alloc_type(__a),_M_start(),_M_finish(),_M_end_of_storage()
		{}

		_Vector_impl(_Tp_alloc_type& __a) noexcept
		: _Tp_alloc_type(std::move(__a)),
		  _M_start(),_M_finish(),_M_end_of_storage()
		  {}

		void _M_swap_data(_Vector_impl& __x) _GLIBCXX_NOEXCEPT
		{
			std::swap(_M_start, __x._M_start);
			std::swap(_M_finish, __x._M_finish);
			std::swap(_M_end_of_storage, __x._M_end_of_storage);
		}
	};

	public:
	typedef _Alloc allocator_type;

	_Tp_alloc_type&
	_M_get_Tp_allocator() _GLIBCXX_NOEXCEPT
	{
		return *static_cast<_Tp_alloc_type*>(&this->_M_impl);
	}

	const _Tp_alloc_type&
	_M_get_Tp_allocator() const _GLIBCXX_NOEXCEPT
	{
		return *static_cast<const _Tp_alloc_type*>(&this->_M_impl);
	}

	allocator_type
	get_allocator() const _GLIBCXX_NOEXCEPT
	{
		return allocator_type(_M_get_Tp_allocator());
	}

	_Vector_base()
	:_M_impl(){}

	_Vector_base(const allocator_type& __a) _GLIBCXX_NOEXCEPT
	:_M_impl(__a){}

	_Vector_base(size_t __n)
	:_M_impl()
	{_M_create_storage(__n);}

	_Vector_base(size_t __n, const allocator_type& __a)
	:_M_impl(__a)
	{_M_create_storage(__n);}

	_Vector_base(_Tp_alloc_type&& __a) noexcept
	:_M_impl(std::move(__a))
	{}

	_Vector_base(_Vector_base&& __x) noexcept
	:_M_impl(std::move(__x._M_get_Tp_allocator()))
	{this->_M_impl._M_swap_data(__x._M_impl);}

	_Vector_base(_Vector_base&& __x, const allocator_type& __a)
	:_M_impl(__a)
	{
		if(__x.get_allocator() == __a)
		{
			this->_M_impl._M_swap_data(__x._M_impl);
		}
		else
		{
			size_t __n = __x._M_impl._M_finish - __x._M_impl._M_start;
			_M_create_storage(__n);
		}
	}
	//析构函数
	~_Vector_base() _GLIBCXX_NOEXCEPT
	{
		_M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage
				- this->_M_impl._M_start);
	}

	public:
	_Vector_impl _M_impl;

	//内存分配函数
	pointer _M_allocate(size_t __n)
	{
		typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Tr;
		//如果__n不等于0则按照__n构建内存,否则返回一个初始的地址
		return __n != 0 ? _Tr::allocate(_M_impl, __n) : pointer();
	}

	//内存释放函数
	void _M_deallocate(pointer __p, size_t __n)
	{
		typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Tr;
		if(__p)
		{
			_Tr::deallocate(_M_impl, __p, __n);
		}
	}
	private:
	void _M_create_storage(size_t __n)
	{
		//创建指定大小的内存空间
		this->_M_impl._M_start = this->_M_allocate(__n);
		this->_M_impl._M_finish = this->_M_impl._M_start;
		this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
	}
};

template<typename _Tp, typename _Alloc = std::allocator<_Tp>>
class my_vector: protected _Vector_base<_Tp, _Alloc>
{
	typedef typename _Alloc::value_type _Alloc_value_type;
	__glibcxx_class_requires(_Tp, _SGIAssignableConcept)
	__glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept)

	typedef _Vector_base<_Tp, _Alloc> _Base;
	typedef typename _Base::_Tp_alloc_type _Tp_alloc_type;
	typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Alloc_traits;

public:
	typedef _Tp value_type;
	typedef typename _Base::pointer pointer;
	typedef typename _Alloc_traits::const_pointer const_pointer;
	typedef typename _Alloc_traits::reference reference;
	typedef typename _Alloc_traits::const_reference const_reference;
	typedef __gnu_cxx::__normal_iterator<pointer, my_vector> iterator;
	typedef __gnu_cxx::__normal_iterator<const_pointer, my_vector> const_iterator;
	typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
	typedef std::reverse_iterator<iterator> reverse_iterator;
	typedef size_t size_type;
	typedef ptrdiff_t difference_type;
	typedef _Alloc allocator_type;

protected:
	using _Base::_M_allocate;
	using _Base::_M_deallocate;
	using _Base::_M_impl;
	using _Base::_M_get_Tp_allocator;

public:
	my_vector()
//判断是否为默认构造
#if __cplusplus >= 201103L
	noexcept(is_nothrow_default_constructible<_Alloc>::value)
#endif
	:_Base(){ }

	explicit
	my_vector(const allocator_type& __a) _GLIBCXX_NOEXCEPT
	:_Base(__a){}

#if __cpluscplus >= 201103L
	explicit
	my_vector(size_type __n, const allocator_type$ __a = allocator_type())
	:_Base(__n, __a)
	{ _M_default_initialize(__n);}

	my_vector(size_type __n, const value_type& __value,
			const allocator_type& __a = allocate_type())
	:_Base(__n, __a)
	{_M_fill_initialize(__n, __value);}
#else
	my_vector(const my_vector& __x)
	:_Base(__x.size(), _Alloc_traits::_S_select_on_copy(__x._M_get_Tp_allocator()))
	{
		std::__uninitialized_copy_a(__x.begin(), __x.end(), this->_M_impl._M_start,
				_M_get_Tp_allocator());
	}

	~my_vector() _GLIBCXX_NOEXCEPT
	{
		std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
				_M_get_Tp_allocator());
	}
#endif

	void clear() _GLIBCXX_NOEXCEPT
	{_M_erase_at_end(this->_M_impl._M_start);}

	size_type
	capacity() const _GLIBCXX_NOEXCEPT
	{
		return size_type(this->_M_impl._M_end_of_storage
				- this->_M_impl._M_start);
	}

	my_vector&
	operator=(const my_vector& __x)
	{
		if(&__x != this)
		{
			if(_Alloc_traits::_S_propagate_on_copy_assign())
			{

				if(!_Alloc_traits::_S_always_equal()
				&& _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
				{
					this->clear();
					_M_deallocate(this->_M_impl._M_start,
							this->_M_impl._M_end_of_storage
							- this->_M_start);
					this->_M_impl._M_start = nullptr;
					this->_M_impl._M_finish = nullptr;
					this->_M_impl._M_end_of_storage = nullptr;
				}
				std::__alloc_on_copy(_M_get_Tp_allocator(),
						__x._M_getTp_allocator());
			}

			const size_type __xlen = __x.size();
			if(__xlen > capacity())
			{
				pointer __tmp = _M_allocate_and_copy(__xlen,__x.begin(),
						__x.end());
				std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
						_M_get_Tp_allocator());
				_M_deallocate(this->_M_impl._M_start,
						this->_M_impl._M_end_of_storage
						- this->_M_impl._M_start);
				this->_M_impl._M_start = __tmp;
				this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __xlen;
			}
			else if(size() >= __xlen)
			{
				std::_Destroy(std::copy(__x.begin(), __x.end(), begin()),
						end(), _M_get_Tp_allocator());
			}
			else
			{
				std::copy(__x._M_impl._M_start, __x._M_impl._M_start + size(),
						this->_M_impl._M_start);
				std::__uninitialized_copy_a(__x._M_impl._M_start + size(),
						__x._M_impl._M_finish,
						this->_M_impl._M_finish,
						_M_get_Tp_allocator());
			}
			this->_M_impl._M_finish = this->_M_impl._M_start + __xlen;
		}
		return *this;
	}

	iterator begin() _GLIBCXX_NOEXCEPT
	{
		return iterator(this->_M_impl._M_start);
	}

	const_iterator begin() const _GLIBCXX_NOEXCEPT
	{
		return const_iterator(this->_M_impl._M_start);
	}

	iterator end() const _GLIBCXX_NOEXCEPT
	{
		return iterator(this->_M_impl._M_finish);
	}

	size_type size() const _GLIBCXX_NOEXCEPT
	{
		return size_type(this->_M_impl._M_finish - this->_M_impl._M_start);
	}

	size_type
	max_size() const _GLIBCXX_NOEXCEPT
	{
		return _Alloc_traits::max_size(_M_get_Tp_allocator());
	}

	bool empty() const _GLIBCXX_NOEXCEPT
	{
		return begin() == end();
	}

	reference
	operator[](size_type __n) _GLIBCXX_NOEXCEPT
	{
		return *(this->_M_impl._M_start + __n);
	}

	void
	push_back(const value_type& __x)
	{
		if(this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
		{
			_Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
					__x);
			++this->_M_impl._M_finish;
		}
		else
		{
			_M_emplace_back_aux(__x);
		}
	}

	const_iterator
	cbegin() const noexcept
	{
		return const_iterator(this->_M_impl._M_start);
	}

	iterator
	erase(const_iterator __position)
	{
		return _M_erase(begin() + (__position - cbegin()));
	}

	iterator
	erase(const_iterator __first, const_iterator __last)
	{
		const auto __beg = begin();
		const auto __cbeg = cbegin();
		return _M_erase(__beg + (__first - __cbeg), __beg + (__last - __cbeg));
	}

protected:

	template<typename _ForwardIterator>
	pointer
	_M_allocate_and_copy(size_type __n,
			_ForwardIterator __first,_ForwardIterator __last)
	{
		pointer __result = this->_M_allocate(__n);
		try
		{
			std::__uninitialized_copy_a(__first, __last, __result,
					_M_get_Tp_allocator());
			return __result;
		}
		catch(...)
		{
			_M_deallocate(__result,__n);
			__throw_exception_again;
		}
	}

	void
	_M_erase_at_end(iterator __pos)
	{
		this->_M_impl._M_finish = __pos;
	}

	size_type
	_M_check_len(size_type __n, const char* __s) const
	{
		if(max_size() - size() < __n)
		{
			__throw_length_error(__N(__s));
		}

		const size_type __len = size() + std::max(size(), __n);
		return (__len < size() || __len > max_size()) ? max_size() : __len;
	}

	//原有存储空间不够用时的push操作
	template<typename... _Args>
	void _M_emplace_back_aux(_Args&&... __args)
	{
		const size_type __len =
				_M_check_len(size_type(1), "Vector::_M_emplace_back_aux");
		pointer __new_start(this->_M_allocate(__len));
		pointer __new_finish(__new_start);
		try
		{
			_Alloc_traits::construct(this->_M_impl, __new_start + size(),
					std::forward<_Args>(__args)...);
			__new_finish = pointer();

			__new_finish
			= std::__uninitialized_move_if_noexcept_a
			(this->_M_impl._M_start, this->_M_impl._M_finish,
					__new_start,_M_get_Tp_allocator());
			++__new_finish;
		}
		catch(...)
		{
			//出现异常则执行内存回收操作
			if(!__new_finish)
			{
				_Alloc_traits::destroy(this->_M_impl, __new_start + size());
			}
			else
			{
				std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator());
				_M_deallocate(__new_start, __len);
				__throw_exception_again;
			}
		}

		std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
				_M_get_Tp_allocator());
		_M_deallocate(this->_M_impl._M_start,
				this->_M_impl._M_end_of_storage
				- this->_M_impl._M_start);
		this->_M_impl._M_start = __new_start;
		this->_M_impl._M_finish = __new_finish;
		this->_M_impl._M_end_of_storage = __new_start + __len;
	}


	iterator _M_erase(iterator __position)
	{
		if(__position +1 != end())
		{
			//从__position +1的位置开始拷贝所有的元素到__position的位置
			//相当于用__position +1的元素替换__position
			std::copy(__position+1  , end(), __position);
		}
		//拷贝完毕后将内存大小--
		--this->_M_impl._M_finish;
		return __position;
	}

//	iterator _M_erase(iterator __first, iterator __last)
//	{
//		if(__first != __last)
//		{
//			_M_erase_at_end(std::copy(__last, end(), __first));
//		}
//		return __first;
//	}
};

#endif /* VECTOR_H_ */

下面是调用代码:

/*
 * test.cpp
 *
 *  Created on: Jul 31, 2018
 *      Author: clh01s
 */
#include <iostream>
#include "RB_tree.h"
#include "Vector.h"


using namespace std;

int main()
{
	my_vector<int> vec_a;
	//为vector添加元素
	for(int i = 0; i < 10; ++i)
	{
		vec_a.push_back(i);
	}
	cout<<"输出所有元素!"<<endl;
	for(int i = 0; i < vec_a.size(); ++i)
	{
		cout<<"vec["<<i<<"] = "<<vec_a[i]<<endl;
	}

	cout<<"删除0123号元素"<<endl;
	//未实现范围删除,所以使用一个个删除
	vec_a.erase(vec_a.begin());
	vec_a.erase(vec_a.begin());
	vec_a.erase(vec_a.begin());
	vec_a.erase(vec_a.begin());
	cout<<"输出删除后的元素!"<<endl;
	for(int i = 0; i < vec_a.size(); ++i)
	{
		cout<<"vec["<<i<<"] = "<<vec_a[i]<<endl;
	}
	return 0;
}

执行结果:

clh01s@clh01s:~/testcode/数据结构$ ./a.out
输出所有元素!
vec[0] = 0
vec[1] = 1
vec[2] = 2
vec[3] = 3
vec[4] = 4
vec[5] = 5
vec[6] = 6
vec[7] = 7
vec[8] = 8
vec[9] = 9
删除0123号元素
输出删除后的元素!
vec[0] = 4
vec[1] = 5
vec[2] = 6
vec[3] = 7
vec[4] = 8
vec[5] = 9

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值