1 //===- llvm/unittest/Support/AnyTest.cpp - Any tests ---===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/ADT/Any.h"
10 #include "gtest/gtest.h"
17 // Make sure we can construct, copy-construct, move-construct, and assign Any's.
18 TEST(AnyTest
, ConstructionAndAssignment
) {
25 // An empty Any is not anything.
26 EXPECT_FALSE(A
.has_value());
27 EXPECT_FALSE(llvm::any_cast
<int>(&A
));
29 // An int is an int but not something else.
30 EXPECT_TRUE(B
.has_value());
31 EXPECT_TRUE(llvm::any_cast
<int>(&B
));
32 EXPECT_FALSE(llvm::any_cast
<float>(&B
));
34 EXPECT_TRUE(C
.has_value());
35 EXPECT_TRUE(llvm::any_cast
<int>(&C
));
37 // A const char * is a const char * but not an int.
38 EXPECT_TRUE(D
.has_value());
39 EXPECT_TRUE(llvm::any_cast
<const char *>(&D
));
40 EXPECT_FALSE(llvm::any_cast
<int>(&D
));
42 // A double is a double but not a float.
43 EXPECT_TRUE(E
.has_value());
44 EXPECT_TRUE(llvm::any_cast
<double>(&E
));
45 EXPECT_FALSE(llvm::any_cast
<float>(&E
));
47 // After copy constructing from an int, the new item and old item are both
50 EXPECT_TRUE(B
.has_value());
51 EXPECT_TRUE(F
.has_value());
52 EXPECT_TRUE(llvm::any_cast
<int>(&F
));
53 EXPECT_TRUE(llvm::any_cast
<int>(&B
));
55 // After move constructing from an int, the new item is an int and the old one
57 llvm::Any
G(std::move(C
));
58 EXPECT_FALSE(C
.has_value());
59 EXPECT_TRUE(G
.has_value());
60 EXPECT_TRUE(llvm::any_cast
<int>(&G
));
61 EXPECT_FALSE(llvm::any_cast
<int>(&C
));
63 // After copy-assigning from an int, the new item and old item are both ints.
65 EXPECT_TRUE(A
.has_value());
66 EXPECT_TRUE(F
.has_value());
67 EXPECT_TRUE(llvm::any_cast
<int>(&A
));
68 EXPECT_TRUE(llvm::any_cast
<int>(&F
));
70 // After move-assigning from an int, the new item and old item are both ints.
72 EXPECT_TRUE(B
.has_value());
73 EXPECT_FALSE(G
.has_value());
74 EXPECT_TRUE(llvm::any_cast
<int>(&B
));
75 EXPECT_FALSE(llvm::any_cast
<int>(&G
));
78 TEST(AnyTest
, GoodAnyCast
) {
85 // Check each value twice to make sure it isn't damaged by the cast.
86 EXPECT_EQ(7, llvm::any_cast
<int>(B
));
87 EXPECT_EQ(7, llvm::any_cast
<int>(B
));
89 EXPECT_STREQ("hello", llvm::any_cast
<const char *>(D
));
90 EXPECT_STREQ("hello", llvm::any_cast
<const char *>(D
));
92 EXPECT_EQ('x', llvm::any_cast
<char>(E
));
93 EXPECT_EQ('x', llvm::any_cast
<char>(E
));
96 EXPECT_EQ(7, llvm::any_cast
<int>(F
));
97 EXPECT_EQ(7, llvm::any_cast
<int>(F
));
99 llvm::Any
G(std::move(C
));
100 EXPECT_EQ(8, llvm::any_cast
<int>(G
));
101 EXPECT_EQ(8, llvm::any_cast
<int>(G
));
104 EXPECT_EQ(7, llvm::any_cast
<int>(A
));
105 EXPECT_EQ(7, llvm::any_cast
<int>(A
));
108 EXPECT_EQ(8, llvm::any_cast
<int>(E
));
109 EXPECT_EQ(8, llvm::any_cast
<int>(E
));
111 // Make sure we can any_cast from an rvalue and that it's properly destroyed
113 EXPECT_EQ(8, llvm::any_cast
<int>(std::move(E
)));
114 EXPECT_TRUE(E
.has_value());
116 // Make sure moving from pointers gives back pointers, and that we can modify
117 // the underlying value through those pointers.
118 EXPECT_EQ(7, *llvm::any_cast
<int>(&A
));
119 int *N
= llvm::any_cast
<int>(&A
);
121 EXPECT_EQ(42, llvm::any_cast
<int>(A
));
123 // Make sure that we can any_cast to a reference and this is considered a good
124 // cast, resulting in an lvalue which can be modified.
125 llvm::any_cast
<int &>(A
) = 43;
126 EXPECT_EQ(43, llvm::any_cast
<int>(A
));
129 TEST(AnyTest
, CopiesAndMoves
) {
131 TestType() = default;
132 TestType(const TestType
&Other
)
133 : Copies(Other
.Copies
+ 1), Moves(Other
.Moves
) {}
134 TestType(TestType
&&Other
) : Copies(Other
.Copies
), Moves(Other
.Moves
+ 1) {}
139 // One move to get TestType into the Any, and one move on the cast.
140 TestType T1
= llvm::any_cast
<TestType
>(Any
{TestType()});
141 EXPECT_EQ(0, T1
.Copies
);
142 EXPECT_EQ(2, T1
.Moves
);
144 // One move to get TestType into the Any, and one copy on the cast.
146 TestType T2
= llvm::any_cast
<TestType
>(A
);
147 EXPECT_EQ(1, T2
.Copies
);
148 EXPECT_EQ(1, T2
.Moves
);
150 // One move to get TestType into the Any, and one move on the cast.
151 TestType T3
= llvm::any_cast
<TestType
>(std::move(A
));
152 EXPECT_EQ(0, T3
.Copies
);
153 EXPECT_EQ(2, T3
.Moves
);
156 TEST(AnyTest
, BadAnyCast
) {
159 llvm::Any C
{"hello"};
162 #if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST
163 EXPECT_DEATH(llvm::any_cast
<int>(A
), "");
165 EXPECT_DEATH(llvm::any_cast
<float>(B
), "");
166 EXPECT_DEATH(llvm::any_cast
<int *>(B
), "");
168 EXPECT_DEATH(llvm::any_cast
<std::string
>(C
), "");
170 EXPECT_DEATH(llvm::any_cast
<unsigned char>(D
), "");
174 } // anonymous namespace