mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-22 01:11:42 +00:00
[upstream_utils] Upgrade to LLVM 19.1.6 (#7101)
This commit is contained in:
17
wpiutil/src/test/native/cpp/llvm/CountCopyAndMove.cpp
Normal file
17
wpiutil/src/test/native/cpp/llvm/CountCopyAndMove.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
//===- llvm/unittest/ADT/CountCopyAndMove.cpp - Optional unit tests -------===//
|
||||
//
|
||||
// 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 "CountCopyAndMove.h"
|
||||
|
||||
using namespace wpi;
|
||||
|
||||
int CountCopyAndMove::CopyConstructions = 0;
|
||||
int CountCopyAndMove::CopyAssignments = 0;
|
||||
int CountCopyAndMove::MoveConstructions = 0;
|
||||
int CountCopyAndMove::MoveAssignments = 0;
|
||||
int CountCopyAndMove::Destructions = 0;
|
||||
57
wpiutil/src/test/native/cpp/llvm/CountCopyAndMove.h
Normal file
57
wpiutil/src/test/native/cpp/llvm/CountCopyAndMove.h
Normal file
@@ -0,0 +1,57 @@
|
||||
//===- llvm/unittest/ADT/CountCopyAndMove.h - Optional unit tests ---------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_UNITTESTS_ADT_COUNTCOPYANDMOVE_H
|
||||
#define LLVM_UNITTESTS_ADT_COUNTCOPYANDMOVE_H
|
||||
|
||||
namespace wpi {
|
||||
|
||||
struct CountCopyAndMove {
|
||||
static int CopyConstructions;
|
||||
static int CopyAssignments;
|
||||
static int MoveConstructions;
|
||||
static int MoveAssignments;
|
||||
static int Destructions;
|
||||
int val;
|
||||
|
||||
CountCopyAndMove() = default;
|
||||
explicit CountCopyAndMove(int val) : val(val) {}
|
||||
CountCopyAndMove(const CountCopyAndMove &other) : val(other.val) {
|
||||
++CopyConstructions;
|
||||
}
|
||||
CountCopyAndMove &operator=(const CountCopyAndMove &other) {
|
||||
val = other.val;
|
||||
++CopyAssignments;
|
||||
return *this;
|
||||
}
|
||||
CountCopyAndMove(CountCopyAndMove &&other) : val(other.val) {
|
||||
++MoveConstructions;
|
||||
}
|
||||
CountCopyAndMove &operator=(CountCopyAndMove &&other) {
|
||||
val = other.val;
|
||||
++MoveAssignments;
|
||||
return *this;
|
||||
}
|
||||
~CountCopyAndMove() { ++Destructions; }
|
||||
|
||||
static void ResetCounts() {
|
||||
CopyConstructions = 0;
|
||||
CopyAssignments = 0;
|
||||
MoveConstructions = 0;
|
||||
MoveAssignments = 0;
|
||||
Destructions = 0;
|
||||
}
|
||||
|
||||
static int TotalCopies() { return CopyConstructions + CopyAssignments; }
|
||||
|
||||
static int TotalMoves() { return MoveConstructions + MoveAssignments; }
|
||||
};
|
||||
|
||||
} // end namespace wpi
|
||||
|
||||
#endif // LLVM_UNITTESTS_ADT_COUNTCOPYANDMOVE_H
|
||||
@@ -11,6 +11,7 @@
|
||||
#endif
|
||||
|
||||
#include "wpi/DenseMap.h"
|
||||
#include "CountCopyAndMove.h"
|
||||
#include "wpi/DenseMapInfo.h"
|
||||
#include "wpi/DenseMapInfoVariant.h"
|
||||
#include "gmock/gmock.h"
|
||||
@@ -24,7 +25,6 @@
|
||||
using namespace wpi;
|
||||
|
||||
namespace {
|
||||
|
||||
uint32_t getTestKey(int i, uint32_t *) { return i; }
|
||||
uint32_t getTestValue(int i, uint32_t *) { return 42 + i; }
|
||||
|
||||
@@ -39,6 +39,14 @@ uint32_t *getTestValue(int i, uint32_t **) {
|
||||
return &dummy_arr1[i];
|
||||
}
|
||||
|
||||
enum class EnumClass { Val };
|
||||
|
||||
EnumClass getTestKey(int i, EnumClass *) {
|
||||
// We can't possibly support 100 values for the swap test, so just return an
|
||||
// invalid EnumClass for testing.
|
||||
return static_cast<EnumClass>(i);
|
||||
}
|
||||
|
||||
/// A test class that tries to check that construction and destruction
|
||||
/// occur correctly.
|
||||
class CtorTester {
|
||||
@@ -107,14 +115,19 @@ template <typename T>
|
||||
typename T::mapped_type *const DenseMapTest<T>::dummy_value_ptr = nullptr;
|
||||
|
||||
// Register these types for testing.
|
||||
// clang-format off
|
||||
typedef ::testing::Types<DenseMap<uint32_t, uint32_t>,
|
||||
DenseMap<uint32_t *, uint32_t *>,
|
||||
DenseMap<CtorTester, CtorTester, CtorTesterMapInfo>,
|
||||
DenseMap<EnumClass, uint32_t>,
|
||||
SmallDenseMap<uint32_t, uint32_t>,
|
||||
SmallDenseMap<uint32_t *, uint32_t *>,
|
||||
SmallDenseMap<CtorTester, CtorTester, 4,
|
||||
CtorTesterMapInfo>
|
||||
CtorTesterMapInfo>,
|
||||
SmallDenseMap<EnumClass, uint32_t>
|
||||
> DenseMapTestTypes;
|
||||
// clang-format on
|
||||
|
||||
TYPED_TEST_SUITE(DenseMapTest, DenseMapTestTypes, );
|
||||
|
||||
// Empty map tests
|
||||
@@ -350,29 +363,6 @@ TYPED_TEST(DenseMapTest, ConstIteratorTest) {
|
||||
EXPECT_TRUE(cit == cit2);
|
||||
}
|
||||
|
||||
namespace {
|
||||
// Simple class that counts how many moves and copy happens when growing a map
|
||||
struct CountCopyAndMove {
|
||||
static int Move;
|
||||
static int Copy;
|
||||
CountCopyAndMove() {}
|
||||
|
||||
CountCopyAndMove(const CountCopyAndMove &) { Copy++; }
|
||||
CountCopyAndMove &operator=(const CountCopyAndMove &) {
|
||||
Copy++;
|
||||
return *this;
|
||||
}
|
||||
CountCopyAndMove(CountCopyAndMove &&) { Move++; }
|
||||
CountCopyAndMove &operator=(const CountCopyAndMove &&) {
|
||||
Move++;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
int CountCopyAndMove::Copy = 0;
|
||||
int CountCopyAndMove::Move = 0;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// Test initializer list construction.
|
||||
TEST(DenseMapCustomTest, InitializerList) {
|
||||
DenseMap<int, int> M({{0, 0}, {0, 1}, {1, 2}});
|
||||
@@ -405,8 +395,8 @@ TEST(DenseMapCustomTest, DefaultMinReservedSizeTest) {
|
||||
// Will allocate 64 buckets
|
||||
Map.reserve(1);
|
||||
unsigned MemorySize = Map.getMemorySize();
|
||||
CountCopyAndMove::Copy = 0;
|
||||
CountCopyAndMove::Move = 0;
|
||||
CountCopyAndMove::ResetCounts();
|
||||
|
||||
for (int i = 0; i < ExpectedMaxInitialEntries; ++i)
|
||||
Map.insert(std::pair<int, CountCopyAndMove>(std::piecewise_construct,
|
||||
std::forward_as_tuple(i),
|
||||
@@ -414,9 +404,9 @@ TEST(DenseMapCustomTest, DefaultMinReservedSizeTest) {
|
||||
// Check that we didn't grow
|
||||
EXPECT_EQ(MemorySize, Map.getMemorySize());
|
||||
// Check that move was called the expected number of times
|
||||
EXPECT_EQ(ExpectedMaxInitialEntries, CountCopyAndMove::Move);
|
||||
EXPECT_EQ(ExpectedMaxInitialEntries, CountCopyAndMove::TotalMoves());
|
||||
// Check that no copy occurred
|
||||
EXPECT_EQ(0, CountCopyAndMove::Copy);
|
||||
EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
|
||||
|
||||
// Adding one extra element should grow the map
|
||||
Map.insert(std::pair<int, CountCopyAndMove>(
|
||||
@@ -429,7 +419,7 @@ TEST(DenseMapCustomTest, DefaultMinReservedSizeTest) {
|
||||
// This relies on move-construction elision, and cannot be reliably tested.
|
||||
// EXPECT_EQ(ExpectedMaxInitialEntries + 2, CountCopyAndMove::Move);
|
||||
// Check that no copy occurred
|
||||
EXPECT_EQ(0, CountCopyAndMove::Copy);
|
||||
EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
|
||||
}
|
||||
|
||||
// Make sure creating the map with an initial size of N actually gives us enough
|
||||
@@ -443,8 +433,8 @@ TEST(DenseMapCustomTest, InitialSizeTest) {
|
||||
for (auto Size : {1, 2, 48, 66}) {
|
||||
DenseMap<int, CountCopyAndMove> Map(Size);
|
||||
unsigned MemorySize = Map.getMemorySize();
|
||||
CountCopyAndMove::Copy = 0;
|
||||
CountCopyAndMove::Move = 0;
|
||||
CountCopyAndMove::ResetCounts();
|
||||
|
||||
for (int i = 0; i < Size; ++i)
|
||||
Map.insert(std::pair<int, CountCopyAndMove>(std::piecewise_construct,
|
||||
std::forward_as_tuple(i),
|
||||
@@ -452,9 +442,9 @@ TEST(DenseMapCustomTest, InitialSizeTest) {
|
||||
// Check that we didn't grow
|
||||
EXPECT_EQ(MemorySize, Map.getMemorySize());
|
||||
// Check that move was called the expected number of times
|
||||
EXPECT_EQ(Size, CountCopyAndMove::Move);
|
||||
EXPECT_EQ(Size, CountCopyAndMove::TotalMoves());
|
||||
// Check that no copy occurred
|
||||
EXPECT_EQ(0, CountCopyAndMove::Copy);
|
||||
EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -465,15 +455,14 @@ TEST(DenseMapCustomTest, InitFromIterator) {
|
||||
const int Count = 65;
|
||||
Values.reserve(Count);
|
||||
for (int i = 0; i < Count; i++)
|
||||
Values.emplace_back(i, CountCopyAndMove());
|
||||
Values.emplace_back(i, CountCopyAndMove(i));
|
||||
|
||||
CountCopyAndMove::Move = 0;
|
||||
CountCopyAndMove::Copy = 0;
|
||||
CountCopyAndMove::ResetCounts();
|
||||
DenseMap<int, CountCopyAndMove> Map(Values.begin(), Values.end());
|
||||
// Check that no move occurred
|
||||
EXPECT_EQ(0, CountCopyAndMove::Move);
|
||||
EXPECT_EQ(0, CountCopyAndMove::TotalMoves());
|
||||
// Check that copy was called the expected number of times
|
||||
EXPECT_EQ(Count, CountCopyAndMove::Copy);
|
||||
EXPECT_EQ(Count, CountCopyAndMove::TotalCopies());
|
||||
}
|
||||
|
||||
// Make sure reserve actually gives us enough buckets to insert N items
|
||||
@@ -488,8 +477,7 @@ TEST(DenseMapCustomTest, ReserveTest) {
|
||||
DenseMap<int, CountCopyAndMove> Map;
|
||||
Map.reserve(Size);
|
||||
unsigned MemorySize = Map.getMemorySize();
|
||||
CountCopyAndMove::Copy = 0;
|
||||
CountCopyAndMove::Move = 0;
|
||||
CountCopyAndMove::ResetCounts();
|
||||
for (int i = 0; i < Size; ++i)
|
||||
Map.insert(std::pair<int, CountCopyAndMove>(std::piecewise_construct,
|
||||
std::forward_as_tuple(i),
|
||||
@@ -497,12 +485,48 @@ TEST(DenseMapCustomTest, ReserveTest) {
|
||||
// Check that we didn't grow
|
||||
EXPECT_EQ(MemorySize, Map.getMemorySize());
|
||||
// Check that move was called the expected number of times
|
||||
EXPECT_EQ(Size, CountCopyAndMove::Move);
|
||||
EXPECT_EQ(Size, CountCopyAndMove::TotalMoves());
|
||||
// Check that no copy occurred
|
||||
EXPECT_EQ(0, CountCopyAndMove::Copy);
|
||||
EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(DenseMapCustomTest, InsertOrAssignTest) {
|
||||
DenseMap<int, CountCopyAndMove> Map;
|
||||
|
||||
CountCopyAndMove val1(1);
|
||||
CountCopyAndMove::ResetCounts();
|
||||
auto try0 = Map.insert_or_assign(0, val1);
|
||||
EXPECT_TRUE(try0.second);
|
||||
EXPECT_EQ(0, CountCopyAndMove::TotalMoves());
|
||||
EXPECT_EQ(1, CountCopyAndMove::CopyConstructions);
|
||||
EXPECT_EQ(0, CountCopyAndMove::CopyAssignments);
|
||||
|
||||
CountCopyAndMove::ResetCounts();
|
||||
auto try1 = Map.insert_or_assign(0, val1);
|
||||
EXPECT_FALSE(try1.second);
|
||||
EXPECT_EQ(0, CountCopyAndMove::TotalMoves());
|
||||
EXPECT_EQ(0, CountCopyAndMove::CopyConstructions);
|
||||
EXPECT_EQ(1, CountCopyAndMove::CopyAssignments);
|
||||
|
||||
int key2 = 2;
|
||||
CountCopyAndMove val2(2);
|
||||
CountCopyAndMove::ResetCounts();
|
||||
auto try2 = Map.insert_or_assign(key2, std::move(val2));
|
||||
EXPECT_TRUE(try2.second);
|
||||
EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
|
||||
EXPECT_EQ(1, CountCopyAndMove::MoveConstructions);
|
||||
EXPECT_EQ(0, CountCopyAndMove::MoveAssignments);
|
||||
|
||||
CountCopyAndMove val3(3);
|
||||
CountCopyAndMove::ResetCounts();
|
||||
auto try3 = Map.insert_or_assign(key2, std::move(val3));
|
||||
EXPECT_FALSE(try3.second);
|
||||
EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
|
||||
EXPECT_EQ(0, CountCopyAndMove::MoveConstructions);
|
||||
EXPECT_EQ(1, CountCopyAndMove::MoveAssignments);
|
||||
}
|
||||
|
||||
// Key traits that allows lookup with either an unsigned or char* key;
|
||||
// In the latter case, "a" == 0, "b" == 1 and so on.
|
||||
struct TestDenseMapInfo {
|
||||
|
||||
@@ -35,6 +35,29 @@ TEST(Endian, Read) {
|
||||
1)));
|
||||
}
|
||||
|
||||
TEST(Endian, WriteNext) {
|
||||
unsigned char bigval[] = {0x00, 0x00}, *p = bigval;
|
||||
endian::writeNext<int16_t, wpi::endianness::big>(p, short(0xaabb));
|
||||
EXPECT_EQ(bigval[0], 0xaa);
|
||||
EXPECT_EQ(bigval[1], 0xbb);
|
||||
EXPECT_EQ(p, bigval + 2);
|
||||
|
||||
char littleval[8] = {}, *q = littleval;
|
||||
endian::writeNext<uint32_t, wpi::endianness::little>(q, 0x44556677);
|
||||
EXPECT_EQ(littleval[0], 0x77);
|
||||
EXPECT_EQ(littleval[1], 0x66);
|
||||
EXPECT_EQ(littleval[2], 0x55);
|
||||
EXPECT_EQ(littleval[3], 0x44);
|
||||
EXPECT_EQ(q, littleval + 4);
|
||||
|
||||
endian::writeNext<uint32_t>(q, 0x11223344, wpi::endianness::little);
|
||||
EXPECT_EQ(littleval[4], 0x44);
|
||||
EXPECT_EQ(littleval[5], 0x33);
|
||||
EXPECT_EQ(littleval[6], 0x22);
|
||||
EXPECT_EQ(littleval[7], 0x11);
|
||||
EXPECT_EQ(q, littleval + 8);
|
||||
}
|
||||
|
||||
TEST(Endian, ReadBitAligned) {
|
||||
// Simple test to make sure we properly pull out the 0x0 word.
|
||||
unsigned char littleval[] = {0x3f, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff};
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "wpi/MathExtras.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include <limits>
|
||||
|
||||
using namespace wpi;
|
||||
|
||||
@@ -41,6 +42,9 @@ TEST(MathExtras, onesMask) {
|
||||
TEST(MathExtras, isIntN) {
|
||||
EXPECT_TRUE(isIntN(16, 32767));
|
||||
EXPECT_FALSE(isIntN(16, 32768));
|
||||
EXPECT_TRUE(isIntN(0, 0));
|
||||
EXPECT_FALSE(isIntN(0, 1));
|
||||
EXPECT_FALSE(isIntN(0, -1));
|
||||
}
|
||||
|
||||
TEST(MathExtras, isUIntN) {
|
||||
@@ -48,6 +52,8 @@ TEST(MathExtras, isUIntN) {
|
||||
EXPECT_FALSE(isUIntN(16, 65536));
|
||||
EXPECT_TRUE(isUIntN(1, 0));
|
||||
EXPECT_TRUE(isUIntN(6, 63));
|
||||
EXPECT_TRUE(isUIntN(0, 0));
|
||||
EXPECT_FALSE(isUIntN(0, 1));
|
||||
}
|
||||
|
||||
TEST(MathExtras, maxIntN) {
|
||||
@@ -55,6 +61,7 @@ TEST(MathExtras, maxIntN) {
|
||||
EXPECT_EQ(2147483647, maxIntN(32));
|
||||
EXPECT_EQ(std::numeric_limits<int32_t>::max(), maxIntN(32));
|
||||
EXPECT_EQ(std::numeric_limits<int64_t>::max(), maxIntN(64));
|
||||
EXPECT_EQ(0, maxIntN(0));
|
||||
}
|
||||
|
||||
TEST(MathExtras, minIntN) {
|
||||
@@ -62,6 +69,7 @@ TEST(MathExtras, minIntN) {
|
||||
EXPECT_EQ(-64LL, minIntN(7));
|
||||
EXPECT_EQ(std::numeric_limits<int32_t>::min(), minIntN(32));
|
||||
EXPECT_EQ(std::numeric_limits<int64_t>::min(), minIntN(64));
|
||||
EXPECT_EQ(0, minIntN(0));
|
||||
}
|
||||
|
||||
TEST(MathExtras, maxUIntN) {
|
||||
@@ -70,6 +78,7 @@ TEST(MathExtras, maxUIntN) {
|
||||
EXPECT_EQ(0xffffffffffffffffULL, maxUIntN(64));
|
||||
EXPECT_EQ(1ULL, maxUIntN(1));
|
||||
EXPECT_EQ(0x0fULL, maxUIntN(4));
|
||||
EXPECT_EQ(0ULL, maxUIntN(0));
|
||||
}
|
||||
|
||||
TEST(MathExtras, reverseBits) {
|
||||
@@ -167,6 +176,7 @@ TEST(MathExtras, MinAlign) {
|
||||
EXPECT_EQ(2u, MinAlign(2, 4));
|
||||
EXPECT_EQ(1u, MinAlign(17, 64));
|
||||
EXPECT_EQ(256u, MinAlign(256, 512));
|
||||
EXPECT_EQ(2u, MinAlign(0, 2));
|
||||
}
|
||||
|
||||
TEST(MathExtras, NextPowerOf2) {
|
||||
@@ -175,15 +185,48 @@ TEST(MathExtras, NextPowerOf2) {
|
||||
EXPECT_EQ(256u, NextPowerOf2(128));
|
||||
}
|
||||
|
||||
TEST(MathExtras, alignTo) {
|
||||
TEST(MathExtras, AlignTo) {
|
||||
EXPECT_EQ(8u, alignTo(5, 8));
|
||||
EXPECT_EQ(24u, alignTo(17, 8));
|
||||
EXPECT_EQ(0u, alignTo(~0LL, 8));
|
||||
EXPECT_EQ(8u, alignTo(5ULL, 8ULL));
|
||||
|
||||
EXPECT_EQ(8u, alignTo<8>(5));
|
||||
EXPECT_EQ(24u, alignTo<8>(17));
|
||||
EXPECT_EQ(0u, alignTo<8>(~0LL));
|
||||
EXPECT_EQ(254u,
|
||||
alignTo<static_cast<uint8_t>(127)>(static_cast<uint8_t>(200)));
|
||||
|
||||
EXPECT_EQ(7u, alignTo(5, 8, 7));
|
||||
EXPECT_EQ(17u, alignTo(17, 8, 1));
|
||||
EXPECT_EQ(3u, alignTo(~0LL, 8, 3));
|
||||
EXPECT_EQ(552u, alignTo(321, 255, 42));
|
||||
EXPECT_EQ(std::numeric_limits<uint32_t>::max(),
|
||||
alignTo(std::numeric_limits<uint32_t>::max(), 2, 1));
|
||||
|
||||
// Overflow.
|
||||
EXPECT_EQ(0u, alignTo(static_cast<uint8_t>(200), static_cast<uint8_t>(128)));
|
||||
EXPECT_EQ(0u, alignTo<static_cast<uint8_t>(128)>(static_cast<uint8_t>(200)));
|
||||
EXPECT_EQ(0u, alignTo(static_cast<uint8_t>(200), static_cast<uint8_t>(128),
|
||||
static_cast<uint8_t>(0)));
|
||||
EXPECT_EQ(0u, alignTo(std::numeric_limits<uint32_t>::max(), 2));
|
||||
}
|
||||
|
||||
TEST(MathExtras, AlignToPowerOf2) {
|
||||
EXPECT_EQ(0u, alignToPowerOf2(0u, 8));
|
||||
EXPECT_EQ(8u, alignToPowerOf2(5, 8));
|
||||
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));
|
||||
}
|
||||
|
||||
TEST(MathExtras, AlignDown) {
|
||||
EXPECT_EQ(0u, alignDown(5, 8));
|
||||
EXPECT_EQ(16u, alignDown(17, 8));
|
||||
EXPECT_EQ(std::numeric_limits<uint32_t>::max() - 1,
|
||||
alignDown(std::numeric_limits<uint32_t>::max(), 2));
|
||||
}
|
||||
|
||||
template <typename T> void SaturatingAddTestHelper() {
|
||||
@@ -426,8 +469,102 @@ TEST(MathExtras, IsShiftedInt) {
|
||||
EXPECT_FALSE((isShiftedInt<6, 10>(int64_t(1) << 15)));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class OverflowTest : public ::testing::Test { };
|
||||
TEST(MathExtras, DivideNearest) {
|
||||
EXPECT_EQ(divideNearest(14, 3), 5u);
|
||||
EXPECT_EQ(divideNearest(15, 3), 5u);
|
||||
EXPECT_EQ(divideNearest(0, 3), 0u);
|
||||
EXPECT_EQ(divideNearest(5, 4), 1u);
|
||||
EXPECT_EQ(divideNearest(6, 4), 2u);
|
||||
EXPECT_EQ(divideNearest(3, 1), 3u);
|
||||
EXPECT_EQ(divideNearest(3, 6), 1u);
|
||||
EXPECT_EQ(divideNearest(3, 7), 0u);
|
||||
EXPECT_EQ(divideNearest(std::numeric_limits<uint32_t>::max(), 2),
|
||||
std::numeric_limits<uint32_t>::max() / 2 + 1);
|
||||
EXPECT_EQ(divideNearest(std::numeric_limits<uint64_t>::max(), 2),
|
||||
std::numeric_limits<uint64_t>::max() / 2 + 1);
|
||||
EXPECT_EQ(divideNearest(std::numeric_limits<uint64_t>::max(), 1),
|
||||
std::numeric_limits<uint64_t>::max());
|
||||
EXPECT_EQ(divideNearest(std::numeric_limits<uint64_t>::max() - 1,
|
||||
std::numeric_limits<uint64_t>::max()),
|
||||
1u);
|
||||
}
|
||||
|
||||
TEST(MathExtras, DivideCeil) {
|
||||
EXPECT_EQ(divideCeil(14, 3), 5u);
|
||||
EXPECT_EQ(divideCeil(15, 3), 5u);
|
||||
EXPECT_EQ(divideCeil(0, 3), 0u);
|
||||
EXPECT_EQ(divideCeil(5, 4), 2u);
|
||||
EXPECT_EQ(divideCeil(6, 4), 2u);
|
||||
EXPECT_EQ(divideCeil(3, 1), 3u);
|
||||
EXPECT_EQ(divideCeil(3, 6), 1u);
|
||||
EXPECT_EQ(divideCeil(3, 7), 1u);
|
||||
EXPECT_EQ(divideCeil(std::numeric_limits<uint32_t>::max(), 2),
|
||||
std::numeric_limits<uint32_t>::max() / 2 + 1);
|
||||
EXPECT_EQ(divideCeil(std::numeric_limits<uint64_t>::max(), 2),
|
||||
std::numeric_limits<uint64_t>::max() / 2 + 1);
|
||||
EXPECT_EQ(divideCeil(std::numeric_limits<uint64_t>::max(), 1),
|
||||
std::numeric_limits<uint64_t>::max());
|
||||
|
||||
EXPECT_EQ(divideCeilSigned(14, 3), 5);
|
||||
EXPECT_EQ(divideCeilSigned(15, 3), 5);
|
||||
EXPECT_EQ(divideCeilSigned(14, -3), -4);
|
||||
EXPECT_EQ(divideCeilSigned(-14, -3), 5);
|
||||
EXPECT_EQ(divideCeilSigned(-14, 3), -4);
|
||||
EXPECT_EQ(divideCeilSigned(-15, 3), -5);
|
||||
EXPECT_EQ(divideCeilSigned(0, 3), 0);
|
||||
EXPECT_EQ(divideCeilSigned(0, -3), 0);
|
||||
EXPECT_EQ(divideCeilSigned(std::numeric_limits<int32_t>::max(), 2),
|
||||
std::numeric_limits<int32_t>::max() / 2 + 1);
|
||||
EXPECT_EQ(divideCeilSigned(std::numeric_limits<int64_t>::max(), 2),
|
||||
std::numeric_limits<int64_t>::max() / 2 + 1);
|
||||
EXPECT_EQ(divideCeilSigned(std::numeric_limits<int32_t>::max(), -2),
|
||||
std::numeric_limits<int32_t>::min() / 2 + 1);
|
||||
EXPECT_EQ(divideCeilSigned(std::numeric_limits<int64_t>::max(), -2),
|
||||
std::numeric_limits<int64_t>::min() / 2 + 1);
|
||||
EXPECT_EQ(divideCeilSigned(std::numeric_limits<int64_t>::min(), 1),
|
||||
std::numeric_limits<int64_t>::min());
|
||||
|
||||
// Overflow.
|
||||
EXPECT_TRUE(
|
||||
divideSignedWouldOverflow(std::numeric_limits<int8_t>::min(), -1));
|
||||
EXPECT_TRUE(
|
||||
divideSignedWouldOverflow(std::numeric_limits<int64_t>::min(), -1));
|
||||
}
|
||||
|
||||
TEST(MathExtras, DivideFloorSigned) {
|
||||
EXPECT_EQ(divideFloorSigned(14, 3), 4);
|
||||
EXPECT_EQ(divideFloorSigned(15, 3), 5);
|
||||
EXPECT_EQ(divideFloorSigned(14, -3), -5);
|
||||
EXPECT_EQ(divideFloorSigned(-14, -3), 4);
|
||||
EXPECT_EQ(divideFloorSigned(-14, 3), -5);
|
||||
EXPECT_EQ(divideFloorSigned(-15, 3), -5);
|
||||
EXPECT_EQ(divideFloorSigned(0, 3), 0);
|
||||
EXPECT_EQ(divideFloorSigned(0, -3), 0);
|
||||
EXPECT_EQ(divideFloorSigned(std::numeric_limits<int32_t>::max(), 2),
|
||||
std::numeric_limits<int32_t>::max() / 2);
|
||||
EXPECT_EQ(divideFloorSigned(std::numeric_limits<int64_t>::max(), 2),
|
||||
std::numeric_limits<int64_t>::max() / 2);
|
||||
EXPECT_EQ(divideFloorSigned(std::numeric_limits<int32_t>::max(), -2),
|
||||
std::numeric_limits<int32_t>::min() / 2);
|
||||
EXPECT_EQ(divideFloorSigned(std::numeric_limits<int64_t>::max(), -2),
|
||||
std::numeric_limits<int64_t>::min() / 2);
|
||||
EXPECT_EQ(divideFloorSigned(std::numeric_limits<int64_t>::min(), 1),
|
||||
std::numeric_limits<int64_t>::min());
|
||||
|
||||
// Same overflow condition, divideSignedWouldOverflow, applies.
|
||||
}
|
||||
|
||||
TEST(MathExtras, Mod) {
|
||||
EXPECT_EQ(mod(1, 14), 1);
|
||||
EXPECT_EQ(mod(-1, 14), 13);
|
||||
EXPECT_EQ(mod(14, 3), 2);
|
||||
EXPECT_EQ(mod(15, 3), 0);
|
||||
EXPECT_EQ(mod(-14, 3), 1);
|
||||
EXPECT_EQ(mod(-15, 3), 0);
|
||||
EXPECT_EQ(mod(0, 3), 0);
|
||||
}
|
||||
|
||||
template <typename T> class OverflowTest : public ::testing::Test {};
|
||||
|
||||
using OverflowTestTypes = ::testing::Types<signed char, short, int, long,
|
||||
long long>;
|
||||
@@ -552,5 +689,4 @@ TYPED_TEST(OverflowTest, MulResultZero) {
|
||||
EXPECT_FALSE(MulOverflow<TypeParam>(0, -5, Result));
|
||||
EXPECT_EQ(Result, TypeParam(0));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
//===- llvm/unittest/ADT/MoveOnly.cpp - Optional unit tests ---------------===//
|
||||
//
|
||||
// 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 "MoveOnly.h"
|
||||
|
||||
using namespace wpi;
|
||||
|
||||
unsigned MoveOnly::MoveConstructions = 0;
|
||||
unsigned MoveOnly::Destructions = 0;
|
||||
unsigned MoveOnly::MoveAssignments = 0;
|
||||
@@ -1,42 +0,0 @@
|
||||
//===- llvm/unittest/ADT/MoveOnly.h - Optional unit tests -----------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_UNITTESTS_ADT_MOVEONLY_H
|
||||
#define LLVM_UNITTESTS_ADT_MOVEONLY_H
|
||||
|
||||
namespace wpi {
|
||||
|
||||
struct MoveOnly {
|
||||
static unsigned MoveConstructions;
|
||||
static unsigned Destructions;
|
||||
static unsigned MoveAssignments;
|
||||
int val;
|
||||
explicit MoveOnly(int val) : val(val) {
|
||||
}
|
||||
MoveOnly(MoveOnly&& other) {
|
||||
val = other.val;
|
||||
++MoveConstructions;
|
||||
}
|
||||
MoveOnly &operator=(MoveOnly&& other) {
|
||||
val = other.val;
|
||||
++MoveAssignments;
|
||||
return *this;
|
||||
}
|
||||
~MoveOnly() {
|
||||
++Destructions;
|
||||
}
|
||||
static void ResetCounts() {
|
||||
MoveConstructions = 0;
|
||||
Destructions = 0;
|
||||
MoveAssignments = 0;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace wpi
|
||||
|
||||
#endif // LLVM_UNITTESTS_ADT_MOVEONLY_H
|
||||
@@ -7,7 +7,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "wpi/STLForwardCompat.h"
|
||||
#include "MoveOnly.h"
|
||||
#include "CountCopyAndMove.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace {
|
||||
@@ -58,27 +58,29 @@ TEST(TransformTest, TransformStd) {
|
||||
}
|
||||
|
||||
TEST(TransformTest, MoveTransformStd) {
|
||||
using wpi::MoveOnly;
|
||||
using wpi::CountCopyAndMove;
|
||||
|
||||
std::optional<MoveOnly> A;
|
||||
std::optional<CountCopyAndMove> A;
|
||||
|
||||
MoveOnly::ResetCounts();
|
||||
CountCopyAndMove::ResetCounts();
|
||||
std::optional<int> B = wpi::transformOptional(
|
||||
std::move(A), [&](const MoveOnly &M) { return M.val + 2; });
|
||||
std::move(A), [&](const CountCopyAndMove &M) { return M.val + 2; });
|
||||
EXPECT_FALSE(B.has_value());
|
||||
EXPECT_EQ(0u, MoveOnly::MoveConstructions);
|
||||
EXPECT_EQ(0u, MoveOnly::MoveAssignments);
|
||||
EXPECT_EQ(0u, MoveOnly::Destructions);
|
||||
EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
|
||||
EXPECT_EQ(0, CountCopyAndMove::MoveConstructions);
|
||||
EXPECT_EQ(0, CountCopyAndMove::MoveAssignments);
|
||||
EXPECT_EQ(0, CountCopyAndMove::Destructions);
|
||||
|
||||
A = MoveOnly(5);
|
||||
MoveOnly::ResetCounts();
|
||||
A = CountCopyAndMove(5);
|
||||
CountCopyAndMove::ResetCounts();
|
||||
std::optional<int> C = wpi::transformOptional(
|
||||
std::move(A), [&](const MoveOnly &M) { return M.val + 2; });
|
||||
std::move(A), [&](const CountCopyAndMove &M) { return M.val + 2; });
|
||||
EXPECT_TRUE(C.has_value());
|
||||
EXPECT_EQ(7, *C);
|
||||
EXPECT_EQ(0u, MoveOnly::MoveConstructions);
|
||||
EXPECT_EQ(0u, MoveOnly::MoveAssignments);
|
||||
EXPECT_EQ(0u, MoveOnly::Destructions);
|
||||
EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
|
||||
EXPECT_EQ(0, CountCopyAndMove::MoveConstructions);
|
||||
EXPECT_EQ(0, CountCopyAndMove::MoveAssignments);
|
||||
EXPECT_EQ(0, CountCopyAndMove::Destructions);
|
||||
}
|
||||
|
||||
TEST(TransformTest, TransformLlvm) {
|
||||
@@ -96,27 +98,29 @@ TEST(TransformTest, TransformLlvm) {
|
||||
}
|
||||
|
||||
TEST(TransformTest, MoveTransformLlvm) {
|
||||
using wpi::MoveOnly;
|
||||
using wpi::CountCopyAndMove;
|
||||
|
||||
std::optional<MoveOnly> A;
|
||||
std::optional<CountCopyAndMove> A;
|
||||
|
||||
MoveOnly::ResetCounts();
|
||||
CountCopyAndMove::ResetCounts();
|
||||
std::optional<int> B = wpi::transformOptional(
|
||||
std::move(A), [&](const MoveOnly &M) { return M.val + 2; });
|
||||
std::move(A), [&](const CountCopyAndMove &M) { return M.val + 2; });
|
||||
EXPECT_FALSE(B.has_value());
|
||||
EXPECT_EQ(0u, MoveOnly::MoveConstructions);
|
||||
EXPECT_EQ(0u, MoveOnly::MoveAssignments);
|
||||
EXPECT_EQ(0u, MoveOnly::Destructions);
|
||||
EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
|
||||
EXPECT_EQ(0, CountCopyAndMove::MoveConstructions);
|
||||
EXPECT_EQ(0, CountCopyAndMove::MoveAssignments);
|
||||
EXPECT_EQ(0, CountCopyAndMove::Destructions);
|
||||
|
||||
A = MoveOnly(5);
|
||||
MoveOnly::ResetCounts();
|
||||
A = CountCopyAndMove(5);
|
||||
CountCopyAndMove::ResetCounts();
|
||||
std::optional<int> C = wpi::transformOptional(
|
||||
std::move(A), [&](const MoveOnly &M) { return M.val + 2; });
|
||||
std::move(A), [&](const CountCopyAndMove &M) { return M.val + 2; });
|
||||
EXPECT_TRUE(C.has_value());
|
||||
EXPECT_EQ(7, *C);
|
||||
EXPECT_EQ(0u, MoveOnly::MoveConstructions);
|
||||
EXPECT_EQ(0u, MoveOnly::MoveAssignments);
|
||||
EXPECT_EQ(0u, MoveOnly::Destructions);
|
||||
EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
|
||||
EXPECT_EQ(0, CountCopyAndMove::MoveConstructions);
|
||||
EXPECT_EQ(0, CountCopyAndMove::MoveAssignments);
|
||||
EXPECT_EQ(0, CountCopyAndMove::Destructions);
|
||||
}
|
||||
|
||||
TEST(TransformTest, ToUnderlying) {
|
||||
|
||||
@@ -244,45 +244,6 @@ TEST(SmallPtrSetTest, SwapTest) {
|
||||
EXPECT_TRUE(a.count(&buf[3]));
|
||||
}
|
||||
|
||||
void checkEraseAndIterators(SmallPtrSetImpl<int*> &S) {
|
||||
int buf[3];
|
||||
|
||||
S.insert(&buf[0]);
|
||||
S.insert(&buf[1]);
|
||||
S.insert(&buf[2]);
|
||||
|
||||
// Iterators must still be valid after erase() calls;
|
||||
auto B = S.begin();
|
||||
auto M = std::next(B);
|
||||
auto E = S.end();
|
||||
EXPECT_TRUE(*B == &buf[0] || *B == &buf[1] || *B == &buf[2]);
|
||||
EXPECT_TRUE(*M == &buf[0] || *M == &buf[1] || *M == &buf[2]);
|
||||
EXPECT_TRUE(*B != *M);
|
||||
int *Removable = *std::next(M);
|
||||
// No iterator points to Removable now.
|
||||
EXPECT_TRUE(Removable == &buf[0] || Removable == &buf[1] ||
|
||||
Removable == &buf[2]);
|
||||
EXPECT_TRUE(Removable != *B && Removable != *M);
|
||||
|
||||
S.erase(Removable);
|
||||
|
||||
// B,M,E iterators should still be valid
|
||||
EXPECT_EQ(B, S.begin());
|
||||
EXPECT_EQ(M, std::next(B));
|
||||
EXPECT_EQ(E, S.end());
|
||||
EXPECT_EQ(std::next(M), E);
|
||||
}
|
||||
|
||||
TEST(SmallPtrSetTest, EraseTest) {
|
||||
// Test when set stays small.
|
||||
SmallPtrSet<int *, 8> B;
|
||||
checkEraseAndIterators(B);
|
||||
|
||||
// Test when set grows big.
|
||||
SmallPtrSet<int *, 2> A;
|
||||
checkEraseAndIterators(A);
|
||||
}
|
||||
|
||||
// Verify that dereferencing and iteration work.
|
||||
TEST(SmallPtrSetTest, dereferenceAndIterate) {
|
||||
int Ints[] = {0, 1, 2, 3, 4, 5, 6, 7};
|
||||
@@ -410,3 +371,41 @@ TEST(SmallPtrSetTest, InsertIterator) {
|
||||
for (const auto *Ptr : Buf)
|
||||
EXPECT_TRUE(Set.contains(Ptr));
|
||||
}
|
||||
|
||||
TEST(SmallPtrSetTest, RemoveIf) {
|
||||
SmallPtrSet<int *, 5> Set;
|
||||
int Vals[6] = {0, 1, 2, 3, 4, 5};
|
||||
|
||||
// Stay in small regime.
|
||||
Set.insert(&Vals[0]);
|
||||
Set.insert(&Vals[1]);
|
||||
Set.insert(&Vals[2]);
|
||||
Set.insert(&Vals[3]);
|
||||
Set.erase(&Vals[0]); // Leave a tombstone.
|
||||
|
||||
// Remove odd elements.
|
||||
bool Removed = Set.remove_if([](int *Ptr) { return *Ptr % 2 != 0; });
|
||||
// We should only have element 2 left now.
|
||||
EXPECT_TRUE(Removed);
|
||||
EXPECT_EQ(Set.size(), 1u);
|
||||
EXPECT_TRUE(Set.contains(&Vals[2]));
|
||||
|
||||
// Switch to big regime.
|
||||
Set.insert(&Vals[0]);
|
||||
Set.insert(&Vals[1]);
|
||||
Set.insert(&Vals[3]);
|
||||
Set.insert(&Vals[4]);
|
||||
Set.insert(&Vals[5]);
|
||||
Set.erase(&Vals[0]); // Leave a tombstone.
|
||||
|
||||
// Remove odd elements.
|
||||
Removed = Set.remove_if([](int *Ptr) { return *Ptr % 2 != 0; });
|
||||
// We should only have elements 2 and 4 left now.
|
||||
EXPECT_TRUE(Removed);
|
||||
EXPECT_EQ(Set.size(), 2u);
|
||||
EXPECT_TRUE(Set.contains(&Vals[2]));
|
||||
EXPECT_TRUE(Set.contains(&Vals[4]));
|
||||
|
||||
Removed = Set.remove_if([](int *Ptr) { return false; });
|
||||
EXPECT_FALSE(Removed);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,26 @@
|
||||
|
||||
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"));
|
||||
@@ -61,3 +81,52 @@ TEST(xxhashTest, xxh3) {
|
||||
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