// 參考侯捷大大的《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;
}
vector (仿sgi stl)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.