diff --git a/src/tint/sem/type_manager.h b/src/tint/sem/type_manager.h index fb08689674..d2befcd03d 100644 --- a/src/tint/sem/type_manager.h +++ b/src/tint/sem/type_manager.h @@ -59,6 +59,22 @@ class Manager final : public utils::UniqueAllocator { return out; } + /// @param args the arguments used to create the temporary type used for the search. + /// @return a pointer to an instance of `T` with the provided arguments, or nullptr if the type + /// was not found. + template + TYPE* Find(ARGS&&... args) const { + // Create a temporary T instance on the stack so that we can hash it, and + // use it for equality lookup for the std::unordered_set. + TYPE key{args...}; + auto hash = Hasher{}(key); + auto it = items.find(Entry{hash, &key}); + if (it != items.end()) { + return static_cast(it->ptr); + } + return nullptr; + } + /// @returns an iterator to the beginning of the types Iterator begin() const { return allocator.Objects().begin(); } /// @returns an iterator to the end of the types diff --git a/src/tint/sem/type_manager_test.cc b/src/tint/sem/type_manager_test.cc index c670db00ca..b9c90fec7e 100644 --- a/src/tint/sem/type_manager_test.cc +++ b/src/tint/sem/type_manager_test.cc @@ -62,6 +62,14 @@ TEST_F(TypeManagerTest, GetDifferentTypeReturnsDifferentPtr) { EXPECT_TRUE(t2->Is()); } +TEST_F(TypeManagerTest, Find) { + Manager tm; + auto* created = tm.Get(); + + EXPECT_EQ(tm.Find(), nullptr); + EXPECT_EQ(tm.Find(), created); +} + TEST_F(TypeManagerTest, WrapDoesntAffectInner) { Manager inner; Manager outer = Manager::Wrap(inner); diff --git a/src/tint/utils/unique_allocator.h b/src/tint/utils/unique_allocator.h index 628bc792ce..129770113b 100644 --- a/src/tint/utils/unique_allocator.h +++ b/src/tint/utils/unique_allocator.h @@ -39,7 +39,7 @@ class UniqueAllocator { // found in the set, then we create the persisted instance with the // allocator. TYPE key{args...}; - auto hash = HASH{}(key); + auto hash = Hasher{}(key); auto it = items.find(Entry{hash, &key}); if (it != items.end()) { return static_cast(it->ptr); @@ -50,6 +50,11 @@ class UniqueAllocator { } protected: + /// The hash function + using Hasher = HASH; + /// The equality function + using Equality = EQUAL; + /// Entry is used as the entry to the unordered_set struct Entry { /// The pre-calculated hash of the entry