diff --git a/src/MyTinySTL-master/MyTinySTL/unordered_map.h b/src/MyTinySTL-master/MyTinySTL/unordered_map.h index 5838a21..cb9d68f 100644 --- a/src/MyTinySTL-master/MyTinySTL/unordered_map.h +++ b/src/MyTinySTL-master/MyTinySTL/unordered_map.h @@ -1,4 +1,4 @@ -#ifndef MYTINYSTL_UNORDERED_MAP_H_ +#ifndef MYTINYSTL_UNORDERED_MAP_H_ // 预处理指令,防止头文件被重复包含 #define MYTINYSTL_UNORDERED_MAP_H_ // 这个头文件包含两个模板类 unordered_map 和 unordered_multimap @@ -12,297 +12,407 @@ // * emplace_hint // * insert -#include "hashtable.h" +#include "hashtable.h" // 包含自定义的 hashtable 头文件 -namespace mystl +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_; - + // 模板类 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); + } + // 插入移动构造的元素 + pair insert(value_type&& value) + { + return ht_.emplace_unique(mystl::move(value)); + } + + // 使用 hint 提示插入位置 + iterator insert(const_iterator hint, const value_type& value) + { + return ht_.insert_unique_use_hint(hint, value); + } + // 使用 hint 提示插入位置,并插入移动构造的元素 + iterator insert(const_iterator hint, value_type&& value) + { + return ht_.emplace_unique_use_hint(hint, mystl::move(value)); + } + + // 从迭代器范围插入元素 + template + void insert(InputIterator first, InputIterator last) + { + ht_.insert_unique(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_unique(key); + } + + // 清空容器 + void clear() + { + ht_.clear(); + } + + // 交换两个 unordered_map 对象的内容 + void swap(unordered_map& other) noexcept + { + ht_.swap(other.ht_); + } + + // 查找相关 + // 返回指定键的值的引用,如果键不存在则抛出异常 + 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); + } + + // 查找元素 + iterator find(const key_type& key) + { + return ht_.find(key); + } + const_iterator find(const key_type& key) const + { + return ht_.find(key); + } + + // 返回给定键的元素范围 + pair equal_range(const key_type& key) + { + return ht_.equal_range_unique(key); + } + pair equal_range(const key_type& key) const + { + return ht_.equal_range_unique(key); + } + + // 桶接口 + + // 返回指定桶的本地迭代器 + local_iterator begin(size_type n) noexcept + { + return ht_.begin(n); + } + const_local_iterator begin(size_type n) const noexcept + { + return ht_.begin(n); + } + const_local_iterator cbegin(size_type n) const noexcept + { + return ht_.cbegin(n); + } + + // 返回指定桶的本地迭代器 + local_iterator end(size_type n) noexcept + { + return ht_.end(n); + } + const_local_iterator end(size_type n) const noexcept + { + return ht_.end(n); + } + const_local_iterator cend(size_type n) const noexcept + { + return ht_.cend(n); + } + + // 返回桶的数量 + size_type bucket_count() const noexcept + { + return ht_.bucket_count(); + } + size_type max_bucket_count() const noexcept + { + return ht_.max_bucket_count(); + } + + // 返回指定桶的大小 + size_type bucket_size(size_type n) const noexcept + { + return ht_.bucket_size(n); + } + // 返回给定键的元素所在的桶编号 + size_type bucket(const key_type& key) const + { + return ht_.bucket(key); + } + + // 哈希策略 + + // 返回当前负载因子 + 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: - // 使用 hashtable 的型别 - - 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() - :ht_(100, Hash(), KeyEqual()) - { - } - - explicit unordered_map(size_type bucket_count, - const Hash& hash = Hash(), - const KeyEqual& equal = KeyEqual()) - :ht_(bucket_count, hash, equal) - { - } - - 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(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(); } - - 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(); } - - // 修改容器操作 - - // empalce / empalce_hint - - template - pair emplace(Args&& ...args) - { return ht_.emplace_unique(mystl::forward(args)...); } - - 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); } - pair insert(value_type&& value) - { return ht_.emplace_unique(mystl::move(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_.emplace_unique_use_hint(hint, mystl::move(value)); } - - template - void insert(InputIterator first, InputIterator last) - { ht_.insert_unique(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_unique(key); } - - void clear() - { ht_.clear(); } - - void swap(unordered_map& other) noexcept - { ht_.swap(other.ht_); } - - // 查找相关 - - 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); } - - iterator find(const key_type& key) - { return ht_.find(key); } - const_iterator find(const key_type& key) const - { return ht_.find(key); } - - pair equal_range(const key_type& key) - { return ht_.equal_range_unique(key); } - pair equal_range(const key_type& key) const - { return ht_.equal_range_unique(key); } - - // bucket interface - - local_iterator begin(size_type n) noexcept - { return ht_.begin(n); } - const_local_iterator begin(size_type n) const noexcept - { return ht_.begin(n); } - const_local_iterator cbegin(size_type n) const noexcept - { return ht_.cbegin(n); } - - local_iterator end(size_type n) noexcept - { return ht_.end(n); } - const_local_iterator end(size_type n) const noexcept - { return ht_.end(n); } - const_local_iterator cend(size_type n) const noexcept - { return ht_.cend(n); } - - size_type bucket_count() const noexcept - { return ht_.bucket_count(); } - size_type max_bucket_count() const noexcept - { return ht_.max_bucket_count(); } - - size_type bucket_size(size_type n) const noexcept - { return ht_.bucket_size(n); } - size_type bucket(const key_type& key) const - { return ht_.bucket(key); } - - // hash policy - - 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_); - } - friend bool operator!=(const unordered_map& lhs, const unordered_map& rhs) - { - return !lhs.ht_.equal_range_unique(rhs.ht_); - } + friend bool operator==(const unordered_map& lhs, const unordered_map& rhs) + { + return lhs.ht_.equal_range_unique(rhs.ht_); + } + friend bool operator!=(const unordered_map& lhs, const unordered_map& rhs) + { + return !lhs.ht_.equal_range_unique(rhs.ht_); + } }; // 重载比较操作符 template bool operator==(const unordered_map& lhs, - const unordered_map& rhs) + const unordered_map& rhs) { - return lhs == rhs; + return lhs == rhs; } template bool operator!=(const unordered_map& lhs, - const unordered_map& rhs) + const unordered_map& rhs) { - return lhs != rhs; + return lhs != rhs; } -// 重载 mystl 的 swap +// 重载 mystl 的 swap 函数 template void swap(unordered_map& lhs, - unordered_map& rhs) + unordered_map& rhs) { - lhs.swap(rhs); + lhs.swap(rhs); } - -/*****************************************************************************************/ - // 模板类 unordered_multimap,键值允许重复 // 参数一代表键值类型,参数二代表实值类型,参数三代表哈希函数,缺省使用 mystl::hash // 参数四代表键值比较方式,缺省使用 mystl::equal_to @@ -310,254 +420,341 @@ template , class KeyEqual = my class unordered_multimap { private: - // 使用 hashtable 作为底层机制 - typedef hashtable, Hash, KeyEqual> base_type; - base_type ht_; + // 使用 hashtable 作为底层机制 + typedef hashtable, 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::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 的型别 + // 以下定义了与 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(); } public: - // 构造、复制、移动函数 - - unordered_multimap() - :ht_(100, Hash(), KeyEqual()) - { - } - - explicit unordered_multimap(size_type bucket_count, - const Hash& hash = Hash(), - const KeyEqual& equal = KeyEqual()) - :ht_(bucket_count, hash, equal) - { - } - - 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) - { - for (; first != last; ++first) - ht_.insert_multi_noresize(*first); - } - - 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) - { - 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_) - { - } - unordered_multimap(unordered_multimap&& rhs) noexcept - :ht_(mystl::move(rhs.ht_)) - { - } - - unordered_multimap& operator=(const unordered_multimap& rhs) - { - ht_ = rhs.ht_; - return *this; - } - unordered_multimap& operator=(unordered_multimap&& rhs) - { - ht_ = mystl::move(rhs.ht_); - 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(); } - const_iterator begin() const noexcept - { return ht_.begin(); } - iterator end() noexcept - { return ht_.end(); } - const_iterator end() const noexcept - { return ht_.end(); } - - 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 - iterator emplace(Args&& ...args) - { return ht_.emplace_multi(mystl::forward(args)...); } - - template - iterator emplace_hint(const_iterator hint, Args&& ...args) - { return ht_.emplace_multi_use_hint(hint, mystl::forward(args)...); } - - // insert - - iterator insert(const value_type& value) - { return ht_.insert_multi(value); } - iterator insert(value_type&& value) - { return ht_.emplace_multi(mystl::move(value)); } + // 构造、复制、移动函数 + // 默认构造函数,初始化一个空的 unordered_multimap + unordered_multimap() + :ht_(100, Hash(), KeyEqual()) + { + } + + // 带桶数量的构造函数,允许自定义哈希函数和键值比较函数 + explicit unordered_multimap(size_type bucket_count, + const Hash& hash = Hash(), + const KeyEqual& equal = KeyEqual()) + :ht_(bucket_count, hash, equal) + { + } + + // 范围构造函数,从给定的迭代器范围构造 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) + { + 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) + { + 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_) + { + } + + // 移动构造函数 + unordered_multimap(unordered_multimap&& rhs) noexcept + :ht_(mystl::move(rhs.ht_)) + { + } + + // 赋值运算符重载 + unordered_multimap& operator=(const unordered_multimap& rhs) + { + ht_ = rhs.ht_; + return *this; + } + unordered_multimap& operator=(unordered_multimap&& rhs) + { + ht_ = mystl::move(rhs.ht_); + 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(); } +// 返回指向第一个元素的常量迭代器 +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 +iterator emplace(Args&& ...args) { + return ht_.emplace_multi(mystl::forward(args)...); +} - iterator insert(const_iterator hint, const value_type& value) - { return ht_.insert_multi_use_hint(hint, value); } - iterator insert(const_iterator hint, value_type&& value) - { return ht_.emplace_multi_use_hint(hint, mystl::move(value)); } +// 就地构造元素,并使用 hint 提示插入位置,返回插入的迭代器 +template +iterator emplace_hint(const_iterator hint, Args&& ...args) { + return ht_.emplace_multi_use_hint(hint, mystl::forward(args)...); +} - template - void insert(InputIterator first, InputIterator last) - { ht_.insert_multi(first, last); } - - // erase / clear +// insert +// 插入元素,返回插入的迭代器 +iterator insert(const value_type& value) { + return ht_.insert_multi(value); +} +// 插入移动构造的元素 +iterator insert(value_type&& value) { + return ht_.emplace_multi(mystl::move(value)); +} - void erase(iterator it) - { ht_.erase(it); } - void erase(iterator first, iterator last) - { ht_.erase(first, last); } +// 使用 hint 提示插入位置 +iterator insert(const_iterator hint, const value_type& 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)); +} - size_type erase(const key_type& key) - { return ht_.erase_multi(key); } +// 从迭代器范围插入元素 +template +void insert(InputIterator first, InputIterator last) { + ht_.insert_multi(first, last); +} - void clear() - { ht_.clear(); } +// erase / clear +// 删除指定迭代器位置的元素 +void erase(iterator it) { + ht_.erase(it); +} +// 删除指定范围的元素 +void erase(iterator first, iterator last) { + ht_.erase(first, last); +} - void swap(unordered_multimap& other) noexcept - { ht_.swap(other.ht_); } +// 删除指定键的所有元素,并返回被删除的元素数量 +size_type erase(const key_type& key) { + return ht_.erase_multi(key); +} - // 查找相关 +// 清空容器 +void clear() { + ht_.clear(); +} - size_type count(const key_type& key) const - { return ht_.count(key); } +// 交换两个 unordered_multimap 对象的内容 +void swap(unordered_multimap& other) noexcept { + ht_.swap(other.ht_); +} - iterator find(const key_type& key) - { return ht_.find(key); } - const_iterator find(const key_type& key) const - { return ht_.find(key); } +// 查找相关 +// 返回指定键的元素数量 +size_type count(const key_type& key) const { + return ht_.count(key); +} - pair equal_range(const key_type& key) - { return ht_.equal_range_multi(key); } - pair equal_range(const key_type& key) const - { return ht_.equal_range_multi(key); } +// 查找元素 +iterator find(const key_type& key) { + return ht_.find(key); +} +const_iterator find(const key_type& key) const { + return ht_.find(key); +} - // bucket interface +// 返回给定键的元素范围 +pair equal_range(const key_type& key) { + return ht_.equal_range_multi(key); +} +pair equal_range(const key_type& key) const { + return ht_.equal_range_multi(key); +} - local_iterator begin(size_type n) noexcept - { return ht_.begin(n); } - const_local_iterator begin(size_type n) const noexcept - { return ht_.begin(n); } - const_local_iterator cbegin(size_type n) const noexcept - { return ht_.cbegin(n); } +// 桶接口 - local_iterator end(size_type n) noexcept - { return ht_.end(n); } - const_local_iterator end(size_type n) const noexcept - { return ht_.end(n); } - const_local_iterator cend(size_type n) const noexcept - { return ht_.cend(n); } +// 返回指定桶的本地迭代器 +local_iterator begin(size_type n) noexcept { + return ht_.begin(n); +} +const_local_iterator begin(size_type n) const noexcept { + return ht_.begin(n); +} +const_local_iterator cbegin(size_type n) const noexcept { + return ht_.cbegin(n); +} - size_type bucket_count() const noexcept - { return ht_.bucket_count(); } - size_type max_bucket_count() const noexcept - { return ht_.max_bucket_count(); } +// 返回指定桶的本地迭代器 +local_iterator end(size_type n) noexcept { + return ht_.end(n); +} +const_local_iterator end(size_type n) const noexcept { + return ht_.end(n); +} +const_local_iterator cend(size_type n) const noexcept { + return ht_.cend(n); +} - size_type bucket_size(size_type n) const noexcept - { return ht_.bucket_size(n); } - size_type bucket(const key_type& key) const - { return ht_.bucket(key); } +// 返回桶的数量 +size_type bucket_count() const noexcept { + return ht_.bucket_count(); +} +size_type max_bucket_count() const noexcept { + return ht_.max_bucket_count(); +} - // hash policy +// 返回指定桶的大小 +size_type bucket_size(size_type n) const noexcept { + return ht_.bucket_size(n); +} +// 返回给定键的元素所在的桶编号 +size_type bucket(const key_type& key) const { + return ht_.bucket(key); +} - 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); } +// 返回当前负载因子 +float load_factor() const noexcept { + return ht_.load_factor(); +} - void rehash(size_type count) { ht_.rehash(count); } - void reserve(size_type count) { ht_.reserve(count); } +// 返回最大负载因子 +float max_load_factor() const noexcept { + return ht_.max_load_factor(); +} +// 设置最大负载因子 +void max_load_factor(float ml) { + ht_.max_load_factor(ml); +} - hasher hash_fcn() const { return ht_.hash_fcn(); } - key_equal key_eq() const { return ht_.key_eq(); } +// 重新哈希,调整桶的数量 +void rehash(size_type count) { + ht_.rehash(count); +} +// 调整桶的数量以至少容纳指定数量的元素 +void reserve(size_type count) { + ht_.reserve(count); +} -public: - friend bool operator==(const unordered_multimap& lhs, const unordered_multimap& rhs) - { +// 返回哈希函数 +hasher hash_fcn() const { + return ht_.hash_fcn(); +} +// 返回键比较函数 +key_equal key_eq() const { + return ht_.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_); - } - friend bool operator!=(const unordered_multimap& lhs, const unordered_multimap& rhs) - { +} + +// 友元函数,重载比较操作符 != +// 比较两个 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) + const unordered_multimap& rhs) { - return lhs == rhs; + // 调用友元函数实现的比较逻辑 + return lhs == rhs; } +// 重载比较操作符 != +// 模板特化,使得可以不写明完整类型定义直接比较两个 unordered_multimap 对象是否不相等 template bool operator!=(const unordered_multimap& lhs, - const unordered_multimap& rhs) + const unordered_multimap& rhs) { - return lhs != rhs; + // 调用友元函数实现的比较逻辑 + return lhs != rhs; } -// 重载 mystl 的 swap +// 重载 mystl 的 swap 函数 +// 模板特化,使得可以不写明完整类型定义直接交换两个 unordered_multimap 对象的内容 template void swap(unordered_multimap& lhs, - unordered_multimap& rhs) + unordered_multimap& rhs) { - lhs.swap(rhs); + // 调用 unordered_multimap 类的 swap 成员函数 + lhs.swap(rhs); } -} // namespace mystl -#endif // !MYTINYSTL_UNORDERED_MAP_H_ +} // namespace mystl 结束命名空间 mystl + +#endif // !MYTINYSTL_UNORDERED_MAP_H_ 结束头文件保护