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 
OptionalWorksInConstexpr()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;
NonDefaultConstructible__anon243dbdea0111::NonDefaultConstructible50   explicit NonDefaultConstructible(int) {
51   }
NonDefaultConstructible__anon243dbdea0111::NonDefaultConstructible52   NonDefaultConstructible(const NonDefaultConstructible&) {
53     ++CopyConstructions;
54   }
operator =__anon243dbdea0111::NonDefaultConstructible55   NonDefaultConstructible &operator=(const NonDefaultConstructible&) {
56     ++CopyAssignments;
57     return *this;
58   }
~NonDefaultConstructible__anon243dbdea0111::NonDefaultConstructible59   ~NonDefaultConstructible() {
60     ++Destructions;
61   }
ResetCounts__anon243dbdea0111::NonDefaultConstructible62   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 
TEST(OptionalTest,NonDefaultConstructibleTest)77 TEST(OptionalTest, NonDefaultConstructibleTest) {
78   Optional<NonDefaultConstructible> O;
79   EXPECT_FALSE(O);
80 }
81 
TEST(OptionalTest,ResetTest)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 
TEST(OptionalTest,InitializationLeakTest)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 
TEST(OptionalTest,CopyConstructionTest)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 
TEST(OptionalTest,ConstructingCopyAssignmentTest)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 
TEST(OptionalTest,CopyingCopyAssignmentTest)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 
TEST(OptionalTest,DeletingCopyAssignmentTest)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 
TEST(OptionalTest,NullCopyConstructionTest)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 
TEST(OptionalTest,InPlaceConstructionNonDefaultConstructibleTest)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 
TEST(OptionalTest,GetValueOr)210 TEST(OptionalTest, GetValueOr) {
211   Optional<int> A;
212   EXPECT_EQ(42, A.value_or(42));
213 
214   A = 5;
215   EXPECT_EQ(5, A.value_or(42));
216 }
217 
218 struct MultiArgConstructor {
219   int x, y;
MultiArgConstructor__anon243dbdea0111::MultiArgConstructor220   MultiArgConstructor(int x, int y) : x(x), y(y) {}
MultiArgConstructor__anon243dbdea0111::MultiArgConstructor221   explicit MultiArgConstructor(int x, bool positive)
222     : x(x), y(positive ? x : -x) {}
223 
224   MultiArgConstructor(const MultiArgConstructor &) = delete;
225   MultiArgConstructor(MultiArgConstructor &&) = delete;
226   MultiArgConstructor &operator=(const MultiArgConstructor &) = delete;
227   MultiArgConstructor &operator=(MultiArgConstructor &&) = delete;
228 
operator ==(const MultiArgConstructor & LHS,const MultiArgConstructor & RHS)229   friend bool operator==(const MultiArgConstructor &LHS,
230                          const MultiArgConstructor &RHS) {
231     return LHS.x == RHS.x && LHS.y == RHS.y;
232   }
233 
234   static unsigned Destructions;
~MultiArgConstructor__anon243dbdea0111::MultiArgConstructor235   ~MultiArgConstructor() {
236     ++Destructions;
237   }
ResetCounts__anon243dbdea0111::MultiArgConstructor238   static void ResetCounts() {
239     Destructions = 0;
240   }
241 };
242 unsigned MultiArgConstructor::Destructions = 0;
243 
244 static_assert(!std::is_trivially_copyable<Optional<MultiArgConstructor>>::value,
245               "not trivially copyable");
246 
TEST(OptionalTest,Emplace)247 TEST(OptionalTest, Emplace) {
248   MultiArgConstructor::ResetCounts();
249   Optional<MultiArgConstructor> A;
250 
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);
257 
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);
264 }
265 
TEST(OptionalTest,InPlaceConstructionMultiArgConstructorTest)266 TEST(OptionalTest, InPlaceConstructionMultiArgConstructorTest) {
267   MultiArgConstructor::ResetCounts();
268   {
269     Optional<MultiArgConstructor> A{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{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);
280   }
281   EXPECT_EQ(2u, MultiArgConstructor::Destructions);
282 }
283 
TEST(OptionalTest,InPlaceConstructionAndEmplaceEquivalentTest)284 TEST(OptionalTest, InPlaceConstructionAndEmplaceEquivalentTest) {
285   MultiArgConstructor::ResetCounts();
286   {
287     Optional<MultiArgConstructor> A{in_place, 1, 2};
288     Optional<MultiArgConstructor> B;
289     B.emplace(1, 2);
290     EXPECT_EQ(0u, MultiArgConstructor::Destructions);
291     ASSERT_EQ(A, B);
292   }
293   EXPECT_EQ(2u, MultiArgConstructor::Destructions);
294 }
295 
296 struct MoveOnly {
297   static unsigned MoveConstructions;
298   static unsigned Destructions;
299   static unsigned MoveAssignments;
300   int val;
MoveOnly__anon243dbdea0111::MoveOnly301   explicit MoveOnly(int val) : val(val) {
302   }
MoveOnly__anon243dbdea0111::MoveOnly303   MoveOnly(MoveOnly&& other) {
304     val = other.val;
305     ++MoveConstructions;
306   }
operator =__anon243dbdea0111::MoveOnly307   MoveOnly &operator=(MoveOnly&& other) {
308     val = other.val;
309     ++MoveAssignments;
310     return *this;
311   }
~MoveOnly__anon243dbdea0111::MoveOnly312   ~MoveOnly() {
313     ++Destructions;
314   }
ResetCounts__anon243dbdea0111::MoveOnly315   static void ResetCounts() {
316     MoveConstructions = 0;
317     Destructions = 0;
318     MoveAssignments = 0;
319   }
320 };
321 
322 unsigned MoveOnly::MoveConstructions = 0;
323 unsigned MoveOnly::Destructions = 0;
324 unsigned MoveOnly::MoveAssignments = 0;
325 
326 static_assert(!std::is_trivially_copyable<Optional<MoveOnly>>::value,
327               "not trivially copyable");
328 
TEST(OptionalTest,MoveOnlyNull)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);
335 }
336 
TEST(OptionalTest,MoveOnlyConstruction)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);
345 }
346 
TEST(OptionalTest,MoveOnlyMoveConstruction)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);
357 }
358 
TEST(OptionalTest,MoveOnlyAssignment)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);
368 }
369 
TEST(OptionalTest,MoveOnlyInitializingAssignment)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);
381 }
382 
TEST(OptionalTest,MoveOnlyNullingAssignment)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);
393 }
394 
TEST(OptionalTest,MoveOnlyAssigningAssignment)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);
406 }
407 
408 struct Immovable {
409   static unsigned Constructions;
410   static unsigned Destructions;
411   int val;
Immovable__anon243dbdea0111::Immovable412   explicit Immovable(int val) : val(val) {
413     ++Constructions;
414   }
~Immovable__anon243dbdea0111::Immovable415   ~Immovable() {
416     ++Destructions;
417   }
ResetCounts__anon243dbdea0111::Immovable418   static void ResetCounts() {
419     Constructions = 0;
420     Destructions = 0;
421   }
422 private:
423   // This should disable all move/copy operations.
424   Immovable(Immovable&& other) = delete;
425 };
426 
427 unsigned Immovable::Constructions = 0;
428 unsigned Immovable::Destructions = 0;
429 
430 static_assert(!std::is_trivially_copyable<Optional<Immovable>>::value,
431               "not trivially copyable");
432 
TEST(OptionalTest,ImmovableEmplace)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);
441 }
442 
TEST(OptionalTest,ImmovableInPlaceConstruction)443 TEST(OptionalTest, ImmovableInPlaceConstruction) {
444   Immovable::ResetCounts();
445   Optional<Immovable> A{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);
450 }
451 
452 // Craft a class which is_trivially_copyable, but not
453 // is_trivially_copy_constructible.
454 struct NonTCopy {
455   NonTCopy() = default;
456 
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;
460 
461   // Leave the non-volatile default copy constructor unspecified (deleted by
462   // rule of 3)
463 
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>
NonTCopy__anon243dbdea0111::NonTCopy467   NonTCopy(Self const &Other) : Val(Other.Val) {}
468 
469   NonTCopy &operator=(NonTCopy const &) = default;
470 
471   int Val{0};
472 };
473 
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");
478 
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
482 
TEST(OptionalTest,DeletedCopyConstructor)483 TEST(OptionalTest, DeletedCopyConstructor) {
484 
485   // Expect compile to fail if 'trivial' version of
486   // optional_detail::OptionalStorage is chosen.
487   using NonTCopyOptT = Optional<NonTCopy>;
488   NonTCopyOptT NonTCopy1;
489 
490   // Check that the Optional can be copy constructed.
491   NonTCopyOptT NonTCopy2{NonTCopy1};
492 
493   // Check that the Optional can be copy assigned.
494   NonTCopy1 = NonTCopy2;
495 }
496 
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;
503 
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;
507 
508   // Leave the non-volatile default copy assignment unspecified (deleted by rule
509   // of 3).
510 
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>
operator =(Self const & Other)514   NonTAssign &operator=(Self const &Other) {
515     A = Other.A;
516     return *this;
517   }
518 
519   int A{0};
520 };
521 
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");
526 
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
530 
TEST(OptionalTest,DeletedCopyAssignment)531 TEST(OptionalTest, DeletedCopyAssignment) {
532 
533   // Expect compile to fail if 'trivial' version of
534   // optional_detail::OptionalStorage is chosen.
535   using NonTAssignOptT = Optional<NonTAssign>;
536   NonTAssignOptT NonTAssign1;
537 
538   // Check that the Optional can be copy constructed.
539   NonTAssignOptT NonTAssign2{NonTAssign1};
540 
541   // Check that the Optional can be copy assigned.
542   NonTAssign1 = NonTAssign2;
543 }
544 
545 struct NoTMove {
546   NoTMove() = default;
547   NoTMove(NoTMove const &) = default;
548   NoTMove &operator=(NoTMove const &) = default;
549 
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;
555 
556   int Val{0};
557 };
558 
TEST(OptionalTest,DeletedMoveConstructor)559 TEST(OptionalTest, DeletedMoveConstructor) {
560   using NoTMoveOptT = Optional<NoTMove>;
561 
562   NoTMoveOptT NonTMove1;
563   NoTMoveOptT NonTMove2{std::move(NonTMove1)};
564 
565   NonTMove1 = std::move(NonTMove2);
566 
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.");
571 }
572 
573 class NoCopyStringMap {
574 public:
575   NoCopyStringMap() = default;
576 
577 private:
578   llvm::StringMap<std::unique_ptr<int>> Map;
579 };
580 
TEST(OptionalTest,DeletedCopyStringMap)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;
587 }
588 
TEST(OptionalTest,MoveValueOr)589 TEST(OptionalTest, MoveValueOr) {
590   Optional<MoveOnly> A;
591 
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);
597 
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);
604 }
605 
606 struct EqualTo {
apply__anon243dbdea0111::EqualTo607   template <typename T, typename U> static bool apply(const T &X, const U &Y) {
608     return X == Y;
609   }
610 };
611 
612 struct NotEqualTo {
apply__anon243dbdea0111::NotEqualTo613   template <typename T, typename U> static bool apply(const T &X, const U &Y) {
614     return X != Y;
615   }
616 };
617 
618 struct Less {
apply__anon243dbdea0111::Less619   template <typename T, typename U> static bool apply(const T &X, const U &Y) {
620     return X < Y;
621   }
622 };
623 
624 struct Greater {
apply__anon243dbdea0111::Greater625   template <typename T, typename U> static bool apply(const T &X, const U &Y) {
626     return X > Y;
627   }
628 };
629 
630 struct LessEqual {
apply__anon243dbdea0111::LessEqual631   template <typename T, typename U> static bool apply(const T &X, const U &Y) {
632     return X <= Y;
633   }
634 };
635 
636 struct GreaterEqual {
apply__anon243dbdea0111::GreaterEqual637   template <typename T, typename U> static bool apply(const T &X, const U &Y) {
638     return X >= Y;
639   }
640 };
641 
642 template <typename OperatorT, typename T>
CheckRelation(const Optional<T> & Lhs,const Optional<T> & Rhs,bool Expected)643 void CheckRelation(const Optional<T> &Lhs, const Optional<T> &Rhs,
644                    bool Expected) {
645   EXPECT_EQ(Expected, OperatorT::apply(Lhs, Rhs));
646 
647   if (Lhs)
648     EXPECT_EQ(Expected, OperatorT::apply(*Lhs, Rhs));
649   else
650     EXPECT_EQ(Expected, OperatorT::apply(None, Rhs));
651 
652   if (Rhs)
653     EXPECT_EQ(Expected, OperatorT::apply(Lhs, *Rhs));
654   else
655     EXPECT_EQ(Expected, OperatorT::apply(Lhs, None));
656 }
657 
658 struct EqualityMock {};
659 const Optional<EqualityMock> NoneEq, EqualityLhs((EqualityMock())),
660     EqualityRhs((EqualityMock()));
661 bool IsEqual;
662 
operator ==(const EqualityMock & Lhs,const EqualityMock & Rhs)663 bool operator==(const EqualityMock &Lhs, const EqualityMock &Rhs) {
664   EXPECT_EQ(&*EqualityLhs, &Lhs);
665   EXPECT_EQ(&*EqualityRhs, &Rhs);
666   return IsEqual;
667 }
668 
TEST(OptionalTest,OperatorEqual)669 TEST(OptionalTest, OperatorEqual) {
670   CheckRelation<EqualTo>(NoneEq, NoneEq, true);
671   CheckRelation<EqualTo>(NoneEq, EqualityRhs, false);
672   CheckRelation<EqualTo>(EqualityLhs, NoneEq, false);
673 
674   IsEqual = false;
675   CheckRelation<EqualTo>(EqualityLhs, EqualityRhs, IsEqual);
676   IsEqual = true;
677   CheckRelation<EqualTo>(EqualityLhs, EqualityRhs, IsEqual);
678 }
679 
TEST(OptionalTest,OperatorNotEqual)680 TEST(OptionalTest, OperatorNotEqual) {
681   CheckRelation<NotEqualTo>(NoneEq, NoneEq, false);
682   CheckRelation<NotEqualTo>(NoneEq, EqualityRhs, true);
683   CheckRelation<NotEqualTo>(EqualityLhs, NoneEq, true);
684 
685   IsEqual = false;
686   CheckRelation<NotEqualTo>(EqualityLhs, EqualityRhs, !IsEqual);
687   IsEqual = true;
688   CheckRelation<NotEqualTo>(EqualityLhs, EqualityRhs, !IsEqual);
689 }
690 
691 struct InequalityMock {};
692 const Optional<InequalityMock> NoneIneq, InequalityLhs((InequalityMock())),
693     InequalityRhs((InequalityMock()));
694 bool IsLess;
695 
operator <(const InequalityMock & Lhs,const InequalityMock & Rhs)696 bool operator<(const InequalityMock &Lhs, const InequalityMock &Rhs) {
697   EXPECT_EQ(&*InequalityLhs, &Lhs);
698   EXPECT_EQ(&*InequalityRhs, &Rhs);
699   return IsLess;
700 }
701 
TEST(OptionalTest,OperatorLess)702 TEST(OptionalTest, OperatorLess) {
703   CheckRelation<Less>(NoneIneq, NoneIneq, false);
704   CheckRelation<Less>(NoneIneq, InequalityRhs, true);
705   CheckRelation<Less>(InequalityLhs, NoneIneq, false);
706 
707   IsLess = false;
708   CheckRelation<Less>(InequalityLhs, InequalityRhs, IsLess);
709   IsLess = true;
710   CheckRelation<Less>(InequalityLhs, InequalityRhs, IsLess);
711 }
712 
TEST(OptionalTest,OperatorGreater)713 TEST(OptionalTest, OperatorGreater) {
714   CheckRelation<Greater>(NoneIneq, NoneIneq, false);
715   CheckRelation<Greater>(NoneIneq, InequalityRhs, false);
716   CheckRelation<Greater>(InequalityLhs, NoneIneq, true);
717 
718   IsLess = false;
719   CheckRelation<Greater>(InequalityRhs, InequalityLhs, IsLess);
720   IsLess = true;
721   CheckRelation<Greater>(InequalityRhs, InequalityLhs, IsLess);
722 }
723 
TEST(OptionalTest,OperatorLessEqual)724 TEST(OptionalTest, OperatorLessEqual) {
725   CheckRelation<LessEqual>(NoneIneq, NoneIneq, true);
726   CheckRelation<LessEqual>(NoneIneq, InequalityRhs, true);
727   CheckRelation<LessEqual>(InequalityLhs, NoneIneq, false);
728 
729   IsLess = false;
730   CheckRelation<LessEqual>(InequalityRhs, InequalityLhs, !IsLess);
731   IsLess = true;
732   CheckRelation<LessEqual>(InequalityRhs, InequalityLhs, !IsLess);
733 }
734 
TEST(OptionalTest,OperatorGreaterEqual)735 TEST(OptionalTest, OperatorGreaterEqual) {
736   CheckRelation<GreaterEqual>(NoneIneq, NoneIneq, true);
737   CheckRelation<GreaterEqual>(NoneIneq, InequalityRhs, false);
738   CheckRelation<GreaterEqual>(InequalityLhs, NoneIneq, true);
739 
740   IsLess = false;
741   CheckRelation<GreaterEqual>(InequalityLhs, InequalityRhs, !IsLess);
742   IsLess = true;
743   CheckRelation<GreaterEqual>(InequalityLhs, InequalityRhs, !IsLess);
744 }
745 
746 struct ComparableAndStreamable {
operator ==(ComparableAndStreamable,ComparableAndStreamable)747   friend bool operator==(ComparableAndStreamable,
748                          ComparableAndStreamable) LLVM_ATTRIBUTE_USED {
749     return true;
750   }
751 
operator <<(raw_ostream & OS,ComparableAndStreamable)752   friend raw_ostream &operator<<(raw_ostream &OS, ComparableAndStreamable) {
753     return OS << "ComparableAndStreamable";
754   }
755 
get__anon243dbdea0111::ComparableAndStreamable756   static Optional<ComparableAndStreamable> get() {
757     return ComparableAndStreamable();
758   }
759 };
760 
TEST(OptionalTest,StreamOperator)761 TEST(OptionalTest, StreamOperator) {
762   auto to_string = [](Optional<ComparableAndStreamable> O) {
763     SmallString<16> S;
764     raw_svector_ostream OS(S);
765     OS << O;
766     return S;
767   };
768   EXPECT_EQ("ComparableAndStreamable",
769             to_string(ComparableAndStreamable::get()));
770   EXPECT_EQ("None", to_string(None));
771 }
772 
773 struct Comparable {
operator ==(Comparable,Comparable)774   friend bool operator==(Comparable, Comparable) LLVM_ATTRIBUTE_USED {
775     return true;
776   }
get__anon243dbdea0111::Comparable777   static Optional<Comparable> get() { return Comparable(); }
778 };
779 
TEST(OptionalTest,UseInUnitTests)780 TEST(OptionalTest, UseInUnitTests) {
781   // Test that we invoke the streaming operators when pretty-printing values in
782   // EXPECT macros.
783   EXPECT_NONFATAL_FAILURE(EXPECT_EQ(llvm::None, ComparableAndStreamable::get()),
784                           "Expected equality of these values:\n"
785                           "  llvm::None\n"
786                           "    Which is: None\n"
787                           "  ComparableAndStreamable::get()\n"
788                           "    Which is: ComparableAndStreamable");
789 
790   // Test that it is still possible to compare objects which do not have a
791   // custom streaming operator.
792   EXPECT_NONFATAL_FAILURE(EXPECT_EQ(llvm::None, Comparable::get()), "object");
793 }
794 
TEST(OptionalTest,HashValue)795 TEST(OptionalTest, HashValue) {
796   // Check that None, false, and true all hash differently.
797   Optional<bool> B, B0 = false, B1 = true;
798   EXPECT_NE(hash_value(B0), hash_value(B));
799   EXPECT_NE(hash_value(B1), hash_value(B));
800   EXPECT_NE(hash_value(B1), hash_value(B0));
801 
802   // Check that None, 0, and 1 all hash differently.
803   Optional<int> I, I0 = 0, I1 = 1;
804   EXPECT_NE(hash_value(I0), hash_value(I));
805   EXPECT_NE(hash_value(I1), hash_value(I));
806   EXPECT_NE(hash_value(I1), hash_value(I0));
807 
808   // Check None hash the same way regardless of type.
809   EXPECT_EQ(hash_value(B), hash_value(I));
810 }
811 
812 struct NotTriviallyCopyable {
813   NotTriviallyCopyable(); // Constructor out-of-line.
814   virtual ~NotTriviallyCopyable() = default;
815   Optional<MoveOnly> MO;
816 };
817 
TEST(OptionalTest,GCCIsTriviallyMoveConstructibleCompat)818 TEST(OptionalTest, GCCIsTriviallyMoveConstructibleCompat) {
819   Optional<NotTriviallyCopyable> V;
820   EXPECT_FALSE(V);
821 }
822 
823 } // end anonymous namespace
824