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