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 "MoveOnly.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 | |
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 | |
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 | |
48 | TEST(TransformTest, TransformStd) { |
49 | std::optional<int> A; |
50 | |
51 | std::optional<int> B = llvm::transformOptional(O: A, F: [&](int N) { return N + 1; }); |
52 | EXPECT_FALSE(B.has_value()); |
53 | |
54 | A = 3; |
55 | std::optional<int> C = llvm::transformOptional(O: A, F: [&](int N) { return N + 1; }); |
56 | EXPECT_TRUE(C.has_value()); |
57 | EXPECT_EQ(4, *C); |
58 | } |
59 | |
60 | TEST(TransformTest, MoveTransformStd) { |
61 | using llvm::MoveOnly; |
62 | |
63 | std::optional<MoveOnly> A; |
64 | |
65 | MoveOnly::ResetCounts(); |
66 | std::optional<int> B = llvm::transformOptional( |
67 | O: std::move(A), F: [&](const MoveOnly &M) { return M.val + 2; }); |
68 | EXPECT_FALSE(B.has_value()); |
69 | EXPECT_EQ(0u, MoveOnly::MoveConstructions); |
70 | EXPECT_EQ(0u, MoveOnly::MoveAssignments); |
71 | EXPECT_EQ(0u, MoveOnly::Destructions); |
72 | |
73 | A = MoveOnly(5); |
74 | MoveOnly::ResetCounts(); |
75 | std::optional<int> C = llvm::transformOptional( |
76 | O: std::move(A), F: [&](const MoveOnly &M) { return M.val + 2; }); |
77 | EXPECT_TRUE(C.has_value()); |
78 | EXPECT_EQ(7, *C); |
79 | EXPECT_EQ(0u, MoveOnly::MoveConstructions); |
80 | EXPECT_EQ(0u, MoveOnly::MoveAssignments); |
81 | EXPECT_EQ(0u, MoveOnly::Destructions); |
82 | } |
83 | |
84 | TEST(TransformTest, TransformLlvm) { |
85 | std::optional<int> A; |
86 | |
87 | std::optional<int> B = |
88 | llvm::transformOptional(O: A, F: [&](int N) { return N + 1; }); |
89 | EXPECT_FALSE(B.has_value()); |
90 | |
91 | A = 3; |
92 | std::optional<int> C = |
93 | llvm::transformOptional(O: A, F: [&](int N) { return N + 1; }); |
94 | EXPECT_TRUE(C.has_value()); |
95 | EXPECT_EQ(4, *C); |
96 | } |
97 | |
98 | TEST(TransformTest, MoveTransformLlvm) { |
99 | using llvm::MoveOnly; |
100 | |
101 | std::optional<MoveOnly> A; |
102 | |
103 | MoveOnly::ResetCounts(); |
104 | std::optional<int> B = llvm::transformOptional( |
105 | O: std::move(A), F: [&](const MoveOnly &M) { return M.val + 2; }); |
106 | EXPECT_FALSE(B.has_value()); |
107 | EXPECT_EQ(0u, MoveOnly::MoveConstructions); |
108 | EXPECT_EQ(0u, MoveOnly::MoveAssignments); |
109 | EXPECT_EQ(0u, MoveOnly::Destructions); |
110 | |
111 | A = MoveOnly(5); |
112 | MoveOnly::ResetCounts(); |
113 | std::optional<int> C = llvm::transformOptional( |
114 | O: std::move(A), F: [&](const MoveOnly &M) { return M.val + 2; }); |
115 | EXPECT_TRUE(C.has_value()); |
116 | EXPECT_EQ(7, *C); |
117 | EXPECT_EQ(0u, MoveOnly::MoveConstructions); |
118 | EXPECT_EQ(0u, MoveOnly::MoveAssignments); |
119 | EXPECT_EQ(0u, MoveOnly::Destructions); |
120 | } |
121 | |
122 | TEST(TransformTest, ToUnderlying) { |
123 | enum E { A1 = 0, B1 = -1 }; |
124 | static_assert(llvm::to_underlying(E: A1) == 0); |
125 | static_assert(llvm::to_underlying(E: B1) == -1); |
126 | |
127 | enum E2 : unsigned char { A2 = 0, B2 }; |
128 | static_assert( |
129 | std::is_same_v<unsigned char, decltype(llvm::to_underlying(E: A2))>); |
130 | static_assert(llvm::to_underlying(E: A2) == 0); |
131 | static_assert(llvm::to_underlying(E: B2) == 1); |
132 | |
133 | enum class E3 { A3 = -1, B3 }; |
134 | static_assert(std::is_same_v<int, decltype(llvm::to_underlying(E: E3::A3))>); |
135 | static_assert(llvm::to_underlying(E: E3::A3) == -1); |
136 | static_assert(llvm::to_underlying(E: E3::B3) == 0); |
137 | } |
138 | |
139 | } // namespace |
140 | |