序列式容器
研究数据的特定排列方式,以利于搜索或排序或其它特殊目的,称为数据结构。
STL容器将运用最广的一些数据结构实现出来。
常用的数据结构不外乎array(数组), list(链表), tree(树), stack(堆栈), queue(队列), hash table(散列表), set(集合), map(映射),根据数据在容器中排列的特性,数据结构又分为序列式(sequence)和关联式(associative)。
序列式容器,其中元素可序,但未必有序。
C++提供序列式容器array,STL提供vector, list, deque, stack, queue, priority-queue等序列式容器。
其中stack和queue只是将deque改头换面而已,技术上归类为一种配接器。
vector
vector维护的是一个连续线性空间,普通指针也可作为vector的迭代器使用。
vector提供的迭代器是Random Access Iterators。
为了降低空间配置时的速度成本,vector实际配置大小比需求量更大,以备将来可能的扩充,这便是容量capacity。
uninitialized_fill_n()根据第一参数的类型特性,type traits,决定使用算法fill_n()或反复调用construct()来完成任务。
动态增加大小,并不是在原空间之后续接新空间,而是以原大小的两倍另外配置一块较大空间,然后将原内容拷贝过来,然后在原内容之后构造新元素,并释放原空间。
namespace std _GLIBCXX_VISIBILITY(default)
{
template<typename _Tp, typename _Alloc>
struct _Vector_base
{
//声明内存分配器_Alloc下rebind<_Tp>::other别名为_Tp_alloc_type
typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
rebind<_Tp>::other _Tp_alloc_type
//pointer声明为_Alloc<_Tp>::pointer即_Tp*
typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type>::pointer
pointer;
struct _Vector_impl //vector内存分配器
: public _Tp_alloc_type //继承自_Alloc<_Tp>
{ //增加配置空间的指针_M_start、_M_finish、_M_end_of_storage
pointer _M_start; //表已配置空间的头
pointer _M_finish; //表已配置空间的尾
pointer _M_end_of_storage; //表可用空间的尾
//以下省略部分构造函数
void _M_swap_data(_Vector_impl& __x) _GLIBCXX_NOEXCEPT //交换函数
{ //使用算法std::swap完成配置空间指针值的交换
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);
}
}; //vector内存结构及分配
public:
typedef _Alloc allocator_type; //_Alloc重命名为allocator_type
_Tp_alloc_type& //取成员_M_impl,static_cast将该成员由派生类转换为基类并返回
_M_get_Tp_allocator() _GLIBCXX_NOEXCEPT
{ return *static_cast<_Tp_alloc_type*>(&this->_M_impl); }
allocator_type //将_M_get_Tp_allocator返回的类型成员构造临时allocator_type对象返回
get_allocator() const _GLIBCXX_NOEXCEPT
{ return allocator_type(_M_get_Tp_allocator()); }
//以下省略部分构造函数和析构函数
public:
_Vector_impl _M_impl;
pointer //分配一段原始的、未构造的内存,大小为n
_M_allocate(size_t __n)
{
typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Tr;
return __n != 0 ? _Tr::allocate(_M_impl, __n) : pointer();
}
void //释放地址p开始大小为n的内存
_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;
}
}; //模板类_Vector_base定义完成
//模板类vector,缺省使用allocator作为空间配置器
template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
class vector : protected _Vector_base<_Tp, _Alloc>
{
static_assert(is_same<typename remove_cv<_Tp>::type, _Tp>::value,
"std::vector must have a non-const, non-volatile value_type");
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: //vector内嵌类型定义
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<pointer, vector> iterator; //迭代器
typedef __gnu_cxx::__normal_iterator<const_pointer, vector>
const_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef std::reverse_iterator<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:
//以下构造函数
vector() //默认构造函数
noexcept(is_nothrow_default_constructible<_Alloc>::value)
: _Base() { }
explicit //构造函数,不可隐式类型转换
vector(const allocator_type& __a) _GLIBCXX_NOEXCEPT
: _Base(__a) { }
explicit //分配__n个内存空间
vector(size_type __n, const allocator_type& __a = allocator_type())
: _Base(__n, __a)
{ _M_default_initialize(__n); }
vector(size_type __n, const value_type& __value,
const allocator_type& __a = allocator_type()) //分配__n个内存空间,并初始化为__value
: _Base(__n, __a)
{ _M_fill_initialize(__n, __value); }
vector(const vector& __x) //拷贝构造函数
: _Base(__x.size(),
_Alloc_traits::_S_select_on_copy(__x._M_get_Tp_allocator()))
{
this->_M_impl._M_finish =
std::__uninitialized_copy_a(__x.begin(), __x.end(),
this->_M_impl._M_start,
_M_get_Tp_allocator());
}
vector(vector&& __x) noexcept //移动构造函数,通知标准库不抛出异常
: _Base(std::move(__x)) { }
vector(const vector& __x, const allocator_type& __a)
: _Base(__x.size(), __a)
{
this->_M_impl._M_finish =
std::__uninitialized_copy_a(__x.begin(), __x.end(),
this->_M_impl._M_start,
_M_get_Tp_allocator());
}
vector(vector&& __rv, const allocator_type& __m)
noexcept(_Alloc_traits::_S_always_equal())
: _Base(std::move(__rv), __m)
{
if (__rv.get_allocator() != __m)
{
this->_M_impl._M_finish =
std::__uninitialized_move_a(__rv.begin(), __rv.end(),
this->_M_impl._M_start,
_M_get_Tp_allocator());
__rv.clear();
}
}
vector(initializer_list<value_type> __l,
const allocator_type& __a = allocator_type()) //初始值列表
: _Base(__a)
{
_M_range_initialize(__l.begin(), __l.end(),
random_access_iterator_tag());
}
template<typename _InputIterator,
typename = std::_RequireInputIter<_InputIterator>>
vector(_InputIterator __first, _InputIterator __last,
const allocator_type& __a = allocator_type()) //指定迭代器范围初始化
: _Base(__a)
{ _M_initialize_dispatch(__first, __last, __false_type()); }
~vector() _GLIBCXX_NOEXCEPT //析构函数
{
std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
_M_get_Tp_allocator());
_GLIBCXX_ASAN_ANNOTATE_BEFORE_DEALLOC;
}
//赋值运算符重载,可接受左值引用、右值引用及初始值列表赋值
vector&
operator=(const vector& __x);
vector&
operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
{
constexpr bool __move_storage =
_Alloc_traits::_S_propagate_on_move_assign()
|| _Alloc_traits::_S_always_equal();
_M_move_assign(std::move(__x), __bool_constant<__move_storage>());
return *this;
}
vector&
operator=(initializer_list<value_type> __l)
{
this->_M_assign_aux(__l.begin(), __l.end(),
random_access_iterator_tag());
return *this;
}
//assign,接受大小及初始值、迭代器范围、初始值列表
void
assign(size_type __n, const value_type& __val)
{ _M_fill_assign(__n, __val); }
template<typename _InputIterator,
typename = std::_RequireInputIter<_InputIterator>>
void
assign(_InputIterator __first, _InputIterator __last)
{ _M_assign_dispatch(__first, __last, __false_type()); }
void
assign(initializer_list<value_type> __l)
{
this->_M_assign_aux(__l.begin(), __l.end(),
random_access_iterator_tag());
}
using _Base::get_allocator;
//begin、end、rbegin、rend,省略const迭代器返回
iterator
begin() _GLIBCXX_NOEXCEPT
{ return iterator(this->_M_impl._M_start); }
iterator
end() _GLIBCXX_NOEXCEPT
{ return iterator(this->_M_impl._M_finish); }
reverse_iterator
rbegin() _GLIBCXX_NOEXCEPT
{ return reverse_iterator(end()); }
reverse_iterator
rend() _GLIBCXX_NOEXCEPT
{ return reverse_iterator(begin()); }
//cbegin、cend、crbegin、crend
const_iterator
cbegin() const noexcept
{ return const_iterator(this->_M_impl._M_start); }
const_iterator
cend() const noexcept
{ return const_iterator(this->_M_impl._M_finish); }
const_reverse_iterator
crbegin() const noexcept
{ return const_reverse_iterator(end()); }
const_reverse_iterator
crend() const noexcept
{ return const_reverse_iterator(begin()); }
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()); }
//增大或缩小容器
void
resize(size_type __new_size)
{
if (__new_size > size())
_M_default_append(__new_size - size());
else if (__new_size < size())
_M_erase_at_end(this->_M_impl._M_start + __new_size);
}
void
resize(size_type __new_size, const value_type& __x)
{
if (__new_size > size())
_M_fill_insert(end(), __new_size - size(), __x);
else if (__new_size < size())
_M_erase_at_end(this->_M_impl._M_start + __new_size);
}
void
shrink_to_fit() //将capacity()减少为与size()相同大小
{ _M_shrink_to_fit(); }
size_type //容器容量
capacity() const _GLIBCXX_NOEXCEPT //不重新分配内存空间下,可以保存多少元素
{ return size_type(this->_M_impl._M_end_of_storage
- this->_M_impl._M_start); }
bool //容器是否为空
empty() const _GLIBCXX_NOEXCEPT
{ return begin() == end(); }
void
reserve(size_type __n); //分配至少容纳n个元素的内存空间。
//下标运算符重载,省略返回const引用
reference
operator[](size_type __n) _GLIBCXX_NOEXCEPT
{
__glibcxx_requires_subscript(__n);
return *(this->_M_impl._M_start + __n);
}
protected:
void //检查__n是否在容器范围内
_M_range_check(size_type __n) const //at中安全检查,下标运算符不检查
{
if (__n >= this->size())
__throw_out_of_range_fmt(__N("vector::_M_range_check: __n "
"(which is %zu) >= this->size() "
"(which is %zu)"),
__n, this->size());
}
public:
//at、front、back、data,省略返回const引用或指针
reference
at(size_type __n)
{
_M_range_check(__n); //安全检查
return (*this)[__n]; //调用下标运算符
}
reference
front() _GLIBCXX_NOEXCEPT
{
__glibcxx_requires_nonempty();
return *begin();
}
reference
back() _GLIBCXX_NOEXCEPT
{
__glibcxx_requires_nonempty();
return *(end() - 1);
}
_Tp*
data() _GLIBCXX_NOEXCEPT
{ return _M_data_ptr(this->_M_impl._M_start); }
//push_back,接受左值引用、右值引用
void
push_back(const value_type& __x)
{
if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
{
_GLIBCXX_ASAN_ANNOTATE_GROW(1);
_Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
__x);
++this->_M_impl._M_finish;
_GLIBCXX_ASAN_ANNOTATE_GREW(1);
}
else
_M_realloc_insert(end(), __x);
}
void
push_back(value_type&& __x)
{ emplace_back(std::move(__x)); }
//emplace_back
template<typename... _Args>
void
emplace_back(_Args&&... __args);
void
pop_back() _GLIBCXX_NOEXCEPT
{
__glibcxx_requires_nonempty();
--this->_M_impl._M_finish;
_Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish);
_GLIBCXX_ASAN_ANNOTATE_SHRINK(1);
}
template<typename... _Args>
iterator
emplace(const_iterator __position, _Args&&... __args)
{ return _M_emplace_aux(__position, std::forward<_Args>(__args)...); }
//insert插入操作
iterator
insert(const_iterator __position, const value_type& __x);
iterator
insert(const_iterator __position, value_type&& __x)
{ return _M_insert_rval(__position, std::move(__x)); }
iterator
insert(const_iterator __position, initializer_list<value_type> __l)
{
auto __offset = __position - cbegin();
_M_range_insert(begin() + __offset, __l.begin(), __l.end(),
std::random_access_iterator_tag());
return begin() + __offset;
}
iterator
insert(const_iterator __position, size_type __n, const value_type& __x)
{
difference_type __offset = __position - cbegin();
_M_fill_insert(begin() + __offset, __n, __x);
return begin() + __offset;
}
template<typename _InputIterator,
typename = std::_RequireInputIter<_InputIterator>>
iterator
insert(const_iterator __position, _InputIterator __first,
_InputIterator __last)
{
difference_type __offset = __position - cbegin();
_M_insert_dispatch(begin() + __offset,
__first, __last, __false_type());
return begin() + __offset;
}
//erase
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));
}
//swap
void
swap(vector& __x) _GLIBCXX_NOEXCEPT
{
__glibcxx_assert(_Alloc_traits::propagate_on_container_swap::value
|| _M_get_Tp_allocator() == __x._M_get_Tp_allocator());
this->_M_impl._M_swap_data(__x._M_impl);
_Alloc_traits::_S_on_swap(_M_get_Tp_allocator(),
__x._M_get_Tp_allocator());
}
//clear
void
clear() _GLIBCXX_NOEXCEPT
{ _M_erase_at_end(this->_M_impl._M_start); }
//以下省略部分内容
};
//容器比较
template<typename _Tp, typename _Alloc>
inline bool
operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
{ return (__x.size() == __y.size()
&& std::equal(__x.begin(), __x.end(), __y.begin())); }
template<typename _Tp, typename _Alloc>
inline bool
operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
{ return std::lexicographical_compare(__x.begin(), __x.end(),
__y.begin(), __y.end()); }
/// Based on operator==
template<typename _Tp, typename _Alloc>
inline bool
operator!=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
{ return !(__x == __y); } //调用相等运算符比较
/// Based on operator<
template<typename _Tp, typename _Alloc>
inline bool
operator>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
{ return __y < __x; } //调用<运算符比较
/// Based on operator<
template<typename _Tp, typename _Alloc>
inline bool
operator<=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
{ return !(__y < __x); } //调用<运算符比较
/// Based on operator<
template<typename _Tp, typename _Alloc>
inline bool
operator>=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
{ return !(__x < __y); } //调用<运算符比较
/// See std::vector::swap().
template<typename _Tp, typename _Alloc>
inline void
swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>& __y)
_GLIBCXX_NOEXCEPT_IF(noexcept(__x.swap(__y)))
{ __x.swap(__y); } //容器交换
} // namespace std