From 43772d3dd2756884e6dbc6b2b18f214ffff41794 Mon Sep 17 00:00:00 2001 From: sunjiawei <1911007196@qq.com> Date: Mon, 6 Jan 2025 20:35:41 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=99=E6=AE=B5=E4=BB=A3=E7=A0=81=E4=B8=BA?= =?UTF-8?q?=20`unordered=5Fmultimap`=20=E7=B1=BB=E6=8F=90=E4=BE=9B?= =?UTF-8?q?=E4=BA=86=E8=AF=A6=E7=BB=86=E7=9A=84=E6=A1=B6=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E5=92=8C=E5=93=88=E5=B8=8C=E7=AD=96=E7=95=A5=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E7=9A=84=E6=96=B9=E6=B3=95=EF=BC=8C=E4=BB=A5=E5=8F=8A=E5=8F=8B?= =?UTF-8?q?=E5=85=83=E5=87=BD=E6=95=B0=E5=92=8C=E9=87=8D=E8=BD=BD=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E7=AC=A6=E7=9A=84=E5=AE=9E=E7=8E=B0=E3=80=82=E6=A1=B6?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E5=85=81=E8=AE=B8=E7=94=A8=E6=88=B7=E8=AE=BF?= =?UTF-8?q?=E9=97=AE=E5=92=8C=E6=93=8D=E4=BD=9C=E5=AE=B9=E5=99=A8=E7=9A=84?= =?UTF-8?q?=E5=86=85=E9=83=A8=E6=A1=B6=E7=BB=93=E6=9E=84=EF=BC=8C=E5=8C=85?= =?UTF-8?q?=E6=8B=AC=E8=8E=B7=E5=8F=96=E6=A1=B6=E7=9A=84=E6=95=B0=E9=87=8F?= =?UTF-8?q?=E3=80=81=E5=A4=A7=E5=B0=8F=E5=92=8C=E7=89=B9=E5=AE=9A=E6=A1=B6?= =?UTF-8?q?=E7=9A=84=E8=BF=AD=E4=BB=A3=E5=99=A8=E3=80=82=E5=93=88=E5=B8=8C?= =?UTF-8?q?=E7=AD=96=E7=95=A5=E9=83=A8=E5=88=86=E6=8F=90=E4=BE=9B=E4=BA=86?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E5=92=8C=E8=AE=BE=E7=BD=AE=E8=B4=9F=E8=BD=BD?= =?UTF-8?q?=E5=9B=A0=E5=AD=90=E3=80=81=E5=93=88=E5=B8=8C=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E5=92=8C=E9=94=AE=E6=AF=94=E8=BE=83=E5=87=BD=E6=95=B0=E7=9A=84?= =?UTF-8?q?=E6=96=B9=E6=B3=95=EF=BC=8C=E4=BB=A5=E4=BE=BF=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E6=A0=B9=E6=8D=AE=E9=9C=80=E8=A6=81=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E5=AE=B9=E5=99=A8=E7=9A=84=E6=80=A7=E8=83=BD=E3=80=82?= =?UTF-8?q?=E6=AD=A4=E5=A4=96=EF=BC=8C=E5=8F=8B=E5=85=83=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E5=92=8C=E9=87=8D=E8=BD=BD=E6=93=8D=E4=BD=9C=E7=AC=A6=E4=BD=BF?= =?UTF-8?q?=E5=BE=97=E5=AE=B9=E5=99=A8=E4=B9=8B=E9=97=B4=E7=9A=84=E6=AF=94?= =?UTF-8?q?=E8=BE=83=E5=92=8C=E4=BA=A4=E6=8D=A2=E6=93=8D=E4=BD=9C=E6=9B=B4?= =?UTF-8?q?=E5=8A=A0=E6=96=B9=E4=BE=BF=E5=92=8C=E7=9B=B4=E8=A7=82=EF=BC=8C?= =?UTF-8?q?=E6=8F=90=E5=8D=87=E4=BA=86=E5=AE=B9=E5=99=A8=E7=9A=84=E6=98=93?= =?UTF-8?q?=E7=94=A8=E6=80=A7=E5=92=8C=E7=81=B5=E6=B4=BB=E6=80=A7=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MyTinySTL/unordered_map.h | 991 +++++++++--------- 1 file changed, 477 insertions(+), 514 deletions(-) diff --git a/src/MyTinySTL-master/MyTinySTL/unordered_map.h b/src/MyTinySTL-master/MyTinySTL/unordered_map.h index cb9d68f..4cf0e23 100644 --- a/src/MyTinySTL-master/MyTinySTL/unordered_map.h +++ b/src/MyTinySTL-master/MyTinySTL/unordered_map.h @@ -26,29 +26,29 @@ namespace mystl // 命名空间 mystl,用于封装自定义的 STL 组件 private: // 使用 hashtable 作为底层机制 typedef hashtable, Hash, KeyEqual> base_type; - base_type ht_; + base_type ht_; // 基础类型的实例,用于存储数据 public: // 使用 hashtable 的型别 // 以下定义了与 hashtable 相关的类型别名,方便在 unordered_map 中使用 - typedef typename base_type::allocator_type allocator_type; - typedef typename base_type::key_type key_type; - typedef typename base_type::mapped_type mapped_type; - typedef typename base_type::value_type value_type; - typedef typename base_type::hasher hasher; - typedef typename base_type::key_equal key_equal; - - typedef typename base_type::size_type size_type; - typedef typename base_type::difference_type difference_type; - typedef typename base_type::pointer pointer; - typedef typename base_type::const_pointer const_pointer; - typedef typename base_type::reference reference; - typedef typename base_type::const_reference const_reference; - - typedef typename base_type::iterator iterator; - typedef typename base_type::const_iterator const_iterator; - typedef typename base_type::local_iterator local_iterator; - typedef typename base_type::const_local_iterator const_local_iterator; + typedef typename base_type::allocator_type allocator_type; // 分配器类型 + typedef typename base_type::key_type key_type; // 键类型 + typedef typename base_type::mapped_type mapped_type; // 映射类型 + typedef typename base_type::value_type value_type; // 值类型 + typedef typename base_type::hasher hasher; // 哈希函数类型 + typedef typename base_type::key_equal key_equal; // 键值比较函数类型 + + typedef typename base_type::size_type size_type; // 容器大小类型 + typedef typename base_type::difference_type difference_type;// 容器差值类型 + typedef typename base_type::pointer pointer; // 指针类型 + typedef typename base_type::const_pointer const_pointer; // 常量指针类型 + typedef typename base_type::reference reference; // 引用类型 + typedef typename base_type::const_reference const_reference;// 常量引用类型 + + typedef typename base_type::iterator iterator; // 迭代器类型 + typedef typename base_type::const_iterator const_iterator; // 常量迭代器类型 + typedef typename base_type::local_iterator local_iterator; // 本地迭代器类型 + typedef typename base_type::const_local_iterator const_local_iterator; // 常量本地迭代器类型 allocator_type get_allocator() const { return ht_.get_allocator(); } // 获取分配器 @@ -77,7 +77,7 @@ namespace mystl // 命名空间 mystl,用于封装自定义的 STL 组件 : ht_(mystl::max(bucket_count, static_cast(mystl::distance(first, last))), hash, equal) { for (; first != last; ++first) - ht_.insert_unique_noresize(*first); + ht_.insert_unique_noresize(*first); // 插入元素,不调整桶大小 } // 初始化列表构造函数,从给定的值初始化 unordered_map @@ -88,7 +88,7 @@ namespace mystl // 命名空间 mystl,用于封装自定义的 STL 组件 :ht_(mystl::max(bucket_count, static_cast(ilist.size())), hash, equal) { for (auto first = ilist.begin(), last = ilist.end(); first != last; ++first) - ht_.insert_unique_noresize(*first); + ht_.insert_unique_noresize(*first); // 插入元素,不调整桶大小 } // 复制构造函数 @@ -102,292 +102,292 @@ namespace mystl // 命名空间 mystl,用于封装自定义的 STL 组件 :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=(const unordered_map& rhs) + { + ht_ = 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& operator=(unordered_map&& rhs) + { + ht_ = mystl::move(rhs.ht_); + return *this; + } - // 默认析构函数 - ~unordered_map() = default; + // 从初始化列表赋值 + 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; + } - // 迭代器相关 - // 返回指向第一个元素的迭代器 - 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(); - } + // 默认析构函数 + ~unordered_map() = default; - // 返回指向第一个元素的常量迭代器(cbegin 和 cend 是 C++11 新增的,用于明确表达“常量迭代器”) - const_iterator cbegin() const noexcept - { - return ht_.cbegin(); - } - const_iterator cend() const noexcept - { - return ht_.cend(); - } + // 迭代器相关 + // 返回指向第一个元素的迭代器 + 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(); + } - // 容量相关 - // 检查容器是否为空 - 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(); } + // 返回指向第一个元素的常量迭代器(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)...); - } + // emplace / emplace_hint + // 就地构造元素,返回插入的迭代器和是否插入的布尔值 + template + pair emplace(Args&& ...args) + { + return ht_.emplace_unique(mystl::forward(args)...); + } - // insert + // 就地构造元素,并使用 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)); - } +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 提示插入位置,并插入移动构造的元素 - iterator insert(const_iterator hint, value_type&& value) - { - return ht_.emplace_unique_use_hint(hint, mystl::move(value)); - } +// 使用 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); - } +// 从迭代器范围插入元素 +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); - } +// 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); - } +// 删除指定键的元素,并返回被删除的元素数量 +size_type erase(const key_type& key) +{ + return ht_.erase_unique(key); // 调用底层 hashtable 的 erase_unique 方法 +} - // 清空容器 - void clear() - { - ht_.clear(); - } +// 清空容器 +void clear() +{ + ht_.clear(); // 调用底层 hashtable 的 clear 方法 +} - // 交换两个 unordered_map 对象的内容 - void swap(unordered_map& other) noexcept - { - ht_.swap(other.ht_); - } +// 交换两个 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& 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[](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; - } +// 下标操作符重载,用于移动构造的键 +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); - } +// 计算给定键的元素数量 +size_type count(const key_type& key) const +{ + return ht_.count(key); // 调用底层 hashtable 的 count 方法 +} - // 查找元素 - iterator find(const key_type& key) - { - return ht_.find(key); - } - const_iterator find(const key_type& key) const - { - return ht_.find(key); - } +// 查找元素 +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); - } - pair equal_range(const key_type& key) const - { - return ht_.equal_range_unique(key); - } +// 返回给定键的元素范围 +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); - } - 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 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); - } - 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 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(); - } - size_type max_bucket_count() const noexcept - { - return ht_.max_bucket_count(); - } +// 返回桶的数量 +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); - } - // 返回给定键的元素所在的桶编号 - size_type bucket(const key_type& key) const - { - return ht_.bucket(key); - } +// 返回指定桶的大小 +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 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 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); } +// 重新哈希,调整桶的数量 +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(); } +// 返回哈希函数 +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_); + return lhs.ht_.equal_range_unique(rhs.ht_); // 比较两个 unordered_map 是否相等 } friend bool operator!=(const unordered_map& lhs, const unordered_map& rhs) { - return !lhs.ht_.equal_range_unique(rhs.ht_); + return !lhs.ht_.equal_range_unique(rhs.ht_); // 比较两个 unordered_map 是否不相等 } }; @@ -396,14 +396,14 @@ template bool operator==(const unordered_map& lhs, const unordered_map& rhs) { - return lhs == rhs; + return lhs == rhs; // 使用友元函数中的比较逻辑 } template bool operator!=(const unordered_map& lhs, const unordered_map& rhs) { - return lhs != rhs; + return lhs != rhs; // 使用友元函数中的比较逻辑 } // 重载 mystl 的 swap 函数 @@ -411,49 +411,40 @@ template void swap(unordered_map& lhs, unordered_map& rhs) { - lhs.swap(rhs); + lhs.swap(rhs); // 调用 unordered_map 的 swap 方法 } -// 模板类 unordered_multimap,键值允许重复 -// 参数一代表键值类型,参数二代表实值类型,参数三代表哈希函数,缺省使用 mystl::hash -// 参数四代表键值比较方式,缺省使用 mystl::equal_to -template , class KeyEqual = mystl::equal_to> -class unordered_multimap -{ -private: - // 使用 hashtable 作为底层机制 - typedef hashtable, Hash, KeyEqual> base_type; - base_type ht_; +// 模板类 unordered_multimap,键值允许重复 public: // 使用 hashtable 的型别 // 以下定义了与 hashtable 相关的类型别名,方便在 unordered_multimap 中使用 - typedef typename base_type::allocator_type allocator_type; - typedef typename base_type::key_type key_type; - typedef typename base_type::mapped_type mapped_type; - typedef typename base_type::value_type value_type; - typedef typename base_type::hasher hasher; - typedef typename base_type::key_equal key_equal; - - typedef typename base_type::size_type size_type; - typedef typename base_type::difference_type difference_type; - typedef typename base_type::pointer pointer; - typedef typename base_type::const_pointer const_pointer; - typedef typename base_type::reference reference; - typedef typename base_type::const_reference const_reference; - - typedef typename base_type::iterator iterator; - typedef typename base_type::const_iterator const_iterator; - typedef typename base_type::local_iterator local_iterator; - typedef typename base_type::const_local_iterator const_local_iterator; + typedef typename base_type::allocator_type allocator_type; // 分配器类型 + typedef typename base_type::key_type key_type; // 键类型 + typedef typename base_type::mapped_type mapped_type; // 映射类型 + typedef typename base_type::value_type value_type; // 值类型 + typedef typename base_type::hasher hasher; // 哈希函数类型 + typedef typename base_type::key_equal key_equal; // 键值比较函数类型 + + typedef typename base_type::size_type size_type; // 容器大小类型 + typedef typename base_type::difference_type difference_type;// 容器差值类型 + typedef typename base_type::pointer pointer; // 指针类型 + typedef typename base_type::const_pointer const_pointer; // 常量指针类型 + typedef typename base_type::reference reference; // 引用类型 + typedef typename base_type::const_reference const_reference;// 常量引用类型 + + typedef typename base_type::iterator iterator; // 迭代器类型 + typedef typename base_type::const_iterator const_iterator; // 常量迭代器类型 + typedef typename base_type::local_iterator local_iterator; // 本地迭代器类型 + typedef typename base_type::const_local_iterator const_local_iterator; // 常量本地迭代器类型 // 获取分配器 - allocator_type get_allocator() const { return ht_.get_allocator(); } + allocator_type get_allocator() const { return ht_.get_allocator(); } // 返回底层 hashtable 的分配器 public: // 构造、复制、移动函数 // 默认构造函数,初始化一个空的 unordered_multimap unordered_multimap() - :ht_(100, Hash(), KeyEqual()) + :ht_(100, Hash(), KeyEqual()) // 初始化底层 hashtable,设置默认桶数量为 100 { } @@ -461,7 +452,7 @@ public: explicit unordered_multimap(size_type bucket_count, const Hash& hash = Hash(), const KeyEqual& equal = KeyEqual()) - :ht_(bucket_count, hash, equal) + :ht_(bucket_count, hash, equal) // 初始化底层 hashtable,设置桶数量、哈希函数和键值比较函数 { } @@ -471,7 +462,7 @@ public: const size_type bucket_count = 100, const Hash& hash = Hash(), const KeyEqual& equal = KeyEqual()) - : ht_(mystl::max(bucket_count, static_cast(mystl::distance(first, last))), hash, equal) + : ht_(mystl::max(bucket_count, static_cast(mystl::distance(first, last))), hash, equal) // 初始化底层 hashtable,设置桶数量、哈希函数和键值比较函数 { for (; first != last; ++first) ht_.insert_multi_noresize(*first); // 插入元素,不调整桶大小 @@ -482,7 +473,7 @@ public: const size_type bucket_count = 100, const Hash& hash = Hash(), const KeyEqual& equal = KeyEqual()) - :ht_(mystl::max(bucket_count, static_cast(ilist.size())), hash, equal) + :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); // 插入元素,不调整桶大小 @@ -490,25 +481,25 @@ public: // 复制构造函数 unordered_multimap(const unordered_multimap& rhs) - :ht_(rhs.ht_) + :ht_(rhs.ht_) // 深拷贝底层 hashtable { } // 移动构造函数 unordered_multimap(unordered_multimap&& rhs) noexcept - :ht_(mystl::move(rhs.ht_)) + :ht_(mystl::move(rhs.ht_)) // 移动底层 hashtable { } // 赋值运算符重载 unordered_multimap& operator=(const unordered_multimap& rhs) { - ht_ = rhs.ht_; + ht_ = rhs.ht_; // 深拷贝底层 hashtable return *this; } unordered_multimap& operator=(unordered_multimap&& rhs) { - ht_ = mystl::move(rhs.ht_); + ht_ = mystl::move(rhs.ht_); // 移动底层 hashtable return *this; } @@ -523,238 +514,210 @@ public: } // 默认析构函数 - ~unordered_multimap() = default; -}; + ~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)...); -} - -// 就地构造元素,并使用 hint 提示插入位置,返回插入的迭代器 -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)); -} + 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 常量迭代器 -// 使用 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)); -} + // 返回指向第一个元素的常量迭代器(cbegin 和 cend 是 C++11 新增的,用于明确表达“常量迭代器”) + const_iterator cbegin() const noexcept { return ht_.cbegin(); } // 返回底层 hashtable 的 cbegin 常量迭代器 + const_iterator cend() const noexcept { return ht_.cend(); } // 返回底层 hashtable 的 cend 常量迭代器 -// 从迭代器范围插入元素 -template -void insert(InputIterator first, InputIterator last) { - ht_.insert_multi(first, last); -} + // 容量相关 + // 检查容器是否为空 + 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 的最大元素数量 -// 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); -} + // emplace / emplace_hint + // 就地构造元素,返回插入的迭代器 + template + iterator emplace(Args&& ...args) { + return ht_.emplace_multi(mystl::forward(args)...); // 就地构造元素并插入 + } -// 清空容器 -void clear() { - ht_.clear(); -} + // 就地构造元素,并使用 hint 提示插入位置,返回插入的迭代器 + template + iterator emplace_hint(const_iterator hint, Args&& ...args) { + return ht_.emplace_multi_use_hint(hint, mystl::forward(args)...); // 使用 hint 提示插入位置并就地构造元素 + } -// 交换两个 unordered_multimap 对象的内容 -void swap(unordered_multimap& other) noexcept { - ht_.swap(other.ht_); -} + // insert + // 插入元素,返回插入的迭代器 + iterator insert(const value_type & value) { + return ht_.insert_multi(value); // 插入元素 + } + // 插入移动构造的元素 + iterator insert(value_type && value) { + return ht_.emplace_multi(mystl::move(value)); // 插入移动构造的元素 + } -// 查找相关 -// 返回指定键的元素数量 -size_type count(const key_type& key) const { - return ht_.count(key); -} + // 使用 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 提示插入位置并插入移动构造的元素 + } -// 查找元素 -iterator find(const key_type& key) { - return ht_.find(key); -} -const_iterator find(const key_type& key) const { - return ht_.find(key); -} + // 从迭代器范围插入元素 + template + void insert(InputIterator first, InputIterator last) { + ht_.insert_multi(first, last); // 插入范围内的所有元素 + } -// 返回给定键的元素范围 -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); -} + // 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); // 删除指定键的所有元素 + } -// 返回指定桶的本地迭代器 -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); -} + // 清空容器 + void clear() { + ht_.clear(); // 清空底层 hashtable + } + // 桶接口 -// 返回指定桶的本地迭代器 -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); // 调用底层 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 方法,返回指定桶的本地常量迭代器 + } -// 返回桶的数量 -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); // 调用底层 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_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(); // 调用底层 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); -} + // 返回当前负载因子 + float load_factor() const noexcept { + return ht_.load_factor(); // 调用底层 hashtable 的 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(); // 调用底层 hashtable 的 max_load_factor 方法,返回最大负载因子 + } + // 设置最大负载因子 + void max_load_factor(float ml) { + ht_.max_load_factor(ml); // 调用底层 hashtable 的 max_load_factor 方法,设置最大负载因子 + } -// 返回哈希函数 -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_); -} + // 重新哈希,调整桶的数量 + void rehash(size_type count) { + ht_.rehash(count); // 调用底层 hashtable 的 rehash 方法,重新哈希并调整桶的数量 + } + // 调整桶的数量以至少容纳指定数量的元素 + void reserve(size_type count) { + ht_.reserve(count); // 调用底层 hashtable 的 reserve 方法,调整桶的数量以至少容纳指定数量的元素 + } -// 友元函数,重载比较操作符 != -// 比较两个 unordered_multimap 对象是否不相等 -friend bool operator!=(const unordered_multimap& lhs, const unordered_multimap& rhs) -{ - // 直接返回 == 操作符的相反结果 - return !lhs.ht_.equal_range_multi(rhs.ht_); -} + // 返回哈希函数 + 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 对象是否相等 -template -bool operator==(const unordered_multimap& lhs, - const unordered_multimap& rhs) -{ - // 调用友元函数实现的比较逻辑 - return lhs == rhs; -} + // 友元函数,重载比较操作符 == + // 比较两个 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 对象是否不相等 -template -bool operator!=(const unordered_multimap& lhs, - const unordered_multimap& rhs) -{ - // 调用友元函数实现的比较逻辑 - return lhs != rhs; -} + // 友元函数,重载比较操作符 != + // 比较两个 unordered_multimap 对象是否不相等 + friend bool operator!=(const unordered_multimap& lhs, const unordered_multimap& rhs) + { + // 直接返回 == 操作符的相反结果 + return !lhs.ht_.equal_range_multi(rhs.ht_); + } -// 重载 mystl 的 swap 函数 -// 模板特化,使得可以不写明完整类型定义直接交换两个 unordered_multimap 对象的内容 -template -void swap(unordered_multimap& lhs, - unordered_multimap& rhs) -{ - // 调用 unordered_multimap 类的 swap 成员函数 - lhs.swap(rhs); -} + // 重载比较操作符 == + // 模板特化,使得可以不写明完整类型定义直接比较两个 unordered_multimap 对象是否相等 + template + bool operator==(const unordered_multimap& lhs, + const unordered_multimap& rhs) + { + // 调用友元函数实现的比较逻辑 + return lhs == rhs; + } -} // namespace mystl 结束命名空间 mystl + // 重载比较操作符 != + // 模板特化,使得可以不写明完整类型定义直接比较两个 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); + } -#endif // !MYTINYSTL_UNORDERED_MAP_H_ 结束头文件保护 +} // namespace mystl 结束命名空间 mystl +#endif // !MYTINYSTL_UNORDERED_MAP_H_ 结束头文件保护 \ No newline at end of file