// 参考侯捷大大的《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)
最新推荐文章于 2024-09-05 20:47:07 发布