DenseMapInfo.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. //===- llvm/ADT/DenseMapInfo.h - Type traits for DenseMap -------*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file defines DenseMapInfo traits for DenseMap.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_ADT_DENSEMAPINFO_H
  14. #define LLVM_ADT_DENSEMAPINFO_H
  15. #include "llvm/ADT/Hashing.h"
  16. #include "llvm/ADT/StringRef.h"
  17. #include "llvm/Support/PointerLikeTypeTraits.h"
  18. #include "llvm/Support/type_traits.h"
  19. namespace llvm {
  20. template<typename T>
  21. struct DenseMapInfo {
  22. //static inline T getEmptyKey();
  23. //static inline T getTombstoneKey();
  24. //static unsigned getHashValue(const T &Val);
  25. //static bool isEqual(const T &LHS, const T &RHS);
  26. };
  27. // Provide DenseMapInfo for all pointers.
  28. template<typename T>
  29. struct DenseMapInfo<T*> {
  30. static inline T* getEmptyKey() {
  31. uintptr_t Val = static_cast<uintptr_t>(-1);
  32. Val <<= PointerLikeTypeTraits<T*>::NumLowBitsAvailable;
  33. return reinterpret_cast<T*>(Val);
  34. }
  35. static inline T* getTombstoneKey() {
  36. uintptr_t Val = static_cast<uintptr_t>(-2);
  37. Val <<= PointerLikeTypeTraits<T*>::NumLowBitsAvailable;
  38. return reinterpret_cast<T*>(Val);
  39. }
  40. static unsigned getHashValue(const T *PtrVal) {
  41. return (unsigned((uintptr_t)PtrVal) >> 4) ^
  42. (unsigned((uintptr_t)PtrVal) >> 9);
  43. }
  44. static bool isEqual(const T *LHS, const T *RHS) { return LHS == RHS; }
  45. };
  46. // Provide DenseMapInfo for chars.
  47. template<> struct DenseMapInfo<char> {
  48. static inline char getEmptyKey() { return ~0; }
  49. static inline char getTombstoneKey() { return ~0 - 1; }
  50. static unsigned getHashValue(const char& Val) { return Val * 37U; }
  51. static bool isEqual(const char &LHS, const char &RHS) {
  52. return LHS == RHS;
  53. }
  54. };
  55. // Provide DenseMapInfo for unsigned ints.
  56. template<> struct DenseMapInfo<unsigned> {
  57. static inline unsigned getEmptyKey() { return ~0U; }
  58. static inline unsigned getTombstoneKey() { return ~0U - 1; }
  59. static unsigned getHashValue(const unsigned& Val) { return Val * 37U; }
  60. static bool isEqual(const unsigned& LHS, const unsigned& RHS) {
  61. return LHS == RHS;
  62. }
  63. };
  64. // Provide DenseMapInfo for unsigned longs.
  65. template<> struct DenseMapInfo<unsigned long> {
  66. static inline unsigned long getEmptyKey() { return ~0UL; }
  67. static inline unsigned long getTombstoneKey() { return ~0UL - 1L; }
  68. static unsigned getHashValue(const unsigned long& Val) {
  69. return (unsigned)(Val * 37UL);
  70. }
  71. static bool isEqual(const unsigned long& LHS, const unsigned long& RHS) {
  72. return LHS == RHS;
  73. }
  74. };
  75. // Provide DenseMapInfo for unsigned long longs.
  76. template<> struct DenseMapInfo<unsigned long long> {
  77. static inline unsigned long long getEmptyKey() { return ~0ULL; }
  78. static inline unsigned long long getTombstoneKey() { return ~0ULL - 1ULL; }
  79. static unsigned getHashValue(const unsigned long long& Val) {
  80. return (unsigned)(Val * 37ULL);
  81. }
  82. static bool isEqual(const unsigned long long& LHS,
  83. const unsigned long long& RHS) {
  84. return LHS == RHS;
  85. }
  86. };
  87. // Provide DenseMapInfo for ints.
  88. template<> struct DenseMapInfo<int> {
  89. static inline int getEmptyKey() { return 0x7fffffff; }
  90. static inline int getTombstoneKey() { return -0x7fffffff - 1; }
  91. static unsigned getHashValue(const int& Val) { return (unsigned)(Val * 37U); }
  92. static bool isEqual(const int& LHS, const int& RHS) {
  93. return LHS == RHS;
  94. }
  95. };
  96. // Provide DenseMapInfo for longs.
  97. template<> struct DenseMapInfo<long> {
  98. static inline long getEmptyKey() {
  99. return (1UL << (sizeof(long) * 8 - 1)) - 1UL;
  100. }
  101. static inline long getTombstoneKey() { return getEmptyKey() - 1L; }
  102. static unsigned getHashValue(const long& Val) {
  103. return (unsigned)(Val * 37UL);
  104. }
  105. static bool isEqual(const long& LHS, const long& RHS) {
  106. return LHS == RHS;
  107. }
  108. };
  109. // Provide DenseMapInfo for long longs.
  110. template<> struct DenseMapInfo<long long> {
  111. static inline long long getEmptyKey() { return 0x7fffffffffffffffLL; }
  112. static inline long long getTombstoneKey() { return -0x7fffffffffffffffLL-1; }
  113. static unsigned getHashValue(const long long& Val) {
  114. return (unsigned)(Val * 37ULL);
  115. }
  116. static bool isEqual(const long long& LHS,
  117. const long long& RHS) {
  118. return LHS == RHS;
  119. }
  120. };
  121. // Provide DenseMapInfo for all pairs whose members have info.
  122. template<typename T, typename U>
  123. struct DenseMapInfo<std::pair<T, U> > {
  124. typedef std::pair<T, U> Pair;
  125. typedef DenseMapInfo<T> FirstInfo;
  126. typedef DenseMapInfo<U> SecondInfo;
  127. static inline Pair getEmptyKey() {
  128. return std::make_pair(FirstInfo::getEmptyKey(),
  129. SecondInfo::getEmptyKey());
  130. }
  131. static inline Pair getTombstoneKey() {
  132. return std::make_pair(FirstInfo::getTombstoneKey(),
  133. SecondInfo::getTombstoneKey());
  134. }
  135. static unsigned getHashValue(const Pair& PairVal) {
  136. uint64_t key = (uint64_t)FirstInfo::getHashValue(PairVal.first) << 32
  137. | (uint64_t)SecondInfo::getHashValue(PairVal.second);
  138. key += ~(key << 32);
  139. key ^= (key >> 22);
  140. key += ~(key << 13);
  141. key ^= (key >> 8);
  142. key += (key << 3);
  143. key ^= (key >> 15);
  144. key += ~(key << 27);
  145. key ^= (key >> 31);
  146. return (unsigned)key;
  147. }
  148. static bool isEqual(const Pair &LHS, const Pair &RHS) {
  149. return FirstInfo::isEqual(LHS.first, RHS.first) &&
  150. SecondInfo::isEqual(LHS.second, RHS.second);
  151. }
  152. };
  153. // Provide DenseMapInfo for StringRefs.
  154. template <> struct DenseMapInfo<StringRef> {
  155. static inline StringRef getEmptyKey() {
  156. return StringRef(reinterpret_cast<const char *>(~static_cast<uintptr_t>(0)),
  157. 0);
  158. }
  159. static inline StringRef getTombstoneKey() {
  160. return StringRef(reinterpret_cast<const char *>(~static_cast<uintptr_t>(1)),
  161. 0);
  162. }
  163. static unsigned getHashValue(StringRef Val) {
  164. assert(Val.data() != getEmptyKey().data() && "Cannot hash the empty key!");
  165. assert(Val.data() != getTombstoneKey().data() &&
  166. "Cannot hash the tombstone key!");
  167. return (unsigned)(hash_value(Val));
  168. }
  169. static bool isEqual(StringRef LHS, StringRef RHS) {
  170. if (RHS.data() == getEmptyKey().data())
  171. return LHS.data() == getEmptyKey().data();
  172. if (RHS.data() == getTombstoneKey().data())
  173. return LHS.data() == getTombstoneKey().data();
  174. return LHS == RHS;
  175. }
  176. };
  177. } // end namespace llvm
  178. #endif