51c54523b88d89356bc92e31ea4048956cd53b6e
[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 TEST_F(OptionalTest, GetValueOr) {
173   Optional<int> A;
174   EXPECT_EQ(42, A.getValueOr(42));
175
176   A = 5;
177   EXPECT_EQ(5, A.getValueOr(42));
178 }
179
180 struct MoveOnly {
181   static unsigned MoveConstructions;
182   static unsigned Destructions;
183   static unsigned MoveAssignments;
184   int val;
185   explicit MoveOnly(int val) : val(val) {
186   }
187   MoveOnly(MoveOnly&& other) {
188     val = other.val;
189     ++MoveConstructions;
190   }
191   MoveOnly &operator=(MoveOnly&& other) {
192     val = other.val;
193     ++MoveAssignments;
194     return *this;
195   }
196   ~MoveOnly() {
197     ++Destructions;
198   }
199   static void ResetCounts() {
200     MoveConstructions = 0;
201     Destructions = 0;
202     MoveAssignments = 0;
203   }
204 };
205
206 unsigned MoveOnly::MoveConstructions = 0;
207 unsigned MoveOnly::Destructions = 0;
208 unsigned MoveOnly::MoveAssignments = 0;
209
210 TEST_F(OptionalTest, MoveOnlyNull) {
211   MoveOnly::ResetCounts();
212   Optional<MoveOnly> O;
213   EXPECT_EQ(0u, MoveOnly::MoveConstructions);
214   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
215   EXPECT_EQ(0u, MoveOnly::Destructions);
216 }
217
218 TEST_F(OptionalTest, MoveOnlyConstruction) {
219   MoveOnly::ResetCounts();
220   Optional<MoveOnly> O(MoveOnly(3));
221   EXPECT_TRUE((bool)O);
222   EXPECT_EQ(3, O->val);
223   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
224   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
225   EXPECT_EQ(1u, MoveOnly::Destructions);
226 }
227
228 TEST_F(OptionalTest, MoveOnlyMoveConstruction) {
229   Optional<MoveOnly> A(MoveOnly(3));
230   MoveOnly::ResetCounts();
231   Optional<MoveOnly> B(std::move(A));
232   EXPECT_FALSE((bool)A);
233   EXPECT_TRUE((bool)B);
234   EXPECT_EQ(3, B->val);
235   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
236   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
237   EXPECT_EQ(1u, MoveOnly::Destructions);
238 }
239
240 TEST_F(OptionalTest, MoveOnlyAssignment) {
241   MoveOnly::ResetCounts();
242   Optional<MoveOnly> O;
243   O = MoveOnly(3);
244   EXPECT_TRUE((bool)O);
245   EXPECT_EQ(3, O->val);
246   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
247   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
248   EXPECT_EQ(1u, MoveOnly::Destructions);
249 }
250
251 TEST_F(OptionalTest, MoveOnlyInitializingAssignment) {
252   Optional<MoveOnly> A(MoveOnly(3));
253   Optional<MoveOnly> B;
254   MoveOnly::ResetCounts();
255   B = std::move(A);
256   EXPECT_FALSE((bool)A);
257   EXPECT_TRUE((bool)B);
258   EXPECT_EQ(3, B->val);
259   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
260   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
261   EXPECT_EQ(1u, MoveOnly::Destructions);
262 }
263
264 TEST_F(OptionalTest, MoveOnlyNullingAssignment) {
265   Optional<MoveOnly> A;
266   Optional<MoveOnly> B(MoveOnly(3));
267   MoveOnly::ResetCounts();
268   B = std::move(A);
269   EXPECT_FALSE((bool)A);
270   EXPECT_FALSE((bool)B);
271   EXPECT_EQ(0u, MoveOnly::MoveConstructions);
272   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
273   EXPECT_EQ(1u, MoveOnly::Destructions);
274 }
275
276 TEST_F(OptionalTest, MoveOnlyAssigningAssignment) {
277   Optional<MoveOnly> A(MoveOnly(3));
278   Optional<MoveOnly> B(MoveOnly(4));
279   MoveOnly::ResetCounts();
280   B = std::move(A);
281   EXPECT_FALSE((bool)A);
282   EXPECT_TRUE((bool)B);
283   EXPECT_EQ(3, B->val);
284   EXPECT_EQ(0u, MoveOnly::MoveConstructions);
285   EXPECT_EQ(1u, MoveOnly::MoveAssignments);
286   EXPECT_EQ(1u, MoveOnly::Destructions);
287 }
288
289 #if LLVM_HAS_RVALUE_REFERENCE_THIS
290
291 TEST_F(OptionalTest, MoveGetValueOr) {
292   Optional<MoveOnly> A;
293
294   MoveOnly::ResetCounts();
295   EXPECT_EQ(42, std::move(A).getValueOr(MoveOnly(42)).val);
296   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
297   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
298   EXPECT_EQ(2u, MoveOnly::Destructions);
299
300   A = MoveOnly(5);
301   MoveOnly::ResetCounts();
302   EXPECT_EQ(5, std::move(A).getValueOr(MoveOnly(42)).val);
303   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
304   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
305   EXPECT_EQ(2u, MoveOnly::Destructions);
306 }
307
308 #endif // LLVM_HAS_RVALUE_REFERENCE_THIS
309
310 } // end anonymous namespace
311