forked from OSchip/llvm-project
[llvm] Add support for hashing std::optional
The credit for the hashing code, taken from D138934, goes to Ramkumar Ramachandra. The test comes from OptionalTest.cpp and updated for std::optional. This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716 Differential Revision: https://reviews.llvm.org/D139240
This commit is contained in:
parent
8a1f12c6fb
commit
f64d4a26ce
|
@ -51,6 +51,7 @@
|
|||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
@ -122,6 +123,8 @@ hash_code hash_value(const std::tuple<Ts...> &arg);
|
|||
template <typename T>
|
||||
hash_code hash_value(const std::basic_string<T> &arg);
|
||||
|
||||
/// Compute a hash_code for a standard string.
|
||||
template <typename T> hash_code hash_value(const std::optional<T> &arg);
|
||||
|
||||
/// Override the execution seed with a fixed value.
|
||||
///
|
||||
|
@ -662,6 +665,10 @@ hash_code hash_value(const std::basic_string<T> &arg) {
|
|||
return hash_combine_range(arg.begin(), arg.end());
|
||||
}
|
||||
|
||||
template <typename T> hash_code hash_value(const std::optional<T> &arg) {
|
||||
return arg ? hash_combine(true, *arg) : hash_value(false);
|
||||
}
|
||||
|
||||
template <> struct DenseMapInfo<hash_code, void> {
|
||||
static inline hash_code getEmptyKey() { return hash_code(-1); }
|
||||
static inline hash_code getTombstoneKey() { return hash_code(-2); }
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <deque>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
@ -130,6 +131,23 @@ TEST(HashingTest, HashValueStdString) {
|
|||
hash_value(ws.substr(1, ws.size() - 2)));
|
||||
}
|
||||
|
||||
TEST(HashingTest, HashValueStdOptional) {
|
||||
// Check that std::nullopt, false, and true all hash differently.
|
||||
std::optional<bool> B, B0 = false, B1 = true;
|
||||
EXPECT_NE(hash_value(B0), hash_value(B));
|
||||
EXPECT_NE(hash_value(B1), hash_value(B));
|
||||
EXPECT_NE(hash_value(B1), hash_value(B0));
|
||||
|
||||
// Check that std::nullopt, 0, and 1 all hash differently.
|
||||
std::optional<int> I, I0 = 0, I1 = 1;
|
||||
EXPECT_NE(hash_value(I0), hash_value(I));
|
||||
EXPECT_NE(hash_value(I1), hash_value(I));
|
||||
EXPECT_NE(hash_value(I1), hash_value(I0));
|
||||
|
||||
// Check std::nullopt hash the same way regardless of type.
|
||||
EXPECT_EQ(hash_value(B), hash_value(I));
|
||||
}
|
||||
|
||||
template <typename T, size_t N> T *begin(T (&arr)[N]) { return arr; }
|
||||
template <typename T, size_t N> T *end(T (&arr)[N]) { return arr + N; }
|
||||
|
||||
|
|
Loading…
Reference in New Issue