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