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