以上注释详细解释了 `unordered_set` 和 `unordered_multiset` 这两个基于哈希表实现的容器类。这些类提供了构造、复制、移动、迭代器操作、容量查询、元素插入与删除、查找以及桶管理等功能。它们允许开发者在不保证元素顺序的情况下,高效地进行元素的存储和检索,其中 `unordered_set` 不允许键值重复,而 `unordered_multiset` 允许键值重复。此外,还包括了比较操作符的重载和 `swap` 函数的特化,以支持容器间的比较和数据交换。这些容器的设计遵循异常安全保证,其中 `emplace`、`emplace_hint` 和 `insert` 操作提供强异常安全保证。

main
sunjiawei 8 months ago
parent ec89b4253a
commit 5e94302b07

@ -1,79 +1,5 @@
#ifndef MYTINYSTL_UNORDERED_SET_H_ for (; first != last; ++first)
#define MYTINYSTL_UNORDERED_SET_H_ ht_.insert_unique_noresize(*first);
// 这个头文件包含两个模板类 unordered_set 和 unordered_multiset
// 功能与用法与 set 和 multiset 类似,不同的是使用 hashtable 作为底层实现机制,容器中的元素不会自动排序
// notes:
//
// 异常保证:
// mystl::unordered_set<Key> / mystl::unordered_multiset<Key> 满足基本异常保证,对以下等函数做强异常安全保证:
// * emplace
// * emplace_hint
// * insert
#include "hashtable.h"
namespace mystl
{
// 模板类 unordered_set键值不允许重复
// 参数一代表键值类型,参数二代表哈希函数,缺省使用 mystl::hash
// 参数三代表键值比较方式,缺省使用 mystl::equal_to
template <class Key, class Hash = mystl::hash<Key>, class KeyEqual = mystl::equal_to<Key>>
class unordered_set
{
private:
// 使用 hashtable 作为底层机制
typedef hashtable<Key, Hash, KeyEqual> base_type;
base_type ht_;
public:
// 使用 hashtable 的型别
typedef typename base_type::allocator_type allocator_type;
typedef typename base_type::key_type key_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::const_iterator iterator;
typedef typename base_type::const_iterator const_iterator;
typedef typename base_type::const_local_iterator local_iterator;
typedef typename base_type::const_local_iterator const_local_iterator;
allocator_type get_allocator() const { return ht_.get_allocator(); }
public:
// 构造、复制、移动函数
unordered_set()
:ht_(100, Hash(), KeyEqual())
{
}
explicit unordered_set(size_type bucket_count,
const Hash& hash = Hash(),
const KeyEqual& equal = KeyEqual())
:ht_(bucket_count, hash, equal)
{
}
template <class InputIterator>
unordered_set(InputIterator first, InputIterator last,
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)
{
for (; first != last; ++first)
ht_.insert_unique_noresize(*first);
} }
unordered_set(std::initializer_list<value_type> ilist, unordered_set(std::initializer_list<value_type> ilist,
@ -120,18 +46,30 @@ public:
// 迭代器相关 // 迭代器相关
iterator begin() noexcept iterator begin() noexcept
{ return ht_.begin(); } {
return ht_.begin();
}
const_iterator begin() const noexcept const_iterator begin() const noexcept
{ return ht_.begin(); } {
return ht_.begin();
}
iterator end() noexcept iterator end() noexcept
{ return ht_.end(); } {
return ht_.end();
}
const_iterator end() const noexcept const_iterator end() const noexcept
{ return ht_.end(); } {
return ht_.end();
}
const_iterator cbegin() const noexcept const_iterator cbegin() const noexcept
{ return ht_.cbegin(); } {
return ht_.cbegin();
}
const_iterator cend() const noexcept const_iterator cend() const noexcept
{ return ht_.cend(); } {
return ht_.cend();
}
// 容量相关 // 容量相关
@ -145,104 +83,182 @@ public:
template <class ...Args> template <class ...Args>
pair<iterator, bool> emplace(Args&& ...args) pair<iterator, bool> emplace(Args&& ...args)
{ return ht_.emplace_unique(mystl::forward<Args>(args)...); } {
return ht_.emplace_unique(mystl::forward<Args>(args)...);
}
template <class ...Args> template <class ...Args>
iterator emplace_hint(const_iterator hint, Args&& ...args) iterator emplace_hint(const_iterator hint, Args&& ...args)
{ return ht_.emplace_unique_use_hint(hint, mystl::forward<Args>(args)...); } {
return ht_.emplace_unique_use_hint(hint, mystl::forward<Args>(args)...);
}
// insert // insert
pair<iterator, bool> insert(const value_type& value) pair<iterator, bool> insert(const value_type & value)
{ return ht_.insert_unique(value); } {
pair<iterator, bool> insert(value_type&& value) return ht_.insert_unique(value);
{ return ht_.emplace_unique(mystl::move(value)); } }
pair<iterator, bool> insert(value_type && value)
{
return ht_.emplace_unique(mystl::move(value));
}
iterator insert(const_iterator hint, const value_type& value) iterator insert(const_iterator hint, const value_type & value)
{ return ht_.insert_unique_use_hint(hint, value); } {
iterator insert(const_iterator hint, value_type&& value) return ht_.insert_unique_use_hint(hint, value);
{ return ht_.emplace_unique_use_hint(hint, mystl::move(value)); } }
iterator insert(const_iterator hint, value_type && value)
{
return ht_.emplace_unique_use_hint(hint, mystl::move(value));
}
template <class InputIterator> template <class InputIterator>
void insert(InputIterator first, InputIterator last) void insert(InputIterator first, InputIterator last)
{ ht_.insert_unique(first, last); } {
ht_.insert_unique(first, last);
}
// erase / clear // erase / clear
void erase(iterator it) void erase(iterator it)
{ ht_.erase(it); } {
ht_.erase(it);
}
void erase(iterator first, iterator last) void erase(iterator first, iterator last)
{ ht_.erase(first, last); } {
ht_.erase(first, last);
}
size_type erase(const key_type& key) size_type erase(const key_type & key)
{ return ht_.erase_unique(key); } {
return ht_.erase_unique(key);
}
void clear() void clear()
{ ht_.clear(); } {
ht_.clear();
}
void swap(unordered_set& other) noexcept void swap(unordered_set & other) noexcept
{ ht_.swap(other.ht_); } {
ht_.swap(other.ht_);
}
// 查找相关 // 查找相关
size_type count(const key_type& key) const size_type count(const key_type & key) const
{ return ht_.count(key); } {
return ht_.count(key);
}
iterator find(const key_type& key) iterator find(const key_type & key)
{ return ht_.find(key); } {
const_iterator find(const key_type& key) const return ht_.find(key);
{ return ht_.find(key); } }
```c+ +
// 查找相关(续)
// 在 const 版本中查找指定键的迭代器
const_iterator find(const key_type & key) const
{
return ht_.find(key);
}
// 返回一个迭代器对,表示下界和上界,用于查找指定键的范围
pair<iterator, iterator> equal_range(const key_type& key) pair<iterator, iterator> equal_range(const key_type& key)
{ return ht_.equal_range_unique(key); } {
return ht_.equal_range_unique(key);
}
// 返回一个常量迭代器对表示下界和上界用于查找指定键的范围const 版本)
pair<const_iterator, const_iterator> equal_range(const key_type& key) const pair<const_iterator, const_iterator> equal_range(const key_type& key) const
{ return ht_.equal_range_unique(key); } {
return ht_.equal_range_unique(key);
}
// bucket interface // bucket interface
// 返回指定桶的本地迭代器
local_iterator begin(size_type n) noexcept local_iterator begin(size_type n) noexcept
{ return ht_.begin(n); } {
return ht_.begin(n);
}
// 返回指定桶的常量本地迭代器const 版本)
const_local_iterator begin(size_type n) const noexcept const_local_iterator begin(size_type n) const noexcept
{ return ht_.begin(n); } {
return ht_.begin(n);
}
// 返回指定桶的常量本地迭代器const 版本C++11 范围for循环使用
const_local_iterator cbegin(size_type n) const noexcept const_local_iterator cbegin(size_type n) const noexcept
{ return ht_.cbegin(n); } {
return ht_.cbegin(n);
}
// 返回指定桶的结束本地迭代器
local_iterator end(size_type n) noexcept local_iterator end(size_type n) noexcept
{ return ht_.end(n); } {
return ht_.end(n);
}
// 返回指定桶的常量本地迭代器const 版本)
const_local_iterator end(size_type n) const noexcept const_local_iterator end(size_type n) const noexcept
{ return ht_.end(n); } {
return ht_.end(n);
}
// 返回指定桶的常量本地迭代器const 版本C++11 范围for循环使用
const_local_iterator cend(size_type n) const noexcept const_local_iterator cend(size_type n) const noexcept
{ return ht_.cend(n); } {
return ht_.cend(n);
}
// 返回桶的数量
size_type bucket_count() const noexcept size_type bucket_count() const noexcept
{ return ht_.bucket_count(); } {
return ht_.bucket_count();
}
// 返回最大桶的数量
size_type max_bucket_count() const noexcept size_type max_bucket_count() const noexcept
{ return ht_.max_bucket_count(); } {
return ht_.max_bucket_count();
}
// 返回指定桶的大小
size_type bucket_size(size_type n) const noexcept size_type bucket_size(size_type n) const noexcept
{ return ht_.bucket_size(n); } {
return ht_.bucket_size(n);
}
// 返回指定键所在的桶编号
size_type bucket(const key_type& key) const size_type bucket(const key_type& key) const
{ return ht_.bucket(key); } {
return ht_.bucket(key);
}
// hash policy // hash policy
// 返回当前负载因子
float load_factor() const noexcept { return ht_.load_factor(); } float load_factor() const noexcept { return ht_.load_factor(); }
// 返回最大负载因子
float max_load_factor() const noexcept { return ht_.max_load_factor(); } float max_load_factor() const noexcept { return ht_.max_load_factor(); }
// 设置最大负载因子
void max_load_factor(float ml) { ht_.max_load_factor(ml); } void max_load_factor(float ml) { ht_.max_load_factor(ml); }
// 重新哈希,桶的数量至少为 count
void rehash(size_type count) { ht_.rehash(count); } void rehash(size_type count) { ht_.rehash(count); }
// 重新分配桶,使得桶的数量至少为 count
void reserve(size_type count) { ht_.reserve(count); } void reserve(size_type count) { ht_.reserve(count); }
// 返回哈希函数
hasher hash_fcn() const { return ht_.hash_fcn(); } hasher hash_fcn() const { return ht_.hash_fcn(); }
// 返回键比较函数
key_equal key_eq() const { return ht_.key_eq(); } key_equal key_eq() const { return ht_.key_eq(); }
public: public:
// 友元函数,用于比较两个 unordered_set 是否相等
friend bool operator==(const unordered_set& lhs, const unordered_set& rhs) friend bool operator==(const unordered_set& lhs, const unordered_set& rhs)
{ {
return lhs.ht_.equal_range_unique(rhs.ht_); return lhs.ht_.equal_range_unique(rhs.ht_);
} }
// 友元函数,用于比较两个 unordered_set 是否不相等
friend bool operator!=(const unordered_set& lhs, const unordered_set& rhs) friend bool operator!=(const unordered_set& lhs, const unordered_set& rhs)
{ {
return !lhs.ht_.equal_range_unique(rhs.ht_); return !lhs.ht_.equal_range_unique(rhs.ht_);
@ -287,34 +303,39 @@ private:
public: public:
// 使用 hashtable 的型别 // 使用 hashtable 的型别
typedef typename base_type::allocator_type allocator_type; typedef typename base_type::allocator_type allocator_type; // 存储分配器类型
typedef typename base_type::key_type key_type; typedef typename base_type::key_type key_type; // 键类型
typedef typename base_type::value_type value_type; typedef typename base_type::value_type value_type; // 值类型,与键类型相同
typedef typename base_type::hasher hasher; typedef typename base_type::hasher hasher; // 哈希函数类型
typedef typename base_type::key_equal key_equal; typedef typename base_type::key_equal key_equal; // 键比较函数类型
typedef typename base_type::size_type size_type; typedef typename base_type::size_type size_type; // 容器大小类型
typedef typename base_type::difference_type difference_type; typedef typename base_type::difference_type difference_type;// 差值类型
typedef typename base_type::pointer pointer; typedef typename base_type::pointer pointer; // 指针类型
typedef typename base_type::const_pointer const_pointer; typedef typename base_type::const_pointer const_pointer; // 常量指针类型
typedef typename base_type::reference reference; typedef typename base_type::reference reference; // 引用类型
typedef typename base_type::const_reference const_reference; typedef typename base_type::const_reference const_reference;// 常量引用类型
typedef typename base_type::const_iterator iterator; typedef typename base_type::const_iterator iterator; // 迭代器类型
typedef typename base_type::const_iterator const_iterator; typedef typename base_type::const_iterator const_iterator; // 常量迭代器类型
typedef typename base_type::const_local_iterator local_iterator; typedef typename base_type::const_local_iterator local_iterator; // 本地迭代器类型
typedef typename base_type::const_local_iterator const_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(); }
```
```c+ +
public: public:
// 构造、复制、移动函数 // 构造、复制、移动函数
// 默认构造函数初始化桶的数量为100使用默认的哈希函数和键比较函数
unordered_multiset() unordered_multiset()
:ht_(100, Hash(), KeyEqual()) :ht_(100, Hash(), KeyEqual())
{ {
} }
// 构造函数,指定桶的数量,哈希函数和键比较函数
explicit unordered_multiset(size_type bucket_count, explicit unordered_multiset(size_type bucket_count,
const Hash& hash = Hash(), const Hash& hash = Hash(),
const KeyEqual& equal = KeyEqual()) const KeyEqual& equal = KeyEqual())
@ -322,6 +343,7 @@ public:
{ {
} }
// 构造函数,从迭代器范围构造,指定桶的数量,哈希函数和键比较函数
template <class InputIterator> template <class InputIterator>
unordered_multiset(InputIterator first, InputIterator last, unordered_multiset(InputIterator first, InputIterator last,
const size_type bucket_count = 100, const size_type bucket_count = 100,
@ -329,40 +351,50 @@ public:
const KeyEqual& equal = KeyEqual()) 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)
{ {
// 插入元素,不重新哈希
for (; first != last; ++first) for (; first != last; ++first)
ht_.insert_multi_noresize(*first); ht_.insert_multi_noresize(*first);
} }
// 构造函数,从初始化列表构造,指定桶的数量,哈希函数和键比较函数
unordered_multiset(std::initializer_list<value_type> ilist, unordered_multiset(std::initializer_list<value_type> ilist,
const size_type bucket_count = 100, const size_type bucket_count = 100,
const Hash& hash = Hash(), const Hash& hash = Hash(),
const KeyEqual& equal = KeyEqual()) 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)
{ {
// 插入元素,不重新哈希
for (auto first = ilist.begin(), last = ilist.end(); first != last; ++first) for (auto first = ilist.begin(), last = ilist.end(); first != last; ++first)
ht_.insert_multi_noresize(*first); ht_.insert_multi_noresize(*first);
} }
// 复制构造函数
unordered_multiset(const unordered_multiset& rhs) unordered_multiset(const unordered_multiset& rhs)
:ht_(rhs.ht_) :ht_(rhs.ht_)
{ {
} }
// 移动构造函数
unordered_multiset(unordered_multiset&& rhs) noexcept unordered_multiset(unordered_multiset&& rhs) noexcept
: ht_(mystl::move(rhs.ht_)) : ht_(mystl::move(rhs.ht_))
{ {
} }
// 复制赋值运算符
unordered_multiset& operator=(const unordered_multiset& rhs) unordered_multiset& operator=(const unordered_multiset& rhs)
{ {
ht_ = rhs.ht_; ht_ = rhs.ht_;
return *this; return *this;
} }
// 移动赋值运算符
unordered_multiset& operator=(unordered_multiset&& rhs) unordered_multiset& operator=(unordered_multiset&& rhs)
{ {
ht_ = mystl::move(rhs.ht_); ht_ = mystl::move(rhs.ht_);
return *this; return *this;
} }
// 从初始化列表赋值
unordered_multiset& operator=(std::initializer_list<value_type> ilist) unordered_multiset& operator=(std::initializer_list<value_type> ilist)
{ {
ht_.clear(); ht_.clear();
@ -372,134 +404,246 @@ public:
return *this; return *this;
} }
// 析构函数,使用默认的
~unordered_multiset() = default; ~unordered_multiset() = default;
// 迭代器相关 // 迭代器相关
// 返回指向第一个元素的迭代器
iterator begin() noexcept iterator begin() noexcept
{ return ht_.begin(); } {
return ht_.begin();
}
// 返回指向第一个元素的常量迭代器const 版本)
const_iterator begin() const noexcept const_iterator begin() const noexcept
{ return ht_.begin(); } {
return ht_.begin();
}
// 返回指向最后一个元素的迭代器
iterator end() noexcept iterator end() noexcept
{ return ht_.end(); } {
return ht_.end();
}
// 返回指向最后一个元素的常量迭代器const 版本)
const_iterator end() const noexcept const_iterator end() const noexcept
{ return ht_.end(); } {
return ht_.end();
}
// 返回指向第一个元素的常量迭代器const 版本C++11 范围for循环使用
const_iterator cbegin() const noexcept const_iterator cbegin() const noexcept
{ return ht_.cbegin(); } {
return ht_.cbegin();
}
// 返回指向最后一个元素的常量迭代器const 版本C++11 范围for循环使用
const_iterator cend() const noexcept const_iterator cend() const noexcept
{ return ht_.cend(); } {
return ht_.cend();
}
// 容量相关 // 容量相关
// 检查容器是否为空
bool empty() const noexcept { return ht_.empty(); } bool empty() const noexcept { return ht_.empty(); }
// 返回容器大小
size_type size() const noexcept { return ht_.size(); } size_type size() const noexcept { return ht_.size(); }
// 返回容器最大可能大小
size_type max_size() const noexcept { return ht_.max_size(); } size_type max_size() const noexcept { return ht_.max_size(); }
// 修改容器相关 // 修改容器相关
// emplace / emplace_hint // emplace / emplace_hint
// 就地构造元素并插入
template <class ...Args> template <class ...Args>
iterator emplace(Args&& ...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> template <class ...Args>
iterator emplace_hint(const_iterator hint, Args&& ...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)...);
}
// insert // insert
iterator insert(const value_type& value) // 插入元素
{ return ht_.insert_multi(value); } iterator insert(const value_type & value)
iterator insert(value_type&& value) {
{ return ht_.emplace_multi(mystl::move(value)); } return ht_.insert_multi(value);
}
// 插入移动构造的元素
iterator insert(value_type && value)
{
return ht_.emplace_multi(mystl::move(value));
}
iterator insert(const_iterator hint, const value_type& value) // 插入元素,使用 hint 提示位置
{ return ht_.insert_multi_use_hint(hint, value); } iterator insert(const_iterator hint, const value_type & value)
iterator insert(const_iterator hint, value_type&& value) {
{ return ht_.emplace_multi_use_hint(hint, mystl::move(value)); } return ht_.insert_multi_use_hint(hint, value);
}
// 插入移动构造的元素,使用 hint 提示位置
iterator insert(const_iterator hint, value_type && value)
{
return ht_.emplace_multi_use_hint(hint, mystl::move(value));
}
// 插入迭代器范围的元素
template <class InputIterator> template <class InputIterator>
void insert(InputIterator first, InputIterator last) void insert(InputIterator first, InputIterator last)
{ ht_.insert_multi(first, last); } {
ht_.insert_multi(first, last);
}
// erase / clear // erase / clear
// 擦除指定位置的元素
void erase(iterator it) void erase(iterator it)
{ ht_.erase(it); } {
ht_.erase(it);
}
// 擦除指定范围的元素
void erase(iterator first, iterator last) 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); } size_type erase(const key_type & key)
{
return ht_.erase_multi(key);
}
// 清空容器
void clear() void clear()
{ ht_.clear(); } {
ht_.clear();
}
void swap(unordered_multiset& other) noexcept // 交换两个 unordered_multiset 的内容
{ ht_.swap(other.ht_); } void swap(unordered_multiset & other) noexcept
{
ht_.swap(other.ht_);
}
// 查找相关 // 查找相关
size_type count(const key_type& key) const // 返回指定键出现的次数
{ return ht_.count(key); } size_type count(const key_type & key) const
{
return ht_.count(key);
}
iterator find(const key_type& key) // 查找指定键的迭代器
{ return ht_.find(key); } iterator find(const key_type & key)
const_iterator find(const key_type& key) const {
{ return ht_.find(key); } return ht_.find(key);
}
// 查找指定键的常量迭代器const 版本)
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<iterator, iterator> equal_range(const key_type & key)
pair<const_iterator, const_iterator> equal_range(const key_type& key) const {
{ return ht_.equal_range_multi(key); } return ht_.equal_range_multi(key);
}
// 返回一个常量迭代器对表示下界和上界用于查找指定键的范围const 版本)
pair<const_iterator, const_iterator> equal_range(const key_type & key) const
{
return ht_.equal_range_multi(key);
}
```
// bucket interface // bucket interface
// 返回指定桶的本地迭代器
local_iterator begin(size_type n) noexcept local_iterator begin(size_type n) noexcept
{ return ht_.begin(n); } {
return ht_.begin(n);
}
// 返回指定桶的常量本地迭代器const 版本)
const_local_iterator begin(size_type n) const noexcept const_local_iterator begin(size_type n) const noexcept
{ return ht_.begin(n); } {
return ht_.begin(n);
}
// 返回指定桶的常量本地迭代器const 版本C++11 范围for循环使用
const_local_iterator cbegin(size_type n) const noexcept const_local_iterator cbegin(size_type n) const noexcept
{ return ht_.cbegin(n); } {
return ht_.cbegin(n);
}
// 返回指定桶的结束本地迭代器
local_iterator end(size_type n) noexcept local_iterator end(size_type n) noexcept
{ return ht_.end(n); } {
return ht_.end(n);
}
// 返回指定桶的常量本地迭代器const 版本)
const_local_iterator end(size_type n) const noexcept const_local_iterator end(size_type n) const noexcept
{ return ht_.end(n); } {
return ht_.end(n);
}
// 返回指定桶的常量本地迭代器const 版本C++11 范围for循环使用
const_local_iterator cend(size_type n) const noexcept const_local_iterator cend(size_type n) const noexcept
{ return ht_.cend(n); } {
return ht_.cend(n);
}
// 返回桶的数量
size_type bucket_count() const noexcept size_type bucket_count() const noexcept
{ return ht_.bucket_count(); } {
return ht_.bucket_count();
}
// 返回最大桶的数量
size_type max_bucket_count() const noexcept size_type max_bucket_count() const noexcept
{ return ht_.max_bucket_count(); } {
return ht_.max_bucket_count();
}
// 返回指定桶的大小
size_type bucket_size(size_type n) const noexcept size_type bucket_size(size_type n) const noexcept
{ return ht_.bucket_size(n); } {
return ht_.bucket_size(n);
}
// 返回指定键所在的桶编号
size_type bucket(const key_type& key) const size_type bucket(const key_type& key) const
{ return ht_.bucket(key); } {
return ht_.bucket(key);
}
// hash policy // hash policy
// 返回当前负载因子
float load_factor() const noexcept { return ht_.load_factor(); } float load_factor() const noexcept { return ht_.load_factor(); }
// 返回最大负载因子
float max_load_factor() const noexcept { return ht_.max_load_factor(); } float max_load_factor() const noexcept { return ht_.max_load_factor(); }
// 设置最大负载因子
void max_load_factor(float ml) { ht_.max_load_factor(ml); } void max_load_factor(float ml) { ht_.max_load_factor(ml); }
// 重新哈希,桶的数量至少为 count
void rehash(size_type count) { ht_.rehash(count); } void rehash(size_type count) { ht_.rehash(count); }
// 重新分配桶,使得桶的数量至少为 count
void reserve(size_type count) { ht_.reserve(count); } void reserve(size_type count) { ht_.reserve(count); }
// 返回哈希函数
hasher hash_fcn() const { return ht_.hash_fcn(); } hasher hash_fcn() const { return ht_.hash_fcn(); }
// 返回键比较函数
key_equal key_eq() const { return ht_.key_eq(); } key_equal key_eq() const { return ht_.key_eq(); }
public: public:
// 友元函数,用于比较两个 unordered_multiset 是否相等
friend bool operator==(const unordered_multiset& lhs, const unordered_multiset& rhs) friend bool operator==(const unordered_multiset& lhs, const unordered_multiset& rhs)
{ {
return lhs.ht_.equal_range_multi(rhs.ht_); return lhs.ht_.equal_range_multi(rhs.ht_);
} }
// 友元函数,用于比较两个 unordered_multiset 是否不相等
friend bool operator!=(const unordered_multiset& lhs, const unordered_multiset& rhs) friend bool operator!=(const unordered_multiset& lhs, const unordered_multiset& rhs)
{ {
return !lhs.ht_.equal_range_multi(rhs.ht_); return !lhs.ht_.equal_range_multi(rhs.ht_);
@ -531,4 +675,3 @@ void swap(unordered_multiset<Key, Hash, KeyEqual>& lhs,
} // namespace mystl } // namespace mystl
#endif // !MYTINYSTL_UNORDERED_SET_H_ #endif // !MYTINYSTL_UNORDERED_SET_H_

Loading…
Cancel
Save