实现的vector跟标准库有那么一点点不同:
1. 支持头部插入和删除,但头部无空位时插入失败
2. 不检查越界
3. resize后改变capacity,如果此时size大于capacity,则size = capacity,否则,size不变
本次实现也是练习而已,如有问题,欢迎指出!
编译环境:GCC 7.3、vs 2005
很久以前实现过一次,现在重新实现,当作练习,熟悉一下底层结构。
有什么问题,欢迎指出!
代码如下:
#ifndef __VECTOR_H__
#define __VECTOR_H__
#if __cplusplus >= 201103L
#include <type_traits> // std::forward std::move std::declval
#endif
#include <string.h> // memcpy
#if __cplusplus >= 201103L
#define null nullptr
#else
#define null NULL
#endif
template<typename _Tp>
class vector
{
public:
typedef _Tp value_type;
typedef value_type & reference;
typedef const value_type & const_reference;
typedef value_type* iterator;
typedef const value_type* const_iterator;
typedef unsigned long size_type;
#if __cplusplus >= 201103L
typedef value_type && rvalue_reference;
#endif
public:
vector()
#if __cplusplus >= 201103L
: vector(1)
{ }
#else
: _M_data(null), _M_beg(0), _M_end(0), _M_capacity(1)
{ resize(1); }
#endif
vector(size_type s)
: _M_data(null), _M_beg(0), _M_end(0), _M_capacity(s)
{ resize(_M_capacity); }
#if __cplusplus >= 201103L
vector(vector &&v)
: _M_data(null), _M_beg(0), _M_end(0), _M_capacity(1)
{ swap(v); }
#endif
vector(const vector &v)
: _M_data(null), _M_beg(0), _M_end(0), _M_capacity(1)
{ operator=(v); }
~vector()
{
_M_destroy<iterator, value_type>(begin(), end());
::operator delete[](_M_data);
}
void swap(vector &v)
{
_M_swap<value_type *>(_M_data, v._M_data);
_M_swap<size_type>(_M_beg, v._M_beg);
_M_swap<size_type>(_M_end, v._M_end);
}
vector& operator=(const vector &v)
{
resize(v.size());
memcpy(begin(), v.begin(), sizeof(value_type) * v.size());
_M_end += v.size();
return *this;
}
void resize(size_type s)
{
value_type *tmp = static_cast<value_type *>(::operator new[](sizeof(value_type) * s));
memcpy(tmp, begin(), sizeof(value_type) * size());
if(null != _M_data)
{ ::operator delete[](_M_data); }
_M_data = tmp;
_M_end = size();
_M_beg = 0;
_M_capacity = s;
}
void push_back(const_reference t)
{
#if __cplusplus >= 201103L
emplace_back(t);
#else
if(_M_end >= capacity())
{ resize(capacity() * 2); }
::new(&_M_data[_M_end++]) value_type(t);
#endif
}
#if __cplusplus >= 201103L
void push_back(rvalue_reference t)
{
if(_M_end >= capacity())
{ resize(capacity() * 2); }
::new(&_M_data[_M_end++]) value_type(std::move(t));
}
#endif
bool push_front(const_reference t)
{
#if __cplusplus >= 201103L
return emplace_front(t);
#else
if(_M_beg == 0)
{ return false; }
::new(&_M_data[--_M_beg]) value_type(t);
return true;
#endif
}
#if __cplusplus >= 201103L
bool push_front(rvalue_reference t)
{
if(_M_beg == 0)
{ return false; }
::new(&_M_data[--_M_beg]) value_type(std::move(t));
return true;
}
#endif
void pop_front()
{ _M_data[_M_beg++].~value_type(); }
void pop_back()
{ _M_data[_M_end--].~value_type(); }
reference front()
{ return *begin(); }
reference back()
{ return *(end() - 1); }
size_type capacity() const
{ return _M_capacity; }
size_type size() const
{ return _M_end - _M_beg; }
bool empty() const
{ return size() == 0; }
iterator begin()
{ return &_M_data[_M_beg]; }
const_iterator begin() const
{ return &_M_data[_M_beg]; }
iterator end()
{ return &_M_data[_M_end]; }
const_iterator end() const
{ return &_M_data[_M_end]; }
const_iterator cbegin() const
{ return begin(); }
const_iterator cend() const
{ return end(); }
reference operator[](size_type i)
{ return _M_data[i + _M_beg]; }
const_reference operator[](size_type i) const
{ return _M_data[i + _M_beg]; }
reference at(size_type i)
{ return operator[](i); }
const_reference at(size_type i) const
{ return operator[](i); }
void clear()
{
_M_destroy<iterator, value_type>(begin(), end());
_M_beg = _M_end = 0;
}
#if __cplusplus >= 201103L
template<typename ... Args>
void emplace_back(Args && ...args)
{
if(size() >= capacity())
{ resize(capacity() * 2); }
::new(&_M_data[_M_end++]) value_type(std::forward<value_type>(args)...);
}
template<typename ... Args>
bool emplace_front(Args && ...args)
{
if(_M_beg == 0)
{ return false; }
::new(&_M_data[--_M_beg]) value_type(std::forward<value_type>(args)...);
return true;
}
#endif
private:
#if __cplusplus >= 201103L
template<typename __ForwardIterator,
typename __ValueType = decltype(*std::declval<__ForwardIterator>())>
#else
template<typename __ForwardIterator, typename __ValueType>
#endif
void _M_destroy(__ForwardIterator b, __ForwardIterator e)
{
while(b != e)
{ b++->~__ValueType(); }
}
template<typename __Type>
void _M_swap(__Type &t1, __Type &t2)
{
__Type tmp = t1;
t1 = t2;
t2 = tmp;
}
private:
value_type *_M_data;
size_type _M_beg;
size_type _M_end; // 不包含该位置
size_type _M_capacity;
};
#endif // __VECTOR_H__