【C++】std::vector原始碼淺析
阿新 • • 發佈:2018-12-31
std::vector是stl標準模板庫中的一個序列容器,其原始碼實現有幾個特點:
(1)C++中include的標準標頭檔案是沒有“.h”字尾的,其實這是C++的一層包裹,內部實現還是在“.h”檔案中完成的,以我們include的vector為例,其中還會include一些真正的vector實現檔案,如“stl_vector.h”。
(2)vector的實現有一些內部使用的函式和資料型別,它們以下劃線“_”開頭。
(3)vector是個模板類,繼承自_Vector_base,_Vector_base是個struct,它有一個巢狀的struct為_Vector_impl,其中有三個關鍵的指標成員變數,_M_start,_M_finish,_M_end_of_storage,明白這三個變數對vector的理解很有幫助。
(4)我們通常使用的vector介面,大部分是通過形如“_M_xxx”的內部函式實現的。
(5)vector的操作符首先實現了判等“==”和小於“<”,其它的操作符都是基於這兩個操作符實現的。
(6)vector中有一些C++11引入的語法,可在原始碼中茶看得到。
下面看一下原始碼中的“vector”和“stl_vector.h”都有什麼內容。
/* vector */
//>標頭檔案普遍都有的巨集保護, 防止多重include
//>GNU C++ Library, 即libstdc++.so, 而非libc++.so
//>lib庫名不同也就是GNU與標準C++的不同實現的區別
#ifndef _GLIBCXX_VECTOR
#define _GLIBCXX_VECTOR 1
//>pragma預處理用法
//>告訴GCC該位置下面的include為系統標頭檔案
//>不影響該位置上面的部分
#pragma GCC system_header
/* 從下面的include可以看出, 有多個不同型別的vector. */
//>演算法相關的模板函式
#include <bits/stl_algobase.h>
//>用於記憶體分配的模板類
//>typedef了許多常見的資料型別
#include <bits/allocator.h>
//>非標準的物件建立/銷燬的模板函式
//>如_Construct/_Destroy
#include <bits/stl_construct.h>
//>操作原始記憶體的模板函式
//>從標頭檔案的名字就可以看出, 函式並不初始化記憶體
#include <bits/stl_uninitialized.h>
//>正宗的vector模版類
#include <bits/stl_vector.h>
//>vector模板類的特化版本
//>用bool特化的vector模板, 即vector<bool>
#include <bits/stl_bvector.h>
//>模板函式, 獲取迭代器Iterator的begin/end
#include <bits/range_access.h>
//>tcc版vector
#ifndef _GLIBCXX_EXPORT_TEMPLATE
# include <bits/vector.tcc>
#endif
//>debug版vector
#ifdef _GLIBCXX_DEBUG
# include <debug/vector>
#endif
//>profile版vector
#ifdef _GLIBCXX_PROFILE
# include <profile/vector>
#endif
#endif /* _GLIBCXX_VECTOR */
/* stl_vector.h */
//>標頭檔案普遍都有的巨集保護
#ifndef _STL_VECTOR_H
#define _STL_VECTOR_H 1
//>Iterator迭代器通用的函式, 如distance/advance/next/prev
#include <bits/stl_iterator_base_funcs.h>
//>異常控制的幾個函式宣告
#include <bits/functexcept.h>
//>一些精巧的巨集定義,typedef了一些資料型別
#include <bits/concept_check.h>
//>__cplusplus C++版本
#if __cplusplus >= 201103L
//>initializer_list模板類
//>C++11引入的, 初始化列表, 提供了迭代器
#include <initializer_list>
#endif
//>_GLIBCXX_VISIBILIT在c++config.h中有定義
//>簡單來說即__attribute__((__visibility__("default")))
//>這個是gcc __attribute__的用法
//>詳細定義如下
/***********
#define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY 1
#if _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY
# define _GLIBCXX_VISIBILITY(V) __attribute__((__visibility__(#V)))
#else
# define _GLIBCXX_VISIBILITY(V) _GLIBCXX_PSEUDO_VISIBILITY(V)
#endif
#ifndef _GLIBCXX_PSEUDO_VISIBILITY
# define _GLIBCXX_PSEUDO_VISIBILITY(V)
#endif
**********/
namespace std _GLIBCXX_VISIBILITY(default)
{
//>_GLIBCXX_BEGIN_NAMESPACE_CONTAINER在c++config.h中有定義
//>這裡即一個空的巨集定義
//>詳細定義如下
/**********
#if defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PROFILE)
# define _GLIBCXX_STD_C __cxx1998
# define _GLIBCXX_BEGIN_NAMESPACE_CONTAINER \
namespace _GLIBCXX_STD_C { _GLIBCXX_BEGIN_NAMESPACE_VERSION
# define _GLIBCXX_END_NAMESPACE_CONTAINER \
} _GLIBCXX_END_NAMESPACE_VERSION
#endif
#ifndef _GLIBCXX_STD_C
# define _GLIBCXX_STD_C std
#endif
#ifndef _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
# define _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
#endif
#ifndef _GLIBCXX_END_NAMESPACE_CONTAINER
# define _GLIBCXX_END_NAMESPACE_CONTAINER
#endif
#define _GLIBCXX_INLINE_VERSION 0
#if _GLIBCXX_INLINE_VERSION
# define _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __7 {
# define _GLIBCXX_END_NAMESPACE_VERSION }
#else
# define _GLIBCXX_BEGIN_NAMESPACE_VERSION
# define _GLIBCXX_END_NAMESPACE_VERSION
#endif
**********/
_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
//>_Vector_base為vector的基類, 模板類
//>_Tp是個具體的型別
//>_Alloc為記憶體分配器, 可參照std::allocator
template<typename _Tp, typename _Alloc>
struct _Vector_base
{
//>typedef定義型別的別名
//>typename表示其後的內容是個型別, 否則會被當作普通欄位
//>__gnu_cxx名字空間中的__alloc_traits是allocator的統一介面
//>_Tp_alloc_type定義的簡單形式如下
//>typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type;
//>如果模板引數_Alloc為std::allocator的話, _Tp_alloc_type的定義如下
//>typedef typename allocator<_Tp> _Tp_alloc_type;
typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
rebind<_Tp>::other _Tp_alloc_type;
//>同上, pointer即typedef typename _Tp_alloc_type::pointer pointer;
//>同上, 如果模板引數_Alloc為std::allocator的話, pointer將非常簡單, 如下所示
//>typedef typename _Tp* pointer;
//>繞了一大圈, 其實很簡單!
typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type>::pointer
pointer;
//>巢狀struct
//>_Vector_base implementation
struct _Vector_impl
: public _Tp_alloc_type
{
//>三個重要的指標成員變數, 貫穿於整個vector
//>用集合的方法表示vector就是[_M_start, _M_finish)
//>指向vector中第一個元素的地址
pointer _M_start;
//>指向vector中最後一個元素的下一個位置的地址
pointer _M_finish;
//>指向vector的容量的末地址
pointer _M_end_of_storage;
//>建構函式的兩個版本
//>初始化列表中呼叫了對應的基類建構函式
//>初始化列表中初始化了各指標成員變數, 且初始化順序與變數宣告的順序保持一致
_Vector_impl()
: _Tp_alloc_type(), _M_start(0), _M_finish(0), _M_end_of_storage(0)
{ }
_Vector_impl(_Tp_alloc_type const& __a)
: _Tp_alloc_type(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0)
{ }
#if __cplusplus >= 201103L
//>符號&&即rvalue, 右值引用, C++11引進的, 呼叫std::move
//>符號&即lvalue, 傳統的左值引用
_Vector_impl(_Tp_alloc_type&& __a)
: _Tp_alloc_type(std::move(__a)),
_M_start(0), _M_finish(0), _M_end_of_storage(0)
{ }
#endif
//>資料交換, 引數型別為&, 直接呼叫了std::swap
//>交換的是三個指標成員變數
void _M_swap_data(_Vector_impl& __x)
{
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);
}
}; //> struct _Vector_impl
public:
//>stl中多處使用了typedef, 目的就是讓資料型別更加簡單、具體
typedef _Alloc allocator_type;
//>非const版本與const版本的_M_get_Tp_allocator
//>使用static_cast把子類指標轉化為父類指標, 即up-cast, 型別安全
//>_GLIBCXX_NOEXCEPT即異常相關的巨集定義
/**********
#ifndef _GLIBCXX_NOEXCEPT
# if __cplusplus >= 201103L
# define _GLIBCXX_NOEXCEPT noexcept
# else
# define _GLIBCXX_NOEXCEPT
# endif
#endif
**********/
//>noexcept是C++11引進的, 即不丟擲任何異常, 等價於throw()
_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<const _Tp_alloc_type*>(&this->_M_impl); }
//>獲取allocator_type物件
//>可理解為_Alloc<_Tp>型別的物件
//>呼叫了某個版本的建構函式
allocator_type
get_allocator() const _GLIBCXX_NOEXCEPT
{ return allocator_type(_M_get_Tp_allocator()); }
//>下面是幾個版本的建構函式
_Vector_base()
: _M_impl() { }
_Vector_base(const allocator_type& __a)
: _M_impl(__a) { }
//>引數__n指定了vector大小
//>呼叫_M_create_storage分配記憶體
_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); }
#if __cplusplus >= 201103L
//>rvalue版本的幾個建構函式
_Vector_base(_Tp_alloc_type&& __a)
: _M_impl(std::move(__a)) { }
_Vector_base(_Vector_base&& __x)
: _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);
}
}
#endif
//>析構, 記憶體釋放, 最終會呼叫到::operator delete操作符
~_Vector_base()
{ _M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage
- this->_M_impl._M_start); }
public:
//>成員變數型別為內嵌的struct, 一種簡單的設計模式
_Vector_impl _M_impl;
//>記憶體分配, 最終會呼叫到::operator new操作符
pointer
_M_allocate(size_t __n)
{ return __n != 0 ? _M_impl.allocate(__n) : 0; }
//>記憶體釋放
void
_M_deallocate(pointer __p, size_t __n)
{
if (__p)
_M_impl.deallocate(__p, __n);
}
private:
//>私有的建立儲存空間的函式
//>呼叫上面的_M_Allocate來分配記憶體
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模板類, _Alloc預設型別為std::vector<_Tp>
template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
//>protected方式繼承自_Vector_base, 繼承下來的public內容會將級至protected
//>_Vector_base為struct, 預設的訪問級別為public
class vector : protected _Vector_base<_Tp, _Alloc>
{
//>_Alloc_value_type即_Tp
typedef typename _Alloc::value_type _Alloc_value_type;
//>concept_check.h中的巨集, 作型別檢查, 從最後一個引數可以看出對型別作何檢查
__glibcxx_class_requires(_Tp, _SGIAssignableConcept)
__glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept)
//>_Base為vector基類的型別
typedef _Vector_base<_Tp, _Alloc> _Base;
//>_Tp_alloc_type可理解為_Alloc<_Tp>
typedef typename _Base::_Tp_alloc_type _Tp_alloc_type;
typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Alloc_traits;
public:
//>typedef常用的資料型別
//>_Tp
typedef _Tp value_type;
//>Tp*
typedef typename _Base::pointer pointer;
//>const Tp*
typedef typename _Alloc_traits::const_pointer const_pointer;
//>_Tp&
typedef typename _Alloc_traits::reference reference;
//>const _Tp&
typedef typename _Alloc_traits::const_reference const_reference;
//>iterator
typedef __gnu_cxx::__normal_iterator<pointer, vector> iterator;
//>const_iterator
typedef __gnu_cxx::__normal_iterator<const_pointer, vector> const_iterator;
//>const_reverse_iterator
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
//>reverse_iterator
typedef std::reverse_iterator<iterator> reverse_iterator;
/**********
namespace std
{
typedef __SIZE_TYPE__ size_t;
typedef __PTRDIFF_TYPE__ ptrdiff_t;
}
**********/
typedef size_t size_type;
typedef std::ptrdiff_t difference_type;
//>_Alloc
typedef _Alloc allocator_type;
protected:
//>using常用於namespapce
//>這個地方的using使用了基類的成員, 甚至可以使用基類的private成員
//>C++11還引進了using的其它用法, 類似於typedef
using _Base::_M_allocate;
using _Base::_M_deallocate;
using _Base::_M_impl;
using _Base::_M_get_Tp_allocator;
public:
//>預設建構函式, vector為空
vector()
: _Base() { }
//>指定_Alloc的建構函式, vector也為空
//>explicit關鍵字, 建構函式可以傳遞一個引數時的慣用法, 防止型別隱式轉換
explicit
vector(const allocator_type& __a)
: _Base(__a) { }
#if __cplusplus >= 201103L
//>建構函式, 指定了vector大小和預設的記憶體分配器
//>vector採取了預設的初始化方式, 呼叫_M_default_initialize
explicit
vector(size_type __n, const allocator_type& __a = allocator_type())
: _Base(__n, __a)
{ _M_default_initialize(__n); }
//>建構函式, 指定了vector大小、元素型別和預設的記憶體分配器
//>通過指定的value_type初始化vector, 呼叫_M_fill_initialize
vector(size_type __n, const value_type& __value,
const allocator_type& __a = allocator_type())
: _Base(__n, __a)
{ _M_fill_initialize(__n, __value); }
#else
//>建構函式, 指定了vector大小、預設的元素型別和預設的記憶體分配器
//>同樣, 呼叫_M_fill_initialize進行初始化
explicit
vector(size_type __n, const value_type& __value = value_type(),
const allocator_type& __a = allocator_type())
: _Base(__n, __a)
{ _M_fill_initialize(__n, __value); }
#endif
//>拷貝建構函式
//>拷貝了同樣的元素和記憶體分配器
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());
}
#if __cplusplus >= 201103L
//>rvalue版本的建構函式
//>noexcept不丟擲任何異常
//>呼叫了std::move
vector(vector&& __x) noexcept
: _Base(std::move(__x)) { }
//>指定了記憶體分配器的copy constructor
//>呼叫了std::__uninitialized_copy_a
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());
}
//>指定了記憶體分配器的move constructor
//>當記憶體分配器不同時才進行真正的拷貝
vector(vector&& __rv, const allocator_type& __m)
: _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();
}
}
//>初始化列表形式的建構函式, 會呼叫value_type型別的拷貝建構函式
//>呼叫了_M_range_initialize
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());
}
#endif
#if __cplusplus >= 201103L
//>函式引數為迭代器的模板建構函式, 以及預設的記憶體分配器
//>呼叫了_M_initialize_dispatch進行初始化
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()); }
#else
template<typename _InputIterator>
vector(_InputIterator __first, _InputIterator __last,
const allocator_type& __a = allocator_type())
: _Base(__a)
{
typedef typename std::__is_integer<_InputIterator>::__type _Integral;
_M_initialize_dispatch(__first, __last, _Integral());
}
#endif
//>解構函式, 清空vector中的元素
//>需要注意的是, 如果vector中的元素為指標的話, 指標指向的記憶體需要我們自己管理
~vector() _GLIBCXX_NOEXCEPT
{ std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
_M_get_Tp_allocator()); }
//>賦值操作符
vector&
operator=(const vector& __x);
#if __cplusplus >= 201103L
//>rvalue版本的賦值操作符
//>constexpr是C++11引入的, 常量表達式
//>呼叫了_M_move_assign
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), integral_constant<bool, __move_storage>());
return *this;
}
//>引數為initializer_list的賦值操作符
//>直接呼叫assign進行賦值
vector&
operator=(initializer_list<value_type> __l)
{
this->assign(__l.begin(), __l.end());
return *this;
}
#endif
//>下面是幾個版本的賦值函式assign
//>新的資料會覆蓋vector中原來的資料
//>指定了vector的長度和元素型別, 呼叫了_M_fill_assign
void
assign(size_type __n, const value_type& __val)
{ _M_fill_assign(__n, __val); }
#if __cplusplus >= 201103L
//>assign引數為迭代器的模板函式
//>呼叫_M_assign_dispatch
template<typename _InputIterator,
typename = std::_RequireInputIter<_InputIterator>>
void
assign(_InputIterator __first, _InputIterator __last)
{ _M_assign_dispatch(__first, __last, __false_type()); }
#else
template<typename _InputIterator>
void
assign(_InputIterator __first, _InputIterator __last)
{
typedef typename std::__is_integer<_InputIterator>::__type _Integral;
_M_assign_dispatch(__first, __last, _Integral());
}
#endif
#if __cplusplus >= 201103L
//>引數為initializer_list
//>直接呼叫迭代器版本的assign函式, 程式碼簡潔之道
void
assign(initializer_list<value_type> __l)
{ this->assign(__l.begin(), __l.end()); }
#endif
//>使用基類的分配器
using _Base::get_allocator;
//>下面是幾個不同版本的begin/end函式
//>用於獲取不同版本的迭代器iterator/const_iterator
//>begin返回的是指向vector第一個元素的迭代器
//>end返回的是指向vector最後一個元素的下一個位置的迭代器
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() _GLIBCXX_NOEXCEPT
{ return iterator(this->_M_impl._M_finish); }
const_iterator
end() const _GLIBCXX_NOEXCEPT
{ return const_iterator(this->_M_impl._M_finish); }
//>下面是幾個不同版本的rbegin/rend函式
//>rbegin/rend與begin/end不同, 函式實現呼叫了end/begin, 返回的是返向迭代器
//>用於獲取不同版本的迭代器reverse_iterator/const_reverse_iterator
//>rbegin返回的是指向vector最後一個元素的迭代器
//>rend返回的是指向vector第一個元素的前一個位置的迭代器
reverse_iterator
rbegin() _GLIBCXX_NOEXCEPT
{ return reverse_iterator(end()); }
const_reverse_iterator
rbegin() const _GLIBCXX_NOEXCEPT
{ return const_reverse_iterator(end()); }
reverse_iterator
rend() _GLIBCXX_NOEXCEPT
{ return reverse_iterator(begin()); }
const_reverse_iterator
rend() const _GLIBCXX_NOEXCEPT
{ return const_reverse_iterator(begin()); }
#if __cplusplus >= 201103L
//>下面是幾個const版本的迭代器函式
//>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()); }
#endif
//>獲取vector實有的元素個數
size_type
size() const _GLIBCXX_NOEXCEPT
{ return size_type(this->_M_impl._M_finish - this->_M_impl._M_start); }
//>獲取vector可容納元素個數的最大值
//>但是這個最大值僅僅是個可能值, 有可能根本就達不到
size_type
max_size() const _GLIBCXX_NOEXCEPT
{ return _Alloc_traits::max_size(_M_get_Tp_allocator()); }
#if __cplusplus >= 201103L
//>下面是幾個版本的resize, 重置vector大小
//>vector可能被截短或者以一定的方式追加元素
//>size變大時呼叫_M_default_append追加
//>size變小時呼叫_M_erase_at_end移除多餘的
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);
}
//>size變大時, 呼叫insert在vector尾端插入
void
resize(size_type __new_size, const value_type& __x)
{
if (__new_size > size())
insert(end(), __new_size - size(), __x);
else if (__new_size < size())
_M_erase_at_end(this->_M_impl._M_start + __new_size);
}
#else
//>帶預設value_type的resize
void
resize(size_type __new_size, value_type __x = value_type())
{
if (__new_size > size())
insert(end(), __new_size - size(), __x);
else if (__new_size < size())
_M_erase_at_end(this->_M_impl._M_start + __new_size);
}
#endif
#if __cplusplus >= 201103L
//>調整vector容量
//>當capacity()大於size()時, 這個函式就起作用了
//>前者大小會減小為後者大小
//>通過_M_shrink_to_fit來實現
void
shrink_to_fit()
{ _M_shrink_to_fit(); }
#endif
//>獲取vector的容量
//>從函式實現可以看出capacity不小於size
size_type
capacity() const _GLIBCXX_NOEXCEPT
{ return size_type(this->_M_impl._M_end_of_storage
- this->_M_impl._M_start); }
//>判斷vector是否為空
//>實現是通過迭代器判斷完成的
bool
empty() const _GLIBCXX_NOEXCEPT
{ return begin() == end(); }
//>重置vector的容量, 使其接近於size()
//>當__n超過max_size()時會有異常std::length_error
void
reserve(size_type __n);
//>元素訪問操作符, const與非const兩個版本
//>需要注意的是, 函式實現沒有檢查vector索引的有效性
//>vector索引有可能越界, 後果...斷錯誤
reference
operator[](size_type __n)
{ return *(this->_M_impl._M_start + __n); }
const_reference
operator[](size_type __n) const
{ return *(this->_M_impl._M_start + __n); }
protected:
//>vector索引的有效性檢查, 用於at()
//>索引越界時會丟擲std::out_of_range異常
void
_M_range_check(size_type __n) const
{
if (__n >= this->size())
__throw_out_of_range(__N("vector::_M_range_check"));
}
public:
//>元素訪問, const與非const兩個版本
//>呼叫了_M_range_check()進行索引的有效性檢查
reference
at(size_type __n)
{
_M_range_check(__n);
return (*this)[__n];
}
const_reference
at(size_type __n) const
{
_M_range_check(__n);
return (*this)[__n];
}
//>front/back返回vector的第一個/最後一個元素
//>函式實現對是begin()/end()返回的迭代器取引用
//>如果vector為空的話, 函式返回的結果是不可預料的...
reference
front()
{ return *begin(); }
const_reference
front() const
{ return *begin(); }
reference
back()
{ return *(end() - 1); }
const_reference
back() const
{ return *(end() - 1); }
//>獲取vector第一個元素, 返回指標
//>函式實現呼叫了front()
#if __cplusplus >= 201103L
_Tp*
#else
pointer
#endif
data() _GLIBCXX_NOEXCEPT
{ return std::__addressof(front()); }
#if __cplusplus >= 201103L
const _Tp*
#else
const_pointer
#endif
data() const _GLIBCXX_NOEXCEPT
{ return std::__addressof(front()); }
//>追加一個元素到vector末尾
//>從函式實現可以看出, 當size()小於capacity()時
//>在vector末尾直接構建一個元素, 常量耗時
//>否則會根據__cplusplus版本做不同的事
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
#if __cplusplus >= 201103L
_M_emplace_back_aux(__x);
#else
_M_insert_aux(end(), __x);
#endif
}
#if __cplusplus >= 201103L
//>rvalue版本
//>通過emplace_back實現
void
push_back(value_type&& __x)
{ emplace_back(std::move(__x)); }
//>emplace_back與push_back不同
//>emplace_back是在vector末尾直接構建一個元素
//>而push_back是複製、移動一個元素到vector末尾
//>不定引數的模板函式
template<typename... _Args>
void
emplace_back(_Args&&... __args);
#endif
//>從vector末尾移除一個元素
//>操作的自然是_M_finish指標
void
pop_back()
{
--this->_M_impl._M_finish;
_Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish);
}
#if __cplusplus >= 201103L
//>在__position前emplace一個元素
//>原理同emplace_back
template<typename... _Args>
iterator
emplace(iterator __position, _Args&&... __args);
#endif
//>下面是幾個版本的insert
//>在指定的位置插入元素
iterator
insert(iterator __position, const value_type& __x);
#if __cplusplus >= 201103L
//>通過emplace來insert rvalue版本的元素
iterator
insert(iterator __position, value_type&& __x)
{ return emplace(__position, std::move(__x)); }
//>引數為initializer_list時直接呼叫迭代器版本的insert
void
insert(iterator __position, initializer_list<value_type> __l)
{ this->insert(__position, __l.begin(), __l.end()); }
#endif
//>呼叫_M_fill_insert
void
insert(iterator __position, size_type __n, const value_type& __x)
{ _M_fill_insert(__position, __n, __x); }
//>迭代器版本的insert
//>呼叫_M_insert_dispatch
#if __cplusplus >= 201103L
template<typename _InputIterator,
typename = std::_RequireInputIter<_InputIterator>>
void
insert(iterator __position, _InputIterator __first,
_InputIterator __last)
{ _M_insert_dispatch(__position, __first, __last, __false_type()); }
#else
template<typename _InputIterator>
void
insert(iterator __position, _InputIterator __first,
_InputIterator __last)
{
typedef typename std::__is_integer<_InputIterator>::__type _Integral;
_M_insert_dispatch(__position, __first, __last, _Integral());
}
#endif
//>erase移除指定位置的元素
iterator
erase(iterator __position);
//>erase移除指定範圍的元素
iterator
erase(iterator __first, iterator __last);
//>交換兩個vector中的內容
//>其實交換的就是_Vector_base::_Vector_impl中的三個指標
void
swap(vector& __x)
#if __cplusplus >= 201103L
noexcept(_Alloc_traits::_S_nothrow_swap())
#endif
{
this->_M_impl._M_swap_data(__x._M_impl);
_Alloc_traits::_S_on_swap(_M_get_Tp_allocator(),
__x._M_get_Tp_allocator());
}
//>清空vector
//>呼叫_M_erase_at_end
void
clear() _GLIBCXX_NOEXCEPT
{ _M_erase_at_end(this->_M_impl._M_start); }
protected:
//>_M_allocate_and_copy
//>從函式名可以看出
//>先allocate記憶體, 再copy資料
//>使用了異常處理
//>有異常時需要釋放剛才分配的記憶體並再次丟擲異常
//>__try/__catch/__throw_exception_again定義在exception_define.h中
/**********
#ifndef __EXCEPTIONS
// If -fno-exceptions, transform error handling code to work without it.
# define __try if (true)
# define __catch(X) if (false)
# define __throw_exception_again
#else
// Else proceed normally.
# define __try try
# define __catch(X) catch(X)
# define __throw_exception_again throw
#endif
**********/
template<typename _ForwardIterator>
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;
}
}
//>_M_initialize_dispatch
//>從函式名可以看出
//>分配了指定位元組的記憶體後需要進行初始化
//>初始化呼叫_M_fill_initialize
template<typename _Integer>
void
_M_initialize_dispatch(_Integer __n, _Integer __value, __true_type)
{
this->_M_impl._M_start = _M_allocate(static_cast<size_type>(__n));
this->_M_impl._M_end_of_storage =
this->_M_impl._M_start + static_cast<size_type>(__n);
_M_fill_initialize(static_cast<size_type>(__n), __value);
}
//>_M_initialize_dispatch
//>迭代器版本
//>初始化呼叫_M_range_initialize
template<typename _InputIterator>
void
_M_initialize_dispatch(_InputIterator __first, _InputIterator __last,
__false_type)
{
typedef typename std::iterator_traits<_InputIterator>::
iterator_category _IterCategory;
_M_range_initialize(__first, __last, _IterCategory());
}
//>根據迭代器指向的內容初始化當前vector
//>函式的第三個引數是個啞元
//>根據啞元型別的不同, 有兩個版本的_M_range_initialize
template<typename _InputIterator>
void
_M_range_initialize(_InputIterator __first,
_InputIterator __last, std::input_iterator_tag)
{
for (; __first != __last; ++__first)
#if __cplusplus >= 201103L
emplace_back(*__first);
#else
push_back(*__first);
#endif
}
template<typename _ForwardIterator>
void
_M_range_initialize(_ForwardIterator __first,
_ForwardIterator __last, std::forward_iterator_tag)
{
const size_type __n = std::distance(__first, __last);
this->_M_impl._M_start = this->_M_allocate(__n);
this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
this->_M_impl._M_finish =
std::__uninitialized_copy_a(__first, __last,
this->_M_impl._M_start,
_M_get_Tp_allocator());
}
//>_M_fill_initialize
void
_M_fill_initialize(size_type __n, const value_type& __value)
{
std::__uninitialized_fill_n_a(this->_M_impl._M_start, __n, __value,
_M_get_Tp_allocator());
this->_M_impl._M_finish = this->_M_impl._M_end_of_storage;
}
#if __cplusplus >= 201103L
//>_M_default_initialize
void
_M_default_initialize(size_type __n)
{
std::__uninitialized_default_n_a(this->_M_impl._M_start, __n,
_M_get_Tp_allocator());
this->_M_impl._M_finish = this->_M_impl._M_end_of_storage;
}
#endif
//>兩個_M_assign_dispatch函式
template<typename _Integer>
void
_M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
{ _M_fill_assign(__n, __val); }
template<typename _InputIterator>
void
_M_assign_dispatch(_InputIterator __first, _InputIterator __last,
__false_type)
{
typedef typename std::iterator_traits<_InputIterator>::
iterator_category _IterCategory;
_M_assign_aux(__first, __last, _IterCategory());
}
//>兩個_M_assign_aux函式
template<typename _InputIterator>
void
_M_assign_aux(_InputIterator __first, _InputIterator __last,
std::input_iterator_tag);
template<typename _ForwardIterator>
void
_M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
std::forward_iterator_tag);
//>_M_fill_assign
void
_M_fill_assign(size_type __n, const value_type& __val);
//>兩個_M_insert_dispatch函式
template<typename _Integer>
void
_M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val,
__true_type)
{ _M_fill_insert(__pos, __n, __val); }
template<typename _InputIterator>
void
_M_insert_dispatch(iterator __pos, _InputIterator __first,
_InputIterator __last, __false_type)
{
typedef typename std::iterator_traits<_InputIterator>::
iterator_category _IterCategory;
_M_range_insert(__pos, __first, __last, _IterCategory());
}
//>兩個_M_range_insert函式
template<typename _InputIterator>
void
_M_range_insert(iterator __pos, _InputIterator __first,
_InputIterator __last, std::input_iterator_tag);
template<typename _ForwardIterator>
void
_M_range_insert(iterator __pos, _ForwardIterator __first,
_ForwardIterator __last, std::forward_iterator_tag);
//>_M_fill_insert
void
_M_fill_insert(iterator __pos, size_type __n, const value_type& __x);
#if __cplusplus >= 201103L
//>用於resize(n)
void
_M_default_append(size_type __n);
//>_M_shrink_to_fit
bool
_M_shrink_to_fit();
#endif
#if __cplusplus < 201103L
//>用於insert(p, x)
void
_M_insert_aux(iterator __position, const value_type& __x);
#else
template<typename... _Args>
void
_M_insert_aux(iterator __position, _Args&&... __args);
//>_M_emplace_back_aux
template<typename... _Args>
void
_M_emplace_back_aux(_Args&&... __args);
#endif
//>vector大小檢查
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()) ?