Skip to content

Commit 9c0b79a

Browse files
johnstiles-googleSkia Commit-Bot
authored andcommitted
Implement assignment and copy-construction for SkTHashSet/Map.
This will enable us to use SkTHashMap to store our definition maps. Change-Id: I6017dfa71e1c5e68a20c97e955bb3d3abf347f0d Reviewed-on: https://skia-review.googlesource.com/c/skia/+/323891 Reviewed-by: Mike Klein <[email protected]> Commit-Queue: John Stiles <[email protected]> Auto-Submit: John Stiles <[email protected]>
1 parent 0039874 commit 9c0b79a

File tree

2 files changed

+63
-22
lines changed

2 files changed

+63
-22
lines changed

include/private/SkTHash.h

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,17 @@ class SkTHashTable {
3939
return *this;
4040
}
4141

42+
SkTHashTable(const SkTHashTable& that) {
43+
this->copyFrom(that);
44+
}
45+
46+
SkTHashTable& operator=(const SkTHashTable& that) {
47+
if (this != &that) {
48+
this->copyFrom(that);
49+
}
50+
return *this;
51+
}
52+
4253
// Clear the table.
4354
void reset() { *this = SkTHashTable(); }
4455

@@ -135,6 +146,16 @@ class SkTHashTable {
135146
}
136147

137148
private:
149+
// Copy from another hash table into this one.
150+
void copyFrom(const SkTHashTable& that) {
151+
fCount = that.fCount;
152+
fCapacity = that.fCapacity;
153+
fSlots = SkAutoTArray<Slot>(fCapacity);
154+
for (int i = 0; i < fCapacity; i++) {
155+
fSlots[i] = that.fSlots[i];
156+
}
157+
}
158+
138159
T* uncheckedSet(T&& val) {
139160
const K& key = Traits::GetKey(val);
140161
uint32_t hash = Hash(key);
@@ -223,26 +244,21 @@ class SkTHashTable {
223244
}
224245

225246
struct Slot {
226-
Slot() : val{}, hash(0) {}
247+
Slot() = default;
248+
Slot(const Slot& o) = default;
249+
Slot(Slot&& o) = default;
250+
Slot& operator=(const Slot& o) = default;
251+
Slot& operator=(Slot&& o) = default;
227252
Slot(T&& v, uint32_t h) : val(std::move(v)), hash(h) {}
228-
Slot(Slot&& o) { *this = std::move(o); }
229-
Slot& operator=(Slot&& o) {
230-
val = std::move(o.val);
231-
hash = o.hash;
232-
return *this;
233-
}
234253

235254
bool empty() const { return this->hash == 0; }
236255

237-
T val;
238-
uint32_t hash;
256+
T val{};
257+
uint32_t hash = 0;
239258
};
240259

241260
int fCount, fCapacity;
242261
SkAutoTArray<Slot> fSlots;
243-
244-
SkTHashTable(const SkTHashTable&) = delete;
245-
SkTHashTable& operator=(const SkTHashTable&) = delete;
246262
};
247263

248264
// Maps K->V. A more user-friendly wrapper around SkTHashTable, suitable for most use cases.
@@ -253,6 +269,8 @@ class SkTHashMap {
253269
SkTHashMap() {}
254270
SkTHashMap(SkTHashMap&&) = default;
255271
SkTHashMap& operator=(SkTHashMap&&) = default;
272+
SkTHashMap(const SkTHashMap& that) = default;
273+
SkTHashMap& operator=(const SkTHashMap& that) = default;
256274

257275
// Clear the map.
258276
void reset() { fTable.reset(); }
@@ -315,9 +333,6 @@ class SkTHashMap {
315333
};
316334

317335
SkTHashTable<Pair, K> fTable;
318-
319-
SkTHashMap(const SkTHashMap&) = delete;
320-
SkTHashMap& operator=(const SkTHashMap&) = delete;
321336
};
322337

323338
// A set of T. T is treated as an ordinary copyable C++ type.
@@ -327,6 +342,8 @@ class SkTHashSet {
327342
SkTHashSet() {}
328343
SkTHashSet(SkTHashSet&&) = default;
329344
SkTHashSet& operator=(SkTHashSet&&) = default;
345+
SkTHashSet(const SkTHashSet& that) = default;
346+
SkTHashSet& operator=(const SkTHashSet& that) = default;
330347

331348
// Clear the set.
332349
void reset() { fTable.reset(); }
@@ -368,9 +385,6 @@ class SkTHashSet {
368385
static auto Hash(const T& item) { return HashT()(item); }
369386
};
370387
SkTHashTable<T, T, Traits> fTable;
371-
372-
SkTHashSet(const SkTHashSet&) = delete;
373-
SkTHashSet& operator=(const SkTHashSet&) = delete;
374388
};
375389

376390
#endif//SkTHash_DEFINED

tests/HashTest.cpp

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,28 +44,45 @@ DEF_TEST(HashMap, r) {
4444
for (int i = 0; i < N; i++) {
4545
map.set(i, 2.0*i);
4646
}
47+
48+
SkTHashMap<int, double> clone = map;
49+
4750
for (int i = 0; i < N; i++) {
4851
double* found = map.find(i);
4952
REPORTER_ASSERT(r, found);
5053
REPORTER_ASSERT(r, *found == i*2.0);
54+
55+
found = clone.find(i);
56+
REPORTER_ASSERT(r, found);
57+
REPORTER_ASSERT(r, *found == i*2.0);
5158
}
5259
for (int i = N; i < 2*N; i++) {
5360
REPORTER_ASSERT(r, !map.find(i));
61+
REPORTER_ASSERT(r, !clone.find(i));
5462
}
5563

5664
REPORTER_ASSERT(r, map.count() == N);
65+
REPORTER_ASSERT(r, clone.count() == N);
5766

5867
for (int i = 0; i < N/2; i++) {
5968
map.remove(i);
6069
}
6170
for (int i = 0; i < N; i++) {
6271
double* found = map.find(i);
63-
REPORTER_ASSERT(r, (found == nullptr) == (i < N/2));
72+
REPORTER_ASSERT(r, (found == nullptr) == (i < N/2));
73+
74+
found = clone.find(i);
75+
REPORTER_ASSERT(r, *found == i*2.0);
6476
}
6577
REPORTER_ASSERT(r, map.count() == N/2);
78+
REPORTER_ASSERT(r, clone.count() == N);
6679

6780
map.reset();
6881
REPORTER_ASSERT(r, map.count() == 0);
82+
REPORTER_ASSERT(r, clone.count() == N);
83+
84+
clone = map;
85+
REPORTER_ASSERT(r, clone.count() == 0);
6986

7087
{
7188
// Test that we don't leave dangling values in empty slots.
@@ -88,22 +105,32 @@ DEF_TEST(HashSet, r) {
88105

89106
set.add(SkString("Hello"));
90107
set.add(SkString("World"));
91-
92108
REPORTER_ASSERT(r, set.count() == 2);
93-
94109
REPORTER_ASSERT(r, set.contains(SkString("Hello")));
95110
REPORTER_ASSERT(r, set.contains(SkString("World")));
96111
REPORTER_ASSERT(r, !set.contains(SkString("Goodbye")));
97-
98112
REPORTER_ASSERT(r, set.find(SkString("Hello")));
99113
REPORTER_ASSERT(r, *set.find(SkString("Hello")) == SkString("Hello"));
100114

115+
SkTHashSet<SkString> clone = set;
116+
REPORTER_ASSERT(r, clone.count() == 2);
117+
REPORTER_ASSERT(r, clone.contains(SkString("Hello")));
118+
REPORTER_ASSERT(r, clone.contains(SkString("World")));
119+
REPORTER_ASSERT(r, !clone.contains(SkString("Goodbye")));
120+
REPORTER_ASSERT(r, clone.find(SkString("Hello")));
121+
REPORTER_ASSERT(r, *clone.find(SkString("Hello")) == SkString("Hello"));
122+
101123
set.remove(SkString("Hello"));
102124
REPORTER_ASSERT(r, !set.contains(SkString("Hello")));
103125
REPORTER_ASSERT(r, set.count() == 1);
126+
REPORTER_ASSERT(r, clone.contains(SkString("Hello")));
127+
REPORTER_ASSERT(r, clone.count() == 2);
104128

105129
set.reset();
106130
REPORTER_ASSERT(r, set.count() == 0);
131+
132+
clone = set;
133+
REPORTER_ASSERT(r, clone.count() == 0);
107134
}
108135

109136
namespace {

0 commit comments

Comments
 (0)