X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=unittests%2FADT%2FOptionalTest.cpp;h=18b59e315818eaa84eb35464e702b131c9099c1d;hb=813f44a29fd0fd140127023222d0633e23783bcc;hp=8bdea45c5a93de63947c1d6b51e723a2abe50740;hpb=a28eda7e401f37a2fe42ca9bba96b6e662b60cf0;p=oota-llvm.git diff --git a/unittests/ADT/OptionalTest.cpp b/unittests/ADT/OptionalTest.cpp index 8bdea45c5a9..18b59e31581 100644 --- a/unittests/ADT/OptionalTest.cpp +++ b/unittests/ADT/OptionalTest.cpp @@ -56,7 +56,7 @@ TEST_F(OptionalTest, ResetTest) { EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); EXPECT_EQ(1u, NonDefaultConstructible::Destructions); NonDefaultConstructible::ResetCounts(); - O.Reset(); + O.reset(); EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); EXPECT_EQ(1u, NonDefaultConstructible::Destructions); @@ -169,5 +169,226 @@ TEST_F(OptionalTest, NullCopyConstructionTest) { EXPECT_EQ(0u, NonDefaultConstructible::Destructions); } +TEST_F(OptionalTest, GetValueOr) { + Optional A; + EXPECT_EQ(42, A.getValueOr(42)); + + A = 5; + EXPECT_EQ(5, A.getValueOr(42)); +} + +struct MultiArgConstructor { + int x, y; + MultiArgConstructor(int x, int y) : x(x), y(y) {} + explicit MultiArgConstructor(int x, bool positive) + : x(x), y(positive ? x : -x) {} + + MultiArgConstructor(const MultiArgConstructor &) = delete; + MultiArgConstructor(MultiArgConstructor &&) = delete; + MultiArgConstructor &operator=(const MultiArgConstructor &) = delete; + MultiArgConstructor &operator=(MultiArgConstructor &&) = delete; + + static unsigned Destructions; + ~MultiArgConstructor() { + ++Destructions; + } + static void ResetCounts() { + Destructions = 0; + } +}; +unsigned MultiArgConstructor::Destructions = 0; + +TEST_F(OptionalTest, Emplace) { + MultiArgConstructor::ResetCounts(); + Optional A; + + A.emplace(1, 2); + EXPECT_TRUE(A.hasValue()); + EXPECT_EQ(1, A->x); + EXPECT_EQ(2, A->y); + EXPECT_EQ(0u, MultiArgConstructor::Destructions); + + A.emplace(5, false); + EXPECT_TRUE(A.hasValue()); + EXPECT_EQ(5, A->x); + EXPECT_EQ(-5, A->y); + EXPECT_EQ(1u, MultiArgConstructor::Destructions); +} + +struct MoveOnly { + static unsigned MoveConstructions; + static unsigned Destructions; + static unsigned MoveAssignments; + int val; + explicit MoveOnly(int val) : val(val) { + } + MoveOnly(MoveOnly&& other) { + val = other.val; + ++MoveConstructions; + } + MoveOnly &operator=(MoveOnly&& other) { + val = other.val; + ++MoveAssignments; + return *this; + } + ~MoveOnly() { + ++Destructions; + } + static void ResetCounts() { + MoveConstructions = 0; + Destructions = 0; + MoveAssignments = 0; + } +}; + +unsigned MoveOnly::MoveConstructions = 0; +unsigned MoveOnly::Destructions = 0; +unsigned MoveOnly::MoveAssignments = 0; + +TEST_F(OptionalTest, MoveOnlyNull) { + MoveOnly::ResetCounts(); + Optional O; + EXPECT_EQ(0u, MoveOnly::MoveConstructions); + EXPECT_EQ(0u, MoveOnly::MoveAssignments); + EXPECT_EQ(0u, MoveOnly::Destructions); +} + +TEST_F(OptionalTest, MoveOnlyConstruction) { + MoveOnly::ResetCounts(); + Optional O(MoveOnly(3)); + EXPECT_TRUE((bool)O); + EXPECT_EQ(3, O->val); + EXPECT_EQ(1u, MoveOnly::MoveConstructions); + EXPECT_EQ(0u, MoveOnly::MoveAssignments); + EXPECT_EQ(1u, MoveOnly::Destructions); +} + +TEST_F(OptionalTest, MoveOnlyMoveConstruction) { + Optional A(MoveOnly(3)); + MoveOnly::ResetCounts(); + Optional B(std::move(A)); + EXPECT_FALSE((bool)A); + EXPECT_TRUE((bool)B); + EXPECT_EQ(3, B->val); + EXPECT_EQ(1u, MoveOnly::MoveConstructions); + EXPECT_EQ(0u, MoveOnly::MoveAssignments); + EXPECT_EQ(1u, MoveOnly::Destructions); +} + +TEST_F(OptionalTest, MoveOnlyAssignment) { + MoveOnly::ResetCounts(); + Optional O; + O = MoveOnly(3); + EXPECT_TRUE((bool)O); + EXPECT_EQ(3, O->val); + EXPECT_EQ(1u, MoveOnly::MoveConstructions); + EXPECT_EQ(0u, MoveOnly::MoveAssignments); + EXPECT_EQ(1u, MoveOnly::Destructions); +} + +TEST_F(OptionalTest, MoveOnlyInitializingAssignment) { + Optional A(MoveOnly(3)); + Optional B; + MoveOnly::ResetCounts(); + B = std::move(A); + EXPECT_FALSE((bool)A); + EXPECT_TRUE((bool)B); + EXPECT_EQ(3, B->val); + EXPECT_EQ(1u, MoveOnly::MoveConstructions); + EXPECT_EQ(0u, MoveOnly::MoveAssignments); + EXPECT_EQ(1u, MoveOnly::Destructions); +} + +TEST_F(OptionalTest, MoveOnlyNullingAssignment) { + Optional A; + Optional B(MoveOnly(3)); + MoveOnly::ResetCounts(); + B = std::move(A); + EXPECT_FALSE((bool)A); + EXPECT_FALSE((bool)B); + EXPECT_EQ(0u, MoveOnly::MoveConstructions); + EXPECT_EQ(0u, MoveOnly::MoveAssignments); + EXPECT_EQ(1u, MoveOnly::Destructions); +} + +TEST_F(OptionalTest, MoveOnlyAssigningAssignment) { + Optional A(MoveOnly(3)); + Optional B(MoveOnly(4)); + MoveOnly::ResetCounts(); + B = std::move(A); + EXPECT_FALSE((bool)A); + EXPECT_TRUE((bool)B); + EXPECT_EQ(3, B->val); + EXPECT_EQ(0u, MoveOnly::MoveConstructions); + EXPECT_EQ(1u, MoveOnly::MoveAssignments); + EXPECT_EQ(1u, MoveOnly::Destructions); +} + +struct Immovable { + static unsigned Constructions; + static unsigned Destructions; + int val; + explicit Immovable(int val) : val(val) { + ++Constructions; + } + ~Immovable() { + ++Destructions; + } + static void ResetCounts() { + Constructions = 0; + Destructions = 0; + } +private: + // This should disable all move/copy operations. + Immovable(Immovable&& other) = delete; +}; + +unsigned Immovable::Constructions = 0; +unsigned Immovable::Destructions = 0; + +TEST_F(OptionalTest, ImmovableEmplace) { + Optional A; + Immovable::ResetCounts(); + A.emplace(4); + EXPECT_TRUE((bool)A); + EXPECT_EQ(4, A->val); + EXPECT_EQ(1u, Immovable::Constructions); + EXPECT_EQ(0u, Immovable::Destructions); +} + +#if LLVM_HAS_RVALUE_REFERENCE_THIS + +TEST_F(OptionalTest, MoveGetValueOr) { + Optional A; + + MoveOnly::ResetCounts(); + EXPECT_EQ(42, std::move(A).getValueOr(MoveOnly(42)).val); + EXPECT_EQ(1u, MoveOnly::MoveConstructions); + EXPECT_EQ(0u, MoveOnly::MoveAssignments); + EXPECT_EQ(2u, MoveOnly::Destructions); + + A = MoveOnly(5); + MoveOnly::ResetCounts(); + EXPECT_EQ(5, std::move(A).getValueOr(MoveOnly(42)).val); + EXPECT_EQ(1u, MoveOnly::MoveConstructions); + EXPECT_EQ(0u, MoveOnly::MoveAssignments); + EXPECT_EQ(2u, MoveOnly::Destructions); +} + +#endif // LLVM_HAS_RVALUE_REFERENCE_THIS + +TEST_F(OptionalTest, NoneComparison) { + Optional o; + EXPECT_EQ(o, None); + EXPECT_EQ(None, o); + EXPECT_FALSE(o != None); + EXPECT_FALSE(None != o); + o = 3; + EXPECT_FALSE(o == None); + EXPECT_FALSE(None == o); + EXPECT_TRUE(o != None); + EXPECT_TRUE(None != o); +} + } // end anonymous namespace