template <class _Tp, class _Allocator, bool _IsStatic> // 模版包括類型定義跟名字定義
class _Vector_alloc_base {
public:
typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
allocator_type;
allocator_type get_allocator() const { return _M_data_allocator; }
_Vector_alloc_base(const allocator_type& __a)
: _M_data_allocator(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0)
{}
protected:
allocator_type _M_data_allocator;
_Tp* _M_start;
_Tp* _M_finish;
_Tp* _M_end_of_storage;
_Tp* _M_allocate(size_t __n)
{ return _M_data_allocator.allocate(__n); }
void _M_deallocate(_Tp* __p, size_t __n)
{ if (__p) _M_data_allocator.deallocate(__p, __n); }
};
// vector..........
void push_back(const _Tp& __x) {
if (_M_finish != _M_end_of_storage) { // push back 的代碼 如果沒有達到分配內存的最後
construct(_M_finish, __x);// 在已經分配的內存上 進行new 調用構造函數
++_M_finish; // ++
}
else
_M_insert_aux(end(), __x);
}
看看這個函數:
vector<_Tp, _Alloc>::_M_insert_aux(iterator __position, const _Tp& __x)
{
if (_M_finish != _M_end_of_storage) {
construct(_M_finish, *(_M_finish - 1));
++_M_finish;
_Tp __x_copy = __x;
copy_backward(__position, _M_finish - 2, _M_finish - 1);
*__position = __x_copy;
}
else {
const size_type __old_size = size();
const size_type __len = __old_size != 0 ? 2 * __old_size : 1; // 重新分配 size *2
iterator __new_start = _M_allocate(__len); // 重新分配的空間
iterator __new_finish = __new_start;// 現在end 根start(begin)
__STL_TRY { // try
__new_finish = uninitialized_copy(_M_start, __position, __new_start);// 將現在的數據拷貝到新分配區域
construct(__new_finish, __x);// 分配
++__new_finish;
__new_finish = uninitialized_copy(__position, _M_finish, __new_finish); // 將position之後的數據插入
}
__STL_UNWIND((destroy(__new_start,__new_finish), //異常處理
_M_deallocate(__new_start,__len)));
destroy(begin(), end());
_M_deallocate(_M_start, _M_end_of_storage - _M_start); // 釋放原來的空間
_M_start = __new_start;
_M_finish = __new_finish;
_M_end_of_storage = __new_start + __len; // 更新
}
}
push back 的函數比較簡單.
Swap 函數:
void swap(vector<_Tp, _Alloc>& __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);
}
交換兩個vextor vector 只有三個變量 start end 還有 mem 這幾個是很重要的變量.
iterator insert(iterator __position, const _Tp& __x) {
size_type __n = __position - begin();
if (_M_finish != _M_end_of_storage && __position == end()) {
construct(_M_finish, __x);
++_M_finish;
}
else
_M_insert_aux(__position, __x);
return begin() + __n;
} // 插入操作 返回值是 插入元素所在的 iterator
iterator insert(iterator __position) {
size_type __n = __position - begin();
if (_M_finish != _M_end_of_storage && __position == end()) {
construct(_M_finish); // 這個插入的是缺省的
++_M_finish;
}
else
_M_insert_aux(__position);
return begin() + __n;
}// 同上
還有一種就是一種 向量的插入:
// template <class _InputIterator>
void insert(iterator __pos, _InputIterator __first, _InputIterator __last) {
typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
_M_insert_dispatch(__pos, __first, __last, _Integral());
}
//
void _M_insert_dispatch(iterator __pos,
_InputIterator __first, _InputIterator __last,
__false_type) {
_M_range_insert(__pos, __first, __last, __ITERATOR_CATEGORY(__first));
}
//
template <class _Tp, class _Alloc> template <class _InputIterator>
void
vector<_Tp, _Alloc>::_M_range_insert(iterator __pos,
_InputIterator __first,
_InputIterator __last,
input_iterator_tag)
{
for ( ; __first != __last; ++__first) {
__pos = insert(__pos, *__first);
++__pos;
}// 這個纔是根本的代碼
}
向量插入最根本是歸入到一個元素的插入.
下面的這種插入是一種,元素的重複插入:
void insert (iterator __pos, size_type __n, const _Tp& __x)
{ _M_fill_insert(__pos, __n, __x); }
template <class _Tp, class _Alloc>
void vector<_Tp, _Alloc>::_M_fill_insert(iterator __position, size_type __n,
const _Tp& __x)
{
if (__n != 0) { // 插入的元素格式不是0
if (size_type(_M_end_of_storage - _M_finish) >= __n) { // 判斷剩餘的內存是不是夠用
_Tp __x_copy = __x; //這種命名方式可以借鑑
const size_type __elems_after = _M_finish - __position;// 看看插入位置的後面有多少個元素
iterator __old_finish = _M_finish;// 原來的結束位置
if (__elems_after > __n) { // 如果已經分配的內存夠用的話
uninitialized_copy(_M_finish - __n, _M_finish, _M_finish); // 後面面的拷貝
_M_finish += __n;
copy_backward(__position, __old_finish - __n, __old_finish); //後面的拷貝
fill(__position, __position + __n, __x_copy); // 填充n個
}// 先拷貝最後的n個, 爲了防止數據覆蓋.最後再拷貝position 後面的.
else { // 不夠用
uninitialized_fill_n(_M_finish, __n - __elems_after, __x_copy); // 現有的空間的拷貝
_M_finish += __n - __elems_after;// 更新
uninitialized_copy(__position, __old_finish, _M_finish); // 現有空間的拷貝
_M_finish += __elems_after; //
fill(__position, __old_finish, __x_copy);//
}
}// 元素覆蓋的問題
else {
const size_type __old_size = size();
const size_type __len = __old_size + max(__old_size, __n); //最後大小是 當前vector的兩倍或者
iterator __new_start = _M_allocate(__len); // 分配空間
iterator __new_finish = __new_start;
__STL_TRY { //
__new_finish = uninitialized_copy(_M_start, __position, __new_start);
__new_finish = uninitialized_fill_n(__new_finish, __n, __x);
__new_finish
= uninitialized_copy(__position, _M_finish, __new_finish);
}// 這個就比較簡單了
__STL_UNWIND((destroy(__new_start,__new_finish),
_M_deallocate(__new_start,__len))); // 不成功 釋放空間,這種方法比較好,在異常中釋放空間.
destroy(_M_start, _M_finish);
_M_deallocate(_M_start, _M_end_of_storage - _M_start);
_M_start = __new_start;
_M_finish = __new_finish;
_M_end_of_storage = __new_start + __len;
}
}
}// ^_^
template <class _RandomAccessIter, class _BidirectionalIter, class _Distance>
inline _BidirectionalIter __copy_backward(_RandomAccessIter __first,
_RandomAccessIter __last,
_BidirectionalIter __result,
random_access_iterator_tag,
_Distance*)
{
for (_Distance __n = __last - __first; __n > 0; --__n)
*--__result = *--__last;
return __result;
} //
//
///
// pop_back()
//
void pop_back() {
--_M_finish; // 數量減少
destroy(_M_finish); // 析構
}
template <class _Tp>
inline void destroy(_Tp* __pointer) {
__pointer->~_Tp(); //注意inline應用.調用一下析構函數.
}
// erase()
//
//
iterator erase(iterator __position) {
if (__position + 1 != end()) // 如果是最後一個的話那就不用copy了
copy(__position + 1, _M_finish, __position); // 把後面的元素拷貝
--_M_finish; // 減少
destroy(_M_finish);//
return __position; // 返回刪除 元素的位置
}
iterator erase(iterator __first, iterator __last) {
iterator __i = copy(__last, _M_finish, __first);
destroy(__i, _M_finish);
_M_finish = _M_finish - (__last - __first);
return __first;
}// 拷貝
//
// resize()
//
void resize(size_type __new_size, const _Tp& __x) {
if (__new_size < size()) //如果後來的size 小於 原來的size, 就把後面的erase掉
erase(begin() + __new_size, end());
else // 如果比原來的大,則使用擦如操作
insert(end(), __new_size - size(), __x);
}
void resize(size_type __new_size) { resize(__new_size, _Tp()); } //如果參數缺省, 那麼就調用缺省參數.