mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-21 01:01:43 +00:00
[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:
@@ -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;
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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) {
|
||||
|
||||
@@ -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]));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user