summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/ADT/IntervalMap.h15
-rw-r--r--llvm/unittests/ADT/IntervalMapTest.cpp47
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;
OpenPOWER on IntegriCloud