1 //===- llvm/unittest/ADT/OptionalTest.cpp - Optional unit tests -----------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "llvm/ADT/Optional.h"
11 #include "gtest/gtest.h"
12 
13 using namespace llvm;
14 
15 namespace {
16 
17 struct NonDefaultConstructible {
18   static unsigned CopyConstructions;
19   static unsigned Destructions;
20   static unsigned CopyAssignments;
NonDefaultConstructible__anon239a63540111::NonDefaultConstructible21   explicit NonDefaultConstructible(int) {
22   }
NonDefaultConstructible__anon239a63540111::NonDefaultConstructible23   NonDefaultConstructible(const NonDefaultConstructible&) {
24     ++CopyConstructions;
25   }
operator =__anon239a63540111::NonDefaultConstructible26   NonDefaultConstructible &operator=(const NonDefaultConstructible&) {
27     ++CopyAssignments;
28     return *this;
29   }
~NonDefaultConstructible__anon239a63540111::NonDefaultConstructible30   ~NonDefaultConstructible() {
31     ++Destructions;
32   }
ResetCounts__anon239a63540111::NonDefaultConstructible33   static void ResetCounts() {
34     CopyConstructions = 0;
35     Destructions = 0;
36     CopyAssignments = 0;
37   }
38 };
39 
40 unsigned NonDefaultConstructible::CopyConstructions = 0;
41 unsigned NonDefaultConstructible::Destructions = 0;
42 unsigned NonDefaultConstructible::CopyAssignments = 0;
43 
44 // Test fixture
45 class OptionalTest : public testing::Test {
46 };
47 
TEST_F(OptionalTest,NonDefaultConstructibleTest)48 TEST_F(OptionalTest, NonDefaultConstructibleTest) {
49   Optional<NonDefaultConstructible> O;
50   EXPECT_FALSE(O);
51 }
52 
TEST_F(OptionalTest,ResetTest)53 TEST_F(OptionalTest, ResetTest) {
54   NonDefaultConstructible::ResetCounts();
55   Optional<NonDefaultConstructible> O(NonDefaultConstructible(3));
56   EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
57   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
58   EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
59   NonDefaultConstructible::ResetCounts();
60   O.reset();
61   EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
62   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
63   EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
64 }
65 
TEST_F(OptionalTest,InitializationLeakTest)66 TEST_F(OptionalTest, InitializationLeakTest) {
67   NonDefaultConstructible::ResetCounts();
68   Optional<NonDefaultConstructible>(NonDefaultConstructible(3));
69   EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
70   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
71   EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
72 }
73 
TEST_F(OptionalTest,CopyConstructionTest)74 TEST_F(OptionalTest, CopyConstructionTest) {
75   NonDefaultConstructible::ResetCounts();
76   {
77     Optional<NonDefaultConstructible> A(NonDefaultConstructible(3));
78     EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
79     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
80     EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
81     NonDefaultConstructible::ResetCounts();
82     Optional<NonDefaultConstructible> B(A);
83     EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
84     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
85     EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
86     NonDefaultConstructible::ResetCounts();
87   }
88   EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
89   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
90   EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
91 }
92 
TEST_F(OptionalTest,ConstructingCopyAssignmentTest)93 TEST_F(OptionalTest, ConstructingCopyAssignmentTest) {
94   NonDefaultConstructible::ResetCounts();
95   {
96     Optional<NonDefaultConstructible> A(NonDefaultConstructible(3));
97     Optional<NonDefaultConstructible> B;
98     EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
99     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
100     EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
101     NonDefaultConstructible::ResetCounts();
102     B = A;
103     EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
104     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
105     EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
106     NonDefaultConstructible::ResetCounts();
107   }
108   EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
109   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
110   EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
111 }
112 
TEST_F(OptionalTest,CopyingCopyAssignmentTest)113 TEST_F(OptionalTest, CopyingCopyAssignmentTest) {
114   NonDefaultConstructible::ResetCounts();
115   {
116     Optional<NonDefaultConstructible> A(NonDefaultConstructible(3));
117     Optional<NonDefaultConstructible> B(NonDefaultConstructible(4));
118     EXPECT_EQ(2u, NonDefaultConstructible::CopyConstructions);
119     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
120     EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
121     NonDefaultConstructible::ResetCounts();
122     B = A;
123     EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
124     EXPECT_EQ(1u, NonDefaultConstructible::CopyAssignments);
125     EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
126     NonDefaultConstructible::ResetCounts();
127   }
128   EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
129   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
130   EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
131 }
132 
TEST_F(OptionalTest,DeletingCopyAssignmentTest)133 TEST_F(OptionalTest, DeletingCopyAssignmentTest) {
134   NonDefaultConstructible::ResetCounts();
135   {
136     Optional<NonDefaultConstructible> A;
137     Optional<NonDefaultConstructible> B(NonDefaultConstructible(3));
138     EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
139     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
140     EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
141     NonDefaultConstructible::ResetCounts();
142     B = A;
143     EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
144     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
145     EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
146     NonDefaultConstructible::ResetCounts();
147   }
148   EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
149   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
150   EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
151 }
152 
TEST_F(OptionalTest,NullCopyConstructionTest)153 TEST_F(OptionalTest, NullCopyConstructionTest) {
154   NonDefaultConstructible::ResetCounts();
155   {
156     Optional<NonDefaultConstructible> A;
157     Optional<NonDefaultConstructible> B;
158     EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
159     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
160     EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
161     NonDefaultConstructible::ResetCounts();
162     B = A;
163     EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
164     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
165     EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
166     NonDefaultConstructible::ResetCounts();
167   }
168   EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
169   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
170   EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
171 }
172 
TEST_F(OptionalTest,GetValueOr)173 TEST_F(OptionalTest, GetValueOr) {
174   Optional<int> A;
175   EXPECT_EQ(42, A.getValueOr(42));
176 
177   A = 5;
178   EXPECT_EQ(5, A.getValueOr(42));
179 }
180 
181 struct MultiArgConstructor {
182   int x, y;
MultiArgConstructor__anon239a63540111::MultiArgConstructor183   MultiArgConstructor(int x, int y) : x(x), y(y) {}
MultiArgConstructor__anon239a63540111::MultiArgConstructor184   explicit MultiArgConstructor(int x, bool positive)
185     : x(x), y(positive ? x : -x) {}
186 
187   MultiArgConstructor(const MultiArgConstructor &) = delete;
188   MultiArgConstructor(MultiArgConstructor &&) = delete;
189   MultiArgConstructor &operator=(const MultiArgConstructor &) = delete;
190   MultiArgConstructor &operator=(MultiArgConstructor &&) = delete;
191 
192   static unsigned Destructions;
~MultiArgConstructor__anon239a63540111::MultiArgConstructor193   ~MultiArgConstructor() {
194     ++Destructions;
195   }
ResetCounts__anon239a63540111::MultiArgConstructor196   static void ResetCounts() {
197     Destructions = 0;
198   }
199 };
200 unsigned MultiArgConstructor::Destructions = 0;
201 
TEST_F(OptionalTest,Emplace)202 TEST_F(OptionalTest, Emplace) {
203   MultiArgConstructor::ResetCounts();
204   Optional<MultiArgConstructor> A;
205 
206   A.emplace(1, 2);
207   EXPECT_TRUE(A.hasValue());
208   EXPECT_EQ(1, A->x);
209   EXPECT_EQ(2, A->y);
210   EXPECT_EQ(0u, MultiArgConstructor::Destructions);
211 
212   A.emplace(5, false);
213   EXPECT_TRUE(A.hasValue());
214   EXPECT_EQ(5, A->x);
215   EXPECT_EQ(-5, A->y);
216   EXPECT_EQ(1u, MultiArgConstructor::Destructions);
217 }
218 
219 struct MoveOnly {
220   static unsigned MoveConstructions;
221   static unsigned Destructions;
222   static unsigned MoveAssignments;
223   int val;
MoveOnly__anon239a63540111::MoveOnly224   explicit MoveOnly(int val) : val(val) {
225   }
MoveOnly__anon239a63540111::MoveOnly226   MoveOnly(MoveOnly&& other) {
227     val = other.val;
228     ++MoveConstructions;
229   }
operator =__anon239a63540111::MoveOnly230   MoveOnly &operator=(MoveOnly&& other) {
231     val = other.val;
232     ++MoveAssignments;
233     return *this;
234   }
~MoveOnly__anon239a63540111::MoveOnly235   ~MoveOnly() {
236     ++Destructions;
237   }
ResetCounts__anon239a63540111::MoveOnly238   static void ResetCounts() {
239     MoveConstructions = 0;
240     Destructions = 0;
241     MoveAssignments = 0;
242   }
243 };
244 
245 unsigned MoveOnly::MoveConstructions = 0;
246 unsigned MoveOnly::Destructions = 0;
247 unsigned MoveOnly::MoveAssignments = 0;
248 
TEST_F(OptionalTest,MoveOnlyNull)249 TEST_F(OptionalTest, MoveOnlyNull) {
250   MoveOnly::ResetCounts();
251   Optional<MoveOnly> O;
252   EXPECT_EQ(0u, MoveOnly::MoveConstructions);
253   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
254   EXPECT_EQ(0u, MoveOnly::Destructions);
255 }
256 
TEST_F(OptionalTest,MoveOnlyConstruction)257 TEST_F(OptionalTest, MoveOnlyConstruction) {
258   MoveOnly::ResetCounts();
259   Optional<MoveOnly> O(MoveOnly(3));
260   EXPECT_TRUE((bool)O);
261   EXPECT_EQ(3, O->val);
262   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
263   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
264   EXPECT_EQ(1u, MoveOnly::Destructions);
265 }
266 
TEST_F(OptionalTest,MoveOnlyMoveConstruction)267 TEST_F(OptionalTest, MoveOnlyMoveConstruction) {
268   Optional<MoveOnly> A(MoveOnly(3));
269   MoveOnly::ResetCounts();
270   Optional<MoveOnly> B(std::move(A));
271   EXPECT_TRUE((bool)A);
272   EXPECT_TRUE((bool)B);
273   EXPECT_EQ(3, B->val);
274   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
275   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
276   EXPECT_EQ(0u, MoveOnly::Destructions);
277 }
278 
TEST_F(OptionalTest,MoveOnlyAssignment)279 TEST_F(OptionalTest, MoveOnlyAssignment) {
280   MoveOnly::ResetCounts();
281   Optional<MoveOnly> O;
282   O = MoveOnly(3);
283   EXPECT_TRUE((bool)O);
284   EXPECT_EQ(3, O->val);
285   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
286   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
287   EXPECT_EQ(1u, MoveOnly::Destructions);
288 }
289 
TEST_F(OptionalTest,MoveOnlyInitializingAssignment)290 TEST_F(OptionalTest, MoveOnlyInitializingAssignment) {
291   Optional<MoveOnly> A(MoveOnly(3));
292   Optional<MoveOnly> B;
293   MoveOnly::ResetCounts();
294   B = std::move(A);
295   EXPECT_TRUE((bool)A);
296   EXPECT_TRUE((bool)B);
297   EXPECT_EQ(3, B->val);
298   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
299   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
300   EXPECT_EQ(0u, MoveOnly::Destructions);
301 }
302 
TEST_F(OptionalTest,MoveOnlyNullingAssignment)303 TEST_F(OptionalTest, MoveOnlyNullingAssignment) {
304   Optional<MoveOnly> A;
305   Optional<MoveOnly> B(MoveOnly(3));
306   MoveOnly::ResetCounts();
307   B = std::move(A);
308   EXPECT_FALSE((bool)A);
309   EXPECT_FALSE((bool)B);
310   EXPECT_EQ(0u, MoveOnly::MoveConstructions);
311   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
312   EXPECT_EQ(1u, MoveOnly::Destructions);
313 }
314 
TEST_F(OptionalTest,MoveOnlyAssigningAssignment)315 TEST_F(OptionalTest, MoveOnlyAssigningAssignment) {
316   Optional<MoveOnly> A(MoveOnly(3));
317   Optional<MoveOnly> B(MoveOnly(4));
318   MoveOnly::ResetCounts();
319   B = std::move(A);
320   EXPECT_TRUE((bool)A);
321   EXPECT_TRUE((bool)B);
322   EXPECT_EQ(3, B->val);
323   EXPECT_EQ(0u, MoveOnly::MoveConstructions);
324   EXPECT_EQ(1u, MoveOnly::MoveAssignments);
325   EXPECT_EQ(0u, MoveOnly::Destructions);
326 }
327 
328 struct Immovable {
329   static unsigned Constructions;
330   static unsigned Destructions;
331   int val;
Immovable__anon239a63540111::Immovable332   explicit Immovable(int val) : val(val) {
333     ++Constructions;
334   }
~Immovable__anon239a63540111::Immovable335   ~Immovable() {
336     ++Destructions;
337   }
ResetCounts__anon239a63540111::Immovable338   static void ResetCounts() {
339     Constructions = 0;
340     Destructions = 0;
341   }
342 private:
343   // This should disable all move/copy operations.
344   Immovable(Immovable&& other) = delete;
345 };
346 
347 unsigned Immovable::Constructions = 0;
348 unsigned Immovable::Destructions = 0;
349 
TEST_F(OptionalTest,ImmovableEmplace)350 TEST_F(OptionalTest, ImmovableEmplace) {
351   Optional<Immovable> A;
352   Immovable::ResetCounts();
353   A.emplace(4);
354   EXPECT_TRUE((bool)A);
355   EXPECT_EQ(4, A->val);
356   EXPECT_EQ(1u, Immovable::Constructions);
357   EXPECT_EQ(0u, Immovable::Destructions);
358 }
359 
360 #if LLVM_HAS_RVALUE_REFERENCE_THIS
361 
TEST_F(OptionalTest,MoveGetValueOr)362 TEST_F(OptionalTest, MoveGetValueOr) {
363   Optional<MoveOnly> A;
364 
365   MoveOnly::ResetCounts();
366   EXPECT_EQ(42, std::move(A).getValueOr(MoveOnly(42)).val);
367   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
368   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
369   EXPECT_EQ(2u, MoveOnly::Destructions);
370 
371   A = MoveOnly(5);
372   MoveOnly::ResetCounts();
373   EXPECT_EQ(5, std::move(A).getValueOr(MoveOnly(42)).val);
374   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
375   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
376   EXPECT_EQ(2u, MoveOnly::Destructions);
377 }
378 
379 #endif // LLVM_HAS_RVALUE_REFERENCE_THIS
380 
381 struct EqualTo {
apply__anon239a63540111::EqualTo382   template <typename T, typename U> static bool apply(const T &X, const U &Y) {
383     return X == Y;
384   }
385 };
386 
387 struct NotEqualTo {
apply__anon239a63540111::NotEqualTo388   template <typename T, typename U> static bool apply(const T &X, const U &Y) {
389     return X != Y;
390   }
391 };
392 
393 struct Less {
apply__anon239a63540111::Less394   template <typename T, typename U> static bool apply(const T &X, const U &Y) {
395     return X < Y;
396   }
397 };
398 
399 struct Greater {
apply__anon239a63540111::Greater400   template <typename T, typename U> static bool apply(const T &X, const U &Y) {
401     return X > Y;
402   }
403 };
404 
405 struct LessEqual {
apply__anon239a63540111::LessEqual406   template <typename T, typename U> static bool apply(const T &X, const U &Y) {
407     return X <= Y;
408   }
409 };
410 
411 struct GreaterEqual {
apply__anon239a63540111::GreaterEqual412   template <typename T, typename U> static bool apply(const T &X, const U &Y) {
413     return X >= Y;
414   }
415 };
416 
417 template <typename OperatorT, typename T>
CheckRelation(const Optional<T> & Lhs,const Optional<T> & Rhs,bool Expected)418 void CheckRelation(const Optional<T> &Lhs, const Optional<T> &Rhs,
419                    bool Expected) {
420   EXPECT_EQ(Expected, OperatorT::apply(Lhs, Rhs));
421 
422   if (Lhs)
423     EXPECT_EQ(Expected, OperatorT::apply(*Lhs, Rhs));
424   else
425     EXPECT_EQ(Expected, OperatorT::apply(None, Rhs));
426 
427   if (Rhs)
428     EXPECT_EQ(Expected, OperatorT::apply(Lhs, *Rhs));
429   else
430     EXPECT_EQ(Expected, OperatorT::apply(Lhs, None));
431 }
432 
433 struct EqualityMock {};
434 const Optional<EqualityMock> NoneEq, EqualityLhs((EqualityMock())),
435     EqualityRhs((EqualityMock()));
436 bool IsEqual;
437 
operator ==(const EqualityMock & Lhs,const EqualityMock & Rhs)438 bool operator==(const EqualityMock &Lhs, const EqualityMock &Rhs) {
439   EXPECT_EQ(&*EqualityLhs, &Lhs);
440   EXPECT_EQ(&*EqualityRhs, &Rhs);
441   return IsEqual;
442 }
443 
TEST_F(OptionalTest,OperatorEqual)444 TEST_F(OptionalTest, OperatorEqual) {
445   CheckRelation<EqualTo>(NoneEq, NoneEq, true);
446   CheckRelation<EqualTo>(NoneEq, EqualityRhs, false);
447   CheckRelation<EqualTo>(EqualityLhs, NoneEq, false);
448 
449   IsEqual = false;
450   CheckRelation<EqualTo>(EqualityLhs, EqualityRhs, IsEqual);
451   IsEqual = true;
452   CheckRelation<EqualTo>(EqualityLhs, EqualityRhs, IsEqual);
453 }
454 
TEST_F(OptionalTest,OperatorNotEqual)455 TEST_F(OptionalTest, OperatorNotEqual) {
456   CheckRelation<NotEqualTo>(NoneEq, NoneEq, false);
457   CheckRelation<NotEqualTo>(NoneEq, EqualityRhs, true);
458   CheckRelation<NotEqualTo>(EqualityLhs, NoneEq, true);
459 
460   IsEqual = false;
461   CheckRelation<NotEqualTo>(EqualityLhs, EqualityRhs, !IsEqual);
462   IsEqual = true;
463   CheckRelation<NotEqualTo>(EqualityLhs, EqualityRhs, !IsEqual);
464 }
465 
466 struct InequalityMock {};
467 const Optional<InequalityMock> NoneIneq, InequalityLhs((InequalityMock())),
468     InequalityRhs((InequalityMock()));
469 bool IsLess;
470 
operator <(const InequalityMock & Lhs,const InequalityMock & Rhs)471 bool operator<(const InequalityMock &Lhs, const InequalityMock &Rhs) {
472   EXPECT_EQ(&*InequalityLhs, &Lhs);
473   EXPECT_EQ(&*InequalityRhs, &Rhs);
474   return IsLess;
475 }
476 
TEST_F(OptionalTest,OperatorLess)477 TEST_F(OptionalTest, OperatorLess) {
478   CheckRelation<Less>(NoneIneq, NoneIneq, false);
479   CheckRelation<Less>(NoneIneq, InequalityRhs, true);
480   CheckRelation<Less>(InequalityLhs, NoneIneq, false);
481 
482   IsLess = false;
483   CheckRelation<Less>(InequalityLhs, InequalityRhs, IsLess);
484   IsLess = true;
485   CheckRelation<Less>(InequalityLhs, InequalityRhs, IsLess);
486 }
487 
TEST_F(OptionalTest,OperatorGreater)488 TEST_F(OptionalTest, OperatorGreater) {
489   CheckRelation<Greater>(NoneIneq, NoneIneq, false);
490   CheckRelation<Greater>(NoneIneq, InequalityRhs, false);
491   CheckRelation<Greater>(InequalityLhs, NoneIneq, true);
492 
493   IsLess = false;
494   CheckRelation<Greater>(InequalityRhs, InequalityLhs, IsLess);
495   IsLess = true;
496   CheckRelation<Greater>(InequalityRhs, InequalityLhs, IsLess);
497 }
498 
TEST_F(OptionalTest,OperatorLessEqual)499 TEST_F(OptionalTest, OperatorLessEqual) {
500   CheckRelation<LessEqual>(NoneIneq, NoneIneq, true);
501   CheckRelation<LessEqual>(NoneIneq, InequalityRhs, true);
502   CheckRelation<LessEqual>(InequalityLhs, NoneIneq, false);
503 
504   IsLess = false;
505   CheckRelation<LessEqual>(InequalityRhs, InequalityLhs, !IsLess);
506   IsLess = true;
507   CheckRelation<LessEqual>(InequalityRhs, InequalityLhs, !IsLess);
508 }
509 
TEST_F(OptionalTest,OperatorGreaterEqual)510 TEST_F(OptionalTest, OperatorGreaterEqual) {
511   CheckRelation<GreaterEqual>(NoneIneq, NoneIneq, true);
512   CheckRelation<GreaterEqual>(NoneIneq, InequalityRhs, false);
513   CheckRelation<GreaterEqual>(InequalityLhs, NoneIneq, true);
514 
515   IsLess = false;
516   CheckRelation<GreaterEqual>(InequalityLhs, InequalityRhs, !IsLess);
517   IsLess = true;
518   CheckRelation<GreaterEqual>(InequalityLhs, InequalityRhs, !IsLess);
519 }
520 
521 #if __has_feature(is_trivially_copyable) && defined(_LIBCPP_VERSION)
522 static_assert(std::is_trivially_copyable<Optional<int>>::value,
523               "Should be trivially copyable");
524 static_assert(
525     !std::is_trivially_copyable<Optional<NonDefaultConstructible>>::value,
526     "Shouldn't be trivially copyable");
527 #endif
528 
529 } // end anonymous namespace
530 
531