CloneContext: Add InsertFront()
Inserts a new node at the start of a (potentially empty) list. Change-Id: Ie2896fa3e1beabeb89f64e69a84091986ffbf7a2 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/51369 Reviewed-by: James Price <jrprice@google.com> Reviewed-by: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
parent
81cbe07c12
commit
61fbf13d25
|
@ -226,6 +226,9 @@ class CloneContext {
|
||||||
auto list_transform_it = list_transforms_.find(&v);
|
auto list_transform_it = list_transforms_.find(&v);
|
||||||
if (list_transform_it != list_transforms_.end()) {
|
if (list_transform_it != list_transforms_.end()) {
|
||||||
const auto& transforms = list_transform_it->second;
|
const auto& transforms = list_transform_it->second;
|
||||||
|
for (auto* o : transforms.insert_front_) {
|
||||||
|
out.emplace_back(CheckedCast<T>(o));
|
||||||
|
}
|
||||||
for (auto& el : v) {
|
for (auto& el : v) {
|
||||||
auto insert_before_it = transforms.insert_before_.find(el);
|
auto insert_before_it = transforms.insert_before_.find(el);
|
||||||
if (insert_before_it != transforms.insert_before_.end()) {
|
if (insert_before_it != transforms.insert_before_.end()) {
|
||||||
|
@ -374,6 +377,20 @@ class CloneContext {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Inserts `object` before any other objects of `vector`, when it is cloned.
|
||||||
|
/// @param vector the vector in #src
|
||||||
|
/// @param object a pointer to the object in #dst that will be inserted at the
|
||||||
|
/// front of the vector
|
||||||
|
/// @returns this CloneContext so calls can be chained
|
||||||
|
template <typename T, typename OBJECT>
|
||||||
|
CloneContext& InsertFront(const std::vector<T>& vector, OBJECT* object) {
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(dst, object);
|
||||||
|
auto& transforms = list_transforms_[&vector];
|
||||||
|
auto& list = transforms.insert_front_;
|
||||||
|
list.emplace_back(object);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
/// Inserts `object` before `before` whenever `vector` is cloned.
|
/// Inserts `object` before `before` whenever `vector` is cloned.
|
||||||
/// @param vector the vector in #src
|
/// @param vector the vector in #src
|
||||||
/// @param before a pointer to the object in #src
|
/// @param before a pointer to the object in #src
|
||||||
|
@ -481,6 +498,10 @@ class CloneContext {
|
||||||
/// A map of object in #src to omit when cloned into #dst.
|
/// A map of object in #src to omit when cloned into #dst.
|
||||||
std::unordered_set<const Cloneable*> remove_;
|
std::unordered_set<const Cloneable*> remove_;
|
||||||
|
|
||||||
|
/// A list of objects in #dst to insert before any others when the vector is
|
||||||
|
/// cloned.
|
||||||
|
CloneableList insert_front_;
|
||||||
|
|
||||||
/// A map of object in #src to the list of cloned objects in #dst.
|
/// A map of object in #src to the list of cloned objects in #dst.
|
||||||
/// Clone(const std::vector<T*>& v) will use this to insert the map-value
|
/// Clone(const std::vector<T*>& v) will use this to insert the map-value
|
||||||
/// list into the target vector before cloning and inserting the map-key.
|
/// list into the target vector before cloning and inserting the map-key.
|
||||||
|
|
|
@ -349,6 +349,58 @@ TEST_F(CloneContextNodeTest, CloneWithRemove) {
|
||||||
EXPECT_EQ(cloned_root->vec[1]->name, cloned.Symbols().Get("c"));
|
EXPECT_EQ(cloned_root->vec[1]->name, cloned.Symbols().Get("c"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(CloneContextNodeTest, CloneWithInsertFront) {
|
||||||
|
Allocator a;
|
||||||
|
|
||||||
|
ProgramBuilder builder;
|
||||||
|
auto* original_root = a.Create<Node>(builder.Symbols().Register("root"));
|
||||||
|
original_root->a = a.Create<Node>(builder.Symbols().Register("a"));
|
||||||
|
original_root->b = a.Create<Node>(builder.Symbols().Register("b"));
|
||||||
|
original_root->c = a.Create<Node>(builder.Symbols().Register("c"));
|
||||||
|
original_root->vec = {original_root->a, original_root->b, original_root->c};
|
||||||
|
Program original(std::move(builder));
|
||||||
|
|
||||||
|
ProgramBuilder cloned;
|
||||||
|
auto* insertion = a.Create<Node>(cloned.Symbols().New("insertion"));
|
||||||
|
|
||||||
|
auto* cloned_root = CloneContext(&cloned, &original)
|
||||||
|
.InsertFront(original_root->vec, insertion)
|
||||||
|
.Clone(original_root);
|
||||||
|
|
||||||
|
EXPECT_EQ(cloned_root->vec.size(), 4u);
|
||||||
|
|
||||||
|
EXPECT_NE(cloned_root->vec[0], cloned_root->a);
|
||||||
|
EXPECT_NE(cloned_root->vec[1], cloned_root->b);
|
||||||
|
EXPECT_NE(cloned_root->vec[2], cloned_root->c);
|
||||||
|
|
||||||
|
EXPECT_EQ(cloned_root->name, cloned.Symbols().Get("root"));
|
||||||
|
EXPECT_EQ(cloned_root->vec[0]->name, cloned.Symbols().Get("insertion"));
|
||||||
|
EXPECT_EQ(cloned_root->vec[1]->name, cloned.Symbols().Get("a"));
|
||||||
|
EXPECT_EQ(cloned_root->vec[2]->name, cloned.Symbols().Get("b"));
|
||||||
|
EXPECT_EQ(cloned_root->vec[3]->name, cloned.Symbols().Get("c"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(CloneContextNodeTest, CloneWithInsertFront_Empty) {
|
||||||
|
Allocator a;
|
||||||
|
|
||||||
|
ProgramBuilder builder;
|
||||||
|
auto* original_root = a.Create<Node>(builder.Symbols().Register("root"));
|
||||||
|
original_root->vec = {};
|
||||||
|
Program original(std::move(builder));
|
||||||
|
|
||||||
|
ProgramBuilder cloned;
|
||||||
|
auto* insertion = a.Create<Node>(cloned.Symbols().New("insertion"));
|
||||||
|
|
||||||
|
auto* cloned_root = CloneContext(&cloned, &original)
|
||||||
|
.InsertFront(original_root->vec, insertion)
|
||||||
|
.Clone(original_root);
|
||||||
|
|
||||||
|
EXPECT_EQ(cloned_root->vec.size(), 1u);
|
||||||
|
|
||||||
|
EXPECT_EQ(cloned_root->name, cloned.Symbols().Get("root"));
|
||||||
|
EXPECT_EQ(cloned_root->vec[0]->name, cloned.Symbols().Get("insertion"));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(CloneContextNodeTest, CloneWithInsertBefore) {
|
TEST_F(CloneContextNodeTest, CloneWithInsertBefore) {
|
||||||
Allocator a;
|
Allocator a;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue