tint/sem: Add Find() to the type manager

Lets you lookup a type without modifying anything.

Change-Id: I7a37d37f1c49c7f37f96c35b8e73a66743d9000a
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/100906
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
Ben Clayton 2022-09-01 09:15:20 +00:00 committed by Dawn LUCI CQ
parent 6903fc0c46
commit 2b47c21640
3 changed files with 30 additions and 1 deletions

View File

@ -59,6 +59,22 @@ class Manager final : public utils::UniqueAllocator<Type> {
return out; 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 <typename TYPE, typename... ARGS>
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<TYPE*>(it->ptr);
}
return nullptr;
}
/// @returns an iterator to the beginning of the types /// @returns an iterator to the beginning of the types
Iterator begin() const { return allocator.Objects().begin(); } Iterator begin() const { return allocator.Objects().begin(); }
/// @returns an iterator to the end of the types /// @returns an iterator to the end of the types

View File

@ -62,6 +62,14 @@ TEST_F(TypeManagerTest, GetDifferentTypeReturnsDifferentPtr) {
EXPECT_TRUE(t2->Is<U32>()); EXPECT_TRUE(t2->Is<U32>());
} }
TEST_F(TypeManagerTest, Find) {
Manager tm;
auto* created = tm.Get<I32>();
EXPECT_EQ(tm.Find<U32>(), nullptr);
EXPECT_EQ(tm.Find<I32>(), created);
}
TEST_F(TypeManagerTest, WrapDoesntAffectInner) { TEST_F(TypeManagerTest, WrapDoesntAffectInner) {
Manager inner; Manager inner;
Manager outer = Manager::Wrap(inner); Manager outer = Manager::Wrap(inner);

View File

@ -39,7 +39,7 @@ class UniqueAllocator {
// found in the set, then we create the persisted instance with the // found in the set, then we create the persisted instance with the
// allocator. // allocator.
TYPE key{args...}; TYPE key{args...};
auto hash = HASH{}(key); auto hash = Hasher{}(key);
auto it = items.find(Entry{hash, &key}); auto it = items.find(Entry{hash, &key});
if (it != items.end()) { if (it != items.end()) {
return static_cast<TYPE*>(it->ptr); return static_cast<TYPE*>(it->ptr);
@ -50,6 +50,11 @@ class UniqueAllocator {
} }
protected: protected:
/// The hash function
using Hasher = HASH;
/// The equality function
using Equality = EQUAL;
/// Entry is used as the entry to the unordered_set /// Entry is used as the entry to the unordered_set
struct Entry { struct Entry {
/// The pre-calculated hash of the entry /// The pre-calculated hash of the entry