[upstream_utils] Upgrade to LLVM 20.1.7 (#8033)

Also removes xxhash, Hashing, and MapVector to reduce the size of the patches and to speed up compile times by a smidge.
This commit is contained in:
Gold856
2025-06-25 01:36:22 -04:00
committed by GitHub
parent a77441b78a
commit 22b58c1853
73 changed files with 1154 additions and 3813 deletions

View File

@@ -10,6 +10,8 @@
using namespace wpi;
int CountCopyAndMove::DefaultConstructions = 0;
int CountCopyAndMove::ValueConstructions = 0;
int CountCopyAndMove::CopyConstructions = 0;
int CountCopyAndMove::CopyAssignments = 0;
int CountCopyAndMove::MoveConstructions = 0;

View File

@@ -12,6 +12,8 @@
namespace wpi {
struct CountCopyAndMove {
static int DefaultConstructions;
static int ValueConstructions;
static int CopyConstructions;
static int CopyAssignments;
static int MoveConstructions;
@@ -19,8 +21,8 @@ struct CountCopyAndMove {
static int Destructions;
int val;
CountCopyAndMove() = default;
explicit CountCopyAndMove(int val) : val(val) {}
CountCopyAndMove() { ++DefaultConstructions; }
explicit CountCopyAndMove(int val) : val(val) { ++ValueConstructions; }
CountCopyAndMove(const CountCopyAndMove &other) : val(other.val) {
++CopyConstructions;
}
@@ -40,6 +42,8 @@ struct CountCopyAndMove {
~CountCopyAndMove() { ++Destructions; }
static void ResetCounts() {
DefaultConstructions = 0;
ValueConstructions = 0;
CopyConstructions = 0;
CopyAssignments = 0;
MoveConstructions = 0;
@@ -47,6 +51,11 @@ struct CountCopyAndMove {
Destructions = 0;
}
static int TotalConstructions() {
return DefaultConstructions + ValueConstructions + MoveConstructions +
CopyConstructions;
}
static int TotalCopies() { return CopyConstructions + CopyAssignments; }
static int TotalMoves() { return MoveConstructions + MoveAssignments; }

View File

@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "wpi/FunctionExtras.h"
#include "CountCopyAndMove.h"
#include "gtest/gtest.h"
#include <memory>
@@ -310,4 +311,43 @@ class Incomplete {};
Incomplete incompleteFunction() { return {}; }
const Incomplete incompleteFunctionConst() { return {}; }
// Check that we can store a pointer-sized payload inline in the unique_function.
TEST(UniqueFunctionTest, InlineStorageWorks) {
// We do assume a couple of implementation details of the unique_function here:
// - It can store certain small-enough payload inline
// - Inline storage size is at least >= sizeof(void*)
void *ptr = nullptr;
unique_function<void(void *)> UniqueFunctionWithInlineStorage{
[ptr](void *self) {
auto mid = reinterpret_cast<uintptr_t>(&ptr);
auto beg = reinterpret_cast<uintptr_t>(self);
auto end = reinterpret_cast<uintptr_t>(self) +
sizeof(unique_function<void(void *)>);
// Make sure the address of the captured pointer lies somewhere within
// the unique_function object.
EXPECT_TRUE(mid >= beg && mid < end);
}};
UniqueFunctionWithInlineStorage(&UniqueFunctionWithInlineStorage);
}
// GCC warns that val in CountCopyAndMove is uninitialized
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuninitialized"
#endif
// Check that the moved-from captured state is properly destroyed during
// move construction/assignment.
TEST(UniqueFunctionTest, MovedFromStateIsDestroyedCorrectly) {
CountCopyAndMove::ResetCounts();
{
unique_function<void()> CapturingFunction{
[Counter = CountCopyAndMove{}] {}};
unique_function<void()> CapturingFunctionMoved{
std::move(CapturingFunction)};
}
EXPECT_EQ(CountCopyAndMove::TotalConstructions(),
CountCopyAndMove::Destructions);
}
} // anonymous namespace

View File

@@ -1,542 +0,0 @@
//===- unittest/ADT/MapVectorTest.cpp - MapVector unit tests ----*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#if defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wpedantic"
#if !defined(__clang__)
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
#endif
#include "wpi/MapVector.h"
#include "wpi/iterator_range.h"
#include "gtest/gtest.h"
#include <memory>
#include <utility>
using namespace wpi;
namespace {
struct CountCopyAndMove {
CountCopyAndMove() = default;
CountCopyAndMove(const CountCopyAndMove &) { copy = 1; }
CountCopyAndMove(CountCopyAndMove &&) { move = 1; }
void operator=(const CountCopyAndMove &) { ++copy; }
void operator=(CountCopyAndMove &&) { ++move; }
int copy = 0;
int move = 0;
};
struct A : CountCopyAndMove {
A(int v) : v(v) {}
int v;
};
} // namespace
namespace wpi {
template <> struct DenseMapInfo<A> {
static inline A getEmptyKey() { return 0x7fffffff; }
static inline A getTombstoneKey() { return -0x7fffffff - 1; }
static unsigned getHashValue(const A &Val) { return (unsigned)(Val.v * 37U); }
static bool isEqual(const A &LHS, const A &RHS) { return LHS.v == RHS.v; }
};
} // namespace wpi
namespace {
TEST(MapVectorTest, swap) {
MapVector<int, int> MV1, MV2;
std::pair<MapVector<int, int>::iterator, bool> R;
R = MV1.insert(std::make_pair(1, 2));
ASSERT_EQ(R.first, MV1.begin());
EXPECT_EQ(R.first->first, 1);
EXPECT_EQ(R.first->second, 2);
EXPECT_TRUE(R.second);
EXPECT_FALSE(MV1.empty());
EXPECT_TRUE(MV2.empty());
MV2.swap(MV1);
EXPECT_TRUE(MV1.empty());
EXPECT_FALSE(MV2.empty());
auto I = MV1.find(1);
ASSERT_EQ(MV1.end(), I);
I = MV2.find(1);
ASSERT_EQ(I, MV2.begin());
EXPECT_EQ(I->first, 1);
EXPECT_EQ(I->second, 2);
}
TEST(MapVectorTest, insert_pop) {
MapVector<int, int> MV;
std::pair<MapVector<int, int>::iterator, bool> R;
R = MV.insert(std::make_pair(1, 2));
ASSERT_EQ(R.first, MV.begin());
EXPECT_EQ(R.first->first, 1);
EXPECT_EQ(R.first->second, 2);
EXPECT_TRUE(R.second);
R = MV.insert(std::make_pair(1, 3));
ASSERT_EQ(R.first, MV.begin());
EXPECT_EQ(R.first->first, 1);
EXPECT_EQ(R.first->second, 2);
EXPECT_FALSE(R.second);
R = MV.insert(std::make_pair(4, 5));
ASSERT_NE(R.first, MV.end());
EXPECT_EQ(R.first->first, 4);
EXPECT_EQ(R.first->second, 5);
EXPECT_TRUE(R.second);
EXPECT_EQ(MV.size(), 2u);
EXPECT_EQ(MV[1], 2);
EXPECT_EQ(MV[4], 5);
MV.pop_back();
EXPECT_EQ(MV.size(), 1u);
EXPECT_EQ(MV[1], 2);
R = MV.insert(std::make_pair(4, 7));
ASSERT_NE(R.first, MV.end());
EXPECT_EQ(R.first->first, 4);
EXPECT_EQ(R.first->second, 7);
EXPECT_TRUE(R.second);
EXPECT_EQ(MV.size(), 2u);
EXPECT_EQ(MV[1], 2);
EXPECT_EQ(MV[4], 7);
}
TEST(MapVectorTest, try_emplace) {
struct AAndU {
A a;
std::unique_ptr<int> b;
AAndU(A a, std::unique_ptr<int> b) : a(a), b(std::move(b)) {}
};
MapVector<A, AAndU> mv;
A zero(0);
auto try0 = mv.try_emplace(zero, zero, nullptr);
EXPECT_TRUE(try0.second);
EXPECT_EQ(0, try0.first->second.a.v);
EXPECT_EQ(1, try0.first->second.a.copy);
EXPECT_EQ(0, try0.first->second.a.move);
auto try1 = mv.try_emplace(zero, zero, nullptr);
EXPECT_FALSE(try1.second);
EXPECT_EQ(0, try1.first->second.a.v);
EXPECT_EQ(1, try1.first->second.a.copy);
EXPECT_EQ(0, try1.first->second.a.move);
EXPECT_EQ(try0.first, try1.first);
EXPECT_EQ(1, try1.first->first.copy);
EXPECT_EQ(0, try1.first->first.move);
A two(2);
auto try2 = mv.try_emplace(2, std::move(two), std::make_unique<int>(2));
EXPECT_TRUE(try2.second);
EXPECT_EQ(2, try2.first->second.a.v);
EXPECT_EQ(0, try2.first->second.a.move);
std::unique_ptr<int> p(new int(3));
auto try3 = mv.try_emplace(std::move(two), 3, std::move(p));
EXPECT_FALSE(try3.second);
EXPECT_EQ(2, try3.first->second.a.v);
EXPECT_EQ(1, try3.first->second.a.copy);
EXPECT_EQ(0, try3.first->second.a.move);
EXPECT_EQ(try2.first, try3.first);
EXPECT_EQ(0, try3.first->first.copy);
EXPECT_EQ(1, try3.first->first.move);
EXPECT_NE(nullptr, p);
}
TEST(MapVectorTest, insert_or_assign) {
MapVector<A, A> mv;
A zero(0);
auto try0 = mv.insert_or_assign(zero, zero);
EXPECT_TRUE(try0.second);
EXPECT_EQ(0, try0.first->second.v);
EXPECT_EQ(1, try0.first->second.copy);
EXPECT_EQ(0, try0.first->second.move);
auto try1 = mv.insert_or_assign(zero, zero);
EXPECT_FALSE(try1.second);
EXPECT_EQ(0, try1.first->second.v);
EXPECT_EQ(2, try1.first->second.copy);
EXPECT_EQ(0, try1.first->second.move);
EXPECT_EQ(try0.first, try1.first);
EXPECT_EQ(1, try1.first->first.copy);
EXPECT_EQ(0, try1.first->first.move);
A two(2);
auto try2 = mv.try_emplace(2, std::move(two));
EXPECT_TRUE(try2.second);
EXPECT_EQ(2, try2.first->second.v);
EXPECT_EQ(1, try2.first->second.move);
auto try3 = mv.insert_or_assign(std::move(two), 3);
EXPECT_FALSE(try3.second);
EXPECT_EQ(3, try3.first->second.v);
EXPECT_EQ(0, try3.first->second.copy);
EXPECT_EQ(2, try3.first->second.move);
EXPECT_EQ(try2.first, try3.first);
EXPECT_EQ(0, try3.first->first.copy);
EXPECT_EQ(1, try3.first->first.move);
}
TEST(MapVectorTest, erase) {
MapVector<int, int> MV;
MV.insert(std::make_pair(1, 2));
MV.insert(std::make_pair(3, 4));
MV.insert(std::make_pair(5, 6));
ASSERT_EQ(MV.size(), 3u);
ASSERT_TRUE(MV.contains(1));
MV.erase(MV.find(1));
ASSERT_EQ(MV.size(), 2u);
ASSERT_FALSE(MV.contains(1));
ASSERT_EQ(MV.find(1), MV.end());
ASSERT_EQ(MV[3], 4);
ASSERT_EQ(MV[5], 6);
ASSERT_EQ(MV.erase(3), 1u);
ASSERT_EQ(MV.size(), 1u);
ASSERT_EQ(MV.find(3), MV.end());
ASSERT_EQ(MV[5], 6);
ASSERT_EQ(MV.erase(79), 0u);
ASSERT_EQ(MV.size(), 1u);
}
TEST(MapVectorTest, remove_if) {
MapVector<int, int> MV;
MV.insert(std::make_pair(1, 11));
MV.insert(std::make_pair(2, 12));
MV.insert(std::make_pair(3, 13));
MV.insert(std::make_pair(4, 14));
MV.insert(std::make_pair(5, 15));
MV.insert(std::make_pair(6, 16));
ASSERT_EQ(MV.size(), 6u);
MV.remove_if([](const std::pair<int, int> &Val) { return Val.second % 2; });
ASSERT_EQ(MV.size(), 3u);
ASSERT_EQ(MV.find(1), MV.end());
ASSERT_EQ(MV.find(3), MV.end());
ASSERT_EQ(MV.find(5), MV.end());
ASSERT_EQ(MV[2], 12);
ASSERT_EQ(MV[4], 14);
ASSERT_EQ(MV[6], 16);
}
TEST(MapVectorTest, iteration_test) {
MapVector<int, int> MV;
MV.insert(std::make_pair(1, 11));
MV.insert(std::make_pair(2, 12));
MV.insert(std::make_pair(3, 13));
MV.insert(std::make_pair(4, 14));
MV.insert(std::make_pair(5, 15));
MV.insert(std::make_pair(6, 16));
ASSERT_EQ(MV.size(), 6u);
int count = 1;
for (auto P : make_range(MV.begin(), MV.end())) {
ASSERT_EQ(P.first, count);
count++;
}
count = 6;
for (auto P : make_range(MV.rbegin(), MV.rend())) {
ASSERT_EQ(P.first, count);
count--;
}
}
TEST(MapVectorTest, NonCopyable) {
MapVector<int, std::unique_ptr<int>> MV;
MV.insert(std::make_pair(1, std::make_unique<int>(1)));
MV.insert(std::make_pair(2, std::make_unique<int>(2)));
ASSERT_EQ(MV.count(1), 1u);
ASSERT_EQ(*MV.find(2)->second, 2);
}
template <class IntType> struct MapVectorMappedTypeTest : ::testing::Test {
using int_type = IntType;
};
using MapIntTypes = ::testing::Types<int, long, long long, unsigned,
unsigned long, unsigned long long>;
TYPED_TEST_SUITE(MapVectorMappedTypeTest, MapIntTypes, );
TYPED_TEST(MapVectorMappedTypeTest, DifferentDenseMap) {
// Test that using a map with a mapped type other than 'unsigned' compiles
// and works.
using IntType = typename TestFixture::int_type;
using MapVectorType = MapVector<int, int, DenseMap<int, IntType>>;
MapVectorType MV;
std::pair<typename MapVectorType::iterator, bool> R;
R = MV.insert(std::make_pair(1, 2));
ASSERT_EQ(R.first, MV.begin());
EXPECT_EQ(R.first->first, 1);
EXPECT_EQ(R.first->second, 2);
EXPECT_TRUE(R.second);
const std::pair<int, int> Elem(1, 3);
R = MV.insert(Elem);
ASSERT_EQ(R.first, MV.begin());
EXPECT_EQ(R.first->first, 1);
EXPECT_EQ(R.first->second, 2);
EXPECT_FALSE(R.second);
int& value = MV[4];
EXPECT_EQ(value, 0);
value = 5;
EXPECT_EQ(MV.size(), 2u);
EXPECT_EQ(MV[1], 2);
EXPECT_EQ(MV[4], 5);
}
TEST(SmallMapVectorSmallTest, insert_pop) {
SmallMapVector<int, int, 32> MV;
std::pair<SmallMapVector<int, int, 32>::iterator, bool> R;
R = MV.insert(std::make_pair(1, 2));
ASSERT_EQ(R.first, MV.begin());
EXPECT_EQ(R.first->first, 1);
EXPECT_EQ(R.first->second, 2);
EXPECT_TRUE(R.second);
R = MV.insert(std::make_pair(1, 3));
ASSERT_EQ(R.first, MV.begin());
EXPECT_EQ(R.first->first, 1);
EXPECT_EQ(R.first->second, 2);
EXPECT_FALSE(R.second);
R = MV.insert(std::make_pair(4, 5));
ASSERT_NE(R.first, MV.end());
EXPECT_EQ(R.first->first, 4);
EXPECT_EQ(R.first->second, 5);
EXPECT_TRUE(R.second);
EXPECT_EQ(MV.size(), 2u);
EXPECT_EQ(MV[1], 2);
EXPECT_EQ(MV[4], 5);
MV.pop_back();
EXPECT_EQ(MV.size(), 1u);
EXPECT_EQ(MV[1], 2);
R = MV.insert(std::make_pair(4, 7));
ASSERT_NE(R.first, MV.end());
EXPECT_EQ(R.first->first, 4);
EXPECT_EQ(R.first->second, 7);
EXPECT_TRUE(R.second);
EXPECT_EQ(MV.size(), 2u);
EXPECT_EQ(MV[1], 2);
EXPECT_EQ(MV[4], 7);
}
TEST(SmallMapVectorSmallTest, erase) {
SmallMapVector<int, int, 32> MV;
MV.insert(std::make_pair(1, 2));
MV.insert(std::make_pair(3, 4));
MV.insert(std::make_pair(5, 6));
ASSERT_EQ(MV.size(), 3u);
MV.erase(MV.find(1));
ASSERT_EQ(MV.size(), 2u);
ASSERT_EQ(MV.find(1), MV.end());
ASSERT_EQ(MV[3], 4);
ASSERT_EQ(MV[5], 6);
ASSERT_EQ(MV.erase(3), 1u);
ASSERT_EQ(MV.size(), 1u);
ASSERT_EQ(MV.find(3), MV.end());
ASSERT_EQ(MV[5], 6);
ASSERT_EQ(MV.erase(79), 0u);
ASSERT_EQ(MV.size(), 1u);
}
TEST(SmallMapVectorSmallTest, remove_if) {
SmallMapVector<int, int, 32> MV;
MV.insert(std::make_pair(1, 11));
MV.insert(std::make_pair(2, 12));
MV.insert(std::make_pair(3, 13));
MV.insert(std::make_pair(4, 14));
MV.insert(std::make_pair(5, 15));
MV.insert(std::make_pair(6, 16));
ASSERT_EQ(MV.size(), 6u);
MV.remove_if([](const std::pair<int, int> &Val) { return Val.second % 2; });
ASSERT_EQ(MV.size(), 3u);
ASSERT_EQ(MV.find(1), MV.end());
ASSERT_EQ(MV.find(3), MV.end());
ASSERT_EQ(MV.find(5), MV.end());
ASSERT_EQ(MV[2], 12);
ASSERT_EQ(MV[4], 14);
ASSERT_EQ(MV[6], 16);
}
TEST(SmallMapVectorSmallTest, iteration_test) {
SmallMapVector<int, int, 32> MV;
MV.insert(std::make_pair(1, 11));
MV.insert(std::make_pair(2, 12));
MV.insert(std::make_pair(3, 13));
MV.insert(std::make_pair(4, 14));
MV.insert(std::make_pair(5, 15));
MV.insert(std::make_pair(6, 16));
ASSERT_EQ(MV.size(), 6u);
int count = 1;
for (auto P : make_range(MV.begin(), MV.end())) {
ASSERT_EQ(P.first, count);
count++;
}
count = 6;
for (auto P : make_range(MV.rbegin(), MV.rend())) {
ASSERT_EQ(P.first, count);
count--;
}
}
TEST(SmallMapVectorSmallTest, NonCopyable) {
SmallMapVector<int, std::unique_ptr<int>, 8> MV;
MV.insert(std::make_pair(1, std::make_unique<int>(1)));
MV.insert(std::make_pair(2, std::make_unique<int>(2)));
ASSERT_EQ(MV.count(1), 1u);
ASSERT_EQ(*MV.find(2)->second, 2);
}
TEST(SmallMapVectorLargeTest, insert_pop) {
SmallMapVector<int, int, 1> MV;
std::pair<SmallMapVector<int, int, 1>::iterator, bool> R;
R = MV.insert(std::make_pair(1, 2));
ASSERT_EQ(R.first, MV.begin());
EXPECT_EQ(R.first->first, 1);
EXPECT_EQ(R.first->second, 2);
EXPECT_TRUE(R.second);
R = MV.insert(std::make_pair(1, 3));
ASSERT_EQ(R.first, MV.begin());
EXPECT_EQ(R.first->first, 1);
EXPECT_EQ(R.first->second, 2);
EXPECT_FALSE(R.second);
R = MV.insert(std::make_pair(4, 5));
ASSERT_NE(R.first, MV.end());
EXPECT_EQ(R.first->first, 4);
EXPECT_EQ(R.first->second, 5);
EXPECT_TRUE(R.second);
EXPECT_EQ(MV.size(), 2u);
EXPECT_EQ(MV[1], 2);
EXPECT_EQ(MV[4], 5);
MV.pop_back();
EXPECT_EQ(MV.size(), 1u);
EXPECT_EQ(MV[1], 2);
R = MV.insert(std::make_pair(4, 7));
ASSERT_NE(R.first, MV.end());
EXPECT_EQ(R.first->first, 4);
EXPECT_EQ(R.first->second, 7);
EXPECT_TRUE(R.second);
EXPECT_EQ(MV.size(), 2u);
EXPECT_EQ(MV[1], 2);
EXPECT_EQ(MV[4], 7);
}
TEST(SmallMapVectorLargeTest, erase) {
SmallMapVector<int, int, 1> MV;
MV.insert(std::make_pair(1, 2));
MV.insert(std::make_pair(3, 4));
MV.insert(std::make_pair(5, 6));
ASSERT_EQ(MV.size(), 3u);
MV.erase(MV.find(1));
ASSERT_EQ(MV.size(), 2u);
ASSERT_EQ(MV.find(1), MV.end());
ASSERT_EQ(MV[3], 4);
ASSERT_EQ(MV[5], 6);
ASSERT_EQ(MV.erase(3), 1u);
ASSERT_EQ(MV.size(), 1u);
ASSERT_EQ(MV.find(3), MV.end());
ASSERT_EQ(MV[5], 6);
ASSERT_EQ(MV.erase(79), 0u);
ASSERT_EQ(MV.size(), 1u);
}
TEST(SmallMapVectorLargeTest, remove_if) {
SmallMapVector<int, int, 1> MV;
MV.insert(std::make_pair(1, 11));
MV.insert(std::make_pair(2, 12));
MV.insert(std::make_pair(3, 13));
MV.insert(std::make_pair(4, 14));
MV.insert(std::make_pair(5, 15));
MV.insert(std::make_pair(6, 16));
ASSERT_EQ(MV.size(), 6u);
MV.remove_if([](const std::pair<int, int> &Val) { return Val.second % 2; });
ASSERT_EQ(MV.size(), 3u);
ASSERT_EQ(MV.find(1), MV.end());
ASSERT_EQ(MV.find(3), MV.end());
ASSERT_EQ(MV.find(5), MV.end());
ASSERT_EQ(MV[2], 12);
ASSERT_EQ(MV[4], 14);
ASSERT_EQ(MV[6], 16);
}
TEST(SmallMapVectorLargeTest, iteration_test) {
SmallMapVector<int, int, 1> MV;
MV.insert(std::make_pair(1, 11));
MV.insert(std::make_pair(2, 12));
MV.insert(std::make_pair(3, 13));
MV.insert(std::make_pair(4, 14));
MV.insert(std::make_pair(5, 15));
MV.insert(std::make_pair(6, 16));
ASSERT_EQ(MV.size(), 6u);
int count = 1;
for (auto P : make_range(MV.begin(), MV.end())) {
ASSERT_EQ(P.first, count);
count++;
}
count = 6;
for (auto P : make_range(MV.rbegin(), MV.rend())) {
ASSERT_EQ(P.first, count);
count--;
}
}
} // namespace

View File

@@ -218,8 +218,11 @@ TEST(MathExtras, AlignToPowerOf2) {
EXPECT_EQ(24u, alignToPowerOf2(17, 8));
EXPECT_EQ(0u, alignToPowerOf2(~0LL, 8));
EXPECT_EQ(240u, alignToPowerOf2(240, 16));
EXPECT_EQ(static_cast<uint64_t>(std::numeric_limits<uint32_t>::max()) + 1,
alignToPowerOf2(std::numeric_limits<uint32_t>::max(), 2));
// Overflow.
EXPECT_EQ(0u, alignToPowerOf2(static_cast<uint8_t>(200),
static_cast<uint8_t>(128)));
EXPECT_EQ(0u, alignToPowerOf2(std::numeric_limits<uint32_t>::max(), 2));
}
TEST(MathExtras, AlignDown) {

View File

@@ -13,11 +13,13 @@
#include "wpi/SmallPtrSet.h"
#include "wpi/PointerIntPair.h"
#include "wpi/PointerLikeTypeTraits.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <algorithm>
using namespace wpi;
using testing::UnorderedElementsAre;
TEST(SmallPtrSetTest, Assignment) {
int buf[8];
@@ -409,3 +411,50 @@ TEST(SmallPtrSetTest, RemoveIf) {
Removed = Set.remove_if([](int *Ptr) { return false; });
EXPECT_FALSE(Removed);
}
TEST(SmallPtrSetTest, Reserve) {
// Check that we don't do anything silly when using reserve().
SmallPtrSet<int *, 4> Set;
int Vals[8] = {0, 1, 2, 3, 4, 5, 6, 7};
Set.insert(&Vals[0]);
// We shouldn't reallocate when this happens.
Set.reserve(4);
EXPECT_EQ(Set.capacity(), 4u);
Set.insert(&Vals[1]);
Set.insert(&Vals[2]);
Set.insert(&Vals[3]);
// We shouldn't reallocate this time either.
Set.reserve(4);
EXPECT_EQ(Set.capacity(), 4u);
EXPECT_EQ(Set.size(), 4u);
EXPECT_THAT(Set,
UnorderedElementsAre(&Vals[0], &Vals[1], &Vals[2], &Vals[3]));
// Reserving further should lead to a reallocation. And matching the existing
// insertion approach, we immediately allocate up to 128 elements.
Set.reserve(5);
EXPECT_EQ(Set.capacity(), 128u);
EXPECT_EQ(Set.size(), 4u);
EXPECT_THAT(Set,
UnorderedElementsAre(&Vals[0], &Vals[1], &Vals[2], &Vals[3]));
// And we should be able to insert another two or three elements without
// reallocating.
Set.insert(&Vals[4]);
Set.insert(&Vals[5]);
// Calling a smaller reserve size should have no effect.
Set.reserve(1);
EXPECT_EQ(Set.capacity(), 128u);
EXPECT_EQ(Set.size(), 6u);
// Reserving zero should have no effect either.
Set.reserve(0);
EXPECT_EQ(Set.capacity(), 128u);
EXPECT_EQ(Set.size(), 6u);
EXPECT_THAT(Set, UnorderedElementsAre(&Vals[0], &Vals[1], &Vals[2], &Vals[3], &Vals[4], &Vals[5]));
}

View File

@@ -11,12 +11,64 @@
//===----------------------------------------------------------------------===//
#include "wpi/SmallSet.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <algorithm>
#include <string>
using namespace wpi;
TEST(SmallSetTest, ConstructorIteratorPair) {
std::initializer_list<int> L = {1, 2, 3, 4, 5};
SmallSet<int, 4> S(std::begin(L), std::end(L));
EXPECT_THAT(S, testing::UnorderedElementsAreArray(L));
}
TEST(SmallSet, ConstructorRange) {
std::initializer_list<int> L = {1, 2, 3, 4, 5};
SmallSet<int, 4> S(wpi::make_range(std::begin(L), std::end(L)));
EXPECT_THAT(S, testing::UnorderedElementsAreArray(L));
}
TEST(SmallSet, ConstructorInitializerList) {
std::initializer_list<int> L = {1, 2, 3, 4, 5};
SmallSet<int, 4> S = {1, 2, 3, 4, 5};
EXPECT_THAT(S, testing::UnorderedElementsAreArray(L));
}
TEST(SmallSet, CopyConstructor) {
SmallSet<int, 4> S = {1, 2, 3};
SmallSet<int, 4> T = S;
EXPECT_THAT(S, testing::ContainerEq(T));
}
TEST(SmallSet, MoveConstructor) {
std::initializer_list<int> L = {1, 2, 3};
SmallSet<int, 4> S = L;
SmallSet<int, 4> T = std::move(S);
EXPECT_THAT(T, testing::UnorderedElementsAreArray(L));
}
TEST(SmallSet, CopyAssignment) {
SmallSet<int, 4> S = {1, 2, 3};
SmallSet<int, 4> T;
T = S;
EXPECT_THAT(S, testing::ContainerEq(T));
}
TEST(SmallSet, MoveAssignment) {
std::initializer_list<int> L = {1, 2, 3};
SmallSet<int, 4> S = L;
SmallSet<int, 4> T;
T = std::move(S);
EXPECT_THAT(T, testing::UnorderedElementsAreArray(L));
}
TEST(SmallSetTest, Insert) {
SmallSet<int, 4> s1;
@@ -41,6 +93,40 @@ TEST(SmallSetTest, Insert) {
EXPECT_EQ(0u, s1.count(4));
}
TEST(SmallSetTest, InsertPerfectFwd) {
struct Value {
int Key;
bool Moved;
Value(int Key) : Key(Key), Moved(false) {}
Value(const Value &) = default;
Value(Value &&Other) : Key(Other.Key), Moved(false) { Other.Moved = true; }
bool operator==(const Value &Other) const { return Key == Other.Key; }
bool operator<(const Value &Other) const { return Key < Other.Key; }
};
{
SmallSet<Value, 4> S;
Value V1(1), V2(2);
S.insert(V1);
EXPECT_EQ(V1.Moved, false);
S.insert(std::move(V2));
EXPECT_EQ(V2.Moved, true);
}
{
SmallSet<Value, 1> S;
Value V1(1), V2(2);
S.insert(V1);
EXPECT_EQ(V1.Moved, false);
S.insert(std::move(V2));
EXPECT_EQ(V2.Moved, true);
}
}
TEST(SmallSetTest, Grow) {
SmallSet<int, 4> s1;

View File

@@ -1,132 +0,0 @@
//===- llvm/unittest/Support/xxhashTest.cpp -------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "wpi/xxhash.h"
#include "gtest/gtest.h"
using namespace wpi;
/* use #define to make them constant, required for initialization */
#define PRIME32 2654435761U
#define PRIME64 11400714785074694797ULL
/*
* Fills a test buffer with pseudorandom data.
*
* This is used in the sanity check - its values must not be changed.
*/
static void fillTestBuffer(uint8_t *buffer, size_t len) {
uint64_t byteGen = PRIME32;
assert(buffer != NULL);
for (size_t i = 0; i < len; i++) {
buffer[i] = (uint8_t)(byteGen >> 56);
byteGen *= PRIME64;
}
}
TEST(xxhashTest, Basic) {
EXPECT_EQ(0xef46db3751d8e999U, xxHash64(std::string_view()));
EXPECT_EQ(0x33bf00a859c4ba3fU, xxHash64("foo"));
EXPECT_EQ(0x48a37c90ad27a659U, xxHash64("bar"));
EXPECT_EQ(0x69196c1b3af0bff9U,
xxHash64("0123456789abcdefghijklmnopqrstuvwxyz"));
}
TEST(xxhashTest, xxh3) {
constexpr size_t size = 2243;
uint8_t a[size];
uint64_t x = 1;
for (size_t i = 0; i < size; ++i) {
x ^= x << 13;
x ^= x >> 7;
x ^= x << 17;
a[i] = uint8_t(x);
}
#define F(len, expected) \
EXPECT_EQ(uint64_t(expected), xxh3_64bits(std::span(a, size_t(len))))
F(0, 0x2d06800538d394c2);
F(1, 0xd0d496e05c553485);
F(2, 0x84d625edb7055eac);
F(3, 0x6ea2d59aca5c3778);
F(4, 0xbf65290914e80242);
F(5, 0xc01fd099ad4fc8e4);
F(6, 0x9e3ea8187399caa5);
F(7, 0x9da8b60540644f5a);
F(8, 0xabc1413da6cd0209);
F(9, 0x8bc89400bfed51f6);
F(16, 0x7e46916754d7c9b8);
F(17, 0xed4be912ba5f836d);
F(32, 0xf59b59b58c304fd1);
F(33, 0x9013fb74ca603e0c);
F(64, 0xfa5271fcce0db1c3);
F(65, 0x79c42431727f1012);
F(96, 0x591ee0ddf9c9ccd1);
F(97, 0x8ffc6a3111fe19da);
F(128, 0x06a146ee9a2da378);
F(129, 0xbc7138129bf065da);
F(403, 0xcefeb3ffa532ad8c);
F(512, 0xcdfa6b6268e3650f);
F(513, 0x4bb5d42742f9765f);
F(2048, 0x330ce110cbb79eae);
F(2049, 0x3ba6afa0249fef9a);
F(2240, 0xd61d4d2a94e926a8);
F(2243, 0x0979f786a24edde7);
#undef F
}
TEST(xxhashTest, xxh3_128bits) {
#define SANITY_BUFFER_SIZE 2367
uint8_t sanityBuffer[SANITY_BUFFER_SIZE];
fillTestBuffer(sanityBuffer, sizeof(sanityBuffer));
#define F(len, expected) \
EXPECT_EQ(XXH128_hash_t(expected), \
xxh3_128bits(std::span(sanityBuffer, size_t(len))))
F(0, (XXH128_hash_t{0x6001C324468D497FULL,
0x99AA06D3014798D8ULL})); /* empty string */
F(1, (XXH128_hash_t{0xC44BDFF4074EECDBULL,
0xA6CD5E9392000F6AULL})); /* 1 - 3 */
F(6, (XXH128_hash_t{0x3E7039BDDA43CFC6ULL,
0x082AFE0B8162D12AULL})); /* 4 - 8 */
F(12, (XXH128_hash_t{0x061A192713F69AD9ULL,
0x6E3EFD8FC7802B18ULL})); /* 9 - 16 */
F(24, (XXH128_hash_t{0x1E7044D28B1B901DULL,
0x0CE966E4678D3761ULL})); /* 17 - 32 */
F(48, (XXH128_hash_t{0xF942219AED80F67BULL,
0xA002AC4E5478227EULL})); /* 33 - 64 */
F(81, (XXH128_hash_t{0x5E8BAFB9F95FB803ULL,
0x4952F58181AB0042ULL})); /* 65 - 96 */
F(222, (XXH128_hash_t{0xF1AEBD597CEC6B3AULL,
0x337E09641B948717ULL})); /* 129-240 */
F(403,
(XXH128_hash_t{
0xCDEB804D65C6DEA4ULL,
0x1B6DE21E332DD73DULL})); /* one block, last stripe is overlapping */
F(512,
(XXH128_hash_t{
0x617E49599013CB6BULL,
0x18D2D110DCC9BCA1ULL})); /* one block, finishing at stripe boundary */
F(2048,
(XXH128_hash_t{
0xDD59E2C3A5F038E0ULL,
0xF736557FD47073A5ULL})); /* 2 blocks, finishing at block boundary */
F(2240,
(XXH128_hash_t{
0x6E73A90539CF2948ULL,
0xCCB134FBFA7CE49DULL})); /* 3 blocks, finishing at stripe boundary */
F(2367,
(XXH128_hash_t{
0xCB37AEB9E5D361EDULL,
0xE89C0F6FF369B427ULL})); /* 3 blocks, last stripe is overlapping */
#undef F
}