磨磨蹭蹭了三
个月终于吧vector的实现给写了一遍 = =
/*
* Vector.h
*
* Created on: Dec 6, 2018
* Author: clh01s
*/
#ifndef VECTOR_H_
#define VECTOR_H_
//#include
#include
#include
#include
#include
#include
template
struct _Vector_base
{
typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
rebind<_Tp>::other _Tp_alloc_type;
typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type>::pointer
pointer;
struct _Vector_impl: public _Tp_alloc_type
{
pointer _M_start; //表示目前使用空间的头
pointer _M_finish; //表示目前使用空间的尾
pointer _M_end_of_storage; //表示目前可用空间的尾
_Vector_impl()
: _Tp_alloc_type(),_M_start(),_M_finish(),_M_end_of_storage()
{}
_Vector_impl(_Tp_alloc_type const& __a) _GLIBCXX_NOEXCEPT
: _Tp_alloc_type(__a),_M_start(),_M_finish(),_M_end_of_storage()
{}
_Vector_impl(_Tp_alloc_type& __a) noexcept
: _Tp_alloc_type(std::move(__a)),
_M_start(),_M_finish(),_M_end_of_storage()
{}
void _M_swap_data(_Vector_impl& __x) _GLIBCXX_NOEXCEPT
{
std::swap(_M_start, __x._M_start);
std::swap(_M_finish, __x._M_finish);
std::swap(_M_end_of_storage, __x._M_end_of_storage);
}
};
public:
typedef _Alloc allocator_type;
_Tp_alloc_type&
_M_get_Tp_allocator() _GLIBCXX_NOEXCEPT
{
return *static_cast<_Tp_alloc_type*>(&this->_M_impl);
}
const _Tp_alloc_type&
_M_get_Tp_allocator() const _GLIBCXX_NOEXCEPT
{
return *static_cast(&this->_M_impl);
}
allocator_type
get_allocator() const _GLIBCXX_NOEXCEPT
{
return allocator_type(_M_get_Tp_allocator());
}
_Vector_base()
:_M_impl(){}
_Vector_base(const allocator_type& __a) _GLIBCXX_NOEXCEPT
:_M_impl(__a){}
_Vector_base(size_t __n)
:_M_impl()
{_M_create_storage(__n);}
_Vector_base(size_t __n, const allocator_type& __a)
:_M_impl(__a)
{_M_create_storage(__n);}
_Vector_base(_Tp_alloc_type&& __a) noexcept
:_M_impl(std::move(__a))
{}
_Vector_base(_Vector_base&& __x) noexcept
:_M_impl(std::move(__x._M_get_Tp_allocator()))
{this->_M_impl._M_swap_data(__x._M_impl);}
_Vector_base(_Vector_base&& __x, const allocator_type& __a)
:_M_impl(__a)
{
if(__x.get_allocator() == __a)
{
this->_M_impl._M_swap_data(__x._M_impl);
}
else
{
size_t __n = __x._M_impl._M_finish - __x._M_impl._M_start;
_M_create_storage(__n);
}
}
//析构函数
~_Vector_base() _GLIBCXX_NOEXCEPT
{
_M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage
- this->_M_impl._M_start);
}
public:
_Vector_impl _M_impl;
//内存分配函数
pointer _M_allocate(size_t __n)
{
typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Tr;
//如果__n不等于0则按照__n构建内存,否则返回一个初始的地址
return __n != 0 ? _Tr::allocate(_M_impl, __n) : pointer();
}
//内存释放函数
void _M_deallocate(pointer __p, size_t __n)
{
typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Tr;
if(__p)
{
_Tr::deallocate(_M_impl, __p, __n);
}
}
private:
void _M_create_storage(size_t __n)
{
//创建指定大小的内存空间
this->_M_impl._M_start = this->_M_allocate(__n);
this->_M_impl._M_finish = this->_M_impl._M_start;
this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
}
};
template>
class my_vector: protected _Vector_base<_Tp, _Alloc>
{
typedef typename _Alloc::value_type _Alloc_value_type;
__glibcxx_class_requires(_Tp, _SGIAssignableConcept)
__glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept)
typedef _Vector_base<_Tp, _Alloc> _Base;
typedef typename _Base::_Tp_alloc_type _Tp_alloc_type;
typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Alloc_traits;
public:
typedef _Tp value_type;
typedef typename _Base::pointer pointer;
typedef typename _Alloc_traits::const_pointer const_pointer;
typedef typename _Alloc_traits::reference reference;
typedef typename _Alloc_traits::const_reference const_reference;
typedef __gnu_cxx::__normal_iterator iterator;
typedef __gnu_cxx::__normal_iterator const_iterator;
typedef std::reverse_iterator const_reverse_iterator;
typedef std::reverse_iterator reverse_iterator;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef _Alloc allocator_type;
protected:
using _Base::_M_allocate;
using _Base::_M_deallocate;
using _Base::_M_impl;
using _Base::_M_get_Tp_allocator;
public:
my_vector()
//判断是否为默认构造
#if __cplusplus >= 201103L
noexcept(is_nothrow_default_constructible<_Alloc>::value)
#endif
:_Base(){ }
explicit
my_vector(const allocator_type& __a) _GLIBCXX_NOEXCEPT
:_Base(__a){}
#if __cpluscplus >= 201103L
explicit
my_vector(size_type __n, const allocator_type$ __a = allocator_type())
:_Base(__n, __a)
{ _M_default_initialize(__n);}
my_vector(size_type __n, const value_type& __value,
const allocator_type& __a = allocate_type())
:_Base(__n, __a)
{_M_fill_initialize(__n, __value);}
#else
my_vector(const my_vector& __x)
:_Base(__x.size(), _Alloc_traits::_S_select_on_copy(__x._M_get_Tp_allocator()))
{
std::__uninitialized_copy_a(__x.begin(), __x.end(), this->_M_impl._M_start,
_M_get_Tp_allocator());
}
~my_vector() _GLIBCXX_NOEXCEPT
{
std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
_M_get_Tp_allocator());
}
#endif
void clear() _GLIBCXX_NOEXCEPT
{_M_erase_at_end(this->_M_impl._M_start);}
size_type
capacity() const _GLIBCXX_NOEXCEPT
{
return size_type(this->_M_impl._M_end_of_storage
- this->_M_impl._M_start);
}
my_vector&
operator=(const my_vector& __x)
{
if(&__x != this)
{
if(_Alloc_traits::_S_propagate_on_copy_assign())
{
if(!_Alloc_traits::_S_always_equal()
&& _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
{
this->clear();
_M_deallocate(this->_M_impl._M_start,
this->_M_impl._M_end_of_storage
- this->_M_start);
this->_M_impl._M_start = nullptr;
this->_M_impl._M_finish = nullptr;
this->_M_impl._M_end_of_storage = nullptr;
}
std::__alloc_on_copy(_M_get_Tp_allocator(),
__x._M_getTp_allocator());
}
const size_type __xlen = __x.size();
if(__xlen > capacity())
{
pointer __tmp = _M_allocate_and_copy(__xlen,__x.begin(),
__x.end());
std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
_M_get_Tp_allocator());
_M_deallocate(this->_M_impl._M_start,
this->_M_impl._M_end_of_storage
- this->_M_impl._M_start);
this->_M_impl._M_start = __tmp;
this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __xlen;
}
else if(size() >= __xlen)
{
std::_Destroy(std::copy(__x.begin(), __x.end(), begin()),
end(), _M_get_Tp_allocator());
}
else
{
std::copy(__x._M_impl._M_start, __x._M_impl._M_start + size(),
this->_M_impl._M_start);
std::__uninitialized_copy_a(__x._M_impl._M_start + size(),
__x._M_impl._M_finish,
this->_M_impl._M_finish,
_M_get_Tp_allocator());
}
this->_M_impl._M_finish = this->_M_impl._M_start + __xlen;
}
return *this;
}
iterator begin() _GLIBCXX_NOEXCEPT
{
return iterator(this->_M_impl._M_start);
}
const_iterator begin() const _GLIBCXX_NOEXCEPT
{
return const_iterator(this->_M_impl._M_start);
}
iterator end() const _GLIBCXX_NOEXCEPT
{
return iterator(this->_M_impl._M_finish);
}
size_type size() const _GLIBCXX_NOEXCEPT
{
return size_type(this->_M_impl._M_finish - this->_M_impl._M_start);
}
size_type
max_size() const _GLIBCXX_NOEXCEPT
{
return _Alloc_traits::max_size(_M_get_Tp_allocator());
}
bool empty() const _GLIBCXX_NOEXCEPT
{
return begin() == end();
}
reference
operator[](size_type __n) _GLIBCXX_NOEXCEPT
{
return *(this->_M_impl._M_start + __n);
}
void
push_back(const value_type& __x)
{
if(this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
{
_Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
__x);
++this->_M_impl._M_finish;
}
else
{
_M_emplace_back_aux(__x);
}
}
const_iterator
cbegin() const noexcept
{
return const_iterator(this->_M_impl._M_start);
}
iterator
erase(const_iterator __position)
{
return _M_erase(begin() + (__position - cbegin()));
}
iterator
erase(const_iterator __first, const_iterator __last)
{
const auto __beg = begin();
const auto __cbeg = cbegin();
return _M_erase(__beg + (__first - __cbeg), __beg + (__last - __cbeg));
}
protected:
template
pointer
_M_allocate_and_copy(size_type __n,
_ForwardIterator __first,_ForwardIterator __last)
{
pointer __result = this->_M_allocate(__n);
try
{
std::__uninitialized_copy_a(__first, __last, __result,
_M_get_Tp_allocator());
return __result;
}
catch(...)
{
_M_deallocate(__result,__n);
__throw_exception_again;
}
}
void
_M_erase_at_end(iterator __pos)
{
this->_M_impl._M_finish = __pos;
}
size_type
_M_check_len(size_type __n, const char* __s) const
{
if(max_size() - size() < __n)
{
__throw_length_error(__N(__s));
}
const size_type __len = size() + std::max(size(), __n);
return (__len < size() || __len > max_size()) ? max_size() : __len;
}
//原有存储空间不够用时的push操作
template
void _M_emplace_back_aux(_Args&&... __args)
{
const size_type __len =
_M_check_len(size_type(1), "Vector::_M_emplace_back_aux");
pointer __new_start(this->_M_allocate(__len));
pointer __new_finish(__new_start);
try
{
_Alloc_traits::construct(this->_M_impl, __new_start + size(),
std::forward<_Args>(__args)...);
__new_finish = pointer();
__new_finish
= std::__uninitialized_move_if_noexcept_a
(this->_M_impl._M_start, this->_M_impl._M_finish,
__new_start,_M_get_Tp_allocator());
++__new_finish;
}
catch(...)
{
//出现异常则执行内存回收操作
if(!__new_finish)
{
_Alloc_traits::destroy(this->_M_impl, __new_start + size());
}
else
{
std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator());
_M_deallocate(__new_start, __len);
__throw_exception_again;
}
}
std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
_M_get_Tp_allocator());
_M_deallocate(this->_M_impl._M_start,
this->_M_impl._M_end_of_storage
- this->_M_impl._M_start);
this->_M_impl._M_start = __new_start;
this->_M_impl._M_finish = __new_finish;
this->_M_impl._M_end_of_storage = __new_start + __len;
}
iterator _M_erase(iterator __position)
{
if(__position +1 != end())
{
//从__position +1的位置开始拷贝所有的元素到__position的位置
//相当于用__position +1的元素替换__position
std::copy(__position+1 , end(), __position);
}
//拷贝完毕后将内存大小--
--this->_M_impl._M_finish;
return __position;
}
// iterator _M_erase(iterator __first, iterator __last)
// {
// if(__first != __last)
// {
// _M_erase_at_end(std::copy(__last, end(), __first));
// }
// return __first;
// }
};
#endif /* VECTOR_H_ */
下面是调用代码:
/*
* test.cpp
*
* Created on: Jul 31, 2018
* Author: clh01s
*/
#include
#include "RB_tree.h"
#include "Vector.h"
using namespace std;
int main()
{
my_vector vec_a;
//为vector添加元素
for(int i = 0; i < 10; ++i)
{
vec_a.push_back(i);
}
cout<<"输出所有元素!"<
执行结果:
clh01s@clh01s:~/testcode/数据结构$ ./a.out
输出所有元素!
vec[0] = 0
vec[1] = 1
vec[2] = 2
vec[3] = 3
vec[4] = 4
vec[5] = 5
vec[6] = 6
vec[7] = 7
vec[8] = 8
vec[9] = 9
删除0123号元素
输出删除后的元素!
vec[0] = 4
vec[1] = 5
vec[2] = 6
vec[3] = 7
vec[4] = 8
vec[5] = 9