blob: 0650f1bb4aeb118d999880f8d8cad739310eb0bc [file] [log] [blame]
dan sinclairc9949ac2022-12-08 12:03:53 +00001// Copyright 2022 The Tint Authors.
Ryan Harrisondbc13af2022-02-21 15:19:07 +00002//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
dan sinclair837b8042022-12-09 05:00:07 +000015#ifndef SRC_TINT_TYPE_MANAGER_H_
16#define SRC_TINT_TYPE_MANAGER_H_
Ryan Harrisondbc13af2022-02-21 15:19:07 +000017
Ryan Harrisondbc13af2022-02-21 15:19:07 +000018#include <utility>
19
dan sinclair5f764d82022-12-08 00:32:27 +000020#include "src/tint/type/type.h"
Ben Clayton7c3e9a62022-12-16 15:31:19 +000021#include "src/tint/utils/hash.h"
Ben Clayton43919752022-03-07 17:05:28 +000022#include "src/tint/utils/unique_allocator.h"
Ryan Harrisondbc13af2022-02-21 15:19:07 +000023
dan sinclairc9949ac2022-12-08 12:03:53 +000024namespace tint::type {
Ryan Harrisondbc13af2022-02-21 15:19:07 +000025
26/// The type manager holds all the pointers to the known types.
dan sinclair837b8042022-12-09 05:00:07 +000027class Manager final {
dan sinclair41e4d9a2022-05-01 14:40:55 +000028 public:
29 /// Iterator is the type returned by begin() and end()
dan sinclair98705d42022-12-08 22:21:24 +000030 using TypeIterator = utils::BlockAllocator<Type>::ConstIterator;
Ryan Harrisondbc13af2022-02-21 15:19:07 +000031
dan sinclair41e4d9a2022-05-01 14:40:55 +000032 /// Constructor
dan sinclair837b8042022-12-09 05:00:07 +000033 Manager();
Ryan Harrisondbc13af2022-02-21 15:19:07 +000034
dan sinclair41e4d9a2022-05-01 14:40:55 +000035 /// Move constructor
dan sinclair837b8042022-12-09 05:00:07 +000036 Manager(Manager&&);
Ryan Harrisondbc13af2022-02-21 15:19:07 +000037
dan sinclair41e4d9a2022-05-01 14:40:55 +000038 /// Move assignment operator
39 /// @param rhs the Manager to move
40 /// @return this Manager
dan sinclair837b8042022-12-09 05:00:07 +000041 Manager& operator=(Manager&& rhs);
Ryan Harrisondbc13af2022-02-21 15:19:07 +000042
dan sinclair41e4d9a2022-05-01 14:40:55 +000043 /// Destructor
dan sinclair837b8042022-12-09 05:00:07 +000044 ~Manager();
Ryan Harrisondbc13af2022-02-21 15:19:07 +000045
dan sinclair41e4d9a2022-05-01 14:40:55 +000046 /// Wrap returns a new Manager created with the types of `inner`.
47 /// The Manager returned by Wrap is intended to temporarily extend the types
48 /// of an existing immutable Manager.
49 /// As the copied types are owned by `inner`, `inner` must not be destructed
50 /// or assigned while using the returned Manager.
51 /// TODO(bclayton) - Evaluate whether there are safer alternatives to this
52 /// function. See crbug.com/tint/460.
53 /// @param inner the immutable Manager to extend
54 /// @return the Manager that wraps `inner`
dan sinclair837b8042022-12-09 05:00:07 +000055 static Manager Wrap(const Manager& inner) {
56 Manager out;
dan sinclair847cfa02022-12-01 21:42:47 +000057 out.types_.Wrap(inner.types_);
Ben Clayton7c3e9a62022-12-16 15:31:19 +000058 out.unique_nodes_.Wrap(inner.unique_nodes_);
dan sinclair41e4d9a2022-05-01 14:40:55 +000059 return out;
60 }
Ryan Harrisondbc13af2022-02-21 15:19:07 +000061
Ben Clayton7c3e9a62022-12-16 15:31:19 +000062 /// @param args the arguments used to construct the type, unique node or node.
dan sinclair847cfa02022-12-01 21:42:47 +000063 /// @return a pointer to an instance of `T` with the provided arguments.
Ben Clayton7c3e9a62022-12-16 15:31:19 +000064 /// If NODE derives from UniqueNode and an existing instance of `T` has been
65 /// constructed, then the same pointer is returned.
66 template <typename NODE, typename... ARGS>
67 NODE* Get(ARGS&&... args) {
dan sinclair05590052023-04-19 16:52:46 +000068 if constexpr (utils::traits::IsTypeOrDerived<NODE, Type>) {
Ben Clayton7c3e9a62022-12-16 15:31:19 +000069 return types_.Get<NODE>(std::forward<ARGS>(args)...);
dan sinclair05590052023-04-19 16:52:46 +000070 } else if constexpr (utils::traits::IsTypeOrDerived<NODE, UniqueNode>) {
Ben Clayton7c3e9a62022-12-16 15:31:19 +000071 return unique_nodes_.Get<NODE>(std::forward<ARGS>(args)...);
72 } else {
73 return nodes_.Create<NODE>(std::forward<ARGS>(args)...);
74 }
dan sinclair847cfa02022-12-01 21:42:47 +000075 }
76
77 /// @param args the arguments used to create the temporary used for the search.
78 /// @return a pointer to an instance of `T` with the provided arguments, or nullptr if the item
Ben Clayton2b47c212022-09-01 09:15:20 +000079 /// was not found.
dan sinclair847cfa02022-12-01 21:42:47 +000080 template <typename TYPE,
dan sinclair05590052023-04-19 16:52:46 +000081 typename _ = std::enable_if<utils::traits::IsTypeOrDerived<TYPE, Type>>,
dan sinclair847cfa02022-12-01 21:42:47 +000082 typename... ARGS>
Ben Clayton2b47c212022-09-01 09:15:20 +000083 TYPE* Find(ARGS&&... args) const {
dan sinclair847cfa02022-12-01 21:42:47 +000084 return types_.Find<TYPE>(std::forward<ARGS>(args)...);
Ben Clayton2b47c212022-09-01 09:15:20 +000085 }
86
dan sinclair41e4d9a2022-05-01 14:40:55 +000087 /// @returns an iterator to the beginning of the types
dan sinclair847cfa02022-12-01 21:42:47 +000088 TypeIterator begin() const { return types_.begin(); }
dan sinclair41e4d9a2022-05-01 14:40:55 +000089 /// @returns an iterator to the end of the types
dan sinclair847cfa02022-12-01 21:42:47 +000090 TypeIterator end() const { return types_.end(); }
91
92 private:
Ben Clayton7c3e9a62022-12-16 15:31:19 +000093 /// Unique types owned by the manager
dan sinclair98705d42022-12-08 22:21:24 +000094 utils::UniqueAllocator<Type> types_;
Ben Clayton7c3e9a62022-12-16 15:31:19 +000095 /// Unique nodes (excluding types) owned by the manager
96 utils::UniqueAllocator<UniqueNode> unique_nodes_;
97 /// Non-unique nodes owned by the manager
98 utils::BlockAllocator<Node> nodes_;
Ryan Harrisondbc13af2022-02-21 15:19:07 +000099};
100
dan sinclairc9949ac2022-12-08 12:03:53 +0000101} // namespace tint::type
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000102
dan sinclair837b8042022-12-09 05:00:07 +0000103#endif // SRC_TINT_TYPE_MANAGER_H_