LLVM API Documentation

DenseMapInfo.h
Go to the documentation of this file.
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