diff --git a/lldb/include/lldb/Utility/RangeMap.h b/lldb/include/lldb/Utility/RangeMap.h --- a/lldb/include/lldb/Utility/RangeMap.h +++ b/lldb/include/lldb/Utility/RangeMap.h @@ -599,36 +599,17 @@ RangeData(B base, S size) : Range(base, size), data() {} RangeData(B base, S size, DataType d) : Range(base, size), data(d) {} - - bool operator<(const RangeData &rhs) const { - if (this->base == rhs.base) { - if (this->size == rhs.size) - return this->data < rhs.data; - else - return this->size < rhs.size; - } - return this->base < rhs.base; - } - - bool operator==(const RangeData &rhs) const { - return this->GetRangeBase() == rhs.GetRangeBase() && - this->GetByteSize() == rhs.GetByteSize() && this->data == rhs.data; - } - - bool operator!=(const RangeData &rhs) const { - return this->GetRangeBase() != rhs.GetRangeBase() || - this->GetByteSize() != rhs.GetByteSize() || this->data != rhs.data; - } }; -template +template > class RangeDataVector { public: typedef lldb_private::Range Range; typedef RangeData Entry; typedef llvm::SmallVector Collection; - RangeDataVector() = default; + RangeDataVector(Compare compare = Compare()) : m_compare(compare) {} ~RangeDataVector() = default; @@ -636,7 +617,14 @@ void Sort() { if (m_entries.size() > 1) - std::stable_sort(m_entries.begin(), m_entries.end()); + std::stable_sort(m_entries.begin(), m_entries.end(), + [&compare = m_compare](const Entry &a, const Entry &b) { + if (a.base != b.base) + return a.base < b.base; + if (a.size != b.size) + return a.size < b.size; + return compare(a.data, b.data); + }); } #ifdef ASSERT_RANGEMAP_ARE_SORTED @@ -817,6 +805,7 @@ protected: Collection m_entries; + Compare m_compare; }; // A simple range with data class where you get to define the type of diff --git a/lldb/unittests/Utility/RangeMapTest.cpp b/lldb/unittests/Utility/RangeMapTest.cpp --- a/lldb/unittests/Utility/RangeMapTest.cpp +++ b/lldb/unittests/Utility/RangeMapTest.cpp @@ -52,3 +52,45 @@ // TODO: This should probably return the range (0, 40) as well. EXPECT_THAT(Map.FindEntryThatContains(35), nullptr); } + +TEST(RangeDataVector, CustomSort) { + // First the default ascending order sorting of the data field. + auto Map = RangeDataVectorT(); + Map.Append(EntryT(0, 10, 50)); + Map.Append(EntryT(0, 10, 52)); + Map.Append(EntryT(0, 10, 53)); + Map.Append(EntryT(0, 10, 51)); + Map.Sort(); + + EXPECT_THAT(Map.GetSize(), 4); + EXPECT_THAT(Map.GetEntryRef(0).data, 50); + EXPECT_THAT(Map.GetEntryRef(1).data, 51); + EXPECT_THAT(Map.GetEntryRef(2).data, 52); + EXPECT_THAT(Map.GetEntryRef(3).data, 53); + + // And then a custom descending order sorting of the data field. + class CtorParam {}; + class CustomSort { + public: + CustomSort(CtorParam) {} + bool operator()(const uint32_t a_data, const uint32_t b_data) { + return a_data > b_data; + } + }; + using RangeDataVectorCustomSortT = + RangeDataVector; + using EntryT = RangeDataVectorT::Entry; + + auto MapC = RangeDataVectorCustomSortT(CtorParam()); + MapC.Append(EntryT(0, 10, 50)); + MapC.Append(EntryT(0, 10, 52)); + MapC.Append(EntryT(0, 10, 53)); + MapC.Append(EntryT(0, 10, 51)); + MapC.Sort(); + + EXPECT_THAT(MapC.GetSize(), 4); + EXPECT_THAT(MapC.GetEntryRef(0).data, 53); + EXPECT_THAT(MapC.GetEntryRef(1).data, 52); + EXPECT_THAT(MapC.GetEntryRef(2).data, 51); + EXPECT_THAT(MapC.GetEntryRef(3).data, 50); +}