1 //===- llvm/unittest/ADT/OptionalTest.cpp - Optional unit tests -----------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/ADT/Optional.h"
11 #include "gtest/gtest.h"
17 struct NonDefaultConstructible
{
18 static unsigned CopyConstructions
;
19 static unsigned Destructions
;
20 static unsigned CopyAssignments
;
21 explicit NonDefaultConstructible(int) {
23 NonDefaultConstructible(const NonDefaultConstructible
&) {
26 NonDefaultConstructible
&operator=(const NonDefaultConstructible
&) {
30 ~NonDefaultConstructible() {
33 static void ResetCounts() {
34 CopyConstructions
= 0;
40 unsigned NonDefaultConstructible::CopyConstructions
= 0;
41 unsigned NonDefaultConstructible::Destructions
= 0;
42 unsigned NonDefaultConstructible::CopyAssignments
= 0;
45 class OptionalTest
: public testing::Test
{
48 TEST_F(OptionalTest
, NonDefaultConstructibleTest
) {
49 Optional
<NonDefaultConstructible
> 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();
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();
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();
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();
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();
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
) {
175 EXPECT_EQ(42, A
.getValueOr(42));
178 EXPECT_EQ(5, A
.getValueOr(42));
181 struct MultiArgConstructor
{
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() {
196 static void ResetCounts() {
200 unsigned MultiArgConstructor::Destructions
= 0;
202 TEST_F(OptionalTest
, Emplace
) {
203 MultiArgConstructor::ResetCounts();
204 Optional
<MultiArgConstructor
> A
;
207 EXPECT_TRUE(A
.hasValue());
210 EXPECT_EQ(0u, MultiArgConstructor::Destructions
);
213 EXPECT_TRUE(A
.hasValue());
216 EXPECT_EQ(1u, MultiArgConstructor::Destructions
);
220 static unsigned MoveConstructions
;
221 static unsigned Destructions
;
222 static unsigned MoveAssignments
;
224 explicit MoveOnly(int val
) : val(val
) {
226 MoveOnly(MoveOnly
&& other
) {
230 MoveOnly
&operator=(MoveOnly
&& other
) {
238 static void ResetCounts() {
239 MoveConstructions
= 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
;
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();
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();
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();
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
);
329 static unsigned Constructions
;
330 static unsigned Destructions
;
332 explicit Immovable(int val
) : val(val
) {
338 static void ResetCounts() {
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();
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
);
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
382 template <typename T
, typename U
> static bool apply(const T
&X
, const U
&Y
) {
388 template <typename T
, typename U
> static bool apply(const T
&X
, const U
&Y
) {
394 template <typename T
, typename U
> static bool apply(const T
&X
, const U
&Y
) {
400 template <typename T
, typename U
> static bool apply(const T
&X
, const U
&Y
) {
406 template <typename T
, typename U
> static bool apply(const T
&X
, const U
&Y
) {
411 struct GreaterEqual
{
412 template <typename T
, typename U
> static bool apply(const T
&X
, const U
&Y
) {
417 template <typename OperatorT
, typename T
>
418 void CheckRelation(const Optional
<T
> &Lhs
, const Optional
<T
> &Rhs
,
420 EXPECT_EQ(Expected
, OperatorT::apply(Lhs
, Rhs
));
423 EXPECT_EQ(Expected
, OperatorT::apply(*Lhs
, Rhs
));
425 EXPECT_EQ(Expected
, OperatorT::apply(None
, Rhs
));
428 EXPECT_EQ(Expected
, OperatorT::apply(Lhs
, *Rhs
));
430 EXPECT_EQ(Expected
, OperatorT::apply(Lhs
, None
));
433 struct EqualityMock
{};
434 const Optional
<EqualityMock
> NoneEq
, EqualityLhs((EqualityMock())),
435 EqualityRhs((EqualityMock()));
438 bool operator==(const EqualityMock
&Lhs
, const EqualityMock
&Rhs
) {
439 EXPECT_EQ(&*EqualityLhs
, &Lhs
);
440 EXPECT_EQ(&*EqualityRhs
, &Rhs
);
444 TEST_F(OptionalTest
, OperatorEqual
) {
445 CheckRelation
<EqualTo
>(NoneEq
, NoneEq
, true);
446 CheckRelation
<EqualTo
>(NoneEq
, EqualityRhs
, false);
447 CheckRelation
<EqualTo
>(EqualityLhs
, NoneEq
, false);
450 CheckRelation
<EqualTo
>(EqualityLhs
, EqualityRhs
, IsEqual
);
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);
461 CheckRelation
<NotEqualTo
>(EqualityLhs
, EqualityRhs
, !IsEqual
);
463 CheckRelation
<NotEqualTo
>(EqualityLhs
, EqualityRhs
, !IsEqual
);
466 struct InequalityMock
{};
467 const Optional
<InequalityMock
> NoneIneq
, InequalityLhs((InequalityMock())),
468 InequalityRhs((InequalityMock()));
471 bool operator<(const InequalityMock
&Lhs
, const InequalityMock
&Rhs
) {
472 EXPECT_EQ(&*InequalityLhs
, &Lhs
);
473 EXPECT_EQ(&*InequalityRhs
, &Rhs
);
477 TEST_F(OptionalTest
, OperatorLess
) {
478 CheckRelation
<Less
>(NoneIneq
, NoneIneq
, false);
479 CheckRelation
<Less
>(NoneIneq
, InequalityRhs
, true);
480 CheckRelation
<Less
>(InequalityLhs
, NoneIneq
, false);
483 CheckRelation
<Less
>(InequalityLhs
, InequalityRhs
, IsLess
);
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);
494 CheckRelation
<Greater
>(InequalityRhs
, InequalityLhs
, IsLess
);
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);
505 CheckRelation
<LessEqual
>(InequalityRhs
, InequalityLhs
, !IsLess
);
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);
516 CheckRelation
<GreaterEqual
>(InequalityLhs
, InequalityRhs
, !IsLess
);
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");
525 !std::is_trivially_copyable
<Optional
<NonDefaultConstructible
>>::value
,
526 "Shouldn't be trivially copyable");
529 } // end anonymous namespace