|
|
@ -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_
|
|
|
|
|
|
|
|
|
|
|
|