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