• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- llvm/unittest/Support/AnyTest.cpp - Any tests ---===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "llvm/ADT/Any.h"
11 #include "gtest/gtest.h"
12 #include <cstdlib>
13 
14 using namespace llvm;
15 
16 namespace {
17 
18 // Make sure we can construct, copy-construct, move-construct, and assign Any's.
TEST(AnyTest,ConstructionAndAssignment)19 TEST(AnyTest, ConstructionAndAssignment) {
20   llvm::Any A;
21   llvm::Any B{7};
22   llvm::Any C{8};
23   llvm::Any D{"hello"};
24   llvm::Any E{3.7};
25 
26   // An empty Any is not anything.
27   EXPECT_FALSE(A.hasValue());
28   EXPECT_FALSE(any_isa<int>(A));
29 
30   // An int is an int but not something else.
31   EXPECT_TRUE(B.hasValue());
32   EXPECT_TRUE(any_isa<int>(B));
33   EXPECT_FALSE(any_isa<float>(B));
34 
35   EXPECT_TRUE(C.hasValue());
36   EXPECT_TRUE(any_isa<int>(C));
37 
38   // A const char * is a const char * but not an int.
39   EXPECT_TRUE(D.hasValue());
40   EXPECT_TRUE(any_isa<const char *>(D));
41   EXPECT_FALSE(any_isa<int>(D));
42 
43   // A double is a double but not a float.
44   EXPECT_TRUE(E.hasValue());
45   EXPECT_TRUE(any_isa<double>(E));
46   EXPECT_FALSE(any_isa<float>(E));
47 
48   // After copy constructing from an int, the new item and old item are both
49   // ints.
50   llvm::Any F(B);
51   EXPECT_TRUE(B.hasValue());
52   EXPECT_TRUE(F.hasValue());
53   EXPECT_TRUE(any_isa<int>(F));
54   EXPECT_TRUE(any_isa<int>(B));
55 
56   // After move constructing from an int, the new item is an int and the old one
57   // isn't.
58   llvm::Any G(std::move(C));
59   EXPECT_FALSE(C.hasValue());
60   EXPECT_TRUE(G.hasValue());
61   EXPECT_TRUE(any_isa<int>(G));
62   EXPECT_FALSE(any_isa<int>(C));
63 
64   // After copy-assigning from an int, the new item and old item are both ints.
65   A = F;
66   EXPECT_TRUE(A.hasValue());
67   EXPECT_TRUE(F.hasValue());
68   EXPECT_TRUE(any_isa<int>(A));
69   EXPECT_TRUE(any_isa<int>(F));
70 
71   // After move-assigning from an int, the new item and old item are both ints.
72   B = std::move(G);
73   EXPECT_TRUE(B.hasValue());
74   EXPECT_FALSE(G.hasValue());
75   EXPECT_TRUE(any_isa<int>(B));
76   EXPECT_FALSE(any_isa<int>(G));
77 }
78 
TEST(AnyTest,GoodAnyCast)79 TEST(AnyTest, GoodAnyCast) {
80   llvm::Any A;
81   llvm::Any B{7};
82   llvm::Any C{8};
83   llvm::Any D{"hello"};
84   llvm::Any E{'x'};
85 
86   // Check each value twice to make sure it isn't damaged by the cast.
87   EXPECT_EQ(7, llvm::any_cast<int>(B));
88   EXPECT_EQ(7, llvm::any_cast<int>(B));
89 
90   EXPECT_STREQ("hello", llvm::any_cast<const char *>(D));
91   EXPECT_STREQ("hello", llvm::any_cast<const char *>(D));
92 
93   EXPECT_EQ('x', llvm::any_cast<char>(E));
94   EXPECT_EQ('x', llvm::any_cast<char>(E));
95 
96   llvm::Any F(B);
97   EXPECT_EQ(7, llvm::any_cast<int>(F));
98   EXPECT_EQ(7, llvm::any_cast<int>(F));
99 
100   llvm::Any G(std::move(C));
101   EXPECT_EQ(8, llvm::any_cast<int>(G));
102   EXPECT_EQ(8, llvm::any_cast<int>(G));
103 
104   A = F;
105   EXPECT_EQ(7, llvm::any_cast<int>(A));
106   EXPECT_EQ(7, llvm::any_cast<int>(A));
107 
108   E = std::move(G);
109   EXPECT_EQ(8, llvm::any_cast<int>(E));
110   EXPECT_EQ(8, llvm::any_cast<int>(E));
111 
112   // Make sure we can any_cast from an rvalue and that it's properly destroyed
113   // in the process.
114   EXPECT_EQ(8, llvm::any_cast<int>(std::move(E)));
115   EXPECT_TRUE(E.hasValue());
116 
117   // Make sure moving from pointers gives back pointers, and that we can modify
118   // the underlying value through those pointers.
119   EXPECT_EQ(7, *llvm::any_cast<int>(&A));
120   int *N = llvm::any_cast<int>(&A);
121   *N = 42;
122   EXPECT_EQ(42, llvm::any_cast<int>(A));
123 
124   // Make sure that we can any_cast to a reference and this is considered a good
125   // cast, resulting in an lvalue which can be modified.
126   llvm::any_cast<int &>(A) = 43;
127   EXPECT_EQ(43, llvm::any_cast<int>(A));
128 }
129 
TEST(AnyTest,CopiesAndMoves)130 TEST(AnyTest, CopiesAndMoves) {
131   struct TestType {
132     TestType() = default;
133     TestType(const TestType &Other)
134         : Copies(Other.Copies + 1), Moves(Other.Moves) {}
135     TestType(TestType &&Other) : Copies(Other.Copies), Moves(Other.Moves + 1) {}
136     int Copies = 0;
137     int Moves = 0;
138   };
139 
140   // One move to get TestType into the Any, and one move on the cast.
141   TestType T1 = llvm::any_cast<TestType>(Any{TestType()});
142   EXPECT_EQ(0, T1.Copies);
143   EXPECT_EQ(2, T1.Moves);
144 
145   // One move to get TestType into the Any, and one copy on the cast.
146   Any A{TestType()};
147   TestType T2 = llvm::any_cast<TestType>(A);
148   EXPECT_EQ(1, T2.Copies);
149   EXPECT_EQ(1, T2.Moves);
150 
151   // One move to get TestType into the Any, and one move on the cast.
152   TestType T3 = llvm::any_cast<TestType>(std::move(A));
153   EXPECT_EQ(0, T3.Copies);
154   EXPECT_EQ(2, T3.Moves);
155 }
156 
TEST(AnyTest,BadAnyCast)157 TEST(AnyTest, BadAnyCast) {
158   llvm::Any A;
159   llvm::Any B{7};
160   llvm::Any C{"hello"};
161   llvm::Any D{'x'};
162 
163 #if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST
164   EXPECT_DEATH(llvm::any_cast<int>(A), "");
165 
166   EXPECT_DEATH(llvm::any_cast<float>(B), "");
167   EXPECT_DEATH(llvm::any_cast<int *>(B), "");
168 
169   EXPECT_DEATH(llvm::any_cast<std::string>(C), "");
170 
171   EXPECT_DEATH(llvm::any_cast<unsigned char>(D), "");
172 #endif
173 }
174 
175 } // anonymous namespace
176