// Copyright 2016 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_HASH_UTIL_H_ #define MOJO_PUBLIC_CPP_BINDINGS_LIB_HASH_UTIL_H_ #include #include #include #include #include "base/optional.h" #include "mojo/public/cpp/bindings/lib/template_util.h" namespace mojo { namespace internal { template size_t HashCombine(size_t seed, const T& value) { // Based on proposal in: // http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf return seed ^ (std::hash()(value) + (seed << 6) + (seed >> 2)); } template struct HasHashMethod { template static char Test(decltype(&U::Hash)); template static int Test(...); static const bool value = sizeof(Test(0)) == sizeof(char); private: EnsureTypeIsComplete check_t_; }; template ::value> struct HashTraits; template size_t Hash(size_t seed, const T& value); template struct HashTraits { static size_t Hash(size_t seed, const T& value) { return value.Hash(seed); } }; template struct HashTraits { static size_t Hash(size_t seed, const T& value) { return HashCombine(seed, value); } }; template struct HashTraits, false> { static size_t Hash(size_t seed, const std::vector& value) { for (const auto& element : value) { seed = HashCombine(seed, element); } return seed; } }; template struct HashTraits>, false> { static size_t Hash(size_t seed, const base::Optional>& value) { if (!value) return HashCombine(seed, 0); return Hash(seed, *value); } }; template size_t Hash(size_t seed, const T& value) { return HashTraits::Hash(seed, value); } } // namespace internal } // namespace mojo #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_HASH_UTIL_H_