|
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