[docs] Fix build-docs.sh
[llvm-project.git] / llvm / unittests / ADT / OptionalTest.cpp
blobc583ff0df9af16feab7ba9b0802aa3e9594422ed
1 //===- llvm/unittest/ADT/OptionalTest.cpp - Optional unit tests -----------===//
2 //
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
6 //
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"
16 #include <array>
17 #include <utility>
19 using namespace llvm;
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");
44 namespace {
46 struct NonDefaultConstructible {
47 static unsigned CopyConstructions;
48 static unsigned Destructions;
49 static unsigned CopyAssignments;
50 explicit NonDefaultConstructible(int) {
52 NonDefaultConstructible(const NonDefaultConstructible&) {
53 ++CopyConstructions;
55 NonDefaultConstructible &operator=(const NonDefaultConstructible&) {
56 ++CopyAssignments;
57 return *this;
59 ~NonDefaultConstructible() {
60 ++Destructions;
62 static void ResetCounts() {
63 CopyConstructions = 0;
64 Destructions = 0;
65 CopyAssignments = 0;
69 unsigned NonDefaultConstructible::CopyConstructions = 0;
70 unsigned NonDefaultConstructible::Destructions = 0;
71 unsigned NonDefaultConstructible::CopyAssignments = 0;
73 static_assert(
74 !std::is_trivially_copyable<Optional<NonDefaultConstructible>>::value,
75 "not trivially copyable");
77 TEST(OptionalTest, NonDefaultConstructibleTest) {
78 Optional<NonDefaultConstructible> O;
79 EXPECT_FALSE(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();
89 O.reset();
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();
131 B = A;
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();
151 B = A;
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();
171 B = A;
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();
191 B = A;
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) {
211 Optional<int> A;
212 EXPECT_EQ(42, A.value_or(42));
214 A = 5;
215 EXPECT_EQ(5, A.value_or(42));
218 struct MultiArgConstructor {
219 int x, y;
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() {
236 ++Destructions;
238 static void ResetCounts() {
239 Destructions = 0;
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;
251 A.emplace(1, 2);
252 EXPECT_TRUE(A.has_value());
253 EXPECT_TRUE(A.has_value());
254 EXPECT_EQ(1, A->x);
255 EXPECT_EQ(2, A->y);
256 EXPECT_EQ(0u, MultiArgConstructor::Destructions);
258 A.emplace(5, false);
259 EXPECT_TRUE(A.has_value());
260 EXPECT_TRUE(A.has_value());
261 EXPECT_EQ(5, A->x);
262 EXPECT_EQ(-5, A->y);
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());
272 EXPECT_EQ(1, A->x);
273 EXPECT_EQ(2, A->y);
274 Optional<MultiArgConstructor> B{std::in_place, 5, false};
275 EXPECT_TRUE(B.has_value());
276 EXPECT_TRUE(B.has_value());
277 EXPECT_EQ(5, B->x);
278 EXPECT_EQ(-5, B->y);
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;
289 B.emplace(1, 2);
290 EXPECT_EQ(0u, MultiArgConstructor::Destructions);
291 ASSERT_EQ(A, B);
293 EXPECT_EQ(2u, MultiArgConstructor::Destructions);
296 struct MoveOnly {
297 static unsigned MoveConstructions;
298 static unsigned Destructions;
299 static unsigned MoveAssignments;
300 int val;
301 explicit MoveOnly(int val) : val(val) {
303 MoveOnly(MoveOnly&& other) {
304 val = other.val;
305 ++MoveConstructions;
307 MoveOnly &operator=(MoveOnly&& other) {
308 val = other.val;
309 ++MoveAssignments;
310 return *this;
312 ~MoveOnly() {
313 ++Destructions;
315 static void ResetCounts() {
316 MoveConstructions = 0;
317 Destructions = 0;
318 MoveAssignments = 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;
362 O = MoveOnly(3);
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();
374 B = std::move(A);
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();
387 B = std::move(A);
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();
399 B = std::move(A);
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);
408 struct Immovable {
409 static unsigned Constructions;
410 static unsigned Destructions;
411 int val;
412 explicit Immovable(int val) : val(val) {
413 ++Constructions;
415 ~Immovable() {
416 ++Destructions;
418 static void ResetCounts() {
419 Constructions = 0;
420 Destructions = 0;
422 private:
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();
436 A.emplace(4);
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.
454 struct NonTCopy {
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
462 // rule of 3)
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;
471 int Val{0};
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.
499 class NonTAssign {
500 public:
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
509 // of 3).
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) {
515 A = Other.A;
516 return *this;
519 int A{0};
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;
545 struct NoTMove {
546 NoTMove() = default;
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
552 // specialization.
553 NoTMove(NoTMove &&) = delete;
554 NoTMove &operator=(NoTMove &&) = delete;
556 int Val{0};
559 TEST(OptionalTest, DeletedMoveConstructor) {
560 using NoTMoveOptT = Optional<NoTMove>;
562 NoTMoveOptT NonTMove1;
563 NoTMoveOptT NonTMove2{std::move(NonTMove1)};
565 NonTMove1 = std::move(NonTMove2);
567 static_assert(
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 {
574 public:
575 NoCopyStringMap() = default;
577 private:
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);
598 A = MoveOnly(5);
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) {
607 Optional<int> A;
609 Optional<int> B = A.transform([&](int N) { return N + 1; });
610 EXPECT_FALSE(B.has_value());
612 A = 3;
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();
622 Optional<int> B =
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);
629 A = MoveOnly(5);
630 MoveOnly::ResetCounts();
631 Optional<int> C =
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);
640 struct EqualTo {
641 template <typename T, typename U> static bool apply(const T &X, const U &Y) {
642 return X == Y;
646 struct NotEqualTo {
647 template <typename T, typename U> static bool apply(const T &X, const U &Y) {
648 return X != Y;
652 struct Less {
653 template <typename T, typename U> static bool apply(const T &X, const U &Y) {
654 return X < Y;
658 struct Greater {
659 template <typename T, typename U> static bool apply(const T &X, const U &Y) {
660 return X > Y;
664 struct LessEqual {
665 template <typename T, typename U> static bool apply(const T &X, const U &Y) {
666 return X <= Y;
670 struct GreaterEqual {
671 template <typename T, typename U> static bool apply(const T &X, const U &Y) {
672 return X >= Y;
676 template <typename OperatorT, typename T>
677 void CheckRelation(const Optional<T> &Lhs, const Optional<T> &Rhs,
678 bool Expected) {
679 EXPECT_EQ(Expected, OperatorT::apply(Lhs, Rhs));
681 if (Lhs)
682 EXPECT_EQ(Expected, OperatorT::apply(*Lhs, Rhs));
683 else
684 EXPECT_EQ(Expected, OperatorT::apply(None, Rhs));
686 if (Rhs)
687 EXPECT_EQ(Expected, OperatorT::apply(Lhs, *Rhs));
688 else
689 EXPECT_EQ(Expected, OperatorT::apply(Lhs, None));
692 struct EqualityMock {};
693 const Optional<EqualityMock> NoneEq, EqualityLhs((EqualityMock())),
694 EqualityRhs((EqualityMock()));
695 bool IsEqual;
697 bool operator==(const EqualityMock &Lhs, const EqualityMock &Rhs) {
698 EXPECT_EQ(&*EqualityLhs, &Lhs);
699 EXPECT_EQ(&*EqualityRhs, &Rhs);
700 return IsEqual;
703 TEST(OptionalTest, OperatorEqual) {
704 CheckRelation<EqualTo>(NoneEq, NoneEq, true);
705 CheckRelation<EqualTo>(NoneEq, EqualityRhs, false);
706 CheckRelation<EqualTo>(EqualityLhs, NoneEq, false);
708 IsEqual = false;
709 CheckRelation<EqualTo>(EqualityLhs, EqualityRhs, IsEqual);
710 IsEqual = true;
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);
719 IsEqual = false;
720 CheckRelation<NotEqualTo>(EqualityLhs, EqualityRhs, !IsEqual);
721 IsEqual = true;
722 CheckRelation<NotEqualTo>(EqualityLhs, EqualityRhs, !IsEqual);
725 struct InequalityMock {};
726 const Optional<InequalityMock> NoneIneq, InequalityLhs((InequalityMock())),
727 InequalityRhs((InequalityMock()));
728 bool IsLess;
730 bool operator<(const InequalityMock &Lhs, const InequalityMock &Rhs) {
731 EXPECT_EQ(&*InequalityLhs, &Lhs);
732 EXPECT_EQ(&*InequalityRhs, &Rhs);
733 return IsLess;
736 TEST(OptionalTest, OperatorLess) {
737 CheckRelation<Less>(NoneIneq, NoneIneq, false);
738 CheckRelation<Less>(NoneIneq, InequalityRhs, true);
739 CheckRelation<Less>(InequalityLhs, NoneIneq, false);
741 IsLess = false;
742 CheckRelation<Less>(InequalityLhs, InequalityRhs, IsLess);
743 IsLess = true;
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);
752 IsLess = false;
753 CheckRelation<Greater>(InequalityRhs, InequalityLhs, IsLess);
754 IsLess = true;
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);
763 IsLess = false;
764 CheckRelation<LessEqual>(InequalityRhs, InequalityLhs, !IsLess);
765 IsLess = true;
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);
774 IsLess = false;
775 CheckRelation<GreaterEqual>(InequalityLhs, InequalityRhs, !IsLess);
776 IsLess = true;
777 CheckRelation<GreaterEqual>(InequalityLhs, InequalityRhs, !IsLess);
780 struct ComparableAndStreamable {
781 friend bool operator==(ComparableAndStreamable,
782 ComparableAndStreamable) LLVM_ATTRIBUTE_USED {
783 return true;
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) {
797 SmallString<16> S;
798 raw_svector_ostream OS(S);
799 OS << O;
800 return S;
802 EXPECT_EQ("ComparableAndStreamable",
803 to_string(ComparableAndStreamable::get()));
804 EXPECT_EQ("None", to_string(None));
807 struct Comparable {
808 friend bool operator==(Comparable, Comparable) LLVM_ATTRIBUTE_USED {
809 return true;
811 static Optional<Comparable> get() { return Comparable(); }
814 TEST(OptionalTest, UseInUnitTests) {
815 // Test that we invoke the streaming operators when pretty-printing values in
816 // EXPECT macros.
817 EXPECT_NONFATAL_FAILURE(EXPECT_EQ(llvm::None, ComparableAndStreamable::get()),
818 "Expected equality of these values:\n"
819 " llvm::None\n"
820 " Which is: None\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;
854 EXPECT_FALSE(V);
857 } // end anonymous namespace