[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

llvm-svn: 285957
diff --git a/llvm/unittests/ADT/IntervalMapTest.cpp b/llvm/unittests/ADT/IntervalMapTest.cpp
index b5556d2..11f1375 100644
--- a/llvm/unittests/ADT/IntervalMapTest.cpp
+++ b/llvm/unittests/ADT/IntervalMapTest.cpp
@@ -15,6 +15,8 @@
 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 @@
   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;