Add move ctor/assignment to Optional<T>

Code review feedback for r175580 by Jordan Rose.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175729 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Blaikie
2013-02-21 07:55:39 +00:00
parent 17cec5a685
commit ea72255f5b
2 changed files with 138 additions and 0 deletions

View File

@@ -40,6 +40,36 @@ unsigned NonDefaultConstructible::CopyConstructions = 0;
unsigned NonDefaultConstructible::Destructions = 0;
unsigned NonDefaultConstructible::CopyAssignments = 0;
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 fixture
class OptionalTest : public testing::Test {
};
@@ -169,5 +199,84 @@ TEST_F(OptionalTest, NullCopyConstructionTest) {
EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
}
TEST_F(OptionalTest, MoveOnlyNull) {
MoveOnly::ResetCounts();
Optional<MoveOnly> O;
EXPECT_EQ(0u, MoveOnly::MoveConstructions);
EXPECT_EQ(0u, MoveOnly::MoveAssignments);
EXPECT_EQ(0u, MoveOnly::Destructions);
}
TEST_F(OptionalTest, MoveOnlyConstruction) {
MoveOnly::ResetCounts();
Optional<MoveOnly> 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<MoveOnly> A(MoveOnly(3));
MoveOnly::ResetCounts();
Optional<MoveOnly> 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<MoveOnly> 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<MoveOnly> A(MoveOnly(3));
Optional<MoveOnly> 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<MoveOnly> A;
Optional<MoveOnly> 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<MoveOnly> A(MoveOnly(3));
Optional<MoveOnly> 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);
}
} // end anonymous namespace