Home | History | Annotate | Download | only in lib
      1 // Copyright 2016 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_WTF_HASH_UTIL_H_
      6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_WTF_HASH_UTIL_H_
      7 
      8 #include <type_traits>
      9 
     10 #include "mojo/public/cpp/bindings/lib/hash_util.h"
     11 #include "mojo/public/cpp/bindings/struct_ptr.h"
     12 #include "third_party/blink/renderer/platform/wtf/hash_functions.h"
     13 #include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
     14 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
     15 
     16 namespace mojo {
     17 namespace internal {
     18 
     19 template <typename T>
     20 size_t WTFHashCombine(size_t seed, const T& value) {
     21   // Based on proposal in:
     22   // http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
     23   //
     24   // TODO(tibell): We'd like to use WTF::DefaultHash instead of std::hash, but
     25   //     there is no general template specialization of DefaultHash for enums
     26   //     and there can't be an instance for bool.
     27   return seed ^ (std::hash<T>()(value) + (seed << 6) + (seed >> 2));
     28 }
     29 
     30 template <typename T, bool has_hash_method = HasHashMethod<T>::value>
     31 struct WTFHashTraits;
     32 
     33 template <typename T>
     34 size_t WTFHash(size_t seed, const T& value);
     35 
     36 template <typename T>
     37 struct WTFHashTraits<T, true> {
     38   static size_t Hash(size_t seed, const T& value) { return value.Hash(seed); }
     39 };
     40 
     41 template <typename T>
     42 struct WTFHashTraits<T, false> {
     43   static size_t Hash(size_t seed, const T& value) {
     44     return WTFHashCombine(seed, value);
     45   }
     46 };
     47 
     48 template <>
     49 struct WTFHashTraits<WTF::String, false> {
     50   static size_t Hash(size_t seed, const WTF::String& value) {
     51     return HashCombine(seed, WTF::StringHash::GetHash(value));
     52   }
     53 };
     54 
     55 template <typename T>
     56 size_t WTFHash(size_t seed, const T& value) {
     57   return WTFHashTraits<T>::Hash(seed, value);
     58 }
     59 
     60 template <typename T>
     61 struct StructPtrHashFn {
     62   static unsigned GetHash(const StructPtr<T>& value) {
     63     return value.Hash(kHashSeed);
     64   }
     65   static bool Equal(const StructPtr<T>& left, const StructPtr<T>& right) {
     66     return left.Equals(right);
     67   }
     68   static const bool safe_to_compare_to_empty_or_deleted = false;
     69 };
     70 
     71 template <typename T>
     72 struct InlinedStructPtrHashFn {
     73   static unsigned GetHash(const InlinedStructPtr<T>& value) {
     74     return value.Hash(kHashSeed);
     75   }
     76   static bool Equal(const InlinedStructPtr<T>& left,
     77                     const InlinedStructPtr<T>& right) {
     78     return left.Equals(right);
     79   }
     80   static const bool safe_to_compare_to_empty_or_deleted = false;
     81 };
     82 
     83 }  // namespace internal
     84 }  // namespace mojo
     85 
     86 namespace WTF {
     87 
     88 template <typename T>
     89 struct DefaultHash<mojo::StructPtr<T>> {
     90   using Hash = mojo::internal::StructPtrHashFn<T>;
     91 };
     92 
     93 template <typename T>
     94 struct HashTraits<mojo::StructPtr<T>>
     95     : public GenericHashTraits<mojo::StructPtr<T>> {
     96   static const bool kHasIsEmptyValueFunction = true;
     97   static bool IsEmptyValue(const mojo::StructPtr<T>& value) {
     98     return value.is_null();
     99   }
    100   static void ConstructDeletedValue(mojo::StructPtr<T>& slot, bool) {
    101     mojo::internal::StructPtrWTFHelper<T>::ConstructDeletedValue(slot);
    102   }
    103   static bool IsDeletedValue(const mojo::StructPtr<T>& value) {
    104     return mojo::internal::StructPtrWTFHelper<T>::IsHashTableDeletedValue(
    105         value);
    106   }
    107 };
    108 
    109 template <typename T>
    110 struct DefaultHash<mojo::InlinedStructPtr<T>> {
    111   using Hash = mojo::internal::InlinedStructPtrHashFn<T>;
    112 };
    113 
    114 template <typename T>
    115 struct HashTraits<mojo::InlinedStructPtr<T>>
    116     : public GenericHashTraits<mojo::InlinedStructPtr<T>> {
    117   static const bool kHasIsEmptyValueFunction = true;
    118   static bool IsEmptyValue(const mojo::InlinedStructPtr<T>& value) {
    119     return value.is_null();
    120   }
    121   static void ConstructDeletedValue(mojo::InlinedStructPtr<T>& slot, bool) {
    122     mojo::internal::InlinedStructPtrWTFHelper<T>::ConstructDeletedValue(slot);
    123   }
    124   static bool IsDeletedValue(const mojo::InlinedStructPtr<T>& value) {
    125     return mojo::internal::InlinedStructPtrWTFHelper<
    126         T>::IsHashTableDeletedValue(value);
    127   }
    128 };
    129 
    130 }  // namespace WTF
    131 
    132 #endif  // MOJO_PUBLIC_CPP_BINDINGS_LIB_WTF_HASH_UTIL_H_
    133