LLVM API Documentation
00001 //===- llvm/ADT/DenseMapInfo.h - Type traits for DenseMap -------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines DenseMapInfo traits for DenseMap. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_ADT_DENSEMAPINFO_H 00015 #define LLVM_ADT_DENSEMAPINFO_H 00016 00017 #include "llvm/Support/PointerLikeTypeTraits.h" 00018 #include "llvm/Support/type_traits.h" 00019 00020 namespace llvm { 00021 00022 template<typename T> 00023 struct DenseMapInfo { 00024 //static inline T getEmptyKey(); 00025 //static inline T getTombstoneKey(); 00026 //static unsigned getHashValue(const T &Val); 00027 //static bool isEqual(const T &LHS, const T &RHS); 00028 }; 00029 00030 // Provide DenseMapInfo for all pointers. 00031 template<typename T> 00032 struct DenseMapInfo<T*> { 00033 static inline T* getEmptyKey() { 00034 uintptr_t Val = static_cast<uintptr_t>(-1); 00035 Val <<= PointerLikeTypeTraits<T*>::NumLowBitsAvailable; 00036 return reinterpret_cast<T*>(Val); 00037 } 00038 static inline T* getTombstoneKey() { 00039 uintptr_t Val = static_cast<uintptr_t>(-2); 00040 Val <<= PointerLikeTypeTraits<T*>::NumLowBitsAvailable; 00041 return reinterpret_cast<T*>(Val); 00042 } 00043 static unsigned getHashValue(const T *PtrVal) { 00044 return (unsigned((uintptr_t)PtrVal) >> 4) ^ 00045 (unsigned((uintptr_t)PtrVal) >> 9); 00046 } 00047 static bool isEqual(const T *LHS, const T *RHS) { return LHS == RHS; } 00048 }; 00049 00050 // Provide DenseMapInfo for chars. 00051 template<> struct DenseMapInfo<char> { 00052 static inline char getEmptyKey() { return ~0; } 00053 static inline char getTombstoneKey() { return ~0 - 1; } 00054 static unsigned getHashValue(const char& Val) { return Val * 37U; } 00055 static bool isEqual(const char &LHS, const char &RHS) { 00056 return LHS == RHS; 00057 } 00058 }; 00059 00060 // Provide DenseMapInfo for unsigned ints. 00061 template<> struct DenseMapInfo<unsigned> { 00062 static inline unsigned getEmptyKey() { return ~0U; } 00063 static inline unsigned getTombstoneKey() { return ~0U - 1; } 00064 static unsigned getHashValue(const unsigned& Val) { return Val * 37U; } 00065 static bool isEqual(const unsigned& LHS, const unsigned& RHS) { 00066 return LHS == RHS; 00067 } 00068 }; 00069 00070 // Provide DenseMapInfo for unsigned longs. 00071 template<> struct DenseMapInfo<unsigned long> { 00072 static inline unsigned long getEmptyKey() { return ~0UL; } 00073 static inline unsigned long getTombstoneKey() { return ~0UL - 1L; } 00074 static unsigned getHashValue(const unsigned long& Val) { 00075 return (unsigned)(Val * 37UL); 00076 } 00077 static bool isEqual(const unsigned long& LHS, const unsigned long& RHS) { 00078 return LHS == RHS; 00079 } 00080 }; 00081 00082 // Provide DenseMapInfo for unsigned long longs. 00083 template<> struct DenseMapInfo<unsigned long long> { 00084 static inline unsigned long long getEmptyKey() { return ~0ULL; } 00085 static inline unsigned long long getTombstoneKey() { return ~0ULL - 1ULL; } 00086 static unsigned getHashValue(const unsigned long long& Val) { 00087 return (unsigned)(Val * 37ULL); 00088 } 00089 static bool isEqual(const unsigned long long& LHS, 00090 const unsigned long long& RHS) { 00091 return LHS == RHS; 00092 } 00093 }; 00094 00095 // Provide DenseMapInfo for ints. 00096 template<> struct DenseMapInfo<int> { 00097 static inline int getEmptyKey() { return 0x7fffffff; } 00098 static inline int getTombstoneKey() { return -0x7fffffff - 1; } 00099 static unsigned getHashValue(const int& Val) { return (unsigned)(Val * 37U); } 00100 static bool isEqual(const int& LHS, const int& RHS) { 00101 return LHS == RHS; 00102 } 00103 }; 00104 00105 // Provide DenseMapInfo for longs. 00106 template<> struct DenseMapInfo<long> { 00107 static inline long getEmptyKey() { 00108 return (1UL << (sizeof(long) * 8 - 1)) - 1UL; 00109 } 00110 static inline long getTombstoneKey() { return getEmptyKey() - 1L; } 00111 static unsigned getHashValue(const long& Val) { 00112 return (unsigned)(Val * 37UL); 00113 } 00114 static bool isEqual(const long& LHS, const long& RHS) { 00115 return LHS == RHS; 00116 } 00117 }; 00118 00119 // Provide DenseMapInfo for long longs. 00120 template<> struct DenseMapInfo<long long> { 00121 static inline long long getEmptyKey() { return 0x7fffffffffffffffLL; } 00122 static inline long long getTombstoneKey() { return -0x7fffffffffffffffLL-1; } 00123 static unsigned getHashValue(const long long& Val) { 00124 return (unsigned)(Val * 37ULL); 00125 } 00126 static bool isEqual(const long long& LHS, 00127 const long long& RHS) { 00128 return LHS == RHS; 00129 } 00130 }; 00131 00132 // Provide DenseMapInfo for all pairs whose members have info. 00133 template<typename T, typename U> 00134 struct DenseMapInfo<std::pair<T, U> > { 00135 typedef std::pair<T, U> Pair; 00136 typedef DenseMapInfo<T> FirstInfo; 00137 typedef DenseMapInfo<U> SecondInfo; 00138 00139 static inline Pair getEmptyKey() { 00140 return std::make_pair(FirstInfo::getEmptyKey(), 00141 SecondInfo::getEmptyKey()); 00142 } 00143 static inline Pair getTombstoneKey() { 00144 return std::make_pair(FirstInfo::getTombstoneKey(), 00145 SecondInfo::getTombstoneKey()); 00146 } 00147 static unsigned getHashValue(const Pair& PairVal) { 00148 uint64_t key = (uint64_t)FirstInfo::getHashValue(PairVal.first) << 32 00149 | (uint64_t)SecondInfo::getHashValue(PairVal.second); 00150 key += ~(key << 32); 00151 key ^= (key >> 22); 00152 key += ~(key << 13); 00153 key ^= (key >> 8); 00154 key += (key << 3); 00155 key ^= (key >> 15); 00156 key += ~(key << 27); 00157 key ^= (key >> 31); 00158 return (unsigned)key; 00159 } 00160 static bool isEqual(const Pair &LHS, const Pair &RHS) { 00161 return FirstInfo::isEqual(LHS.first, RHS.first) && 00162 SecondInfo::isEqual(LHS.second, RHS.second); 00163 } 00164 }; 00165 00166 } // end namespace llvm 00167 00168 #endif