1 //===- llvm/unittest/ADT/OptionalTest.cpp - Optional unit tests -----------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/ADT/Optional.h"
10 #include "llvm/ADT/SmallString.h"
11 #include "llvm/ADT/StringMap.h"
12 #include "llvm/Support/raw_ostream.h"
13 #include "gtest/gtest-spi.h"
14 #include "gtest/gtest.h"
21 static_assert(std::is_trivially_copyable
<Optional
<int>>::value
,
22 "trivially copyable");
24 static_assert(std::is_trivially_copyable
<Optional
<std::array
<int, 3>>>::value
,
25 "trivially copyable");
27 void OptionalWorksInConstexpr() {
28 constexpr auto x1
= Optional
<int>();
29 constexpr Optional
<int> x2
{};
30 static_assert(!x1
.has_value() && !x2
.has_value(),
31 "Default construction and hasValue() are contexpr");
32 static_assert(!x1
.has_value() && !x2
.has_value(),
33 "Default construction and hasValue() are contexpr");
34 constexpr auto y1
= Optional
<int>(3);
35 constexpr Optional
<int> y2
{3};
36 static_assert(y1
.value() == y2
.value() && y1
.value() == 3,
37 "Construction with value and getValue() are constexpr");
38 static_assert(y1
.value() == y2
.value() && y1
.value() == 3,
39 "Construction with value and getValue() are constexpr");
40 static_assert(Optional
<int>{3} >= 2 && Optional
<int>{1} < Optional
<int>{2},
41 "Comparisons work in constexpr");
46 struct NonDefaultConstructible
{
47 static unsigned CopyConstructions
;
48 static unsigned Destructions
;
49 static unsigned CopyAssignments
;
50 explicit NonDefaultConstructible(int) {
52 NonDefaultConstructible(const NonDefaultConstructible
&) {
55 NonDefaultConstructible
&operator=(const NonDefaultConstructible
&) {
59 ~NonDefaultConstructible() {
62 static void ResetCounts() {
63 CopyConstructions
= 0;
69 unsigned NonDefaultConstructible::CopyConstructions
= 0;
70 unsigned NonDefaultConstructible::Destructions
= 0;
71 unsigned NonDefaultConstructible::CopyAssignments
= 0;
74 !std::is_trivially_copyable
<Optional
<NonDefaultConstructible
>>::value
,
75 "not trivially copyable");
77 TEST(OptionalTest
, NonDefaultConstructibleTest
) {
78 Optional
<NonDefaultConstructible
> O
;
82 TEST(OptionalTest
, ResetTest
) {
83 NonDefaultConstructible::ResetCounts();
84 Optional
<NonDefaultConstructible
> O(NonDefaultConstructible(3));
85 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions
);
86 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments
);
87 EXPECT_EQ(1u, NonDefaultConstructible::Destructions
);
88 NonDefaultConstructible::ResetCounts();
90 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions
);
91 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments
);
92 EXPECT_EQ(1u, NonDefaultConstructible::Destructions
);
95 TEST(OptionalTest
, InitializationLeakTest
) {
96 NonDefaultConstructible::ResetCounts();
97 Optional
<NonDefaultConstructible
>(NonDefaultConstructible(3));
98 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions
);
99 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments
);
100 EXPECT_EQ(2u, NonDefaultConstructible::Destructions
);
103 TEST(OptionalTest
, CopyConstructionTest
) {
104 NonDefaultConstructible::ResetCounts();
106 Optional
<NonDefaultConstructible
> A(NonDefaultConstructible(3));
107 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions
);
108 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments
);
109 EXPECT_EQ(1u, NonDefaultConstructible::Destructions
);
110 NonDefaultConstructible::ResetCounts();
111 Optional
<NonDefaultConstructible
> B(A
);
112 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions
);
113 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments
);
114 EXPECT_EQ(0u, NonDefaultConstructible::Destructions
);
115 NonDefaultConstructible::ResetCounts();
117 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions
);
118 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments
);
119 EXPECT_EQ(2u, NonDefaultConstructible::Destructions
);
122 TEST(OptionalTest
, ConstructingCopyAssignmentTest
) {
123 NonDefaultConstructible::ResetCounts();
125 Optional
<NonDefaultConstructible
> A(NonDefaultConstructible(3));
126 Optional
<NonDefaultConstructible
> B
;
127 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions
);
128 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments
);
129 EXPECT_EQ(1u, NonDefaultConstructible::Destructions
);
130 NonDefaultConstructible::ResetCounts();
132 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions
);
133 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments
);
134 EXPECT_EQ(0u, NonDefaultConstructible::Destructions
);
135 NonDefaultConstructible::ResetCounts();
137 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions
);
138 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments
);
139 EXPECT_EQ(2u, NonDefaultConstructible::Destructions
);
142 TEST(OptionalTest
, CopyingCopyAssignmentTest
) {
143 NonDefaultConstructible::ResetCounts();
145 Optional
<NonDefaultConstructible
> A(NonDefaultConstructible(3));
146 Optional
<NonDefaultConstructible
> B(NonDefaultConstructible(4));
147 EXPECT_EQ(2u, NonDefaultConstructible::CopyConstructions
);
148 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments
);
149 EXPECT_EQ(2u, NonDefaultConstructible::Destructions
);
150 NonDefaultConstructible::ResetCounts();
152 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions
);
153 EXPECT_EQ(1u, NonDefaultConstructible::CopyAssignments
);
154 EXPECT_EQ(0u, NonDefaultConstructible::Destructions
);
155 NonDefaultConstructible::ResetCounts();
157 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions
);
158 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments
);
159 EXPECT_EQ(2u, NonDefaultConstructible::Destructions
);
162 TEST(OptionalTest
, DeletingCopyAssignmentTest
) {
163 NonDefaultConstructible::ResetCounts();
165 Optional
<NonDefaultConstructible
> A
;
166 Optional
<NonDefaultConstructible
> B(NonDefaultConstructible(3));
167 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions
);
168 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments
);
169 EXPECT_EQ(1u, NonDefaultConstructible::Destructions
);
170 NonDefaultConstructible::ResetCounts();
172 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions
);
173 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments
);
174 EXPECT_EQ(1u, NonDefaultConstructible::Destructions
);
175 NonDefaultConstructible::ResetCounts();
177 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions
);
178 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments
);
179 EXPECT_EQ(0u, NonDefaultConstructible::Destructions
);
182 TEST(OptionalTest
, NullCopyConstructionTest
) {
183 NonDefaultConstructible::ResetCounts();
185 Optional
<NonDefaultConstructible
> A
;
186 Optional
<NonDefaultConstructible
> B
;
187 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions
);
188 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments
);
189 EXPECT_EQ(0u, NonDefaultConstructible::Destructions
);
190 NonDefaultConstructible::ResetCounts();
192 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions
);
193 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments
);
194 EXPECT_EQ(0u, NonDefaultConstructible::Destructions
);
195 NonDefaultConstructible::ResetCounts();
197 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions
);
198 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments
);
199 EXPECT_EQ(0u, NonDefaultConstructible::Destructions
);
202 TEST(OptionalTest
, InPlaceConstructionNonDefaultConstructibleTest
) {
203 NonDefaultConstructible::ResetCounts();
204 { Optional
<NonDefaultConstructible
> A
{std::in_place
, 1}; }
205 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions
);
206 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments
);
207 EXPECT_EQ(1u, NonDefaultConstructible::Destructions
);
210 TEST(OptionalTest
, GetValueOr
) {
212 EXPECT_EQ(42, A
.value_or(42));
215 EXPECT_EQ(5, A
.value_or(42));
218 struct MultiArgConstructor
{
220 MultiArgConstructor(int x
, int y
) : x(x
), y(y
) {}
221 explicit MultiArgConstructor(int x
, bool positive
)
222 : x(x
), y(positive
? x
: -x
) {}
224 MultiArgConstructor(const MultiArgConstructor
&) = delete;
225 MultiArgConstructor(MultiArgConstructor
&&) = delete;
226 MultiArgConstructor
&operator=(const MultiArgConstructor
&) = delete;
227 MultiArgConstructor
&operator=(MultiArgConstructor
&&) = delete;
229 friend bool operator==(const MultiArgConstructor
&LHS
,
230 const MultiArgConstructor
&RHS
) {
231 return LHS
.x
== RHS
.x
&& LHS
.y
== RHS
.y
;
234 static unsigned Destructions
;
235 ~MultiArgConstructor() {
238 static void ResetCounts() {
242 unsigned MultiArgConstructor::Destructions
= 0;
244 static_assert(!std::is_trivially_copyable
<Optional
<MultiArgConstructor
>>::value
,
245 "not trivially copyable");
247 TEST(OptionalTest
, Emplace
) {
248 MultiArgConstructor::ResetCounts();
249 Optional
<MultiArgConstructor
> A
;
252 EXPECT_TRUE(A
.has_value());
253 EXPECT_TRUE(A
.has_value());
256 EXPECT_EQ(0u, MultiArgConstructor::Destructions
);
259 EXPECT_TRUE(A
.has_value());
260 EXPECT_TRUE(A
.has_value());
263 EXPECT_EQ(1u, MultiArgConstructor::Destructions
);
266 TEST(OptionalTest
, InPlaceConstructionMultiArgConstructorTest
) {
267 MultiArgConstructor::ResetCounts();
269 Optional
<MultiArgConstructor
> A
{std::in_place
, 1, 2};
270 EXPECT_TRUE(A
.has_value());
271 EXPECT_TRUE(A
.has_value());
274 Optional
<MultiArgConstructor
> B
{std::in_place
, 5, false};
275 EXPECT_TRUE(B
.has_value());
276 EXPECT_TRUE(B
.has_value());
279 EXPECT_EQ(0u, MultiArgConstructor::Destructions
);
281 EXPECT_EQ(2u, MultiArgConstructor::Destructions
);
284 TEST(OptionalTest
, InPlaceConstructionAndEmplaceEquivalentTest
) {
285 MultiArgConstructor::ResetCounts();
287 Optional
<MultiArgConstructor
> A
{std::in_place
, 1, 2};
288 Optional
<MultiArgConstructor
> B
;
290 EXPECT_EQ(0u, MultiArgConstructor::Destructions
);
293 EXPECT_EQ(2u, MultiArgConstructor::Destructions
);
297 static unsigned MoveConstructions
;
298 static unsigned Destructions
;
299 static unsigned MoveAssignments
;
301 explicit MoveOnly(int val
) : val(val
) {
303 MoveOnly(MoveOnly
&& other
) {
307 MoveOnly
&operator=(MoveOnly
&& other
) {
315 static void ResetCounts() {
316 MoveConstructions
= 0;
322 unsigned MoveOnly::MoveConstructions
= 0;
323 unsigned MoveOnly::Destructions
= 0;
324 unsigned MoveOnly::MoveAssignments
= 0;
326 static_assert(!std::is_trivially_copyable
<Optional
<MoveOnly
>>::value
,
327 "not trivially copyable");
329 TEST(OptionalTest
, MoveOnlyNull
) {
330 MoveOnly::ResetCounts();
331 Optional
<MoveOnly
> O
;
332 EXPECT_EQ(0u, MoveOnly::MoveConstructions
);
333 EXPECT_EQ(0u, MoveOnly::MoveAssignments
);
334 EXPECT_EQ(0u, MoveOnly::Destructions
);
337 TEST(OptionalTest
, MoveOnlyConstruction
) {
338 MoveOnly::ResetCounts();
339 Optional
<MoveOnly
> O(MoveOnly(3));
340 EXPECT_TRUE((bool)O
);
341 EXPECT_EQ(3, O
->val
);
342 EXPECT_EQ(1u, MoveOnly::MoveConstructions
);
343 EXPECT_EQ(0u, MoveOnly::MoveAssignments
);
344 EXPECT_EQ(1u, MoveOnly::Destructions
);
347 TEST(OptionalTest
, MoveOnlyMoveConstruction
) {
348 Optional
<MoveOnly
> A(MoveOnly(3));
349 MoveOnly::ResetCounts();
350 Optional
<MoveOnly
> B(std::move(A
));
351 EXPECT_TRUE((bool)A
);
352 EXPECT_TRUE((bool)B
);
353 EXPECT_EQ(3, B
->val
);
354 EXPECT_EQ(1u, MoveOnly::MoveConstructions
);
355 EXPECT_EQ(0u, MoveOnly::MoveAssignments
);
356 EXPECT_EQ(0u, MoveOnly::Destructions
);
359 TEST(OptionalTest
, MoveOnlyAssignment
) {
360 MoveOnly::ResetCounts();
361 Optional
<MoveOnly
> O
;
363 EXPECT_TRUE((bool)O
);
364 EXPECT_EQ(3, O
->val
);
365 EXPECT_EQ(1u, MoveOnly::MoveConstructions
);
366 EXPECT_EQ(0u, MoveOnly::MoveAssignments
);
367 EXPECT_EQ(1u, MoveOnly::Destructions
);
370 TEST(OptionalTest
, MoveOnlyInitializingAssignment
) {
371 Optional
<MoveOnly
> A(MoveOnly(3));
372 Optional
<MoveOnly
> B
;
373 MoveOnly::ResetCounts();
375 EXPECT_TRUE((bool)A
);
376 EXPECT_TRUE((bool)B
);
377 EXPECT_EQ(3, B
->val
);
378 EXPECT_EQ(1u, MoveOnly::MoveConstructions
);
379 EXPECT_EQ(0u, MoveOnly::MoveAssignments
);
380 EXPECT_EQ(0u, MoveOnly::Destructions
);
383 TEST(OptionalTest
, MoveOnlyNullingAssignment
) {
384 Optional
<MoveOnly
> A
;
385 Optional
<MoveOnly
> B(MoveOnly(3));
386 MoveOnly::ResetCounts();
388 EXPECT_FALSE((bool)A
);
389 EXPECT_FALSE((bool)B
);
390 EXPECT_EQ(0u, MoveOnly::MoveConstructions
);
391 EXPECT_EQ(0u, MoveOnly::MoveAssignments
);
392 EXPECT_EQ(1u, MoveOnly::Destructions
);
395 TEST(OptionalTest
, MoveOnlyAssigningAssignment
) {
396 Optional
<MoveOnly
> A(MoveOnly(3));
397 Optional
<MoveOnly
> B(MoveOnly(4));
398 MoveOnly::ResetCounts();
400 EXPECT_TRUE((bool)A
);
401 EXPECT_TRUE((bool)B
);
402 EXPECT_EQ(3, B
->val
);
403 EXPECT_EQ(0u, MoveOnly::MoveConstructions
);
404 EXPECT_EQ(1u, MoveOnly::MoveAssignments
);
405 EXPECT_EQ(0u, MoveOnly::Destructions
);
409 static unsigned Constructions
;
410 static unsigned Destructions
;
412 explicit Immovable(int val
) : val(val
) {
418 static void ResetCounts() {
423 // This should disable all move/copy operations.
424 Immovable(Immovable
&& other
) = delete;
427 unsigned Immovable::Constructions
= 0;
428 unsigned Immovable::Destructions
= 0;
430 static_assert(!std::is_trivially_copyable
<Optional
<Immovable
>>::value
,
431 "not trivially copyable");
433 TEST(OptionalTest
, ImmovableEmplace
) {
434 Optional
<Immovable
> A
;
435 Immovable::ResetCounts();
437 EXPECT_TRUE((bool)A
);
438 EXPECT_EQ(4, A
->val
);
439 EXPECT_EQ(1u, Immovable::Constructions
);
440 EXPECT_EQ(0u, Immovable::Destructions
);
443 TEST(OptionalTest
, ImmovableInPlaceConstruction
) {
444 Immovable::ResetCounts();
445 Optional
<Immovable
> A
{std::in_place
, 4};
446 EXPECT_TRUE((bool)A
);
447 EXPECT_EQ(4, A
->val
);
448 EXPECT_EQ(1u, Immovable::Constructions
);
449 EXPECT_EQ(0u, Immovable::Destructions
);
452 // Craft a class which is_trivially_copyable, but not
453 // is_trivially_copy_constructible.
455 NonTCopy() = default;
457 // Delete the volatile copy constructor to engage the "rule of 3" and delete
458 // any unspecified copy assignment or constructor.
459 NonTCopy(volatile NonTCopy
const &) = delete;
461 // Leave the non-volatile default copy constructor unspecified (deleted by
464 // This template can serve as the copy constructor, but isn't chosen
465 // by =default in a class with a 'NonTCopy' member.
466 template <typename Self
= NonTCopy
>
467 NonTCopy(Self
const &Other
) : Val(Other
.Val
) {}
469 NonTCopy
&operator=(NonTCopy
const &) = default;
474 #if defined(_MSC_VER) && _MSC_VER >= 1927 && !defined(__clang__)
475 // Currently only true on recent MSVC releases.
476 static_assert(std::is_trivially_copyable
<NonTCopy
>::value
,
477 "Expect NonTCopy to be trivially copyable");
479 static_assert(!std::is_trivially_copy_constructible
<NonTCopy
>::value
,
480 "Expect NonTCopy not to be trivially copy constructible.");
481 #endif // defined(_MSC_VER) && _MSC_VER >= 1927
483 TEST(OptionalTest
, DeletedCopyConstructor
) {
485 // Expect compile to fail if 'trivial' version of
486 // optional_detail::OptionalStorage is chosen.
487 using NonTCopyOptT
= Optional
<NonTCopy
>;
488 NonTCopyOptT NonTCopy1
;
490 // Check that the Optional can be copy constructed.
491 NonTCopyOptT NonTCopy2
{NonTCopy1
};
493 // Check that the Optional can be copy assigned.
494 NonTCopy1
= NonTCopy2
;
497 // Craft a class which is_trivially_copyable, but not
498 // is_trivially_copy_assignable.
501 NonTAssign() = default;
502 NonTAssign(NonTAssign
const &) = default;
504 // Delete the volatile copy assignment to engage the "rule of 3" and delete
505 // any unspecified copy assignment or constructor.
506 NonTAssign
&operator=(volatile NonTAssign
const &) = delete;
508 // Leave the non-volatile default copy assignment unspecified (deleted by rule
511 // This template can serve as the copy assignment, but isn't chosen
512 // by =default in a class with a 'NonTAssign' member.
513 template <typename Self
= NonTAssign
>
514 NonTAssign
&operator=(Self
const &Other
) {
522 #if defined(_MSC_VER) && _MSC_VER >= 1927 && !defined(__clang__)
523 // Currently only true on recent MSVC releases.
524 static_assert(std::is_trivially_copyable
<NonTAssign
>::value
,
525 "Expect NonTAssign to be trivially copyable");
527 static_assert(!std::is_trivially_copy_assignable
<NonTAssign
>::value
,
528 "Expect NonTAssign not to be trivially assignable.");
529 #endif // defined(_MSC_VER) && _MSC_VER >= 1927
531 TEST(OptionalTest
, DeletedCopyAssignment
) {
533 // Expect compile to fail if 'trivial' version of
534 // optional_detail::OptionalStorage is chosen.
535 using NonTAssignOptT
= Optional
<NonTAssign
>;
536 NonTAssignOptT NonTAssign1
;
538 // Check that the Optional can be copy constructed.
539 NonTAssignOptT NonTAssign2
{NonTAssign1
};
541 // Check that the Optional can be copy assigned.
542 NonTAssign1
= NonTAssign2
;
547 NoTMove(NoTMove
const &) = default;
548 NoTMove
&operator=(NoTMove
const &) = default;
550 // Delete move constructor / assignment. Compiler should fall-back to the
551 // trivial copy constructor / assignment in the trivial OptionalStorage
553 NoTMove(NoTMove
&&) = delete;
554 NoTMove
&operator=(NoTMove
&&) = delete;
559 TEST(OptionalTest
, DeletedMoveConstructor
) {
560 using NoTMoveOptT
= Optional
<NoTMove
>;
562 NoTMoveOptT NonTMove1
;
563 NoTMoveOptT NonTMove2
{std::move(NonTMove1
)};
565 NonTMove1
= std::move(NonTMove2
);
568 std::is_trivially_copyable
<NoTMoveOptT
>::value
,
569 "Expect Optional<NoTMove> to still use the trivial specialization "
570 "of OptionalStorage despite the deleted move constructor / assignment.");
573 class NoCopyStringMap
{
575 NoCopyStringMap() = default;
578 llvm::StringMap
<std::unique_ptr
<int>> Map
;
581 TEST(OptionalTest
, DeletedCopyStringMap
) {
582 // Old versions of gcc (7.3 and prior) instantiate the copy constructor when
583 // std::is_trivially_copyable is instantiated. This test will fail
584 // compilation if std::is_trivially_copyable is used in the OptionalStorage
585 // specialization condition by gcc <= 7.3.
586 Optional
<NoCopyStringMap
> TestInstantiation
;
589 TEST(OptionalTest
, MoveValueOr
) {
590 Optional
<MoveOnly
> A
;
592 MoveOnly::ResetCounts();
593 EXPECT_EQ(42, std::move(A
).value_or(MoveOnly(42)).val
);
594 EXPECT_EQ(1u, MoveOnly::MoveConstructions
);
595 EXPECT_EQ(0u, MoveOnly::MoveAssignments
);
596 EXPECT_EQ(2u, MoveOnly::Destructions
);
599 MoveOnly::ResetCounts();
600 EXPECT_EQ(5, std::move(A
).value_or(MoveOnly(42)).val
);
601 EXPECT_EQ(1u, MoveOnly::MoveConstructions
);
602 EXPECT_EQ(0u, MoveOnly::MoveAssignments
);
603 EXPECT_EQ(2u, MoveOnly::Destructions
);
606 TEST(OptionalTest
, Transform
) {
609 Optional
<int> B
= A
.transform([&](int N
) { return N
+ 1; });
610 EXPECT_FALSE(B
.has_value());
613 Optional
<int> C
= A
.transform([&](int N
) { return N
+ 1; });
614 EXPECT_TRUE(C
.has_value());
615 EXPECT_EQ(4, C
.value());
618 TEST(OptionalTest
, MoveTransform
) {
619 Optional
<MoveOnly
> A
;
621 MoveOnly::ResetCounts();
623 std::move(A
).transform([&](const MoveOnly
&M
) { return M
.val
+ 2; });
624 EXPECT_FALSE(B
.has_value());
625 EXPECT_EQ(0u, MoveOnly::MoveConstructions
);
626 EXPECT_EQ(0u, MoveOnly::MoveAssignments
);
627 EXPECT_EQ(0u, MoveOnly::Destructions
);
630 MoveOnly::ResetCounts();
632 std::move(A
).transform([&](const MoveOnly
&M
) { return M
.val
+ 2; });
633 EXPECT_TRUE(C
.has_value());
634 EXPECT_EQ(7, C
.value());
635 EXPECT_EQ(0u, MoveOnly::MoveConstructions
);
636 EXPECT_EQ(0u, MoveOnly::MoveAssignments
);
637 EXPECT_EQ(0u, MoveOnly::Destructions
);
641 template <typename T
, typename U
> static bool apply(const T
&X
, const U
&Y
) {
647 template <typename T
, typename U
> static bool apply(const T
&X
, const U
&Y
) {
653 template <typename T
, typename U
> static bool apply(const T
&X
, const U
&Y
) {
659 template <typename T
, typename U
> static bool apply(const T
&X
, const U
&Y
) {
665 template <typename T
, typename U
> static bool apply(const T
&X
, const U
&Y
) {
670 struct GreaterEqual
{
671 template <typename T
, typename U
> static bool apply(const T
&X
, const U
&Y
) {
676 template <typename OperatorT
, typename T
>
677 void CheckRelation(const Optional
<T
> &Lhs
, const Optional
<T
> &Rhs
,
679 EXPECT_EQ(Expected
, OperatorT::apply(Lhs
, Rhs
));
682 EXPECT_EQ(Expected
, OperatorT::apply(*Lhs
, Rhs
));
684 EXPECT_EQ(Expected
, OperatorT::apply(None
, Rhs
));
687 EXPECT_EQ(Expected
, OperatorT::apply(Lhs
, *Rhs
));
689 EXPECT_EQ(Expected
, OperatorT::apply(Lhs
, None
));
692 struct EqualityMock
{};
693 const Optional
<EqualityMock
> NoneEq
, EqualityLhs((EqualityMock())),
694 EqualityRhs((EqualityMock()));
697 bool operator==(const EqualityMock
&Lhs
, const EqualityMock
&Rhs
) {
698 EXPECT_EQ(&*EqualityLhs
, &Lhs
);
699 EXPECT_EQ(&*EqualityRhs
, &Rhs
);
703 TEST(OptionalTest
, OperatorEqual
) {
704 CheckRelation
<EqualTo
>(NoneEq
, NoneEq
, true);
705 CheckRelation
<EqualTo
>(NoneEq
, EqualityRhs
, false);
706 CheckRelation
<EqualTo
>(EqualityLhs
, NoneEq
, false);
709 CheckRelation
<EqualTo
>(EqualityLhs
, EqualityRhs
, IsEqual
);
711 CheckRelation
<EqualTo
>(EqualityLhs
, EqualityRhs
, IsEqual
);
714 TEST(OptionalTest
, OperatorNotEqual
) {
715 CheckRelation
<NotEqualTo
>(NoneEq
, NoneEq
, false);
716 CheckRelation
<NotEqualTo
>(NoneEq
, EqualityRhs
, true);
717 CheckRelation
<NotEqualTo
>(EqualityLhs
, NoneEq
, true);
720 CheckRelation
<NotEqualTo
>(EqualityLhs
, EqualityRhs
, !IsEqual
);
722 CheckRelation
<NotEqualTo
>(EqualityLhs
, EqualityRhs
, !IsEqual
);
725 struct InequalityMock
{};
726 const Optional
<InequalityMock
> NoneIneq
, InequalityLhs((InequalityMock())),
727 InequalityRhs((InequalityMock()));
730 bool operator<(const InequalityMock
&Lhs
, const InequalityMock
&Rhs
) {
731 EXPECT_EQ(&*InequalityLhs
, &Lhs
);
732 EXPECT_EQ(&*InequalityRhs
, &Rhs
);
736 TEST(OptionalTest
, OperatorLess
) {
737 CheckRelation
<Less
>(NoneIneq
, NoneIneq
, false);
738 CheckRelation
<Less
>(NoneIneq
, InequalityRhs
, true);
739 CheckRelation
<Less
>(InequalityLhs
, NoneIneq
, false);
742 CheckRelation
<Less
>(InequalityLhs
, InequalityRhs
, IsLess
);
744 CheckRelation
<Less
>(InequalityLhs
, InequalityRhs
, IsLess
);
747 TEST(OptionalTest
, OperatorGreater
) {
748 CheckRelation
<Greater
>(NoneIneq
, NoneIneq
, false);
749 CheckRelation
<Greater
>(NoneIneq
, InequalityRhs
, false);
750 CheckRelation
<Greater
>(InequalityLhs
, NoneIneq
, true);
753 CheckRelation
<Greater
>(InequalityRhs
, InequalityLhs
, IsLess
);
755 CheckRelation
<Greater
>(InequalityRhs
, InequalityLhs
, IsLess
);
758 TEST(OptionalTest
, OperatorLessEqual
) {
759 CheckRelation
<LessEqual
>(NoneIneq
, NoneIneq
, true);
760 CheckRelation
<LessEqual
>(NoneIneq
, InequalityRhs
, true);
761 CheckRelation
<LessEqual
>(InequalityLhs
, NoneIneq
, false);
764 CheckRelation
<LessEqual
>(InequalityRhs
, InequalityLhs
, !IsLess
);
766 CheckRelation
<LessEqual
>(InequalityRhs
, InequalityLhs
, !IsLess
);
769 TEST(OptionalTest
, OperatorGreaterEqual
) {
770 CheckRelation
<GreaterEqual
>(NoneIneq
, NoneIneq
, true);
771 CheckRelation
<GreaterEqual
>(NoneIneq
, InequalityRhs
, false);
772 CheckRelation
<GreaterEqual
>(InequalityLhs
, NoneIneq
, true);
775 CheckRelation
<GreaterEqual
>(InequalityLhs
, InequalityRhs
, !IsLess
);
777 CheckRelation
<GreaterEqual
>(InequalityLhs
, InequalityRhs
, !IsLess
);
780 struct ComparableAndStreamable
{
781 friend bool operator==(ComparableAndStreamable
,
782 ComparableAndStreamable
) LLVM_ATTRIBUTE_USED
{
786 friend raw_ostream
&operator<<(raw_ostream
&OS
, ComparableAndStreamable
) {
787 return OS
<< "ComparableAndStreamable";
790 static Optional
<ComparableAndStreamable
> get() {
791 return ComparableAndStreamable();
795 TEST(OptionalTest
, StreamOperator
) {
796 auto to_string
= [](Optional
<ComparableAndStreamable
> O
) {
798 raw_svector_ostream
OS(S
);
802 EXPECT_EQ("ComparableAndStreamable",
803 to_string(ComparableAndStreamable::get()));
804 EXPECT_EQ("None", to_string(None
));
808 friend bool operator==(Comparable
, Comparable
) LLVM_ATTRIBUTE_USED
{
811 static Optional
<Comparable
> get() { return Comparable(); }
814 TEST(OptionalTest
, UseInUnitTests
) {
815 // Test that we invoke the streaming operators when pretty-printing values in
817 EXPECT_NONFATAL_FAILURE(EXPECT_EQ(llvm::None
, ComparableAndStreamable::get()),
818 "Expected equality of these values:\n"
821 " ComparableAndStreamable::get()\n"
822 " Which is: ComparableAndStreamable");
824 // Test that it is still possible to compare objects which do not have a
825 // custom streaming operator.
826 EXPECT_NONFATAL_FAILURE(EXPECT_EQ(llvm::None
, Comparable::get()), "object");
829 TEST(OptionalTest
, HashValue
) {
830 // Check that None, false, and true all hash differently.
831 Optional
<bool> B
, B0
= false, B1
= true;
832 EXPECT_NE(hash_value(B0
), hash_value(B
));
833 EXPECT_NE(hash_value(B1
), hash_value(B
));
834 EXPECT_NE(hash_value(B1
), hash_value(B0
));
836 // Check that None, 0, and 1 all hash differently.
837 Optional
<int> I
, I0
= 0, I1
= 1;
838 EXPECT_NE(hash_value(I0
), hash_value(I
));
839 EXPECT_NE(hash_value(I1
), hash_value(I
));
840 EXPECT_NE(hash_value(I1
), hash_value(I0
));
842 // Check None hash the same way regardless of type.
843 EXPECT_EQ(hash_value(B
), hash_value(I
));
846 struct NotTriviallyCopyable
{
847 NotTriviallyCopyable(); // Constructor out-of-line.
848 virtual ~NotTriviallyCopyable() = default;
849 Optional
<MoveOnly
> MO
;
852 TEST(OptionalTest
, GCCIsTriviallyMoveConstructibleCompat
) {
853 Optional
<NotTriviallyCopyable
> V
;
857 } // end anonymous namespace