参考 c++ primer 5th ,stl 源码剖析
// myVector.cpp : 简单的vector实现。
//
#include "stdafx.h"
#include <iostream>
#include <initializer_list>
#include <algorithm>
using namespace std;
template< typename T>
class Vector {
public:
typedef T value_type;
typedef value_type* pointer_type;
typedef value_type* iterator;
typedef value_type& reference;
typedef std::ptrdiff_t difference_type;
typedef std::size_t size_type;
Vector():start(nullptr),finish(nullptr),end_of_storage(nullptr){ }
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); }
explicit Vector(size_type n){ fill_initialize(n, T()); }
Vector(std::initializer_list< T>);
Vector(const Vector&);
Vector & operator=( const Vector&);
~Vector();
iterator begin() const{ return start; }
iterator end() const{ return finish; }
void push_back(const T&);
reference operator[] ( size_type n) { return *( begin() + n); }
bool empty() const { return begin() == end(); }
size_type size() const{ return finish - start; }
size_type capacity() const{ return end_of_storage - start; }
void reserve(size_type newsize);
void resize(size_type newsize);
void resize(size_type newsize,const T& t);
void insert(iterator position, size_type n, const T& x);
iterator erase(iterator position)
{
if ( position + 1 != end())
{
copy( position + 1, finish, position);
}
-- finish;
alloc. destroy( finish);
return position;
}
void pop_back()
{
alloc. destroy(-- finish);
}
reference back() {
return *( end() - 1);
}
reference front() {
return * begin();
}
private:
iterator start;
iterator finish;
iterator end_of_storage;
std::allocator<T> alloc;
void chk_n_alloc()
{
if ( size() == capacity())
{
reallocate();
}
}
void reallocate();
void free();
void _alloc_n_move(size_type n);
iterator _allocate_and_fill(size_type n,const T& x);
void fill_initialize(size_type n, const T& value)
{
start = _allocate_and_fill( n, value);
finish = start + n;
end_of_storage = finish;
}
};
template< typename T>
Vector< T>:: Vector( initializer_list< T> l)
{
T * const NewData = alloc.allocate(l.size());
T *p = NewData;
for (const auto &ele : l)
alloc. construct( p++, ele);
start = NewData;
finish = end_of_storage = start + l.size();
}
template< typename T>
Vector< T>:: Vector( const Vector& rhs)
{
T *newData = alloc.allocate(rhs.end() - rhs.begin());
std::uninitialized_copy( rhs. begin(), rhs. end(), newData);
start = newData;
finish = end_of_storage = start + rhs.size();
}
template< typename T>
Vector< T> & Vector< T>::operator=( const Vector& rhs)
{
T *newData = alloc.allocate(rhs.end() - rhs.begin());
std::uninitialized_copy( rhs. begin(), rhs. end(), newData);
free();
start = newData;
finish = end_of_storage = start + rhs.size();
return *this;
}
template< typename T>
Vector< T>::~ Vector()
{
free();
}
template< typename T>
void Vector< T>:: reallocate()
{
std::size_t newCapacity = size() ? 2 * size() : 1;
_alloc_n_move(newCapacity);
}
//tool-function move element to new place which size is n
template< typename T>
void Vector< T>:: _alloc_n_move( size_type n){
T *newAddr = alloc.allocate(n);
T *des = newAddr;
T *old = start;
for (size_type i = 0; i != size(); ++i)
alloc. construct( des++, std:: move(* old++));
free();
start = newAddr;
finish = des;
end_of_storage = start + n;
}
template< typename T>
void Vector< T>:: free() {
if (start)
{
for ( auto it = finish; it != start;)
alloc. destroy(-- it);
alloc. deallocate( start, capacity());
}
}
template< typename T>
void Vector< T>:: push_back( const T& value)
{
chk_n_alloc();
alloc.construct(finish++, value);
}
template< typename T>
void Vector< T>:: reserve( size_type newsize)
{
if (newsize > capacity())
{
_alloc_n_move( newsize);
}
}
template< typename T>
void Vector< T>:: resize( size_type newsize, const T& t)
{
if (newsize > capacity())
{
for ( auto i = size(); i != newsize; ++ i)
push_back( t);
}
else{
for ( auto p = start + newsize; p != finish;)
alloc. destroy( p++);
finish = start + newsize;
}
}
template< typename T>
void Vector< T>:: resize( size_type newsize)
{
resize(newsize, T());
}
template< typename T>
typename Vector< T>:: iterator Vector< T>:: _allocate_and_fill( size_type n, const T& x)
{
iterator result = alloc.allocate(n);
uninitialized_fill_n( result, n, x);
return result;
}
template< typename T>
void Vector< T>:: insert( iterator position, size_type n, const T& x)
{
if (n != 0) {
if ( size_type( end_of_storage - finish) >= 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);
//uninitialized_fill_n(position, elems_after, x_copy);
}
}
else {
//备用空间小于 新增元素个数,须配置额外内存
//首先决定新长度:旧长度的两倍或者旧长度+新增元素个数
const size_type old_size = size();
const size_type len = old_size + max( old_size, n);
iterator new_start = alloc. 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);
for ( auto iter = start; iter != finish;)
alloc. destroy( iter++);
alloc. deallocate( start, end_of_storage - start);
start = new_start;
finish = new_finish;
end_of_storage = new_start + len;
}
}
}
int _tmain( int argc, _TCHAR* argv[])
{
Vector<int> vec;
vec.push_back(1);
vec.push_back(2);
Vector<int> v = { 2, 3, 45, 6, 7 };
vec = v;
v.push_back(111);
Vector<int> v2(v);
for (auto e : v2)
cout << e << '\t';
cout << endl;
//cout << vec.capacity() << endl;
//cout << vec.size() << endl;
vec.pop_back();
vec.pop_back();
for (auto e : vec)
cout << e << '\t';
cout << endl;
//cout << "front " << vec.front() << endl;
//cout << "back " << vec.back() << endl;
vec.insert(vec.end(), 3, 2);
for (auto e : vec)
cout << e << '\t';
cout << endl;
return 0;
}