From 5e94302b07c353fba64ecb5149433c698897406c Mon Sep 17 00:00:00 2001 From: sunjiawei <1911007196@qq.com> Date: Wed, 25 Dec 2024 08:45:08 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A5=E4=B8=8A=E6=B3=A8=E9=87=8A=E8=AF=A6?= =?UTF-8?q?=E7=BB=86=E8=A7=A3=E9=87=8A=E4=BA=86=20`unordered=5Fset`=20?= =?UTF-8?q?=E5=92=8C=20`unordered=5Fmultiset`=20=E8=BF=99=E4=B8=A4?= =?UTF-8?q?=E4=B8=AA=E5=9F=BA=E4=BA=8E=E5=93=88=E5=B8=8C=E8=A1=A8=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E7=9A=84=E5=AE=B9=E5=99=A8=E7=B1=BB=E3=80=82=E8=BF=99?= =?UTF-8?q?=E4=BA=9B=E7=B1=BB=E6=8F=90=E4=BE=9B=E4=BA=86=E6=9E=84=E9=80=A0?= =?UTF-8?q?=E3=80=81=E5=A4=8D=E5=88=B6=E3=80=81=E7=A7=BB=E5=8A=A8=E3=80=81?= =?UTF-8?q?=E8=BF=AD=E4=BB=A3=E5=99=A8=E6=93=8D=E4=BD=9C=E3=80=81=E5=AE=B9?= =?UTF-8?q?=E9=87=8F=E6=9F=A5=E8=AF=A2=E3=80=81=E5=85=83=E7=B4=A0=E6=8F=92?= =?UTF-8?q?=E5=85=A5=E4=B8=8E=E5=88=A0=E9=99=A4=E3=80=81=E6=9F=A5=E6=89=BE?= =?UTF-8?q?=E4=BB=A5=E5=8F=8A=E6=A1=B6=E7=AE=A1=E7=90=86=E7=AD=89=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E3=80=82=E5=AE=83=E4=BB=AC=E5=85=81=E8=AE=B8=E5=BC=80?= =?UTF-8?q?=E5=8F=91=E8=80=85=E5=9C=A8=E4=B8=8D=E4=BF=9D=E8=AF=81=E5=85=83?= =?UTF-8?q?=E7=B4=A0=E9=A1=BA=E5=BA=8F=E7=9A=84=E6=83=85=E5=86=B5=E4=B8=8B?= =?UTF-8?q?=EF=BC=8C=E9=AB=98=E6=95=88=E5=9C=B0=E8=BF=9B=E8=A1=8C=E5=85=83?= =?UTF-8?q?=E7=B4=A0=E7=9A=84=E5=AD=98=E5=82=A8=E5=92=8C=E6=A3=80=E7=B4=A2?= =?UTF-8?q?=EF=BC=8C=E5=85=B6=E4=B8=AD=20`unordered=5Fset`=20=E4=B8=8D?= =?UTF-8?q?=E5=85=81=E8=AE=B8=E9=94=AE=E5=80=BC=E9=87=8D=E5=A4=8D=EF=BC=8C?= =?UTF-8?q?=E8=80=8C=20`unordered=5Fmultiset`=20=E5=85=81=E8=AE=B8?= =?UTF-8?q?=E9=94=AE=E5=80=BC=E9=87=8D=E5=A4=8D=E3=80=82=E6=AD=A4=E5=A4=96?= =?UTF-8?q?=EF=BC=8C=E8=BF=98=E5=8C=85=E6=8B=AC=E4=BA=86=E6=AF=94=E8=BE=83?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=E7=AC=A6=E7=9A=84=E9=87=8D=E8=BD=BD=E5=92=8C?= =?UTF-8?q?=20`swap`=20=E5=87=BD=E6=95=B0=E7=9A=84=E7=89=B9=E5=8C=96?= =?UTF-8?q?=EF=BC=8C=E4=BB=A5=E6=94=AF=E6=8C=81=E5=AE=B9=E5=99=A8=E9=97=B4?= =?UTF-8?q?=E7=9A=84=E6=AF=94=E8=BE=83=E5=92=8C=E6=95=B0=E6=8D=AE=E4=BA=A4?= =?UTF-8?q?=E6=8D=A2=E3=80=82=E8=BF=99=E4=BA=9B=E5=AE=B9=E5=99=A8=E7=9A=84?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E9=81=B5=E5=BE=AA=E5=BC=82=E5=B8=B8=E5=AE=89?= =?UTF-8?q?=E5=85=A8=E4=BF=9D=E8=AF=81=EF=BC=8C=E5=85=B6=E4=B8=AD=20`empla?= =?UTF-8?q?ce`=E3=80=81`emplace=5Fhint`=20=E5=92=8C=20`insert`=20=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E6=8F=90=E4=BE=9B=E5=BC=BA=E5=BC=82=E5=B8=B8=E5=AE=89?= =?UTF-8?q?=E5=85=A8=E4=BF=9D=E8=AF=81=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MyTinySTL/unordered_set.h | 905 ++++++++++-------- 1 file changed, 524 insertions(+), 381 deletions(-) diff --git a/src/MyTinySTL-master/MyTinySTL-master/MyTinySTL/unordered_set.h b/src/MyTinySTL-master/MyTinySTL-master/MyTinySTL/unordered_set.h index eb60589..e6da81c 100755 --- a/src/MyTinySTL-master/MyTinySTL-master/MyTinySTL/unordered_set.h +++ b/src/MyTinySTL-master/MyTinySTL-master/MyTinySTL/unordered_set.h @@ -1,118 +1,44 @@ -#ifndef MYTINYSTL_UNORDERED_SET_H_ -#define MYTINYSTL_UNORDERED_SET_H_ - -// 这个头文件包含两个模板类 unordered_set 和 unordered_multiset -// 功能与用法与 set 和 multiset 类似,不同的是使用 hashtable 作为底层实现机制,容器中的元素不会自动排序 - -// notes: -// -// 异常保证: -// mystl::unordered_set / mystl::unordered_multiset 满足基本异常保证,对以下等函数做强异常安全保证: -// * emplace -// * emplace_hint -// * insert - -#include "hashtable.h" - -namespace mystl -{ - -// 模板类 unordered_set,键值不允许重复 -// 参数一代表键值类型,参数二代表哈希函数,缺省使用 mystl::hash, -// 参数三代表键值比较方式,缺省使用 mystl::equal_to -template , class KeyEqual = mystl::equal_to> -class unordered_set -{ -private: - // 使用 hashtable 作为底层机制 - typedef hashtable base_type; - base_type ht_; - -public: - // 使用 hashtable 的型别 - typedef typename base_type::allocator_type allocator_type; - typedef typename base_type::key_type key_type; - typedef typename base_type::value_type value_type; - typedef typename base_type::hasher hasher; - typedef typename base_type::key_equal key_equal; - - typedef typename base_type::size_type size_type; - typedef typename base_type::difference_type difference_type; - typedef typename base_type::pointer pointer; - typedef typename base_type::const_pointer const_pointer; - typedef typename base_type::reference reference; - typedef typename base_type::const_reference const_reference; - - typedef typename base_type::const_iterator iterator; - typedef typename base_type::const_iterator const_iterator; - typedef typename base_type::const_local_iterator local_iterator; - typedef typename base_type::const_local_iterator const_local_iterator; - - allocator_type get_allocator() const { return ht_.get_allocator(); } - -public: - // 构造、复制、移动函数 - - unordered_set() - :ht_(100, Hash(), KeyEqual()) - { - } - - explicit unordered_set(size_type bucket_count, - const Hash& hash = Hash(), - const KeyEqual& equal = KeyEqual()) - :ht_(bucket_count, hash, equal) - { - } - - template - unordered_set(InputIterator first, InputIterator last, - const size_type bucket_count = 100, - const Hash& hash = Hash(), - const KeyEqual& equal = KeyEqual()) - : ht_(mystl::max(bucket_count, static_cast(mystl::distance(first, last))), hash, equal) - { - for (; first != last; ++first) - ht_.insert_unique_noresize(*first); +for (; first != last; ++first) +ht_.insert_unique_noresize(*first); } unordered_set(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) + 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); + for (auto first = ilist.begin(), last = ilist.end(); first != last; ++first) + ht_.insert_unique_noresize(*first); } unordered_set(const unordered_set& rhs) - :ht_(rhs.ht_) + :ht_(rhs.ht_) { } unordered_set(unordered_set&& rhs) noexcept - : ht_(mystl::move(rhs.ht_)) + : ht_(mystl::move(rhs.ht_)) { } unordered_set& operator=(const unordered_set& rhs) { - ht_ = rhs.ht_; - return *this; + ht_ = rhs.ht_; + return *this; } unordered_set& operator=(unordered_set&& rhs) { - ht_ = mystl::move(rhs.ht_); - return *this; + ht_ = mystl::move(rhs.ht_); + return *this; } unordered_set& 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; + 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_set() = default; @@ -120,18 +46,30 @@ public: // 迭代器相关 iterator begin() noexcept - { return ht_.begin(); } + { + return ht_.begin(); + } const_iterator begin() const noexcept - { return ht_.begin(); } + { + return ht_.begin(); + } iterator end() noexcept - { return ht_.end(); } + { + return ht_.end(); + } const_iterator end() const noexcept - { return ht_.end(); } + { + return ht_.end(); + } const_iterator cbegin() const noexcept - { return ht_.cbegin(); } + { + return ht_.cbegin(); + } const_iterator cend() const noexcept - { return ht_.cend(); } + { + return ht_.cend(); + } // 容量相关 @@ -145,131 +83,209 @@ public: template pair emplace(Args&& ...args) - { return ht_.emplace_unique(mystl::forward(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)...); } + { + 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); + } + 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)); } + 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); } + { + ht_.insert_unique(first, last); + } // erase / clear void erase(iterator it) - { ht_.erase(it); } + { + ht_.erase(it); + } void erase(iterator first, iterator last) - { ht_.erase(first, 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); + } void clear() - { ht_.clear(); } + { + ht_.clear(); + } - void swap(unordered_set& other) noexcept - { ht_.swap(other.ht_); } + void swap(unordered_set & other) noexcept + { + ht_.swap(other.ht_); + } // 查找相关 - size_type count(const key_type& key) const - { return ht_.count(key); } + size_type count(const key_type & key) const + { + return ht_.count(key); + } - iterator find(const key_type& key) - { return ht_.find(key); } - const_iterator find(const key_type& key) const - { return ht_.find(key); } + iterator find(const key_type & key) + { + return ht_.find(key); + } + ```c+ + + // 查找相关(续) + + // 在 const 版本中查找指定键的迭代器 + 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); } + { + return ht_.equal_range_unique(key); + } + // 返回一个常量迭代器对,表示下界和上界,用于查找指定键的范围(const 版本) pair equal_range(const key_type& key) const - { return ht_.equal_range_unique(key); } + { + return ht_.equal_range_unique(key); + } // bucket interface + // 返回指定桶的本地迭代器 local_iterator begin(size_type n) noexcept - { return ht_.begin(n); } + { + return ht_.begin(n); + } + // 返回指定桶的常量本地迭代器(const 版本) const_local_iterator begin(size_type n) const noexcept - { return ht_.begin(n); } + { + return ht_.begin(n); + } + // 返回指定桶的常量本地迭代器(const 版本,C++11 范围for循环使用) const_local_iterator cbegin(size_type n) const noexcept - { return ht_.cbegin(n); } + { + return ht_.cbegin(n); + } + // 返回指定桶的结束本地迭代器 local_iterator end(size_type n) noexcept - { return ht_.end(n); } + { + return ht_.end(n); + } + // 返回指定桶的常量本地迭代器(const 版本) const_local_iterator end(size_type n) const noexcept - { return ht_.end(n); } + { + return ht_.end(n); + } + // 返回指定桶的常量本地迭代器(const 版本,C++11 范围for循环使用) const_local_iterator cend(size_type n) const noexcept - { return ht_.cend(n); } + { + return ht_.cend(n); + } + // 返回桶的数量 size_type bucket_count() const noexcept - { return ht_.bucket_count(); } + { + return ht_.bucket_count(); + } + // 返回最大桶的数量 size_type max_bucket_count() const noexcept - { return ht_.max_bucket_count(); } + { + return ht_.max_bucket_count(); + } + // 返回指定桶的大小 size_type bucket_size(size_type n) const noexcept - { return ht_.bucket_size(n); } + { + return ht_.bucket_size(n); + } + // 返回指定键所在的桶编号 size_type bucket(const key_type& key) const - { return ht_.bucket(key); } + { + 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 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(); } + // 重新哈希,桶的数量至少为 count + void rehash(size_type count) { ht_.rehash(count); } + // 重新分配桶,使得桶的数量至少为 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_set& lhs, const unordered_set& rhs) - { - return lhs.ht_.equal_range_unique(rhs.ht_); - } - friend bool operator!=(const unordered_set& lhs, const unordered_set& rhs) - { - return !lhs.ht_.equal_range_unique(rhs.ht_); - } + // 友元函数,用于比较两个 unordered_set 是否相等 + friend bool operator==(const unordered_set& lhs, const unordered_set& rhs) + { + return lhs.ht_.equal_range_unique(rhs.ht_); + } + // 友元函数,用于比较两个 unordered_set 是否不相等 + friend bool operator!=(const unordered_set& lhs, const unordered_set& rhs) + { + return !lhs.ht_.equal_range_unique(rhs.ht_); + } }; // 重载比较操作符 template bool operator==(const unordered_set& lhs, - const unordered_set& rhs) + const unordered_set& rhs) { - return lhs == rhs; + return lhs == rhs; } template bool operator!=(const unordered_set& lhs, - const unordered_set& rhs) + const unordered_set& rhs) { - return lhs != rhs; + return lhs != rhs; } // 重载 mystl 的 swap template void swap(unordered_set& lhs, - unordered_set& rhs) + unordered_set& rhs) { - lhs.swap(rhs); + lhs.swap(rhs); } /*****************************************************************************************/ @@ -281,254 +297,381 @@ template , class KeyEqual = mystl::equa class unordered_multiset { private: - // 使用 hashtable 作为底层机制 - typedef hashtable base_type; - base_type ht_; + // 使用 hashtable 作为底层机制 + typedef hashtable base_type; + base_type ht_; public: - // 使用 hashtable 的型别 - typedef typename base_type::allocator_type allocator_type; - typedef typename base_type::key_type key_type; - typedef typename base_type::value_type value_type; - typedef typename base_type::hasher hasher; - typedef typename base_type::key_equal key_equal; - - typedef typename base_type::size_type size_type; - typedef typename base_type::difference_type difference_type; - typedef typename base_type::pointer pointer; - typedef typename base_type::const_pointer const_pointer; - typedef typename base_type::reference reference; - typedef typename base_type::const_reference const_reference; - - typedef typename base_type::const_iterator iterator; - typedef typename base_type::const_iterator const_iterator; - typedef typename base_type::const_local_iterator local_iterator; - typedef typename base_type::const_local_iterator const_local_iterator; - - allocator_type get_allocator() const { return ht_.get_allocator(); } - + // 使用 hashtable 的型别 + typedef typename base_type::allocator_type allocator_type; // 存储分配器类型 + typedef typename base_type::key_type key_type; // 键类型 + typedef typename base_type::value_type value_type; // 值类型,与键类型相同 + typedef typename base_type::hasher hasher; // 哈希函数类型 + typedef typename base_type::key_equal key_equal; // 键比较函数类型 + + typedef typename base_type::size_type size_type; // 容器大小类型 + typedef typename base_type::difference_type difference_type;// 差值类型 + typedef typename base_type::pointer pointer; // 指针类型 + typedef typename base_type::const_pointer const_pointer; // 常量指针类型 + typedef typename base_type::reference reference; // 引用类型 + typedef typename base_type::const_reference const_reference;// 常量引用类型 + + typedef typename base_type::const_iterator iterator; // 迭代器类型 + typedef typename base_type::const_iterator const_iterator; // 常量迭代器类型 + typedef typename base_type::const_local_iterator local_iterator; // 本地迭代器类型 + typedef typename base_type::const_local_iterator const_local_iterator; // 常量本地迭代器类型 + + // 获取分配器 + allocator_type get_allocator() const { return ht_.get_allocator(); } + ``` + + ```c+ + public: - // 构造、复制、移动函数 - - unordered_multiset() - :ht_(100, Hash(), KeyEqual()) - { - } - - explicit unordered_multiset(size_type bucket_count, - const Hash& hash = Hash(), - const KeyEqual& equal = KeyEqual()) - :ht_(bucket_count, hash, equal) - { - } - - template - unordered_multiset(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_multiset(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_multiset(const unordered_multiset& rhs) - :ht_(rhs.ht_) - { - } - unordered_multiset(unordered_multiset&& rhs) noexcept - : ht_(mystl::move(rhs.ht_)) - { - } - - unordered_multiset& operator=(const unordered_multiset& rhs) - { - ht_ = rhs.ht_; - return *this; - } - unordered_multiset& operator=(unordered_multiset&& rhs) - { - ht_ = mystl::move(rhs.ht_); - return *this; - } - - unordered_multiset& 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_multiset() = 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)); } - - 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)); } - - 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(); } - - void swap(unordered_multiset& other) noexcept - { ht_.swap(other.ht_); } - - // 查找相关 - - 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_multi(key); } - pair equal_range(const key_type& key) const - { return ht_.equal_range_multi(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(); } + // 构造、复制、移动函数 + + // 默认构造函数,初始化桶的数量为100,使用默认的哈希函数和键比较函数 + unordered_multiset() + :ht_(100, Hash(), KeyEqual()) + { + } + + // 构造函数,指定桶的数量,哈希函数和键比较函数 + explicit unordered_multiset(size_type bucket_count, + const Hash& hash = Hash(), + const KeyEqual& equal = KeyEqual()) + :ht_(bucket_count, hash, equal) + { + } + + // 构造函数,从迭代器范围构造,指定桶的数量,哈希函数和键比较函数 + template + unordered_multiset(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_multiset(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_multiset(const unordered_multiset& rhs) + :ht_(rhs.ht_) + { + } + + // 移动构造函数 + unordered_multiset(unordered_multiset&& rhs) noexcept + : ht_(mystl::move(rhs.ht_)) + { + } + + // 复制赋值运算符 + unordered_multiset& operator=(const unordered_multiset& rhs) + { + ht_ = rhs.ht_; + return *this; + } + + // 移动赋值运算符 + unordered_multiset& operator=(unordered_multiset&& rhs) + { + ht_ = mystl::move(rhs.ht_); + return *this; + } + + // 从初始化列表赋值 + unordered_multiset& 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_multiset() = default; + + // 迭代器相关 + + // 返回指向第一个元素的迭代器 + iterator begin() noexcept + { + return ht_.begin(); + } + // 返回指向第一个元素的常量迭代器(const 版本) + const_iterator begin() const noexcept + { + return ht_.begin(); + } + // 返回指向最后一个元素的迭代器 + iterator end() noexcept + { + return ht_.end(); + } + // 返回指向最后一个元素的常量迭代器(const 版本) + const_iterator end() const noexcept + { + return ht_.end(); + } + + // 返回指向第一个元素的常量迭代器(const 版本,C++11 范围for循环使用) + const_iterator cbegin() const noexcept + { + return ht_.cbegin(); + } + // 返回指向最后一个元素的常量迭代器(const 版本,C++11 范围for循环使用) + 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)); + } + + // 插入元素,使用 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)); + } + + // 插入迭代器范围的元素 + 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(); + } + + // 交换两个 unordered_multiset 的内容 + void swap(unordered_multiset & other) noexcept + { + ht_.swap(other.ht_); + } + + // 查找相关 + + // 返回指定键出现的次数 + size_type count(const key_type & key) const + { + return ht_.count(key); + } + + // 查找指定键的迭代器 + iterator find(const key_type & key) + { + return ht_.find(key); + } + // 查找指定键的常量迭代器(const 版本) + const_iterator find(const key_type & key) const + { + return ht_.find(key); + } + + // 返回一个迭代器对,表示下界和上界,用于查找指定键的范围 + pair equal_range(const key_type & key) + { + return ht_.equal_range_multi(key); + } + // 返回一个常量迭代器对,表示下界和上界,用于查找指定键的范围(const 版本) + pair equal_range(const key_type & key) const + { + return ht_.equal_range_multi(key); + } + ``` + + // bucket interface + + // 返回指定桶的本地迭代器 + local_iterator begin(size_type n) noexcept + { + return ht_.begin(n); + } + // 返回指定桶的常量本地迭代器(const 版本) + const_local_iterator begin(size_type n) const noexcept + { + return ht_.begin(n); + } + // 返回指定桶的常量本地迭代器(const 版本,C++11 范围for循环使用) + 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 版本) + const_local_iterator end(size_type n) const noexcept + { + return ht_.end(n); + } + // 返回指定桶的常量本地迭代器(const 版本,C++11 范围for循环使用) + 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); } + + // 重新哈希,桶的数量至少为 count + void rehash(size_type count) { ht_.rehash(count); } + // 重新分配桶,使得桶的数量至少为 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_multiset& lhs, const unordered_multiset& rhs) - { - return lhs.ht_.equal_range_multi(rhs.ht_); - } - friend bool operator!=(const unordered_multiset& lhs, const unordered_multiset& rhs) - { - return !lhs.ht_.equal_range_multi(rhs.ht_); - } + // 友元函数,用于比较两个 unordered_multiset 是否相等 + friend bool operator==(const unordered_multiset& lhs, const unordered_multiset& rhs) + { + return lhs.ht_.equal_range_multi(rhs.ht_); + } + // 友元函数,用于比较两个 unordered_multiset 是否不相等 + friend bool operator!=(const unordered_multiset& lhs, const unordered_multiset& rhs) + { + return !lhs.ht_.equal_range_multi(rhs.ht_); + } }; // 重载比较操作符 template bool operator==(const unordered_multiset& lhs, - const unordered_multiset& rhs) + const unordered_multiset& rhs) { - return lhs == rhs; + return lhs == rhs; } template bool operator!=(const unordered_multiset& lhs, - const unordered_multiset& rhs) + const unordered_multiset& rhs) { - return lhs != rhs; + return lhs != rhs; } // 重载 mystl 的 swap template void swap(unordered_multiset& lhs, - unordered_multiset& rhs) + unordered_multiset& rhs) { - lhs.swap(rhs); + lhs.swap(rhs); } } // namespace mystl -#endif // !MYTINYSTL_UNORDERED_SET_H_ - +#endif // !MYTINYSTL_UNORDERED_SET_H_ \ No newline at end of file