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 //===----------------------------------------------------------------------===//
8 
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"
15 
16 #include <array>
17 
18 
19 using namespace llvm;
20 
21 static_assert(std::is_trivially_copyable<Optional<int>>::value,
22               "trivially copyable");
23 
24 static_assert(std::is_trivially_copyable<Optional<std::array<int, 3>>>::value,
25               "trivially copyable");
26 
27 void OptionalWorksInConstexpr() {
28   constexpr auto x1 = Optional<int>();
29   constexpr Optional<int> x2{};
30   static_assert(!x1.hasValue() && !x2.hasValue(),
31                 "Default construction and hasValue() are contexpr");
32   constexpr auto y1 = Optional<int>(3);
33   constexpr Optional<int> y2{3};
34   static_assert(y1.getValue() == y2.getValue() && y1.getValue() == 3,
35                 "Construction with value and getValue() are constexpr");
36   static_assert(Optional<int>{3} >= 2 && Optional<int>{1} < Optional<int>{2},
37                 "Comparisons work in constexpr");
38 }
39 
40 namespace {
41 
42 struct NonDefaultConstructible {
43   static unsigned CopyConstructions;
44   static unsigned Destructions;
45   static unsigned CopyAssignments;
46   explicit NonDefaultConstructible(int) {
47   }
48   NonDefaultConstructible(const NonDefaultConstructible&) {
49     ++CopyConstructions;
50   }
51   NonDefaultConstructible &operator=(const NonDefaultConstructible&) {
52     ++CopyAssignments;
53     return *this;
54   }
55   ~NonDefaultConstructible() {
56     ++Destructions;
57   }
58   static void ResetCounts() {
59     CopyConstructions = 0;
60     Destructions = 0;
61     CopyAssignments = 0;
62   }
63 };
64 
65 unsigned NonDefaultConstructible::CopyConstructions = 0;
66 unsigned NonDefaultConstructible::Destructions = 0;
67 unsigned NonDefaultConstructible::CopyAssignments = 0;
68 
69 static_assert(
70     !std::is_trivially_copyable<Optional<NonDefaultConstructible>>::value,
71     "not trivially copyable");
72 
73 TEST(OptionalTest, NonDefaultConstructibleTest) {
74   Optional<NonDefaultConstructible> O;
75   EXPECT_FALSE(O);
76 }
77 
78 TEST(OptionalTest, ResetTest) {
79   NonDefaultConstructible::ResetCounts();
80   Optional<NonDefaultConstructible> O(NonDefaultConstructible(3));
81   EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
82   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
83   EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
84   NonDefaultConstructible::ResetCounts();
85   O.reset();
86   EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
87   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
88   EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
89 }
90 
91 TEST(OptionalTest, InitializationLeakTest) {
92   NonDefaultConstructible::ResetCounts();
93   Optional<NonDefaultConstructible>(NonDefaultConstructible(3));
94   EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
95   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
96   EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
97 }
98 
99 TEST(OptionalTest, CopyConstructionTest) {
100   NonDefaultConstructible::ResetCounts();
101   {
102     Optional<NonDefaultConstructible> A(NonDefaultConstructible(3));
103     EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
104     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
105     EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
106     NonDefaultConstructible::ResetCounts();
107     Optional<NonDefaultConstructible> B(A);
108     EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
109     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
110     EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
111     NonDefaultConstructible::ResetCounts();
112   }
113   EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
114   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
115   EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
116 }
117 
118 TEST(OptionalTest, ConstructingCopyAssignmentTest) {
119   NonDefaultConstructible::ResetCounts();
120   {
121     Optional<NonDefaultConstructible> A(NonDefaultConstructible(3));
122     Optional<NonDefaultConstructible> B;
123     EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
124     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
125     EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
126     NonDefaultConstructible::ResetCounts();
127     B = A;
128     EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
129     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
130     EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
131     NonDefaultConstructible::ResetCounts();
132   }
133   EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
134   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
135   EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
136 }
137 
138 TEST(OptionalTest, CopyingCopyAssignmentTest) {
139   NonDefaultConstructible::ResetCounts();
140   {
141     Optional<NonDefaultConstructible> A(NonDefaultConstructible(3));
142     Optional<NonDefaultConstructible> B(NonDefaultConstructible(4));
143     EXPECT_EQ(2u, NonDefaultConstructible::CopyConstructions);
144     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
145     EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
146     NonDefaultConstructible::ResetCounts();
147     B = A;
148     EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
149     EXPECT_EQ(1u, NonDefaultConstructible::CopyAssignments);
150     EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
151     NonDefaultConstructible::ResetCounts();
152   }
153   EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
154   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
155   EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
156 }
157 
158 TEST(OptionalTest, DeletingCopyAssignmentTest) {
159   NonDefaultConstructible::ResetCounts();
160   {
161     Optional<NonDefaultConstructible> A;
162     Optional<NonDefaultConstructible> B(NonDefaultConstructible(3));
163     EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
164     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
165     EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
166     NonDefaultConstructible::ResetCounts();
167     B = A;
168     EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
169     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
170     EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
171     NonDefaultConstructible::ResetCounts();
172   }
173   EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
174   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
175   EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
176 }
177 
178 TEST(OptionalTest, NullCopyConstructionTest) {
179   NonDefaultConstructible::ResetCounts();
180   {
181     Optional<NonDefaultConstructible> A;
182     Optional<NonDefaultConstructible> B;
183     EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
184     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
185     EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
186     NonDefaultConstructible::ResetCounts();
187     B = A;
188     EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
189     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
190     EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
191     NonDefaultConstructible::ResetCounts();
192   }
193   EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
194   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
195   EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
196 }
197 
198 TEST(OptionalTest, InPlaceConstructionNonDefaultConstructibleTest) {
199   NonDefaultConstructible::ResetCounts();
200   { Optional<NonDefaultConstructible> A{in_place, 1}; }
201   EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
202   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
203   EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
204 }
205 
206 TEST(OptionalTest, GetValueOr) {
207   Optional<int> A;
208   EXPECT_EQ(42, A.getValueOr(42));
209 
210   A = 5;
211   EXPECT_EQ(5, A.getValueOr(42));
212 }
213 
214 struct MultiArgConstructor {
215   int x, y;
216   MultiArgConstructor(int x, int y) : x(x), y(y) {}
217   explicit MultiArgConstructor(int x, bool positive)
218     : x(x), y(positive ? x : -x) {}
219 
220   MultiArgConstructor(const MultiArgConstructor &) = delete;
221   MultiArgConstructor(MultiArgConstructor &&) = delete;
222   MultiArgConstructor &operator=(const MultiArgConstructor &) = delete;
223   MultiArgConstructor &operator=(MultiArgConstructor &&) = delete;
224 
225   friend bool operator==(const MultiArgConstructor &LHS,
226                          const MultiArgConstructor &RHS) {
227     return LHS.x == RHS.x && LHS.y == RHS.y;
228   }
229 
230   static unsigned Destructions;
231   ~MultiArgConstructor() {
232     ++Destructions;
233   }
234   static void ResetCounts() {
235     Destructions = 0;
236   }
237 };
238 unsigned MultiArgConstructor::Destructions = 0;
239 
240 static_assert(!std::is_trivially_copyable<Optional<MultiArgConstructor>>::value,
241               "not trivially copyable");
242 
243 TEST(OptionalTest, Emplace) {
244   MultiArgConstructor::ResetCounts();
245   Optional<MultiArgConstructor> A;
246 
247   A.emplace(1, 2);
248   EXPECT_TRUE(A.hasValue());
249   EXPECT_EQ(1, A->x);
250   EXPECT_EQ(2, A->y);
251   EXPECT_EQ(0u, MultiArgConstructor::Destructions);
252 
253   A.emplace(5, false);
254   EXPECT_TRUE(A.hasValue());
255   EXPECT_EQ(5, A->x);
256   EXPECT_EQ(-5, A->y);
257   EXPECT_EQ(1u, MultiArgConstructor::Destructions);
258 }
259 
260 TEST(OptionalTest, InPlaceConstructionMultiArgConstructorTest) {
261   MultiArgConstructor::ResetCounts();
262   {
263     Optional<MultiArgConstructor> A{in_place, 1, 2};
264     EXPECT_TRUE(A.hasValue());
265     EXPECT_EQ(1, A->x);
266     EXPECT_EQ(2, A->y);
267     Optional<MultiArgConstructor> B{in_place, 5, false};
268     EXPECT_TRUE(B.hasValue());
269     EXPECT_EQ(5, B->x);
270     EXPECT_EQ(-5, B->y);
271     EXPECT_EQ(0u, MultiArgConstructor::Destructions);
272   }
273   EXPECT_EQ(2u, MultiArgConstructor::Destructions);
274 }
275 
276 TEST(OptionalTest, InPlaceConstructionAndEmplaceEquivalentTest) {
277   MultiArgConstructor::ResetCounts();
278   {
279     Optional<MultiArgConstructor> A{in_place, 1, 2};
280     Optional<MultiArgConstructor> B;
281     B.emplace(1, 2);
282     EXPECT_EQ(0u, MultiArgConstructor::Destructions);
283     ASSERT_EQ(A, B);
284   }
285   EXPECT_EQ(2u, MultiArgConstructor::Destructions);
286 }
287 
288 struct MoveOnly {
289   static unsigned MoveConstructions;
290   static unsigned Destructions;
291   static unsigned MoveAssignments;
292   int val;
293   explicit MoveOnly(int val) : val(val) {
294   }
295   MoveOnly(MoveOnly&& other) {
296     val = other.val;
297     ++MoveConstructions;
298   }
299   MoveOnly &operator=(MoveOnly&& other) {
300     val = other.val;
301     ++MoveAssignments;
302     return *this;
303   }
304   ~MoveOnly() {
305     ++Destructions;
306   }
307   static void ResetCounts() {
308     MoveConstructions = 0;
309     Destructions = 0;
310     MoveAssignments = 0;
311   }
312 };
313 
314 unsigned MoveOnly::MoveConstructions = 0;
315 unsigned MoveOnly::Destructions = 0;
316 unsigned MoveOnly::MoveAssignments = 0;
317 
318 static_assert(!std::is_trivially_copyable<Optional<MoveOnly>>::value,
319               "not trivially copyable");
320 
321 TEST(OptionalTest, MoveOnlyNull) {
322   MoveOnly::ResetCounts();
323   Optional<MoveOnly> O;
324   EXPECT_EQ(0u, MoveOnly::MoveConstructions);
325   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
326   EXPECT_EQ(0u, MoveOnly::Destructions);
327 }
328 
329 TEST(OptionalTest, MoveOnlyConstruction) {
330   MoveOnly::ResetCounts();
331   Optional<MoveOnly> O(MoveOnly(3));
332   EXPECT_TRUE((bool)O);
333   EXPECT_EQ(3, O->val);
334   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
335   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
336   EXPECT_EQ(1u, MoveOnly::Destructions);
337 }
338 
339 TEST(OptionalTest, MoveOnlyMoveConstruction) {
340   Optional<MoveOnly> A(MoveOnly(3));
341   MoveOnly::ResetCounts();
342   Optional<MoveOnly> B(std::move(A));
343   EXPECT_TRUE((bool)A);
344   EXPECT_TRUE((bool)B);
345   EXPECT_EQ(3, B->val);
346   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
347   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
348   EXPECT_EQ(0u, MoveOnly::Destructions);
349 }
350 
351 TEST(OptionalTest, MoveOnlyAssignment) {
352   MoveOnly::ResetCounts();
353   Optional<MoveOnly> O;
354   O = MoveOnly(3);
355   EXPECT_TRUE((bool)O);
356   EXPECT_EQ(3, O->val);
357   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
358   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
359   EXPECT_EQ(1u, MoveOnly::Destructions);
360 }
361 
362 TEST(OptionalTest, MoveOnlyInitializingAssignment) {
363   Optional<MoveOnly> A(MoveOnly(3));
364   Optional<MoveOnly> B;
365   MoveOnly::ResetCounts();
366   B = std::move(A);
367   EXPECT_TRUE((bool)A);
368   EXPECT_TRUE((bool)B);
369   EXPECT_EQ(3, B->val);
370   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
371   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
372   EXPECT_EQ(0u, MoveOnly::Destructions);
373 }
374 
375 TEST(OptionalTest, MoveOnlyNullingAssignment) {
376   Optional<MoveOnly> A;
377   Optional<MoveOnly> B(MoveOnly(3));
378   MoveOnly::ResetCounts();
379   B = std::move(A);
380   EXPECT_FALSE((bool)A);
381   EXPECT_FALSE((bool)B);
382   EXPECT_EQ(0u, MoveOnly::MoveConstructions);
383   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
384   EXPECT_EQ(1u, MoveOnly::Destructions);
385 }
386 
387 TEST(OptionalTest, MoveOnlyAssigningAssignment) {
388   Optional<MoveOnly> A(MoveOnly(3));
389   Optional<MoveOnly> B(MoveOnly(4));
390   MoveOnly::ResetCounts();
391   B = std::move(A);
392   EXPECT_TRUE((bool)A);
393   EXPECT_TRUE((bool)B);
394   EXPECT_EQ(3, B->val);
395   EXPECT_EQ(0u, MoveOnly::MoveConstructions);
396   EXPECT_EQ(1u, MoveOnly::MoveAssignments);
397   EXPECT_EQ(0u, MoveOnly::Destructions);
398 }
399 
400 struct Immovable {
401   static unsigned Constructions;
402   static unsigned Destructions;
403   int val;
404   explicit Immovable(int val) : val(val) {
405     ++Constructions;
406   }
407   ~Immovable() {
408     ++Destructions;
409   }
410   static void ResetCounts() {
411     Constructions = 0;
412     Destructions = 0;
413   }
414 private:
415   // This should disable all move/copy operations.
416   Immovable(Immovable&& other) = delete;
417 };
418 
419 unsigned Immovable::Constructions = 0;
420 unsigned Immovable::Destructions = 0;
421 
422 static_assert(!std::is_trivially_copyable<Optional<Immovable>>::value,
423               "not trivially copyable");
424 
425 TEST(OptionalTest, ImmovableEmplace) {
426   Optional<Immovable> A;
427   Immovable::ResetCounts();
428   A.emplace(4);
429   EXPECT_TRUE((bool)A);
430   EXPECT_EQ(4, A->val);
431   EXPECT_EQ(1u, Immovable::Constructions);
432   EXPECT_EQ(0u, Immovable::Destructions);
433 }
434 
435 TEST(OptionalTest, ImmovableInPlaceConstruction) {
436   Immovable::ResetCounts();
437   Optional<Immovable> A{in_place, 4};
438   EXPECT_TRUE((bool)A);
439   EXPECT_EQ(4, A->val);
440   EXPECT_EQ(1u, Immovable::Constructions);
441   EXPECT_EQ(0u, Immovable::Destructions);
442 }
443 
444 // Craft a class which is_trivially_copyable, but not
445 // is_trivially_copy_constructible.
446 struct NonTCopy {
447   NonTCopy() = default;
448 
449   // Delete the volatile copy constructor to engage the "rule of 3" and delete
450   // any unspecified copy assignment or constructor.
451   NonTCopy(volatile NonTCopy const &) = delete;
452 
453   // Leave the non-volatile default copy constructor unspecified (deleted by
454   // rule of 3)
455 
456   // This template can serve as the copy constructor, but isn't chosen
457   // by =default in a class with a 'NonTCopy' member.
458   template <typename Self = NonTCopy>
459   NonTCopy(Self const &Other) : Val(Other.Val) {}
460 
461   NonTCopy &operator=(NonTCopy const &) = default;
462 
463   int Val{0};
464 };
465 
466 #if defined(_MSC_VER) && _MSC_VER >= 1927 && !defined(__clang__)
467 // Currently only true on recent MSVC releases.
468 static_assert(std::is_trivially_copyable<NonTCopy>::value,
469               "Expect NonTCopy to be trivially copyable");
470 
471 static_assert(!std::is_trivially_copy_constructible<NonTCopy>::value,
472               "Expect NonTCopy not to be trivially copy constructible.");
473 #endif // defined(_MSC_VER) && _MSC_VER >= 1927
474 
475 TEST(OptionalTest, DeletedCopyConstructor) {
476 
477   // Expect compile to fail if 'trivial' version of
478   // optional_detail::OptionalStorage is chosen.
479   using NonTCopyOptT = Optional<NonTCopy>;
480   NonTCopyOptT NonTCopy1;
481 
482   // Check that the Optional can be copy constructed.
483   NonTCopyOptT NonTCopy2{NonTCopy1};
484 
485   // Check that the Optional can be copy assigned.
486   NonTCopy1 = NonTCopy2;
487 }
488 
489 // Craft a class which is_trivially_copyable, but not
490 // is_trivially_copy_assignable.
491 class NonTAssign {
492 public:
493   NonTAssign() = default;
494   NonTAssign(NonTAssign const &) = default;
495 
496   // Delete the volatile copy assignment to engage the "rule of 3" and delete
497   // any unspecified copy assignment or constructor.
498   NonTAssign &operator=(volatile NonTAssign const &) = delete;
499 
500   // Leave the non-volatile default copy assignment unspecified (deleted by rule
501   // of 3).
502 
503   // This template can serve as the copy assignment, but isn't chosen
504   // by =default in a class with a 'NonTAssign' member.
505   template <typename Self = NonTAssign>
506   NonTAssign &operator=(Self const &Other) {
507     A = Other.A;
508     return *this;
509   }
510 
511   int A{0};
512 };
513 
514 #if defined(_MSC_VER) && _MSC_VER >= 1927 && !defined(__clang__)
515 // Currently only true on recent MSVC releases.
516 static_assert(std::is_trivially_copyable<NonTAssign>::value,
517               "Expect NonTAssign to be trivially copyable");
518 
519 static_assert(!std::is_trivially_copy_assignable<NonTAssign>::value,
520               "Expect NonTAssign not to be trivially assignable.");
521 #endif // defined(_MSC_VER) && _MSC_VER >= 1927
522 
523 TEST(OptionalTest, DeletedCopyAssignment) {
524 
525   // Expect compile to fail if 'trivial' version of
526   // optional_detail::OptionalStorage is chosen.
527   using NonTAssignOptT = Optional<NonTAssign>;
528   NonTAssignOptT NonTAssign1;
529 
530   // Check that the Optional can be copy constructed.
531   NonTAssignOptT NonTAssign2{NonTAssign1};
532 
533   // Check that the Optional can be copy assigned.
534   NonTAssign1 = NonTAssign2;
535 }
536 
537 struct NoTMove {
538   NoTMove() = default;
539   NoTMove(NoTMove const &) = default;
540   NoTMove &operator=(NoTMove const &) = default;
541 
542   // Delete move constructor / assignment.  Compiler should fall-back to the
543   // trivial copy constructor / assignment in the trivial OptionalStorage
544   // specialization.
545   NoTMove(NoTMove &&) = delete;
546   NoTMove &operator=(NoTMove &&) = delete;
547 
548   int Val{0};
549 };
550 
551 TEST(OptionalTest, DeletedMoveConstructor) {
552   using NoTMoveOptT = Optional<NoTMove>;
553 
554   NoTMoveOptT NonTMove1;
555   NoTMoveOptT NonTMove2{std::move(NonTMove1)};
556 
557   NonTMove1 = std::move(NonTMove2);
558 
559   static_assert(
560       std::is_trivially_copyable<NoTMoveOptT>::value,
561       "Expect Optional<NoTMove> to still use the trivial specialization "
562       "of OptionalStorage despite the deleted move constructor / assignment.");
563 }
564 
565 class NoCopyStringMap {
566 public:
567   NoCopyStringMap() = default;
568 
569 private:
570   llvm::StringMap<std::unique_ptr<int>> Map;
571 };
572 
573 TEST(OptionalTest, DeletedCopyStringMap) {
574   // Old versions of gcc (7.3 and prior) instantiate the copy constructor when
575   // std::is_trivially_copyable is instantiated.  This test will fail
576   // compilation if std::is_trivially_copyable is used in the OptionalStorage
577   // specialization condition by gcc <= 7.3.
578   Optional<NoCopyStringMap> TestInstantiation;
579 }
580 
581 #if LLVM_HAS_RVALUE_REFERENCE_THIS
582 
583 TEST(OptionalTest, MoveGetValueOr) {
584   Optional<MoveOnly> A;
585 
586   MoveOnly::ResetCounts();
587   EXPECT_EQ(42, std::move(A).getValueOr(MoveOnly(42)).val);
588   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
589   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
590   EXPECT_EQ(2u, MoveOnly::Destructions);
591 
592   A = MoveOnly(5);
593   MoveOnly::ResetCounts();
594   EXPECT_EQ(5, std::move(A).getValueOr(MoveOnly(42)).val);
595   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
596   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
597   EXPECT_EQ(2u, MoveOnly::Destructions);
598 }
599 
600 #endif // LLVM_HAS_RVALUE_REFERENCE_THIS
601 
602 struct EqualTo {
603   template <typename T, typename U> static bool apply(const T &X, const U &Y) {
604     return X == Y;
605   }
606 };
607 
608 struct NotEqualTo {
609   template <typename T, typename U> static bool apply(const T &X, const U &Y) {
610     return X != Y;
611   }
612 };
613 
614 struct Less {
615   template <typename T, typename U> static bool apply(const T &X, const U &Y) {
616     return X < Y;
617   }
618 };
619 
620 struct Greater {
621   template <typename T, typename U> static bool apply(const T &X, const U &Y) {
622     return X > Y;
623   }
624 };
625 
626 struct LessEqual {
627   template <typename T, typename U> static bool apply(const T &X, const U &Y) {
628     return X <= Y;
629   }
630 };
631 
632 struct GreaterEqual {
633   template <typename T, typename U> static bool apply(const T &X, const U &Y) {
634     return X >= Y;
635   }
636 };
637 
638 template <typename OperatorT, typename T>
639 void CheckRelation(const Optional<T> &Lhs, const Optional<T> &Rhs,
640                    bool Expected) {
641   EXPECT_EQ(Expected, OperatorT::apply(Lhs, Rhs));
642 
643   if (Lhs)
644     EXPECT_EQ(Expected, OperatorT::apply(*Lhs, Rhs));
645   else
646     EXPECT_EQ(Expected, OperatorT::apply(None, Rhs));
647 
648   if (Rhs)
649     EXPECT_EQ(Expected, OperatorT::apply(Lhs, *Rhs));
650   else
651     EXPECT_EQ(Expected, OperatorT::apply(Lhs, None));
652 }
653 
654 struct EqualityMock {};
655 const Optional<EqualityMock> NoneEq, EqualityLhs((EqualityMock())),
656     EqualityRhs((EqualityMock()));
657 bool IsEqual;
658 
659 bool operator==(const EqualityMock &Lhs, const EqualityMock &Rhs) {
660   EXPECT_EQ(&*EqualityLhs, &Lhs);
661   EXPECT_EQ(&*EqualityRhs, &Rhs);
662   return IsEqual;
663 }
664 
665 TEST(OptionalTest, OperatorEqual) {
666   CheckRelation<EqualTo>(NoneEq, NoneEq, true);
667   CheckRelation<EqualTo>(NoneEq, EqualityRhs, false);
668   CheckRelation<EqualTo>(EqualityLhs, NoneEq, false);
669 
670   IsEqual = false;
671   CheckRelation<EqualTo>(EqualityLhs, EqualityRhs, IsEqual);
672   IsEqual = true;
673   CheckRelation<EqualTo>(EqualityLhs, EqualityRhs, IsEqual);
674 }
675 
676 TEST(OptionalTest, OperatorNotEqual) {
677   CheckRelation<NotEqualTo>(NoneEq, NoneEq, false);
678   CheckRelation<NotEqualTo>(NoneEq, EqualityRhs, true);
679   CheckRelation<NotEqualTo>(EqualityLhs, NoneEq, true);
680 
681   IsEqual = false;
682   CheckRelation<NotEqualTo>(EqualityLhs, EqualityRhs, !IsEqual);
683   IsEqual = true;
684   CheckRelation<NotEqualTo>(EqualityLhs, EqualityRhs, !IsEqual);
685 }
686 
687 struct InequalityMock {};
688 const Optional<InequalityMock> NoneIneq, InequalityLhs((InequalityMock())),
689     InequalityRhs((InequalityMock()));
690 bool IsLess;
691 
692 bool operator<(const InequalityMock &Lhs, const InequalityMock &Rhs) {
693   EXPECT_EQ(&*InequalityLhs, &Lhs);
694   EXPECT_EQ(&*InequalityRhs, &Rhs);
695   return IsLess;
696 }
697 
698 TEST(OptionalTest, OperatorLess) {
699   CheckRelation<Less>(NoneIneq, NoneIneq, false);
700   CheckRelation<Less>(NoneIneq, InequalityRhs, true);
701   CheckRelation<Less>(InequalityLhs, NoneIneq, false);
702 
703   IsLess = false;
704   CheckRelation<Less>(InequalityLhs, InequalityRhs, IsLess);
705   IsLess = true;
706   CheckRelation<Less>(InequalityLhs, InequalityRhs, IsLess);
707 }
708 
709 TEST(OptionalTest, OperatorGreater) {
710   CheckRelation<Greater>(NoneIneq, NoneIneq, false);
711   CheckRelation<Greater>(NoneIneq, InequalityRhs, false);
712   CheckRelation<Greater>(InequalityLhs, NoneIneq, true);
713 
714   IsLess = false;
715   CheckRelation<Greater>(InequalityRhs, InequalityLhs, IsLess);
716   IsLess = true;
717   CheckRelation<Greater>(InequalityRhs, InequalityLhs, IsLess);
718 }
719 
720 TEST(OptionalTest, OperatorLessEqual) {
721   CheckRelation<LessEqual>(NoneIneq, NoneIneq, true);
722   CheckRelation<LessEqual>(NoneIneq, InequalityRhs, true);
723   CheckRelation<LessEqual>(InequalityLhs, NoneIneq, false);
724 
725   IsLess = false;
726   CheckRelation<LessEqual>(InequalityRhs, InequalityLhs, !IsLess);
727   IsLess = true;
728   CheckRelation<LessEqual>(InequalityRhs, InequalityLhs, !IsLess);
729 }
730 
731 TEST(OptionalTest, OperatorGreaterEqual) {
732   CheckRelation<GreaterEqual>(NoneIneq, NoneIneq, true);
733   CheckRelation<GreaterEqual>(NoneIneq, InequalityRhs, false);
734   CheckRelation<GreaterEqual>(InequalityLhs, NoneIneq, true);
735 
736   IsLess = false;
737   CheckRelation<GreaterEqual>(InequalityLhs, InequalityRhs, !IsLess);
738   IsLess = true;
739   CheckRelation<GreaterEqual>(InequalityLhs, InequalityRhs, !IsLess);
740 }
741 
742 struct ComparableAndStreamable {
743   friend bool operator==(ComparableAndStreamable,
744                          ComparableAndStreamable) LLVM_ATTRIBUTE_USED {
745     return true;
746   }
747 
748   friend raw_ostream &operator<<(raw_ostream &OS, ComparableAndStreamable) {
749     return OS << "ComparableAndStreamable";
750   }
751 
752   static Optional<ComparableAndStreamable> get() {
753     return ComparableAndStreamable();
754   }
755 };
756 
757 TEST(OptionalTest, StreamOperator) {
758   auto to_string = [](Optional<ComparableAndStreamable> O) {
759     SmallString<16> S;
760     raw_svector_ostream OS(S);
761     OS << O;
762     return S;
763   };
764   EXPECT_EQ("ComparableAndStreamable",
765             to_string(ComparableAndStreamable::get()));
766   EXPECT_EQ("None", to_string(None));
767 }
768 
769 struct Comparable {
770   friend bool operator==(Comparable, Comparable) LLVM_ATTRIBUTE_USED {
771     return true;
772   }
773   static Optional<Comparable> get() { return Comparable(); }
774 };
775 
776 TEST(OptionalTest, UseInUnitTests) {
777   // Test that we invoke the streaming operators when pretty-printing values in
778   // EXPECT macros.
779   EXPECT_NONFATAL_FAILURE(EXPECT_EQ(llvm::None, ComparableAndStreamable::get()),
780                           "Expected equality of these values:\n"
781                           "  llvm::None\n"
782                           "    Which is: None\n"
783                           "  ComparableAndStreamable::get()\n"
784                           "    Which is: ComparableAndStreamable");
785 
786   // Test that it is still possible to compare objects which do not have a
787   // custom streaming operator.
788   EXPECT_NONFATAL_FAILURE(EXPECT_EQ(llvm::None, Comparable::get()), "object");
789 }
790 
791 TEST(OptionalTest, HashValue) {
792   // Check that None, false, and true all hash differently.
793   Optional<bool> B, B0 = false, B1 = true;
794   EXPECT_NE(hash_value(B0), hash_value(B));
795   EXPECT_NE(hash_value(B1), hash_value(B));
796   EXPECT_NE(hash_value(B1), hash_value(B0));
797 
798   // Check that None, 0, and 1 all hash differently.
799   Optional<int> I, I0 = 0, I1 = 1;
800   EXPECT_NE(hash_value(I0), hash_value(I));
801   EXPECT_NE(hash_value(I1), hash_value(I));
802   EXPECT_NE(hash_value(I1), hash_value(I0));
803 
804   // Check None hash the same way regardless of type.
805   EXPECT_EQ(hash_value(B), hash_value(I));
806 }
807 
808 struct NotTriviallyCopyable {
809   NotTriviallyCopyable(); // Constructor out-of-line.
810   virtual ~NotTriviallyCopyable() = default;
811   Optional<MoveOnly> MO;
812 };
813 
814 TEST(OptionalTest, GCCIsTriviallyMoveConstructibleCompat) {
815   Optional<NotTriviallyCopyable> V;
816   EXPECT_FALSE(V);
817 }
818 
819 } // end anonymous namespace
820