Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/50347 )

Change subject: base,python: Expand AddrRange exclude and add subtraction operators.
......................................................................

base,python: Expand AddrRange exclude and add subtraction operators.

Expand exclude to work with an AddrRange or AddrRangeList, define
versions to exclude both from an AddrRangeList, and make all available
through subtraction operators. Add -= operators for AddrRangeList with
another AddrRangeList or AddrRange.

Change-Id: Ic48f0c45a4809dbc51e1d3133e8319134aabe29e
---
M src/base/addr_range.hh
M src/base/addr_range.test.cc
M src/python/pybind11/core.cc
3 files changed, 199 insertions(+), 1 deletion(-)



diff --git a/src/base/addr_range.hh b/src/base/addr_range.hh
index 3fce412..89789fb 100644
--- a/src/base/addr_range.hh
+++ b/src/base/addr_range.hh
@@ -675,6 +675,12 @@
         return ranges;
     }

+    AddrRangeList
+    exclude(const AddrRange &excluded_range) const
+    {
+        return exclude(AddrRangeList{excluded_range});
+    }
+
     /**
      * Less-than operator used to turn an STL map into a binary search
      * tree of non-overlapping address ranges.
@@ -726,6 +732,62 @@
     }
 };

+static inline AddrRangeList
+operator-(const AddrRange &range, const AddrRangeList &to_exclude)
+{
+    return range.exclude(to_exclude);
+}
+
+static inline AddrRangeList
+operator-(const AddrRange &range, const AddrRange &to_exclude)
+{
+    return range.exclude(to_exclude);
+}
+
+static inline AddrRangeList
+exclude(const AddrRangeList &base, AddrRangeList to_exclude)
+{
+    to_exclude.sort();
+
+    AddrRangeList ret;
+    for (const auto &range: base)
+        ret.splice(ret.end(), range.exclude(to_exclude));
+
+    return ret;
+}
+
+static inline AddrRangeList
+exclude(const AddrRangeList &base, const AddrRange &to_exclude)
+{
+    return exclude(base, AddrRangeList{to_exclude});
+}
+
+static inline AddrRangeList
+operator-(const AddrRangeList &base, const AddrRangeList &to_exclude)
+{
+    return exclude(base, to_exclude);
+}
+
+static inline AddrRangeList
+operator-=(AddrRangeList &base, const AddrRangeList &to_exclude)
+{
+    base = base - to_exclude;
+    return base;
+}
+
+static inline AddrRangeList
+operator-(const AddrRangeList &base, const AddrRange &to_exclude)
+{
+    return exclude(base, to_exclude);
+}
+
+static inline AddrRangeList
+operator-=(AddrRangeList &base, const AddrRange &to_exclude)
+{
+    base = base - to_exclude;
+    return base;
+}
+
 /**
  * @ingroup api_addr_range
  */
diff --git a/src/base/addr_range.test.cc b/src/base/addr_range.test.cc
index ada9d3f..1e86154 100644
--- a/src/base/addr_range.test.cc
+++ b/src/base/addr_range.test.cc
@@ -1409,6 +1409,141 @@
     EXPECT_THAT(ranges, ElementsAre(expected_range1, expected_range2));
 }

+TEST(AddrRangeTest, ExclusionOfSingleRange)
+{
+    const AddrRange expected_range1(0x100, 0x140);
+    const AddrRange expected_range2(0x1c0, 0x200);
+
+    AddrRange r(0x100, 0x200);
+    auto ranges = r.exclude(AddrRange(0x140, 0x1c0));
+
+    EXPECT_EQ(ranges.size(), 2);
+    EXPECT_THAT(ranges, ElementsAre(expected_range1, expected_range2));
+}
+
+TEST(AddrRangeTest, ExclusionOfRangeFromRangeList)
+{
+    AddrRangeList base({AddrRange(0x100, 0x200), AddrRange(0x300, 0x400)});
+
+    const AddrRange expected_range1(0x100, 0x180);
+    const AddrRange expected_range2(0x380, 0x400);
+
+    auto ranges = exclude(base, AddrRange(0x180, 0x380));
+
+    EXPECT_EQ(ranges.size(), 2);
+    EXPECT_THAT(ranges, ElementsAre(expected_range1, expected_range2));
+}
+
+TEST(AddrRangeTest, ExclusionOfRangeListFromRangeList)
+{
+    AddrRangeList base({AddrRange(0x100, 0x200), AddrRange(0x300, 0x400)});
+
+    const AddrRange expected_range1(0x100, 0x140);
+    const AddrRange expected_range2(0x180, 0x200);
+    const AddrRange expected_range3(0x300, 0x340);
+    const AddrRange expected_range4(0x380, 0x400);
+
+    const AddrRangeList to_exclude({
+            AddrRange(0x140, 0x180), AddrRange(0x340, 0x380)});
+    auto ranges = exclude(base, to_exclude);
+
+    EXPECT_EQ(ranges.size(), 4);
+    EXPECT_THAT(ranges, ElementsAre(
+                expected_range1, expected_range2,
+                expected_range3, expected_range4));
+}
+
+TEST(AddrRangeTest, SubtractionOperatorRange)
+{
+    const AddrRange expected_range1(0x100, 0x140);
+    const AddrRange expected_range2(0x1c0, 0x200);
+
+    AddrRange r(0x100, 0x200);
+    auto ranges = r - AddrRange(0x140, 0x1c0);
+
+    EXPECT_EQ(ranges.size(), 2);
+    EXPECT_THAT(ranges, ElementsAre(expected_range1, expected_range2));
+}
+
+TEST(AddrRangeTest, SubtractionOperatorRangeList)
+{
+    const AddrRange expected_range1(0x100, 0x140);
+    const AddrRange expected_range2(0x160, 0x180);
+    const AddrRange expected_range3(0x1a0, 0x200);
+
+    AddrRange r(0x100, 0x200);
+    auto ranges = r - AddrRangeList(
+            {AddrRange(0x140, 0x160), AddrRange(0x180, 0x1a0)});
+
+    EXPECT_EQ(ranges.size(), 3);
+    EXPECT_THAT(ranges, ElementsAre(
+                expected_range1, expected_range2, expected_range3));
+}
+
+TEST(AddrRangeTest, SubtractionOfRangeFromRangeList)
+{
+    AddrRangeList base({AddrRange(0x100, 0x200), AddrRange(0x300, 0x400)});
+
+    const AddrRange expected_range1(0x100, 0x180);
+    const AddrRange expected_range2(0x380, 0x400);
+
+    auto ranges = base - AddrRange(0x180, 0x380);
+
+    EXPECT_EQ(ranges.size(), 2);
+    EXPECT_THAT(ranges, ElementsAre(expected_range1, expected_range2));
+}
+
+TEST(AddrRangeTest, SubtractionOfRangeListFromRangeList)
+{
+    AddrRangeList base({AddrRange(0x100, 0x200), AddrRange(0x300, 0x400)});
+
+    const AddrRange expected_range1(0x100, 0x140);
+    const AddrRange expected_range2(0x180, 0x200);
+    const AddrRange expected_range3(0x300, 0x340);
+    const AddrRange expected_range4(0x380, 0x400);
+
+    const AddrRangeList to_exclude({
+            AddrRange(0x140, 0x180), AddrRange(0x340, 0x380)});
+    auto ranges = base - to_exclude;
+
+    EXPECT_EQ(ranges.size(), 4);
+    EXPECT_THAT(ranges, ElementsAre(
+                expected_range1, expected_range2,
+                expected_range3, expected_range4));
+}
+
+TEST(AddrRangeTest, SubtractionAssignmentOfRangeFromRangeList)
+{
+    AddrRangeList base({AddrRange(0x100, 0x200), AddrRange(0x300, 0x400)});
+
+    const AddrRange expected_range1(0x100, 0x180);
+    const AddrRange expected_range2(0x380, 0x400);
+
+    base -= AddrRange(0x180, 0x380);
+
+    EXPECT_EQ(base.size(), 2);
+    EXPECT_THAT(base, ElementsAre(expected_range1, expected_range2));
+}
+
+TEST(AddrRangeTest, SubtractionAssignmentOfRangeListFromRangeList)
+{
+    AddrRangeList base({AddrRange(0x100, 0x200), AddrRange(0x300, 0x400)});
+
+    const AddrRange expected_range1(0x100, 0x140);
+    const AddrRange expected_range2(0x180, 0x200);
+    const AddrRange expected_range3(0x300, 0x340);
+    const AddrRange expected_range4(0x380, 0x400);
+
+    const AddrRangeList to_exclude({
+            AddrRange(0x140, 0x180), AddrRange(0x340, 0x380)});
+    base -= to_exclude;
+
+    EXPECT_EQ(base.size(), 4);
+    EXPECT_THAT(base, ElementsAre(
+                expected_range1, expected_range2,
+                expected_range3, expected_range4));
+}
+
 /*
  * InterleavingRanges:
  * The exclude method does not support interleaving ranges
diff --git a/src/python/pybind11/core.cc b/src/python/pybind11/core.cc
index 6f4acd3..c456b6a 100644
--- a/src/python/pybind11/core.cc
+++ b/src/python/pybind11/core.cc
@@ -166,7 +166,8 @@
         .def("mergesWith", &AddrRange::mergesWith)
         .def("intersects", &AddrRange::intersects)
         .def("isSubset", &AddrRange::isSubset)
-        .def("exclude", &AddrRange::exclude)
+        .def("exclude", static_cast<AddrRangeList (AddrRange::*)(
+                    const AddrRangeList &) const>(&AddrRange::exclude))
         ;

     m.def("RangeEx", &RangeEx);

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/50347
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: Ic48f0c45a4809dbc51e1d3133e8319134aabe29e
Gerrit-Change-Number: 50347
Gerrit-PatchSet: 1
Gerrit-Owner: Gabe Black <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to