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 TEST(OptionalTest, MoveGetValueOr) { 582 Optional<MoveOnly> A; 583 584 MoveOnly::ResetCounts(); 585 EXPECT_EQ(42, std::move(A).getValueOr(MoveOnly(42)).val); 586 EXPECT_EQ(1u, MoveOnly::MoveConstructions); 587 EXPECT_EQ(0u, MoveOnly::MoveAssignments); 588 EXPECT_EQ(2u, MoveOnly::Destructions); 589 590 A = MoveOnly(5); 591 MoveOnly::ResetCounts(); 592 EXPECT_EQ(5, std::move(A).getValueOr(MoveOnly(42)).val); 593 EXPECT_EQ(1u, MoveOnly::MoveConstructions); 594 EXPECT_EQ(0u, MoveOnly::MoveAssignments); 595 EXPECT_EQ(2u, MoveOnly::Destructions); 596 } 597 598 struct EqualTo { 599 template <typename T, typename U> static bool apply(const T &X, const U &Y) { 600 return X == Y; 601 } 602 }; 603 604 struct NotEqualTo { 605 template <typename T, typename U> static bool apply(const T &X, const U &Y) { 606 return X != Y; 607 } 608 }; 609 610 struct Less { 611 template <typename T, typename U> static bool apply(const T &X, const U &Y) { 612 return X < Y; 613 } 614 }; 615 616 struct Greater { 617 template <typename T, typename U> static bool apply(const T &X, const U &Y) { 618 return X > Y; 619 } 620 }; 621 622 struct LessEqual { 623 template <typename T, typename U> static bool apply(const T &X, const U &Y) { 624 return X <= Y; 625 } 626 }; 627 628 struct GreaterEqual { 629 template <typename T, typename U> static bool apply(const T &X, const U &Y) { 630 return X >= Y; 631 } 632 }; 633 634 template <typename OperatorT, typename T> 635 void CheckRelation(const Optional<T> &Lhs, const Optional<T> &Rhs, 636 bool Expected) { 637 EXPECT_EQ(Expected, OperatorT::apply(Lhs, Rhs)); 638 639 if (Lhs) 640 EXPECT_EQ(Expected, OperatorT::apply(*Lhs, Rhs)); 641 else 642 EXPECT_EQ(Expected, OperatorT::apply(None, Rhs)); 643 644 if (Rhs) 645 EXPECT_EQ(Expected, OperatorT::apply(Lhs, *Rhs)); 646 else 647 EXPECT_EQ(Expected, OperatorT::apply(Lhs, None)); 648 } 649 650 struct EqualityMock {}; 651 const Optional<EqualityMock> NoneEq, EqualityLhs((EqualityMock())), 652 EqualityRhs((EqualityMock())); 653 bool IsEqual; 654 655 bool operator==(const EqualityMock &Lhs, const EqualityMock &Rhs) { 656 EXPECT_EQ(&*EqualityLhs, &Lhs); 657 EXPECT_EQ(&*EqualityRhs, &Rhs); 658 return IsEqual; 659 } 660 661 TEST(OptionalTest, OperatorEqual) { 662 CheckRelation<EqualTo>(NoneEq, NoneEq, true); 663 CheckRelation<EqualTo>(NoneEq, EqualityRhs, false); 664 CheckRelation<EqualTo>(EqualityLhs, NoneEq, false); 665 666 IsEqual = false; 667 CheckRelation<EqualTo>(EqualityLhs, EqualityRhs, IsEqual); 668 IsEqual = true; 669 CheckRelation<EqualTo>(EqualityLhs, EqualityRhs, IsEqual); 670 } 671 672 TEST(OptionalTest, OperatorNotEqual) { 673 CheckRelation<NotEqualTo>(NoneEq, NoneEq, false); 674 CheckRelation<NotEqualTo>(NoneEq, EqualityRhs, true); 675 CheckRelation<NotEqualTo>(EqualityLhs, NoneEq, true); 676 677 IsEqual = false; 678 CheckRelation<NotEqualTo>(EqualityLhs, EqualityRhs, !IsEqual); 679 IsEqual = true; 680 CheckRelation<NotEqualTo>(EqualityLhs, EqualityRhs, !IsEqual); 681 } 682 683 struct InequalityMock {}; 684 const Optional<InequalityMock> NoneIneq, InequalityLhs((InequalityMock())), 685 InequalityRhs((InequalityMock())); 686 bool IsLess; 687 688 bool operator<(const InequalityMock &Lhs, const InequalityMock &Rhs) { 689 EXPECT_EQ(&*InequalityLhs, &Lhs); 690 EXPECT_EQ(&*InequalityRhs, &Rhs); 691 return IsLess; 692 } 693 694 TEST(OptionalTest, OperatorLess) { 695 CheckRelation<Less>(NoneIneq, NoneIneq, false); 696 CheckRelation<Less>(NoneIneq, InequalityRhs, true); 697 CheckRelation<Less>(InequalityLhs, NoneIneq, false); 698 699 IsLess = false; 700 CheckRelation<Less>(InequalityLhs, InequalityRhs, IsLess); 701 IsLess = true; 702 CheckRelation<Less>(InequalityLhs, InequalityRhs, IsLess); 703 } 704 705 TEST(OptionalTest, OperatorGreater) { 706 CheckRelation<Greater>(NoneIneq, NoneIneq, false); 707 CheckRelation<Greater>(NoneIneq, InequalityRhs, false); 708 CheckRelation<Greater>(InequalityLhs, NoneIneq, true); 709 710 IsLess = false; 711 CheckRelation<Greater>(InequalityRhs, InequalityLhs, IsLess); 712 IsLess = true; 713 CheckRelation<Greater>(InequalityRhs, InequalityLhs, IsLess); 714 } 715 716 TEST(OptionalTest, OperatorLessEqual) { 717 CheckRelation<LessEqual>(NoneIneq, NoneIneq, true); 718 CheckRelation<LessEqual>(NoneIneq, InequalityRhs, true); 719 CheckRelation<LessEqual>(InequalityLhs, NoneIneq, false); 720 721 IsLess = false; 722 CheckRelation<LessEqual>(InequalityRhs, InequalityLhs, !IsLess); 723 IsLess = true; 724 CheckRelation<LessEqual>(InequalityRhs, InequalityLhs, !IsLess); 725 } 726 727 TEST(OptionalTest, OperatorGreaterEqual) { 728 CheckRelation<GreaterEqual>(NoneIneq, NoneIneq, true); 729 CheckRelation<GreaterEqual>(NoneIneq, InequalityRhs, false); 730 CheckRelation<GreaterEqual>(InequalityLhs, NoneIneq, true); 731 732 IsLess = false; 733 CheckRelation<GreaterEqual>(InequalityLhs, InequalityRhs, !IsLess); 734 IsLess = true; 735 CheckRelation<GreaterEqual>(InequalityLhs, InequalityRhs, !IsLess); 736 } 737 738 struct ComparableAndStreamable { 739 friend bool operator==(ComparableAndStreamable, 740 ComparableAndStreamable) LLVM_ATTRIBUTE_USED { 741 return true; 742 } 743 744 friend raw_ostream &operator<<(raw_ostream &OS, ComparableAndStreamable) { 745 return OS << "ComparableAndStreamable"; 746 } 747 748 static Optional<ComparableAndStreamable> get() { 749 return ComparableAndStreamable(); 750 } 751 }; 752 753 TEST(OptionalTest, StreamOperator) { 754 auto to_string = [](Optional<ComparableAndStreamable> O) { 755 SmallString<16> S; 756 raw_svector_ostream OS(S); 757 OS << O; 758 return S; 759 }; 760 EXPECT_EQ("ComparableAndStreamable", 761 to_string(ComparableAndStreamable::get())); 762 EXPECT_EQ("None", to_string(None)); 763 } 764 765 struct Comparable { 766 friend bool operator==(Comparable, Comparable) LLVM_ATTRIBUTE_USED { 767 return true; 768 } 769 static Optional<Comparable> get() { return Comparable(); } 770 }; 771 772 TEST(OptionalTest, UseInUnitTests) { 773 // Test that we invoke the streaming operators when pretty-printing values in 774 // EXPECT macros. 775 EXPECT_NONFATAL_FAILURE(EXPECT_EQ(llvm::None, ComparableAndStreamable::get()), 776 "Expected equality of these values:\n" 777 " llvm::None\n" 778 " Which is: None\n" 779 " ComparableAndStreamable::get()\n" 780 " Which is: ComparableAndStreamable"); 781 782 // Test that it is still possible to compare objects which do not have a 783 // custom streaming operator. 784 EXPECT_NONFATAL_FAILURE(EXPECT_EQ(llvm::None, Comparable::get()), "object"); 785 } 786 787 TEST(OptionalTest, HashValue) { 788 // Check that None, false, and true all hash differently. 789 Optional<bool> B, B0 = false, B1 = true; 790 EXPECT_NE(hash_value(B0), hash_value(B)); 791 EXPECT_NE(hash_value(B1), hash_value(B)); 792 EXPECT_NE(hash_value(B1), hash_value(B0)); 793 794 // Check that None, 0, and 1 all hash differently. 795 Optional<int> I, I0 = 0, I1 = 1; 796 EXPECT_NE(hash_value(I0), hash_value(I)); 797 EXPECT_NE(hash_value(I1), hash_value(I)); 798 EXPECT_NE(hash_value(I1), hash_value(I0)); 799 800 // Check None hash the same way regardless of type. 801 EXPECT_EQ(hash_value(B), hash_value(I)); 802 } 803 804 struct NotTriviallyCopyable { 805 NotTriviallyCopyable(); // Constructor out-of-line. 806 virtual ~NotTriviallyCopyable() = default; 807 Optional<MoveOnly> MO; 808 }; 809 810 TEST(OptionalTest, GCCIsTriviallyMoveConstructibleCompat) { 811 Optional<NotTriviallyCopyable> V; 812 EXPECT_FALSE(V); 813 } 814 815 } // end anonymous namespace 816