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