40 enum entry_type { BEGIN_RANGE = 1, END_RANGE = 2, SINGLE_BYTE_RANGE = 3 };
75 size_t size()
const {
return m_size; }
90 auto iter = m_lut.lower_bound(addr);
91 return (iter != m_lut.end() && (iter->second.type == END_RANGE || iter->first == addr)) ? iter->second.index :
null_entry;
107 using const_iterator =
typename std::map<uint64_t, lut_entry>::const_iterator;
109 const_iterator begin()
const {
return m_lut.begin(); }
111 const_iterator end()
const {
return m_lut.end(); }
115 std::map<uint64_t, lut_entry> m_lut{};
127 os << lut.toString();
132 auto iter = m_lut.find(base_addr);
133 if(iter != m_lut.end() && iter->second.index != null_entry)
134 throw std::runtime_error(
"range already mapped");
136 auto eaddr = base_addr + size - 1;
137 if(eaddr < base_addr)
138 throw std::runtime_error(
"address wrap-around occurred");
140 m_lut[base_addr] =
lut_entry{i, size > 1 ? BEGIN_RANGE : SINGLE_BYTE_RANGE};
147 auto start = m_lut.begin();
148 while(start->second.index != i && start != m_lut.end())
150 if(start != m_lut.end()) {
151 if(start->second.type == SINGLE_BYTE_RANGE) {
157 m_lut.erase(start, end);
167 for(
auto iter = m_lut.begin(); iter != m_lut.end(); iter++) {
168 switch(iter->second.type) {
169 case SINGLE_BYTE_RANGE:
170 if(iter->second.index != null_entry && mapped)
171 throw std::runtime_error(
"range overlap: begin range while in mapped range");
175 if(iter->second.index != null_entry) {
177 throw std::runtime_error(
"range overlap: begin range while in mapped range");
184 throw std::runtime_error(
"range overlap: end range while in unmapped region");
193 std::ostringstream buf;
194 for(
auto iter = m_lut.begin(); iter != m_lut.end(); ++iter) {
195 switch(iter->second.type) {
197 if(iter->second.index != null_entry) {
198 buf <<
" from 0x" << std::setw(
sizeof(uint64_t) * 2) << std::setfill(
'0') << std::uppercase << std::hex << iter->first
203 buf <<
" to 0x" << std::setw(
sizeof(uint64_t) * 2) << std::setfill(
'0') << std::uppercase << std::hex << iter->first << std::dec
204 <<
" as " << iter->second->index << std::endl;
std::string toString() const
void addEntry(T i, uint64_t base_addr, uint64_t size)
const T null_entry
the null entry
T getEntry(uint64_t addr) const
entry_type
the type of lut entry
std::ostream & operator<<(std::ostream &os, range_lut< T > &lut)