1 //===- STLForwardCompatTest.cpp - Unit tests for STLForwardCompat ---------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/ADT/STLForwardCompat.h"
10 #include "CountCopyAndMove.h"
11 #include "gtest/gtest.h"
12
13 namespace {
14
15 template <typename T>
16 class STLForwardCompatRemoveCVRefTest : public ::testing::Test {};
17
18 using STLForwardCompatRemoveCVRefTestTypes = ::testing::Types<
19 // clang-format off
20 std::pair<int, int>,
21 std::pair<int &, int>,
22 std::pair<const int, int>,
23 std::pair<volatile int, int>,
24 std::pair<const volatile int &, int>,
25 std::pair<int *, int *>,
26 std::pair<int *const, int *>,
27 std::pair<const int *, const int *>,
28 std::pair<int *&, int *>
29 // clang-format on
30 >;
31
32 TYPED_TEST_SUITE(STLForwardCompatRemoveCVRefTest,
33 STLForwardCompatRemoveCVRefTestTypes, );
34
TYPED_TEST(STLForwardCompatRemoveCVRefTest,RemoveCVRef)35 TYPED_TEST(STLForwardCompatRemoveCVRefTest, RemoveCVRef) {
36 using From = typename TypeParam::first_type;
37 using To = typename TypeParam::second_type;
38 EXPECT_TRUE(
39 (std::is_same<typename llvm::remove_cvref<From>::type, To>::value));
40 }
41
TYPED_TEST(STLForwardCompatRemoveCVRefTest,RemoveCVRefT)42 TYPED_TEST(STLForwardCompatRemoveCVRefTest, RemoveCVRefT) {
43 using From = typename TypeParam::first_type;
44 EXPECT_TRUE((std::is_same<typename llvm::remove_cvref<From>::type,
45 llvm::remove_cvref_t<From>>::value));
46 }
47
TEST(TransformTest,TransformStd)48 TEST(TransformTest, TransformStd) {
49 std::optional<int> A;
50
51 std::optional<int> B = llvm::transformOptional(A, [&](int N) { return N + 1; });
52 EXPECT_FALSE(B.has_value());
53
54 A = 3;
55 std::optional<int> C = llvm::transformOptional(A, [&](int N) { return N + 1; });
56 EXPECT_TRUE(C.has_value());
57 EXPECT_EQ(4, *C);
58 }
59
TEST(TransformTest,MoveTransformStd)60 TEST(TransformTest, MoveTransformStd) {
61 using llvm::CountCopyAndMove;
62
63 std::optional<CountCopyAndMove> A;
64
65 CountCopyAndMove::ResetCounts();
66 std::optional<int> B = llvm::transformOptional(
67 std::move(A), [&](const CountCopyAndMove &M) { return M.val + 2; });
68 EXPECT_FALSE(B.has_value());
69 EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
70 EXPECT_EQ(0, CountCopyAndMove::MoveConstructions);
71 EXPECT_EQ(0, CountCopyAndMove::MoveAssignments);
72 EXPECT_EQ(0, CountCopyAndMove::Destructions);
73
74 A = CountCopyAndMove(5);
75 CountCopyAndMove::ResetCounts();
76 std::optional<int> C = llvm::transformOptional(
77 std::move(A), [&](const CountCopyAndMove &M) { return M.val + 2; });
78 EXPECT_TRUE(C.has_value());
79 EXPECT_EQ(7, *C);
80 EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
81 EXPECT_EQ(0, CountCopyAndMove::MoveConstructions);
82 EXPECT_EQ(0, CountCopyAndMove::MoveAssignments);
83 EXPECT_EQ(0, CountCopyAndMove::Destructions);
84 }
85
TEST(TransformTest,TransformLlvm)86 TEST(TransformTest, TransformLlvm) {
87 std::optional<int> A;
88
89 std::optional<int> B =
90 llvm::transformOptional(A, [&](int N) { return N + 1; });
91 EXPECT_FALSE(B.has_value());
92
93 A = 3;
94 std::optional<int> C =
95 llvm::transformOptional(A, [&](int N) { return N + 1; });
96 EXPECT_TRUE(C.has_value());
97 EXPECT_EQ(4, *C);
98 }
99
TEST(TransformTest,MoveTransformLlvm)100 TEST(TransformTest, MoveTransformLlvm) {
101 using llvm::CountCopyAndMove;
102
103 std::optional<CountCopyAndMove> A;
104
105 CountCopyAndMove::ResetCounts();
106 std::optional<int> B = llvm::transformOptional(
107 std::move(A), [&](const CountCopyAndMove &M) { return M.val + 2; });
108 EXPECT_FALSE(B.has_value());
109 EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
110 EXPECT_EQ(0, CountCopyAndMove::MoveConstructions);
111 EXPECT_EQ(0, CountCopyAndMove::MoveAssignments);
112 EXPECT_EQ(0, CountCopyAndMove::Destructions);
113
114 A = CountCopyAndMove(5);
115 CountCopyAndMove::ResetCounts();
116 std::optional<int> C = llvm::transformOptional(
117 std::move(A), [&](const CountCopyAndMove &M) { return M.val + 2; });
118 EXPECT_TRUE(C.has_value());
119 EXPECT_EQ(7, *C);
120 EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
121 EXPECT_EQ(0, CountCopyAndMove::MoveConstructions);
122 EXPECT_EQ(0, CountCopyAndMove::MoveAssignments);
123 EXPECT_EQ(0, CountCopyAndMove::Destructions);
124 }
125
TEST(TransformTest,ToUnderlying)126 TEST(TransformTest, ToUnderlying) {
127 enum E { A1 = 0, B1 = -1 };
128 static_assert(llvm::to_underlying(A1) == 0);
129 static_assert(llvm::to_underlying(B1) == -1);
130
131 enum E2 : unsigned char { A2 = 0, B2 };
132 static_assert(
133 std::is_same_v<unsigned char, decltype(llvm::to_underlying(A2))>);
134 static_assert(llvm::to_underlying(A2) == 0);
135 static_assert(llvm::to_underlying(B2) == 1);
136
137 enum class E3 { A3 = -1, B3 };
138 static_assert(std::is_same_v<int, decltype(llvm::to_underlying(E3::A3))>);
139 static_assert(llvm::to_underlying(E3::A3) == -1);
140 static_assert(llvm::to_underlying(E3::B3) == 0);
141 }
142
143 } // namespace
144