base: Make AddrRangeMap able to return non-const iterators.

The erase() method only accepts regular iterators which is consistent
with the normal STL map, but the existing find() only returns const
iterators. The STL container can return either depending on if "this"
is const.

Unfortunately there isn't a great way to have only one find
implementation which returns the right type of iterator under the right
conditions. Also, it's not possible to turn a const_iterator into an
iterator, but it is possible to go the other way. This change
duplicates very short functions which return iterators, and for find
does the only thing I could find which avoids having to copy that
whole large function.

Change-Id: I2f789b5d0881feb9adff9978bd40e31731c6a688
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/17588
Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br>
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
diff --git a/src/base/addr_range_map.hh b/src/base/addr_range_map.hh
index f43671c..2f93ec7 100644
--- a/src/base/addr_range_map.hh
+++ b/src/base/addr_range_map.hh
@@ -83,6 +83,11 @@
     {
         return find(r, [r](const AddrRange r1) { return r.isSubset(r1); });
     }
+    iterator
+    contains(const AddrRange &r)
+    {
+        return find(r, [r](const AddrRange r1) { return r.isSubset(r1); });
+    }
 
     /**
      * Find entry that contains the given address
@@ -99,6 +104,11 @@
     {
         return contains(RangeSize(r, 1));
     }
+    iterator
+    contains(Addr r)
+    {
+        return contains(RangeSize(r, 1));
+    }
 
     /**
      * Find entry that intersects with the given address range
@@ -115,8 +125,13 @@
     {
         return find(r, [r](const AddrRange r1) { return r.intersects(r1); });
     }
+    iterator
+    intersects(const AddrRange &r)
+    {
+        return find(r, [r](const AddrRange r1) { return r.intersects(r1); });
+    }
 
-    const_iterator
+    iterator
     insert(const AddrRange &r, const V& d)
     {
         if (intersects(r) != end())
@@ -191,7 +206,7 @@
      * @param it Iterator to the entry in the address range map
      */
     void
-    addNewEntryToCache(const_iterator it) const
+    addNewEntryToCache(iterator it) const
     {
         if (max_cache_size != 0) {
             // If there's a cache, add this element to it.
@@ -221,8 +236,8 @@
      * @param f A condition on an address range
      * @return An iterator that contains the input address range
      */
-    const_iterator
-    find(const AddrRange &r, std::function<bool(const AddrRange)> cond) const
+    iterator
+    find(const AddrRange &r, std::function<bool(const AddrRange)> cond)
     {
         // Check the cache first
         for (auto c = cache.begin(); c != cache.end(); c++) {
@@ -235,7 +250,7 @@
             }
         }
 
-        const_iterator next = tree.upper_bound(r);
+        iterator next = tree.upper_bound(r);
         if (next != end() && cond(next->first)) {
             addNewEntryToCache(next);
             return next;
@@ -244,7 +259,7 @@
             return end();
         next--;
 
-        const_iterator i;
+        iterator i;
         do {
             i = next;
             if (cond(i->first)) {
@@ -258,6 +273,12 @@
         return end();
     }
 
+    const_iterator
+    find(const AddrRange &r, std::function<bool(const AddrRange)> cond) const
+    {
+        return const_cast<AddrRangeMap *>(this)->find(r, cond);
+    }
+
     RangeMap tree;
 
     /**
@@ -266,7 +287,7 @@
      * used to optimize lookups. The elements in the list should
      * always be valid iterators of the tree.
      */
-    mutable std::list<const_iterator> cache;
+    mutable std::list<iterator> cache;
 };
 
 #endif //__BASE_ADDR_RANGE_MAP_HH__