[wpiutil] Upgrade to LLVM 16.0.6 (#5435)

Fixes #5332.
This commit is contained in:
Tyler Veness
2023-07-12 22:50:13 -07:00
committed by GitHub
parent 701df9eb87
commit 828bc5276f
77 changed files with 3798 additions and 1879 deletions

View File

@@ -26,6 +26,18 @@ TEST(ConvertUTFTest, ConvertUTF16LittleEndianToUTF8String) {
EXPECT_EQ(Expected, std::string{Result});
}
TEST(ConvertUTFTest, ConvertUTF32LittleEndianToUTF8String) {
// Src is the look of disapproval.
alignas(UTF32) static const char Src[] =
"\xFF\xFE\x00\x00\xA0\x0C\x00\x00\x5F\x00\x00\x00\xA0\x0C\x00\x00";
std::span<const char> Ref(Src, sizeof(Src) - 1);
std::string Result;
bool Success = convertUTF32ToUTF8String(Ref, Result);
EXPECT_TRUE(Success);
std::string Expected("\xE0\xB2\xA0_\xE0\xB2\xA0");
EXPECT_EQ(Expected, Result);
}
TEST(ConvertUTFTest, ConvertUTF16BigEndianToUTF8String) {
// Src is the look of disapproval.
alignas(UTF16) static const char Src[] = "\xfe\xff\x0c\xa0\x00_\x0c\xa0";
@@ -37,6 +49,18 @@ TEST(ConvertUTFTest, ConvertUTF16BigEndianToUTF8String) {
EXPECT_EQ(Expected, std::string{Result});
}
TEST(ConvertUTFTest, ConvertUTF32BigEndianToUTF8String) {
// Src is the look of disapproval.
alignas(UTF32) static const char Src[] =
"\x00\x00\xFE\xFF\x00\x00\x0C\xA0\x00\x00\x00\x5F\x00\x00\x0C\xA0";
std::span<const char> Ref(Src, sizeof(Src) - 1);
std::string Result;
bool Success = convertUTF32ToUTF8String(Ref, Result);
EXPECT_TRUE(Success);
std::string Expected("\xE0\xB2\xA0_\xE0\xB2\xA0");
EXPECT_EQ(Expected, Result);
}
TEST(ConvertUTFTest, ConvertUTF8ToUTF16String) {
// Src is the look of disapproval.
static const char Src[] = "\xe0\xb2\xa0_\xe0\xb2\xa0";
@@ -58,7 +82,8 @@ TEST(ConvertUTFTest, OddLengthInput) {
TEST(ConvertUTFTest, Empty) {
SmallString<20> Result;
bool Success = convertUTF16ToUTF8String(std::span<const char>(), Result);
bool Success =
convertUTF16ToUTF8String(std::span<const char>(), Result);
EXPECT_TRUE(Success);
EXPECT_TRUE(std::string{Result}.empty());
}

View File

@@ -11,9 +11,13 @@
#endif
#include "wpi/DenseMap.h"
#include "wpi/DenseMapInfo.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <map>
#include <set>
#include <utility>
#include <variant>
using namespace wpi;
@@ -446,6 +450,7 @@ TEST(DenseMapCustomTest, InitFromIterator) {
std::vector<std::pair<int, CountCopyAndMove>> Values;
// The size is a random value greater than 64 (hardcoded DenseMap min init)
const int Count = 65;
Values.reserve(Count);
for (int i = 0; i < Count; i++)
Values.emplace_back(i, CountCopyAndMove());
@@ -586,6 +591,15 @@ TEST(DenseMapCustomTest, LargeSmallDenseMapCompaction) {
EXPECT_TRUE(map.find(0) == map.end());
}
TEST(DenseMapCustomTest, SmallDenseMapWithNumBucketsNonPowerOf2) {
// Is not power of 2.
const unsigned NumInitBuckets = 33;
// Power of 2 less then NumInitBuckets.
constexpr unsigned InlineBuckets = 4;
// Constructor should not trigger assert.
SmallDenseMap<int, int, InlineBuckets> map(NumInitBuckets);
}
TEST(DenseMapCustomTest, TryEmplaceTest) {
DenseMap<int, std::unique_ptr<int>> Map;
std::unique_ptr<int> P(new int(2));
@@ -648,7 +662,7 @@ struct B : public A {
namespace wpi {
template <typename T>
struct DenseMapInfo<T, std::enable_if_t<std::is_base_of<A, T>::value>> {
struct DenseMapInfo<T, std::enable_if_t<std::is_base_of_v<A, T>>> {
static inline T getEmptyKey() { return {static_cast<int>(~0)}; }
static inline T getTombstoneKey() { return {static_cast<int>(~0U - 1)}; }
static unsigned getHashValue(const T &Val) { return Val.value; }
@@ -677,4 +691,18 @@ TEST(DenseMapCustomTest, SFINAEMapInfo) {
EXPECT_EQ(Map.find(Keys[1]), Map.end());
EXPECT_EQ(Map.find(Keys[2]), Map.end());
}
TEST(DenseMapCustomTest, VariantSupport) {
using variant = std::variant<int, int>;
DenseMap<variant, int> Map;
variant Keys[] = {
variant(std::in_place_index<0>, 1),
variant(std::in_place_index<1>, 1),
};
Map.try_emplace(Keys[0], 0);
Map.try_emplace(Keys[1], 1);
EXPECT_THAT(Map, testing::SizeIs(2));
EXPECT_NE(DenseMapInfo<variant>::getHashValue(Keys[0]),
DenseMapInfo<variant>::getHashValue(Keys[1]));
}
} // namespace

View File

@@ -175,6 +175,44 @@ TEST(MathExtras, reverseBits) {
EXPECT_EQ(0x5400000000000000ULL, reverseBits(NZ64));
}
TEST(MathExtras, isShiftedMask_32) {
EXPECT_FALSE(isShiftedMask_32(0x01010101));
EXPECT_TRUE(isShiftedMask_32(0xf0000000));
EXPECT_TRUE(isShiftedMask_32(0xffff0000));
EXPECT_TRUE(isShiftedMask_32(0xff << 1));
unsigned MaskIdx, MaskLen;
EXPECT_FALSE(isShiftedMask_32(0x01010101, MaskIdx, MaskLen));
EXPECT_TRUE(isShiftedMask_32(0xf0000000, MaskIdx, MaskLen));
EXPECT_EQ(28, (int)MaskIdx);
EXPECT_EQ(4, (int)MaskLen);
EXPECT_TRUE(isShiftedMask_32(0xffff0000, MaskIdx, MaskLen));
EXPECT_EQ(16, (int)MaskIdx);
EXPECT_EQ(16, (int)MaskLen);
EXPECT_TRUE(isShiftedMask_32(0xff << 1, MaskIdx, MaskLen));
EXPECT_EQ(1, (int)MaskIdx);
EXPECT_EQ(8, (int)MaskLen);
}
TEST(MathExtras, isShiftedMask_64) {
EXPECT_FALSE(isShiftedMask_64(0x0101010101010101ull));
EXPECT_TRUE(isShiftedMask_64(0xf000000000000000ull));
EXPECT_TRUE(isShiftedMask_64(0xffff000000000000ull));
EXPECT_TRUE(isShiftedMask_64(0xffull << 55));
unsigned MaskIdx, MaskLen;
EXPECT_FALSE(isShiftedMask_64(0x0101010101010101ull, MaskIdx, MaskLen));
EXPECT_TRUE(isShiftedMask_64(0xf000000000000000ull, MaskIdx, MaskLen));
EXPECT_EQ(60, (int)MaskIdx);
EXPECT_EQ(4, (int)MaskLen);
EXPECT_TRUE(isShiftedMask_64(0xffff000000000000ull, MaskIdx, MaskLen));
EXPECT_EQ(48, (int)MaskIdx);
EXPECT_EQ(16, (int)MaskLen);
EXPECT_TRUE(isShiftedMask_64(0xffull << 55, MaskIdx, MaskLen));
EXPECT_EQ(55, (int)MaskIdx);
EXPECT_EQ(8, (int)MaskLen);
}
TEST(MathExtras, isPowerOf2_32) {
EXPECT_FALSE(isPowerOf2_32(0));
EXPECT_TRUE(isPowerOf2_32(1 << 6));
@@ -271,9 +309,7 @@ TEST(MathExtras, alignTo) {
EXPECT_EQ(552u, alignTo(321, 255, 42));
}
template<typename T>
void SaturatingAddTestHelper()
{
template <typename T> void SaturatingAddTestHelper() {
const T Max = std::numeric_limits<T>::max();
bool ResultOverflowed;
@@ -296,6 +332,42 @@ void SaturatingAddTestHelper()
EXPECT_EQ(Max, SaturatingAdd(Max, Max));
EXPECT_EQ(Max, SaturatingAdd(Max, Max, &ResultOverflowed));
EXPECT_TRUE(ResultOverflowed);
EXPECT_EQ(T(6), SaturatingAdd(T(1), T(2), T(3)));
EXPECT_EQ(T(6), SaturatingAdd(T(1), T(2), T(3), &ResultOverflowed));
EXPECT_FALSE(ResultOverflowed);
EXPECT_EQ(T(10), SaturatingAdd(T(1), T(2), T(3), T(4)));
EXPECT_EQ(T(10), SaturatingAdd(T(1), T(2), T(3), T(4), &ResultOverflowed));
EXPECT_FALSE(ResultOverflowed);
EXPECT_EQ(Max, SaturatingAdd(Max, T(0), T(0)));
EXPECT_EQ(Max, SaturatingAdd(Max, T(0), T(0), &ResultOverflowed));
EXPECT_FALSE(ResultOverflowed);
EXPECT_EQ(Max, SaturatingAdd(T(0), T(0), Max));
EXPECT_EQ(Max, SaturatingAdd(T(0), T(0), Max, &ResultOverflowed));
EXPECT_FALSE(ResultOverflowed);
EXPECT_EQ(Max, SaturatingAdd(Max, T(0), T(1)));
EXPECT_EQ(Max, SaturatingAdd(Max, T(0), T(1), &ResultOverflowed));
EXPECT_TRUE(ResultOverflowed);
EXPECT_EQ(Max, SaturatingAdd(T(0), T(1), Max));
EXPECT_EQ(Max, SaturatingAdd(T(0), T(1), Max, &ResultOverflowed));
EXPECT_TRUE(ResultOverflowed);
EXPECT_EQ(Max, SaturatingAdd(T(1), T(Max - 2), T(1)));
EXPECT_EQ(Max, SaturatingAdd(T(1), T(Max - 2), T(1), &ResultOverflowed));
EXPECT_FALSE(ResultOverflowed);
EXPECT_EQ(Max, SaturatingAdd(T(1), T(1), T(Max - 2)));
EXPECT_EQ(Max, SaturatingAdd(T(1), T(1), T(Max - 2), &ResultOverflowed));
EXPECT_FALSE(ResultOverflowed);
EXPECT_EQ(Max, SaturatingAdd(Max, Max, Max));
EXPECT_EQ(Max, SaturatingAdd(Max, Max, Max, &ResultOverflowed));
EXPECT_TRUE(ResultOverflowed);
}
TEST(MathExtras, SaturatingAdd) {

View File

@@ -0,0 +1,15 @@
//===- 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;

View File

@@ -0,0 +1,42 @@
//===- 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

View File

@@ -62,7 +62,11 @@ TEST(PointerIntPairTest, GetSet) {
EXPECT_EQ(&s, Pair2.getPointer());
EXPECT_EQ(E::Case3, Pair2.getInt());
static_assert(std::is_trivially_copyable<PointerIntPair<S *, 2, E>>::value,
auto [Pointer2, Int2] = Pair2;
EXPECT_EQ(Pair2.getPointer(), Pointer2);
EXPECT_EQ(Pair2.getInt(), Int2);
static_assert(std::is_trivially_copyable_v<PointerIntPair<S *, 2, E>>,
"trivially copyable");
}
@@ -100,10 +104,9 @@ TEST(PointerIntPairTest, ManyUnusedBits) {
EXPECT_EQ(FixnumPointerTraits::NumLowBitsAvailable - 1,
(int)PointerLikeTypeTraits<decltype(pair)>::NumLowBitsAvailable);
static_assert(
std::is_trivially_copyable<
PointerIntPair<Fixnum31, 1, bool, FixnumPointerTraits>>::value,
"trivially copyable");
static_assert(std::is_trivially_copyable_v<
PointerIntPair<Fixnum31, 1, bool, FixnumPointerTraits>>,
"trivially copyable");
}
} // end anonymous namespace

View File

@@ -156,4 +156,137 @@ TEST_F(PointerUnionTest, GetAddrOfPtr1) {
EXPECT_TRUE((void *)n.getAddrOfPtr1() == (void *)&n);
}
TEST_F(PointerUnionTest, NewCastInfra) {
// test isa<>
EXPECT_TRUE(isa<float *>(a));
EXPECT_TRUE(isa<int *>(b));
EXPECT_TRUE(isa<int *>(c));
EXPECT_TRUE(isa<int *>(n));
EXPECT_TRUE(isa<int *>(i3));
EXPECT_TRUE(isa<float *>(f3));
EXPECT_TRUE(isa<long long *>(l3));
EXPECT_TRUE(isa<int *>(i4));
EXPECT_TRUE(isa<float *>(f4));
EXPECT_TRUE(isa<long long *>(l4));
EXPECT_TRUE(isa<double *>(d4));
EXPECT_TRUE(isa<int *>(i4null));
EXPECT_TRUE(isa<float *>(f4null));
EXPECT_TRUE(isa<long long *>(l4null));
EXPECT_TRUE(isa<double *>(d4null));
EXPECT_FALSE(isa<int *>(a));
EXPECT_FALSE(isa<float *>(b));
EXPECT_FALSE(isa<float *>(c));
EXPECT_FALSE(isa<float *>(n));
EXPECT_FALSE(isa<float *>(i3));
EXPECT_FALSE(isa<long long *>(i3));
EXPECT_FALSE(isa<int *>(f3));
EXPECT_FALSE(isa<long long *>(f3));
EXPECT_FALSE(isa<int *>(l3));
EXPECT_FALSE(isa<float *>(l3));
EXPECT_FALSE(isa<float *>(i4));
EXPECT_FALSE(isa<long long *>(i4));
EXPECT_FALSE(isa<double *>(i4));
EXPECT_FALSE(isa<int *>(f4));
EXPECT_FALSE(isa<long long *>(f4));
EXPECT_FALSE(isa<double *>(f4));
EXPECT_FALSE(isa<int *>(l4));
EXPECT_FALSE(isa<float *>(l4));
EXPECT_FALSE(isa<double *>(l4));
EXPECT_FALSE(isa<int *>(d4));
EXPECT_FALSE(isa<float *>(d4));
EXPECT_FALSE(isa<long long *>(d4));
EXPECT_FALSE(isa<float *>(i4null));
EXPECT_FALSE(isa<long long *>(i4null));
EXPECT_FALSE(isa<double *>(i4null));
EXPECT_FALSE(isa<int *>(f4null));
EXPECT_FALSE(isa<long long *>(f4null));
EXPECT_FALSE(isa<double *>(f4null));
EXPECT_FALSE(isa<int *>(l4null));
EXPECT_FALSE(isa<float *>(l4null));
EXPECT_FALSE(isa<double *>(l4null));
EXPECT_FALSE(isa<int *>(d4null));
EXPECT_FALSE(isa<float *>(d4null));
EXPECT_FALSE(isa<long long *>(d4null));
// test cast<>
EXPECT_EQ(cast<float *>(a), &f);
EXPECT_EQ(cast<int *>(b), &i);
EXPECT_EQ(cast<int *>(c), &i);
EXPECT_EQ(cast<int *>(i3), &i);
EXPECT_EQ(cast<float *>(f3), &f);
EXPECT_EQ(cast<long long *>(l3), &l);
EXPECT_EQ(cast<int *>(i4), &i);
EXPECT_EQ(cast<float *>(f4), &f);
EXPECT_EQ(cast<long long *>(l4), &l);
EXPECT_EQ(cast<double *>(d4), &d);
// test dyn_cast
EXPECT_EQ(dyn_cast<int *>(a), nullptr);
EXPECT_EQ(dyn_cast<float *>(a), &f);
EXPECT_EQ(dyn_cast<int *>(b), &i);
EXPECT_EQ(dyn_cast<float *>(b), nullptr);
EXPECT_EQ(dyn_cast<int *>(c), &i);
EXPECT_EQ(dyn_cast<float *>(c), nullptr);
EXPECT_EQ(dyn_cast_if_present<int *>(n), nullptr);
EXPECT_EQ(dyn_cast_if_present<float *>(n), nullptr);
EXPECT_EQ(dyn_cast<int *>(i3), &i);
EXPECT_EQ(dyn_cast<float *>(i3), nullptr);
EXPECT_EQ(dyn_cast<long long *>(i3), nullptr);
EXPECT_EQ(dyn_cast<int *>(f3), nullptr);
EXPECT_EQ(dyn_cast<float *>(f3), &f);
EXPECT_EQ(dyn_cast<long long *>(f3), nullptr);
EXPECT_EQ(dyn_cast<int *>(l3), nullptr);
EXPECT_EQ(dyn_cast<float *>(l3), nullptr);
EXPECT_EQ(dyn_cast<long long *>(l3), &l);
EXPECT_EQ(dyn_cast<int *>(i4), &i);
EXPECT_EQ(dyn_cast<float *>(i4), nullptr);
EXPECT_EQ(dyn_cast<long long *>(i4), nullptr);
EXPECT_EQ(dyn_cast<double *>(i4), nullptr);
EXPECT_EQ(dyn_cast<int *>(f4), nullptr);
EXPECT_EQ(dyn_cast<float *>(f4), &f);
EXPECT_EQ(dyn_cast<long long *>(f4), nullptr);
EXPECT_EQ(dyn_cast<double *>(f4), nullptr);
EXPECT_EQ(dyn_cast<int *>(l4), nullptr);
EXPECT_EQ(dyn_cast<float *>(l4), nullptr);
EXPECT_EQ(dyn_cast<long long *>(l4), &l);
EXPECT_EQ(dyn_cast<double *>(l4), nullptr);
EXPECT_EQ(dyn_cast<int *>(d4), nullptr);
EXPECT_EQ(dyn_cast<float *>(d4), nullptr);
EXPECT_EQ(dyn_cast<long long *>(d4), nullptr);
EXPECT_EQ(dyn_cast<double *>(d4), &d);
EXPECT_EQ(dyn_cast_if_present<int *>(i4null), nullptr);
EXPECT_EQ(dyn_cast_if_present<float *>(i4null), nullptr);
EXPECT_EQ(dyn_cast_if_present<long long *>(i4null), nullptr);
EXPECT_EQ(dyn_cast_if_present<double *>(i4null), nullptr);
EXPECT_EQ(dyn_cast_if_present<int *>(f4null), nullptr);
EXPECT_EQ(dyn_cast_if_present<float *>(f4null), nullptr);
EXPECT_EQ(dyn_cast_if_present<long long *>(f4null), nullptr);
EXPECT_EQ(dyn_cast_if_present<double *>(f4null), nullptr);
EXPECT_EQ(dyn_cast_if_present<int *>(l4null), nullptr);
EXPECT_EQ(dyn_cast_if_present<float *>(l4null), nullptr);
EXPECT_EQ(dyn_cast_if_present<long long *>(l4null), nullptr);
EXPECT_EQ(dyn_cast_if_present<double *>(l4null), nullptr);
EXPECT_EQ(dyn_cast_if_present<int *>(d4null), nullptr);
EXPECT_EQ(dyn_cast_if_present<float *>(d4null), nullptr);
EXPECT_EQ(dyn_cast_if_present<long long *>(d4null), nullptr);
EXPECT_EQ(dyn_cast_if_present<double *>(d4null), nullptr);
// test for const
const PU4 constd4(&d);
EXPECT_TRUE(isa<double *>(constd4));
EXPECT_FALSE(isa<int *>(constd4));
EXPECT_EQ(cast<double *>(constd4), &d);
EXPECT_EQ(dyn_cast<long long *>(constd4), nullptr);
auto *result1 = cast<double *>(constd4);
static_assert(std::is_same_v<double *, decltype(result1)>,
"type mismatch for cast with PointerUnion");
PointerUnion<int *, const double *> constd2(&d);
auto *result2 = cast<const double *>(constd2);
EXPECT_EQ(result2, &d);
static_assert(std::is_same_v<const double *, decltype(result2)>,
"type mismatch for cast with PointerUnion");
}
} // end anonymous namespace

View File

@@ -7,41 +7,11 @@
//===----------------------------------------------------------------------===//
#include "wpi/STLForwardCompat.h"
#include "MoveOnly.h"
#include "gtest/gtest.h"
namespace {
TEST(STLForwardCompatTest, NegationTest) {
EXPECT_TRUE((wpi::negation<std::false_type>::value));
EXPECT_FALSE((wpi::negation<std::true_type>::value));
}
struct incomplete_type;
TEST(STLForwardCompatTest, ConjunctionTest) {
EXPECT_TRUE((wpi::conjunction<>::value));
EXPECT_FALSE((wpi::conjunction<std::false_type>::value));
EXPECT_TRUE((wpi::conjunction<std::true_type>::value));
EXPECT_FALSE((wpi::conjunction<std::false_type, incomplete_type>::value));
EXPECT_FALSE((wpi::conjunction<std::false_type, std::true_type>::value));
EXPECT_FALSE((wpi::conjunction<std::true_type, std::false_type>::value));
EXPECT_TRUE((wpi::conjunction<std::true_type, std::true_type>::value));
EXPECT_TRUE((wpi::conjunction<std::true_type, std::true_type,
std::true_type>::value));
}
TEST(STLForwardCompatTest, DisjunctionTest) {
EXPECT_FALSE((wpi::disjunction<>::value));
EXPECT_FALSE((wpi::disjunction<std::false_type>::value));
EXPECT_TRUE((wpi::disjunction<std::true_type>::value));
EXPECT_TRUE((wpi::disjunction<std::true_type, incomplete_type>::value));
EXPECT_TRUE((wpi::disjunction<std::false_type, std::true_type>::value));
EXPECT_TRUE((wpi::disjunction<std::true_type, std::false_type>::value));
EXPECT_TRUE((wpi::disjunction<std::true_type, std::true_type>::value));
EXPECT_TRUE((wpi::disjunction<std::true_type, std::true_type,
std::true_type>::value));
}
template <typename T>
class STLForwardCompatRemoveCVRefTest : public ::testing::Test {};
@@ -75,4 +45,78 @@ TYPED_TEST(STLForwardCompatRemoveCVRefTest, RemoveCVRefT) {
wpi::remove_cvref_t<From>>::value));
}
TEST(TransformTest, TransformStd) {
std::optional<int> A;
std::optional<int> B = wpi::transformOptional(A, [&](int N) { return N + 1; });
EXPECT_FALSE(B.has_value());
A = 3;
std::optional<int> C = wpi::transformOptional(A, [&](int N) { return N + 1; });
EXPECT_TRUE(C.has_value());
EXPECT_EQ(4, *C);
}
TEST(TransformTest, MoveTransformStd) {
using wpi::MoveOnly;
std::optional<MoveOnly> A;
MoveOnly::ResetCounts();
std::optional<int> B = wpi::transformOptional(
std::move(A), [&](const MoveOnly &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);
A = MoveOnly(5);
MoveOnly::ResetCounts();
std::optional<int> C = wpi::transformOptional(
std::move(A), [&](const MoveOnly &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);
}
TEST(TransformTest, TransformLlvm) {
std::optional<int> A;
std::optional<int> B =
wpi::transformOptional(A, [&](int N) { return N + 1; });
EXPECT_FALSE(B.has_value());
A = 3;
std::optional<int> C =
wpi::transformOptional(A, [&](int N) { return N + 1; });
EXPECT_TRUE(C.has_value());
EXPECT_EQ(4, *C);
}
TEST(TransformTest, MoveTransformLlvm) {
using wpi::MoveOnly;
std::optional<MoveOnly> A;
MoveOnly::ResetCounts();
std::optional<int> B = wpi::transformOptional(
std::move(A), [&](const MoveOnly &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);
A = MoveOnly(5);
MoveOnly::ResetCounts();
std::optional<int> C = wpi::transformOptional(
std::move(A), [&](const MoveOnly &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);
}
} // namespace

View File

@@ -12,6 +12,7 @@
#include "wpi/SmallSet.h"
#include "gtest/gtest.h"
#include <algorithm>
#include <string>
using namespace wpi;
@@ -20,11 +21,17 @@ TEST(SmallSetTest, Insert) {
SmallSet<int, 4> s1;
for (int i = 0; i < 4; i++)
s1.insert(i);
for (int i = 0; i < 4; i++) {
auto InsertResult = s1.insert(i);
EXPECT_EQ(*InsertResult.first, i);
EXPECT_EQ(InsertResult.second, true);
}
for (int i = 0; i < 4; i++)
s1.insert(i);
for (int i = 0; i < 4; i++) {
auto InsertResult = s1.insert(i);
EXPECT_EQ(*InsertResult.first, i);
EXPECT_EQ(InsertResult.second, false);
}
EXPECT_EQ(4u, s1.size());
@@ -37,8 +44,17 @@ TEST(SmallSetTest, Insert) {
TEST(SmallSetTest, Grow) {
SmallSet<int, 4> s1;
for (int i = 0; i < 8; i++)
s1.insert(i);
for (int i = 0; i < 8; i++) {
auto InsertResult = s1.insert(i);
EXPECT_EQ(*InsertResult.first, i);
EXPECT_EQ(InsertResult.second, true);
}
for (int i = 0; i < 8; i++) {
auto InsertResult = s1.insert(i);
EXPECT_EQ(*InsertResult.first, i);
EXPECT_EQ(InsertResult.second, false);
}
EXPECT_EQ(8u, s1.size());

File diff suppressed because it is too large Load Diff

View File

@@ -15,6 +15,10 @@ using namespace wpi;
namespace {
static_assert(sizeof(StringMap<uint32_t>) <
sizeof(StringMap<uint32_t, MallocAllocator &>),
"Ensure empty base optimization happens with default allocator");
// Test fixture
class StringMapTest : public testing::Test {
protected:
@@ -22,7 +26,7 @@ protected:
static const char testKey[];
static const uint32_t testValue;
static const char* testKeyFirst;
static const char *testKeyFirst;
static size_t testKeyLength;
static const std::string testKeyStr;
@@ -39,7 +43,7 @@ protected:
EXPECT_EQ(0u, testMap.count(std::string_view(testKeyFirst, testKeyLength)));
EXPECT_EQ(0u, testMap.count(testKeyStr));
EXPECT_TRUE(testMap.find(testKey) == testMap.end());
EXPECT_TRUE(testMap.find(std::string_view(testKeyFirst, testKeyLength)) ==
EXPECT_TRUE(testMap.find(std::string_view(testKeyFirst, testKeyLength)) ==
testMap.end());
EXPECT_TRUE(testMap.find(testKeyStr) == testMap.end());
}
@@ -62,7 +66,7 @@ protected:
EXPECT_EQ(1u, testMap.count(std::string_view(testKeyFirst, testKeyLength)));
EXPECT_EQ(1u, testMap.count(testKeyStr));
EXPECT_TRUE(testMap.find(testKey) == testMap.begin());
EXPECT_TRUE(testMap.find(std::string_view(testKeyFirst, testKeyLength)) ==
EXPECT_TRUE(testMap.find(std::string_view(testKeyFirst, testKeyLength)) ==
testMap.begin());
EXPECT_TRUE(testMap.find(testKeyStr) == testMap.begin());
}
@@ -70,7 +74,7 @@ protected:
const char StringMapTest::testKey[] = "key";
const uint32_t StringMapTest::testValue = 1u;
const char* StringMapTest::testKeyFirst = testKey;
const char *StringMapTest::testKeyFirst = testKey;
size_t StringMapTest::testKeyLength = sizeof(testKey) - 1;
const std::string StringMapTest::testKeyStr(testKey);
@@ -85,13 +89,11 @@ struct CountCopyAndMove {
};
// Empty map tests.
TEST_F(StringMapTest, EmptyMapTest) {
assertEmptyMap();
}
TEST_F(StringMapTest, EmptyMapTest) { assertEmptyMap(); }
// Constant map tests.
TEST_F(StringMapTest, ConstEmptyMapTest) {
const StringMap<uint32_t>& constTestMap = testMap;
const StringMap<uint32_t> &constTestMap = testMap;
// Size tests
EXPECT_EQ(0u, constTestMap.size());
@@ -214,8 +216,8 @@ TEST_F(StringMapTest, IterationTest) {
}
// Iterate over all numbers and mark each one found.
for (StringMap<uint32_t>::iterator it = testMap.begin();
it != testMap.end(); ++it) {
for (StringMap<uint32_t>::iterator it = testMap.begin(); it != testMap.end();
++it) {
std::stringstream ss;
ss << "key_" << it->second;
ASSERT_STREQ(ss.str().c_str(), it->first().data());
@@ -232,7 +234,7 @@ TEST_F(StringMapTest, IterationTest) {
TEST_F(StringMapTest, StringMapEntryTest) {
MallocAllocator Allocator;
StringMap<uint32_t>::value_type *entry =
StringMap<uint32_t>::value_type::Create(
StringMap<uint32_t>::value_type::create(
std::string_view(testKeyFirst, testKeyLength), Allocator, 1u);
EXPECT_STREQ(testKey, entry->first().data());
EXPECT_EQ(1u, entry->second);
@@ -242,10 +244,8 @@ TEST_F(StringMapTest, StringMapEntryTest) {
// Test insert() method.
TEST_F(StringMapTest, InsertTest) {
SCOPED_TRACE("InsertTest");
testMap.insert(
StringMap<uint32_t>::value_type::Create(
std::string_view(testKeyFirst, testKeyLength),
testMap.getAllocator(), 1u));
testMap.insert(StringMap<uint32_t>::value_type::create(
std::string_view(testKeyFirst, testKeyLength), testMap.getAllocator(), 1u));
assertSingleItemMap();
}
@@ -280,7 +280,7 @@ TEST_F(StringMapTest, InsertRehashingPairTest) {
EXPECT_EQ(0u, t.getNumBuckets());
StringMap<uint32_t>::iterator It =
t.insert(std::make_pair("abcdef", 42)).first;
t.insert(std::make_pair("abcdef", 42)).first;
EXPECT_EQ(16u, t.getNumBuckets());
EXPECT_EQ("abcdef", It->first());
EXPECT_EQ(42u, It->second);
@@ -338,13 +338,13 @@ TEST_F(StringMapTest, NonDefaultConstructable) {
struct Immovable {
Immovable() {}
Immovable(Immovable&&) = delete; // will disable the other special members
Immovable(Immovable &&) = delete; // will disable the other special members
};
struct MoveOnly {
int i;
MoveOnly(int i) : i(i) {}
MoveOnly(const Immovable&) : i(0) {}
MoveOnly(const Immovable &) : i(0) {}
MoveOnly(MoveOnly &&RHS) : i(RHS.i) {}
MoveOnly &operator=(MoveOnly &&RHS) {
i = RHS.i;
@@ -360,14 +360,14 @@ TEST_F(StringMapTest, MoveOnly) {
StringMap<MoveOnly> t;
t.insert(std::make_pair("Test", MoveOnly(42)));
std::string_view Key = "Test";
StringMapEntry<MoveOnly>::Create(Key, t.getAllocator(), MoveOnly(42))
StringMapEntry<MoveOnly>::create(Key, t.getAllocator(), MoveOnly(42))
->Destroy(t.getAllocator());
}
TEST_F(StringMapTest, CtorArg) {
std::string_view Key = "Test";
MallocAllocator Allocator;
StringMapEntry<MoveOnly>::Create(Key, Allocator, Immovable())
StringMapEntry<MoveOnly>::create(Key, Allocator, Immovable())
->Destroy(Allocator);
}
@@ -501,6 +501,16 @@ TEST_F(StringMapTest, MoveDtor) {
ASSERT_TRUE(B.empty());
}
TEST_F(StringMapTest, StructuredBindings) {
StringMap<int> A;
A["a"] = 42;
for (auto &[Key, Value] : A) {
EXPECT_EQ("a", Key);
EXPECT_EQ(42, Value);
}
}
namespace {
// Simple class that counts how many moves and copy happens when growing a map
struct CountCtorCopyAndMove {
@@ -570,7 +580,7 @@ struct NonMoveableNonCopyableType {
NonMoveableNonCopyableType(const NonMoveableNonCopyableType &) = delete;
NonMoveableNonCopyableType(NonMoveableNonCopyableType &&) = delete;
};
}
} // namespace
// Test that we can "emplace" an element in the map without involving map/move
TEST(StringMapCustomTest, EmplaceTest) {