#pragma once
#include "ast/substitution/expr_offset.h"
#include "util/vector.h"
template<typename T>
class expr_offset_map {
struct data {
T m_data;
unsigned m_timestamp;
data():m_timestamp(0) {}
};
vector<svector<data> > m_map;
unsigned m_timestamp;
public:
expr_offset_map():
m_timestamp(1) {}
bool contains(expr_offset const & n) const {
unsigned off = n.get_offset();
if (off < m_map.size()) {
svector<data> const & v = m_map[off];
unsigned id = n.get_expr()->get_id();
if (id < v.size())
return v[id].m_timestamp == m_timestamp;
}
return false;
}
bool find(expr_offset const & n, T & r) const {
unsigned off = n.get_offset();
if (off < m_map.size()) {
svector<data> const & v = m_map[off];
unsigned id = n.get_expr()->get_id();
if (id < v.size() && v[id].m_timestamp == m_timestamp) {
r = v[id].m_data;
return true;
}
}
return false;
}
void insert(expr_offset const & n, T const & r) {
unsigned off = n.get_offset();
if (off >= m_map.size())
m_map.resize(off+1, svector<data>());
svector<data> & v = m_map[off];
unsigned id = n.get_expr()->get_id();
if (id >= v.size())
v.resize(id+1);
v[id].m_data = r;
v[id].m_timestamp = m_timestamp;
}
void reset() {
m_timestamp++;
if (m_timestamp == UINT_MAX) {
typename vector<svector<data> >::iterator it = m_map.begin();
typename vector<svector<data> >::iterator end = m_map.end();
for (; it != end; ++it) {
svector<data> & v = *it;
typename svector<data>::iterator it2 = v.begin();
typename svector<data>::iterator end2 = v.end();
for (; it2 != end2; ++it2)
it2->m_timestamp = 0;
}
m_timestamp = 1;
}
}
};