@@ -51,10 +51,10 @@ inline unsigned combineHashValue(unsigned a, unsigned b) {
51
51
// / just be `void`.
52
52
template <typename T, typename Enable = void >
53
53
struct DenseMapInfo {
54
- // static inline T getEmptyKey();
55
- // static inline T getTombstoneKey();
56
- // static unsigned getHashValue(const T &Val);
57
- // static bool isEqual(const T &LHS, const T &RHS);
54
+ // static constexpr T getEmptyKey();
55
+ // static constexpr T getTombstoneKey();
56
+ // static unsigned getHashValue(const T &Val);
57
+ // static bool isEqual(const T &LHS, const T &RHS);
58
58
};
59
59
60
60
// Provide DenseMapInfo for all pointers. Come up with sentinel pointer values
@@ -70,13 +70,13 @@ struct DenseMapInfo<T*> {
70
70
// "Log2MaxAlign bits of alignment");
71
71
static constexpr uintptr_t Log2MaxAlign = 12 ;
72
72
73
- static inline T* getEmptyKey () {
73
+ static constexpr T * getEmptyKey () {
74
74
uintptr_t Val = static_cast <uintptr_t >(-1 );
75
75
Val <<= Log2MaxAlign;
76
76
return reinterpret_cast <T*>(Val);
77
77
}
78
78
79
- static inline T* getTombstoneKey () {
79
+ static constexpr T * getTombstoneKey () {
80
80
uintptr_t Val = static_cast <uintptr_t >(-2 );
81
81
Val <<= Log2MaxAlign;
82
82
return reinterpret_cast <T*>(Val);
@@ -92,8 +92,8 @@ struct DenseMapInfo<T*> {
92
92
93
93
// Provide DenseMapInfo for chars.
94
94
template <> struct DenseMapInfo <char > {
95
- static inline char getEmptyKey () { return ~0 ; }
96
- static inline char getTombstoneKey () { return ~0 - 1 ; }
95
+ static constexpr char getEmptyKey () { return ~0 ; }
96
+ static constexpr char getTombstoneKey () { return ~0 - 1 ; }
97
97
static unsigned getHashValue (const char & Val) { return Val * 37U ; }
98
98
99
99
static bool isEqual (const char &LHS, const char &RHS) {
@@ -103,8 +103,8 @@ template<> struct DenseMapInfo<char> {
103
103
104
104
// Provide DenseMapInfo for unsigned chars.
105
105
template <> struct DenseMapInfo <unsigned char > {
106
- static inline unsigned char getEmptyKey () { return ~0 ; }
107
- static inline unsigned char getTombstoneKey () { return ~0 - 1 ; }
106
+ static constexpr unsigned char getEmptyKey () { return ~0 ; }
107
+ static constexpr unsigned char getTombstoneKey () { return ~0 - 1 ; }
108
108
static unsigned getHashValue (const unsigned char &Val) { return Val * 37U ; }
109
109
110
110
static bool isEqual (const unsigned char &LHS, const unsigned char &RHS) {
@@ -114,8 +114,8 @@ template <> struct DenseMapInfo<unsigned char> {
114
114
115
115
// Provide DenseMapInfo for unsigned shorts.
116
116
template <> struct DenseMapInfo <unsigned short > {
117
- static inline unsigned short getEmptyKey () { return 0xFFFF ; }
118
- static inline unsigned short getTombstoneKey () { return 0xFFFF - 1 ; }
117
+ static constexpr unsigned short getEmptyKey () { return 0xFFFF ; }
118
+ static constexpr unsigned short getTombstoneKey () { return 0xFFFF - 1 ; }
119
119
static unsigned getHashValue (const unsigned short &Val) { return Val * 37U ; }
120
120
121
121
static bool isEqual (const unsigned short &LHS, const unsigned short &RHS) {
@@ -125,8 +125,8 @@ template <> struct DenseMapInfo<unsigned short> {
125
125
126
126
// Provide DenseMapInfo for unsigned ints.
127
127
template <> struct DenseMapInfo <unsigned > {
128
- static inline unsigned getEmptyKey () { return ~0U ; }
129
- static inline unsigned getTombstoneKey () { return ~0U - 1 ; }
128
+ static constexpr unsigned getEmptyKey () { return ~0U ; }
129
+ static constexpr unsigned getTombstoneKey () { return ~0U - 1 ; }
130
130
static unsigned getHashValue (const unsigned & Val) { return Val * 37U ; }
131
131
132
132
static bool isEqual (const unsigned & LHS, const unsigned & RHS) {
@@ -136,8 +136,8 @@ template<> struct DenseMapInfo<unsigned> {
136
136
137
137
// Provide DenseMapInfo for unsigned longs.
138
138
template <> struct DenseMapInfo <unsigned long > {
139
- static inline unsigned long getEmptyKey () { return ~0UL ; }
140
- static inline unsigned long getTombstoneKey () { return ~0UL - 1L ; }
139
+ static constexpr unsigned long getEmptyKey () { return ~0UL ; }
140
+ static constexpr unsigned long getTombstoneKey () { return ~0UL - 1L ; }
141
141
142
142
static unsigned getHashValue (const unsigned long & Val) {
143
143
if constexpr (sizeof (Val) == 4 )
@@ -153,8 +153,8 @@ template<> struct DenseMapInfo<unsigned long> {
153
153
154
154
// Provide DenseMapInfo for unsigned long longs.
155
155
template <> struct DenseMapInfo <unsigned long long > {
156
- static inline unsigned long long getEmptyKey () { return ~0ULL ; }
157
- static inline unsigned long long getTombstoneKey () { return ~0ULL - 1ULL ; }
156
+ static constexpr unsigned long long getEmptyKey () { return ~0ULL ; }
157
+ static constexpr unsigned long long getTombstoneKey () { return ~0ULL - 1ULL ; }
158
158
159
159
static unsigned getHashValue (const unsigned long long & Val) {
160
160
return densemap::detail::mix (Val);
@@ -168,16 +168,16 @@ template<> struct DenseMapInfo<unsigned long long> {
168
168
169
169
// Provide DenseMapInfo for shorts.
170
170
template <> struct DenseMapInfo <short > {
171
- static inline short getEmptyKey () { return 0x7FFF ; }
172
- static inline short getTombstoneKey () { return -0x7FFF - 1 ; }
171
+ static constexpr short getEmptyKey () { return 0x7FFF ; }
172
+ static constexpr short getTombstoneKey () { return -0x7FFF - 1 ; }
173
173
static unsigned getHashValue (const short &Val) { return Val * 37U ; }
174
174
static bool isEqual (const short &LHS, const short &RHS) { return LHS == RHS; }
175
175
};
176
176
177
177
// Provide DenseMapInfo for ints.
178
178
template <> struct DenseMapInfo <int > {
179
- static inline int getEmptyKey () { return 0x7fffffff ; }
180
- static inline int getTombstoneKey () { return -0x7fffffff - 1 ; }
179
+ static constexpr int getEmptyKey () { return 0x7fffffff ; }
180
+ static constexpr int getTombstoneKey () { return -0x7fffffff - 1 ; }
181
181
static unsigned getHashValue (const int & Val) { return (unsigned )(Val * 37U ); }
182
182
183
183
static bool isEqual (const int & LHS, const int & RHS) {
@@ -187,11 +187,11 @@ template<> struct DenseMapInfo<int> {
187
187
188
188
// Provide DenseMapInfo for longs.
189
189
template <> struct DenseMapInfo <long > {
190
- static inline long getEmptyKey () {
190
+ static constexpr long getEmptyKey () {
191
191
return (1UL << (sizeof (long ) * 8 - 1 )) - 1UL ;
192
192
}
193
193
194
- static inline long getTombstoneKey () { return getEmptyKey () - 1L ; }
194
+ static constexpr long getTombstoneKey () { return getEmptyKey () - 1L ; }
195
195
196
196
static unsigned getHashValue (const long & Val) {
197
197
return (unsigned )(Val * 37UL );
@@ -204,8 +204,10 @@ template<> struct DenseMapInfo<long> {
204
204
205
205
// Provide DenseMapInfo for long longs.
206
206
template <> struct DenseMapInfo <long long > {
207
- static inline long long getEmptyKey () { return 0x7fffffffffffffffLL ; }
208
- static inline long long getTombstoneKey () { return -0x7fffffffffffffffLL -1 ; }
207
+ static constexpr long long getEmptyKey () { return 0x7fffffffffffffffLL ; }
208
+ static constexpr long long getTombstoneKey () {
209
+ return -0x7fffffffffffffffLL - 1 ;
210
+ }
209
211
210
212
static unsigned getHashValue (const long long & Val) {
211
213
return (unsigned )(Val * 37ULL );
@@ -224,12 +226,12 @@ struct DenseMapInfo<std::pair<T, U>> {
224
226
using FirstInfo = DenseMapInfo<T>;
225
227
using SecondInfo = DenseMapInfo<U>;
226
228
227
- static inline Pair getEmptyKey () {
229
+ static constexpr Pair getEmptyKey () {
228
230
return std::make_pair (FirstInfo::getEmptyKey (),
229
231
SecondInfo::getEmptyKey ());
230
232
}
231
233
232
- static inline Pair getTombstoneKey () {
234
+ static constexpr Pair getTombstoneKey () {
233
235
return std::make_pair (FirstInfo::getTombstoneKey (),
234
236
SecondInfo::getTombstoneKey ());
235
237
}
@@ -257,11 +259,11 @@ struct DenseMapInfo<std::pair<T, U>> {
257
259
template <typename ... Ts> struct DenseMapInfo <std::tuple<Ts...>> {
258
260
using Tuple = std::tuple<Ts...>;
259
261
260
- static inline Tuple getEmptyKey () {
262
+ static constexpr Tuple getEmptyKey () {
261
263
return Tuple (DenseMapInfo<Ts>::getEmptyKey ()...);
262
264
}
263
265
264
- static inline Tuple getTombstoneKey () {
266
+ static constexpr Tuple getTombstoneKey () {
265
267
return Tuple (DenseMapInfo<Ts>::getTombstoneKey ()...);
266
268
}
267
269
@@ -309,10 +311,22 @@ struct DenseMapInfo<Enum, std::enable_if_t<std::is_enum_v<Enum>>> {
309
311
using UnderlyingType = std::underlying_type_t <Enum>;
310
312
using Info = DenseMapInfo<UnderlyingType>;
311
313
312
- static Enum getEmptyKey () { return static_cast <Enum>(Info::getEmptyKey ()); }
314
+ // If an enum does not have a "fixed" underlying type, it may be UB to cast
315
+ // some values of the underlying type to the enum. We use an "extra" constexpr
316
+ // local to ensure that such UB would trigger "static assertion expression is
317
+ // not an integral constant expression", rather than runtime UB.
318
+ //
319
+ // If you hit this error, you can fix by switching to `enum class`, or adding
320
+ // an explicit underlying type (e.g. `enum X : int`) to the enum's definition.
321
+
322
+ static constexpr Enum getEmptyKey () {
323
+ constexpr Enum V = static_cast <Enum>(Info::getEmptyKey ());
324
+ return V;
325
+ }
313
326
314
- static Enum getTombstoneKey () {
315
- return static_cast <Enum>(Info::getTombstoneKey ());
327
+ static constexpr Enum getTombstoneKey () {
328
+ constexpr Enum V = static_cast <Enum>(Info::getTombstoneKey ());
329
+ return V;
316
330
}
317
331
318
332
static unsigned getHashValue (const Enum &Val) {
@@ -326,9 +340,11 @@ template <typename T> struct DenseMapInfo<std::optional<T>> {
326
340
using Optional = std::optional<T>;
327
341
using Info = DenseMapInfo<T>;
328
342
329
- static inline Optional getEmptyKey () { return {Info::getEmptyKey ()}; }
343
+ static constexpr Optional getEmptyKey () { return {Info::getEmptyKey ()}; }
330
344
331
- static inline Optional getTombstoneKey () { return {Info::getTombstoneKey ()}; }
345
+ static constexpr Optional getTombstoneKey () {
346
+ return {Info::getTombstoneKey ()};
347
+ }
332
348
333
349
static unsigned getHashValue (const Optional &OptionalVal) {
334
350
return detail::combineHashValue (
0 commit comments