#include "llvm/ADT/IntervalMap.h"
#include "gtest/gtest.h"
#include <type_traits>
using namespace llvm;
namespace {
typedef IntervalMap<unsigned, unsigned, 4> UUMap;
typedef IntervalMap<unsigned, unsigned, 4,
IntervalMapHalfOpenInfo<unsigned>> UUHalfOpenMap;
static_assert(!std::is_copy_constructible<UUMap>::value,
"IntervalMap copy constructor should be deleted");
static_assert(!std::is_move_constructible<UUMap>::value,
"IntervalMap move constructor should be deleted");
static_assert(!std::is_copy_assignable<UUMap>::value,
"IntervalMap copy assignment should be deleted");
static_assert(!std::is_move_assignable<UUMap>::value,
"IntervalMap move assignment should be deleted");
TEST(IntervalMapTest, EmptyMap) {
UUMap::Allocator allocator;
UUMap map(allocator);
EXPECT_TRUE(map.empty());
EXPECT_EQ(0u, map.lookup(0));
EXPECT_EQ(7u, map.lookup(0, 7));
EXPECT_EQ(0u, map.lookup(~0u-1));
EXPECT_EQ(7u, map.lookup(~0u-1, 7));
EXPECT_TRUE(map.begin() == map.begin());
EXPECT_TRUE(map.begin() == map.end());
EXPECT_TRUE(map.end() == map.end());
EXPECT_FALSE(map.begin() != map.begin());
EXPECT_FALSE(map.begin() != map.end());
EXPECT_FALSE(map.end() != map.end());
EXPECT_FALSE(map.begin().valid());
EXPECT_FALSE(map.end().valid());
UUMap::iterator I = map.begin();
EXPECT_FALSE(I.valid());
EXPECT_TRUE(I == map.end());
UUMap::const_iterator CI;
CI = map.begin();
EXPECT_TRUE(CI == I);
UUMap::iterator I2;
I2 = map.end();
EXPECT_TRUE(I2 == CI);
}
TEST(IntervalMapTest, OneElementRanges) {
UUMap::Allocator allocator;
UUMap map(allocator);
map.insert(1, 1, 1);
map.insert(2, 2, 2);
EXPECT_EQ(1u, map.lookup(1));
EXPECT_EQ(2u, map.lookup(2));
}
TEST(IntervalMapTest, SingleEntryMap) {
UUMap::Allocator allocator;
UUMap map(allocator);
map.insert(100, 150, 1);
EXPECT_FALSE(map.empty());
EXPECT_EQ(0u, map.lookup(0));
EXPECT_EQ(0u, map.lookup(99));
EXPECT_EQ(1u, map.lookup(100));
EXPECT_EQ(1u, map.lookup(101));
EXPECT_EQ(1u, map.lookup(125));
EXPECT_EQ(1u, map.lookup(149));
EXPECT_EQ(1u, map.lookup(150));
EXPECT_EQ(0u, map.lookup(151));
EXPECT_EQ(0u, map.lookup(200));
EXPECT_EQ(0u, map.lookup(~0u-1));
EXPECT_TRUE(map.begin() == map.begin());
EXPECT_FALSE(map.begin() == map.end());
EXPECT_TRUE(map.end() == map.end());
EXPECT_TRUE(map.begin().valid());
EXPECT_FALSE(map.end().valid());
UUMap::iterator I = map.begin();
ASSERT_TRUE(I.valid());
EXPECT_EQ(100u, I.start());
EXPECT_EQ(150u, I.stop());
EXPECT_EQ(1u, I.value());
++I;
EXPECT_FALSE(I.valid());
EXPECT_FALSE(I == map.begin());
EXPECT_TRUE(I == map.end());
--I;
ASSERT_TRUE(I.valid());
EXPECT_EQ(100u, I.start());
EXPECT_EQ(150u, I.stop());
EXPECT_EQ(1u, I.value());
EXPECT_TRUE(I == map.begin());
EXPECT_FALSE(I == map.end());
I.setValue(2);
ASSERT_TRUE(I.valid());
EXPECT_EQ(100u, I.start());
EXPECT_EQ(150u, I.stop());
EXPECT_EQ(2u, I.value());
I.setStart(0);
ASSERT_TRUE(I.valid());
EXPECT_EQ(0u, I.start());
EXPECT_EQ(150u, I.stop());
EXPECT_EQ(2u, I.value());
I.setStop(200);
ASSERT_TRUE(I.valid());
EXPECT_EQ(0u, I.start());
EXPECT_EQ(200u, I.stop());
EXPECT_EQ(2u, I.value());
I.setStart(150);
ASSERT_TRUE(I.valid());
EXPECT_EQ(150u, I.start());
EXPECT_EQ(200u, I.stop());
EXPECT_EQ(2u, I.value());
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());
I.setStart(160);
ASSERT_TRUE(I.valid());
EXPECT_EQ(160u, I.start());
EXPECT_EQ(160u, I.stop());
EXPECT_EQ(2u, I.value());
I.erase();
EXPECT_TRUE(map.empty());
EXPECT_EQ(0, std::distance(map.begin(), map.end()));
}
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());
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());
I.setStop(150);
ASSERT_TRUE(I.valid());
EXPECT_EQ(149u, I.start());
EXPECT_EQ(150u, I.stop());
EXPECT_EQ(1u, I.value());
}
TEST(IntervalMapTest, RootCoalescing) {
UUMap::Allocator allocator;
UUMap map(allocator);
map.insert(100, 150, 1);
map.insert(90, 99, 1);
EXPECT_EQ(1, std::distance(map.begin(), map.end()));
EXPECT_EQ(90u, map.start());
EXPECT_EQ(150u, map.stop());
map.insert(151, 200, 1);
EXPECT_EQ(1, std::distance(map.begin(), map.end()));
EXPECT_EQ(90u, map.start());
EXPECT_EQ(200u, map.stop());
map.insert(60, 89, 2);
EXPECT_EQ(2, std::distance(map.begin(), map.end()));
EXPECT_EQ(60u, map.start());
EXPECT_EQ(200u, map.stop());
EXPECT_EQ(2u, map.lookup(89));
EXPECT_EQ(1u, map.lookup(90));
UUMap::iterator I = map.begin();
EXPECT_EQ(60u, I.start());
EXPECT_EQ(89u, I.stop());
EXPECT_EQ(2u, I.value());
++I;
EXPECT_EQ(90u, I.start());
EXPECT_EQ(200u, I.stop());
EXPECT_EQ(1u, I.value());
++I;
EXPECT_FALSE(I.valid());
map.insert(201, 210, 2);
EXPECT_EQ(3, std::distance(map.begin(), map.end()));
EXPECT_EQ(60u, map.start());
EXPECT_EQ(210u, map.stop());
EXPECT_EQ(2u, map.lookup(201));
EXPECT_EQ(1u, map.lookup(200));
map.begin().erase();
EXPECT_EQ(2, std::distance(map.begin(), map.end()));
EXPECT_EQ(90u, map.start());
EXPECT_EQ(210u, map.stop());
(--map.end()).erase();
EXPECT_EQ(1, std::distance(map.begin(), map.end()));
EXPECT_EQ(90u, map.start());
EXPECT_EQ(200u, map.stop());
map.insert(80, 89, 2);
map.insert(201, 210, 2);
EXPECT_EQ(3, std::distance(map.begin(), map.end()));
(++map.begin()).setValue(2);
EXPECT_EQ(1, std::distance(map.begin(), map.end()));
I = map.begin();
ASSERT_TRUE(I.valid());
EXPECT_EQ(80u, I.start());
EXPECT_EQ(210u, I.stop());
EXPECT_EQ(2u, I.value());
}
TEST(IntervalMapTest, RootMultiCoalescing) {
UUMap::Allocator allocator;
UUMap map(allocator);
map.insert(140, 150, 1);
map.insert(160, 170, 1);
map.insert(100, 110, 1);
map.insert(120, 130, 1);
EXPECT_EQ(4, std::distance(map.begin(), map.end()));
EXPECT_EQ(100u, map.start());
EXPECT_EQ(170u, map.stop());
UUMap::iterator I = map.begin();
EXPECT_EQ(100u, I.start());
EXPECT_EQ(110u, I.stop());
++I;
EXPECT_EQ(120u, I.start());
EXPECT_EQ(130u, I.stop());
++I;
EXPECT_EQ(140u, I.start());
EXPECT_EQ(150u, I.stop());
++I;
EXPECT_EQ(160u, I.start());
EXPECT_EQ(170u, I.stop());
++I;
EXPECT_FALSE(I.valid());
I = map.begin();
I.advanceTo(135);
ASSERT_TRUE(I.valid());
EXPECT_EQ(140u, I.start());
EXPECT_EQ(150u, I.stop());
I.advanceTo(145);
ASSERT_TRUE(I.valid());
EXPECT_EQ(140u, I.start());
EXPECT_EQ(150u, I.stop());
I.advanceTo(200);
EXPECT_FALSE(I.valid());
I.advanceTo(300);
EXPECT_FALSE(I.valid());
map.insert(111, 115, 1);
I = map.begin();
ASSERT_TRUE(I.valid());
EXPECT_EQ(100u, I.start());
EXPECT_EQ(115u, I.stop());
++I;
ASSERT_TRUE(I.valid());
EXPECT_EQ(120u, I.start());
EXPECT_EQ(130u, I.stop());
++I;
ASSERT_TRUE(I.valid());
EXPECT_EQ(140u, I.start());
EXPECT_EQ(150u, I.stop());
++I;
ASSERT_TRUE(I.valid());
EXPECT_EQ(160u, I.start());
EXPECT_EQ(170u, I.stop());
++I;
EXPECT_FALSE(I.valid());
map.insert(135, 139, 1);
I = map.begin();
ASSERT_TRUE(I.valid());
EXPECT_EQ(100u, I.start());
EXPECT_EQ(115u, I.stop());
++I;
ASSERT_TRUE(I.valid());
EXPECT_EQ(120u, I.start());
EXPECT_EQ(130u, I.stop());
++I;
ASSERT_TRUE(I.valid());
EXPECT_EQ(135u, I.start());
EXPECT_EQ(150u, I.stop());
++I;
ASSERT_TRUE(I.valid());
EXPECT_EQ(160u, I.start());
EXPECT_EQ(170u, I.stop());
++I;
EXPECT_FALSE(I.valid());
map.insert(131, 134, 1);
I = map.begin();
ASSERT_TRUE(I.valid());
EXPECT_EQ(100u, I.start());
EXPECT_EQ(115u, I.stop());
++I;
ASSERT_TRUE(I.valid());
EXPECT_EQ(120u, I.start());
EXPECT_EQ(150u, I.stop());
++I;
ASSERT_TRUE(I.valid());
EXPECT_EQ(160u, I.start());
EXPECT_EQ(170u, I.stop());
++I;
EXPECT_FALSE(I.valid());
map.clear();
EXPECT_TRUE(map.empty());
EXPECT_TRUE(map.begin() == map.end());
}
TEST(IntervalMapTest, Branched) {
UUMap::Allocator allocator;
UUMap map(allocator);
for (unsigned i = 1; i < 100; ++i) {
map.insert(10*i, 10*i+5, i);
EXPECT_EQ(10u, map.start());
EXPECT_EQ(10*i+5, map.stop());
}
EXPECT_FALSE(map.empty());
EXPECT_EQ(10u, map.start());
EXPECT_EQ(995u, map.stop());
for (unsigned i = 1; i < 100; ++i) {
EXPECT_EQ(0u, map.lookup(10*i-1));
EXPECT_EQ(i, map.lookup(10*i));
EXPECT_EQ(i, map.lookup(10*i+5));
EXPECT_EQ(0u, map.lookup(10*i+6));
}
UUMap::iterator I = map.begin();
for (unsigned i = 1; i < 100; ++i) {
ASSERT_TRUE(I.valid());
EXPECT_EQ(10*i, I.start());
EXPECT_EQ(10*i+5, I.stop());
EXPECT_EQ(i, *I);
++I;
}
EXPECT_FALSE(I.valid());
EXPECT_TRUE(I == map.end());
for (unsigned i = 99; i; --i) {
--I;
ASSERT_TRUE(I.valid());
EXPECT_EQ(10*i, I.start());
EXPECT_EQ(10*i+5, I.stop());
EXPECT_EQ(i, *I);
}
EXPECT_TRUE(I == map.begin());
I.advanceTo(20);
ASSERT_TRUE(I.valid());
EXPECT_EQ(20u, I.start());
EXPECT_EQ(25u, I.stop());
I.setValue(0);
ASSERT_TRUE(I.valid());
EXPECT_EQ(20u, I.start());
EXPECT_EQ(25u, I.stop());
EXPECT_EQ(0u, I.value());
I.setStop(29);
ASSERT_TRUE(I.valid());
EXPECT_EQ(20u, I.start());
EXPECT_EQ(29u, I.stop());
EXPECT_EQ(0u, I.value());
I.setValue(2);
ASSERT_TRUE(I.valid());
EXPECT_EQ(20u, I.start());
EXPECT_EQ(29u, I.stop());
EXPECT_EQ(2u, I.value());
I.setValue(3);
ASSERT_TRUE(I.valid());
EXPECT_EQ(20u, I.start());
EXPECT_EQ(35u, I.stop());
EXPECT_EQ(3u, I.value());
I.setValue(4);
ASSERT_TRUE(I.valid());
I.setStop(39);
ASSERT_TRUE(I.valid());
EXPECT_EQ(20u, I.start());
EXPECT_EQ(45u, I.stop());
EXPECT_EQ(4u, I.value());
I.advanceTo(200);
ASSERT_TRUE(I.valid());
EXPECT_EQ(200u, I.start());
EXPECT_EQ(205u, I.stop());
I.setStart(196);
ASSERT_TRUE(I.valid());
EXPECT_EQ(196u, I.start());
EXPECT_EQ(205u, I.stop());
EXPECT_EQ(20u, I.value());
I.setValue(0);
ASSERT_TRUE(I.valid());
EXPECT_EQ(196u, I.start());
EXPECT_EQ(205u, I.stop());
EXPECT_EQ(0u, I.value());
I.setValue(19);
ASSERT_TRUE(I.valid());
EXPECT_EQ(190u, I.start());
EXPECT_EQ(205u, I.stop());
EXPECT_EQ(19u, I.value());
I.setValue(18);
ASSERT_TRUE(I.valid());
I.setStart(186);
ASSERT_TRUE(I.valid());
EXPECT_EQ(180u, I.start());
EXPECT_EQ(205u, I.stop());
EXPECT_EQ(18u, I.value());
I = map.begin();
for (unsigned i = 0; i != 20; ++i) {
I.erase();
EXPECT_TRUE(I == map.begin());
EXPECT_FALSE(map.empty());
EXPECT_EQ(I.start(), map.start());
EXPECT_EQ(995u, map.stop());
}
map.clear();
EXPECT_TRUE(map.empty());
EXPECT_TRUE(map.begin() == map.end());
}
TEST(IntervalMapTest, Branched2) {
UUMap::Allocator allocator;
UUMap map(allocator);
for (unsigned i = 1; i < 1000; ++i)
map.insert(10*i, 10*i+5, i);
EXPECT_FALSE(map.empty());
EXPECT_EQ(10u, map.start());
EXPECT_EQ(9995u, map.stop());
for (unsigned i = 1; i < 1000; ++i) {
EXPECT_EQ(0u, map.lookup(10*i-1));
EXPECT_EQ(i, map.lookup(10*i));
EXPECT_EQ(i, map.lookup(10*i+5));
EXPECT_EQ(0u, map.lookup(10*i+6));
}
UUMap::iterator I = map.begin();
for (unsigned i = 1; i < 1000; ++i) {
ASSERT_TRUE(I.valid());
EXPECT_EQ(10*i, I.start());
EXPECT_EQ(10*i+5, I.stop());
EXPECT_EQ(i, *I);
++I;
}
EXPECT_FALSE(I.valid());
EXPECT_TRUE(I == map.end());
for (unsigned i = 999; i; --i) {
--I;
ASSERT_TRUE(I.valid());
EXPECT_EQ(10*i, I.start());
EXPECT_EQ(10*i+5, I.stop());
EXPECT_EQ(i, *I);
}
EXPECT_TRUE(I == map.begin());
I.advanceTo(20);
ASSERT_TRUE(I.valid());
EXPECT_EQ(20u, I.start());
EXPECT_EQ(25u, I.stop());
I.advanceTo(200);
ASSERT_TRUE(I.valid());
EXPECT_EQ(200u, I.start());
EXPECT_EQ(205u, I.stop());
I.advanceTo(2000);
ASSERT_TRUE(I.valid());
EXPECT_EQ(2000u, I.start());
EXPECT_EQ(2005u, I.stop());
I.advanceTo(20000);
EXPECT_FALSE(I.valid());
I.advanceTo(30000);
EXPECT_FALSE(I.valid());
map.clear();
EXPECT_TRUE(map.empty());
EXPECT_TRUE(map.begin() == map.end());
}
TEST(IntervalMapTest, RandomCoalescing) {
UUMap::Allocator allocator;
UUMap map(allocator);
unsigned x = 100;
for (unsigned i = 0; i != 4096; ++i) {
map.insert(10*x, 10*x+9, 1);
EXPECT_GE(10*x, map.start());
EXPECT_LE(10*x+9, map.stop());
x = (5*x+1)%4096;
}
EXPECT_FALSE(map.empty());
EXPECT_EQ(0u, map.start());
EXPECT_EQ(40959u, map.stop());
EXPECT_EQ(1, std::distance(map.begin(), map.end()));
}
TEST(IntervalMapTest, Overlaps) {
UUMap::Allocator allocator;
UUMap map(allocator);
map.insert(10, 20, 0);
map.insert(30, 40, 0);
map.insert(50, 60, 0);
EXPECT_FALSE(map.overlaps(0, 9));
EXPECT_TRUE(map.overlaps(0, 10));
EXPECT_TRUE(map.overlaps(0, 15));
EXPECT_TRUE(map.overlaps(0, 25));
EXPECT_TRUE(map.overlaps(0, 45));
EXPECT_TRUE(map.overlaps(10, 45));
EXPECT_TRUE(map.overlaps(30, 45));
EXPECT_TRUE(map.overlaps(35, 36));
EXPECT_TRUE(map.overlaps(40, 45));
EXPECT_FALSE(map.overlaps(45, 45));
EXPECT_TRUE(map.overlaps(60, 60));
EXPECT_TRUE(map.overlaps(60, 66));
EXPECT_FALSE(map.overlaps(66, 66));
}
TEST(IntervalMapTest, OverlapsHalfOpen) {
UUHalfOpenMap::Allocator allocator;
UUHalfOpenMap map(allocator);
map.insert(10, 20, 0);
map.insert(30, 40, 0);
map.insert(50, 60, 0);
EXPECT_FALSE(map.overlaps(0, 9));
EXPECT_FALSE(map.overlaps(0, 10));
EXPECT_TRUE(map.overlaps(0, 15));
EXPECT_TRUE(map.overlaps(0, 25));
EXPECT_TRUE(map.overlaps(0, 45));
EXPECT_TRUE(map.overlaps(10, 45));
EXPECT_TRUE(map.overlaps(30, 45));
EXPECT_TRUE(map.overlaps(35, 36));
EXPECT_FALSE(map.overlaps(40, 45));
EXPECT_FALSE(map.overlaps(45, 46));
EXPECT_FALSE(map.overlaps(60, 61));
EXPECT_FALSE(map.overlaps(60, 66));
EXPECT_FALSE(map.overlaps(66, 67));
}
TEST(IntervalMapOverlapsTest, SmallMaps) {
typedef IntervalMapOverlaps<UUMap,UUMap> UUOverlaps;
UUMap::Allocator allocator;
UUMap mapA(allocator);
UUMap mapB(allocator);
EXPECT_FALSE(UUOverlaps(mapA, mapB).valid());
mapA.insert(1, 2, 3);
EXPECT_FALSE(UUOverlaps(mapA, mapB).valid());
EXPECT_FALSE(UUOverlaps(mapB, mapA).valid());
mapB.insert(3, 4, 5);
EXPECT_FALSE(UUOverlaps(mapA, mapB).valid());
EXPECT_FALSE(UUOverlaps(mapB, mapA).valid());
mapA.insert(4, 5, 6);
UUOverlaps AB(mapA, mapB);
ASSERT_TRUE(AB.valid());
EXPECT_EQ(4u, AB.a().start());
EXPECT_EQ(3u, AB.b().start());
++AB;
EXPECT_FALSE(AB.valid());
UUOverlaps BA(mapB, mapA);
ASSERT_TRUE(BA.valid());
EXPECT_EQ(3u, BA.a().start());
EXPECT_EQ(4u, BA.b().start());
BA.advanceTo(6);
EXPECT_FALSE(BA.valid());
BA.advanceTo(7);
EXPECT_FALSE(BA.valid());
}
TEST(IntervalMapOverlapsTest, BigMaps) {
typedef IntervalMapOverlaps<UUMap,UUMap> UUOverlaps;
UUMap::Allocator allocator;
UUMap mapA(allocator);
UUMap mapB(allocator);
for (unsigned n = 0; n != 100; ++n)
mapA.insert(10*n, 10*n+4, n);
for (unsigned n = 10; n != 20; ++n)
mapB.insert(10*n+5, 10*n+6, n);
for (unsigned n = 20; n != 30; ++n)
mapB.insert(10*n+8, 10*n+9, n);
mapB.insert(400, 400, 400);
mapB.insert(401, 401, 401);
mapB.insert(402, 500, 402);
mapB.insert(600, 601, 402);
UUOverlaps AB(mapA, mapB);
ASSERT_TRUE(AB.valid());
EXPECT_EQ(400u, AB.a().start());
EXPECT_EQ(400u, AB.b().start());
++AB;
ASSERT_TRUE(AB.valid());
EXPECT_EQ(400u, AB.a().start());
EXPECT_EQ(401u, AB.b().start());
++AB;
ASSERT_TRUE(AB.valid());
EXPECT_EQ(400u, AB.a().start());
EXPECT_EQ(402u, AB.b().start());
++AB;
ASSERT_TRUE(AB.valid());
EXPECT_EQ(410u, AB.a().start());
EXPECT_EQ(402u, AB.b().start());
++AB;
ASSERT_TRUE(AB.valid());
EXPECT_EQ(420u, AB.a().start());
EXPECT_EQ(402u, AB.b().start());
AB.skipB();
ASSERT_TRUE(AB.valid());
EXPECT_EQ(600u, AB.a().start());
EXPECT_EQ(600u, AB.b().start());
++AB;
EXPECT_FALSE(AB.valid());
UUOverlaps AB2(mapA, mapB);
AB2.advanceTo(410);
ASSERT_TRUE(AB2.valid());
EXPECT_EQ(410u, AB2.a().start());
EXPECT_EQ(402u, AB2.b().start());
AB2.advanceTo(411);
ASSERT_TRUE(AB2.valid());
EXPECT_EQ(410u, AB2.a().start());
EXPECT_EQ(402u, AB2.b().start());
UUOverlaps BA(mapB, mapA);
ASSERT_TRUE(BA.valid());
EXPECT_EQ(400u, BA.b().start());
EXPECT_EQ(400u, BA.a().start());
++BA;
ASSERT_TRUE(BA.valid());
EXPECT_EQ(400u, BA.b().start());
EXPECT_EQ(401u, BA.a().start());
++BA;
ASSERT_TRUE(BA.valid());
EXPECT_EQ(400u, BA.b().start());
EXPECT_EQ(402u, BA.a().start());
++BA;
ASSERT_TRUE(BA.valid());
EXPECT_EQ(410u, BA.b().start());
EXPECT_EQ(402u, BA.a().start());
++BA;
ASSERT_TRUE(BA.valid());
EXPECT_EQ(420u, BA.b().start());
EXPECT_EQ(402u, BA.a().start());
BA.skipA();
ASSERT_TRUE(BA.valid());
EXPECT_EQ(600u, BA.b().start());
EXPECT_EQ(600u, BA.a().start());
++BA;
EXPECT_FALSE(BA.valid());
UUOverlaps BA2(mapB, mapA);
BA2.advanceTo(410);
ASSERT_TRUE(BA2.valid());
EXPECT_EQ(410u, BA2.b().start());
EXPECT_EQ(402u, BA2.a().start());
BA2.advanceTo(411);
ASSERT_TRUE(BA2.valid());
EXPECT_EQ(410u, BA2.b().start());
EXPECT_EQ(402u, BA2.a().start());
}
}