diff --git a/src/tint/sem/type_manager.h b/src/tint/sem/type_manager.h index 636b7a04e6..72f843ad5b 100644 --- a/src/tint/sem/type_manager.h +++ b/src/tint/sem/type_manager.h @@ -25,10 +25,10 @@ namespace tint::sem { /// The type manager holds all the pointers to the known types. -class TypeManager final : public utils::UniqueAllocator { +class TypeManager final { public: /// Iterator is the type returned by begin() and end() - using Iterator = utils::BlockAllocator::ConstIterator; + using TypeIterator = utils::BlockAllocator::ConstIterator; /// Constructor TypeManager(); @@ -55,30 +55,38 @@ class TypeManager final : public utils::UniqueAllocator { /// @return the Manager that wraps `inner` static TypeManager Wrap(const TypeManager& inner) { TypeManager out; - out.items = inner.items; + out.types_.Wrap(inner.types_); 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 + /// @param args the arguments used to construct the object. + /// @return a pointer to an instance of `T` with the provided arguments. + /// If an existing instance of `T` has been constructed, then the same + /// pointer is returned. + template >, + typename... ARGS> + TYPE* Get(ARGS&&... args) { + return types_.Get(std::forward(args)...); + } + + /// @param args the arguments used to create the temporary used for the search. + /// @return a pointer to an instance of `T` with the provided arguments, or nullptr if the item /// was not found. - template + template >, + 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(it->ptr); - } - return nullptr; + return types_.Find(std::forward(args)...); } /// @returns an iterator to the beginning of the types - Iterator begin() const { return allocator.Objects().begin(); } + TypeIterator begin() const { return types_.begin(); } /// @returns an iterator to the end of the types - Iterator end() const { return allocator.Objects().end(); } + TypeIterator end() const { return types_.end(); } + + private: + utils::UniqueAllocator types_; }; } // namespace tint::sem diff --git a/src/tint/utils/unique_allocator.h b/src/tint/utils/unique_allocator.h index 129770113b..25681cdfff 100644 --- a/src/tint/utils/unique_allocator.h +++ b/src/tint/utils/unique_allocator.h @@ -28,6 +28,9 @@ namespace tint::utils { template , typename EQUAL = std::equal_to> class UniqueAllocator { public: + /// Iterator is the type returned by begin() and end() + using Iterator = typename BlockAllocator::ConstIterator; + /// @param args the arguments used to construct the object. /// @return a pointer to an instance of `T` with the provided arguments. /// If an existing instance of `T` has been constructed, then the same @@ -49,7 +52,36 @@ class UniqueAllocator { return ptr; } - protected: + /// @param args the arguments used to create the temporary used for the search. + /// @return a pointer to an instance of `T` with the provided arguments, or nullptr if the item + /// 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; + } + + /// Wrap sets this allocator to the objects created with the content of `inner`. + /// The allocator after Wrap is intended to temporarily extend the objects + /// of an existing immutable UniqueAllocator. + /// As the copied objects are owned by `inner`, `inner` must not be destructed + /// or assigned while using this allocator. + /// @param o the immutable UniqueAlllocator to extend + void Wrap(const UniqueAllocator& o) { items = o.items; } + + /// @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 + Iterator end() const { return allocator.Objects().end(); } + + private: /// The hash function using Hasher = HASH; /// The equality function