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;
NonDefaultConstructible__anonbc7c359b0111::NonDefaultConstructible20 explicit NonDefaultConstructible(int) {
21 }
NonDefaultConstructible__anonbc7c359b0111::NonDefaultConstructible22 NonDefaultConstructible(const NonDefaultConstructible&) {
23 ++CopyConstructions;
24 }
operator =__anonbc7c359b0111::NonDefaultConstructible25 NonDefaultConstructible &operator=(const NonDefaultConstructible&) {
26 ++CopyAssignments;
27 return *this;
28 }
~NonDefaultConstructible__anonbc7c359b0111::NonDefaultConstructible29 ~NonDefaultConstructible() {
30 ++Destructions;
31 }
ResetCounts__anonbc7c359b0111::NonDefaultConstructible32 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
TEST_F(OptionalTest,NonDefaultConstructibleTest)47 TEST_F(OptionalTest, NonDefaultConstructibleTest) {
48 Optional<NonDefaultConstructible> O;
49 EXPECT_FALSE(O);
50 }
51
TEST_F(OptionalTest,ResetTest)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
TEST_F(OptionalTest,InitializationLeakTest)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
TEST_F(OptionalTest,CopyConstructionTest)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
TEST_F(OptionalTest,ConstructingCopyAssignmentTest)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
TEST_F(OptionalTest,CopyingCopyAssignmentTest)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
TEST_F(OptionalTest,DeletingCopyAssignmentTest)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
TEST_F(OptionalTest,NullCopyConstructionTest)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
TEST_F(OptionalTest,GetValueOr)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 MultiArgConstructor {
181 int x, y;
MultiArgConstructor__anonbc7c359b0111::MultiArgConstructor182 MultiArgConstructor(int x, int y) : x(x), y(y) {}
MultiArgConstructor__anonbc7c359b0111::MultiArgConstructor183 explicit MultiArgConstructor(int x, bool positive)
184 : x(x), y(positive ? x : -x) {}
185
186 MultiArgConstructor(const MultiArgConstructor &) = delete;
187 MultiArgConstructor(MultiArgConstructor &&) = delete;
188 MultiArgConstructor &operator=(const MultiArgConstructor &) = delete;
189 MultiArgConstructor &operator=(MultiArgConstructor &&) = delete;
190
191 static unsigned Destructions;
~MultiArgConstructor__anonbc7c359b0111::MultiArgConstructor192 ~MultiArgConstructor() {
193 ++Destructions;
194 }
ResetCounts__anonbc7c359b0111::MultiArgConstructor195 static void ResetCounts() {
196 Destructions = 0;
197 }
198 };
199 unsigned MultiArgConstructor::Destructions = 0;
200
TEST_F(OptionalTest,Emplace)201 TEST_F(OptionalTest, Emplace) {
202 MultiArgConstructor::ResetCounts();
203 Optional<MultiArgConstructor> A;
204
205 A.emplace(1, 2);
206 EXPECT_TRUE(A.hasValue());
207 EXPECT_EQ(1, A->x);
208 EXPECT_EQ(2, A->y);
209 EXPECT_EQ(0u, MultiArgConstructor::Destructions);
210
211 A.emplace(5, false);
212 EXPECT_TRUE(A.hasValue());
213 EXPECT_EQ(5, A->x);
214 EXPECT_EQ(-5, A->y);
215 EXPECT_EQ(1u, MultiArgConstructor::Destructions);
216 }
217
218 struct MoveOnly {
219 static unsigned MoveConstructions;
220 static unsigned Destructions;
221 static unsigned MoveAssignments;
222 int val;
MoveOnly__anonbc7c359b0111::MoveOnly223 explicit MoveOnly(int val) : val(val) {
224 }
MoveOnly__anonbc7c359b0111::MoveOnly225 MoveOnly(MoveOnly&& other) {
226 val = other.val;
227 ++MoveConstructions;
228 }
operator =__anonbc7c359b0111::MoveOnly229 MoveOnly &operator=(MoveOnly&& other) {
230 val = other.val;
231 ++MoveAssignments;
232 return *this;
233 }
~MoveOnly__anonbc7c359b0111::MoveOnly234 ~MoveOnly() {
235 ++Destructions;
236 }
ResetCounts__anonbc7c359b0111::MoveOnly237 static void ResetCounts() {
238 MoveConstructions = 0;
239 Destructions = 0;
240 MoveAssignments = 0;
241 }
242 };
243
244 unsigned MoveOnly::MoveConstructions = 0;
245 unsigned MoveOnly::Destructions = 0;
246 unsigned MoveOnly::MoveAssignments = 0;
247
TEST_F(OptionalTest,MoveOnlyNull)248 TEST_F(OptionalTest, MoveOnlyNull) {
249 MoveOnly::ResetCounts();
250 Optional<MoveOnly> O;
251 EXPECT_EQ(0u, MoveOnly::MoveConstructions);
252 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
253 EXPECT_EQ(0u, MoveOnly::Destructions);
254 }
255
TEST_F(OptionalTest,MoveOnlyConstruction)256 TEST_F(OptionalTest, MoveOnlyConstruction) {
257 MoveOnly::ResetCounts();
258 Optional<MoveOnly> O(MoveOnly(3));
259 EXPECT_TRUE((bool)O);
260 EXPECT_EQ(3, O->val);
261 EXPECT_EQ(1u, MoveOnly::MoveConstructions);
262 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
263 EXPECT_EQ(1u, MoveOnly::Destructions);
264 }
265
TEST_F(OptionalTest,MoveOnlyMoveConstruction)266 TEST_F(OptionalTest, MoveOnlyMoveConstruction) {
267 Optional<MoveOnly> A(MoveOnly(3));
268 MoveOnly::ResetCounts();
269 Optional<MoveOnly> B(std::move(A));
270 EXPECT_FALSE((bool)A);
271 EXPECT_TRUE((bool)B);
272 EXPECT_EQ(3, B->val);
273 EXPECT_EQ(1u, MoveOnly::MoveConstructions);
274 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
275 EXPECT_EQ(1u, MoveOnly::Destructions);
276 }
277
TEST_F(OptionalTest,MoveOnlyAssignment)278 TEST_F(OptionalTest, MoveOnlyAssignment) {
279 MoveOnly::ResetCounts();
280 Optional<MoveOnly> O;
281 O = MoveOnly(3);
282 EXPECT_TRUE((bool)O);
283 EXPECT_EQ(3, O->val);
284 EXPECT_EQ(1u, MoveOnly::MoveConstructions);
285 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
286 EXPECT_EQ(1u, MoveOnly::Destructions);
287 }
288
TEST_F(OptionalTest,MoveOnlyInitializingAssignment)289 TEST_F(OptionalTest, MoveOnlyInitializingAssignment) {
290 Optional<MoveOnly> A(MoveOnly(3));
291 Optional<MoveOnly> B;
292 MoveOnly::ResetCounts();
293 B = std::move(A);
294 EXPECT_FALSE((bool)A);
295 EXPECT_TRUE((bool)B);
296 EXPECT_EQ(3, B->val);
297 EXPECT_EQ(1u, MoveOnly::MoveConstructions);
298 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
299 EXPECT_EQ(1u, MoveOnly::Destructions);
300 }
301
TEST_F(OptionalTest,MoveOnlyNullingAssignment)302 TEST_F(OptionalTest, MoveOnlyNullingAssignment) {
303 Optional<MoveOnly> A;
304 Optional<MoveOnly> B(MoveOnly(3));
305 MoveOnly::ResetCounts();
306 B = std::move(A);
307 EXPECT_FALSE((bool)A);
308 EXPECT_FALSE((bool)B);
309 EXPECT_EQ(0u, MoveOnly::MoveConstructions);
310 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
311 EXPECT_EQ(1u, MoveOnly::Destructions);
312 }
313
TEST_F(OptionalTest,MoveOnlyAssigningAssignment)314 TEST_F(OptionalTest, MoveOnlyAssigningAssignment) {
315 Optional<MoveOnly> A(MoveOnly(3));
316 Optional<MoveOnly> B(MoveOnly(4));
317 MoveOnly::ResetCounts();
318 B = std::move(A);
319 EXPECT_FALSE((bool)A);
320 EXPECT_TRUE((bool)B);
321 EXPECT_EQ(3, B->val);
322 EXPECT_EQ(0u, MoveOnly::MoveConstructions);
323 EXPECT_EQ(1u, MoveOnly::MoveAssignments);
324 EXPECT_EQ(1u, MoveOnly::Destructions);
325 }
326
327 struct Immovable {
328 static unsigned Constructions;
329 static unsigned Destructions;
330 int val;
Immovable__anonbc7c359b0111::Immovable331 explicit Immovable(int val) : val(val) {
332 ++Constructions;
333 }
~Immovable__anonbc7c359b0111::Immovable334 ~Immovable() {
335 ++Destructions;
336 }
ResetCounts__anonbc7c359b0111::Immovable337 static void ResetCounts() {
338 Constructions = 0;
339 Destructions = 0;
340 }
341 private:
342 // This should disable all move/copy operations.
343 Immovable(Immovable&& other) = delete;
344 };
345
346 unsigned Immovable::Constructions = 0;
347 unsigned Immovable::Destructions = 0;
348
TEST_F(OptionalTest,ImmovableEmplace)349 TEST_F(OptionalTest, ImmovableEmplace) {
350 Optional<Immovable> A;
351 Immovable::ResetCounts();
352 A.emplace(4);
353 EXPECT_TRUE((bool)A);
354 EXPECT_EQ(4, A->val);
355 EXPECT_EQ(1u, Immovable::Constructions);
356 EXPECT_EQ(0u, Immovable::Destructions);
357 }
358
359 #if LLVM_HAS_RVALUE_REFERENCE_THIS
360
TEST_F(OptionalTest,MoveGetValueOr)361 TEST_F(OptionalTest, MoveGetValueOr) {
362 Optional<MoveOnly> A;
363
364 MoveOnly::ResetCounts();
365 EXPECT_EQ(42, std::move(A).getValueOr(MoveOnly(42)).val);
366 EXPECT_EQ(1u, MoveOnly::MoveConstructions);
367 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
368 EXPECT_EQ(2u, MoveOnly::Destructions);
369
370 A = MoveOnly(5);
371 MoveOnly::ResetCounts();
372 EXPECT_EQ(5, std::move(A).getValueOr(MoveOnly(42)).val);
373 EXPECT_EQ(1u, MoveOnly::MoveConstructions);
374 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
375 EXPECT_EQ(2u, MoveOnly::Destructions);
376 }
377
378 #endif // LLVM_HAS_RVALUE_REFERENCE_THIS
379
TEST_F(OptionalTest,NoneComparison)380 TEST_F(OptionalTest, NoneComparison) {
381 Optional<int> o;
382 EXPECT_EQ(o, None);
383 EXPECT_EQ(None, o);
384 EXPECT_FALSE(o != None);
385 EXPECT_FALSE(None != o);
386 o = 3;
387 EXPECT_FALSE(o == None);
388 EXPECT_FALSE(None == o);
389 EXPECT_TRUE(o != None);
390 EXPECT_TRUE(None != o);
391 }
392
393 } // end anonymous namespace
394
395