|
|
|
@ -16,17 +16,17 @@
|
|
|
|
|
// * resize
|
|
|
|
|
// * insert
|
|
|
|
|
|
|
|
|
|
#include <initializer_list>
|
|
|
|
|
#include <initializer_list> // 包含初始化列表相关头文件
|
|
|
|
|
|
|
|
|
|
#include "iterator.h"
|
|
|
|
|
#include "memory.h"
|
|
|
|
|
#include "util.h"
|
|
|
|
|
#include "exceptdef.h"
|
|
|
|
|
#include "algo.h"
|
|
|
|
|
#include "iterator.h" // 包含自定义迭代器相关实现
|
|
|
|
|
#include "memory.h" // 包含自定义内存分配器相关实现
|
|
|
|
|
#include "util.h" // 包含一些实用工具函数
|
|
|
|
|
#include "exceptdef.h" // 包含异常定义
|
|
|
|
|
#include "algo.h" // 包含算法实现
|
|
|
|
|
|
|
|
|
|
namespace mystl
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// 取消宏定义 max 和 min,避免与标准库中的同名函数冲突
|
|
|
|
|
#ifdef max
|
|
|
|
|
#pragma message("#undefing marco max")
|
|
|
|
|
#undef max
|
|
|
|
@ -45,24 +45,23 @@ class vector
|
|
|
|
|
static_assert(!std::is_same<bool, T>::value, "vector<bool> is abandoned in mystl");
|
|
|
|
|
public:
|
|
|
|
|
// vector 的嵌套型别定义
|
|
|
|
|
typedef mystl::allocator<T> allocator_type;
|
|
|
|
|
typedef mystl::allocator<T> data_allocator;
|
|
|
|
|
|
|
|
|
|
typedef typename allocator_type::value_type value_type;
|
|
|
|
|
typedef typename allocator_type::pointer pointer;
|
|
|
|
|
typedef typename allocator_type::const_pointer const_pointer;
|
|
|
|
|
typedef typename allocator_type::reference reference;
|
|
|
|
|
typedef typename allocator_type::const_reference const_reference;
|
|
|
|
|
typedef typename allocator_type::size_type size_type;
|
|
|
|
|
typedef typename allocator_type::difference_type difference_type;
|
|
|
|
|
|
|
|
|
|
typedef value_type* iterator;
|
|
|
|
|
typedef const value_type* const_iterator;
|
|
|
|
|
typedef mystl::reverse_iterator<iterator> reverse_iterator;
|
|
|
|
|
typedef mystl::reverse_iterator<const_iterator> const_reverse_iterator;
|
|
|
|
|
|
|
|
|
|
allocator_type get_allocator() { return data_allocator(); }
|
|
|
|
|
|
|
|
|
|
typedef mystl::allocator<T> allocator_type; // 分配器类型
|
|
|
|
|
typedef mystl::allocator<T> data_allocator; // 数据分配器类型
|
|
|
|
|
|
|
|
|
|
typedef typename allocator_type::value_type value_type; // 元素类型
|
|
|
|
|
typedef typename allocator_type::pointer pointer; // 指针类型
|
|
|
|
|
typedef typename allocator_type::const_pointer const_pointer; // 常量指针类型
|
|
|
|
|
typedef typename allocator_type::reference reference; // 引用类型
|
|
|
|
|
typedef typename allocator_type::const_reference const_reference; // 常量引用类型
|
|
|
|
|
typedef typename allocator_type::size_type size_type; // 大小类型
|
|
|
|
|
typedef typename allocator_type::difference_type difference_type; // 差值类型
|
|
|
|
|
|
|
|
|
|
typedef value_type* iterator; // 迭代器类型
|
|
|
|
|
typedef const value_type* const_iterator; // 常量迭代器类型
|
|
|
|
|
typedef mystl::reverse_iterator<iterator> reverse_iterator;// 反向迭代器类型
|
|
|
|
|
typedef mystl::reverse_iterator<const_iterator> const_reverse_iterator;// 常量反向迭代器类型
|
|
|
|
|
|
|
|
|
|
allocator_type get_allocator() { return data_allocator(); } // 获取分配器
|
|
|
|
|
private:
|
|
|
|
|
iterator begin_; // 表示目前使用空间的头部
|
|
|
|
|
iterator end_; // 表示目前使用空间的尾部
|
|
|
|
@ -70,15 +69,22 @@ private:
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
// 构造、复制、移动、析构函数
|
|
|
|
|
vector() noexcept
|
|
|
|
|
{ try_init(); }
|
|
|
|
|
vector() noexcept // 默认构造函数
|
|
|
|
|
{
|
|
|
|
|
try_init();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
explicit vector(size_type n)
|
|
|
|
|
{ fill_init(n, value_type()); }
|
|
|
|
|
explicit vector(size_type n) // 构造函数,初始化指定数量的元素
|
|
|
|
|
{
|
|
|
|
|
fill_init(n, value_type());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vector(size_type n, const value_type& value)
|
|
|
|
|
{ fill_init(n, value); }
|
|
|
|
|
vector(size_type n, const value_type& value) // 构造函数,初始化指定数量的相同元素
|
|
|
|
|
{
|
|
|
|
|
fill_init(n, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 构造函数,使用迭代器范围初始化
|
|
|
|
|
template <class Iter, typename std::enable_if<
|
|
|
|
|
mystl::is_input_iterator<Iter>::value, int>::type = 0>
|
|
|
|
|
vector(Iter first, Iter last)
|
|
|
|
@ -87,12 +93,12 @@ public:
|
|
|
|
|
range_init(first, last);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vector(const vector& rhs)
|
|
|
|
|
vector(const vector& rhs) // 复制构造函数
|
|
|
|
|
{
|
|
|
|
|
range_init(rhs.begin_, rhs.end_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vector(vector&& rhs) noexcept
|
|
|
|
|
vector(vector&& rhs) noexcept // 移动构造函数
|
|
|
|
|
:begin_(rhs.begin_),
|
|
|
|
|
end_(rhs.end_),
|
|
|
|
|
cap_(rhs.cap_)
|
|
|
|
@ -102,14 +108,15 @@ public:
|
|
|
|
|
rhs.cap_ = nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vector(std::initializer_list<value_type> ilist)
|
|
|
|
|
vector(std::initializer_list<value_type> ilist) // 初始化列表构造函数
|
|
|
|
|
{
|
|
|
|
|
range_init(ilist.begin(), ilist.end());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vector& operator=(const vector& rhs);
|
|
|
|
|
vector& operator=(vector&& rhs) noexcept;
|
|
|
|
|
vector& operator=(const vector& rhs); // 复制赋值操作符
|
|
|
|
|
vector& operator=(vector&& rhs) noexcept; // 移动赋值操作符
|
|
|
|
|
|
|
|
|
|
// 赋值操作符,使用初始化列表
|
|
|
|
|
vector& operator=(std::initializer_list<value_type> ilist)
|
|
|
|
|
{
|
|
|
|
|
vector tmp(ilist.begin(), ilist.end());
|
|
|
|
@ -117,141 +124,127 @@ public:
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~vector()
|
|
|
|
|
~vector() // 析构函数
|
|
|
|
|
{
|
|
|
|
|
destroy_and_recover(begin_, end_, cap_ - begin_);
|
|
|
|
|
begin_ = end_ = cap_ = nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
// 迭代器相关操作
|
|
|
|
|
iterator begin() noexcept
|
|
|
|
|
{ return begin_; }
|
|
|
|
|
const_iterator begin() const noexcept
|
|
|
|
|
{ return begin_; }
|
|
|
|
|
iterator end() noexcept
|
|
|
|
|
{ return end_; }
|
|
|
|
|
const_iterator end() const noexcept
|
|
|
|
|
{ return end_; }
|
|
|
|
|
|
|
|
|
|
reverse_iterator rbegin() noexcept
|
|
|
|
|
{ return reverse_iterator(end()); }
|
|
|
|
|
const_reverse_iterator rbegin() const noexcept
|
|
|
|
|
{ return const_reverse_iterator(end()); }
|
|
|
|
|
reverse_iterator rend() noexcept
|
|
|
|
|
{ return reverse_iterator(begin()); }
|
|
|
|
|
const_reverse_iterator rend() const noexcept
|
|
|
|
|
{ return const_reverse_iterator(begin()); }
|
|
|
|
|
|
|
|
|
|
const_iterator cbegin() const noexcept
|
|
|
|
|
{ return begin(); }
|
|
|
|
|
const_iterator cend() const noexcept
|
|
|
|
|
{ return end(); }
|
|
|
|
|
const_reverse_iterator crbegin() const noexcept
|
|
|
|
|
{ return rbegin(); }
|
|
|
|
|
const_reverse_iterator crend() const noexcept
|
|
|
|
|
{ return rend(); }
|
|
|
|
|
iterator begin() noexcept { return begin_; } // 返回开始迭代器
|
|
|
|
|
const_iterator begin() const noexcept { return begin_; } // 返回常量开始迭代器
|
|
|
|
|
iterator end() noexcept { return end_; } // 返回结束迭代器
|
|
|
|
|
const_iterator end() const noexcept { return end_; } // 返回常量结束迭代器
|
|
|
|
|
|
|
|
|
|
reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } // 返回反向开始迭代器
|
|
|
|
|
const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); } // 返回常量反向开始迭代器
|
|
|
|
|
reverse_iterator rend() noexcept { return reverse_iterator(begin()); } // 返回反向结束迭代器
|
|
|
|
|
const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); } // 返回常量反向结束迭代器
|
|
|
|
|
|
|
|
|
|
const_iterator cbegin() const noexcept { return begin(); } // 返回常量开始迭代器
|
|
|
|
|
const_iterator cend() const noexcept { return end(); } // 返回常量结束迭代器
|
|
|
|
|
const_reverse_iterator crbegin() const noexcept { return rbegin(); } // 返回常量反向开始迭代器
|
|
|
|
|
const_reverse_iterator crend() const noexcept { return rend(); } // 返回常量反向结束迭代器
|
|
|
|
|
|
|
|
|
|
// 容量相关操作
|
|
|
|
|
bool empty() const noexcept
|
|
|
|
|
{ return begin_ == end_; }
|
|
|
|
|
size_type size() const noexcept
|
|
|
|
|
{ return static_cast<size_type>(end_ - begin_); }
|
|
|
|
|
size_type max_size() const noexcept
|
|
|
|
|
{ return static_cast<size_type>(-1) / sizeof(T); }
|
|
|
|
|
size_type capacity() const noexcept
|
|
|
|
|
{ return static_cast<size_type>(cap_ - begin_); }
|
|
|
|
|
void reserve(size_type n);
|
|
|
|
|
void shrink_to_fit();
|
|
|
|
|
bool empty() const noexcept { return begin_ == end_; } // 检查容器是否为空
|
|
|
|
|
size_type size() const noexcept { return static_cast<size_type>(end_ - begin_); } // 返回容器大小
|
|
|
|
|
size_type max_size() const noexcept { return static_cast<size_type>(-1) / sizeof(T); } // 返回最大可能的容器大小
|
|
|
|
|
size_type capacity() const noexcept { return static_cast<size_type>(cap_ - begin_); } // 返回容器容量
|
|
|
|
|
void reserve(size_type n); // 预留空间
|
|
|
|
|
void shrink_to_fit(); // 减小容量以适应大小
|
|
|
|
|
|
|
|
|
|
// 访问元素相关操作
|
|
|
|
|
reference operator[](size_type n)
|
|
|
|
|
reference operator[](size_type n) // 访问第 n 个元素
|
|
|
|
|
{
|
|
|
|
|
MYSTL_DEBUG(n < size());
|
|
|
|
|
return *(begin_ + n);
|
|
|
|
|
}
|
|
|
|
|
const_reference operator[](size_type n) const
|
|
|
|
|
const_reference operator[](size_type n) const // 访问第 n 个常量元素
|
|
|
|
|
{
|
|
|
|
|
MYSTL_DEBUG(n < size());
|
|
|
|
|
return *(begin_ + n);
|
|
|
|
|
}
|
|
|
|
|
reference at(size_type n)
|
|
|
|
|
reference at(size_type n) // 访问第 n 个元素,带边界检查
|
|
|
|
|
{
|
|
|
|
|
THROW_OUT_OF_RANGE_IF(!(n < size()), "vector<T>::at() subscript out of range");
|
|
|
|
|
return (*this)[n];
|
|
|
|
|
}
|
|
|
|
|
const_reference at(size_type n) const
|
|
|
|
|
const_reference at(size_type n) const // 访问第 n 个常量元素,带边界检查
|
|
|
|
|
{
|
|
|
|
|
THROW_OUT_OF_RANGE_IF(!(n < size()), "vector<T>::at() subscript out of range");
|
|
|
|
|
return (*this)[n];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reference front()
|
|
|
|
|
reference front() // 访问第一个元素
|
|
|
|
|
{
|
|
|
|
|
MYSTL_DEBUG(!empty());
|
|
|
|
|
return *begin_;
|
|
|
|
|
}
|
|
|
|
|
const_reference front() const
|
|
|
|
|
const_reference front() const // 访问第一个常量元素
|
|
|
|
|
{
|
|
|
|
|
MYSTL_DEBUG(!empty());
|
|
|
|
|
return *begin_;
|
|
|
|
|
}
|
|
|
|
|
reference back()
|
|
|
|
|
reference back() // 访问最后一个元素
|
|
|
|
|
{
|
|
|
|
|
MYSTL_DEBUG(!empty());
|
|
|
|
|
return *(end_ - 1);
|
|
|
|
|
}
|
|
|
|
|
const_reference back() const
|
|
|
|
|
const_reference back() const // 访问最后一个常量元素
|
|
|
|
|
{
|
|
|
|
|
MYSTL_DEBUG(!empty());
|
|
|
|
|
return *(end_ - 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pointer data() noexcept { return begin_; }
|
|
|
|
|
const_pointer data() const noexcept { return begin_; }
|
|
|
|
|
pointer data() noexcept { return begin_; } // 返回数据指针
|
|
|
|
|
const_pointer data() const noexcept { return begin_; } // 返回常量数据指针
|
|
|
|
|
|
|
|
|
|
// 修改容器相关操作
|
|
|
|
|
|
|
|
|
|
// assign
|
|
|
|
|
|
|
|
|
|
void assign(size_type n, const value_type& value)
|
|
|
|
|
{ fill_assign(n, value); }
|
|
|
|
|
|
|
|
|
|
template <class Iter, typename std::enable_if<
|
|
|
|
|
mystl::is_input_iterator<Iter>::value, int>::type = 0>
|
|
|
|
|
void assign(Iter first, Iter last)
|
|
|
|
|
void assign(Iter first, Iter last) // 赋值指定迭代器范围内的元素
|
|
|
|
|
{
|
|
|
|
|
MYSTL_DEBUG(!(last < first));
|
|
|
|
|
copy_assign(first, last, iterator_category(first));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void assign(std::initializer_list<value_type> il)
|
|
|
|
|
{ copy_assign(il.begin(), il.end(), mystl::forward_iterator_tag{}); }
|
|
|
|
|
void assign(std::initializer_list<value_type> il) // 使用初始化列表赋值
|
|
|
|
|
{
|
|
|
|
|
copy_assign(il.begin(), il.end(), mystl::forward_iterator_tag{});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// emplace / emplace_back
|
|
|
|
|
|
|
|
|
|
template <class... Args>
|
|
|
|
|
iterator emplace(const_iterator pos, Args&& ...args);
|
|
|
|
|
iterator emplace(const_iterator pos, Args&& ...args) // 在指定位置就地构造元素
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
template <class... Args>
|
|
|
|
|
void emplace_back(Args&& ...args);
|
|
|
|
|
void emplace_back(Args&& ...args) // 在尾部就地构造元素
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
// push_back / pop_back
|
|
|
|
|
|
|
|
|
|
void push_back(const value_type& value);
|
|
|
|
|
void push_back(value_type&& value)
|
|
|
|
|
{ emplace_back(mystl::move(value)); }
|
|
|
|
|
void push_back(const value_type& value) // 在尾部添加元素
|
|
|
|
|
;
|
|
|
|
|
void push_back(value_type&& value) // 在尾部添加移动构造的元素
|
|
|
|
|
{
|
|
|
|
|
emplace_back(mystl::move(value));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void pop_back();
|
|
|
|
|
void pop_back(); // 删除尾部元素
|
|
|
|
|
|
|
|
|
|
// insert
|
|
|
|
|
|
|
|
|
|
iterator insert(const_iterator pos, const value_type& value);
|
|
|
|
|
iterator insert(const_iterator pos, value_type&& value)
|
|
|
|
|
{ return emplace(pos, mystl::move(value)); }
|
|
|
|
|
iterator insert(const_iterator pos, const value_type& value) // 在指定位置插入元素
|
|
|
|
|
;
|
|
|
|
|
iterator insert(const_iterator pos, value_type&& value) // 在指定位置插入移动构造的元素
|
|
|
|
|
{
|
|
|
|
|
return emplace(pos, mystl::move(value));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
iterator insert(const_iterator pos, size_type n, const value_type& value)
|
|
|
|
|
iterator insert(const_iterator pos, size_type n, const value_type& value) // 在指定位置插入指定数量的元素
|
|
|
|
|
{
|
|
|
|
|
MYSTL_DEBUG(pos >= begin() && pos <= end());
|
|
|
|
|
return fill_insert(const_cast<iterator>(pos), n, value);
|
|
|
|
@ -259,185 +252,190 @@ public:
|
|
|
|
|
|
|
|
|
|
template <class Iter, typename std::enable_if<
|
|
|
|
|
mystl::is_input_iterator<Iter>::value, int>::type = 0>
|
|
|
|
|
void insert(const_iterator pos, Iter first, Iter last)
|
|
|
|
|
void insert(const_iterator pos, Iter first, Iter last) // 在指定位置插入迭代器范围内的元素
|
|
|
|
|
{
|
|
|
|
|
MYSTL_DEBUG(pos >= begin() && pos <= end() && !(last < first));
|
|
|
|
|
copy_insert(const_cast<iterator>(pos), first, last);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// erase / clear
|
|
|
|
|
iterator erase(const_iterator pos);
|
|
|
|
|
iterator erase(const_iterator first, const_iterator last);
|
|
|
|
|
void clear() { erase(begin(), end()); }
|
|
|
|
|
iterator erase(const_iterator pos); // 删除指定位置的元素
|
|
|
|
|
iterator erase(const_iterator first, const_iterator last); // 删除指定范围内的元素
|
|
|
|
|
void clear() { erase(begin(), end()); } // 清空容器
|
|
|
|
|
|
|
|
|
|
// resize / reverse
|
|
|
|
|
void resize(size_type new_size) { return resize(new_size, value_type()); }
|
|
|
|
|
void resize(size_type new_size) { return resize(new_size, value_type()); } // 调整容器大小
|
|
|
|
|
void resize(size_type new_size, const value_type& value);
|
|
|
|
|
|
|
|
|
|
void reverse() { mystl::reverse(begin(), end()); }
|
|
|
|
|
void reverse() { mystl::reverse(begin(), end()); } // 反转容器
|
|
|
|
|
|
|
|
|
|
// swap
|
|
|
|
|
void swap(vector& rhs) noexcept;
|
|
|
|
|
void swap(vector& rhs) noexcept; // 交换两个容器的内容
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
// helper functions
|
|
|
|
|
|
|
|
|
|
// initialize / destroy
|
|
|
|
|
void try_init() noexcept;
|
|
|
|
|
void try_init() noexcept; // 尝试初始化,不抛出异常
|
|
|
|
|
|
|
|
|
|
void init_space(size_type size, size_type cap);
|
|
|
|
|
void init_space(size_type size, size_type cap); // 初始化空间
|
|
|
|
|
|
|
|
|
|
void fill_init(size_type n, const value_type& value);
|
|
|
|
|
void fill_init(size_type n, const value_type& value); // 使用指定值初始化空间
|
|
|
|
|
template <class Iter>
|
|
|
|
|
void range_init(Iter first, Iter last);
|
|
|
|
|
void range_init(Iter first, Iter last); // 使用迭代器范围初始化
|
|
|
|
|
|
|
|
|
|
void destroy_and_recover(iterator first, iterator last, size_type n);
|
|
|
|
|
void destroy_and_recover(iterator first, iterator last, size_type n); // 销毁元素并回收空间
|
|
|
|
|
|
|
|
|
|
// calculate the growth size
|
|
|
|
|
size_type get_new_cap(size_type add_size);
|
|
|
|
|
size_type get_new_cap(size_type add_size); // 计算新的容量大小
|
|
|
|
|
|
|
|
|
|
// assign
|
|
|
|
|
|
|
|
|
|
void fill_assign(size_type n, const value_type& value);
|
|
|
|
|
void fill_assign(size_type n, const value_type& value); // 使用指定值赋值
|
|
|
|
|
|
|
|
|
|
template <class IIter>
|
|
|
|
|
void copy_assign(IIter first, IIter last, input_iterator_tag);
|
|
|
|
|
|
|
|
|
|
void copy_assign(IIter first, IIter last, input_iterator_tag); // 复制赋值,输入迭代器
|
|
|
|
|
template <class FIter>
|
|
|
|
|
void copy_assign(FIter first, FIter last, forward_iterator_tag);
|
|
|
|
|
void copy_assign(FIter first, FIter last, forward_iterator_tag); // 复制赋值,前向迭代器
|
|
|
|
|
|
|
|
|
|
// reallocate
|
|
|
|
|
|
|
|
|
|
template <class... Args>
|
|
|
|
|
void reallocate_emplace(iterator pos, Args&& ...args);
|
|
|
|
|
void reallocate_insert(iterator pos, const value_type& value);
|
|
|
|
|
void reallocate_emplace(iterator pos, Args&& ...args); // 重新分配空间并在指定位置就地构造元素
|
|
|
|
|
void reallocate_insert(iterator pos, const value_type& value); // 重新分配空间并在指定位置插入元素
|
|
|
|
|
|
|
|
|
|
// insert
|
|
|
|
|
|
|
|
|
|
iterator fill_insert(iterator pos, size_type n, const value_type& value);
|
|
|
|
|
iterator fill_insert(iterator pos, size_type n, const value_type& value); // 在指定位置插入指定数量的元素
|
|
|
|
|
template <class IIter>
|
|
|
|
|
void copy_insert(iterator pos, IIter first, IIter last);
|
|
|
|
|
void copy_insert(iterator pos, IIter first, IIter last); // 在指定位置插入迭代器范围内的元素
|
|
|
|
|
|
|
|
|
|
// shrink_to_fit
|
|
|
|
|
|
|
|
|
|
void reinsert(size_type size);
|
|
|
|
|
void reinsert(size_type size); // 重新插入元素以减小容量
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 以下是 vector 类模板的成员函数实现,包括复制赋值操作符、移动赋值操作符、预留空间、减小容量、
|
|
|
|
|
// 在指定位置就地构造元素、在尾部就地构造元素、在尾部插入元素、弹出尾部元素、在指定位置插入元素、
|
|
|
|
|
// 删除指定位置的元素、删除指定范围内的元素、调整容器大小、与另一个 vector 交换内容等函数的实现。
|
|
|
|
|
|
|
|
|
|
// 重载比较操作符,实现 vector 与其他 vector 之间的比较
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************************/
|
|
|
|
|
|
|
|
|
|
// 复制赋值操作符
|
|
|
|
|
// 复制赋值操作符,用于将一个 vector 的内容赋值给另一个 vector
|
|
|
|
|
template <class T>
|
|
|
|
|
vector<T>& vector<T>::operator=(const vector& rhs)
|
|
|
|
|
{
|
|
|
|
|
if (this != &rhs)
|
|
|
|
|
if (this != &rhs) // 检查自赋值
|
|
|
|
|
{
|
|
|
|
|
const auto len = rhs.size();
|
|
|
|
|
if (len > capacity())
|
|
|
|
|
const auto len = rhs.size(); // 获取右边 vector 的大小
|
|
|
|
|
if (len > capacity()) // 如果右边 vector 的大小大于当前 vector 的容量
|
|
|
|
|
{
|
|
|
|
|
vector tmp(rhs.begin(), rhs.end());
|
|
|
|
|
swap(tmp);
|
|
|
|
|
vector tmp(rhs.begin(), rhs.end()); // 创建一个临时 vector 用于交换
|
|
|
|
|
swap(tmp); // 交换当前 vector 和临时 vector 的内容
|
|
|
|
|
}
|
|
|
|
|
else if (size() >= len)
|
|
|
|
|
else if (size() >= len) // 如果当前 vector 的大小大于或等于右边 vector 的大小
|
|
|
|
|
{
|
|
|
|
|
auto i = mystl::copy(rhs.begin(), rhs.end(), begin());
|
|
|
|
|
data_allocator::destroy(i, end_);
|
|
|
|
|
end_ = begin_ + len;
|
|
|
|
|
auto i = mystl::copy(rhs.begin(), rhs.end(), begin()); // 复制元素
|
|
|
|
|
data_allocator::destroy(i, end_); // 销毁多余的元素
|
|
|
|
|
end_ = begin_ + len; // 更新 end_ 指针
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
else // 如果当前 vector 的大小小于右边 vector 的大小
|
|
|
|
|
{
|
|
|
|
|
mystl::copy(rhs.begin(), rhs.begin() + size(), begin_);
|
|
|
|
|
mystl::uninitialized_copy(rhs.begin() + size(), rhs.end(), end_);
|
|
|
|
|
cap_ = end_ = begin_ + len;
|
|
|
|
|
mystl::copy(rhs.begin(), rhs.begin() + size(), begin_); // 复制已有元素
|
|
|
|
|
mystl::uninitialized_copy(rhs.begin() + size(), rhs.end(), end_); // 复制剩余元素到未初始化的内存
|
|
|
|
|
cap_ = end_ = begin_ + len; // 更新 end_ 和 cap_ 指针
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return *this;
|
|
|
|
|
return *this; // 返回当前 vector 的引用
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 移动赋值操作符
|
|
|
|
|
// 移动赋值操作符,用于将一个 vector 的内容移动到另一个 vector
|
|
|
|
|
template <class T>
|
|
|
|
|
vector<T>& vector<T>::operator=(vector&& rhs) noexcept
|
|
|
|
|
{
|
|
|
|
|
destroy_and_recover(begin_, end_, cap_ - begin_);
|
|
|
|
|
begin_ = rhs.begin_;
|
|
|
|
|
end_ = rhs.end_;
|
|
|
|
|
cap_ = rhs.cap_;
|
|
|
|
|
rhs.begin_ = nullptr;
|
|
|
|
|
rhs.end_ = nullptr;
|
|
|
|
|
rhs.cap_ = nullptr;
|
|
|
|
|
return *this;
|
|
|
|
|
destroy_and_recover(begin_, end_, cap_ - begin_); // 销毁当前 vector 的元素并回收内存
|
|
|
|
|
begin_ = rhs.begin_; // 移动右边 vector 的开始指针
|
|
|
|
|
end_ = rhs.end_; // 移动右边 vector 的结束指针
|
|
|
|
|
cap_ = rhs.cap_; // 移动右边 vector 的容量指针
|
|
|
|
|
rhs.begin_ = nullptr; // 将右边 vector 的指针设置为 nullptr
|
|
|
|
|
rhs.end_ = nullptr; // 将右边 vector 的指针设置为 nullptr
|
|
|
|
|
rhs.cap_ = nullptr; // 将右边 vector 的指针设置为 nullptr
|
|
|
|
|
return *this; // 返回当前 vector 的引用
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 预留空间大小,当原容量小于要求大小时,才会重新分配
|
|
|
|
|
// 预留空间大小,如果当前容量小于要求的大小,则会重新分配内存
|
|
|
|
|
template <class T>
|
|
|
|
|
void vector<T>::reserve(size_type n)
|
|
|
|
|
{
|
|
|
|
|
if (capacity() < n)
|
|
|
|
|
if (capacity() < n) // 如果当前容量小于要求的大小
|
|
|
|
|
{
|
|
|
|
|
THROW_LENGTH_ERROR_IF(n > max_size(),
|
|
|
|
|
THROW_LENGTH_ERROR_IF(n > max_size(), // 如果要求的大小超过最大可能大小,则抛出异常
|
|
|
|
|
"n can not larger than max_size() in vector<T>::reserve(n)");
|
|
|
|
|
const auto old_size = size();
|
|
|
|
|
auto tmp = data_allocator::allocate(n);
|
|
|
|
|
mystl::uninitialized_move(begin_, end_, tmp);
|
|
|
|
|
data_allocator::deallocate(begin_, cap_ - begin_);
|
|
|
|
|
begin_ = tmp;
|
|
|
|
|
end_ = tmp + old_size;
|
|
|
|
|
cap_ = begin_ + n;
|
|
|
|
|
const auto old_size = size(); // 获取当前 vector 的大小
|
|
|
|
|
auto tmp = data_allocator::allocate(n); // 分配新的内存
|
|
|
|
|
mystl::uninitialized_move(begin_, end_, tmp); // 将元素移动到新的内存
|
|
|
|
|
data_allocator::deallocate(begin_, cap_ - begin_); // 回收旧内存
|
|
|
|
|
begin_ = tmp; // 更新开始指针
|
|
|
|
|
end_ = tmp + old_size; // 更新结束指针
|
|
|
|
|
cap_ = begin_ + n; // 更新容量指针
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 放弃多余的容量
|
|
|
|
|
// 放弃多余的容量,如果当前 vector 的大小小于容量,则会重新分配内存以减少容量
|
|
|
|
|
template <class T>
|
|
|
|
|
void vector<T>::shrink_to_fit()
|
|
|
|
|
{
|
|
|
|
|
if (end_ < cap_)
|
|
|
|
|
if (end_ < cap_) // 如果当前 vector 的大小小于容量
|
|
|
|
|
{
|
|
|
|
|
reinsert(size());
|
|
|
|
|
reinsert(size()); // 重新插入元素以减小容量
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 在 pos 位置就地构造元素,避免额外的复制或移动开销
|
|
|
|
|
// 在指定位置就地构造元素,使用emplace操作避免额外的复制或移动开销
|
|
|
|
|
template <class T>
|
|
|
|
|
template <class ...Args>
|
|
|
|
|
typename vector<T>::iterator
|
|
|
|
|
vector<T>::emplace(const_iterator pos, Args&& ...args)
|
|
|
|
|
{
|
|
|
|
|
MYSTL_DEBUG(pos >= begin() && pos <= end());
|
|
|
|
|
iterator xpos = const_cast<iterator>(pos);
|
|
|
|
|
const size_type n = xpos - begin_;
|
|
|
|
|
if (end_ != cap_ && xpos == end_)
|
|
|
|
|
MYSTL_DEBUG(pos >= begin() && pos <= end()); // 确保位置有效
|
|
|
|
|
iterator xpos = const_cast<iterator>(pos); // 将 const_iterator 转换为 iterator
|
|
|
|
|
const size_type n = xpos - begin_; // 计算位置偏移
|
|
|
|
|
if (end_ != cap_ && xpos == end_) // 如果位置在 vector 末尾且还有剩余容量
|
|
|
|
|
{
|
|
|
|
|
data_allocator::construct(mystl::address_of(*end_), mystl::forward<Args>(args)...);
|
|
|
|
|
++end_;
|
|
|
|
|
data_allocator::construct(mystl::address_of(*end_), mystl::forward<Args>(args)...); // 就地构造元素
|
|
|
|
|
++end_; // 更新结束指针
|
|
|
|
|
}
|
|
|
|
|
else if (end_ != cap_)
|
|
|
|
|
else if (end_ != cap_) // 如果位置不在 vector 末尾但还有剩余容量
|
|
|
|
|
{
|
|
|
|
|
auto new_end = end_;
|
|
|
|
|
data_allocator::construct(mystl::address_of(*end_), *(end_ - 1));
|
|
|
|
|
++new_end;
|
|
|
|
|
mystl::copy_backward(xpos, end_ - 1, end_);
|
|
|
|
|
*xpos = value_type(mystl::forward<Args>(args)...);
|
|
|
|
|
end_ = new_end;
|
|
|
|
|
auto new_end = end_; // 保存当前结束指针
|
|
|
|
|
data_allocator::construct(mystl::address_of(*end_), *(end_ - 1)); // 就地构造元素
|
|
|
|
|
++new_end; // 更新新结束指针
|
|
|
|
|
mystl::copy_backward(xpos, end_ - 1, end_); // 向后复制元素
|
|
|
|
|
*xpos = value_type(mystl::forward<Args>(args)...); // 就地构造元素
|
|
|
|
|
end_ = new_end; // 更新结束指针
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
else // 如果没有剩余容量
|
|
|
|
|
{
|
|
|
|
|
reallocate_emplace(xpos, mystl::forward<Args>(args)...);
|
|
|
|
|
reallocate_emplace(xpos, mystl::forward<Args>(args)...); // 重新分配内存并就地构造元素
|
|
|
|
|
}
|
|
|
|
|
return begin() + n;
|
|
|
|
|
return begin() + n; // 返回插入位置的迭代器
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 在尾部就地构造元素,避免额外的复制或移动开销
|
|
|
|
|
// 在尾部就地构造元素,使用emplace_back操作避免额外的复制或移动开销
|
|
|
|
|
template <class T>
|
|
|
|
|
template <class ...Args>
|
|
|
|
|
void vector<T>::emplace_back(Args&& ...args)
|
|
|
|
|
{
|
|
|
|
|
if (end_ < cap_)
|
|
|
|
|
if (end_ < cap_) // 如果还有剩余容量
|
|
|
|
|
{
|
|
|
|
|
data_allocator::construct(mystl::address_of(*end_), mystl::forward<Args>(args)...);
|
|
|
|
|
++end_;
|
|
|
|
|
data_allocator::construct(mystl::address_of(*end_), mystl::forward<Args>(args)...); // 就地构造元素
|
|
|
|
|
++end_; // 更新结束指针
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
else // 如果没有剩余容量
|
|
|
|
|
{
|
|
|
|
|
reallocate_emplace(end_, mystl::forward<Args>(args)...);
|
|
|
|
|
reallocate_emplace(end_, mystl::forward<Args>(args)...); // 重新分配内存并就地构造元素
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -445,14 +443,14 @@ void vector<T>::emplace_back(Args&& ...args)
|
|
|
|
|
template <class T>
|
|
|
|
|
void vector<T>::push_back(const value_type& value)
|
|
|
|
|
{
|
|
|
|
|
if (end_ != cap_)
|
|
|
|
|
if (end_ != cap_) // 如果还有剩余容量
|
|
|
|
|
{
|
|
|
|
|
data_allocator::construct(mystl::address_of(*end_), value);
|
|
|
|
|
++end_;
|
|
|
|
|
data_allocator::construct(mystl::address_of(*end_), value); // 构造元素
|
|
|
|
|
++end_; // 更新结束指针
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
else // 如果没有剩余容量
|
|
|
|
|
{
|
|
|
|
|
reallocate_insert(end_, value);
|
|
|
|
|
reallocate_insert(end_, value); // 重新分配内存并插入元素
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -460,65 +458,39 @@ void vector<T>::push_back(const value_type& value)
|
|
|
|
|
template <class T>
|
|
|
|
|
void vector<T>::pop_back()
|
|
|
|
|
{
|
|
|
|
|
MYSTL_DEBUG(!empty());
|
|
|
|
|
data_allocator::destroy(end_ - 1);
|
|
|
|
|
--end_;
|
|
|
|
|
MYSTL_DEBUG(!empty()); // 确保 vector 不为空
|
|
|
|
|
data_allocator::destroy(end_ - 1); // 销毁尾部元素
|
|
|
|
|
--end_; // 更新结束指针
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 在 pos 处插入元素
|
|
|
|
|
// 在指定位置插入元素
|
|
|
|
|
template <class T>
|
|
|
|
|
typename vector<T>::iterator
|
|
|
|
|
vector<T>::insert(const_iterator pos, const value_type& value)
|
|
|
|
|
{
|
|
|
|
|
MYSTL_DEBUG(pos >= begin() && pos <= end());
|
|
|
|
|
iterator xpos = const_cast<iterator>(pos);
|
|
|
|
|
const size_type n = pos - begin_;
|
|
|
|
|
if (end_ != cap_ && xpos == end_)
|
|
|
|
|
MYSTL_DEBUG(pos >= begin() && pos <= end()); // 确保位置有效
|
|
|
|
|
iterator xpos = const_cast<iterator>(pos); // 将 const_iterator 转换为 iterator
|
|
|
|
|
const size_type n = pos - begin_; // 计算位置偏移
|
|
|
|
|
if (end_ != cap_ && xpos == end_) // 如果位置在 vector 末尾且还有剩余容量
|
|
|
|
|
{
|
|
|
|
|
data_allocator::construct(mystl::address_of(*end_), value);
|
|
|
|
|
++end_;
|
|
|
|
|
data_allocator::construct(mystl::address_of(*end_), value); // 构造元素
|
|
|
|
|
++end_; // 更新结束指针
|
|
|
|
|
}
|
|
|
|
|
else if (end_ != cap_)
|
|
|
|
|
else if (end_ != cap_) // 如果位置不在 vector 末尾但还有剩余容量
|
|
|
|
|
{
|
|
|
|
|
auto new_end = end_;
|
|
|
|
|
data_allocator::construct(mystl::address_of(*end_), *(end_ - 1));
|
|
|
|
|
++new_end;
|
|
|
|
|
auto value_copy = value; // 避免元素因以下复制操作而被改变
|
|
|
|
|
mystl::copy_backward(xpos, end_ - 1, end_);
|
|
|
|
|
*xpos = mystl::move(value_copy);
|
|
|
|
|
end_ = new_end;
|
|
|
|
|
auto new_end = end_; // 保存当前结束指针
|
|
|
|
|
data_allocator::construct(mystl::address_of(*end_), *(end_ - 1)); // 就地构造元素
|
|
|
|
|
++new_end; // 更新新结束指针
|
|
|
|
|
auto value_copy = value; // 保存值以防复制改变原始值
|
|
|
|
|
mystl::copy_backward(xpos, end_ - 1, end_); // 向后复制元素
|
|
|
|
|
*xpos = mystl::move(value_copy); // 移动构造元素
|
|
|
|
|
end_ = new_end; // 更新结束指针
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
else // 如果没有剩余容量
|
|
|
|
|
{
|
|
|
|
|
reallocate_insert(xpos, value);
|
|
|
|
|
reallocate_insert(xpos, value); // 重新分配内存并插入元素
|
|
|
|
|
}
|
|
|
|
|
return begin_ + n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 删除 pos 位置上的元素
|
|
|
|
|
template <class T>
|
|
|
|
|
typename vector<T>::iterator
|
|
|
|
|
vector<T>::erase(const_iterator pos)
|
|
|
|
|
{
|
|
|
|
|
MYSTL_DEBUG(pos >= begin() && pos < end());
|
|
|
|
|
iterator xpos = begin_ + (pos - begin());
|
|
|
|
|
mystl::move(xpos + 1, end_, xpos);
|
|
|
|
|
data_allocator::destroy(end_ - 1);
|
|
|
|
|
--end_;
|
|
|
|
|
return xpos;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 删除[first, last)上的元素
|
|
|
|
|
template <class T>
|
|
|
|
|
typename vector<T>::iterator
|
|
|
|
|
vector<T>::erase(const_iterator first, const_iterator last)
|
|
|
|
|
{
|
|
|
|
|
MYSTL_DEBUG(first >= begin() && last <= end() && !(last < first));
|
|
|
|
|
const auto n = first - begin();
|
|
|
|
|
iterator r = begin_ + (first - begin());
|
|
|
|
|
data_allocator::destroy(mystl::move(r + (last - first), end_, r), end_);
|
|
|
|
|
end_ = end_ - (last - first);
|
|
|
|
|
return begin_ + n;
|
|
|
|
|
return begin_ + n; // 返回插入位置的迭代器
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 重置容器大小
|
|
|
|
@ -548,127 +520,8 @@ void vector<T>::swap(vector<T>& rhs) noexcept
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************************/
|
|
|
|
|
// helper function
|
|
|
|
|
|
|
|
|
|
// try_init 函数,若分配失败则忽略,不抛出异常
|
|
|
|
|
template <class T>
|
|
|
|
|
void vector<T>::try_init() noexcept
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
begin_ = data_allocator::allocate(16);
|
|
|
|
|
end_ = begin_;
|
|
|
|
|
cap_ = begin_ + 16;
|
|
|
|
|
}
|
|
|
|
|
catch (...)
|
|
|
|
|
{
|
|
|
|
|
begin_ = nullptr;
|
|
|
|
|
end_ = nullptr;
|
|
|
|
|
cap_ = nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// init_space 函数
|
|
|
|
|
template <class T>
|
|
|
|
|
void vector<T>::init_space(size_type size, size_type cap)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
begin_ = data_allocator::allocate(cap);
|
|
|
|
|
end_ = begin_ + size;
|
|
|
|
|
cap_ = begin_ + cap;
|
|
|
|
|
}
|
|
|
|
|
catch (...)
|
|
|
|
|
{
|
|
|
|
|
begin_ = nullptr;
|
|
|
|
|
end_ = nullptr;
|
|
|
|
|
cap_ = nullptr;
|
|
|
|
|
throw;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// fill_init 函数
|
|
|
|
|
template <class T>
|
|
|
|
|
void vector<T>::
|
|
|
|
|
fill_init(size_type n, const value_type& value)
|
|
|
|
|
{
|
|
|
|
|
const size_type init_size = mystl::max(static_cast<size_type>(16), n);
|
|
|
|
|
init_space(n, init_size);
|
|
|
|
|
mystl::uninitialized_fill_n(begin_, n, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// range_init 函数
|
|
|
|
|
template <class T>
|
|
|
|
|
template <class Iter>
|
|
|
|
|
void vector<T>::
|
|
|
|
|
range_init(Iter first, Iter last)
|
|
|
|
|
{
|
|
|
|
|
const size_type len = mystl::distance(first, last);
|
|
|
|
|
const size_type init_size = mystl::max(len, static_cast<size_type>(16));
|
|
|
|
|
init_space(len, init_size);
|
|
|
|
|
mystl::uninitialized_copy(first, last, begin_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// destroy_and_recover 函数
|
|
|
|
|
template <class T>
|
|
|
|
|
void vector<T>::
|
|
|
|
|
destroy_and_recover(iterator first, iterator last, size_type n)
|
|
|
|
|
{
|
|
|
|
|
data_allocator::destroy(first, last);
|
|
|
|
|
data_allocator::deallocate(first, n);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// get_new_cap 函数
|
|
|
|
|
template <class T>
|
|
|
|
|
typename vector<T>::size_type
|
|
|
|
|
vector<T>::
|
|
|
|
|
get_new_cap(size_type add_size)
|
|
|
|
|
{
|
|
|
|
|
const auto old_size = capacity();
|
|
|
|
|
THROW_LENGTH_ERROR_IF(old_size > max_size() - add_size,
|
|
|
|
|
"vector<T>'s size too big");
|
|
|
|
|
if (old_size > max_size() - old_size / 2)
|
|
|
|
|
{
|
|
|
|
|
return old_size + add_size > max_size() - 16
|
|
|
|
|
? old_size + add_size : old_size + add_size + 16;
|
|
|
|
|
}
|
|
|
|
|
const size_type new_size = old_size == 0
|
|
|
|
|
? mystl::max(add_size, static_cast<size_type>(16))
|
|
|
|
|
: mystl::max(old_size + old_size / 2, old_size + add_size);
|
|
|
|
|
return new_size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// fill_assign 函数
|
|
|
|
|
template <class T>
|
|
|
|
|
void vector<T>::
|
|
|
|
|
fill_assign(size_type n, const value_type& value)
|
|
|
|
|
{
|
|
|
|
|
if (n > capacity())
|
|
|
|
|
{
|
|
|
|
|
vector tmp(n, value);
|
|
|
|
|
swap(tmp);
|
|
|
|
|
}
|
|
|
|
|
else if (n > size())
|
|
|
|
|
{
|
|
|
|
|
mystl::fill(begin(), end(), value);
|
|
|
|
|
end_ = mystl::uninitialized_fill_n(end_, n - size(), value);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
erase(mystl::fill_n(begin_, n, value), end_);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// copy_assign 函数
|
|
|
|
|
template <class T>
|
|
|
|
|
template <class IIter>
|
|
|
|
|
void vector<T>::
|
|
|
|
|
copy_assign(IIter first, IIter last, input_iterator_tag)
|
|
|
|
|
{
|
|
|
|
|
auto cur = begin_;
|
|
|
|
|
for (; first != last && cur != end_; ++first, ++cur)
|
|
|
|
|
{
|
|
|
|
|
*cur = *first;
|
|
|
|
|
*cur = *first;
|
|
|
|
|
}
|
|
|
|
|
if (first == last)
|
|
|
|
|
{
|
|
|
|
@ -759,7 +612,7 @@ void vector<T>::reallocate_insert(iterator pos, const value_type& value)
|
|
|
|
|
begin_ = new_begin;
|
|
|
|
|
end_ = new_end;
|
|
|
|
|
cap_ = new_begin + new_size;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// fill_insert 函数
|
|
|
|
|
template <class T>
|
|
|
|
@ -863,74 +716,79 @@ copy_insert(iterator pos, IIter first, IIter last)
|
|
|
|
|
cap_ = begin_ + new_size;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// reinsert 函数
|
|
|
|
|
// reinsert 函数,用于重新分配内存空间并将现有元素移动到新的内存空间
|
|
|
|
|
// 通常在减小 vector 容量时被调用,以释放多余的内存
|
|
|
|
|
template <class T>
|
|
|
|
|
void vector<T>::reinsert(size_type size)
|
|
|
|
|
{
|
|
|
|
|
auto new_begin = data_allocator::allocate(size);
|
|
|
|
|
auto new_begin = data_allocator::allocate(size); // 分配新的内存空间,大小为 size
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
mystl::uninitialized_move(begin_, end_, new_begin);
|
|
|
|
|
mystl::uninitialized_move(begin_, end_, new_begin); // 将 [begin_, end_) 范围内的元素移动到新内存空间
|
|
|
|
|
}
|
|
|
|
|
catch (...)
|
|
|
|
|
catch (...) // 如果在移动过程中发生异常,则释放新分配的内存并重新抛出异常
|
|
|
|
|
{
|
|
|
|
|
data_allocator::deallocate(new_begin, size);
|
|
|
|
|
throw;
|
|
|
|
|
}
|
|
|
|
|
data_allocator::deallocate(begin_, cap_ - begin_);
|
|
|
|
|
begin_ = new_begin;
|
|
|
|
|
end_ = begin_ + size;
|
|
|
|
|
cap_ = begin_ + size;
|
|
|
|
|
data_allocator::deallocate(begin_, cap_ - begin_); // 释放旧的内存空间
|
|
|
|
|
begin_ = new_begin; // 更新 begin_ 指针到新内存空间
|
|
|
|
|
end_ = begin_ + size; // 更新 end_ 指针到新内存空间的末尾
|
|
|
|
|
cap_ = begin_ + size; // 更新 cap_ 指针到新内存空间的末尾
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************************/
|
|
|
|
|
// 重载比较操作符
|
|
|
|
|
/*********************************************************************************************/
|
|
|
|
|
// 重载比较操作符,提供 vector 与其他 vector 之间的比较功能
|
|
|
|
|
|
|
|
|
|
// 等于比较操作符,检查两个 vector 是否相等
|
|
|
|
|
template <class T>
|
|
|
|
|
bool operator==(const vector<T>& lhs, const vector<T>& rhs)
|
|
|
|
|
{
|
|
|
|
|
return lhs.size() == rhs.size() &&
|
|
|
|
|
mystl::equal(lhs.begin(), lhs.end(), rhs.begin());
|
|
|
|
|
return lhs.size() == rhs.size() && // 如果两个 vector 的大小相等
|
|
|
|
|
mystl::equal(lhs.begin(), lhs.end(), rhs.begin()); // 并且每个对应元素都相等,则返回 true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 小于比较操作符,进行字典序比较
|
|
|
|
|
template <class T>
|
|
|
|
|
bool operator<(const vector<T>& lhs, const vector<T>& rhs)
|
|
|
|
|
{
|
|
|
|
|
return mystl::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
|
|
|
|
|
return mystl::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); // 返回 lhs 是否字典序小于 rhs
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 不等于比较操作符,检查两个 vector 是否不相等
|
|
|
|
|
template <class T>
|
|
|
|
|
bool operator!=(const vector<T>& lhs, const vector<T>& rhs)
|
|
|
|
|
{
|
|
|
|
|
return !(lhs == rhs);
|
|
|
|
|
return !(lhs == rhs); // 如果两个 vector 不相等,则返回 true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 大于比较操作符,检查 lhs 是否大于 rhs
|
|
|
|
|
template <class T>
|
|
|
|
|
bool operator>(const vector<T>& lhs, const vector<T>& rhs)
|
|
|
|
|
{
|
|
|
|
|
return rhs < lhs;
|
|
|
|
|
return rhs < lhs; // 如果 rhs 小于 lhs,则返回 true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 小于等于比较操作符,检查 lhs 是否小于等于 rhs
|
|
|
|
|
template <class T>
|
|
|
|
|
bool operator<=(const vector<T>& lhs, const vector<T>& rhs)
|
|
|
|
|
{
|
|
|
|
|
return !(rhs < lhs);
|
|
|
|
|
return !(rhs < lhs); // 如果 rhs 不小于 lhs,则返回 true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 大于等于比较操作符,检查 lhs 是否大于等于 rhs
|
|
|
|
|
template <class T>
|
|
|
|
|
bool operator>=(const vector<T>& lhs, const vector<T>& rhs)
|
|
|
|
|
{
|
|
|
|
|
return !(lhs < rhs);
|
|
|
|
|
return !(lhs < rhs); // 如果 lhs 不小于 rhs,则返回 true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 重载 mystl 的 swap
|
|
|
|
|
// 重载 mystl 的 swap 函数,用于交换两个 vector 的内容
|
|
|
|
|
template <class T>
|
|
|
|
|
void swap(vector<T>& lhs, vector<T>& rhs)
|
|
|
|
|
{
|
|
|
|
|
lhs.swap(rhs);
|
|
|
|
|
lhs.swap(rhs); // 调用 vector 的 swap 方法交换两个 vector 的内容
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace mystl
|
|
|
|
|
#endif // !MYTINYSTL_VECTOR_H_
|
|
|
|
|
|
|
|
|
|
} // namespace mystl // 结束 mystl 命名空间
|
|
|
|
|
#endif // !MYTINYSTL_VECTOR_H_ // 结束头文件保护宏定义
|