Go to the documentation of this file.
38 _top = std::move(_rest.back());
45 _rest.push_back(std::move(_top));
68 return _empty ? 0 : (_rest.size() + 1);
93 template<
typename T =
void>
96 std::map<std::string, SmallStack<T>> table;
98 const Scope<T> *containing_scope =
nullptr;
107 Scope(
const Scope<T> &) =
delete;
108 Scope<T> &
operator=(
const Scope<T> &) =
delete;
114 containing_scope = s;
126 template<
typename T2 = T,
127 typename =
typename std::enable_if<!std::is_same<T2, void>::value>::type>
128 T2
get(
const std::string &name)
const {
129 typename std::map<std::string, SmallStack<T>>::const_iterator iter = table.find(name);
130 if (iter == table.end() || iter->second.empty()) {
131 if (containing_scope) {
132 return containing_scope->get(name);
138 return iter->second.top();
142 template<
typename T2 = T,
143 typename =
typename std::enable_if<!std::is_same<T2, void>::value>::type>
144 T2 &
ref(
const std::string &name) {
145 typename std::map<std::string, SmallStack<T>>::iterator iter = table.find(name);
146 if (iter == table.end() || iter->second.empty()) {
150 return iter->second.top_ref();
155 typename std::map<std::string, SmallStack<T>>::const_iterator iter = table.find(name);
156 if (iter == table.end() || iter->second.empty()) {
157 if (containing_scope) {
158 return containing_scope->contains(name);
167 size_t count(
const std::string &name)
const {
168 auto it = table.find(name);
169 if (it == table.end()) {
172 return it->second.size();
179 template<
typename T2 = T,
180 typename =
typename std::enable_if<!std::is_same<T2, void>::value>::type>
181 void push(
const std::string &name, T2 &&value) {
182 table[name].push(std::forward<T2>(value));
185 template<
typename T2 = T,
186 typename =
typename std::enable_if<std::is_same<T2, void>::value>::type>
187 void push(
const std::string &name) {
194 void pop(
const std::string &name) {
195 typename std::map<std::string, SmallStack<T>>::iterator iter = table.find(name);
196 internal_assert(iter != table.end()) <<
"Name not in Scope: " << name <<
"\n"
199 if (iter->second.empty()) {
216 return iter != other.iter;
231 template<
typename T2 = T,
232 typename =
typename std::enable_if<!std::is_same<T2, void>::value>::type>
234 return iter->second.top_ref();
239 return const_iterator(table.begin());
243 return const_iterator(table.end());
247 table.swap(other.table);
248 std::swap(containing_scope, other.containing_scope);
256 for (iter = s.cbegin(); iter != s.cend(); ++iter) {
257 stream <<
" " << iter.
name() <<
"\n";
271 template<
typename T =
void>
284 :
scope(condition ? &s : nullptr),
name(n) {
291 return scope !=
nullptr;
304 name(std::move(that.name)) {
306 that.scope =
nullptr;
322 :
scope(condition ? &s : nullptr),
name(n) {
337 name(std::move(that.name)) {
339 that.scope =
nullptr;
const_iterator(const typename std::map< std::string, SmallStack< T >>::const_iterator &i)
Iterate through the scope.
const std::string & name()
#define internal_assert(c)
void operator=(const ScopedBinding &that)=delete
std::ostream & operator<<(std::ostream &stream, const Stmt &)
Emit a halide statement on an output stream (such as std::cout) in a human-readable form.
void pop(const std::string &name)
A name goes out of scope.
Helper class for pushing/popping Scope<> values, to allow for early-exit in Visitor/Mutators that pre...
bool contains(const std::string &name) const
Tests if a name is in scope.
ScopedBinding(Scope< T > &s, const std::string &n, T value)
T2 get(const std::string &name) const
Retrieve the value referred to by a name.
A common pattern when traversing Halide IR is that you need to keep track of stuff when you find a Le...
void set_containing_scope(const Scope< T > *s)
Set the parent scope.
ScopedBinding(Scope<> &s, const std::string &n)
void swap(Scope< T > &other)
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
size_t count(const std::string &name) const
How many nested definitions of a single name exist?
ScopedBinding(ScopedBinding &&that) noexcept
const SmallStack< T > & stack()
@ Internal
Not visible externally, similar to 'static' linkage in C.
bool operator!=(const const_iterator &other)
void push(const std::string &name)
ScopedBinding(bool condition, Scope< T > &s, const std::string &n, const T &value)
Scope & operator=(Scope &&that) noexcept=default
ScopedBinding(ScopedBinding &&that) noexcept
void push(const std::string &name, T2 &&value)
Add a new (name, value) pair to the current scope.
A stack which can store one item very efficiently.
static const Scope< T > & empty_scope()
A const ref to an empty scope.
ScopedBinding(bool condition, Scope<> &s, const std::string &n)
const T & top_ref() const
T2 & ref(const std::string &name)
Return a reference to an entry.
const_iterator cend() const
const_iterator cbegin() const