xref: /llvm-project/llvm/unittests/ADT/STLForwardCompatTest.cpp (revision 68716573b627b86af50356edf63ba86856edd859)
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