|
17 | 17 | #include <cassert> |
18 | 18 | #include <cstddef> |
19 | 19 | #include <cstdint> |
| 20 | +#include <limits> |
20 | 21 | #include <optional> |
21 | 22 | #include <tuple> |
22 | 23 | #include <type_traits> |
@@ -101,122 +102,32 @@ template<> struct DenseMapInfo<char> { |
101 | 102 | } |
102 | 103 | }; |
103 | 104 |
|
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; |
145 | 119 | else |
146 | | - return densemap::detail::mix(Val); |
| 120 | + return std::numeric_limits<T>::min(); |
147 | 121 | } |
148 | 122 |
|
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); |
214 | 128 | } |
215 | 129 |
|
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; } |
220 | 131 | }; |
221 | 132 |
|
222 | 133 | // Provide DenseMapInfo for all pairs whose members have info. |
|
0 commit comments