summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/common_funcs.h12
-rw-r--r--src/common/hash.h35
2 files changed, 7 insertions, 40 deletions
diff --git a/src/common/common_funcs.h b/src/common/common_funcs.h
index c029dc7b3..052254678 100644
--- a/src/common/common_funcs.h
+++ b/src/common/common_funcs.h
@@ -19,13 +19,15 @@
19 19
20/// Helper macros to insert unused bytes or words to properly align structs. These values will be 20/// Helper macros to insert unused bytes or words to properly align structs. These values will be
21/// zero-initialized. 21/// zero-initialized.
22#define INSERT_PADDING_BYTES(num_bytes) std::array<u8, num_bytes> CONCAT2(pad, __LINE__){}; 22#define INSERT_PADDING_BYTES(num_bytes) \
23#define INSERT_PADDING_WORDS(num_words) std::array<u32, num_words> CONCAT2(pad, __LINE__){}; 23 std::array<u8, num_bytes> CONCAT2(pad, __LINE__) {}
24#define INSERT_PADDING_WORDS(num_words) \
25 std::array<u32, num_words> CONCAT2(pad, __LINE__) {}
24 26
25/// These are similar to the INSERT_PADDING_* macros, but are needed for padding unions. This is 27/// These are similar to the INSERT_PADDING_* macros, but are needed for padding unions. This is
26/// because unions can only be initialized by one member. 28/// because unions can only be initialized by one member.
27#define INSERT_UNION_PADDING_BYTES(num_bytes) std::array<u8, num_bytes> CONCAT2(pad, __LINE__); 29#define INSERT_UNION_PADDING_BYTES(num_bytes) std::array<u8, num_bytes> CONCAT2(pad, __LINE__)
28#define INSERT_UNION_PADDING_WORDS(num_words) std::array<u32, num_words> CONCAT2(pad, __LINE__); 30#define INSERT_UNION_PADDING_WORDS(num_words) std::array<u32, num_words> CONCAT2(pad, __LINE__)
29 31
30#ifndef _MSC_VER 32#ifndef _MSC_VER
31 33
@@ -56,7 +58,7 @@ std::string GetLastErrorMsg();
56namespace Common { 58namespace Common {
57 59
58constexpr u32 MakeMagic(char a, char b, char c, char d) { 60constexpr u32 MakeMagic(char a, char b, char c, char d) {
59 return a | b << 8 | c << 16 | d << 24; 61 return u32(a) | u32(b) << 8 | u32(c) << 16 | u32(d) << 24;
60} 62}
61 63
62} // namespace Common 64} // namespace Common
diff --git a/src/common/hash.h b/src/common/hash.h
index ebd4125e2..b2538f3ea 100644
--- a/src/common/hash.h
+++ b/src/common/hash.h
@@ -35,41 +35,6 @@ static inline u64 ComputeStructHash64(const T& data) {
35 return ComputeHash64(&data, sizeof(data)); 35 return ComputeHash64(&data, sizeof(data));
36} 36}
37 37
38/// A helper template that ensures the padding in a struct is initialized by memsetting to 0.
39template <typename T>
40struct HashableStruct {
41 // In addition to being trivially copyable, T must also have a trivial default constructor,
42 // because any member initialization would be overridden by memset
43 static_assert(std::is_trivial_v<T>, "Type passed to HashableStruct must be trivial");
44 /*
45 * We use a union because "implicitly-defined copy/move constructor for a union X copies the
46 * object representation of X." and "implicitly-defined copy assignment operator for a union X
47 * copies the object representation (3.9) of X." = Bytewise copy instead of memberwise copy.
48 * This is important because the padding bytes are included in the hash and comparison between
49 * objects.
50 */
51 union {
52 T state;
53 };
54
55 HashableStruct() {
56 // Memset structure to zero padding bits, so that they will be deterministic when hashing
57 std::memset(&state, 0, sizeof(T));
58 }
59
60 bool operator==(const HashableStruct<T>& o) const {
61 return std::memcmp(&state, &o.state, sizeof(T)) == 0;
62 };
63
64 bool operator!=(const HashableStruct<T>& o) const {
65 return !(*this == o);
66 };
67
68 std::size_t Hash() const {
69 return Common::ComputeStructHash64(state);
70 }
71};
72
73struct PairHash { 38struct PairHash {
74 template <class T1, class T2> 39 template <class T1, class T2>
75 std::size_t operator()(const std::pair<T1, T2>& pair) const noexcept { 40 std::size_t operator()(const std::pair<T1, T2>& pair) const noexcept {