Add assignment support to the hashtables. (#4066)

This lets copy and move assignment work. While it's a bit suboptimal to
do assignment with these tables, it still seems like an unreasonable
burden to not allow the basics to work. Even the toolchain ended up
doing this in a few places.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This commit is contained in:
Chandler Carruth
2024-06-21 21:49:56 +00:00
committed by GitHub
co-authored by Richard Smith
parent 7e4f2f2b49
commit af6312a3aa
5 changed files with 302 additions and 55 deletions
+49
View File
@@ -134,6 +134,22 @@ TYPED_TEST(SetTest, Copy) {
// A new copy does.
SetT other_s2 = s;
ExpectSetElementsAre(other_s2, MakeElements(llvm::seq(1, 32)));
// Copy-assign updates.
other_s1 = s;
ExpectSetElementsAre(other_s1, MakeElements(llvm::seq(1, 32)));
// Self-assign is a no-op.
other_s1 = const_cast<const SetT&>(other_s1);
ExpectSetElementsAre(other_s1, MakeElements(llvm::seq(1, 32)));
// But mutating original still doesn't change copies.
for (int i : llvm::seq(32, 48)) {
SCOPED_TRACE(llvm::formatv("Key: {0}", i).str());
ASSERT_TRUE(s.Insert(i).is_inserted());
}
ExpectSetElementsAre(other_s1, MakeElements(llvm::seq(1, 32)));
ExpectSetElementsAre(other_s2, MakeElements(llvm::seq(1, 32)));
}
TYPED_TEST(SetTest, Move) {
@@ -157,6 +173,39 @@ TYPED_TEST(SetTest, Move) {
ASSERT_TRUE(other_s1.Insert(i).is_inserted());
}
ExpectSetElementsAre(other_s1, MakeElements(llvm::seq(1, 32)));
// Move back over a moved-from.
s = std::move(other_s1);
ExpectSetElementsAre(s, MakeElements(llvm::seq(1, 32)));
// Copy over moved-from state also works.
other_s1 = s;
ExpectSetElementsAre(other_s1, MakeElements(llvm::seq(1, 32)));
// Now add still more elements.
for (int i : llvm::seq(32, 48)) {
SCOPED_TRACE(llvm::formatv("Key: {0}", i).str());
ASSERT_TRUE(other_s1.Insert(i).is_inserted());
}
ExpectSetElementsAre(other_s1, MakeElements(llvm::seq(1, 48)));
// Move-assign over the copy looks like the moved-from table not the copy.
other_s1 = std::move(s);
ExpectSetElementsAre(other_s1, MakeElements(llvm::seq(1, 32)));
// Self-swap (which does a self-move) works and is a no-op.
std::swap(other_s1, other_s1);
ExpectSetElementsAre(other_s1, MakeElements(llvm::seq(1, 32)));
// Test copying of a moved-from table over a valid table and self-move-assign.
// The former is required to be valid, and the latter is in at least the case
// of self-move-assign-when-moved-from, but the result can be in any state so
// just do them and ensure we don't crash.
SetT other_s2 = other_s1;
// NOLINTNEXTLINE(bugprone-use-after-move): Testing required use-after-move.
other_s2 = s;
other_s1 = std::move(other_s1);
s = std::move(s);
}
TYPED_TEST(SetTest, Conversions) {