Skip to content

Commit ffcbaa2

Browse files
[ADT] Refactor DenseMapInfo for integer types (NFC) (#155549)
This patch consolidates DenseMapInfo<T> for integer types T with a common templated implementation. DenseMapInfo<char> is excluded because it uses ~0 for the empty key despite char being a signed type. Also, we preserve the tombstone key value for long, which is: std::numeric_limits<long>::max() - 1
1 parent 238fe4e commit ffcbaa2

File tree

1 file changed

+22
-111
lines changed

1 file changed

+22
-111
lines changed

llvm/include/llvm/ADT/DenseMapInfo.h

Lines changed: 22 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <cassert>
1818
#include <cstddef>
1919
#include <cstdint>
20+
#include <limits>
2021
#include <optional>
2122
#include <tuple>
2223
#include <type_traits>
@@ -101,122 +102,32 @@ template<> struct DenseMapInfo<char> {
101102
}
102103
};
103104

104-
// Provide DenseMapInfo for unsigned chars.
105-
template <> struct DenseMapInfo<unsigned char> {
106-
static constexpr unsigned char getEmptyKey() { return ~0; }
107-
static constexpr unsigned char getTombstoneKey() { return ~0 - 1; }
108-
static unsigned getHashValue(const unsigned char &Val) { return Val * 37U; }
109-
110-
static bool isEqual(const unsigned char &LHS, const unsigned char &RHS) {
111-
return LHS == RHS;
112-
}
113-
};
114-
115-
// Provide DenseMapInfo for unsigned shorts.
116-
template <> struct DenseMapInfo<unsigned short> {
117-
static constexpr unsigned short getEmptyKey() { return 0xFFFF; }
118-
static constexpr unsigned short getTombstoneKey() { return 0xFFFF - 1; }
119-
static unsigned getHashValue(const unsigned short &Val) { return Val * 37U; }
120-
121-
static bool isEqual(const unsigned short &LHS, const unsigned short &RHS) {
122-
return LHS == RHS;
123-
}
124-
};
125-
126-
// Provide DenseMapInfo for unsigned ints.
127-
template<> struct DenseMapInfo<unsigned> {
128-
static constexpr unsigned getEmptyKey() { return ~0U; }
129-
static constexpr unsigned getTombstoneKey() { return ~0U - 1; }
130-
static unsigned getHashValue(const unsigned& Val) { return Val * 37U; }
131-
132-
static bool isEqual(const unsigned& LHS, const unsigned& RHS) {
133-
return LHS == RHS;
134-
}
135-
};
136-
137-
// Provide DenseMapInfo for unsigned longs.
138-
template<> struct DenseMapInfo<unsigned long> {
139-
static constexpr unsigned long getEmptyKey() { return ~0UL; }
140-
static constexpr unsigned long getTombstoneKey() { return ~0UL - 1L; }
141-
142-
static unsigned getHashValue(const unsigned long& Val) {
143-
if constexpr (sizeof(Val) == 4)
144-
return DenseMapInfo<unsigned>::getHashValue(Val);
105+
// Provide DenseMapInfo for all integral types except char.
106+
//
107+
// The "char" case is excluded because it uses ~0 as the empty key despite
108+
// "char" being a signed type. "std::is_same_v<T, char>" is included below
109+
// for clarity; technically, we do not need it because the explicit
110+
// specialization above "wins",
111+
template <typename T>
112+
struct DenseMapInfo<
113+
T, std::enable_if_t<std::is_integral_v<T> && !std::is_same_v<T, char>>> {
114+
static constexpr T getEmptyKey() { return std::numeric_limits<T>::max(); }
115+
116+
static constexpr T getTombstoneKey() {
117+
if constexpr (std::is_unsigned_v<T> || std::is_same_v<T, long>)
118+
return std::numeric_limits<T>::max() - 1;
145119
else
146-
return densemap::detail::mix(Val);
120+
return std::numeric_limits<T>::min();
147121
}
148122

149-
static bool isEqual(const unsigned long& LHS, const unsigned long& RHS) {
150-
return LHS == RHS;
151-
}
152-
};
153-
154-
// Provide DenseMapInfo for unsigned long longs.
155-
template<> struct DenseMapInfo<unsigned long long> {
156-
static constexpr unsigned long long getEmptyKey() { return ~0ULL; }
157-
static constexpr unsigned long long getTombstoneKey() { return ~0ULL - 1ULL; }
158-
159-
static unsigned getHashValue(const unsigned long long& Val) {
160-
return densemap::detail::mix(Val);
161-
}
162-
163-
static bool isEqual(const unsigned long long& LHS,
164-
const unsigned long long& RHS) {
165-
return LHS == RHS;
166-
}
167-
};
168-
169-
// Provide DenseMapInfo for shorts.
170-
template <> struct DenseMapInfo<short> {
171-
static constexpr short getEmptyKey() { return 0x7FFF; }
172-
static constexpr short getTombstoneKey() { return -0x7FFF - 1; }
173-
static unsigned getHashValue(const short &Val) { return Val * 37U; }
174-
static bool isEqual(const short &LHS, const short &RHS) { return LHS == RHS; }
175-
};
176-
177-
// Provide DenseMapInfo for ints.
178-
template<> struct DenseMapInfo<int> {
179-
static constexpr int getEmptyKey() { return 0x7fffffff; }
180-
static constexpr int getTombstoneKey() { return -0x7fffffff - 1; }
181-
static unsigned getHashValue(const int& Val) { return (unsigned)(Val * 37U); }
182-
183-
static bool isEqual(const int& LHS, const int& RHS) {
184-
return LHS == RHS;
185-
}
186-
};
187-
188-
// Provide DenseMapInfo for longs.
189-
template<> struct DenseMapInfo<long> {
190-
static constexpr long getEmptyKey() {
191-
return (1UL << (sizeof(long) * 8 - 1)) - 1UL;
192-
}
193-
194-
static constexpr long getTombstoneKey() { return getEmptyKey() - 1L; }
195-
196-
static unsigned getHashValue(const long& Val) {
197-
return (unsigned)(Val * 37UL);
198-
}
199-
200-
static bool isEqual(const long& LHS, const long& RHS) {
201-
return LHS == RHS;
202-
}
203-
};
204-
205-
// Provide DenseMapInfo for long longs.
206-
template<> struct DenseMapInfo<long long> {
207-
static constexpr long long getEmptyKey() { return 0x7fffffffffffffffLL; }
208-
static constexpr long long getTombstoneKey() {
209-
return -0x7fffffffffffffffLL - 1;
210-
}
211-
212-
static unsigned getHashValue(const long long& Val) {
213-
return (unsigned)(Val * 37ULL);
123+
static unsigned getHashValue(const T &Val) {
124+
if constexpr (std::is_unsigned_v<T> && sizeof(T) > sizeof(unsigned))
125+
return densemap::detail::mix(Val);
126+
else
127+
return static_cast<unsigned>(Val * 37U);
214128
}
215129

216-
static bool isEqual(const long long& LHS,
217-
const long long& RHS) {
218-
return LHS == RHS;
219-
}
130+
static bool isEqual(const T &LHS, const T &RHS) { return LHS == RHS; }
220131
};
221132

222133
// Provide DenseMapInfo for all pairs whose members have info.

0 commit comments

Comments
 (0)