|
|
|
@ -26,29 +26,29 @@ namespace mystl // 命名空间 mystl,用于封装自定义的 STL 组件
|
|
|
|
|
private:
|
|
|
|
|
// 使用 hashtable 作为底层机制
|
|
|
|
|
typedef hashtable<mystl::pair<const Key, T>, Hash, KeyEqual> base_type;
|
|
|
|
|
base_type ht_;
|
|
|
|
|
base_type ht_; // 基础类型的实例,用于存储数据
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
// 使用 hashtable 的型别
|
|
|
|
|
// 以下定义了与 hashtable 相关的类型别名,方便在 unordered_map 中使用
|
|
|
|
|
typedef typename base_type::allocator_type allocator_type;
|
|
|
|
|
typedef typename base_type::key_type key_type;
|
|
|
|
|
typedef typename base_type::mapped_type mapped_type;
|
|
|
|
|
typedef typename base_type::value_type value_type;
|
|
|
|
|
typedef typename base_type::hasher hasher;
|
|
|
|
|
typedef typename base_type::key_equal key_equal;
|
|
|
|
|
|
|
|
|
|
typedef typename base_type::size_type size_type;
|
|
|
|
|
typedef typename base_type::difference_type difference_type;
|
|
|
|
|
typedef typename base_type::pointer pointer;
|
|
|
|
|
typedef typename base_type::const_pointer const_pointer;
|
|
|
|
|
typedef typename base_type::reference reference;
|
|
|
|
|
typedef typename base_type::const_reference const_reference;
|
|
|
|
|
|
|
|
|
|
typedef typename base_type::iterator iterator;
|
|
|
|
|
typedef typename base_type::const_iterator const_iterator;
|
|
|
|
|
typedef typename base_type::local_iterator local_iterator;
|
|
|
|
|
typedef typename base_type::const_local_iterator const_local_iterator;
|
|
|
|
|
typedef typename base_type::allocator_type allocator_type; // 分配器类型
|
|
|
|
|
typedef typename base_type::key_type key_type; // 键类型
|
|
|
|
|
typedef typename base_type::mapped_type mapped_type; // 映射类型
|
|
|
|
|
typedef typename base_type::value_type value_type; // 值类型
|
|
|
|
|
typedef typename base_type::hasher hasher; // 哈希函数类型
|
|
|
|
|
typedef typename base_type::key_equal key_equal; // 键值比较函数类型
|
|
|
|
|
|
|
|
|
|
typedef typename base_type::size_type size_type; // 容器大小类型
|
|
|
|
|
typedef typename base_type::difference_type difference_type;// 容器差值类型
|
|
|
|
|
typedef typename base_type::pointer pointer; // 指针类型
|
|
|
|
|
typedef typename base_type::const_pointer const_pointer; // 常量指针类型
|
|
|
|
|
typedef typename base_type::reference reference; // 引用类型
|
|
|
|
|
typedef typename base_type::const_reference const_reference;// 常量引用类型
|
|
|
|
|
|
|
|
|
|
typedef typename base_type::iterator iterator; // 迭代器类型
|
|
|
|
|
typedef typename base_type::const_iterator const_iterator; // 常量迭代器类型
|
|
|
|
|
typedef typename base_type::local_iterator local_iterator; // 本地迭代器类型
|
|
|
|
|
typedef typename base_type::const_local_iterator const_local_iterator; // 常量本地迭代器类型
|
|
|
|
|
|
|
|
|
|
allocator_type get_allocator() const { return ht_.get_allocator(); } // 获取分配器
|
|
|
|
|
|
|
|
|
@ -77,7 +77,7 @@ namespace mystl // 命名空间 mystl,用于封装自定义的 STL 组件
|
|
|
|
|
: ht_(mystl::max(bucket_count, static_cast<size_type>(mystl::distance(first, last))), hash, equal)
|
|
|
|
|
{
|
|
|
|
|
for (; first != last; ++first)
|
|
|
|
|
ht_.insert_unique_noresize(*first);
|
|
|
|
|
ht_.insert_unique_noresize(*first); // 插入元素,不调整桶大小
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 初始化列表构造函数,从给定的值初始化 unordered_map
|
|
|
|
@ -88,7 +88,7 @@ namespace mystl // 命名空间 mystl,用于封装自定义的 STL 组件
|
|
|
|
|
:ht_(mystl::max(bucket_count, static_cast<size_type>(ilist.size())), hash, equal)
|
|
|
|
|
{
|
|
|
|
|
for (auto first = ilist.begin(), last = ilist.end(); first != last; ++first)
|
|
|
|
|
ht_.insert_unique_noresize(*first);
|
|
|
|
|
ht_.insert_unique_noresize(*first); // 插入元素,不调整桶大小
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 复制构造函数
|
|
|
|
@ -102,7 +102,7 @@ namespace mystl // 命名空间 mystl,用于封装自定义的 STL 组件
|
|
|
|
|
:ht_(mystl::move(rhs.ht_))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 赋值运算符重载
|
|
|
|
|
// 复制赋值运算符,将右侧对象的值赋给当前对象
|
|
|
|
|
unordered_map& operator=(const unordered_map& rhs)
|
|
|
|
@ -187,125 +187,125 @@ namespace mystl // 命名空间 mystl,用于封装自定义的 STL 组件
|
|
|
|
|
{
|
|
|
|
|
return ht_.emplace_unique_use_hint(hint, mystl::forward<Args>(args)...);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// insert
|
|
|
|
|
};
|
|
|
|
|
} // insert
|
|
|
|
|
// 插入元素,返回插入的迭代器和是否插入的布尔值
|
|
|
|
|
pair<iterator, bool> insert(const value_type& value)
|
|
|
|
|
{
|
|
|
|
|
return ht_.insert_unique(value);
|
|
|
|
|
return ht_.insert_unique(value); // 调用底层 hashtable 的 insert_unique 方法
|
|
|
|
|
}
|
|
|
|
|
// 插入移动构造的元素
|
|
|
|
|
pair<iterator, bool> insert(value_type&& value)
|
|
|
|
|
{
|
|
|
|
|
return ht_.emplace_unique(mystl::move(value));
|
|
|
|
|
return ht_.emplace_unique(mystl::move(value)); // 使用 emplace_unique 插入移动构造的元素
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 使用 hint 提示插入位置
|
|
|
|
|
iterator insert(const_iterator hint, const value_type& value)
|
|
|
|
|
{
|
|
|
|
|
return ht_.insert_unique_use_hint(hint, value);
|
|
|
|
|
return ht_.insert_unique_use_hint(hint, value); // 使用 hint 提示插入位置
|
|
|
|
|
}
|
|
|
|
|
// 使用 hint 提示插入位置,并插入移动构造的元素
|
|
|
|
|
iterator insert(const_iterator hint, value_type&& value)
|
|
|
|
|
{
|
|
|
|
|
return ht_.emplace_unique_use_hint(hint, mystl::move(value));
|
|
|
|
|
return ht_.emplace_unique_use_hint(hint, mystl::move(value)); // 使用 hint 插入移动构造的元素
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 从迭代器范围插入元素
|
|
|
|
|
template <class InputIterator>
|
|
|
|
|
void insert(InputIterator first, InputIterator last)
|
|
|
|
|
{
|
|
|
|
|
ht_.insert_unique(first, last);
|
|
|
|
|
ht_.insert_unique(first, last); // 插入范围内的所有元素
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// erase / clear
|
|
|
|
|
// 删除指定迭代器位置的元素
|
|
|
|
|
void erase(iterator it)
|
|
|
|
|
{
|
|
|
|
|
ht_.erase(it);
|
|
|
|
|
ht_.erase(it); // 调用底层 hashtable 的 erase 方法
|
|
|
|
|
}
|
|
|
|
|
// 删除指定范围的元素
|
|
|
|
|
void erase(iterator first, iterator last)
|
|
|
|
|
{
|
|
|
|
|
ht_.erase(first, last);
|
|
|
|
|
ht_.erase(first, last); // 删除范围内的所有元素
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 删除指定键的元素,并返回被删除的元素数量
|
|
|
|
|
size_type erase(const key_type& key)
|
|
|
|
|
{
|
|
|
|
|
return ht_.erase_unique(key);
|
|
|
|
|
return ht_.erase_unique(key); // 调用底层 hashtable 的 erase_unique 方法
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 清空容器
|
|
|
|
|
void clear()
|
|
|
|
|
{
|
|
|
|
|
ht_.clear();
|
|
|
|
|
ht_.clear(); // 调用底层 hashtable 的 clear 方法
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 交换两个 unordered_map 对象的内容
|
|
|
|
|
void swap(unordered_map& other) noexcept
|
|
|
|
|
{
|
|
|
|
|
ht_.swap(other.ht_);
|
|
|
|
|
ht_.swap(other.ht_); // 交换底层 hashtable 的内容
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查找相关
|
|
|
|
|
// 返回指定键的值的引用,如果键不存在则抛出异常
|
|
|
|
|
mapped_type& at(const key_type& key)
|
|
|
|
|
{
|
|
|
|
|
iterator it = ht_.find(key);
|
|
|
|
|
THROW_OUT_OF_RANGE_IF(it.node == nullptr, "unordered_map<Key, T> no such element exists");
|
|
|
|
|
return it->second;
|
|
|
|
|
iterator it = ht_.find(key); // 查找键
|
|
|
|
|
THROW_OUT_OF_RANGE_IF(it.node == nullptr, "unordered_map<Key, T> no such element exists"); // 如果键不存在,抛出异常
|
|
|
|
|
return it->second; // 返回值的引用
|
|
|
|
|
}
|
|
|
|
|
// 返回指定键的值的常量引用,如果键不存在则抛出异常
|
|
|
|
|
const mapped_type& at(const key_type& key) const
|
|
|
|
|
{
|
|
|
|
|
iterator it = ht_.find(key);
|
|
|
|
|
THROW_OUT_OF_RANGE_IF(it.node == nullptr, "unordered_map<Key, T> no such element exists");
|
|
|
|
|
return it->second;
|
|
|
|
|
iterator it = ht_.find(key); // 查找键
|
|
|
|
|
THROW_OUT_OF_RANGE_IF(it.node == nullptr, "unordered_map<Key, T> no such element exists"); // 如果键不存在,抛出异常
|
|
|
|
|
return it->second; // 返回值的常量引用
|
|
|
|
|
}
|
|
|
|
|
// 下标操作符重载
|
|
|
|
|
// 通过键查找或创建元素,并返回元素的引用
|
|
|
|
|
mapped_type& operator[](const key_type& key)
|
|
|
|
|
{
|
|
|
|
|
iterator it = ht_.find(key);
|
|
|
|
|
iterator it = ht_.find(key); // 查找键
|
|
|
|
|
if (it.node == nullptr)
|
|
|
|
|
it = ht_.emplace_unique(key, T{}).first; // 如果元素不存在,则插入新元素
|
|
|
|
|
return it->second;
|
|
|
|
|
return it->second; // 返回值的引用
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 下标操作符重载,用于移动构造的键
|
|
|
|
|
mapped_type& operator[](key_type&& key)
|
|
|
|
|
{
|
|
|
|
|
iterator it = ht_.find(key);
|
|
|
|
|
iterator it = ht_.find(key); // 查找键
|
|
|
|
|
if (it.node == nullptr)
|
|
|
|
|
it = ht_.emplace_unique(mystl::move(key), T{}).first; // 如果元素不存在,则插入新元素
|
|
|
|
|
return it->second;
|
|
|
|
|
return it->second; // 返回值的引用
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 计算给定键的元素数量
|
|
|
|
|
size_type count(const key_type& key) const
|
|
|
|
|
{
|
|
|
|
|
return ht_.count(key);
|
|
|
|
|
return ht_.count(key); // 调用底层 hashtable 的 count 方法
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查找元素
|
|
|
|
|
iterator find(const key_type& key)
|
|
|
|
|
{
|
|
|
|
|
return ht_.find(key);
|
|
|
|
|
return ht_.find(key); // 调用底层 hashtable 的 find 方法
|
|
|
|
|
}
|
|
|
|
|
const_iterator find(const key_type& key) const
|
|
|
|
|
{
|
|
|
|
|
return ht_.find(key);
|
|
|
|
|
return ht_.find(key); // 调用底层 hashtable 的 find 方法
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 返回给定键的元素范围
|
|
|
|
|
pair<iterator, iterator> equal_range(const key_type& key)
|
|
|
|
|
{
|
|
|
|
|
return ht_.equal_range_unique(key);
|
|
|
|
|
return ht_.equal_range_unique(key); // 调用底层 hashtable 的 equal_range_unique 方法
|
|
|
|
|
}
|
|
|
|
|
pair<const_iterator, const_iterator> equal_range(const key_type& key) const
|
|
|
|
|
{
|
|
|
|
|
return ht_.equal_range_unique(key);
|
|
|
|
|
return ht_.equal_range_unique(key); // 调用底层 hashtable 的 equal_range_unique 方法
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 桶接口
|
|
|
|
@ -313,50 +313,50 @@ namespace mystl // 命名空间 mystl,用于封装自定义的 STL 组件
|
|
|
|
|
// 返回指定桶的本地迭代器
|
|
|
|
|
local_iterator begin(size_type n) noexcept
|
|
|
|
|
{
|
|
|
|
|
return ht_.begin(n);
|
|
|
|
|
return ht_.begin(n); // 调用底层 hashtable 的 begin 方法
|
|
|
|
|
}
|
|
|
|
|
const_local_iterator begin(size_type n) const noexcept
|
|
|
|
|
{
|
|
|
|
|
return ht_.begin(n);
|
|
|
|
|
return ht_.begin(n); // 调用底层 hashtable 的 begin 方法
|
|
|
|
|
}
|
|
|
|
|
const_local_iterator cbegin(size_type n) const noexcept
|
|
|
|
|
{
|
|
|
|
|
return ht_.cbegin(n);
|
|
|
|
|
return ht_.cbegin(n); // 调用底层 hashtable 的 cbegin 方法
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 返回指定桶的本地迭代器
|
|
|
|
|
local_iterator end(size_type n) noexcept
|
|
|
|
|
{
|
|
|
|
|
return ht_.end(n);
|
|
|
|
|
return ht_.end(n); // 调用底层 hashtable 的 end 方法
|
|
|
|
|
}
|
|
|
|
|
const_local_iterator end(size_type n) const noexcept
|
|
|
|
|
{
|
|
|
|
|
return ht_.end(n);
|
|
|
|
|
return ht_.end(n); // 调用底层 hashtable 的 end 方法
|
|
|
|
|
}
|
|
|
|
|
const_local_iterator cend(size_type n) const noexcept
|
|
|
|
|
{
|
|
|
|
|
return ht_.cend(n);
|
|
|
|
|
return ht_.cend(n); // 调用底层 hashtable 的 cend 方法
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 返回桶的数量
|
|
|
|
|
size_type bucket_count() const noexcept
|
|
|
|
|
{
|
|
|
|
|
return ht_.bucket_count();
|
|
|
|
|
return ht_.bucket_count(); // 调用底层 hashtable 的 bucket_count 方法
|
|
|
|
|
}
|
|
|
|
|
size_type max_bucket_count() const noexcept
|
|
|
|
|
{
|
|
|
|
|
return ht_.max_bucket_count();
|
|
|
|
|
return ht_.max_bucket_count(); // 调用底层 hashtable 的 max_bucket_count 方法
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 返回指定桶的大小
|
|
|
|
|
size_type bucket_size(size_type n) const noexcept
|
|
|
|
|
{
|
|
|
|
|
return ht_.bucket_size(n);
|
|
|
|
|
return ht_.bucket_size(n); // 调用底层 hashtable 的 bucket_size 方法
|
|
|
|
|
}
|
|
|
|
|
// 返回给定键的元素所在的桶编号
|
|
|
|
|
size_type bucket(const key_type& key) const
|
|
|
|
|
{
|
|
|
|
|
return ht_.bucket(key);
|
|
|
|
|
return ht_.bucket(key); // 调用底层 hashtable 的 bucket 方法
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 哈希策略
|
|
|
|
@ -383,11 +383,11 @@ namespace mystl // 命名空间 mystl,用于封装自定义的 STL 组件
|
|
|
|
|
public:
|
|
|
|
|
friend bool operator==(const unordered_map& lhs, const unordered_map& rhs)
|
|
|
|
|
{
|
|
|
|
|
return lhs.ht_.equal_range_unique(rhs.ht_);
|
|
|
|
|
return lhs.ht_.equal_range_unique(rhs.ht_); // 比较两个 unordered_map 是否相等
|
|
|
|
|
}
|
|
|
|
|
friend bool operator!=(const unordered_map& lhs, const unordered_map& rhs)
|
|
|
|
|
{
|
|
|
|
|
return !lhs.ht_.equal_range_unique(rhs.ht_);
|
|
|
|
|
return !lhs.ht_.equal_range_unique(rhs.ht_); // 比较两个 unordered_map 是否不相等
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
@ -396,14 +396,14 @@ template <class Key, class T, class Hash, class KeyEqual>
|
|
|
|
|
bool operator==(const unordered_map<Key, T, Hash, KeyEqual>& lhs,
|
|
|
|
|
const unordered_map<Key, T, Hash, KeyEqual>& rhs)
|
|
|
|
|
{
|
|
|
|
|
return lhs == rhs;
|
|
|
|
|
return lhs == rhs; // 使用友元函数中的比较逻辑
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class Key, class T, class Hash, class KeyEqual>
|
|
|
|
|
bool operator!=(const unordered_map<Key, T, Hash, KeyEqual>& lhs,
|
|
|
|
|
const unordered_map<Key, T, Hash, KeyEqual>& rhs)
|
|
|
|
|
{
|
|
|
|
|
return lhs != rhs;
|
|
|
|
|
return lhs != rhs; // 使用友元函数中的比较逻辑
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 重载 mystl 的 swap 函数
|
|
|
|
@ -411,49 +411,40 @@ template <class Key, class T, class Hash, class KeyEqual>
|
|
|
|
|
void swap(unordered_map<Key, T, Hash, KeyEqual>& lhs,
|
|
|
|
|
unordered_map<Key, T, Hash, KeyEqual>& rhs)
|
|
|
|
|
{
|
|
|
|
|
lhs.swap(rhs);
|
|
|
|
|
lhs.swap(rhs); // 调用 unordered_map 的 swap 方法
|
|
|
|
|
}
|
|
|
|
|
// 模板类 unordered_multimap,键值允许重复
|
|
|
|
|
// 参数一代表键值类型,参数二代表实值类型,参数三代表哈希函数,缺省使用 mystl::hash
|
|
|
|
|
// 参数四代表键值比较方式,缺省使用 mystl::equal_to
|
|
|
|
|
template <class Key, class T, class Hash = mystl::hash<Key>, class KeyEqual = mystl::equal_to<Key>>
|
|
|
|
|
class unordered_multimap
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
// 使用 hashtable 作为底层机制
|
|
|
|
|
typedef hashtable<pair<const Key, T>, Hash, KeyEqual> base_type;
|
|
|
|
|
base_type ht_;
|
|
|
|
|
|
|
|
|
|
// 模板类 unordered_multimap,键值允许重复
|
|
|
|
|
public:
|
|
|
|
|
// 使用 hashtable 的型别
|
|
|
|
|
// 以下定义了与 hashtable 相关的类型别名,方便在 unordered_multimap 中使用
|
|
|
|
|
typedef typename base_type::allocator_type allocator_type;
|
|
|
|
|
typedef typename base_type::key_type key_type;
|
|
|
|
|
typedef typename base_type::mapped_type mapped_type;
|
|
|
|
|
typedef typename base_type::value_type value_type;
|
|
|
|
|
typedef typename base_type::hasher hasher;
|
|
|
|
|
typedef typename base_type::key_equal key_equal;
|
|
|
|
|
|
|
|
|
|
typedef typename base_type::size_type size_type;
|
|
|
|
|
typedef typename base_type::difference_type difference_type;
|
|
|
|
|
typedef typename base_type::pointer pointer;
|
|
|
|
|
typedef typename base_type::const_pointer const_pointer;
|
|
|
|
|
typedef typename base_type::reference reference;
|
|
|
|
|
typedef typename base_type::const_reference const_reference;
|
|
|
|
|
|
|
|
|
|
typedef typename base_type::iterator iterator;
|
|
|
|
|
typedef typename base_type::const_iterator const_iterator;
|
|
|
|
|
typedef typename base_type::local_iterator local_iterator;
|
|
|
|
|
typedef typename base_type::const_local_iterator const_local_iterator;
|
|
|
|
|
typedef typename base_type::allocator_type allocator_type; // 分配器类型
|
|
|
|
|
typedef typename base_type::key_type key_type; // 键类型
|
|
|
|
|
typedef typename base_type::mapped_type mapped_type; // 映射类型
|
|
|
|
|
typedef typename base_type::value_type value_type; // 值类型
|
|
|
|
|
typedef typename base_type::hasher hasher; // 哈希函数类型
|
|
|
|
|
typedef typename base_type::key_equal key_equal; // 键值比较函数类型
|
|
|
|
|
|
|
|
|
|
typedef typename base_type::size_type size_type; // 容器大小类型
|
|
|
|
|
typedef typename base_type::difference_type difference_type;// 容器差值类型
|
|
|
|
|
typedef typename base_type::pointer pointer; // 指针类型
|
|
|
|
|
typedef typename base_type::const_pointer const_pointer; // 常量指针类型
|
|
|
|
|
typedef typename base_type::reference reference; // 引用类型
|
|
|
|
|
typedef typename base_type::const_reference const_reference;// 常量引用类型
|
|
|
|
|
|
|
|
|
|
typedef typename base_type::iterator iterator; // 迭代器类型
|
|
|
|
|
typedef typename base_type::const_iterator const_iterator; // 常量迭代器类型
|
|
|
|
|
typedef typename base_type::local_iterator local_iterator; // 本地迭代器类型
|
|
|
|
|
typedef typename base_type::const_local_iterator const_local_iterator; // 常量本地迭代器类型
|
|
|
|
|
|
|
|
|
|
// 获取分配器
|
|
|
|
|
allocator_type get_allocator() const { return ht_.get_allocator(); }
|
|
|
|
|
allocator_type get_allocator() const { return ht_.get_allocator(); } // 返回底层 hashtable 的分配器
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
// 构造、复制、移动函数
|
|
|
|
|
// 默认构造函数,初始化一个空的 unordered_multimap
|
|
|
|
|
unordered_multimap()
|
|
|
|
|
:ht_(100, Hash(), KeyEqual())
|
|
|
|
|
:ht_(100, Hash(), KeyEqual()) // 初始化底层 hashtable,设置默认桶数量为 100
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -461,7 +452,7 @@ public:
|
|
|
|
|
explicit unordered_multimap(size_type bucket_count,
|
|
|
|
|
const Hash& hash = Hash(),
|
|
|
|
|
const KeyEqual& equal = KeyEqual())
|
|
|
|
|
:ht_(bucket_count, hash, equal)
|
|
|
|
|
:ht_(bucket_count, hash, equal) // 初始化底层 hashtable,设置桶数量、哈希函数和键值比较函数
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -471,7 +462,7 @@ public:
|
|
|
|
|
const size_type bucket_count = 100,
|
|
|
|
|
const Hash& hash = Hash(),
|
|
|
|
|
const KeyEqual& equal = KeyEqual())
|
|
|
|
|
: ht_(mystl::max(bucket_count, static_cast<size_type>(mystl::distance(first, last))), hash, equal)
|
|
|
|
|
: ht_(mystl::max(bucket_count, static_cast<size_type>(mystl::distance(first, last))), hash, equal) // 初始化底层 hashtable,设置桶数量、哈希函数和键值比较函数
|
|
|
|
|
{
|
|
|
|
|
for (; first != last; ++first)
|
|
|
|
|
ht_.insert_multi_noresize(*first); // 插入元素,不调整桶大小
|
|
|
|
@ -482,7 +473,7 @@ public:
|
|
|
|
|
const size_type bucket_count = 100,
|
|
|
|
|
const Hash& hash = Hash(),
|
|
|
|
|
const KeyEqual& equal = KeyEqual())
|
|
|
|
|
:ht_(mystl::max(bucket_count, static_cast<size_type>(ilist.size())), hash, equal)
|
|
|
|
|
:ht_(mystl::max(bucket_count, static_cast<size_type>(ilist.size())), hash, equal) // 初始化底层 hashtable,设置桶数量、哈希函数和键值比较函数
|
|
|
|
|
{
|
|
|
|
|
for (auto first = ilist.begin(), last = ilist.end(); first != last; ++first)
|
|
|
|
|
ht_.insert_multi_noresize(*first); // 插入元素,不调整桶大小
|
|
|
|
@ -490,25 +481,25 @@ public:
|
|
|
|
|
|
|
|
|
|
// 复制构造函数
|
|
|
|
|
unordered_multimap(const unordered_multimap& rhs)
|
|
|
|
|
:ht_(rhs.ht_)
|
|
|
|
|
:ht_(rhs.ht_) // 深拷贝底层 hashtable
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 移动构造函数
|
|
|
|
|
unordered_multimap(unordered_multimap&& rhs) noexcept
|
|
|
|
|
:ht_(mystl::move(rhs.ht_))
|
|
|
|
|
:ht_(mystl::move(rhs.ht_)) // 移动底层 hashtable
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 赋值运算符重载
|
|
|
|
|
unordered_multimap& operator=(const unordered_multimap& rhs)
|
|
|
|
|
{
|
|
|
|
|
ht_ = rhs.ht_;
|
|
|
|
|
ht_ = rhs.ht_; // 深拷贝底层 hashtable
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
unordered_multimap& operator=(unordered_multimap&& rhs)
|
|
|
|
|
{
|
|
|
|
|
ht_ = mystl::move(rhs.ht_);
|
|
|
|
|
ht_ = mystl::move(rhs.ht_); // 移动底层 hashtable
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -523,29 +514,29 @@ public:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 默认析构函数
|
|
|
|
|
~unordered_multimap() = default;
|
|
|
|
|
};
|
|
|
|
|
~unordered_multimap() = default; // 默认析构函数,由编译器生成
|
|
|
|
|
|
|
|
|
|
// 迭代器访问
|
|
|
|
|
// 返回指向第一个元素的迭代器
|
|
|
|
|
iterator begin() noexcept { return ht_.begin(); }
|
|
|
|
|
iterator begin() noexcept { return ht_.begin(); } // 返回底层 hashtable 的 begin 迭代器
|
|
|
|
|
// 返回指向第一个元素的常量迭代器
|
|
|
|
|
const_iterator begin() const noexcept { return ht_.begin(); }
|
|
|
|
|
const_iterator begin() const noexcept { return ht_.begin(); } // 返回底层 hashtable 的 begin 常量迭代器
|
|
|
|
|
// 返回指向最后一个元素的迭代器
|
|
|
|
|
iterator end() noexcept { return ht_.end(); }
|
|
|
|
|
iterator end() noexcept { return ht_.end(); } // 返回底层 hashtable 的 end 迭代器
|
|
|
|
|
// 返回指向最后一个元素的常量迭代器
|
|
|
|
|
const_iterator end() const noexcept { return ht_.end(); }
|
|
|
|
|
const_iterator end() const noexcept { return ht_.end(); } // 返回底层 hashtable 的 end 常量迭代器
|
|
|
|
|
|
|
|
|
|
// 返回指向第一个元素的常量迭代器(cbegin 和 cend 是 C++11 新增的,用于明确表达“常量迭代器”)
|
|
|
|
|
const_iterator cbegin() const noexcept { return ht_.cbegin(); }
|
|
|
|
|
const_iterator cend() const noexcept { return ht_.cend(); }
|
|
|
|
|
const_iterator cbegin() const noexcept { return ht_.cbegin(); } // 返回底层 hashtable 的 cbegin 常量迭代器
|
|
|
|
|
const_iterator cend() const noexcept { return ht_.cend(); } // 返回底层 hashtable 的 cend 常量迭代器
|
|
|
|
|
|
|
|
|
|
// 容量相关
|
|
|
|
|
// 检查容器是否为空
|
|
|
|
|
bool empty() const noexcept { return ht_.empty(); }
|
|
|
|
|
bool empty() const noexcept { return ht_.empty(); } // 返回底层 hashtable 是否为空
|
|
|
|
|
// 返回容器中的元素数量
|
|
|
|
|
size_type size() const noexcept { return ht_.size(); }
|
|
|
|
|
size_type size() const noexcept { return ht_.size(); } // 返回底层 hashtable 的元素数量
|
|
|
|
|
// 返回容器能容纳的最大元素数量
|
|
|
|
|
size_type max_size() const noexcept { return ht_.max_size(); }
|
|
|
|
|
size_type max_size() const noexcept { return ht_.max_size(); } // 返回底层 hashtable 的最大元素数量
|
|
|
|
|
|
|
|
|
|
// 修改容器操作
|
|
|
|
|
|
|
|
|
@ -553,161 +544,134 @@ size_type max_size() const noexcept { return ht_.max_size(); }
|
|
|
|
|
// 就地构造元素,返回插入的迭代器
|
|
|
|
|
template <class ...Args>
|
|
|
|
|
iterator emplace(Args&& ...args) {
|
|
|
|
|
return ht_.emplace_multi(mystl::forward<Args>(args)...);
|
|
|
|
|
return ht_.emplace_multi(mystl::forward<Args>(args)...); // 就地构造元素并插入
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 就地构造元素,并使用 hint 提示插入位置,返回插入的迭代器
|
|
|
|
|
template <class ...Args>
|
|
|
|
|
iterator emplace_hint(const_iterator hint, Args&& ...args) {
|
|
|
|
|
return ht_.emplace_multi_use_hint(hint, mystl::forward<Args>(args)...);
|
|
|
|
|
return ht_.emplace_multi_use_hint(hint, mystl::forward<Args>(args)...); // 使用 hint 提示插入位置并就地构造元素
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// insert
|
|
|
|
|
// 插入元素,返回插入的迭代器
|
|
|
|
|
iterator insert(const value_type & value) {
|
|
|
|
|
return ht_.insert_multi(value);
|
|
|
|
|
return ht_.insert_multi(value); // 插入元素
|
|
|
|
|
}
|
|
|
|
|
// 插入移动构造的元素
|
|
|
|
|
iterator insert(value_type && value) {
|
|
|
|
|
return ht_.emplace_multi(mystl::move(value));
|
|
|
|
|
return ht_.emplace_multi(mystl::move(value)); // 插入移动构造的元素
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 使用 hint 提示插入位置
|
|
|
|
|
iterator insert(const_iterator hint, const value_type & value) {
|
|
|
|
|
return ht_.insert_multi_use_hint(hint, value);
|
|
|
|
|
return ht_.insert_multi_use_hint(hint, value); // 使用 hint 提示插入位置
|
|
|
|
|
}
|
|
|
|
|
// 使用 hint 提示插入位置,并插入移动构造的元素
|
|
|
|
|
iterator insert(const_iterator hint, value_type && value) {
|
|
|
|
|
return ht_.emplace_multi_use_hint(hint, mystl::move(value));
|
|
|
|
|
return ht_.emplace_multi_use_hint(hint, mystl::move(value)); // 使用 hint 提示插入位置并插入移动构造的元素
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 从迭代器范围插入元素
|
|
|
|
|
template <class InputIterator>
|
|
|
|
|
void insert(InputIterator first, InputIterator last) {
|
|
|
|
|
ht_.insert_multi(first, last);
|
|
|
|
|
ht_.insert_multi(first, last); // 插入范围内的所有元素
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// erase / clear
|
|
|
|
|
// 删除指定迭代器位置的元素
|
|
|
|
|
void erase(iterator it) {
|
|
|
|
|
ht_.erase(it);
|
|
|
|
|
ht_.erase(it); // 删除指定迭代器位置的元素
|
|
|
|
|
}
|
|
|
|
|
// 删除指定范围的元素
|
|
|
|
|
void erase(iterator first, iterator last) {
|
|
|
|
|
ht_.erase(first, last);
|
|
|
|
|
ht_.erase(first, last); // 删除指定范围的元素
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 删除指定键的所有元素,并返回被删除的元素数量
|
|
|
|
|
size_type erase(const key_type & key) {
|
|
|
|
|
return ht_.erase_multi(key);
|
|
|
|
|
return ht_.erase_multi(key); // 删除指定键的所有元素
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 清空容器
|
|
|
|
|
void clear() {
|
|
|
|
|
ht_.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 交换两个 unordered_multimap 对象的内容
|
|
|
|
|
void swap(unordered_multimap& other) noexcept {
|
|
|
|
|
ht_.swap(other.ht_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查找相关
|
|
|
|
|
// 返回指定键的元素数量
|
|
|
|
|
size_type count(const key_type& key) const {
|
|
|
|
|
return ht_.count(key);
|
|
|
|
|
ht_.clear(); // 清空底层 hashtable
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查找元素
|
|
|
|
|
iterator find(const key_type& key) {
|
|
|
|
|
return ht_.find(key);
|
|
|
|
|
}
|
|
|
|
|
const_iterator find(const key_type& key) const {
|
|
|
|
|
return ht_.find(key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 返回给定键的元素范围
|
|
|
|
|
pair<iterator, iterator> equal_range(const key_type& key) {
|
|
|
|
|
return ht_.equal_range_multi(key);
|
|
|
|
|
}
|
|
|
|
|
pair<const_iterator, const_iterator> equal_range(const key_type& key) const {
|
|
|
|
|
return ht_.equal_range_multi(key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 桶接口
|
|
|
|
|
|
|
|
|
|
// 返回指定桶的本地迭代器
|
|
|
|
|
local_iterator begin(size_type n) noexcept {
|
|
|
|
|
return ht_.begin(n);
|
|
|
|
|
return ht_.begin(n); // 调用底层 hashtable 的 begin 方法,返回指定桶的本地迭代器
|
|
|
|
|
}
|
|
|
|
|
const_local_iterator begin(size_type n) const noexcept {
|
|
|
|
|
return ht_.begin(n);
|
|
|
|
|
return ht_.begin(n); // 调用底层 hashtable 的 begin 方法,返回指定桶的本地常量迭代器
|
|
|
|
|
}
|
|
|
|
|
const_local_iterator cbegin(size_type n) const noexcept {
|
|
|
|
|
return ht_.cbegin(n);
|
|
|
|
|
return ht_.cbegin(n); // 调用底层 hashtable 的 cbegin 方法,返回指定桶的本地常量迭代器
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 返回指定桶的本地迭代器
|
|
|
|
|
local_iterator end(size_type n) noexcept {
|
|
|
|
|
return ht_.end(n);
|
|
|
|
|
return ht_.end(n); // 调用底层 hashtable 的 end 方法,返回指定桶的本地迭代器
|
|
|
|
|
}
|
|
|
|
|
const_local_iterator end(size_type n) const noexcept {
|
|
|
|
|
return ht_.end(n);
|
|
|
|
|
return ht_.end(n); // 调用底层 hashtable 的 end 方法,返回指定桶的本地常量迭代器
|
|
|
|
|
}
|
|
|
|
|
const_local_iterator cend(size_type n) const noexcept {
|
|
|
|
|
return ht_.cend(n);
|
|
|
|
|
return ht_.cend(n); // 调用底层 hashtable 的 cend 方法,返回指定桶的本地常量迭代器
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 返回桶的数量
|
|
|
|
|
size_type bucket_count() const noexcept {
|
|
|
|
|
return ht_.bucket_count();
|
|
|
|
|
return ht_.bucket_count(); // 调用底层 hashtable 的 bucket_count 方法,返回桶的数量
|
|
|
|
|
}
|
|
|
|
|
size_type max_bucket_count() const noexcept {
|
|
|
|
|
return ht_.max_bucket_count();
|
|
|
|
|
return ht_.max_bucket_count(); // 调用底层 hashtable 的 max_bucket_count 方法,返回最大桶数量
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 返回指定桶的大小
|
|
|
|
|
size_type bucket_size(size_type n) const noexcept {
|
|
|
|
|
return ht_.bucket_size(n);
|
|
|
|
|
return ht_.bucket_size(n); // 调用底层 hashtable 的 bucket_size 方法,返回指定桶的大小
|
|
|
|
|
}
|
|
|
|
|
// 返回给定键的元素所在的桶编号
|
|
|
|
|
size_type bucket(const key_type& key) const {
|
|
|
|
|
return ht_.bucket(key);
|
|
|
|
|
return ht_.bucket(key); // 调用底层 hashtable 的 bucket 方法,返回给定键的元素所在的桶编号
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 哈希策略
|
|
|
|
|
|
|
|
|
|
// 返回当前负载因子
|
|
|
|
|
float load_factor() const noexcept {
|
|
|
|
|
return ht_.load_factor();
|
|
|
|
|
return ht_.load_factor(); // 调用底层 hashtable 的 load_factor 方法,返回当前负载因子
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 返回最大负载因子
|
|
|
|
|
float max_load_factor() const noexcept {
|
|
|
|
|
return ht_.max_load_factor();
|
|
|
|
|
return ht_.max_load_factor(); // 调用底层 hashtable 的 max_load_factor 方法,返回最大负载因子
|
|
|
|
|
}
|
|
|
|
|
// 设置最大负载因子
|
|
|
|
|
void max_load_factor(float ml) {
|
|
|
|
|
ht_.max_load_factor(ml);
|
|
|
|
|
ht_.max_load_factor(ml); // 调用底层 hashtable 的 max_load_factor 方法,设置最大负载因子
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 重新哈希,调整桶的数量
|
|
|
|
|
void rehash(size_type count) {
|
|
|
|
|
ht_.rehash(count);
|
|
|
|
|
ht_.rehash(count); // 调用底层 hashtable 的 rehash 方法,重新哈希并调整桶的数量
|
|
|
|
|
}
|
|
|
|
|
// 调整桶的数量以至少容纳指定数量的元素
|
|
|
|
|
void reserve(size_type count) {
|
|
|
|
|
ht_.reserve(count);
|
|
|
|
|
ht_.reserve(count); // 调用底层 hashtable 的 reserve 方法,调整桶的数量以至少容纳指定数量的元素
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 返回哈希函数
|
|
|
|
|
hasher hash_fcn() const {
|
|
|
|
|
return ht_.hash_fcn();
|
|
|
|
|
return ht_.hash_fcn(); // 调用底层 hashtable 的 hash_fcn 方法,返回哈希函数
|
|
|
|
|
}
|
|
|
|
|
// 返回键比较函数
|
|
|
|
|
key_equal key_eq() const {
|
|
|
|
|
return ht_.key_eq();
|
|
|
|
|
return ht_.key_eq(); // 调用底层 hashtable 的 key_eq 方法,返回键比较函数
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 友元函数,重载比较操作符 ==
|
|
|
|
|
// 比较两个 unordered_multimap 对象是否相等
|
|
|
|
|
friend bool operator==(const unordered_multimap& lhs, const unordered_multimap& rhs)
|
|
|
|
@ -757,4 +721,3 @@ void swap(unordered_multimap<Key, T, Hash, KeyEqual>& lhs,
|
|
|
|
|
} // namespace mystl 结束命名空间 mystl
|
|
|
|
|
|
|
|
|
|
#endif // !MYTINYSTL_UNORDERED_MAP_H_ 结束头文件保护
|
|
|
|
|
|
|
|
|
|