mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
introduce hash_combine (#39511)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/39511 changelog: [internal] C++ standard library doesn't offer a way to combine hashes together. This is implementation for uses in React Native code. Reviewed By: javache Differential Revision: D49349539 fbshipit-source-id: 1e1f47585969181d5910f5bbc5b6ebfffa12e96b
This commit is contained in:
committed by
Facebook GitHub Bot
parent
d6c9a488b2
commit
bf186471d3
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename... Rest,
|
||||
bool Enabled = !std::is_same<T, const char*>::value,
|
||||
typename = typename std::enable_if<Enabled>::type>
|
||||
void hash_combine(std::size_t& seed, const T& v, const Rest&... rest) {
|
||||
seed ^= std::hash<T>{}(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||
(hash_combine(seed, rest), ...);
|
||||
}
|
||||
|
||||
template <typename T, typename... Args>
|
||||
std::size_t hash_combine(const T& v, const Args&... args) {
|
||||
std::size_t seed = 0;
|
||||
hash_combine<T, Args...>(seed, v, args...);
|
||||
return seed;
|
||||
}
|
||||
|
||||
} // namespace facebook::react
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <react/utils/hash_combine.h>
|
||||
|
||||
struct Person {
|
||||
std::string firstName;
|
||||
std::string lastName;
|
||||
};
|
||||
|
||||
namespace std {
|
||||
template <>
|
||||
struct hash<Person> {
|
||||
size_t operator()(const Person& person) const {
|
||||
return facebook::react::hash_combine(person.firstName, person.lastName);
|
||||
}
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
TEST(hash_combineTests, testIntegerTemplating) {
|
||||
std::size_t seed = 0;
|
||||
hash_combine(seed, 1);
|
||||
|
||||
auto hashedValue = hash_combine(1);
|
||||
EXPECT_EQ(hashedValue, seed);
|
||||
|
||||
EXPECT_NE(hash_combine(1), hash_combine(2));
|
||||
}
|
||||
|
||||
TEST(hash_combineTests, testIntegerCombinationsHashing) {
|
||||
std::size_t seed = 0;
|
||||
hash_combine(seed, 1, 2);
|
||||
|
||||
auto hashedValue = hash_combine(1, 2);
|
||||
EXPECT_EQ(hashedValue, seed);
|
||||
|
||||
EXPECT_NE(hash_combine(1, 2), hash_combine(2, 1));
|
||||
}
|
||||
|
||||
TEST(hash_combineTests, testContiniousIntegerHashing) {
|
||||
std::size_t seed = 0;
|
||||
|
||||
for (int i = 1; i <= 200; ++i) {
|
||||
auto previousSeed = seed;
|
||||
hash_combine(seed, i);
|
||||
EXPECT_NE(seed, previousSeed);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(hash_combineTests, testStrings) {
|
||||
std::size_t seed = 0;
|
||||
hash_combine<std::string>(seed, "react");
|
||||
|
||||
auto hashedValue = hash_combine<std::string>("react");
|
||||
EXPECT_EQ(hashedValue, seed);
|
||||
|
||||
EXPECT_NE(
|
||||
hash_combine<std::string>("react"),
|
||||
hash_combine<std::string>("react native"));
|
||||
}
|
||||
|
||||
TEST(hash_combineTests, testCustomTypes) {
|
||||
auto person1 = Person{"John", "Doe"};
|
||||
auto person2 = Person{"Jane", "Doe"};
|
||||
|
||||
std::size_t seed = 0;
|
||||
hash_combine(seed, person1);
|
||||
|
||||
auto hashedValue = hash_combine(person1);
|
||||
EXPECT_EQ(hashedValue, seed);
|
||||
|
||||
EXPECT_NE(hash_combine(person1), hash_combine(person2));
|
||||
}
|
||||
|
||||
} // namespace facebook::react
|
||||
Reference in New Issue
Block a user