Add hashing and DenseMapInfo for ArrayRef
authorRafael Espindola <rafael.espindola@gmail.com>
Sun, 18 Oct 2015 14:04:56 +0000 (14:04 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Sun, 18 Oct 2015 14:04:56 +0000 (14:04 +0000)
Sometimes it is more natural to use a ArrayRef<uint8_t> than a StringRef to
represent a range of bytes that is not, semantically, a string.

This will be used in lld in a sec.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@250658 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ADT/ArrayRef.h
include/llvm/ADT/DenseMapInfo.h

index aaf32ff020ef12731abe6af17e76a909673392e7..517ba39849e1def8ad29d8aa80ef914a6615203c 100644 (file)
@@ -10,6 +10,7 @@
 #ifndef LLVM_ADT_ARRAYREF_H
 #define LLVM_ADT_ARRAYREF_H
 
+#include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/None.h"
 #include "llvm/ADT/SmallVector.h"
 #include <vector>
@@ -374,6 +375,10 @@ namespace llvm {
   template <typename T> struct isPodLike<ArrayRef<T> > {
     static const bool value = true;
   };
+
+  template <typename T> hash_code hash_value(ArrayRef<T> S) {
+    return hash_combine_range(S.begin(), S.end());
+  }
 }
 
 #endif
index 07f79df0d200717f952d046246c258afac40d54e..a844ebcccf5b89306186097295bb4d9b5f4b86a4 100644 (file)
@@ -14,6 +14,7 @@
 #ifndef LLVM_ADT_DENSEMAPINFO_H
 #define LLVM_ADT_DENSEMAPINFO_H
 
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/PointerLikeTypeTraits.h"
@@ -190,6 +191,31 @@ template <> struct DenseMapInfo<StringRef> {
   }
 };
 
+// Provide DenseMapInfo for ArrayRefs.
+template <typename T> struct DenseMapInfo<ArrayRef<T>> {
+  static inline ArrayRef<T> getEmptyKey() {
+    return ArrayRef<T>(reinterpret_cast<const T *>(~static_cast<uintptr_t>(0)),
+                       size_t(0));
+  }
+  static inline ArrayRef<T> getTombstoneKey() {
+    return ArrayRef<T>(reinterpret_cast<const T *>(~static_cast<uintptr_t>(1)),
+                       size_t(0));
+  }
+  static unsigned getHashValue(ArrayRef<T> Val) {
+    assert(Val.data() != getEmptyKey().data() && "Cannot hash the empty key!");
+    assert(Val.data() != getTombstoneKey().data() &&
+           "Cannot hash the tombstone key!");
+    return (unsigned)(hash_value(Val));
+  }
+  static bool isEqual(ArrayRef<T> LHS, ArrayRef<T> RHS) {
+    if (RHS.data() == getEmptyKey().data())
+      return LHS.data() == getEmptyKey().data();
+    if (RHS.data() == getTombstoneKey().data())
+      return LHS.data() == getTombstoneKey().data();
+    return LHS == RHS;
+  }
+};
+
 } // end namespace llvm
 
 #endif