Skip to content

Commit adafeca

Browse files
committed
Add tests and fix some bugs
1 parent bd7a367 commit adafeca

File tree

3 files changed

+139
-8
lines changed

3 files changed

+139
-8
lines changed

CMakeLists.txt

+4
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,7 @@ set(CMAKE_CXX_FLAGS "-std=c++14 -Wall")
55
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
66

77
add_executable(benchmark benchmark.cpp)
8+
add_executable(tests tests.cpp)
9+
10+
enable_testing()
11+
add_test(test tests)

HashMap.h

+11-8
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ class HashMap {
8484
private:
8585
explicit hm_iterator(ContT *hm) : hm_(hm) { advance_past_empty(); }
8686
explicit hm_iterator(ContT *hm, size_type idx) : hm_(hm), idx_(idx) {}
87+
template <typename OtherContT, typename OtherIterVal>
88+
hm_iterator(const hm_iterator<OtherContT, OtherIterVal> &other)
89+
: hm_(other.hm_), idx_(other.idx_) {}
8790

8891
void advance_past_empty() {
8992
while (idx_ < hm_->buckets_.size() &&
@@ -132,9 +135,8 @@ class HashMap {
132135

133136
// Modifiers
134137
void clear() {
135-
for (auto it = begin(); it != end(); ++it) {
136-
it->first = empty_key_;
137-
}
138+
HashMap other(bucket_count(), empty_key_);
139+
swap(other);
138140
}
139141

140142
std::pair<iterator, bool> insert(const value_type &value) {
@@ -193,15 +195,17 @@ class HashMap {
193195
}
194196

195197
// Lookup
196-
reference at(key_type key) {
198+
mapped_type &at(key_type key) {
197199
iterator it = find(key);
198200
if (it != end()) {
199201
return it->second;
200202
}
201-
throw std::out_of_range();
203+
throw std::out_of_range("key not found");
202204
}
203205

204-
const_reference at(key_type key) const { return at(key); }
206+
const mapped_type &at(key_type key) const { return at(key); }
207+
208+
mapped_type &operator[](key_type key) { return emplace(key).first->second; }
205209

206210
size_type count(key_type key) const { return find(key) == end() ? 0 : 1; }
207211

@@ -232,8 +236,7 @@ class HashMap {
232236

233237
void reserve(size_type count) {
234238
if (count * 2 > buckets_.size()) {
235-
HashMap other(*this, buckets_.size() * 2);
236-
swap(other);
239+
rehash(count * 2);
237240
}
238241
}
239242

tests.cpp

+124
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
#include "HashMap.h"
2+
#include <cassert>
3+
4+
int main(int argc, char *argv[]) {
5+
6+
{
7+
HashMap<int, int> hm(16, 0);
8+
assert(hm.empty());
9+
assert(hm.size() == 0);
10+
}
11+
12+
{
13+
HashMap<int, int> hm(16, 0);
14+
hm.insert({1, 1});
15+
assert(!hm.empty());
16+
assert(hm.size() == 1);
17+
hm.clear();
18+
assert(hm.empty());
19+
assert(hm.size() == 0);
20+
}
21+
22+
{
23+
HashMap<int, int> hm(16, 0);
24+
auto res = hm.insert({1, 1});
25+
assert(res.second);
26+
assert(!hm.empty());
27+
assert(hm.size() == 1);
28+
assert(res.first->first == 1);
29+
assert(res.first->second == 1);
30+
res = hm.insert({1, 2});
31+
assert(!res.second);
32+
assert(hm.size() == 1);
33+
assert(res.first->first == 1);
34+
assert(res.first->second == 1);
35+
}
36+
37+
{
38+
HashMap<int, int> hm(16, 0);
39+
auto res = hm.emplace(1, 1);
40+
assert(res.second);
41+
assert(!hm.empty());
42+
assert(hm.size() == 1);
43+
assert(res.first->first == 1);
44+
assert(res.first->second == 1);
45+
res = hm.emplace(1, 2);
46+
assert(!res.second);
47+
assert(hm.size() == 1);
48+
assert(res.first->first == 1);
49+
assert(res.first->second == 1);
50+
}
51+
52+
{
53+
HashMap<int, int> hm(16, 0);
54+
auto res = hm.emplace(1, 1);
55+
assert(hm.size() == 1);
56+
hm.erase(res.first);
57+
assert(hm.size() == 0);
58+
assert(hm.erase(1) == 0);
59+
hm.emplace(1, 1);
60+
assert(hm.erase(1) == 1);
61+
}
62+
63+
{
64+
HashMap<int, int> hm(16, 0);
65+
hm.emplace(1, 1);
66+
assert(hm.at(1) == 1);
67+
hm.at(1) = 2;
68+
assert(hm.at(1) == 2);
69+
bool exception = false;
70+
try {
71+
hm.at(2);
72+
} catch (std::out_of_range) {
73+
exception = true;
74+
}
75+
assert(exception);
76+
}
77+
78+
{
79+
HashMap<int, int> hm(16, 0);
80+
assert(hm[1] == 0);
81+
hm[1] = 2;
82+
assert(hm[1] == 2);
83+
}
84+
85+
{
86+
HashMap<int, int> hm(16, 0);
87+
hm.emplace(1, 1);
88+
assert(hm.count(1) == 1);
89+
assert(hm.count(2) == 0);
90+
}
91+
92+
{
93+
HashMap<int, int> hm(16, 0);
94+
hm.emplace(1, 1);
95+
auto it = hm.find(1);
96+
assert(it != hm.end());
97+
assert(it->first == 1);
98+
assert(it->second == 1);
99+
it = hm.find(2);
100+
assert(it == hm.end());
101+
}
102+
103+
{
104+
HashMap<int, int> hm(16, 0);
105+
assert(hm.bucket_count() == 16);
106+
}
107+
108+
{
109+
HashMap<int, int> hm(2, 0);
110+
hm.emplace(1, 1);
111+
hm.emplace(2, 2);
112+
assert(hm.bucket_count() == 4);
113+
hm.rehash(2);
114+
assert(hm.bucket_count() == 4);
115+
hm.rehash(16);
116+
assert(hm.bucket_count() == 16);
117+
hm.reserve(2);
118+
assert(hm.bucket_count() == 16);
119+
hm.reserve(16);
120+
assert(hm.bucket_count() == 32);
121+
}
122+
123+
return 0;
124+
}

0 commit comments

Comments
 (0)