38 _top = std::move(_rest.back());
45 _rest.push_back(std::move(_top));
68 return _empty ? 0 : (_rest.size() + 1);
93template<
typename T =
void>
96 std::map<std::string, SmallStack<T>> table;
98 const Scope<T> *containing_scope =
nullptr;
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();
157 template<
typename T2 = T,
158 typename =
typename std::enable_if<!std::is_same<T2, void>::value>::type>
159 const T2 *
find(
const std::string &name)
const {
160 typename std::map<std::string, SmallStack<T>>::const_iterator iter = table.find(name);
161 if (iter == table.end() || iter->second.empty()) {
162 if (containing_scope) {
163 return containing_scope->
find(name);
168 return &(iter->second.top_ref());
173 template<
typename T2 = T,
174 typename =
typename std::enable_if<!std::is_same<T2, void>::value>::type>
176 typename std::map<std::string, SmallStack<T>>::iterator iter = table.find(name);
177 if (iter == table.end() || iter->second.empty()) {
180 return &(iter->second.top_ref());
187 typename std::map<std::string, SmallStack<T>>::const_iterator iter = table.find(name);
188 if (iter == table.end() || iter->second.empty()) {
189 if (containing_scope) {
190 return containing_scope->
contains(name);
199 size_t count(
const std::string &name)
const {
200 auto it = table.find(name);
201 if (it == table.end()) {
204 return it->second.size();
214 typename std::map<std::string, SmallStack<T>>::iterator
iter;
221 template<
typename T2 = T,
222 typename =
typename std::enable_if<!std::is_same<T2, void>::value>::type>
224 auto it = table.try_emplace(name).first;
225 it->second.push(std::forward<T2>(value));
229 template<
typename T2 = T,
230 typename =
typename std::enable_if<std::is_same<T2, void>::value>::type>
232 auto it = table.try_emplace(name).first;
240 void pop(
const std::string &name) {
241 typename std::map<std::string, SmallStack<T>>::iterator iter = table.find(name);
242 internal_assert(iter != table.end()) <<
"Name not in Scope: " << name <<
"\n"
245 if (iter->second.empty()) {
252 p.
iter->second.pop();
253 if (p.
iter->second.empty()) {
270 return iter != other.iter;
285 template<
typename T2 = T,
286 typename =
typename std::enable_if<!std::is_same<T2, void>::value>::type>
288 return iter->second.top_ref();
301 table.swap(other.table);
302 std::swap(containing_scope, other.containing_scope);
310 for (iter = s.
cbegin(); iter != s.
cend(); ++iter) {
311 stream <<
" " << iter.
name() <<
"\n";
325template<
typename T =
void>
337 :
scope(condition ? &s : nullptr),
338 token(condition ?
scope->push(n, value) : typename
Scope<T>::PushToken{}) {
342 return scope !=
nullptr;
357 that.scope =
nullptr;
372 :
scope(condition ? &s : nullptr),
387 that.scope =
nullptr;
Defines functions for debug logging during code generation.
#define internal_assert(c)
Iterate through the scope.
bool operator!=(const const_iterator &other)
const std::string & name()
const SmallStack< T > & stack()
const_iterator(const typename std::map< std::string, SmallStack< T > >::const_iterator &i)
A common pattern when traversing Halide IR is that you need to keep track of stuff when you find a Le...
void swap(Scope< T > &other) noexcept
const T2 * find(const std::string &name) const
Returns a const pointer to an entry if it exists in this scope or any containing scope,...
Scope & operator=(Scope &&that) noexcept=default
Scope(const Scope< T > &)=delete
Scope(Scope &&that) noexcept=default
T2 & ref(const std::string &name)
Return a reference to an entry.
Scope< T > & operator=(const Scope< T > &)=delete
PushToken push(const std::string &name)
T2 get(const std::string &name) const
Retrieve the value referred to by a name.
void pop(PushToken p)
Pop a name using a token returned by push instead of a string.
size_t count(const std::string &name) const
How many nested definitions of a single name exist?
const_iterator cbegin() const
static const Scope< T > & empty_scope()
A const ref to an empty scope.
bool contains(const std::string &name) const
Tests if a name is in scope.
PushToken push(const std::string &name, T2 &&value)
Add a new (name, value) pair to the current scope.
T2 * shallow_find(const std::string &name)
A version of find that returns a non-const pointer, but ignores containing scope.
const_iterator cend() const
void set_containing_scope(const Scope< T > *s)
Set the parent scope.
size_t size() const
How many distinct names exist (does not count nested definitions of the same name)
void pop(const std::string &name)
A name goes out of scope.
A stack which can store one item very efficiently.
const T & top_ref() const
ConstantInterval operator<<(const ConstantInterval &a, const ConstantInterval &b)
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
@ Internal
Not visible externally, similar to 'static' linkage in C.
std::map< std::string, SmallStack< T > >::iterator iter
ScopedBinding(const ScopedBinding &that)=delete
void operator=(const ScopedBinding &that)=delete
ScopedBinding(bool condition, Scope<> &s, const std::string &n)
ScopedBinding(Scope<> &s, const std::string &n)
void operator=(ScopedBinding &&that)=delete
ScopedBinding(ScopedBinding &&that) noexcept
Helper class for pushing/popping Scope<> values, to allow for early-exit in Visitor/Mutators that pre...
void operator=(const ScopedBinding &that)=delete
ScopedBinding(Scope< T > &s, const std::string &n, T value)
ScopedBinding(const ScopedBinding &that)=delete
Scope< T >::PushToken token
ScopedBinding(bool condition, Scope< T > &s, const std::string &n, const T &value)
ScopedBinding(ScopedBinding &&that) noexcept
void operator=(ScopedBinding &&that)=delete