• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Tint Authors.
2 //
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 
15 #ifndef SRC_SEM_TYPE_MANAGER_H_
16 #define SRC_SEM_TYPE_MANAGER_H_
17 
18 #include <string>
19 #include <unordered_map>
20 #include <utility>
21 
22 #include "src/block_allocator.h"
23 #include "src/sem/type.h"
24 
25 namespace tint {
26 namespace sem {
27 
28 /// The type manager holds all the pointers to the known types.
29 class Manager {
30  public:
31   /// Iterator is the type returned by begin() and end()
32   using Iterator = BlockAllocator<sem::Type>::ConstIterator;
33 
34   /// Constructor
35   Manager();
36 
37   /// Move constructor
38   Manager(Manager&&);
39 
40   /// Move assignment operator
41   /// @param rhs the Manager to move
42   /// @return this Manager
43   Manager& operator=(Manager&& rhs);
44 
45   /// Destructor
46   ~Manager();
47 
48   /// Get the given type `T` from the type manager
49   /// @param args the arguments to pass to the type constructor
50   /// @return the pointer to the registered type
51   template <typename T, typename... ARGS>
Get(ARGS &&...args)52   T* Get(ARGS&&... args) {
53     // Note: We do not use std::forward here, as we may need to use the
54     // arguments again for the call to Create<T>() below.
55     auto name = T(args...).type_name();
56     auto it = by_name_.find(name);
57     if (it != by_name_.end()) {
58       return static_cast<T*>(it->second);
59     }
60 
61     auto* type = types_.Create<T>(std::forward<ARGS>(args)...);
62     by_name_.emplace(name, type);
63     return type;
64   }
65 
66   /// Wrap returns a new Manager created with the types of `inner`.
67   /// The Manager returned by Wrap is intended to temporarily extend the types
68   /// of an existing immutable Manager.
69   /// As the copied types are owned by `inner`, `inner` must not be destructed
70   /// or assigned while using the returned Manager.
71   /// TODO(bclayton) - Evaluate whether there are safer alternatives to this
72   /// function. See crbug.com/tint/460.
73   /// @param inner the immutable Manager to extend
74   /// @return the Manager that wraps `inner`
Wrap(const Manager & inner)75   static Manager Wrap(const Manager& inner) {
76     Manager out;
77     out.by_name_ = inner.by_name_;
78     return out;
79   }
80 
81   /// Returns the type map
82   /// @returns the mapping from name string to type.
types()83   const std::unordered_map<std::string, sem::Type*>& types() const {
84     return by_name_;
85   }
86 
87   /// @returns an iterator to the beginning of the types
begin()88   Iterator begin() const { return types_.Objects().begin(); }
89   /// @returns an iterator to the end of the types
end()90   Iterator end() const { return types_.Objects().end(); }
91 
92  private:
93   std::unordered_map<std::string, sem::Type*> by_name_;
94   BlockAllocator<sem::Type> types_;
95 };
96 
97 }  // namespace sem
98 }  // namespace tint
99 
100 #endif  // SRC_SEM_TYPE_MANAGER_H_
101