Commit r331416 breaks the big-endian PPC bot. On the big endian build, we
[llvm-core.git] / unittests / ADT / OptionalTest.cpp
blob2e09c5340fa3f0b84e5d6ef0fb04491fd44125ec
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 //===----------------------------------------------------------------------===//
10 #include "llvm/ADT/Optional.h"
11 #include "gtest/gtest.h"
13 using namespace llvm;
15 namespace {
17 struct NonDefaultConstructible {
18 static unsigned CopyConstructions;
19 static unsigned Destructions;
20 static unsigned CopyAssignments;
21 explicit NonDefaultConstructible(int) {
23 NonDefaultConstructible(const NonDefaultConstructible&) {
24 ++CopyConstructions;
26 NonDefaultConstructible &operator=(const NonDefaultConstructible&) {
27 ++CopyAssignments;
28 return *this;
30 ~NonDefaultConstructible() {
31 ++Destructions;
33 static void ResetCounts() {
34 CopyConstructions = 0;
35 Destructions = 0;
36 CopyAssignments = 0;
40 unsigned NonDefaultConstructible::CopyConstructions = 0;
41 unsigned NonDefaultConstructible::Destructions = 0;
42 unsigned NonDefaultConstructible::CopyAssignments = 0;
44 // Test fixture
45 class OptionalTest : public testing::Test {
48 TEST_F(OptionalTest, NonDefaultConstructibleTest) {
49 Optional<NonDefaultConstructible> O;
50 EXPECT_FALSE(O);
53 TEST_F(OptionalTest, ResetTest) {
54 NonDefaultConstructible::ResetCounts();
55 Optional<NonDefaultConstructible> O(NonDefaultConstructible(3));
56 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
57 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
58 EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
59 NonDefaultConstructible::ResetCounts();
60 O.reset();
61 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
62 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
63 EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
66 TEST_F(OptionalTest, InitializationLeakTest) {
67 NonDefaultConstructible::ResetCounts();
68 Optional<NonDefaultConstructible>(NonDefaultConstructible(3));
69 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
70 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
71 EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
74 TEST_F(OptionalTest, CopyConstructionTest) {
75 NonDefaultConstructible::ResetCounts();
77 Optional<NonDefaultConstructible> A(NonDefaultConstructible(3));
78 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
79 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
80 EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
81 NonDefaultConstructible::ResetCounts();
82 Optional<NonDefaultConstructible> B(A);
83 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
84 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
85 EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
86 NonDefaultConstructible::ResetCounts();
88 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
89 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
90 EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
93 TEST_F(OptionalTest, ConstructingCopyAssignmentTest) {
94 NonDefaultConstructible::ResetCounts();
96 Optional<NonDefaultConstructible> A(NonDefaultConstructible(3));
97 Optional<NonDefaultConstructible> B;
98 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
99 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
100 EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
101 NonDefaultConstructible::ResetCounts();
102 B = A;
103 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
104 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
105 EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
106 NonDefaultConstructible::ResetCounts();
108 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
109 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
110 EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
113 TEST_F(OptionalTest, CopyingCopyAssignmentTest) {
114 NonDefaultConstructible::ResetCounts();
116 Optional<NonDefaultConstructible> A(NonDefaultConstructible(3));
117 Optional<NonDefaultConstructible> B(NonDefaultConstructible(4));
118 EXPECT_EQ(2u, NonDefaultConstructible::CopyConstructions);
119 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
120 EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
121 NonDefaultConstructible::ResetCounts();
122 B = A;
123 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
124 EXPECT_EQ(1u, NonDefaultConstructible::CopyAssignments);
125 EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
126 NonDefaultConstructible::ResetCounts();
128 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
129 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
130 EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
133 TEST_F(OptionalTest, DeletingCopyAssignmentTest) {
134 NonDefaultConstructible::ResetCounts();
136 Optional<NonDefaultConstructible> A;
137 Optional<NonDefaultConstructible> B(NonDefaultConstructible(3));
138 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
139 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
140 EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
141 NonDefaultConstructible::ResetCounts();
142 B = A;
143 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
144 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
145 EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
146 NonDefaultConstructible::ResetCounts();
148 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
149 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
150 EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
153 TEST_F(OptionalTest, NullCopyConstructionTest) {
154 NonDefaultConstructible::ResetCounts();
156 Optional<NonDefaultConstructible> A;
157 Optional<NonDefaultConstructible> B;
158 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
159 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
160 EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
161 NonDefaultConstructible::ResetCounts();
162 B = A;
163 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
164 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
165 EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
166 NonDefaultConstructible::ResetCounts();
168 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
169 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
170 EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
173 TEST_F(OptionalTest, GetValueOr) {
174 Optional<int> A;
175 EXPECT_EQ(42, A.getValueOr(42));
177 A = 5;
178 EXPECT_EQ(5, A.getValueOr(42));
181 struct MultiArgConstructor {
182 int x, y;
183 MultiArgConstructor(int x, int y) : x(x), y(y) {}
184 explicit MultiArgConstructor(int x, bool positive)
185 : x(x), y(positive ? x : -x) {}
187 MultiArgConstructor(const MultiArgConstructor &) = delete;
188 MultiArgConstructor(MultiArgConstructor &&) = delete;
189 MultiArgConstructor &operator=(const MultiArgConstructor &) = delete;
190 MultiArgConstructor &operator=(MultiArgConstructor &&) = delete;
192 static unsigned Destructions;
193 ~MultiArgConstructor() {
194 ++Destructions;
196 static void ResetCounts() {
197 Destructions = 0;
200 unsigned MultiArgConstructor::Destructions = 0;
202 TEST_F(OptionalTest, Emplace) {
203 MultiArgConstructor::ResetCounts();
204 Optional<MultiArgConstructor> A;
206 A.emplace(1, 2);
207 EXPECT_TRUE(A.hasValue());
208 EXPECT_EQ(1, A->x);
209 EXPECT_EQ(2, A->y);
210 EXPECT_EQ(0u, MultiArgConstructor::Destructions);
212 A.emplace(5, false);
213 EXPECT_TRUE(A.hasValue());
214 EXPECT_EQ(5, A->x);
215 EXPECT_EQ(-5, A->y);
216 EXPECT_EQ(1u, MultiArgConstructor::Destructions);
219 struct MoveOnly {
220 static unsigned MoveConstructions;
221 static unsigned Destructions;
222 static unsigned MoveAssignments;
223 int val;
224 explicit MoveOnly(int val) : val(val) {
226 MoveOnly(MoveOnly&& other) {
227 val = other.val;
228 ++MoveConstructions;
230 MoveOnly &operator=(MoveOnly&& other) {
231 val = other.val;
232 ++MoveAssignments;
233 return *this;
235 ~MoveOnly() {
236 ++Destructions;
238 static void ResetCounts() {
239 MoveConstructions = 0;
240 Destructions = 0;
241 MoveAssignments = 0;
245 unsigned MoveOnly::MoveConstructions = 0;
246 unsigned MoveOnly::Destructions = 0;
247 unsigned MoveOnly::MoveAssignments = 0;
249 TEST_F(OptionalTest, MoveOnlyNull) {
250 MoveOnly::ResetCounts();
251 Optional<MoveOnly> O;
252 EXPECT_EQ(0u, MoveOnly::MoveConstructions);
253 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
254 EXPECT_EQ(0u, MoveOnly::Destructions);
257 TEST_F(OptionalTest, MoveOnlyConstruction) {
258 MoveOnly::ResetCounts();
259 Optional<MoveOnly> O(MoveOnly(3));
260 EXPECT_TRUE((bool)O);
261 EXPECT_EQ(3, O->val);
262 EXPECT_EQ(1u, MoveOnly::MoveConstructions);
263 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
264 EXPECT_EQ(1u, MoveOnly::Destructions);
267 TEST_F(OptionalTest, MoveOnlyMoveConstruction) {
268 Optional<MoveOnly> A(MoveOnly(3));
269 MoveOnly::ResetCounts();
270 Optional<MoveOnly> B(std::move(A));
271 EXPECT_TRUE((bool)A);
272 EXPECT_TRUE((bool)B);
273 EXPECT_EQ(3, B->val);
274 EXPECT_EQ(1u, MoveOnly::MoveConstructions);
275 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
276 EXPECT_EQ(0u, MoveOnly::Destructions);
279 TEST_F(OptionalTest, MoveOnlyAssignment) {
280 MoveOnly::ResetCounts();
281 Optional<MoveOnly> O;
282 O = MoveOnly(3);
283 EXPECT_TRUE((bool)O);
284 EXPECT_EQ(3, O->val);
285 EXPECT_EQ(1u, MoveOnly::MoveConstructions);
286 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
287 EXPECT_EQ(1u, MoveOnly::Destructions);
290 TEST_F(OptionalTest, MoveOnlyInitializingAssignment) {
291 Optional<MoveOnly> A(MoveOnly(3));
292 Optional<MoveOnly> B;
293 MoveOnly::ResetCounts();
294 B = std::move(A);
295 EXPECT_TRUE((bool)A);
296 EXPECT_TRUE((bool)B);
297 EXPECT_EQ(3, B->val);
298 EXPECT_EQ(1u, MoveOnly::MoveConstructions);
299 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
300 EXPECT_EQ(0u, MoveOnly::Destructions);
303 TEST_F(OptionalTest, MoveOnlyNullingAssignment) {
304 Optional<MoveOnly> A;
305 Optional<MoveOnly> B(MoveOnly(3));
306 MoveOnly::ResetCounts();
307 B = std::move(A);
308 EXPECT_FALSE((bool)A);
309 EXPECT_FALSE((bool)B);
310 EXPECT_EQ(0u, MoveOnly::MoveConstructions);
311 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
312 EXPECT_EQ(1u, MoveOnly::Destructions);
315 TEST_F(OptionalTest, MoveOnlyAssigningAssignment) {
316 Optional<MoveOnly> A(MoveOnly(3));
317 Optional<MoveOnly> B(MoveOnly(4));
318 MoveOnly::ResetCounts();
319 B = std::move(A);
320 EXPECT_TRUE((bool)A);
321 EXPECT_TRUE((bool)B);
322 EXPECT_EQ(3, B->val);
323 EXPECT_EQ(0u, MoveOnly::MoveConstructions);
324 EXPECT_EQ(1u, MoveOnly::MoveAssignments);
325 EXPECT_EQ(0u, MoveOnly::Destructions);
328 struct Immovable {
329 static unsigned Constructions;
330 static unsigned Destructions;
331 int val;
332 explicit Immovable(int val) : val(val) {
333 ++Constructions;
335 ~Immovable() {
336 ++Destructions;
338 static void ResetCounts() {
339 Constructions = 0;
340 Destructions = 0;
342 private:
343 // This should disable all move/copy operations.
344 Immovable(Immovable&& other) = delete;
347 unsigned Immovable::Constructions = 0;
348 unsigned Immovable::Destructions = 0;
350 TEST_F(OptionalTest, ImmovableEmplace) {
351 Optional<Immovable> A;
352 Immovable::ResetCounts();
353 A.emplace(4);
354 EXPECT_TRUE((bool)A);
355 EXPECT_EQ(4, A->val);
356 EXPECT_EQ(1u, Immovable::Constructions);
357 EXPECT_EQ(0u, Immovable::Destructions);
360 #if LLVM_HAS_RVALUE_REFERENCE_THIS
362 TEST_F(OptionalTest, MoveGetValueOr) {
363 Optional<MoveOnly> A;
365 MoveOnly::ResetCounts();
366 EXPECT_EQ(42, std::move(A).getValueOr(MoveOnly(42)).val);
367 EXPECT_EQ(1u, MoveOnly::MoveConstructions);
368 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
369 EXPECT_EQ(2u, MoveOnly::Destructions);
371 A = MoveOnly(5);
372 MoveOnly::ResetCounts();
373 EXPECT_EQ(5, std::move(A).getValueOr(MoveOnly(42)).val);
374 EXPECT_EQ(1u, MoveOnly::MoveConstructions);
375 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
376 EXPECT_EQ(2u, MoveOnly::Destructions);
379 #endif // LLVM_HAS_RVALUE_REFERENCE_THIS
381 struct EqualTo {
382 template <typename T, typename U> static bool apply(const T &X, const U &Y) {
383 return X == Y;
387 struct NotEqualTo {
388 template <typename T, typename U> static bool apply(const T &X, const U &Y) {
389 return X != Y;
393 struct Less {
394 template <typename T, typename U> static bool apply(const T &X, const U &Y) {
395 return X < Y;
399 struct Greater {
400 template <typename T, typename U> static bool apply(const T &X, const U &Y) {
401 return X > Y;
405 struct LessEqual {
406 template <typename T, typename U> static bool apply(const T &X, const U &Y) {
407 return X <= Y;
411 struct GreaterEqual {
412 template <typename T, typename U> static bool apply(const T &X, const U &Y) {
413 return X >= Y;
417 template <typename OperatorT, typename T>
418 void CheckRelation(const Optional<T> &Lhs, const Optional<T> &Rhs,
419 bool Expected) {
420 EXPECT_EQ(Expected, OperatorT::apply(Lhs, Rhs));
422 if (Lhs)
423 EXPECT_EQ(Expected, OperatorT::apply(*Lhs, Rhs));
424 else
425 EXPECT_EQ(Expected, OperatorT::apply(None, Rhs));
427 if (Rhs)
428 EXPECT_EQ(Expected, OperatorT::apply(Lhs, *Rhs));
429 else
430 EXPECT_EQ(Expected, OperatorT::apply(Lhs, None));
433 struct EqualityMock {};
434 const Optional<EqualityMock> NoneEq, EqualityLhs((EqualityMock())),
435 EqualityRhs((EqualityMock()));
436 bool IsEqual;
438 bool operator==(const EqualityMock &Lhs, const EqualityMock &Rhs) {
439 EXPECT_EQ(&*EqualityLhs, &Lhs);
440 EXPECT_EQ(&*EqualityRhs, &Rhs);
441 return IsEqual;
444 TEST_F(OptionalTest, OperatorEqual) {
445 CheckRelation<EqualTo>(NoneEq, NoneEq, true);
446 CheckRelation<EqualTo>(NoneEq, EqualityRhs, false);
447 CheckRelation<EqualTo>(EqualityLhs, NoneEq, false);
449 IsEqual = false;
450 CheckRelation<EqualTo>(EqualityLhs, EqualityRhs, IsEqual);
451 IsEqual = true;
452 CheckRelation<EqualTo>(EqualityLhs, EqualityRhs, IsEqual);
455 TEST_F(OptionalTest, OperatorNotEqual) {
456 CheckRelation<NotEqualTo>(NoneEq, NoneEq, false);
457 CheckRelation<NotEqualTo>(NoneEq, EqualityRhs, true);
458 CheckRelation<NotEqualTo>(EqualityLhs, NoneEq, true);
460 IsEqual = false;
461 CheckRelation<NotEqualTo>(EqualityLhs, EqualityRhs, !IsEqual);
462 IsEqual = true;
463 CheckRelation<NotEqualTo>(EqualityLhs, EqualityRhs, !IsEqual);
466 struct InequalityMock {};
467 const Optional<InequalityMock> NoneIneq, InequalityLhs((InequalityMock())),
468 InequalityRhs((InequalityMock()));
469 bool IsLess;
471 bool operator<(const InequalityMock &Lhs, const InequalityMock &Rhs) {
472 EXPECT_EQ(&*InequalityLhs, &Lhs);
473 EXPECT_EQ(&*InequalityRhs, &Rhs);
474 return IsLess;
477 TEST_F(OptionalTest, OperatorLess) {
478 CheckRelation<Less>(NoneIneq, NoneIneq, false);
479 CheckRelation<Less>(NoneIneq, InequalityRhs, true);
480 CheckRelation<Less>(InequalityLhs, NoneIneq, false);
482 IsLess = false;
483 CheckRelation<Less>(InequalityLhs, InequalityRhs, IsLess);
484 IsLess = true;
485 CheckRelation<Less>(InequalityLhs, InequalityRhs, IsLess);
488 TEST_F(OptionalTest, OperatorGreater) {
489 CheckRelation<Greater>(NoneIneq, NoneIneq, false);
490 CheckRelation<Greater>(NoneIneq, InequalityRhs, false);
491 CheckRelation<Greater>(InequalityLhs, NoneIneq, true);
493 IsLess = false;
494 CheckRelation<Greater>(InequalityRhs, InequalityLhs, IsLess);
495 IsLess = true;
496 CheckRelation<Greater>(InequalityRhs, InequalityLhs, IsLess);
499 TEST_F(OptionalTest, OperatorLessEqual) {
500 CheckRelation<LessEqual>(NoneIneq, NoneIneq, true);
501 CheckRelation<LessEqual>(NoneIneq, InequalityRhs, true);
502 CheckRelation<LessEqual>(InequalityLhs, NoneIneq, false);
504 IsLess = false;
505 CheckRelation<LessEqual>(InequalityRhs, InequalityLhs, !IsLess);
506 IsLess = true;
507 CheckRelation<LessEqual>(InequalityRhs, InequalityLhs, !IsLess);
510 TEST_F(OptionalTest, OperatorGreaterEqual) {
511 CheckRelation<GreaterEqual>(NoneIneq, NoneIneq, true);
512 CheckRelation<GreaterEqual>(NoneIneq, InequalityRhs, false);
513 CheckRelation<GreaterEqual>(InequalityLhs, NoneIneq, true);
515 IsLess = false;
516 CheckRelation<GreaterEqual>(InequalityLhs, InequalityRhs, !IsLess);
517 IsLess = true;
518 CheckRelation<GreaterEqual>(InequalityLhs, InequalityRhs, !IsLess);
521 #if __has_feature(is_trivially_copyable) && defined(_LIBCPP_VERSION)
522 static_assert(std::is_trivially_copyable<Optional<int>>::value,
523 "Should be trivially copyable");
524 static_assert(
525 !std::is_trivially_copyable<Optional<NonDefaultConstructible>>::value,
526 "Shouldn't be trivially copyable");
527 #endif
529 } // end anonymous namespace