STL源码剖析__vector

按书中给出的简化的代码编写的,省略了异常处理。

vs2012编译时候会报告警,是copy操作的越界告警,虽然没影响,估计要修改下编码方式来解决。

//自行加入reserve函数的实现

 

#ifndef vector_H_
#define vector_H_

#include "allocator.h"

namespace SGISTL
{
	template<typename T, typename Alloc = SGISTL::alloc>
	class vector
	{
	public:
		typedef T            value_type;
		typedef value_type*  pointer;
		typedef value_type*  iterator;
		typedef value_type&  reference;
		typedef size_t       size_type;
		typedef ptrdiff_t    difference_type;
	protected:
		typedef simple_alloc<value_type, alloc> data_allocator;
		iterator start;
		iterator finish;
		iterator end_of_storage;
	protected:
		void insert_aux(iterator position, const T& x) 
		{
			if(finish != end_of_storage) //感觉这里可以再细分成2个函数,一个处理已分配的空间足够,一个处理已分配的空间不足
			{
				construct(finish, *(finish - 1));
				++finish;
				std::copy_backward(position, finish - 2, finish - 1);
				*position = std::move(x);
			}
			else
			{
				const size_type old_size = size();
				const size_type new_size = (old_size != 0 ? old_size * 2 : 1);
				iterator new_start  = data_allocator::allocate(new_size);
				iterator new_finish = new_start; 

				//省略异常处理
				new_finish = SGISTL::uninitialized_copy(start, position, new_start);
				construct(new_finish, x);
				++new_finish;
                new_finish = SGISTL::uninitialized_copy(position, finish, new_finish);

				destroy(start, finish);
				deallocate();

				start = new_start;
				finish = new_finish;
				end_of_storage = start + new_size;
			}
		}

		void deallocate()
		{
			if(start != nullptr)
			{
				data_allocator::deallocate(start, end_of_storage - start);
			}
		}

		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& value)
		{
			iterator result = data_allocator::allocate(n);
			SGISTL::uninitialized_fill_n(result, value);
			return result;
		}

	public:
		vector(): start(nullptr), finish(nullptr), end_of_storage(nullptr) 
		{
		}

		vector(size_type n, const T& value)
		{
			fill_initialize(n, value);
		}

		explicit vector(size_type n)
		{
			fill_initialize(n, T());
		}

		~vector()
		{
			destroy(start, finish);
			deallocate();
		}

		reference operator[](size_type n)
		{
			return *(begin() + n);
		}
	public:
		iterator begin()
		{
			return start;
		}

		iterator end()
		{
			return finish;
		}

		const iterator cbegin()const
		{
			return start;
		}

		const iterator cend()const
		{
			return finish;
		}

		size_type size()const
		{
			return static_cast<size_type>(finish - start);
		}

		size_type capacity()const
		{
			return static_cast<size_type>(end_of_storage - start);
		}

		bool empty()const
		{
			return start == finish;
		}

		reference front()
		{
			return *(begin());
		}

		reference back()
		{
			return *(finish - 1);
		}

		void push_back(const T& value)
		{
			if(finish != end_of_storage)
			{
				construct(finish, value);
				++finish;
			}
			else
			{
				insert_aux(finish, value);
			}
		}

		void pop_back()
		{
			--finish;
			destroy(finish);
		}

		iterator erase(iterator postion)
		{
			if((postion	+ 1) != end)
			{
				std::copy(postion + 1, finish, postion);
				
			}
			--finish;
			destroy(finish);
			return postion;
		}

		iterator erase(iterator first, iterator last)
		{
			iterator iter = std::copy(last, finish, first);
			destroy(iter, finish);
			finish = finish - (last - first);
			return first;
		}

		void resize(size_type new_size, const T& value)
		{
			if(new_size < size())
			{
				erase(begin() + new_size, finish);
			}
			else
			{
				insert(end(), new_size - size(), value);
			}
		}

		void resize(size_type new_size)
		{
			resize(new_size, T());
		}

		void clear()
		{
			erase(start, finish);
		};

		void insert(iterator position, size_type n, const T& value)
		{
			if(n == 0)
			{
				return;
			}

			if(static_cast<size_type>(end_of_storage - finish) >= n)
			{
				const size_type elems_after = finish - position;
				iterator old_finish = finish;
				if(elems_after > n)
				{
					SGISTL::uninitialized_copy(finish - n, finish, finish);
					finish += n;
					std::copy_backward(position, old_finish - n, old_finish);
					std::fill(position, position + n, value);
				}
				else
				{
					uninitialized_fill_n(finish, n - elems_after, value);
					finish += n - elems_after;
					uninitialized_copy(position, old_finish, finish);
					finish += elems_after;
					std::fill(position, old_finish, value);
				}
			}
			else
			{
				const size_type old_size = size();
				const size_type new_size = old_size + max(old_size, n);
				iterator new_start  = data_allocator::allocate(new_size);
				iterator new_finish = new_start;

				new_finish = SGISTL::uninitialized_copy(start, position, new_start);
				new_finish = SGISTL::uninitialized_fill_n(new_finish, n, value);
				new_finish = SGISTL::uninitialized_copy(position, finish, new_finish);

				destroy(start, finish);
				deallocate();

				start  = new_start;
				finish = new_finish;
				end_of_storage = start + new_size;
			};
		};

		void reserve(size_type n)
		{
			if(static_cast<size_type>(end_of_storage - start) < n)
			{
				iterator new_start  = data_allocator::allocate(n);
				iterator new_finish = new_start;
				new_finish = SGISTL::uninitialized_copy(start, finish, new_start);
                
				destroy(start, finish);
				deallocate();

				start  = new_start;
				finish = new_finish;
				end_of_storage = start + n;
			}
		}
	};
};

#endif  

你可能感兴趣的:(STL源码剖析__vector)