blob: 5e8b57ef50da3ca288c2dd3ec02e7a4b309f8e84 [file] [log] [blame]
dan sinclairc2d97ae2020-04-03 02:35:23 +00001// Copyright 2020 The Tint Authors. //
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14#ifndef SRC_SCOPE_STACK_H_
15#define SRC_SCOPE_STACK_H_
16
17#include <string>
18#include <unordered_map>
19#include <vector>
20
21namespace tint {
22
23/// Used to store a stack of scope information.
24/// The stack starts with a global scope which can not be popped.
25template <class T>
26class ScopeStack {
27 public:
28 /// Constructor
29 ScopeStack() {
30 // Push global bucket
31 stack_.push_back({});
32 }
33 /// Copy Constructor
34 ScopeStack(const ScopeStack&) = default;
35 ~ScopeStack() = default;
36
37 /// Push a new scope on to the stack
38 void push_scope() { stack_.push_back({}); }
39
40 /// Pop the scope off the top of the stack
41 void pop_scope() {
42 if (stack_.size() > 1) {
43 stack_.pop_back();
44 }
45 }
46
47 /// Set a global variable in the stack
48 /// @param name the name of the variable
49 /// @param val the value
50 void set_global(const std::string& name, T val) { stack_[0][name] = val; }
51
52 /// Sets variable into the top most scope of the stack
53 /// @param name the name of the variable
54 /// @param val the value
55 void set(const std::string& name, T val) { stack_.back()[name] = val; }
56
57 /// Checks for the given |name| in the stack
58 /// @param name the name to look for
59 /// @returns true if the stack contains |name|
60 bool has(const std::string& name) const { return get(name, nullptr); }
61
62 /// Retrieves a given name from the stack
63 /// @param name the name to look for
64 /// @param ret where to place the name
65 /// @returns true if the name was successfully found, false otherwise
66 bool get(const std::string& name, T* ret) const {
67 for (auto iter = stack_.rbegin(); iter != stack_.rend(); ++iter) {
68 auto& map = *iter;
69
70 auto val = map.find(name);
71 if (val != map.end()) {
72 if (ret) {
73 *ret = val->second;
74 }
75 return true;
76 }
77 }
78 return false;
79 }
80
81 private:
82 std::vector<std::unordered_map<std::string, T>> stack_;
83};
84
85} // namespace tint
86
87#endif // SRC_SCOPE_STACK_H_