mirror of
https://github.com/RPCS3/llvm.git
synced 2025-04-02 21:31:41 +00:00
[ADT] IntervalMap: fix setStart and setStop
Summary: These functions currently require that the new closed interval has a length of at least 2. They also currently permit empty half-open intervals. This patch defines nonEmpty in each traits structure and uses it to correct the implementations of setStart and setStop. Reviewers: stoklund, chandlerc Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D26064 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@285957 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a625bffced
commit
cbbb2b1243
@ -150,6 +150,12 @@ struct IntervalMapInfo {
|
||||
return a+1 == b;
|
||||
}
|
||||
|
||||
/// nonEmpty - Return true if [a;b] is non-empty.
|
||||
/// This is a <= b for a closed interval, a < b for [a;b) half-open intervals.
|
||||
static inline bool nonEmpty(const T &a, const T &b) {
|
||||
return a <= b;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
@ -170,6 +176,11 @@ struct IntervalMapHalfOpenInfo {
|
||||
return a == b;
|
||||
}
|
||||
|
||||
/// nonEmpty - Return true if [a;b) is non-empty.
|
||||
static inline bool nonEmpty(const T &a, const T &b) {
|
||||
return a < b;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/// IntervalMapImpl - Namespace used for IntervalMap implementation details.
|
||||
@ -1669,7 +1680,7 @@ iterator::setNodeStop(unsigned Level, KeyT Stop) {
|
||||
template <typename KeyT, typename ValT, unsigned N, typename Traits>
|
||||
void IntervalMap<KeyT, ValT, N, Traits>::
|
||||
iterator::setStart(KeyT a) {
|
||||
assert(Traits::stopLess(a, this->stop()) && "Cannot move start beyond stop");
|
||||
assert(Traits::nonEmpty(a, this->stop()) && "Cannot move start beyond stop");
|
||||
KeyT &CurStart = this->unsafeStart();
|
||||
if (!Traits::startLess(a, CurStart) || !canCoalesceLeft(a, this->value())) {
|
||||
CurStart = a;
|
||||
@ -1685,7 +1696,7 @@ iterator::setStart(KeyT a) {
|
||||
template <typename KeyT, typename ValT, unsigned N, typename Traits>
|
||||
void IntervalMap<KeyT, ValT, N, Traits>::
|
||||
iterator::setStop(KeyT b) {
|
||||
assert(Traits::stopLess(this->start(), b) && "Cannot move stop beyond start");
|
||||
assert(Traits::nonEmpty(this->start(), b) && "Cannot move stop beyond start");
|
||||
if (Traits::startLess(b, this->stop()) ||
|
||||
!canCoalesceRight(b, this->value())) {
|
||||
setStopUnchecked(b);
|
||||
|
@ -15,6 +15,8 @@ using namespace llvm;
|
||||
namespace {
|
||||
|
||||
typedef IntervalMap<unsigned, unsigned, 4> UUMap;
|
||||
typedef IntervalMap<unsigned, unsigned, 4,
|
||||
IntervalMapHalfOpenInfo<unsigned>> UUHalfOpenMap;
|
||||
|
||||
// Empty map tests
|
||||
TEST(IntervalMapTest, EmptyMap) {
|
||||
@ -125,18 +127,63 @@ TEST(IntervalMapTest, SingleEntryMap) {
|
||||
EXPECT_EQ(200u, I.stop());
|
||||
EXPECT_EQ(2u, I.value());
|
||||
|
||||
// Shrink the interval to have a length of 1
|
||||
I.setStop(150);
|
||||
ASSERT_TRUE(I.valid());
|
||||
EXPECT_EQ(150u, I.start());
|
||||
EXPECT_EQ(150u, I.stop());
|
||||
EXPECT_EQ(2u, I.value());
|
||||
|
||||
I.setStop(160);
|
||||
ASSERT_TRUE(I.valid());
|
||||
EXPECT_EQ(150u, I.start());
|
||||
EXPECT_EQ(160u, I.stop());
|
||||
EXPECT_EQ(2u, I.value());
|
||||
|
||||
// Shrink the interval to have a length of 1
|
||||
I.setStart(160);
|
||||
ASSERT_TRUE(I.valid());
|
||||
EXPECT_EQ(160u, I.start());
|
||||
EXPECT_EQ(160u, I.stop());
|
||||
EXPECT_EQ(2u, I.value());
|
||||
|
||||
// Erase last elem.
|
||||
I.erase();
|
||||
EXPECT_TRUE(map.empty());
|
||||
EXPECT_EQ(0, std::distance(map.begin(), map.end()));
|
||||
}
|
||||
|
||||
// Single entry half-open map tests
|
||||
TEST(IntervalMapTest, SingleEntryHalfOpenMap) {
|
||||
UUHalfOpenMap::Allocator allocator;
|
||||
UUHalfOpenMap map(allocator);
|
||||
map.insert(100, 150, 1);
|
||||
EXPECT_FALSE(map.empty());
|
||||
|
||||
UUHalfOpenMap::iterator I = map.begin();
|
||||
ASSERT_TRUE(I.valid());
|
||||
|
||||
// Shrink the interval to have a length of 1
|
||||
I.setStart(149);
|
||||
ASSERT_TRUE(I.valid());
|
||||
EXPECT_EQ(149u, I.start());
|
||||
EXPECT_EQ(150u, I.stop());
|
||||
EXPECT_EQ(1u, I.value());
|
||||
|
||||
I.setStop(160);
|
||||
ASSERT_TRUE(I.valid());
|
||||
EXPECT_EQ(149u, I.start());
|
||||
EXPECT_EQ(160u, I.stop());
|
||||
EXPECT_EQ(1u, I.value());
|
||||
|
||||
// Shrink the interval to have a length of 1
|
||||
I.setStop(150);
|
||||
ASSERT_TRUE(I.valid());
|
||||
EXPECT_EQ(149u, I.start());
|
||||
EXPECT_EQ(150u, I.stop());
|
||||
EXPECT_EQ(1u, I.value());
|
||||
}
|
||||
|
||||
// Flat coalescing tests.
|
||||
TEST(IntervalMapTest, RootCoalescing) {
|
||||
UUMap::Allocator allocator;
|
||||
|
Loading…
x
Reference in New Issue
Block a user