Skip to content

Commit 971f8f3

Browse files
committed
Add unordered_set
1 parent 2f86e05 commit 971f8f3

3 files changed

Lines changed: 104 additions & 18 deletions

File tree

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ mystd is a stl-like library.
33

44
[![GitHub Pages](https://img.shields.io/badge/docs-online-blue?logo=github)](https://pets-tech.github.io/mystd/) [![codecov](https://codecov.io/gh/pets-tech/mystd/graph/badge.svg?token=92FQ42MXUZ)](https://codecov.io/gh/pets-tech/mystd) [![mystd CI](https://github.com/pets-tech/mystd/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/pets-tech/mystd/actions/workflows/ci.yml)
55

6+
> [!IMPORTANT]
7+
> In fact, this is a demo, not realy production code. Real containers need weeks of dev and testing, not hours/days. Use at your own risk. I just implemented a lot of basic things quickly.
8+
69

710
## Features
811

@@ -24,7 +27,7 @@ mystd is a stl-like library.
2427
- [ ] hash table
2528
- [x] hash table on separate chaining -> my::hashtable
2629
- [x] my::unordered_map
27-
- [ ] my::unordered_set
30+
- [x] my::unordered_set
2831
- [ ] my::unordered_multimap
2932
- [ ] my::unordered_multiset
3033
- [ ] hash table on open addressing

include/mystd/unordered_set.hpp

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,17 @@
66

77
namespace my {
88

9-
template <class Key, class Hash = std::hash<Key>, class KeyEqual = std::equal_to<Key>>
9+
template <class Value, class Hash = std::hash<Value>, class KeyEqual = std::equal_to<Value>>
1010
class unordered_set {
1111
private:
1212
struct Identity {
13-
const Key& operator()(const Key& k) const noexcept { return k; }
13+
const Value& operator()(const Value& v) const noexcept { return v; }
1414
};
1515

16-
using Base = hashtable<Key, Key, Identity, Hash, KeyEqual, InsertPolicy::UniqueKeys>;
16+
using Base = hashtable<Value, Value, Identity, Hash, KeyEqual, InsertPolicy::UniqueKeys>;
1717
Base table;
1818

1919
public:
20-
using key_type = Key;
2120
using value_type = Value;
2221
using reference = Value&;
2322
using const_reference = const Value&;
@@ -29,28 +28,22 @@ class unordered_set {
2928
unordered_set(const size_type bucket_count = 8) : table(bucket_count) {};
3029

3130
// initializer_list ctor
32-
unordered_set(const std::initializer_list<std::pair<Key, Value>>& init) : unordered_set() {
33-
for (const auto& kv : init) {
34-
insert(kv);
31+
unordered_set(const std::initializer_list<Value>& init) : unordered_set() {
32+
for (const auto& v : init) {
33+
insert(v);
3534
}
3635
}
3736

38-
// observers
39-
reference operator[](const key_type& k) {
40-
auto [it, inserted] = table.insert(k);
41-
return *it;
42-
}
43-
4437
// modifiers
4538

46-
iterator insert(const key_type& k) {
47-
auto it_flag = table.insert(k);
39+
iterator insert(const value_type& v) {
40+
auto it_flag = table.insert(v);
4841
return it_flag.first;
4942
}
5043

51-
iterator find(const key_type& k) { return table.find(k); }
44+
iterator find(const value_type& v) { return table.find(v); }
5245

53-
iterator erase(const key_type& k) { return table.erase(k); }
46+
iterator erase(const value_type& v) { return table.erase(v); }
5447

5548
// capacity
5649
size_type size() const { return table.size(); }
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#include <gtest/gtest.h>
2+
3+
#include "mystd/unordered_set.hpp"
4+
5+
namespace my::testing {
6+
7+
TEST(UnorderedSetTest, Initialization) {
8+
my::unordered_set<int> uset;
9+
EXPECT_TRUE(uset.empty());
10+
EXPECT_EQ(uset.size(), 0);
11+
EXPECT_EQ(uset.bucket_count(), 8);
12+
}
13+
14+
TEST(UnorderedSetTest, InitializerList) {
15+
my::unordered_set<int> uset = {1, 2, 3, 3, 3, 3};
16+
EXPECT_FALSE(uset.empty());
17+
EXPECT_EQ(uset.size(), 3);
18+
EXPECT_EQ(uset.bucket_count(), 8);
19+
}
20+
21+
TEST(UnorderedSetTest, Find) {
22+
my::unordered_set<int> uset1 = {1, 2, 3, 3, 3, 3};
23+
EXPECT_TRUE(uset1.find(1) != uset1.end());
24+
EXPECT_TRUE(uset1.find(2) != uset1.end());
25+
EXPECT_TRUE(uset1.find(3) != uset1.end());
26+
EXPECT_TRUE(uset1.find(4) == uset1.end());
27+
}
28+
29+
TEST(UnorderedSetTest, Erase) {
30+
my::unordered_set<int> uset1 = {1, 2, 3, 3, 3, 3};
31+
32+
uset1.erase(1);
33+
EXPECT_EQ(uset1.size(), 2);
34+
EXPECT_TRUE(uset1.find(1) == uset1.end());
35+
36+
uset1.erase(2);
37+
EXPECT_EQ(uset1.size(), 1);
38+
EXPECT_TRUE(uset1.find(2) == uset1.end());
39+
40+
uset1.erase(3);
41+
EXPECT_EQ(uset1.size(), 0);
42+
EXPECT_TRUE(uset1.find(3) == uset1.end());
43+
44+
EXPECT_TRUE(uset1.empty());
45+
}
46+
47+
TEST(UnorderedSetTest, CopyMode) {
48+
my::unordered_set<int> uset1 = {1, 2, 3, 3, 3, 3};
49+
50+
my::unordered_set<int> uset2(uset1);
51+
EXPECT_EQ(uset2.size(), 3);
52+
53+
my::unordered_set<int> uset3;
54+
uset3 = uset1;
55+
EXPECT_EQ(uset3.size(), 3);
56+
57+
my::unordered_set<int> uset4(std::move(uset1));
58+
EXPECT_EQ(uset4.size(), 3);
59+
EXPECT_TRUE(uset1.empty());
60+
61+
my::unordered_set<int> uset5;
62+
uset5 = std::move(uset4);
63+
EXPECT_EQ(uset5.size(), 3);
64+
EXPECT_TRUE(uset4.empty());
65+
}
66+
67+
TEST(UnorderedSetTest, Iterators) {
68+
my::unordered_set<int> uset = {0, 1, 2, 3, 4, 5};
69+
70+
for (auto& v : uset) {
71+
EXPECT_EQ(*uset.find(v), v);
72+
}
73+
74+
auto it = uset.cbegin();
75+
auto ite = uset.cend();
76+
}
77+
78+
TEST(UnorderedSetTest, Rehashing) {
79+
my::unordered_set<int> uset(3);
80+
81+
EXPECT_EQ(uset.bucket_count(), 3);
82+
83+
for (size_t i = 0; i < 100; ++i) {
84+
uset.insert(i);
85+
}
86+
87+
EXPECT_EQ(uset.bucket_count(), 192);
88+
}
89+
90+
} // namespace my::testing

0 commit comments

Comments
 (0)