diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/include/llvm/ADT/IntervalMap.h | 15 | ||||
-rw-r--r-- | llvm/unittests/ADT/IntervalMapTest.cpp | 47 |
2 files changed, 60 insertions, 2 deletions
diff --git a/llvm/include/llvm/ADT/IntervalMap.h b/llvm/include/llvm/ADT/IntervalMap.h index cd721f8e783..0dcf1266a2b 100644 --- a/llvm/include/llvm/ADT/IntervalMap.h +++ b/llvm/include/llvm/ADT/IntervalMap.h @@ -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); diff --git a/llvm/unittests/ADT/IntervalMapTest.cpp b/llvm/unittests/ADT/IntervalMapTest.cpp index b5556d265ae..11f13752f31 100644 --- a/llvm/unittests/ADT/IntervalMapTest.cpp +++ b/llvm/unittests/ADT/IntervalMapTest.cpp @@ -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; |