(1)内存模型及所实现的操作
(2)源代码,附简要注释(push_back、insert性能和原版vector相当)
#ifndef TINY_VECTOR
#include <memory>
#include <iostream>
namespace tiny_stl
{
//注意:此tiny_vector有四种insert版本
//其中
//template <typename Input>
//iterator insert(const iterator& pos, const Input &first, const Input &last)
//和
//iterator insert(const iterator& pos, size_type count, const value_type& value)
//可能会发生重载冲突,如果value_type = int
template <typename T, typename U = std::allocator<T> >
class tiny_vector
{
public:
using value_type = T; //元素类型
using allocator_type = U; //内存分配器类型
using size_type = size_t; //表示大小的类型
private:
// start——起始地址,first_free——空余内存的起始地址,dest——尾后地址
value_type *start, *first_free, *dest;
static allocator_type alloc; //内存分配器仅有一个
using iterator = value_type*; //用指针表示迭代器
enum dir{head_to_rear, rear_to_head}; //移动对象的次序是从前往后,or从后往前
private:
std::pair<iterator, iterator> alloc_copy(const iterator beg, const iterator end) const
//分配一段内存,并将beg到end之间的对象拷贝过去
{
int n = end - beg;
if(n <= 0)
{
return {NULL, NULL};
}
auto data = alloc.allocate(n);
return {data, std::uninitialized_copy(beg, end, data)}; //调用拷贝构造函数
}
std::pair<iterator, iterator> alloc_move(const iterator beg, const iterator end) const
//分配一段内存,并将beg到end之间的对象移动过去
{
int n = end - beg;
if(n <= 0)
{
return {NULL, NULL};
}
auto data = alloc.allocate(n);
auto ptr = data;
for(auto it = beg; it != end; ++it)
{
alloc.construct(ptr++, std::move(*it)); //调用移动构造函数,窃取it所指对象的资源
}
return {data, ptr};
}
void free_space()
//释放start到dest之间的内存
{
if(start)
{
for(auto it = start; it != first_free; ++it)
{
alloc.destroy(it); //调用对象的析构函数,以释放对象拥有的动态资源
}
alloc.deallocate(start, dest - start); //归还内存给系统
}
start = first_free = dest = NULL;
}
void change_cap(int cap)
//分配大小为cap的连续内存,并将原有的对象(start到first_free之间的对象)部分(or整体)移动过去
//cap大小无限制,故原对象集可能会被截断
{
auto data = alloc.allocate(cap);
size_type n_move = std::min(cap, size());
move_to_raw(start, start + n_move, data);
free_space();
start = data;
dest = start + cap;
first_free = start + n_move;
}
template <typename Input>
void mov