11076082aSAlexandre Rames //===- llvm/unittest/Support/HashBuilderTest.cpp - HashBuilder unit tests -===//
21076082aSAlexandre Rames //
31076082aSAlexandre Rames // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
41076082aSAlexandre Rames // See https://llvm.org/LICENSE.txt for license information.
51076082aSAlexandre Rames // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61076082aSAlexandre Rames //
71076082aSAlexandre Rames //===----------------------------------------------------------------------===//
81076082aSAlexandre Rames
91076082aSAlexandre Rames #include "llvm/Support/HashBuilder.h"
101076082aSAlexandre Rames #include "llvm/ADT/ArrayRef.h"
111076082aSAlexandre Rames #include "llvm/Support/MD5.h"
121076082aSAlexandre Rames #include "llvm/Support/SHA1.h"
131076082aSAlexandre Rames #include "llvm/Support/SHA256.h"
141076082aSAlexandre Rames #include "gtest/gtest.h"
151076082aSAlexandre Rames
161076082aSAlexandre Rames #include <list>
171076082aSAlexandre Rames #include <string>
181076082aSAlexandre Rames #include <type_traits>
191076082aSAlexandre Rames #include <utility>
201076082aSAlexandre Rames #include <vector>
211076082aSAlexandre Rames
221076082aSAlexandre Rames // gtest utilities and macros rely on using a single type. So wrap both the
231076082aSAlexandre Rames // hasher type and endianness.
24d7b18d50SKazu Hirata template <typename _HasherT, llvm::endianness _Endianness>
251076082aSAlexandre Rames struct HasherTAndEndianness {
261076082aSAlexandre Rames using HasherT = _HasherT;
27d7b18d50SKazu Hirata static constexpr llvm::endianness Endianness = _Endianness;
281076082aSAlexandre Rames };
29*b8885926SKazu Hirata using HasherTAndEndiannessToTest = ::testing::Types<
30*b8885926SKazu Hirata HasherTAndEndianness<llvm::MD5, llvm::endianness::big>,
31*b8885926SKazu Hirata HasherTAndEndianness<llvm::MD5, llvm::endianness::little>,
32*b8885926SKazu Hirata HasherTAndEndianness<llvm::MD5, llvm::endianness::native>,
33*b8885926SKazu Hirata HasherTAndEndianness<llvm::SHA1, llvm::endianness::big>,
34*b8885926SKazu Hirata HasherTAndEndianness<llvm::SHA1, llvm::endianness::little>,
35*b8885926SKazu Hirata HasherTAndEndianness<llvm::SHA1, llvm::endianness::native>,
36*b8885926SKazu Hirata HasherTAndEndianness<llvm::SHA256, llvm::endianness::big>,
37*b8885926SKazu Hirata HasherTAndEndianness<llvm::SHA256, llvm::endianness::little>,
38*b8885926SKazu Hirata HasherTAndEndianness<llvm::SHA256, llvm::endianness::native>>;
391076082aSAlexandre Rames template <typename HasherT> class HashBuilderTest : public testing::Test {};
40d79bb30dSAlexandre Rames TYPED_TEST_SUITE(HashBuilderTest, HasherTAndEndiannessToTest, );
411076082aSAlexandre Rames
421076082aSAlexandre Rames template <typename HasherTAndEndianness>
431076082aSAlexandre Rames using HashBuilder = llvm::HashBuilder<typename HasherTAndEndianness::HasherT,
441076082aSAlexandre Rames HasherTAndEndianness::Endianness>;
451076082aSAlexandre Rames
461076082aSAlexandre Rames template <typename HasherTAndEndianness, typename... Ts>
47330268baSArgyrios Kyrtzidis static typename HashBuilder<HasherTAndEndianness>::template HashResultTy<>
hashWithBuilder(const Ts &...Args)48330268baSArgyrios Kyrtzidis hashWithBuilder(const Ts &...Args) {
49330268baSArgyrios Kyrtzidis return HashBuilder<HasherTAndEndianness>().add(Args...).final();
501076082aSAlexandre Rames }
511076082aSAlexandre Rames
521076082aSAlexandre Rames template <typename HasherTAndEndianness, typename... Ts>
53330268baSArgyrios Kyrtzidis static typename HashBuilder<HasherTAndEndianness>::template HashResultTy<>
hashRangeWithBuilder(const Ts &...Args)54330268baSArgyrios Kyrtzidis hashRangeWithBuilder(const Ts &...Args) {
55330268baSArgyrios Kyrtzidis return HashBuilder<HasherTAndEndianness>().addRange(Args...).final();
561076082aSAlexandre Rames }
571076082aSAlexandre Rames
581076082aSAlexandre Rames // All the test infrastructure relies on the variadic helpers. Test them first.
TYPED_TEST(HashBuilderTest,VariadicHelpers)591076082aSAlexandre Rames TYPED_TEST(HashBuilderTest, VariadicHelpers) {
601076082aSAlexandre Rames {
611076082aSAlexandre Rames HashBuilder<TypeParam> HBuilder;
621076082aSAlexandre Rames
631076082aSAlexandre Rames HBuilder.add(100);
641076082aSAlexandre Rames HBuilder.add('c');
651076082aSAlexandre Rames HBuilder.add("string");
661076082aSAlexandre Rames
671076082aSAlexandre Rames EXPECT_EQ(HBuilder.final(), hashWithBuilder<TypeParam>(100, 'c', "string"));
681076082aSAlexandre Rames }
691076082aSAlexandre Rames
701076082aSAlexandre Rames {
711076082aSAlexandre Rames HashBuilder<TypeParam> HBuilder;
721076082aSAlexandre Rames
731076082aSAlexandre Rames std::vector<int> Vec{100, 101, 102};
741076082aSAlexandre Rames HBuilder.addRange(Vec);
751076082aSAlexandre Rames
761076082aSAlexandre Rames EXPECT_EQ(HBuilder.final(), hashRangeWithBuilder<TypeParam>(Vec));
771076082aSAlexandre Rames }
781076082aSAlexandre Rames
791076082aSAlexandre Rames {
801076082aSAlexandre Rames HashBuilder<TypeParam> HBuilder;
811076082aSAlexandre Rames
821076082aSAlexandre Rames std::vector<int> Vec{200, 201, 202};
831076082aSAlexandre Rames HBuilder.addRange(Vec.begin(), Vec.end());
841076082aSAlexandre Rames
851076082aSAlexandre Rames EXPECT_EQ(HBuilder.final(),
861076082aSAlexandre Rames hashRangeWithBuilder<TypeParam>(Vec.begin(), Vec.end()));
871076082aSAlexandre Rames }
881076082aSAlexandre Rames }
891076082aSAlexandre Rames
TYPED_TEST(HashBuilderTest,AddRangeElements)901076082aSAlexandre Rames TYPED_TEST(HashBuilderTest, AddRangeElements) {
911076082aSAlexandre Rames HashBuilder<TypeParam> HBuilder;
921076082aSAlexandre Rames int Values[] = {1, 2, 3};
931076082aSAlexandre Rames HBuilder.addRangeElements(llvm::ArrayRef<int>(Values));
941076082aSAlexandre Rames EXPECT_EQ(HBuilder.final(), hashWithBuilder<TypeParam>(1, 2, 3));
951076082aSAlexandre Rames }
961076082aSAlexandre Rames
TYPED_TEST(HashBuilderTest,AddHashableData)971076082aSAlexandre Rames TYPED_TEST(HashBuilderTest, AddHashableData) {
981076082aSAlexandre Rames using HE = TypeParam;
991076082aSAlexandre Rames
1001076082aSAlexandre Rames auto ByteSwapAndHashWithHasher = [](auto Data) {
1011076082aSAlexandre Rames using H = typename HE::HasherT;
1021076082aSAlexandre Rames constexpr auto E = HE::Endianness;
1031076082aSAlexandre Rames H Hasher;
1041076082aSAlexandre Rames auto SwappedData = llvm::support::endian::byte_swap(Data, E);
10538818b60Sserge-sans-paille Hasher.update(llvm::ArrayRef(
1061076082aSAlexandre Rames reinterpret_cast<const uint8_t *>(&SwappedData), sizeof(Data)));
107330268baSArgyrios Kyrtzidis return Hasher.final();
1081076082aSAlexandre Rames };
1091076082aSAlexandre Rames
1101076082aSAlexandre Rames char C = 'c';
1111076082aSAlexandre Rames int32_t I = 0x12345678;
1121076082aSAlexandre Rames uint64_t UI64 = static_cast<uint64_t>(1) << 50;
1131076082aSAlexandre Rames enum TestEnumeration : uint16_t { TE_One = 1, TE_Two = 2 };
1141076082aSAlexandre Rames TestEnumeration Enum = TE_Two;
1151076082aSAlexandre Rames
1161076082aSAlexandre Rames EXPECT_EQ(ByteSwapAndHashWithHasher(C), hashWithBuilder<HE>(C));
1171076082aSAlexandre Rames EXPECT_EQ(ByteSwapAndHashWithHasher(I), hashWithBuilder<HE>(I));
1181076082aSAlexandre Rames EXPECT_EQ(ByteSwapAndHashWithHasher(UI64), hashWithBuilder<HE>(UI64));
1191076082aSAlexandre Rames EXPECT_EQ(ByteSwapAndHashWithHasher(Enum), hashWithBuilder<HE>(Enum));
1201076082aSAlexandre Rames }
1211076082aSAlexandre Rames
1221076082aSAlexandre Rames struct SimpleStruct {
1231076082aSAlexandre Rames char C;
1241076082aSAlexandre Rames int I;
1251076082aSAlexandre Rames };
1261076082aSAlexandre Rames
127d7b18d50SKazu Hirata template <typename HasherT, llvm::endianness Endianness>
addHash(llvm::HashBuilder<HasherT,Endianness> & HBuilder,const SimpleStruct & Value)128f37028c2SKazu Hirata void addHash(llvm::HashBuilder<HasherT, Endianness> &HBuilder,
1291076082aSAlexandre Rames const SimpleStruct &Value) {
1301076082aSAlexandre Rames HBuilder.add(Value.C);
1311076082aSAlexandre Rames HBuilder.add(Value.I);
1321076082aSAlexandre Rames }
1331076082aSAlexandre Rames
1341076082aSAlexandre Rames struct StructWithoutCopyOrMove {
1351076082aSAlexandre Rames int I;
1361076082aSAlexandre Rames StructWithoutCopyOrMove() = default;
StructWithoutCopyOrMoveStructWithoutCopyOrMove137f039a2cfSSamira Bazuzi explicit StructWithoutCopyOrMove(int I) : I(I) {}
1381076082aSAlexandre Rames StructWithoutCopyOrMove(const StructWithoutCopyOrMove &) = delete;
1391076082aSAlexandre Rames StructWithoutCopyOrMove &operator=(const StructWithoutCopyOrMove &) = delete;
1401076082aSAlexandre Rames
141d7b18d50SKazu Hirata template <typename HasherT, llvm::endianness Endianness>
addHash(llvm::HashBuilder<HasherT,Endianness> & HBuilder,const StructWithoutCopyOrMove & Value)142f37028c2SKazu Hirata friend void addHash(llvm::HashBuilder<HasherT, Endianness> &HBuilder,
1431076082aSAlexandre Rames const StructWithoutCopyOrMove &Value) {
1441076082aSAlexandre Rames HBuilder.add(Value.I);
1451076082aSAlexandre Rames }
1461076082aSAlexandre Rames };
1471076082aSAlexandre Rames
1481076082aSAlexandre Rames // The struct and associated tests are simplified to avoid failures caused by
1491076082aSAlexandre Rames // different alignments on different platforms.
1501076082aSAlexandre Rames struct /* __attribute__((packed)) */ StructWithFastHash {
1511076082aSAlexandre Rames int I;
1521076082aSAlexandre Rames // char C;
1531076082aSAlexandre Rames
1541076082aSAlexandre Rames // If possible, we want to hash both `I` and `C` in a single `update`
1551076082aSAlexandre Rames // call for performance concerns.
156d7b18d50SKazu Hirata template <typename HasherT, llvm::endianness Endianness>
addHash(llvm::HashBuilder<HasherT,Endianness> & HBuilder,const StructWithFastHash & Value)157f37028c2SKazu Hirata friend void addHash(llvm::HashBuilder<HasherT, Endianness> &HBuilder,
1581076082aSAlexandre Rames const StructWithFastHash &Value) {
1596b31b026SKazu Hirata if (Endianness == llvm::endianness::native) {
16038818b60Sserge-sans-paille HBuilder.update(llvm::ArrayRef(reinterpret_cast<const uint8_t *>(&Value),
16138818b60Sserge-sans-paille sizeof(Value)));
1621076082aSAlexandre Rames } else {
1631076082aSAlexandre Rames // Rely on existing `add` methods to handle endianness.
1641076082aSAlexandre Rames HBuilder.add(Value.I);
1651076082aSAlexandre Rames // HBuilder.add(Value.C);
1661076082aSAlexandre Rames }
1671076082aSAlexandre Rames }
1681076082aSAlexandre Rames };
1691076082aSAlexandre Rames
1701076082aSAlexandre Rames struct CustomContainer {
1711076082aSAlexandre Rames private:
1721076082aSAlexandre Rames size_t Size;
1731076082aSAlexandre Rames int Elements[100];
1741076082aSAlexandre Rames
1751076082aSAlexandre Rames public:
CustomContainerCustomContainer1761076082aSAlexandre Rames CustomContainer(size_t Size) : Size(Size) {
1771076082aSAlexandre Rames for (size_t I = 0; I != Size; ++I)
1781076082aSAlexandre Rames Elements[I] = I;
1791076082aSAlexandre Rames }
180d7b18d50SKazu Hirata template <typename HasherT, llvm::endianness Endianness>
addHash(llvm::HashBuilder<HasherT,Endianness> & HBuilder,const CustomContainer & Value)181f37028c2SKazu Hirata friend void addHash(llvm::HashBuilder<HasherT, Endianness> &HBuilder,
1821076082aSAlexandre Rames const CustomContainer &Value) {
1836b31b026SKazu Hirata if (Endianness == llvm::endianness::native) {
18438818b60Sserge-sans-paille HBuilder.update(llvm::ArrayRef(
1851076082aSAlexandre Rames reinterpret_cast<const uint8_t *>(&Value.Size),
1861076082aSAlexandre Rames sizeof(Value.Size) + Value.Size * sizeof(Value.Elements[0])));
1871076082aSAlexandre Rames } else {
1881076082aSAlexandre Rames HBuilder.addRange(&Value.Elements[0], &Value.Elements[0] + Value.Size);
1891076082aSAlexandre Rames }
1901076082aSAlexandre Rames }
1911076082aSAlexandre Rames };
1921076082aSAlexandre Rames
TYPED_TEST(HashBuilderTest,HashUserDefinedStruct)1931076082aSAlexandre Rames TYPED_TEST(HashBuilderTest, HashUserDefinedStruct) {
1941076082aSAlexandre Rames using HE = TypeParam;
1951076082aSAlexandre Rames EXPECT_EQ(hashWithBuilder<HE>(SimpleStruct{'c', 123}),
1961076082aSAlexandre Rames hashWithBuilder<HE>('c', 123));
1971076082aSAlexandre Rames EXPECT_EQ(hashWithBuilder<HE>(StructWithoutCopyOrMove{1}),
1981076082aSAlexandre Rames hashWithBuilder<HE>(1));
1991076082aSAlexandre Rames EXPECT_EQ(hashWithBuilder<HE>(StructWithFastHash{123}),
2001076082aSAlexandre Rames hashWithBuilder<HE>(123));
2011076082aSAlexandre Rames EXPECT_EQ(hashWithBuilder<HE>(CustomContainer(3)),
2021076082aSAlexandre Rames hashWithBuilder<HE>(static_cast<size_t>(3), 0, 1, 2));
2031076082aSAlexandre Rames }
2041076082aSAlexandre Rames
TYPED_TEST(HashBuilderTest,HashArrayRefHashableDataTypes)2051076082aSAlexandre Rames TYPED_TEST(HashBuilderTest, HashArrayRefHashableDataTypes) {
2061076082aSAlexandre Rames using HE = TypeParam;
2071076082aSAlexandre Rames int Values[] = {1, 20, 0x12345678};
2081076082aSAlexandre Rames llvm::ArrayRef<int> Array(Values);
2091076082aSAlexandre Rames EXPECT_NE(hashWithBuilder<HE>(Array), hashWithBuilder<HE>(1, 20, 0x12345678));
2101076082aSAlexandre Rames EXPECT_EQ(hashWithBuilder<HE>(Array),
2111076082aSAlexandre Rames hashRangeWithBuilder<HE>(Array.begin(), Array.end()));
2121076082aSAlexandre Rames EXPECT_EQ(
2131076082aSAlexandre Rames hashWithBuilder<HE>(Array),
2141076082aSAlexandre Rames hashRangeWithBuilder<HE>(Array.data(), Array.data() + Array.size()));
2151076082aSAlexandre Rames }
2161076082aSAlexandre Rames
TYPED_TEST(HashBuilderTest,HashArrayRef)2171076082aSAlexandre Rames TYPED_TEST(HashBuilderTest, HashArrayRef) {
2181076082aSAlexandre Rames using HE = TypeParam;
2191076082aSAlexandre Rames int Values[] = {1, 2, 3};
2201076082aSAlexandre Rames llvm::ArrayRef<int> Array123(&Values[0], 3);
2211076082aSAlexandre Rames llvm::ArrayRef<int> Array12(&Values[0], 2);
2221076082aSAlexandre Rames llvm::ArrayRef<int> Array1(&Values[0], 1);
2231076082aSAlexandre Rames llvm::ArrayRef<int> Array23(&Values[1], 2);
2241076082aSAlexandre Rames llvm::ArrayRef<int> Array3(&Values[2], 1);
2251076082aSAlexandre Rames llvm::ArrayRef<int> ArrayEmpty(&Values[0], static_cast<size_t>(0));
2261076082aSAlexandre Rames
2271076082aSAlexandre Rames auto Hash123andEmpty = hashWithBuilder<HE>(Array123, ArrayEmpty);
2281076082aSAlexandre Rames auto Hash12And3 = hashWithBuilder<HE>(Array12, Array3);
2291076082aSAlexandre Rames auto Hash1And23 = hashWithBuilder<HE>(Array1, Array23);
2301076082aSAlexandre Rames auto HashEmptyAnd123 = hashWithBuilder<HE>(ArrayEmpty, Array123);
2311076082aSAlexandre Rames
2321076082aSAlexandre Rames EXPECT_NE(Hash123andEmpty, Hash12And3);
2331076082aSAlexandre Rames EXPECT_NE(Hash123andEmpty, Hash1And23);
2341076082aSAlexandre Rames EXPECT_NE(Hash123andEmpty, HashEmptyAnd123);
2351076082aSAlexandre Rames EXPECT_NE(Hash12And3, Hash1And23);
2361076082aSAlexandre Rames EXPECT_NE(Hash12And3, HashEmptyAnd123);
2371076082aSAlexandre Rames EXPECT_NE(Hash1And23, HashEmptyAnd123);
2381076082aSAlexandre Rames }
2391076082aSAlexandre Rames
TYPED_TEST(HashBuilderTest,HashArrayRefNonHashableDataTypes)2401076082aSAlexandre Rames TYPED_TEST(HashBuilderTest, HashArrayRefNonHashableDataTypes) {
2411076082aSAlexandre Rames using HE = TypeParam;
2421076082aSAlexandre Rames SimpleStruct Values[] = {{'a', 100}, {'b', 200}};
2431076082aSAlexandre Rames llvm::ArrayRef<SimpleStruct> Array(Values);
2441076082aSAlexandre Rames EXPECT_NE(
2451076082aSAlexandre Rames hashWithBuilder<HE>(Array),
2461076082aSAlexandre Rames hashWithBuilder<HE>(SimpleStruct{'a', 100}, SimpleStruct{'b', 200}));
2471076082aSAlexandre Rames }
2481076082aSAlexandre Rames
TYPED_TEST(HashBuilderTest,HashStringRef)2491076082aSAlexandre Rames TYPED_TEST(HashBuilderTest, HashStringRef) {
2501076082aSAlexandre Rames using HE = TypeParam;
2511076082aSAlexandre Rames llvm::StringRef SEmpty("");
2521076082aSAlexandre Rames llvm::StringRef S1("1");
2531076082aSAlexandre Rames llvm::StringRef S12("12");
2541076082aSAlexandre Rames llvm::StringRef S123("123");
2551076082aSAlexandre Rames llvm::StringRef S23("23");
2561076082aSAlexandre Rames llvm::StringRef S3("3");
2571076082aSAlexandre Rames
2581076082aSAlexandre Rames auto Hash123andEmpty = hashWithBuilder<HE>(S123, SEmpty);
2591076082aSAlexandre Rames auto Hash12And3 = hashWithBuilder<HE>(S12, S3);
2601076082aSAlexandre Rames auto Hash1And23 = hashWithBuilder<HE>(S1, S23);
2611076082aSAlexandre Rames auto HashEmptyAnd123 = hashWithBuilder<HE>(SEmpty, S123);
2621076082aSAlexandre Rames
2631076082aSAlexandre Rames EXPECT_NE(Hash123andEmpty, Hash12And3);
2641076082aSAlexandre Rames EXPECT_NE(Hash123andEmpty, Hash1And23);
2651076082aSAlexandre Rames EXPECT_NE(Hash123andEmpty, HashEmptyAnd123);
2661076082aSAlexandre Rames EXPECT_NE(Hash12And3, Hash1And23);
2671076082aSAlexandre Rames EXPECT_NE(Hash12And3, HashEmptyAnd123);
2681076082aSAlexandre Rames EXPECT_NE(Hash1And23, HashEmptyAnd123);
2691076082aSAlexandre Rames }
2701076082aSAlexandre Rames
TYPED_TEST(HashBuilderTest,HashStdString)2711076082aSAlexandre Rames TYPED_TEST(HashBuilderTest, HashStdString) {
2721076082aSAlexandre Rames using HE = TypeParam;
2731076082aSAlexandre Rames EXPECT_EQ(hashWithBuilder<HE>(std::string("123")),
2741076082aSAlexandre Rames hashWithBuilder<HE>(llvm::StringRef("123")));
2751076082aSAlexandre Rames }
2761076082aSAlexandre Rames
TYPED_TEST(HashBuilderTest,HashStdPair)2771076082aSAlexandre Rames TYPED_TEST(HashBuilderTest, HashStdPair) {
2781076082aSAlexandre Rames using HE = TypeParam;
2791076082aSAlexandre Rames EXPECT_EQ(hashWithBuilder<HE>(std::make_pair(1, "string")),
2801076082aSAlexandre Rames hashWithBuilder<HE>(1, "string"));
2811076082aSAlexandre Rames
2821076082aSAlexandre Rames std::pair<StructWithoutCopyOrMove, std::string> Pair;
2831076082aSAlexandre Rames Pair.first.I = 1;
2841076082aSAlexandre Rames Pair.second = "string";
2851076082aSAlexandre Rames EXPECT_EQ(hashWithBuilder<HE>(Pair), hashWithBuilder<HE>(1, "string"));
2861076082aSAlexandre Rames }
2871076082aSAlexandre Rames
TYPED_TEST(HashBuilderTest,HashStdTuple)2881076082aSAlexandre Rames TYPED_TEST(HashBuilderTest, HashStdTuple) {
2891076082aSAlexandre Rames using HE = TypeParam;
2901076082aSAlexandre Rames
2911076082aSAlexandre Rames EXPECT_EQ(hashWithBuilder<HE>(std::make_tuple(1)), hashWithBuilder<HE>(1));
2921076082aSAlexandre Rames EXPECT_EQ(hashWithBuilder<HE>(std::make_tuple(2ULL)),
2931076082aSAlexandre Rames hashWithBuilder<HE>(2ULL));
2941076082aSAlexandre Rames EXPECT_EQ(hashWithBuilder<HE>(std::make_tuple("three")),
2951076082aSAlexandre Rames hashWithBuilder<HE>("three"));
2961076082aSAlexandre Rames EXPECT_EQ(hashWithBuilder<HE>(std::make_tuple(1, 2ULL)),
2971076082aSAlexandre Rames hashWithBuilder<HE>(1, 2ULL));
2981076082aSAlexandre Rames EXPECT_EQ(hashWithBuilder<HE>(std::make_tuple(1, 2ULL, "three")),
2991076082aSAlexandre Rames hashWithBuilder<HE>(1, 2ULL, "three"));
3001076082aSAlexandre Rames
3011076082aSAlexandre Rames std::tuple<StructWithoutCopyOrMove, std::string> Tuple;
3021076082aSAlexandre Rames std::get<0>(Tuple).I = 1;
3031076082aSAlexandre Rames std::get<1>(Tuple) = "two";
3041076082aSAlexandre Rames
3051076082aSAlexandre Rames EXPECT_EQ(hashWithBuilder<HE>(Tuple), hashWithBuilder<HE>(1, "two"));
3061076082aSAlexandre Rames }
3071076082aSAlexandre Rames
TYPED_TEST(HashBuilderTest,HashRangeWithForwardIterator)3081076082aSAlexandre Rames TYPED_TEST(HashBuilderTest, HashRangeWithForwardIterator) {
3091076082aSAlexandre Rames using HE = TypeParam;
3101076082aSAlexandre Rames std::list<int> List;
3111076082aSAlexandre Rames List.push_back(1);
3121076082aSAlexandre Rames List.push_back(2);
3131076082aSAlexandre Rames List.push_back(3);
3141076082aSAlexandre Rames EXPECT_NE(hashRangeWithBuilder<HE>(List), hashWithBuilder<HE>(1, 2, 3));
3151076082aSAlexandre Rames }
3161076082aSAlexandre Rames
TEST(CustomHasher,CustomHasher)3171076082aSAlexandre Rames TEST(CustomHasher, CustomHasher) {
3181076082aSAlexandre Rames struct SumHash {
3191076082aSAlexandre Rames explicit SumHash(uint8_t Seed1, uint8_t Seed2) : Hash(Seed1 + Seed2) {}
3201076082aSAlexandre Rames void update(llvm::ArrayRef<uint8_t> Data) {
3211076082aSAlexandre Rames for (uint8_t C : Data)
3221076082aSAlexandre Rames Hash += C;
3231076082aSAlexandre Rames }
3241076082aSAlexandre Rames uint8_t Hash;
3251076082aSAlexandre Rames };
3261076082aSAlexandre Rames
3271076082aSAlexandre Rames {
328d7b18d50SKazu Hirata llvm::HashBuilder<SumHash, llvm::endianness::little> HBuilder(0, 1);
3291076082aSAlexandre Rames EXPECT_EQ(HBuilder.add(0x02, 0x03, 0x400).getHasher().Hash, 0xa);
3301076082aSAlexandre Rames }
3311076082aSAlexandre Rames {
332d7b18d50SKazu Hirata llvm::HashBuilder<SumHash, llvm::endianness::little> HBuilder(2, 3);
3331076082aSAlexandre Rames EXPECT_EQ(HBuilder.add("ab", 'c').getHasher().Hash,
3341076082aSAlexandre Rames static_cast<uint8_t>(/*seeds*/ 2 + 3 + /*range size*/ 2 +
3351076082aSAlexandre Rames /*characters*/ 'a' + 'b' + 'c'));
3361076082aSAlexandre Rames }
3371076082aSAlexandre Rames }
338