Test the polymorphic behavior of this utility.
[oota-llvm.git] / unittests / ADT / OptionalTest.cpp
1 //===- llvm/unittest/ADT/OptionalTest.cpp - Optional unit 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 "gtest/gtest.h"
11 #include "llvm/ADT/Optional.h"
12 using namespace llvm;
13
14 namespace {
15
16 struct NonDefaultConstructible {
17   static unsigned CopyConstructions;
18   static unsigned Destructions;
19   static unsigned CopyAssignments;
20   explicit NonDefaultConstructible(int) {
21   }
22   NonDefaultConstructible(const NonDefaultConstructible&) {
23     ++CopyConstructions;
24   }
25   NonDefaultConstructible &operator=(const NonDefaultConstructible&) {
26     ++CopyAssignments;
27     return *this;
28   }
29   ~NonDefaultConstructible() {
30     ++Destructions;
31   }
32   static void ResetCounts() {
33     CopyConstructions = 0;
34     Destructions = 0;
35     CopyAssignments = 0;
36   }
37 };
38
39 unsigned NonDefaultConstructible::CopyConstructions = 0;
40 unsigned NonDefaultConstructible::Destructions = 0;
41 unsigned NonDefaultConstructible::CopyAssignments = 0;
42
43 // Test fixture
44 class OptionalTest : public testing::Test {
45 };
46
47 TEST_F(OptionalTest, NonDefaultConstructibleTest) {
48   Optional<NonDefaultConstructible> O;
49   EXPECT_FALSE(O);
50 }
51
52 TEST_F(OptionalTest, ResetTest) {
53   NonDefaultConstructible::ResetCounts();
54   Optional<NonDefaultConstructible> O(NonDefaultConstructible(3));
55   EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
56   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
57   EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
58   NonDefaultConstructible::ResetCounts();
59   O.reset();
60   EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
61   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
62   EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
63 }
64
65 TEST_F(OptionalTest, InitializationLeakTest) {
66   NonDefaultConstructible::ResetCounts();
67   Optional<NonDefaultConstructible>(NonDefaultConstructible(3));
68   EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
69   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
70   EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
71 }
72
73 TEST_F(OptionalTest, CopyConstructionTest) {
74   NonDefaultConstructible::ResetCounts();
75   {
76     Optional<NonDefaultConstructible> A(NonDefaultConstructible(3));
77     EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
78     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
79     EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
80     NonDefaultConstructible::ResetCounts();
81     Optional<NonDefaultConstructible> B(A);
82     EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
83     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
84     EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
85     NonDefaultConstructible::ResetCounts();
86   }
87   EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
88   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
89   EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
90 }
91
92 TEST_F(OptionalTest, ConstructingCopyAssignmentTest) {
93   NonDefaultConstructible::ResetCounts();
94   {
95     Optional<NonDefaultConstructible> A(NonDefaultConstructible(3));
96     Optional<NonDefaultConstructible> B;
97     EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
98     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
99     EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
100     NonDefaultConstructible::ResetCounts();
101     B = A;
102     EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
103     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
104     EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
105     NonDefaultConstructible::ResetCounts();
106   }
107   EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
108   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
109   EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
110 }
111
112 TEST_F(OptionalTest, CopyingCopyAssignmentTest) {
113   NonDefaultConstructible::ResetCounts();
114   {
115     Optional<NonDefaultConstructible> A(NonDefaultConstructible(3));
116     Optional<NonDefaultConstructible> B(NonDefaultConstructible(4));
117     EXPECT_EQ(2u, NonDefaultConstructible::CopyConstructions);
118     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
119     EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
120     NonDefaultConstructible::ResetCounts();
121     B = A;
122     EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
123     EXPECT_EQ(1u, NonDefaultConstructible::CopyAssignments);
124     EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
125     NonDefaultConstructible::ResetCounts();
126   }
127   EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
128   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
129   EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
130 }
131
132 TEST_F(OptionalTest, DeletingCopyAssignmentTest) {
133   NonDefaultConstructible::ResetCounts();
134   {
135     Optional<NonDefaultConstructible> A;
136     Optional<NonDefaultConstructible> B(NonDefaultConstructible(3));
137     EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
138     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
139     EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
140     NonDefaultConstructible::ResetCounts();
141     B = A;
142     EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
143     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
144     EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
145     NonDefaultConstructible::ResetCounts();
146   }
147   EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
148   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
149   EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
150 }
151
152 TEST_F(OptionalTest, NullCopyConstructionTest) {
153   NonDefaultConstructible::ResetCounts();
154   {
155     Optional<NonDefaultConstructible> A;
156     Optional<NonDefaultConstructible> B;
157     EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
158     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
159     EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
160     NonDefaultConstructible::ResetCounts();
161     B = A;
162     EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
163     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
164     EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
165     NonDefaultConstructible::ResetCounts();
166   }
167   EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
168   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
169   EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
170 }
171
172 #if LLVM_HAS_RVALUE_REFERENCES
173 struct MoveOnly {
174   static unsigned MoveConstructions;
175   static unsigned Destructions;
176   static unsigned MoveAssignments;
177   int val;
178   explicit MoveOnly(int val) : val(val) {
179   }
180   MoveOnly(MoveOnly&& other) {
181     val = other.val;
182     ++MoveConstructions;
183   }
184   MoveOnly &operator=(MoveOnly&& other) {
185     val = other.val;
186     ++MoveAssignments;
187     return *this;
188   }
189   ~MoveOnly() {
190     ++Destructions;
191   }
192   static void ResetCounts() {
193     MoveConstructions = 0;
194     Destructions = 0;
195     MoveAssignments = 0;
196   }
197 };
198
199 unsigned MoveOnly::MoveConstructions = 0;
200 unsigned MoveOnly::Destructions = 0;
201 unsigned MoveOnly::MoveAssignments = 0;
202
203 TEST_F(OptionalTest, MoveOnlyNull) {
204   MoveOnly::ResetCounts();
205   Optional<MoveOnly> O;
206   EXPECT_EQ(0u, MoveOnly::MoveConstructions);
207   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
208   EXPECT_EQ(0u, MoveOnly::Destructions);
209 }
210
211 TEST_F(OptionalTest, MoveOnlyConstruction) {
212   MoveOnly::ResetCounts();
213   Optional<MoveOnly> O(MoveOnly(3));
214   EXPECT_TRUE((bool)O);
215   EXPECT_EQ(3, O->val);
216   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
217   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
218   EXPECT_EQ(1u, MoveOnly::Destructions);
219 }
220
221 TEST_F(OptionalTest, MoveOnlyMoveConstruction) {
222   Optional<MoveOnly> A(MoveOnly(3));
223   MoveOnly::ResetCounts();
224   Optional<MoveOnly> B(std::move(A));
225   EXPECT_FALSE((bool)A);
226   EXPECT_TRUE((bool)B);
227   EXPECT_EQ(3, B->val);
228   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
229   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
230   EXPECT_EQ(1u, MoveOnly::Destructions);
231 }
232
233 TEST_F(OptionalTest, MoveOnlyAssignment) {
234   MoveOnly::ResetCounts();
235   Optional<MoveOnly> O;
236   O = MoveOnly(3);
237   EXPECT_TRUE((bool)O);
238   EXPECT_EQ(3, O->val);
239   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
240   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
241   EXPECT_EQ(1u, MoveOnly::Destructions);
242 }
243
244 TEST_F(OptionalTest, MoveOnlyInitializingAssignment) {
245   Optional<MoveOnly> A(MoveOnly(3));
246   Optional<MoveOnly> B;
247   MoveOnly::ResetCounts();
248   B = std::move(A);
249   EXPECT_FALSE((bool)A);
250   EXPECT_TRUE((bool)B);
251   EXPECT_EQ(3, B->val);
252   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
253   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
254   EXPECT_EQ(1u, MoveOnly::Destructions);
255 }
256
257 TEST_F(OptionalTest, MoveOnlyNullingAssignment) {
258   Optional<MoveOnly> A;
259   Optional<MoveOnly> B(MoveOnly(3));
260   MoveOnly::ResetCounts();
261   B = std::move(A);
262   EXPECT_FALSE((bool)A);
263   EXPECT_FALSE((bool)B);
264   EXPECT_EQ(0u, MoveOnly::MoveConstructions);
265   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
266   EXPECT_EQ(1u, MoveOnly::Destructions);
267 }
268
269 TEST_F(OptionalTest, MoveOnlyAssigningAssignment) {
270   Optional<MoveOnly> A(MoveOnly(3));
271   Optional<MoveOnly> B(MoveOnly(4));
272   MoveOnly::ResetCounts();
273   B = std::move(A);
274   EXPECT_FALSE((bool)A);
275   EXPECT_TRUE((bool)B);
276   EXPECT_EQ(3, B->val);
277   EXPECT_EQ(0u, MoveOnly::MoveConstructions);
278   EXPECT_EQ(1u, MoveOnly::MoveAssignments);
279   EXPECT_EQ(1u, MoveOnly::Destructions);
280 }
281 #endif
282
283 } // end anonymous namespace
284