mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-06-20 21:43:29 +00:00
CloneContext: Add Remove()
Omits an object from a vector when that vector is cloned Bug: tint:183 Change-Id: I543c885609591dcd3b930ca00b8c1a78bc61f920 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/51301 Commit-Queue: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
parent
9b54a2e53c
commit
a240c480fa
@ -18,6 +18,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -248,6 +249,9 @@ class CloneContext {
|
|||||||
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& el : v) {
|
for (auto& el : v) {
|
||||||
|
if (transforms.remove_.count(el)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
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()) {
|
||||||
for (auto insert : insert_before_it->second) {
|
for (auto insert : insert_before_it->second) {
|
||||||
@ -369,10 +373,30 @@ class CloneContext {
|
|||||||
/// @returns this CloneContext so calls can be chained
|
/// @returns this CloneContext so calls can be chained
|
||||||
template <typename WHAT, typename WITH>
|
template <typename WHAT, typename WITH>
|
||||||
CloneContext& Replace(WHAT* what, WITH* with) {
|
CloneContext& Replace(WHAT* what, WITH* with) {
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(src, what);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(dst, with);
|
||||||
cloned_[what] = with;
|
cloned_[what] = with;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Removes `object` from the cloned copy of `vector`.
|
||||||
|
/// @param vector the vector in #src
|
||||||
|
/// @param object a pointer to the object in #src that will be omitted from
|
||||||
|
/// the cloned vector.
|
||||||
|
/// @returns this CloneContext so calls can be chained
|
||||||
|
template <typename T, typename OBJECT>
|
||||||
|
CloneContext& Remove(const std::vector<T>& vector, OBJECT* object) {
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(src, object);
|
||||||
|
if (std::find(vector.begin(), vector.end(), object) == vector.end()) {
|
||||||
|
TINT_ICE(Diagnostics())
|
||||||
|
<< "CloneContext::Remove() vector does not contain object";
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
list_transforms_[&vector].remove_.emplace(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
|
||||||
@ -383,6 +407,8 @@ class CloneContext {
|
|||||||
CloneContext& InsertBefore(const std::vector<T>& vector,
|
CloneContext& InsertBefore(const std::vector<T>& vector,
|
||||||
const BEFORE* before,
|
const BEFORE* before,
|
||||||
OBJECT* object) {
|
OBJECT* object) {
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(src, before);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(dst, object);
|
||||||
if (std::find(vector.begin(), vector.end(), before) == vector.end()) {
|
if (std::find(vector.begin(), vector.end(), before) == vector.end()) {
|
||||||
TINT_ICE(Diagnostics())
|
TINT_ICE(Diagnostics())
|
||||||
<< "CloneContext::InsertBefore() vector does not contain before";
|
<< "CloneContext::InsertBefore() vector does not contain before";
|
||||||
@ -405,6 +431,8 @@ class CloneContext {
|
|||||||
CloneContext& InsertAfter(const std::vector<T>& vector,
|
CloneContext& InsertAfter(const std::vector<T>& vector,
|
||||||
const AFTER* after,
|
const AFTER* after,
|
||||||
OBJECT* object) {
|
OBJECT* object) {
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(src, after);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(dst, object);
|
||||||
if (std::find(vector.begin(), vector.end(), after) == vector.end()) {
|
if (std::find(vector.begin(), vector.end(), after) == vector.end()) {
|
||||||
TINT_ICE(Diagnostics())
|
TINT_ICE(Diagnostics())
|
||||||
<< "CloneContext::InsertAfter() vector does not contain after";
|
<< "CloneContext::InsertAfter() vector does not contain after";
|
||||||
@ -453,7 +481,10 @@ class CloneContext {
|
|||||||
if (TO* cast = As<TO>(obj)) {
|
if (TO* cast = As<TO>(obj)) {
|
||||||
return cast;
|
return cast;
|
||||||
}
|
}
|
||||||
TINT_ICE(Diagnostics()) << "Cloned object was not of the expected type";
|
TINT_ICE(Diagnostics())
|
||||||
|
<< "Cloned object was not of the expected type\n"
|
||||||
|
<< "got: " << (obj ? obj->TypeInfo().name : "<null>") << "\n"
|
||||||
|
<< "expected: " << TypeInfo::Of<TO>().name;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -470,6 +501,9 @@ class CloneContext {
|
|||||||
/// Destructor
|
/// Destructor
|
||||||
~ListTransforms();
|
~ListTransforms();
|
||||||
|
|
||||||
|
/// A map of object in #src to omit when cloned into #dst.
|
||||||
|
std::unordered_set<const Cloneable*> remove_;
|
||||||
|
|
||||||
/// 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.
|
||||||
|
@ -397,6 +397,39 @@ TYPED_TEST(CloneContextNodeTest, CloneWithReplace) {
|
|||||||
EXPECT_EQ(cloned_root->c->name, cloned.Symbols().Get("c"));
|
EXPECT_EQ(cloned_root->c->name, cloned.Symbols().Get("c"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(CloneContextNodeTest, CloneWithRemove) {
|
||||||
|
using Node = typename TestFixture::Node;
|
||||||
|
constexpr bool is_unique = TestFixture::is_unique;
|
||||||
|
|
||||||
|
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* cloned_root = CloneContext(&cloned, &original)
|
||||||
|
.Remove(original_root->vec, original_root->b)
|
||||||
|
.Clone(original_root);
|
||||||
|
|
||||||
|
EXPECT_EQ(cloned_root->vec.size(), 2u);
|
||||||
|
if (is_unique) {
|
||||||
|
EXPECT_NE(cloned_root->vec[0], cloned_root->a);
|
||||||
|
EXPECT_NE(cloned_root->vec[1], cloned_root->c);
|
||||||
|
} else {
|
||||||
|
EXPECT_EQ(cloned_root->vec[0], cloned_root->a);
|
||||||
|
EXPECT_EQ(cloned_root->vec[1], cloned_root->c);
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_EQ(cloned_root->name, cloned.Symbols().Get("root"));
|
||||||
|
EXPECT_EQ(cloned_root->vec[0]->name, cloned.Symbols().Get("a"));
|
||||||
|
EXPECT_EQ(cloned_root->vec[1]->name, cloned.Symbols().Get("c"));
|
||||||
|
}
|
||||||
|
|
||||||
TYPED_TEST(CloneContextNodeTest, CloneWithInsertBefore) {
|
TYPED_TEST(CloneContextNodeTest, CloneWithInsertBefore) {
|
||||||
using Node = typename TestFixture::Node;
|
using Node = typename TestFixture::Node;
|
||||||
constexpr bool is_unique = TestFixture::is_unique;
|
constexpr bool is_unique = TestFixture::is_unique;
|
||||||
@ -691,7 +724,7 @@ TEST_F(CloneContextTest, ProgramIDs) {
|
|||||||
EXPECT_EQ(cloned->program_id, dst.ID());
|
EXPECT_EQ(cloned->program_id, dst.ID());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(CloneContextTest, ProgramIDs_ObjectNotOwnedBySrc) {
|
TEST_F(CloneContextTest, ProgramIDs_Clone_ObjectNotOwnedBySrc) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder dst;
|
ProgramBuilder dst;
|
||||||
@ -703,7 +736,7 @@ TEST_F(CloneContextTest, ProgramIDs_ObjectNotOwnedBySrc) {
|
|||||||
R"(internal compiler error: TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(src, a))");
|
R"(internal compiler error: TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(src, a))");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(CloneContextTest, ProgramIDs_ObjectNotOwnedByDst) {
|
TEST_F(CloneContextTest, ProgramIDs_Clone_ObjectNotOwnedByDst) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder dst;
|
ProgramBuilder dst;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user