diff --git a/src/MyTinySTL-master/MyTinySTL/unordered_map.h b/src/MyTinySTL-master/MyTinySTL/unordered_map.h index 4cf0e23..a38c629 100644 --- a/src/MyTinySTL-master/MyTinySTL/unordered_map.h +++ b/src/MyTinySTL-master/MyTinySTL/unordered_map.h @@ -1,723 +1,741 @@ -#ifndef MYTINYSTL_UNORDERED_MAP_H_ // 预处理指令,防止头文件被重复包含 -#define MYTINYSTL_UNORDERED_MAP_H_ - -// 这个头文件包含两个模板类 unordered_map 和 unordered_multimap -// 功能与用法与 map 和 multimap 类似,不同的是使用 hashtable 作为底层实现机制,容器内的元素不会自动排序 - -// notes: -// -// 异常保证: -// mystl::unordered_map / mystl::unordered_multimap 满足基本异常保证,对以下等函数做强异常安全保证: -// * emplace -// * emplace_hint -// * insert - -#include "hashtable.h" // 包含自定义的 hashtable 头文件 - -namespace mystl // 命名空间 mystl,用于封装自定义的 STL 组件 -{ - - // 模板类 unordered_map,键值不允许重复 - // 参数一代表键值类型,参数二代表实值类型,参数三代表哈希函数,缺省使用 mystl::hash - // 参数四代表键值比较方式,缺省使用 mystl::equal_to - template , class KeyEqual = mystl::equal_to> - class unordered_map - { - private: - // 使用 hashtable 作为底层机制 - typedef hashtable, Hash, KeyEqual> base_type; - 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; // 常量本地迭代器类型 - - allocator_type get_allocator() const { return ht_.get_allocator(); } // 获取分配器 - - public: - // 构造、复制、移动、析构函数 - // 默认构造函数,初始化一个空的 unordered_map - unordered_map() - :ht_(100, Hash(), KeyEqual()) - { - } - - // 带桶数量的构造函数,允许自定义哈希函数和键值比较函数 - explicit unordered_map(size_type bucket_count, - const Hash& hash = Hash(), - const KeyEqual& equal = KeyEqual()) - :ht_(bucket_count, hash, equal) - { - } - - // 范围构造函数,从给定的迭代器范围构造 unordered_map - template - unordered_map(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(mystl::distance(first, last))), hash, equal) - { - for (; first != last; ++first) - ht_.insert_unique_noresize(*first); // 插入元素,不调整桶大小 - } - - // 初始化列表构造函数,从给定的值初始化 unordered_map - unordered_map(std::initializer_list ilist, - const size_type bucket_count = 100, - const Hash& hash = Hash(), - const KeyEqual& equal = KeyEqual()) - :ht_(mystl::max(bucket_count, static_cast(ilist.size())), hash, equal) - { - for (auto first = ilist.begin(), last = ilist.end(); first != last; ++first) - ht_.insert_unique_noresize(*first); // 插入元素,不调整桶大小 - } - - // 复制构造函数 - unordered_map(const unordered_map& rhs) - :ht_(rhs.ht_) - { - } - - // 移动构造函数 - unordered_map(unordered_map&& rhs) noexcept - :ht_(mystl::move(rhs.ht_)) - { - } - - // 赋值运算符重载 - // 复制赋值运算符,将右侧对象的值赋给当前对象 - unordered_map& operator=(const unordered_map& rhs) - { - ht_ = rhs.ht_; - return *this; - } - - // 移动赋值运算符,将右侧对象的值移动到当前对象 - unordered_map& operator=(unordered_map&& rhs) - { - ht_ = mystl::move(rhs.ht_); - return *this; - } - - // 从初始化列表赋值 - unordered_map& operator=(std::initializer_list ilist) - { - ht_.clear(); // 清空当前容器 - ht_.reserve(ilist.size()); // 预留足够的空间 - for (auto first = ilist.begin(), last = ilist.end(); first != last; ++first) - ht_.insert_unique_noresize(*first); // 插入元素,不调整桶大小 - return *this; - } - - // 默认析构函数 - ~unordered_map() = default; - - // 迭代器相关 - // 返回指向第一个元素的迭代器 - iterator begin() noexcept - { - return ht_.begin(); - } - // 返回指向第一个元素的常量迭代器 - const_iterator begin() const noexcept - { - return ht_.begin(); - } - // 返回指向最后一个元素的迭代器 - iterator end() noexcept - { - return ht_.end(); - } - // 返回指向最后一个元素的常量迭代器 - const_iterator end() const noexcept - { - return ht_.end(); - } - - // 返回指向第一个元素的常量迭代器(cbegin 和 cend 是 C++11 新增的,用于明确表达“常量迭代器”) - const_iterator cbegin() const noexcept - { - return ht_.cbegin(); - } - const_iterator cend() const noexcept - { - return ht_.cend(); - } - - // 容量相关 - // 检查容器是否为空 - bool empty() const noexcept { return ht_.empty(); } - // 返回容器中的元素数量 - size_type size() const noexcept { return ht_.size(); } - // 返回容器能容纳的最大元素数量 - size_type max_size() const noexcept { return ht_.max_size(); } - - // 修改容器操作 - - // emplace / emplace_hint - // 就地构造元素,返回插入的迭代器和是否插入的布尔值 - template - pair emplace(Args&& ...args) - { - return ht_.emplace_unique(mystl::forward(args)...); - } - - // 就地构造元素,并使用 hint 提示插入位置,返回插入的迭代器 - template - iterator emplace_hint(const_iterator hint, Args&& ...args) - { - return ht_.emplace_unique_use_hint(hint, mystl::forward(args)...); - } - }; -} // insert - // 插入元素,返回插入的迭代器和是否插入的布尔值 -pair insert(const value_type& value) -{ - return ht_.insert_unique(value); // 调用底层 hashtable 的 insert_unique 方法 -} -// 插入移动构造的元素 -pair insert(value_type&& 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); // 使用 hint 提示插入位置 -} -// 使用 hint 提示插入位置,并插入移动构造的元素 -iterator insert(const_iterator hint, value_type&& value) -{ - return ht_.emplace_unique_use_hint(hint, mystl::move(value)); // 使用 hint 插入移动构造的元素 -} - -// 从迭代器范围插入元素 -template -void insert(InputIterator first, InputIterator last) -{ - ht_.insert_unique(first, last); // 插入范围内的所有元素 -} - -// erase / clear -// 删除指定迭代器位置的元素 -void erase(iterator it) -{ - ht_.erase(it); // 调用底层 hashtable 的 erase 方法 -} -// 删除指定范围的元素 -void erase(iterator first, iterator last) -{ - ht_.erase(first, last); // 删除范围内的所有元素 -} - -// 删除指定键的元素,并返回被删除的元素数量 -size_type erase(const key_type& key) -{ - return ht_.erase_unique(key); // 调用底层 hashtable 的 erase_unique 方法 -} - -// 清空容器 -void clear() -{ - ht_.clear(); // 调用底层 hashtable 的 clear 方法 -} - -// 交换两个 unordered_map 对象的内容 -void swap(unordered_map& other) noexcept -{ - 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 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 no such element exists"); // 如果键不存在,抛出异常 - return it->second; // 返回值的常量引用 -} -// 下标操作符重载 -// 通过键查找或创建元素,并返回元素的引用 -mapped_type& operator[](const key_type& key) -{ - iterator it = ht_.find(key); // 查找键 - if (it.node == nullptr) - it = ht_.emplace_unique(key, T{}).first; // 如果元素不存在,则插入新元素 - return it->second; // 返回值的引用 -} - -// 下标操作符重载,用于移动构造的键 -mapped_type& operator[](key_type&& key) -{ - iterator it = ht_.find(key); // 查找键 - if (it.node == nullptr) - it = ht_.emplace_unique(mystl::move(key), T{}).first; // 如果元素不存在,则插入新元素 - return it->second; // 返回值的引用 -} - -// 计算给定键的元素数量 -size_type count(const key_type& key) const -{ - return ht_.count(key); // 调用底层 hashtable 的 count 方法 -} - -// 查找元素 -iterator find(const key_type& key) -{ - return ht_.find(key); // 调用底层 hashtable 的 find 方法 -} -const_iterator find(const key_type& key) const -{ - return ht_.find(key); // 调用底层 hashtable 的 find 方法 -} - -// 返回给定键的元素范围 -pair equal_range(const key_type& key) -{ - return ht_.equal_range_unique(key); // 调用底层 hashtable 的 equal_range_unique 方法 -} -pair equal_range(const key_type& key) const -{ - return ht_.equal_range_unique(key); // 调用底层 hashtable 的 equal_range_unique 方法 -} - -// 桶接口 - -// 返回指定桶的本地迭代器 -local_iterator begin(size_type n) noexcept -{ - return ht_.begin(n); // 调用底层 hashtable 的 begin 方法 -} -const_local_iterator begin(size_type n) const noexcept -{ - return ht_.begin(n); // 调用底层 hashtable 的 begin 方法 -} -const_local_iterator cbegin(size_type n) const noexcept -{ - return ht_.cbegin(n); // 调用底层 hashtable 的 cbegin 方法 -} - -// 返回指定桶的本地迭代器 -local_iterator end(size_type n) noexcept -{ - return ht_.end(n); // 调用底层 hashtable 的 end 方法 -} -const_local_iterator end(size_type n) const noexcept -{ - return ht_.end(n); // 调用底层 hashtable 的 end 方法 -} -const_local_iterator cend(size_type n) const noexcept -{ - return ht_.cend(n); // 调用底层 hashtable 的 cend 方法 -} - -// 返回桶的数量 -size_type bucket_count() const noexcept -{ - return ht_.bucket_count(); // 调用底层 hashtable 的 bucket_count 方法 -} -size_type max_bucket_count() const noexcept -{ - return ht_.max_bucket_count(); // 调用底层 hashtable 的 max_bucket_count 方法 -} - -// 返回指定桶的大小 -size_type bucket_size(size_type n) const noexcept -{ - return ht_.bucket_size(n); // 调用底层 hashtable 的 bucket_size 方法 -} -// 返回给定键的元素所在的桶编号 -size_type bucket(const key_type& key) const -{ - return ht_.bucket(key); // 调用底层 hashtable 的 bucket 方法 -} - -// 哈希策略 - -// 返回当前负载因子 -float load_factor() const noexcept { return ht_.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 rehash(size_type count) { ht_.rehash(count); } -// 调整桶的数量以至少容纳指定数量的元素 -void reserve(size_type count) { ht_.reserve(count); } - -// 返回哈希函数 -hasher hash_fcn() const { return ht_.hash_fcn(); } -// 返回键比较函数 -key_equal key_eq() const { return ht_.key_eq(); } - -// 友元函数,重载比较操作符 -public: - friend bool operator==(const unordered_map& lhs, const unordered_map& rhs) - { - 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_); // 比较两个 unordered_map 是否不相等 - } -}; - -// 重载比较操作符 -template -bool operator==(const unordered_map& lhs, - const unordered_map& rhs) -{ - return lhs == rhs; // 使用友元函数中的比较逻辑 -} - -template -bool operator!=(const unordered_map& lhs, - const unordered_map& rhs) -{ - return lhs != rhs; // 使用友元函数中的比较逻辑 -} - -// 重载 mystl 的 swap 函数 -template -void swap(unordered_map& lhs, - unordered_map& rhs) -{ - lhs.swap(rhs); // 调用 unordered_map 的 swap 方法 -} - -// 模板类 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; // 常量本地迭代器类型 - - // 获取分配器 - allocator_type get_allocator() const { return ht_.get_allocator(); } // 返回底层 hashtable 的分配器 - -public: - // 构造、复制、移动函数 - // 默认构造函数,初始化一个空的 unordered_multimap - unordered_multimap() - :ht_(100, Hash(), KeyEqual()) // 初始化底层 hashtable,设置默认桶数量为 100 - { - } - - // 带桶数量的构造函数,允许自定义哈希函数和键值比较函数 - explicit unordered_multimap(size_type bucket_count, - const Hash& hash = Hash(), - const KeyEqual& equal = KeyEqual()) - :ht_(bucket_count, hash, equal) // 初始化底层 hashtable,设置桶数量、哈希函数和键值比较函数 - { - } - - // 范围构造函数,从给定的迭代器范围构造 unordered_multimap - template - unordered_multimap(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(mystl::distance(first, last))), hash, equal) // 初始化底层 hashtable,设置桶数量、哈希函数和键值比较函数 - { - for (; first != last; ++first) - ht_.insert_multi_noresize(*first); // 插入元素,不调整桶大小 - } - - // 初始化列表构造函数,从给定的值初始化 unordered_multimap - unordered_multimap(std::initializer_list ilist, - const size_type bucket_count = 100, - const Hash& hash = Hash(), - const KeyEqual& equal = KeyEqual()) - :ht_(mystl::max(bucket_count, static_cast(ilist.size())), hash, equal) // 初始化底层 hashtable,设置桶数量、哈希函数和键值比较函数 - { - for (auto first = ilist.begin(), last = ilist.end(); first != last; ++first) - ht_.insert_multi_noresize(*first); // 插入元素,不调整桶大小 - } - - // 复制构造函数 - unordered_multimap(const unordered_multimap& rhs) - :ht_(rhs.ht_) // 深拷贝底层 hashtable - { - } - - // 移动构造函数 - unordered_multimap(unordered_multimap&& rhs) noexcept - :ht_(mystl::move(rhs.ht_)) // 移动底层 hashtable - { - } - - // 赋值运算符重载 - unordered_multimap& operator=(const unordered_multimap& rhs) - { - ht_ = rhs.ht_; // 深拷贝底层 hashtable - return *this; - } - unordered_multimap& operator=(unordered_multimap&& rhs) - { - ht_ = mystl::move(rhs.ht_); // 移动底层 hashtable - return *this; - } - - // 从初始化列表赋值 - unordered_multimap& operator=(std::initializer_list ilist) - { - ht_.clear(); // 清空当前容器 - ht_.reserve(ilist.size()); // 预留足够的空间 - for (auto first = ilist.begin(), last = ilist.end(); first != last; ++first) - ht_.insert_multi_noresize(*first); // 插入元素,不调整桶大小 - return *this; - } - - // 默认析构函数 - ~unordered_multimap() = default; // 默认析构函数,由编译器生成 - -// 迭代器访问 -// 返回指向第一个元素的迭代器 - iterator begin() noexcept { return ht_.begin(); } // 返回底层 hashtable 的 begin 迭代器 - // 返回指向第一个元素的常量迭代器 - const_iterator begin() const noexcept { return ht_.begin(); } // 返回底层 hashtable 的 begin 常量迭代器 - // 返回指向最后一个元素的迭代器 - iterator end() noexcept { return ht_.end(); } // 返回底层 hashtable 的 end 迭代器 - // 返回指向最后一个元素的常量迭代器 - const_iterator end() const noexcept { return ht_.end(); } // 返回底层 hashtable 的 end 常量迭代器 - - // 返回指向第一个元素的常量迭代器(cbegin 和 cend 是 C++11 新增的,用于明确表达“常量迭代器”) - 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(); } // 返回底层 hashtable 是否为空 - // 返回容器中的元素数量 - size_type size() const noexcept { return ht_.size(); } // 返回底层 hashtable 的元素数量 - // 返回容器能容纳的最大元素数量 - size_type max_size() const noexcept { return ht_.max_size(); } // 返回底层 hashtable 的最大元素数量 - - // 修改容器操作 - - // emplace / emplace_hint - // 就地构造元素,返回插入的迭代器 - template - iterator emplace(Args&& ...args) { - return ht_.emplace_multi(mystl::forward(args)...); // 就地构造元素并插入 - } - - // 就地构造元素,并使用 hint 提示插入位置,返回插入的迭代器 - template - iterator emplace_hint(const_iterator hint, Args&& ...args) { - return ht_.emplace_multi_use_hint(hint, mystl::forward(args)...); // 使用 hint 提示插入位置并就地构造元素 - } - - // insert - // 插入元素,返回插入的迭代器 - iterator insert(const value_type & value) { - return ht_.insert_multi(value); // 插入元素 - } - // 插入移动构造的元素 - iterator insert(value_type && 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); // 使用 hint 提示插入位置 - } - // 使用 hint 提示插入位置,并插入移动构造的元素 - iterator insert(const_iterator hint, value_type && value) { - return ht_.emplace_multi_use_hint(hint, mystl::move(value)); // 使用 hint 提示插入位置并插入移动构造的元素 - } - - // 从迭代器范围插入元素 - template - void insert(InputIterator first, InputIterator last) { - ht_.insert_multi(first, last); // 插入范围内的所有元素 - } - - // erase / clear - // 删除指定迭代器位置的元素 - void erase(iterator it) { - ht_.erase(it); // 删除指定迭代器位置的元素 - } - // 删除指定范围的元素 - void erase(iterator first, iterator last) { - ht_.erase(first, last); // 删除指定范围的元素 - } - - // 删除指定键的所有元素,并返回被删除的元素数量 - size_type erase(const key_type & key) { - return ht_.erase_multi(key); // 删除指定键的所有元素 - } - - // 清空容器 - void clear() { - ht_.clear(); // 清空底层 hashtable - } - // 桶接口 - - // 返回指定桶的本地迭代器 - local_iterator begin(size_type n) noexcept { - return ht_.begin(n); // 调用底层 hashtable 的 begin 方法,返回指定桶的本地迭代器 - } - const_local_iterator begin(size_type n) const noexcept { - return ht_.begin(n); // 调用底层 hashtable 的 begin 方法,返回指定桶的本地常量迭代器 - } - const_local_iterator cbegin(size_type n) const noexcept { - return ht_.cbegin(n); // 调用底层 hashtable 的 cbegin 方法,返回指定桶的本地常量迭代器 - } - - // 返回指定桶的本地迭代器 - local_iterator end(size_type n) noexcept { - return ht_.end(n); // 调用底层 hashtable 的 end 方法,返回指定桶的本地迭代器 - } - const_local_iterator end(size_type n) const noexcept { - return ht_.end(n); // 调用底层 hashtable 的 end 方法,返回指定桶的本地常量迭代器 - } - const_local_iterator cend(size_type n) const noexcept { - return ht_.cend(n); // 调用底层 hashtable 的 cend 方法,返回指定桶的本地常量迭代器 - } - - // 返回桶的数量 - size_type bucket_count() const noexcept { - return ht_.bucket_count(); // 调用底层 hashtable 的 bucket_count 方法,返回桶的数量 - } - size_type max_bucket_count() const noexcept { - return ht_.max_bucket_count(); // 调用底层 hashtable 的 max_bucket_count 方法,返回最大桶数量 - } - - // 返回指定桶的大小 - size_type bucket_size(size_type n) const noexcept { - return ht_.bucket_size(n); // 调用底层 hashtable 的 bucket_size 方法,返回指定桶的大小 - } - // 返回给定键的元素所在的桶编号 - size_type bucket(const key_type& key) const { - return ht_.bucket(key); // 调用底层 hashtable 的 bucket 方法,返回给定键的元素所在的桶编号 - } - - // 哈希策略 - - // 返回当前负载因子 - float load_factor() const noexcept { - return ht_.load_factor(); // 调用底层 hashtable 的 load_factor 方法,返回当前负载因子 - } - - // 返回最大负载因子 - float max_load_factor() const noexcept { - return ht_.max_load_factor(); // 调用底层 hashtable 的 max_load_factor 方法,返回最大负载因子 - } - // 设置最大负载因子 - void max_load_factor(float ml) { - ht_.max_load_factor(ml); // 调用底层 hashtable 的 max_load_factor 方法,设置最大负载因子 - } - - // 重新哈希,调整桶的数量 - void rehash(size_type count) { - ht_.rehash(count); // 调用底层 hashtable 的 rehash 方法,重新哈希并调整桶的数量 - } - // 调整桶的数量以至少容纳指定数量的元素 - void reserve(size_type count) { - ht_.reserve(count); // 调用底层 hashtable 的 reserve 方法,调整桶的数量以至少容纳指定数量的元素 - } - - // 返回哈希函数 - hasher hash_fcn() const { - return ht_.hash_fcn(); // 调用底层 hashtable 的 hash_fcn 方法,返回哈希函数 - } - // 返回键比较函数 - key_equal key_eq() const { - return ht_.key_eq(); // 调用底层 hashtable 的 key_eq 方法,返回键比较函数 - } - - // 友元函数,重载比较操作符 == - // 比较两个 unordered_multimap 对象是否相等 - friend bool operator==(const unordered_multimap& lhs, const unordered_multimap& rhs) - { - // 调用底层 hashtable 的 equal_range_multi 方法比较两个容器的元素是否相等 - return lhs.ht_.equal_range_multi(rhs.ht_); - } - - // 友元函数,重载比较操作符 != - // 比较两个 unordered_multimap 对象是否不相等 - friend bool operator!=(const unordered_multimap& lhs, const unordered_multimap& rhs) - { - // 直接返回 == 操作符的相反结果 - return !lhs.ht_.equal_range_multi(rhs.ht_); - } - - // 重载比较操作符 == - // 模板特化,使得可以不写明完整类型定义直接比较两个 unordered_multimap 对象是否相等 - template - bool operator==(const unordered_multimap& lhs, - const unordered_multimap& rhs) - { - // 调用友元函数实现的比较逻辑 - return lhs == rhs; - } - - // 重载比较操作符 != - // 模板特化,使得可以不写明完整类型定义直接比较两个 unordered_multimap 对象是否不相等 - template - bool operator!=(const unordered_multimap& lhs, - const unordered_multimap& rhs) - { - // 调用友元函数实现的比较逻辑 - return lhs != rhs; - } - - // 重载 mystl 的 swap 函数 - // 模板特化,使得可以不写明完整类型定义直接交换两个 unordered_multimap 对象的内容 - template - void swap(unordered_multimap& lhs, - unordered_multimap& rhs) - { - // 调用 unordered_multimap 类的 swap 成员函数 - lhs.swap(rhs); - } - -} // namespace mystl 结束命名空间 mystl - +#ifndef MYTINYSTL_UNORDERED_MAP_H_ // 防止头文件被重复包含的宏定义 +#define MYTINYSTL_UNORDERED_MAP_H_ +/*以上代码合起来实现了一个自定义的 `unordered_multimap` 容器类模板,该类模板提供了与标准库中的 `std::unordered_multimap` 类似的功能。以下是该类实现的主要功能: + +### 容器特性 +- **键值对存储**:`unordered_multimap` 存储的是键值对(`pair`),其中 `Key` 是键的类型,`T` 是值的类型。键可以重复出现,即多个键值对可以有相同的键。 +- **无序存储**:与 `std::map` 不同,`unordered_multimap` 不会对存储的元素进行排序。它使用哈希表(`hashtable`)作为底层数据结构,元素的存储顺序取决于键的哈希值。 + +### 构造与初始化 +- **默认构造**:创建一个空的 `unordered_multimap` 实例。 +- **带桶数量的构造**:允许指定初始桶的数量以及自定义的哈希函数和键比较函数。 +- **范围构造**:从给定的迭代器范围或初始化列表中构造 `unordered_multimap`,自动调整桶的数量以容纳元素。 +- **复制与移动构造**:支持复制构造和移动构造,允许创建新的 `unordered_multimap` 实例并复制或移动现有实例的内容。 + +### 迭代器 +- 提供了迭代器和常量迭代器,用于遍历容器中的元素。 +- 还提供了本地迭代器和常量本地迭代器,用于遍历特定桶中的元素。 + +### 容量操作 +- **`empty`**:检查容器是否为空。 +- **`size`**:返回容器中的元素数量。 +- **`max_size`**:返回容器能容纳的最大元素数量。 + +### 修改操作 +- **`emplace` 和 `emplace_hint`**:就地构造元素并插入容器,`emplace_hint` 允许使用 hint 提示插入位置。 +- **`insert`**:插入元素或移动构造的元素,支持使用 hint 提示插入位置。 +- **`erase`**:删除指定迭代器位置的元素或指定范围的元素,以及删除指定键的所有元素。 +- **`clear`**:清空容器中的所有元素。 + +### 查找操作 +- **`find`**:查找指定键的第一个元素,返回指向该元素的迭代器。 +- **`equal_range`**:查找指定键的所有元素,返回一个迭代器对,表示该键对应元素的范围。 + +### 桶操作 +- **`bucket_count` 和 `max_bucket_count`**:获取当前桶的数量和最大桶数量。 +- **`bucket_size`**:获取指定桶的大小,即桶中元素的数量。 +- **`bucket`**:获取给定键的元素所在的桶编号。 + +### 哈希策略 +- **`load_factor` 和 `max_load_factor`**:获取和设置容器的负载因子,负载因子影响哈希表的性能。 +- **`rehash` 和 `reserve`**:重新哈希和调整桶的数量,以优化性能或容纳更多元素。 + +### 其他 +- **`swap`**:交换两个 `unordered_multimap` 实例的内容。 +- **比较操作符**:重载了 `==` 和 `!=` 操作符,用于比较两个 `unordered_multimap` 实例是否相等或不相等。 + +总体来说,这段代码实现了一个功能完备的无序多映射容器,支持常见的容器操作,适用于需要存储键值对且键可以重复出现的场景。 +*/ +// 包含自定义的 hashtable 头文件,该文件定义了 hashtable 类 +#include "hashtable.h" + +namespace mystl // 定义命名空间 mystl,用于封装自定义的 STL 组件 +{ + // 定义 unordered_map 模板类,该类实现了一个不排序的映射容器 + template , class KeyEqual = mystl::equal_to> + class unordered_map + { + private: + // 定义一个基于 hashtable 的底层数据结构类型 + typedef hashtable, Hash, KeyEqual> base_type; + base_type ht_; // 创建一个 hashtable 实例来存储 unordered_map 的数据 + + public: + // 定义与 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; // 定义常量本地迭代器类型 + + // 提供一个方法来获取 unordered_map 使用的分配器 + allocator_type get_allocator() const { return ht_.get_allocator(); } + + public: + // 默认构造函数,创建一个空的 unordered_map 实例 + unordered_map() + :ht_(100, Hash(), KeyEqual()) + { + } + + // 构造函数,允许指定桶的数量、哈希函数和键比较函数 + explicit unordered_map(size_type bucket_count, + const Hash& hash = Hash(), + const KeyEqual& equal = KeyEqual()) + :ht_(bucket_count, hash, equal) + { + } + + // 范围构造函数,从迭代器指定的范围初始化 unordered_map + template + unordered_map(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(mystl::distance(first, last))), hash, equal) + { + for (; first != last; ++first) + ht_.insert_unique_noresize(*first); // 将范围内的元素插入到 unordered_map 中 + } + + // 初始化列表构造函数,从初始化列表中初始化 unordered_map + unordered_map(std::initializer_list ilist, + const size_type bucket_count = 100, + const Hash& hash = Hash(), + const KeyEqual& equal = KeyEqual()) + :ht_(mystl::max(bucket_count, static_cast(ilist.size())), hash, equal) + { + for (auto first = ilist.begin(), last = ilist.end(); first != last; ++first) + ht_.insert_unique_noresize(*first); // 将初始化列表中的元素插入到 unordered_map 中 + } + + // 复制构造函数,用于创建一个新的 unordered_map 实例,其内容与另一个实例相同 + unordered_map(const unordered_map& rhs) + :ht_(rhs.ht_) + { + } + + // 移动构造函数,用于创建一个新的 unordered_map 实例,接管另一个实例的所有资源 + unordered_map(unordered_map&& rhs) noexcept + :ht_(mystl::move(rhs.ht_)) + { + } + + // 赋值运算符重载,用于将一个 unordered_map 实例的内容复制到另一个实例中 + unordered_map& operator=(const unordered_map& rhs) + { + ht_ = rhs.ht_; + return *this; + } + + // 移动赋值运算符,用于将一个 unordered_map 实例的内容移动到另一个实例中 + unordered_map& operator=(unordered_map&& rhs) + { + ht_ = mystl::move(rhs.ht_); + return *this; + } + + // 从初始化列表赋值,用于将初始化列表中的内容赋给 unordered_map + unordered_map& operator=(std::initializer_list ilist) + { + ht_.clear(); // 清除 unordered_map 中的所有元素 + ht_.reserve(ilist.size()); // 为新元素预留空间 + for (auto first = ilist.begin(), last = ilist.end(); first != last; ++first) + ht_.insert_unique_noresize(*first); // 将初始化列表中的元素插入到 unordered_map 中 + return *this; + } + + // 默认析构函数,用于释放 unordered_map 占用的资源 + ~unordered_map() = default; + + // 返回指向 unordered_map 第一个元素的迭代器 + iterator begin() noexcept + { + return ht_.begin(); + } + // 返回指向 unordered_map 第一个元素的常量迭代器 + const_iterator begin() const noexcept + { + return ht_.begin(); + } + // 返回指向 unordered_map 最后一个元素的迭代器 + iterator end() noexcept + { + return ht_.end(); + } + // 返回指向 unordered_map 最后一个元素的常量迭代器 + const_iterator end() const noexcept + { + return ht_.end(); + } + + // 返回指向 unordered_map 第一个元素的常量迭代器 + const_iterator cbegin() const noexcept + { + return ht_.cbegin(); + } + // 返回指向 unordered_map 最后一个元素的常量迭代器 + const_iterator cend() const noexcept + { + return ht_.cend(); + } + + // 检查 unordered_map 是否为空 + bool empty() const noexcept { return ht_.empty(); } + // 返回 unordered_map 中的元素数量 + size_type size() const noexcept { return ht_.size(); } + // 返回 unordered_map 能容纳的最大元素数量 + size_type max_size() const noexcept { return ht_.max_size(); } + + // 就地构造元素,并返回插入的迭代器和插入状态 + template + pair emplace(Args&& ...args) + { + return ht_.emplace_unique(mystl::forward(args)...); + } + + // 就地构造元素,并使用 hint 提示插入位置,返回插入的迭代器 + template + iterator emplace_hint(const_iterator hint, Args&& ...args) + { + return ht_.emplace_unique_use_hint(hint, mystl::forward(args)...); + } + }; + + // 插入元素,并返回插入的迭代器和插入状态 + pair insert(const value_type& value) + { + return ht_.insert_unique(value); // 调用底层 hashtable 的 insert_unique 方法 + } + + // 插入移动构造的元素,并返回插入的迭代器和插入状态 + pair insert(value_type&& 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); // 使用 hint 提示插入位置 + } + + // 使用 hint 提示插入位置,并插入移动构造的元素,返回插入的迭代器 + iterator insert(const_iterator hint, value_type&& value) + { + return ht_.emplace_unique_use_hint(hint, mystl::move(value)); // 使用 hint 插入移动构造的元素 + } +// 从迭代器范围插入元素 // +template +void insert(InputIterator first, InputIterator last) +{ +ht_.insert_unique(first, last); // 插入范围内的所有元素 +} + +// erase / clear +// 删除指定迭代器位置的元素 +void erase(iterator it) +{ + ht_.erase(it); // 调用底层 hashtable 的 erase 方法 +} + +// 删除指定范围的元素 +void erase(iterator first, iterator last) +{ + ht_.erase(first, last); // 删除范围内的所有元素 +} + +// 删除指定键的元素,并返回被删除的元素数量 +size_type erase(const key_type& key) +{ + return ht_.erase_unique(key); // 调用底层 hashtable 的 erase_unique 方法 +} + +// 清空容器 +void clear() +{ + ht_.clear(); // 调用底层 hashtable 的 clear 方法,移除所有元素 +} + +// 交换两个 unordered_map 对象的内容 +void swap(unordered_map& other) noexcept +{ + ht_.swap(other.ht_); // 交换底层 hashtable 的内容,实现两个 unordered_map 的内容互换 +} + +// 查找相关 +// 返回指定键的值的引用,如果键不存在则抛出异常 +mapped_type& at(const key_type& key) +{ + iterator it = ht_.find(key); // 查找键对应的元素 + THROW_OUT_OF_RANGE_IF(it.node == nullptr, "unordered_map no such element exists"); // 如果键不存在,抛出 out_of_range 异常 + 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 no such element exists"); // 如果键不存在,抛出 out_of_range 异常 + return it->second; // 返回找到的元素的值的常量引用 +} + +// 下标操作符重载 +// 通过键查找或创建元素,并返回元素的引用 +mapped_type& operator[](const key_type& key) +{ + iterator it = ht_.find(key); // 查找键对应的元素 + if (it.node == nullptr) + it = ht_.emplace_unique(key, T{}).first; // 如果元素不存在,则插入新元素,并返回插入元素的迭代器 + return it->second; // 返回找到或插入的元素的值的引用 +} + +// 下标操作符重载,用于移动构造的键 +mapped_type& operator[](key_type&& key) +{ + iterator it = ht_.find(key); // 查找键对应的元素 + if (it.node == nullptr) + it = ht_.emplace_unique(mystl::move(key), T{}).first; // 如果元素不存在,则插入新元素,并返回插入元素的迭代器 + return it->second; // 返回找到或插入的元素的值的引用 +} + +// 计算给定键的元素数量 +size_type count(const key_type& key) const +{ + return ht_.count(key); // 调用底层 hashtable 的 count 方法,返回键对应的元素数量 +} + +// 查找元素 +iterator find(const key_type& key) +{ + return ht_.find(key); // 调用底层 hashtable 的 find 方法,返回指向找到的元素的迭代器 +} +const_iterator find(const key_type& key) const +{ + return ht_.find(key); // 调用底层 hashtable 的 find 方法,返回指向找到的元素的常量迭代器 +} + +// 返回给定键的元素范围 +pair equal_range(const key_type& key) +{ + return ht_.equal_range_unique(key); // 调用底层 hashtable 的 equal_range_unique 方法,返回键对应的元素范围 +} +pair equal_range(const key_type& key) const +{ + return ht_.equal_range_unique(key); // 调用底层 hashtable 的 equal_range_unique 方法,返回键对应的元素范围 +} + +// 桶接口 +// 返回指定桶的本地迭代器 +local_iterator begin(size_type n) noexcept +{ + return ht_.begin(n); // 调用底层 hashtable 的 begin 方法,返回指定桶的本地迭代器 +} +const_local_iterator begin(size_type n) const noexcept +{ + return ht_.begin(n); // 调用底层 hashtable 的 begin 方法,返回指定桶的本地迭代器 +} +const_local_iterator cbegin(size_type n) const noexcept +{ + return ht_.cbegin(n); // 调用底层 hashtable 的 cbegin 方法,返回指定桶的本地迭代器 +} + +// 返回指定桶的本地迭代器 +local_iterator end(size_type n) noexcept +{ + return ht_.end(n); // 调用底层 hashtable 的 end 方法,返回指定桶的本地迭代器 +} +const_local_iterator end(size_type n) const noexcept +{ + return ht_.end(n); // 调用底层 hashtable 的 end 方法,返回指定桶的本地迭代器 +} +const_local_iterator cend(size_type n) const noexcept +{ + return ht_.cend(n); // 调用底层 hashtable 的 cend 方法,返回指定桶的本地迭代器 +} + +// 返回桶的数量 +size_type bucket_count() const noexcept +{ + return ht_.bucket_count(); // 调用底层 hashtable 的 bucket_count 方法,返回桶的数量 +} +size_type max_bucket_count() const noexcept +{ + return ht_.max_bucket_count(); // 调用底层 hashtable 的 max_bucket_count 方法,返回桶的最大数量 +} + +// 返回指定桶的大小 +size_type bucket_size(size_type n) const noexcept +{ + return ht_.bucket_size(n); // 调用底层 hashtable 的 bucket_size 方法,返回指定桶的大小 +} +// 返回给定键的元素所在的桶编号 +size_type bucket(const key_type& key) const +{ + return ht_.bucket(key); // 调用底层 hashtable 的 bucket 方法,返回键对应的桶编号 +} + +// 哈希策略 +// 返回当前负载因子 +float load_factor() const noexcept { return ht_.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 rehash(size_type count) { ht_.rehash(count); } + +// 调整桶的数量以至少容纳指定数量的元素 +void reserve(size_type count) { ht_.reserve(count); } + +// 返回哈希函数 +hasher hash_fcn() const { return ht_.hash_fcn(); } +// 返回键比较函数 +key_equal key_eq() const { return ht_.key_eq(); } + +// 友元函数,重载比较操作符 +public: + friend bool operator==(const unordered_map& lhs, const unordered_map& rhs) + { + 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_); // 比较两个 unordered_map 是否不相等 + } + +// 重载比较操作符 +template +bool operator==(const unordered_map& lhs, + const unordered_map& rhs) +{ + return lhs == rhs; // 使用友元函数中的比较逻辑 +} + +template +bool operator!=(const unordered_map& lhs, + const unordered_map& rhs) +{ + return lhs != rhs; // 使用友元函数中的比较逻辑 +} + +// 重载 mystl 的 swap 函数 +template +void swap(unordered_map& lhs, + unordered_map& rhs) +{ + lhs.swap(rhs); // 调用 unordered_map 的 swap 方法,交换两个对象的内容 +} + +// 模板类 unordered_multimap,键值允许重复1 +public: + // 定义与底层 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; // 定义常量本地迭代器类型 + + // 提供一个方法来获取 unordered_multimap 使用的分配器 + allocator_type get_allocator() const { return ht_.get_allocator(); } + +public: + // 默认构造函数,创建一个空的 unordered_multimap 实例 + unordered_multimap() + :ht_(100, Hash(), KeyEqual()) // 初始化底层 hashtable,设置默认桶数量为 100 + { + } + + // 构造函数,允许指定桶的数量、哈希函数和键比较函数 + explicit unordered_multimap(size_type bucket_count, + const Hash& hash = Hash(), + const KeyEqual& equal = KeyEqual()) + :ht_(bucket_count, hash, equal) // 初始化底层 hashtable,设置桶数量、哈希函数和键比较函数 + { + } + + // 范围构造函数,从迭代器指定的范围初始化 unordered_multimap + template + unordered_multimap(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(mystl::distance(first, last))), hash, equal) // 初始化底层 hashtable,设置桶数量、哈希函数和键比较函数 + { + for (; first != last; ++first) + ht_.insert_multi_noresize(*first); // 将范围内的元素插入到 unordered_multimap 中,不调整桶大小 + } + + // 初始化列表构造函数,从初始化列表中初始化 unordered_multimap + unordered_multimap(std::initializer_list ilist, + const size_type bucket_count = 100, + const Hash& hash = Hash(), + const KeyEqual& equal = KeyEqual()) + :ht_(mystl::max(bucket_count, static_cast(ilist.size())), hash, equal) // 初始化底层 hashtable,设置桶数量、哈希函数和键比较函数 + { + for (auto first = ilist.begin(), last = ilist.end(); first != last; ++first) + ht_.insert_multi_noresize(*first); // 将初始化列表中的元素插入到 unordered_multimap 中,不调整桶大小 + } + + // 复制构造函数,用于创建一个新的 unordered_multimap 实例,其内容与另一个实例相同 + unordered_multimap(const unordered_multimap& rhs) + :ht_(rhs.ht_) // 深拷贝底层 hashtable + { + } + + // 移动构造函数,用于创建一个新的 unordered_multimap 实例,接管另一个实例的所有资源 + unordered_multimap(unordered_multimap&& rhs) noexcept + :ht_(mystl::move(rhs.ht_)) // 移动底层 hashtable + { + } + + // 赋值运算符重载,用于将一个 unordered_multimap 实例的内容复制到另一个实例中 + unordered_multimap& operator=(const unordered_multimap& rhs) + { + ht_ = rhs.ht_; // 深拷贝底层 hashtable + return *this; + } + + // 移动赋值运算符,用于将一个 unordered_multimap 实例的内容移动到另一个实例中 + unordered_multimap& operator=(unordered_multimap&& rhs) + { + ht_ = mystl::move(rhs.ht_); // 移动底层 hashtable + return *this; + } + + // 从初始化列表赋值,用于将初始化列表中的内容赋给 unordered_multimap + unordered_multimap& operator=(std::initializer_list ilist) + { + ht_.clear(); // 清除 unordered_multimap 中的所有元素 + ht_.reserve(ilist.size()); // 为新元素预留空间 + for (auto first = ilist.begin(), last = ilist.end(); first != last; ++first) + ht_.insert_multi_noresize(*first); // 将初始化列表中的元素插入到 unordered_multimap 中,不调整桶大小 + return *this; + } + + // 默认析构函数,用于释放 unordered_multimap 占用的资源 + ~unordered_multimap() = default; + + // 返回指向 unordered_multimap 第一个元素的迭代器 + iterator begin() noexcept { return ht_.begin(); } + // 返回指向 unordered_multimap 第一个元素的常量迭代器 + const_iterator begin() const noexcept { return ht_.begin(); } + // 返回指向 unordered_multimap 最后一个元素的迭代器 + iterator end() noexcept { return ht_.end(); } + // 返回指向 unordered_multimap 最后一个元素的常量迭代器 + const_iterator end() const noexcept { return ht_.end(); } + + // 返回指向 unordered_multimap 第一个元素的常量迭代器 + const_iterator cbegin() const noexcept { return ht_.cbegin(); } + // 返回指向 unordered_multimap 最后一个元素的常量迭代器 + const_iterator cend() const noexcept { return ht_.cend(); } + + // 检查 unordered_multimap 是否为空 + bool empty() const noexcept { return ht_.empty(); } + // 返回 unordered_multimap 中的元素数量 + size_type size() const noexcept { return ht_.size(); } + // 返回 unordered_multimap 能容纳的最大元素数量 + size_type max_size() const noexcept { return ht_.max_size(); } + + // 修改容器操作 + // 就地构造元素,并返回插入的迭代器 + template + iterator emplace(Args&& ...args) { + return ht_.emplace_multi(mystl::forward(args)...); // 就地构造元素并插入到 unordered_multimap 中 + } + + // 就地构造元素,并使用 hint 提示插入位置,返回插入的迭代器 + template + iterator emplace_hint(const_iterator hint, Args&& ...args) { + return ht_.emplace_multi_use_hint(hint, mystl::forward(args)...); // 使用 hint 提示插入位置并就地构造元素 + } + + // 插入元素,并返回插入的迭代器 + iterator insert(const value_type & value) { + return ht_.insert_multi(value); // 插入元素到 unordered_multimap 中 + } + + // 插入移动构造的元素 + iterator insert(value_type && value) { + return ht_.emplace_multi(mystl::move(value)); // 插入移动构造的元素到 unordered_multimap 中 + } + + // 使用 hint 提示插入位置,并插入元素,返回插入的迭代器 + iterator insert(const_iterator hint, const value_type & 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)); // 使用 hint 提示插入位置并插入移动构造的元素 + } + + // 从迭代器范围插入元素 + template + void insert(InputIterator first, InputIterator last) { + ht_.insert_multi(first, last); // 插入范围内的所有元素到 unordered_multimap 中 + } + + // 删除指定迭代器位置的元素 + void erase(iterator it) { + ht_.erase(it); // 删除指定迭代器位置的元素 + } + + // 删除指定范围的元素 + void erase(iterator first, iterator last) { + ht_.erase + + // 删除指定键的所有元素,并返回被删除的元素数量 + // 删除指定键的所有元素,并返回被删除的元素数量 + size_type erase(const key_type & key) { + return ht_.erase_multi(key); // 删除指定键的所有元素 + } + + // 清空容器 + void clear() { + ht_.clear(); // 清空底层 hashtable + } + + // 返回指定桶的本地迭代器 + local_iterator begin(size_type n) noexcept { + return ht_.begin(n); // 调用底层 hashtable 的 begin 方法,返回指定桶的本地迭代器 + } + const_local_iterator begin(size_type n) const noexcept { + return ht_.begin(n); // 调用底层 hashtable 的 begin 方法,返回指定桶的本地常量迭代器 + } + const_local_iterator cbegin(size_type n) const noexcept { + return ht_.cbegin(n); // 调用底层 hashtable 的 cbegin 方法,返回指定桶的本地常量迭代器 + } + + + // 返回指定桶的本地迭代器 // +// 返回指定桶的本地迭代器,用于遍历桶中的元素 +local_iterator end(size_type n) noexcept { + return ht_.end(n); // 调用底层 hashtable 的 end 方法,获取指定桶的结束迭代器 +} + +// 返回指定桶的本地常量迭代器,用于遍历桶中的元素 +const_local_iterator end(size_type n) const noexcept { + return ht_.end(n); // 调用底层 hashtable 的 end 方法,获取指定桶的结束常量迭代器 +} + +// 返回指定桶的本地常量迭代器,用于遍历桶中的元素 +const_local_iterator cend(size_type n) const noexcept { + return ht_.cend(n); // 调用底层 hashtable 的 cend 方法,获取指定桶的结束常量迭代器 +} + +// 返回桶的数量,表示容器中桶的总数 +size_type bucket_count() const noexcept { + return ht_.bucket_count(); // 调用底层 hashtable 的 bucket_count 方法,获取桶的数量 +} + +// 返回桶的最大数量,表示容器中桶的最大可能数量 +size_type max_bucket_count() const noexcept { + return ht_.max_bucket_count(); // 调用底层 hashtable 的 max_bucket_count 方法,获取最大桶数量 +} + +// 返回指定桶的大小,即桶中元素的数量 +size_type bucket_size(size_type n) const noexcept { + return ht_.bucket_size(n); // 调用底层 hashtable 的 bucket_size 方法,获取指定桶的大小 +} + +// 返回给定键的元素所在的桶编号 +size_type bucket(const key_type& key) const { + return ht_.bucket(key); // 调用底层 hashtable 的 bucket 方法,获取键所在桶的编号 +} + +// 哈希策略相关操作 + +// 返回当前负载因子,即容器中元素数量与桶数量的比值 +float load_factor() const noexcept { + return ht_.load_factor(); // 调用底层 hashtable 的 load_factor 方法,获取当前负载因子 +} + +// 返回最大负载因子,即容器允许的最大负载因子 +float max_load_factor() const noexcept { + return ht_.max_load_factor(); // 调用底层 hashtable 的 max_load_factor 方法,获取最大负载因子 +} + +// 设置最大负载因子,用于调整容器的负载因子上限 +void max_load_factor(float ml) { + ht_.max_load_factor(ml); // 调用底层 hashtable 的 max_load_factor 方法,设置最大负载因子 +} + +// 重新哈希,调整桶的数量以优化性能 +void rehash(size_type count) { + ht_.rehash(count); // 调用底层 hashtable 的 rehash 方法,重新哈希并调整桶的数量 +} + +// 调整桶的数量以至少容纳指定数量的元素 +void reserve(size_type count) { + ht_.reserve(count); // 调用底层 hashtable 的 reserve 方法,调整桶的数量以至少容纳指定数量的元素 +} + +// 返回哈希函数,用于计算键的哈希值 +hasher hash_fcn() const { + return ht_.hash_fcn(); // 调用底层 hashtable 的 hash_fcn 方法,获取哈希函数 +} + +// 返回键比较函数,用于比较键的相等性 +key_equal key_eq() const { + return ht_.key_eq(); // 调用底层 hashtable 的 key_eq 方法,获取键比较函数 +} + +// 友元函数,重载比较操作符 ==,用于比较两个 unordered_multimap 对象是否相等 +friend bool operator==(const unordered_multimap& lhs, const unordered_multimap& rhs) { + return lhs.ht_.equal_range_multi(rhs.ht_); // 调用底层 hashtable 的 equal_range_multi 方法比较两个容器的元素是否相等 +} + +// 友元函数,重载比较操作符 !=,用于比较两个 unordered_multimap 对象是否不相等 +friend bool operator!=(const unordered_multimap& lhs, const unordered_multimap& rhs) { + return !lhs.ht_.equal_range_multi(rhs.ht_); // 直接返回 == 操作符的相反结果 +} + +// 重载比较操作符 ==,模板特化,使得可以不写明完整类型定义直接比较两个 unordered_multimap 对象是否相等 +template +bool operator==(const unordered_multimap& lhs, + const unordered_multimap& rhs) { + return lhs == rhs; // 调用友元函数实现的比较逻辑 +} + +// 重载比较操作符 !=,模板特化,使得可以不写明完整类型定义直接比较两个 unordered_multimap 对象是否不相等 +template +bool operator!=(const unordered_multimap& lhs, + const unordered_multimap& rhs) { + return lhs != rhs; // 调用友元函数实现的比较逻辑 +} + +// 重载 mystl 的 swap 函数,模板特化,使得可以不写明完整类型定义直接交换两个 unordered_multimap 对象的内容 +template +void swap(unordered_multimap& lhs, + unordered_multimap& rhs) { + lhs.swap(rhs); // 调用 unordered_multimap 类的 swap 成员函数 +} + +} // namespace mystl 结束命名空间 mystl + #endif // !MYTINYSTL_UNORDERED_MAP_H_ 结束头文件保护 \ No newline at end of file